Guy,

Comments inline.

> "dh_end" still isn't being used, as per my original comment:
> 
> > In addition, there are no TCHECK(), TCHECK2(), TTEST(), or TTEST2()
> > calls, and the "dh_end" variable isn't used, so no check appears to be
> > done to prevent the print routine from running past the end of the
> > captured data in the packet.
> 
> It might not need to be used - if there are a sufficient set of
> TCHECK/TTEST-family calls, checking against the captured data length is
> being done, and if all checks for the end of the packet (rather than the
> end of the captured data length) are done by checking against "len", it
> presumably wouldn't need to be - but if it's not used, it shouldn't exist.

I am checking explicitly at each set with the TCHECK/TTEST macros. I
have tested this with deliberately short packets and my old code
segfaulted and the new one doesn't. I haven't used dh_end because I
check each one before use. I believe this to be robust now - I spent
quite a few hours testing this after your orginal comments :-)

> 
> Also:
> 
>         1) FILES needs to be modified to include dccp.h and print-dccp.c;

Done
> 
>         2) INSTALL should be, too;

Done
> 
>         3) I've attached a patch to clean up some compiler warnings on OS X
> 10.3.9 (which probably show up on at least some other platforms).
> 

I've put these in place and also more picked up by using -Wall on gcc
(which I should have done in the first place).

I've also put in one warning picked up by Matthew Luckie and at his
suggestion also removed register keyword against variables and I'll
let the compiler work it out.

Please find attached new patch.

Regards,

Ian
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-06 10:24:24.276683776 +1200
@@ -0,0 +1,136 @@
+#ifndef __DCCP_HDR__
+#define __DCCP_HDR__
+/*
+ * Copyright (C) Arnaldo Carvalho de Melo 2004
+ * Copyright (C) Ian McDonald 2005 <[EMAIL PROTECTED]>
+ * 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) & 0x0FFF)
+
+/**
+ * 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) & 0x0FFF)
+
+/**
+ * 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-06 10:53:24.506128688 +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-06 10:54:23.370179992 +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-06 10:24:24.304679520 +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-06 10:24:24.305679368 +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-06 10:24:24.305679368 +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-06 10:24:24.333675112 +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-06 10:51:53.144017840 +1200
@@ -0,0 +1,523 @@
+/*
+ * 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);
+
+	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 = (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);
+
+	if (DCCPH_X(dh) != 0) {
+		u_int32_t ack_low = dh_ack->dccph_ack_nr_low;
+		
+		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;
+}
Binary files tcpdump-2005.08.22/.print-dccp.c.swp and dccpdump/.print-dccp.c.swp differ
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-06 10:24:24.362670704 +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-06 10:24:24.363670552 +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));
-
This is the tcpdump-workers list.
Visit https://lists.sandelman.ca/ to unsubscribe.

Reply via email to