From Ian McDonald and Arnaldo Carvalho de Melo: DCCP support.

This commit is contained in:
guy 2005-09-20 06:01:20 +00:00
parent 2173aaca25
commit 1c902dcdf3
12 changed files with 687 additions and 13 deletions

View File

@ -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. ken@xelerance.com. Summary for 3.9.4 tcpdump release
Mon. September 19, 2005. ken@xelerance.com. 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. ken@xelerance.com. 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. ken@xelerance.com. Summary for 3.9.3 tcpdump release

View File

@ -20,6 +20,7 @@ Additional people who have contributed patches:
Andy Heffernan <ahh@juniper.net>
Arkadiusz Miskiewicz <misiek@pld.org.pl>
Armando L. Caro Jr. <acaro@mail.eecis.udel.edu>
Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Atsushi Onoe <onoe@netbsd.org>
Ben Smithurst <ben@scientia.demon.co.uk>
Brent L. Bates <blbates@vigyan.com>
@ -53,6 +54,7 @@ Additional people who have contributed patches:
Harry Raaymakers <harryr@connect.com.au>
Heinz-Ado Arnolds <Ado.Arnolds@dhm-systems.de>
Hendrik Scholz <hendrik@scholz.net>
Ian McDonald <imcdnzl@gmail.com>
Jakob Schlyter <jakob@openbsd.org>
Jan Oravec <wsx@wsx6.net>
Jason R. Thorpe <thorpej@netbsd.org>

2
FILES
View File

@ -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

View File

@ -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

View 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 \

135
dccp.h Normal file
View File

@ -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__ */

View 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);

View File

@ -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" },

View File

@ -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

520
print-dccp.c Normal file
View File

@ -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;
}

View 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));

View 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;