mirror of
https://github.com/the-tcpdump-group/tcpdump.git
synced 2024-11-23 18:14:29 +08:00
From Ian McDonald and Arnaldo Carvalho de Melo: DCCP support.
This commit is contained in:
parent
2173aaca25
commit
1c902dcdf3
5
CHANGES
5
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. 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
|
||||
|
||||
|
2
CREDITS
2
CREDITS
@ -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
2
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
|
||||
|
4
INSTALL
4
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
|
||||
|
@ -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
135
dccp.h
Normal 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__ */
|
@ -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);
|
||||
|
@ -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" },
|
||||
|
@ -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
520
print-dccp.c
Normal 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;
|
||||
}
|
@ -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));
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user