diff -urN tcpdump-2005.08.22/dccp.h dccpdump/dccp.h
--- tcpdump-2005.08.22/dccp.h	1970-01-01 12:00:00.000000000 +1200
+++ dccpdump/dccp.h	2005-09-14 14:18:54.000000000 +1200
@@ -0,0 +1,135 @@
+#ifndef __DCCP_HDR__
+#define __DCCP_HDR__
+/*
+ * Copyright (C) Arnaldo Carvalho de Melo 2004
+ * Copyright (C) Ian McDonald 2005 <iam4@cs.waikato.ac.nz>
+ * Copyright (C) Yoshifumi Nishida 2005
+ *
+ * This software may be distributed either under the terms of the
+ * BSD-style license that accompanies tcpdump or the GNU GPL version 2
+ */
+
+/**
+ * struct dccp_hdr - generic part of DCCP packet header
+ *
+ * @dccph_sport - Relevant port on the endpoint that sent this packet
+ * @dccph_dport - Relevant port on the other endpoint
+ * @dccph_doff - Data Offset from the start of the DCCP header, in 32-bit words
+ * @dccph_ccval - Used by the HC-Sender CCID
+ * @dccph_cscov - Parts of the packet that are covered by the Checksum field
+ * @dccph_checksum - Internet checksum, depends on dccph_cscov
+ * @dccph_x - 0 = 24 bit sequence number, 1 = 48
+ * @dccph_type - packet type, see DCCP_PKT_ prefixed macros
+ * @dccph_seq - sequence number high or low order 24 bits, depends on dccph_x
+ */
+struct dccp_hdr {
+	u_int16_t	dccph_sport,
+			dccph_dport;
+	u_int8_t	dccph_doff;
+	u_int8_t	dccph_ccval_cscov;
+	u_int16_t	dccph_checksum;
+	union {
+	u_int8_t	dccph_xtr;
+	u_int32_t	dccph_seq;
+	}		dccph_xtrs;
+};
+
+#define DCCPH_CCVAL(dh)	(((dh)->dccph_ccval_cscov) & 0x0F)
+#define DCCPH_CSCOV(dh)	(((dh)->dccph_ccval_cscov >> 4) & 0x0F)
+
+#define DCCPH_X(dh)	((dh)->dccph_xtrs.dccph_xtr & 1)
+#define DCCPH_TYPE(dh)	(((dh)->dccph_xtrs.dccph_xtr >> 1) & 0xF)
+#define DCCPH_SEQ(dh)   (((dh)->dccph_xtrs.dccph_seq) >> 8)
+
+/**
+ * struct dccp_hdr_ext - the low bits of a 48 bit seq packet
+ *
+ * @dccph_seq_low - low 24 bits of a 48 bit seq packet
+ */
+struct dccp_hdr_ext {
+	u_int32_t	dccph_seq_low;
+};
+
+/**
+ * struct dccp_hdr_request - Conection initiation request header
+ *
+ * @dccph_req_service - Service to which the client app wants to connect
+ */
+struct dccp_hdr_request {
+	u_int32_t	dccph_req_service;
+};
+
+/**
+ * struct dccp_hdr_ack_bits - acknowledgment bits common to most packets
+ *
+ * @dccph_resp_ack_nr_high - 48 bit ack number high order bits, contains GSR
+ * @dccph_resp_ack_nr_low - 48 bit ack number low order bits, contains GSR
+ */
+struct dccp_hdr_ack_bits {
+	u_int32_t	dccph_ra;
+	u_int32_t	dccph_ack_nr_low;
+};
+
+#define DCCPH_ACK(dh_ack)   ((dh_ack)->dccph_ra >> 8)
+
+/**
+ * struct dccp_hdr_response - Conection initiation response header
+ *
+ * @dccph_resp_ack_nr_high - 48 bit ack number high order bits, contains GSR
+ * @dccph_resp_ack_nr_low - 48 bit ack number low order bits, contains GSR
+ * @dccph_resp_service - Echoes the Service Code on a received DCCP-Request
+ */
+struct dccp_hdr_response {
+	struct dccp_hdr_ack_bits	dccph_resp_ack;
+	u_int32_t			dccph_resp_service;
+};
+
+static inline struct dccp_hdr_data *dccp_hdr_data(struct dccp_hdr *hdrg)
+{
+	const int ext = DCCPH_X(hdrg) ? sizeof(struct dccp_hdr_ext) : 0;
+
+	return (struct dccp_hdr_data *)(((u_char *)hdrg) + sizeof(hdrg) + ext);
+}
+
+/**
+ * struct dccp_hdr_reset - Unconditionally shut down a connection
+ *
+ * @dccph_reset_service - Echoes the Service Code on a received DCCP-Request
+ */
+struct dccp_hdr_reset {
+	struct dccp_hdr_ack_bits	dccph_reset_ack;
+	u_int8_t			dccph_reset_code,
+					dccph_reset_data[3];
+};
+
+enum dccp_pkt_type {
+	DCCP_PKT_REQUEST = 0,
+	DCCP_PKT_RESPONSE,
+	DCCP_PKT_DATA,
+	DCCP_PKT_ACK,
+	DCCP_PKT_DATAACK,
+	DCCP_PKT_CLOSEREQ,
+	DCCP_PKT_CLOSE,
+	DCCP_PKT_RESET,
+	DCCP_PKT_SYNC,
+	DCCP_PKT_SYNCACK,
+	DCCP_PKT_INVALID,
+};
+
+enum dccp_reset_codes {
+	DCCP_RESET_CODE_UNSPECIFIED = 0,
+	DCCP_RESET_CODE_CLOSED,
+	DCCP_RESET_CODE_ABORTED,
+	DCCP_RESET_CODE_NO_CONNECTION,
+	DCCP_RESET_CODE_PACKET_ERROR,
+	DCCP_RESET_CODE_OPTION_ERROR,
+	DCCP_RESET_CODE_MANDATORY_ERROR,
+	DCCP_RESET_CODE_CONNECTION_REFUSED,
+	DCCP_RESET_CODE_BAD_SERVICE_CODE,
+	DCCP_RESET_CODE_TOO_BUSY,
+	DCCP_RESET_CODE_BAD_INIT_COOKIE,
+	DCCP_RESET_CODE_AGGRESSION_PENALTY,
+	__DCCP_RESET_CODE_LAST,
+};
+
+#endif /* __DCCP_HDR__ */
diff -urN tcpdump-2005.08.22/FILES dccpdump/FILES
--- tcpdump-2005.08.22/FILES	2005-07-11 02:44:51.000000000 +1200
+++ dccpdump/FILES	2005-09-14 14:18:50.000000000 +1200
@@ -29,6 +29,7 @@
 configure.in
 cpack.c
 cpack.h
