]> The Tcpdump Group git mirrors - tcpdump/commitdiff
From Ian McDonald and Arnaldo Carvalho de Melo: DCCP support.
authorguy <guy>
Tue, 20 Sep 2005 06:01:20 +0000 (06:01 +0000)
committerguy <guy>
Tue, 20 Sep 2005 06:01:20 +0000 (06:01 +0000)
12 files changed:
CHANGES
CREDITS
FILES
INSTALL
Makefile.in
dccp.h [new file with mode: 0644]
interface.h
ipproto.c
ipproto.h
print-dccp.c [new file with mode: 0644]
print-ip.c
print-ip6.c

diff --git a/CHANGES b/CHANGES
index ab3a6d713bc6796aa3faf4282f6a5008b77cae41..efa4780ad73bfb88df7b5b14d6370d942a550551 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,6 @@
-$Header: /tcpdump/master/tcpdump/CHANGES,v 1.96 2005-09-06 21:21:54 guy Exp $
+$Header: /tcpdump/master/tcpdump/CHANGES,v 1.97 2005-09-20 06:01:20 guy Exp $
 
-Tue.   September 6, 2005.  [email protected]. Summary for 3.9.4 tcpdump release
+Mon.   September 19, 2005.  [email protected]. Summary for 3.9.4 tcpdump release
        Decoder support for more Juniper link-layer types
        Fix a potential buffer overflow (although it can't occur in
                practice).
@@ -17,6 +17,7 @@ Tue.  September 6, 2005.  [email protected]. Summary for 3.9.4 tcpdump release
        Don't require any fields other than flags to be present in IS-IS
                restart signaling TLVs, and only print the system ID in
                those TLVs as system IDs, not as node IDs.
+       Support for DCCP.
 
 Tue.   July 5, 2005.  [email protected]. Summary for 3.9.3 tcpdump release
 
diff --git a/CREDITS b/CREDITS
index 8c52ae76c3fab62f7d1f63697b513bddc3f36604..df778f89f860366874ae7a2595185ccf57ffc7fa 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -20,6 +20,7 @@ Additional people who have contributed patches:
         Andy Heffernan                  <[email protected]>
        Arkadiusz Miskiewicz            <[email protected]>
        Armando L. Caro Jr.             <[email protected]>
+       Arnaldo Carvalho de Melo        <[email protected]>
        Atsushi Onoe                    <[email protected]>
        Ben Smithurst                   <[email protected]>
        Brent L. Bates                  <[email protected]>
@@ -53,6 +54,7 @@ Additional people who have contributed patches:
        Harry Raaymakers                <[email protected]>
        Heinz-Ado Arnolds               <[email protected]>
        Hendrik Scholz                  <[email protected]>
+       Ian McDonald                    <[email protected]>
        Jakob Schlyter                  <[email protected]>
        Jan Oravec                      <[email protected]>
        Jason R. Thorpe                 <[email protected]>
diff --git a/FILES b/FILES
index 73e2919762ee633d1e1d6c5a8641d880c76b1627..d6c110b21ef213a43765f2a01991350cf59dc1d0 100644 (file)
--- a/FILES
+++ b/FILES
@@ -29,6 +29,7 @@ configure
 configure.in
 cpack.c
 cpack.h
+dccp.h
 decnet.h
 decode_prefix.h
 enc.h
@@ -125,6 +126,7 @@ print-cdp.c
 print-chdlc.c
 print-cip.c
 print-cnfp.c
+print-dccp.c
 print-decnet.c
 print-dhcp6.c
 print-domain.c
