diff -uNr tcpdump-2004.11.25.orig/Makefile.in tcpdump-2004.11.25.dccp/Makefile.in --- tcpdump-2004.11.25.orig/Makefile.in 2004-10-29 08:42:53.000000000 -0300 +++ tcpdump-2004.11.25.dccp/Makefile.in 2004-11-26 10:20:07.000000000 -0200 @@ -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 \ diff -uNr tcpdump-2004.11.25.orig/dccp.h tcpdump-2004.11.25.dccp/dccp.h --- tcpdump-2004.11.25.orig/dccp.h 1969-12-31 21:00:00.000000000 -0300 +++ tcpdump-2004.11.25.dccp/dccp.h 2004-11-26 11:54:18.000000000 -0200 @@ -0,0 +1,204 @@ +#ifndef __DCCP_HDR__ +#define __DCCP_HDR__ +/* + * Copyright (C) Arnaldo Carvalho de Melo 2004 + * + * This software may be distributed either under the terms of the + * BSD-style license that accompanies tcpdump or the GNU GPL version 2 + */ + +#define __LITTLE_ENDIAN_BITFIELD + +/** + * 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; +#if defined(__LITTLE_ENDIAN_BITFIELD) + u_int8_t dccph_cscov:4, + dccph_ccval:4; +#elif defined(__BIG_ENDIAN_BITFIELD) + u_int8_t dccph_ccval:4, + dccph_cscov:4; +#else +#error "Adjust your defines" +#endif + u_int16_t dccph_checksum; +#if defined(__LITTLE_ENDIAN_BITFIELD) + u_int32_t dccph_seq:24, + dccph_type:4, + dccph_x:1, + dccph_reserved:3; +#elif defined(__BIG_ENDIAN_BITFIELD) + u_int32_t dccph_reserved:3, + dccph_x:1, + dccph_type:4, + dccph_seq:24; +#else +#error "Adjust your defines" +#endif + u_int32_t dccph_options[0]; +}; + +/** + * 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 { +#if defined(__LITTLE_ENDIAN_BITFIELD) + u_int32_t dccph_reserved:8, + dccph_seq_low:24; +#elif defined(__BIG_ENDIAN_BITFIELD) + u_int32_t dccph_seq_low:24, + dccph_reserved:8; +#else +#error "Adjust your defines" +#endif + u_int32_t dccph_options[0]; +}; + +/** + * struct dccp_hdr_request - Conection initiation request header + * + * @dccph_req_service - Service to which the client app wants to connect + * @dccph_req_options - list of options (must be a multiple of 32 bits + */ +struct dccp_hdr_request { + u_int32_t dccph_req_service; + u_int32_t dccph_req_options[0]; +}; + +/** + * 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 { +#if defined(__LITTLE_ENDIAN_BITFIELD) + u_int32_t dccph_ack_nr_low:24, + dccph_reserved1:8; + u_int32_t dccph_options[0]; + u_int32_t dccph_reserved2:8, + dccph_ack_nr_high:24; +#elif defined(__BIG_ENDIAN_BITFIELD) + u_int32_t dccph_reserved1:8, + dccph_ack_nr_high:24; + u_int32_t dccph_options[0]; + u_int32_t dccph_ack_nr_low:24, + dccph_reserved2:8; +#else +#error "Adjust your defines" +#endif +}; + +/** + * 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 + * @dccph_resp_options - list of options (must be a multiple of 32 bits + */ +struct dccp_hdr_response { + struct dccp_hdr_ack_bits dccph_resp_ack; + u_int32_t dccph_resp_service; + u_int32_t dccph_resp_options[0]; +}; + +/** + * struct dccp_hdr_data - DataAck and Ack packets + * + * @dccph_data_options - list of options (must be a multiple of 32 bits + */ +struct dccp_hdr_data { + struct dccp_hdr_ack_bits dccph_data_ack; + u_int32_t dccph_data_options[0]; +}; + +static inline struct dccp_hdr_data *dccp_hdr_data(struct dccp_hdr *hdrg) +{ + const int ext = hdrg->dccph_x ? sizeof(struct dccp_hdr_ext) : 0; + + return (struct dccp_hdr_data *)(((u_char *)hdrg) + sizeof(hdrg) + ext); +} + +#define dccp_hdr_ack(hdrg) dccp_hdr_data(hdrg) + +/** + * struct dccp_hdr_close - Conection CloseReq and Close packets + * + * @dccph_close_options - list of options (must be a multiple of 32 bits + */ +struct dccp_hdr_close { + struct dccp_hdr_ack_bits dccph_close_ack; + u_int32_t dccph_close_options[0]; +}; + +/** + * struct dccp_hdr_reset - Unconditionally shut down a connection + * + * @dccph_reset_service - Echoes the Service Code on a received DCCP-Request + * @dccph_reset_options - list of options (must be a multiple of 32 bits + */ +struct dccp_hdr_reset { + struct dccp_hdr_ack_bits dccph_reset_ack; + u_int8_t dccph_reset_code, + dccph_reset_data[3]; + u_int32_t dccph_reset_options[0]; +}; + +/** + * struct dccp_hdr_sync - Conection CloseReq and Close packets + * + * @dccph_sync_service - Echoes the Service Code on a received DCCP-Request + * @dccph_sync_options - list of options (must be a multiple of 32 bits + */ +struct dccp_hdr_sync { + struct dccp_hdr_ack_bits dccph_sync_ack; + u_int32_t dccph_sync_options[0]; +}; + +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 -uNr tcpdump-2004.11.25.orig/interface.h tcpdump-2004.11.25.dccp/interface.h --- tcpdump-2004.11.25.orig/interface.h 2004-11-07 20:05:20.000000000 -0200 +++ tcpdump-2004.11.25.dccp/interface.h 2004-11-26 10:25:04.000000000 -0200 @@ -275,6 +275,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 -uNr tcpdump-2004.11.25.orig/ipproto.c tcpdump-2004.11.25.dccp/ipproto.c --- tcpdump-2004.11.25.orig/ipproto.c 2004-04-28 23:16:40.000000000 -0300 +++ tcpdump-2004.11.25.dccp/ipproto.c 2004-11-26 10:22:57.000000000 -0200 @@ -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 -uNr tcpdump-2004.11.25.orig/ipproto.h tcpdump-2004.11.25.dccp/ipproto.h --- tcpdump-2004.11.25.orig/ipproto.h 2004-04-28 19:02:23.000000000 -0300 +++ tcpdump-2004.11.25.dccp/ipproto.h 2004-11-26 10:22:12.000000000 -0200 @@ -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 -uNr tcpdump-2004.11.25.orig/print-dccp.c tcpdump-2004.11.25.dccp/print-dccp.c --- tcpdump-2004.11.25.orig/print-dccp.c 1969-12-31 21:00:00.000000000 -0300 +++ tcpdump-2004.11.25.dccp/print-dccp.c 2004-11-26 20:16:20.000000000 -0200 @@ -0,0 +1,173 @@ +/* + * Copyright (C) Arnaldo Carvalho de Melo 2004 + * + * 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 + +#include "dccp.h" +#include + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" /* must come after interface.h */ +#include "ip.h" +#ifdef INET6 +#include "ip6.h" +#endif + +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_reset_code(u_int8_t code) +{ + if (code >= __DCCP_RESET_CODE_LAST) + return "invalid"; + return dccp_reset_codes[code]; +} + +/** + * 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; + + 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("[|dccp]"); + return; + } + + if (len < sizeof(struct dccp_hdr)) { + (void)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; + } + + switch (dh->dccph_type) { + case DCCP_PKT_REQUEST: { + struct dccp_hdr_request *dhr = + (struct dccp_hdr_request *)(bp + sizeof(*dh)); + (void)printf("request (service=%d)", dhr->dccph_req_service); + break; + } + case DCCP_PKT_RESPONSE: { + struct dccp_hdr_response *dhr = + (struct dccp_hdr_response *)(bp + sizeof(*dh)); + (void)printf("response (service=%d, ack=%d)", + dhr->dccph_resp_service, + dhr->dccph_resp_ack.dccph_ack_nr_low); + break; + } + case DCCP_PKT_DATA: + (void)printf("data "); + break; + case DCCP_PKT_ACK: { + struct dccp_hdr_data *dhr = + (struct dccp_hdr_data *)(bp + sizeof(*dh)); + (void)printf("ack (ack=%d)", + dhr->dccph_data_ack.dccph_ack_nr_low); + break; + } + break; + case DCCP_PKT_DATAACK: + (void)printf("dataack "); + break; + case DCCP_PKT_CLOSEREQ: + (void)printf("closereq "); + break; + case DCCP_PKT_CLOSE: + (void)printf("close "); + break; + case DCCP_PKT_RESET: { + struct dccp_hdr_reset *dhr = + (struct dccp_hdr_reset *)(bp + sizeof(*dh)); + (void)printf("reset (code=%s)", + dccp_reset_code(dhr->dccph_reset_code)); + break; + } + case DCCP_PKT_SYNC: + (void)printf("sync "); + break; + case DCCP_PKT_SYNCACK: + (void)printf("syncack "); + break; + default: + (void)printf("invalid "); + break; + } + + if (vflag < 2) + return; +} diff -uNr tcpdump-2004.11.25.orig/print-ip.c tcpdump-2004.11.25.dccp/print-ip.c --- tcpdump-2004.11.25.orig/print-ip.c 2004-09-27 18:13:09.000000000 -0300 +++ tcpdump-2004.11.25.dccp/print-ip.c 2004-11-26 10:58:12.000000000 -0200 @@ -476,7 +476,7 @@ nh = ip->ip_p; if (nh != IPPROTO_TCP && nh != IPPROTO_UDP && - nh != IPPROTO_SCTP) { + nh != IPPROTO_DCCP && nh != IPPROTO_SCTP) { (void)printf("%s > %s: ", ipaddr_string(&ip->ip_src), ipaddr_string(&ip->ip_dst)); } @@ -520,6 +520,10 @@ sctp_print(cp, (const u_char *)ip, len); break; + case IPPROTO_DCCP: + dccp_print(cp, (const u_char *)ip, len); + break; + case IPPROTO_TCP: tcp_print(cp, len, (const u_char *)ip, (off &~ 0x6000)); break; diff -uNr tcpdump-2004.11.25.orig/print-ip6.c tcpdump-2004.11.25.dccp/print-ip6.c --- tcpdump-2004.11.25.orig/print-ip6.c 2004-09-29 13:49:32.000000000 -0300 +++ tcpdump-2004.11.25.dccp/print-ip6.c 2004-11-26 10:26:39.000000000 -0200 @@ -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;