+dccp.h
 decnet.h
 decode_prefix.h
 enc.h
@@ -125,6 +126,7 @@
 print-chdlc.c
 print-cip.c
 print-cnfp.c
+print-dccp.c
 print-decnet.c
 print-dhcp6.c
 print-domain.c
diff -urN tcpdump-2005.08.22/INSTALL dccpdump/INSTALL
--- tcpdump-2005.08.22/INSTALL	2005-07-12 05:36:27.000000000 +1200
+++ dccpdump/INSTALL	2005-09-14 14:18:50.000000000 +1200
@@ -71,6 +71,7 @@
 config.sub	- autoconf support
 configure	- configure script (run this first)
 configure.in	- configure script source
+dccp.h		- DCCP definitions
 decnet.h	- DECnet definitions
 decode_prefix.h	- Declarations of "decode_prefix{4,6}()"
 enc.h		- OpenBSD IPsec encapsulation BPF layer definitions
@@ -146,6 +147,7 @@
 print-chdlc.c	- Cisco HDLC printer routines
 print-cip.c	- Classical-IP over ATM routines
 print-cnfp.c	- Cisco NetFlow printer routines
+print-dccp.c	- DCCP printer routines
 print-decnet.c	- DECnet printer routines
 print-dhcp6.c	- IPv6 DHCP printer routines
 print-domain.c	- Domain Name System printer routines