diff --git a/INSTALL b/INSTALL
index b015ce00d3961e4262cd2b1377220aff0fbca4df..30e822072db3122c1d28b8ac7a82baa4c732d827 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -1,4 +1,4 @@
-@(#) $Header: /tcpdump/master/tcpdump/Attic/INSTALL,v 1.66 2005-07-11 17:36:27 guy Exp $ (LBL)
+@(#) $Header: /tcpdump/master/tcpdump/Attic/INSTALL,v 1.67 2005-09-20 06:01:21 guy Exp $ (LBL)
 
 If you have not built libpcap, do so first.  See the README
 file in this directory for the ftp location.
@@ -71,6 +71,7 @@ config.h.in   - autoconf input
 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-cdp.c - Cisco Discovery Protocol printer routines
 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
index 9cdf409864f4b493120a7d94904b91f3109128b9..3859bce6fa558937a8edbd9d2de8af769058d1a9 100644 (file)
@@ -17,7 +17,7 @@
 #  WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 #  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 #
-# @(#) $Header: /tcpdump/master/tcpdump/Makefile.in,v 1.295 2005-07-10 14:44:50 hannes Exp $ (LBL)
+# @(#) $Header: /tcpdump/master/tcpdump/Makefile.in,v 1.296 2005-09-20 06:01:21 guy Exp $ (LBL)
 
 #
 # Various configurable paths (remember to edit Makefile.in, not Makefile)
@@ -70,7 +70,7 @@ CSRC =        addrtoname.c cpack.c gmpls.c oui.c gmt2local.c ipproto.c \
        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 @@ SRC = $(CSRC) $(GENSRC) $(LOCALSRC)
 # 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 --git a/dccp.h b/dccp.h
new file mode 100644 (file)
index 0000000..2c479aa
--- /dev/null
+++ b/dccp.h
@@ -0,0 +1,135 @@
+#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)
+
+/**
+ * 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__ */
index 148cfd94bf94eeb9a733d981026dea5756ba470a..8a1b87885b18676c2d3b20bbd39408903630ae89 100644 (file)
@@ -18,7 +18,7 @@
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- * @(#) $Header: /tcpdump/master/tcpdump/interface.h,v 1.260 2005-08-23 10:24:58 hannes Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/tcpdump/interface.h,v 1.261 2005-09-20 06:01:21 guy Exp $ (LBL)
  */
 
 #ifndef tcpdump_interface_h
@@ -298,6 +298,7 @@ extern void stp_print(const u_char *, u_int);
 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);
index d45864498e249d99530db67dcd46b3de0b632ed8..7b89afb9c836e067ebab932c466a835471a17a66 100755 (executable)
--- a/ipproto.c
+++ b/ipproto.c
@@ -15,7 +15,7 @@
 
 #ifndef lint
 static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/tcpdump/ipproto.c,v 1.5 2005-05-20 21:02:30 hannes Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/ipproto.c,v 1.6 2005-09-20 06:01:22 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -36,6 +36,7 @@ struct tok ipproto_values[] = {
     { IPPROTO_EGP, "EGP" },
     { IPPROTO_PIGP, "IGRP" },
     { IPPROTO_UDP, "UDP" },
+    { IPPROTO_DCCP, "DCCP" },
     { IPPROTO_IPV6, "IPv6" },
     { IPPROTO_ROUTING, "Routing" },
     { IPPROTO_FRAGMENT, "Fragment" },
index e588518d62473ac8c888a98e7c9c4b5961927328..f5257863ceddfab24f7446fce2bdd8fb55e11fdb 100644 (file)
--- a/ipproto.h
+++ b/ipproto.h
@@ -30,7 +30,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * @(#) $Header: /tcpdump/master/tcpdump/ipproto.h,v 1.5 2005-05-20 21:02:30 hannes Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/tcpdump/ipproto.h,v 1.6 2005-09-20 06:01:22 guy Exp $ (LBL)
  *
  * From:
  *     @(#)in.h        8.3 (Berkeley) 1/3/94
@@ -66,6 +66,9 @@ extern struct tok ipproto_values[];
 #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 --git a/print-dccp.c b/print-dccp.c
new file mode 100644 (file)
index 0000000..24b1232
--- /dev/null
@@ -0,0 +1,520 @@
+/*
+ * 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;
+       u_short sport, dport;
+       u_int hlen;
+       u_int extlen = 0;
+
+       dh = (const struct dccp_hdr *)bp;
+
+       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;
+}
index 18dc8a42c4d5077dd5e7d9968bb564d91a1a8a1f..552e6ab6f03ab661b3e4f8b35a2bc996c526dffd 100644 (file)
@@ -21,7 +21,7 @@
 
 #ifndef lint
 static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.150 2005-05-20 21:02:30 hannes Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.151 2005-09-20 06:01:22 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -411,6 +411,10 @@ again:
        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 @@ ip_print(netdissect_options *ndo,
                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));
index a3bc90d5da0dcfa1462496dba020672319aff73b..f43d61aab2e82e203abd5c09ff646c514fa723e1 100644 (file)
@@ -21,7 +21,7 @@
 
 #ifndef lint
 static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-ip6.c,v 1.49 2005-07-03 20:33:06 hannes Exp $";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-ip6.c,v 1.50 2005-09-20 06:01:23 guy Exp $";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -116,7 +116,7 @@ ip6_print(register const u_char *bp, register u_int length)
 
                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 @@ ip6_print(register const u_char *bp, register u_int length)
                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;