diff -urN tcpdump-2005.08.22/interface.h dccpdump/interface.h
--- tcpdump-2005.08.22/interface.h	2005-07-21 10:12:39.000000000 +1200
+++ dccpdump/interface.h	2005-09-14 14:18:50.000000000 +1200
@@ -293,6 +293,7 @@
 extern void radius_print(const u_char *, u_int);
 extern void lwres_print(const u_char *, u_int);
 extern void pptp_print(const u_char *);
+extern void dccp_print(const u_char *, const u_char *, u_int);
 extern void sctp_print(const u_char *, const u_char *, u_int);
 extern void mpls_print(const u_char *, u_int);
 extern void mpls_lsp_ping_print(const u_char *, u_int);
diff -urN tcpdump-2005.08.22/ipproto.c dccpdump/ipproto.c
--- tcpdump-2005.08.22/ipproto.c	2005-05-21 09:02:30.000000000 +1200
+++ dccpdump/ipproto.c	2005-09-14 14:18:50.000000000 +1200
@@ -36,6 +36,7 @@
     { IPPROTO_EGP, "EGP" },
     { IPPROTO_PIGP, "IGRP" },
     { IPPROTO_UDP, "UDP" },
+    { IPPROTO_DCCP, "DCCP" },
     { IPPROTO_IPV6, "IPv6" },
     { IPPROTO_ROUTING, "Routing" },
     { IPPROTO_FRAGMENT, "Fragment" },
diff -urN tcpdump-2005.08.22/ipproto.h dccpdump/ipproto.h
--- tcpdump-2005.08.22/ipproto.h	2005-05-21 09:02:30.000000000 +1200
+++ dccpdump/ipproto.h	2005-09-14 14:18:50.000000000 +1200
@@ -66,6 +66,9 @@
 #ifndef IPPROTO_UDP
 #define	IPPROTO_UDP		17		/* user datagram protocol */
 #endif
+#ifndef IPPROTO_DCCP
+#define	IPPROTO_DCCP		33		/* datagram congestion control protocol */
+#endif
 #ifndef IPPROTO_IPV6
 #define IPPROTO_IPV6		41
 #endif
diff -urN tcpdump-2005.08.22/Makefile.in dccpdump/Makefile.in
--- tcpdump-2005.08.22/Makefile.in	2005-07-11 02:44:50.000000000 +1200
+++ dccpdump/Makefile.in	2005-09-14 14:18:50.000000000 +1200
@@ -70,7 +70,7 @@
 	print-802_11.c print-ap1394.c print-ah.c print-arcnet.c \
 	print-aodv.c print-arp.c print-ascii.c print-atalk.c print-atm.c \
 	print-beep.c print-bfd.c print-bgp.c print-bootp.c print-cdp.c \
-	print-chdlc.c print-cip.c print-cnfp.c print-decnet.c \
+	print-chdlc.c print-cip.c print-cnfp.c print-dccp.c print-decnet.c \
 	print-domain.c print-dvmrp.c print-enc.c print-egp.c \
 	print-eap.c print-eigrp.c\
 	print-esp.c print-ether.c print-fddi.c print-fr.c \
@@ -98,7 +98,7 @@
 # We would like to say "OBJ = $(SRC:.c=.o)" but Ultrix's make cannot
 # hack the extra indirection
 OBJ =	$(CSRC:.c=.o) $(GENSRC:.c=.o) $(LOCALSRC:.c=.o) $(LIBOBJS)
-HDR =   addrtoname.h appletalk.h bootp.h cpack.h decnet.h \
+HDR =   addrtoname.h appletalk.h bootp.h cpack.h dccp.h decnet.h \
 	ethertype.h extract.h fddi.h gmt2local.h igrp.h interface.h \
 	ipx.h llc.h machdep.h mib.h nfsfh.h nfsv2.h ntp.h ospf.h \
 	setsignal.h \
diff -urN tcpdump-2005.08.22/print-dccp.c dccpdump/print-dccp.c
--- tcpdump-2005.08.22/print-dccp.c	1970-01-01 12:00:00.000000000 +1200
+++ dccpdump/print-dccp.c	2005-09-14 14:18:54.000000000 +1200
@@ -0,0 +1,524 @@
+/*
+ * Copyright (C) Arnaldo Carvalho de Melo 2004
+ * Copyright (C) Ian McDonald 2005
+ * Copyright (C) Yoshifumi Nishida 2005
+ *
+ * This software may be distributed either under the terms of the
+ * BSD-style license that accompanies tcpdump or the GNU GPL version 2
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include "dccp.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"			/* must come after interface.h */
+#include "ip.h"
+#ifdef INET6
+#include "ip6.h"
+#endif
+#include "ipproto.h"
+
+static const char *dccp_reset_codes[] = {
+	"unspecified",
+	"closed",
+	"aborted",
+	"no_connection",
+	"packet_error",
+	"option_error",
+	"mandatory_error",
+	"connection_refused",
+	"bad_service_code",
+	"too_busy",
+	"bad_init_cookie",
+	"aggression_penalty",
+};
+
+static const char *dccp_feature_nums[] = {
+	"reserved", 
+	"ccid",
+	"allow_short_seqno",
+	"sequence_window",
+	"ecn_incapable", 
+	"ack_ratio",     
+	"send_ack_vector",
+	"send_ndp_count", 
+	"minimum checksum coverage", 
+	"check data checksum",
+};
+
+static int dccp_cksum(const struct ip *ip,
+	const struct dccp_hdr *dh, u_int len)
+{
+	union phu {
+		struct phdr {
+			u_int32_t src;
+			u_int32_t dst;
+			u_char mbz;
+			u_char proto;
+			u_int16_t len;
+		} ph;
+		u_int16_t pa[6];
+	} phu;
+	const u_int16_t *sp;
+
+	/* pseudo-header.. */
+	phu.ph.mbz = 0;
+	phu.ph.len = htons(len);
+	phu.ph.proto = IPPROTO_DCCP;
+	memcpy(&phu.ph.src, &ip->ip_src.s_addr, sizeof(u_int32_t));
+	if (IP_HL(ip) == 5)
+		memcpy(&phu.ph.dst, &ip->ip_dst.s_addr, sizeof(u_int32_t));
+	else
+		phu.ph.dst = ip_finddst(ip);
+
+	sp = &phu.pa[0];
+	return in_cksum((u_short *)dh, len, sp[0]+sp[1]+sp[2]+sp[3]+sp[4]+sp[5]);
+}
+
+#ifdef INET6
+static int dccp6_cksum(const struct ip6_hdr *ip6, const struct dccp_hdr *dh, u_int len)
+{
+	size_t i;
+	const u_int16_t *sp;
+	u_int32_t sum;
+	union {
+		struct {
+			struct in6_addr ph_src;
+			struct in6_addr ph_dst;
+			u_int32_t   ph_len;
+			u_int8_t    ph_zero[3];
+			u_int8_t    ph_nxt;
+		} ph;
+		u_int16_t pa[20];
+	} phu;
+
+	/* pseudo-header */
+	memset(&phu, 0, sizeof(phu));
+	phu.ph.ph_src = ip6->ip6_src;
+	phu.ph.ph_dst = ip6->ip6_dst;
+	phu.ph.ph_len = htonl(len);
+	phu.ph.ph_nxt = IPPROTO_DCCP;
+
+	sum = 0;
+	for (i = 0; i < sizeof(phu.pa) / sizeof(phu.pa[0]); i++)
+		sum += phu.pa[i];
+
+	sp = (const u_int16_t *)dh;
+
+	for (i = 0; i < (len & ~1); i += 2)
+		sum += *sp++;
+
+	if (len & 1)
+		sum += htons((*(const u_int8_t *)sp) << 8);
+
+	while (sum > 0xffff)
+		sum = (sum & 0xffff) + (sum >> 16);
+	sum = ~sum & 0xffff;
+
+	return (sum);
+}
+#endif
+
+static const char *dccp_reset_code(u_int8_t code)
+{
+	if (code >= __DCCP_RESET_CODE_LAST)
+		return "invalid";
+	return dccp_reset_codes[code];
+}
+
+static u_int64_t dccp_seqno(const struct dccp_hdr *dh)
+{
+	u_int32_t seq_high = DCCPH_SEQ(dh);
+	u_int64_t seqno = EXTRACT_24BITS(&seq_high) & 0xFFFFFF;
+
+	if (DCCPH_X(dh) != 0) {
+		const struct dccp_hdr_ext *dhx = (void *)dh + sizeof(*dh);
+		u_int32_t seq_low = dhx->dccph_seq_low;
+		seqno &= 0x00FFFF;  /* clear reserved field */
+		seqno = (seqno << 32) + EXTRACT_32BITS(&seq_low);
+	}
+
+	return seqno;
+}
+
+static u_int64_t dccp_ack_no(const struct dccp_hdr *dh,
+		const struct dccp_hdr_ack_bits *dh_ack)
+{
+	u_int32_t ack_high = DCCPH_ACK(dh_ack);
+	u_int64_t ackno = EXTRACT_24BITS(&ack_high) & 0xFFFFFF;
+
+	if (DCCPH_X(dh) != 0) {
+		u_int32_t ack_low = dh_ack->dccph_ack_nr_low;
+		
+		ackno &= 0x00FFFF;  /* clear reserved field */
+		ackno = (ackno << 32) + EXTRACT_32BITS(&ack_low);
+	}
+
+	return ackno;
+}
+
+static inline unsigned int dccp_basic_hdr_len(const struct dccp_hdr *dh)
+{
+	return sizeof(*dh) + (DCCPH_X(dh) ? sizeof(struct dccp_hdr_ext) : 0);
+}
+
+static inline unsigned int dccp_packet_hdr_len(const u_int8_t type)
+{
+	if (type == DCCP_PKT_DATA)
+		return 0;
+	if (type == DCCP_PKT_DATAACK	||
+	    type == DCCP_PKT_ACK	||
+	    type == DCCP_PKT_SYNC	||
+	    type == DCCP_PKT_SYNCACK	||
+	    type == DCCP_PKT_CLOSE	||
+	    type == DCCP_PKT_CLOSEREQ)
+		return sizeof(struct dccp_hdr_ack_bits);
+	if (type == DCCP_PKT_REQUEST)
+		return sizeof(struct dccp_hdr_request);
+	if (type == DCCP_PKT_RESPONSE)
+		return sizeof(struct dccp_hdr_response);
+	return sizeof(struct dccp_hdr_reset);
+}
+
+static int dccp_print_option(const u_char *option);
+
+/**
+ * dccp_print - show dccp packet
+ * @bp - beginning of dccp packet
+ * @data2 - beginning of enclosing 
+ * @len - lenght of ip packet
+ */
+void dccp_print(const u_char *bp, const u_char *data2, u_int len)
+{
+	const struct dccp_hdr *dh;
+	const struct ip *ip;
+#ifdef INET6
+	const struct ip6_hdr *ip6;
+#endif
+	const u_char *cp;
+	const void *dh_end;
+	u_short sport, dport;
+	u_int hlen;
+	u_int extlen = 0;
+
+	dh = (const struct dccp_hdr *)bp;
+	dh_end = (const u_char *)dh + len;
+
+	if ((u_long)dh_end > (u_long)snapend)
+		dh_end = (const void *)snapend;
+	ip = (struct ip *)data2;
+#ifdef INET6
+	if (IP_V(ip) == 6)
+		ip6 = (const struct ip6_hdr *)data2;
+	else
+		ip6 = NULL;
+#endif /*INET6*/
+	cp = (const u_char *)(dh + 1);
+	if (cp > snapend) {
+		printf("[Invalid packet|dccp]");
+		return;
+	}
+
+	if (len < sizeof(struct dccp_hdr)) {
+		printf("truncated-dccp - %ld bytes missing!",
+			     (long)len - sizeof(struct dccp_hdr));
+		return;
+	}
+
+	sport = EXTRACT_16BITS(&dh->dccph_sport);
+	dport = EXTRACT_16BITS(&dh->dccph_dport);
+	hlen = dh->dccph_doff * 4;
+
+#ifdef INET6
+	if (ip6) {
+		(void)printf("%s.%d > %s.%d: ",
+			     ip6addr_string(&ip6->ip6_src), sport,
+			     ip6addr_string(&ip6->ip6_dst), dport);
+	} else
+#endif /*INET6*/
+	{
+		(void)printf("%s.%d > %s.%d: ",
+			     ipaddr_string(&ip->ip_src), sport,
+			     ipaddr_string(&ip->ip_dst), dport);
+	}
+	fflush(stdout);
+
+	if (qflag) {
+		(void)printf(" %d", len - hlen);
+		if (hlen > len) {
+			(void)printf("dccp [bad hdr length %u - too long, > %u]",
+			    hlen, len);
+		}
+		return;
+	}
+
+	/* other variables in generic header */
+	if (vflag) {
+		(void)printf("CCVal %d, CsCov %d, ", DCCPH_CCVAL(dh), DCCPH_CSCOV(dh));
+	}
+
+	/* checksum calculation */
+#ifdef INET6
+	if (ip6) {
+		if (ip6->ip6_plen && vflag) {
+			u_int16_t sum, dccp_sum;
+
+			sum = dccp6_cksum(ip6, dh, len);
+			dccp_sum = EXTRACT_16BITS(&dh->dccph_checksum);		
+			printf("cksum 0x%04x", dccp_sum);		
+			if (sum != 0) {
+				(void)printf(" (incorrect (-> 0x%04x), ",in_cksum_shouldbe(dccp_sum, sum));
+			} else
+				(void)printf(" (correct), ");
+		}					
+	} else 
+#endif /* INET6 */
+	if (vflag)
+	{
+		u_int16_t sum, dccp_sum;
+
+		sum = dccp_cksum(ip, dh, len);
+		dccp_sum = EXTRACT_16BITS(&dh->dccph_checksum);		
+		printf("cksum 0x%04x", dccp_sum);		
+		if (sum != 0) {
+			(void)printf(" (incorrect (-> 0x%04x), ",in_cksum_shouldbe(dccp_sum, sum));
+		} else
+			(void)printf(" (correct), ");
+	}
+
+	switch (DCCPH_TYPE(dh)) {
+	case DCCP_PKT_REQUEST: {
+		struct dccp_hdr_request *dhr =
+			(struct dccp_hdr_request *)(bp + dccp_basic_hdr_len(dh));
+		TCHECK(*dhr);
+		(void)printf("request (service=%d) ", dhr->dccph_req_service);
+		extlen += 4;
+		break;
+	}
+	case DCCP_PKT_RESPONSE: {
+		struct dccp_hdr_response *dhr =
+			(struct dccp_hdr_response *)(bp + dccp_basic_hdr_len(dh));
+		TCHECK(*dhr);
+		(void)printf("response (service=%d, ack=%" PRIu64 ") ",
+			     dhr->dccph_resp_service,
+			     dccp_ack_no(dh,&(dhr->dccph_resp_ack)));
+		extlen += 12;
+		break;
+	}
+	case DCCP_PKT_DATA:
+		(void)printf("data ");
+		break;
+	case DCCP_PKT_ACK: {
+		struct dccp_hdr_ack_bits *dha =
+			(struct dccp_hdr_ack_bits *)(bp + dccp_basic_hdr_len(dh));
+		TCHECK(*dha);
+		(void)printf("ack (ack=%" PRIu64 ") ",
+			     dccp_ack_no(dh,dha));
+		extlen += 8;
+		break;
+	}
+	case DCCP_PKT_DATAACK: {
+		struct dccp_hdr_ack_bits *dha =
+			(struct dccp_hdr_ack_bits *)(bp + dccp_basic_hdr_len(dh));
+		TCHECK(*dha);
+		(void)printf("dataack (ack=%" PRIu64 ") ",
+			     dccp_ack_no(dh,dha));
+		extlen += 8;
+		break;
+	}
+	case DCCP_PKT_CLOSEREQ:
+		(void)printf("closereq ");
+		extlen += 8;
+		break;
+	case DCCP_PKT_CLOSE:
+		(void)printf("close ");
+		extlen += 8;
+		break;
+	case DCCP_PKT_RESET: {
+		struct dccp_hdr_reset *dhr =
+			(struct dccp_hdr_reset *)(bp + dccp_basic_hdr_len(dh));
+		TCHECK(*dhr);
+		(void)printf("reset (code=%s) ",
+			     dccp_reset_code(dhr->dccph_reset_code));
+		extlen += 12;
+		break;
+	}
+	case DCCP_PKT_SYNC:
+		(void)printf("sync ");
+		extlen += 8;
+		break;
+	case DCCP_PKT_SYNCACK:
+		(void)printf("syncack ");
+		extlen += 8;
+		break;
+	default:
+		(void)printf("invalid ");
+		break;
+	}
+
+	if (vflag < 2)
+		return;
+
+	(void)printf("seq %" PRIu64, dccp_seqno(dh));
+
+	/* process options */
+	if (hlen > dccp_basic_hdr_len(dh) + extlen){
+		const u_char *cp;
+		u_int optlen;
+		cp = bp + dccp_basic_hdr_len(dh) + extlen;
+		printf(" <");	
+
+		hlen -= dccp_basic_hdr_len(dh) + extlen;
+		while(1){
+			TCHECK(*cp);
+			optlen = dccp_print_option(cp);
+			if (!optlen) goto trunc2;
+			if (hlen <= optlen) break; 
+			hlen -= optlen;
+			cp += optlen;
+			printf(", ");
+		}
+		printf(">");	
+	}
+	return;
+trunc:
+	printf("[|dccp]");
+trunc2:
+	return;
+}
+
+static int dccp_print_option(const u_char *option)
+{	
+	u_int8_t optlen, i;
+	u_int32_t *ts;
+	u_int16_t *var16;
+	u_int32_t *var32;
+
+	TCHECK(*option);
+
+	if (*option >= 32) {
+		TCHECK(*(option+1));
+		optlen = *(option +1);
+		if (optlen < 2) {
+			printf("Option %d optlen too short",*option);
+			return 1;
+		}
+	} else optlen = 1;
+
+	TCHECK2(*option,optlen);
+
+	switch (*option){
+	case 0:
+		printf("nop");
+		break;	
+	case 1:
+		printf("mandatory");
+		break;	
+	case 2:
+		printf("slowreceiver");
+		break;	
+	case 32:
+		printf("change_l");
+		if (*(option +2) < 10){
+			printf(" %s", dccp_feature_nums[*(option +2)]);
+			for (i = 0; i < optlen -3; i ++) printf(" %d", *(option +3 + i));	
+		}
+		break;	
+	case 33:
+		printf("confirm_l");
+		if (*(option +2) < 10){
+			printf(" %s", dccp_feature_nums[*(option +2)]);
+			for (i = 0; i < optlen -3; i ++) printf(" %d", *(option +3 + i));	
+		}
+		break;
+	case 34:
+	        printf("change_r");
+		if (*(option +2) < 10){
+			printf(" %s", dccp_feature_nums[*(option +2)]);
+			for (i = 0; i < optlen -3; i ++) printf(" %d", *(option +3 + i));	
+		}
+		break;
+	case 35:
+		printf("confirm_r");
+		if (*(option +2) < 10){
+			printf(" %s", dccp_feature_nums[*(option +2)]);
+			for (i = 0; i < optlen -3; i ++) printf(" %d", *(option +3 + i));	
+		}
+		break;
+	case 36:
+		printf("initcookie 0x");
+		for (i = 0; i < optlen -2; i ++) printf("%02x", *(option +2 + i));	
+		break;
+	case 37:
+		printf("ndp_count");
+		for (i = 0; i < optlen -2; i ++) printf(" %d", *(option +2 + i));	
+		break;
+	case 38:
+		printf("ack_vector0 0x");
+		for (i = 0; i < optlen -2; i ++) printf("%02x", *(option +2 + i));	
+		break;
+	case 39:
+		printf("ack_vector1 0x");
+		for (i = 0; i < optlen -2; i ++) printf("%02x", *(option +2 + i));	
+		break;
+	case 40:
+		printf("data_dropped 0x");
+		for (i = 0; i < optlen -2; i ++) printf("%02x", *(option +2 + i));	
+		break;
+	case 41:
+		ts = (u_int32_t *)(option + 2);
+		printf("timestamp %u", (u_int32_t)ntohl(*ts));
+		break;
+	case 42:
+		ts = (u_int32_t *)(option + 2);
+		printf("timestamp_echo %u", (u_int32_t)ntohl(*ts));
+		break;
+	case 43:
+		printf("elapsed_time ");
+		if (optlen == 6){
+			ts = (u_int32_t *)(option + 2);
+			printf("%u", (u_int32_t)ntohl(*ts));
+		} else {
+			var16 = (u_int16_t *)(option + 2);
+			printf("%u", ntohs(*var16));
+		}	
+		break;
+	case 44:
+		printf("data_checksum ");
+		for (i = 0; i < optlen -2; i ++) printf("%02x", *(option +2 + i));	
+		break;
+	default :
+		if (*option >= 128) {
+			printf("CCID option %d",*option);
+			switch (optlen) {
+				case 4:
+					var16 = (u_int16_t *)(option + 2);
+					printf(" %u",ntohs(*var16));
+					break;
+				case 6:
+					var32 = (u_int32_t *)(option + 2);
+					printf(" %u",(u_int32_t)ntohl(*var32));
+					break;
+				default:
+					break;
+			}
+			break;
+		}
+			
+		printf("unknown_opt %d", *option);
+		break;
+	}
+
+	return optlen;
+trunc:
+	printf("[|dccp]");
+	return 0;
+}
diff -urN tcpdump-2005.08.22/print-ip6.c dccpdump/print-ip6.c
--- tcpdump-2005.08.22/print-ip6.c	2005-07-04 08:33:06.000000000 +1200
+++ dccpdump/print-ip6.c	2005-09-14 14:18:50.000000000 +1200
@@ -116,7 +116,7 @@
 
 		if (cp == (const u_char *)(ip6 + 1) &&
 		    nh != IPPROTO_TCP && nh != IPPROTO_UDP &&
-		    nh != IPPROTO_SCTP) {
+		    nh != IPPROTO_DCCP && nh != IPPROTO_SCTP) {
 			(void)printf("%s > %s: ", ip6addr_string(&ip6->ip6_src),
 				     ip6addr_string(&ip6->ip6_dst));
 		}
@@ -160,6 +160,9 @@
 		case IPPROTO_SCTP:
 			sctp_print(cp, (const u_char *)ip6, len);
 			return;
+		case IPPROTO_DCCP:
+			dccp_print(cp, (const u_char *)ip6, len);
+			return;
 		case IPPROTO_TCP:
 			tcp_print(cp, len, (const u_char *)ip6, fragmented);
 			return;
diff -urN tcpdump-2005.08.22/print-ip.c dccpdump/print-ip.c
--- tcpdump-2005.08.22/print-ip.c	2005-05-21 09:02:30.000000000 +1200
+++ dccpdump/print-ip.c	2005-09-14 14:18:50.000000000 +1200
@@ -411,6 +411,10 @@
 	case IPPROTO_SCTP:
 		sctp_print(ipds->cp, (const u_char *)ipds->ip, ipds->len);
 		break;
+
+	case IPPROTO_DCCP:
+		dccp_print(ipds->cp, (const u_char *)ipds->ip, ipds->len);
+		break;
 		
 	case IPPROTO_TCP:
 		tcp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip,
@@ -665,7 +669,7 @@
 		ipds->nh = ipds->ip->ip_p;
 
 		if (ipds->nh != IPPROTO_TCP && ipds->nh != IPPROTO_UDP &&
-		    ipds->nh != IPPROTO_SCTP) {
+		    ipds->nh != IPPROTO_SCTP && ipds->nh != IPPROTO_DCCP) {
 			(void)printf("%s > %s: ",
 				     ipaddr_string(&ipds->ip->ip_src),
 				     ipaddr_string(&ipds->ip->ip_dst));
