From 27bfbee10c1ae9c37f9eca737077e1bbf1bd4d52 Mon Sep 17 00:00:00 2001 From: Peter Avalos Date: Sun, 22 Jan 2012 17:08:25 -0800 Subject: [PATCH] Import tcpdump-4.2.1. See the CHANGES files for the details. --- contrib/tcpdump/CHANGES | 104 +- contrib/tcpdump/INSTALL.txt | 3 +- contrib/tcpdump/README | 14 +- contrib/tcpdump/README.DELETED | 8 +- contrib/tcpdump/VERSION | 2 +- contrib/tcpdump/addrtoname.c | 75 +- contrib/tcpdump/addrtoname.h | 1 + contrib/tcpdump/af.c | 4 +- contrib/tcpdump/af.h | 4 +- contrib/tcpdump/atmuni31.h | 2 +- contrib/tcpdump/bootp.h | 9 +- contrib/tcpdump/bpf_dump.c | 66 - contrib/tcpdump/checksum.c | 67 +- contrib/tcpdump/cpack.c | 4 +- contrib/tcpdump/cpack.h | 3 + contrib/tcpdump/ethertype.h | 25 +- contrib/tcpdump/forces.h | 679 +++++++++ contrib/tcpdump/gmpls.c | 18 +- contrib/tcpdump/gmpls.h | 18 +- contrib/tcpdump/gmt2local.h | 2 +- contrib/tcpdump/icmp6.h | 10 +- contrib/tcpdump/ieee802_11.h | 58 +- contrib/tcpdump/ieee802_11_radio.h | 130 +- contrib/tcpdump/in_cksum.c | 200 +++ contrib/tcpdump/interface.h | 53 +- contrib/tcpdump/ip.h | 6 +- contrib/tcpdump/ip6.h | 23 +- contrib/tcpdump/ipnet.h | 13 + contrib/tcpdump/ipproto.c | 3 +- contrib/tcpdump/ipproto.h | 5 +- contrib/tcpdump/isakmp.h | 24 +- contrib/tcpdump/l2vpn.c | 2 +- contrib/tcpdump/l2vpn.h | 2 +- contrib/tcpdump/makemib | 249 ---- contrib/tcpdump/netdissect.h | 111 +- contrib/tcpdump/nfs.h | 3 +- contrib/tcpdump/nlpid.c | 2 +- contrib/tcpdump/nlpid.h | 2 +- contrib/tcpdump/ospf.h | 4 +- contrib/tcpdump/oui.c | 7 +- contrib/tcpdump/oui.h | 7 +- contrib/tcpdump/pcap_dump_ftell.c | 36 - contrib/tcpdump/ppi.h | 9 + contrib/tcpdump/print-802_11.c | 1493 ++++++++++++++++--- contrib/tcpdump/print-802_15_4.c | 183 +++ contrib/tcpdump/print-ap1394.c | 18 +- contrib/tcpdump/print-arcnet.c | 9 +- contrib/tcpdump/print-arp.c | 1 + contrib/tcpdump/print-atalk.c | 62 +- contrib/tcpdump/print-atm.c | 12 +- contrib/tcpdump/print-babel.c | 414 +++++ contrib/tcpdump/print-bfd.c | 14 +- contrib/tcpdump/print-bgp.c | 334 +++-- contrib/tcpdump/print-bootp.c | 8 +- contrib/tcpdump/print-bt.c | 79 + contrib/tcpdump/print-carp.c | 88 ++ contrib/tcpdump/print-cdp.c | 31 +- contrib/tcpdump/print-cfm.c | 4 + contrib/tcpdump/print-chdlc.c | 2 +- contrib/tcpdump/print-dccp.c | 84 +- contrib/tcpdump/print-dhcp6.c | 268 ++-- contrib/tcpdump/print-domain.c | 2 +- contrib/tcpdump/print-eigrp.c | 4 +- contrib/tcpdump/print-enc.c | 9 +- contrib/tcpdump/print-esp.c | 397 +++-- contrib/tcpdump/print-ether.c | 326 ++-- contrib/tcpdump/print-forces.c | 1055 +++++++++++++ contrib/tcpdump/print-fr.c | 9 +- contrib/tcpdump/print-gre.c | 5 +- contrib/tcpdump/print-icmp.c | 21 +- contrib/tcpdump/print-icmp6.c | 193 ++- contrib/tcpdump/print-igmp.c | 6 +- contrib/tcpdump/print-ip.c | 159 +- contrib/tcpdump/print-ip6.c | 89 +- contrib/tcpdump/print-ipnet.c | 109 ++ contrib/tcpdump/print-ipx.c | 4 +- contrib/tcpdump/print-isakmp.c | 259 +++- contrib/tcpdump/print-isoclns.c | 74 +- contrib/tcpdump/print-juniper.c | 19 +- contrib/tcpdump/print-l2tp.c | 41 +- contrib/tcpdump/print-lane.c | 69 +- contrib/tcpdump/print-ldp.c | 2 +- contrib/tcpdump/print-llc.c | 14 +- contrib/tcpdump/print-lldp.c | 450 +++++- contrib/tcpdump/print-lmp.c | 2 +- contrib/tcpdump/print-lspping.c | 32 +- contrib/tcpdump/print-mobile.c | 5 +- contrib/tcpdump/print-mpls.c | 202 ++- contrib/tcpdump/print-nfs.c | 35 +- contrib/tcpdump/print-ntp.c | 27 +- contrib/tcpdump/print-null.c | 2 +- contrib/tcpdump/print-olsr.c | 377 ++++- contrib/tcpdump/print-ospf.c | 8 +- contrib/tcpdump/print-pflog.c | 7 +- contrib/tcpdump/print-pgm.c | 88 ++ contrib/tcpdump/print-pim.c | 40 +- contrib/tcpdump/print-ppi.c | 104 ++ contrib/tcpdump/print-ppp.c | 24 +- contrib/tcpdump/print-rpki-rtr.c | 368 +++++ contrib/tcpdump/print-rrcp.c | 134 +- contrib/tcpdump/print-rsvp.c | 210 ++- contrib/tcpdump/print-rx.c | 2 +- contrib/tcpdump/print-sctp.c | 60 +- contrib/tcpdump/print-sflow.c | 805 +++++++--- contrib/tcpdump/print-sip.c | 4 + contrib/tcpdump/print-sl.c | 2 +- contrib/tcpdump/print-sll.c | 49 +- contrib/tcpdump/print-slow.c | 4 +- contrib/tcpdump/print-smb.c | 2 +- contrib/tcpdump/print-sunrpc.c | 25 +- contrib/tcpdump/print-symantec.c | 9 +- contrib/tcpdump/print-tcp.c | 172 ++- contrib/tcpdump/print-tftp.c | 10 +- contrib/tcpdump/print-token.c | 15 +- contrib/tcpdump/print-udp.c | 143 +- contrib/tcpdump/print-usb.c | 174 +++ contrib/tcpdump/print-vrrp.c | 12 +- contrib/tcpdump/setsignal.h | 2 +- contrib/tcpdump/signature.c | 159 ++ contrib/tcpdump/{l2vpn.h => signature.h} | 13 +- contrib/tcpdump/sll.h | 2 +- contrib/tcpdump/smbutil.c | 4 +- contrib/tcpdump/strcasecmp.c | 93 -- contrib/tcpdump/tcp.h | 6 +- contrib/tcpdump/tcpdump-stdinc.h | 53 +- contrib/tcpdump/{tcpdump.1 => tcpdump.1.in} | 120 +- contrib/tcpdump/tcpdump.c | 392 ++++- contrib/tcpdump/tftp.h | 2 +- contrib/tcpdump/timed.h | 2 +- contrib/tcpdump/token.h | 12 +- contrib/tcpdump/udp.h | 2 + contrib/tcpdump/util.c | 33 +- contrib/tcpdump/vfprintf.c | 59 - 133 files changed, 9736 insertions(+), 2858 deletions(-) delete mode 100644 contrib/tcpdump/bpf_dump.c create mode 100644 contrib/tcpdump/forces.h create mode 100644 contrib/tcpdump/in_cksum.c create mode 100644 contrib/tcpdump/ipnet.h delete mode 100755 contrib/tcpdump/makemib delete mode 100644 contrib/tcpdump/pcap_dump_ftell.c create mode 100644 contrib/tcpdump/ppi.h create mode 100644 contrib/tcpdump/print-802_15_4.c create mode 100644 contrib/tcpdump/print-babel.c create mode 100644 contrib/tcpdump/print-bt.c create mode 100644 contrib/tcpdump/print-carp.c create mode 100644 contrib/tcpdump/print-forces.c create mode 100644 contrib/tcpdump/print-ipnet.c create mode 100644 contrib/tcpdump/print-ppi.c create mode 100644 contrib/tcpdump/print-rpki-rtr.c create mode 100644 contrib/tcpdump/print-usb.c create mode 100644 contrib/tcpdump/signature.c copy contrib/tcpdump/{l2vpn.h => signature.h} (63%) mode change 100755 => 100644 delete mode 100644 contrib/tcpdump/strcasecmp.c rename contrib/tcpdump/{tcpdump.1 => tcpdump.1.in} (94%) delete mode 100644 contrib/tcpdump/vfprintf.c diff --git a/contrib/tcpdump/CHANGES b/contrib/tcpdump/CHANGES index 3f3b6759ce..2fa51b9d00 100644 --- a/contrib/tcpdump/CHANGES +++ b/contrib/tcpdump/CHANGES @@ -1,4 +1,106 @@ -$Header: /tcpdump/master/tcpdump/CHANGES,v 1.98.2.2 2008-10-15 23:26:30 ken Exp $ +Friday December 9, 2011. guy@alum.mit.edu. + Summary for 4.2.1 tcpdump release + Only build the Babel printer if IPv6 is enabled. + Support Babel on port 6696 as well as 6697. + Include ppi.h in release tarball. + Include all the test files in the release tarball, and don't + "include" test files that no longer exist. + Don't assume we have - check for it. + Support "-T carp" as a way of dissecting IP protocol 112 as CARP + rather than VRRP. + Support Hilscher NetAnalyzer link-layer header format. + Constify some pointers and fix compiler warnings. + Get rid of never-true test. + Fix an unintended fall-through in a case statement in the ARP + printer. + Fix several cases where sizeof(sizeof(XXX)) was used when just + sizeof(XXX) was intended. + Make stricter sanity checks in the ES-IS printer. + Get rid of some GCCisms that caused builds to fai with compilers + that don't support them. + Fix typo in man page. + Added length checks to Babel printer. + +Sunday July 24, 2011. mcr@sandelman.ca. + Summary for 4.2.+ + merged 802.15.4 decoder from Dmitry Eremin-Solenikov + updates to forces for new port numbers + Use "-H", not "-h", for the 802.11s option. (-h always help) + Better ICMPv6 checksum handling. + add support for the RPKI/Router Protocol, per -ietf-sidr-rpki-rtr-12 + get rid of uuencoded pcap test files, git can do binary. + sFlow changes for 64-bit counters. + fixes for PPI packet header handling and printing. + Add DCB Exchange protocol (DCBX) version 1.01. + Babel dissector, from Juliusz Chroboczek and Grégoire Henry. + improvements to radiotap for rate values > 127. + Many improvements to ForCES decode, including fix SCTP TML port + updated RPL type code to RPL-17 draft + Improve printout of DHCPv6 options. + added support and test case for QinQ (802.1q VLAN) packets + Handle DLT_IEEE802_15_4_NOFCS like DLT_IEEE802_15_4. + Build fixes for Sparc and other machines with alignment restrictions. + Merged changes from Debian package. + PGM: Add ACK decoding and add PGMCC DATA and FEEDBACK options. + Build fixes for OSX (Snow Leopard and others) + Add support for IEEE 802.15.4 packets + +Tue. July 20, 2010. guy@alum.mit.edu. + Summary for 4.1.2 tcpdump release + If -U is specified, flush the file after creating it, so it's + not zero-length + Fix TCP flags output description, and some typoes, in the man + page + Add a -h flag, and only attempt to recognize 802.11s mesh + headers if it's set + When printing the link-layer type list, send *all* output to + stderr + Include the CFLAGS setting when configure was run in the + compiler flags + +Thu. April 1, 2010. guy@alum.mit.edu. + Summary for 4.1.1 tcpdump release + Fix build on systems with PF, such as FreeBSD and OpenBSD. + Don't blow up if a zero-length link-layer address is passed to + linkaddr_string(). + +Thu. March 11, 2010. ken@netfunctional.ca/guy@alum.mit.edu. + Summary for 4.1.0 tcpdump release + Fix printing of MAC addresses for VLAN frames with a length + field + Add some additional bounds checks and use the EXTRACT_ macros + more + Add a -b flag to print the AS number in BGP packets in ASDOT + notation rather than ASPLAIN notation + Add ICMPv6 RFC 5006 support + Decode the access flags in NFS access requests + Handle the new DLT_ for memory-mapped USB captures on Linux + Make the default snapshot (-s) the maximum + Print name of device (when -L is used) + Support for OpenSolaris (and SXCE build 125 and later) + Print new TCP flags + Add support for RPL DIO + Add support for TCP User Timeout (UTO) + Add support for non-standard Ethertypes used by 3com PPPoE gear + Add support for 802.11n and 802.11s + Add support for Transparent Ethernet Bridge ethertype in GRE + Add 4 byte AS support for BGP printer + Add support for the MDT SAFI 66 BG printer + Add basic IPv6 support to print-olsr + Add USB printer + Add printer for ForCES + Handle frames with an FCS + Handle 802.11n Control Wrapper, Block Acq Req and Block Ack frames + Fix TCP sequence number printing + Report 802.2 packets as 802.2 instead of 802.3 + Don't include -L/usr/lib in LDFLAGS + On x86_64 Linux, look in lib64 directory too + Lots of code clean ups + Autoconf clean ups + Update testcases to make output changes + Fix compiling with/out smi (--with{,out}-smi) + Fix compiling without IPv6 support (--disable-ipv6) Mon. October 27, 2008. ken@netfunctional.ca. Summary for 4.0.0 tcpdump release Add support for Bluetooth Sniffing diff --git a/contrib/tcpdump/INSTALL.txt b/contrib/tcpdump/INSTALL.txt index e263f5368f..a03e2c0001 100644 --- a/contrib/tcpdump/INSTALL.txt +++ b/contrib/tcpdump/INSTALL.txt @@ -1,4 +1,4 @@ -@(#) $Header: /tcpdump/master/tcpdump/INSTALL.txt,v 1.1.2.1 2008-02-06 10:49:22 guy Exp $ (LBL) +@(#) $Header: /tcpdump/master/tcpdump/INSTALL.txt,v 1.2 2008-02-06 10:47:53 guy Exp $ (LBL) If you have not built libpcap, and your system does not have libpcap installed, install libpcap first. Your system might provide a version @@ -221,6 +221,7 @@ print-tftp.c - Trivial File Transfer Protocol printer routines print-timed.c - BSD time daemon protocol printer routines print-token.c - Token Ring printer routines print-udp.c - UDP printer routines +print-usb.c - USB printer routines print-vjc.c - PPP Van Jacobson compression (RFC1144) printer routines print-vrrp.c - Virtual Router Redundancy Protocol print-wb.c - White Board printer routines diff --git a/contrib/tcpdump/README b/contrib/tcpdump/README index c2b6760aba..ed657c1e3a 100644 --- a/contrib/tcpdump/README +++ b/contrib/tcpdump/README @@ -1,19 +1,17 @@ -@(#) $Header: /tcpdump/master/tcpdump/README,v 1.66.2.1 2008-05-30 01:38:20 guy Exp $ (LBL) +@(#) $Header: /tcpdump/master/tcpdump/README,v 1.68 2008-12-15 00:05:27 guy Exp $ (LBL) -TCPDUMP 3.9 +TCPDUMP 4.x.y Now maintained by "The Tcpdump Group" See www.tcpdump.org Please send inquiries/comments/reports to: tcpdump-workers@lists.tcpdump.org -Anonymous CVS is available via: - cvs -d :pserver:cvs.tcpdump.org:/tcpdump/master login - (password "anoncvs") - cvs -d :pserver:cvs.tcpdump.org:/tcpdump/master checkout tcpdump +Anonymous Git is available via: + git clone git://bpf.tcpdump.org/tcpdump -Version 3.9 of TCPDUMP can be retrieved with the CVS tag "tcpdump_3_9rel1": - cvs -d :pserver:cvs.tcpdump.org:/tcpdump/master checkout -r tcpdump_3_9rel1 tcpdump +Version 4.x.y of TCPDUMP can be retrieved with the CVS tag "tcpdump_4_xrely": + cvs -d :pserver:cvs.tcpdump.org:/tcpdump/master checkout -r tcpdump_4_xrely tcpdump Please submit patches against the master copy to the tcpdump project on sourceforge.net. diff --git a/contrib/tcpdump/README.DELETED b/contrib/tcpdump/README.DELETED index faea7ee91e..005d29e119 100644 --- a/contrib/tcpdump/README.DELETED +++ b/contrib/tcpdump/README.DELETED @@ -1,9 +1,11 @@ CREDITS +Makefile-devel-adds Makefile.in Readme.Win32 acconfig.h aclocal.m4 atime.awk +bpf_dump.c config.guess config.h.in config.sub @@ -11,10 +13,14 @@ configure configure.in install-sh lbl/ +makemib missing/ mkdep packetdat.awk -print-bt.c +pcap_dump_ftell.c send-ack.awk stime.awk +strcasecmp.c +tests/ +vfprintf.c win32/ diff --git a/contrib/tcpdump/VERSION b/contrib/tcpdump/VERSION index fcdb2e109f..fae6e3d04b 100644 --- a/contrib/tcpdump/VERSION +++ b/contrib/tcpdump/VERSION @@ -1 +1 @@ -4.0.0 +4.2.1 diff --git a/contrib/tcpdump/addrtoname.c b/contrib/tcpdump/addrtoname.c index e67d1148c9..d77f27b0ac 100644 --- a/contrib/tcpdump/addrtoname.c +++ b/contrib/tcpdump/addrtoname.c @@ -86,12 +86,12 @@ struct hnamemem { struct hnamemem *nxt; }; -struct hnamemem hnametable[HASHNAMESIZE]; -struct hnamemem tporttable[HASHNAMESIZE]; -struct hnamemem uporttable[HASHNAMESIZE]; -struct hnamemem eprototable[HASHNAMESIZE]; -struct hnamemem dnaddrtable[HASHNAMESIZE]; -struct hnamemem ipxsaptable[HASHNAMESIZE]; +static struct hnamemem hnametable[HASHNAMESIZE]; +static struct hnamemem tporttable[HASHNAMESIZE]; +static struct hnamemem uporttable[HASHNAMESIZE]; +static struct hnamemem eprototable[HASHNAMESIZE]; +static struct hnamemem dnaddrtable[HASHNAMESIZE]; +static struct hnamemem ipxsaptable[HASHNAMESIZE]; #if defined(INET6) && defined(WIN32) /* @@ -140,7 +140,7 @@ struct h6namemem { struct h6namemem *nxt; }; -struct h6namemem h6nametable[HASHNAMESIZE]; +static struct h6namemem h6nametable[HASHNAMESIZE]; #endif /* INET6 */ struct enamemem { @@ -153,9 +153,9 @@ struct enamemem { struct enamemem *e_nxt; }; -struct enamemem enametable[HASHNAMESIZE]; -struct enamemem nsaptable[HASHNAMESIZE]; -struct enamemem bytestringtable[HASHNAMESIZE]; +static struct enamemem enametable[HASHNAMESIZE]; +static struct enamemem nsaptable[HASHNAMESIZE]; +static struct enamemem bytestringtable[HASHNAMESIZE]; struct protoidmem { u_int32_t p_oui; @@ -164,7 +164,7 @@ struct protoidmem { struct protoidmem *p_nxt; }; -struct protoidmem protoidtable[HASHNAMESIZE]; +static struct protoidmem protoidtable[HASHNAMESIZE]; /* * A faster replacement for inet_ntoa(). @@ -311,7 +311,7 @@ getname6(const u_char *ap) } #endif /* INET6 */ -static char hex[] = "0123456789abcdef"; +static const char hex[] = "0123456789abcdef"; /* Find the hash node that corresponds the ether address 'ep' */ @@ -507,6 +507,34 @@ etheraddr_string(register const u_char *ep) return (tp->e_name); } +const char * +le64addr_string(const u_char *ep) +{ + const unsigned int len = 8; + register u_int i; + register char *cp; + register struct enamemem *tp; + char buf[BUFSIZE]; + + tp = lookup_bytestring(ep, len); + if (tp->e_name) + return (tp->e_name); + + cp = buf; + for (i = len; i > 0 ; --i) { + *cp++ = hex[*(ep + i - 1) >> 4]; + *cp++ = hex[*(ep + i - 1) & 0xf]; + *cp++ = ':'; + } + cp --; + + *cp = '\0'; + + tp->e_name = strdup(buf); + + return (tp->e_name); +} + const char * linkaddr_string(const u_char *ep, const unsigned int type, const unsigned int len) { @@ -514,13 +542,14 @@ linkaddr_string(const u_char *ep, const unsigned int type, const unsigned int le register char *cp; register struct enamemem *tp; - if (type == LINKADDR_ETHER && len == ETHER_ADDR_LEN) { - return etheraddr_string(ep); - } + if (len == 0) + return (""); + + if (type == LINKADDR_ETHER && len == ETHER_ADDR_LEN) + return (etheraddr_string(ep)); - if (type == LINKADDR_FRELAY) { - return q922_string(ep); - } + if (type == LINKADDR_FRELAY) + return (q922_string(ep)); tp = lookup_bytestring(ep, len); if (tp->e_name) @@ -747,7 +776,7 @@ init_eprotoarray(void) } } -static struct protoidlist { +static const struct protoidlist { const u_char protoid[5]; const char *name; } protoidlist[] = { @@ -768,7 +797,7 @@ init_protoidarray(void) { register int i; register struct protoidmem *tp; - struct protoidlist *pl; + const struct protoidlist *pl; u_char protoid[5]; protoid[0] = 0; @@ -792,7 +821,7 @@ init_protoidarray(void) } } -static struct etherlist { +static const struct etherlist { const u_char addr[6]; const char *name; } etherlist[] = { @@ -817,7 +846,7 @@ static struct etherlist { static void init_etherarray(void) { - register struct etherlist *el; + register const struct etherlist *el; register struct enamemem *tp; #ifdef USE_ETHER_NTOHOST char name[256]; @@ -861,7 +890,7 @@ init_etherarray(void) } } -static struct tok ipxsap_db[] = { +static const struct tok ipxsap_db[] = { { 0x0000, "Unknown" }, { 0x0001, "User" }, { 0x0002, "User Group" }, diff --git a/contrib/tcpdump/addrtoname.h b/contrib/tcpdump/addrtoname.h index 1df204a941..cd5c41f4a5 100644 --- a/contrib/tcpdump/addrtoname.h +++ b/contrib/tcpdump/addrtoname.h @@ -34,6 +34,7 @@ enum { extern const char *linkaddr_string(const u_char *, const unsigned int, const unsigned int); extern const char *etheraddr_string(const u_char *); +extern const char *le64addr_string(const u_char *); extern const char *etherproto_string(u_short); extern const char *tcpport_string(u_short); extern const char *udpport_string(u_short); diff --git a/contrib/tcpdump/af.c b/contrib/tcpdump/af.c index e3c77bf3c4..2c8a928e02 100644 --- a/contrib/tcpdump/af.c +++ b/contrib/tcpdump/af.c @@ -28,7 +28,7 @@ static const char rcsid[] _U_ = #include "interface.h" #include "af.h" -struct tok af_values[] = { +const struct tok af_values[] = { { 0, "Reserved"}, { AFNUM_INET, "IPv4"}, { AFNUM_INET6, "IPv6"}, @@ -50,7 +50,7 @@ struct tok af_values[] = { { 0, NULL}, }; -struct tok bsd_af_values[] = { +const struct tok bsd_af_values[] = { { BSD_AFNUM_INET, "IPv4" }, { BSD_AFNUM_NS, "NS" }, { BSD_AFNUM_ISO, "ISO" }, diff --git a/contrib/tcpdump/af.h b/contrib/tcpdump/af.h index c036cef963..679cc8e5fa 100644 --- a/contrib/tcpdump/af.h +++ b/contrib/tcpdump/af.h @@ -17,8 +17,8 @@ * Original code by Hannes Gredler (hannes@juniper.net) */ -extern struct tok af_values[]; -extern struct tok bsd_af_values[]; +extern const struct tok af_values[]; +extern const struct tok bsd_af_values[]; /* RFC1700 address family numbers */ #define AFNUM_INET 1 diff --git a/contrib/tcpdump/atmuni31.h b/contrib/tcpdump/atmuni31.h index 32acfb1ee5..ab7a03ddf5 100644 --- a/contrib/tcpdump/atmuni31.h +++ b/contrib/tcpdump/atmuni31.h @@ -29,7 +29,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * @(#) $Header: /tcpdump/master/tcpdump/atmuni31.h,v 1.2.6.1 2007-10-22 19:39:12 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/tcpdump/atmuni31.h,v 1.3 2007-10-22 19:37:51 guy Exp $ (LBL) */ /* Based on UNI3.1 standard by ATM Forum */ diff --git a/contrib/tcpdump/bootp.h b/contrib/tcpdump/bootp.h index 8f61b13a86..b1b81dce90 100644 --- a/contrib/tcpdump/bootp.h +++ b/contrib/tcpdump/bootp.h @@ -1,4 +1,4 @@ -/* @(#) $Header: /tcpdump/master/tcpdump/bootp.h,v 1.18 2007-08-21 21:59:11 guy Exp $ (LBL) */ +/* @(#) $Header: /tcpdump/master/tcpdump/bootp.h,v 1.19 2008-04-22 09:46:03 hannes Exp $ (LBL) */ /* * Bootstrap Protocol (BOOTP). RFC951 and RFC1048. * @@ -27,7 +27,8 @@ struct bootp { u_int8_t bp_hops; /* gateway hops */ u_int32_t bp_xid; /* transaction ID */ u_int16_t bp_secs; /* seconds since boot began */ - u_int16_t bp_flags; /* flags - see bootp_flag_values[] in print-bootp.c */ + u_int16_t bp_flags; /* flags - see bootp_flag_values[] + in print-bootp.c */ struct in_addr bp_ciaddr; /* client IP address */ struct in_addr bp_yiaddr; /* 'your' IP address */ struct in_addr bp_siaddr; /* server IP address */ @@ -36,7 +37,7 @@ struct bootp { u_int8_t bp_sname[64]; /* server host name */ u_int8_t bp_file[128]; /* boot file name */ u_int8_t bp_vend[64]; /* vendor-specific area */ -}; +} UNALIGNED; /* * UDP port numbers, server and client. @@ -216,7 +217,7 @@ struct cmu_vend { struct in_addr v_ins1, v_ins2; /* IEN-116 name servers */ struct in_addr v_ts1, v_ts2; /* Time servers */ u_int8_t v_unused[24]; /* currently unused */ -}; +} UNALIGNED; /* v_flags values */ diff --git a/contrib/tcpdump/bpf_dump.c b/contrib/tcpdump/bpf_dump.c deleted file mode 100644 index f509b7edbf..0000000000 --- a/contrib/tcpdump/bpf_dump.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1994, 1995, 1996 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that: (1) source code distributions - * retain the above copyright notice and this paragraph in its entirety, (2) - * distributions including binary code include the above copyright notice and - * this paragraph in its entirety in the documentation or other materials - * provided with the distribution, and (3) all advertising materials mentioning - * features or use of this software display the following acknowledgement: - * ``This product includes software developed by the University of California, - * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of - * the University nor the names of its contributors may be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/bpf_dump.c,v 1.16.4.1 2008-02-14 20:54:53 guy Exp $ (LBL)"; -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include -#include - -#include "interface.h" - -void -bpf_dump(const struct bpf_program *p, int option) -{ - struct bpf_insn *insn; - int i; - int n = p->bf_len; - - insn = p->bf_insns; - if (option > 2) { - printf("%d\n", n); - for (i = 0; i < n; ++insn, ++i) { - printf("%u %u %u %u\n", insn->code, - insn->jt, insn->jf, insn->k); - } - return ; - } - if (option > 1) { - for (i = 0; i < n; ++insn, ++i) - printf("{ 0x%x, %d, %d, 0x%08x },\n", - insn->code, insn->jt, insn->jf, insn->k); - return; - } - for (i = 0; i < n; ++insn, ++i) { -#ifdef BDEBUG - extern int bids[]; - printf(bids[i] > 0 ? "[%02d]" : " -- ", bids[i] - 1); -#endif - puts(bpf_image(insn, i)); - } -} diff --git a/contrib/tcpdump/checksum.c b/contrib/tcpdump/checksum.c index f441be3d4d..da4718ff53 100644 --- a/contrib/tcpdump/checksum.c +++ b/contrib/tcpdump/checksum.c @@ -31,17 +31,73 @@ static const char rcsid[] _U_ = #include #include #include +#include #include "interface.h" -#define CRC10_POLYNOMIAL 0x633 -static u_int16_t crc10_table[256]; +/* + * CRC-10 table generated using the following Python snippet: + +import sys + +crc_table = [] +for i in range(256): + accum = i << 2 + for j in range(8): + accum <<= 1 + if accum & 0x400: + accum ^= 0x633 + crc_table.append(accum) + +for i in range(len(crc_table)/8): + for j in range(8): + sys.stdout.write("0x%04x, " % crc_table[i*8+j]) + sys.stdout.write("\n") + + */ +static const u_int16_t crc10_table[256] = +{ + 0x0000, 0x0233, 0x0255, 0x0066, 0x0299, 0x00aa, 0x00cc, 0x02ff, + 0x0301, 0x0132, 0x0154, 0x0367, 0x0198, 0x03ab, 0x03cd, 0x01fe, + 0x0031, 0x0202, 0x0264, 0x0057, 0x02a8, 0x009b, 0x00fd, 0x02ce, + 0x0330, 0x0103, 0x0165, 0x0356, 0x01a9, 0x039a, 0x03fc, 0x01cf, + 0x0062, 0x0251, 0x0237, 0x0004, 0x02fb, 0x00c8, 0x00ae, 0x029d, + 0x0363, 0x0150, 0x0136, 0x0305, 0x01fa, 0x03c9, 0x03af, 0x019c, + 0x0053, 0x0260, 0x0206, 0x0035, 0x02ca, 0x00f9, 0x009f, 0x02ac, + 0x0352, 0x0161, 0x0107, 0x0334, 0x01cb, 0x03f8, 0x039e, 0x01ad, + 0x00c4, 0x02f7, 0x0291, 0x00a2, 0x025d, 0x006e, 0x0008, 0x023b, + 0x03c5, 0x01f6, 0x0190, 0x03a3, 0x015c, 0x036f, 0x0309, 0x013a, + 0x00f5, 0x02c6, 0x02a0, 0x0093, 0x026c, 0x005f, 0x0039, 0x020a, + 0x03f4, 0x01c7, 0x01a1, 0x0392, 0x016d, 0x035e, 0x0338, 0x010b, + 0x00a6, 0x0295, 0x02f3, 0x00c0, 0x023f, 0x000c, 0x006a, 0x0259, + 0x03a7, 0x0194, 0x01f2, 0x03c1, 0x013e, 0x030d, 0x036b, 0x0158, + 0x0097, 0x02a4, 0x02c2, 0x00f1, 0x020e, 0x003d, 0x005b, 0x0268, + 0x0396, 0x01a5, 0x01c3, 0x03f0, 0x010f, 0x033c, 0x035a, 0x0169, + 0x0188, 0x03bb, 0x03dd, 0x01ee, 0x0311, 0x0122, 0x0144, 0x0377, + 0x0289, 0x00ba, 0x00dc, 0x02ef, 0x0010, 0x0223, 0x0245, 0x0076, + 0x01b9, 0x038a, 0x03ec, 0x01df, 0x0320, 0x0113, 0x0175, 0x0346, + 0x02b8, 0x008b, 0x00ed, 0x02de, 0x0021, 0x0212, 0x0274, 0x0047, + 0x01ea, 0x03d9, 0x03bf, 0x018c, 0x0373, 0x0140, 0x0126, 0x0315, + 0x02eb, 0x00d8, 0x00be, 0x028d, 0x0072, 0x0241, 0x0227, 0x0014, + 0x01db, 0x03e8, 0x038e, 0x01bd, 0x0342, 0x0171, 0x0117, 0x0324, + 0x02da, 0x00e9, 0x008f, 0x02bc, 0x0043, 0x0270, 0x0216, 0x0025, + 0x014c, 0x037f, 0x0319, 0x012a, 0x03d5, 0x01e6, 0x0180, 0x03b3, + 0x024d, 0x007e, 0x0018, 0x022b, 0x00d4, 0x02e7, 0x0281, 0x00b2, + 0x017d, 0x034e, 0x0328, 0x011b, 0x03e4, 0x01d7, 0x01b1, 0x0382, + 0x027c, 0x004f, 0x0029, 0x021a, 0x00e5, 0x02d6, 0x02b0, 0x0083, + 0x012e, 0x031d, 0x037b, 0x0148, 0x03b7, 0x0184, 0x01e2, 0x03d1, + 0x022f, 0x001c, 0x007a, 0x0249, 0x00b6, 0x0285, 0x02e3, 0x00d0, + 0x011f, 0x032c, 0x034a, 0x0179, 0x0386, 0x01b5, 0x01d3, 0x03e0, + 0x021e, 0x002d, 0x004b, 0x0278, 0x0087, 0x02b4, 0x02d2, 0x00e1 +}; static void init_crc10_table(void) { +#define CRC10_POLYNOMIAL 0x633 register int i, j; register u_int16_t accum; + u_int16_t verify_crc10_table[256]; for ( i = 0; i < 256; i++ ) { @@ -50,9 +106,12 @@ init_crc10_table(void) { if ((accum <<= 1) & 0x400) accum ^= CRC10_POLYNOMIAL; } - crc10_table[i] = accum; + verify_crc10_table[i] = accum; } - return; + assert(memcmp(verify_crc10_table, + crc10_table, + sizeof(verify_crc10_table)) == 0); +#undef CRC10_POLYNOMIAL } u_int16_t diff --git a/contrib/tcpdump/cpack.c b/contrib/tcpdump/cpack.c index 14c0a9ee2a..c921b39059 100644 --- a/contrib/tcpdump/cpack.c +++ b/contrib/tcpdump/cpack.c @@ -38,7 +38,7 @@ #include "cpack.h" #include "extract.h" -static u_int8_t * +u_int8_t * cpack_next_boundary(u_int8_t *buf, u_int8_t *p, size_t alignment) { size_t misalignment = (size_t)(p - buf) % alignment; @@ -53,7 +53,7 @@ cpack_next_boundary(u_int8_t *buf, u_int8_t *p, size_t alignment) * wordsize bytes remain in the buffer after the boundary. Otherwise, * return a pointer to the boundary. */ -static u_int8_t * +u_int8_t * cpack_align_and_reserve(struct cpack_state *cs, size_t wordsize) { u_int8_t *next; diff --git a/contrib/tcpdump/cpack.h b/contrib/tcpdump/cpack.h index 14ed37692c..74f97960ad 100644 --- a/contrib/tcpdump/cpack.h +++ b/contrib/tcpdump/cpack.h @@ -43,6 +43,9 @@ int cpack_uint16(struct cpack_state *, u_int16_t *); int cpack_uint32(struct cpack_state *, u_int32_t *); int cpack_uint64(struct cpack_state *, u_int64_t *); +u_int8_t *cpack_next_boundary(u_int8_t *buf, u_int8_t *p, size_t alignment); +u_int8_t *cpack_align_and_reserve(struct cpack_state *cs, size_t wordsize); + #define cpack_int8(__s, __p) cpack_uint8((__s), (u_int8_t*)(__p)) #define cpack_int16(__s, __p) cpack_uint16((__s), (u_int16_t*)(__p)) #define cpack_int32(__s, __p) cpack_uint32((__s), (u_int32_t*)(__p)) diff --git a/contrib/tcpdump/ethertype.h b/contrib/tcpdump/ethertype.h index 97550c7fdc..fc5e515c6b 100644 --- a/contrib/tcpdump/ethertype.h +++ b/contrib/tcpdump/ethertype.h @@ -18,7 +18,7 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: /tcpdump/master/tcpdump/ethertype.h,v 1.29.2.1 2008-02-06 10:49:22 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/tcpdump/ethertype.h,v 1.30 2008-02-06 10:47:53 guy Exp $ (LBL) */ /* @@ -76,6 +76,9 @@ #ifndef ETHERTYPE_SCA #define ETHERTYPE_SCA 0x6007 #endif +#ifndef ETHERTYPE_TEB +#define ETHERTYPE_TEB 0x6558 +#endif #ifndef ETHERTYPE_LANBRIDGE #define ETHERTYPE_LANBRIDGE 0x8038 #endif @@ -100,6 +103,20 @@ #ifndef ETHERTYPE_8021Q #define ETHERTYPE_8021Q 0x8100 #endif + +/* see: + http://en.wikipedia.org/wiki/IEEE_802.1Q + and http://en.wikipedia.org/wiki/QinQ +*/ +#ifndef ETHERTYPE_8021Q9100 +#define ETHERTYPE_8021Q9100 0x9100 +#endif +#ifndef ETHERTYPE_8021Q9200 +#define ETHERTYPE_8021Q9200 0x9200 +#endif +#ifndef ETHERTYPE_8021QinQ +#define ETHERTYPE_8021QinQ 0x88a8 +#endif #ifndef ETHERTYPE_IPX #define ETHERTYPE_IPX 0x8137 #endif @@ -127,6 +144,12 @@ #ifndef ETHERTYPE_PPPOES #define ETHERTYPE_PPPOES 0x8864 #endif +#ifndef ETHERTYPE_PPPOED2 +#define ETHERTYPE_PPPOED2 0x3c12 +#endif +#ifndef ETHERTYPE_PPPOES2 +#define ETHERTYPE_PPPOES2 0x3c13 +#endif #ifndef ETHERTYPE_JUMBO #define ETHERTYPE_JUMBO 0x8870 #endif diff --git a/contrib/tcpdump/forces.h b/contrib/tcpdump/forces.h new file mode 100644 index 0000000000..ed497d41d7 --- /dev/null +++ b/contrib/tcpdump/forces.h @@ -0,0 +1,679 @@ +/* + * Copyright (c) 1982, 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Copyright (c) 2009 Mojatatu Networks, Inc + * + */ + +/* + * Per draft-ietf-forces-protocol-22 +*/ +#define ForCES_VERS 1 +#define ForCES_HDRL 24 +#define ForCES_ALNL 4U +#define TLV_HDRL 4 +#define ILV_HDRL 8 + +#define TOM_RSVD 0x0 +#define TOM_ASSNSETUP 0x1 +#define TOM_ASSNTEARD 0x2 +#define TOM_CONFIG 0x3 +#define TOM_QUERY 0x4 +#define TOM_EVENTNOT 0x5 +#define TOM_PKTREDIR 0x6 +#define TOM_HEARTBT 0x0F +#define TOM_ASSNSETREP 0x11 +#define TOM_CONFIGREP 0x13 +#define TOM_QUERYREP 0x14 + +/* + * tom_h Flags: resv1(8b):maxtlvs(4b):resv2(2b):mintlv(2b) +*/ +#define ZERO_TTLV 0x01 +#define ZERO_MORE_TTLV 0x02 +#define ONE_MORE_TTLV 0x04 +#define ZERO_TLV 0x00 +#define ONE_TLV 0x10 +#define TWO_TLV 0x20 +#define MAX_TLV 0xF0 + +#define TTLV_T1 (ONE_MORE_TTLV|ONE_TLV) +#define TTLV_T2 (ONE_MORE_TTLV|MAX_TLV) + +struct tom_h { + u_int32_t v; + u_int16_t flags; + u_int16_t op_msk; + const char *s; + int (*print) (register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +}; + +enum { + TOM_RSV_I, + TOM_ASS_I, + TOM_AST_I, + TOM_CFG_I, + TOM_QRY_I, + TOM_EVN_I, + TOM_RED_I, + TOM_HBT_I, + TOM_ASR_I, + TOM_CNR_I, + TOM_QRR_I, + _TOM_RSV_MAX +}; +#define TOM_MAX_IND (_TOM_RSV_MAX - 1) + +int lfbselect_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +int redirect_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +int asrtlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +int asttlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +int gentltlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +int print_metailv(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +int print_metatlv(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +int print_reddata(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); + +static inline int tom_valid(u_int8_t tom) +{ + if (tom > 0) { + if (tom >= 0x7 && tom <= 0xe) + return 0; + if (tom == 0x10) + return 0; + if (tom > 0x14) + return 0; + return 1; + } else + return 0; +} + +static inline const char *ForCES_node(u_int32_t node) +{ + if (node <= 0x3FFFFFFF) + return "FE"; + if (node >= 0x40000000 && node <= 0x7FFFFFFF) + return "CE"; + if (node >= 0xC0000000 && node <= 0xFFFFFFEF) + return "AllMulticast"; + if (node == 0xFFFFFFFD) + return "AllCEsBroadcast"; + if (node == 0xFFFFFFFE) + return "AllFEsBroadcast"; + if (node == 0xFFFFFFFF) + return "AllBroadcast"; + + return "ForCESreserved"; + +} + +static inline const char *ForCES_ACKp(u_int32_t flg) +{ + if (flg == 0x0) + return "NoACK"; + if (flg == 0x1) + return "SuccessACK"; + if (flg == 0x2) + return "FailureACK"; + if (flg == 0x3) + return "AlwaysACK"; + return "ACKUnknown"; +} + +static inline const char *ForCES_EMp(u_int32_t flg) +{ + if (flg == 0x0) + return "EMReserved"; + if (flg == 0x1) + return "execute-all-or-none"; + if (flg == 0x2) + return "execute-until-failure"; + if (flg == 0x3) + return "continue-execute-on-failure"; + return "EMUnknown"; +} + +static inline const char *ForCES_ATp(u_int32_t flg) +{ + if (flg == 0x0) + return "Standalone"; + if (flg == 0x1) + return "2PCtransaction"; + return "ATUnknown"; +} + +static inline const char *ForCES_TPp(u_int32_t flg) +{ + if (flg == 0x0) + return "StartofTransaction"; + if (flg == 0x1) + return "MiddleofTransaction"; + if (flg == 0x2) + return "EndofTransaction"; + if (flg == 0x3) + return "abort"; + return "TPUnknown"; +} + +/* + * Structure of forces header, naked of TLVs. + */ +struct forcesh { + u_int8_t fm_vrsvd; /* version and reserved */ +#define ForCES_V(forcesh) ((forcesh)->fm_vrsvd >> 4) + u_int8_t fm_tom; /* type of message */ + u_int16_t fm_len; /* total length * 4 bytes */ +#define ForCES_BLN(forcesh) ((u_int32_t)(EXTRACT_16BITS(&(forcesh)->fm_len) << 2)) + u_int32_t fm_sid; /* Source ID */ +#define ForCES_SID(forcesh) EXTRACT_32BITS(&(forcesh)->fm_sid) + u_int32_t fm_did; /* Destination ID */ +#define ForCES_DID(forcesh) EXTRACT_32BITS(&(forcesh)->fm_did) + u_int8_t fm_cor[8]; /* correlator */ + u_int32_t fm_flags; /* flags */ +#define ForCES_ACK(forcesh) ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0xC0000000) >> 30) +#define ForCES_PRI(forcesh) ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x38000000) >> 27) +#define ForCES_RS1(forcesh) ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x07000000) >> 24) +#define ForCES_EM(forcesh) ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x00C00000) >> 22) +#define ForCES_AT(forcesh) ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x00200000) >> 21) +#define ForCES_TP(forcesh) ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x00180000) >> 19) +#define ForCES_RS2(forcesh) ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x0007FFFF) >> 0) +}; + +#define ForCES_HLN_VALID(fhl,tlen) ((tlen) >= ForCES_HDRL && \ + (fhl) >= ForCES_HDRL && \ + (fhl) == (tlen)) + +#define F_LFB_RSVD 0x0 +#define F_LFB_FEO 0x1 +#define F_LFB_FEPO 0x2 +const struct tok ForCES_LFBs[] = { + {F_LFB_RSVD, "Invalid TLV"}, + {F_LFB_FEO, "FEObj LFB"}, + {F_LFB_FEPO, "FEProtoObj LFB"}, + {0, NULL} +}; + +int forces_type_print(register const u_char * pptr, const struct forcesh *fhdr, + register u_int mlen, const struct tom_h *tops); + +enum { + F_OP_RSV, + F_OP_SET, + F_OP_SETPROP, + F_OP_SETRESP, + F_OP_SETPRESP, + F_OP_DEL, + F_OP_DELRESP, + F_OP_GET, + F_OP_GETPROP, + F_OP_GETRESP, + F_OP_GETPRESP, + F_OP_REPORT, + F_OP_COMMIT, + F_OP_RCOMMIT, + F_OP_RTRCOMP, + _F_OP_MAX +}; + +#define F_OP_MAX (_F_OP_MAX - 1) +enum { + B_OP_SET = 1 << (F_OP_SET - 1), + B_OP_SETPROP = 1 << (F_OP_SETPROP - 1), + B_OP_SETRESP = 1 << (F_OP_SETRESP - 1), + B_OP_SETPRESP = 1 << (F_OP_SETPRESP - 1), + B_OP_DEL = 1 << (F_OP_DEL - 1), + B_OP_DELRESP = 1 << (F_OP_DELRESP - 1), + B_OP_GET = 1 << (F_OP_GET - 1), + B_OP_GETPROP = 1 << (F_OP_GETPROP - 1), + B_OP_GETRESP = 1 << (F_OP_GETRESP - 1), + B_OP_GETPRESP = 1 << (F_OP_GETPRESP - 1), + B_OP_REPORT = 1 << (F_OP_REPORT - 1), + B_OP_COMMIT = 1 << (F_OP_COMMIT - 1), + B_OP_RCOMMIT = 1 << (F_OP_RCOMMIT - 1), + B_OP_RTRCOMP = 1 << (F_OP_RTRCOMP - 1), +}; + +struct optlv_h { + u_int16_t flags; + u_int16_t op_msk; + const char *s; + int (*print) (register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +}; + +int genoptlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +int recpdoptlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +int invoptlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); + +#define OP_MIN_SIZ 8 +struct pathdata_h { + u_int16_t pflags; + u_int16_t pIDcnt; +}; + +#define B_FULLD 0x1 +#define B_SPARD 0x2 +#define B_RESTV 0x4 +#define B_KEYIN 0x8 + +static const struct optlv_h OPTLV_msg[F_OP_MAX + 1] = { + /* F_OP_RSV */ {ZERO_TTLV, 0, "Invalid OPTLV", invoptlv_print}, + /* F_OP_SET */ {TTLV_T2, B_FULLD | B_SPARD, " Set", recpdoptlv_print}, + /* F_OP_SETPROP */ + {TTLV_T2, B_FULLD | B_SPARD, " SetProp", recpdoptlv_print}, + /* F_OP_SETRESP */ {TTLV_T2, B_RESTV, " SetResp", recpdoptlv_print}, + /* F_OP_SETPRESP */ {TTLV_T2, B_RESTV, " SetPropResp", recpdoptlv_print}, + /* F_OP_DEL */ {ZERO_TTLV, 0, " Del", recpdoptlv_print}, + /* F_OP_DELRESP */ {TTLV_T2, B_RESTV, " DelResp", recpdoptlv_print}, + /* F_OP_GET */ {ZERO_TTLV, 0, " Get", recpdoptlv_print}, + /* F_OP_GETPROP */ {ZERO_TTLV, 0, " GetProp", recpdoptlv_print}, + /* F_OP_GETRESP */ + {TTLV_T2, B_FULLD | B_RESTV, " GetResp", recpdoptlv_print}, + /* F_OP_GETPRESP */ + {TTLV_T2, B_FULLD | B_RESTV, " GetPropResp", recpdoptlv_print}, + /* F_OP_REPORT */ + {TTLV_T2, B_FULLD | B_SPARD, " Report", recpdoptlv_print}, + /* F_OP_COMMIT */ {ZERO_TTLV, 0, " Commit", NULL}, + /* F_OP_RCOMMIT */ {TTLV_T1, B_RESTV, " RCommit", genoptlv_print}, + /* F_OP_RTRCOMP */ {ZERO_TTLV, 0, " RTRCOMP", NULL}, +}; + +static inline const struct optlv_h *get_forces_optlv_h(u_int16_t opt) +{ + if (opt > F_OP_MAX || opt <= F_OP_RSV) + return &OPTLV_msg[F_OP_RSV]; + + return &OPTLV_msg[opt]; +} + +#define IND_SIZE 256 +#define IND_CHR ' ' +#define IND_PREF '\n' +#define IND_SUF 0x0 +char ind_buf[IND_SIZE]; + +static inline char *indent_pr(int indent, int nlpref) +{ + int i = 0; + char *r = ind_buf; + + if (indent > (IND_SIZE - 1)) + indent = IND_SIZE - 1; + + if (nlpref) { + r[i] = IND_PREF; + i++; + indent--; + } + + while (--indent >= 0) + r[i++] = IND_CHR; + + r[i] = IND_SUF; + return r; +} + +static inline int op_valid(u_int16_t op, u_int16_t mask) +{ + int opb = 1 << (op - 1); + + if (op == 0) + return 0; + if (opb & mask) + return 1; + /* I guess we should allow vendor operations? */ + if (op >= 0x8000) + return 1; + return 0; +} + +#define F_TLV_RSVD 0x0000 +#define F_TLV_REDR 0x0001 +#define F_TLV_ASRS 0x0010 +#define F_TLV_ASRT 0x0011 +#define F_TLV_LFBS 0x1000 +#define F_TLV_PDAT 0x0110 +#define F_TLV_KEYI 0x0111 +#define F_TLV_FULD 0x0112 +#define F_TLV_SPAD 0x0113 +#define F_TLV_REST 0x0114 +#define F_TLV_METD 0x0115 +#define F_TLV_REDD 0x0116 +#define F_TLV_VNST 0x8000 + +static const struct tok ForCES_TLV[] = { + {F_TLV_RSVD, "Invalid TLV"}, + {F_TLV_REDR, "REDIRECT TLV"}, + {F_TLV_ASRS, "ASResult TLV"}, + {F_TLV_ASRT, "ASTreason TLV"}, + {F_TLV_LFBS, "LFBselect TLV"}, + {F_TLV_PDAT, "PATH-DATA TLV"}, + {F_TLV_KEYI, "KEYINFO TLV"}, + {F_TLV_FULD, "FULLDATA TLV"}, + {F_TLV_SPAD, "SPARSEDATA TLV"}, + {F_TLV_REST, "RESULT TLV"}, + {F_TLV_METD, "METADATA TLV"}, + {F_TLV_REDD, "REDIRECTDATA TLV"}, + {0, NULL} +}; + +#define TLV_HLN 4 +static inline int ttlv_valid(u_int16_t ttlv) +{ + if (ttlv > 0) { + if (ttlv == 1 || ttlv == 0x1000) + return 1; + if (ttlv >= 0x10 && ttlv <= 0x11) + return 1; + if (ttlv >= 0x110 && ttlv <= 0x116) + return 1; + if (ttlv >= 0x8000) + return 0; /* XXX: */ + } + + return 0; +} + +struct forces_ilv { + u_int32_t type; + u_int32_t length; +}; + +struct forces_tlv { + u_int16_t type; + u_int16_t length; +}; + +int otlv_print(const struct forces_tlv *otlv, u_int16_t op_msk, int indent); + +#define F_ALN_LEN(len) ( ((len)+ForCES_ALNL-1) & ~(ForCES_ALNL-1) ) +#define GET_TOP_TLV(fhdr) ((struct forces_tlv *)((fhdr) + sizeof (struct forcesh))) +#define TLV_SET_LEN(len) (F_ALN_LEN(TLV_HDRL) + (len)) +#define TLV_ALN_LEN(len) F_ALN_LEN(TLV_SET_LEN(len)) +#define TLV_RDAT_LEN(tlv) ((int)(EXTRACT_16BITS(&(tlv)->length) - TLV_SET_LEN(0)) +#define TLV_DATA(tlvp) ((void*)(((char*)(tlvp)) + TLV_SET_LEN(0))) +#define GO_NXT_TLV(tlv,rlen) ((rlen) -= F_ALN_LEN(EXTRACT_16BITS(&(tlv)->length)), \ + (struct forces_tlv*)(((char*)(tlv)) \ + + F_ALN_LEN(EXTRACT_16BITS(&(tlv)->length)))) +#define ILV_SET_LEN(len) (F_ALN_LEN(ILV_HDRL) + (len)) +#define ILV_ALN_LEN(len) F_ALN_LEN(ILV_SET_LEN(len)) +#define ILV_RDAT_LEN(ilv) ((int)(EXTRACT_32BITS(&(ilv)->length)) - ILV_SET_LEN(0)) +#define ILV_DATA(ilvp) ((void*)(((char*)(ilvp)) + ILV_SET_LEN(0))) +#define GO_NXT_ILV(ilv,rlen) ((rlen) -= F_ALN_LEN(EXTRACT_32BITS(&(ilv)->length)), \ + (struct forces_ilv *)(((char*)(ilv)) \ + + F_ALN_LEN(EXTRACT_32BITS(&(ilv)->length)))) +#define INVALID_RLEN -1 +#define INVALID_STLN -2 +#define INVALID_LTLN -3 +#define INVALID_ALEN -4 + +static const struct tok ForCES_TLV_err[] = { + {INVALID_RLEN, "Invalid total length"}, + {INVALID_STLN, "xLV too short"}, + {INVALID_LTLN, "xLV too long"}, + {INVALID_ALEN, "data padding missing"}, + {0, NULL} +}; + +static inline int tlv_valid(const struct forces_tlv *tlv, u_int rlen) +{ + if (rlen < TLV_HDRL) + return INVALID_RLEN; + if (EXTRACT_16BITS(&tlv->length) < TLV_HDRL) + return INVALID_STLN; + if (EXTRACT_16BITS(&tlv->length) > rlen) + return INVALID_LTLN; + if (rlen < F_ALN_LEN(EXTRACT_16BITS(&tlv->length))) + return INVALID_ALEN; + + return 0; +} + +static inline int ilv_valid(const struct forces_ilv *ilv, u_int rlen) +{ + if (rlen < ILV_HDRL) + return INVALID_RLEN; + if (EXTRACT_32BITS(&ilv->length) < ILV_HDRL) + return INVALID_STLN; + if (EXTRACT_32BITS(&ilv->length) > rlen) + return INVALID_LTLN; + if (rlen < F_ALN_LEN(EXTRACT_32BITS(&ilv->length))) + return INVALID_ALEN; + + return 0; +} + +struct forces_lfbsh { + u_int32_t class; + u_int32_t instance; +}; + +#define ASSNS_OPS (B_OP_REPORT) +#define CFG_OPS (B_OP_SET|B_OP_SETPROP|B_OP_DEL|B_OP_COMMIT|B_OP_RTRCOMP) +#define CFG_ROPS (B_OP_SETRESP|B_OP_SETPRESP|B_OP_DELRESP|B_OP_RCOMMIT) +#define CFG_QY (B_OP_GET|B_OP_GETPROP) +#define CFG_QYR (B_OP_GETRESP|B_OP_GETPRESP) +#define CFG_EVN (B_OP_REPORT) + +static const struct tom_h ForCES_msg[TOM_MAX_IND + 1] = { + /* TOM_RSV_I */ {TOM_RSVD, ZERO_TTLV, 0, "Invalid message", NULL}, + /* TOM_ASS_I */ {TOM_ASSNSETUP, ZERO_MORE_TTLV | TWO_TLV, ASSNS_OPS, + "Association Setup", lfbselect_print}, + /* TOM_AST_I */ + {TOM_ASSNTEARD, TTLV_T1, 0, "Association TearDown", asttlv_print}, + /* TOM_CFG_I */ {TOM_CONFIG, TTLV_T2, CFG_OPS, "Config", lfbselect_print}, + /* TOM_QRY_I */ {TOM_QUERY, TTLV_T2, CFG_QY, "Query", lfbselect_print}, + /* TOM_EVN_I */ {TOM_EVENTNOT, TTLV_T1, CFG_EVN, "Event Notification", + lfbselect_print}, + /* TOM_RED_I */ + {TOM_PKTREDIR, TTLV_T2, 0, "Packet Redirect", redirect_print}, + /* TOM_HBT_I */ {TOM_HEARTBT, ZERO_TTLV, 0, "HeartBeat", NULL}, + /* TOM_ASR_I */ + {TOM_ASSNSETREP, TTLV_T1, 0, "Association Response", asrtlv_print}, + /* TOM_CNR_I */ {TOM_CONFIGREP, TTLV_T2, CFG_ROPS, "Config Response", + lfbselect_print}, + /* TOM_QRR_I */ + {TOM_QUERYREP, TTLV_T2, CFG_QYR, "Query Response", lfbselect_print}, +}; + +static inline const struct tom_h *get_forces_tom(u_int8_t tom) +{ + int i; + for (i = TOM_RSV_I; i <= TOM_MAX_IND; i++) { + const struct tom_h *th = &ForCES_msg[i]; + if (th->v == tom) + return th; + } + return &ForCES_msg[TOM_RSV_I]; +} + +struct pdata_ops { + u_int32_t v; + u_int16_t flags; + u_int16_t op_msk; + const char *s; + int (*print) (register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +}; + +enum { + PD_RSV_I, + PD_SEL_I, + PD_FDT_I, + PD_SDT_I, + PD_RES_I, + PD_PDT_I, + _PD_RSV_MAX +}; +#define PD_MAX_IND (_TOM_RSV_MAX - 1) + +static inline int pd_valid(u_int16_t pd) +{ + if (pd >= F_TLV_PDAT && pd <= F_TLV_REST) + return 1; + return 0; +} + +static inline void chk_op_type(u_int16_t type, u_int16_t msk, u_int16_t omsk) +{ + if (type != F_TLV_PDAT) { + if (msk & B_KEYIN) { + if (type != F_TLV_KEYI) { + printf + ("Based on flags expected KEYINFO TLV!\n"); + } + } else { + if (!(msk & omsk)) { + printf + ("Illegal DATA encoding for type 0x%x programmed %x got %x \n", + type, omsk, msk); + } + } + } + +} + +int fdatatlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +int sdatailv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +int sdatatlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +int pdatatlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +int pkeyitlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); + +int pdatacnt_print(register const u_char * pptr, register u_int len, + u_int16_t IDcnt, u_int16_t op_msk, int indent); +int pdata_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); + +int prestlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +#define F_SELKEY 1 + +struct res_val { + u_int8_t result; + u_int8_t resv1; + u_int16_t resv2; +}; + +static const struct pdata_ops ForCES_pdata[PD_MAX_IND + 1] = { + /* PD_RSV_I */ {0, 0, 0, "Invalid message", NULL}, + /* PD_SEL_I */ {F_TLV_KEYI, 0, 0, "KEYINFO TLV", pkeyitlv_print}, + /* PD_FDT_I */ {F_TLV_FULD, 0, B_FULLD, "FULLDATA TLV", fdatatlv_print}, + /* PD_SDT_I */ {F_TLV_SPAD, 0, B_SPARD, "SPARSEDATA TLV", sdatatlv_print}, + /* PD_RES_I */ {F_TLV_REST, 0, B_RESTV, "RESULT TLV", prestlv_print}, + /* PD_PDT_I */ + {F_TLV_PDAT, 0, 0, "Inner PATH-DATA TLV", recpdoptlv_print}, +}; + +static inline const struct pdata_ops *get_forces_pd(u_int16_t pd) +{ + int i; + for (i = PD_RSV_I + 1; i <= PD_MAX_IND; i++) { + const struct pdata_ops *pdo = &ForCES_pdata[i]; + if (pdo->v == pd) + return pdo; + } + return &ForCES_pdata[TOM_RSV_I]; +} + +enum { + E_SUCCESS, + E_INVALID_HEADER, + E_LENGTH_MISMATCH, + E_VERSION_MISMATCH, + E_INVALID_DESTINATION_PID, + E_LFB_UNKNOWN, + E_LFB_NOT_FOUND, + E_LFB_INSTANCE_ID_NOT_FOUND, + E_INVALID_PATH, + E_COMPONENT_DOES_NOT_EXIST, + E_EXISTS, + E_NOT_FOUND, + E_READ_ONLY, + E_INVALID_ARRAY_CREATION, + E_VALUE_OUT_OF_RANGE, + E_CONTENTS_TOO_LONG, + E_INVALID_PARAMETERS, + E_INVALID_MESSAGE_TYPE, + E_INVALID_FLAGS, + E_INVALID_TLV, + E_EVENT_ERROR, + E_NOT_SUPPORTED, + E_MEMORY_ERROR, + E_INTERNAL_ERROR, + /* 0x18-0xFE are reserved .. */ + E_UNSPECIFIED_ERROR = 0XFF +}; + +const struct tok ForCES_errs[] = { + {E_SUCCESS, "SUCCESS"}, + {E_INVALID_HEADER, "INVALID HEADER"}, + {E_LENGTH_MISMATCH, "LENGTH MISMATCH"}, + {E_VERSION_MISMATCH, "VERSION MISMATCH"}, + {E_INVALID_DESTINATION_PID, "INVALID DESTINATION PID"}, + {E_LFB_UNKNOWN, "LFB UNKNOWN"}, + {E_LFB_NOT_FOUND, "LFB NOT FOUND"}, + {E_LFB_INSTANCE_ID_NOT_FOUND, "LFB INSTANCE ID NOT FOUND"}, + {E_INVALID_PATH, "INVALID PATH"}, + {E_COMPONENT_DOES_NOT_EXIST, "COMPONENT DOES NOT EXIST"}, + {E_EXISTS, "EXISTS ALREADY"}, + {E_NOT_FOUND, "NOT FOUND"}, + {E_READ_ONLY, "READ ONLY"}, + {E_INVALID_ARRAY_CREATION, "INVALID ARRAY CREATION"}, + {E_VALUE_OUT_OF_RANGE, "VALUE OUT OF RANGE"}, + {E_CONTENTS_TOO_LONG, "CONTENTS TOO LONG"}, + {E_INVALID_PARAMETERS, "INVALID PARAMETERS"}, + {E_INVALID_MESSAGE_TYPE, "INVALID MESSAGE TYPE"}, + {E_INVALID_FLAGS, "INVALID FLAGS"}, + {E_INVALID_TLV, "INVALID TLV"}, + {E_EVENT_ERROR, "EVENT ERROR"}, + {E_NOT_SUPPORTED, "NOT SUPPORTED"}, + {E_MEMORY_ERROR, "MEMORY ERROR"}, + {E_INTERNAL_ERROR, "INTERNAL ERROR"}, + {E_UNSPECIFIED_ERROR, "UNSPECIFIED ERROR"}, + {0, NULL} +}; diff --git a/contrib/tcpdump/gmpls.c b/contrib/tcpdump/gmpls.c index ff9adb5950..739176798c 100644 --- a/contrib/tcpdump/gmpls.c +++ b/contrib/tcpdump/gmpls.c @@ -28,7 +28,7 @@ static const char rcsid[] _U_ = #include "gmpls.h" /* rfc3471 */ -struct tok gmpls_link_prot_values[] = { +const struct tok gmpls_link_prot_values[] = { { 0x01, "Extra Traffic"}, { 0x02, "Unprotected"}, { 0x04, "Shared"}, @@ -41,7 +41,7 @@ struct tok gmpls_link_prot_values[] = { }; /* rfc3471 */ -struct tok gmpls_switch_cap_values[] = { +const struct tok gmpls_switch_cap_values[] = { { GMPLS_PSC1, "Packet-Switch Capable-1"}, { GMPLS_PSC2, "Packet-Switch Capable-2"}, { GMPLS_PSC3, "Packet-Switch Capable-3"}, @@ -54,14 +54,14 @@ struct tok gmpls_switch_cap_values[] = { }; /* rfc4205 */ -struct tok gmpls_switch_cap_tsc_indication_values[] = { +const struct tok gmpls_switch_cap_tsc_indication_values[] = { { 0, "Standard SONET/SDH" }, { 1, "Arbitrary SONET/SDH" }, { 0, NULL } }; /* rfc3471 */ -struct tok gmpls_encoding_values[] = { +const struct tok gmpls_encoding_values[] = { { 1, "Packet"}, { 2, "Ethernet V2/DIX"}, { 3, "ANSI/ETSI PDH"}, @@ -77,7 +77,7 @@ struct tok gmpls_encoding_values[] = { }; /* rfc3471 */ -struct tok gmpls_payload_values[] = { +const struct tok gmpls_payload_values[] = { { 0, "Unknown"}, { 1, "Reserved"}, { 2, "Reserved"}, @@ -145,7 +145,7 @@ struct tok gmpls_payload_values[] = { * Link Type values used by LMP Service Discovery (specifically, the Client * Port Service Attributes Object). See UNI 1.0 section 9.4.2 for details. */ -struct tok lmp_sd_service_config_cpsa_link_type_values[] = { +const struct tok lmp_sd_service_config_cpsa_link_type_values[] = { { 5, "SDH ITU-T G.707"}, { 6, "SONET ANSI T1.105"}, { 0, NULL} @@ -156,7 +156,7 @@ struct tok lmp_sd_service_config_cpsa_link_type_values[] = { * the Client Port Service Attributes Object). See UNI 1.0 section 9.4.2 for * details. */ -struct tok lmp_sd_service_config_cpsa_signal_type_sdh_values[] = { +const struct tok lmp_sd_service_config_cpsa_signal_type_sdh_values[] = { { 5, "VC-3"}, { 6, "VC-4"}, { 7, "STM-0"}, @@ -173,7 +173,7 @@ struct tok lmp_sd_service_config_cpsa_signal_type_sdh_values[] = { * the Client Port Service Attributes Object). See UNI 1.0 section 9.4.2 for * details. */ -struct tok lmp_sd_service_config_cpsa_signal_type_sonet_values[] = { +const struct tok lmp_sd_service_config_cpsa_signal_type_sonet_values[] = { { 5, "STS-1 SPE"}, { 6, "STS-3c SPE"}, { 7, "STS-1"}, @@ -189,7 +189,7 @@ struct tok lmp_sd_service_config_cpsa_signal_type_sonet_values[] = { #define DIFFSERV_BC_MODEL_MAM 1 /* draft-ietf-tewg-diff-te-proto-07 */ #define DIFFSERV_BC_MODEL_EXTD_MAM 254 /* experimental */ -struct tok diffserv_te_bc_values[] = { +const struct tok diffserv_te_bc_values[] = { { DIFFSERV_BC_MODEL_RDM, "Russian dolls"}, { DIFFSERV_BC_MODEL_MAM, "Maximum allocation"}, { DIFFSERV_BC_MODEL_EXTD_MAM, "Maximum allocation with E-LSP support"}, diff --git a/contrib/tcpdump/gmpls.h b/contrib/tcpdump/gmpls.h index 6b2db230a1..8db99deac8 100644 --- a/contrib/tcpdump/gmpls.h +++ b/contrib/tcpdump/gmpls.h @@ -23,12 +23,12 @@ #define GMPLS_LSC 150 #define GMPLS_FSC 200 -extern struct tok gmpls_link_prot_values[]; -extern struct tok gmpls_switch_cap_values[]; -extern struct tok gmpls_switch_cap_tsc_indication_values[]; -extern struct tok gmpls_encoding_values[]; -extern struct tok gmpls_payload_values[]; -extern struct tok diffserv_te_bc_values[]; -extern struct tok lmp_sd_service_config_cpsa_link_type_values[]; -extern struct tok lmp_sd_service_config_cpsa_signal_type_sdh_values[]; -extern struct tok lmp_sd_service_config_cpsa_signal_type_sonet_values[]; +extern const struct tok gmpls_link_prot_values[]; +extern const struct tok gmpls_switch_cap_values[]; +extern const struct tok gmpls_switch_cap_tsc_indication_values[]; +extern const struct tok gmpls_encoding_values[]; +extern const struct tok gmpls_payload_values[]; +extern const struct tok diffserv_te_bc_values[]; +extern const struct tok lmp_sd_service_config_cpsa_link_type_values[]; +extern const struct tok lmp_sd_service_config_cpsa_signal_type_sdh_values[]; +extern const struct tok lmp_sd_service_config_cpsa_signal_type_sonet_values[]; diff --git a/contrib/tcpdump/gmt2local.h b/contrib/tcpdump/gmt2local.h index 17120c5b78..f7b3841e6a 100644 --- a/contrib/tcpdump/gmt2local.h +++ b/contrib/tcpdump/gmt2local.h @@ -18,7 +18,7 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: /tcpdump/master/tcpdump/gmt2local.h,v 1.2.1.1 1999-10-07 23:47:10 mcr Exp $ (LBL) + * @(#) $Header: /tcpdump/master/tcpdump/gmt2local.h,v 1.2 1999-10-07 23:47:10 mcr Exp $ (LBL) */ #ifndef gmt2local_h #define gmt2local_h diff --git a/contrib/tcpdump/icmp6.h b/contrib/tcpdump/icmp6.h index 5d272703fa..168a70897f 100644 --- a/contrib/tcpdump/icmp6.h +++ b/contrib/tcpdump/icmp6.h @@ -276,7 +276,7 @@ struct nd_opt_hdr { /* Neighbor discovery option header */ #define ND_OPT_ADVINTERVAL 7 #define ND_OPT_HOMEAGENT_INFO 8 #define ND_OPT_ROUTE_INFO 9 /* draft-ietf-ipngwg-router-preference, not officially assigned yet */ - +#define ND_OPT_RDNSS 25 struct nd_opt_prefix_info { /* prefix information */ u_int8_t nd_opt_pi_type; @@ -308,6 +308,14 @@ struct nd_opt_mtu { /* MTU option */ u_int32_t nd_opt_mtu_mtu; }; +struct nd_opt_rdnss { /* RDNSS RFC 5006 */ + u_int8_t nd_opt_rdnss_type; + u_int8_t nd_opt_rdnss_len; + u_int16_t nd_opt_rdnss_reserved; + u_int32_t nd_opt_rdnss_lifetime; + struct in6_addr nd_opt_rdnss_addr[1]; /* variable-length */ +}; + struct nd_opt_advinterval { /* Advertisement interval option */ u_int8_t nd_opt_adv_type; u_int8_t nd_opt_adv_len; diff --git a/contrib/tcpdump/ieee802_11.h b/contrib/tcpdump/ieee802_11.h index 3bcda7d22b..2aa1345038 100644 --- a/contrib/tcpdump/ieee802_11.h +++ b/contrib/tcpdump/ieee802_11.h @@ -30,6 +30,7 @@ #define IEEE802_11_RA_LEN 6 #define IEEE802_11_TA_LEN 6 #define IEEE802_11_SEQ_LEN 2 +#define IEEE802_11_CTL_LEN 2 #define IEEE802_11_IV_LEN 3 #define IEEE802_11_KID_LEN 1 @@ -67,11 +68,14 @@ #define ST_DISASSOC 0xA #define ST_AUTH 0xB #define ST_DEAUTH 0xC -/* RESERVED 0xD */ +#define ST_ACTION 0xD /* RESERVED 0xE */ /* RESERVED 0xF */ +#define CTRL_CONTROL_WRAPPER 0x7 +#define CTRL_BAR 0x8 +#define CTRL_BA 0x9 #define CTRL_PS_POLL 0xA #define CTRL_RTS 0xB #define CTRL_CTS 0xC @@ -140,12 +144,6 @@ struct mgmt_header_t { #define CAPABILITY_CFP_REQ(cap) ((cap) & 0x0008) #define CAPABILITY_PRIVACY(cap) ((cap) & 0x0010) -typedef enum { - NOT_PRESENT, - PRESENT, - TRUNCATED -} elem_status_t; - struct ssid_t { u_int8_t element_id; u_int8_t length; @@ -233,20 +231,20 @@ struct mgmt_body_t { u_int16_t reason_code; u_int16_t auth_alg; u_int16_t auth_trans_seq_num; - elem_status_t challenge_status; + int challenge_present; struct challenge_t challenge; u_int16_t capability_info; - elem_status_t ssid_status; + int ssid_present; struct ssid_t ssid; - elem_status_t rates_status; + int rates_present; struct rates_t rates; - elem_status_t ds_status; + int ds_present; struct ds_t ds; - elem_status_t cf_status; + int cf_present; struct cf_t cf; - elem_status_t fh_status; + int fh_present; struct fh_t fh; - elem_status_t tim_status; + int tim_present; struct tim_t tim; }; @@ -312,6 +310,38 @@ struct ctrl_end_ack_t { #define CTRL_END_ACK_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ IEEE802_11_RA_LEN+IEEE802_11_BSSID_LEN) +struct ctrl_ba_t { + u_int16_t fc; + u_int16_t duration; + u_int8_t ra[6]; + u_int8_t fcs[4]; +}; + +#define CTRL_BA_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN) + +struct ctrl_bar_t { + u_int16_t fc; + u_int16_t dur; + u_int8_t ra[6]; + u_int8_t ta[6]; + u_int16_t ctl; + u_int16_t seq; + u_int8_t fcs[4]; +}; + +#define CTRL_BAR_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ + IEEE802_11_RA_LEN+IEEE802_11_TA_LEN+\ + IEEE802_11_CTL_LEN+IEEE802_11_SEQ_LEN) + +struct meshcntl_t { + u_int8_t flags; + u_int8_t ttl; + u_int8_t seq[4]; + u_int8_t addr4[6]; + u_int8_t addr5[6]; + u_int8_t addr6[6]; +}; + #define IV_IV(iv) ((iv) & 0xFFFFFF) #define IV_PAD(iv) (((iv) >> 24) & 0x3F) #define IV_KEYID(iv) (((iv) >> 30) & 0x03) diff --git a/contrib/tcpdump/ieee802_11_radio.h b/contrib/tcpdump/ieee802_11_radio.h index 3f2b836f3b..5aff13786a 100644 --- a/contrib/tcpdump/ieee802_11_radio.h +++ b/contrib/tcpdump/ieee802_11_radio.h @@ -33,11 +33,11 @@ #ifndef _NET_IF_IEEE80211RADIOTAP_H_ #define _NET_IF_IEEE80211RADIOTAP_H_ -/* A generic radio capture format is desirable. There is one for - * Linux, but it is neither rigidly defined (there were not even - * units given for some fields) nor easily extensible. +/* A generic radio capture format is desirable. It must be + * rigidly defined (e.g., units for fields should be given), + * and easily extensible. * - * I suggest the following extensible radio capture format. It is + * The following is an extensible radio capture format. It is * based on a bitmap indicating which fields are present. * * I am trying to describe precisely what the application programmer @@ -47,13 +47,12 @@ * function of...") that I cannot set false expectations for lawyerly * readers. */ -#if defined(__KERNEL__) || defined(_KERNEL) -#ifndef DLT_IEEE802_11_RADIO -#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus WLAN header */ -#endif -#endif /* defined(__KERNEL__) || defined(_KERNEL) */ -/* The radio capture header precedes the 802.11 header. */ +/* + * The radio capture header precedes the 802.11 header. + * + * Note well: all radiotap fields are little-endian. + */ struct ieee80211_radiotap_header { u_int8_t it_version; /* Version 0. Only increases * for drastic changes, @@ -73,7 +72,7 @@ struct ieee80211_radiotap_header { * Additional extensions are made * by setting bit 31. */ -} __attribute__((__packed__)); +}; /* Name Data type Units * ---- --------- ----- @@ -87,15 +86,19 @@ struct ieee80211_radiotap_header { * IEEE80211_RADIOTAP_CHANNEL 2 x u_int16_t MHz, bitmap * * Tx/Rx frequency in MHz, followed by flags (see below). + * Note that IEEE80211_RADIOTAP_XCHANNEL must be used to + * represent an HT channel as there is not enough room in + * the flags word. * * IEEE80211_RADIOTAP_FHSS u_int16_t see below * * For frequency-hopping radios, the hop set (first byte) * and pattern (second byte). * - * IEEE80211_RADIOTAP_RATE u_int8_t 500kb/s + * IEEE80211_RADIOTAP_RATE u_int8_t 500kb/s or index * - * Tx/Rx data rate + * Tx/Rx data rate. If bit 0x80 is set then it represents an + * an MCS index and not an IEEE rate. * * IEEE80211_RADIOTAP_DBM_ANTSIGNAL int8_t decibels from * one milliwatt (dBm) @@ -155,9 +158,39 @@ struct ieee80211_radiotap_header { * Unitless indication of the Rx/Tx antenna for this packet. * The first antenna is antenna 0. * - * IEEE80211_RADIOTAP_FCS u_int32_t data + * IEEE80211_RADIOTAP_RX_FLAGS u_int16_t bitmap + * + * Properties of received frames. See flags defined below. + * + * IEEE80211_RADIOTAP_XCHANNEL u_int32_t bitmap + * u_int16_t MHz + * u_int8_t channel number + * u_int8_t .5 dBm + * + * Extended channel specification: flags (see below) followed by + * frequency in MHz, the corresponding IEEE channel number, and + * finally the maximum regulatory transmit power cap in .5 dBm + * units. This property supersedes IEEE80211_RADIOTAP_CHANNEL + * and only one of the two should be present. + * + * IEEE80211_RADIOTAP_MCS u_int8_t known + * u_int8_t flags + * u_int8_t mcs + * + * Bitset indicating which fields have known values, followed + * by bitset of flag values, followed by the MCS rate index as + * in IEEE 802.11n. + * + * IEEE80211_RADIOTAP_VENDOR_NAMESPACE + * u_int8_t OUI[3] + * u_int8_t subspace + * u_int16_t length + * + * The Vendor Namespace Field contains three sub-fields. The first + * sub-field is 3 bytes long. It contains the vendor's IEEE 802 + * Organizationally Unique Identifier (OUI). The fourth byte is a + * vendor-specific "namespace selector." * - * FCS from frame in network byte order. */ enum ieee80211_radiotap_type { IEEE80211_RADIOTAP_TSFT = 0, @@ -174,20 +207,44 @@ enum ieee80211_radiotap_type { IEEE80211_RADIOTAP_ANTENNA = 11, IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12, IEEE80211_RADIOTAP_DB_ANTNOISE = 13, + IEEE80211_RADIOTAP_RX_FLAGS = 14, + /* NB: gap for netbsd definitions */ + IEEE80211_RADIOTAP_XCHANNEL = 18, + IEEE80211_RADIOTAP_MCS = 19, + IEEE80211_RADIOTAP_NAMESPACE = 29, + IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30, IEEE80211_RADIOTAP_EXT = 31 }; -#ifndef _KERNEL -/* Channel flags. */ -#define IEEE80211_CHAN_TURBO 0x0010 /* Turbo channel */ -#define IEEE80211_CHAN_CCK 0x0020 /* CCK channel */ -#define IEEE80211_CHAN_OFDM 0x0040 /* OFDM channel */ -#define IEEE80211_CHAN_2GHZ 0x0080 /* 2 GHz spectrum channel. */ -#define IEEE80211_CHAN_5GHZ 0x0100 /* 5 GHz spectrum channel */ -#define IEEE80211_CHAN_PASSIVE 0x0200 /* Only passive scan allowed */ -#define IEEE80211_CHAN_DYN 0x0400 /* Dynamic CCK-OFDM channel */ -#define IEEE80211_CHAN_GFSK 0x0800 /* GFSK channel (FHSS PHY) */ -#endif /* !_KERNEL */ +/* channel attributes */ +#define IEEE80211_CHAN_TURBO 0x00010 /* Turbo channel */ +#define IEEE80211_CHAN_CCK 0x00020 /* CCK channel */ +#define IEEE80211_CHAN_OFDM 0x00040 /* OFDM channel */ +#define IEEE80211_CHAN_2GHZ 0x00080 /* 2 GHz spectrum channel. */ +#define IEEE80211_CHAN_5GHZ 0x00100 /* 5 GHz spectrum channel */ +#define IEEE80211_CHAN_PASSIVE 0x00200 /* Only passive scan allowed */ +#define IEEE80211_CHAN_DYN 0x00400 /* Dynamic CCK-OFDM channel */ +#define IEEE80211_CHAN_GFSK 0x00800 /* GFSK channel (FHSS PHY) */ +#define IEEE80211_CHAN_GSM 0x01000 /* 900 MHz spectrum channel */ +#define IEEE80211_CHAN_STURBO 0x02000 /* 11a static turbo channel only */ +#define IEEE80211_CHAN_HALF 0x04000 /* Half rate channel */ +#define IEEE80211_CHAN_QUARTER 0x08000 /* Quarter rate channel */ +#define IEEE80211_CHAN_HT20 0x10000 /* HT 20 channel */ +#define IEEE80211_CHAN_HT40U 0x20000 /* HT 40 channel w/ ext above */ +#define IEEE80211_CHAN_HT40D 0x40000 /* HT 40 channel w/ ext below */ + +/* Useful combinations of channel characteristics, borrowed from Ethereal */ +#define IEEE80211_CHAN_A \ + (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM) +#define IEEE80211_CHAN_B \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK) +#define IEEE80211_CHAN_G \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN) +#define IEEE80211_CHAN_TA \ + (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO) +#define IEEE80211_CHAN_TG \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN | IEEE80211_CHAN_TURBO) + /* For IEEE80211_RADIOTAP_FLAGS */ #define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received @@ -210,4 +267,25 @@ enum ieee80211_radiotap_type { */ #define IEEE80211_RADIOTAP_F_BADFCS 0x40 /* does not pass FCS check */ +/* For IEEE80211_RADIOTAP_RX_FLAGS */ +#define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001 /* frame failed crc check */ +#define IEEE80211_RADIOTAP_F_RX_PLCP_CRC 0x0002 /* frame failed PLCP CRC check */ + +/* For IEEE80211_RADIOTAP_MCS known */ +#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN 0x01 +#define IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN 0x02 /* MCS index field */ +#define IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN 0x04 +#define IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN 0x08 +#define IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN 0x10 + +/* For IEEE80211_RADIOTAP_MCS flags */ +#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK 0x03 +#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20 0 +#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_40 1 +#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20L 2 +#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20U 3 +#define IEEE80211_RADIOTAP_MCS_SHORT_GI 0x04 /* short guard interval */ +#define IEEE80211_RADIOTAP_MCS_HT_GREENFIELD 0x08 +#define IEEE80211_RADIOTAP_MCS_FEC_LDPC 0x10 + #endif /* _NET_IF_IEEE80211RADIOTAP_H_ */ diff --git a/contrib/tcpdump/in_cksum.c b/contrib/tcpdump/in_cksum.c new file mode 100644 index 0000000000..93cdfc9aad --- /dev/null +++ b/contrib/tcpdump/in_cksum.c @@ -0,0 +1,200 @@ +/* in_cksum.c + * 4.4-Lite-2 Internet checksum routine, modified to take a vector of + * pointers/lengths giving the pieces to be checksummed. Also using + * Tahoe/CGI version of ADDCARRY(x) macro instead of from portable version. + */ + +/* + * Copyright (c) 1988, 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)in_cksum.c 8.1 (Berkeley) 6/10/93 + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "interface.h" + +/* + * Checksum routine for Internet Protocol family headers (Portable Version). + * + * This routine is very heavily used in the network + * code and should be modified for each CPU to be as fast as possible. + */ + +#define ADDCARRY(x) {if ((x) > 65535) (x) -= 65535;} +#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);} + +u_int16_t +in_cksum(const struct cksum_vec *vec, int veclen) +{ + register const u_int16_t *w; + register int sum = 0; + register int mlen = 0; + int byte_swapped = 0; + + union { + u_int8_t c[2]; + u_int16_t s; + } s_util; + union { + u_int16_t s[2]; + u_int32_t l; + } l_util; + + for (; veclen != 0; vec++, veclen--) { + if (vec->len == 0) + continue; + w = (const u_int16_t *)(void *)vec->ptr; + if (mlen == -1) { + /* + * The first byte of this chunk is the continuation + * of a word spanning between this chunk and the + * last chunk. + * + * s_util.c[0] is already saved when scanning previous + * chunk. + */ + s_util.c[1] = *(const u_int8_t *)w; + sum += s_util.s; + w = (const u_int16_t *)(void *)((const u_int8_t *)w + 1); + mlen = vec->len - 1; + } else + mlen = vec->len; + /* + * Force to even boundary. + */ + if ((1 & (unsigned long) w) && (mlen > 0)) { + REDUCE; + sum <<= 8; + s_util.c[0] = *(const u_int8_t *)w; + w = (const u_int16_t *)(void *)((const u_int8_t *)w + 1); + mlen--; + byte_swapped = 1; + } + /* + * Unroll the loop to make overhead from + * branches &c small. + */ + while ((mlen -= 32) >= 0) { + sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3]; + sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7]; + sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11]; + sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15]; + w += 16; + } + mlen += 32; + while ((mlen -= 8) >= 0) { + sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3]; + w += 4; + } + mlen += 8; + if (mlen == 0 && byte_swapped == 0) + continue; + REDUCE; + while ((mlen -= 2) >= 0) { + sum += *w++; + } + if (byte_swapped) { + REDUCE; + sum <<= 8; + byte_swapped = 0; + if (mlen == -1) { + s_util.c[1] = *(const u_int8_t *)w; + sum += s_util.s; + mlen = 0; + } else + mlen = -1; + } else if (mlen == -1) + s_util.c[0] = *(const u_int8_t *)w; + } + if (mlen == -1) { + /* The last mbuf has odd # of bytes. Follow the + standard (the odd byte may be shifted left by 8 bits + or not as determined by endian-ness of the machine) */ + s_util.c[1] = 0; + sum += s_util.s; + } + REDUCE; + return (~sum & 0xffff); +} + +/* + * Given the host-byte-order value of the checksum field in a packet + * header, and the network-byte-order computed checksum of the data + * that the checksum covers (including the checksum itself), compute + * what the checksum field *should* have been. + */ +u_int16_t +in_cksum_shouldbe(u_int16_t sum, u_int16_t computed_sum) +{ + u_int32_t shouldbe; + + /* + * The value that should have gone into the checksum field + * is the negative of the value gotten by summing up everything + * *but* the checksum field. + * + * We can compute that by subtracting the value of the checksum + * field from the sum of all the data in the packet, and then + * computing the negative of that value. + * + * "sum" is the value of the checksum field, and "computed_sum" + * is the negative of the sum of all the data in the packets, + * so that's -(-computed_sum - sum), or (sum + computed_sum). + * + * All the arithmetic in question is one's complement, so the + * addition must include an end-around carry; we do this by + * doing the arithmetic in 32 bits (with no sign-extension), + * and then adding the upper 16 bits of the sum, which contain + * the carry, to the lower 16 bits of the sum, and then do it + * again in case *that* sum produced a carry. + * + * As RFC 1071 notes, the checksum can be computed without + * byte-swapping the 16-bit words; summing 16-bit words + * on a big-endian machine gives a big-endian checksum, which + * can be directly stuffed into the big-endian checksum fields + * in protocol headers, and summing words on a little-endian + * machine gives a little-endian checksum, which must be + * byte-swapped before being stuffed into a big-endian checksum + * field. + * + * "computed_sum" is a network-byte-order value, so we must put + * it in host byte order before subtracting it from the + * host-byte-order value from the header; the adjusted checksum + * will be in host byte order, which is what we'll return. + */ + shouldbe = sum; + shouldbe += ntohs(computed_sum); + shouldbe = (shouldbe & 0xFFFF) + (shouldbe >> 16); + shouldbe = (shouldbe & 0xFFFF) + (shouldbe >> 16); + return shouldbe; +} diff --git a/contrib/tcpdump/interface.h b/contrib/tcpdump/interface.h index 1f031231d4..18668a21f3 100644 --- a/contrib/tcpdump/interface.h +++ b/contrib/tcpdump/interface.h @@ -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.280.2.4 2008-04-04 19:42:52 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/tcpdump/interface.h,v 1.285 2008-08-16 11:36:20 hannes Exp $ (LBL) */ #ifndef tcpdump_interface_h @@ -28,10 +28,6 @@ #include "os-proto.h" #endif -#ifndef HAVE___ATTRIBUTE__ -#define __attribute__(x) -#endif - /* snprintf et al */ #include @@ -74,6 +70,7 @@ extern char *strsep(char **, const char *); #define PT_CNFP 7 /* Cisco NetFlow protocol */ #define PT_TFTP 8 /* trivial file transfer protocol */ #define PT_AODV 9 /* Ad-hoc On-demand Distance Vector Protocol */ +#define PT_CARP 10 /* Common Address Redundancy Protocol */ #ifndef min #define min(a,b) ((a)>(b)?(b):(a)) @@ -82,21 +79,6 @@ extern char *strsep(char **, const char *); #define max(a,b) ((b)>(a)?(b):(a)) #endif -/* - * The default snapshot length. This value allows most printers to print - * useful information while keeping the amount of unwanted data down. - */ -#ifndef INET6 -#define DEFAULT_SNAPLEN 68 /* ether + IPv4 + TCP + 14 */ -#else -#define DEFAULT_SNAPLEN 96 /* ether + IPv6 + TCP + 22 */ -#endif - -#ifndef BIG_ENDIAN -#define BIG_ENDIAN 4321 -#define LITTLE_ENDIAN 1234 -#endif - #define ESRC(ep) ((ep)->ether_shost) #define EDST(ep) ((ep)->ether_dhost) @@ -181,10 +163,9 @@ extern void hex_and_ascii_print(const char *, const u_char *, u_int); extern void hex_print_with_offset(const char *, const u_char *, u_int, u_int); extern void hex_print(const char *, const u_char *, u_int); extern void telnet_print(const u_char *, u_int); -extern int ether_encap_print(u_short, const u_char *, u_int, u_int, u_short *); extern int llc_print(const u_char *, u_int, u_int, const u_char *, const u_char *, u_short *); -extern int snap_print(const u_char *, u_int, u_int, u_short *, u_int); +extern int snap_print(const u_char *, u_int, u_int, u_int); extern void aarp_print(const u_char *, u_int); extern void aodv_print(const u_char *, u_int, int); extern void atalk_print(const u_char *, u_int); @@ -204,8 +185,6 @@ extern u_int enc_if_print(const struct pcap_pkthdr *, const u_char *); extern u_int pflog_if_print(const struct pcap_pkthdr *, const u_char *); extern u_int arcnet_if_print(const struct pcap_pkthdr *, const u_char *); extern u_int arcnet_linux_if_print(const struct pcap_pkthdr *, const u_char *); -extern void ether_print(const u_char *, u_int, u_int); -extern u_int ether_if_print(const struct pcap_pkthdr *, const u_char *); extern u_int token_print(const u_char *, u_int, u_int); extern u_int token_if_print(const struct pcap_pkthdr *, const u_char *); extern void fddi_print(const u_char *, u_int, u_int); @@ -239,19 +218,20 @@ extern void ns_print(const u_char *, u_int, int); extern void ntp_print(const u_char *, u_int); extern u_int null_if_print(const struct pcap_pkthdr *, const u_char *); extern void ospf_print(const u_char *, u_int, const u_char *); -extern void olsr_print (const u_char *, u_int); +extern void olsr_print (const u_char *, u_int, int); extern void pimv1_print(const u_char *, u_int); extern void cisco_autorp_print(const u_char *, u_int); extern void rsvp_print(const u_char *, u_int); extern void ldp_print(const u_char *, u_int); extern void lldp_print(const u_char *, u_int); +extern void rpki_rtr_print(const u_char *, u_int); extern void lmp_print(const u_char *, u_int); extern void lspping_print(const u_char *, u_int); extern void lwapp_control_print(const u_char *, u_int, int); extern void lwapp_data_print(const u_char *, u_int); extern void eigrp_print(const u_char *, u_int); extern void mobile_print(const u_char *, u_int); -extern void pim_print(const u_char *, u_int); +extern void pim_print(const u_char *, u_int, u_int); extern u_int pppoe_print(const u_char *, u_int); extern u_int ppp_print(register const u_char *, u_int); extern u_int ppp_if_print(const struct pcap_pkthdr *, const u_char *); @@ -311,6 +291,7 @@ extern const char *nt_errstr(u_int32_t); extern void print_data(const unsigned char *, int); extern void l2tp_print(const u_char *, u_int); extern void vrrp_print(const u_char *, u_int, int); +extern void carp_print(const u_char *, u_int, int); extern void slow_print(const u_char *, u_int); extern void sflow_print(const u_char *, u_int); extern void mpcp_print(const u_char *, u_int); @@ -324,6 +305,7 @@ 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 forces_print(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); extern void zephyr_print(const u_char *, int); @@ -332,21 +314,29 @@ extern void bfd_print(const u_char *, u_int, u_int); extern void sip_print(const u_char *, u_int); extern void syslog_print(const u_char *, u_int); extern u_int bt_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int usb_linux_48_byte_print(const struct pcap_pkthdr *, const u_char *); +extern u_int usb_linux_64_byte_print(const struct pcap_pkthdr *, const u_char *); + #ifdef INET6 -extern void ip6_print(const u_char *, u_int); extern void ip6_opt_print(const u_char *, int); extern int hbhopt_print(const u_char *); extern int dstopt_print(const u_char *); extern int frag6_print(const u_char *, const u_char *); extern int mobility_print(const u_char *, const u_char *); -extern void icmp6_print(const u_char *, u_int, const u_char *, int); extern void ripng_print(const u_char *, unsigned int); extern int rt6_print(const u_char *, const u_char *); extern void ospf6_print(const u_char *, u_int); extern void dhcp6_print(const u_char *, u_int); +extern void babel_print(const u_char *, u_int); +extern int mask62plen(const u_char *); #endif /*INET6*/ -extern u_short in_cksum(const u_short *, register u_int, int); + +struct cksum_vec { + const u_int8_t *ptr; + int len; +}; +extern u_int16_t in_cksum(const struct cksum_vec *, int); extern u_int16_t in_cksum_shouldbe(u_int16_t, u_int16_t); #ifndef HAVE_BPF_DUMP @@ -363,8 +353,10 @@ extern void bpf_dump(const struct bpf_program *, int); #ifndef NETDISSECT_REWORKED extern netdissect_options *gndo; +#define bflag gndo->ndo_bflag #define eflag gndo->ndo_eflag #define fflag gndo->ndo_fflag +#define jflag gndo->ndo_jflag #define Kflag gndo->ndo_Kflag #define nflag gndo->ndo_nflag #define Nflag gndo->ndo_Nflag @@ -387,12 +379,13 @@ extern netdissect_options *gndo; #define Iflag gndo->ndo_Iflag #define suppress_default_print gndo->ndo_suppress_default_print #define packettype gndo->ndo_packettype -#define tcpmd5secret gndo->ndo_tcpmd5secret +#define sigsecret gndo->ndo_sigsecret #define Wflag gndo->ndo_Wflag #define WflagChars gndo->ndo_WflagChars #define Cflag_count gndo->ndo_Cflag_count #define Gflag_count gndo->ndo_Gflag_count #define Gflag_time gndo->ndo_Gflag_time +#define Hflag gndo->ndo_Hflag #define snaplen gndo->ndo_snaplen #define snapend gndo->ndo_snapend diff --git a/contrib/tcpdump/ip.h b/contrib/tcpdump/ip.h index a01d0f07d4..8a97632e51 100644 --- a/contrib/tcpdump/ip.h +++ b/contrib/tcpdump/ip.h @@ -62,7 +62,7 @@ struct ip { u_int8_t ip_p; /* protocol */ u_int16_t ip_sum; /* checksum */ struct in_addr ip_src,ip_dst; /* source and dest address */ -}; +} UNALIGNED; #define IP_MAXPACKET 65535 /* maximum packet size */ @@ -134,7 +134,7 @@ struct ip_timestamp { u_int32_t ipt_time; } ipt_ta[1]; } ipt_timestamp; -}; +} UNALIGNED; /* flag bits for ipt_flg */ #define IPOPT_TS_TSONLY 0 /* timestamps only */ @@ -161,4 +161,4 @@ struct ip_timestamp { #define IP_MSS 576 /* default maximum segment size */ /* in print-ip.c */ -extern u_int32_t ip_finddst(const struct ip *); +extern int nextproto4_cksum(const struct ip *, const u_int8_t *, u_int, u_int); diff --git a/contrib/tcpdump/ip6.h b/contrib/tcpdump/ip6.h index e4f9fe1c9e..12c87ad292 100644 --- a/contrib/tcpdump/ip6.h +++ b/contrib/tcpdump/ip6.h @@ -86,7 +86,7 @@ struct ip6_hdr { } ip6_ctlun; struct in6_addr ip6_src; /* source address */ struct in6_addr ip6_dst; /* destination address */ -}; +} UNALIGNED; #define ip6_vfc ip6_ctlun.ip6_un2_vfc #define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow @@ -109,25 +109,23 @@ struct ip6_hdr { */ struct ip6_ext { - u_char ip6e_nxt; - u_char ip6e_len; -}; + u_int8_t ip6e_nxt; + u_int8_t ip6e_len; +} UNALIGNED; /* Hop-by-Hop options header */ -/* XXX should we pad it to force alignment on an 8-byte boundary? */ struct ip6_hbh { u_int8_t ip6h_nxt; /* next header */ u_int8_t ip6h_len; /* length in units of 8 octets */ /* followed by options */ -}; +} UNALIGNED; /* Destination options header */ -/* XXX should we pad it to force alignment on an 8-byte boundary? */ struct ip6_dest { u_int8_t ip6d_nxt; /* next header */ u_int8_t ip6d_len; /* length in units of 8 octets */ /* followed by options */ -}; +} UNALIGNED; /* Option types and related macros */ #define IP6OPT_PAD1 0x00 /* 00 0 00000 */ @@ -163,7 +161,7 @@ struct ip6_rthdr { u_int8_t ip6r_type; /* routing type */ u_int8_t ip6r_segleft; /* segments left */ /* followed by routing type specific data */ -}; +} UNALIGNED; /* Type 0 Routing header */ struct ip6_rthdr0 { @@ -174,7 +172,7 @@ struct ip6_rthdr0 { u_int8_t ip6r0_reserved; /* reserved field */ u_int8_t ip6r0_slmap[3]; /* strict/loose bit map */ struct in6_addr ip6r0_addr[1]; /* up to 23 addresses */ -}; +} UNALIGNED; /* Fragment header */ struct ip6_frag { @@ -182,10 +180,13 @@ struct ip6_frag { u_int8_t ip6f_reserved; /* reserved field */ u_int16_t ip6f_offlg; /* offset, reserved, and flag */ u_int32_t ip6f_ident; /* identification */ -}; +} UNALIGNED; #define IP6F_OFF_MASK 0xfff8 /* mask out offset from ip6f_offlg */ #define IP6F_RESERVED_MASK 0x0006 /* reserved bits in ip6f_offlg */ #define IP6F_MORE_FRAG 0x0001 /* more-fragments flag */ +/* in print-ip6.c */ +extern int nextproto6_cksum(const struct ip6_hdr *, const u_int8_t *, u_int, u_int); + #endif /* not _NETINET_IP6_H_ */ diff --git a/contrib/tcpdump/ipnet.h b/contrib/tcpdump/ipnet.h new file mode 100644 index 0000000000..ae692842e3 --- /dev/null +++ b/contrib/tcpdump/ipnet.h @@ -0,0 +1,13 @@ +typedef struct ipnet_hdr { + uint8_t iph_version; + uint8_t iph_family; + uint16_t iph_htype; + uint32_t iph_pktlen; + uint32_t iph_ifindex; + uint32_t iph_grifindex; + uint32_t iph_zsrc; + uint32_t iph_zdst; +} ipnet_hdr_t; + +#define IPH_AF_INET 2 /* Matches Solaris's AF_INET */ +#define IPH_AF_INET6 26 /* Matches Solaris's AF_INET6 */ diff --git a/contrib/tcpdump/ipproto.c b/contrib/tcpdump/ipproto.c index 7b89afb9c8..cbb9bf3f74 100755 --- a/contrib/tcpdump/ipproto.c +++ b/contrib/tcpdump/ipproto.c @@ -27,7 +27,7 @@ static const char rcsid[] _U_ = #include "interface.h" #include "ipproto.h" -struct tok ipproto_values[] = { +const struct tok ipproto_values[] = { { IPPROTO_HOPOPTS, "Options" }, { IPPROTO_ICMP, "ICMP" }, { IPPROTO_IGMP, "IGMP" }, @@ -55,6 +55,7 @@ struct tok ipproto_values[] = { { IPPROTO_PGM, "PGM" }, { IPPROTO_SCTP, "SCTP" }, { IPPROTO_MOBILITY, "Mobility" }, + { IPPROTO_CARP, "CARP" }, { 0, NULL } }; diff --git a/contrib/tcpdump/ipproto.h b/contrib/tcpdump/ipproto.h index f5257863ce..c9801a624a 100644 --- a/contrib/tcpdump/ipproto.h +++ b/contrib/tcpdump/ipproto.h @@ -37,7 +37,7 @@ * $FreeBSD: src/sys/netinet/in.h,v 1.38.2.3 1999/08/29 16:29:34 peter Exp $ */ -extern struct tok ipproto_values[]; +extern const struct tok ipproto_values[]; #ifndef IPPROTO_IP #define IPPROTO_IP 0 /* dummy for IP */ @@ -133,6 +133,9 @@ extern struct tok ipproto_values[]; #ifndef IPPROTO_VRRP #define IPPROTO_VRRP 112 #endif +#ifndef IPPROTO_CARP +#define IPPROTO_CARP 112 +#endif #ifndef IPPROTO_PGM #define IPPROTO_PGM 113 #endif diff --git a/contrib/tcpdump/isakmp.h b/contrib/tcpdump/isakmp.h index 85d383d1b3..d628f7ae32 100644 --- a/contrib/tcpdump/isakmp.h +++ b/contrib/tcpdump/isakmp.h @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -/* YIPS @(#)$Id: isakmp.h,v 1.11 2007-08-29 02:38:14 mcr Exp $ */ +/* YIPS @(#)$Id: isakmp.h,v 1.12 2007-11-24 18:13:33 mcr Exp $ */ /* refer to RFC 2408 */ @@ -127,6 +127,7 @@ struct isakmp { #define ISAKMP_NPTYPE_N 11 /* Notification */ #define ISAKMP_NPTYPE_D 12 /* Delete */ #define ISAKMP_NPTYPE_VID 13 /* Vendor ID */ +#define ISAKMP_NPTYPE_v2E 46 /* v2 Encrypted payload */ #define IKEv1_MAJOR_VERSION 1 #define IKEv1_MINOR_VERSION 0 @@ -422,14 +423,31 @@ struct ikev2_ke { }; +/* 3.5. Identification Payloads */ +enum ikev2_id_type { + ID_IPV4_ADDR=1, + ID_FQDN=2, + ID_RFC822_ADDR=3, + ID_IPV6_ADDR=5, + ID_DER_ASN1_DN=9, + ID_DER_ASN1_GN=10, + ID_KEY_ID=11, +}; +struct ikev2_id { + struct isakmp_gen h; + u_int8_t type; /* ID type */ + u_int8_t res1; + u_int16_t res2; + /* SPI */ + /* Notification Data */ +}; + /* 3.10 Notification Payload */ struct ikev2_n { struct isakmp_gen h; u_int8_t prot_id; /* Protocol-ID */ u_int8_t spi_size; /* SPI Size */ u_int16_t type; /* Notify Message Type */ - /* SPI */ - /* Notification Data */ }; enum ikev2_n_type { diff --git a/contrib/tcpdump/l2vpn.c b/contrib/tcpdump/l2vpn.c index a822191782..021e7f0ad2 100755 --- a/contrib/tcpdump/l2vpn.c +++ b/contrib/tcpdump/l2vpn.c @@ -27,7 +27,7 @@ static const char rcsid[] _U_ = #include "l2vpn.h" /* draft-ietf-pwe3-iana-allocation-04 */ -struct tok l2vpn_encaps_values[] = { +const struct tok l2vpn_encaps_values[] = { { 0x00, "Reserved"}, { 0x01, "Frame Relay"}, { 0x02, "ATM AAL5 VCC transport"}, diff --git a/contrib/tcpdump/l2vpn.h b/contrib/tcpdump/l2vpn.h index 766cda546a..871eca0e0d 100755 --- a/contrib/tcpdump/l2vpn.h +++ b/contrib/tcpdump/l2vpn.h @@ -14,4 +14,4 @@ * Original code by Hannes Gredler (hannes@juniper.net) */ -extern struct tok l2vpn_encaps_values[]; +extern const struct tok l2vpn_encaps_values[]; diff --git a/contrib/tcpdump/makemib b/contrib/tcpdump/makemib deleted file mode 100755 index b59e2f105a..0000000000 --- a/contrib/tcpdump/makemib +++ /dev/null @@ -1,249 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 1990, 1996 -# John Robert LoVerso. All rights reserved. -# SMIv2 parsing copyright (c) 1999 -# William C. Fenner. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the above copyright -# notices, this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notices, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR -# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# @(#) $Id: makemib,v 1.3 2001-09-17 22:16:52 fenner Exp $ (jlv) - -# -# This script will read either ASN.1-style MIB files or the ".defs" files -# created by the ISODE "mosy" program on such files. -# -# The output of this script is the "mib.h" file used by tcpdumps' ASN.1/SNMP -# decoding code. -# -# This script needs to be run by "gawk" (GNU awk). "nawk" will work, but -# dump will get a recursion error if you process LARGE mibs. While it would -# by farily easy to rewrite this not to use recursion (and also easy to -# eliminate use of gsub and functions to use classic "awk"), you have to -# order the structure declarations in defined-first order for the compiler -# not to barf; too bad tsort doesn't take arguments. -# - -cat << EOF -/* - * This file was generated by tcpdump/makemib on `date` - * You probably don't want to edit this by hand! - * - * struct mib somename = { desc, oid-octet, type, child-pointer, next-pointer -}; - */ - -EOF - -awk ' -BEGIN { - debug=0; - # for sanity, we prep the namespace with objects from RFC-1155 - # (we manually establish the root) - oid["iso"]=1 - oidadd("org", "iso", 3) - oidadd("dod", "org", 6) - oidadd("internet", "dod", 1) - oidadd("directory", "internet", 1) - oidadd("mgmt", "internet", 2) -#XXX oidadd("mib", "mgmt", 1) - oidadd("mib-2", "mgmt", 1) - oidadd("experimental", "internet", 3) - oidadd("private", "internet", 4) - oidadd("enterprises", "private", 1) - oidadd("ip", "mib-2", 4) - oidadd("transmission", "mib-2", 10) - - holddesc="none" -} - -# -# Read mosy "*.defs" file. mosy does all the parsing work; we just read -# its simple and straightforward output. It would not be too hard to make -# tcpdump directly read mosy output, but... -# -# Ignore these unless the current file is called something.defs; false -# positives are too common in DESCRIPTIONs. - -NF > 1 && index($2,".")>0 && FILENAME ~ /\.defs/ { - # currently ignore items of the form "{ iso.3.6.1 }" - if (split($2, p, ".") == 2) { - oidadd($1, p[1], p[2]) - } - next -} - -# -# Must be a MIB file -# Make it easier to parse - used to be done by sed -{ sub(/--\*.*\*--/, ""); sub(/--.*/, ""); gsub(/[{}]/, " & "); } - -# -# this next section is simple and naive, but does the job ok -# - -# foo OBJECT IDENTIFIER ::= { baz 17 } -# or -# foo OBJECT IDENTIFIER ::= -# { baz 17 } -$2$3$4 == "OBJECTIDENTIFIER::=" { - holddesc="none" - if (NF == 8) - oidadd($1, $6, $7) - if (NF == 4) - holddesc=$1 - next -} -$1 == "{" && holddesc != "none" && NF == 4 { - oidadd(holddesc, $2, $3) - holddesc="none" -} -# -# foo OBJECT IDENTIFIER -# ::= { bar 1 } -$2$3 == "OBJECTIDENTIFIER" && $1 != "SYNTAX" && NF == 3 { - holddesc=$1 -} -# -# foo -# OBJECT IDENTIFIER ::= { bar 1 } -# a couple of heuristics to exclude single words in e.g. long -# DESCRIPTION clauses -NF == 1 && $1 ~ "[a-z][a-z]*[A-Z]" && $1 !~ /[(){}.,]/ && holddesc == "none" { - holddesc=$1 -} -$1$2$3 == "OBJECTIDENTIFIER::=" && holddesc != "none" { - oidadd(holddesc, $5, $6) - holddesc="none" -} -# -# "normal" style -# foo OBJECT-TYPE ... -# ... -# ::= { baz 5 } -$2 == "MODULE-IDENTITY" || $2 == "MODULE-COMPLIANCE" || - $2 == "OBJECT-IDENTITY" || $2 == "OBJECT-TYPE" || - $2 == "OBJECT-GROUP" || - $2 == "NOTIFICATION-TYPE" || $2 == "NOTIFICATION-GROUP" { - holddesc=$1 -} -$1 == "::=" && holddesc != "none" && NF == 5 { - oidadd(holddesc, $3, $4) - holddesc="none" -} -# -# foo ::= { baz 17 } -$2$3 == "::={" { - oidadd($1,$4,$5) - holddesc="none" -} - - -# -# End of the road - output the data. -# - -END { - print "struct obj" - dump("iso") - print "*mibroot = &_iso_obj;" -} - -function inn(file) { - if (file == "" || file == "-") - return "" - return " in " file -} - -# -# add a new object to the tree -# -# new OBJECT IDENTIFIER ::= { parent value } -# - -function oidadd(new, parent, value) { - # Ignore 0.0 - if (parent == "0" && value == 0) - return - if (debug) - print "/* oidadd" inn(FILENAME) ":", new, "in", parent, "as", value, "line", $0, "*/" - # use safe C identifiers - gsub(/[-&\/]/,"",new) - gsub(/[-&\/]/,"",parent) - # check if parent missing - if (oid[parent] == "") { - printf "/* parse problem%s: no parent for %s.%s(%d) */\n", \ - inn(FILENAME), parent, new, value - return - } - # check if parent.value already exists - if (oid[new] > 0 && oid[new] != value) { - printf "/* parse problem%s: dup %s.%s(%d) != old (%d) */\n", \ - inn(FILENAME), parent, new, value, oid[new] - return - } - # check for new name for parent.value - if (child[parent] != "") { - for (sib = child[parent]; sib != ""; sib = sibling[sib]) - if (oid[sib] == value) { - if (new != sib) - printf "/* parse problem%s: new name" \ - " \"%s\"" \ - " for %s.%s(%d) ignored */\n", \ - inn(FILENAME), new, parent, \ - sib, value - return - } - } - - oid[new]=value - if (child[parent] == "") { - child[parent] = new - } else { - sibling[new] = child[parent] - child[parent] = new - } -} - -# -# old(?) routine to recurse down the tree (in postfix order for convenience) -# - -function dump(item, c, s) { -# newitem=sofar"."item"("oid[item]")" -# printf "/* %s c=%s s=%s */\n", newitem, child[item], sibling[item] - c="NULL" - if (child[item] != "") { - dump(child[item]) - c = "&_"child[item]"_obj" - } - s="NULL" - if (sibling[item] != "") { - dump(sibling[item]) - s = "&_"sibling[item]"_obj" - } - printf "_%s_obj = {\n\t\"%s\", %d, 0,\n\t%s, %s\n},\n", \ - item, item, oid[item], c, s -} -' $@ -exit 0 diff --git a/contrib/tcpdump/netdissect.h b/contrib/tcpdump/netdissect.h index cd6f2f1372..0c66dfaf80 100644 --- a/contrib/tcpdump/netdissect.h +++ b/contrib/tcpdump/netdissect.h @@ -21,7 +21,7 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: /tcpdump/master/tcpdump/netdissect.h,v 1.23.2.2 2008-04-04 19:42:52 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/tcpdump/netdissect.h,v 1.27 2008-08-16 11:36:20 hannes Exp $ (LBL) */ #ifndef netdissect_h @@ -84,6 +84,7 @@ typedef struct netdissect_options netdissect_options; struct netdissect_options { int ndo_aflag; /* translate network and broadcast addresses */ + int ndo_bflag; /* print 4 byte ASes in ASDOT notation */ int ndo_eflag; /* print ethernet header */ int ndo_fflag; /* don't translate "foreign" IP address */ int ndo_Kflag; /* don't check TCP checksums */ @@ -106,6 +107,7 @@ struct netdissect_options { int ndo_Iflag; /* rfmon (monitor) mode */ int ndo_Oflag; /* run filter code optimizer */ int ndo_dlt; /* if != -1, ask libpcap for the DLT it names*/ + int ndo_jflag; /* packet time stamp source */ int ndo_pflag; /* don't go promiscuous */ int ndo_Cflag; /* rotate dump files after this many bytes */ @@ -115,6 +117,7 @@ struct netdissect_options { time_t ndo_Gflag_time; /* The last time_t the dump file was rotated. */ int ndo_Wflag; /* recycle output files after this number of files */ int ndo_WflagChars; + int ndo_Hflag; /* dissect 802.11s draft mesh standard */ int ndo_suppress_default_print; /* don't use default_print() for unknown packet types */ const char *ndo_dltname; @@ -122,7 +125,7 @@ struct netdissect_options { struct sa_list *ndo_sa_list_head; /* used by print-esp.c */ struct sa_list *ndo_sa_default; - char *ndo_tcpmd5secret; /* TCP-MD5 secret key */ + char *ndo_sigsecret; /* Signature verification secret key */ struct esp_algorithm *ndo_espsecret_xform; /* cache of decoded */ char *ndo_espsecret_key; @@ -148,11 +151,23 @@ struct netdissect_options { void (*ndo_info)(netdissect_options *, int verbose); int (*ndo_printf)(netdissect_options *, - const char *fmt, ...); + const char *fmt, ...) +#ifdef __ATTRIBUTE___FORMAT_OK_FOR_FUNCTION_POINTERS + __attribute__ ((format (printf, 2, 3))) +#endif + ; void (*ndo_error)(netdissect_options *, - const char *fmt, ...); + const char *fmt, ...) +#ifdef __ATTRIBUTE___FORMAT_OK_FOR_FUNCTION_POINTERS + __attribute__ ((noreturn, format (printf, 2, 3))) +#endif + ; void (*ndo_warning)(netdissect_options *, - const char *fmt, ...); + const char *fmt, ...) +#ifdef __ATTRIBUTE___FORMAT_OK_FOR_FUNCTION_POINTERS + __attribute__ ((format (printf, 2, 3))) +#endif + ; }; #define PT_VAT 1 /* Visual Audio Tool */ @@ -170,22 +185,21 @@ struct netdissect_options { #define max(a,b) ((b)>(a)?(b):(a)) #endif -#ifndef INET6 /* - * The default snapshot length. This value allows most printers to print - * useful information while keeping the amount of unwanted data down. - * In particular, it allows for an ethernet header, tcp/ip header, and - * 14 bytes of data (assuming no ip options). + * Maximum snapshot length. This should be enough to capture the full + * packet on most network interfaces. + * + * XXX - could it be larger? If so, should it? Some applications might + * use the snapshot length in a savefile header to control the size of + * the buffer they allocate, so a size of, say, 2^31-1 might not work + * well. */ -#define DEFAULT_SNAPLEN 68 -#else -#define DEFAULT_SNAPLEN 96 -#endif +#define MAXIMUM_SNAPLEN 65535 -#ifndef BIG_ENDIAN -#define BIG_ENDIAN 4321 -#define LITTLE_ENDIAN 1234 -#endif +/* + * The default snapshot length is the maximum. + */ +#define DEFAULT_SNAPLEN MAXIMUM_SNAPLEN #define ESRC(ep) ((ep)->ether_shost) #define EDST(ep) ((ep)->ether_dhost) @@ -240,6 +254,9 @@ extern char *copy_argv(netdissect_options *, char **); extern void safeputchar(int); extern void safeputs(const char *, int); +#define PLURAL_SUFFIX(n) \ + (((n) != 1) ? "s" : "") + #if 0 extern const char *isonsap_string(netdissect_options *, const u_char *); extern const char *protoid_string(netdissect_options *, const u_char *); @@ -251,12 +268,20 @@ extern const char *dnnum_string(netdissect_options *, u_short); #include +typedef u_int (*if_ndo_printer)(struct netdissect_options *ndo, + const struct pcap_pkthdr *, const u_char *); +typedef u_int (*if_printer)(const struct pcap_pkthdr *, const u_char *); + +extern if_ndo_printer lookup_ndo_printer(int); +extern if_printer lookup_printer(int); extern void eap_print(netdissect_options *,const u_char *, u_int); extern int esp_print(netdissect_options *, register const u_char *bp, int len, register const u_char *bp2, int *nhdr, int *padlen); extern void arp_print(netdissect_options *,const u_char *, u_int, u_int); +extern void icmp6_print(netdissect_options *ndo, const u_char *, + u_int, const u_char *, int); extern void isakmp_print(netdissect_options *,const u_char *, u_int, const u_char *); extern void isakmp_rfc3948_print(netdissect_options *,const u_char *, @@ -267,6 +292,22 @@ extern void ip_print_inner(netdissect_options *ndo, const u_char *bp2); extern void rrcp_print(netdissect_options *,const u_char *, u_int); +extern void ether_print(netdissect_options *, + const u_char *, u_int, u_int, + void (*)(netdissect_options *, const u_char *), + const u_char *); + +extern u_int ether_if_print(netdissect_options *, + const struct pcap_pkthdr *,const u_char *); +extern u_int netanalyzer_if_print(netdissect_options *, + const struct pcap_pkthdr *,const u_char *); +extern u_int netanalyzer_transparent_if_print(netdissect_options *, + const struct pcap_pkthdr *, + const u_char *); + +extern int ethertype_print(netdissect_options *,u_short, const u_char *, + u_int, u_int); + /* stuff that has not yet been rototiled */ #if 0 extern void ascii_print(netdissect_options *,u_int); @@ -277,8 +318,6 @@ extern void hex_print_with_offset(netdissect_options *,const char *, u_int, u_int); extern void hex_print(netdissect_options *,const char *, u_int); extern void telnet_print(netdissect_options *,const u_char *, u_int); -extern int ether_encap_print(netdissect_options *,u_short, const u_char *, - u_int, u_int, u_short *); extern int llc_print(netdissect_options *, const u_char *, u_int, u_int, const u_char *, const u_char *, u_short *); @@ -305,7 +344,6 @@ extern void egp_print(netdissect_options *,const u_char *, u_int, const u_char *); extern void arcnet_if_print(u_char*,const struct pcap_pkthdr *,const u_char *); -extern void ether_if_print(u_char *,const struct pcap_pkthdr *,const u_char *); extern void token_if_print(u_char *,const struct pcap_pkthdr *,const u_char *); extern void fddi_if_print(u_char *,const struct pcap_pkthdr *, const u_char *); @@ -319,6 +357,7 @@ extern void igmp_print(netdissect_options *, register const u_char *, u_int); extern void igrp_print(netdissect_options *,const u_char *, u_int, const u_char *); +extern int nextproto4_cksum(const struct ip *, const u_int8_t *, u_int, u_int); extern void ipN_print(netdissect_options *,const u_char *, u_int); extern void ipx_print(netdissect_options *,const u_char *, u_int); extern void isoclns_print(netdissect_options *,const u_char *, @@ -345,7 +384,7 @@ extern void ospf_print(netdissect_options *,const u_char *, u_int, const u_char *); extern void pimv1_print(netdissect_options *,const u_char *, u_int); extern void mobile_print(netdissect_options *,const u_char *, u_int); -extern void pim_print(netdissect_options *,const u_char *, u_int); +extern void pim_print(netdissect_options *,const u_char *, u_int, u_int); extern void pppoe_if_print(u_char *,const struct pcap_pkthdr *, const u_char *); extern void pppoe_print(netdissect_options *,const u_char *, u_int); extern void ppp_print(netdissect_options *, @@ -364,6 +403,7 @@ extern void raw_if_print(u_char *, const struct pcap_pkthdr *, const u_char *); extern void rip_print(netdissect_options *,const u_char *, u_int); +extern void rpki_rtr_print(netdissect_options *,const u_char *, u_int); extern void sctp_print(netdissect_options *ndo, const u_char *bp, const u_char *bp2, @@ -410,16 +450,26 @@ extern void l2tp_print(netdissect_options *,const u_char *, u_int); extern void lcp_print(netdissect_options *,const u_char *, u_int); extern void vrrp_print(netdissect_options *,const u_char *bp, u_int len, int ttl); +extern void carp_print(netdissect_options *,const u_char *bp, + u_int len, int ttl); extern void cdp_print(netdissect_options *,const u_char *, u_int, u_int, const u_char *, const u_char *); extern void stp_print(netdissect_options *,const u_char *p, u_int length); extern void radius_print(netdissect_options *,const u_char *, u_int); extern void lwres_print(netdissect_options *,const u_char *, u_int); extern void pptp_print(netdissect_options *,const u_char *, u_int); +#endif + +extern u_int ipnet_if_print(netdissect_options *,const struct pcap_pkthdr *, const u_char *); +extern u_int ppi_if_print(netdissect_options *,const struct pcap_pkthdr *, const u_char *); + +extern u_int ieee802_15_4_if_print(netdissect_options *,const struct pcap_pkthdr *, const u_char *); #ifdef INET6 extern void ip6_print(netdissect_options *,const u_char *, u_int); +#if 0 extern void ip6_opt_print(netdissect_options *,const u_char *, int); +extern int nextproto6_cksum(const struct ip6_hdr *, const u_int8_t *, u_int, u_int); extern int hbhopt_print(netdissect_options *,const u_char *); extern int dstopt_print(netdissect_options *,const u_char *); extern int frag6_print(netdissect_options *,const u_char *, @@ -434,11 +484,24 @@ extern void dhcp6_print(netdissect_options *,const u_char *, extern void zephyr_print(netdissect_options * ndo, const u_char *cp, int length); +#endif /* 0 */ #endif /*INET6*/ -extern u_short in_cksum(const u_short *, - register u_int, int); +#if 0 +struct cksum_vec { + const u_int8_t *ptr; + int len; +}; +extern u_int16_t in_cksum(const struct cksum_vec *, int); +extern u_int16_t in_cksum_shouldbe(u_int16_t, u_int16_t); #endif +extern void esp_print_decodesecret(netdissect_options *ndo); +extern int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo, + int initiator, + u_char spii[8], u_char spir[8], + u_char *buf, u_char *end); + + #endif /* netdissect_h */ diff --git a/contrib/tcpdump/nfs.h b/contrib/tcpdump/nfs.h index bf6c9838c8..a5b502582a 100644 --- a/contrib/tcpdump/nfs.h +++ b/contrib/tcpdump/nfs.h @@ -1,4 +1,4 @@ -/* @(#) $Header: /tcpdump/master/tcpdump/nfs.h,v 1.8.2.1 2007-11-18 03:24:55 guy Exp $ (LBL) */ +/* @(#) $Header: /tcpdump/master/tcpdump/nfs.h,v 1.9 2007-11-18 03:24:38 guy Exp $ (LBL) */ /* NetBSD: nfs.h,v 1.1 1996/05/23 22:49:53 fvdl Exp */ /* @@ -215,6 +215,7 @@ #define NFSV3ACCESS_EXTEND 0x08 #define NFSV3ACCESS_DELETE 0x10 #define NFSV3ACCESS_EXECUTE 0x20 +#define NFSV3ACCESS_FULL 0x3f #define NFSV3WRITE_UNSTABLE 0 #define NFSV3WRITE_DATASYNC 1 diff --git a/contrib/tcpdump/nlpid.c b/contrib/tcpdump/nlpid.c index 47ebb53504..64a359baca 100755 --- a/contrib/tcpdump/nlpid.c +++ b/contrib/tcpdump/nlpid.c @@ -26,7 +26,7 @@ static const char rcsid[] _U_ = #include "interface.h" #include "nlpid.h" -struct tok nlpid_values[] = { +const struct tok nlpid_values[] = { { NLPID_NULLNS, "NULL" }, { NLPID_Q933, "Q.933" }, { NLPID_LMI, "LMI" }, diff --git a/contrib/tcpdump/nlpid.h b/contrib/tcpdump/nlpid.h index 31f6b66da6..8931835a99 100644 --- a/contrib/tcpdump/nlpid.h +++ b/contrib/tcpdump/nlpid.h @@ -14,7 +14,7 @@ * Original code by Hannes Gredler (hannes@juniper.net) */ -extern struct tok nlpid_values[]; +extern const struct tok nlpid_values[]; #define NLPID_NULLNS 0x00 #define NLPID_Q933 0x08 /* ANSI T1.617 Annex D or ITU-T Q.933 Annex A */ diff --git a/contrib/tcpdump/ospf.h b/contrib/tcpdump/ospf.h index 2b1c6ee4c6..b86458baa7 100644 --- a/contrib/tcpdump/ospf.h +++ b/contrib/tcpdump/ospf.h @@ -324,5 +324,5 @@ struct ospfhdr { #define ospf_lsa ospf_un.un_lsa /* Functions shared by ospf and ospf6 */ -extern int ospf_print_te_lsa(u_int8_t *, u_int); -extern int ospf_print_grace_lsa(u_int8_t *, u_int); +extern int ospf_print_te_lsa(const u_int8_t *, u_int); +extern int ospf_print_grace_lsa(const u_int8_t *, u_int); diff --git a/contrib/tcpdump/oui.c b/contrib/tcpdump/oui.c index e6569d4654..1067aa1c5c 100644 --- a/contrib/tcpdump/oui.c +++ b/contrib/tcpdump/oui.c @@ -15,7 +15,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/oui.c,v 1.8.2.1 2008-01-09 09:44:39 hannes Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/oui.c,v 1.9 2008-01-09 09:40:47 hannes Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -28,7 +28,7 @@ static const char rcsid[] _U_ = /* FIXME complete OUI list using a script */ -struct tok oui_values[] = { +const struct tok oui_values[] = { { OUI_ENCAP_ETHER, "Ethernet" }, { OUI_CISCO, "Cisco" }, { OUI_NORTEL, "Nortel Networks SONMP" }, @@ -42,6 +42,7 @@ struct tok oui_values[] = { { OUI_IEEE_8021_PRIVATE, "IEEE 802.1 Private"}, { OUI_IEEE_8023_PRIVATE, "IEEE 802.3 Private"}, { OUI_TIA, "ANSI/TIA"}, + { OUI_DCBX, "DCBX"}, { 0, NULL } }; @@ -55,7 +56,7 @@ struct tok oui_values[] = { * * List taken from Ethereal's epan/sminmpec.c. */ -struct tok smi_values[] = { +const struct tok smi_values[] = { { SMI_IETF, "IETF (reserved)"}, { SMI_ACC, "ACC"}, { SMI_CISCO, "Cisco"}, diff --git a/contrib/tcpdump/oui.h b/contrib/tcpdump/oui.h index e70f82ab62..d39cb6cae3 100644 --- a/contrib/tcpdump/oui.h +++ b/contrib/tcpdump/oui.h @@ -1,4 +1,4 @@ -/* @(#) $Header: /tcpdump/master/tcpdump/oui.h,v 1.7.2.1 2008-01-09 09:44:39 hannes Exp $ (LBL) */ +/* @(#) $Header: /tcpdump/master/tcpdump/oui.h,v 1.8 2008-01-09 09:40:47 hannes Exp $ (LBL) */ /* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code @@ -14,8 +14,8 @@ * Original code by Hannes Gredler (hannes@juniper.net) */ -extern struct tok oui_values[]; -extern struct tok smi_values[]; +extern const struct tok oui_values[]; +extern const struct tok smi_values[]; #define OUI_ENCAP_ETHER 0x000000 /* encapsulated Ethernet */ #define OUI_CISCO 0x00000c /* Cisco protocols */ @@ -30,6 +30,7 @@ extern struct tok smi_values[]; #define OUI_IEEE_8021_PRIVATE 0x0080c2 /* IEEE 802.1 Organisation Specific - Annex F */ #define OUI_IEEE_8023_PRIVATE 0x00120f /* IEEE 802.3 Organisation Specific - Annex G */ #define OUI_TIA 0x0012bb /* TIA - Telecommunications Industry Association - ANSI/TIA-1057- 2006 */ +#define OUI_DCBX 0x001B21 /* DCBX */ /* * These are SMI Network Management Private Enterprise Codes for diff --git a/contrib/tcpdump/pcap_dump_ftell.c b/contrib/tcpdump/pcap_dump_ftell.c deleted file mode 100644 index 6eb3a4ab75..0000000000 --- a/contrib/tcpdump/pcap_dump_ftell.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 1993, 1994, 1995, 1996, 1997 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that: (1) source code distributions - * retain the above copyright notice and this paragraph in its entirety, (2) - * distributions including binary code include the above copyright notice and - * this paragraph in its entirety in the documentation or other materials - * provided with the distribution, and (3) all advertising materials mentioning - * features or use of this software display the following acknowledgement: - * ``This product includes software developed by the University of California, - * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of - * the University nor the names of its contributors may be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/pcap_dump_ftell.c,v 1.1 2005-06-03 22:08:52 guy Exp $ (LBL)"; -#endif - -#include -#include - -#include "pcap-missing.h" - -long -pcap_dump_ftell(pcap_dumper_t *p) -{ - return (ftell((FILE *)p)); -} diff --git a/contrib/tcpdump/ppi.h b/contrib/tcpdump/ppi.h new file mode 100644 index 0000000000..733eb950f0 --- /dev/null +++ b/contrib/tcpdump/ppi.h @@ -0,0 +1,9 @@ +typedef struct ppi_header { + uint8_t ppi_ver; + uint8_t ppi_flags; + uint16_t ppi_len; + uint32_t ppi_dlt; +} ppi_header_t; + +#define PPI_HDRLEN 8 + diff --git a/contrib/tcpdump/print-802_11.c b/contrib/tcpdump/print-802_11.c index 835d21bd37..24ab625a61 100644 --- a/contrib/tcpdump/print-802_11.c +++ b/contrib/tcpdump/print-802_11.c @@ -22,7 +22,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-802_11.c,v 1.47.2.2 2007-12-29 23:25:28 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-802_11.c,v 1.49 2007-12-29 23:25:02 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -46,94 +46,593 @@ static const char rcsid[] _U_ = #include "ieee802_11.h" #include "ieee802_11_radio.h" +/* Radiotap state */ +/* This is used to save state when parsing/processing parameters */ +struct radiotap_state +{ + u_int32_t present; + + u_int8_t rate; +}; + #define PRINT_SSID(p) \ - switch (p.ssid_status) { \ - case TRUNCATED: \ - return 0; \ - case PRESENT: \ + if (p.ssid_present) { \ printf(" ("); \ fn_print(p.ssid.ssid, NULL); \ printf(")"); \ - break; \ - case NOT_PRESENT: \ - break; \ } #define PRINT_RATE(_sep, _r, _suf) \ printf("%s%2.1f%s", _sep, (.5 * ((_r) & 0x7f)), _suf) #define PRINT_RATES(p) \ - switch (p.rates_status) { \ - case TRUNCATED: \ - return 0; \ - case PRESENT: \ - do { \ - int z; \ - const char *sep = " ["; \ - for (z = 0; z < p.rates.length ; z++) { \ - PRINT_RATE(sep, p.rates.rate[z], \ - (p.rates.rate[z] & 0x80 ? "*" : "")); \ - sep = " "; \ - } \ - if (p.rates.length != 0) \ - printf(" Mbit]"); \ - } while (0); \ - break; \ - case NOT_PRESENT: \ - break; \ + if (p.rates_present) { \ + int z; \ + const char *sep = " ["; \ + for (z = 0; z < p.rates.length ; z++) { \ + PRINT_RATE(sep, p.rates.rate[z], \ + (p.rates.rate[z] & 0x80 ? "*" : "")); \ + sep = " "; \ + } \ + if (p.rates.length != 0) \ + printf(" Mbit]"); \ } #define PRINT_DS_CHANNEL(p) \ - switch (p.ds_status) { \ - case TRUNCATED: \ - return 0; \ - case PRESENT: \ + if (p.ds_present) \ printf(" CH: %u", p.ds.channel); \ - break; \ - case NOT_PRESENT: \ - break; \ - } \ printf("%s", \ CAPABILITY_PRIVACY(p.capability_info) ? ", PRIVACY" : "" ); +#define MAX_MCS_INDEX 76 + +/* + * Indices are: + * + * the MCS index (0-76); + * + * 0 for 20 MHz, 1 for 40 MHz; + * + * 0 for a long guard interval, 1 for a short guard interval. + */ +static const float ieee80211_float_htrates[MAX_MCS_INDEX+1][2][2] = { + /* MCS 0 */ + { /* 20 Mhz */ { 6.5, /* SGI */ 7.2, }, + /* 40 Mhz */ { 13.5, /* SGI */ 15.0, }, + }, + + /* MCS 1 */ + { /* 20 Mhz */ { 13.0, /* SGI */ 14.4, }, + /* 40 Mhz */ { 27.0, /* SGI */ 30.0, }, + }, + + /* MCS 2 */ + { /* 20 Mhz */ { 19.5, /* SGI */ 21.7, }, + /* 40 Mhz */ { 40.5, /* SGI */ 45.0, }, + }, + + /* MCS 3 */ + { /* 20 Mhz */ { 26.0, /* SGI */ 28.9, }, + /* 40 Mhz */ { 54.0, /* SGI */ 60.0, }, + }, + + /* MCS 4 */ + { /* 20 Mhz */ { 39.0, /* SGI */ 43.3, }, + /* 40 Mhz */ { 81.0, /* SGI */ 90.0, }, + }, + + /* MCS 5 */ + { /* 20 Mhz */ { 52.0, /* SGI */ 57.8, }, + /* 40 Mhz */ { 108.0, /* SGI */ 120.0, }, + }, + + /* MCS 6 */ + { /* 20 Mhz */ { 58.5, /* SGI */ 65.0, }, + /* 40 Mhz */ { 121.5, /* SGI */ 135.0, }, + }, + + /* MCS 7 */ + { /* 20 Mhz */ { 65.0, /* SGI */ 72.2, }, + /* 40 Mhz */ { 135.0, /* SGI */ 150.0, }, + }, + + /* MCS 8 */ + { /* 20 Mhz */ { 13.0, /* SGI */ 14.4, }, + /* 40 Mhz */ { 27.0, /* SGI */ 30.0, }, + }, + + /* MCS 9 */ + { /* 20 Mhz */ { 26.0, /* SGI */ 28.9, }, + /* 40 Mhz */ { 54.0, /* SGI */ 60.0, }, + }, + + /* MCS 10 */ + { /* 20 Mhz */ { 39.0, /* SGI */ 43.3, }, + /* 40 Mhz */ { 81.0, /* SGI */ 90.0, }, + }, + + /* MCS 11 */ + { /* 20 Mhz */ { 52.0, /* SGI */ 57.8, }, + /* 40 Mhz */ { 108.0, /* SGI */ 120.0, }, + }, + + /* MCS 12 */ + { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, }, + /* 40 Mhz */ { 162.0, /* SGI */ 180.0, }, + }, + + /* MCS 13 */ + { /* 20 Mhz */ { 104.0, /* SGI */ 115.6, }, + /* 40 Mhz */ { 216.0, /* SGI */ 240.0, }, + }, + + /* MCS 14 */ + { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, }, + /* 40 Mhz */ { 243.0, /* SGI */ 270.0, }, + }, + + /* MCS 15 */ + { /* 20 Mhz */ { 130.0, /* SGI */ 144.4, }, + /* 40 Mhz */ { 270.0, /* SGI */ 300.0, }, + }, + + /* MCS 16 */ + { /* 20 Mhz */ { 19.5, /* SGI */ 21.7, }, + /* 40 Mhz */ { 40.5, /* SGI */ 45.0, }, + }, + + /* MCS 17 */ + { /* 20 Mhz */ { 39.0, /* SGI */ 43.3, }, + /* 40 Mhz */ { 81.0, /* SGI */ 90.0, }, + }, + + /* MCS 18 */ + { /* 20 Mhz */ { 58.5, /* SGI */ 65.0, }, + /* 40 Mhz */ { 121.5, /* SGI */ 135.0, }, + }, + + /* MCS 19 */ + { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, }, + /* 40 Mhz */ { 162.0, /* SGI */ 180.0, }, + }, + + /* MCS 20 */ + { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, }, + /* 40 Mhz */ { 243.0, /* SGI */ 270.0, }, + }, + + /* MCS 21 */ + { /* 20 Mhz */ { 156.0, /* SGI */ 173.3, }, + /* 40 Mhz */ { 324.0, /* SGI */ 360.0, }, + }, + + /* MCS 22 */ + { /* 20 Mhz */ { 175.5, /* SGI */ 195.0, }, + /* 40 Mhz */ { 364.5, /* SGI */ 405.0, }, + }, + + /* MCS 23 */ + { /* 20 Mhz */ { 195.0, /* SGI */ 216.7, }, + /* 40 Mhz */ { 405.0, /* SGI */ 450.0, }, + }, + + /* MCS 24 */ + { /* 20 Mhz */ { 26.0, /* SGI */ 28.9, }, + /* 40 Mhz */ { 54.0, /* SGI */ 60.0, }, + }, + + /* MCS 25 */ + { /* 20 Mhz */ { 52.0, /* SGI */ 57.8, }, + /* 40 Mhz */ { 108.0, /* SGI */ 120.0, }, + }, + + /* MCS 26 */ + { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, }, + /* 40 Mhz */ { 162.0, /* SGI */ 180.0, }, + }, + + /* MCS 27 */ + { /* 20 Mhz */ { 104.0, /* SGI */ 115.6, }, + /* 40 Mhz */ { 216.0, /* SGI */ 240.0, }, + }, + + /* MCS 28 */ + { /* 20 Mhz */ { 156.0, /* SGI */ 173.3, }, + /* 40 Mhz */ { 324.0, /* SGI */ 360.0, }, + }, + + /* MCS 29 */ + { /* 20 Mhz */ { 208.0, /* SGI */ 231.1, }, + /* 40 Mhz */ { 432.0, /* SGI */ 480.0, }, + }, + + /* MCS 30 */ + { /* 20 Mhz */ { 234.0, /* SGI */ 260.0, }, + /* 40 Mhz */ { 486.0, /* SGI */ 540.0, }, + }, + + /* MCS 31 */ + { /* 20 Mhz */ { 260.0, /* SGI */ 288.9, }, + /* 40 Mhz */ { 540.0, /* SGI */ 600.0, }, + }, + + /* MCS 32 */ + { /* 20 Mhz */ { 0.0, /* SGI */ 0.0, }, /* not valid */ + /* 40 Mhz */ { 6.0, /* SGI */ 6.7, }, + }, + + /* MCS 33 */ + { /* 20 Mhz */ { 39.0, /* SGI */ 43.3, }, + /* 40 Mhz */ { 81.0, /* SGI */ 90.0, }, + }, + + /* MCS 34 */ + { /* 20 Mhz */ { 52.0, /* SGI */ 57.8, }, + /* 40 Mhz */ { 108.0, /* SGI */ 120.0, }, + }, + + /* MCS 35 */ + { /* 20 Mhz */ { 65.0, /* SGI */ 72.2, }, + /* 40 Mhz */ { 135.0, /* SGI */ 150.0, }, + }, + + /* MCS 36 */ + { /* 20 Mhz */ { 58.5, /* SGI */ 65.0, }, + /* 40 Mhz */ { 121.5, /* SGI */ 135.0, }, + }, + + /* MCS 37 */ + { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, }, + /* 40 Mhz */ { 162.0, /* SGI */ 180.0, }, + }, + + /* MCS 38 */ + { /* 20 Mhz */ { 97.5, /* SGI */ 108.3, }, + /* 40 Mhz */ { 202.5, /* SGI */ 225.0, }, + }, + + /* MCS 39 */ + { /* 20 Mhz */ { 52.0, /* SGI */ 57.8, }, + /* 40 Mhz */ { 108.0, /* SGI */ 120.0, }, + }, + + /* MCS 40 */ + { /* 20 Mhz */ { 65.0, /* SGI */ 72.2, }, + /* 40 Mhz */ { 135.0, /* SGI */ 150.0, }, + }, + + /* MCS 41 */ + { /* 20 Mhz */ { 65.0, /* SGI */ 72.2, }, + /* 40 Mhz */ { 135.0, /* SGI */ 150.0, }, + }, + + /* MCS 42 */ + { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, }, + /* 40 Mhz */ { 162.0, /* SGI */ 180.0, }, + }, + + /* MCS 43 */ + { /* 20 Mhz */ { 91.0, /* SGI */ 101.1, }, + /* 40 Mhz */ { 189.0, /* SGI */ 210.0, }, + }, + + /* MCS 44 */ + { /* 20 Mhz */ { 91.0, /* SGI */ 101.1, }, + /* 40 Mhz */ { 189.0, /* SGI */ 210.0, }, + }, + + /* MCS 45 */ + { /* 20 Mhz */ { 104.0, /* SGI */ 115.6, }, + /* 40 Mhz */ { 216.0, /* SGI */ 240.0, }, + }, + + /* MCS 46 */ + { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, }, + /* 40 Mhz */ { 162.0, /* SGI */ 180.0, }, + }, + + /* MCS 47 */ + { /* 20 Mhz */ { 97.5, /* SGI */ 108.3, }, + /* 40 Mhz */ { 202.5, /* SGI */ 225.0, }, + }, + + /* MCS 48 */ + { /* 20 Mhz */ { 97.5, /* SGI */ 108.3, }, + /* 40 Mhz */ { 202.5, /* SGI */ 225.0, }, + }, + + /* MCS 49 */ + { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, }, + /* 40 Mhz */ { 243.0, /* SGI */ 270.0, }, + }, + + /* MCS 50 */ + { /* 20 Mhz */ { 136.5, /* SGI */ 151.7, }, + /* 40 Mhz */ { 283.5, /* SGI */ 315.0, }, + }, + + /* MCS 51 */ + { /* 20 Mhz */ { 136.5, /* SGI */ 151.7, }, + /* 40 Mhz */ { 283.5, /* SGI */ 315.0, }, + }, + + /* MCS 52 */ + { /* 20 Mhz */ { 156.0, /* SGI */ 173.3, }, + /* 40 Mhz */ { 324.0, /* SGI */ 360.0, }, + }, + + /* MCS 53 */ + { /* 20 Mhz */ { 65.0, /* SGI */ 72.2, }, + /* 40 Mhz */ { 135.0, /* SGI */ 150.0, }, + }, + + /* MCS 54 */ + { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, }, + /* 40 Mhz */ { 162.0, /* SGI */ 180.0, }, + }, + + /* MCS 55 */ + { /* 20 Mhz */ { 91.0, /* SGI */ 101.1, }, + /* 40 Mhz */ { 189.0, /* SGI */ 210.0, }, + }, + + /* MCS 56 */ + { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, }, + /* 40 Mhz */ { 162.0, /* SGI */ 180.0, }, + }, + + /* MCS 57 */ + { /* 20 Mhz */ { 91.0, /* SGI */ 101.1, }, + /* 40 Mhz */ { 189.0, /* SGI */ 210.0, }, + }, + + /* MCS 58 */ + { /* 20 Mhz */ { 104.0, /* SGI */ 115.6, }, + /* 40 Mhz */ { 216.0, /* SGI */ 240.0, }, + }, + + /* MCS 59 */ + { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, }, + /* 40 Mhz */ { 243.0, /* SGI */ 270.0, }, + }, + + /* MCS 60 */ + { /* 20 Mhz */ { 104.0, /* SGI */ 115.6, }, + /* 40 Mhz */ { 216.0, /* SGI */ 240.0, }, + }, + + /* MCS 61 */ + { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, }, + /* 40 Mhz */ { 243.0, /* SGI */ 270.0, }, + }, + + /* MCS 62 */ + { /* 20 Mhz */ { 130.0, /* SGI */ 144.4, }, + /* 40 Mhz */ { 270.0, /* SGI */ 300.0, }, + }, + + /* MCS 63 */ + { /* 20 Mhz */ { 130.0, /* SGI */ 144.4, }, + /* 40 Mhz */ { 270.0, /* SGI */ 300.0, }, + }, + + /* MCS 64 */ + { /* 20 Mhz */ { 143.0, /* SGI */ 158.9, }, + /* 40 Mhz */ { 297.0, /* SGI */ 330.0, }, + }, + + /* MCS 65 */ + { /* 20 Mhz */ { 97.5, /* SGI */ 108.3, }, + /* 40 Mhz */ { 202.5, /* SGI */ 225.0, }, + }, + + /* MCS 66 */ + { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, }, + /* 40 Mhz */ { 243.0, /* SGI */ 270.0, }, + }, + + /* MCS 67 */ + { /* 20 Mhz */ { 136.5, /* SGI */ 151.7, }, + /* 40 Mhz */ { 283.5, /* SGI */ 315.0, }, + }, + + /* MCS 68 */ + { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, }, + /* 40 Mhz */ { 243.0, /* SGI */ 270.0, }, + }, + + /* MCS 69 */ + { /* 20 Mhz */ { 136.5, /* SGI */ 151.7, }, + /* 40 Mhz */ { 283.5, /* SGI */ 315.0, }, + }, + + /* MCS 70 */ + { /* 20 Mhz */ { 156.0, /* SGI */ 173.3, }, + /* 40 Mhz */ { 324.0, /* SGI */ 360.0, }, + }, + + /* MCS 71 */ + { /* 20 Mhz */ { 175.5, /* SGI */ 195.0, }, + /* 40 Mhz */ { 364.5, /* SGI */ 405.0, }, + }, + + /* MCS 72 */ + { /* 20 Mhz */ { 156.0, /* SGI */ 173.3, }, + /* 40 Mhz */ { 324.0, /* SGI */ 360.0, }, + }, + + /* MCS 73 */ + { /* 20 Mhz */ { 175.5, /* SGI */ 195.0, }, + /* 40 Mhz */ { 364.5, /* SGI */ 405.0, }, + }, + + /* MCS 74 */ + { /* 20 Mhz */ { 195.0, /* SGI */ 216.7, }, + /* 40 Mhz */ { 405.0, /* SGI */ 450.0, }, + }, + + /* MCS 75 */ + { /* 20 Mhz */ { 195.0, /* SGI */ 216.7, }, + /* 40 Mhz */ { 405.0, /* SGI */ 450.0, }, + }, + + /* MCS 76 */ + { /* 20 Mhz */ { 214.5, /* SGI */ 238.3, }, + /* 40 Mhz */ { 445.5, /* SGI */ 495.0, }, + }, +}; + static const char *auth_alg_text[]={"Open System","Shared Key","EAP"}; #define NUM_AUTH_ALGS (sizeof auth_alg_text / sizeof auth_alg_text[0]) static const char *status_text[] = { - "Succesful", /* 0 */ - "Unspecified failure", /* 1 */ - "Reserved", /* 2 */ - "Reserved", /* 3 */ - "Reserved", /* 4 */ - "Reserved", /* 5 */ - "Reserved", /* 6 */ - "Reserved", /* 7 */ - "Reserved", /* 8 */ - "Reserved", /* 9 */ - "Cannot Support all requested capabilities in the Capability Information field", /* 10 */ - "Reassociation denied due to inability to confirm that association exists", /* 11 */ - "Association denied due to reason outside the scope of the standard", /* 12 */ - "Responding station does not support the specified authentication algorithm ", /* 13 */ - "Received an Authentication frame with authentication transaction " \ - "sequence number out of expected sequence", /* 14 */ - "Authentication rejected because of challenge failure", /* 15 */ - "Authentication rejected due to timeout waiting for next frame in sequence", /* 16 */ - "Association denied because AP is unable to handle additional associated stations", /* 17 */ - "Association denied due to requesting station not supporting all of the " \ - "data rates in BSSBasicRateSet parameter", /* 18 */ + "Succesful", /* 0 */ + "Unspecified failure", /* 1 */ + "Reserved", /* 2 */ + "Reserved", /* 3 */ + "Reserved", /* 4 */ + "Reserved", /* 5 */ + "Reserved", /* 6 */ + "Reserved", /* 7 */ + "Reserved", /* 8 */ + "Reserved", /* 9 */ + "Cannot Support all requested capabilities in the Capability " + "Information field", /* 10 */ + "Reassociation denied due to inability to confirm that association " + "exists", /* 11 */ + "Association denied due to reason outside the scope of the " + "standard", /* 12 */ + "Responding station does not support the specified authentication " + "algorithm ", /* 13 */ + "Received an Authentication frame with authentication transaction " + "sequence number out of expected sequence", /* 14 */ + "Authentication rejected because of challenge failure", /* 15 */ + "Authentication rejected due to timeout waiting for next frame in " + "sequence", /* 16 */ + "Association denied because AP is unable to handle additional" + "associated stations", /* 17 */ + "Association denied due to requesting station not supporting all of " + "the data rates in BSSBasicRateSet parameter", /* 18 */ + "Association denied due to requesting station not supporting " + "short preamble operation", /* 19 */ + "Association denied due to requesting station not supporting " + "PBCC encoding", /* 20 */ + "Association denied due to requesting station not supporting " + "channel agility", /* 21 */ + "Association request rejected because Spectrum Management " + "capability is required", /* 22 */ + "Association request rejected because the information in the " + "Power Capability element is unacceptable", /* 23 */ + "Association request rejected because the information in the " + "Supported Channels element is unacceptable", /* 24 */ + "Association denied due to requesting station not supporting " + "short slot operation", /* 25 */ + "Association denied due to requesting station not supporting " + "DSSS-OFDM operation", /* 26 */ + "Association denied because the requested STA does not support HT " + "features", /* 27 */ + "Reserved", /* 28 */ + "Association denied because the requested STA does not support " + "the PCO transition time required by the AP", /* 29 */ + "Reserved", /* 30 */ + "Reserved", /* 31 */ + "Unspecified, QoS-related failure", /* 32 */ + "Association denied due to QAP having insufficient bandwidth " + "to handle another QSTA", /* 33 */ + "Association denied due to excessive frame loss rates and/or " + "poor conditions on current operating channel", /* 34 */ + "Association (with QBSS) denied due to requesting station not " + "supporting the QoS facility", /* 35 */ + "Association denied due to requesting station not supporting " + "Block Ack", /* 36 */ + "The request has been declined", /* 37 */ + "The request has not been successful as one or more parameters " + "have invalid values", /* 38 */ + "The TS has not been created because the request cannot be honored. " + "However, a suggested TSPEC is provided so that the initiating QSTA" + "may attempt to set another TS with the suggested changes to the " + "TSPEC", /* 39 */ + "Invalid Information Element", /* 40 */ + "Group Cipher is not valid", /* 41 */ + "Pairwise Cipher is not valid", /* 42 */ + "AKMP is not valid", /* 43 */ + "Unsupported RSN IE version", /* 44 */ + "Invalid RSN IE Capabilities", /* 45 */ + "Cipher suite is rejected per security policy", /* 46 */ + "The TS has not been created. However, the HC may be capable of " + "creating a TS, in response to a request, after the time indicated " + "in the TS Delay element", /* 47 */ + "Direct Link is not allowed in the BSS by policy", /* 48 */ + "Destination STA is not present within this QBSS.", /* 49 */ + "The Destination STA is not a QSTA.", /* 50 */ + }; #define NUM_STATUSES (sizeof status_text / sizeof status_text[0]) static const char *reason_text[] = { - "Reserved", /* 0 */ - "Unspecified reason", /* 1 */ - "Previous authentication no longer valid", /* 2 */ - "Deauthenticated because sending station is leaving (or has left) IBSS or ESS", /* 3 */ - "Disassociated due to inactivity", /* 4 */ - "Disassociated because AP is unable to handle all currently associated stations", /* 5 */ + "Reserved", /* 0 */ + "Unspecified reason", /* 1 */ + "Previous authentication no longer valid", /* 2 */ + "Deauthenticated because sending station is leaving (or has left) " + "IBSS or ESS", /* 3 */ + "Disassociated due to inactivity", /* 4 */ + "Disassociated because AP is unable to handle all currently " + " associated stations", /* 5 */ "Class 2 frame received from nonauthenticated station", /* 6 */ - "Class 3 frame received from nonassociated station", /* 7 */ - "Disassociated because sending station is leaving (or has left) BSS", /* 8 */ - "Station requesting (re)association is not authenticated with responding station", /* 9 */ + "Class 3 frame received from nonassociated station", /* 7 */ + "Disassociated because sending station is leaving " + "(or has left) BSS", /* 8 */ + "Station requesting (re)association is not authenticated with " + "responding station", /* 9 */ + "Disassociated because the information in the Power Capability " + "element is unacceptable", /* 10 */ + "Disassociated because the information in the SupportedChannels " + "element is unacceptable", /* 11 */ + "Invalid Information Element", /* 12 */ + "Reserved", /* 13 */ + "Michael MIC failure", /* 14 */ + "4-Way Handshake timeout", /* 15 */ + "Group key update timeout", /* 16 */ + "Information element in 4-Way Handshake different from (Re)Association" + "Request/Probe Response/Beacon", /* 17 */ + "Group Cipher is not valid", /* 18 */ + "AKMP is not valid", /* 20 */ + "Unsupported RSN IE version", /* 21 */ + "Invalid RSN IE Capabilities", /* 22 */ + "IEEE 802.1X Authentication failed", /* 23 */ + "Cipher suite is rejected per security policy", /* 24 */ + "Reserved", /* 25 */ + "Reserved", /* 26 */ + "Reserved", /* 27 */ + "Reserved", /* 28 */ + "Reserved", /* 29 */ + "Reserved", /* 30 */ + "TS deleted because QoS AP lacks sufficient bandwidth for this " + "QoS STA due to a change in BSS service characteristics or " + "operational mode (e.g. an HT BSS change from 40 MHz channel " + "to 20 MHz channel)", /* 31 */ + "Disassociated for unspecified, QoS-related reason", /* 32 */ + "Disassociated because QoS AP lacks sufficient bandwidth for this " + "QoS STA", /* 33 */ + "Disassociated because of excessive number of frames that need to be " + "acknowledged, but are not acknowledged for AP transmissions " + "and/or poor channel conditions", /* 34 */ + "Disassociated because STA is transmitting outside the limits " + "of its TXOPs", /* 35 */ + "Requested from peer STA as the STA is leaving the BSS " + "(or resetting)", /* 36 */ + "Requested from peer STA as it does not want to use the " + "mechanism", /* 37 */ + "Requested from peer STA as the STA received frames using the " + "mechanism for which a set up is required", /* 38 */ + "Requested from peer STA due to time out", /* 39 */ + "Reserved", /* 40 */ + "Reserved", /* 41 */ + "Reserved", /* 42 */ + "Reserved", /* 43 */ + "Reserved", /* 44 */ + "Peer STA does not support the requested cipher suite", /* 45 */ + "Association denied due to requesting STA not supporting HT " + "features", /* 46 */ }; #define NUM_REASONS (sizeof reason_text / sizeof reason_text[0]) @@ -152,141 +651,242 @@ wep_print(const u_char *p) return 1; } -static void -parse_elements(struct mgmt_body_t *pbody, const u_char *p, int offset) +static int +parse_elements(struct mgmt_body_t *pbody, const u_char *p, int offset, + u_int length) { + u_int elementlen; + struct ssid_t ssid; + struct challenge_t challenge; + struct rates_t rates; + struct ds_t ds; + struct cf_t cf; + struct tim_t tim; + /* * We haven't seen any elements yet. */ - pbody->challenge_status = NOT_PRESENT; - pbody->ssid_status = NOT_PRESENT; - pbody->rates_status = NOT_PRESENT; - pbody->ds_status = NOT_PRESENT; - pbody->cf_status = NOT_PRESENT; - pbody->tim_status = NOT_PRESENT; - - for (;;) { + pbody->challenge_present = 0; + pbody->ssid_present = 0; + pbody->rates_present = 0; + pbody->ds_present = 0; + pbody->cf_present = 0; + pbody->tim_present = 0; + + while (length != 0) { if (!TTEST2(*(p + offset), 1)) - return; + return 0; + if (length < 1) + return 0; switch (*(p + offset)) { case E_SSID: - /* Present, possibly truncated */ - pbody->ssid_status = TRUNCATED; if (!TTEST2(*(p + offset), 2)) - return; - memcpy(&pbody->ssid, p + offset, 2); + return 0; + if (length < 2) + return 0; + memcpy(&ssid, p + offset, 2); offset += 2; - if (pbody->ssid.length != 0) { - if (pbody->ssid.length > - sizeof(pbody->ssid.ssid) - 1) - return; - if (!TTEST2(*(p + offset), pbody->ssid.length)) - return; - memcpy(&pbody->ssid.ssid, p + offset, - pbody->ssid.length); - offset += pbody->ssid.length; + length -= 2; + if (ssid.length != 0) { + if (ssid.length > sizeof(ssid.ssid) - 1) + return 0; + if (!TTEST2(*(p + offset), ssid.length)) + return 0; + if (length < ssid.length) + return 0; + memcpy(&ssid.ssid, p + offset, ssid.length); + offset += ssid.length; + length -= ssid.length; + } + ssid.ssid[ssid.length] = '\0'; + /* + * Present and not truncated. + * + * If we haven't already seen an SSID IE, + * copy this one, otherwise ignore this one, + * so we later report the first one we saw. + */ + if (!pbody->ssid_present) { + pbody->ssid = ssid; + pbody->ssid_present = 1; } - pbody->ssid.ssid[pbody->ssid.length] = '\0'; - /* Present and not truncated */ - pbody->ssid_status = PRESENT; break; case E_CHALLENGE: - /* Present, possibly truncated */ - pbody->challenge_status = TRUNCATED; if (!TTEST2(*(p + offset), 2)) - return; - memcpy(&pbody->challenge, p + offset, 2); + return 0; + if (length < 2) + return 0; + memcpy(&challenge, p + offset, 2); offset += 2; - if (pbody->challenge.length != 0) { - if (pbody->challenge.length > - sizeof(pbody->challenge.text) - 1) - return; - if (!TTEST2(*(p + offset), pbody->challenge.length)) - return; - memcpy(&pbody->challenge.text, p + offset, - pbody->challenge.length); - offset += pbody->challenge.length; + length -= 2; + if (challenge.length != 0) { + if (challenge.length > + sizeof(challenge.text) - 1) + return 0; + if (!TTEST2(*(p + offset), challenge.length)) + return 0; + if (length < challenge.length) + return 0; + memcpy(&challenge.text, p + offset, + challenge.length); + offset += challenge.length; + length -= challenge.length; + } + challenge.text[challenge.length] = '\0'; + /* + * Present and not truncated. + * + * If we haven't already seen a challenge IE, + * copy this one, otherwise ignore this one, + * so we later report the first one we saw. + */ + if (!pbody->challenge_present) { + pbody->challenge = challenge; + pbody->challenge_present = 1; } - pbody->challenge.text[pbody->challenge.length] = '\0'; - /* Present and not truncated */ - pbody->challenge_status = PRESENT; break; case E_RATES: - /* Present, possibly truncated */ - pbody->rates_status = TRUNCATED; if (!TTEST2(*(p + offset), 2)) - return; - memcpy(&(pbody->rates), p + offset, 2); + return 0; + if (length < 2) + return 0; + memcpy(&rates, p + offset, 2); offset += 2; - if (pbody->rates.length != 0) { - if (pbody->rates.length > sizeof pbody->rates.rate) - return; - if (!TTEST2(*(p + offset), pbody->rates.length)) - return; - memcpy(&pbody->rates.rate, p + offset, - pbody->rates.length); - offset += pbody->rates.length; + length -= 2; + if (rates.length != 0) { + if (rates.length > sizeof rates.rate) + return 0; + if (!TTEST2(*(p + offset), rates.length)) + return 0; + if (length < rates.length) + return 0; + memcpy(&rates.rate, p + offset, rates.length); + offset += rates.length; + length -= rates.length; + } + /* + * Present and not truncated. + * + * If we haven't already seen a rates IE, + * copy this one if it's not zero-length, + * otherwise ignore this one, so we later + * report the first one we saw. + * + * We ignore zero-length rates IEs as some + * devices seem to put a zero-length rates + * IE, followed by an SSID IE, followed by + * a non-zero-length rates IE into frames, + * even though IEEE Std 802.11-2007 doesn't + * seem to indicate that a zero-length rates + * IE is valid. + */ + if (!pbody->rates_present && rates.length != 0) { + pbody->rates = rates; + pbody->rates_present = 1; } - /* Present and not truncated */ - pbody->rates_status = PRESENT; break; case E_DS: - /* Present, possibly truncated */ - pbody->ds_status = TRUNCATED; if (!TTEST2(*(p + offset), 3)) - return; - memcpy(&pbody->ds, p + offset, 3); + return 0; + if (length < 3) + return 0; + memcpy(&ds, p + offset, 3); offset += 3; - /* Present and not truncated */ - pbody->ds_status = PRESENT; + length -= 3; + /* + * Present and not truncated. + * + * If we haven't already seen a DS IE, + * copy this one, otherwise ignore this one, + * so we later report the first one we saw. + */ + if (!pbody->ds_present) { + pbody->ds = ds; + pbody->ds_present = 1; + } break; case E_CF: - /* Present, possibly truncated */ - pbody->cf_status = TRUNCATED; if (!TTEST2(*(p + offset), 8)) - return; - memcpy(&pbody->cf, p + offset, 8); + return 0; + if (length < 8) + return 0; + memcpy(&cf, p + offset, 8); offset += 8; - /* Present and not truncated */ - pbody->cf_status = PRESENT; + length -= 8; + /* + * Present and not truncated. + * + * If we haven't already seen a CF IE, + * copy this one, otherwise ignore this one, + * so we later report the first one we saw. + */ + if (!pbody->cf_present) { + pbody->cf = cf; + pbody->cf_present = 1; + } break; case E_TIM: - /* Present, possibly truncated */ - pbody->tim_status = TRUNCATED; if (!TTEST2(*(p + offset), 2)) - return; - memcpy(&pbody->tim, p + offset, 2); + return 0; + if (length < 2) + return 0; + memcpy(&tim, p + offset, 2); offset += 2; + length -= 2; if (!TTEST2(*(p + offset), 3)) - return; - memcpy(&pbody->tim.count, p + offset, 3); + return 0; + if (length < 3) + return 0; + memcpy(&tim.count, p + offset, 3); offset += 3; + length -= 3; - if (pbody->tim.length <= 3) + if (tim.length <= 3) break; - if (pbody->tim.length - 3 > (int)sizeof pbody->tim.bitmap) - return; - if (!TTEST2(*(p + offset), pbody->tim.length - 3)) - return; - memcpy(pbody->tim.bitmap, p + (pbody->tim.length - 3), - (pbody->tim.length - 3)); - offset += pbody->tim.length - 3; - /* Present and not truncated */ - pbody->tim_status = PRESENT; + if (tim.length - 3 > (int)sizeof tim.bitmap) + return 0; + if (!TTEST2(*(p + offset), tim.length - 3)) + return 0; + if (length < (u_int)(tim.length - 3)) + return 0; + memcpy(tim.bitmap, p + (tim.length - 3), + (tim.length - 3)); + offset += tim.length - 3; + length -= tim.length - 3; + /* + * Present and not truncated. + * + * If we haven't already seen a TIM IE, + * copy this one, otherwise ignore this one, + * so we later report the first one we saw. + */ + if (!pbody->tim_present) { + pbody->tim = tim; + pbody->tim_present = 1; + } break; default: #if 0 printf("(1) unhandled element_id (%d) ", - *(p + offset) ); + *(p + offset)); #endif if (!TTEST2(*(p + offset), 2)) - return; - if (!TTEST2(*(p + offset + 2), *(p + offset + 1))) - return; - offset += *(p + offset + 1) + 2; + return 0; + if (length < 2) + return 0; + elementlen = *(p + offset + 1); + if (!TTEST2(*(p + offset + 2), elementlen)) + return 0; + if (length < elementlen + 2) + return 0; + offset += elementlen + 2; + length -= elementlen + 2; break; } } + + /* No problems found. */ + return 1; } /********************************************************************************* @@ -294,24 +894,31 @@ parse_elements(struct mgmt_body_t *pbody, const u_char *p, int offset) *********************************************************************************/ static int -handle_beacon(const u_char *p) +handle_beacon(const u_char *p, u_int length) { struct mgmt_body_t pbody; int offset = 0; + int ret; memset(&pbody, 0, sizeof(pbody)); if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN + IEEE802_11_CAPINFO_LEN)) return 0; + if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN + + IEEE802_11_CAPINFO_LEN) + return 0; memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN); offset += IEEE802_11_TSTAMP_LEN; + length -= IEEE802_11_TSTAMP_LEN; pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset); offset += IEEE802_11_BCNINT_LEN; + length -= IEEE802_11_BCNINT_LEN; pbody.capability_info = EXTRACT_LE_16BITS(p+offset); offset += IEEE802_11_CAPINFO_LEN; + length -= IEEE802_11_CAPINFO_LEN; - parse_elements(&pbody, p, offset); + ret = parse_elements(&pbody, p, offset, length); PRINT_SSID(pbody); PRINT_RATES(pbody); @@ -319,50 +926,62 @@ handle_beacon(const u_char *p) CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS"); PRINT_DS_CHANNEL(pbody); - return 1; + return ret; } static int -handle_assoc_request(const u_char *p) +handle_assoc_request(const u_char *p, u_int length) { struct mgmt_body_t pbody; int offset = 0; + int ret; memset(&pbody, 0, sizeof(pbody)); if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN)) return 0; + if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN) + return 0; pbody.capability_info = EXTRACT_LE_16BITS(p); offset += IEEE802_11_CAPINFO_LEN; + length -= IEEE802_11_CAPINFO_LEN; pbody.listen_interval = EXTRACT_LE_16BITS(p+offset); offset += IEEE802_11_LISTENINT_LEN; + length -= IEEE802_11_LISTENINT_LEN; - parse_elements(&pbody, p, offset); + ret = parse_elements(&pbody, p, offset, length); PRINT_SSID(pbody); PRINT_RATES(pbody); - return 1; + return ret; } static int -handle_assoc_response(const u_char *p) +handle_assoc_response(const u_char *p, u_int length) { struct mgmt_body_t pbody; int offset = 0; + int ret; memset(&pbody, 0, sizeof(pbody)); if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN + IEEE802_11_AID_LEN)) return 0; + if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN + + IEEE802_11_AID_LEN) + return 0; pbody.capability_info = EXTRACT_LE_16BITS(p); offset += IEEE802_11_CAPINFO_LEN; + length -= IEEE802_11_CAPINFO_LEN; pbody.status_code = EXTRACT_LE_16BITS(p+offset); offset += IEEE802_11_STATUS_LEN; + length -= IEEE802_11_STATUS_LEN; pbody.aid = EXTRACT_LE_16BITS(p+offset); offset += IEEE802_11_AID_LEN; + length -= IEEE802_11_AID_LEN; - parse_elements(&pbody, p, offset); + ret = parse_elements(&pbody, p, offset, length); printf(" AID(%x) :%s: %s", ((u_int16_t)(pbody.aid << 2 )) >> 2 , CAPABILITY_PRIVACY(pbody.capability_info) ? " PRIVACY " : "", @@ -370,84 +989,98 @@ handle_assoc_response(const u_char *p) ? status_text[pbody.status_code] : "n/a")); - return 1; + return ret; } static int -handle_reassoc_request(const u_char *p) +handle_reassoc_request(const u_char *p, u_int length) { struct mgmt_body_t pbody; int offset = 0; + int ret; memset(&pbody, 0, sizeof(pbody)); if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN + IEEE802_11_AP_LEN)) return 0; + if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN + + IEEE802_11_AP_LEN) + return 0; pbody.capability_info = EXTRACT_LE_16BITS(p); offset += IEEE802_11_CAPINFO_LEN; + length -= IEEE802_11_CAPINFO_LEN; pbody.listen_interval = EXTRACT_LE_16BITS(p+offset); offset += IEEE802_11_LISTENINT_LEN; + length -= IEEE802_11_LISTENINT_LEN; memcpy(&pbody.ap, p+offset, IEEE802_11_AP_LEN); offset += IEEE802_11_AP_LEN; + length -= IEEE802_11_AP_LEN; - parse_elements(&pbody, p, offset); + ret = parse_elements(&pbody, p, offset, length); PRINT_SSID(pbody); printf(" AP : %s", etheraddr_string( pbody.ap )); - return 1; + return ret; } static int -handle_reassoc_response(const u_char *p) +handle_reassoc_response(const u_char *p, u_int length) { /* Same as a Association Reponse */ - return handle_assoc_response(p); + return handle_assoc_response(p, length); } static int -handle_probe_request(const u_char *p) +handle_probe_request(const u_char *p, u_int length) { struct mgmt_body_t pbody; int offset = 0; + int ret; memset(&pbody, 0, sizeof(pbody)); - parse_elements(&pbody, p, offset); + ret = parse_elements(&pbody, p, offset, length); PRINT_SSID(pbody); PRINT_RATES(pbody); - return 1; + return ret; } static int -handle_probe_response(const u_char *p) +handle_probe_response(const u_char *p, u_int length) { struct mgmt_body_t pbody; int offset = 0; + int ret; memset(&pbody, 0, sizeof(pbody)); if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN + IEEE802_11_CAPINFO_LEN)) return 0; - + if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN + + IEEE802_11_CAPINFO_LEN) + return 0; memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN); offset += IEEE802_11_TSTAMP_LEN; + length -= IEEE802_11_TSTAMP_LEN; pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset); offset += IEEE802_11_BCNINT_LEN; + length -= IEEE802_11_BCNINT_LEN; pbody.capability_info = EXTRACT_LE_16BITS(p+offset); offset += IEEE802_11_CAPINFO_LEN; + length -= IEEE802_11_CAPINFO_LEN; - parse_elements(&pbody, p, offset); + ret = parse_elements(&pbody, p, offset, length); PRINT_SSID(pbody); PRINT_RATES(pbody); PRINT_DS_CHANNEL(pbody); - return 1; + return ret; } static int @@ -458,7 +1091,7 @@ handle_atim(void) } static int -handle_disassoc(const u_char *p) +handle_disassoc(const u_char *p, u_int length) { struct mgmt_body_t pbody; @@ -466,6 +1099,8 @@ handle_disassoc(const u_char *p) if (!TTEST2(*p, IEEE802_11_REASON_LEN)) return 0; + if (length < IEEE802_11_REASON_LEN) + return 0; pbody.reason_code = EXTRACT_LE_16BITS(p); printf(": %s", @@ -477,23 +1112,29 @@ handle_disassoc(const u_char *p) } static int -handle_auth(const u_char *p) +handle_auth(const u_char *p, u_int length) { struct mgmt_body_t pbody; int offset = 0; + int ret; memset(&pbody, 0, sizeof(pbody)); if (!TTEST2(*p, 6)) return 0; + if (length < 6) + return 0; pbody.auth_alg = EXTRACT_LE_16BITS(p); offset += 2; + length -= 2; pbody.auth_trans_seq_num = EXTRACT_LE_16BITS(p + offset); offset += 2; + length -= 2; pbody.status_code = EXTRACT_LE_16BITS(p + offset); offset += 2; + length -= 2; - parse_elements(&pbody, p, offset); + ret = parse_elements(&pbody, p, offset, length); if ((pbody.auth_alg == 1) && ((pbody.auth_trans_seq_num == 2) || @@ -507,7 +1148,7 @@ handle_auth(const u_char *p) ? ((pbody.status_code < NUM_STATUSES) ? status_text[pbody.status_code] : "n/a") : "")); - return 1; + return ret; } printf(" (%s)-%x: %s", (pbody.auth_alg < NUM_AUTH_ALGS) @@ -520,11 +1161,11 @@ handle_auth(const u_char *p) : "n/a") : ""); - return 1; + return ret; } static int -handle_deauth(const struct mgmt_header_t *pmh, const u_char *p) +handle_deauth(const struct mgmt_header_t *pmh, const u_char *p, u_int length) { struct mgmt_body_t pbody; int offset = 0; @@ -534,8 +1175,11 @@ handle_deauth(const struct mgmt_header_t *pmh, const u_char *p) if (!TTEST2(*p, IEEE802_11_REASON_LEN)) return 0; + if (length < IEEE802_11_REASON_LEN) + return 0; pbody.reason_code = EXTRACT_LE_16BITS(p); offset += IEEE802_11_REASON_LEN; + length -= IEEE802_11_REASON_LEN; reason = (pbody.reason_code < NUM_REASONS) ? reason_text[pbody.reason_code] @@ -549,6 +1193,68 @@ handle_deauth(const struct mgmt_header_t *pmh, const u_char *p) return 1; } +#define PRINT_HT_ACTION(v) (\ + (v) == 0 ? printf("TxChWidth") : \ + (v) == 1 ? printf("MIMOPwrSave") : \ + printf("Act#%d", (v)) \ +) +#define PRINT_BA_ACTION(v) (\ + (v) == 0 ? printf("ADDBA Request") : \ + (v) == 1 ? printf("ADDBA Response") : \ + (v) == 2 ? printf("DELBA") : \ + printf("Act#%d", (v)) \ +) +#define PRINT_MESHLINK_ACTION(v) (\ + (v) == 0 ? printf("Request") : \ + (v) == 1 ? printf("Report") : \ + printf("Act#%d", (v)) \ +) +#define PRINT_MESHPEERING_ACTION(v) (\ + (v) == 0 ? printf("Open") : \ + (v) == 1 ? printf("Confirm") : \ + (v) == 2 ? printf("Close") : \ + printf("Act#%d", (v)) \ +) +#define PRINT_MESHPATH_ACTION(v) (\ + (v) == 0 ? printf("Request") : \ + (v) == 1 ? printf("Report") : \ + (v) == 2 ? printf("Error") : \ + (v) == 3 ? printf("RootAnnouncement") : \ + printf("Act#%d", (v)) \ +) + +static int +handle_action(const struct mgmt_header_t *pmh, const u_char *p, u_int length) +{ + if (!TTEST2(*p, 2)) + return 0; + if (length < 2) + return 0; + if (eflag) { + printf(": "); + } else { + printf(" (%s): ", etheraddr_string(pmh->sa)); + } + switch (p[0]) { + case 0: printf("Spectrum Management Act#%d", p[1]); break; + case 1: printf("QoS Act#%d", p[1]); break; + case 2: printf("DLS Act#%d", p[1]); break; + case 3: printf("BA "); PRINT_BA_ACTION(p[1]); break; + case 7: printf("HT "); PRINT_HT_ACTION(p[1]); break; + case 13: printf("MeshLMetric "); PRINT_MESHLINK_ACTION(p[1]); break; + case 15: printf("Interwork Act#%d", p[1]); break; + case 16: printf("Resource Act#%d", p[1]); break; + case 17: printf("Proxy Act#%d", p[1]); break; + case 30: printf("MeshPeering "); PRINT_MESHPEERING_ACTION(p[1]); break; + case 32: printf("MeshPath "); PRINT_MESHPATH_ACTION(p[1]); break; + case 127: printf("Vendor Act#%d", p[1]); break; + default: + printf("Reserved(%d) Act#%d", p[0], p[1]); + break; + } + return 1; +} + /********************************************************************************* * Print Body funcs @@ -557,36 +1263,36 @@ handle_deauth(const struct mgmt_header_t *pmh, const u_char *p) static int mgmt_body_print(u_int16_t fc, const struct mgmt_header_t *pmh, - const u_char *p) + const u_char *p, u_int length) { switch (FC_SUBTYPE(fc)) { case ST_ASSOC_REQUEST: printf("Assoc Request"); - return handle_assoc_request(p); + return handle_assoc_request(p, length); case ST_ASSOC_RESPONSE: printf("Assoc Response"); - return handle_assoc_response(p); + return handle_assoc_response(p, length); case ST_REASSOC_REQUEST: printf("ReAssoc Request"); - return handle_reassoc_request(p); + return handle_reassoc_request(p, length); case ST_REASSOC_RESPONSE: printf("ReAssoc Response"); - return handle_reassoc_response(p); + return handle_reassoc_response(p, length); case ST_PROBE_REQUEST: printf("Probe Request"); - return handle_probe_request(p); + return handle_probe_request(p, length); case ST_PROBE_RESPONSE: printf("Probe Response"); - return handle_probe_response(p); + return handle_probe_response(p, length); case ST_BEACON: printf("Beacon"); - return handle_beacon(p); + return handle_beacon(p, length); case ST_ATIM: printf("ATIM"); return handle_atim(); case ST_DISASSOC: printf("Disassociation"); - return handle_disassoc(p); + return handle_disassoc(p, length); case ST_AUTH: printf("Authentication"); if (!TTEST2(*p, 3)) @@ -595,10 +1301,14 @@ mgmt_body_print(u_int16_t fc, const struct mgmt_header_t *pmh, printf("Authentication (Shared-Key)-3 "); return wep_print(p); } - return handle_auth(p); + return handle_auth(p, length); case ST_DEAUTH: printf("DeAuthentication"); - return handle_deauth(pmh, p); + return handle_deauth(pmh, p, length); + break; + case ST_ACTION: + printf("Action"); + return handle_action(pmh, p, length); break; default: printf("Unhandled Management subtype(%x)", @@ -616,6 +1326,29 @@ static int ctrl_body_print(u_int16_t fc, const u_char *p) { switch (FC_SUBTYPE(fc)) { + case CTRL_CONTROL_WRAPPER: + printf("Control Wrapper"); + /* XXX - requires special handling */ + break; + case CTRL_BAR: + printf("BAR"); + if (!TTEST2(*p, CTRL_BAR_HDRLEN)) + return 0; + if (!eflag) + printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ", + etheraddr_string(((const struct ctrl_bar_t *)p)->ra), + etheraddr_string(((const struct ctrl_bar_t *)p)->ta), + EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)), + EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq))); + break; + case CTRL_BA: + printf("BA"); + if (!TTEST2(*p, CTRL_BA_HDRLEN)) + return 0; + if (!eflag) + printf(" RA:%s ", + etheraddr_string(((const struct ctrl_ba_t *)p)->ra)); + break; case CTRL_PS_POLL: printf("Power Save-Poll"); if (!TTEST2(*p, CTRL_PS_POLL_HDRLEN)) @@ -789,6 +1522,17 @@ ctrl_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp, return; switch (FC_SUBTYPE(fc)) { + case CTRL_BAR: + printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ", + etheraddr_string(((const struct ctrl_bar_t *)p)->ra), + etheraddr_string(((const struct ctrl_bar_t *)p)->ta), + EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)), + EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq))); + break; + case CTRL_BA: + printf("RA:%s ", + etheraddr_string(((const struct ctrl_ba_t *)p)->ra)); + break; case CTRL_PS_POLL: printf("BSSID:%s TA:%s ", etheraddr_string(((const struct ctrl_ps_poll_t *)p)->bssid), @@ -833,6 +1577,8 @@ extract_header_length(u_int16_t fc) return MGMT_HDRLEN; case T_CTRL: switch (FC_SUBTYPE(fc)) { + case CTRL_BAR: + return CTRL_BAR_HDRLEN; case CTRL_PS_POLL: return CTRL_PS_POLL_HDRLEN; case CTRL_RTS: @@ -859,14 +1605,20 @@ extract_header_length(u_int16_t fc) } } +static int +extract_mesh_header_length(const u_char *p) +{ + return (p[0] &~ 3) ? 0 : 6*(1 + (p[0] & 3)); +} + /* * Print the 802.11 MAC header if eflag is set, and set "*srcp" and "*dstp" * to point to the source and destination MAC addresses in any case if * "srcp" and "dstp" aren't null. */ -static inline void -ieee_802_11_hdr_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp, - const u_int8_t **dstp) +static void +ieee_802_11_hdr_print(u_int16_t fc, const u_char *p, u_int hdrlen, + u_int meshdrlen, const u_int8_t **srcp, const u_int8_t **dstp) { if (vflag) { if (FC_MORE_DATA(fc)) @@ -886,6 +1638,21 @@ ieee_802_11_hdr_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp, EXTRACT_LE_16BITS( &((const struct mgmt_header_t *)p)->duration)); } + if (meshdrlen != 0) { + const struct meshcntl_t *mc = + (const struct meshcntl_t *)&p[hdrlen - meshdrlen]; + int ae = mc->flags & 3; + + printf("MeshData (AE %d TTL %u seq %u", ae, mc->ttl, + EXTRACT_LE_32BITS(mc->seq)); + if (ae > 0) + printf(" A4:%s", etheraddr_string(mc->addr4)); + if (ae > 1) + printf(" A5:%s", etheraddr_string(mc->addr5)); + if (ae > 2) + printf(" A6:%s", etheraddr_string(mc->addr6)); + printf(") "); + } switch (FC_TYPE(fc)) { case T_MGMT: @@ -911,29 +1678,51 @@ ieee_802_11_hdr_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp, #endif static u_int -ieee802_11_print(const u_char *p, u_int length, u_int caplen, int pad) +ieee802_11_print(const u_char *p, u_int length, u_int orig_caplen, int pad, + u_int fcslen) { u_int16_t fc; - u_int hdrlen; + u_int caplen, hdrlen, meshdrlen; const u_int8_t *src, *dst; u_short extracted_ethertype; - if (caplen < IEEE802_11_FC_LEN) { + caplen = orig_caplen; + /* Remove FCS, if present */ + if (length < fcslen) { printf("[|802.11]"); return caplen; } + length -= fcslen; + if (caplen > length) { + /* Amount of FCS in actual packet data, if any */ + fcslen = caplen - length; + caplen -= fcslen; + snapend -= fcslen; + } + + if (caplen < IEEE802_11_FC_LEN) { + printf("[|802.11]"); + return orig_caplen; + } fc = EXTRACT_LE_16BITS(p); hdrlen = extract_header_length(fc); if (pad) hdrlen = roundup2(hdrlen, 4); + if (Hflag && FC_TYPE(fc) == T_DATA && + DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) { + meshdrlen = extract_mesh_header_length(p+hdrlen); + hdrlen += meshdrlen; + } else + meshdrlen = 0; + if (caplen < hdrlen) { printf("[|802.11]"); return hdrlen; } - ieee_802_11_hdr_print(fc, p, &src, &dst); + ieee_802_11_hdr_print(fc, p, hdrlen, meshdrlen, &src, &dst); /* * Go past the 802.11 header. @@ -945,7 +1734,7 @@ ieee802_11_print(const u_char *p, u_int length, u_int caplen, int pad) switch (FC_TYPE(fc)) { case T_MGMT: if (!mgmt_body_print(fc, - (const struct mgmt_header_t *)(p - hdrlen), p)) { + (const struct mgmt_header_t *)(p - hdrlen), p, length)) { printf("[|802.11]"); return hdrlen; } @@ -972,8 +1761,8 @@ ieee802_11_print(const u_char *p, u_int length, u_int caplen, int pad) * handle intelligently */ if (!eflag) - ieee_802_11_hdr_print(fc, p - hdrlen, NULL, - NULL); + ieee_802_11_hdr_print(fc, p - hdrlen, hdrlen, + meshdrlen, NULL, NULL); if (extracted_ethertype) printf("(LLC %s) ", etherproto_string( @@ -999,11 +1788,70 @@ ieee802_11_print(const u_char *p, u_int length, u_int caplen, int pad) u_int ieee802_11_if_print(const struct pcap_pkthdr *h, const u_char *p) { - return ieee802_11_print(p, h->len, h->caplen, 0); + return ieee802_11_print(p, h->len, h->caplen, 0, 0); +} + +#define IEEE80211_CHAN_FHSS \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK) +#define IEEE80211_CHAN_A \ + (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM) +#define IEEE80211_CHAN_B \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK) +#define IEEE80211_CHAN_PUREG \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM) +#define IEEE80211_CHAN_G \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN) + +#define IS_CHAN_FHSS(flags) \ + ((flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS) +#define IS_CHAN_A(flags) \ + ((flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A) +#define IS_CHAN_B(flags) \ + ((flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B) +#define IS_CHAN_PUREG(flags) \ + ((flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG) +#define IS_CHAN_G(flags) \ + ((flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G) +#define IS_CHAN_ANYG(flags) \ + (IS_CHAN_PUREG(flags) || IS_CHAN_G(flags)) + +static void +print_chaninfo(int freq, int flags) +{ + printf("%u MHz", freq); + if (IS_CHAN_FHSS(flags)) + printf(" FHSS"); + if (IS_CHAN_A(flags)) { + if (flags & IEEE80211_CHAN_HALF) + printf(" 11a/10Mhz"); + else if (flags & IEEE80211_CHAN_QUARTER) + printf(" 11a/5Mhz"); + else + printf(" 11a"); + } + if (IS_CHAN_ANYG(flags)) { + if (flags & IEEE80211_CHAN_HALF) + printf(" 11g/10Mhz"); + else if (flags & IEEE80211_CHAN_QUARTER) + printf(" 11g/5Mhz"); + else + printf(" 11g"); + } else if (IS_CHAN_B(flags)) + printf(" 11b"); + if (flags & IEEE80211_CHAN_TURBO) + printf(" Turbo"); + if (flags & IEEE80211_CHAN_HT20) + printf(" ht/20"); + else if (flags & IEEE80211_CHAN_HT40D) + printf(" ht/40-"); + else if (flags & IEEE80211_CHAN_HT40U) + printf(" ht/40+"); + printf(" "); } static int -print_radiotap_field(struct cpack_state *s, u_int32_t bit, int *pad) +print_radiotap_field(struct cpack_state *s, u_int32_t bit, u_int8_t *flags, + struct radiotap_state *state, u_int32_t presentflags) { union { int8_t i8; @@ -1012,16 +1860,24 @@ print_radiotap_field(struct cpack_state *s, u_int32_t bit, int *pad) u_int16_t u16; u_int32_t u32; u_int64_t u64; - } u, u2; + } u, u2, u3, u4; int rc; switch (bit) { case IEEE80211_RADIOTAP_FLAGS: rc = cpack_uint8(s, &u.u8); - if (u.u8 & IEEE80211_RADIOTAP_F_DATAPAD) - *pad = 1; + if (rc != 0) + break; + *flags = u.u8; break; case IEEE80211_RADIOTAP_RATE: + rc = cpack_uint8(s, &u.u8); + if (rc != 0) + break; + + /* Save state rate */ + state->rate = u.u8; + break; case IEEE80211_RADIOTAP_DB_ANTSIGNAL: case IEEE80211_RADIOTAP_DB_ANTNOISE: case IEEE80211_RADIOTAP_ANTENNA: @@ -1040,6 +1896,7 @@ print_radiotap_field(struct cpack_state *s, u_int32_t bit, int *pad) case IEEE80211_RADIOTAP_FHSS: case IEEE80211_RADIOTAP_LOCK_QUALITY: case IEEE80211_RADIOTAP_TX_ATTENUATION: + case IEEE80211_RADIOTAP_RX_FLAGS: rc = cpack_uint16(s, &u.u16); break; case IEEE80211_RADIOTAP_DB_TX_ATTENUATION: @@ -1051,12 +1908,63 @@ print_radiotap_field(struct cpack_state *s, u_int32_t bit, int *pad) case IEEE80211_RADIOTAP_TSFT: rc = cpack_uint64(s, &u.u64); break; + case IEEE80211_RADIOTAP_XCHANNEL: + rc = cpack_uint32(s, &u.u32); + if (rc != 0) + break; + rc = cpack_uint16(s, &u2.u16); + if (rc != 0) + break; + rc = cpack_uint8(s, &u3.u8); + if (rc != 0) + break; + rc = cpack_uint8(s, &u4.u8); + break; + case IEEE80211_RADIOTAP_MCS: + rc = cpack_uint8(s, &u.u8); + if (rc != 0) + break; + rc = cpack_uint8(s, &u2.u8); + if (rc != 0) + break; + rc = cpack_uint8(s, &u3.u8); + break; + case IEEE80211_RADIOTAP_VENDOR_NAMESPACE: { + u_int8_t vns[3]; + u_int16_t length; + u_int8_t subspace; + + if ((cpack_align_and_reserve(s, 2)) == NULL) { + rc = -1; + break; + } + + rc = cpack_uint8(s, &vns[0]); + if (rc != 0) + break; + rc = cpack_uint8(s, &vns[1]); + if (rc != 0) + break; + rc = cpack_uint8(s, &vns[2]); + if (rc != 0) + break; + rc = cpack_uint8(s, &subspace); + if (rc != 0) + break; + rc = cpack_uint16(s, &length); + if (rc != 0) + break; + + /* Skip up to length */ + s->c_next += length; + break; + } default: /* this bit indicates a field whose * size we do not know, so we cannot - * proceed. + * proceed. Just print the bit number. */ - printf("[0x%08x] ", bit); + printf("[bit %u] ", bit); return -1; } @@ -1065,17 +1973,64 @@ print_radiotap_field(struct cpack_state *s, u_int32_t bit, int *pad) return rc; } + /* Preserve the state present flags */ + state->present = presentflags; + switch (bit) { case IEEE80211_RADIOTAP_CHANNEL: - printf("%u MHz ", u.u16); - if (u2.u16 != 0) - printf("(0x%04x) ", u2.u16); + /* + * If CHANNEL and XCHANNEL are both present, skip + * CHANNEL. + */ + if (presentflags & (1 << IEEE80211_RADIOTAP_XCHANNEL)) + break; + print_chaninfo(u.u16, u2.u16); break; case IEEE80211_RADIOTAP_FHSS: printf("fhset %d fhpat %d ", u.u16 & 0xff, (u.u16 >> 8) & 0xff); break; case IEEE80211_RADIOTAP_RATE: - PRINT_RATE("", u.u8, " Mb/s "); + /* + * XXX On FreeBSD rate & 0x80 means we have an MCS. On + * Linux and AirPcap it does not. (What about + * Mac OS X, NetBSD, OpenBSD, and DragonFly BSD?) + * + * This is an issue either for proprietary extensions + * to 11a or 11g, which do exist, or for 11n + * implementations that stuff a rate value into + * this field, which also appear to exist. + * + * We currently handle that by assuming that + * if the 0x80 bit is set *and* the remaining + * bits have a value between 0 and 15 it's + * an MCS value, otherwise it's a rate. If + * there are cases where systems that use + * "0x80 + MCS index" for MCS indices > 15, + * or stuff a rate value here between 64 and + * 71.5 Mb/s in here, we'll need a preference + * setting. Such rates do exist, e.g. 11n + * MCS 7 at 20 MHz with a long guard interval. + */ + if (u.u8 >= 0x80 && u.u8 <= 0x8f) { + /* + * XXX - we don't know the channel width + * or guard interval length, so we can't + * convert this to a data rate. + * + * If you want us to show a data rate, + * use the MCS field, not the Rate field; + * the MCS field includes not only the + * MCS index, it also includes bandwidth + * and guard interval information. + * + * XXX - can we get the channel width + * from XChannel and the guard interval + * information from Flags, at least on + * FreeBSD? + */ + printf("MCS %u ", u.u8 & 0x7f); + } else + printf("%2.1f Mb/s ", .5*u.u8); break; case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: printf("%ddB signal ", u.i8); @@ -1119,6 +2074,89 @@ print_radiotap_field(struct cpack_state *s, u_int32_t bit, int *pad) case IEEE80211_RADIOTAP_TSFT: printf("%" PRIu64 "us tsft ", u.u64); break; + case IEEE80211_RADIOTAP_RX_FLAGS: + /* Do nothing for now */ + break; + case IEEE80211_RADIOTAP_XCHANNEL: + print_chaninfo(u2.u16, u.u32); + break; + case IEEE80211_RADIOTAP_MCS: { + static const char *bandwidth[4] = { + "20 MHz", + "40 MHz", + "20 MHz (L)", + "20 MHz (U)" + }; + float htrate; + + if (u.u8 & IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN) { + /* + * We know the MCS index. + */ + if (u3.u8 <= MAX_MCS_INDEX) { + /* + * And it's in-range. + */ + if (u.u8 & (IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN|IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN)) { + /* + * And we know both the bandwidth and + * the guard interval, so we can look + * up the rate. + */ + htrate = + ieee80211_float_htrates \ + [u3.u8] \ + [((u2.u8 & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK) == IEEE80211_RADIOTAP_MCS_BANDWIDTH_40 ? 1 : 0)] \ + [((u2.u8 & IEEE80211_RADIOTAP_MCS_SHORT_GI) ? 1 : 0)]; + } else { + /* + * We don't know both the bandwidth + * and the guard interval, so we can + * only report the MCS index. + */ + htrate = 0.0; + } + } else { + /* + * The MCS value is out of range. + */ + htrate = 0.0; + } + if (htrate != 0.0) { + /* + * We have the rate. + * Print it. + */ + printf("%.1f Mb/s MCS %u ", htrate, u3.u8); + } else { + /* + * We at least have the MCS index. + * Print it. + */ + printf("MCS %u ", u3.u8); + } + } + if (u.u8 & IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN) { + printf("%s ", + bandwidth[u2.u8 & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK]); + } + if (u.u8 & IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN) { + printf("%s GI ", + (u2.u8 & IEEE80211_RADIOTAP_MCS_SHORT_GI) ? + "short" : "lon"); + } + if (u.u8 & IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN) { + printf("%s ", + (u2.u8 & IEEE80211_RADIOTAP_MCS_HT_GREENFIELD) ? + "greenfield" : "mixed"); + } + if (u.u8 & IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN) { + printf("%s FEC ", + (u2.u8 & IEEE80211_RADIOTAP_MCS_FEC_LDPC) ? + "LDPC" : "BCC"); + } + break; + } } return 0; } @@ -1131,19 +2169,23 @@ ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen) #define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x))) #define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x))) #define BITNO_2(x) (((x) & 2) ? 1 : 0) -#define BIT(n) (1 << n) +#define BIT(n) (1U << n) #define IS_EXTENDED(__p) \ (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0 struct cpack_state cpacker; struct ieee80211_radiotap_header *hdr; u_int32_t present, next_present; + u_int32_t presentflags = 0; u_int32_t *presentp, *last_presentp; enum ieee80211_radiotap_type bit; int bit0; const u_char *iter; u_int len; + u_int8_t flags; int pad; + u_int fcslen; + struct radiotap_state state; if (caplen < sizeof(*hdr)) { printf("[|802.11]"); @@ -1177,10 +2219,19 @@ ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen) return caplen; } + /* Assume no flags */ + flags = 0; /* Assume no Atheros padding between 802.11 header and body */ pad = 0; + /* Assume no FCS at end of frame */ + fcslen = 0; for (bit0 = 0, presentp = &hdr->it_present; presentp <= last_presentp; presentp++, bit0 += 32) { + presentflags = EXTRACT_LE_32BITS(presentp); + + /* Clear state. */ + memset(&state, 0, sizeof(state)); + for (present = EXTRACT_LE_32BITS(presentp); present; present = next_present) { /* clear the least significant bit that is set */ @@ -1190,12 +2241,18 @@ ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen) bit = (enum ieee80211_radiotap_type) (bit0 + BITNO_32(present ^ next_present)); - if (print_radiotap_field(&cpacker, bit, &pad) != 0) + if (print_radiotap_field(&cpacker, bit, &flags, &state, presentflags) != 0) goto out; } } + out: - return len + ieee802_11_print(p + len, length - len, caplen - len, pad); + if (flags & IEEE80211_RADIOTAP_F_DATAPAD) + pad = 1; /* Atheros padding */ + if (flags & IEEE80211_RADIOTAP_F_FCS) + fcslen = 4; /* FCS at end of packet */ + return len + ieee802_11_print(p + len, length - len, caplen - len, pad, + fcslen); #undef BITNO_32 #undef BITNO_16 #undef BITNO_8 @@ -1231,7 +2288,7 @@ ieee802_11_avs_radio_print(const u_char *p, u_int length, u_int caplen) } return caphdr_len + ieee802_11_print(p + caphdr_len, - length - caphdr_len, caplen - caphdr_len, 0); + length - caphdr_len, caplen - caphdr_len, 0, 0); } #define PRISM_HDR_LEN 144 @@ -1276,7 +2333,7 @@ prism_if_print(const struct pcap_pkthdr *h, const u_char *p) } return PRISM_HDR_LEN + ieee802_11_print(p + PRISM_HDR_LEN, - length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN, 0); + length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN, 0, 0); } /* diff --git a/contrib/tcpdump/print-802_15_4.c b/contrib/tcpdump/print-802_15_4.c new file mode 100644 index 0000000000..2016552cea --- /dev/null +++ b/contrib/tcpdump/print-802_15_4.c @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2009 + * Siemens AG, All rights reserved. + * Dmitry Eremin-Solenikov (dbaryshkov@gmail.com) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "addrtoname.h" + +#include "extract.h" + +static const char *ftypes[] = { + "Beacon", /* 0 */ + "Data", /* 1 */ + "ACK", /* 2 */ + "Command", /* 3 */ + "Reserved", /* 4 */ + "Reserved", /* 5 */ + "Reserved", /* 6 */ + "Reserved", /* 7 */ +}; + +static int +extract_header_length(u_int16_t fc) +{ + int len = 0; + + switch ((fc >> 10) & 0x3) { + case 0x00: + if (fc & (1 << 6)) /* intra-PAN with none dest addr */ + return -1; + break; + case 0x01: + return -1; + case 0x02: + len += 4; + break; + case 0x03: + len += 10; + break; + } + + switch ((fc >> 14) & 0x3) { + case 0x00: + break; + case 0x01: + return -1; + case 0x02: + len += 4; + break; + case 0x03: + len += 10; + break; + } + + if (fc & (1 << 6)) { + if (len < 2) + return -1; + len -= 2; + } + + return len; +} + + +u_int +ieee802_15_4_if_print(struct netdissect_options *ndo, + const struct pcap_pkthdr *h, const u_char *p) +{ + u_int caplen = h->caplen; + int hdrlen; + u_int16_t fc; + u_int8_t seq; + + if (caplen < 3) { + ND_PRINT((ndo, "[|802.15.4] %x", caplen)); + return caplen; + } + + fc = EXTRACT_LE_16BITS(p); + hdrlen = extract_header_length(fc); + + seq = EXTRACT_LE_8BITS(p + 2); + + p += 3; + caplen -= 3; + + ND_PRINT((ndo,"IEEE 802.15.4 %s packet ", ftypes[fc & 0x7])); + if (vflag) + ND_PRINT((ndo,"seq %02x ", seq)); + if (hdrlen == -1) { + ND_PRINT((ndo,"malformed! ")); + return caplen; + } + + + if (!vflag) { + p+= hdrlen; + caplen -= hdrlen; + } else { + u_int16_t panid = 0; + + switch ((fc >> 10) & 0x3) { + case 0x00: + ND_PRINT((ndo,"none ")); + break; + case 0x01: + ND_PRINT((ndo,"reserved destination addressing mode")); + return 0; + case 0x02: + panid = EXTRACT_LE_16BITS(p); + p += 2; + ND_PRINT((ndo,"%04x:%04x ", panid, EXTRACT_LE_16BITS(p))); + p += 2; + break; + case 0x03: + panid = EXTRACT_LE_16BITS(p); + p += 2; + ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(p))); + p += 8; + break; + } + ND_PRINT((ndo,"< "); + + switch ((fc >> 14) & 0x3) { + case 0x00: + ND_PRINT((ndo,"none ")); + break; + case 0x01: + ND_PRINT((ndo,"reserved source addressing mode")); + return 0; + case 0x02: + if (!(fc & (1 << 6))) { + panid = EXTRACT_LE_16BITS(p); + p += 2; + } + ND_PRINT((ndo,"%04x:%04x ", panid, EXTRACT_LE_16BITS(p))); + p += 2; + break; + case 0x03: + if (!(fc & (1 << 6))) { + panid = EXTRACT_LE_16BITS(p); + p += 2; + } + ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(p)))); + p += 8; + break; + } + + caplen -= hdrlen; + } + + if (!suppress_default_print) + (ndo->ndo_default_print)(ndo, p, caplen); + + return 0; +} diff --git a/contrib/tcpdump/print-ap1394.c b/contrib/tcpdump/print-ap1394.c index dd9bc5a6c2..ab0713b5a7 100644 --- a/contrib/tcpdump/print-ap1394.c +++ b/contrib/tcpdump/print-ap1394.c @@ -33,6 +33,7 @@ static const char rcsid[] _U_ = #include #include "interface.h" +#include "extract.h" #include "addrtoname.h" #include "ethertype.h" @@ -57,18 +58,21 @@ static inline void ap1394_hdr_print(register const u_char *bp, u_int length) { register const struct firewire_header *fp; + u_int16_t firewire_type; + fp = (const struct firewire_header *)bp; (void)printf("%s > %s", linkaddr_string(fp->firewire_dhost, LINKADDR_IEEE1394, FIREWIRE_EUI64_LEN), linkaddr_string(fp->firewire_shost, LINKADDR_IEEE1394, FIREWIRE_EUI64_LEN)); + firewire_type = EXTRACT_16BITS(&fp->firewire_type); if (!qflag) { (void)printf(", ethertype %s (0x%04x)", - tok2str(ethertype_values,"Unknown", ntohs(fp->firewire_type)), - ntohs(fp->firewire_type)); + tok2str(ethertype_values,"Unknown", firewire_type), + firewire_type); } else { - (void)printf(", %s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", ntohs(fp->firewire_type))); + (void)printf(", %s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", firewire_type)); } (void)printf(", length %u: ", length); @@ -87,7 +91,6 @@ ap1394_if_print(const struct pcap_pkthdr *h, const u_char *p) u_int caplen = h->caplen; struct firewire_header *fp; u_short ether_type; - u_short extracted_ether_type; if (caplen < FIREWIRE_HDRLEN) { printf("[|ap1394]"); @@ -102,11 +105,8 @@ ap1394_if_print(const struct pcap_pkthdr *h, const u_char *p) fp = (struct firewire_header *)p; p += FIREWIRE_HDRLEN; - ether_type = ntohs(fp->firewire_type); - - extracted_ether_type = 0; - if (ether_encap_print(ether_type, p, length, caplen, - &extracted_ether_type) == 0) { + ether_type = EXTRACT_16BITS(&fp->firewire_type); + if (ethertype_print(gndo, ether_type, p, length, caplen) == 0) { /* ether_type not known, print raw packet */ if (!eflag) ap1394_hdr_print((u_char *)fp, length + FIREWIRE_HDRLEN); diff --git a/contrib/tcpdump/print-arcnet.c b/contrib/tcpdump/print-arcnet.c index 48a43030b4..9531f346bf 100644 --- a/contrib/tcpdump/print-arcnet.c +++ b/contrib/tcpdump/print-arcnet.c @@ -35,6 +35,7 @@ static const char rcsid[] _U_ = #include #include "interface.h" +#include "extract.h" #include "arcnet.h" static int arcnet_encap_print(u_char arctype, const u_char *p, @@ -151,11 +152,11 @@ arcnet_if_print(const struct pcap_pkthdr *h, const u_char *p) return (caplen); } flag = ap->arc_flag2; - seqid = ntohs(ap->arc_seqid2); + seqid = EXTRACT_16BITS(&ap->arc_seqid2); archdrlen = ARC_HDRNEWLEN_EXC; } else { flag = ap->arc_flag; - seqid = ntohs(ap->arc_seqid); + seqid = EXTRACT_16BITS(&ap->arc_seqid); archdrlen = ARC_HDRNEWLEN; } } @@ -264,14 +265,14 @@ arcnet_encap_print(u_char arctype, const u_char *p, #ifdef INET6 case ARCTYPE_INET6: - ip6_print(p, length); + ip6_print(gndo, p, length); return (1); #endif /*INET6*/ case ARCTYPE_ARP_OLD: case ARCTYPE_ARP: case ARCTYPE_REVARP: - arp_print(gndo, p, length, caplen); + arp_print(gndo, p, length, caplen); return (1); case ARCTYPE_ATALK: /* XXX was this ever used? */ diff --git a/contrib/tcpdump/print-arp.c b/contrib/tcpdump/print-arp.c index 0ca86cfca0..905ef46560 100644 --- a/contrib/tcpdump/print-arp.c +++ b/contrib/tcpdump/print-arp.c @@ -318,6 +318,7 @@ arp_print(netdissect_options *ndo, return; case ARPHRD_FRELAY: linkaddr = LINKADDR_FRELAY; + break; default: linkaddr = LINKADDR_ETHER; break; diff --git a/contrib/tcpdump/print-atalk.c b/contrib/tcpdump/print-atalk.c index 6ea1361167..0a08ef9daa 100644 --- a/contrib/tcpdump/print-atalk.c +++ b/contrib/tcpdump/print-atalk.c @@ -99,14 +99,10 @@ llap_print(register const u_char *bp, u_int length) u_short snet; u_int hdrlen; - /* - * Our packet is on a 4-byte boundary, as we're either called - * directly from a top-level link-layer printer (ltalk_if_print) - * or from the UDP printer. The LLAP+DDP header is a multiple - * of 4 bytes in length, so the DDP payload is also on a 4-byte - * boundary, and we don't need to align it before calling - * "ddp_print()". - */ + if (length < sizeof(*lp)) { + (void)printf(" [|llap %u]", length); + return (length); + } lp = (const struct LAP *)bp; bp += sizeof(*lp); length -= sizeof(*lp); @@ -115,7 +111,7 @@ llap_print(register const u_char *bp, u_int length) case lapShortDDP: if (length < ddpSSize) { - (void)printf(" [|sddp %d]", length); + (void)printf(" [|sddp %u]", length); return (length); } sdp = (const struct atShortDDP *)bp; @@ -131,7 +127,7 @@ llap_print(register const u_char *bp, u_int length) case lapDDP: if (length < ddpSize) { - (void)printf(" [|ddp %d]", length); + (void)printf(" [|ddp %u]", length); return (length); } dp = (const struct atDDP *)bp; @@ -154,7 +150,7 @@ llap_print(register const u_char *bp, u_int length) #endif default: - printf("%d > %d at-lap#%d %d", + printf("%d > %d at-lap#%d %u", lp->src, lp->dst, lp->type, length); break; } @@ -176,7 +172,7 @@ atalk_print(register const u_char *bp, u_int length) printf("AT "); if (length < ddpSize) { - (void)printf(" [|ddp %d]", length); + (void)printf(" [|ddp %u]", length); return; } dp = (const struct atDDP *)bp; @@ -213,7 +209,7 @@ aarp_print(register const u_char *bp, u_int length) case 2: /* response */ (void)printf("reply %s is-at %s", - AT(pdaddr), etheraddr_string(ap->hdaddr)); + AT(psaddr), etheraddr_string(ap->hsaddr)); return; case 3: /* probe (oy!) */ @@ -265,6 +261,10 @@ atp_print(register const struct atATP *ap, u_int length) fputs(tstr, stdout); return; } + if (length < sizeof(*ap)) { + (void)printf(" [|atp %u]", length); + return; + } length -= sizeof(*ap); switch (ap->control & 0xc0) { @@ -276,7 +276,7 @@ atp_print(register const struct atATP *ap, u_int length) atp_bitmap_print(ap->bitmap); if (length != 0) - (void)printf(" [len=%d]", length); + (void)printf(" [len=%u]", length); switch (ap->control & (atpEOM|atpSTS)) { case atpEOM: @@ -292,7 +292,7 @@ atp_print(register const struct atATP *ap, u_int length) break; case atpRspCode: - (void)printf(" atp-resp%s%d:%d (%d)", + (void)printf(" atp-resp%s%d:%d (%u)", ap->control & atpEOM? "*" : " ", EXTRACT_16BITS(&ap->transID), ap->bitmap, length); switch (ap->control & (atpXO|atpSTS)) { @@ -315,7 +315,7 @@ atp_print(register const struct atATP *ap, u_int length) /* length should be zero */ if (length) - (void)printf(" [len=%d]", length); + (void)printf(" [len=%u]", length); /* there shouldn't be any control flags */ if (ap->control & (atpXO|atpEOM|atpSTS)) { @@ -337,7 +337,7 @@ atp_print(register const struct atATP *ap, u_int length) break; default: - (void)printf(" atp-0x%x %d (%d)", ap->control, + (void)printf(" atp-0x%x %d (%u)", ap->control, EXTRACT_16BITS(&ap->transID), length); break; } @@ -387,14 +387,14 @@ nbp_print(register const struct atNBP *np, u_int length, register u_short snet, const u_char *ep; if (length < nbpHeaderSize) { - (void)printf(" truncated-nbp %d", length); + (void)printf(" truncated-nbp %u", length); return; } length -= nbpHeaderSize; if (length < 8) { /* must be room for at least one tuple */ - (void)printf(" truncated-nbp %d", length + nbpHeaderSize); + (void)printf(" truncated-nbp %u", length + nbpHeaderSize); return; } /* ep points to end of available data */ @@ -439,7 +439,7 @@ nbp_print(register const struct atNBP *np, u_int length, register u_short snet, break; default: - (void)printf(" nbp-0x%x %d (%d)", np->control, np->id, + (void)printf(" nbp-0x%x %d (%u)", np->control, np->id, length); break; } @@ -551,26 +551,24 @@ ataddr_string(u_short atnet, u_char athost) if (first && (first = 0, !nflag) && (fp = fopen("/etc/atalk.names", "r"))) { char line[256]; - int i1, i2, i3; + int i1, i2; while (fgets(line, sizeof(line), fp)) { if (line[0] == '\n' || line[0] == 0 || line[0] == '#') continue; - if (sscanf(line, "%d.%d.%d %256s", &i1, &i2, &i3, - nambuf) == 4) + if (sscanf(line, "%d.%d %256s", &i1, &i2, nambuf) == 3) /* got a hostname. */ - i3 |= ((i1 << 8) | i2) << 8; - else if (sscanf(line, "%d.%d %256s", &i1, &i2, - nambuf) == 3) + i2 |= (i1 << 8); + else if (sscanf(line, "%d %256s", &i1, nambuf) == 2) /* got a net name */ - i3 = (((i1 << 8) | i2) << 8) | 255; + i2 = (i1 << 8) | 255; else continue; - for (tp = &hnametable[i3 & (HASHNAMESIZE-1)]; + for (tp = &hnametable[i2 & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) ; - tp->addr = i3; + tp->addr = i2; tp->nxt = newhnamemem(); tp->name = strdup(nambuf); } @@ -596,11 +594,9 @@ ataddr_string(u_short atnet, u_char athost) tp->addr = (atnet << 8) | athost; tp->nxt = newhnamemem(); if (athost != 255) - (void)snprintf(nambuf, sizeof(nambuf), "%d.%d.%d", - atnet >> 8, atnet & 0xff, athost); + (void)snprintf(nambuf, sizeof(nambuf), "%d.%d", atnet, athost); else - (void)snprintf(nambuf, sizeof(nambuf), "%d.%d", atnet >> 8, - atnet & 0xff); + (void)snprintf(nambuf, sizeof(nambuf), "%d", atnet); tp->name = strdup(nambuf); return (tp->name); diff --git a/contrib/tcpdump/print-atm.c b/contrib/tcpdump/print-atm.c index f50918bfb2..935d182753 100644 --- a/contrib/tcpdump/print-atm.c +++ b/contrib/tcpdump/print-atm.c @@ -20,7 +20,7 @@ */ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-atm.c,v 1.48.2.1 2007-10-22 19:39:12 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-atm.c,v 1.49 2007-10-22 19:37:51 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -270,10 +270,12 @@ sig_print(const u_char *p, int caplen) printf(":%s ", tok2str(msgtype2str, "msgtype#%d", p[MSG_TYPE_POS])); - if (caplen < CALL_REF_POS+3) { - printf("[|atm]"); - return; - } + /* + * The call reference comes before the message type, + * so if we know we have the message type, which we + * do from the caplen test above, we also know we have + * the call reference. + */ call_ref = EXTRACT_24BITS(&p[CALL_REF_POS]); printf("CALL_REF:0x%06x", call_ref); } else { diff --git a/contrib/tcpdump/print-babel.c b/contrib/tcpdump/print-babel.c new file mode 100644 index 0000000000..e787f8b2fc --- /dev/null +++ b/contrib/tcpdump/print-babel.c @@ -0,0 +1,414 @@ +/* + * Copyright (c) 2007-2011 Grégoire Henry, Juliusz Chroboczek + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "addrtoname.h" +#include "interface.h" +#include "extract.h" + +static void babel_print_v2(const u_char *cp, u_int length); + +void +babel_print(const u_char *cp, u_int length) { + printf("babel"); + + TCHECK2(*cp, 4); + + if(cp[0] != 42) { + printf(" malformed header"); + return; + } else { + printf(" %d", cp[1]); + } + + switch(cp[1]) { + case 2: + babel_print_v2(cp,length); + break; + default: + printf(" unknown version"); + break; + } + + return; + + trunc: + printf(" [|babel]"); + return; +} + +#define MESSAGE_PAD1 0 +#define MESSAGE_PADN 1 +#define MESSAGE_ACK_REQ 2 +#define MESSAGE_ACK 3 +#define MESSAGE_HELLO 4 +#define MESSAGE_IHU 5 +#define MESSAGE_ROUTER_ID 6 +#define MESSAGE_NH 7 +#define MESSAGE_UPDATE 8 +#define MESSAGE_REQUEST 9 +#define MESSAGE_MH_REQUEST 10 + +static const char * +format_id(const u_char *id) +{ + static char buf[25]; + snprintf(buf, 25, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7]); + buf[24] = '\0'; + return buf; +} + +static const unsigned char v4prefix[16] = + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 }; + +static const char * +format_prefix(const u_char *prefix, unsigned char plen) +{ + static char buf[50]; + if(plen >= 96 && memcmp(prefix, v4prefix, 12) == 0) + snprintf(buf, 50, "%s/%u", ipaddr_string(prefix + 12), plen - 96); + else + snprintf(buf, 50, "%s/%u", ip6addr_string(prefix), plen); + buf[49] = '\0'; + return buf; +} + +static const char * +format_address(const u_char *prefix) +{ + if(memcmp(prefix, v4prefix, 12) == 0) + return ipaddr_string(prefix + 12); + else + return ip6addr_string(prefix); +} + +static int +network_prefix(int ae, int plen, unsigned int omitted, + const unsigned char *p, const unsigned char *dp, + unsigned int len, unsigned char *p_r) +{ + unsigned pb; + unsigned char prefix[16]; + + if(plen >= 0) + pb = (plen + 7) / 8; + else if(ae == 1) + pb = 4; + else + pb = 16; + + if(pb > 16) + return -1; + + memset(prefix, 0, 16); + + switch(ae) { + case 0: break; + case 1: + if(omitted > 4 || pb > 4 || (pb > omitted && len < pb - omitted)) + return -1; + memcpy(prefix, v4prefix, 12); + if(omitted) { + if (dp == NULL) return -1; + memcpy(prefix, dp, 12 + omitted); + } + if(pb > omitted) memcpy(prefix + 12 + omitted, p, pb - omitted); + break; + case 2: + if(omitted > 16 || (pb > omitted && len < pb - omitted)) + return -1; + if(omitted) { + if (dp == NULL) return -1; + memcpy(prefix, dp, omitted); + } + if(pb > omitted) memcpy(prefix + omitted, p, pb - omitted); + break; + case 3: + if(pb > 8 && len < pb - 8) return -1; + prefix[0] = 0xfe; + prefix[1] = 0x80; + if(pb > 8) memcpy(prefix + 8, p, pb - 8); + break; + default: + return -1; + } + + memcpy(p_r, prefix, 16); + return 1; +} + +static int +network_address(int ae, const unsigned char *a, unsigned int len, + unsigned char *a_r) +{ + return network_prefix(ae, -1, 0, a, NULL, len, a_r); +} + +#define ICHECK(i, l) \ + if ((i) + (l) > bodylen || (i) + (l) > length) goto corrupt; + +static void +babel_print_v2(const u_char *cp, u_int length) { + u_int i; + u_short bodylen; + u_char v4_prefix[16] = + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 }; + u_char v6_prefix[16] = {0}; + + TCHECK2(*cp, 4); + if (length < 4) + goto corrupt; + bodylen = EXTRACT_16BITS(cp + 2); + printf(" (%u)", bodylen); + + /* Process the TLVs in the body */ + i = 0; + while(i < bodylen) { + const u_char *message; + u_char type, len; + + message = cp + 4 + i; + TCHECK2(*message, 2); + ICHECK(i, 2); + type = message[0]; + len = message[1]; + + TCHECK2(*message, 2 + len); + ICHECK(i, 2 + len); + + switch(type) { + case MESSAGE_PAD1: { + if(!vflag) + printf(" pad1"); + else + printf("\n\tPad 1"); + } + break; + + case MESSAGE_PADN: { + if(!vflag) + printf(" padN"); + else + printf("\n\tPad %d", len + 2); + } + break; + + case MESSAGE_ACK_REQ: { + u_short nonce, interval; + if(!vflag) + printf(" ack-req"); + else { + printf("\n\tAcknowledgment Request "); + if(len < 6) goto corrupt; + nonce = EXTRACT_16BITS(message + 4); + interval = EXTRACT_16BITS(message + 6); + printf("%04x %d", nonce, interval); + } + } + break; + + case MESSAGE_ACK: { + u_short nonce; + if(!vflag) + printf(" ack"); + else { + printf("\n\tAcknowledgment "); + if(len < 2) goto corrupt; + nonce = EXTRACT_16BITS(message + 2); + printf("%04x", nonce); + } + } + break; + + case MESSAGE_HELLO: { + u_short seqno, interval; + if(!vflag) + printf(" hello"); + else { + printf("\n\tHello "); + if(len < 6) goto corrupt; + seqno = EXTRACT_16BITS(message + 4); + interval = EXTRACT_16BITS(message + 6); + printf("seqno %u interval %u", seqno, interval); + } + } + break; + + case MESSAGE_IHU: { + unsigned short txcost, interval; + if(!vflag) + printf(" ihu"); + else { + u_char address[16]; + int rc; + printf("\n\tIHU "); + if(len < 6) goto corrupt; + txcost = EXTRACT_16BITS(message + 4); + interval = EXTRACT_16BITS(message + 6); + rc = network_address(message[2], message + 8, len - 6, address); + if(rc < 0) { printf("[|babel]"); break; } + printf("%s txcost %u interval %d", + format_address(address), txcost, interval); + } + } + break; + + case MESSAGE_ROUTER_ID: { + if(!vflag) + printf(" router-id"); + else { + printf("\n\tRouter Id"); + if(len < 10) goto corrupt; + printf(" %s", format_id(message + 4)); + } + } + break; + + case MESSAGE_NH: { + if(!vflag) + printf(" nh"); + else { + int rc; + u_char nh[16]; + printf("\n\tNext Hop"); + if(len < 2) goto corrupt; + rc = network_address(message[2], message + 4, len - 2, nh); + if(rc < 0) goto corrupt; + printf(" %s", format_address(nh)); + } + } + break; + + case MESSAGE_UPDATE: { + if(!vflag) { + printf(" update"); + if(len < 1) + printf("/truncated"); + else + printf("%s%s%s", + (message[3] & 0x80) ? "/prefix": "", + (message[3] & 0x40) ? "/id" : "", + (message[3] & 0x3f) ? "/unknown" : ""); + } else { + u_short interval, seqno, metric; + u_char plen; + int rc; + u_char prefix[16]; + printf("\n\tUpdate"); + if(len < 10) goto corrupt; + plen = message[4] + (message[2] == 1 ? 96 : 0); + rc = network_prefix(message[2], message[4], message[5], + message + 12, + message[2] == 1 ? v4_prefix : v6_prefix, + len - 10, prefix); + if(rc < 0) goto corrupt; + interval = EXTRACT_16BITS(message + 6); + seqno = EXTRACT_16BITS(message + 8); + metric = EXTRACT_16BITS(message + 10); + printf("%s%s%s %s metric %u seqno %u interval %u", + (message[3] & 0x80) ? "/prefix": "", + (message[3] & 0x40) ? "/id" : "", + (message[3] & 0x3f) ? "/unknown" : "", + format_prefix(prefix, plen), + metric, seqno, interval); + if(message[3] & 0x80) { + if(message[2] == 1) + memcpy(v4_prefix, prefix, 16); + else + memcpy(v6_prefix, prefix, 16); + } + } + } + break; + + case MESSAGE_REQUEST: { + if(!vflag) + printf(" request"); + else { + int rc; + u_char prefix[16], plen; + printf("\n\tRequest "); + if(len < 2) goto corrupt; + plen = message[3] + (message[2] == 1 ? 96 : 0); + rc = network_prefix(message[2], message[3], 0, + message + 4, NULL, len - 2, prefix); + if(rc < 0) goto corrupt; + plen = message[3] + (message[2] == 1 ? 96 : 0); + printf("for %s", + message[2] == 0 ? "any" : format_prefix(prefix, plen)); + } + } + break; + + case MESSAGE_MH_REQUEST : { + if(!vflag) + printf(" mh-request"); + else { + int rc; + u_short seqno; + u_char prefix[16], plen; + printf("\n\tMH-Request "); + if(len < 14) goto corrupt; + seqno = EXTRACT_16BITS(message + 4); + rc = network_prefix(message[2], message[3], 0, + message + 16, NULL, len - 14, prefix); + if(rc < 0) goto corrupt; + plen = message[3] + (message[2] == 1 ? 96 : 0); + printf("(%u hops) for %s seqno %u id %s", + message[6], format_prefix(prefix, plen), + seqno, format_id(message + 8)); + } + } + break; + default: + if(!vflag) + printf(" unknown"); + else + printf("\n\tUnknown message type %d", type); + } + i += len + 2; + } + return; + + trunc: + printf(" [|babel]"); + return; + + corrupt: + printf(" (corrupt)"); + return; +} diff --git a/contrib/tcpdump/print-bfd.c b/contrib/tcpdump/print-bfd.c index 6406168b1b..f157684f07 100644 --- a/contrib/tcpdump/print-bfd.c +++ b/contrib/tcpdump/print-bfd.c @@ -171,13 +171,17 @@ bfd_print(register const u_char *pptr, register u_int len, register u_int port) { const struct bfd_header_t *bfd_header; const struct bfd_auth_header_t *bfd_auth_header; - u_int8_t version; + u_int8_t version = 0; bfd_header = (const struct bfd_header_t *)pptr; - TCHECK(*bfd_header); - version = BFD_EXTRACT_VERSION(bfd_header->version_diag); - - switch (port << 8 | version) { + if (port == BFD_CONTROL_PORT) { + TCHECK(*bfd_header); + version = BFD_EXTRACT_VERSION(bfd_header->version_diag); + } else if (port == BFD_ECHO_PORT) { + /* Echo is BFD v1 only */ + version = 1; + } + switch ((port << 8) | version) { /* BFDv0 */ case (BFD_CONTROL_PORT << 8): diff --git a/contrib/tcpdump/print-bgp.c b/contrib/tcpdump/print-bgp.c index 2dfdf52e07..6460a59e0c 100644 --- a/contrib/tcpdump/print-bgp.c +++ b/contrib/tcpdump/print-bgp.c @@ -36,7 +36,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-bgp.c,v 1.117.2.1 2007-12-08 10:08:07 hannes Exp $"; + "@(#) $Header: /tcpdump/master/tcpdump/print-bgp.c,v 1.118 2007-12-07 15:54:52 hannes Exp $"; #endif #include @@ -346,7 +346,8 @@ static struct tok bgp_pmsi_flag_values[] = { #define SAFNUM_MULTICAST_VPN 5 #define SAFNUM_TUNNEL 64 /* XXX */ #define SAFNUM_VPLS 65 /* XXX */ -#define SAFNUM_MDT 66 /* XXX */ +/* draft-nalawade-idr-mdt-safi-03 */ +#define SAFNUM_MDT 66 /* Section 4.3.4 of draft-rosen-rfc2547bis-03.txt */ #define SAFNUM_VPNUNICAST 128 #define SAFNUM_VPNMULTICAST 129 @@ -400,8 +401,11 @@ static struct tok bgp_safi_values[] = { #define BGP_EXT_COM_L2INFO 0x800a /* draft-kompella-ppvpn-l2vpn */ -#define BGP_EXT_COM_SOURCE_AS 0x0009 /* draft-ietf-l3vpn-2547bis-mcast-bgp-02.txt */ -#define BGP_EXT_COM_VRF_RT_IMP 0x010a /* draft-ietf-l3vpn-2547bis-mcast-bgp-02.txt */ +#define BGP_EXT_COM_SOURCE_AS 0x0009 /* RFC-ietf-l3vpn-2547bis-mcast-bgp-08.txt */ +#define BGP_EXT_COM_VRF_RT_IMP 0x010b /* RFC-ietf-l3vpn-2547bis-mcast-bgp-08.txt */ +#define BGP_EXT_COM_L2VPN_RT_0 0x000a /* L2VPN Identifier,Format AS(2bytes):AN(4bytes) */ +#define BGP_EXT_COM_L2VPN_RT_1 0xF10a /* L2VPN Identifier,Format IP address:AN(2bytes) */ + /* http://www.cisco.com/en/US/tech/tk436/tk428/technologies_tech_note09186a00801eb09a.shtml */ #define BGP_EXT_COM_EIGRP_GEN 0x8800 @@ -442,6 +446,8 @@ static struct tok bgp_extd_comm_subtype_values[] = { { BGP_EXT_COM_EIGRP_EXT_REMPROTO_REMMETRIC , "eigrp-external-route (remote-proto, remote-metric)" }, { BGP_EXT_COM_SOURCE_AS, "source-AS" }, { BGP_EXT_COM_VRF_RT_IMP, "vrf-route-import"}, + { BGP_EXT_COM_L2VPN_RT_0, "l2vpn-id"}, + { BGP_EXT_COM_L2VPN_RT_1, "l2vpn-id"}, { 0, NULL}, }; @@ -464,6 +470,29 @@ static struct tok bgp_extd_comm_ospf_rtype_values[] = { { 0, NULL }, }; +#define TOKBUFSIZE 128 +static char astostr[20]; + +/* + * as_printf + * + * Convert an AS number into a string and return string pointer. + * + * Bepending on bflag is set or not, AS number is converted into ASDOT notation + * or plain number notation. + * + */ +static char * +as_printf (char *str, int size, u_int asnum) +{ + if (!bflag || asnum <= 0xFFFF) { + snprintf(str, size, "%u", asnum); + } else { + snprintf(str, size, "%u.%u", asnum >> 16, asnum & 0xFFFF); + } + return str; +} + int decode_prefix4(const u_char *pptr, char *buf, u_int buflen) { @@ -656,9 +685,10 @@ bgp_vpn_rd_print (const u_char *pptr) { /* 4-byte-AS:number fmt*/ case 2: - snprintf(pos, sizeof(rd) - (pos - rd), "%u:%u (%u.%u.%u.%u:%u)", - EXTRACT_32BITS(pptr+2), EXTRACT_16BITS(pptr+6), - *(pptr+2), *(pptr+3), *(pptr+4), *(pptr+5), EXTRACT_16BITS(pptr+6)); + snprintf(pos, sizeof(rd) - (pos - rd), "%s:%u (%u.%u.%u.%u:%u)", + as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(pptr+2)), + EXTRACT_16BITS(pptr+6), *(pptr+2), *(pptr+3), *(pptr+4), + *(pptr+5), EXTRACT_16BITS(pptr+6)); break; default: snprintf(pos, sizeof(rd) - (pos - rd), "unknown RD format"); @@ -696,9 +726,9 @@ decode_rt_routing_info(const u_char *pptr, char *buf, u_int buflen) ((u_char *)&route_target)[(plen + 7) / 8 - 1] &= ((0xff00 >> (plen % 8)) & 0xff); } - snprintf(buf, buflen, "origin AS: %u, route target %s", - EXTRACT_32BITS(pptr+1), - bgp_vpn_rd_print((u_char *)&route_target)); + snprintf(buf, buflen, "origin AS: %s, route target %s", + as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(pptr+1)), + bgp_vpn_rd_print((u_char *)&route_target)); return 5 + (plen + 7) / 8; @@ -744,6 +774,55 @@ trunc: return -2; } +/* + * +-------------------------------+ + * | | + * | RD:IPv4-address (12 octets) | + * | | + * +-------------------------------+ + * | MDT Group-address (4 octets) | + * +-------------------------------+ + */ + +#define MDT_VPN_NLRI_LEN 16 + +static int +decode_mdt_vpn_nlri(const u_char *pptr, char *buf, u_int buflen) +{ + + const u_char *rd; + const u_char *vpn_ip; + + TCHECK(pptr[0]); + + /* if the NLRI is not predefined length, quit.*/ + if (*pptr != MDT_VPN_NLRI_LEN * NBBY) + return -1; + pptr++; + + /* RD */ + TCHECK2(pptr[0], 8); + rd = pptr; + pptr+=8; + + /* IPv4 address */ + TCHECK2(pptr[0], sizeof(struct in_addr)); + vpn_ip = pptr; + pptr+=sizeof(struct in_addr); + + /* MDT Group Address */ + TCHECK2(pptr[0], sizeof(struct in_addr)); + + snprintf(buf, buflen, "RD: %s, VPN IP Address: %s, MC Group Address: %s", + bgp_vpn_rd_print(rd), ipaddr_string(vpn_ip), ipaddr_string(pptr)); + + return MDT_VPN_NLRI_LEN + 1; + + trunc: + +return -2; +} + #define BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI 1 #define BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI 2 #define BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI 3 @@ -789,9 +868,10 @@ decode_multicast_vpn(const u_char *pptr, char *buf, u_int buflen) case BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI: TCHECK2(pptr[0], BGP_VPN_RD_LEN + 4); offset = strlen(buf); - snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %u", - bgp_vpn_rd_print(pptr), - EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN)); + snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s", + bgp_vpn_rd_print(pptr), + as_printf(astostr, sizeof(astostr), + EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN))); break; case BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI: @@ -824,9 +904,10 @@ decode_multicast_vpn(const u_char *pptr, char *buf, u_int buflen) case BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN: TCHECK2(pptr[0], BGP_VPN_RD_LEN); offset = strlen(buf); - snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %u", - bgp_vpn_rd_print(pptr), - EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN)); + snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s", + bgp_vpn_rd_print(pptr), + as_printf(astostr, sizeof(astostr), + EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN))); pptr += BGP_VPN_RD_LEN; bgp_vpn_sg_print(pptr, buf, buflen); @@ -875,57 +956,84 @@ decode_labeled_vpn_l2(const u_char *pptr, char *buf, u_int buflen) plen=EXTRACT_16BITS(pptr); tlen=plen; pptr+=2; - TCHECK2(pptr[0],15); - buf[0]='\0'; - strlen=snprintf(buf, buflen, "RD: %s, CE-ID: %u, Label-Block Offset: %u, Label Base %u", - bgp_vpn_rd_print(pptr), - EXTRACT_16BITS(pptr+8), - EXTRACT_16BITS(pptr+10), - EXTRACT_24BITS(pptr+12)>>4); /* the label is offsetted by 4 bits so lets shift it right */ - UPDATE_BUF_BUFLEN(buf, buflen, strlen); - pptr+=15; - tlen-=15; - - /* ok now the variable part - lets read out TLVs*/ - while (tlen>0) { - if (tlen < 3) - return -1; - TCHECK2(pptr[0], 3); - tlv_type=*pptr++; - tlv_len=EXTRACT_16BITS(pptr); - ttlv_len=tlv_len; - pptr+=2; - - switch(tlv_type) { - case 1: - if (buflen!=0) { - strlen=snprintf(buf,buflen, "\n\t\tcircuit status vector (%u) length: %u: 0x", - tlv_type, - tlv_len); - UPDATE_BUF_BUFLEN(buf, buflen, strlen); - } - ttlv_len=ttlv_len/8+1; /* how many bytes do we need to read ? */ - while (ttlv_len>0) { - TCHECK(pptr[0]); - if (buflen!=0) { - strlen=snprintf(buf,buflen, "%02x",*pptr++); - UPDATE_BUF_BUFLEN(buf, buflen, strlen); - } - ttlv_len--; - } - break; - default: - if (buflen!=0) { - strlen=snprintf(buf,buflen, "\n\t\tunknown TLV #%u, length: %u", - tlv_type, - tlv_len); - UPDATE_BUF_BUFLEN(buf, buflen, strlen); - } - break; - } - tlen-=(tlv_len<<3); /* the tlv-length is expressed in bits so lets shift it right */ + /* Old and new L2VPN NLRI share AFI/SAFI + * -> Assume a 12 Byte-length NLRI is auto-discovery-only + * and > 17 as old format. Complain for the middle case + */ + if (plen==12) { + /* assume AD-only with RD, BGPNH */ + TCHECK2(pptr[0],12); + buf[0]='\0'; + strlen=snprintf(buf, buflen, "RD: %s, BGPNH: %s", + bgp_vpn_rd_print(pptr), + /* need something like getname() here */ + getname(pptr+8) + ); + UPDATE_BUF_BUFLEN(buf, buflen, strlen); + pptr+=12; + tlen-=12; + return plen; + } else if (plen>17) { + /* assume old format */ + /* RD, ID, LBLKOFF, LBLBASE */ + + TCHECK2(pptr[0],15); + buf[0]='\0'; + strlen=snprintf(buf, buflen, "RD: %s, CE-ID: %u, Label-Block Offset: %u, Label Base %u", + bgp_vpn_rd_print(pptr), + EXTRACT_16BITS(pptr+8), + EXTRACT_16BITS(pptr+10), + EXTRACT_24BITS(pptr+12)>>4); /* the label is offsetted by 4 bits so lets shift it right */ + UPDATE_BUF_BUFLEN(buf, buflen, strlen); + pptr+=15; + tlen-=15; + + /* ok now the variable part - lets read out TLVs*/ + while (tlen>0) { + if (tlen < 3) + return -1; + TCHECK2(pptr[0], 3); + tlv_type=*pptr++; + tlv_len=EXTRACT_16BITS(pptr); + ttlv_len=tlv_len; + pptr+=2; + + switch(tlv_type) { + case 1: + if (buflen!=0) { + strlen=snprintf(buf,buflen, "\n\t\tcircuit status vector (%u) length: %u: 0x", + tlv_type, + tlv_len); + UPDATE_BUF_BUFLEN(buf, buflen, strlen); + } + ttlv_len=ttlv_len/8+1; /* how many bytes do we need to read ? */ + while (ttlv_len>0) { + TCHECK(pptr[0]); + if (buflen!=0) { + strlen=snprintf(buf,buflen, "%02x",*pptr++); + UPDATE_BUF_BUFLEN(buf, buflen, strlen); + } + ttlv_len--; + } + break; + default: + if (buflen!=0) { + strlen=snprintf(buf,buflen, "\n\t\tunknown TLV #%u, length: %u", + tlv_type, + tlv_len); + UPDATE_BUF_BUFLEN(buf, buflen, strlen); + } + break; + } + tlen-=(tlv_len<<3); /* the tlv-length is expressed in bits so lets shift it right */ + } + return plen+2; + + } else { + /* complain bitterly ? */ + /* fall through */ + goto trunc; } - return plen+2; trunc: return -2; @@ -1222,9 +1330,11 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) tokbuf, sizeof(tokbuf))); for (i = 0; i < tptr[1] * as_size; i += as_size) { TCHECK2(tptr[2 + i], as_size); - printf("%u ", - as_size == 2 ? EXTRACT_16BITS(&tptr[2 + i]) : - EXTRACT_32BITS(&tptr[2 + i])); + printf("%s ", + as_printf(astostr, sizeof(astostr), + as_size == 2 ? + EXTRACT_16BITS(&tptr[2 + i]) : + EXTRACT_32BITS(&tptr[2 + i]))); } TCHECK(tptr[0]); printf("%s", tok2strbuf(bgp_as_path_segment_close_values, @@ -1255,23 +1365,36 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) if (len != 0) printf("invalid len"); break; - case BGPTYPE_AGGREGATOR: - if (len != 6) { - printf("invalid len"); - break; - } - TCHECK2(tptr[0], 6); - printf(" AS #%u, origin %s", EXTRACT_16BITS(tptr), + case BGPTYPE_AGGREGATOR: + + /* + * Depending on the AS encoded is of 2 bytes or of 4 bytes, + * the length of this PA can be either 6 bytes or 8 bytes. + */ + if (len != 6 && len != 8) { + printf("invalid len"); + break; + } + TCHECK2(tptr[0], len); + if (len == 6) { + printf(" AS #%s, origin %s", + as_printf(astostr, sizeof(astostr), EXTRACT_16BITS(tptr)), getname(tptr + 2)); - break; + } else { + printf(" AS #%s, origin %s", + as_printf(astostr, sizeof(astostr), + EXTRACT_32BITS(tptr)), getname(tptr + 4)); + } + break; case BGPTYPE_AGGREGATOR4: if (len != 8) { printf("invalid len"); break; } TCHECK2(tptr[0], 8); - printf(" AS #%u, origin %s", EXTRACT_32BITS(tptr), - getname(tptr + 4)); + printf(" AS #%s, origin %s", + as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(tptr)), + getname(tptr + 4)); break; case BGPTYPE_COMMUNITIES: if (len % 4) { @@ -1349,6 +1472,7 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST): case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST): case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): + case (AFNUM_INET<<8 | SAFNUM_MDT): #ifdef INET6 case (AFNUM_INET6<<8 | SAFNUM_UNICAST): case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): @@ -1395,7 +1519,8 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO): case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): - if (tlen < (int)sizeof(struct in_addr)) { + case (AFNUM_INET<<8 | SAFNUM_MDT): + if (tlen < (int)sizeof(struct in_addr)) { printf("invalid len"); tlen = 0; } else { @@ -1579,6 +1704,16 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) else printf("\n\t %s", buf); break; + + case (AFNUM_INET<<8 | SAFNUM_MDT): + advance = decode_mdt_vpn_nlri(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; #ifdef INET6 case (AFNUM_INET6<<8 | SAFNUM_UNICAST): case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): @@ -1781,6 +1916,15 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) else printf("\n\t %s", buf); break; + case (AFNUM_INET<<8 | SAFNUM_MDT): + advance = decode_mdt_vpn_nlri(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): /* fall through */ case (AFNUM_INET6<<8 | SAFNUM_MULTICAST_VPN): advance = decode_multicast_vpn(tptr, buf, sizeof(buf)); @@ -1827,6 +1971,7 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) switch(extd_comm) { case BGP_EXT_COM_RT_0: case BGP_EXT_COM_RO_0: + case BGP_EXT_COM_L2VPN_RT_0: printf(": %u:%u (= %s)", EXTRACT_16BITS(tptr+2), EXTRACT_32BITS(tptr+4), @@ -1834,6 +1979,7 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) break; case BGP_EXT_COM_RT_1: case BGP_EXT_COM_RO_1: + case BGP_EXT_COM_L2VPN_RT_1: case BGP_EXT_COM_VRF_RT_IMP: printf(": %s:%u", getname(tptr+2), @@ -1841,10 +1987,10 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) break; case BGP_EXT_COM_RT_2: case BGP_EXT_COM_RO_2: - printf(": %u:%u", - EXTRACT_32BITS(tptr+2), - EXTRACT_16BITS(tptr+6)); - break; + printf(": %s:%u", + as_printf(astostr, sizeof(astostr), + EXTRACT_32BITS(tptr+2)), EXTRACT_16BITS(tptr+6)); + break; case BGP_EXT_COM_LINKBAND: bw.i = EXTRACT_32BITS(tptr+2); printf(": bandwidth: %.3f Mbps", @@ -1951,8 +2097,9 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) } case BGPTYPE_ATTR_SET: TCHECK2(tptr[0], 4); - printf("\n\t Origin AS: %u", EXTRACT_32BITS(tptr)); - tptr+=4; + printf("\n\t Origin AS: %s", + as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(tptr))); + tptr+=4; len -=4; while (len >= 2 ) { @@ -2022,7 +2169,8 @@ bgp_open_print(const u_char *dat, int length) memcpy(&bgpo, dat, BGP_OPEN_SIZE); printf("\n\t Version %d, ", bgpo.bgpo_version); - printf("my AS %u, ", ntohs(bgpo.bgpo_myas)); + printf("my AS %s, ", + as_printf(astostr, sizeof(astostr), ntohs(bgpo.bgpo_myas))); printf("Holdtime %us, ", ntohs(bgpo.bgpo_holdtime)); printf("ID %s", getname((u_char *)&bgpo.bgpo_id)); printf("\n\t Optional parameters, length: %u", bgpo.bgpo_optlen); @@ -2098,6 +2246,18 @@ bgp_open_print(const u_char *dat, int length) case BGP_CAPCODE_RR: case BGP_CAPCODE_RR_CISCO: break; + case BGP_CAPCODE_AS_NEW: + + /* + * Extract the 4 byte AS number encoded. + */ + TCHECK2(opt[i + BGP_OPT_SIZE + 2], cap_len); + if (cap_len == 4) { + printf("\n\t\t 4 Byte AS %s", + as_printf(astostr, sizeof(astostr), + EXTRACT_32BITS(opt + i + BGP_OPT_SIZE + 2))); + } + break; default: TCHECK2(opt[i+BGP_OPT_SIZE+2],cap_len); printf("\n\t\tno decoder for Capability %u", diff --git a/contrib/tcpdump/print-bootp.c b/contrib/tcpdump/print-bootp.c index b442c18388..c7538ff871 100644 --- a/contrib/tcpdump/print-bootp.c +++ b/contrib/tcpdump/print-bootp.c @@ -22,7 +22,7 @@ */ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-bootp.c,v 1.88 2007-09-20 15:04:45 hannes Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-bootp.c,v 1.89 2008-04-22 09:45:08 hannes Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -585,8 +585,6 @@ rfc1048_print(register const u_char *bp) if (len < 1) { printf("ERROR: option %u len %u < 1 bytes", TAG_NETBIOS_NODE, len); - bp += len; - len = 0; break; } tag = *bp++; @@ -599,8 +597,6 @@ rfc1048_print(register const u_char *bp) if (len < 1) { printf("ERROR: option %u len %u < 1 bytes", TAG_OPT_OVERLOAD, len); - bp += len; - len = 0; break; } tag = *bp++; @@ -640,8 +636,6 @@ rfc1048_print(register const u_char *bp) if (len < 1) { printf("ERROR: option %u len %u < 1 bytes", TAG_CLIENT_ID, len); - bp += len; - len = 0; break; } type = *bp++; diff --git a/contrib/tcpdump/print-bt.c b/contrib/tcpdump/print-bt.c new file mode 100644 index 0000000000..259f3e5d9c --- /dev/null +++ b/contrib/tcpdump/print-bt.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2007 + * paolo.abeni@email.it All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by Paolo Abeni.'' + * The name of author may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-bt.c,v 1.2 2008-09-25 21:45:50 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +#if defined(DLT_BLUETOOTH_HCI_H4_WITH_PHDR) && defined(HAVE_PCAP_BLUETOOTH_H) +#include + +#define BT_HDRLEN sizeof(pcap_bluetooth_h4_header) +/* + * This is the top level routine of the printer. 'p' points + * to the bluetooth header of the packet, 'h->ts' is the timestamp, + * 'h->len' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. + */ +u_int +bt_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + u_int length = h->len; + u_int caplen = h->caplen; + const pcap_bluetooth_h4_header* hdr = (const pcap_bluetooth_h4_header*)p; + + if (caplen < BT_HDRLEN) { + printf("[|bt]"); + return (BT_HDRLEN); + } + caplen -= BT_HDRLEN; + length -= BT_HDRLEN; + p += BT_HDRLEN; + if (eflag) + (void)printf("hci length %d, direction %s, ", length, (EXTRACT_32BITS(&hdr->direction)&0x1)?"in":"out"); + + if (!suppress_default_print) + default_print(p, caplen); + + return (BT_HDRLEN); +} +#endif + + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/contrib/tcpdump/print-carp.c b/contrib/tcpdump/print-carp.c new file mode 100644 index 0000000000..ba5be7c621 --- /dev/null +++ b/contrib/tcpdump/print-carp.c @@ -0,0 +1,88 @@ +/* $OpenBSD: print-carp.c,v 1.6 2009/10/27 23:59:55 deraadt Exp $ */ + +/* + * Copyright (c) 2000 William C. Fenner. + * All rights reserved. + * + * Kevin Steves July 2000 + * Modified to: + * - print version, type string and packet length + * - print IP address count if > 1 (-v) + * - verify checksum (-v) + * - print authentication string (-v) + * + * Copyright (c) 2011 Advanced Computing Technologies + * George V. Neille-Neil + * + * Modified to: + * - work correctly with CARP + * - compile into the latest tcpdump + * - print out the counter + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * The name of William C. Fenner may not be used to endorse or + * promote products derived from this software without specific prior + * written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +void +carp_print(register const u_char *bp, register u_int len, int ttl) +{ + int version, type; + const char *type_s; + + TCHECK(bp[0]); + version = (bp[0] & 0xf0) >> 4; + type = bp[0] & 0x0f; + if (type == 1) + type_s = "advertise"; + else + type_s = "unknown"; + printf("CARPv%d-%s %d: ", version, type_s, len); + if (ttl != 255) + printf("[ttl=%d!] ", ttl); + if (version != 2 || type != 1) + return; + TCHECK(bp[2]); + TCHECK(bp[5]); + printf("vhid=%d advbase=%d advskew=%d authlen=%d ", + bp[1], bp[5], bp[2], bp[3]); + if (vflag) { + struct cksum_vec vec[1]; + vec[0].ptr = (const u_int8_t *)bp; + vec[0].len = len; + if (TTEST2(bp[0], len) && in_cksum(vec, 1)) + printf(" (bad carp cksum %x!)", + EXTRACT_16BITS(&bp[6])); + } + printf("counter=%" PRIu64, EXTRACT_64BITS(&bp[8])); + + return; +trunc: + printf("[|carp]"); +} diff --git a/contrib/tcpdump/print-cdp.c b/contrib/tcpdump/print-cdp.c index f8f4427c04..7bc617a963 100644 --- a/contrib/tcpdump/print-cdp.c +++ b/contrib/tcpdump/print-cdp.c @@ -124,22 +124,25 @@ cdp_print(const u_char *pptr, u_int length, u_int caplen) tok2str(cdp_tlv_values,"unknown field type", type), type, len, - len>1 ? "s" : ""); /* plural */ + PLURAL_SUFFIX(len)); /* plural */ switch (type) { case 0x01: /* Device-ID */ if (!vflag) - printf(", Device-ID '%.*s'", len, tptr); - else - printf("'%.*s'", len, tptr); + printf(", Device-ID "); + printf("'"); + fn_printn(tptr, len, NULL); + printf("'"); break; case 0x02: /* Address */ if (cdp_print_addr(tptr, len) < 0) goto trunc; break; case 0x03: /* Port-ID */ - printf("'%.*s'", len, tptr); + printf("'"); + fn_printn(tptr, len, NULL); + printf("'"); break; case 0x04: /* Capabilities */ printf("(0x%08x): %s", @@ -156,7 +159,9 @@ cdp_print(const u_char *pptr, u_int length, u_int caplen) } break; case 0x06: /* Platform */ - printf("'%.*s'", len, tptr); + printf("'"); + fn_printn(tptr, len, NULL); + printf("'"); break; case 0x07: /* Prefixes */ if (cdp_print_prefixes(tptr, len) < 0) @@ -165,7 +170,9 @@ cdp_print(const u_char *pptr, u_int length, u_int caplen) case 0x08: /* Protocol Hello Option - not documented */ break; case 0x09: /* VTP Mgmt Domain - not documented */ - printf("'%.*s'", len,tptr); + printf("'"); + fn_printn(tptr, len, NULL); + printf("'"); break; case 0x0a: /* Native VLAN ID - not documented */ printf("%d",EXTRACT_16BITS(tptr)); @@ -195,14 +202,20 @@ cdp_print(const u_char *pptr, u_int length, u_int caplen) printf("0x%02x", *(tptr)); break; case 0x14: /* System Name - not documented */ - printf("'%.*s'", len, tptr); + printf("'"); + fn_printn(tptr, len, NULL); + printf("'"); break; case 0x16: /* System Object ID - not documented */ if (cdp_print_addr(tptr, len) < 0) goto trunc; break; case 0x17: /* Physical Location - not documented */ - printf("0x%02x/%.*s", *(tptr), len - 1, tptr + 1 ); + printf("0x%02x", *(tptr)); + if (len > 1) { + printf("/"); + fn_printn(tptr + 1, len - 1, NULL); + } break; default: print_unknown_data(tptr,"\n\t ",len); diff --git a/contrib/tcpdump/print-cfm.c b/contrib/tcpdump/print-cfm.c index bd98dd26d2..fb0476f558 100644 --- a/contrib/tcpdump/print-cfm.c +++ b/contrib/tcpdump/print-cfm.c @@ -423,6 +423,8 @@ cfm_print(register const u_char *pptr, register u_int length) { break; case CFM_OPCODE_LTM: + msg_ptr.cfm_ltm = (const struct cfm_ltm_t *)tptr; + printf(", Flags [%s]", bittok2str(cfm_ltm_flag_values, "none", cfm_common_header->flags)); @@ -437,6 +439,8 @@ cfm_print(register const u_char *pptr, register u_int length) { break; case CFM_OPCODE_LTR: + msg_ptr.cfm_ltr = (const struct cfm_ltr_t *)tptr; + printf(", Flags [%s]", bittok2str(cfm_ltr_flag_values, "none", cfm_common_header->flags)); diff --git a/contrib/tcpdump/print-chdlc.c b/contrib/tcpdump/print-chdlc.c index 238e91a98c..261b15ad7e 100644 --- a/contrib/tcpdump/print-chdlc.c +++ b/contrib/tcpdump/print-chdlc.c @@ -85,7 +85,7 @@ chdlc_print(register const u_char *p, u_int length) { break; #ifdef INET6 case ETHERTYPE_IPV6: - ip6_print(p, length); + ip6_print(gndo, p, length); break; #endif case CHDLC_TYPE_SLARP: diff --git a/contrib/tcpdump/print-dccp.c b/contrib/tcpdump/print-dccp.c index b7377cf915..79ea5f72ee 100644 --- a/contrib/tcpdump/print-dccp.c +++ b/contrib/tcpdump/print-dccp.c @@ -9,7 +9,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-dccp.c,v 1.7.2.1 2007-11-09 00:45:16 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-dccp.c,v 1.8 2007-11-09 00:44:09 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -60,7 +60,7 @@ static const char *dccp_feature_nums[] = { "check data checksum", }; -static inline int dccp_csum_coverage(const struct dccp_hdr* dh, u_int len) +static inline u_int dccp_csum_coverage(const struct dccp_hdr* dh, u_int len) { u_int cov; @@ -73,61 +73,15 @@ static inline int dccp_csum_coverage(const struct dccp_hdr* dh, u_int len) static int dccp_cksum(const struct ip *ip, const struct dccp_hdr *dh, u_int len) { - int cov = dccp_csum_coverage(dh, 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, cov, sp[0]+sp[1]+sp[2]+sp[3]+sp[4]+sp[5]); + return nextproto4_cksum(ip, (const u_int8_t *)(void *)dh, + dccp_csum_coverage(dh, len), IPPROTO_DCCP); } #ifdef INET6 static int dccp6_cksum(const struct ip6_hdr *ip6, const struct dccp_hdr *dh, u_int len) { - size_t i; - u_int32_t sum = 0; - int cov = dccp_csum_coverage(dh, len); - 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; - - for (i = 0; i < sizeof(phu.pa) / sizeof(phu.pa[0]); i++) - sum += phu.pa[i]; - - return in_cksum((u_short *)dh, cov, sum); + return nextproto6_cksum(ip6, (const u_int8_t *)(void *)dh, + dccp_csum_coverage(dh, len), IPPROTO_DCCP); } #endif @@ -394,9 +348,6 @@ trunc2: 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); @@ -470,22 +421,17 @@ static int dccp_print_option(const u_char *option) 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)); + printf("timestamp %u", EXTRACT_32BITS(option + 2)); break; case 42: - ts = (u_int32_t *)(option + 2); - printf("timestamp_echo %u", (u_int32_t)ntohl(*ts)); + printf("timestamp_echo %u", EXTRACT_32BITS(option + 2)); 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)); - } + if (optlen == 6) + printf("%u", EXTRACT_32BITS(option + 2)); + else + printf("%u", EXTRACT_16BITS(option + 2)); break; case 44: printf("data_checksum "); @@ -496,12 +442,10 @@ static int dccp_print_option(const u_char *option) printf("CCID option %d",*option); switch (optlen) { case 4: - var16 = (u_int16_t *)(option + 2); - printf(" %u",ntohs(*var16)); + printf(" %u", EXTRACT_16BITS(option + 2)); break; case 6: - var32 = (u_int32_t *)(option + 2); - printf(" %u",(u_int32_t)ntohl(*var32)); + printf(" %u", EXTRACT_32BITS(option + 2)); break; default: break; diff --git a/contrib/tcpdump/print-dhcp6.c b/contrib/tcpdump/print-dhcp6.c index ec0df763c0..a75da82381 100644 --- a/contrib/tcpdump/print-dhcp6.c +++ b/contrib/tcpdump/print-dhcp6.c @@ -40,7 +40,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-dhcp6.c,v 1.36.2.1 2008-02-06 10:26:27 guy Exp $"; + "@(#) $Header: /tcpdump/master/tcpdump/print-dhcp6.c,v 1.37 2008-02-06 10:26:09 guy Exp $"; #endif #ifdef HAVE_CONFIG_H @@ -177,54 +177,19 @@ struct dhcp6opt { /* type-dependent data follows */ }; -struct dhcp6_ia { - u_int16_t dh6opt_ia_type; - u_int16_t dh6opt_ia_len; - u_int32_t dh6opt_ia_iaid; - u_int32_t dh6opt_ia_t1; - u_int32_t dh6opt_ia_t2; -}; - -struct dhcp6_ia_addr { - u_int16_t dh6opt_ia_addr_type; - u_int16_t dh6opt_ia_addr_len; - struct in6_addr dh6opt_ia_addr_addr; - u_int32_t dh6opt_ia_addr_pltime; - u_int32_t dh6opt_ia_addr_vltime; -} __attribute__ ((__packed__)); - -struct dhcp6_ia_prefix { - u_int16_t dh6opt_ia_prefix_type; - u_int16_t dh6opt_ia_prefix_len; - u_int32_t dh6opt_ia_prefix_pltime; - u_int32_t dh6opt_ia_prefix_vltime; - u_int8_t dh6opt_ia_prefix_plen; - struct in6_addr dh6opt_ia_prefix_addr; -} __attribute__ ((__packed__)); - -struct dhcp6_auth { - u_int16_t dh6opt_auth_type; - u_int16_t dh6opt_auth_len; - u_int8_t dh6opt_auth_proto; - u_int8_t dh6opt_auth_alg; - u_int8_t dh6opt_auth_rdm; - u_int8_t dh6opt_auth_rdinfo[8]; - /* authentication information follows */ -} __attribute__ ((__packed__)); - static const char * dhcp6opt_name(int type) { static char genstr[sizeof("opt_65535") + 1]; /* XXX thread unsafe */ if (type > 65535) - return "INVALID option"; + return "INVALID-option"; switch(type) { case DH6OPT_CLIENTID: - return "client ID"; + return "client-ID"; case DH6OPT_SERVERID: - return "server ID"; + return "server-ID"; case DH6OPT_IA_NA: return "IA_NA"; case DH6OPT_IA_TA: @@ -232,87 +197,87 @@ dhcp6opt_name(int type) case DH6OPT_IA_ADDR: return "IA_ADDR"; case DH6OPT_ORO: - return "option request"; + return "option-request"; case DH6OPT_PREFERENCE: return "preference"; case DH6OPT_ELAPSED_TIME: - return "elapsed time"; + return "elapsed-time"; case DH6OPT_RELAY_MSG: - return "relay message"; + return "relay-message"; case DH6OPT_AUTH: return "authentication"; case DH6OPT_UNICAST: - return "server unicast"; + return "server-unicast"; case DH6OPT_STATUS_CODE: - return "status code"; + return "status-code"; case DH6OPT_RAPID_COMMIT: - return "rapid commit"; + return "rapid-commit"; case DH6OPT_USER_CLASS: - return "user class"; + return "user-class"; case DH6OPT_VENDOR_CLASS: - return "vendor class"; + return "vendor-class"; case DH6OPT_VENDOR_OPTS: - return "vendor-specific info"; + return "vendor-specific-info"; case DH6OPT_INTERFACE_ID: - return "interface ID"; + return "interface-ID"; case DH6OPT_RECONF_MSG: - return "reconfigure message"; + return "reconfigure-message"; case DH6OPT_RECONF_ACCEPT: - return "reconfigure accept"; + return "reconfigure-accept"; case DH6OPT_SIP_SERVER_D: - return "SIP servers domain"; + return "SIP-servers-domain"; case DH6OPT_SIP_SERVER_A: - return "SIP servers address"; + return "SIP-servers-address"; case DH6OPT_DNS: - return "DNS"; + return "DNS-server"; case DH6OPT_DNSNAME: - return "DNS name"; + return "DNS-search-list"; case DH6OPT_IA_PD: return "IA_PD"; case DH6OPT_IA_PD_PREFIX: - return "IA_PD prefix"; + return "IA_PD-prefix"; case DH6OPT_NTP_SERVERS: - return "NTP Server"; + return "NTP-server"; case DH6OPT_LIFETIME: return "lifetime"; case DH6OPT_NIS_SERVERS: - return "NIS server"; + return "NIS-server"; case DH6OPT_NISP_SERVERS: - return "NIS+ server"; + return "NIS+-server"; case DH6OPT_NIS_NAME: - return "NIS domain name"; + return "NIS-domain-name"; case DH6OPT_NISP_NAME: - return "NIS+ domain name"; + return "NIS+-domain-name"; case DH6OPT_BCMCS_SERVER_D: - return "BCMCS domain name"; + return "BCMCS-domain-name"; case DH6OPT_BCMCS_SERVER_A: - return "BCMCS server"; + return "BCMCS-server"; case DH6OPT_GEOCONF_CIVIC: - return "Geoconf Civic"; + return "Geoconf-Civic"; case DH6OPT_REMOTE_ID: - return "Remote ID"; + return "Remote-ID"; case DH6OPT_SUBSCRIBER_ID: - return "Subscriber ID"; + return "Subscriber-ID"; case DH6OPT_CLIENT_FQDN: - return "Client FQDN"; + return "Client-FQDN"; case DH6OPT_PANA_AGENT: - return "PANA agent"; + return "PANA-agent"; case DH6OPT_NEW_POSIX_TIMEZONE: - return "POSIX timezone"; + return "POSIX-timezone"; case DH6OPT_NEW_TZDB_TIMEZONE: - return "POSIX tz database"; + return "POSIX-tz-database"; case DH6OPT_ERO: - return "Echo request option"; + return "Echo-request-option"; case DH6OPT_LQ_QUERY: - return "Lease query"; + return "Lease-query"; case DH6OPT_CLIENT_DATA: - return "LQ client data"; + return "LQ-client-data"; case DH6OPT_CLT_TIME: - return "Clt time"; + return "Clt-time"; case DH6OPT_LQ_RELAY_DATA: - return "LQ relay data"; + return "LQ-relay-data"; case DH6OPT_LQ_CLIENT_LINK: - return "LQ client link"; + return "LQ-client-link"; default: snprintf(genstr, sizeof(genstr), "opt_%d", type); return(genstr); @@ -364,12 +329,7 @@ dhcp6opt_print(const u_char *cp, const u_char *ep) size_t i; u_int16_t opttype; size_t optlen; - u_int16_t val16; - u_int32_t val32; - struct dhcp6_ia ia; - struct dhcp6_ia_prefix ia_prefix; - struct dhcp6_ia_addr ia_addr; - struct dhcp6_auth authopt; + u_int8_t auth_proto; u_int authinfolen, authrealmlen; if (cp == ep) @@ -438,25 +398,19 @@ dhcp6opt_print(const u_char *cp, const u_char *ep) } break; case DH6OPT_IA_ADDR: - if (optlen < sizeof(ia_addr) - 4) { + if (optlen < 24) { + /*(*/ printf(" ?)"); break; } - memcpy(&ia_addr, (u_char *)dh6o, sizeof(ia_addr)); - printf(" %s", - ip6addr_string(&ia_addr.dh6opt_ia_addr_addr)); - ia_addr.dh6opt_ia_addr_pltime = - ntohl(ia_addr.dh6opt_ia_addr_pltime); - ia_addr.dh6opt_ia_addr_vltime = - ntohl(ia_addr.dh6opt_ia_addr_vltime); - printf(" pltime:%lu vltime:%lu", - (unsigned long)ia_addr.dh6opt_ia_addr_pltime, - (unsigned long)ia_addr.dh6opt_ia_addr_vltime); - if (optlen > sizeof(ia_addr) - 4) { + tp = (u_char *)(dh6o + 1); + printf(" %s", ip6addr_string(&tp[0])); + printf(" pltime:%u vltime:%u", + EXTRACT_32BITS(&tp[16]), + EXTRACT_32BITS(&tp[20])); + if (optlen > 24) { /* there are sub-options */ - dhcp6opt_print((u_char *)dh6o + - sizeof(ia_addr), - (u_char *)(dh6o + 1) + optlen); + dhcp6opt_print(tp + 24, tp + 24 + optlen); } printf(")"); break; @@ -468,10 +422,8 @@ dhcp6opt_print(const u_char *cp, const u_char *ep) } tp = (u_char *)(dh6o + 1); for (i = 0; i < optlen; i += 2) { - u_int16_t opt; - - memcpy(&opt, &tp[i], sizeof(opt)); - printf(" %s", dhcp6opt_name(ntohs(opt))); + printf(" %s", + dhcp6opt_name(EXTRACT_16BITS(&tp[i]))); } printf(")"); break; @@ -480,29 +432,31 @@ dhcp6opt_print(const u_char *cp, const u_char *ep) printf(" ?)"); break; } - printf(" %d)", *((u_char *)(dh6o + 1) + 1)); + tp = (u_char *)(dh6o + 1); + printf(" %d)", *tp); break; case DH6OPT_ELAPSED_TIME: if (optlen != 2) { printf(" ?)"); break; } - memcpy(&val16, dh6o + 1, sizeof(val16)); - val16 = ntohs(val16); - printf(" %d)", (int)val16); + tp = (u_char *)(dh6o + 1); + printf(" %d)", EXTRACT_16BITS(tp)); break; case DH6OPT_RELAY_MSG: printf(" ("); - dhcp6_print((const u_char *)(dh6o + 1), optlen); + tp = (u_char *)(dh6o + 1); + dhcp6_print(tp, optlen); printf(")"); break; case DH6OPT_AUTH: - if (optlen < sizeof(authopt) - sizeof(*dh6o)) { + if (optlen < 11) { printf(" ?)"); break; } - memcpy(&authopt, dh6o, sizeof(authopt)); - switch (authopt.dh6opt_auth_proto) { + tp = (u_char *)(dh6o + 1); + auth_proto = *tp; + switch (auth_proto) { case DH6OPT_AUTHPROTO_DELAYED: printf(" proto: delayed"); break; @@ -510,37 +464,36 @@ dhcp6opt_print(const u_char *cp, const u_char *ep) printf(" proto: reconfigure"); break; default: - printf(" proto: %d", - authopt.dh6opt_auth_proto); + printf(" proto: %d", auth_proto); break; } - switch (authopt.dh6opt_auth_alg) { + tp++; + switch (*tp) { case DH6OPT_AUTHALG_HMACMD5: /* XXX: may depend on the protocol */ printf(", alg: HMAC-MD5"); break; default: - printf(", alg: %d", authopt.dh6opt_auth_alg); + printf(", alg: %d", *tp); break; } - switch (authopt.dh6opt_auth_rdm) { + tp++; + switch (*tp) { case DH6OPT_AUTHRDM_MONOCOUNTER: printf(", RDM: mono"); break; default: - printf(", RDM: %d", authopt.dh6opt_auth_rdm); + printf(", RDM: %d", *tp); break; } - tp = (u_char *)&authopt.dh6opt_auth_rdinfo; + tp++; printf(", RD:"); - for (i = 0; i < 4; i++, tp += sizeof(val16)) + for (i = 0; i < 4; i++, tp += 2) printf(" %04x", EXTRACT_16BITS(tp)); /* protocol dependent part */ - tp = (u_char *)dh6o + sizeof(authopt); - authinfolen = - optlen + sizeof(*dh6o) - sizeof(authopt); - switch (authopt.dh6opt_auth_proto) { + authinfolen = optlen - 11; + switch (auth_proto) { case DH6OPT_AUTHPROTO_DELAYED: if (authinfolen == 0) break; @@ -596,9 +549,10 @@ dhcp6opt_print(const u_char *cp, const u_char *ep) * Since we cannot predict the encoding, print hex dump * at most 10 characters. */ + tp = (u_char *)(dh6o + 1); printf(" "); for (i = 0; i < optlen && i < 10; i++) - printf("%02x", ((u_char *)(dh6o + 1))[i]); + printf("%02x", tp[i]); printf("...)"); break; case DH6OPT_RECONF_MSG: @@ -640,28 +594,23 @@ dhcp6opt_print(const u_char *cp, const u_char *ep) printf(" ?)"); break; } - memcpy(&val16, (u_char *)(dh6o + 1), sizeof(val16)); - val16 = ntohs(val16); - printf(" %s)", dhcp6stcode(val16)); + tp = (u_char *)(dh6o + 1); + printf(" %s)", dhcp6stcode(EXTRACT_16BITS(&tp[0]))); break; case DH6OPT_IA_NA: case DH6OPT_IA_PD: - if (optlen < sizeof(ia) - 4) { + if (optlen < 12) { printf(" ?)"); break; } - memcpy(&ia, (u_char *)dh6o, sizeof(ia)); - ia.dh6opt_ia_iaid = ntohl(ia.dh6opt_ia_iaid); - ia.dh6opt_ia_t1 = ntohl(ia.dh6opt_ia_t1); - ia.dh6opt_ia_t2 = ntohl(ia.dh6opt_ia_t2); - printf(" IAID:%lu T1:%lu T2:%lu", - (unsigned long)ia.dh6opt_ia_iaid, - (unsigned long)ia.dh6opt_ia_t1, - (unsigned long)ia.dh6opt_ia_t2); - if (optlen > sizeof(ia) - 4) { + tp = (u_char *)(dh6o + 1); + printf(" IAID:%u T1:%u T2:%u", + EXTRACT_32BITS(&tp[0]), + EXTRACT_32BITS(&tp[4]), + EXTRACT_32BITS(&tp[8])); + if (optlen > 12) { /* there are sub-options */ - dhcp6opt_print((u_char *)dh6o + sizeof(ia), - (u_char *)(dh6o + 1) + optlen); + dhcp6opt_print(tp + 12, tp + 12 + optlen); } printf(")"); break; @@ -670,37 +619,27 @@ dhcp6opt_print(const u_char *cp, const u_char *ep) printf(" ?)"); break; } - memcpy(&val32, dh6o + 1, sizeof(val32)); - val32 = ntohl(val32); - printf(" IAID:%lu", (unsigned long)val32); + tp = (u_char *)(dh6o + 1); + printf(" IAID:%u", EXTRACT_32BITS(tp)); if (optlen > 4) { /* there are sub-options */ - dhcp6opt_print((u_char *)(dh6o + 1) + 4, - (u_char *)(dh6o + 1) + optlen); + dhcp6opt_print(tp + 4, tp + 4 + optlen); } printf(")"); break; case DH6OPT_IA_PD_PREFIX: - if (optlen < sizeof(ia_prefix) - 4) { + if (optlen < 25) { printf(" ?)"); break; } - memcpy(&ia_prefix, (u_char *)dh6o, sizeof(ia_prefix)); - printf(" %s/%d", - ip6addr_string(&ia_prefix.dh6opt_ia_prefix_addr), - ia_prefix.dh6opt_ia_prefix_plen); - ia_prefix.dh6opt_ia_prefix_pltime = - ntohl(ia_prefix.dh6opt_ia_prefix_pltime); - ia_prefix.dh6opt_ia_prefix_vltime = - ntohl(ia_prefix.dh6opt_ia_prefix_vltime); - printf(" pltime:%lu vltime:%lu", - (unsigned long)ia_prefix.dh6opt_ia_prefix_pltime, - (unsigned long)ia_prefix.dh6opt_ia_prefix_vltime); - if (optlen > sizeof(ia_prefix) - 4) { + tp = (u_char *)(dh6o + 1); + printf(" %s/%d", ip6addr_string(&tp[9]), tp[8]); + printf(" pltime:%u vltime:%u", + EXTRACT_32BITS(&tp[0]), + EXTRACT_32BITS(&tp[4])); + if (optlen > 25) { /* there are sub-options */ - dhcp6opt_print((u_char *)dh6o + - sizeof(ia_prefix), - (u_char *)(dh6o + 1) + optlen); + dhcp6opt_print(tp + 25, tp + 25 + optlen); } printf(")"); break; @@ -710,9 +649,8 @@ dhcp6opt_print(const u_char *cp, const u_char *ep) printf(" ?)"); break; } - memcpy(&val32, dh6o + 1, sizeof(val32)); - val32 = ntohl(val32); - printf(" %d)", (int)val32); + tp = (u_char *)(dh6o + 1); + printf(" %d)", EXTRACT_32BITS(tp)); break; case DH6OPT_REMOTE_ID: if (optlen < 4) { @@ -720,9 +658,7 @@ dhcp6opt_print(const u_char *cp, const u_char *ep) break; } tp = (u_char *)(dh6o + 1); - memcpy(&val32, &tp[0], sizeof(val32)); - val32 = ntohl(val32); - printf(" %d ", (int)val32); + printf(" %d ", EXTRACT_32BITS(tp)); /* * Print hex dump first 10 characters. */ @@ -755,10 +691,10 @@ dhcp6opt_print(const u_char *cp, const u_char *ep) printf(")"); break; case DH6OPT_CLIENT_DATA: + tp = (u_char *)(dh6o + 1); if (optlen > 0) { /* there are encapsulated options */ - dhcp6opt_print((u_char *)(dh6o + 1), - (u_char *)(dh6o + 1) + optlen); + dhcp6opt_print(tp, tp + optlen); } printf(")"); break; diff --git a/contrib/tcpdump/print-domain.c b/contrib/tcpdump/print-domain.c index 80b4b33d3d..43e8f41df4 100644 --- a/contrib/tcpdump/print-domain.c +++ b/contrib/tcpdump/print-domain.c @@ -21,7 +21,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-domain.c,v 1.97.2.1 2007-12-09 01:51:12 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-domain.c,v 1.98 2007-12-09 01:40:32 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H diff --git a/contrib/tcpdump/print-eigrp.c b/contrib/tcpdump/print-eigrp.c index 2787bafb9d..4f941d9662 100644 --- a/contrib/tcpdump/print-eigrp.c +++ b/contrib/tcpdump/print-eigrp.c @@ -280,7 +280,7 @@ eigrp_print(register const u_char *pptr, register u_int len) { if (eigrp_tlv_len < sizeof(struct eigrp_tlv_header) || eigrp_tlv_len > tlen) { - print_unknown_data(tptr+sizeof(sizeof(struct eigrp_tlv_header)),"\n\t ",tlen); + print_unknown_data(tptr+sizeof(struct eigrp_tlv_header),"\n\t ",tlen); return; } @@ -468,7 +468,7 @@ eigrp_print(register const u_char *pptr, register u_int len) { } /* do we want to see an additionally hexdump ? */ if (vflag > 1) - print_unknown_data(tptr+sizeof(sizeof(struct eigrp_tlv_header)),"\n\t ", + print_unknown_data(tptr+sizeof(struct eigrp_tlv_header),"\n\t ", eigrp_tlv_len-sizeof(struct eigrp_tlv_header)); tptr+=eigrp_tlv_len; diff --git a/contrib/tcpdump/print-enc.c b/contrib/tcpdump/print-enc.c index 9569534cbd..5c01f3ef7b 100644 --- a/contrib/tcpdump/print-enc.c +++ b/contrib/tcpdump/print-enc.c @@ -23,7 +23,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-enc.c,v 1.4.4.1 2008-02-06 10:34:15 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-enc.c,v 1.6 2008-11-18 07:35:32 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -35,6 +35,7 @@ static const char rcsid[] _U_ = #include #include "interface.h" +#include "extract.h" #include "addrtoname.h" #include "enc.h" @@ -67,7 +68,7 @@ enc_if_print(const struct pcap_pkthdr *h, register const u_char *p) ENC_PRINT_TYPE(flags, M_AUTH, "authentic"); ENC_PRINT_TYPE(flags, M_CONF, "confidential"); /* ENC_PRINT_TYPE(flags, M_TUNNEL, "tunnel"); */ - printf("SPI 0x%08x: ", (u_int32_t)ntohl(hdr->spi)); + printf("SPI 0x%08x: ", EXTRACT_32BITS(&hdr->spi)); length -= ENC_HDRLEN; caplen -= ENC_HDRLEN; @@ -77,9 +78,11 @@ enc_if_print(const struct pcap_pkthdr *h, register const u_char *p) case AF_INET: ip_print(gndo, p, length); break; +#ifdef INET6 case AF_INET6: - ip6_print(p, length); + ip6_print(gndo, p, length); break; +#endif /*INET6*/ } out: diff --git a/contrib/tcpdump/print-esp.c b/contrib/tcpdump/print-esp.c index 260fe8710e..ade654a337 100644 --- a/contrib/tcpdump/print-esp.c +++ b/contrib/tcpdump/print-esp.c @@ -23,7 +23,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-esp.c,v 1.56 2005-04-21 06:44:40 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-esp.c,v 1.58 2007-12-07 00:03:07 mcr Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -71,14 +71,72 @@ struct sockaddr_storage { struct sa_list { struct sa_list *next; struct sockaddr_storage daddr; - u_int32_t spi; + u_int32_t spi; /* if == 0, then IKEv2 */ + int initiator; + u_char spii[8]; /* for IKEv2 */ + u_char spir[8]; const EVP_CIPHER *evp; int ivlen; int authlen; + u_char authsecret[256]; + int authsecret_len; u_char secret[256]; /* is that big enough for all secrets? */ int secretlen; }; +/* + * this will adjust ndo_packetp and ndo_snapend to new buffer! + */ +int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo, + int initiator, + u_char spii[8], u_char spir[8], + u_char *buf, u_char *end) +{ + struct sa_list *sa; + u_char *iv; + int len; + EVP_CIPHER_CTX ctx; + + /* initiator arg is any non-zero value */ + if(initiator) initiator=1; + + /* see if we can find the SA, and if so, decode it */ + for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) { + if (sa->spi == 0 + && initiator == sa->initiator + && memcmp(spii, sa->spii, 8) == 0 + && memcmp(spir, sa->spir, 8) == 0) + break; + } + + if(sa == NULL) return 0; + if(sa->evp == NULL) return 0; + + /* + * remove authenticator, and see if we still have something to + * work with + */ + end = end - sa->authlen; + iv = buf; + buf = buf + sa->ivlen; + len = end-buf; + + if(end <= buf) return 0; + + memset(&ctx, 0, sizeof(ctx)); + if (EVP_CipherInit(&ctx, sa->evp, sa->secret, NULL, 0) < 0) + (*ndo->ndo_warning)(ndo, "espkey init failed"); + EVP_CipherInit(&ctx, NULL, NULL, iv, 0); + EVP_Cipher(&ctx, buf, buf, len); + EVP_CIPHER_CTX_cleanup(&ctx); + + ndo->ndo_packetp = buf; + ndo->ndo_snapend = end; + + return 1; + +} + static void esp_print_addsa(netdissect_options *ndo, struct sa_list *sa, int sa_def) { @@ -122,14 +180,194 @@ static u_int hex2byte(netdissect_options *ndo, char *hexstring) return byte; } +/* + * returns size of binary, 0 on failure. + */ +static +int espprint_decode_hex(netdissect_options *ndo, + u_char *binbuf, unsigned int binbuf_len, + char *hex) +{ + unsigned int len; + int i; + + len = strlen(hex) / 2; + + if (len > binbuf_len) { + (*ndo->ndo_warning)(ndo, "secret is too big: %d\n", len); + return 0; + } + + i = 0; + while (hex[0] != '\0' && hex[1]!='\0') { + binbuf[i] = hex2byte(ndo, hex); + hex += 2; + i++; + } + + return i; +} + /* * decode the form: SPINUM@IP ALGONAME:0xsecret + */ + +static int +espprint_decode_encalgo(netdissect_options *ndo, + char *decode, struct sa_list *sa) +{ + int len; + size_t i; + const EVP_CIPHER *evp; + int authlen = 0; + char *colon, *p; + + colon = strchr(decode, ':'); + if (colon == NULL) { + (*ndo->ndo_warning)(ndo, "failed to decode espsecret: %s\n", decode); + return 0; + } + *colon = '\0'; + + len = colon - decode; + if (strlen(decode) > strlen("-hmac96") && + !strcmp(decode + strlen(decode) - strlen("-hmac96"), + "-hmac96")) { + p = strstr(decode, "-hmac96"); + *p = '\0'; + authlen = 12; + } + if (strlen(decode) > strlen("-cbc") && + !strcmp(decode + strlen(decode) - strlen("-cbc"), "-cbc")) { + p = strstr(decode, "-cbc"); + *p = '\0'; + } + evp = EVP_get_cipherbyname(decode); + + if (!evp) { + (*ndo->ndo_warning)(ndo, "failed to find cipher algo %s\n", decode); + sa->evp = NULL; + sa->authlen = 0; + sa->ivlen = 0; + return 0; + } + + sa->evp = evp; + sa->authlen = authlen; + sa->ivlen = EVP_CIPHER_iv_length(evp); + + colon++; + if (colon[0] == '0' && colon[1] == 'x') { + /* decode some hex! */ + + colon += 2; + sa->secretlen = espprint_decode_hex(ndo, sa->secret, sizeof(sa->secret), colon); + if(sa->secretlen == 0) return 0; + } else { + i = strlen(colon); + + if (i < sizeof(sa->secret)) { + memcpy(sa->secret, colon, i); + sa->secretlen = i; + } else { + memcpy(sa->secret, colon, sizeof(sa->secret)); + sa->secretlen = sizeof(sa->secret); + } + } + + return 1; +} + +/* + * for the moment, ignore the auth algorith, just hard code the authenticator + * length. Need to research how openssl looks up HMAC stuff. + */ +static int +espprint_decode_authalgo(netdissect_options *ndo, + char *decode, struct sa_list *sa) +{ + char *colon; + + colon = strchr(decode, ':'); + if (colon == NULL) { + (*ndo->ndo_warning)(ndo, "failed to decode espsecret: %s\n", decode); + return 0; + } + *colon = '\0'; + + if(strcasecmp(colon,"sha1") == 0 || + strcasecmp(colon,"md5") == 0) { + sa->authlen = 12; + } + return 1; +} + +static void esp_print_decode_ikeline(netdissect_options *ndo, char *line, + const char *file, int lineno) +{ + /* it's an IKEv2 secret, store it instead */ + struct sa_list sa1; + + char *init; + char *icookie, *rcookie; + int ilen, rlen; + char *authkey; + char *enckey; + + init = strsep(&line, " \t"); + icookie = strsep(&line, " \t"); + rcookie = strsep(&line, " \t"); + authkey = strsep(&line, " \t"); + enckey = strsep(&line, " \t"); + + /* if any fields are missing */ + if(!init || !icookie || !rcookie || !authkey || !enckey) { + (*ndo->ndo_warning)(ndo, "print_esp: failed to find all fields for ikev2 at %s:%u", + file, lineno); + + return; + } + + ilen = strlen(icookie); + rlen = strlen(rcookie); + + if((init[0]!='I' && init[0]!='R') + || icookie[0]!='0' || icookie[1]!='x' + || rcookie[0]!='0' || rcookie[1]!='x' + || ilen!=18 + || rlen!=18) { + (*ndo->ndo_warning)(ndo, "print_esp: line %s:%u improperly formatted.", + file, lineno); + + (*ndo->ndo_warning)(ndo, "init=%s icookie=%s(%u) rcookie=%s(%u)", + init, icookie, ilen, rcookie, rlen); + + return; + } + + sa1.spi = 0; + sa1.initiator = (init[0] == 'I'); + if(espprint_decode_hex(ndo, sa1.spii, sizeof(sa1.spii), icookie+2)!=8) + return; + + if(espprint_decode_hex(ndo, sa1.spir, sizeof(sa1.spir), rcookie+2)!=8) + return; + + if(!espprint_decode_encalgo(ndo, enckey, &sa1)) return; + + if(!espprint_decode_authalgo(ndo, authkey, &sa1)) return; + + esp_print_addsa(ndo, &sa1, FALSE); +} + +/* * * special form: file /name * causes us to go read from this file instead. * */ -static void esp_print_decode_onesecret(netdissect_options *ndo, char *line) +static void esp_print_decode_onesecret(netdissect_options *ndo, char *line, + const char *file, int lineno) { struct sa_list sa1; int sa_def; @@ -155,15 +393,18 @@ static void esp_print_decode_onesecret(netdissect_options *ndo, char *line) /* open file and read it */ FILE *secretfile; char fileline[1024]; + int lineno=0; char *nl; + char *filename = line; - secretfile = fopen(line, FOPEN_READ_TXT); + secretfile = fopen(filename, FOPEN_READ_TXT); if (secretfile == NULL) { - perror(line); + perror(filename); exit(3); } while (fgets(fileline, sizeof(fileline)-1, secretfile) != NULL) { + lineno++; /* remove newline from the line */ nl = strchr(fileline, '\n'); if (nl) @@ -171,31 +412,37 @@ static void esp_print_decode_onesecret(netdissect_options *ndo, char *line) if (fileline[0] == '#') continue; if (fileline[0] == '\0') continue; - esp_print_decode_onesecret(ndo, fileline); + esp_print_decode_onesecret(ndo, fileline, filename, lineno); } fclose(secretfile); return; } + if (spikey && strcasecmp(spikey, "ikev2") == 0) { + esp_print_decode_ikeline(ndo, line, file, lineno); + return; + } + if (spikey) { + char *spistr, *foo; u_int32_t spino; struct sockaddr_in *sin; #ifdef INET6 struct sockaddr_in6 *sin6; #endif - + spistr = strsep(&spikey, "@"); - + spino = strtoul(spistr, &foo, 0); if (spistr == foo || !spikey) { (*ndo->ndo_warning)(ndo, "print_esp: failed to decode spi# %s\n", foo); return; } - + sa1.spi = spino; - + sin = (struct sockaddr_in *)&sa1.daddr; #ifdef INET6 sin6 = (struct sockaddr_in6 *)&sa1.daddr; @@ -206,122 +453,63 @@ static void esp_print_decode_onesecret(netdissect_options *ndo, char *line) sin6->sin6_family = AF_INET6; } else #endif - if (inet_pton(AF_INET, spikey, &sin->sin_addr) == 1) { + if (inet_pton(AF_INET, spikey, &sin->sin_addr) == 1) { #ifdef HAVE_SOCKADDR_SA_LEN - sin->sin_len = sizeof(struct sockaddr_in); + sin->sin_len = sizeof(struct sockaddr_in); #endif - sin->sin_family = AF_INET; - } else { - (*ndo->ndo_warning)(ndo, "print_esp: can not decode IP# %s\n", spikey); - return; - } + sin->sin_family = AF_INET; + } else { + (*ndo->ndo_warning)(ndo, "print_esp: can not decode IP# %s\n", spikey); + return; + } } if (decode) { - char *colon, *p; - u_char espsecret_key[256]; - int len; - size_t i; - const EVP_CIPHER *evp; - int authlen = 0; - /* skip any blank spaces */ while (isspace((unsigned char)*decode)) decode++; - - colon = strchr(decode, ':'); - if (colon == NULL) { - (*ndo->ndo_warning)(ndo, "failed to decode espsecret: %s\n", decode); + + if(!espprint_decode_encalgo(ndo, decode, &sa1)) { return; } - *colon = '\0'; - - len = colon - decode; - if (strlen(decode) > strlen("-hmac96") && - !strcmp(decode + strlen(decode) - strlen("-hmac96"), - "-hmac96")) { - p = strstr(decode, "-hmac96"); - *p = '\0'; - authlen = 12; - } - if (strlen(decode) > strlen("-cbc") && - !strcmp(decode + strlen(decode) - strlen("-cbc"), "-cbc")) { - p = strstr(decode, "-cbc"); - *p = '\0'; - } - evp = EVP_get_cipherbyname(decode); - if (!evp) { - (*ndo->ndo_warning)(ndo, "failed to find cipher algo %s\n", decode); - sa1.evp = NULL; - sa1.authlen = 0; - sa1.ivlen = 0; - return; - } - - sa1.evp = evp; - sa1.authlen = authlen; - sa1.ivlen = EVP_CIPHER_iv_length(evp); - - colon++; - if (colon[0] == '0' && colon[1] == 'x') { - /* decode some hex! */ - colon += 2; - len = strlen(colon) / 2; - - if (len > 256) { - (*ndo->ndo_warning)(ndo, "secret is too big: %d\n", len); - return; - } - - i = 0; - while (colon[0] != '\0' && colon[1]!='\0') { - espsecret_key[i] = hex2byte(ndo, colon); - colon += 2; - i++; - } - - memcpy(sa1.secret, espsecret_key, i); - sa1.secretlen = i; - } else { - i = strlen(colon); - - if (i < sizeof(sa1.secret)) { - memcpy(sa1.secret, colon, i); - sa1.secretlen = i; - } else { - memcpy(sa1.secret, colon, sizeof(sa1.secret)); - sa1.secretlen = sizeof(sa1.secret); - } - } } esp_print_addsa(ndo, &sa1, sa_def); } -static void esp_print_decodesecret(netdissect_options *ndo) +static void esp_init(netdissect_options *ndo _U_) +{ + + OpenSSL_add_all_algorithms(); + EVP_add_cipher_alias(SN_des_ede3_cbc, "3des"); +} + +void esp_print_decodesecret(netdissect_options *ndo) { char *line; char *p; + static int initialized = 0; + + if (!initialized) { + esp_init(ndo); + initialized = 1; + } p = ndo->ndo_espsecret; - while (ndo->ndo_espsecret && ndo->ndo_espsecret[0] != '\0') { + while (p && p[0] != '\0') { /* pick out the first line or first thing until a comma */ - if ((line = strsep(&ndo->ndo_espsecret, "\n,")) == NULL) { - line = ndo->ndo_espsecret; - ndo->ndo_espsecret = NULL; + if ((line = strsep(&p, "\n,")) == NULL) { + line = p; + p = NULL; } - esp_print_decode_onesecret(ndo, line); + esp_print_decode_onesecret(ndo, line, "cmdline", 0); } -} -static void esp_init(netdissect_options *ndo _U_) -{ - - OpenSSL_add_all_algorithms(); - EVP_add_cipher_alias(SN_des_ede3_cbc, "3des"); + ndo->ndo_espsecret = NULL; } + #endif int @@ -359,7 +547,6 @@ esp_print(netdissect_options *ndo, u_char *p; EVP_CIPHER_CTX ctx; int blocksz; - static int initialized = 0; #endif esp = (struct newesp *)bp; @@ -367,11 +554,6 @@ esp_print(netdissect_options *ndo, #ifdef HAVE_LIBCRYPTO secret = NULL; advance = 0; - - if (!initialized) { - esp_init(ndo); - initialized = 1; - } #endif #if 0 @@ -418,7 +600,7 @@ esp_print(netdissect_options *ndo, /* see if we can find the SA, and if so, decode it */ for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) { struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa->daddr; - if (sa->spi == ntohl(esp->esp_spi) && + if (sa->spi == EXTRACT_32BITS(&esp->esp_spi) && sin6->sin6_family == AF_INET6 && memcmp(&sin6->sin6_addr, &ip6->ip6_dst, sizeof(struct in6_addr)) == 0) { @@ -436,7 +618,7 @@ esp_print(netdissect_options *ndo, /* see if we can find the SA, and if so, decode it */ for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) { struct sockaddr_in *sin = (struct sockaddr_in *)&sa->daddr; - if (sa->spi == ntohl(esp->esp_spi) && + if (sa->spi == EXTRACT_32BITS(&esp->esp_spi) && sin->sin_family == AF_INET && sin->sin_addr.s_addr == ip->ip_dst.s_addr) { break; @@ -481,6 +663,7 @@ esp_print(netdissect_options *ndo, p = ivoff; EVP_CipherInit(&ctx, NULL, NULL, p, 0); EVP_Cipher(&ctx, p + ivlen, p + ivlen, ep - (p + ivlen)); + EVP_CIPHER_CTX_cleanup(&ctx); advance = ivoff - (u_char *)esp + ivlen; } else advance = sizeof(struct newesp); diff --git a/contrib/tcpdump/print-ether.c b/contrib/tcpdump/print-ether.c index b66e885c6b..76505721af 100644 --- a/contrib/tcpdump/print-ether.c +++ b/contrib/tcpdump/print-ether.c @@ -20,9 +20,10 @@ */ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-ether.c,v 1.105.2.1 2008-02-06 10:49:22 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-ether.c,v 1.106 2008-02-06 10:47:53 guy Exp $ (LBL)"; #endif +#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -33,6 +34,7 @@ static const char rcsid[] _U_ = #include #include "interface.h" +#include "extract.h" #include "addrtoname.h" #include "ethertype.h" @@ -44,6 +46,9 @@ const struct tok ethertype_values[] = { { ETHERTYPE_MPLS_MULTI, "MPLS multicast" }, { ETHERTYPE_IPV6, "IPv6" }, { ETHERTYPE_8021Q, "802.1Q" }, + { ETHERTYPE_8021Q9100, "802.1Q-9100" }, + { ETHERTYPE_8021QinQ, "802.1Q-QinQ" }, + { ETHERTYPE_8021Q9200, "802.1Q-9200" }, { ETHERTYPE_VMAN, "VMAN" }, { ETHERTYPE_PUP, "PUP" }, { ETHERTYPE_ARP, "ARP"}, @@ -56,6 +61,7 @@ const struct tok ethertype_values[] = { { ETHERTYPE_DN, "DN" }, { ETHERTYPE_LAT, "LAT" }, { ETHERTYPE_SCA, "SCA" }, + { ETHERTYPE_TEB, "TEB" }, { ETHERTYPE_LANBRIDGE, "Lanbridge" }, { ETHERTYPE_DECDNS, "DEC DNS" }, { ETHERTYPE_DECDTS, "DEC DTS" }, @@ -82,54 +88,72 @@ const struct tok ethertype_values[] = { }; static inline void -ether_hdr_print(register const u_char *bp, u_int length) +ether_hdr_print(netdissect_options *ndo, + const u_char *bp, u_int length) { register const struct ether_header *ep; + u_int16_t ether_type; + ep = (const struct ether_header *)bp; - (void)printf("%s > %s", + (void)ND_PRINT((ndo, "%s > %s", etheraddr_string(ESRC(ep)), - etheraddr_string(EDST(ep))); + etheraddr_string(EDST(ep)))); - if (!qflag) { - if (ntohs(ep->ether_type) <= ETHERMTU) - (void)printf(", 802.3"); + ether_type = EXTRACT_16BITS(&ep->ether_type); + if (!ndo->ndo_qflag) { + if (ether_type <= ETHERMTU) + (void)ND_PRINT((ndo, ", 802.3")); else - (void)printf(", ethertype %s (0x%04x)", - tok2str(ethertype_values,"Unknown", ntohs(ep->ether_type)), - ntohs(ep->ether_type)); + (void)ND_PRINT((ndo, ", ethertype %s (0x%04x)", + tok2str(ethertype_values,"Unknown", ether_type), + ether_type)); } else { - if (ntohs(ep->ether_type) <= ETHERMTU) - (void)printf(", 802.3"); + if (ether_type <= ETHERMTU) + (void)ND_PRINT((ndo, ", 802.3")); else - (void)printf(", %s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", ntohs(ep->ether_type))); + (void)ND_PRINT((ndo, ", %s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", ether_type))); } - (void)printf(", length %u: ", length); + (void)ND_PRINT((ndo, ", length %u: ", length)); } +/* + * Print an Ethernet frame. + * This might be encapsulated within another frame; we might be passed + * a pointer to a function that can print header information for that + * frame's protocol, and an argument to pass to that function. + */ void -ether_print(const u_char *p, u_int length, u_int caplen) +ether_print(netdissect_options *ndo, + const u_char *p, u_int length, u_int caplen, + void (*print_encap_header)(netdissect_options *ndo, const u_char *), const u_char *encap_header_arg) { struct ether_header *ep; + u_int orig_length; u_short ether_type; u_short extracted_ether_type; - if (caplen < ETHER_HDRLEN) { - printf("[|ether]"); + if (caplen < ETHER_HDRLEN || length < ETHER_HDRLEN) { + ND_PRINT((ndo, "[|ether]")); return; } - if (eflag) - ether_hdr_print(p, length); + if (ndo->ndo_eflag) { + if (print_encap_header != NULL) + (*print_encap_header)(ndo, encap_header_arg); + ether_hdr_print(ndo, p, length); + } + orig_length = length; length -= ETHER_HDRLEN; caplen -= ETHER_HDRLEN; ep = (struct ether_header *)p; p += ETHER_HDRLEN; - ether_type = ntohs(ep->ether_type); + ether_type = EXTRACT_16BITS(&ep->ether_type); +recurse: /* * Is it (gag) an 802.3 encapsulation? */ @@ -138,21 +162,79 @@ ether_print(const u_char *p, u_int length, u_int caplen) if (llc_print(p, length, caplen, ESRC(ep), EDST(ep), &extracted_ether_type) == 0) { /* ether_type not known, print raw packet */ - if (!eflag) - ether_hdr_print((u_char *)ep, length + ETHER_HDRLEN); + if (!ndo->ndo_eflag) { + if (print_encap_header != NULL) + (*print_encap_header)(ndo, encap_header_arg); + ether_hdr_print(ndo, (u_char *)ep, orig_length); + } + + if (!ndo->ndo_suppress_default_print) + ndo->ndo_default_print(ndo, p, caplen); + } + } else if (ether_type == ETHERTYPE_8021Q || + ether_type == ETHERTYPE_8021Q9100 || + ether_type == ETHERTYPE_8021Q9200 || + ether_type == ETHERTYPE_8021QinQ) { + /* + * Print VLAN information, and then go back and process + * the enclosed type field. + */ + if (caplen < 4 || length < 4) { + ND_PRINT((ndo, "[|vlan]")); + return; + } + if (ndo->ndo_eflag) { + u_int16_t tag = EXTRACT_16BITS(p); - if (!suppress_default_print) - default_print(p, caplen); + ND_PRINT((ndo, "vlan %u, p %u%s, ", + tag & 0xfff, + tag >> 13, + (tag & 0x1000) ? ", CFI" : "")); } - } else if (ether_encap_print(ether_type, p, length, caplen, - &extracted_ether_type) == 0) { - /* ether_type not known, print raw packet */ - if (!eflag) - ether_hdr_print((u_char *)ep, length + ETHER_HDRLEN); - - if (!suppress_default_print) - default_print(p, caplen); - } + + ether_type = EXTRACT_16BITS(p + 2); + if (ndo->ndo_eflag && ether_type > ETHERMTU) + ND_PRINT((ndo, "ethertype %s, ", tok2str(ethertype_values,"0x%04x", ether_type))); + p += 4; + length -= 4; + caplen -= 4; + goto recurse; + } else if (ether_type == ETHERTYPE_JUMBO) { + /* + * Alteon jumbo frames. + * See + * + * http://tools.ietf.org/html/draft-ietf-isis-ext-eth-01 + * + * which indicates that, following the type field, + * there's an LLC header and payload. + */ + /* Try to print the LLC-layer header & higher layers */ + if (llc_print(p, length, caplen, ESRC(ep), EDST(ep), + &extracted_ether_type) == 0) { + /* ether_type not known, print raw packet */ + if (!ndo->ndo_eflag) { + if (print_encap_header != NULL) + (*print_encap_header)(ndo, encap_header_arg); + ether_hdr_print(ndo, (u_char *)ep, orig_length); + } + + if (!ndo->ndo_suppress_default_print) + ndo->ndo_default_print(ndo, p, caplen); + } + } else { + if (ethertype_print(ndo, ether_type, p, length, caplen) == 0) { + /* ether_type not known, print raw packet */ + if (!ndo->ndo_eflag) { + if (print_encap_header != NULL) + (*print_encap_header)(ndo, encap_header_arg); + ether_hdr_print(ndo, (u_char *)ep, orig_length); + } + + if (!ndo->ndo_suppress_default_print) + ndo->ndo_default_print(ndo, p, caplen); + } + } } /* @@ -162,166 +244,160 @@ ether_print(const u_char *p, u_int length, u_int caplen) * is the number of bytes actually captured. */ u_int -ether_if_print(const struct pcap_pkthdr *h, const u_char *p) +ether_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, + const u_char *p) { - ether_print(p, h->len, h->caplen); + ether_print(ndo, p, h->len, h->caplen, NULL, NULL); return (ETHER_HDRLEN); } /* - * Prints the packet encapsulated in an Ethernet data segment - * (or an equivalent encapsulation), given the Ethernet type code. + * This is the top level routine of the printer. 'p' points + * to the ether header of the packet, 'h->ts' is the timestamp, + * 'h->len' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. * - * Returns non-zero if it can do so, zero if the ethertype is unknown. + * This is for DLT_NETANALYZER, which has a 4-byte pseudo-header + * before the Ethernet header. + */ +u_int +netanalyzer_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, + const u_char *p) +{ + /* + * Fail if we don't have enough data for the Hilscher pseudo-header. + */ + if (h->len < 4 || h->caplen < 4) { + printf("[|netanalyzer]"); + return (h->caplen); + } + + /* Skip the pseudo-header. */ + ether_print(ndo, p + 4, h->len - 4, h->caplen - 4, NULL, NULL); + + return (4 + ETHER_HDRLEN); +} + +/* + * This is the top level routine of the printer. 'p' points + * to the ether header of the packet, 'h->ts' is the timestamp, + * 'h->len' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. + * + * This is for DLT_NETANALYZER_TRANSPARENT, which has a 4-byte + * pseudo-header, a 7-byte Ethernet preamble, and a 1-byte Ethernet SOF + * before the Ethernet header. + */ +u_int +netanalyzer_transparent_if_print(netdissect_options *ndo, + const struct pcap_pkthdr *h, + const u_char *p) +{ + /* + * Fail if we don't have enough data for the Hilscher pseudo-header, + * preamble, and SOF. + */ + if (h->len < 12 || h->caplen < 12) { + printf("[|netanalyzer-transparent]"); + return (h->caplen); + } + + /* Skip the pseudo-header, preamble, and SOF. */ + ether_print(ndo, p + 12, h->len - 12, h->caplen - 12, NULL, NULL); + + return (12 + ETHER_HDRLEN); +} + +/* + * Prints the packet payload, given an Ethernet type code for the payload's + * protocol. * - * The Ethernet type code is passed through a pointer; if it was - * ETHERTYPE_8021Q, it gets updated to be the Ethernet type of - * the 802.1Q payload, for the benefit of lower layers that might - * want to know what it is. + * Returns non-zero if it can do so, zero if the ethertype is unknown. */ int -ether_encap_print(u_short ether_type, const u_char *p, - u_int length, u_int caplen, u_short *extracted_ether_type) +ethertype_print(netdissect_options *ndo, + u_short ether_type, const u_char *p, + u_int length, u_int caplen) { - recurse: - *extracted_ether_type = ether_type; - switch (ether_type) { case ETHERTYPE_IP: - ip_print(gndo, p, length); + ip_print(ndo, p, length); return (1); #ifdef INET6 case ETHERTYPE_IPV6: - ip6_print(p, length); + ip6_print(ndo, p, length); return (1); #endif /*INET6*/ case ETHERTYPE_ARP: case ETHERTYPE_REVARP: - arp_print(gndo, p, length, caplen); + arp_print(ndo, p, length, caplen); return (1); case ETHERTYPE_DN: - decnet_print(p, length, caplen); + decnet_print(/*ndo,*/p, length, caplen); return (1); case ETHERTYPE_ATALK: - if (vflag) + if (ndo->ndo_vflag) fputs("et1 ", stdout); - atalk_print(p, length); + atalk_print(/*ndo,*/p, length); return (1); case ETHERTYPE_AARP: - aarp_print(p, length); + aarp_print(/*ndo,*/p, length); return (1); case ETHERTYPE_IPX: - printf("(NOV-ETHII) "); - ipx_print(p, length); - return (1); - - case ETHERTYPE_8021Q: - if (eflag) - printf("vlan %u, p %u%s, ", - ntohs(*(u_int16_t *)p) & 0xfff, - ntohs(*(u_int16_t *)p) >> 13, - (ntohs(*(u_int16_t *)p) & 0x1000) ? ", CFI" : ""); - - ether_type = ntohs(*(u_int16_t *)(p + 2)); - p += 4; - length -= 4; - caplen -= 4; - - if (ether_type > ETHERMTU) { - if (eflag) - printf("ethertype %s, ", - tok2str(ethertype_values,"0x%04x", ether_type)); - goto recurse; - } - - *extracted_ether_type = 0; - - if (llc_print(p, length, caplen, p - 18, p - 12, - extracted_ether_type) == 0) { - ether_hdr_print(p - 18, length + 4); - - if (!suppress_default_print) { - default_print(p - 18, caplen + 4); - } - } - - + ND_PRINT((ndo, "(NOV-ETHII) ")); + ipx_print(/*ndo,*/p, length); return (1); - case ETHERTYPE_JUMBO: - ether_type = ntohs(*(u_int16_t *)(p)); - p += 2; - length -= 2; - caplen -= 2; - - if (ether_type > ETHERMTU) { - if (eflag) - printf("ethertype %s, ", - tok2str(ethertype_values,"0x%04x", ether_type)); - goto recurse; - } - - *extracted_ether_type = 0; - - if (llc_print(p, length, caplen, p - 16, p - 10, - extracted_ether_type) == 0) { - ether_hdr_print(p - 16, length + 2); - - if (!suppress_default_print) { - default_print(p - 16, caplen + 2); - } - } - - return (1); - case ETHERTYPE_ISO: - isoclns_print(p+1, length-1, length-1); + isoclns_print(/*ndo,*/p+1, length-1, length-1); return(1); case ETHERTYPE_PPPOED: case ETHERTYPE_PPPOES: - pppoe_print(p, length); + case ETHERTYPE_PPPOED2: + case ETHERTYPE_PPPOES2: + pppoe_print(/*ndo,*/p, length); return (1); case ETHERTYPE_EAPOL: - eap_print(gndo, p, length); + eap_print(ndo, p, length); return (1); case ETHERTYPE_RRCP: - rrcp_print(gndo, p - 14 , length + 14); + rrcp_print(ndo, p - 14 , length + 14); return (1); case ETHERTYPE_PPP: if (length) { printf(": "); - ppp_print(p, length); + ppp_print(/*ndo,*/p, length); } return (1); case ETHERTYPE_MPCP: - mpcp_print(p, length); + mpcp_print(/*ndo,*/p, length); return (1); case ETHERTYPE_SLOW: - slow_print(p, length); + slow_print(/*ndo,*/p, length); return (1); case ETHERTYPE_CFM: case ETHERTYPE_CFM_OLD: - cfm_print(p, length); + cfm_print(/*ndo,*/p, length); return (1); case ETHERTYPE_LLDP: - lldp_print(p, length); + lldp_print(/*ndo,*/p, length); return (1); case ETHERTYPE_LOOPBACK: @@ -329,7 +405,7 @@ ether_encap_print(u_short ether_type, const u_char *p, case ETHERTYPE_MPLS: case ETHERTYPE_MPLS_MULTI: - mpls_print(p, length); + mpls_print(/*ndo,*/p, length); return (1); case ETHERTYPE_LAT: diff --git a/contrib/tcpdump/print-forces.c b/contrib/tcpdump/print-forces.c new file mode 100644 index 0000000000..033580e51b --- /dev/null +++ b/contrib/tcpdump/print-forces.c @@ -0,0 +1,1055 @@ +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * Copyright (c) 2009 Mojatatu Networks, Inc + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "extract.h" + +#include "forces.h" + +#define RESLEN 4 + +int +prestlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent) +{ + const struct forces_tlv *tlv = (struct forces_tlv *)pptr; + register const u_char *tdp = (u_char *) TLV_DATA(tlv); + struct res_val *r = (struct res_val *)tdp; + u_int dlen; + + /* + * pdatacnt_print() has ensured that len (the TLV length) + * >= TLV_HDRL. + */ + dlen = len - TLV_HDRL; + if (dlen != RESLEN) { + printf("illegal RESULT-TLV: %d bytes!\n", dlen); + return -1; + } + + TCHECK(*r); + if (r->result >= 0x18 && r->result <= 0xFE) { + printf("illegal reserved result code: 0x%x!\n", r->result); + return -1; + } + + if (vflag >= 3) { + char *ib = indent_pr(indent, 0); + printf("%s Result: %s (code 0x%x)\n", ib, + tok2str(ForCES_errs, NULL, r->result), r->result); + } + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +fdatatlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent) +{ + const struct forces_tlv *tlv = (struct forces_tlv *)pptr; + u_int rlen; + register const u_char *tdp = (u_char *) TLV_DATA(tlv); + u_int16_t type; + + /* + * pdatacnt_print() or pkeyitlv_print() has ensured that len + * (the TLV length) >= TLV_HDRL. + */ + rlen = len - TLV_HDRL; + TCHECK(*tlv); + type = EXTRACT_16BITS(&tlv->type); + if (type != F_TLV_FULD) { + printf("Error: expecting FULLDATA!\n"); + return -1; + } + + if (vflag >= 3) { + char *ib = indent_pr(indent + 2, 1); + printf("%s[", &ib[1]); + hex_print_with_offset(ib, tdp, rlen, 0); + printf("\n%s]\n", &ib[1]); + } + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +sdatailv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent) +{ + u_int rlen; + const struct forces_ilv *ilv = (struct forces_ilv *)pptr; + int invilv; + + if (len < ILV_HDRL) { + printf("Error: BAD SPARSEDATA-TLV!\n"); + return -1; + } + rlen = len - ILV_HDRL; + indent += 1; + while (rlen != 0) { + TCHECK(*ilv); + invilv = ilv_valid(ilv, rlen); + if (invilv) { + printf("Error: BAD ILV!\n"); + return -1; + } + if (vflag >= 3) { + register const u_char *tdp = (u_char *) ILV_DATA(ilv); + char *ib = indent_pr(indent, 1); + printf("\n%s SPARSEDATA: type %x length %d\n", &ib[1], + EXTRACT_32BITS(&ilv->type), + EXTRACT_32BITS(&ilv->length)); + printf("%s[", &ib[1]); + hex_print_with_offset(ib, tdp, rlen, 0); + printf("\n%s]\n", &ib[1]); + } + + ilv = GO_NXT_ILV(ilv, rlen); + } + + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +sdatatlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent) +{ + const struct forces_tlv *tlv = (struct forces_tlv *)pptr; + u_int rlen; + register const u_char *tdp = (u_char *) TLV_DATA(tlv); + u_int16_t type; + + /* + * pdatacnt_print() has ensured that len (the TLV length) + * >= TLV_HDRL. + */ + rlen = len - TLV_HDRL; + TCHECK(*tlv); + type = EXTRACT_16BITS(&tlv->type); + if (type != F_TLV_SPAD) { + printf("Error: expecting SPARSEDATA!\n"); + return -1; + } + + return sdatailv_print(tdp, rlen, op_msk, indent); + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +pkeyitlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent) +{ + const struct forces_tlv *tlv = (struct forces_tlv *)pptr; + register const u_char *tdp = (u_char *) TLV_DATA(tlv); + register const u_char *dp = tdp + 4; + const struct forces_tlv *kdtlv = (struct forces_tlv *)dp; + u_int32_t id; + char *ib = indent_pr(indent, 0); + u_int16_t type, tll; + int invtlv; + + TCHECK(*tdp); + id = EXTRACT_32BITS(tdp); + printf("%sKeyinfo: Key 0x%x\n", ib, id); + TCHECK(*kdtlv); + type = EXTRACT_16BITS(&kdtlv->type); + invtlv = tlv_valid(kdtlv, len); + + if (invtlv) { + printf("%s TLV type 0x%x len %d\n", + tok2str(ForCES_TLV_err, NULL, invtlv), type, + EXTRACT_16BITS(&kdtlv->length)); + return -1; + } + /* + * At this point, tlv_valid() has ensured that the TLV + * length is large enough but not too large (it doesn't + * go past the end of the containing TLV). + */ + tll = EXTRACT_16BITS(&kdtlv->length); + dp = (u_char *) TLV_DATA(kdtlv); + return fdatatlv_print(dp, tll, op_msk, indent); + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +pdatacnt_print(register const u_char * pptr, register u_int len, + u_int16_t IDcnt, u_int16_t op_msk, int indent) +{ + u_int i; + int rc; + u_int32_t id; + char *ib = indent_pr(indent, 0); + + for (i = 0; i < IDcnt; i++) { + TCHECK2(*pptr, 4); + if (len < 4) + goto trunc; + id = EXTRACT_32BITS(pptr); + if (vflag >= 3) + printf("%s ID#%02u: %d\n", ib, i + 1, id); + len -= 4; + pptr += 4; + } + if (len) { + const struct forces_tlv *pdtlv = (struct forces_tlv *)pptr; + u_int16_t type; + u_int16_t tll; + int pad = 0; + u_int aln; + int invtlv; + + TCHECK(*pdtlv); + type = EXTRACT_16BITS(&pdtlv->type); + invtlv = tlv_valid(pdtlv, len); + if (invtlv) { + printf + ("%s Outstanding bytes %d for TLV type 0x%x TLV len %d\n", + tok2str(ForCES_TLV_err, NULL, invtlv), len, type, + EXTRACT_16BITS(&pdtlv->length)); + goto pd_err; + } + /* + * At this point, tlv_valid() has ensured that the TLV + * length is large enough but not too large (it doesn't + * go past the end of the containing TLV). + */ + tll = EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL; + aln = F_ALN_LEN(EXTRACT_16BITS(&pdtlv->length)); + if (aln > EXTRACT_16BITS(&pdtlv->length)) { + if (aln > len) { + printf + ("Invalid padded pathdata TLV type 0x%x len %d missing %d pad bytes\n", + type, EXTRACT_16BITS(&pdtlv->length), aln - len); + } else { + pad = aln - EXTRACT_16BITS(&pdtlv->length); + } + } + if (pd_valid(type)) { + const struct pdata_ops *ops = get_forces_pd(type); + + if (vflag >= 3 && ops->v != F_TLV_PDAT) { + if (pad) + printf + ("%s %s (Length %d DataLen %d pad %d Bytes)\n", + ib, ops->s, EXTRACT_16BITS(&pdtlv->length), + tll, pad); + else + printf + ("%s %s (Length %d DataLen %d Bytes)\n", + ib, ops->s, EXTRACT_16BITS(&pdtlv->length), + tll); + } + + chk_op_type(type, op_msk, ops->op_msk); + + rc = ops->print((const u_char *)pdtlv, + tll + pad + TLV_HDRL, op_msk, + indent + 2); + len -= (TLV_HDRL + pad + tll); + } else { + printf("Invalid path data content type 0x%x len %d\n", + type, EXTRACT_16BITS(&pdtlv->length)); +pd_err: + if (EXTRACT_16BITS(&pdtlv->length)) { + hex_print_with_offset("Bad Data val\n\t [", + pptr, len, 0); + printf("]\n"); + + return -1; + } + } + } + return len; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +pdata_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent) +{ + const struct pathdata_h *pdh = (struct pathdata_h *)pptr; + char *ib = indent_pr(indent, 0); + u_int minsize = 0; + int more_pd = 0; + u_int16_t idcnt = 0; + + TCHECK(*pdh); + if (len < sizeof(struct pathdata_h)) + goto trunc; + if (vflag >= 3) { + printf("\n%sPathdata: Flags 0x%x ID count %d\n", + ib, EXTRACT_16BITS(&pdh->pflags), EXTRACT_16BITS(&pdh->pIDcnt)); + } + + if (EXTRACT_16BITS(&pdh->pflags) & F_SELKEY) { + op_msk |= B_KEYIN; + } + pptr += sizeof(struct pathdata_h); + len -= sizeof(struct pathdata_h); + idcnt = EXTRACT_16BITS(&pdh->pIDcnt); + minsize = idcnt * 4; + if (len < minsize) { + printf("\t\t\ttruncated IDs expected %uB got %uB\n", minsize, + len); + hex_print_with_offset("\t\t\tID Data[", pptr, len, 0); + printf("]\n"); + return -1; + } + more_pd = pdatacnt_print(pptr, len, idcnt, op_msk, indent); + if (more_pd > 0) { + int consumed = len - more_pd; + pptr += consumed; + len = more_pd; + /* XXX: Argh, recurse some more */ + return recpdoptlv_print(pptr, len, op_msk, indent+1); + } else + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +genoptlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent) +{ + const struct forces_tlv *pdtlv = (struct forces_tlv *)pptr; + u_int16_t type; + int tll; + int invtlv; + char *ib = indent_pr(indent, 0); + + TCHECK(*pdtlv); + type = EXTRACT_16BITS(&pdtlv->type); + tll = EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL; + invtlv = tlv_valid(pdtlv, len); + printf("genoptlvprint - %s TLV type 0x%x len %d\n", + tok2str(ForCES_TLV, NULL, type), type, EXTRACT_16BITS(&pdtlv->length)); + if (!invtlv) { + /* + * At this point, tlv_valid() has ensured that the TLV + * length is large enough but not too large (it doesn't + * go past the end of the containing TLV). + */ + register const u_char *dp = (u_char *) TLV_DATA(pdtlv); + if (!ttlv_valid(type)) { + printf("%s TLV type 0x%x len %d\n", + tok2str(ForCES_TLV_err, NULL, invtlv), type, + EXTRACT_16BITS(&pdtlv->length)); + return -1; + } + if (vflag >= 3) + printf("%s%s, length %d (data length %d Bytes)", + ib, tok2str(ForCES_TLV, NULL, type), + EXTRACT_16BITS(&pdtlv->length), tll); + + return pdata_print(dp, tll, op_msk, indent + 1); + } else { + printf("\t\t\tInvalid ForCES TLV type=%x", type); + return -1; + } + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +recpdoptlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent) +{ + const struct forces_tlv *pdtlv = (struct forces_tlv *)pptr; + int tll; + int rc = 0; + int invtlv; + u_int16_t type; + register const u_char *dp; + char *ib; + + while (len != 0) { + TCHECK(*pdtlv); + invtlv = tlv_valid(pdtlv, len); + if (invtlv) { + break; + } + + /* + * At this point, tlv_valid() has ensured that the TLV + * length is large enough but not too large (it doesn't + * go past the end of the containing TLV). + */ + ib = indent_pr(indent, 0); + type = EXTRACT_16BITS(&pdtlv->type); + dp = (u_char *) TLV_DATA(pdtlv); + tll = EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL; + + if (vflag >= 3) + printf + ("%s%s, length %d (data encapsulated %d Bytes)", + ib, tok2str(ForCES_TLV, NULL, type), + EXTRACT_16BITS(&pdtlv->length), + EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL); + + rc = pdata_print(dp, tll, op_msk, indent + 1); + pdtlv = GO_NXT_TLV(pdtlv, len); + } + + if (len) { + printf + ("\n\t\tMessy PATHDATA TLV header, type (0x%x)\n\t\texcess of %d Bytes ", + EXTRACT_16BITS(&pdtlv->type), len - EXTRACT_16BITS(&pdtlv->length)); + return -1; + } + + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +invoptlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent) +{ + char *ib = indent_pr(indent, 1); + + if (vflag >= 3) { + printf("%sData[", &ib[1]); + hex_print_with_offset(ib, pptr, len, 0); + printf("%s]\n", ib); + } + return -1; +} + +int otlv_print(const struct forces_tlv *otlv, u_int16_t op_msk _U_, int indent) +{ + int rc = 0; + register const u_char *dp = (u_char *) TLV_DATA(otlv); + u_int16_t type; + int tll; + char *ib = indent_pr(indent, 0); + const struct optlv_h *ops; + + /* + * lfbselect_print() has ensured that EXTRACT_16BITS(&otlv->length) + * >= TLV_HDRL. + */ + TCHECK(*otlv); + type = EXTRACT_16BITS(&otlv->type); + tll = EXTRACT_16BITS(&otlv->length) - TLV_HDRL; + ops = get_forces_optlv_h(type); + if (vflag >= 3) { + printf("%sOper TLV %s(0x%x) length %d\n", ib, ops->s, type, + EXTRACT_16BITS(&otlv->length)); + } + /* empty TLVs like COMMIT and TRCOMMIT are empty, we stop here .. */ + if (!ops->flags & ZERO_TTLV) { + if (tll != 0) /* instead of "if (tll)" - for readability .. */ + printf("%s: Illegal - MUST be empty\n", ops->s); + return rc; + } + /* rest of ops must at least have 12B {pathinfo} */ + if (tll < OP_MIN_SIZ) { + printf("\t\tOper TLV %s(0x%x) length %d\n", ops->s, type, + EXTRACT_16BITS(&otlv->length)); + printf("\t\tTruncated data size %d minimum required %d\n", tll, + OP_MIN_SIZ); + return invoptlv_print(dp, tll, ops->op_msk, indent); + + } + + rc = ops->print(dp, tll, ops->op_msk, indent + 1); + return rc; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +#define ASTDLN 4 +#define ASTMCD 255 +int +asttlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent) +{ + u_int32_t rescode; + u_int dlen; + char *ib = indent_pr(indent, 0); + + /* + * forces_type_print() has ensured that len (the TLV length) + * >= TLV_HDRL. + */ + dlen = len - TLV_HDRL; + if (dlen != ASTDLN) { + printf("illegal ASTresult-TLV: %d bytes!\n", dlen); + return -1; + } + TCHECK2(*pptr, 4); + rescode = EXTRACT_32BITS(pptr); + if (rescode > ASTMCD) { + printf("illegal ASTresult result code: %d!\n", rescode); + return -1; + } + + if (vflag >= 3) { + printf("Teardown reason:\n%s", ib); + switch (rescode) { + case 0: + printf("Normal Teardown"); + break; + case 1: + printf("Loss of Heartbeats"); + break; + case 2: + printf("Out of bandwidth"); + break; + case 3: + printf("Out of Memory"); + break; + case 4: + printf("Application Crash"); + break; + default: + printf("Unknown Teardown reason"); + break; + } + printf("(%x)\n%s", rescode, ib); + } + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +#define ASRDLN 4 +#define ASRMCD 3 +int +asrtlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent) +{ + u_int32_t rescode; + u_int dlen; + char *ib = indent_pr(indent, 0); + + /* + * forces_type_print() has ensured that len (the TLV length) + * >= TLV_HDRL. + */ + dlen = len - TLV_HDRL; + if (dlen != ASRDLN) { /* id, instance, oper tlv */ + printf("illegal ASRresult-TLV: %d bytes!\n", dlen); + return -1; + } + TCHECK2(*pptr, 4); + rescode = EXTRACT_32BITS(pptr); + + if (rescode > ASRMCD) { + printf("illegal ASRresult result code: %d!\n", rescode); + return -1; + } + + if (vflag >= 3) { + printf("\n%s", ib); + switch (rescode) { + case 0: + printf("Success "); + break; + case 1: + printf("FE ID invalid "); + break; + case 2: + printf("permission denied "); + break; + default: + printf("Unknown "); + break; + } + printf("(%x)\n%s", rescode, ib); + } + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +/* + * XXX - not used. + */ +int +gentltlv_print(register const u_char * pptr _U_, register u_int len, + u_int16_t op_msk _U_, int indent _U_) +{ + u_int dlen = len - TLV_HDRL; + + if (dlen < 4) { /* at least 32 bits must exist */ + printf("truncated TLV: %d bytes missing! ", 4 - dlen); + return -1; + } + return 0; +} + +#define RD_MIN 8 +int +print_metailv(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent) +{ + u_int dlen; + u_int rlen; + char *ib = indent_pr(indent, 0); + /* XXX: check header length */ + const struct forces_ilv *ilv = (struct forces_ilv *)pptr; + + /* + * print_metatlv() has ensured that len (what remains in the + * ILV) >= ILV_HDRL. + */ + dlen = len - ILV_HDRL; + rlen = dlen; + TCHECK(*ilv); + printf("\n%sMetaID 0x%x length %d\n", ib, EXTRACT_32BITS(&ilv->type), + EXTRACT_32BITS(&ilv->length)); + hex_print_with_offset("\n\t\t\t\t[", ILV_DATA(ilv), rlen, 0); + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +print_metatlv(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent) +{ + u_int dlen; + char *ib = indent_pr(indent, 0); + u_int rlen; + const struct forces_ilv *ilv = (struct forces_ilv *)pptr; + int invilv; + + /* + * redirect_print() has ensured that len (what remains in the + * TLV) >= TLV_HDRL. + */ + dlen = len - TLV_HDRL; + rlen = dlen; + printf("\n%s METADATA\n", ib); + while (rlen != 0) { + TCHECK(*ilv); + invilv = ilv_valid(ilv, rlen); + if (invilv) + break; + + /* + * At this point, ilv_valid() has ensured that the ILV + * length is large enough but not too large (it doesn't + * go past the end of the containing TLV). + */ + print_metailv((u_char *) ilv, rlen, 0, indent + 1); + + ilv = GO_NXT_ILV(ilv, rlen); + } + + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +/* +*/ +int +print_reddata(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent _U_) +{ + u_int dlen; + u_int rlen; + int invtlv; + const struct forces_tlv *tlv = (struct forces_tlv *)pptr; + + /* + * redirect_print() has ensured that len (what remains in the + * TLV) >= TLV_HDRL. + */ + dlen = len - TLV_HDRL; + printf("\n\t\t Redirect DATA\n"); + if (dlen <= RD_MIN) { + printf("\n\t\ttruncated Redirect data: %d bytes missing! ", + RD_MIN - dlen); + return -1; + } + + rlen = dlen; + TCHECK(*tlv); + invtlv = tlv_valid(tlv, rlen); + + if (invtlv) { + printf("Redir data type 0x%x len %d\n", EXTRACT_16BITS(&tlv->type), + EXTRACT_16BITS(&tlv->length)); + return -1; + } + + /* + * At this point, tlv_valid() has ensured that the TLV + * length is large enough but not too large (it doesn't + * go past the end of the containing TLV). + */ + rlen -= TLV_HDRL; + hex_print_with_offset("\n\t\t\t[", TLV_DATA(tlv), rlen, 0); + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +redirect_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent) +{ + const struct forces_tlv *tlv = (struct forces_tlv *)pptr; + u_int dlen; + u_int rlen; + int invtlv; + + /* + * forces_type_print() has ensured that len (the TLV length) + * >= TLV_HDRL. + */ + dlen = len - TLV_HDRL; + if (dlen <= RD_MIN) { + printf("\n\t\ttruncated Redirect TLV: %d bytes missing! ", + RD_MIN - dlen); + return -1; + } + + rlen = dlen; + indent += 1; + while (rlen != 0) { + TCHECK(*tlv); + invtlv = tlv_valid(tlv, rlen); + if (invtlv) + break; + + /* + * At this point, tlv_valid() has ensured that the TLV + * length is large enough but not too large (it doesn't + * go past the end of the containing TLV). + */ + if (EXTRACT_16BITS(&tlv->type) == F_TLV_METD) { + print_metatlv((u_char *) TLV_DATA(tlv), rlen, 0, indent); + } else if ((EXTRACT_16BITS(&tlv->type) == F_TLV_REDD)) { + print_reddata((u_char *) TLV_DATA(tlv), rlen, 0, indent); + } else { + printf("Unknown REDIRECT TLV 0x%x len %d\n", + EXTRACT_16BITS(&tlv->type), EXTRACT_16BITS(&tlv->length)); + } + + tlv = GO_NXT_TLV(tlv, rlen); + } + + if (rlen) { + printf + ("\n\t\tMessy Redirect TLV header, type (0x%x)\n\t\texcess of %d Bytes ", + EXTRACT_16BITS(&tlv->type), rlen - EXTRACT_16BITS(&tlv->length)); + return -1; + } + + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +#define OP_OFF 8 +#define OP_MIN 12 + +int +lfbselect_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent) +{ + const struct forces_lfbsh *lfbs; + const struct forces_tlv *otlv; + char *ib = indent_pr(indent, 0); + u_int dlen; + u_int rlen; + int invtlv; + + /* + * forces_type_print() has ensured that len (the TLV length) + * >= TLV_HDRL. + */ + dlen = len - TLV_HDRL; + if (dlen <= OP_MIN) { /* id, instance, oper tlv header .. */ + printf("\n\t\ttruncated lfb selector: %d bytes missing! ", + OP_MIN - dlen); + return -1; + } + + /* + * At this point, we know that dlen > OP_MIN; OP_OFF < OP_MIN, so + * we also know that it's > OP_OFF. + */ + rlen = dlen - OP_OFF; + + lfbs = (const struct forces_lfbsh *)pptr; + TCHECK(*lfbs); + if (vflag >= 3) { + printf("\n%s%s(Classid %x) instance %x\n", + ib, tok2str(ForCES_LFBs, NULL, EXTRACT_32BITS(&lfbs->class)), + EXTRACT_32BITS(&lfbs->class), + EXTRACT_32BITS(&lfbs->instance)); + } + + otlv = (struct forces_tlv *)(lfbs + 1); + + indent += 1; + while (rlen != 0) { + TCHECK(*otlv); + invtlv = tlv_valid(otlv, rlen); + if (invtlv) + break; + + /* + * At this point, tlv_valid() has ensured that the TLV + * length is large enough but not too large (it doesn't + * go past the end of the containing TLV). + */ + if (op_valid(EXTRACT_16BITS(&otlv->type), op_msk)) { + otlv_print(otlv, 0, indent); + } else { + if (vflag < 3) + printf("\n"); + printf + ("\t\tINValid oper-TLV type 0x%x length %d for this ForCES message\n", + EXTRACT_16BITS(&otlv->type), EXTRACT_16BITS(&otlv->length)); + invoptlv_print((u_char *)otlv, rlen, 0, indent); + } + otlv = GO_NXT_TLV(otlv, rlen); + } + + if (rlen) { + printf + ("\n\t\tMessy oper TLV header, type (0x%x)\n\t\texcess of %d Bytes ", + EXTRACT_16BITS(&otlv->type), rlen - EXTRACT_16BITS(&otlv->length)); + return -1; + } + + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +forces_type_print(register const u_char * pptr, const struct forcesh *fhdr _U_, + register u_int mlen, const struct tom_h *tops) +{ + const struct forces_tlv *tltlv; + u_int rlen; + int invtlv; + int rc = 0; + int ttlv = 0; + + /* + * forces_print() has already checked that mlen >= ForCES_HDRL + * by calling ForCES_HLN_VALID(). + */ + rlen = mlen - ForCES_HDRL; + + if (rlen > TLV_HLN) { + if (tops->flags & ZERO_TTLV) { + printf("<0x%x>Illegal Top level TLV!\n", tops->flags); + return -1; + } + } else { + if (tops->flags & ZERO_MORE_TTLV) + return 0; + if (tops->flags & ONE_MORE_TTLV) { + printf("\tTop level TLV Data missing!\n"); + return -1; + } + } + + if (tops->flags & ZERO_TTLV) { + return 0; + } + + ttlv = tops->flags >> 4; + tltlv = GET_TOP_TLV(pptr); + + /*XXX: 15 top level tlvs will probably be fine + You are nuts if you send more ;-> */ + while (rlen != 0) { + TCHECK(*tltlv); + invtlv = tlv_valid(tltlv, rlen); + if (invtlv) + break; + + /* + * At this point, tlv_valid() has ensured that the TLV + * length is large enough but not too large (it doesn't + * go past the end of the packet). + */ + if (!ttlv_valid(EXTRACT_16BITS(&tltlv->type))) { + printf("\n\tInvalid ForCES Top TLV type=0x%x", + EXTRACT_16BITS(&tltlv->type)); + return -1; + } + + if (vflag >= 3) + printf("\t%s, length %d (data length %d Bytes)", + tok2str(ForCES_TLV, NULL, EXTRACT_16BITS(&tltlv->type)), + EXTRACT_16BITS(&tltlv->length), + EXTRACT_16BITS(&tltlv->length) - TLV_HDRL); + + rc = tops->print((u_char *) TLV_DATA(tltlv), + EXTRACT_16BITS(&tltlv->length), tops->op_msk, 9); + if (rc < 0) { + return -1; + } + tltlv = GO_NXT_TLV(tltlv, rlen); + ttlv--; + if (ttlv <= 0) + break; + } + /* + * XXX - if ttlv != 0, does that mean that the packet was too + * short, and didn't have *enough* TLVs in it? + */ + if (rlen) { + printf("\tMess TopTLV header: min %u, total %d advertised %d ", + TLV_HDRL, rlen, EXTRACT_16BITS(&tltlv->length)); + return -1; + } + + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +void forces_print(register const u_char * pptr, register u_int len) +{ + const struct forcesh *fhdr; + u_int mlen; + u_int32_t flg_raw; + const struct tom_h *tops; + int rc = 0; + + fhdr = (const struct forcesh *)pptr; + TCHECK(*fhdr); + if (!tom_valid(fhdr->fm_tom)) { + printf("Invalid ForCES message type %d\n", fhdr->fm_tom); + goto error; + } + + mlen = ForCES_BLN(fhdr); + + tops = get_forces_tom(fhdr->fm_tom); + if (tops->v == TOM_RSVD) { + printf("\n\tUnknown ForCES message type=0x%x", fhdr->fm_tom); + goto error; + } + + printf("\n\tForCES %s ", tops->s); + if (!ForCES_HLN_VALID(mlen, len)) { + printf + ("Illegal ForCES pkt len - min %u, total recvd %d, advertised %d ", + ForCES_HDRL, len, ForCES_BLN(fhdr)); + goto error; + } + + TCHECK2(*(pptr + 20), 4); + flg_raw = EXTRACT_32BITS(pptr + 20); + if (vflag >= 1) { + printf("\n\tForCES Version %d len %uB flags 0x%08x ", + ForCES_V(fhdr), mlen, flg_raw); + printf("\n\tSrcID 0x%x(%s) DstID 0x%x(%s) Correlator 0x%" PRIu64, + ForCES_SID(fhdr), ForCES_node(ForCES_SID(fhdr)), + ForCES_DID(fhdr), ForCES_node(ForCES_DID(fhdr)), + EXTRACT_64BITS(fhdr->fm_cor)); + + } + if (vflag >= 2) { + printf + ("\n\tForCES flags:\n\t %s(0x%x), prio=%d, %s(0x%x),\n\t %s(0x%x), %s(0x%x)\n", + ForCES_ACKp(ForCES_ACK(fhdr)), ForCES_ACK(fhdr), + ForCES_PRI(fhdr), + ForCES_EMp(ForCES_EM(fhdr)), ForCES_EM(fhdr), + ForCES_ATp(ForCES_AT(fhdr)), ForCES_AT(fhdr), + ForCES_TPp(ForCES_TP(fhdr)), ForCES_TP(fhdr)); + printf + ("\t Extra flags: rsv(b5-7) 0x%x rsv(b13-31) 0x%x\n", + ForCES_RS1(fhdr), ForCES_RS2(fhdr)); + } + rc = forces_type_print(pptr, fhdr, mlen, tops); + if (rc < 0) { +error: + hex_print_with_offset("\n\t[", pptr, len, 0); + printf("\n\t]"); + return; + } + + if (vflag >= 4) { + printf("\n\t Raw ForCES message\n\t ["); + hex_print_with_offset("\n\t ", pptr, len, 0); + printf("\n\t ]"); + } + printf("\n"); + return; + +trunc: + fputs("[|forces]", stdout); +} diff --git a/contrib/tcpdump/print-fr.c b/contrib/tcpdump/print-fr.c index f71aee6652..51263066a7 100644 --- a/contrib/tcpdump/print-fr.c +++ b/contrib/tcpdump/print-fr.c @@ -256,11 +256,10 @@ fr_print(register const u_char *p, u_int length) if (eflag) fr_hdr_print(length, addr_len, dlci, flags, extracted_ethertype); - if (ether_encap_print(extracted_ethertype, + if (ethertype_print(gndo, extracted_ethertype, p+addr_len+ETHERTYPE_LEN, length-addr_len-ETHERTYPE_LEN, - length-addr_len-ETHERTYPE_LEN, - &extracted_ethertype) == 0) + length-addr_len-ETHERTYPE_LEN) == 0) /* ether_type not known, probably it wasn't one */ printf("UI %02x! ", p[addr_len]); else @@ -287,7 +286,7 @@ fr_print(register const u_char *p, u_int length) #ifdef INET6 case NLPID_IP6: - ip6_print(p, length); + ip6_print(gndo, p, length); break; #endif case NLPID_CLNP: @@ -297,7 +296,7 @@ fr_print(register const u_char *p, u_int length) break; case NLPID_SNAP: - if (snap_print(p, length, length, &extracted_ethertype, 0) == 0) { + if (snap_print(p, length, length, 0) == 0) { /* ether_type not known, print raw packet */ if (!eflag) fr_hdr_print(length + hdr_len, hdr_len, diff --git a/contrib/tcpdump/print-gre.c b/contrib/tcpdump/print-gre.c index 55f0e9d16b..b6fa522366 100644 --- a/contrib/tcpdump/print-gre.c +++ b/contrib/tcpdump/print-gre.c @@ -210,7 +210,7 @@ gre_print_0(const u_char *bp, u_int length) break; #ifdef INET6 case ETHERTYPE_IPV6: - ip6_print(bp, len); + ip6_print(gndo, bp, len); break; #endif case ETHERTYPE_MPLS: @@ -225,6 +225,9 @@ gre_print_0(const u_char *bp, u_int length) case ETHERTYPE_GRE_ISO: isoclns_print(bp, len, len); break; + case ETHERTYPE_TEB: + ether_print(gndo, bp, len, len, NULL, NULL); + break; default: printf("gre-proto-0x%x", prot); } diff --git a/contrib/tcpdump/print-icmp.c b/contrib/tcpdump/print-icmp.c index 36bff6a412..03b9505b11 100644 --- a/contrib/tcpdump/print-icmp.c +++ b/contrib/tcpdump/print-icmp.c @@ -346,6 +346,7 @@ icmp_print(const u_char *bp, u_int plen, const u_char *bp2, int fragmented) const struct icmp_mpls_ext_object_header_t *icmp_mpls_ext_object_header; u_int hlen, dport, mtu, obj_tlen, obj_class_num, obj_ctype; char buf[MAXHOSTNAMELEN + 100]; + struct cksum_vec vec[1]; dp = (struct icmp *)bp; ext_dp = (struct icmp_ext_t *)bp; @@ -560,8 +561,11 @@ icmp_print(const u_char *bp, u_int plen, const u_char *bp2, int fragmented) (void)printf("ICMP %s, length %u", str, plen); if (vflag && !fragmented) { /* don't attempt checksumming if this is a frag */ u_int16_t sum, icmp_sum; + struct cksum_vec vec[1]; if (TTEST2(*bp, plen)) { - sum = in_cksum((u_short*)dp, plen, 0); + vec[0].ptr = (const u_int8_t *)(void *)dp; + vec[0].len = plen; + sum = in_cksum(vec, 1); if (sum != 0) { icmp_sum = EXTRACT_16BITS(&dp->icmp_cksum); (void)printf(" (wrong icmp cksum %x (->%x)!)", @@ -598,10 +602,12 @@ icmp_print(const u_char *bp, u_int plen, const u_char *bp2, int fragmented) * to check if an extension header is present. This is expedient, * however not all implementations set the length field proper. */ - if (!ext_dp->icmp_length && - in_cksum((const u_short *)&ext_dp->icmp_ext_version_res, - plen - ICMP_EXTD_MINLEN, 0)) { - return; + if (!ext_dp->icmp_length) { + vec[0].ptr = (const u_int8_t *)(void *)&ext_dp->icmp_ext_version_res; + vec[0].len = plen - ICMP_EXTD_MINLEN; + if (in_cksum(vec, 1)) { + return; + } } printf("\n\tMPLS extension v%u", @@ -617,10 +623,11 @@ icmp_print(const u_char *bp, u_int plen, const u_char *bp2, int fragmented) } hlen = plen - ICMP_EXTD_MINLEN; + vec[0].ptr = (const u_int8_t *)(void *)&ext_dp->icmp_ext_version_res; + vec[0].len = hlen; printf(", checksum 0x%04x (%scorrect), length %u", EXTRACT_16BITS(ext_dp->icmp_ext_checksum), - in_cksum((const u_short *)&ext_dp->icmp_ext_version_res, - plen - ICMP_EXTD_MINLEN, 0) ? "in" : "", + in_cksum(vec, 1) ? "in" : "", hlen); hlen -= 4; /* subtract common header size */ diff --git a/contrib/tcpdump/print-icmp6.c b/contrib/tcpdump/print-icmp6.c index 41d56b68da..ce1046ed2e 100644 --- a/contrib/tcpdump/print-icmp6.c +++ b/contrib/tcpdump/print-icmp6.c @@ -21,7 +21,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-icmp6.c,v 1.85.2.1 2008-02-05 19:36:58 guy Exp $"; + "@(#) $Header: /tcpdump/master/tcpdump/print-icmp6.c,v 1.86 2008-02-05 19:36:13 guy Exp $"; #endif #ifdef HAVE_CONFIG_H @@ -62,6 +62,9 @@ static void icmp6_rrenum_print(const u_char *, const u_char *); #define abs(a) ((0 < (a)) ? (a) : -(a)) #endif +/* inline the various RPL definitions */ +#define ND_RPL_MESSAGE 0x9B + static struct tok icmp6_type_values[] = { { ICMP6_DST_UNREACH, "destination unreachable"}, { ICMP6_PACKET_TOO_BIG, "packet too big"}, @@ -91,6 +94,7 @@ static struct tok icmp6_type_values[] = { { ICMP6_NI_REPLY, "node information reply"}, { MLD6_MTRACE, "mtrace message"}, { MLD6_MTRACE_RESP, "mtrace response"}, + { ND_RPL_MESSAGE, "RPL"}, { 0, NULL } }; @@ -131,6 +135,7 @@ static struct tok icmp6_opt_values[] = { { ND_OPT_PREFIX_INFORMATION, "prefix info"}, { ND_OPT_REDIRECTED_HEADER, "redirected header"}, { ND_OPT_MTU, "mtu"}, + { ND_OPT_RDNSS, "rdnss"}, { ND_OPT_ADVINTERVAL, "advertisement interval"}, { ND_OPT_HOMEAGENT_INFO, "homeagent information"}, { ND_OPT_ROUTE_INFO, "route info"}, @@ -192,48 +197,110 @@ print_lladdr(const u_int8_t *p, size_t l) static int icmp6_cksum(const struct ip6_hdr *ip6, const struct icmp6_hdr *icp, u_int len) { - size_t i; - register 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_ICMPV6; - - sum = 0; - for (i = 0; i < sizeof(phu.pa) / sizeof(phu.pa[0]); i++) - sum += phu.pa[i]; - - sp = (const u_int16_t *)icp; - - 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); + return (nextproto6_cksum(ip6, (const u_int8_t *)(void *)icp, len, + IPPROTO_ICMPV6)); +} + +enum ND_RPL_CODE { + ND_RPL_DIS =0x00, + ND_RPL_DIO =0x01, + ND_RPL_DAO =0x02, + ND_RPL_DAO_ACK=0x03, + ND_RPL_SDIS =0x80, + ND_RPL_SDIO =0x81, + ND_RPL_SDAO =0x82, + ND_RPL_SDAO_ACK=0x83, + ND_RPL_SCC =0x8A, +}; + +enum ND_RPL_DIO_FLAGS { + ND_RPL_DIO_GROUNDED = 0x80, + ND_RPL_DIO_DATRIG = 0x40, + ND_RPL_DIO_DASUPPORT= 0x20, + ND_RPL_DIO_RES4 = 0x10, + ND_RPL_DIO_RES3 = 0x08, + ND_RPL_DIO_PRF_MASK = 0x07, /* 3-bit preference */ +}; + +struct nd_rpl_dio { + u_int8_t rpl_flags; + u_int8_t rpl_seq; + u_int8_t rpl_instanceid; + u_int8_t rpl_dagrank; + u_int8_t rpl_dagid[16]; +}; + +static void +rpl_print(netdissect_options *ndo, + const struct icmp6_hdr *hdr, + const u_char *bp, u_int length _U_) +{ + struct nd_rpl_dio *dio = (struct nd_rpl_dio *)bp; + int secured = hdr->icmp6_code & 0x80; + int basecode= hdr->icmp6_code & 0x7f; + + ND_TCHECK(dio->rpl_dagid); + + if(secured) { + ND_PRINT((ndo, ", (SEC)")); + } else { + ND_PRINT((ndo, ", (CLR)")); + } + + switch(basecode) { + case ND_RPL_DIS: + ND_PRINT((ndo, "DODAG Information Solicitation")); + if(ndo->ndo_vflag) { + } + break; + case ND_RPL_DIO: + ND_PRINT((ndo, "DODAG Information Object")); + if(ndo->ndo_vflag) { + char dagid[65]; + char *d = dagid; + int i; + for(i=0;i<16;i++) { + if(isprint(dio->rpl_dagid[i])) { + *d++ = dio->rpl_dagid[i]; + } else { + int cnt=snprintf(d,4,"0x%02x", + dio->rpl_dagid[i]); + d += cnt; + } + } + *d++ = '\0'; + ND_PRINT((ndo, " [seq:%u,instance:%u,rank:%u,dagid:%s]", + dio->rpl_seq, + dio->rpl_instanceid, + dio->rpl_dagrank, + dagid)); + } + break; + case ND_RPL_DAO: + ND_PRINT((ndo, "Destination Advertisement Object")); + if(ndo->ndo_vflag) { + } + break; + case ND_RPL_DAO_ACK: + ND_PRINT((ndo, "Destination Advertisement Object Ack")); + if(ndo->ndo_vflag) { + } + break; + default: + ND_PRINT((ndo, "RPL message, unknown code %u",hdr->icmp6_code)); + break; + } + return; +trunc: + ND_PRINT((ndo," [|truncated]")); + return; + } + void -icmp6_print(const u_char *bp, u_int length, const u_char *bp2, int fragmented) +icmp6_print(netdissect_options *ndo, + const u_char *bp, u_int length, const u_char *bp2, int fragmented) { const struct icmp6_hdr *dp; const struct ip6_hdr *ip; @@ -252,12 +319,15 @@ icmp6_print(const u_char *bp, u_int length, const u_char *bp2, int fragmented) TCHECK(dp->icmp6_cksum); if (vflag && !fragmented) { - int sum = dp->icmp6_cksum; + u_int16_t sum, udp_sum; if (TTEST2(bp[0], length)) { + udp_sum = EXTRACT_16BITS(&dp->icmp6_cksum); sum = icmp6_cksum(ip, dp, length); if (sum != 0) - (void)printf("[bad icmp6 cksum %x!] ", sum); + (void)printf("[bad icmp6 cksum 0x%04x -> 0x%04x!] ", + udp_sum, + in_cksum_shouldbe(udp_sum, sum)); else (void)printf("[icmp6 sum ok] "); } @@ -266,14 +336,13 @@ icmp6_print(const u_char *bp, u_int length, const u_char *bp2, int fragmented) printf("ICMP6, %s", tok2str(icmp6_type_values,"unknown icmp6 type (%u)",dp->icmp6_type)); /* display cosmetics: print the packet length for printer that use the vflag now */ - if (vflag && (dp->icmp6_type == - ND_ROUTER_SOLICIT || - ND_ROUTER_ADVERT || - ND_NEIGHBOR_ADVERT || - ND_NEIGHBOR_SOLICIT || - ND_REDIRECT || - ICMP6_HADISCOV_REPLY || - ICMP6_MOBILEPREFIX_ADVERT )) + if (vflag && (dp->icmp6_type == ND_ROUTER_SOLICIT || + dp->icmp6_type == ND_ROUTER_ADVERT || + dp->icmp6_type == ND_NEIGHBOR_ADVERT || + dp->icmp6_type == ND_NEIGHBOR_SOLICIT || + dp->icmp6_type == ND_REDIRECT || + dp->icmp6_type == ICMP6_HADISCOV_REPLY || + dp->icmp6_type == ICMP6_MOBILEPREFIX_ADVERT )) printf(", length %u", length); switch (dp->icmp6_type) { @@ -505,6 +574,9 @@ icmp6_print(const u_char *bp, u_int length, const u_char *bp2, int fragmented) length - MPADVLEN); } break; + case ND_RPL_MESSAGE: + rpl_print(ndo, dp, &dp->icmp6_data8[0], length); + break; default: printf(", length %u", length); if (vflag <= 1) @@ -600,12 +672,14 @@ icmp6_opt_print(const u_char *bp, int resid) const struct nd_opt_prefix_info *opp; const struct icmp6_opts_redirect *opr; const struct nd_opt_mtu *opm; + const struct nd_opt_rdnss *oprd; const struct nd_opt_advinterval *opa; const struct nd_opt_homeagent_info *oph; const struct nd_opt_route_info *opri; const u_char *cp, *ep; struct in6_addr in6, *in6p; size_t l; + u_int i; #define ECHECK(var) if ((u_char *)&(var) > ep - sizeof(var)) return @@ -664,6 +738,17 @@ icmp6_opt_print(const u_char *bp, int resid) EXTRACT_32BITS(&opm->nd_opt_mtu_mtu), (op->nd_opt_len != 1) ? "bad option length" : "" ); break; + case ND_OPT_RDNSS: + oprd = (struct nd_opt_rdnss *)op; + l = (op->nd_opt_len - 1) / 2; + printf(" lifetime %us,", + EXTRACT_32BITS(&oprd->nd_opt_rdnss_lifetime)); + for (i = 0; i < l; i++) { + TCHECK(oprd->nd_opt_rdnss_addr[i]); + printf(" addr: %s", + ip6addr_string(&oprd->nd_opt_rdnss_addr[i])); + } + break; case ND_OPT_ADVINTERVAL: opa = (struct nd_opt_advinterval *)op; TCHECK(opa->nd_opt_adv_interval); @@ -753,7 +838,7 @@ mldv2_report_print(const u_char *bp, u_int len) } TCHECK(icp->icmp6_data16[1]); - ngroups = ntohs(icp->icmp6_data16[1]); + ngroups = EXTRACT_16BITS(&icp->icmp6_data16[1]); printf(", %d group record(s)", ngroups); if (vflag > 0) { /* Print the group records */ @@ -812,7 +897,7 @@ mldv2_query_print(const u_char *bp, u_int len) return; } TCHECK(icp->icmp6_data16[0]); - mrc = ntohs(icp->icmp6_data16[0]); + mrc = EXTRACT_16BITS(&icp->icmp6_data16[0]); if (mrc < 32768) { mrt = mrc; } else { @@ -841,7 +926,7 @@ mldv2_query_print(const u_char *bp, u_int len) } TCHECK2(bp[26], 2); - nsrcs = ntohs(*(u_short *)&bp[26]); + nsrcs = EXTRACT_16BITS(&bp[26]); if (nsrcs > 0) { if (len < 28 + nsrcs * sizeof(struct in6_addr)) printf(" [invalid number of sources]"); @@ -863,7 +948,7 @@ trunc: return; } -void +static void dnsname_print(const u_char *cp, const u_char *ep) { int i; diff --git a/contrib/tcpdump/print-igmp.c b/contrib/tcpdump/print-igmp.c index a848562985..6522bc3044 100644 --- a/contrib/tcpdump/print-igmp.c +++ b/contrib/tcpdump/print-igmp.c @@ -259,6 +259,8 @@ trunc: void igmp_print(register const u_char *bp, register u_int len) { + struct cksum_vec vec[1]; + if (qflag) { (void)printf("igmp"); return; @@ -327,7 +329,9 @@ igmp_print(register const u_char *bp, register u_int len) if (vflag && TTEST2(bp[0], len)) { /* Check the IGMP checksum */ - if (in_cksum((const u_short*)bp, len, 0)) + vec[0].ptr = bp; + vec[0].len = len; + if (in_cksum(vec, 1)) printf(" bad igmp cksum %x!", EXTRACT_16BITS(&bp[2])); } return; diff --git a/contrib/tcpdump/print-ip.c b/contrib/tcpdump/print-ip.c index 8bdf5ebce3..1fa7aab0d6 100644 --- a/contrib/tcpdump/print-ip.c +++ b/contrib/tcpdump/print-ip.c @@ -87,7 +87,7 @@ ip_printroute(register const u_char *cp, u_int length) * This is used for UDP and TCP pseudo-header in the checksum * calculation. */ -u_int32_t +static u_int32_t ip_finddst(const struct ip *ip) { int length; @@ -129,6 +129,39 @@ trunc: return retval; } +/* + * Compute a V4-style checksum by building a pseudoheader. + */ +int +nextproto4_cksum(const struct ip *ip, const u_int8_t *data, + u_int len, u_int next_proto) +{ + struct phdr { + u_int32_t src; + u_int32_t dst; + u_char mbz; + u_char proto; + u_int16_t len; + } ph; + struct cksum_vec vec[2]; + + /* pseudo-header.. */ + ph.len = htons((u_int16_t)len); + ph.mbz = 0; + ph.proto = next_proto; + memcpy(&ph.src, &ip->ip_src.s_addr, sizeof(u_int32_t)); + if (IP_HL(ip) == 5) + memcpy(&ph.dst, &ip->ip_dst.s_addr, sizeof(u_int32_t)); + else + ph.dst = ip_finddst(ip); + + vec[0].ptr = (const u_int8_t *)(void *)&ph; + vec[0].len = sizeof(ph); + vec[1].ptr = data; + vec[1].len = len; + return (in_cksum(vec, 2)); +} + static void ip_printts(register const u_char *cp, u_int length) { @@ -268,92 +301,6 @@ trunc: printf("[|ip]"); } -/* - * compute an IP header checksum. - * don't modifiy the packet. - */ -u_short -in_cksum(const u_short *addr, register u_int len, int csum) -{ - int nleft = len; - const u_short *w = addr; - u_short answer; - int sum = csum; - - /* - * Our algorithm is simple, using a 32 bit accumulator (sum), - * we add sequential 16 bit words to it, and at the end, fold - * back all the carry bits from the top 16 bits into the lower - * 16 bits. - */ - while (nleft > 1) { - sum += *w++; - nleft -= 2; - } - if (nleft == 1) - sum += htons(*(u_char *)w<<8); - - /* - * add back carry outs from top 16 bits to low 16 bits - */ - sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ - sum += (sum >> 16); /* add carry */ - answer = ~sum; /* truncate to 16 bits */ - return (answer); -} - -/* - * Given the host-byte-order value of the checksum field in a packet - * header, and the network-byte-order computed checksum of the data - * that the checksum covers (including the checksum itself), compute - * what the checksum field *should* have been. - */ -u_int16_t -in_cksum_shouldbe(u_int16_t sum, u_int16_t computed_sum) -{ - u_int32_t shouldbe; - - /* - * The value that should have gone into the checksum field - * is the negative of the value gotten by summing up everything - * *but* the checksum field. - * - * We can compute that by subtracting the value of the checksum - * field from the sum of all the data in the packet, and then - * computing the negative of that value. - * - * "sum" is the value of the checksum field, and "computed_sum" - * is the negative of the sum of all the data in the packets, - * so that's -(-computed_sum - sum), or (sum + computed_sum). - * - * All the arithmetic in question is one's complement, so the - * addition must include an end-around carry; we do this by - * doing the arithmetic in 32 bits (with no sign-extension), - * and then adding the upper 16 bits of the sum, which contain - * the carry, to the lower 16 bits of the sum, and then do it - * again in case *that* sum produced a carry. - * - * As RFC 1071 notes, the checksum can be computed without - * byte-swapping the 16-bit words; summing 16-bit words - * on a big-endian machine gives a big-endian checksum, which - * can be directly stuffed into the big-endian checksum fields - * in protocol headers, and summing words on a little-endian - * machine gives a little-endian checksum, which must be - * byte-swapped before being stuffed into a big-endian checksum - * field. - * - * "computed_sum" is a network-byte-order value, so we must put - * it in host byte order before subtracting it from the - * host-byte-order value from the header; the adjusted checksum - * will be in host byte order, which is what we'll return. - */ - shouldbe = sum; - shouldbe += ntohs(computed_sum); - shouldbe = (shouldbe & 0xFFFF) + (shouldbe >> 16); - shouldbe = (shouldbe & 0xFFFF) + (shouldbe >> 16); - return shouldbe; -} - #define IP_RES 0x8000 static struct tok ip_frag_values[] = { @@ -376,6 +323,7 @@ ip_print_demux(netdissect_options *ndo, struct ip_print_demux_state *ipds) { struct protoent *proto; + struct cksum_vec vec[1]; again: switch (ipds->nh) { @@ -480,7 +428,7 @@ again: case IPPROTO_IPV4: /* DVMRP multicast tunnel (ip-in-ip encapsulation) */ - ip_print(gndo, ipds->cp, ipds->len); + ip_print(ndo, ipds->cp, ipds->len); if (! vflag) { ND_PRINT((ndo, " (ipip-proto-4)")); return; @@ -490,7 +438,7 @@ again: #ifdef INET6 case IPPROTO_IPV6: /* ip6-in-ip encapsulation */ - ip6_print(ipds->cp, ipds->len); + ip6_print(ndo, ipds->cp, ipds->len); break; #endif /*INET6*/ @@ -508,11 +456,25 @@ again: break; case IPPROTO_PIM: - pim_print(ipds->cp, ipds->len); + vec[0].ptr = ipds->cp; + vec[0].len = ipds->len; + pim_print(ipds->cp, ipds->len, in_cksum(vec, 1)); break; case IPPROTO_VRRP: - vrrp_print(ipds->cp, ipds->len, ipds->ip->ip_ttl); + if (packettype == PT_CARP) { + if (vflag) + (void)printf("carp %s > %s: ", + ipaddr_string(&ipds->ip->ip_src), + ipaddr_string(&ipds->ip->ip_dst)); + carp_print(ipds->cp, ipds->len, ipds->ip->ip_ttl); + } else { + if (vflag) + (void)printf("vrrp %s > %s: ", + ipaddr_string(&ipds->ip->ip_src), + ipaddr_string(&ipds->ip->ip_dst)); + vrrp_print(ipds->cp, ipds->len, ipds->ip->ip_ttl); + } break; case IPPROTO_PGM: @@ -560,6 +522,7 @@ ip_print(netdissect_options *ndo, struct ip_print_demux_state *ipds=&ipd; const u_char *ipend; u_int hlen; + struct cksum_vec vec[1]; u_int16_t sum, ip_sum; struct protoent *proto; @@ -572,7 +535,7 @@ ip_print(netdissect_options *ndo, else if (!eflag) printf("IP "); - if ((u_char *)(ipds->ip + 1) > snapend) { + if ((u_char *)(ipds->ip + 1) > ndo->ndo_snapend) { printf("[|ip]"); return; } @@ -610,8 +573,8 @@ ip_print(netdissect_options *ndo, * Cut off the snapshot length to the end of the IP payload. */ ipend = bp + ipds->len; - if (ipend < snapend) - snapend = ipend; + if (ipend < ndo->ndo_snapend) + ndo->ndo_snapend = ipend; ipds->len -= hlen; @@ -657,8 +620,10 @@ ip_print(netdissect_options *ndo, printf(")"); } - if ((u_char *)ipds->ip + hlen <= snapend) { - sum = in_cksum((const u_short *)ipds->ip, hlen, 0); + if (!Kflag && (u_char *)ipds->ip + hlen <= ndo->ndo_snapend) { + vec[0].ptr = (const u_int8_t *)(void *)ipds->ip; + vec[0].len = hlen; + sum = in_cksum(vec, 1); if (sum != 0) { ip_sum = EXTRACT_16BITS(&ipds->ip->ip_sum); (void)printf(", bad cksum %x (->%x)!", ip_sum, @@ -721,7 +686,7 @@ ipN_print(register const u_char *bp, register u_int length) return; #ifdef INET6 case 6: - ip6_print (bp, length); + ip6_print (gndo, bp, length); return; #endif default: diff --git a/contrib/tcpdump/print-ip6.c b/contrib/tcpdump/print-ip6.c index 0758bb952e..f5e62441ea 100644 --- a/contrib/tcpdump/print-ip6.c +++ b/contrib/tcpdump/print-ip6.c @@ -36,6 +36,7 @@ static const char rcsid[] _U_ = #include #include +#include "netdissect.h" #include "interface.h" #include "addrtoname.h" #include "extract.h" @@ -43,11 +44,42 @@ static const char rcsid[] _U_ = #include "ip6.h" #include "ipproto.h" +/* + * Compute a V6-style checksum by building a pseudoheader. + */ +int +nextproto6_cksum(const struct ip6_hdr *ip6, const u_int8_t *data, + u_int len, u_int next_proto) +{ + 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; + struct cksum_vec vec[2]; + + /* pseudo-header */ + memset(&ph, 0, sizeof(ph)); + ph.ph_src = ip6->ip6_src; + ph.ph_dst = ip6->ip6_dst; + ph.ph_len = htonl(len); + ph.ph_nxt = next_proto; + + vec[0].ptr = (const u_int8_t *)(void *)&ph; + vec[0].len = sizeof(ph); + vec[1].ptr = data; + vec[1].len = len; + + return in_cksum(vec, 2); +} + /* * print an IP6 datagram. */ void -ip6_print(register const u_char *bp, register u_int length) +ip6_print(netdissect_options *ndo, const u_char *bp, u_int length) { register const struct ip6_hdr *ip6; register int advance; @@ -63,62 +95,62 @@ ip6_print(register const u_char *bp, register u_int length) TCHECK(*ip6); if (length < sizeof (struct ip6_hdr)) { - (void)printf("truncated-ip6 %u", length); + (void)ND_PRINT((ndo, "truncated-ip6 %u", length)); return; } - if (!eflag) - printf("IP6 "); + if (!ndo->ndo_eflag) + ND_PRINT((ndo, "IP6 ")); payload_len = EXTRACT_16BITS(&ip6->ip6_plen); len = payload_len + sizeof(struct ip6_hdr); if (length < len) - (void)printf("truncated-ip6 - %u bytes missing!", - len - length); + (void)ND_PRINT((ndo, "truncated-ip6 - %u bytes missing!", + len - length)); - if (vflag) { + if (ndo->ndo_vflag) { flow = EXTRACT_32BITS(&ip6->ip6_flow); - printf("("); + ND_PRINT((ndo, "(")); #if 0 /* rfc1883 */ if (flow & 0x0f000000) - (void)printf("pri 0x%02x, ", (flow & 0x0f000000) >> 24); + (void)ND_PRINT((ndo, "pri 0x%02x, ", (flow & 0x0f000000) >> 24)); if (flow & 0x00ffffff) - (void)printf("flowlabel 0x%06x, ", flow & 0x00ffffff); + (void)ND_PRINT((ndo, "flowlabel 0x%06x, ", flow & 0x00ffffff)); #else /* RFC 2460 */ if (flow & 0x0ff00000) - (void)printf("class 0x%02x, ", (flow & 0x0ff00000) >> 20); + (void)ND_PRINT((ndo, "class 0x%02x, ", (flow & 0x0ff00000) >> 20)); if (flow & 0x000fffff) - (void)printf("flowlabel 0x%05x, ", flow & 0x000fffff); + (void)ND_PRINT((ndo, "flowlabel 0x%05x, ", flow & 0x000fffff)); #endif - (void)printf("hlim %u, next-header %s (%u) payload length: %u) ", + (void)ND_PRINT((ndo, "hlim %u, next-header %s (%u) payload length: %u) ", ip6->ip6_hlim, tok2str(ipproto_values,"unknown",ip6->ip6_nxt), ip6->ip6_nxt, - payload_len); + payload_len)); } /* * Cut off the snapshot length to the end of the IP payload. */ ipend = bp + len; - if (ipend < snapend) - snapend = ipend; + if (ipend < ndo->ndo_snapend) + ndo->ndo_snapend = ipend; cp = (const u_char *)ip6; advance = sizeof(struct ip6_hdr); nh = ip6->ip6_nxt; - while (cp < snapend && advance > 0) { + while (cp < ndo->ndo_snapend && advance > 0) { cp += advance; len -= advance; if (cp == (const u_char *)(ip6 + 1) && nh != IPPROTO_TCP && nh != IPPROTO_UDP && nh != IPPROTO_DCCP && nh != IPPROTO_SCTP) { - (void)printf("%s > %s: ", ip6addr_string(&ip6->ip6_src), - ip6addr_string(&ip6->ip6_dst)); + (void)ND_PRINT((ndo, "%s > %s: ", ip6addr_string(&ip6->ip6_src), + ip6addr_string(&ip6->ip6_dst))); } switch (nh) { @@ -132,7 +164,7 @@ ip6_print(register const u_char *bp, register u_int length) break; case IPPROTO_FRAGMENT: advance = frag6_print(cp, (const u_char *)ip6); - if (snapend <= cp + advance) + if (ndo->ndo_snapend <= cp + advance) return; nh = *cp; fragmented = 1; @@ -170,7 +202,7 @@ ip6_print(register const u_char *bp, register u_int length) udp_print(cp, len, (const u_char *)ip6, fragmented); return; case IPPROTO_ICMPV6: - icmp6_print(cp, len, (const u_char *)ip6, fragmented); + icmp6_print(ndo, cp, len, (const u_char *)ip6, fragmented); return; case IPPROTO_AH: advance = ah_print(cp); @@ -179,7 +211,7 @@ ip6_print(register const u_char *bp, register u_int length) case IPPROTO_ESP: { int enh, padlen; - advance = esp_print(gndo, cp, len, (const u_char *)ip6, &enh, &padlen); + advance = esp_print(ndo, cp, len, (const u_char *)ip6, &enh, &padlen); nh = enh & 0xff; len -= padlen; break; @@ -193,7 +225,8 @@ ip6_print(register const u_char *bp, register u_int length) } case IPPROTO_PIM: - pim_print(cp, len); + pim_print(cp, len, nextproto6_cksum(ip6, cp, len, + IPPROTO_PIM)); return; case IPPROTO_OSPF: @@ -201,11 +234,11 @@ ip6_print(register const u_char *bp, register u_int length) return; case IPPROTO_IPV6: - ip6_print(cp, len); + ip6_print(ndo, cp, len); return; case IPPROTO_IPV4: - ip_print(gndo, cp, len); + ip_print(ndo, cp, len); return; case IPPROTO_PGM: @@ -221,18 +254,18 @@ ip6_print(register const u_char *bp, register u_int length) return; case IPPROTO_NONE: - (void)printf("no next header"); + (void)ND_PRINT((ndo, "no next header")); return; default: - (void)printf("ip-proto-%d %d", nh, len); + (void)ND_PRINT((ndo, "ip-proto-%d %d", nh, len)); return; } } return; trunc: - (void)printf("[|ip6]"); + (void)ND_PRINT((ndo, "[|ip6]")); } #endif /* INET6 */ diff --git a/contrib/tcpdump/print-ipnet.c b/contrib/tcpdump/print-ipnet.c new file mode 100644 index 0000000000..187f939d3f --- /dev/null +++ b/contrib/tcpdump/print-ipnet.c @@ -0,0 +1,109 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "netdissect.h" +#include "interface.h" +#include "addrtoname.h" +#include "ipnet.h" + +#ifdef DLT_IPNET + +const struct tok ipnet_values[] = { + { IPH_AF_INET, "IPv4" }, + { IPH_AF_INET6, "IPv6" }, + { 0, NULL } +}; + +static inline void +ipnet_hdr_print(struct netdissect_options *ndo, const u_char *bp, u_int length) +{ + const ipnet_hdr_t *hdr; + hdr = (const ipnet_hdr_t *)bp; + + ND_PRINT((ndo, "%d > %d", hdr->iph_zsrc, hdr->iph_zdst)); + + if (!ndo->ndo_qflag) { + ND_PRINT((ndo,", family %s (%d)", + tok2str(ipnet_values, "Unknown", + hdr->iph_family), + hdr->iph_family)); + } else { + ND_PRINT((ndo,", %s", + tok2str(ipnet_values, + "Unknown Ethertype (0x%04x)", + hdr->iph_family))); + } + + ND_PRINT((ndo, ", length %u: ", length)); +} + +static void +ipnet_print(struct netdissect_options *ndo, const u_char *p, u_int length, u_int caplen) +{ + ipnet_hdr_t *hdr; + + if (caplen < sizeof(ipnet_hdr_t)) { + ND_PRINT((ndo, "[|ipnet]")); + return; + } + + if (ndo->ndo_eflag) + ipnet_hdr_print(ndo, p, length); + + length -= sizeof(ipnet_hdr_t); + caplen -= sizeof(ipnet_hdr_t); + hdr = (ipnet_hdr_t *)p; + p += sizeof(ipnet_hdr_t); + + switch (hdr->iph_family) { + + case IPH_AF_INET: + ip_print(ndo, p, length); + break; + +#ifdef INET6 + case IPH_AF_INET6: + ip6_print(ndo, p, length); + break; +#endif /*INET6*/ + + default: + if (!ndo->ndo_eflag) + ipnet_hdr_print(ndo, (u_char *)hdr, + length + sizeof(ipnet_hdr_t)); + + if (!ndo->ndo_suppress_default_print) + ndo->ndo_default_print(ndo, p, caplen); + break; + } +} + +/* + * This is the top level routine of the printer. 'p' points + * to the ether header of the packet, 'h->ts' is the timestamp, + * 'h->len' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. + */ +u_int +ipnet_if_print(struct netdissect_options *ndo, + const struct pcap_pkthdr *h, const u_char *p) +{ + ipnet_print(ndo, p, h->len, h->caplen); + + return (sizeof(ipnet_hdr_t)); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ + +#endif /* DLT_IPNET */ diff --git a/contrib/tcpdump/print-ipx.c b/contrib/tcpdump/print-ipx.c index 604561c608..c9bde235a1 100644 --- a/contrib/tcpdump/print-ipx.c +++ b/contrib/tcpdump/print-ipx.c @@ -196,7 +196,7 @@ ipx_rip_print(const u_short *ipx, u_int length) (void)printf("ipx-rip-req"); if (length > 0) { TCHECK(ipx[3]); - (void)printf(" %u/%d.%d", EXTRACT_32BITS(&ipx[0]), + (void)printf(" %08x/%d.%d", EXTRACT_32BITS(&ipx[0]), EXTRACT_16BITS(&ipx[2]), EXTRACT_16BITS(&ipx[3])); } break; @@ -204,7 +204,7 @@ ipx_rip_print(const u_short *ipx, u_int length) (void)printf("ipx-rip-resp"); for (i = 0; i < 50 && length > 0; i++) { TCHECK(ipx[3]); - (void)printf(" %u/%d.%d", EXTRACT_32BITS(&ipx[0]), + (void)printf(" %08x/%d.%d", EXTRACT_32BITS(&ipx[0]), EXTRACT_16BITS(&ipx[2]), EXTRACT_16BITS(&ipx[3])); ipx += 4; diff --git a/contrib/tcpdump/print-isakmp.c b/contrib/tcpdump/print-isakmp.c index 763f58aa5e..4f96afe381 100644 --- a/contrib/tcpdump/print-isakmp.c +++ b/contrib/tcpdump/print-isakmp.c @@ -30,7 +30,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.56 2007-08-29 12:31:00 mcr Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.61 2008-02-05 19:34:25 guy Exp $ (LBL)"; #endif #define NETDISSECT_REWORKED @@ -94,16 +94,27 @@ DECLARE_PRINTER(v2_n); DECLARE_PRINTER(v2_d); DECLARE_PRINTER(v2_vid); DECLARE_PRINTER(v2_TS); -DECLARE_PRINTER(v2_e); DECLARE_PRINTER(v2_cp); DECLARE_PRINTER(v2_eap); +static const u_char *ikev2_e_print(netdissect_options *ndo, + struct isakmp *base, + u_char tpay, + const struct isakmp_gen *ext, + u_int item_len, + const u_char *end_pointer, + u_int32_t phase, + u_int32_t doi0, + u_int32_t proto0, int depth); + + static const u_char *ike_sub0_print(netdissect_options *ndo,u_char, const struct isakmp_gen *, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *ikev1_sub_print(netdissect_options *ndo,u_char, const struct isakmp_gen *, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *ikev2_sub_print(netdissect_options *ndo, + struct isakmp *base, u_char np, const struct isakmp_gen *ext, const u_char *ep, u_int32_t phase, u_int32_t doi, u_int32_t proto, @@ -185,7 +196,7 @@ static const u_char *(*npfunc[])(netdissect_options *ndo, u_char tpay, ikev2_vid_print, /* 43 */ ikev2_TS_print, /* 44 */ ikev2_TS_print, /* 45 */ - ikev2_e_print, /* 46 */ + NULL, /* ikev2_e_print,*/ /* 46 - special */ ikev2_cp_print, /* 47 */ ikev2_eap_print, /* 48 */ }; @@ -391,22 +402,29 @@ cookie_sidecheck(int i, const u_char *bp2, int initiator) return 0; } -static int -rawprint(netdissect_options *ndo, caddr_t loc, size_t len) +static void +hexprint(netdissect_options *ndo, caddr_t loc, size_t len) { - static u_char *p; + u_char *p; size_t i; - ND_TCHECK2(*loc, len); - p = (u_char *)loc; for (i = 0; i < len; i++) ND_PRINT((ndo,"%02x", p[i] & 0xff)); +} + +static int +rawprint(netdissect_options *ndo, caddr_t loc, size_t len) +{ + ND_TCHECK2(*loc, len); + + hexprint(ndo, loc, len); return 1; trunc: return 0; } + /* * returns false if we run out of data buffer */ @@ -1495,8 +1513,9 @@ ikev2_p_print(netdissect_options *ndo, u_char tpay _U_, int pcount _U_, safememcpy(&prop, ext, sizeof(prop)); ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_P), prop.h.critical); - ND_PRINT((ndo," #%u protoid=%s transform=%d", - prop.p_no, PROTOIDSTR(prop.prot_id), prop.num_t)); + ND_PRINT((ndo," #%u protoid=%s transform=%d len=%u", + prop.p_no, PROTOIDSTR(prop.prot_id), + prop.num_t, ntohs(prop.h.len))); if (prop.spi_size) { ND_PRINT((ndo," spi=")); if (!rawprint(ndo, (caddr_t)(p + 1), prop.spi_size)) @@ -1505,8 +1524,8 @@ ikev2_p_print(netdissect_options *ndo, u_char tpay _U_, int pcount _U_, ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size); ND_TCHECK(*ext); - - cp = ikev2_sub_print(ndo, ISAKMP_NPTYPE_T, ext, ep, phase, doi0, + + cp = ikev2_sub_print(ndo, NULL, ISAKMP_NPTYPE_T, ext, ep, phase, doi0, prop.prot_id, depth); return cp; @@ -1523,21 +1542,21 @@ ikev2_sa_print(netdissect_options *ndo, u_char tpay, u_int32_t proto _U_, int depth _U_) { struct isakmp_gen e; - int osa_len, sa_len; + int osa_length, sa_length; ND_TCHECK(*ext1); safememcpy(&e, ext1, sizeof(e)); ikev2_pay_print(ndo, "sa", e.critical); - osa_len= ntohs(e.len); - sa_len = osa_len - 4; - ND_PRINT((ndo," len=%d", sa_len)); + osa_length= ntohs(e.len); + sa_length = osa_length - 4; + ND_PRINT((ndo," len=%d", sa_length)); - ikev2_sub_print(ndo, ISAKMP_NPTYPE_P, + ikev2_sub_print(ndo, NULL, ISAKMP_NPTYPE_P, ext1+1, ep, 0, 0, 0, depth); - return (u_char *)ext1 + osa_len; + return (u_char *)ext1 + osa_length; trunc: ND_PRINT((ndo," [|%s]", NPSTR(tpay))); return NULL; @@ -1579,7 +1598,79 @@ ikev2_ID_print(netdissect_options *ndo, u_char tpay, u_int32_t phase _U_, u_int32_t doi _U_, u_int32_t proto _U_, int depth _U_) { - return ikev2_gen_print(ndo, tpay, ext); + struct ikev2_id id; + int id_len, idtype_len, i; + unsigned int dumpascii, dumphex; + unsigned char *typedata; + + ND_TCHECK(*ext); + safememcpy(&id, ext, sizeof(id)); + ikev2_pay_print(ndo, NPSTR(tpay), id.h.critical); + + id_len = ntohs(id.h.len); + + ND_PRINT((ndo," len=%d", id_len - 4)); + if (2 < ndo->ndo_vflag && 4 < id_len) { + ND_PRINT((ndo," ")); + if (!rawprint(ndo, (caddr_t)(ext + 1), id_len - 4)) + goto trunc; + } + + idtype_len =id_len - sizeof(struct ikev2_id); + dumpascii = 0; + dumphex = 0; + typedata = (unsigned char *)(ext)+sizeof(struct ikev2_id); + + switch(id.type) { + case ID_IPV4_ADDR: + ND_PRINT((ndo, " ipv4:")); + dumphex=1; + break; + case ID_FQDN: + ND_PRINT((ndo, " fqdn:")); + dumpascii=1; + break; + case ID_RFC822_ADDR: + ND_PRINT((ndo, " rfc822:")); + dumpascii=1; + break; + case ID_IPV6_ADDR: + ND_PRINT((ndo, " ipv6:")); + dumphex=1; + break; + case ID_DER_ASN1_DN: + ND_PRINT((ndo, " dn:")); + dumphex=1; + break; + case ID_DER_ASN1_GN: + ND_PRINT((ndo, " gn:")); + dumphex=1; + break; + case ID_KEY_ID: + ND_PRINT((ndo, " keyid:")); + dumphex=1; + break; + } + + if(dumpascii) { + ND_TCHECK2(*typedata, idtype_len); + for(i=0; indo_vflag && 4 < ntohs(e.h.len)) { + if (1 < ndo->ndo_vflag && 4 < len) { ND_PRINT((ndo," authdata=(")); - if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.h.len) - 4)) + if (!rawprint(ndo, (caddr_t)authdata, len - sizeof(a))) goto trunc; ND_PRINT((ndo,") ")); - } else if(ndo->ndo_vflag && 4 < ntohs(e.h.len)) { - if(!ike_show_somedata(ndo, (const u_char *)(ext+1), ep)) goto trunc; + } else if(ndo->ndo_vflag && 4 < len) { + if(!ike_show_somedata(ndo, authdata, ep)) goto trunc; } - return (u_char *)ext + ntohs(e.h.len); + return (u_char *)ext + len; trunc: ND_PRINT((ndo," [|%s]", NPSTR(tpay))); return NULL; @@ -1905,7 +1999,7 @@ ikev2_vid_print(netdissect_options *ndo, u_char tpay, ND_TCHECK2(*vid, len); for(i=0; indo_vflag && 4 < len) { ND_PRINT((ndo," ")); @@ -1929,13 +2023,74 @@ ikev2_TS_print(netdissect_options *ndo, u_char tpay, } static const u_char * -ikev2_e_print(netdissect_options *ndo, u_char tpay, - const struct isakmp_gen *ext, - u_int item_len _U_, const u_char *ep _U_, - u_int32_t phase _U_, u_int32_t doi _U_, - u_int32_t proto _U_, int depth _U_) +ikev2_e_print(netdissect_options *ndo, +#ifndef HAVE_LIBCRYPTO + _U_ +#endif + struct isakmp *base, + u_char tpay, + const struct isakmp_gen *ext, + u_int item_len _U_, const u_char *ep _U_, +#ifndef HAVE_LIBCRYPTO + _U_ +#endif + u_int32_t phase, +#ifndef HAVE_LIBCRYPTO + _U_ +#endif + u_int32_t doi, +#ifndef HAVE_LIBCRYPTO + _U_ +#endif + u_int32_t proto, +#ifndef HAVE_LIBCRYPTO + _U_ +#endif + int depth) { - return ikev2_gen_print(ndo, tpay, ext); + struct isakmp_gen e; + u_char *dat; + volatile int dlen; + + ND_TCHECK(*ext); + safememcpy(&e, ext, sizeof(e)); + ikev2_pay_print(ndo, NPSTR(tpay), e.critical); + + dlen = ntohs(e.len)-4; + + ND_PRINT((ndo," len=%d", dlen)); + if (2 < ndo->ndo_vflag && 4 < dlen) { + ND_PRINT((ndo," ")); + if (!rawprint(ndo, (caddr_t)(ext + 1), dlen)) + goto trunc; + } + + dat = (u_char *)(ext+1); + ND_TCHECK2(*dat, dlen); + +#ifdef HAVE_LIBCRYPTO + /* try to decypt it! */ + if(esp_print_decrypt_buffer_by_ikev2(ndo, + base->flags & ISAKMP_FLAG_I, + base->i_ck, base->r_ck, + dat, dat+dlen)) { + + ext = (const struct isakmp_gen *)ndo->ndo_packetp; + + /* got it decrypted, print stuff inside. */ + ikev2_sub_print(ndo, base, e.np, ext, ndo->ndo_snapend, + phase, doi, proto, depth+1); + } +#endif + + + /* always return NULL, because E must be at end, and NP refers + * to what was inside. + */ + return NULL; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(tpay))); + return NULL; } static const u_char * @@ -1961,7 +2116,8 @@ ikev2_eap_print(netdissect_options *ndo, u_char tpay, static const u_char * ike_sub0_print(netdissect_options *ndo, u_char np, const struct isakmp_gen *ext, const u_char *ep, - u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth) + + u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth) { const u_char *cp; struct isakmp_gen e; @@ -2058,7 +2214,7 @@ safememcpy(void *p, const void *q, size_t l) memcpy(p, q, l); } -void +static void ikev1_print(netdissect_options *ndo, const u_char *bp, u_int length, const u_char *bp2, struct isakmp *base) @@ -2135,7 +2291,8 @@ done: } static const u_char * -ikev2_sub0_print(netdissect_options *ndo, u_char np, int pcount, +ikev2_sub0_print(netdissect_options *ndo, struct isakmp *base, + u_char np, int pcount, const struct isakmp_gen *ext, const u_char *ep, u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth) { @@ -2163,6 +2320,9 @@ ikev2_sub0_print(netdissect_options *ndo, u_char np, int pcount, } else if(np == ISAKMP_NPTYPE_T) { cp = ikev2_t_print(ndo, np, pcount, ext, item_len, ep, phase, doi, proto, depth); + } else if(np == ISAKMP_NPTYPE_v2E) { + cp = ikev2_e_print(ndo, base, np, ext, item_len, + ep, phase, doi, proto, depth); } else if (NPFUNC(np)) { /* * XXX - what if item_len is too short, or too long, @@ -2183,6 +2343,7 @@ trunc: static const u_char * ikev2_sub_print(netdissect_options *ndo, + struct isakmp *base, u_char np, const struct isakmp_gen *ext, const u_char *ep, u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth) { @@ -2206,7 +2367,7 @@ ikev2_sub_print(netdissect_options *ndo, for (i = 0; i < depth; i++) ND_PRINT((ndo," ")); ND_PRINT((ndo,"(")); - cp = ikev2_sub0_print(ndo, np, pcount, + cp = ikev2_sub0_print(ndo, base, np, pcount, ext, ep, phase, doi, proto, depth); ND_PRINT((ndo,")")); depth--; @@ -2246,7 +2407,7 @@ ikev2_print(netdissect_options *ndo, ND_PRINT((ndo, " %s", ETYPESTR(base->etype))); if (base->flags) { - ND_PRINT((ndo, "[%s%s]", + ND_PRINT((ndo, "[%s%s%s]", base->flags & ISAKMP_FLAG_I ? "I" : "", base->flags & ISAKMP_FLAG_V ? "V" : "", base->flags & ISAKMP_FLAG_R ? "R" : "")); @@ -2273,7 +2434,7 @@ ikev2_print(netdissect_options *ndo, np = base->np; ext = (struct isakmp_gen *)(p + 1); - ikev2_sub_print(ndo, np, ext, ep, phase, 0, 0, 0); + ikev2_sub_print(ndo, base, np, ext, ep, phase, 0, 0, 0); } done: @@ -2295,6 +2456,14 @@ isakmp_print(netdissect_options *ndo, const u_char *ep; int major, minor; +#ifdef HAVE_LIBCRYPTO + /* initialize SAs */ + if (ndo->ndo_sa_list_head == NULL) { + if (ndo->ndo_espsecret) + esp_print_decodesecret(ndo); + } +#endif + p = (const struct isakmp *)bp; ep = ndo->ndo_snapend; @@ -2317,14 +2486,14 @@ isakmp_print(netdissect_options *ndo, if (ndo->ndo_vflag) { ND_PRINT((ndo," msgid ")); - rawprint(ndo, (caddr_t)&base.msgid, sizeof(base.msgid)); + hexprint(ndo, (caddr_t)&base.msgid, sizeof(base.msgid)); } if (1 < ndo->ndo_vflag) { ND_PRINT((ndo," cookie ")); - rawprint(ndo, (caddr_t)&base.i_ck, sizeof(base.i_ck)); + hexprint(ndo, (caddr_t)&base.i_ck, sizeof(base.i_ck)); ND_PRINT((ndo,"->")); - rawprint(ndo, (caddr_t)&base.r_ck, sizeof(base.r_ck)); + hexprint(ndo, (caddr_t)&base.r_ck, sizeof(base.r_ck)); } ND_PRINT((ndo,":")); diff --git a/contrib/tcpdump/print-isoclns.c b/contrib/tcpdump/print-isoclns.c index 4f8c347b81..5763705537 100644 --- a/contrib/tcpdump/print-isoclns.c +++ b/contrib/tcpdump/print-isoclns.c @@ -26,7 +26,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-isoclns.c,v 1.163 2007-03-02 09:16:19 hannes Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-isoclns.c,v 1.165 2008-08-16 13:38:15 hannes Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -46,6 +46,7 @@ static const char rcsid[] _U_ = #include "extract.h" #include "gmpls.h" #include "oui.h" +#include "signature.h" /* * IS-IS is defined in ISO 10589. Look there for protocol definitions. @@ -392,12 +393,14 @@ static struct tok isis_subtlv_link_attribute_values[] = { }; #define ISIS_SUBTLV_AUTH_SIMPLE 1 +#define ISIS_SUBTLV_AUTH_GENERIC 3 /* rfc 5310 */ #define ISIS_SUBTLV_AUTH_MD5 54 #define ISIS_SUBTLV_AUTH_MD5_LEN 16 #define ISIS_SUBTLV_AUTH_PRIVATE 255 static struct tok isis_subtlv_auth_values[] = { { ISIS_SUBTLV_AUTH_SIMPLE, "simple text password"}, + { ISIS_SUBTLV_AUTH_GENERIC, "Generic Crypto key-id"}, { ISIS_SUBTLV_AUTH_MD5, "HMAC-MD5 password"}, { ISIS_SUBTLV_AUTH_PRIVATE, "Routing Domain private password"}, { 0, NULL } @@ -438,8 +441,8 @@ static struct tok clnp_flag_values[] = { #define ISIS_MASK_MTFLAGS(x) ((x)&0xf000) static struct tok isis_mt_flag_values[] = { - { 0x4000, "sub-TLVs present"}, - { 0x8000, "ATT bit set"}, + { 0x4000, "ATT bit set"}, + { 0x8000, "Overload bit set"}, { 0, NULL} }; @@ -615,10 +618,6 @@ struct isis_tlv_lsp { void isoclns_print(const u_int8_t *p, u_int length, u_int caplen) { - const struct isis_common_header *header; - - header = (const struct isis_common_header *)p; - if (caplen <= 1) { /* enough bytes on the wire ? */ printf("|OSI"); return; @@ -661,7 +660,7 @@ void isoclns_print(const u_int8_t *p, u_int length, u_int caplen) #ifdef INET6 case NLPID_IP6: - ip6_print(p+1, length-1); + ip6_print(gndo, p+1, length-1); break; #endif @@ -1176,15 +1175,15 @@ esis_print(const u_int8_t *pptr, u_int length) } /* now walk the options */ - while (li >= 2) { + while (li != 0) { u_int op, opli; const u_int8_t *tptr; - TCHECK2(*pptr, 2); if (li < 2) { printf(", bad opts/li"); return; } + TCHECK2(*pptr, 2); op = *pptr++; opli = *pptr++; li -= 2; @@ -1203,8 +1202,11 @@ esis_print(const u_int8_t *pptr, u_int length) switch (op) { case ESIS_OPTION_ES_CONF_TIME: - TCHECK2(*pptr, 2); - printf("%us", EXTRACT_16BITS(tptr)); + if (opli == 2) { + TCHECK2(*pptr, 2); + printf("%us", EXTRACT_16BITS(tptr)); + } else + printf("(bad length)"); break; case ESIS_OPTION_PROTOCOLS: @@ -1764,7 +1766,7 @@ static int isis_print (const u_int8_t *p, u_int length) const struct isis_iih_lan_header *header_iih_lan; const struct isis_iih_ptp_header *header_iih_ptp; - const struct isis_lsp_header *header_lsp; + struct isis_lsp_header *header_lsp; const struct isis_csnp_header *header_csnp; const struct isis_psnp_header *header_psnp; @@ -1776,18 +1778,20 @@ static int isis_print (const u_int8_t *p, u_int length) u_int8_t pdu_type, max_area, id_length, tlv_type, tlv_len, tmp, alen, lan_alen, prefix_len; u_int8_t ext_is_len, ext_ip_len, mt_len; const u_int8_t *optr, *pptr, *tptr; - u_short packet_len,pdu_len; + u_short packet_len,pdu_len, key_id; u_int i,vendor_id; + int sigcheck; packet_len=length; optr = p; /* initialize the _o_riginal pointer to the packet start - - need it for parsing the checksum TLV */ + need it for parsing the checksum TLV and authentication + TLV verification */ isis_header = (const struct isis_common_header *)p; TCHECK(*isis_header); pptr = p+(ISIS_COMMON_HEADER_SIZE); header_iih_lan = (const struct isis_iih_lan_header *)pptr; header_iih_ptp = (const struct isis_iih_ptp_header *)pptr; - header_lsp = (const struct isis_lsp_header *)pptr; + header_lsp = (struct isis_lsp_header *)pptr; header_csnp = (const struct isis_csnp_header *)pptr; header_psnp = (const struct isis_psnp_header *)pptr; @@ -2013,6 +2017,15 @@ static int isis_print (const u_int8_t *p, u_int length) osi_print_cksum((u_int8_t *)header_lsp->lsp_id, EXTRACT_16BITS(header_lsp->checksum), 12, length-12); + /* + * Clear checksum and lifetime prior to signature verification. + */ + header_lsp->checksum[0] = 0; + header_lsp->checksum[1] = 0; + header_lsp->remaining_lifetime[0] = 0; + header_lsp->remaining_lifetime[1] = 0; + + printf(", PDU length: %u, Flags: [ %s", pdu_len, ISIS_MASK_LSP_OL_BIT(header_lsp->typeblock) ? "Overload bit set, " : ""); @@ -2188,13 +2201,12 @@ static int isis_print (const u_int8_t *p, u_int length) break; case ISIS_TLV_MT_IS_REACH: + mt_len = isis_print_mtid(tptr, "\n\t "); + if (mt_len == 0) /* did something go wrong ? */ + goto trunctlv; + tptr+=mt_len; + tmp-=mt_len; while (tmp >= 2+NODE_ID_LEN+3+1) { - mt_len = isis_print_mtid(tptr, "\n\t "); - if (mt_len == 0) /* did something go wrong ? */ - goto trunctlv; - tptr+=mt_len; - tmp-=mt_len; - ext_is_len = isis_print_ext_is_reach(tptr,"\n\t ",tlv_type); if (ext_is_len == 0) /* did something go wrong ? */ goto trunctlv; @@ -2355,7 +2367,25 @@ static int isis_print (const u_int8_t *p, u_int length) } if (tlv_len != ISIS_SUBTLV_AUTH_MD5_LEN+1) printf(", (malformed subTLV) "); + +#ifdef HAVE_LIBCRYPTO + sigcheck = signature_verify(optr, length, + (unsigned char *)tptr + 1); +#else + sigcheck = CANT_CHECK_SIGNATURE; +#endif + printf(" (%s)", tok2str(signature_check_values, "Unknown", sigcheck)); + break; + case ISIS_SUBTLV_AUTH_GENERIC: + key_id = EXTRACT_16BITS((tptr+1)); + printf("%u, password: ", key_id); + for(i=1 + sizeof(u_int16_t);ile_header), - etheraddr_string(ep->h_source), - etheraddr_string(ep->h_dest), - length); - else - (void)printf("lecid:%x %s %s %s %d: ", - EXTRACT_16BITS(&ep->le_header), - etheraddr_string(ep->h_source), - etheraddr_string(ep->h_dest), - etherproto_string(ep->h_type), - length); + (void)ND_PRINT((ndo, "lecid:%x ", EXTRACT_16BITS(bp))); } /* @@ -93,9 +78,6 @@ void lane_print(const u_char *p, u_int length, u_int caplen) { struct lane_controlhdr *lec; - struct lecdatahdr_8023 *ep; - u_short ether_type; - u_short extracted_ethertype; if (caplen < sizeof(struct lane_controlhdr)) { printf("[|lane]"); @@ -113,49 +95,18 @@ lane_print(const u_char *p, u_int length, u_int caplen) return; } - if (caplen < sizeof(struct lecdatahdr_8023)) { - printf("[|lane]"); - return; - } - - if (eflag) - lane_hdr_print(p, length); - /* - * Go past the LANE header. + * Go past the LE header. */ - length -= sizeof(struct lecdatahdr_8023); - caplen -= sizeof(struct lecdatahdr_8023); - ep = (struct lecdatahdr_8023 *)p; - p += sizeof(struct lecdatahdr_8023); - - ether_type = EXTRACT_16BITS(&ep->h_type); + length -= 2; + caplen -= 2; + p += 2; /* - * Is it (gag) an 802.3 encapsulation? + * Now print the encapsulated frame, under the assumption + * that it's an Ethernet frame. */ - if (ether_type <= ETHERMTU) { - /* Try to print the LLC-layer header & higher layers */ - if (llc_print(p, length, caplen, ep->h_source, ep->h_dest, - &extracted_ethertype) == 0) { - /* ether_type not known, print raw packet */ - if (!eflag) - lane_hdr_print((u_char *)ep, length + sizeof(*ep)); - if (extracted_ethertype) { - printf("(LLC %s) ", - etherproto_string(htons(extracted_ethertype))); - } - if (!suppress_default_print) - default_print(p, caplen); - } - } else if (ether_encap_print(ether_type, p, length, caplen, - &extracted_ethertype) == 0) { - /* ether_type not known, print raw packet */ - if (!eflag) - lane_hdr_print((u_char *)ep, length + sizeof(*ep)); - if (!suppress_default_print) - default_print(p, caplen); - } + ether_print(gndo, p, length, caplen, lane_hdr_print, p - 2); } u_int diff --git a/contrib/tcpdump/print-ldp.c b/contrib/tcpdump/print-ldp.c index de3b34e5b5..1243104855 100644 --- a/contrib/tcpdump/print-ldp.c +++ b/contrib/tcpdump/print-ldp.c @@ -609,7 +609,7 @@ ldp_msg_print(register const u_char *pptr) { } /* do we want to see an additionally hexdump ? */ if (vflag > 1 || hexdump==TRUE) - print_unknown_data(tptr+sizeof(sizeof(struct ldp_msg_header)),"\n\t ", + print_unknown_data(tptr+sizeof(struct ldp_msg_header),"\n\t ", msg_len); tptr += msg_len+4; diff --git a/contrib/tcpdump/print-llc.c b/contrib/tcpdump/print-llc.c index 0c8259fbb6..a1934715c1 100644 --- a/contrib/tcpdump/print-llc.c +++ b/contrib/tcpdump/print-llc.c @@ -309,8 +309,7 @@ llc_print(const u_char *p, u_int length, u_int caplen, * Does anybody ever bridge one form of LAN traffic * over a networking type that uses 802.2 LLC? */ - ret = snap_print(p+3, length-3, caplen-3, extracted_ethertype, - 2); + ret = snap_print(p+3, length-3, caplen-3, 2); if (ret) return (ret); } @@ -378,8 +377,7 @@ llc_print(const u_char *p, u_int length, u_int caplen, } int -snap_print(const u_char *p, u_int length, u_int caplen, - u_short *extracted_ethertype, u_int bridge_pad) +snap_print(const u_char *p, u_int length, u_int caplen, u_int bridge_pad) { u_int32_t orgcode; register u_short et; @@ -419,8 +417,7 @@ snap_print(const u_char *p, u_int length, u_int caplen, * Cisco hardware; the protocol ID is * an Ethernet protocol type. */ - ret = ether_encap_print(et, p, length, caplen, - extracted_ethertype); + ret = ethertype_print(gndo, et, p, length, caplen); if (ret) return (ret); break; @@ -435,8 +432,7 @@ snap_print(const u_char *p, u_int length, u_int caplen, * but used 0x000000 and an Ethernet * packet type for AARP packets. */ - ret = ether_encap_print(et, p, length, caplen, - extracted_ethertype); + ret = ethertype_print(gndo, et, p, length, caplen); if (ret) return (ret); } @@ -483,7 +479,7 @@ snap_print(const u_char *p, u_int length, u_int caplen, /* * What remains is an Ethernet packet. */ - ether_print(p, length, caplen); + ether_print(gndo, p, length, caplen, NULL, NULL); return (1); case PID_RFC2684_802_5_FCS: diff --git a/contrib/tcpdump/print-lldp.c b/contrib/tcpdump/print-lldp.c index 36b99343ec..0ee2f955db 100644 --- a/contrib/tcpdump/print-lldp.c +++ b/contrib/tcpdump/print-lldp.c @@ -12,15 +12,16 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * support for the IEEE Link Discovery Protocol as per 802.1ab + * support for the IEEE Link Discovery Protocol as per 802.1AB * * Original code by Hannes Gredler (hannes@juniper.net) * IEEE and TIA extensions by Carles Kishimoto + * DCBX extensions by Kaladhar Musunuru */ #ifndef lint static const char rcsid[] _U_ = -"@(#) $Header: /tcpdump/master/tcpdump/print-lldp.c,v 1.7.2.3 2008-03-20 09:33:52 hannes Exp $"; +"@(#) $Header: /tcpdump/master/tcpdump/print-lldp.c,v 1.10 2008-03-20 09:30:56 hannes Exp $"; #endif #ifdef HAVE_CONFIG_H @@ -541,6 +542,23 @@ static const struct tok lldp_aggregation_values[] = { { 0, NULL} }; +/* + * DCBX protocol subtypes. + */ +#define LLDP_DCBX_SUBTYPE_1 1 +#define LLDP_DCBX_SUBTYPE_2 2 + +static const struct tok lldp_dcbx_subtype_values[] = { + { LLDP_DCBX_SUBTYPE_1, "DCB Capability Exchange Protocol Rev 1" }, + { LLDP_DCBX_SUBTYPE_2, "DCB Capability Exchange Protocol Rev 1.01" }, + { 0, NULL} +}; + +#define LLDP_DCBX_CONTROL_TLV 1 +#define LLDP_DCBX_PRIORITY_GROUPS_TLV 2 +#define LLDP_DCBX_PRIORITY_FLOW_CONTROL_TLV 3 +#define LLDP_DCBX_APPLICATION_TLV 4 + /* * Interface numbering subtypes. */ @@ -556,13 +574,17 @@ static const struct tok lldp_intf_numb_subtype_values[] = { #define LLDP_INTF_NUM_LEN 5 /* - * Print IEEE private extensions. (802.1 annex F) + * Print IEEE 802.1 private extensions. (802.1AB annex E) */ static int -lldp_private_8021_print(const u_char *tptr) +lldp_private_8021_print(const u_char *tptr, u_int tlv_len) { int subtype, hexdump = FALSE; + u_int sublen; + if (tlv_len < 4) { + return hexdump; + } subtype = *(tptr+3); printf("\n\t %s Subtype (%u)", @@ -571,24 +593,47 @@ lldp_private_8021_print(const u_char *tptr) switch (subtype) { case LLDP_PRIVATE_8021_SUBTYPE_PORT_VLAN_ID: + if (tlv_len < 6) { + return hexdump; + } printf("\n\t port vlan id (PVID): %u", EXTRACT_16BITS(tptr+4)); break; case LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_VLAN_ID: + if (tlv_len < 7) { + return hexdump; + } printf("\n\t port and protocol vlan id (PPVID): %u, flags [%s] (0x%02x)", EXTRACT_16BITS(tptr+5), bittok2str(lldp_8021_port_protocol_id_values, "none", *(tptr+4)), *(tptr+4)); break; case LLDP_PRIVATE_8021_SUBTYPE_VLAN_NAME: + if (tlv_len < 6) { + return hexdump; + } printf("\n\t vlan id (VID): %u", EXTRACT_16BITS(tptr+4)); + if (tlv_len < 7) { + return hexdump; + } + sublen = *(tptr+6); + if (tlv_len < 7+sublen) { + return hexdump; + } printf("\n\t vlan name: "); - safeputs((const char *)tptr+7, *(tptr+6)); + safeputs((const char *)tptr+7, sublen); break; case LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_IDENTITY: + if (tlv_len < 5) { + return hexdump; + } + sublen = *(tptr+4); + if (tlv_len < 5+sublen) { + return hexdump; + } printf("\n\t protocol identity: "); - safeputs((const char *)tptr+5, *(tptr+4)); + safeputs((const char *)tptr+5, sublen); break; default: @@ -600,13 +645,16 @@ lldp_private_8021_print(const u_char *tptr) } /* - * Print IEEE private extensions. (802.3) + * Print IEEE 802.3 private extensions. (802.3bc) */ static int -lldp_private_8023_print(const u_char *tptr) +lldp_private_8023_print(const u_char *tptr, u_int tlv_len) { int subtype, hexdump = FALSE; + if (tlv_len < 4) { + return hexdump; + } subtype = *(tptr+3); printf("\n\t %s Subtype (%u)", @@ -615,6 +663,9 @@ lldp_private_8023_print(const u_char *tptr) switch (subtype) { case LLDP_PRIVATE_8023_SUBTYPE_MACPHY: + if (tlv_len < 9) { + return hexdump; + } printf("\n\t autonegotiation [%s] (0x%02x)", bittok2str(lldp_8023_autonegotiation_values, "none", *(tptr+4)), *(tptr+4)); @@ -627,6 +678,9 @@ lldp_private_8023_print(const u_char *tptr) break; case LLDP_PRIVATE_8023_SUBTYPE_MDIPOWER: + if (tlv_len < 7) { + return hexdump; + } printf("\n\t MDI power support [%s], power pair %s, power class %s", bittok2str(lldp_mdi_values, "none", *(tptr+4)), tok2str(lldp_mdi_power_pairs_values, "unknown", *(tptr+5)), @@ -634,6 +688,9 @@ lldp_private_8023_print(const u_char *tptr) break; case LLDP_PRIVATE_8023_SUBTYPE_LINKAGGR: + if (tlv_len < 9) { + return hexdump; + } printf("\n\t aggregation status [%s], aggregation port ID %u", bittok2str(lldp_aggregation_values, "none", *(tptr+4)), EXTRACT_32BITS(tptr+5)); @@ -674,8 +731,12 @@ lldp_private_tia_print(const u_char *tptr, u_int tlv_len) int subtype, hexdump = FALSE; u_int8_t location_format; u_int16_t power_val; - u_int8_t lci_len, ca_type, ca_len; + u_int lci_len; + u_int8_t ca_type, ca_len; + if (tlv_len < 4) { + return hexdump; + } subtype = *(tptr+3); printf("\n\t %s Subtype (%u)", @@ -684,6 +745,9 @@ lldp_private_tia_print(const u_char *tptr, u_int tlv_len) switch (subtype) { case LLDP_PRIVATE_TIA_SUBTYPE_CAPABILITIES: + if (tlv_len < 7) { + return hexdump; + } printf("\n\t Media capabilities [%s] (0x%04x)", bittok2str(lldp_tia_capabilities_values, "none", EXTRACT_16BITS(tptr+4)), EXTRACT_16BITS(tptr+4)); @@ -693,6 +757,9 @@ lldp_private_tia_print(const u_char *tptr, u_int tlv_len) break; case LLDP_PRIVATE_TIA_SUBTYPE_NETWORK_POLICY: + if (tlv_len < 8) { + return hexdump; + } printf("\n\t Application type [%s] (0x%02x)", tok2str(lldp_tia_application_type_values, "none", *(tptr+4)), *(tptr+4)); @@ -707,6 +774,9 @@ lldp_private_tia_print(const u_char *tptr, u_int tlv_len) break; case LLDP_PRIVATE_TIA_SUBTYPE_LOCAL_ID: + if (tlv_len < 5) { + return hexdump; + } location_format = *(tptr+4); printf("\n\t Location data format %s (0x%02x)", tok2str(lldp_tia_location_data_format_values, "unknown", location_format), @@ -714,6 +784,9 @@ lldp_private_tia_print(const u_char *tptr, u_int tlv_len) switch (location_format) { case LLDP_TIA_LOCATION_DATA_FORMAT_COORDINATE_BASED: + if (tlv_len < 21) { + return hexdump; + } printf("\n\t Latitude resolution %u, latitude value %" PRIu64, (*(tptr+5)>>2), lldp_extract_latlon(tptr+5)); printf("\n\t Longitude resolution %u, longitude value %" PRIu64, @@ -730,7 +803,16 @@ lldp_private_tia_print(const u_char *tptr, u_int tlv_len) break; case LLDP_TIA_LOCATION_DATA_FORMAT_CIVIC_ADDRESS: + if (tlv_len < 6) { + return hexdump; + } lci_len = *(tptr+5); + if (lci_len < 3) { + return hexdump; + } + if (tlv_len < 7+lci_len) { + return hexdump; + } printf("\n\t LCI length %u, LCI what %s (0x%02x), Country-code ", lci_len, tok2str(lldp_tia_location_lci_what_values, "unknown", *(tptr+6)), @@ -744,6 +826,9 @@ lldp_private_tia_print(const u_char *tptr, u_int tlv_len) /* Decode each civic address element */ while (lci_len > 0) { + if (lci_len < 2) { + return hexdump; + } ca_type = *(tptr); ca_len = *(tptr+1); @@ -758,6 +843,9 @@ lldp_private_tia_print(const u_char *tptr, u_int tlv_len) if ( ca_type == 0 || ca_len == 0) { return hexdump; } + if (lci_len < ca_len) { + return hexdump; + } safeputs((const char *)tptr, ca_len); tptr += ca_len; @@ -777,6 +865,9 @@ lldp_private_tia_print(const u_char *tptr, u_int tlv_len) break; case LLDP_PRIVATE_TIA_SUBTYPE_EXTENDED_POWER_MDI: + if (tlv_len < 7) { + return hexdump; + } printf("\n\t Power type [%s]", (*(tptr+4)&0xC0>>6) ? "PD device" : "PSE device"); printf(", Power source [%s]", @@ -812,24 +903,196 @@ lldp_private_tia_print(const u_char *tptr, u_int tlv_len) return hexdump; } +/* + * Print DCBX Protocol fields (V 1.01). + */ +static int +lldp_private_dcbx_print(const u_char *pptr, u_int len) +{ + int subtype, hexdump = FALSE; + u_int8_t tval; + u_int16_t tlv; + u_int32_t i, pgval, uval; + u_int tlen, tlv_type, tlv_len; + const u_char *tptr, *mptr; + + if (len < 4) { + return hexdump; + } + subtype = *(pptr+3); + + printf("\n\t %s Subtype (%u)", + tok2str(lldp_dcbx_subtype_values, "unknown", subtype), + subtype); + + /* by passing old version */ + if (subtype == LLDP_DCBX_SUBTYPE_1) + return TRUE; + + tptr = pptr + 4; + tlen = len - 4; + + while (tlen >= sizeof(tlv)) { + + TCHECK2(*tptr, sizeof(tlv)); + + tlv = EXTRACT_16BITS(tptr); + + tlv_type = LLDP_EXTRACT_TYPE(tlv); + tlv_len = LLDP_EXTRACT_LEN(tlv); + hexdump = FALSE; + + tlen -= sizeof(tlv); + tptr += sizeof(tlv); + + /* loop check */ + if (!tlv_type || !tlv_len) { + break; + } + + TCHECK2(*tptr, tlv_len); + if (tlen < tlv_len) { + goto trunc; + } + + /* decode every tlv */ + switch (tlv_type) { + case LLDP_DCBX_CONTROL_TLV: + if (tlv_len < 10) { + goto trunc; + } + printf("\n\t Control - Protocol Control (type 0x%x, length %d)", + LLDP_DCBX_CONTROL_TLV, tlv_len); + printf("\n\t Oper_Version: %d", *tptr); + printf("\n\t Max_Version: %d", *(tptr+1)); + printf("\n\t Sequence Number: %d", EXTRACT_32BITS(tptr+2)); + printf("\n\t Acknowledgement Number: %d", + EXTRACT_32BITS(tptr+6)); + break; + case LLDP_DCBX_PRIORITY_GROUPS_TLV: + if (tlv_len < 17) { + goto trunc; + } + printf("\n\t Feature - Priority Group (type 0x%x, length %d)", + LLDP_DCBX_PRIORITY_GROUPS_TLV, tlv_len); + printf("\n\t Oper_Version: %d", *tptr); + printf("\n\t Max_Version: %d", *(tptr+1)); + printf("\n\t Info block(0x%02X): ", *(tptr+2)); + tval = *(tptr+2); + printf("Enable bit: %d, Willing bit: %d, Error Bit: %d", + (tval & 0x80) ? 1 : 0, (tval & 0x40) ? 1 : 0, + (tval & 0x20) ? 1 : 0); + printf("\n\t SubType: %d", *(tptr+3)); + printf("\n\t Priority Allocation"); + + pgval = EXTRACT_32BITS(tptr+4); + for (i = 0; i <= 7; i++) { + tval = *(tptr+4+(i/2)); + printf("\n\t PgId_%d: %d", + i, (pgval >> (28-4*i)) & 0xF); + } + printf("\n\t Priority Group Allocation"); + for (i = 0; i <= 7; i++) + printf("\n\t Pg percentage[%d]: %d", i, *(tptr+8+i)); + printf("\n\t NumTCsSupported: %d", *(tptr+8+8)); + break; + case LLDP_DCBX_PRIORITY_FLOW_CONTROL_TLV: + if (tlv_len < 6) { + goto trunc; + } + printf("\n\t Feature - Priority Flow Control"); + printf(" (type 0x%x, length %d)", + LLDP_DCBX_PRIORITY_FLOW_CONTROL_TLV, tlv_len); + printf("\n\t Oper_Version: %d", *tptr); + printf("\n\t Max_Version: %d", *(tptr+1)); + printf("\n\t Info block(0x%02X): ", *(tptr+2)); + tval = *(tptr+2); + printf("Enable bit: %d, Willing bit: %d, Error Bit: %d", + (tval & 0x80) ? 1 : 0, (tval & 0x40) ? 1 : 0, + (tval & 0x20) ? 1 : 0); + printf("\n\t SubType: %d", *(tptr+3)); + tval = *(tptr+4); + printf("\n\t PFC Config (0x%02X)", *(tptr+4)); + for (i = 0; i <= 7; i++) + printf("\n\t Priority Bit %d: %s", + i, (tval & (1 << i)) ? "Enabled" : "Disabled"); + printf("\n\t NumTCPFCSupported: %d", *(tptr+5)); + break; + case LLDP_DCBX_APPLICATION_TLV: + if (tlv_len < 4) { + goto trunc; + } + printf("\n\t Feature - Application (type 0x%x, length %d)", + LLDP_DCBX_APPLICATION_TLV, tlv_len); + printf("\n\t Oper_Version: %d", *tptr); + printf("\n\t Max_Version: %d", *(tptr+1)); + printf("\n\t Info block(0x%02X): ", *(tptr+2)); + tval = *(tptr+2); + printf("Enable bit: %d, Willing bit: %d, Error Bit: %d", + (tval & 0x80) ? 1 : 0, (tval & 0x40) ? 1 : 0, + (tval & 0x20) ? 1 : 0); + printf("\n\t SubType: %d", *(tptr+3)); + tval = tlv_len - 4; + mptr = tptr + 4; + while (tval >= 6) { + printf("\n\t Application Value"); + printf("\n\t Application Protocol ID: 0x%04x", + EXTRACT_16BITS(mptr)); + uval = EXTRACT_24BITS(mptr+2); + printf("\n\t SF (0x%x) Application Protocol ID is %s", + (uval >> 22), + (uval >> 22) ? "Socket Number" : "L2 EtherType"); + printf("\n\t OUI: 0x%06x", uval & 0x3fffff); + printf("\n\t User Priority Map: 0x%02x", *(mptr+5)); + tval = tval - 6; + mptr = mptr + 6; + } + break; + default: + hexdump = TRUE; + break; + } + + /* do we also want to see a hex dump ? */ + if (vflag > 1 || (vflag && hexdump)) { + print_unknown_data(tptr,"\n\t ", tlv_len); + } + + tlen -= tlv_len; + tptr += tlv_len; + } + + trunc: + return hexdump; +} + static char * -lldp_network_addr_print(const u_char *tptr) { +lldp_network_addr_print(const u_char *tptr, u_int len) { u_int8_t af; static char buf[BUFSIZE]; const char * (*pfunc)(const u_char *); + if (len < 1) + return NULL; + len--; af = *tptr; switch (af) { case AFNUM_INET: + if (len < 4) + return NULL; pfunc = getname; break; #ifdef INET6 case AFNUM_INET6: + if (len < 16) + return NULL; pfunc = getname6; break; #endif case AFNUM_802: + if (len < 6) + return NULL; pfunc = etheraddr_string; break; default: @@ -854,10 +1117,14 @@ lldp_mgmt_addr_tlv_print(const u_char *pptr, u_int len) { u_int8_t mgmt_addr_len, intf_num_subtype, oid_len; const u_char *tptr; u_int tlen; + char *mgmt_addr; tlen = len; tptr = pptr; + if (tlen < 1) { + return 0; + } mgmt_addr_len = *tptr++; tlen--; @@ -865,9 +1132,12 @@ lldp_mgmt_addr_tlv_print(const u_char *pptr, u_int len) { return 0; } + mgmt_addr = lldp_network_addr_print(tptr, mgmt_addr_len); + if (mgmt_addr == NULL) { + return 0; + } printf("\n\t Management Address length %u, %s", - mgmt_addr_len, - lldp_network_addr_print(tptr)); + mgmt_addr_len, mgmt_addr); tptr += mgmt_addr_len; tlen -= mgmt_addr_len; @@ -890,6 +1160,9 @@ lldp_mgmt_addr_tlv_print(const u_char *pptr, u_int len) { if (tlen) { oid_len = *tptr; + if (tlen < oid_len) { + return 0; + } if (oid_len) { printf("\n\t OID length %u", oid_len); safeputs((const char *)tptr+1, oid_len); @@ -906,6 +1179,7 @@ lldp_print(register const u_char *pptr, register u_int len) { u_int16_t tlv, cap, ena_cap; u_int oui, tlen, hexdump, tlv_type, tlv_len; const u_char *tptr; + char *network_addr; tptr = pptr; tlen = len; @@ -939,47 +1213,17 @@ lldp_print(register const u_char *pptr, register u_int len) { } TCHECK2(*tptr, tlv_len); + if (tlen < tlv_len) { + goto trunc; + } switch (tlv_type) { - case LLDP_TTL_TLV: - if (vflag) { - printf(": TTL %us", EXTRACT_16BITS(tptr)); - } - break; - - case LLDP_SYSTEM_NAME_TLV: - - /* - * The system name is also print in non-verbose mode - * similar to the CDP printer. - */ - if (vflag) { - printf(": "); - safeputs((const char *)tptr, tlv_len); - } else { - printf("LLDP, name "); - safeputs((const char *)tptr, tlv_len); - printf(", length %u", len); - } - break; - - case LLDP_PORT_DESCR_TLV: - if (vflag) { - printf(": "); - safeputs((const char *)tptr, tlv_len); - } - break; - - case LLDP_SYSTEM_DESCR_TLV: - if (vflag) { - printf("\n\t "); - safeputs((const char *)tptr, tlv_len); - } - break; - case LLDP_CHASSIS_ID_TLV: if (vflag) { + if (tlv_len < 2) { + goto trunc; + } subtype = *tptr; printf("\n\t Subtype %s (%u): ", tok2str(lldp_chassis_subtype_values, "Unknown", subtype), @@ -987,6 +1231,9 @@ lldp_print(register const u_char *pptr, register u_int len) { switch (subtype) { case LLDP_CHASSIS_MAC_ADDR_SUBTYPE: + if (tlv_len < 1+6) { + goto trunc; + } printf("%s", etheraddr_string(tptr+1)); break; @@ -999,7 +1246,11 @@ lldp_print(register const u_char *pptr, register u_int len) { break; case LLDP_CHASSIS_NETWORK_ADDR_SUBTYPE: - printf("%s", lldp_network_addr_print(tptr+1)); + network_addr = lldp_network_addr_print(tptr+1, tlv_len-1); + if (network_addr == NULL) { + goto trunc; + } + printf("%s", network_addr); break; default: @@ -1011,6 +1262,9 @@ lldp_print(register const u_char *pptr, register u_int len) { case LLDP_PORT_ID_TLV: if (vflag) { + if (tlv_len < 2) { + goto trunc; + } subtype = *tptr; printf("\n\t Subtype %s (%u): ", tok2str(lldp_port_subtype_values, "Unknown", subtype), @@ -1018,6 +1272,9 @@ lldp_print(register const u_char *pptr, register u_int len) { switch (subtype) { case LLDP_PORT_MAC_ADDR_SUBTYPE: + if (tlv_len < 1+6) { + goto trunc; + } printf("%s", etheraddr_string(tptr+1)); break; @@ -1030,7 +1287,11 @@ lldp_print(register const u_char *pptr, register u_int len) { break; case LLDP_PORT_NETWORK_ADDR_SUBTYPE: - printf("%s", lldp_network_addr_print(tptr+1)); + network_addr = lldp_network_addr_print(tptr+1, tlv_len-1); + if (network_addr == NULL) { + goto trunc; + } + printf("%s", network_addr); break; default: @@ -1040,30 +1301,55 @@ lldp_print(register const u_char *pptr, register u_int len) { } break; - case LLDP_PRIVATE_TLV: + case LLDP_TTL_TLV: if (vflag) { - oui = EXTRACT_24BITS(tptr); - printf(": OUI %s (0x%06x)", tok2str(oui_values, "Unknown", oui), oui); - - switch (oui) { - case OUI_IEEE_8021_PRIVATE: - hexdump = lldp_private_8021_print(tptr); - break; - case OUI_IEEE_8023_PRIVATE: - hexdump = lldp_private_8023_print(tptr); - break; - case OUI_TIA: - hexdump = lldp_private_tia_print(tptr, tlv_len); - break; - default: - hexdump = TRUE; - break; + if (tlv_len < 2) { + goto trunc; } + printf(": TTL %us", EXTRACT_16BITS(tptr)); + } + break; + + case LLDP_PORT_DESCR_TLV: + if (vflag) { + printf(": "); + safeputs((const char *)tptr, tlv_len); + } + break; + + case LLDP_SYSTEM_NAME_TLV: + /* + * The system name is also print in non-verbose mode + * similar to the CDP printer. + */ + if (vflag) { + printf(": "); + safeputs((const char *)tptr, tlv_len); + } else { + printf("LLDP, name "); + safeputs((const char *)tptr, tlv_len); + printf(", length %u", len); + } + break; + + case LLDP_SYSTEM_DESCR_TLV: + if (vflag) { + printf("\n\t "); + safeputs((const char *)tptr, tlv_len); } break; case LLDP_SYSTEM_CAP_TLV: if (vflag) { + /* + * XXX - IEEE Std 802.1AB-2009 says the first octet + * if a chassis ID subtype, with the system + * capabilities and enabled capabilities following + * it. + */ + if (tlv_len < 4) { + goto trunc; + } cap = EXTRACT_16BITS(tptr); ena_cap = EXTRACT_16BITS(tptr+2); printf("\n\t System Capabilities [%s] (0x%04x)", @@ -1075,9 +1361,37 @@ lldp_print(register const u_char *pptr, register u_int len) { case LLDP_MGMT_ADDR_TLV: if (vflag) { - if (!lldp_mgmt_addr_tlv_print(tptr, tlen)) { + if (!lldp_mgmt_addr_tlv_print(tptr, tlv_len)) { + goto trunc; + } + } + break; + + case LLDP_PRIVATE_TLV: + if (vflag) { + if (tlv_len < 3) { goto trunc; } + oui = EXTRACT_24BITS(tptr); + printf(": OUI %s (0x%06x)", tok2str(oui_values, "Unknown", oui), oui); + + switch (oui) { + case OUI_IEEE_8021_PRIVATE: + hexdump = lldp_private_8021_print(tptr, tlv_len); + break; + case OUI_IEEE_8023_PRIVATE: + hexdump = lldp_private_8023_print(tptr, tlv_len); + break; + case OUI_TIA: + hexdump = lldp_private_tia_print(tptr, tlv_len); + break; + case OUI_DCBX: + hexdump = lldp_private_dcbx_print(tptr, tlv_len); + break; + default: + hexdump = TRUE; + break; + } } break; diff --git a/contrib/tcpdump/print-lmp.c b/contrib/tcpdump/print-lmp.c index 556db173e4..e09b89fc22 100644 --- a/contrib/tcpdump/print-lmp.c +++ b/contrib/tcpdump/print-lmp.c @@ -871,7 +871,7 @@ lmp_print(register const u_char *pptr, register u_int len) { } /* do we want to see an additionally hexdump ? */ if (vflag > 1 || hexdump==TRUE) - print_unknown_data(tptr+sizeof(sizeof(struct lmp_object_header)),"\n\t ", + print_unknown_data(tptr+sizeof(struct lmp_object_header),"\n\t ", lmp_obj_len-sizeof(struct lmp_object_header)); tptr+=lmp_obj_len; diff --git a/contrib/tcpdump/print-lspping.c b/contrib/tcpdump/print-lspping.c index f47a900485..2ca57fb05c 100644 --- a/contrib/tcpdump/print-lspping.c +++ b/contrib/tcpdump/print-lspping.c @@ -15,7 +15,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-lspping.c,v 1.18.2.1 2008-01-28 13:48:16 hannes Exp $"; + "@(#) $Header: /tcpdump/master/tcpdump/print-lspping.c,v 1.20 2008-01-28 14:20:43 hannes Exp $"; #endif #ifdef HAVE_CONFIG_H @@ -34,6 +34,7 @@ static const char rcsid[] _U_ = #include "bgp.h" #include "l2vpn.h" +#include "oui.h" /* * LSPPING common header @@ -134,7 +135,11 @@ struct lspping_tlv_header { #define LSPPING_TLV_TARGET_FEC_STACK 1 #define LSPPING_TLV_DOWNSTREAM_MAPPING 2 #define LSPPING_TLV_PAD 3 -#define LSPPING_TLV_ERROR_CODE 4 +#define LSPPING_TLV_VENDOR_ENTERPRISE 5 +#define LSPPING_TLV_VENDOR_ENTERPRISE_LEN 4 +#define LSPPING_TLV_INTERFACE_LABEL_STACK 7 +#define LSPPING_TLV_ERROR_CODE 9 +#define LSPPING_TLV_REPLY_TOS_BYTE 10 #define LSPPING_TLV_BFD_DISCRIMINATOR 15 /* draft-ietf-bfd-mpls-02 */ #define LSPPING_TLV_BFD_DISCRIMINATOR_LEN 4 #define LSPPING_TLV_VENDOR_PRIVATE 0xfc00 @@ -144,8 +149,11 @@ static const struct tok lspping_tlv_values[] = { { LSPPING_TLV_DOWNSTREAM_MAPPING, "Downstream Mapping" }, { LSPPING_TLV_PAD, "Pad" }, { LSPPING_TLV_ERROR_CODE, "Error Code" }, + { LSPPING_TLV_VENDOR_ENTERPRISE, "Vendor Enterprise Code" }, + { LSPPING_TLV_INTERFACE_LABEL_STACK, "Interface Label Stack" }, + { LSPPING_TLV_REPLY_TOS_BYTE, "Reply TOS Byte" }, { LSPPING_TLV_BFD_DISCRIMINATOR, "BFD Discriminator" }, - { LSPPING_TLV_VENDOR_PRIVATE, "Vendor Enterprise Code" }, + { LSPPING_TLV_VENDOR_PRIVATE, "Vendor Private Code" }, { 0, NULL} }; @@ -566,6 +574,7 @@ lspping_print(register const u_char *pptr, register u_int len) { tlen-=sizeof(const struct lspping_common_header); while(tlen>(int)sizeof(struct lspping_tlv_header)) { + /* did we capture enough for fully decoding the tlv header ? */ if (!TTEST2(*tptr, sizeof(struct lspping_tlv_header))) goto trunc; @@ -840,11 +849,24 @@ lspping_print(register const u_char *pptr, register u_int len) { goto trunc; printf("\n\t BFD Discriminator 0x%08x", EXTRACT_32BITS(tptr)); break; + + case LSPPING_TLV_VENDOR_ENTERPRISE: + { + u_int32_t vendor_id; + + if (!TTEST2(*tptr, LSPPING_TLV_VENDOR_ENTERPRISE_LEN)) + goto trunc; + vendor_id = EXTRACT_32BITS(tlv_tptr); + printf("\n\t Vendor: %s (0x%04x)", + tok2str(smi_values, "Unknown", vendor_id), + vendor_id); + } + break; + /* * FIXME those are the defined TLVs that lack a decoder * you are welcome to contribute code ;-) */ - case LSPPING_TLV_PAD: case LSPPING_TLV_ERROR_CODE: case LSPPING_TLV_VENDOR_PRIVATE: @@ -856,7 +878,7 @@ lspping_print(register const u_char *pptr, register u_int len) { } /* do we want to see an additionally tlv hexdump ? */ if (vflag > 1 || tlv_hexdump==TRUE) - print_unknown_data(tptr+sizeof(sizeof(struct lspping_tlv_header)),"\n\t ", + print_unknown_data(tptr+sizeof(struct lspping_tlv_header),"\n\t ", lspping_tlv_len); diff --git a/contrib/tcpdump/print-mobile.c b/contrib/tcpdump/print-mobile.c index 816ffd6e65..de4eab1dce 100644 --- a/contrib/tcpdump/print-mobile.c +++ b/contrib/tcpdump/print-mobile.c @@ -72,6 +72,7 @@ mobile_print(const u_char *bp, u_int length) { const u_char *cp = bp +8 ; const struct mobile_ip *mob; + struct cksum_vec vec[1]; u_short proto,crc; u_char osp =0; /* old source address present */ @@ -101,7 +102,9 @@ mobile_print(const u_char *bp, u_int length) (void)printf("> %s ",ipaddr_string(&mob->odst)); (void)printf("(oproto=%d)",proto>>8); } - if (in_cksum((u_short *)mob, osp ? 12 : 8, 0)!=0) { + vec[0].ptr = (const u_int8_t *)(void *)mob; + vec[0].len = osp ? 12 : 8; + if (in_cksum(vec, 1)!=0) { (void)printf(" (bad checksum %d)",crc); } diff --git a/contrib/tcpdump/print-mpls.c b/contrib/tcpdump/print-mpls.c index c6b0814ffe..d97cce5278 100644 --- a/contrib/tcpdump/print-mpls.c +++ b/contrib/tcpdump/print-mpls.c @@ -54,6 +54,13 @@ static const char *mpls_labelname[] = { /*15*/ "rsvd", }; +enum mpls_packet_type { + PT_UNKNOWN, + PT_IPV4, + PT_IPV6, + PT_OSI +}; + /* * RFC3032: MPLS label stack encoding */ @@ -62,7 +69,8 @@ mpls_print(const u_char *bp, u_int length) { const u_char *p; u_int32_t label_entry; - u_int16_t label_stack_depth = 0; + u_int16_t label_stack_depth = 0; + enum mpls_packet_type pt = PT_UNKNOWN; p = bp; printf("MPLS"); @@ -70,9 +78,9 @@ mpls_print(const u_char *bp, u_int length) TCHECK2(*p, sizeof(label_entry)); label_entry = EXTRACT_32BITS(p); printf("%s(label %u", - label_stack_depth ? "\n\t" : " ", - MPLS_LABEL(label_entry)); - label_stack_depth++; + (label_stack_depth && vflag) ? "\n\t" : " ", + MPLS_LABEL(label_entry)); + label_stack_depth++; if (vflag && MPLS_LABEL(label_entry) < sizeof(mpls_labelname) / sizeof(mpls_labelname[0])) printf(" (%s)", mpls_labelname[MPLS_LABEL(label_entry)]); @@ -84,97 +92,127 @@ mpls_print(const u_char *bp, u_int length) p += sizeof(label_entry); } while (!MPLS_STACK(label_entry)); + /* + * Try to figure out the packet type. + */ switch (MPLS_LABEL(label_entry)) { + case 0: /* IPv4 explicit NULL label */ - case 3: /* IPv4 implicit NULL label */ - if (vflag>0) { - printf("\n\t"); - ip_print(gndo, p, length - (p - bp)); - } - else printf(", IP, length: %u",length); + case 3: /* IPv4 implicit NULL label */ + pt = PT_IPV4; break; -#ifdef INET6 + case 2: /* IPv6 explicit NULL label */ - if (vflag>0) { - printf("\n\t"); - ip6_print(p, length - (p - bp)); - } - else printf(", IPv6, length: %u",length); + pt = PT_IPV6; break; -#endif + default: /* * Generally there's no indication of protocol in MPLS label - * encoding, however draft-hsmit-isis-aal5mux-00.txt describes - * a technique that looks at the first payload byte if the BOS (bottom of stack) - * bit is set and tries to determine the network layer protocol - * 0x45-0x4f is IPv4 - * 0x60-0x6f is IPv6 - * 0x81-0x83 is OSI (CLNP,ES-IS,IS-IS) - * this technique is sometimes known as NULL encapsulation - * and decoding is particularly useful for control-plane traffic [BGP] - * which cisco by default sends MPLS encapsulated + * encoding. + * + * However, draft-hsmit-isis-aal5mux-00.txt describes a + * technique for encapsulating IS-IS and IP traffic on the + * same ATM virtual circuit; you look at the first payload + * byte to determine the network layer protocol, based on + * the fact that + * + * 1) the first byte of an IP header is 0x45-0x4f + * for IPv4 and 0x60-0x6f for IPv6; + * + * 2) the first byte of an OSI CLNP packet is 0x81, + * the first byte of an OSI ES-IS packet is 0x82, + * and the first byte of an OSI IS-IS packet is + * 0x83; + * + * so the network layer protocol can be inferred from the + * first byte of the packet, if the protocol is one of the + * ones listed above. + * + * Cisco sends control-plane traffic MPLS-encapsulated in + * this fashion. */ + switch(*p) { + + case 0x45: + case 0x46: + case 0x47: + case 0x48: + case 0x49: + case 0x4a: + case 0x4b: + case 0x4c: + case 0x4d: + case 0x4e: + case 0x4f: + pt = PT_IPV4; + break; + + case 0x60: + case 0x61: + case 0x62: + case 0x63: + case 0x64: + case 0x65: + case 0x66: + case 0x67: + case 0x68: + case 0x69: + case 0x6a: + case 0x6b: + case 0x6c: + case 0x6d: + case 0x6e: + case 0x6f: + pt = PT_IPV6; + break; + + case 0x81: + case 0x82: + case 0x83: + pt = PT_OSI; + break; + + default: + /* ok bail out - we did not figure out what it is*/ + break; + } + } - if (MPLS_STACK(label_entry)) { /* only do this if the stack bit is set */ - switch(*p) { - case 0x45: - case 0x46: - case 0x47: - case 0x48: - case 0x49: - case 0x4a: - case 0x4b: - case 0x4c: - case 0x4d: - case 0x4e: - case 0x4f: - if (vflag>0) { - printf("\n\t"); - ip_print(gndo, p, length - (p - bp)); - } - else printf(", IP, length: %u",length); - break; + /* + * Print the payload. + */ + if (pt == PT_UNKNOWN) { + if (!suppress_default_print) + default_print(p, length - (p - bp)); + return; + } + if (vflag) + printf("\n\t"); + else + printf(" "); + switch (pt) { + + case PT_IPV4: + ip_print(gndo, p, length - (p - bp)); + break; + + case PT_IPV6: #ifdef INET6 - case 0x60: - case 0x61: - case 0x62: - case 0x63: - case 0x64: - case 0x65: - case 0x66: - case 0x67: - case 0x68: - case 0x69: - case 0x6a: - case 0x6b: - case 0x6c: - case 0x6d: - case 0x6e: - case 0x6f: - if (vflag>0) { - printf("\n\t"); - ip6_print(p, length - (p - bp)); - } - else printf(", IPv6, length: %u",length); - break; + ip6_print(gndo, p, length - (p - bp)); +#else + printf("IPv6, length: %u", length); #endif - case 0x81: - case 0x82: - case 0x83: - if (vflag>0) { - printf("\n\t"); - isoclns_print(p, length - (p - bp), length - (p - bp)); - } - else printf(", OSI, length: %u",length); - break; - default: - /* ok bail out - we did not figure out what it is*/ - break; - } - } - return; + break; + + case PT_OSI: + isoclns_print(p, length - (p - bp), length - (p - bp)); + break; + + default: + break; } + return; trunc: printf("[|MPLS]"); diff --git a/contrib/tcpdump/print-nfs.c b/contrib/tcpdump/print-nfs.c index fb09e30843..4d17757f31 100644 --- a/contrib/tcpdump/print-nfs.c +++ b/contrib/tcpdump/print-nfs.c @@ -21,7 +21,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-nfs.c,v 1.110.2.1 2007-12-22 03:08:45 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-nfs.c,v 1.111 2007-12-22 03:08:04 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -508,6 +508,7 @@ nfsreq_print(register const u_char *bp, u_int length, nfs_type type; int v3; u_int32_t proc; + u_int32_t access_flags; struct nfsv3_sattr sa3; char srcid[20], dstid[20]; /*fits 32bit*/ @@ -570,7 +571,37 @@ nfsreq_print(register const u_char *bp, u_int length, if ((dp = parsereq(rp, length)) != NULL && (dp = parsefh(dp, v3)) != NULL) { TCHECK(dp[0]); - printf(" %04x", EXTRACT_32BITS(&dp[0])); + access_flags = EXTRACT_32BITS(&dp[0]); + if (access_flags & ~NFSV3ACCESS_FULL) { + /* NFSV3ACCESS definitions aren't up to date */ + printf(" %04x", access_flags); + } else if ((access_flags & NFSV3ACCESS_FULL) == NFSV3ACCESS_FULL) { + printf(" NFS_ACCESS_FULL"); + } else { + char separator = ' '; + if (access_flags & NFSV3ACCESS_READ) { + printf(" NFS_ACCESS_READ"); + separator = '|'; + } + if (access_flags & NFSV3ACCESS_LOOKUP) { + printf("%cNFS_ACCESS_LOOKUP", separator); + separator = '|'; + } + if (access_flags & NFSV3ACCESS_MODIFY) { + printf("%cNFS_ACCESS_MODIFY", separator); + separator = '|'; + } + if (access_flags & NFSV3ACCESS_EXTEND) { + printf("%cNFS_ACCESS_EXTEND", separator); + separator = '|'; + } + if (access_flags & NFSV3ACCESS_DELETE) { + printf("%cNFS_ACCESS_DELETE", separator); + separator = '|'; + } + if (access_flags & NFSV3ACCESS_EXECUTE) + printf("%cNFS_ACCESS_EXECUTE", separator); + } return; } break; diff --git a/contrib/tcpdump/print-ntp.c b/contrib/tcpdump/print-ntp.c index 4960dc829c..d56f02a262 100644 --- a/contrib/tcpdump/print-ntp.c +++ b/contrib/tcpdump/print-ntp.c @@ -25,7 +25,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-ntp.c,v 1.42 2005-05-06 07:56:53 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-ntp.c,v 1.43 2007-11-30 13:45:10 hannes Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -72,6 +72,12 @@ static struct tok ntp_leapind_values[] = { { 0, NULL } }; +static struct tok ntp_stratum_values[] = { + { UNSPECIFIED, "unspecified" }, + { PRIM_REF, "primary reference" }, + { 0, NULL } +}; + /* * Print ntp requests */ @@ -106,7 +112,9 @@ ntp_print(register const u_char *cp, u_int length) leapind); TCHECK(bp->stratum); - printf(", Stratum %u", bp->stratum); + printf(", Stratum %u (%s)", + bp->stratum, + tok2str(ntp_stratum_values, (bp->stratum >=2 && bp->stratum<=15) ? "secondary reference" : "reserved", bp->stratum)); TCHECK(bp->ppoll); printf(", poll %us", bp->ppoll); @@ -174,8 +182,19 @@ ntp_print(register const u_char *cp, u_int length) fputs("\n\t Originator - Transmit Timestamp: ", stdout); p_ntp_delta(&(bp->org_timestamp), &(bp->xmt_timestamp)); - /* FIXME key-id, authentication */ - + if ( (sizeof(struct ntpdata) - length) == 16) { /* Optional: key-id */ + TCHECK(bp->key_id); + printf("\n\tKey id: %u", bp->key_id); + } else if ( (sizeof(struct ntpdata) - length) == 0) { /* Optional: key-id + authentication */ + TCHECK(bp->key_id); + printf("\n\tKey id: %u", bp->key_id); + TCHECK2(bp->message_digest, sizeof (bp->message_digest)); + printf("\n\tAuthentication: %08x%08x%08x%08x", + EXTRACT_32BITS(bp->message_digest), + EXTRACT_32BITS(bp->message_digest + 4), + EXTRACT_32BITS(bp->message_digest + 8), + EXTRACT_32BITS(bp->message_digest + 12)); + } return; trunc: diff --git a/contrib/tcpdump/print-null.c b/contrib/tcpdump/print-null.c index a69997da12..8eabe5dd99 100644 --- a/contrib/tcpdump/print-null.c +++ b/contrib/tcpdump/print-null.c @@ -125,7 +125,7 @@ null_if_print(const struct pcap_pkthdr *h, const u_char *p) case BSD_AFNUM_INET6_BSD: case BSD_AFNUM_INET6_FREEBSD: case BSD_AFNUM_INET6_DARWIN: - ip6_print(p, length); + ip6_print(gndo, p, length); break; #endif diff --git a/contrib/tcpdump/print-olsr.c b/contrib/tcpdump/print-olsr.c index 174a51eac9..ba0ed2bede 100644 --- a/contrib/tcpdump/print-olsr.c +++ b/contrib/tcpdump/print-olsr.c @@ -1,5 +1,6 @@ /* * Copyright (c) 1998-2007 The TCPDUMP project + * Copyright (c) 2009 Florian Forster * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code @@ -15,6 +16,7 @@ * Optimized Link State Protocl (OLSR) as per rfc3626 * * Original code by Hannes Gredler + * IPv6 additions by Florian Forster */ #ifdef HAVE_CONFIG_H @@ -28,7 +30,7 @@ #include "interface.h" #include "addrtoname.h" -#include "extract.h" +#include "extract.h" #include "ip.h" /* @@ -88,7 +90,7 @@ static struct tok olsr_msg_values[] = { { 0, NULL} }; -struct olsr_msg { +struct olsr_msg4 { u_int8_t msg_type; u_int8_t vtime; u_int8_t msg_len[2]; @@ -98,6 +100,16 @@ struct olsr_msg { u_int8_t msg_seq[2]; }; +struct olsr_msg6 { + u_int8_t msg_type; + u_int8_t vtime; + u_int8_t msg_len[2]; + u_int8_t originator[16]; + u_int8_t ttl; + u_int8_t hopcount; + u_int8_t msg_seq[2]; +}; + struct olsr_hello { u_int8_t res[2]; u_int8_t htime; @@ -115,11 +127,16 @@ struct olsr_tc { u_int8_t res[2]; }; -struct olsr_hna { +struct olsr_hna4 { u_int8_t network[4]; u_int8_t mask[4]; }; +struct olsr_hna6 { + u_int8_t network[16]; + u_int8_t mask[16]; +}; + #define OLSR_EXTRACT_LINK_TYPE(link_code) (link_code & 0x3) #define OLSR_EXTRACT_NEIGHBOR_TYPE(link_code) (link_code >> 2) @@ -139,13 +156,20 @@ static struct tok olsr_neighbor_type_values[] = { { 0, NULL} }; -struct olsr_lq_neighbor { +struct olsr_lq_neighbor4 { u_int8_t neighbor[4]; u_int8_t link_quality; u_int8_t neighbor_link_quality; u_int8_t res[2]; }; +struct olsr_lq_neighbor6 { + u_int8_t neighbor[16]; + u_int8_t link_quality; + u_int8_t neighbor_link_quality; + u_int8_t res[2]; +}; + /* * macro to convert the 8-bit mantissa/exponent to a double float * taken from olsr.org. @@ -158,13 +182,13 @@ struct olsr_lq_neighbor { * print a neighbor list with LQ extensions. */ static void -olsr_print_lq_neighbor (const u_char *msg_data, u_int hello_len) +olsr_print_lq_neighbor4 (const u_char *msg_data, u_int hello_len) { - struct olsr_lq_neighbor *lq_neighbor; + struct olsr_lq_neighbor4 *lq_neighbor; - while (hello_len >= sizeof(struct olsr_lq_neighbor)) { + while (hello_len >= sizeof(struct olsr_lq_neighbor4)) { - lq_neighbor = (struct olsr_lq_neighbor *)msg_data; + lq_neighbor = (struct olsr_lq_neighbor4 *)msg_data; printf("\n\t neighbor %s, link-quality %.2lf%%" ", neighbor-link-quality %.2lf%%", @@ -172,11 +196,33 @@ olsr_print_lq_neighbor (const u_char *msg_data, u_int hello_len) ((double)lq_neighbor->link_quality/2.55), ((double)lq_neighbor->neighbor_link_quality/2.55)); - msg_data += sizeof(struct olsr_lq_neighbor); - hello_len -= sizeof(struct olsr_lq_neighbor); + msg_data += sizeof(struct olsr_lq_neighbor4); + hello_len -= sizeof(struct olsr_lq_neighbor4); } } +#if INET6 +static void +olsr_print_lq_neighbor6 (const u_char *msg_data, u_int hello_len) +{ + struct olsr_lq_neighbor6 *lq_neighbor; + + while (hello_len >= sizeof(struct olsr_lq_neighbor6)) { + + lq_neighbor = (struct olsr_lq_neighbor6 *)msg_data; + + printf("\n\t neighbor %s, link-quality %.2lf%%" + ", neighbor-link-quality %.2lf%%", + ip6addr_string(lq_neighbor->neighbor), + ((double)lq_neighbor->link_quality/2.55), + ((double)lq_neighbor->neighbor_link_quality/2.55)); + + msg_data += sizeof(struct olsr_lq_neighbor6); + hello_len -= sizeof(struct olsr_lq_neighbor6); + } +} +#endif /* INET6 */ + /* * print a neighbor list. */ @@ -202,38 +248,41 @@ olsr_print_neighbor (const u_char *msg_data, u_int hello_len) void -olsr_print (const u_char *pptr, u_int length) +olsr_print (const u_char *pptr, u_int length, int is_ipv6) { union { const struct olsr_common *common; - const struct olsr_msg *msg; + const struct olsr_msg4 *msg4; + const struct olsr_msg6 *msg6; const struct olsr_hello *hello; const struct olsr_hello_link *hello_link; - const struct olsr_lq_neighbor *lq_neighbor; const struct olsr_tc *tc; - const struct olsr_hna *hna; + const struct olsr_hna4 *hna; } ptr; - u_int msg_type, msg_len, msg_tlen, hello_len, prefix; + u_int msg_type, msg_len, msg_tlen, hello_len; + u_int16_t name_entry_type, name_entry_len; + u_int name_entry_padding; u_int8_t link_type, neighbor_type; const u_char *tptr, *msg_data; - tptr = pptr; + tptr = pptr; if (length < sizeof(struct olsr_common)) { goto trunc; } if (!TTEST2(*tptr, sizeof(struct olsr_common))) { - goto trunc; + goto trunc; } ptr.common = (struct olsr_common *)tptr; length = MIN(length, EXTRACT_16BITS(ptr.common->packet_len)); - printf("OLSR, seq 0x%04x, length %u", - EXTRACT_16BITS(ptr.common->packet_seq), - length); + printf("OLSRv%i, seq 0x%04x, length %u", + (is_ipv6 == 0) ? 4 : 6, + EXTRACT_16BITS(ptr.common->packet_seq), + length); tptr += sizeof(struct olsr_common); @@ -241,41 +290,81 @@ olsr_print (const u_char *pptr, u_int length) * In non-verbose mode, just print version. */ if (vflag < 1) { - return; + return; } while (tptr < (pptr+length)) { - - if (!TTEST2(*tptr, sizeof(struct olsr_msg))) + union + { + struct olsr_msg4 *v4; + struct olsr_msg6 *v6; + } msgptr; + int msg_len_valid = 0; + + if (!TTEST2(*tptr, sizeof(struct olsr_msg4))) goto trunc; - ptr.msg = (struct olsr_msg *)tptr; - - msg_type = ptr.msg->msg_type; - msg_len = EXTRACT_16BITS(ptr.msg->msg_len); +#if INET6 + if (is_ipv6) + { + msgptr.v6 = (struct olsr_msg6 *) tptr; + msg_type = msgptr.v6->msg_type; + msg_len = EXTRACT_16BITS(msgptr.v6->msg_len); + if ((msg_len >= sizeof (struct olsr_msg6)) + && (msg_len <= length)) + msg_len_valid = 1; + + /* infinite loop check */ + if (msg_type == 0 || msg_len == 0) { + return; + } - /* infinite loop check */ - if (msg_type == 0 || msg_len == 0) { - return; + printf("\n\t%s Message (%#04x), originator %s, ttl %u, hop %u" + "\n\t vtime %.3lfs, msg-seq 0x%04x, length %u%s", + tok2str(olsr_msg_values, "Unknown", msg_type), + msg_type, ip6addr_string(msgptr.v6->originator), + msgptr.v6->ttl, + msgptr.v6->hopcount, + ME_TO_DOUBLE(msgptr.v6->vtime), + EXTRACT_16BITS(msgptr.v6->msg_seq), + msg_len, (msg_len_valid == 0) ? " (invalid)" : ""); + + msg_tlen = msg_len - sizeof(struct olsr_msg6); + msg_data = tptr + sizeof(struct olsr_msg6); } + else /* (!is_ipv6) */ +#endif /* INET6 */ + { + msgptr.v4 = (struct olsr_msg4 *) tptr; + msg_type = msgptr.v4->msg_type; + msg_len = EXTRACT_16BITS(msgptr.v4->msg_len); + if ((msg_len >= sizeof (struct olsr_msg4)) + && (msg_len <= length)) + msg_len_valid = 1; + + /* infinite loop check */ + if (msg_type == 0 || msg_len == 0) { + return; + } - printf("\n\t%s Message (%u), originator %s, ttl %u, hop %u" - "\n\t vtime %.3lfs, msg-seq 0x%04x, length %u", - tok2str(olsr_msg_values, "Unknown", msg_type), - msg_type, ipaddr_string(ptr.msg->originator), - ptr.msg->ttl, - ptr.msg->hopcount, - ME_TO_DOUBLE(ptr.msg->vtime), - EXTRACT_16BITS(ptr.msg->msg_seq), - msg_len); - - msg_tlen = msg_len - sizeof(struct olsr_msg); - msg_data = tptr + sizeof(struct olsr_msg); + printf("\n\t%s Message (%#04x), originator %s, ttl %u, hop %u" + "\n\t vtime %.3lfs, msg-seq 0x%04x, length %u%s", + tok2str(olsr_msg_values, "Unknown", msg_type), + msg_type, ipaddr_string(msgptr.v4->originator), + msgptr.v4->ttl, + msgptr.v4->hopcount, + ME_TO_DOUBLE(msgptr.v4->vtime), + EXTRACT_16BITS(msgptr.v4->msg_seq), + msg_len, (msg_len_valid == 0) ? " (invalid)" : ""); + + msg_tlen = msg_len - sizeof(struct olsr_msg4); + msg_data = tptr + sizeof(struct olsr_msg4); + } switch (msg_type) { case OLSR_HELLO_MSG: case OLSR_HELLO_LQ_MSG: - if (!TTEST2(*msg_data, sizeof(struct olsr_hello))) + if (!TTEST2(*msg_data, sizeof(struct olsr_hello))) goto trunc; ptr.hello = (struct olsr_hello *)msg_data; @@ -285,11 +374,12 @@ olsr_print (const u_char *pptr, u_int length) msg_tlen -= sizeof(struct olsr_hello); while (msg_tlen >= sizeof(struct olsr_hello_link)) { + int hello_len_valid = 0; /* * link-type. */ - if (!TTEST2(*msg_data, sizeof(struct olsr_hello_link))) + if (!TTEST2(*msg_data, sizeof(struct olsr_hello_link))) goto trunc; ptr.hello_link = (struct olsr_hello_link *)msg_data; @@ -298,10 +388,18 @@ olsr_print (const u_char *pptr, u_int length) link_type = OLSR_EXTRACT_LINK_TYPE(ptr.hello_link->link_code); neighbor_type = OLSR_EXTRACT_NEIGHBOR_TYPE(ptr.hello_link->link_code); - printf("\n\t link-type %s, neighbor-type %s, len %u", + if ((hello_len <= msg_tlen) + && (hello_len >= sizeof(struct olsr_hello_link))) + hello_len_valid = 1; + + printf("\n\t link-type %s, neighbor-type %s, len %u%s", tok2str(olsr_link_type_values, "Unknown", link_type), tok2str(olsr_neighbor_type_values, "Unknown", neighbor_type), - hello_len); + hello_len, + (hello_len_valid == 0) ? " (invalid)" : ""); + + if (hello_len_valid == 0) + break; msg_data += sizeof(struct olsr_hello_link); msg_tlen -= sizeof(struct olsr_hello_link); @@ -310,7 +408,12 @@ olsr_print (const u_char *pptr, u_int length) if (msg_type == OLSR_HELLO_MSG) { olsr_print_neighbor(msg_data, hello_len); } else { - olsr_print_lq_neighbor(msg_data, hello_len); +#if INET6 + if (is_ipv6) + olsr_print_lq_neighbor6(msg_data, hello_len); + else +#endif + olsr_print_lq_neighbor4(msg_data, hello_len); } msg_data += hello_len; @@ -320,7 +423,7 @@ olsr_print (const u_char *pptr, u_int length) case OLSR_TC_MSG: case OLSR_TC_LQ_MSG: - if (!TTEST2(*msg_data, sizeof(struct olsr_tc))) + if (!TTEST2(*msg_data, sizeof(struct olsr_tc))) goto trunc; ptr.tc = (struct olsr_tc *)msg_data; @@ -332,56 +435,182 @@ olsr_print (const u_char *pptr, u_int length) if (msg_type == OLSR_TC_MSG) { olsr_print_neighbor(msg_data, msg_tlen); } else { - olsr_print_lq_neighbor(msg_data, msg_tlen); +#if INET6 + if (is_ipv6) + olsr_print_lq_neighbor6(msg_data, msg_tlen); + else +#endif + olsr_print_lq_neighbor4(msg_data, msg_tlen); } break; case OLSR_MID_MSG: - if (!TTEST2(*msg_data, sizeof(struct in_addr))) - goto trunc; + { + size_t addr_size = sizeof(struct in_addr); - while (msg_tlen >= sizeof(struct in_addr)) { - printf("\n\t interface address %s", ipaddr_string(msg_data)); - msg_data += sizeof(struct in_addr); - msg_tlen -= sizeof(struct in_addr); +#if INET6 + if (is_ipv6) + addr_size = sizeof(struct in6_addr); +#endif + + while (msg_tlen >= addr_size) { + if (!TTEST2(*msg_data, addr_size)) + goto trunc; + + printf("\n\t interface address %s", +#if INET6 + is_ipv6 ? ip6addr_string(msg_data) : +#endif + ipaddr_string(msg_data)); + msg_data += addr_size; + msg_tlen -= addr_size; } break; + } case OLSR_HNA_MSG: - prefix = 1; - printf("\n\t advertised networks\n\t "); - while (msg_tlen >= sizeof(struct olsr_hna)) { - if (!TTEST2(*msg_data, sizeof(struct olsr_hna))) - goto trunc; + printf("\n\t Advertised networks (total %u)", + (unsigned int) (msg_tlen / sizeof(struct olsr_hna6))); +#if INET6 + if (is_ipv6) + { + int i = 0; + while (msg_tlen >= sizeof(struct olsr_hna6)) { + struct olsr_hna6 *hna6; + + if (!TTEST2(*msg_data, sizeof(struct olsr_hna6))) + goto trunc; + + hna6 = (struct olsr_hna6 *)msg_data; + + printf("\n\t #%i: %s/%u", + i, ip6addr_string(hna6->network), + mask62plen (hna6->mask)); + + msg_data += sizeof(struct olsr_hna6); + msg_tlen -= sizeof(struct olsr_hna6); + } + } + else +#endif + { + int col = 0; + while (msg_tlen >= sizeof(struct olsr_hna4)) { + if (!TTEST2(*msg_data, sizeof(struct olsr_hna4))) + goto trunc; + + ptr.hna = (struct olsr_hna4 *)msg_data; - ptr.hna = (struct olsr_hna *)msg_data; + /* print 4 prefixes per line */ + if (col == 0) + printf ("\n\t "); + else + printf (", "); - /* print 4 prefixes per line */ + printf("%s/%u", + ipaddr_string(ptr.hna->network), + mask2plen(EXTRACT_32BITS(ptr.hna->mask))); - printf("%s/%u%s", - ipaddr_string(ptr.hna->network), - mask2plen(EXTRACT_32BITS(ptr.hna->mask)), - prefix % 4 == 0 ? "\n\t " : " "); + msg_data += sizeof(struct olsr_hna4); + msg_tlen -= sizeof(struct olsr_hna4); - msg_data += sizeof(struct olsr_hna); - msg_tlen -= sizeof(struct olsr_hna); - prefix ++; + col = (col + 1) % 4; + } } break; + case OLSR_NAMESERVICE_MSG: + { + u_int name_entries = EXTRACT_16BITS(msg_data+2); + u_int addr_size = 4; + int name_entries_valid = 0; + u_int i; + + if (is_ipv6) + addr_size = 16; + + if ((name_entries > 0) + && ((name_entries * (4 + addr_size)) <= msg_tlen)) + name_entries_valid = 1; + + if (msg_tlen < 4) + goto trunc; + if (!TTEST2(*msg_data, 4)) + goto trunc; + + printf("\n\t Version %u, Entries %u%s", + EXTRACT_16BITS(msg_data), + name_entries, (name_entries_valid == 0) ? " (invalid)" : ""); + + if (name_entries_valid == 0) + break; + + msg_data += 4; + msg_tlen -= 4; + + for (i = 0; i < name_entries; i++) { + int name_entry_len_valid = 0; + + if (msg_tlen < 4) + break; + if (!TTEST2(*msg_data, 4)) + goto trunc; + + name_entry_type = EXTRACT_16BITS(msg_data); + name_entry_len = EXTRACT_16BITS(msg_data+2); + + msg_data += 4; + msg_tlen -= 4; + + if ((name_entry_len > 0) && ((addr_size + name_entry_len) <= msg_tlen)) + name_entry_len_valid = 1; + + printf("\n\t #%u: type %#06x, length %u%s", + (unsigned int) i, name_entry_type, + name_entry_len, (name_entry_len_valid == 0) ? " (invalid)" : ""); + + if (name_entry_len_valid == 0) + break; + + /* 32-bit alignment */ + name_entry_padding = 0; + if (name_entry_len%4 != 0) + name_entry_padding = 4-(name_entry_len%4); + + if (msg_tlen < addr_size + name_entry_len + name_entry_padding) + goto trunc; + + if (!TTEST2(*msg_data, addr_size + name_entry_len + name_entry_padding)) + goto trunc; + +#if INET6 + if (is_ipv6) + printf(", address %s, name \"", + ip6addr_string(msg_data)); + else +#endif + printf(", address %s, name \"", + ipaddr_string(msg_data)); + fn_printn(msg_data + addr_size, name_entry_len, NULL); + printf("\""); + + msg_data += addr_size + name_entry_len + name_entry_padding; + msg_tlen -= addr_size + name_entry_len + name_entry_padding; + } /* for (i = 0; i < name_entries; i++) */ + break; + } /* case OLSR_NAMESERVICE_MSG */ + /* * FIXME those are the defined messages that lack a decoder * you are welcome to contribute code ;-) */ - case OLSR_POWERINFO_MSG: - case OLSR_NAMESERVICE_MSG: default: - print_unknown_data(msg_data, "\n\t ", msg_tlen); + print_unknown_data(msg_data, "\n\t ", msg_tlen); break; - } + } /* switch (msg_type) */ tptr += msg_len; - } + } /* while (tptr < (pptr+length)) */ return; diff --git a/contrib/tcpdump/print-ospf.c b/contrib/tcpdump/print-ospf.c index 4490496468..f8ff4aeac5 100644 --- a/contrib/tcpdump/print-ospf.c +++ b/contrib/tcpdump/print-ospf.c @@ -197,7 +197,7 @@ static int ospf_decode_v2(const struct ospfhdr *, const u_char *); static int ospf_decode_lls(const struct ospfhdr *, register u_int); int -ospf_print_grace_lsa (u_int8_t *tptr, u_int ls_length) { +ospf_print_grace_lsa (const u_int8_t *tptr, u_int ls_length) { u_int tlv_type, tlv_length; @@ -279,7 +279,7 @@ trunc: } int -ospf_print_te_lsa (u_int8_t *tptr, u_int ls_length) { +ospf_print_te_lsa (const u_int8_t *tptr, u_int ls_length) { u_int tlv_type, tlv_length, subtlv_type, subtlv_length; u_int priority_level, te_class, count_srlg; @@ -982,7 +982,7 @@ ospf_decode_v2(register const struct ospfhdr *op, bittok2str(ospf_dd_flag_values,"none",op->ospf_db.db_flags)); TCHECK(op->ospf_db.db_ifmtu); if (op->ospf_db.db_ifmtu) { - printf(", MTU: %u", ntohs(op->ospf_db.db_ifmtu)); + printf(", MTU: %u", EXTRACT_16BITS(&op->ospf_db.db_ifmtu)); } TCHECK(op->ospf_db.db_seq); printf(", Sequence: 0x%08x", EXTRACT_32BITS(&op->ospf_db.db_seq)); @@ -1028,7 +1028,7 @@ ospf_decode_v2(register const struct ospfhdr *op, lsap = op->ospf_lsu.lsu_lsa; TCHECK(op->ospf_lsu.lsu_count); lsa_count_max = EXTRACT_32BITS(&op->ospf_lsu.lsu_count); - printf(", %d LSA%s",lsa_count_max, lsa_count_max > 1 ? "s" : ""); + printf(", %d LSA%s",lsa_count_max, PLURAL_SUFFIX(lsa_count_max)); for (lsa_count=1;lsa_count <= lsa_count_max;lsa_count++) { printf("\n\t LSA #%u",lsa_count); lsap = (const struct lsa *)ospf_print_lsa(lsap); diff --git a/contrib/tcpdump/print-pflog.c b/contrib/tcpdump/print-pflog.c index 972cb4b132..ac325f4b0e 100644 --- a/contrib/tcpdump/print-pflog.c +++ b/contrib/tcpdump/print-pflog.c @@ -42,6 +42,7 @@ static const char rcsid[] _U_ = #include #include +#include "extract.h" #include "interface.h" #include "addrtoname.h" @@ -94,8 +95,8 @@ pflog_print(const struct pfloghdr *hdr) { u_int32_t rulenr, subrulenr; - rulenr = ntohl(hdr->rulenr); - subrulenr = ntohl(hdr->subrulenr); + rulenr = EXTRACT_32BITS(&hdr->rulenr); + subrulenr = EXTRACT_32BITS(&hdr->subrulenr); if (subrulenr == (u_int32_t)-1) printf("rule %u/", rulenr); else @@ -161,7 +162,7 @@ pflog_if_print(const struct pcap_pkthdr *h, register const u_char *p) #if OPENBSD_AF_INET6 != AF_INET6 case OPENBSD_AF_INET6: /* XXX: read pcap files */ #endif - ip6_print(p, length); + ip6_print(gndo, p, length); break; #endif diff --git a/contrib/tcpdump/print-pgm.c b/contrib/tcpdump/print-pgm.c index 73a42914c7..2d4d7449c9 100644 --- a/contrib/tcpdump/print-pgm.c +++ b/contrib/tcpdump/print-pgm.c @@ -72,6 +72,12 @@ struct pgm_nak { /* ... options */ }; +struct pgm_ack { + u_int32_t pgma_rx_max_seq; + u_int32_t pgma_bitmap; + /* ... options */ +}; + struct pgm_poll { u_int32_t pgmp_seq; u_int16_t pgmp_round; @@ -133,6 +139,9 @@ typedef enum _pgm_type { #define PGM_OPT_RST 0x0F #define PGM_OPT_CR 0x10 #define PGM_OPT_CRQST 0x11 + +#define PGM_OPT_PGMCC_DATA 0x12 +#define PGM_OPT_PGMCC_FEEDBACK 0x13 #define PGM_OPT_MASK 0x7f @@ -446,6 +455,17 @@ pgm_print(register const u_char *bp, register u_int length, break; } + case PGM_ACK: { + struct pgm_ack *ack; + + ack = (struct pgm_ack *)(pgm + 1); + TCHECK(*ack); + (void)printf("ACK seq %u", + EXTRACT_32BITS(&ack->pgma_rx_max_seq)); + bp = (u_char *) (ack + 1); + break; + } + case PGM_SPMR: (void)printf("SPMR"); break; @@ -736,6 +756,74 @@ pgm_print(register const u_char *bp, register u_int length, opts_len -= 4; break; + case PGM_OPT_PGMCC_DATA: + flags1 = *bp++; + flags2 = *bp++; + offset = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + switch (EXTRACT_16BITS(bp)) { + case AFI_IP: + addr_size = sizeof(struct in_addr); + nla_af = AF_INET; + break; +#ifdef INET6 + case AFI_IP6: + addr_size = sizeof(struct in6_addr); + nla_af = AF_INET6; + break; +#endif + default: + goto trunc; + break; + } + bp += (2 * sizeof(u_int16_t)); + if (opt_len != 12 + addr_size) { + (void)printf("[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len); + return; + } + TCHECK2(*bp, addr_size); + nla = bp; + bp += addr_size; + + inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf)); + (void)printf(" PGMCC DATA %u %s", offset, (char*)nla); + opts_len -= 16; + break; + + case PGM_OPT_PGMCC_FEEDBACK: + flags1 = *bp++; + flags2 = *bp++; + offset = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + switch (EXTRACT_16BITS(bp)) { + case AFI_IP: + addr_size = sizeof(struct in_addr); + nla_af = AF_INET; + break; +#ifdef INET6 + case AFI_IP6: + addr_size = sizeof(struct in6_addr); + nla_af = AF_INET6; + break; +#endif + default: + goto trunc; + break; + } + bp += (2 * sizeof(u_int16_t)); + if (opt_len != 12 + addr_size) { + (void)printf("[Bad OPT_PGMCC_FEEDBACK option, length %u != 12 + address size]", opt_len); + return; + } + TCHECK2(*bp, addr_size); + nla = bp; + bp += addr_size; + + inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf)); + (void)printf(" PGMCC FEEDBACK %u %s", offset, (char*)nla); + opts_len -= 16; + break; + default: (void)printf(" OPT_%02X [%d] ", opt_type, opt_len); bp += opt_len; diff --git a/contrib/tcpdump/print-pim.c b/contrib/tcpdump/print-pim.c index 774096e2f9..0f558af135 100644 --- a/contrib/tcpdump/print-pim.c +++ b/contrib/tcpdump/print-pim.c @@ -29,7 +29,15 @@ static const char rcsid[] _U_ = #endif #include + +#include +#include + #include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +#include "ip.h" #define PIMV2_TYPE_HELLO 0 #define PIMV2_TYPE_REGISTER 1 @@ -108,17 +116,7 @@ struct pim { u_short pim_cksum; /* IP style check sum */ }; - -#include -#include - -#include "interface.h" -#include "addrtoname.h" -#include "extract.h" - -#include "ip.h" - -static void pimv2_print(register const u_char *bp, register u_int len); +static void pimv2_print(register const u_char *bp, register u_int len, u_int cksum); static void pimv1_join_prune_print(register const u_char *bp, register u_int len) @@ -399,8 +397,12 @@ cisco_autorp_print(register const u_char *bp, register u_int len) TCHECK2(bp[0], 6); (void)printf("%c%s%s/%d", s, bp[0] & 1 ? "!" : "", ipaddr_string(&bp[2]), bp[1]); - if (bp[0] & 0xfe) - (void)printf("[rsvd=0x%02x]", bp[0] & 0xfe); + if (bp[0] & 0x02) { + (void)printf(" bidir"); + } + if (bp[0] & 0xfc) { + (void)printf("[rsvd=0x%02x]", bp[0] & 0xfc); + } s = ','; bp += 6; len -= 6; } @@ -413,7 +415,7 @@ trunc: } void -pim_print(register const u_char *bp, register u_int len) +pim_print(register const u_char *bp, register u_int len, u_int cksum) { register const u_char *ep; register struct pim *pim = (struct pim *)bp; @@ -438,7 +440,7 @@ pim_print(register const u_char *bp, register u_int len) PIM_VER(pim->pim_typever), len, tok2str(pimv2_type_values,"Unknown Type",PIM_TYPE(pim->pim_typever))); - pimv2_print(bp, len); + pimv2_print(bp, len, cksum); } break; default: @@ -618,7 +620,7 @@ trunc: } static void -pimv2_print(register const u_char *bp, register u_int len) +pimv2_print(register const u_char *bp, register u_int len, u_int cksum) { register const u_char *ep; register struct pim *pim = (struct pim *)bp; @@ -638,9 +640,7 @@ pimv2_print(register const u_char *bp, register u_int len) if (EXTRACT_16BITS(&pim->pim_cksum) == 0) { printf("(unverified)"); } else { - printf("(%scorrect)", - TTEST2(bp[0], len) && - in_cksum((const u_short*)bp, len, 0) ? "in" : "" ); + printf("(%scorrect)", TTEST2(bp[0], len) && cksum ? "in" : "" ); } switch (PIM_TYPE(pim->pim_typever)) { @@ -770,7 +770,7 @@ pimv2_print(register const u_char *bp, register u_int len) break; #ifdef INET6 case 6: /* IPv6 */ - ip6_print(bp, len); + ip6_print(gndo, bp, len); break; #endif default: diff --git a/contrib/tcpdump/print-ppi.c b/contrib/tcpdump/print-ppi.c new file mode 100644 index 0000000000..38873c84c5 --- /dev/null +++ b/contrib/tcpdump/print-ppi.c @@ -0,0 +1,104 @@ +/* + * Oracle + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "netdissect.h" +#include "interface.h" +#include "extract.h" +#include "ppi.h" + +#ifdef DLT_PPI + +static inline void +ppi_header_print(struct netdissect_options *ndo, const u_char *bp, u_int length) +{ + const ppi_header_t *hdr; + u_int32_t dlt; + u_int16_t len; + + hdr = (const ppi_header_t *)bp; + + len = EXTRACT_16BITS(&hdr->ppi_len); + dlt = EXTRACT_32BITS(&hdr->ppi_dlt); + + if (!ndo->ndo_qflag) { + ND_PRINT((ndo,", V.%d DLT %s (%d) len %d", hdr->ppi_ver, + pcap_datalink_val_to_name(dlt), dlt, + len)); + } else { + ND_PRINT((ndo,", %s", pcap_datalink_val_to_name(dlt))); + } + + ND_PRINT((ndo, ", length %u: ", length)); +} + +static void +ppi_print(struct netdissect_options *ndo, + const struct pcap_pkthdr *h, const u_char *p) +{ + if_ndo_printer ndo_printer; + if_printer printer; + ppi_header_t *hdr; + u_int caplen = h->caplen; + u_int length = h->len; + u_int32_t dlt; + + if (caplen < sizeof(ppi_header_t)) { + ND_PRINT((ndo, "[|ppi]")); + return; + } + hdr = (ppi_header_t *)p; + dlt = EXTRACT_32BITS(&hdr->ppi_dlt); + + if (ndo->ndo_eflag) + ppi_header_print(ndo, p, length); + + length -= sizeof(ppi_header_t); + caplen -= sizeof(ppi_header_t); + p += sizeof(ppi_header_t); + + if ((printer = lookup_printer(dlt)) != NULL) { + printer(h, p); + } else if ((ndo_printer = lookup_ndo_printer(dlt)) != NULL) { + ndo_printer(ndo, h, p); + } else { + if (!ndo->ndo_eflag) + ppi_header_print(ndo, (u_char *)hdr, + length + sizeof(ppi_header_t)); + + if (!ndo->ndo_suppress_default_print) + ndo->ndo_default_print(ndo, p, caplen); + } +} + +/* + * This is the top level routine of the printer. 'p' points + * to the ether header of the packet, 'h->ts' is the timestamp, + * 'h->len' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. + */ +u_int +ppi_if_print(struct netdissect_options *ndo, + const struct pcap_pkthdr *h, const u_char *p) +{ + ppi_print(ndo, h, p); + + return (sizeof(ppi_header_t)); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ + +#endif /* DLT_PPI */ diff --git a/contrib/tcpdump/print-ppp.c b/contrib/tcpdump/print-ppp.c index 708e934fd8..ea8e00b244 100644 --- a/contrib/tcpdump/print-ppp.c +++ b/contrib/tcpdump/print-ppp.c @@ -1303,11 +1303,11 @@ ppp_hdlc(const u_char *p, int length) goto cleanup; #ifdef INET6 case PPP_IPV6: - ip6_print(b+1, t - b - 1); - goto cleanup; + ip6_print(gndo, b+1, t - b - 1); + goto cleanup; #endif default: /* no luck - try next guess */ - break; + break; } proto = EXTRACT_16BITS(b); /* next guess - load two octets */ @@ -1368,7 +1368,7 @@ handle_ppp(u_int proto, const u_char *p, int length) #ifdef INET6 case ETHERTYPE_IPV6: /*XXX*/ case PPP_IPV6: - ip6_print(p, length); + ip6_print(gndo, p, length); break; #endif case ETHERTYPE_IPX: /*XXX*/ @@ -1629,7 +1629,7 @@ ppp_bsdos_if_print(const struct pcap_pkthdr *h _U_, register const u_char *p _U_ hdrlength += 1; } else { /* Un-compressed protocol field */ - ptype = ntohs(*(u_int16_t *)p); + ptype = EXTRACT_16BITS(p); if (eflag) printf("%04x ", ptype); p += 2; @@ -1649,7 +1649,7 @@ ppp_bsdos_if_print(const struct pcap_pkthdr *h _U_, register const u_char *p _U_ && ph->phdr_ctl == PPP_CONTROL) { if (eflag) printf("%02x %02x ", q[0], q[1]); - ptype = ntohs(ph->phdr_type); + ptype = EXTRACT_16BITS(&ph->phdr_type); if (eflag && (ptype == PPP_VJC || ptype == PPP_VJNC)) { printf("%s ", tok2str(ppptype2str, "proto-#%d", ptype)); @@ -1675,11 +1675,11 @@ ppp_bsdos_if_print(const struct pcap_pkthdr *h _U_, register const u_char *p _U_ p += hdrlength; switch (ptype) { case PPP_IP: - ip_print(p, length); + ip_print(gndo, p, length); break; #ifdef INET6 case PPP_IPV6: - ip6_print(p, length); + ip6_print(gndo, p, length); break; #endif case PPP_MPLS_UCAST: @@ -1694,11 +1694,11 @@ ppp_bsdos_if_print(const struct pcap_pkthdr *h _U_, register const u_char *p _U_ p += hdrlength; switch (ptype) { case PPP_IP: - ip_print(p, length); + ip_print(gndo, p, length); break; #ifdef INET6 case PPP_IPV6: - ip6_print(p, length); + ip6_print(gndo, p, length); break; #endif case PPP_MPLS_UCAST: @@ -1730,12 +1730,12 @@ ppp_bsdos_if_print(const struct pcap_pkthdr *h _U_, register const u_char *p _U_ break; #ifdef INET6 case PPP_IPV6: - ip6_print(p, length); + ip6_print(gndo, p, length); break; #endif case PPP_MPLS_UCAST: case PPP_MPLS_MCAST: - mpls_print(p, length); + mpls_print(gndo, p, length); break; default: printf("%s ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", ptype)); diff --git a/contrib/tcpdump/print-rpki-rtr.c b/contrib/tcpdump/print-rpki-rtr.c new file mode 100644 index 0000000000..8679759ef8 --- /dev/null +++ b/contrib/tcpdump/print-rpki-rtr.c @@ -0,0 +1,368 @@ +/* + * Copyright (c) 1998-2011 The TCPDUMP project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * support for the The RPKI/Router Protocol Protocol as per draft-ietf-sidr-rpki-rtr-12 + * + * Original code by Hannes Gredler (hannes@juniper.net) + */ + +#ifndef lint +static const char rcsid[] _U_ = +"@(#) $Header: /tcpdump/master/tcpdump/print-rpki_rtr.c,v 1.10 2008-03-20 09:30:56 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +/* + * RPKI/Router PDU header + * + * Here's what the PDU header looks like. + * The length does include the version and length fields. + */ +typedef struct rpki_rtr_pdu_ { + u_char version; /* Version number */ + u_char pdu_type; /* PDU type */ + union { + u_char cache_nonce[2]; /* Cache Nonce */ + u_char error_code[2]; /* Error code */ + } u; + u_char length[4]; +} rpki_rtr_pdu; +#define RPKI_RTR_PDU_OVERHEAD (offsetof(rpki_rtr_pdu, rpki_rtr_pdu_msg)) + +/* + * IPv4 Prefix PDU. + */ +typedef struct rpki_rtr_pdu_ipv4_prefix_ { + rpki_rtr_pdu pdu_header; + u_char flags; + u_char prefix_length; + u_char max_length; + u_char zero; + u_char prefix[4]; + u_char as[4]; +} rpki_rtr_pdu_ipv4_prefix; + +/* + * IPv6 Prefix PDU. + */ +typedef struct rpki_rtr_pdu_ipv6_prefix_ { + rpki_rtr_pdu pdu_header; + u_char flags; + u_char prefix_length; + u_char max_length; + u_char zero; + u_char prefix[16]; + u_char as[4]; +} rpki_rtr_pdu_ipv6_prefix; + +/* + * Error report PDU. + */ +typedef struct rpki_rtr_pdu_error_report_ { + rpki_rtr_pdu pdu_header; + u_char encapsulated_pdu_length[4]; /* Encapsulated PDU length */ +} rpki_rtr_pdu_error_report; + +/* + * PDU type codes + */ +#define RPKI_RTR_SERIAL_NOTIFY_PDU 0 +#define RPKI_RTR_SERIAL_QUERY_PDU 1 +#define RPKI_RTR_RESET_QUERY_PDU 2 +#define RPKI_RTR_CACHE_RESPONSE_PDU 3 +#define RPKI_RTR_IPV4_PREFIX_PDU 4 +#define RPKI_RTR_IPV6_PREFIX_PDU 6 +#define RPKI_RTR_END_OF_DATA_PDU 7 +#define RPKI_RTR_CACHE_RESET_PDU 8 +#define RPKI_RTR_ERROR_REPORT_PDU 10 + +static const struct tok rpki_rtr_pdu_values[] = { + { RPKI_RTR_SERIAL_NOTIFY_PDU, "Serial Notify" }, + { RPKI_RTR_SERIAL_QUERY_PDU, "Serial Query" }, + { RPKI_RTR_RESET_QUERY_PDU, "Reset Query" }, + { RPKI_RTR_CACHE_RESPONSE_PDU, "Cache Response" }, + { RPKI_RTR_IPV4_PREFIX_PDU, "IPV4 Prefix" }, + { RPKI_RTR_IPV6_PREFIX_PDU, "IPV6 Prefix" }, + { RPKI_RTR_END_OF_DATA_PDU, "End of Data" }, + { RPKI_RTR_CACHE_RESET_PDU, "Cache Reset" }, + { RPKI_RTR_ERROR_REPORT_PDU, "Error Report" }, + { 0, NULL} +}; + +static const struct tok rpki_rtr_error_codes[] = { + { 0, "Corrupt Data" }, + { 1, "Internal Error" }, + { 2, "No Data Available" }, + { 3, "Invalid Request" }, + { 4, "Unsupported Protocol Version" }, + { 5, "Unsupported PDU Type" }, + { 6, "Withdrawal of Unknown Record" }, + { 7, "Duplicate Announcement Received" }, + { 0, NULL} +}; + +/* + * Build a identation string for a given identation level. + * XXX this should be really in util.c + */ +static char * +indent_string (u_int indent) +{ + static char buf[20]; + u_int idx; + + idx = 0; + buf[idx] = '\0'; + + /* + * Does the static buffer fit ? + */ + if (sizeof(buf) < ((indent/8) + (indent %8) + 2)) { + return buf; + } + + /* + * Heading newline. + */ + buf[idx] = '\n'; + idx++; + + while (indent >= 8) { + buf[idx] = '\t'; + idx++; + indent -= 8; + } + + while (indent > 0) { + buf[idx] = ' '; + idx++; + indent--; + } + + /* + * Trailing zero. + */ + buf[idx] = '\0'; + + return buf; +} + +/* + * Print a single PDU. + */ +static void +rpki_rtr_pdu_print (const u_char *tptr, u_int indent) +{ + const rpki_rtr_pdu *pdu_header; + u_int pdu_type, pdu_len, hexdump; + const u_char *msg; + + pdu_header = (rpki_rtr_pdu *)tptr; + pdu_type = pdu_header->pdu_type; + pdu_len = EXTRACT_32BITS(pdu_header->length); + hexdump = FALSE; + + printf("%sRPKI-RTRv%u, %s PDU (%u), length: %u", + indent_string(8), + pdu_header->version, + tok2str(rpki_rtr_pdu_values, "Unknown", pdu_type), + pdu_type, pdu_len); + + switch (pdu_type) { + + /* + * The following PDUs share the message format. + */ + case RPKI_RTR_SERIAL_NOTIFY_PDU: + case RPKI_RTR_SERIAL_QUERY_PDU: + case RPKI_RTR_END_OF_DATA_PDU: + msg = (const u_char *)(pdu_header + 1); + printf("%sCache-Nonce: 0x%04x, Serial: %u", + indent_string(indent+2), + EXTRACT_16BITS(pdu_header->u.cache_nonce), + EXTRACT_32BITS(msg)); + break; + + /* + * The following PDUs share the message format. + */ + case RPKI_RTR_RESET_QUERY_PDU: + case RPKI_RTR_CACHE_RESET_PDU: + + /* + * Zero payload PDUs. + */ + break; + + case RPKI_RTR_CACHE_RESPONSE_PDU: + printf("%sCache-Nonce: 0x%04x", + indent_string(indent+2), + EXTRACT_16BITS(pdu_header->u.cache_nonce)); + break; + + case RPKI_RTR_IPV4_PREFIX_PDU: + { + rpki_rtr_pdu_ipv4_prefix *pdu; + + pdu = (rpki_rtr_pdu_ipv4_prefix *)tptr; + printf("%sIPv4 Prefix %s/%u-%u, origin-as %u, flags 0x%02x", + indent_string(indent+2), + ipaddr_string(pdu->prefix), + pdu->prefix_length, pdu->max_length, + EXTRACT_32BITS(pdu->as), pdu->flags); + } + break; + +#ifdef INET6 + case RPKI_RTR_IPV6_PREFIX_PDU: + { + rpki_rtr_pdu_ipv6_prefix *pdu; + + pdu = (rpki_rtr_pdu_ipv6_prefix *)tptr; + printf("%sIPv6 Prefix %s/%u-%u, origin-as %u, flags 0x%02x", + indent_string(indent+2), + ip6addr_string(pdu->prefix), + pdu->prefix_length, pdu->max_length, + EXTRACT_32BITS(pdu->as), pdu->flags); + } + break; +#endif + + case RPKI_RTR_ERROR_REPORT_PDU: + { + rpki_rtr_pdu_error_report *pdu; + u_int encapsulated_pdu_length, text_length, tlen, error_code; + u_char buf[80]; + + pdu = (rpki_rtr_pdu_error_report *)tptr; + encapsulated_pdu_length = EXTRACT_32BITS(pdu->encapsulated_pdu_length); + tlen = pdu_len; + + error_code = EXTRACT_16BITS(pdu->pdu_header.u.error_code); + printf("%sError code: %s (%u), Encapsulated PDU length: %u", + indent_string(indent+2), + tok2str(rpki_rtr_error_codes, "Unknown", error_code), + error_code, encapsulated_pdu_length); + + tptr += sizeof(*pdu); + tlen -= sizeof(*pdu); + + /* + * Recurse if there is an encapsulated PDU. + */ + if (encapsulated_pdu_length && + (encapsulated_pdu_length <= tlen)) { + printf("%s-----encapsulated PDU-----", indent_string(indent+4)); + rpki_rtr_pdu_print(tptr, indent+2); + } + + tptr += encapsulated_pdu_length; + tlen -= encapsulated_pdu_length; + + /* + * Extract, trail-zero and print the Error message. + */ + text_length = 0; + if (tlen > 4) { + text_length = EXTRACT_32BITS(tptr); + tptr += 4; + tlen -= 4; + } + if (text_length && (text_length <= tlen )) { + memcpy(buf, tptr, MIN(sizeof(buf)-1, text_length)); + buf[text_length] = '\0'; + printf("%sError text: %s", indent_string(indent+2), buf); + } + } + break; + + default: + + /* + * Unknown data, please hexdump. + */ + hexdump = TRUE; + } + + /* do we also want to see a hex dump ? */ + if (vflag > 1 || (vflag && hexdump)) { + print_unknown_data(tptr,"\n\t ", pdu_len); + } +} + +void +rpki_rtr_print(register const u_char *pptr, register u_int len) { + + u_int tlen, pdu_type, pdu_len; + const u_char *tptr; + const rpki_rtr_pdu *pdu_header; + + tptr = pptr; + tlen = len; + + if (!vflag) { + printf(", RPKI-RTR"); + return; + } + + while (tlen >= sizeof(rpki_rtr_pdu)) { + + TCHECK2(*tptr, sizeof(rpki_rtr_pdu)); + + pdu_header = (rpki_rtr_pdu *)tptr; + pdu_type = pdu_header->pdu_type; + pdu_len = EXTRACT_32BITS(pdu_header->length); + + /* infinite loop check */ + if (!pdu_type || !pdu_len) { + break; + } + + TCHECK2(*tptr, pdu_len); + if (tlen < pdu_len) { + goto trunc; + } + + /* + * Print the PDU. + */ + rpki_rtr_pdu_print(tptr, 8); + + tlen -= pdu_len; + tptr += pdu_len; + } + return; + trunc: + printf("\n\t[|RPKI-RTR]"); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 4 + * End: + */ diff --git a/contrib/tcpdump/print-rrcp.c b/contrib/tcpdump/print-rrcp.c index dc3045793b..64cb7dec31 100644 --- a/contrib/tcpdump/print-rrcp.c +++ b/contrib/tcpdump/print-rrcp.c @@ -23,7 +23,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-rrcp.c,v 1.1.2.2 2008-04-11 17:00:00 gianluca Exp $"; + "@(#) $Header: /tcpdump/master/tcpdump/print-rrcp.c,v 1.2 2008-04-11 17:21:34 gianluca Exp $"; #endif #ifdef HAVE_CONFIG_H @@ -44,33 +44,38 @@ static const char rcsid[] _U_ = #define ETH_ALEN 6 #endif -struct rrcp_packet_t -{ - u_int16_t rrcp_ethertype; /* 0x8899 */ - u_int8_t rrcp_proto; /* must be 0x01 */ - u_int8_t rrcp_opcode:7; /* 0x00 = hello, 0x01 = get, 0x02 = set */ - u_int8_t rrcp_isreply:1; /* 0 = request to switch, 1 = reply from switch */ - u_int16_t rrcp_authkey; /* 0x2379 by default */ - u_int16_t rrcp_reg_addr; /* register address */ - u_int32_t rrcp_reg_data; /* register data */ - u_int32_t cookie1; - u_int32_t cookie2; -}; +#define RRCP_OPCODE_MASK 0x7F /* 0x00 = hello, 0x01 = get, 0x02 = set */ +#define RRCP_ISREPLY 0x80 /* 0 = request to switch, 0x80 = reply from switch */ -struct rrcp_helloreply_packet_t -{ - u_int16_t rrcp_ethertype; /* 0x8899 */ - u_int8_t rrcp_proto; /* must be 0x01 */ - u_int8_t rrcp_opcode:7; /* 0x00 = hello, 0x01 = get, 0x02 = set */ - u_int8_t rrcp_isreply:1; /* 0 = request to switch, 1 = reply from switch */ - u_int16_t rrcp_authkey; /* 0x2379 by default */ - u_int8_t rrcp_downlink_port; /* */ - u_int8_t rrcp_uplink_port; /* */ - u_int8_t rrcp_uplink_mac[ETH_ALEN]; /* */ - u_int16_t rrcp_chip_id; /* */ - u_int32_t rrcp_vendor_id; /* */ +#define RRCP_PROTO_OFFSET 0 /* proto - 1 byte, must be 1 */ +#define RRCP_OPCODE_ISREPLY_OFFSET 1 /* opcode and isreply flag - 1 byte */ +#define RRCP_AUTHKEY_OFFSET 2 /* authorization key - 2 bytes, 0x2379 by default */ + +/* most packets */ +#define RRCP_REG_ADDR_OFFSET 4 /* register address - 2 bytes */ +#define RRCP_REG_DATA_OFFSET 6 /* register data - 4 bytes */ +#define RRCP_COOKIE1_OFFSET 10 /* 4 bytes */ +#define RRCP_COOKIE2_OFFSET 14 /* 4 bytes */ + +/* hello reply packets */ +#define RRCP_DOWNLINK_PORT_OFFSET 4 /* 1 byte */ +#define RRCP_UPLINK_PORT_OFFSET 5 /* 1 byte */ +#define RRCP_UPLINK_MAC_OFFSET 6 /* 6 byte MAC address */ +#define RRCP_CHIP_ID_OFFSET 12 /* 2 bytes */ +#define RRCP_VENDOR_ID_OFFSET 14 /* 4 bytes */ + +static const struct tok proto_values[] = { + { 1, "RRCP" }, + { 2, "RRCP-REP" }, + { 0, NULL } }; +static const struct tok opcode_values[] = { + { 0, "hello" }, + { 1, "get" }, + { 2, "set" }, + { 0, NULL } +}; /* * Print RRCP requests @@ -80,58 +85,59 @@ rrcp_print(netdissect_options *ndo, register const u_char *cp, u_int length _U_) { - const struct rrcp_packet_t *rrcp; - const struct rrcp_helloreply_packet_t *rrcp_hello; + const u_char *rrcp; + u_int8_t rrcp_proto; + u_int8_t rrcp_opcode; register const struct ether_header *ep; char proto_str[16]; char opcode_str[32]; ep = (const struct ether_header *)cp; - rrcp = (const struct rrcp_packet_t *)(cp+12); - rrcp_hello = (const struct rrcp_helloreply_packet_t *)(cp+12); - - if (rrcp->rrcp_proto==1){ - strcpy(proto_str,"RRCP"); - }else if ( rrcp->rrcp_proto==2 ){ - strcpy(proto_str,"RRCP-REP"); - }else{ - sprintf(proto_str,"RRCP-0x%02d",rrcp->rrcp_proto); - } - if (rrcp->rrcp_opcode==0){ - strcpy(opcode_str,"hello"); - }else if ( rrcp->rrcp_opcode==1 ){ - strcpy(opcode_str,"get"); - }else if ( rrcp->rrcp_opcode==2 ){ - strcpy(opcode_str,"set"); - }else{ - sprintf(opcode_str,"unknown opcode (0x%02d)",rrcp->rrcp_opcode); - } + rrcp = cp + ETHER_HDRLEN; + + ND_TCHECK(*(rrcp + RRCP_PROTO_OFFSET)); + rrcp_proto = *(rrcp + RRCP_PROTO_OFFSET); + ND_TCHECK(*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)); + rrcp_opcode = (*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_OPCODE_MASK; ND_PRINT((ndo, "%s > %s, %s %s", etheraddr_string(ESRC(ep)), etheraddr_string(EDST(ep)), - proto_str, rrcp->rrcp_isreply ? "reply" : "query")); - if (rrcp->rrcp_proto==1){ - ND_PRINT((ndo, ": %s", opcode_str)); + tok2strbuf(proto_values,"RRCP-0x%02d",rrcp_proto,proto_str,sizeof(proto_str)), + ((*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY) ? "reply" : "query")); + if (rrcp_proto==1){ + ND_PRINT((ndo, ": %s", + tok2strbuf(opcode_values,"unknown opcode (0x%02d)",rrcp_opcode,opcode_str,sizeof(opcode_str)))); } - if (rrcp->rrcp_opcode==1 || rrcp->rrcp_opcode==2){ - ND_PRINT((ndo, " addr=0x%04x, data=0x%04x", - rrcp->rrcp_reg_addr, rrcp->rrcp_reg_data, rrcp->rrcp_authkey)); + if (rrcp_opcode==1 || rrcp_opcode==2){ + ND_TCHECK2(*(rrcp + RRCP_REG_ADDR_OFFSET), 6); + ND_PRINT((ndo, " addr=0x%04x, data=0x%08x", + EXTRACT_LE_16BITS(rrcp + RRCP_REG_ADDR_OFFSET), + EXTRACT_LE_32BITS(rrcp + RRCP_REG_DATA_OFFSET))); } - if (rrcp->rrcp_proto==1){ + if (rrcp_proto==1){ + ND_TCHECK2(*(rrcp + RRCP_AUTHKEY_OFFSET), 2); ND_PRINT((ndo, ", auth=0x%04x", - ntohs(rrcp->rrcp_authkey))); + EXTRACT_16BITS(rrcp + RRCP_AUTHKEY_OFFSET))); } - if (rrcp->rrcp_proto==1 && rrcp->rrcp_opcode==0 && rrcp->rrcp_isreply){ - ND_PRINT((ndo, " downlink_port=%d, uplink_port=%d, uplink_mac=%s, vendor_id=%08x ,chip_id=%04x ", - rrcp_hello->rrcp_downlink_port, - rrcp_hello->rrcp_uplink_port, - etheraddr_string(rrcp_hello->rrcp_uplink_mac), - rrcp_hello->rrcp_vendor_id, - rrcp_hello->rrcp_chip_id)); - }else if (rrcp->rrcp_opcode==1 || rrcp->rrcp_opcode==2 || rrcp->rrcp_proto==2){ - ND_PRINT((ndo, ", cookie=0x%08x%08x ", - rrcp->cookie2, rrcp->cookie1)); + if (rrcp_proto==1 && rrcp_opcode==0 && + ((*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY)){ + ND_TCHECK2(*(rrcp + RRCP_VENDOR_ID_OFFSET), 4); + ND_PRINT((ndo, " downlink_port=%d, uplink_port=%d, uplink_mac=%s, vendor_id=%08x ,chip_id=%04x ", + *(rrcp + RRCP_DOWNLINK_PORT_OFFSET), + *(rrcp + RRCP_UPLINK_PORT_OFFSET), + etheraddr_string(rrcp + RRCP_UPLINK_MAC_OFFSET), + EXTRACT_32BITS(rrcp + RRCP_VENDOR_ID_OFFSET), + EXTRACT_16BITS(rrcp + RRCP_CHIP_ID_OFFSET))); + }else if (rrcp_opcode==1 || rrcp_opcode==2 || rrcp_proto==2){ + ND_TCHECK2(*(rrcp + RRCP_COOKIE2_OFFSET), 4); + ND_PRINT((ndo, ", cookie=0x%08x%08x ", + EXTRACT_32BITS(rrcp + RRCP_COOKIE2_OFFSET), + EXTRACT_32BITS(rrcp + RRCP_COOKIE1_OFFSET))); } if (!ndo->ndo_vflag) return; + return; + +trunc: + ND_PRINT((ndo, "[|rrcp]")); } diff --git a/contrib/tcpdump/print-rsvp.c b/contrib/tcpdump/print-rsvp.c index 5ed731c3de..1c76dcbbf6 100644 --- a/contrib/tcpdump/print-rsvp.c +++ b/contrib/tcpdump/print-rsvp.c @@ -17,7 +17,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-rsvp.c,v 1.48 2007-09-13 17:29:50 guy Exp $"; + "@(#) $Header: /tcpdump/master/tcpdump/print-rsvp.c,v 1.50 2008-08-16 11:36:20 hannes Exp $"; #endif #ifdef HAVE_CONFIG_H @@ -36,6 +36,7 @@ static const char rcsid[] _U_ = #include "ethertype.h" #include "gmpls.h" #include "af.h" +#include "signature.h" /* * RFC 2205 common header @@ -142,6 +143,7 @@ static const struct tok rsvp_header_flag_values[] = { #define RSVP_OBJ_UPSTREAM_LABEL 35 /* rfc3473 */ #define RSVP_OBJ_LABEL_SET 36 /* rfc3473 */ #define RSVP_OBJ_PROTECTION 37 /* rfc3473 */ +#define RSVP_OBJ_S2L 50 /* rfc4875 */ #define RSVP_OBJ_DETOUR 63 /* draft-ietf-mpls-rsvp-lsp-fastreroute-07 */ #define RSVP_OBJ_CLASSTYPE 66 /* rfc4124 */ #define RSVP_OBJ_CLASSTYPE_OLD 125 /* draft-ietf-tewg-diff-te-proto-07 */ @@ -198,6 +200,7 @@ static const struct tok rsvp_obj_values[] = { { RSVP_OBJ_NOTIFY_REQ, "Notify Request" }, { RSVP_OBJ_PROTECTION, "Protection" }, { RSVP_OBJ_ADMIN_STATUS, "Administrative Status" }, + { RSVP_OBJ_S2L, "Sub-LSP to LSP" }, { 0, NULL} }; @@ -210,6 +213,9 @@ static const struct tok rsvp_obj_values[] = { #define RSVP_CTYPE_2 2 #define RSVP_CTYPE_3 3 #define RSVP_CTYPE_4 4 +#define RSVP_CTYPE_12 12 +#define RSVP_CTYPE_13 13 +#define RSVP_CTYPE_14 14 /* * the ctypes are not globally unique so for @@ -235,13 +241,19 @@ static const struct tok rsvp_ctype_values[] = { { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_IPV6, "IPv6" }, { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_3, "IPv6 Flow-label" }, { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" }, + { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_12, "IPv4 P2MP LSP Tunnel" }, + { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_13, "IPv6 P2MP LSP Tunnel" }, { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_IPV4, "IPv4" }, { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_IPV6, "IPv6" }, { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" }, { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_UNI_IPV4, "UNI IPv4" }, + { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_13, "IPv4 P2MP LSP Tunnel" }, + { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_14, "IPv6 P2MP LSP Tunnel" }, { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_IPV4, "IPv4" }, { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_IPV6, "IPv6" }, { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" }, + { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_12, "IPv4 P2MP LSP Tunnel" }, + { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_13, "IPv6 P2MP LSP Tunnel" }, { 256*RSVP_OBJ_MESSAGE_ID+RSVP_CTYPE_1, "1" }, { 256*RSVP_OBJ_MESSAGE_ID_ACK+RSVP_CTYPE_1, "Message id ack" }, { 256*RSVP_OBJ_MESSAGE_ID_ACK+RSVP_CTYPE_2, "Message id nack" }, @@ -282,6 +294,8 @@ static const struct tok rsvp_ctype_values[] = { { 256*RSVP_OBJ_CLASSTYPE_OLD+RSVP_CTYPE_1, "1" }, { 256*RSVP_OBJ_LABEL_SET+RSVP_CTYPE_1, "1" }, { 256*RSVP_OBJ_GENERALIZED_UNI+RSVP_CTYPE_1, "1" }, + { 256*RSVP_OBJ_S2L+RSVP_CTYPE_IPV4, "IPv4 sub-LSP" }, + { 256*RSVP_OBJ_S2L+RSVP_CTYPE_IPV6, "IPv6 sub-LSP" }, { 0, NULL} }; @@ -316,6 +330,7 @@ struct rsvp_obj_frr_t { #define RSVP_OBJ_XRO_RES 0 #define RSVP_OBJ_XRO_IPV4 1 #define RSVP_OBJ_XRO_IPV6 2 +#define RSVP_OBJ_XRO_LABEL 3 #define RSVP_OBJ_XRO_ASN 32 #define RSVP_OBJ_XRO_MPLS 64 @@ -323,6 +338,7 @@ static const struct tok rsvp_obj_xro_values[] = { { RSVP_OBJ_XRO_RES, "Reserved" }, { RSVP_OBJ_XRO_IPV4, "IPv4 prefix" }, { RSVP_OBJ_XRO_IPV6, "IPv6 prefix" }, + { RSVP_OBJ_XRO_LABEL, "Label" }, { RSVP_OBJ_XRO_ASN, "Autonomous system number" }, { RSVP_OBJ_XRO_MPLS, "MPLS label switched path termination" }, { 0, NULL} @@ -337,6 +353,12 @@ static const struct tok rsvp_obj_rro_flag_values[] = { { 0, NULL} }; +/* RFC3209 */ +static const struct tok rsvp_obj_rro_label_flag_values[] = { + { 0x01, "Global" }, + { 0, NULL} +}; + static const struct tok rsvp_resstyle_values[] = { { 17, "Wildcard Filter" }, { 10, "Fixed Filter" }, @@ -369,11 +391,11 @@ static const struct tok rsvp_intserv_parameter_id_values[] = { }; static struct tok rsvp_session_attribute_flag_values[] = { - { 0x01, "Local Protection desired" }, - { 0x02, "Label Recording desired" }, - { 0x04, "SE Style desired" }, - { 0x08, "Bandwidth protection desired" }, /* draft-ietf-mpls-rsvp-lsp-fastreroute-02.txt */ - { 0x10, "Node protection desired" }, /* draft-ietf-mpls-rsvp-lsp-fastreroute-02.txt */ + { 0x01, "Local Protection" }, + { 0x02, "Label Recording" }, + { 0x04, "SE Style" }, + { 0x08, "Bandwidth protection" }, /* RFC4090 */ + { 0x10, "Node protection" }, /* RFC4090 */ { 0, NULL} }; @@ -614,7 +636,16 @@ rsvp_intserv_print(const u_char *tptr, u_short obj_tlen) { } static int -rsvp_obj_print (const u_char *tptr, const char *ident, u_int tlen) { +rsvp_obj_print (const u_char *pptr +#ifndef HAVE_LIBCRYPTO +_U_ +#endif +, u_int plen +#ifndef HAVE_LIBCRYPTO +_U_ +#endif +, const u_char *tptr, + const char *ident, u_int tlen) { const struct rsvp_object_header *rsvp_obj_header; const u_char *obj_tptr; @@ -624,7 +655,7 @@ rsvp_obj_print (const u_char *tptr, const char *ident, u_int tlen) { } obj_ptr; u_short rsvp_obj_len,rsvp_obj_ctype,obj_tlen,intserv_serv_tlen; - int hexdump,processed,padbytes,error_code,error_value,i; + int hexdump,processed,padbytes,error_code,error_value,i,sigcheck; union { float f; u_int32_t i; @@ -728,7 +759,30 @@ rsvp_obj_print (const u_char *tptr, const char *ident, u_int tlen) { obj_tlen-=36; obj_tptr+=36; break; + + case RSVP_CTYPE_14: /* IPv6 p2mp LSP Tunnel */ + if (obj_tlen < 26) + return -1; + printf("%s IPv6 P2MP LSP ID: 0x%08x, Tunnel ID: 0x%04x, Extended Tunnel ID: %s", + ident, + EXTRACT_32BITS(obj_tptr), + EXTRACT_16BITS(obj_tptr+6), + ip6addr_string(obj_tptr+8)); + obj_tlen-=26; + obj_tptr+=26; + break; #endif + case RSVP_CTYPE_13: /* IPv4 p2mp LSP Tunnel */ + if (obj_tlen < 12) + return -1; + printf("%s IPv4 P2MP LSP ID: %s, Tunnel ID: 0x%04x, Extended Tunnel ID: %s", + ident, + ipaddr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+6), + ipaddr_string(obj_tptr+8)); + obj_tlen-=12; + obj_tptr+=12; + break; case RSVP_CTYPE_TUNNEL_IPV4: case RSVP_CTYPE_UNI_IPV4: if (obj_tlen < 12) @@ -880,6 +934,20 @@ rsvp_obj_print (const u_char *tptr, const char *ident, u_int tlen) { obj_tlen-=20; obj_tptr+=20; break; + case RSVP_CTYPE_13: /* IPv6 p2mp LSP tunnel */ + if (obj_tlen < 40) + return-1; + printf("%s IPv6 Tunnel Sender Address: %s, LSP ID: 0x%04x" + "%s Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x", + ident, + ip6addr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+18), + ident, + ip6addr_string(obj_tptr+20), + EXTRACT_16BITS(obj_tptr+38)); + obj_tlen-=40; + obj_tptr+=40; + break; #endif case RSVP_CTYPE_TUNNEL_IPV4: if (obj_tlen < 8) @@ -891,6 +959,20 @@ rsvp_obj_print (const u_char *tptr, const char *ident, u_int tlen) { obj_tlen-=8; obj_tptr+=8; break; + case RSVP_CTYPE_12: /* IPv4 p2mp LSP tunnel */ + if (obj_tlen < 16) + return-1; + printf("%s IPv4 Tunnel Sender Address: %s, LSP ID: 0x%04x" + "%s Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x", + ident, + ipaddr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+6), + ident, + ipaddr_string(obj_tptr+8), + EXTRACT_16BITS(obj_tptr+12)); + obj_tlen-=16; + obj_tptr+=16; + break; default: hexdump=TRUE; } @@ -999,6 +1081,18 @@ rsvp_obj_print (const u_char *tptr, const char *ident, u_int tlen) { bittok2str(rsvp_obj_rro_flag_values, "none", *(obj_tptr+7))); /* rfc3209 says that this field is rsvd. */ + break; + case RSVP_OBJ_XRO_LABEL: + printf(", Flags: [%s] (%#x), Class-Type: %s (%u), %u", + bittok2str(rsvp_obj_rro_label_flag_values, + "none", + *(obj_tptr+2)), + *(obj_tptr+2), + tok2str(rsvp_ctype_values, + "Unknown", + *(obj_tptr+3) + 256*RSVP_OBJ_RRO), + *(obj_tptr+3), + EXTRACT_32BITS(obj_tptr+4)); } obj_tlen-=*(obj_tptr+1); obj_tptr+=*(obj_tptr+1); @@ -1055,14 +1149,14 @@ rsvp_obj_print (const u_char *tptr, const char *ident, u_int tlen) { printf("%s Session Name: ", ident); for (i = 0; i < namelen; i++) safeputchar(*(obj_tptr+4+i)); - printf("%s Setup Priority: %u, Holding Priority: %u, Flags: [%s]", + printf("%s Setup Priority: %u, Holding Priority: %u, Flags: [%s] (%#x)", ident, (int)*obj_tptr, (int)*(obj_tptr+1), - tok2str(rsvp_session_attribute_flag_values, + bittok2str(rsvp_session_attribute_flag_values, "none", - *(obj_tptr+2))); - + *(obj_tptr+2)), + *(obj_tptr+2)); obj_tlen-=4+*(obj_tptr+3); obj_tptr+=4+*(obj_tptr+3); break; @@ -1306,6 +1400,20 @@ rsvp_obj_print (const u_char *tptr, const char *ident, u_int tlen) { obj_tlen-=20; obj_tptr+=20; break; + case RSVP_CTYPE_13: /* IPv6 p2mp LSP tunnel */ + if (obj_tlen < 40) + return-1; + printf("%s IPv6 Tunnel Sender Address: %s, LSP ID: 0x%04x" + "%s Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x", + ident, + ip6addr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+18), + ident, + ip6addr_string(obj_tptr+20), + EXTRACT_16BITS(obj_tptr+38)); + obj_tlen-=40; + obj_tptr+=40; + break; #endif case RSVP_CTYPE_TUNNEL_IPV4: if (obj_tlen < 8) @@ -1317,6 +1425,20 @@ rsvp_obj_print (const u_char *tptr, const char *ident, u_int tlen) { obj_tlen-=8; obj_tptr+=8; break; + case RSVP_CTYPE_12: /* IPv4 p2mp LSP tunnel */ + if (obj_tlen < 16) + return-1; + printf("%s IPv4 Tunnel Sender Address: %s, LSP ID: 0x%04x" + "%s Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x", + ident, + ipaddr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+6), + ident, + ipaddr_string(obj_tptr+8), + EXTRACT_16BITS(obj_tptr+12)); + obj_tlen-=16; + obj_tptr+=16; + break; default: hexdump=TRUE; } @@ -1544,12 +1666,21 @@ rsvp_obj_print (const u_char *tptr, const char *ident, u_int tlen) { bittok2str(rsvp_obj_integrity_flag_values, "none", obj_ptr.rsvp_obj_integrity->flags)); - printf("%s MD5-sum 0x%08x%08x%08x%08x (unverified)", + printf("%s MD5-sum 0x%08x%08x%08x%08x ", ident, EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest), EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest+4), EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest+8), EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest+12)); + +#ifdef HAVE_LIBCRYPTO + sigcheck = signature_verify(pptr, plen, (unsigned char *)obj_ptr.\ + rsvp_obj_integrity->digest); +#else + sigcheck = CANT_CHECK_SIGNATURE; +#endif + printf(" (%s)", tok2str(signature_check_values, "Unknown", sigcheck)); + obj_tlen+=sizeof(struct rsvp_obj_integrity_t); obj_tptr+=sizeof(struct rsvp_obj_integrity_t); break; @@ -1613,7 +1744,32 @@ rsvp_obj_print (const u_char *tptr, const char *ident, u_int tlen) { break; } break; + default: + hexdump=TRUE; + } + case RSVP_OBJ_S2L: + switch (rsvp_obj_ctype) { + case RSVP_CTYPE_IPV4: + if (obj_tlen < 4) + return-1; + printf("%s Sub-LSP destination address: %s", + ident, ipaddr_string(obj_tptr)); + + obj_tlen-=4; + obj_tptr+=4; + break; +#ifdef INET6 + case RSVP_CTYPE_IPV6: + if (obj_tlen < 16) + return-1; + printf("%s Sub-LSP destination address: %s", + ident, ip6addr_string(obj_tptr)); + + obj_tlen-=16; + obj_tptr+=16; + break; +#endif default: hexdump=TRUE; } @@ -1634,7 +1790,7 @@ rsvp_obj_print (const u_char *tptr, const char *ident, u_int tlen) { } /* do we also want to see a hex dump ? */ if (vflag > 1 || hexdump==TRUE) - print_unknown_data(tptr+sizeof(sizeof(struct rsvp_object_header)),"\n\t ", /* FIXME indentation */ + print_unknown_data(tptr+sizeof(struct rsvp_object_header),"\n\t ", /* FIXME indentation */ rsvp_obj_len-sizeof(struct rsvp_object_header)); tptr+=rsvp_obj_len; @@ -1650,13 +1806,13 @@ trunc: void rsvp_print(register const u_char *pptr, register u_int len) { - const struct rsvp_common_header *rsvp_com_header; + struct rsvp_common_header *rsvp_com_header; const u_char *tptr,*subtptr; - u_short tlen,subtlen; + u_short plen, tlen, subtlen; tptr=pptr; - rsvp_com_header = (const struct rsvp_common_header *)pptr; + rsvp_com_header = (struct rsvp_common_header *)pptr; TCHECK(*rsvp_com_header); /* @@ -1679,7 +1835,7 @@ rsvp_print(register const u_char *pptr, register u_int len) { /* ok they seem to want to know everything - lets fully decode it */ - tlen=EXTRACT_16BITS(rsvp_com_header->length); + plen = tlen = EXTRACT_16BITS(rsvp_com_header->length); printf("\n\tRSVPv%u %s Message (%u), Flags: [%s], length: %u, ttl: %u, checksum: 0x%04x", RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags), @@ -1690,6 +1846,12 @@ rsvp_print(register const u_char *pptr, register u_int len) { rsvp_com_header->ttl, EXTRACT_16BITS(rsvp_com_header->checksum)); + /* + * Clear checksum prior to signature verification. + */ + rsvp_com_header->checksum[0] = 0; + rsvp_com_header->checksum[1] = 0; + if (tlen < sizeof(const struct rsvp_common_header)) { printf("ERROR: common header too short %u < %lu", tlen, (unsigned long)sizeof(const struct rsvp_common_header)); @@ -1704,7 +1866,7 @@ rsvp_print(register const u_char *pptr, register u_int len) { case RSVP_MSGTYPE_AGGREGATE: while(tlen > 0) { subtptr=tptr; - rsvp_com_header = (const struct rsvp_common_header *)subtptr; + rsvp_com_header = (struct rsvp_common_header *)subtptr; TCHECK(*rsvp_com_header); /* @@ -1725,6 +1887,12 @@ rsvp_print(register const u_char *pptr, register u_int len) { subtlen, rsvp_com_header->ttl, EXTRACT_16BITS(rsvp_com_header->checksum)); + + /* + * Clear checksum prior to signature verification. + */ + rsvp_com_header->checksum[0] = 0; + rsvp_com_header->checksum[1] = 0; if (subtlen < sizeof(const struct rsvp_common_header)) { printf("ERROR: common header too short %u < %lu", subtlen, @@ -1741,7 +1909,7 @@ rsvp_print(register const u_char *pptr, register u_int len) { subtptr+=sizeof(const struct rsvp_common_header); subtlen-=sizeof(const struct rsvp_common_header); - if (rsvp_obj_print(subtptr,"\n\t ", subtlen) == -1) + if (rsvp_obj_print(pptr, plen, subtptr,"\n\t ", subtlen) == -1) return; tptr+=subtlen+sizeof(const struct rsvp_common_header); @@ -1761,7 +1929,7 @@ rsvp_print(register const u_char *pptr, register u_int len) { case RSVP_MSGTYPE_HELLO: case RSVP_MSGTYPE_ACK: case RSVP_MSGTYPE_SREFRESH: - if (rsvp_obj_print(tptr,"\n\t ", tlen) == -1) + if (rsvp_obj_print(pptr, plen, tptr,"\n\t ", tlen) == -1) return; break; diff --git a/contrib/tcpdump/print-rx.c b/contrib/tcpdump/print-rx.c index 3812a120fc..70393ea5cb 100644 --- a/contrib/tcpdump/print-rx.c +++ b/contrib/tcpdump/print-rx.c @@ -34,7 +34,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-rx.c,v 1.39.2.3 2008-07-01 07:45:09 guy Exp $"; + "@(#) $Header: /tcpdump/master/tcpdump/print-rx.c,v 1.42 2008-07-01 07:44:50 guy Exp $"; #endif #ifdef HAVE_CONFIG_H diff --git a/contrib/tcpdump/print-sctp.c b/contrib/tcpdump/print-sctp.c index 05c753a52e..a8990a9ae0 100644 --- a/contrib/tcpdump/print-sctp.c +++ b/contrib/tcpdump/print-sctp.c @@ -59,6 +59,29 @@ static const char rcsid[] _U_ = #include "ip6.h" #endif +#define CHAN_HP 6704 +#define CHAN_MP 6705 +#define CHAN_LP 6706 + +struct tok ForCES_channels[] = { + { CHAN_HP, "ForCES HP" }, + { CHAN_MP, "ForCES MP" }, + { CHAN_LP, "ForCES LP" }, + { 0, NULL } +}; + +static inline int isForCES_port(u_short Port) +{ + if (Port == CHAN_HP) + return 1; + if (Port == CHAN_MP) + return 1; + if (Port == CHAN_LP) + return 1; + + return 0; +} + void sctp_print(const u_char *bp, /* beginning of sctp packet */ const u_char *bp2, /* beginning of enclosing */ u_int sctpPacketLength) /* ip packet */ @@ -74,6 +97,8 @@ void sctp_print(const u_char *bp, /* beginning of sctp packet */ const struct sctpChunkDesc *chunkDescPtr; const void *nextChunk; const char *sep; + int isforces = 0; + sctpPktHdr = (const struct sctpHeader*) bp; endPacketPtr = (const u_char*)sctpPktHdr+sctpPacketLength; @@ -120,6 +145,15 @@ void sctp_print(const u_char *bp, /* beginning of sctp packet */ } fflush(stdout); + if (isForCES_port(sourcePort)) { + printf("[%s]", tok2str(ForCES_channels, NULL, sourcePort)); + isforces = 1; + } + if (isForCES_port(destPort)) { + printf("[%s]", tok2str(ForCES_channels, NULL, destPort)); + isforces = 1; + } + if (vflag >= 2) sep = "\n\t"; else @@ -193,9 +227,23 @@ void sctp_print(const u_char *bp, /* beginning of sctp packet */ printf("[SSEQ %u] ", EXTRACT_16BITS(&dataHdrPtr->sequence)); printf("[PPID 0x%x] ", EXTRACT_32BITS(&dataHdrPtr->payloadtype)); fflush(stdout); - - if (vflag >= 2) /* if verbose output is specified */ - { /* at the command line */ + if (isforces) { + const u_char *payloadPtr; + u_int chunksize = sizeof(struct sctpDataPart)+ + sizeof(struct sctpChunkDesc); + payloadPtr = (const u_char *) (dataHdrPtr + 1); + if (EXTRACT_16BITS(&chunkDescPtr->chunkLength) < + sizeof(struct sctpDataPart)+ + sizeof(struct sctpChunkDesc)+1) { + /* Less than 1 byte of chunk payload */ + printf("bogus ForCES chunk length %u]", + EXTRACT_16BITS(&chunkDescPtr->chunkLength)); + return; + } + + forces_print(payloadPtr, EXTRACT_16BITS(&chunkDescPtr->chunkLength)- chunksize); + } else if (vflag >= 2) { /* if verbose output is specified */ + /* at the command line */ const u_char *payloadPtr; printf("[Payload"); @@ -203,16 +251,16 @@ void sctp_print(const u_char *bp, /* beginning of sctp packet */ if (!suppress_default_print) { payloadPtr = (const u_char *) (++dataHdrPtr); printf(":"); - if (htons(chunkDescPtr->chunkLength) < + if (EXTRACT_16BITS(&chunkDescPtr->chunkLength) < sizeof(struct sctpDataPart)+ sizeof(struct sctpChunkDesc)+1) { /* Less than 1 byte of chunk payload */ printf("bogus chunk length %u]", - htons(chunkDescPtr->chunkLength)); + EXTRACT_16BITS(&chunkDescPtr->chunkLength)); return; } default_print(payloadPtr, - htons(chunkDescPtr->chunkLength) - + EXTRACT_16BITS(&chunkDescPtr->chunkLength) - (sizeof(struct sctpDataPart)+ sizeof(struct sctpChunkDesc))); } else diff --git a/contrib/tcpdump/print-sflow.c b/contrib/tcpdump/print-sflow.c index baa55300b6..79a3fdf1d9 100644 --- a/contrib/tcpdump/print-sflow.c +++ b/contrib/tcpdump/print-sflow.c @@ -15,6 +15,8 @@ * The SFLOW protocol as per http://www.sflow.org/developers/specifications.php * * Original code by Carles Kishimoto + * + * Expansion and refactoring by Rick Jones */ #ifndef lint @@ -87,6 +89,18 @@ static const struct tok sflow_format_values[] = { { 0, NULL} }; +struct sflow_flow_sample_t { + u_int8_t seqnum[4]; + u_int8_t typesource[4]; + u_int8_t rate[4]; + u_int8_t pool[4]; + u_int8_t drops[4]; + u_int8_t in_interface[4]; + u_int8_t out_interface[4]; + u_int8_t records[4]; + +}; + struct sflow_expanded_flow_sample_t { u_int8_t seqnum[4]; u_int8_t type[4]; @@ -156,6 +170,36 @@ struct sflow_expanded_flow_raw_t { u_int8_t header_size[4]; }; +struct sflow_ethernet_frame_t { + u_int8_t length[4]; + u_int8_t src_mac[8]; + u_int8_t dst_mac[8]; + u_int8_t type[4]; +}; + +struct sflow_extended_switch_data_t { + u_int8_t src_vlan[4]; + u_int8_t src_pri[4]; + u_int8_t dst_vlan[4]; + u_int8_t dst_pri[4]; +}; + +struct sflow_counter_record_t { + u_int8_t format[4]; + u_int8_t length[4]; +}; + +struct sflow_flow_record_t { + u_int8_t format[4]; + u_int8_t length[4]; +}; + +struct sflow_counter_sample_t { + u_int8_t seqnum[4]; + u_int8_t typesource[4]; + u_int8_t records[4]; +}; + struct sflow_expanded_counter_sample_t { u_int8_t seqnum[4]; u_int8_t type[4]; @@ -259,24 +303,525 @@ struct sflow_vlan_counter_t { u_int8_t discards[4]; }; -void -sflow_print(const u_char *pptr, u_int len) { +static int +print_sflow_counter_generic(const u_char *pointer, u_int len) { - const struct sflow_datagram_t *sflow_datagram; - const struct sflow_sample_header *sflow_sample; - const struct sflow_expanded_flow_sample_t *sflow_expanded_flow_sample; - const struct sflow_expanded_flow_raw_t *sflow_flow_raw; - const struct sflow_expanded_counter_sample_t *sflow_expanded_counter_sample; const struct sflow_generic_counter_t *sflow_gen_counter; + + if (len < sizeof(struct sflow_generic_counter_t)) + return 1; + + + sflow_gen_counter = (const struct sflow_generic_counter_t *)pointer; + printf("\n\t ifindex %u, iftype %u, ifspeed %" PRIu64 ", ifdirection %u (%s)", + EXTRACT_32BITS(sflow_gen_counter->ifindex), + EXTRACT_32BITS(sflow_gen_counter->iftype), + EXTRACT_64BITS(sflow_gen_counter->ifspeed), + EXTRACT_32BITS(sflow_gen_counter->ifdirection), + tok2str(sflow_iface_direction_values, "Unknown", + EXTRACT_32BITS(sflow_gen_counter->ifdirection))); + printf("\n\t ifstatus %u, adminstatus: %s, operstatus: %s", + EXTRACT_32BITS(sflow_gen_counter->ifstatus), + EXTRACT_32BITS(sflow_gen_counter->ifstatus)&1 ? "up" : "down", + (EXTRACT_32BITS(sflow_gen_counter->ifstatus)>>1)&1 ? "up" : "down"); + printf("\n\t In octets %" PRIu64 + ", unicast pkts %u, multicast pkts %u, broadcast pkts %u, discards %u", + EXTRACT_64BITS(sflow_gen_counter->ifinoctets), + EXTRACT_32BITS(sflow_gen_counter->ifinunicastpkts), + EXTRACT_32BITS(sflow_gen_counter->ifinmulticastpkts), + EXTRACT_32BITS(sflow_gen_counter->ifinbroadcastpkts), + EXTRACT_32BITS(sflow_gen_counter->ifindiscards)); + printf("\n\t In errors %u, unknown protos %u", + EXTRACT_32BITS(sflow_gen_counter->ifinerrors), + EXTRACT_32BITS(sflow_gen_counter->ifinunkownprotos)); + printf("\n\t Out octets %" PRIu64 + ", unicast pkts %u, multicast pkts %u, broadcast pkts %u, discards %u", + EXTRACT_64BITS(sflow_gen_counter->ifoutoctets), + EXTRACT_32BITS(sflow_gen_counter->ifoutunicastpkts), + EXTRACT_32BITS(sflow_gen_counter->ifoutmulticastpkts), + EXTRACT_32BITS(sflow_gen_counter->ifoutbroadcastpkts), + EXTRACT_32BITS(sflow_gen_counter->ifoutdiscards)); + printf("\n\t Out errors %u, promisc mode %u", + EXTRACT_32BITS(sflow_gen_counter->ifouterrors), + EXTRACT_32BITS(sflow_gen_counter->ifpromiscmode)); + + return 0; +} + +static int +print_sflow_counter_ethernet(const u_char *pointer, u_int len){ + const struct sflow_ethernet_counter_t *sflow_eth_counter; + + if (len < sizeof(struct sflow_ethernet_counter_t)) + return 1; + + sflow_eth_counter = (const struct sflow_ethernet_counter_t *)pointer; + printf("\n\t align errors %u, fcs errors %u, single collision %u, multiple collision %u, test error %u", + EXTRACT_32BITS(sflow_eth_counter->alignerrors), + EXTRACT_32BITS(sflow_eth_counter->fcserrors), + EXTRACT_32BITS(sflow_eth_counter->single_collision_frames), + EXTRACT_32BITS(sflow_eth_counter->multiple_collision_frames), + EXTRACT_32BITS(sflow_eth_counter->test_errors)); + printf("\n\t deferred %u, late collision %u, excessive collision %u, mac trans error %u", + EXTRACT_32BITS(sflow_eth_counter->deferred_transmissions), + EXTRACT_32BITS(sflow_eth_counter->late_collisions), + EXTRACT_32BITS(sflow_eth_counter->excessive_collisions), + EXTRACT_32BITS(sflow_eth_counter->mac_transmit_errors)); + printf("\n\t carrier error %u, frames too long %u, mac receive errors %u, symbol errors %u", + EXTRACT_32BITS(sflow_eth_counter->carrier_sense_errors), + EXTRACT_32BITS(sflow_eth_counter->frame_too_longs), + EXTRACT_32BITS(sflow_eth_counter->mac_receive_errors), + EXTRACT_32BITS(sflow_eth_counter->symbol_errors)); + + return 0; +} + +static int +print_sflow_counter_token_ring(const u_char *pointer _U_, u_int len _U_) { + + return 0; +} + +static int +print_sflow_counter_basevg(const u_char *pointer, u_int len) { + const struct sflow_100basevg_counter_t *sflow_100basevg_counter; + + if (len < sizeof(struct sflow_100basevg_counter_t)) + return 1; + + sflow_100basevg_counter = (const struct sflow_100basevg_counter_t *)pointer; + printf("\n\t in high prio frames %u, in high prio octets %" PRIu64, + EXTRACT_32BITS(sflow_100basevg_counter->in_highpriority_frames), + EXTRACT_64BITS(sflow_100basevg_counter->in_highpriority_octets)); + printf("\n\t in norm prio frames %u, in norm prio octets %" PRIu64, + EXTRACT_32BITS(sflow_100basevg_counter->in_normpriority_frames), + EXTRACT_64BITS(sflow_100basevg_counter->in_normpriority_octets)); + printf("\n\t in ipm errors %u, oversized %u, in data errors %u, null addressed frames %u", + EXTRACT_32BITS(sflow_100basevg_counter->in_ipmerrors), + EXTRACT_32BITS(sflow_100basevg_counter->in_oversized), + EXTRACT_32BITS(sflow_100basevg_counter->in_data_errors), + EXTRACT_32BITS(sflow_100basevg_counter->in_null_addressed_frames)); + printf("\n\t out high prio frames %u, out high prio octets %" PRIu64 + ", trans into frames %u", + EXTRACT_32BITS(sflow_100basevg_counter->out_highpriority_frames), + EXTRACT_64BITS(sflow_100basevg_counter->out_highpriority_octets), + EXTRACT_32BITS(sflow_100basevg_counter->transitioninto_frames)); + printf("\n\t in hc high prio octets %" PRIu64 + ", in hc norm prio octets %" PRIu64 + ", out hc high prio octets %" PRIu64, + EXTRACT_64BITS(sflow_100basevg_counter->hc_in_highpriority_octets), + EXTRACT_64BITS(sflow_100basevg_counter->hc_in_normpriority_octets), + EXTRACT_64BITS(sflow_100basevg_counter->hc_out_highpriority_octets)); + + return 0; +} + +static int +print_sflow_counter_vlan(const u_char *pointer, u_int len) { + const struct sflow_vlan_counter_t *sflow_vlan_counter; + + if (len < sizeof(struct sflow_vlan_counter_t)) + return 1; + + sflow_vlan_counter = (const struct sflow_vlan_counter_t *)pointer; + printf("\n\t vlan_id %u, octets %" PRIu64 + ", unicast_pkt %u, multicast_pkt %u, broadcast_pkt %u, discards %u", + EXTRACT_32BITS(sflow_vlan_counter->vlan_id), + EXTRACT_64BITS(sflow_vlan_counter->octets), + EXTRACT_32BITS(sflow_vlan_counter->unicast_pkt), + EXTRACT_32BITS(sflow_vlan_counter->multicast_pkt), + EXTRACT_32BITS(sflow_vlan_counter->broadcast_pkt), + EXTRACT_32BITS(sflow_vlan_counter->discards)); + + return 0; +} + +struct sflow_processor_counter_t { + u_int8_t five_sec_util[4]; + u_int8_t one_min_util[4]; + u_int8_t five_min_util[4]; + u_int8_t total_memory[8]; + u_int8_t free_memory[8]; +}; + +static int +print_sflow_counter_processor(const u_char *pointer, u_int len) { + + const struct sflow_processor_counter_t *sflow_processor_counter; + + if (len < sizeof(struct sflow_processor_counter_t)) + return 1; + + sflow_processor_counter = (const struct sflow_processor_counter_t *)pointer; + printf("\n\t 5sec %u, 1min %u, 5min %u, total_mem %" PRIu64 + ", total_mem %" PRIu64, + EXTRACT_32BITS(sflow_processor_counter->five_sec_util), + EXTRACT_32BITS(sflow_processor_counter->one_min_util), + EXTRACT_32BITS(sflow_processor_counter->five_min_util), + EXTRACT_64BITS(sflow_processor_counter->total_memory), + EXTRACT_64BITS(sflow_processor_counter->free_memory)); + + return 0; +} + +static int +sflow_print_counter_records(const u_char *pointer, u_int len, u_int records) { + + u_int nrecords; const u_char *tptr; - int tlen; + u_int tlen; + u_int counter_type; + u_int counter_len; + u_int enterprise; + const struct sflow_counter_record_t *sflow_counter_record; + + nrecords = records; + tptr = pointer; + tlen = len; + + while (nrecords > 0) { + /* do we have the "header?" */ + if (tlen < sizeof(struct sflow_counter_record_t)) + return 1; + sflow_counter_record = (const struct sflow_counter_record_t *)tptr; + + enterprise = EXTRACT_32BITS(sflow_counter_record->format); + counter_type = enterprise & 0x0FFF; + enterprise = enterprise >> 20; + counter_len = EXTRACT_32BITS(sflow_counter_record->length); + printf("\n\t enterprise %u, %s (%u) length %u", + enterprise, + (enterprise == 0) ? tok2str(sflow_counter_type_values,"Unknown",counter_type) : "Unknown", + counter_type, + counter_len); + + tptr += sizeof(struct sflow_counter_record_t); + tlen -= sizeof(struct sflow_counter_record_t); + + if (tlen < counter_len) + return 1; + if (enterprise == 0) { + switch (counter_type) { + case SFLOW_COUNTER_GENERIC: + if (print_sflow_counter_generic(tptr,tlen)) + return 1; + break; + case SFLOW_COUNTER_ETHERNET: + if (print_sflow_counter_ethernet(tptr,tlen)) + return 1; + break; + case SFLOW_COUNTER_TOKEN_RING: + if (print_sflow_counter_token_ring(tptr,tlen)) + return 1; + break; + case SFLOW_COUNTER_BASEVG: + if (print_sflow_counter_basevg(tptr,tlen)) + return 1; + break; + case SFLOW_COUNTER_VLAN: + if (print_sflow_counter_vlan(tptr,tlen)) + return 1; + break; + case SFLOW_COUNTER_PROCESSOR: + if (print_sflow_counter_processor(tptr,tlen)) + return 1; + break; + default: + if (vflag <= 1) + print_unknown_data(tptr, "\n\t\t", counter_len); + break; + } + } + tptr += counter_len; + tlen -= counter_len; + nrecords--; + + } + + return 0; +} + + +static int +sflow_print_counter_sample(const u_char *pointer, u_int len) { + + const struct sflow_counter_sample_t *sflow_counter_sample; + u_int nrecords; + u_int typesource; + u_int type; + u_int index; + + + if (len < sizeof(struct sflow_counter_sample_t)) + return 1; + + sflow_counter_sample = (const struct sflow_counter_sample_t *)pointer; + + typesource = EXTRACT_32BITS(sflow_counter_sample->typesource); + nrecords = EXTRACT_32BITS(sflow_counter_sample->records); + type = typesource >> 24; + index = typesource & 0x0FFF; + + printf(" seqnum %u, type %u, idx %u, records %u", + EXTRACT_32BITS(sflow_counter_sample->seqnum), + type, + index, + nrecords); + + return sflow_print_counter_records(pointer + sizeof(struct sflow_counter_sample_t), + len - sizeof(struct sflow_counter_sample_t), + nrecords); + +} + +static int +sflow_print_expanded_counter_sample(const u_char *pointer, u_int len) { + + const struct sflow_expanded_counter_sample_t *sflow_expanded_counter_sample; + u_int nrecords; + + + if (len < sizeof(struct sflow_expanded_counter_sample_t)) + return 1; + + sflow_expanded_counter_sample = (const struct sflow_expanded_counter_sample_t *)pointer; + + nrecords = EXTRACT_32BITS(sflow_expanded_counter_sample->records); + + printf(" seqnum %u, type %u, idx %u, records %u", + EXTRACT_32BITS(sflow_expanded_counter_sample->seqnum), + EXTRACT_32BITS(sflow_expanded_counter_sample->type), + EXTRACT_32BITS(sflow_expanded_counter_sample->index), + nrecords); + + return sflow_print_counter_records(pointer + sizeof(struct sflow_expanded_counter_sample_t), + len - sizeof(struct sflow_expanded_counter_sample_t), + nrecords); + +} + +static int +print_sflow_raw_packet(const u_char *pointer, u_int len) { + + const struct sflow_expanded_flow_raw_t *sflow_flow_raw; + + if (len < sizeof(struct sflow_expanded_flow_raw_t)) + return 1; + + sflow_flow_raw = (const struct sflow_expanded_flow_raw_t *)pointer; + printf("\n\t protocol %s (%u), length %u, stripped bytes %u, header_size %u", + tok2str(sflow_flow_raw_protocol_values,"Unknown",EXTRACT_32BITS(sflow_flow_raw->protocol)), + EXTRACT_32BITS(sflow_flow_raw->protocol), + EXTRACT_32BITS(sflow_flow_raw->length), + EXTRACT_32BITS(sflow_flow_raw->stripped_bytes), + EXTRACT_32BITS(sflow_flow_raw->header_size)); + + /* QUESTION - should we attempt to print the raw header itself? + assuming of course there is wnough data present to do so... */ + + return 0; +} + +static int +print_sflow_ethernet_frame(const u_char *pointer, u_int len) { + + const struct sflow_ethernet_frame_t *sflow_ethernet_frame; + + if (len < sizeof(struct sflow_ethernet_frame_t)) + return 1; + + sflow_ethernet_frame = (const struct sflow_ethernet_frame_t *)pointer; + + printf("\n\t frame len %u, type %u", + EXTRACT_32BITS(sflow_ethernet_frame->length), + EXTRACT_32BITS(sflow_ethernet_frame->type)); + + return 0; +} + +static int +print_sflow_extended_switch_data(const u_char *pointer, u_int len) { + + const struct sflow_extended_switch_data_t *sflow_extended_sw_data; + + if (len < sizeof(struct sflow_extended_switch_data_t)) + return 1; + + sflow_extended_sw_data = (const struct sflow_extended_switch_data_t *)pointer; + printf("\n\t src vlan %u, src pri %u, dst vlan %u, dst pri %u", + EXTRACT_32BITS(sflow_extended_sw_data->src_vlan), + EXTRACT_32BITS(sflow_extended_sw_data->src_pri), + EXTRACT_32BITS(sflow_extended_sw_data->dst_vlan), + EXTRACT_32BITS(sflow_extended_sw_data->dst_pri)); + + return 0; +} + +static int +sflow_print_flow_records(const u_char *pointer, u_int len, u_int records) { + + u_int nrecords; + const u_char *tptr; + u_int tlen; + u_int flow_type; + u_int enterprise; + u_int flow_len; + const struct sflow_flow_record_t *sflow_flow_record; + + nrecords = records; + tptr = pointer; + tlen = len; + + while (nrecords > 0) { + /* do we have the "header?" */ + if (tlen < sizeof(struct sflow_flow_record_t)) + return 1; + + sflow_flow_record = (const struct sflow_flow_record_t *)tptr; + + /* so, the funky encoding means we cannot blythly mask-off + bits, we must also check the enterprise. */ + + enterprise = EXTRACT_32BITS(sflow_flow_record->format); + flow_type = enterprise & 0x0FFF; + enterprise = enterprise >> 12; + flow_len = EXTRACT_32BITS(sflow_flow_record->length); + printf("\n\t enterprise %u %s (%u) length %u", + enterprise, + (enterprise == 0) ? tok2str(sflow_flow_type_values,"Unknown",flow_type) : "Unknown", + flow_type, + flow_len); + + tptr += sizeof(struct sflow_flow_record_t); + tlen -= sizeof(struct sflow_flow_record_t); + + if (tlen < flow_len) + return 1; + + if (enterprise == 0) { + switch (flow_type) { + case SFLOW_FLOW_RAW_PACKET: + if (print_sflow_raw_packet(tptr,tlen)) + return 1; + break; + case SFLOW_FLOW_EXTENDED_SWITCH_DATA: + if (print_sflow_extended_switch_data(tptr,tlen)) + return 1; + break; + case SFLOW_FLOW_ETHERNET_FRAME: + if (print_sflow_ethernet_frame(tptr,tlen)) + return 1; + break; + /* FIXME these need a decoder */ + case SFLOW_FLOW_IPV4_DATA: + case SFLOW_FLOW_IPV6_DATA: + case SFLOW_FLOW_EXTENDED_ROUTER_DATA: + case SFLOW_FLOW_EXTENDED_GATEWAY_DATA: + case SFLOW_FLOW_EXTENDED_USER_DATA: + case SFLOW_FLOW_EXTENDED_URL_DATA: + case SFLOW_FLOW_EXTENDED_MPLS_DATA: + case SFLOW_FLOW_EXTENDED_NAT_DATA: + case SFLOW_FLOW_EXTENDED_MPLS_TUNNEL: + case SFLOW_FLOW_EXTENDED_MPLS_VC: + case SFLOW_FLOW_EXTENDED_MPLS_FEC: + case SFLOW_FLOW_EXTENDED_MPLS_LVP_FEC: + case SFLOW_FLOW_EXTENDED_VLAN_TUNNEL: + break; + default: + if (vflag <= 1) + print_unknown_data(tptr, "\n\t\t", flow_len); + break; + } + } + tptr += flow_len; + tlen -= flow_len; + nrecords--; + + } + + return 0; +} + +static int +sflow_print_flow_sample(const u_char *pointer, u_int len) { + + const struct sflow_flow_sample_t *sflow_flow_sample; + u_int nrecords; + u_int typesource; + u_int type; + u_int index; + + if (len < sizeof(struct sflow_flow_sample_t)) + return 1; + + sflow_flow_sample = (struct sflow_flow_sample_t *)pointer; + + typesource = EXTRACT_32BITS(sflow_flow_sample->typesource); + nrecords = EXTRACT_32BITS(sflow_flow_sample->records); + type = typesource >> 24; + index = typesource & 0x0FFF; + + printf(" seqnum %u, type %u, idx %u, rate %u, pool %u, drops %u, input %u output %u records %u", + EXTRACT_32BITS(sflow_flow_sample->seqnum), + type, + index, + EXTRACT_32BITS(sflow_flow_sample->rate), + EXTRACT_32BITS(sflow_flow_sample->pool), + EXTRACT_32BITS(sflow_flow_sample->drops), + EXTRACT_32BITS(sflow_flow_sample->in_interface), + EXTRACT_32BITS(sflow_flow_sample->out_interface), + nrecords); + + return sflow_print_flow_records(pointer + sizeof(struct sflow_flow_sample_t), + len - sizeof(struct sflow_flow_sample_t), + nrecords); + +} + +static int +sflow_print_expanded_flow_sample(const u_char *pointer, u_int len) { + + const struct sflow_expanded_flow_sample_t *sflow_expanded_flow_sample; + u_int nrecords; + + if (len < sizeof(struct sflow_expanded_flow_sample_t)) + return 1; + + sflow_expanded_flow_sample = (const struct sflow_expanded_flow_sample_t *)pointer; + + nrecords = EXTRACT_32BITS(sflow_expanded_flow_sample->records); + + printf(" seqnum %u, type %u, idx %u, rate %u, pool %u, drops %u, records %u", + EXTRACT_32BITS(sflow_expanded_flow_sample->seqnum), + EXTRACT_32BITS(sflow_expanded_flow_sample->type), + EXTRACT_32BITS(sflow_expanded_flow_sample->index), + EXTRACT_32BITS(sflow_expanded_flow_sample->rate), + EXTRACT_32BITS(sflow_expanded_flow_sample->pool), + EXTRACT_32BITS(sflow_expanded_flow_sample->drops), + EXTRACT_32BITS(sflow_expanded_flow_sample->records)); + + return sflow_print_flow_records(pointer + sizeof(struct sflow_expanded_flow_sample_t), + len - sizeof(struct sflow_expanded_flow_sample_t), + nrecords); + +} + +void +sflow_print(const u_char *pptr, u_int len) { + + const struct sflow_datagram_t *sflow_datagram; + const struct sflow_sample_header *sflow_sample; + + const u_char *tptr; + u_int tlen; u_int32_t sflow_sample_type, sflow_sample_len; - int nsamples, nrecords, counter_len, counter_type, flow_len, flow_type; + u_int32_t nsamples; + - tptr=pptr; + tptr = pptr; tlen = len; sflow_datagram = (const struct sflow_datagram_t *)pptr; TCHECK(*sflow_datagram); @@ -313,16 +858,21 @@ sflow_print(const u_char *pptr, u_int len) { len); /* skip Common header */ - tptr+=sizeof(const struct sflow_datagram_t); - tlen-=sizeof(const struct sflow_datagram_t); + tptr += sizeof(const struct sflow_datagram_t); + tlen -= sizeof(const struct sflow_datagram_t); while (nsamples > 0 && tlen > 0) { sflow_sample = (const struct sflow_sample_header *)tptr; + TCHECK(*sflow_sample); + sflow_sample_type = (EXTRACT_32BITS(sflow_sample->format)&0x0FFF); sflow_sample_len = EXTRACT_32BITS(sflow_sample->len); - tptr+=sizeof(struct sflow_sample_header); - tlen-=sizeof(struct sflow_sample_header); + if (tlen < sizeof(struct sflow_sample_header)) + goto trunc; + + tptr += sizeof(struct sflow_sample_header); + tlen -= sizeof(struct sflow_sample_header); printf("\n\t%s (%u), length %u,", tok2str(sflow_format_values, "Unknown", sflow_sample_type), @@ -334,226 +884,33 @@ sflow_print(const u_char *pptr, u_int len) { return; } + if (tlen < sflow_sample_len) + goto trunc; + /* did we capture enough for fully decoding the sample ? */ - if (!TTEST2(*tptr, sflow_sample_len)) - goto trunc; + TCHECK2(*tptr, sflow_sample_len); switch(sflow_sample_type) { - case SFLOW_FLOW_SAMPLE: /* XXX */ + case SFLOW_FLOW_SAMPLE: + if (sflow_print_flow_sample(tptr,tlen)) + goto trunc; break; - case SFLOW_COUNTER_SAMPLE: /* XXX */ + case SFLOW_COUNTER_SAMPLE: + if (sflow_print_counter_sample(tptr,tlen)) + goto trunc; break; case SFLOW_EXPANDED_FLOW_SAMPLE: - sflow_expanded_flow_sample = (const struct sflow_expanded_flow_sample_t *)tptr; - nrecords = EXTRACT_32BITS(sflow_expanded_flow_sample->records); - - printf(" seqnum %u, type %u, idx %u, rate %u, pool %u, drops %u, records %u", - EXTRACT_32BITS(sflow_expanded_flow_sample->seqnum), - EXTRACT_32BITS(sflow_expanded_flow_sample->type), - EXTRACT_32BITS(sflow_expanded_flow_sample->index), - EXTRACT_32BITS(sflow_expanded_flow_sample->rate), - EXTRACT_32BITS(sflow_expanded_flow_sample->pool), - EXTRACT_32BITS(sflow_expanded_flow_sample->drops), - EXTRACT_32BITS(sflow_expanded_flow_sample->records)); - - tptr+= sizeof(struct sflow_expanded_flow_sample_t); - tlen-= sizeof(struct sflow_expanded_flow_sample_t); - - while ( nrecords > 0 && tlen > 0) { - - /* decode Flow record - 2 bytes */ - flow_type = EXTRACT_32BITS(tptr)&0x0FFF; - flow_len = EXTRACT_32BITS(tptr+4); - printf("\n\t %s (%u) length %u", - tok2str(sflow_flow_type_values,"Unknown",flow_type), - flow_type, - flow_len); - - tptr += 8; - tlen -= 8; - - /* did we capture enough for fully decoding the flow ? */ - if (!TTEST2(*tptr, flow_len)) - goto trunc; - - switch(flow_type) { - case SFLOW_FLOW_RAW_PACKET: - sflow_flow_raw = (const struct sflow_expanded_flow_raw_t *)tptr; - printf("\n\t protocol %s (%u), length %u, stripped bytes %u, header_size %u", - tok2str(sflow_flow_raw_protocol_values,"Unknown",EXTRACT_32BITS(sflow_flow_raw->protocol)), - EXTRACT_32BITS(sflow_flow_raw->protocol), - EXTRACT_32BITS(sflow_flow_raw->length), - EXTRACT_32BITS(sflow_flow_raw->stripped_bytes), - EXTRACT_32BITS(sflow_flow_raw->header_size)); - break; - - /* - * FIXME those are the defined flow types that lack a decoder - */ - case SFLOW_FLOW_ETHERNET_FRAME: - case SFLOW_FLOW_IPV4_DATA: - case SFLOW_FLOW_IPV6_DATA: - case SFLOW_FLOW_EXTENDED_SWITCH_DATA: - case SFLOW_FLOW_EXTENDED_ROUTER_DATA: - case SFLOW_FLOW_EXTENDED_GATEWAY_DATA: - case SFLOW_FLOW_EXTENDED_USER_DATA: - case SFLOW_FLOW_EXTENDED_URL_DATA: - case SFLOW_FLOW_EXTENDED_MPLS_DATA: - case SFLOW_FLOW_EXTENDED_NAT_DATA: - case SFLOW_FLOW_EXTENDED_MPLS_TUNNEL: - case SFLOW_FLOW_EXTENDED_MPLS_VC: - case SFLOW_FLOW_EXTENDED_MPLS_FEC: - case SFLOW_FLOW_EXTENDED_MPLS_LVP_FEC: - case SFLOW_FLOW_EXTENDED_VLAN_TUNNEL: - break; - default: - if (vflag <= 1) - print_unknown_data(tptr, "\n\t ", flow_len); - break; - - } - tptr += flow_len; - tlen -= flow_len; - nrecords--; - } - break; + if (sflow_print_expanded_flow_sample(tptr,tlen)) + goto trunc; + break; case SFLOW_EXPANDED_COUNTER_SAMPLE: - sflow_expanded_counter_sample = (const struct sflow_expanded_counter_sample_t *)tptr; - nrecords = EXTRACT_32BITS(sflow_expanded_counter_sample->records); - - printf(" seqnum %u, type %u, idx %u, records %u", - EXTRACT_32BITS(sflow_expanded_counter_sample->seqnum), - EXTRACT_32BITS(sflow_expanded_counter_sample->type), - EXTRACT_32BITS(sflow_expanded_counter_sample->index), - nrecords); - - tptr+= sizeof(struct sflow_expanded_counter_sample_t); - tlen-= sizeof(struct sflow_expanded_counter_sample_t); - - while ( nrecords > 0 && tlen > 0) { - - /* decode counter record - 2 bytes */ - counter_type = EXTRACT_32BITS(tptr)&0x0FFF; - counter_len = EXTRACT_32BITS(tptr+4); - printf("\n\t %s (%u) length %u", - tok2str(sflow_counter_type_values,"Unknown",counter_type), - counter_type, - counter_len); - - tptr += 8; - tlen -= 8; - - /* did we capture enough for fully decoding the counter ? */ - if (!TTEST2(*tptr, counter_len)) - goto trunc; - - switch(counter_type) { - case SFLOW_COUNTER_GENERIC: - sflow_gen_counter = (const struct sflow_generic_counter_t *)tptr; - printf("\n\t ifindex %u, iftype %u, ifspeed %u, ifdirection %u (%s)", - EXTRACT_32BITS(sflow_gen_counter->ifindex), - EXTRACT_32BITS(sflow_gen_counter->iftype), - EXTRACT_32BITS(sflow_gen_counter->ifspeed), - EXTRACT_32BITS(sflow_gen_counter->ifdirection), - tok2str(sflow_iface_direction_values, "Unknown", - EXTRACT_32BITS(sflow_gen_counter->ifdirection))); - printf("\n\t ifstatus %u, adminstatus: %s, operstatus: %s", - EXTRACT_32BITS(sflow_gen_counter->ifstatus), - EXTRACT_32BITS(sflow_gen_counter->ifstatus)&1 ? "up" : "down", - (EXTRACT_32BITS(sflow_gen_counter->ifstatus)>>1)&1 ? "up" : "down"); - printf("\n\t In octets %" PRIu64 - ", unicast pkts %u, multicast pkts %u, broadcast pkts %u, discards %u", - EXTRACT_64BITS(sflow_gen_counter->ifinoctets), - EXTRACT_32BITS(sflow_gen_counter->ifinunicastpkts), - EXTRACT_32BITS(sflow_gen_counter->ifinmulticastpkts), - EXTRACT_32BITS(sflow_gen_counter->ifinbroadcastpkts), - EXTRACT_32BITS(sflow_gen_counter->ifindiscards)); - printf("\n\t In errors %u, unknown protos %u", - EXTRACT_32BITS(sflow_gen_counter->ifinerrors), - EXTRACT_32BITS(sflow_gen_counter->ifinunkownprotos)); - printf("\n\t Out octets %" PRIu64 - ", unicast pkts %u, multicast pkts %u, broadcast pkts %u, discards %u", - EXTRACT_64BITS(sflow_gen_counter->ifoutoctets), - EXTRACT_32BITS(sflow_gen_counter->ifoutunicastpkts), - EXTRACT_32BITS(sflow_gen_counter->ifoutmulticastpkts), - EXTRACT_32BITS(sflow_gen_counter->ifoutbroadcastpkts), - EXTRACT_32BITS(sflow_gen_counter->ifoutdiscards)); - printf("\n\t Out errors %u, promisc mode %u", - EXTRACT_32BITS(sflow_gen_counter->ifouterrors), - EXTRACT_32BITS(sflow_gen_counter->ifpromiscmode)); - break; - case SFLOW_COUNTER_ETHERNET: - sflow_eth_counter = (const struct sflow_ethernet_counter_t *)tptr; - printf("\n\t align errors %u, fcs errors %u, single collision %u, multiple collision %u, test error %u", - EXTRACT_32BITS(sflow_eth_counter->alignerrors), - EXTRACT_32BITS(sflow_eth_counter->fcserrors), - EXTRACT_32BITS(sflow_eth_counter->single_collision_frames), - EXTRACT_32BITS(sflow_eth_counter->multiple_collision_frames), - EXTRACT_32BITS(sflow_eth_counter->test_errors)); - printf("\n\t deferred %u, late collision %u, excessive collision %u, mac trans error %u", - EXTRACT_32BITS(sflow_eth_counter->deferred_transmissions), - EXTRACT_32BITS(sflow_eth_counter->late_collisions), - EXTRACT_32BITS(sflow_eth_counter->excessive_collisions), - EXTRACT_32BITS(sflow_eth_counter->mac_transmit_errors)); - printf("\n\t carrier error %u, frames too long %u, mac receive errors %u, symbol errors %u", - EXTRACT_32BITS(sflow_eth_counter->carrier_sense_errors), - EXTRACT_32BITS(sflow_eth_counter->frame_too_longs), - EXTRACT_32BITS(sflow_eth_counter->mac_receive_errors), - EXTRACT_32BITS(sflow_eth_counter->symbol_errors)); - break; - case SFLOW_COUNTER_TOKEN_RING: /* XXX */ - break; - case SFLOW_COUNTER_BASEVG: - sflow_100basevg_counter = (const struct sflow_100basevg_counter_t *)tptr; - printf("\n\t in high prio frames %u, in high prio octets %" PRIu64, - EXTRACT_32BITS(sflow_100basevg_counter->in_highpriority_frames), - EXTRACT_64BITS(sflow_100basevg_counter->in_highpriority_octets)); - printf("\n\t in norm prio frames %u, in norm prio octets %" PRIu64, - EXTRACT_32BITS(sflow_100basevg_counter->in_normpriority_frames), - EXTRACT_64BITS(sflow_100basevg_counter->in_normpriority_octets)); - printf("\n\t in ipm errors %u, oversized %u, in data errors %u, null addressed frames %u", - EXTRACT_32BITS(sflow_100basevg_counter->in_ipmerrors), - EXTRACT_32BITS(sflow_100basevg_counter->in_oversized), - EXTRACT_32BITS(sflow_100basevg_counter->in_data_errors), - EXTRACT_32BITS(sflow_100basevg_counter->in_null_addressed_frames)); - printf("\n\t out high prio frames %u, out high prio octets %" PRIu64 - ", trans into frames %u", - EXTRACT_32BITS(sflow_100basevg_counter->out_highpriority_frames), - EXTRACT_64BITS(sflow_100basevg_counter->out_highpriority_octets), - EXTRACT_32BITS(sflow_100basevg_counter->transitioninto_frames)); - printf("\n\t in hc high prio octets %" PRIu64 - ", in hc norm prio octets %" PRIu64 - ", out hc high prio octets %" PRIu64, - EXTRACT_64BITS(sflow_100basevg_counter->hc_in_highpriority_octets), - EXTRACT_64BITS(sflow_100basevg_counter->hc_in_normpriority_octets), - EXTRACT_64BITS(sflow_100basevg_counter->hc_out_highpriority_octets)); - break; - case SFLOW_COUNTER_VLAN: - sflow_vlan_counter = (const struct sflow_vlan_counter_t *)tptr; - printf("\n\t vlan_id %u, octets %" PRIu64 - ", unicast_pkt %u, multicast_pkt %u, broadcast_pkt %u, discards %u", - EXTRACT_32BITS(sflow_vlan_counter->vlan_id), - EXTRACT_64BITS(sflow_vlan_counter->octets), - EXTRACT_32BITS(sflow_vlan_counter->unicast_pkt), - EXTRACT_32BITS(sflow_vlan_counter->multicast_pkt), - EXTRACT_32BITS(sflow_vlan_counter->broadcast_pkt), - EXTRACT_32BITS(sflow_vlan_counter->discards)); - break; - case SFLOW_COUNTER_PROCESSOR: /* XXX */ - break; - default: - if (vflag <= 1) - print_unknown_data(tptr, "\n\t\t", counter_len); - break; - } - tptr += counter_len; - tlen -= counter_len; - nrecords--; - } - break; + if (sflow_print_expanded_counter_sample(tptr,tlen)) + goto trunc; + break; + default: if (vflag <= 1) print_unknown_data(tptr, "\n\t ", sflow_sample_len); diff --git a/contrib/tcpdump/print-sip.c b/contrib/tcpdump/print-sip.c index 48562f8c38..c5bc8534da 100644 --- a/contrib/tcpdump/print-sip.c +++ b/contrib/tcpdump/print-sip.c @@ -44,6 +44,7 @@ sip_print(register const u_char *pptr, register u_int len) return; for (idx = 0; idx < len; idx++) { + TCHECK2(*(pptr+idx), 2); if (EXTRACT_16BITS(pptr+idx) != 0x0d0a) { /* linefeed ? */ safeputchar(*(pptr+idx)); } else { @@ -57,4 +58,7 @@ sip_print(register const u_char *pptr, register u_int len) print_unknown_data(pptr,"\n\t",len); return; + +trunc: + printf("[|sip]"); } diff --git a/contrib/tcpdump/print-sl.c b/contrib/tcpdump/print-sl.c index f00d3943d3..91dbaadc27 100644 --- a/contrib/tcpdump/print-sl.c +++ b/contrib/tcpdump/print-sl.c @@ -73,7 +73,7 @@ sl_if_print(const struct pcap_pkthdr *h, const u_char *p) break; #ifdef INET6 case 6: - ip6_print((u_char *)ip, length); + ip6_print(gndo, (u_char *)ip, length); break; #endif default: diff --git a/contrib/tcpdump/print-sll.c b/contrib/tcpdump/print-sll.c index d96b3de29e..a044de6709 100644 --- a/contrib/tcpdump/print-sll.c +++ b/contrib/tcpdump/print-sll.c @@ -85,7 +85,7 @@ sll_print(register const struct sll_header *sllp, u_int length) /* * 802.2. */ - (void)printf("802.3"); + (void)printf("802.2"); break; default: @@ -142,8 +142,9 @@ sll_if_print(const struct pcap_pkthdr *h, const u_char *p) caplen -= SLL_HDR_LEN; p += SLL_HDR_LEN; - ether_type = ntohs(sllp->sll_protocol); + ether_type = EXTRACT_16BITS(&sllp->sll_protocol); +recurse: /* * Is it (gag) an 802.3 encapsulation, or some non-Ethernet * packet type? @@ -187,13 +188,43 @@ sll_if_print(const struct pcap_pkthdr *h, const u_char *p) default_print(p, caplen); break; } - } else if (ether_encap_print(ether_type, p, length, caplen, - &extracted_ethertype) == 0) { - /* ether_type not known, print raw packet */ - if (!eflag) - sll_print(sllp, length + SLL_HDR_LEN); - if (!suppress_default_print) - default_print(p, caplen); + } else if (ether_type == ETHERTYPE_8021Q) { + /* + * Print VLAN information, and then go back and process + * the enclosed type field. + */ + if (caplen < 4 || length < 4) { + printf("[|vlan]"); + return (SLL_HDR_LEN); + } + if (eflag) { + u_int16_t tag = EXTRACT_16BITS(p); + + printf("vlan %u, p %u%s, ", + tag & 0xfff, + tag >> 13, + (tag & 0x1000) ? ", CFI" : ""); + } + + ether_type = EXTRACT_16BITS(p + 2); + if (ether_type <= ETHERMTU) + ether_type = LINUX_SLL_P_802_2; + if (!qflag) { + (void)printf("ethertype %s, ", + tok2str(ethertype_values, "Unknown", ether_type)); + } + p += 4; + length -= 4; + caplen -= 4; + goto recurse; + } else { + if (ethertype_print(gndo, ether_type, p, length, caplen) == 0) { + /* ether_type not known, print raw packet */ + if (!eflag) + sll_print(sllp, length + SLL_HDR_LEN); + if (!suppress_default_print) + default_print(p, caplen); + } } return (SLL_HDR_LEN); diff --git a/contrib/tcpdump/print-slow.c b/contrib/tcpdump/print-slow.c index eaf94ed9bb..fdfefccf38 100644 --- a/contrib/tcpdump/print-slow.c +++ b/contrib/tcpdump/print-slow.c @@ -368,7 +368,7 @@ void slow_marker_lacp_print(register const u_char *tptr, register u_int tlen) { tlv_header->type != LACP_TLV_TERMINATOR && tlv_header->type != MARKER_TLV_TERMINATOR) { printf("\n\t-----trailing data-----"); - print_unknown_data(tptr+sizeof(sizeof(struct tlv_header_t)),"\n\t ",tlen); + print_unknown_data(tptr+sizeof(struct tlv_header_t),"\n\t ",tlen); return; } @@ -441,7 +441,7 @@ void slow_marker_lacp_print(register const u_char *tptr, register u_int tlen) { } /* do we want to see an additional hexdump ? */ if (vflag > 1) { - print_unknown_data(tptr+sizeof(sizeof(struct tlv_header_t)),"\n\t ", + print_unknown_data(tptr+sizeof(struct tlv_header_t),"\n\t ", tlv_len-sizeof(struct tlv_header_t)); } diff --git a/contrib/tcpdump/print-smb.c b/contrib/tcpdump/print-smb.c index 391f1860c6..68c73659f8 100644 --- a/contrib/tcpdump/print-smb.c +++ b/contrib/tcpdump/print-smb.c @@ -12,7 +12,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-smb.c,v 1.46.2.1 2007-12-09 00:31:35 guy Exp $"; + "@(#) $Header: /tcpdump/master/tcpdump/print-smb.c,v 1.47 2007-12-09 00:30:47 guy Exp $"; #endif #include diff --git a/contrib/tcpdump/print-sunrpc.c b/contrib/tcpdump/print-sunrpc.c index bfb2fe9a79..21cd85a9c5 100644 --- a/contrib/tcpdump/print-sunrpc.c +++ b/contrib/tcpdump/print-sunrpc.c @@ -28,14 +28,29 @@ static const char rcsid[] _U_ = #include "config.h" #endif +/* + * At least on HP-UX: + * + * 1) getrpcbynumber() is declared in , not any of the RPC + * header files + * + * and + * + * 2) if _XOPEN_SOURCE_EXTENDED is defined, doesn't declare + * it + * + * so we undefine it. + */ +#undef _XOPEN_SOURCE_EXTENDED + #include -#ifdef HAVE_GETRPCBYNUMBER +#if defined(HAVE_GETRPCBYNUMBER) && defined(HAVE_RPC_RPC_H) #include #ifdef HAVE_RPC_RPCENT_H #include #endif /* HAVE_RPC_RPCENT_H */ -#endif /* HAVE_GETRPCBYNUMBER */ +#endif /* defined(HAVE_GETRPCBYNUMBER) && defined(HAVE_RPC_RPC_H) */ #include #include @@ -136,7 +151,7 @@ static char * progstr(prog) u_int32_t prog; { -#ifdef HAVE_GETRPCBYNUMBER +#if defined(HAVE_GETRPCBYNUMBER) && defined(HAVE_RPC_RPC_H) register struct rpcent *rp; #endif static char buf[32]; @@ -144,12 +159,12 @@ progstr(prog) if (lastprog != 0 && prog == lastprog) return (buf); -#ifdef HAVE_GETRPCBYNUMBER +#if defined(HAVE_GETRPCBYNUMBER) && defined(HAVE_RPC_RPC_H) rp = getrpcbynumber(prog); if (rp == NULL) #endif (void) snprintf(buf, sizeof(buf), "#%u", prog); -#ifdef HAVE_GETRPCBYNUMBER +#if defined(HAVE_GETRPCBYNUMBER) && defined(HAVE_RPC_RPC_H) else strlcpy(buf, rp->r_name, sizeof(buf)); #endif diff --git a/contrib/tcpdump/print-symantec.c b/contrib/tcpdump/print-symantec.c index ebb62cd4d1..8b4ee38c40 100644 --- a/contrib/tcpdump/print-symantec.c +++ b/contrib/tcpdump/print-symantec.c @@ -33,6 +33,7 @@ static const char rcsid[] _U_ = #include #include "interface.h" +#include "extract.h" #include "addrtoname.h" #include "ethertype.h" @@ -52,7 +53,7 @@ symantec_hdr_print(register const u_char *bp, u_int length) sp = (const struct symantec_header *)bp; - etype = ntohs(sp->ether_type); + etype = EXTRACT_16BITS(&sp->ether_type); if (!qflag) { if (etype <= ETHERMTU) (void)printf("invalid ethertype %u", etype); @@ -83,7 +84,6 @@ symantec_if_print(const struct pcap_pkthdr *h, const u_char *p) u_int caplen = h->caplen; struct symantec_header *sp; u_short ether_type; - u_short extracted_ether_type; if (caplen < sizeof (struct symantec_header)) { printf("[|symantec]"); @@ -98,7 +98,7 @@ symantec_if_print(const struct pcap_pkthdr *h, const u_char *p) sp = (struct symantec_header *)p; p += sizeof (struct symantec_header); - ether_type = ntohs(sp->ether_type); + ether_type = EXTRACT_16BITS(&sp->ether_type); if (ether_type <= ETHERMTU) { /* ether_type not known, print raw packet */ @@ -107,8 +107,7 @@ symantec_if_print(const struct pcap_pkthdr *h, const u_char *p) if (!suppress_default_print) default_print(p, caplen); - } else if (ether_encap_print(ether_type, p, length, caplen, - &extracted_ether_type) == 0) { + } else if (ethertype_print(gndo, ether_type, p, length, caplen) == 0) { /* ether_type not known, print raw packet */ if (!eflag) symantec_hdr_print((u_char *)sp, length + sizeof (struct symantec_header)); diff --git a/contrib/tcpdump/print-tcp.c b/contrib/tcpdump/print-tcp.c index 5b0a7969a5..88b461576d 100644 --- a/contrib/tcpdump/print-tcp.c +++ b/contrib/tcpdump/print-tcp.c @@ -25,8 +25,8 @@ #ifndef lint static const char rcsid[] _U_ = -"@(#) $Header: /tcpdump/master/tcpdump/print-tcp.c,v 1.130.2.3 2007-12-22 03:08:45 guy Exp $ (LBL)"; - #else +"@(#) $Header: /tcpdump/master/tcpdump/print-tcp.c,v 1.135 2008-11-09 23:35:03 mcr Exp $ (LBL)"; +#else __RCSID("$NetBSD: print-tcp.c,v 1.8 2007/07/24 11:53:48 drochner Exp $"); #endif @@ -58,10 +58,7 @@ __RCSID("$NetBSD: print-tcp.c,v 1.8 2007/07/24 11:53:48 drochner Exp $"); #ifdef HAVE_LIBCRYPTO #include - -#define SIGNATURE_VALID 0 -#define SIGNATURE_INVALID 1 -#define CANT_CHECK_SIGNATURE 2 +#include static int tcp_verify_signature(const struct ip *ip, const struct tcphdr *tp, const u_char *data, int length, const u_char *rcvsig); @@ -124,6 +121,7 @@ struct tok tcp_option_values[] = { { TCPOPT_CCECHO, "" }, { TCPOPT_SIGNATURE, "md5" }, { TCPOPT_AUTH, "enhanced auth" }, + { TCPOPT_UTO, "uto" }, { 0, NULL } }; @@ -131,63 +129,9 @@ static int tcp_cksum(register const struct ip *ip, register const struct tcphdr *tp, register 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.len = htons((u_int16_t)len); - phu.ph.mbz = 0; - phu.ph.proto = IPPROTO_TCP; - 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 *)tp, len, - sp[0]+sp[1]+sp[2]+sp[3]+sp[4]+sp[5]); -} - -#ifdef INET6 -static int tcp6_cksum(const struct ip6_hdr *ip6, const struct tcphdr *tp, - u_int len) -{ - size_t i; - u_int32_t sum = 0; - 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_TCP; - - for (i = 0; i < sizeof(phu.pa) / sizeof(phu.pa[0]); i++) - sum += phu.pa[i]; - - return in_cksum((u_short *)tp, len, sum); + return (nextproto4_cksum(ip, (const u_int8_t *)tp, len, + IPPROTO_TCP)); } -#endif void tcp_print(register const u_char *bp, register u_int length, @@ -200,6 +144,7 @@ tcp_print(register const u_char *bp, register u_int length, register char ch; u_int16_t sport, dport, win, urp; u_int32_t seq, ack, thseq, thack; + u_int utoval; int threv; #ifdef INET6 register const struct ip6_hdr *ip6; @@ -326,7 +271,6 @@ tcp_print(register const u_char *bp, register u_int length, * both directions). */ #ifdef INET6 - memset(&tha, 0, sizeof(tha)); rev = 0; if (ip6) { src = &ip6->ip6_src; @@ -347,6 +291,27 @@ tcp_print(register const u_char *bp, register u_int length, tha.port = sport << 16 | dport; } } else { + /* + * Zero out the tha structure; the src and dst + * fields are big enough to hold an IPv6 + * address, but we only have IPv4 addresses + * and thus must clear out the remaining 124 + * bits. + * + * XXX - should we just clear those bytes after + * copying the IPv4 addresses, rather than + * zeroing out the entire structure and then + * overwriting some of the zeroes? + * + * XXX - this could fail if we see TCP packets + * with an IPv6 address with the lower 124 bits + * all zero and also see TCP packes with an + * IPv4 address with the same 32 bits as the + * upper 32 bits of the IPv6 address in question. + * Can that happen? Is it likely enough to be + * an issue? + */ + memset(&tha, 0, sizeof(tha)); src = &ip->ip_src; dst = &ip->ip_dst; if (sport > dport) @@ -425,37 +390,43 @@ tcp_print(register const u_char *bp, register u_int length, return; } - if (IP_V(ip) == 4 && vflag && !Kflag && !fragmented) { + if (vflag && !Kflag && !fragmented) { + /* Check the checksum, if possible. */ u_int16_t sum, tcp_sum; - if (TTEST2(tp->th_sport, length)) { - sum = tcp_cksum(ip, tp, length); - (void)printf(", cksum 0x%04x",EXTRACT_16BITS(&tp->th_sum)); - if (sum != 0) { + if (IP_V(ip) == 4) { + if (TTEST2(tp->th_sport, length)) { + sum = tcp_cksum(ip, tp, length); tcp_sum = EXTRACT_16BITS(&tp->th_sum); - (void)printf(" (incorrect -> 0x%04x)",in_cksum_shouldbe(tcp_sum, sum)); - } else - (void)printf(" (correct)"); + + (void)printf(", cksum 0x%04x", tcp_sum); + if (sum != 0) + (void)printf(" (incorrect -> 0x%04x)", + in_cksum_shouldbe(tcp_sum, sum)); + else + (void)printf(" (correct)"); + } } - } #ifdef INET6 - if (IP_V(ip) == 6 && ip6->ip6_plen && vflag && !Kflag && !fragmented) { - u_int16_t sum,tcp_sum; - if (TTEST2(tp->th_sport, length)) { - sum = tcp6_cksum(ip6, tp, length); - (void)printf(", cksum 0x%04x",EXTRACT_16BITS(&tp->th_sum)); - if (sum != 0) { + else if (IP_V(ip) == 6 && ip6->ip6_plen) { + if (TTEST2(tp->th_sport, length)) { + sum = nextproto6_cksum(ip6, (const u_int8_t *)tp, length, IPPROTO_TCP); tcp_sum = EXTRACT_16BITS(&tp->th_sum); - (void)printf(" (incorrect -> 0x%04x)",in_cksum_shouldbe(tcp_sum, sum)); - } else - (void)printf(" (correct)"); + (void)printf(", cksum 0x%04x", tcp_sum); + if (sum != 0) + (void)printf(" (incorrect -> 0x%04x)", + in_cksum_shouldbe(tcp_sum, sum)); + else + (void)printf(" (correct)"); + + } } - } #endif + } length -= hlen; - if (vflag > 1 || flags & (TH_SYN | TH_FIN | TH_RST)) { + if (vflag > 1 || length > 0 || flags & (TH_SYN | TH_FIN | TH_RST)) { (void)printf(", seq %u", seq); if (length > 0) { @@ -613,6 +584,18 @@ tcp_print(register const u_char *bp, register u_int length, */ break; + case TCPOPT_UTO: + datalen = 2; + LENCHECK(datalen); + utoval = EXTRACT_16BITS(cp); + (void)printf("0x%x", utoval); + if (utoval & 0x0001) + utoval = (utoval >> 1) * 60; + else + utoval >>= 1; + (void)printf(" %u", utoval); + break; + default: datalen = len - 2; for (i = 0; i < datalen; ++i) { @@ -681,6 +664,8 @@ tcp_print(register const u_char *bp, register u_int length, ns_print(bp + 2, length - 2, 0); } else if (sport == MSDP_PORT || dport == MSDP_PORT) { msdp_print(bp, length); + } else if (sport == RPKI_RTR_PORT || dport == RPKI_RTR_PORT) { + rpki_rtr_print(bp, length); } else if (length > 0 && (sport == LDP_PORT || dport == LDP_PORT)) { ldp_print(bp, length); @@ -750,10 +735,17 @@ tcp_verify_signature(const struct ip *ip, const struct tcphdr *tp, u_int8_t nxt; #endif + if (data + length > snapend) { + printf("snaplen too short, "); + return (CANT_CHECK_SIGNATURE); + } + tp1 = *tp; - if (tcpmd5secret == NULL) + if (sigsecret == NULL) { + printf("shared secret not supplied with -M, "); return (CANT_CHECK_SIGNATURE); + } MD5_Init(&ctx); /* @@ -772,7 +764,7 @@ tcp_verify_signature(const struct ip *ip, const struct tcphdr *tp, ip6 = (struct ip6_hdr *)ip; MD5_Update(&ctx, (char *)&ip6->ip6_src, sizeof(ip6->ip6_src)); MD5_Update(&ctx, (char *)&ip6->ip6_dst, sizeof(ip6->ip6_dst)); - len32 = htonl(ntohs(ip6->ip6_plen)); + len32 = htonl(EXTRACT_16BITS(&ip6->ip6_plen)); MD5_Update(&ctx, (char *)&len32, sizeof(len32)); nxt = 0; MD5_Update(&ctx, (char *)&nxt, sizeof(nxt)); @@ -781,8 +773,14 @@ tcp_verify_signature(const struct ip *ip, const struct tcphdr *tp, nxt = IPPROTO_TCP; MD5_Update(&ctx, (char *)&nxt, sizeof(nxt)); #endif - } else + } else { +#ifdef INET6 + printf("IP version not 4 or 6, "); +#else + printf("IP version not 4, "); +#endif return (CANT_CHECK_SIGNATURE); + } /* * Step 2: Update MD5 hash with TCP header, excluding options. @@ -800,7 +798,7 @@ tcp_verify_signature(const struct ip *ip, const struct tcphdr *tp, /* * Step 4: Update MD5 hash with shared secret. */ - MD5_Update(&ctx, tcpmd5secret, strlen(tcpmd5secret)); + MD5_Update(&ctx, sigsecret, strlen(sigsecret)); MD5_Final(sig, &ctx); if (memcmp(rcvsig, sig, TCP_SIGLEN) == 0) diff --git a/contrib/tcpdump/print-tftp.c b/contrib/tcpdump/print-tftp.c index c4fc7ea2af..84cde3969d 100644 --- a/contrib/tcpdump/print-tftp.c +++ b/contrib/tcpdump/print-tftp.c @@ -23,7 +23,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-tftp.c,v 1.38.2.1 2008-04-11 16:44:17 gianluca Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-tftp.c,v 1.39 2008-04-11 16:47:38 gianluca Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -99,15 +99,7 @@ tftp_print(register const u_char *bp, u_int length) case RRQ: case WRQ: case OACK: - /* - * XXX Not all arpa/tftp.h's specify th_stuff as any - * array; use address of th_block instead - */ -#ifdef notdef p = (u_char *)tp->th_stuff; -#else - p = (u_char *)&tp->th_block; -#endif putchar(' '); /* Print filename or first option */ if (opcode != OACK) diff --git a/contrib/tcpdump/print-token.c b/contrib/tcpdump/print-token.c index 04defa9921..4f8422b5ab 100644 --- a/contrib/tcpdump/print-token.c +++ b/contrib/tcpdump/print-token.c @@ -39,6 +39,7 @@ static const char rcsid[] _U_ = #include #include "interface.h" +#include "extract.h" #include "addrtoname.h" #include "ethertype.h" @@ -126,7 +127,16 @@ token_print(const u_char *p, u_int length, u_int caplen) if (eflag) token_hdr_print(trp, length, ESRC(&ehdr), EDST(&ehdr)); + if (caplen < TOKEN_HDRLEN + 2) { + printf("[|token-ring]"); + return hdr_len; + } route_len = RIF_LENGTH(trp); + hdr_len += route_len; + if (caplen < hdr_len) { + printf("[|token-ring]"); + return hdr_len; + } if (vflag) { printf("%s ", broadcast_indicator[BROADCAST(trp)]); printf("%s", direction[DIRECTION(trp)]); @@ -135,10 +145,10 @@ token_print(const u_char *p, u_int length, u_int caplen) printf(" [%d:%d]", RING_NUMBER(trp, seg), BRIDGE_NUMBER(trp, seg)); } else { - printf("rt = %x", ntohs(trp->token_rcf)); + printf("rt = %x", EXTRACT_16BITS(&trp->token_rcf)); for (seg = 0; seg < SEGMENT_COUNT(trp); seg++) - printf(":%x", ntohs(trp->token_rseg[seg])); + printf(":%x", EXTRACT_16BITS(&trp->token_rseg[seg])); } printf(" (%s) ", largest_frame[LARGEST_FRAME(trp)]); } else { @@ -147,7 +157,6 @@ token_print(const u_char *p, u_int length, u_int caplen) } /* Skip over token ring MAC header and routing information */ - hdr_len += route_len; length -= hdr_len; p += hdr_len; caplen -= hdr_len; diff --git a/contrib/tcpdump/print-udp.c b/contrib/tcpdump/print-udp.c index f534c1bb45..885d42e4da 100644 --- a/contrib/tcpdump/print-udp.c +++ b/contrib/tcpdump/print-udp.c @@ -33,7 +33,6 @@ static const char rcsid[] _U_ = #ifdef SEGSIZE #undef SEGSIZE #endif -#include #include #include @@ -287,75 +286,16 @@ static int udp_cksum(register const struct ip *ip, register const struct udphdr *up, register 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; - register const u_int16_t *sp; - - /* pseudo-header.. */ - phu.ph.len = htons((u_int16_t)len); - phu.ph.mbz = 0; - phu.ph.proto = IPPROTO_UDP; - 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 *)up, len, - sp[0]+sp[1]+sp[2]+sp[3]+sp[4]+sp[5]); + return (nextproto4_cksum(ip, (const u_int8_t *)(void *)up, len, + IPPROTO_UDP)); } #ifdef INET6 static int udp6_cksum(const struct ip6_hdr *ip6, const struct udphdr *up, u_int len) { - size_t i; - register 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_UDP; - - sum = 0; - for (i = 0; i < sizeof(phu.pa) / sizeof(phu.pa[0]); i++) - sum += phu.pa[i]; - - sp = (const u_int16_t *)up; - - 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); + return (nextproto6_cksum(ip6, (const u_int8_t *)(void *)up, len, + IPPROTO_UDP)); } #endif @@ -568,31 +508,46 @@ udp_print(register const u_char *bp, u_int length, } udpipaddr_print(ip, sport, dport); - if (IP_V(ip) == 4 && (vflag > 1) && !fragmented) { - int sum = up->uh_sum; - if (sum == 0) { - (void)printf("[no cksum] "); - } else if (TTEST2(cp[0], length)) { - sum = udp_cksum(ip, up, length + sizeof(struct udphdr)); - if (sum != 0) - (void)printf("[bad udp cksum %x!] ", sum); - else - (void)printf("[udp sum ok] "); + if (vflag && !Kflag && !fragmented) { + /* Check the checksum, if possible. */ + u_int16_t sum, udp_sum; + + /* + * XXX - do this even if vflag == 1? + * TCP does, and we do so for UDP-over-IPv6. + */ + if (IP_V(ip) == 4 && (vflag > 1)) { + udp_sum = EXTRACT_16BITS(&up->uh_sum); + if (udp_sum == 0) { + (void)printf("[no cksum] "); + } else if (TTEST2(cp[0], length)) { + sum = udp_cksum(ip, up, length + sizeof(struct udphdr)); + + if (sum != 0) { + (void)printf("[bad udp cksum 0x%04x -> 0x%04x!] ", + udp_sum, + in_cksum_shouldbe(udp_sum, sum)); + } else + (void)printf("[udp sum ok] "); + } } - } #ifdef INET6 - if (IP_V(ip) == 6 && ip6->ip6_plen && vflag && !fragmented) { - int sum = up->uh_sum; - /* for IPv6, UDP checksum is mandatory */ - if (TTEST2(cp[0], length)) { - sum = udp6_cksum(ip6, up, length + sizeof(struct udphdr)); - if (sum != 0) - (void)printf("[bad udp cksum %x!] ", sum); - else - (void)printf("[udp sum ok] "); + else if (IP_V(ip) == 6 && ip6->ip6_plen) { + /* for IPv6, UDP checksum is mandatory */ + if (TTEST2(cp[0], length)) { + sum = udp6_cksum(ip6, up, length + sizeof(struct udphdr)); + udp_sum = EXTRACT_16BITS(&up->uh_sum); + + if (sum != 0) { + (void)printf("[bad udp cksum 0x%04x -> 0x%04x!] ", + udp_sum, + in_cksum_shouldbe(udp_sum, sum)); + } else + (void)printf("[udp sum ok] "); + } } - } #endif + } if (!qflag) { #define ISPORT(p) (dport == (p) || sport == (p)) @@ -652,9 +607,10 @@ udp_print(register const u_char *bp, u_int length, #ifdef INET6 else if (ISPORT(RIPNG_PORT)) ripng_print((const u_char *)(up + 1), length); - else if (ISPORT(DHCP6_SERV_PORT) || ISPORT(DHCP6_CLI_PORT)) { + else if (ISPORT(DHCP6_SERV_PORT) || ISPORT(DHCP6_CLI_PORT)) dhcp6_print((const u_char *)(up + 1), length); - } + else if (ISPORT(BABEL_PORT) || ISPORT(BABEL_PORT_OLD)) + babel_print((const u_char *)(up + 1), length); #endif /*INET6*/ /* * Kludge in test for whiteboard packets. @@ -672,11 +628,16 @@ udp_print(register const u_char *bp, u_int length, hsrp_print((const u_char *)(up + 1), length); else if (ISPORT(LWRES_PORT)) lwres_print((const u_char *)(up + 1), length); - else if (ISPORT(LDP_PORT)) + else if (ISPORT(LDP_PORT)) ldp_print((const u_char *)(up + 1), length); - else if (ISPORT(OLSR_PORT)) - olsr_print((const u_char *)(up + 1), length); - else if (ISPORT(MPLS_LSP_PING_PORT)) + else if (ISPORT(OLSR_PORT)) + olsr_print((const u_char *)(up + 1), length, +#if INET6 + (IP_V(ip) == 6) ? 1 : 0); +#else + 0); +#endif + else if (ISPORT(MPLS_LSP_PING_PORT)) lspping_print((const u_char *)(up + 1), length); else if (dport == BFD_CONTROL_PORT || dport == BFD_ECHO_PORT ) diff --git a/contrib/tcpdump/print-usb.c b/contrib/tcpdump/print-usb.c new file mode 100644 index 0000000000..8e15e7bf39 --- /dev/null +++ b/contrib/tcpdump/print-usb.c @@ -0,0 +1,174 @@ +/* + * Copyright 2009 Bert Vermeulen + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by Paolo Abeni.'' + * The name of author may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Support for USB packets + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" + + +#if defined(HAVE_PCAP_USB_H) && defined(DLT_USB_LINUX) +#include + +/* returns direction: 1=inbound 2=outbound -1=invalid */ +static int +get_direction(int transfer_type, int event_type) +{ + int direction; + + direction = -1; + switch(transfer_type){ + case URB_BULK: + case URB_CONTROL: + case URB_ISOCHRONOUS: + switch(event_type) + { + case URB_SUBMIT: + direction = 2; + break; + case URB_COMPLETE: + case URB_ERROR: + direction = 1; + break; + default: + direction = -1; + } + break; + case URB_INTERRUPT: + switch(event_type) + { + case URB_SUBMIT: + direction = 1; + break; + case URB_COMPLETE: + case URB_ERROR: + direction = 2; + break; + default: + direction = -1; + } + break; + default: + direction = -1; + } + + return direction; +} + +static void +usb_header_print(const pcap_usb_header *uh) +{ + int direction; + + switch(uh->transfer_type) + { + case URB_ISOCHRONOUS: + printf("ISOCHRONOUS"); + break; + case URB_INTERRUPT: + printf("INTERRUPT"); + break; + case URB_CONTROL: + printf("CONTROL"); + break; + case URB_BULK: + printf("BULK"); + break; + default: + printf(" ?"); + } + + switch(uh->event_type) + { + case URB_SUBMIT: + printf(" SUBMIT"); + break; + case URB_COMPLETE: + printf(" COMPLETE"); + break; + case URB_ERROR: + printf(" ERROR"); + break; + default: + printf(" ?"); + } + + direction = get_direction(uh->transfer_type, uh->event_type); + if(direction == 1) + printf(" from"); + else if(direction == 2) + printf(" to"); + printf(" %d:%d:%d", uh->bus_id, uh->device_address, uh->endpoint_number & 0x7f); +} + +/* + * This is the top level routine of the printer for captures with a + * 48-byte header. + * + * 'p' points to the header of the packet, 'h->ts' is the timestamp, + * 'h->len' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. + */ +u_int +usb_linux_48_byte_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + if (h->caplen < sizeof(pcap_usb_header)) { + printf("[|usb]"); + return(sizeof(pcap_usb_header)); + } + + usb_header_print((const pcap_usb_header *) p); + + return(sizeof(pcap_usb_header)); +} + +#ifdef DLT_USB_LINUX_MMAPPED +/* + * This is the top level routine of the printer for captures with a + * 64-byte header. + * + * 'p' points to the header of the packet, 'h->ts' is the timestamp, + * 'h->len' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. + */ +u_int +usb_linux_64_byte_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + if (h->caplen < sizeof(pcap_usb_header_mmapped)) { + printf("[|usb]"); + return(sizeof(pcap_usb_header_mmapped)); + } + + usb_header_print((const pcap_usb_header *) p); + + return(sizeof(pcap_usb_header_mmapped)); +} +#endif /* DLT_USB_LINUX_MMAPPED */ + +#endif /* defined(HAVE_PCAP_USB_H) && defined(DLT_USB_LINUX) */ + diff --git a/contrib/tcpdump/print-vrrp.c b/contrib/tcpdump/print-vrrp.c index 899542dac4..8b733d228c 100644 --- a/contrib/tcpdump/print-vrrp.c +++ b/contrib/tcpdump/print-vrrp.c @@ -110,9 +110,15 @@ vrrp_print(register const u_char *bp, register u_int len, int ttl) int i; char c; - if (TTEST2(bp[0], len) && in_cksum((const u_short*)bp, len, 0)) - printf(", (bad vrrp cksum %x)", - EXTRACT_16BITS(&bp[6])); + if (TTEST2(bp[0], len)) { + struct cksum_vec vec[1]; + + vec[0].ptr = bp; + vec[0].len = len; + if (in_cksum(vec, 1)) + printf(", (bad vrrp cksum %x)", + EXTRACT_16BITS(&bp[6])); + } printf(", addrs"); if (naddrs > 1) printf("(%d)", naddrs); diff --git a/contrib/tcpdump/setsignal.h b/contrib/tcpdump/setsignal.h index cc8e86c242..984c340730 100644 --- a/contrib/tcpdump/setsignal.h +++ b/contrib/tcpdump/setsignal.h @@ -18,7 +18,7 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: /tcpdump/master/tcpdump/setsignal.h,v 1.2.1.1 1999-10-07 23:47:13 mcr Exp $ (LBL) + * @(#) $Header: /tcpdump/master/tcpdump/setsignal.h,v 1.2 1999-10-07 23:47:13 mcr Exp $ (LBL) */ #ifndef setsignal_h #define setsignal_h diff --git a/contrib/tcpdump/signature.c b/contrib/tcpdump/signature.c new file mode 100644 index 0000000000..c55645fe2b --- /dev/null +++ b/contrib/tcpdump/signature.c @@ -0,0 +1,159 @@ +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * Functions for signature and digest verification. + * + * Original code by Hannes Gredler (hannes@juniper.net) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/signature.c,v 1.2 2008-09-22 20:22:10 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +#include "interface.h" +#include "signature.h" + +#ifdef HAVE_LIBCRYPTO +#include +#endif + +const struct tok signature_check_values[] = { + { SIGNATURE_VALID, "valid"}, + { SIGNATURE_INVALID, "invalid"}, + { CANT_CHECK_SIGNATURE, "unchecked"}, + { 0, NULL } +}; + + +#ifdef HAVE_LIBCRYPTO +/* + * Compute a HMAC MD5 sum. + * Taken from rfc2104, Appendix. + */ +static void +signature_compute_hmac_md5(const u_int8_t *text, int text_len, unsigned char *key, + unsigned int key_len, u_int8_t *digest) +{ + MD5_CTX context; + unsigned char k_ipad[65]; /* inner padding - key XORd with ipad */ + unsigned char k_opad[65]; /* outer padding - key XORd with opad */ + unsigned char tk[16]; + int i; + + /* if key is longer than 64 bytes reset it to key=MD5(key) */ + if (key_len > 64) { + + MD5_CTX tctx; + + MD5_Init(&tctx); + MD5_Update(&tctx, key, key_len); + MD5_Final(tk, &tctx); + + key = tk; + key_len = 16; + } + + /* + * the HMAC_MD5 transform looks like: + * + * MD5(K XOR opad, MD5(K XOR ipad, text)) + * + * where K is an n byte key + * ipad is the byte 0x36 repeated 64 times + * opad is the byte 0x5c repeated 64 times + * and text is the data being protected + */ + + /* start out by storing key in pads */ + memset(k_ipad, 0, sizeof k_ipad); + memset(k_opad, 0, sizeof k_opad); + memcpy(k_ipad, key, key_len); + memcpy(k_opad, key, key_len); + + /* XOR key with ipad and opad values */ + for (i=0; i<64; i++) { + k_ipad[i] ^= 0x36; + k_opad[i] ^= 0x5c; + } + + /* + * perform inner MD5 + */ + MD5_Init(&context); /* init context for 1st pass */ + MD5_Update(&context, k_ipad, 64); /* start with inner pad */ + MD5_Update(&context, text, text_len); /* then text of datagram */ + MD5_Final(digest, &context); /* finish up 1st pass */ + + /* + * perform outer MD5 + */ + MD5_Init(&context); /* init context for 2nd pass */ + MD5_Update(&context, k_opad, 64); /* start with outer pad */ + MD5_Update(&context, digest, 16); /* then results of 1st hash */ + MD5_Final(digest, &context); /* finish up 2nd pass */ +} +#endif + +#ifdef HAVE_LIBCRYPTO +/* + * Verify a cryptographic signature of the packet. + * Currently only MD5 is supported. + */ +int +signature_verify (const u_char *pptr, u_int plen, u_char *sig_ptr) +{ + u_int8_t rcvsig[16]; + u_int8_t sig[16]; + unsigned int i; + + /* + * Save the signature before clearing it. + */ + memcpy(rcvsig, sig_ptr, sizeof(rcvsig)); + memset(sig_ptr, 0, sizeof(rcvsig)); + + if (!sigsecret) { + return (CANT_CHECK_SIGNATURE); + } + + signature_compute_hmac_md5(pptr, plen, (unsigned char *)sigsecret, + strlen(sigsecret), sig); + + if (memcmp(rcvsig, sig, sizeof(sig)) == 0) { + return (SIGNATURE_VALID); + + } else { + + for (i = 0; i < sizeof(sig); ++i) { + (void)printf("%02x", sig[i]); + } + + return (SIGNATURE_INVALID); + } +} +#endif + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 4 + * End: + */ diff --git a/contrib/tcpdump/l2vpn.h b/contrib/tcpdump/signature.h old mode 100755 new mode 100644 similarity index 63% copy from contrib/tcpdump/l2vpn.h copy to contrib/tcpdump/signature.h index 766cda546a..e48b722988 --- a/contrib/tcpdump/l2vpn.h +++ b/contrib/tcpdump/signature.h @@ -1,4 +1,3 @@ -/* @(#) $Header: /tcpdump/master/tcpdump/l2vpn.h,v 1.1 2004-06-15 09:42:41 hannes Exp $ (LBL) */ /* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code @@ -11,7 +10,17 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * + * Functions for signature and digest verification. + * * Original code by Hannes Gredler (hannes@juniper.net) */ -extern struct tok l2vpn_encaps_values[]; +/* @(#) $Header: /tcpdump/master/tcpdump/signature.h,v 1.1 2008-08-16 11:36:20 hannes Exp $ (LBL) */ + +/* signature checking result codes */ +#define SIGNATURE_VALID 0 +#define SIGNATURE_INVALID 1 +#define CANT_CHECK_SIGNATURE 2 + +extern const struct tok signature_check_values[]; +extern int signature_verify (const u_char *, u_int, u_char *); diff --git a/contrib/tcpdump/sll.h b/contrib/tcpdump/sll.h index bad31e27a4..0a34963a53 100644 --- a/contrib/tcpdump/sll.h +++ b/contrib/tcpdump/sll.h @@ -35,7 +35,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#) $Header: /tcpdump/master/tcpdump/sll.h,v 1.7.6.1 2008-05-30 01:38:21 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/tcpdump/sll.h,v 1.8 2008-05-30 01:37:41 guy Exp $ (LBL) */ /* diff --git a/contrib/tcpdump/smbutil.c b/contrib/tcpdump/smbutil.c index ba7ec31a98..5eadb4fdb5 100644 --- a/contrib/tcpdump/smbutil.c +++ b/contrib/tcpdump/smbutil.c @@ -900,7 +900,7 @@ static const err_code_struct dos_msgs[] = { }; /* Server Error Messages */ -err_code_struct server_msgs[] = { +static const err_code_struct server_msgs[] = { { "ERRerror", 1, "Non-specific error code." }, { "ERRbadpw", 2, "Bad password - name/password pair in a Tree Connect or Session Setup are invalid." }, { "ERRbadtype", 3, "reserved." }, @@ -937,7 +937,7 @@ err_code_struct server_msgs[] = { }; /* Hard Error Messages */ -err_code_struct hard_msgs[] = { +static const err_code_struct hard_msgs[] = { { "ERRnowrite", 19, "Attempt to write on write-protected diskette." }, { "ERRbadunit", 20, "Unknown unit." }, { "ERRnotready", 21, "Drive not ready." }, diff --git a/contrib/tcpdump/strcasecmp.c b/contrib/tcpdump/strcasecmp.c deleted file mode 100644 index f19ccf547d..0000000000 --- a/contrib/tcpdump/strcasecmp.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 1987 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that this notice is preserved and that due credit is given - * to the University of California at Berkeley. The name of the University - * may not be used to endorse or promote products derived from this - * software without specific written prior permission. This software - * is provided ``as is'' without express or implied warranty. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/strcasecmp.c,v 1.6 2003-11-16 09:36:43 guy Exp $"; -#endif - -#include - -#include "interface.h" - -/* - * This array is designed for mapping upper and lower case letter - * together for a case independent comparison. The mappings are - * based upon ascii character sequences. - */ -static u_char charmap[] = { - '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', - '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', - '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', - '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', - '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', - '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', - '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', - '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', - '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', - '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', - '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', - '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', - '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', - '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', - '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', - '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177', - '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207', - '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217', - '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227', - '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237', - '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247', - '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257', - '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267', - '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277', - '\300', '\341', '\342', '\343', '\344', '\345', '\346', '\347', - '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', - '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', - '\370', '\371', '\372', '\333', '\334', '\335', '\336', '\337', - '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347', - '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', - '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', - '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377', -}; - -int -strcasecmp(s1, s2) - const char *s1, *s2; -{ - register u_char *cm = charmap, - *us1 = (u_char *)s1, - *us2 = (u_char *)s2; - - while (cm[*us1] == cm[*us2++]) - if (*us1++ == '\0') - return(0); - return(cm[*us1] - cm[*--us2]); -} - -int -strncasecmp(s1, s2, n) - const char *s1, *s2; - register int n; -{ - register u_char *cm = charmap, - *us1 = (u_char *)s1, - *us2 = (u_char *)s2; - - while (--n >= 0 && cm[*us1] == cm[*us2++]) - if (*us1++ == '\0') - return(0); - return(n < 0 ? 0 : cm[*us1] - cm[*--us2]); -} diff --git a/contrib/tcpdump/tcp.h b/contrib/tcpdump/tcp.h index db7dd44775..45fc21c0d5 100644 --- a/contrib/tcpdump/tcp.h +++ b/contrib/tcpdump/tcp.h @@ -1,4 +1,4 @@ -/* @(#) $Header: /tcpdump/master/tcpdump/tcp.h,v 1.13.2.1 2007-12-09 00:31:35 guy Exp $ (LBL) */ +/* @(#) $Header: /tcpdump/master/tcpdump/tcp.h,v 1.14 2007-12-09 00:30:47 guy Exp $ (LBL) */ /* * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. @@ -83,6 +83,9 @@ struct tcphdr { #define TCPOLEN_SIGNATURE 18 #define TCP_SIGLEN 16 /* length of an option 19 digest */ #define TCPOPT_AUTH 20 /* Enhanced AUTH option */ +#define TCPOPT_UTO 28 /* tcp user timeout (rfc5482) */ +#define TCPOLEN_UTO 4 + #define TCPOPT_TSTAMP_HDR \ (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP) @@ -102,6 +105,7 @@ struct tcphdr { #define NFS_PORT 2049 #endif #define MSDP_PORT 639 +#define RPKI_RTR_PORT 2222 /* experimental up until sidr-wg registers a well-known port */ #define LDP_PORT 646 #ifndef SMB_PORT #define SMB_PORT 445 diff --git a/contrib/tcpdump/tcpdump-stdinc.h b/contrib/tcpdump/tcpdump-stdinc.h index 30d42fcd50..d350d1be12 100644 --- a/contrib/tcpdump/tcpdump-stdinc.h +++ b/contrib/tcpdump/tcpdump-stdinc.h @@ -29,7 +29,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * - * @(#) $Header: /tcpdump/master/tcpdump/tcpdump-stdinc.h,v 1.17 2006-05-19 17:55:34 hannes Exp $ (LBL) + * @(#) $Header: /tcpdump/master/tcpdump/tcpdump-stdinc.h,v 1.18 2007-11-24 18:13:33 mcr Exp $ (LBL) */ /* @@ -55,6 +55,10 @@ #include #include /* in wpcap's Win32/include */ +#ifndef NBBY +#define NBBY 8 +#endif + #if !defined(__MINGW32__) && !defined(__WATCOMC__) #undef toascii #define isascii __isascii @@ -127,10 +131,43 @@ typedef char* caddr_t; #endif /* WIN32 */ -#ifdef INET6 -#include "ip6.h" +#ifndef HAVE___ATTRIBUTE__ +#define __attribute__(x) #endif +/* + * Used to declare a structure unaligned, so that the C compiler, + * if necessary, generates code that doesn't assume alignment. + * This is required because there is no guarantee that the packet + * data we get from libpcap/WinPcap is properly aligned. + * + * This assumes that, for all compilers that support __attribute__: + * + * 1) they support __attribute__((packed)); + * + * 2) for all instruction set architectures requiring strict + * alignment, declaring a structure with that attribute + * causes the compiler to generate code that handles + * misaligned 2-byte, 4-byte, and 8-byte integral + * quantities. + * + * It does not (yet) handle compilers where you can get the compiler + * to generate code of that sort by some other means. + * + * This is required in order to, for example, keep the compiler from + * generating, for + * + * if (bp->bp_htype == 1 && bp->bp_hlen == 6 && bp->bp_op == BOOTPREQUEST) { + * + * in print-bootp.c, code that loads the first 4-byte word of a + * "struct bootp", masking out the bp_hops field, and comparing the result + * against 0x01010600. + * + * Note: this also requires that padding be put into the structure, + * at least for compilers where it's implemented as __attribute__((packed)). + */ +#define UNALIGNED __attribute__((packed)) + #if defined(WIN32) || defined(MSDOS) #define FOPEN_READ_TXT "rt" #define FOPEN_READ_BIN "rb" @@ -143,21 +180,21 @@ typedef char* caddr_t; #define FOPEN_WRITE_BIN FOPEN_WRITE_TXT #endif -#if defined(__GNUC__) && defined(__i386__) && !defined(__ntohl) +#if defined(__GNUC__) && defined(__i386__) && !defined(__APPLE__) && !defined(__ntohl) #undef ntohl #undef ntohs #undef htonl #undef htons - extern __inline__ unsigned long __ntohl (unsigned long x); - extern __inline__ unsigned short __ntohs (unsigned short x); + static __inline__ unsigned long __ntohl (unsigned long x); + static __inline__ unsigned short __ntohs (unsigned short x); #define ntohl(x) __ntohl(x) #define ntohs(x) __ntohs(x) #define htonl(x) __ntohl(x) #define htons(x) __ntohs(x) - extern __inline__ unsigned long __ntohl (unsigned long x) + static __inline__ unsigned long __ntohl (unsigned long x) { __asm__ ("xchgb %b0, %h0\n\t" /* swap lower bytes */ "rorl $16, %0\n\t" /* swap words */ @@ -166,7 +203,7 @@ typedef char* caddr_t; return (x); } - extern __inline__ unsigned short __ntohs (unsigned short x) + static __inline__ unsigned short __ntohs (unsigned short x) { __asm__ ("xchgb %b0, %h0" /* swap bytes */ : "=q" (x) : "0" (x)); diff --git a/contrib/tcpdump/tcpdump.1 b/contrib/tcpdump/tcpdump.1.in similarity index 94% rename from contrib/tcpdump/tcpdump.1 rename to contrib/tcpdump/tcpdump.1.in index 50efc31c56..aabda77149 100644 --- a/contrib/tcpdump/tcpdump.1 +++ b/contrib/tcpdump/tcpdump.1.in @@ -1,4 +1,4 @@ -.\" @(#) $Header: /tcpdump/master/tcpdump/tcpdump.1,v 1.185.2.6 2008-05-30 01:38:21 guy Exp $ (LBL) +.\" @(#) $Header: /tcpdump/master/tcpdump/tcpdump.1.in,v 1.2 2008-11-09 23:35:03 mcr Exp $ (LBL) .\" .\" $NetBSD: tcpdump.8,v 1.9 2003/03/31 00:18:17 perry Exp $ .\" @@ -22,14 +22,14 @@ .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. .\" -.TH TCPDUMP 1 "07 January 2008" +.TH TCPDUMP 1 "05 March 2009" .SH NAME tcpdump \- dump traffic on a network .SH SYNOPSIS .na .B tcpdump [ -.B \-AdDefIKlLnNOpqRStuUvxX +.B \-AbdDefhHIJKlLnNOpqRStuUvxX ] [ .B \-B .I buffer_size @@ -56,6 +56,10 @@ tcpdump \- dump traffic on a network .I interface ] [ +.B \-j +.I tstamp_type +] +[ .B \-m .I module ] @@ -191,6 +195,10 @@ special privileges. Print each packet (minus its link level header) in ASCII. Handy for capturing web pages. .TP +.B \-b +Print the AS number in BGP packets in ASDOT notation rather than ASPLAIN +notation. +.TP .B \-B Set the operating system capture buffer size to \fIbuffer_size\fP. .TP @@ -252,7 +260,7 @@ Print the link-level header on each dump line. .B \-E Use \fIspi@ipaddr algo:secret\fP for decrypting IPsec ESP packets that are addressed to \fIaddr\fP and contain Security Parameter Index value -\fIspi\fP. This combination may be repeated with comma or newline seperation. +\fIspi\fP. This combination may be repeated with comma or newline separation. .IP Note that setting the secret for IPv4 ESP packets is supported at this time. .IP @@ -268,7 +276,7 @@ The ability to decrypt packets is only present if \fItcpdump\fP was compiled with cryptography enabled. .IP \fIsecret\fP is the ASCII text for ESP secret key. -If preceeded by 0x, then a hex value will be read. +If preceded by 0x, then a hex value will be read. .IP The option assumes RFC2406 ESP, not RFC1827 ESP. The option is only for debugging purposes, and @@ -315,6 +323,13 @@ If used in conjunction with the .B \-C option, filenames will take the form of `\fIfile\fP'. .TP +.B \-h +Print the tcpdump and libpcap version strings, print a usage message, +and exit. +.TP +.B \-H +Attempt to detect 802.11s draft mesh headers. +.TP .B \-i Listen on \fIinterface\fP. If unspecified, \fItcpdump\fP searches the system interface list for the @@ -344,11 +359,33 @@ any wireless networks with that adapter. This could prevent accessing files on a network server, or resolving host names or network addresses, if you are capturing in monitor mode and are not connected to another network with another adapter. +.IP +This flag will affect the output of the +.B \-L +flag. If +.B \-I +isn't specified, only those link-layer types available when not in +monitor mode will be shown; if +.B \-I +is specified, only those link-layer types available when in monitor mode +will be shown. +.TP +.B \-j +Set the time stamp type for the capture to \fItstamp_type\fP. The names +to use for the time stamp types are given in +.BR pcap-tstamp-type (@MAN_MISC_INFO@); +not all the types listed there will necessarily be valid for any given +interface. +.TP +.B \-J +List the supported time stamp types for the interface and exit. If the +time stamp type cannot be set for the interface, no time stamp types are +listed. .TP .B \-K -Don't attempt to verify TCP checksums. This is useful for interfaces -that perform the TCP checksum calculation in hardware; otherwise, -all outgoing TCP checksums will be flagged as bad. +Don't attempt to verify IP, TCP, or UDP checksums. This is useful for +interfaces that perform some or all of those checksum calculation in +hardware; otherwise, all outgoing TCP checksums will be flagged as bad. .TP .B \-l Make stdout line buffered. @@ -360,7 +397,15 @@ E.g., ``tcpdump\ \ \-l \ \ > dat\ \ &\ \ tail\ \ \-f\ \ dat''. .TP .B \-L -List the known data link types for the interface and exit. +List the known data link types for the interface, in the specified mode, +and exit. The list of known data link types may be dependent on the +specified mode; for example, on some platforms, a Wi-Fi interface might +support one set of data link types when not in monitor mode (for +example, it might support only fake Ethernet headers, or might support +802.11 headers but not support 802.11 headers with radio information) +and another set of data link types when in monitor mode (for example, it +might support 802.11 headers, or 802.11 headers with radio information, +only in monitor mode). .TP .B \-m Load SMI MIB module definitions from file \fImodule\fR. @@ -414,10 +459,7 @@ Print absolute, rather than relative, TCP sequence numbers. .TP .B \-s Snarf \fIsnaplen\fP bytes of data from each packet rather than the -default of 68 (with SunOS's NIT, the minimum is actually 96). -68 bytes is adequate for IP, ICMP, TCP -and UDP but may truncate protocol information from name server and NFS -packets (see below). +default of 65535 bytes. Packets truncated because of a limited snapshot are indicated in the output with ``[|\fIproto\fP]'', where \fIproto\fP is the name of the protocol level at which the truncation has occurred. @@ -429,7 +471,9 @@ lost. You should limit \fIsnaplen\fP to the smallest number that will capture the protocol information you're interested in. Setting -\fIsnaplen\fP to 0 means use the required length to catch whole packets. +\fIsnaplen\fP to 0 sets it to the default of 65535, +for backwards compatibility with recent older versions of +.IR tcpdump . .TP .B \-T Force packets selected by "\fIexpression\fP" to be interpreted the @@ -513,6 +557,9 @@ Write the raw packets to \fIfile\fR rather than parsing and printing them out. They can later be printed with the \-r option. Standard output is used if \fIfile\fR is ``-''. +See +.BR pcap-savefile (@MAN_FILE_FORMATS@) +for a description of the file format. .TP .B \-W Used in conjunction with the @@ -591,7 +638,10 @@ savefile name as the only argument, make the flags & arguments arrangements and execute the command that you want. .TP .B \-Z -Drops privileges (if root) and changes user ID to +If +.I tcpdump +is running as root, after opening the capture device or input savefile, +but before opening any savefiles for output, change the user ID to .I user and the group ID to the primary group of .IR user . @@ -606,7 +656,7 @@ Otherwise, only packets for which \fIexpression\fP is `true' will be dumped. .LP For the \fIexpression\fP syntax, see -.BR pcap-filter (4). +.BR pcap-filter (@MAN_MISC_INFO@). .LP Expression arguments can be passed to \fItcpdump\fP as either a single argument or as multiple arguments, whichever is more convenient. @@ -847,8 +897,8 @@ The general format of a tcp protocol line is: \fISrc\fP and \fIdst\fP are the source and destination IP addresses and ports. \fIFlags\fP are some combination of S (SYN), -F (FIN), P (PUSH), R (RST), W (ECN CWR) or E (ECN-Echo), or a single -`.' (no flags). +F (FIN), P (PUSH), R (RST), U (URG), W (ECN CWR), E (ECN-Echo) or +`.' (ACK), or `none' if no flags are set. \fIData-seqno\fP describes the portion of sequence space covered by the data in this packet (see example below). \fIAck\fP is sequence number of the next data expected the other @@ -895,8 +945,7 @@ bytes and there was a max-segment-size option requesting an mss of Csam replies with a similar packet except it includes a piggy-backed ack for rtsg's SYN. Rtsg then acks csam's SYN. -The `.' means no -flags were set. +The `.' means the ACK flag was set. The packet contained no data so there is no data sequence number. Note that the ack sequence number is a small integer (1). @@ -1123,6 +1172,18 @@ This points us to the \fItcpdump\fP filter expression tcpdump -i xl0 'tcp[13] & 2 == 2' .RE .PP +Some offsets and field values may be expressed as names +rather than as numeric values. For example tcp[13] may +be replaced with tcp[tcpflags]. The following TCP flag +field values are also available: tcp-fin, tcp-syn, tcp-rst, +tcp-push, tcp-act, tcp-urg. +.PP +This can be demonstrated as: +.RS +.B + tcpdump -i xl0 'tcp[tcpflags] & tcp-push != 0' +.RE +.PP Note that you should use single quotes or a backslash in the expression to hide the AND ('&') special character from the shell. @@ -1230,15 +1291,6 @@ RA, \fInot\fP set) and `|' (truncated message, TC, set). If the `question' section doesn't contain exactly one entry, `[\fIn\fPq]' is printed. -.LP -Note that name server requests and responses tend to be large and the -default \fIsnaplen\fP of 68 bytes may not capture enough of the packet -to print. -Use the \fB\-s\fP flag to increase the snaplen if you -need to seriously investigate name server traffic. -`\fB\-s 128\fP' -has worked well for me. - .HD SMB/CIFS decoding .LP @@ -1246,19 +1298,18 @@ SMB/CIFS decoding on UDP/137, UDP/138 and TCP/139. Some primitive decoding of IPX and NetBEUI SMB data is also done. - +.LP By default a fairly minimal decode is done, with a much more detailed decode done if -v is used. Be warned that with -v a single SMB packet may take up a page or more, so only use -v if you really want all the gory details. - -For information on SMB packet formats and what all te fields mean see +.LP +For information on SMB packet formats and what all the fields mean see www.cifs.org or the pub/samba/specs/ directory on your favorite samba.org mirror site. The SMB patches were written by Andrew Tridgell (tridge@samba.org). - .HD NFS Requests and Replies .LP @@ -1610,7 +1661,8 @@ is made to account for the time lag between when the Ethernet interface removed the packet from the wire and when the kernel serviced the `new packet' interrupt. .SH "SEE ALSO" -stty(1), pcap(3PCAP), pcap-filter(4), bpf(4), nit(4P) +stty(1), pcap(3PCAP), bpf(4), nit(4P), pcap-savefile(@MAN_FILE_FORMATS@), +pcap-filter(@MAN_MISC_INFO@), pcap-tstamp-type(@MAN_MISC_INFO@) .SH AUTHORS The original authors are: .LP diff --git a/contrib/tcpdump/tcpdump.c b/contrib/tcpdump/tcpdump.c index 4328b30490..ac35b2b349 100644 --- a/contrib/tcpdump/tcpdump.c +++ b/contrib/tcpdump/tcpdump.c @@ -30,7 +30,7 @@ static const char copyright[] _U_ = "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\ The Regents of the University of California. All rights reserved.\n"; static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.271.2.11 2008-09-25 21:50:04 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.283 2008-09-25 21:45:50 guy Exp $ (LBL)"; #endif /* @@ -90,9 +90,12 @@ extern int SIZE_BUF; netdissect_options Gndo; netdissect_options *gndo = &Gndo; -int dflag; /* print filter code */ -int Lflag; /* list available data link types and exit */ -char *zflag = NULL; /* compress each savefile using a specified command (like gzip or bzip2) */ +static int dflag; /* print filter code */ +static int Lflag; /* list available data link types and exit */ +#ifdef HAVE_PCAP_SET_TSTAMP_TYPE +static int Jflag; /* list available time stamp types */ +#endif +static char *zflag = NULL; /* compress each savefile using a specified command (like gzip or bzip2) */ static int infodelay; static int infoprint; @@ -105,14 +108,15 @@ int32_t thiszone; /* seconds offset from gmt to local time */ static RETSIGTYPE cleanup(int); static RETSIGTYPE child_cleanup(int); static void usage(void) __attribute__((noreturn)); -static void show_dlts_and_exit(pcap_t *pd) __attribute__((noreturn)); +static void show_dlts_and_exit(const char *device, pcap_t *pd) __attribute__((noreturn)); static void print_packet(u_char *, const struct pcap_pkthdr *, const u_char *); static void ndo_default_print(netdissect_options *, const u_char *, u_int); static void dump_packet_and_trunc(u_char *, const struct pcap_pkthdr *, const u_char *); static void dump_packet(u_char *, const struct pcap_pkthdr *, const u_char *); static void droproot(const char *, const char *); -static void ndo_error(netdissect_options *ndo, const char *fmt, ...); +static void ndo_error(netdissect_options *ndo, const char *fmt, ...) + __attribute__ ((noreturn, format (printf, 2, 3))); static void ndo_warning(netdissect_options *ndo, const char *fmt, ...); #ifdef SIGINFO @@ -130,19 +134,23 @@ RETSIGTYPE requestinfo(int); static void info(int); static u_int packets_captured; -typedef u_int (*if_printer)(const struct pcap_pkthdr *, const u_char *); - struct printer { - if_printer f; + if_printer f; int type; }; + +struct ndo_printer { + if_ndo_printer f; + int type; +}; + + static struct printer printers[] = { { arcnet_if_print, DLT_ARCNET }, #ifdef DLT_ARCNET_LINUX { arcnet_linux_if_print, DLT_ARCNET_LINUX }, #endif - { ether_if_print, DLT_EN10MB }, { token_if_print, DLT_IEEE802 }, #ifdef DLT_LANE8023 { lane_if_print, DLT_LANE8023 }, @@ -151,7 +159,7 @@ static struct printer printers[] = { { cip_if_print, DLT_CIP }, #endif #ifdef DLT_ATM_CLIP - { cip_if_print, DLT_ATM_CLIP }, + { cip_if_print, DLT_ATM_CLIP }, #endif { sl_if_print, DLT_SLIP }, #ifdef DLT_SLIP_BSDOS @@ -178,7 +186,7 @@ static struct printer printers[] = { { chdlc_if_print, DLT_HDLC }, #endif #ifdef DLT_PPP_SERIAL - { ppp_hdlc_if_print, DLT_PPP_SERIAL }, + { ppp_hdlc_if_print, DLT_PPP_SERIAL }, #endif #ifdef DLT_PPP_ETHER { pppoe_if_print, DLT_PPP_ETHER }, @@ -193,7 +201,7 @@ static struct printer printers[] = { { ltalk_if_print, DLT_LTALK }, #endif #if defined(DLT_PFLOG) && defined(HAVE_NET_PFVAR_H) - { pflog_if_print, DLT_PFLOG }, + { pflog_if_print, DLT_PFLOG }, #endif #ifdef DLT_FR { fr_if_print, DLT_FR }, @@ -214,10 +222,10 @@ static struct printer printers[] = { { ieee802_11_radio_if_print, DLT_IEEE802_11_RADIO }, #endif #ifdef DLT_ENC - { enc_if_print, DLT_ENC }, + { enc_if_print, DLT_ENC }, #endif #ifdef DLT_SYMANTEC_FIREWALL - { symantec_if_print, DLT_SYMANTEC_FIREWALL }, + { symantec_if_print, DLT_SYMANTEC_FIREWALL }, #endif #ifdef DLT_APPLE_IP_OVER_IEEE1394 { ap1394_if_print, DLT_APPLE_IP_OVER_IEEE1394 }, @@ -259,27 +267,64 @@ static struct printer printers[] = { { juniper_services_print, DLT_JUNIPER_SERVICES }, #endif #ifdef DLT_JUNIPER_ETHER - { juniper_ether_print, DLT_JUNIPER_ETHER }, + { juniper_ether_print, DLT_JUNIPER_ETHER }, #endif #ifdef DLT_JUNIPER_PPP - { juniper_ppp_print, DLT_JUNIPER_PPP }, + { juniper_ppp_print, DLT_JUNIPER_PPP }, #endif #ifdef DLT_JUNIPER_FRELAY - { juniper_frelay_print, DLT_JUNIPER_FRELAY }, + { juniper_frelay_print, DLT_JUNIPER_FRELAY }, #endif #ifdef DLT_JUNIPER_CHDLC - { juniper_chdlc_print, DLT_JUNIPER_CHDLC }, + { juniper_chdlc_print, DLT_JUNIPER_CHDLC }, #endif #ifdef DLT_MFR - { mfr_if_print, DLT_MFR }, + { mfr_if_print, DLT_MFR }, #endif #if defined(DLT_BLUETOOTH_HCI_H4_WITH_PHDR) && defined(HAVE_PCAP_BLUETOOTH_H) - { bt_if_print, DLT_BLUETOOTH_HCI_H4_WITH_PHDR}, + { bt_if_print, DLT_BLUETOOTH_HCI_H4_WITH_PHDR}, +#endif +#ifdef HAVE_PCAP_USB_H +#ifdef DLT_USB_LINUX + { usb_linux_48_byte_print, DLT_USB_LINUX}, +#endif /* DLT_USB_LINUX */ +#ifdef DLT_USB_LINUX_MMAPPED + { usb_linux_64_byte_print, DLT_USB_LINUX_MMAPPED}, +#endif /* DLT_USB_LINUX_MMAPPED */ +#endif /* HAVE_PCAP_USB_H */ +#ifdef DLT_IPV4 + { raw_if_print, DLT_IPV4 }, +#endif +#ifdef DLT_IPV6 + { raw_if_print, DLT_IPV6 }, +#endif + { NULL, 0 }, +}; + +static struct ndo_printer ndo_printers[] = { + { ether_if_print, DLT_EN10MB }, +#ifdef DLT_IPNET + { ipnet_if_print, DLT_IPNET }, +#endif +#ifdef DLT_IEEE802_15_4 + { ieee802_15_4_if_print, DLT_IEEE802_15_4 }, +#endif +#ifdef DLT_IEEE802_15_4_NOFCS + { ieee802_15_4_if_print, DLT_IEEE802_15_4_NOFCS }, +#endif +#ifdef DLT_PPI + { ppi_if_print, DLT_PPI }, +#endif +#ifdef DLT_NETANALYZER + { netanalyzer_if_print, DLT_NETANALYZER }, +#endif +#ifdef DLT_NETANALYZER_TRANSPARENT + { netanalyzer_transparent_if_print, DLT_NETANALYZER_TRANSPARENT }, #endif { NULL, 0 }, }; -static if_printer +if_printer lookup_printer(int type) { struct printer *p; @@ -292,14 +337,34 @@ lookup_printer(int type) /* NOTREACHED */ } +if_ndo_printer +lookup_ndo_printer(int type) +{ + struct ndo_printer *p; + + for (p = ndo_printers; p->f; ++p) + if (type == p->type) + return p->f; + + return NULL; + /* NOTREACHED */ +} + static pcap_t *pd; +static int supports_monitor_mode; + extern int optind; extern int opterr; extern char *optarg; struct print_info { - if_printer printer; + netdissect_options *ndo; + union { + if_printer printer; + if_ndo_printer ndo_printer; + } p; + int ndo_type; }; struct dump_info { @@ -309,8 +374,42 @@ struct dump_info { pcap_dumper_t *p; }; +#ifdef HAVE_PCAP_SET_TSTAMP_TYPE +static void +show_tstamp_types_and_exit(const char *device, pcap_t *pd) +{ + int n_tstamp_types; + int *tstamp_types = 0; + const char *tstamp_type_name; + int i; + + n_tstamp_types = pcap_list_tstamp_types(pd, &tstamp_types); + if (n_tstamp_types < 0) + error("%s", pcap_geterr(pd)); + + if (n_tstamp_types == 0) { + fprintf(stderr, "Time stamp type cannot be set for %s\n", + device); + exit(0); + } + fprintf(stderr, "Time stamp types for %s (use option -j to set):\n", + device); + for (i = 0; i < n_tstamp_types; i++) { + tstamp_type_name = pcap_tstamp_type_val_to_name(tstamp_types[i]); + if (tstamp_type_name != NULL) { + (void) fprintf(stderr, " %s (%s)\n", tstamp_type_name, + pcap_tstamp_type_val_to_description(tstamp_types[i])); + } else { + (void) fprintf(stderr, " %d\n", tstamp_types[i]); + } + } + pcap_free_tstamp_types(tstamp_types); + exit(0); +} +#endif + static void -show_dlts_and_exit(pcap_t *pd) +show_dlts_and_exit(const char *device, pcap_t *pd) { int n_dlts; int *dlts = 0; @@ -322,7 +421,21 @@ show_dlts_and_exit(pcap_t *pd) else if (n_dlts == 0 || !dlts) error("No data link types."); - (void) fprintf(stderr, "Data link types (use option -y to set):\n"); + /* + * If the interface is known to support monitor mode, indicate + * whether these are the data link types available when not in + * monitor mode, if -I wasn't specified, or when in monitor mode, + * when -I was specified (the link-layer types available in + * monitor mode might be different from the ones available when + * not in monitor mode). + */ + if (supports_monitor_mode) + (void) fprintf(stderr, "Data link types for %s %s (use option -y to set):\n", + device, + Iflag ? "when in monitor mode" : "when not in monitor mode"); + else + (void) fprintf(stderr, "Data link types for %s (use option -y to set):\n", + device); while (--n_dlts >= 0) { dlt_name = pcap_datalink_val_to_name(dlts[n_dlts]); @@ -333,15 +446,16 @@ show_dlts_and_exit(pcap_t *pd) /* * OK, does tcpdump handle that type? */ - if (lookup_printer(dlts[n_dlts]) == NULL) + if (lookup_printer(dlts[n_dlts]) == NULL + && lookup_ndo_printer(dlts[n_dlts]) == NULL) (void) fprintf(stderr, " (printing not supported)"); - putchar('\n'); + fprintf(stderr, "\n"); } else { (void) fprintf(stderr, " DLT %d (printing not supported)\n", dlts[n_dlts]); } } - free(dlts); + pcap_free_datalinks(dlts); exit(0); } @@ -363,6 +477,16 @@ show_dlts_and_exit(pcap_t *pd) #define I_FLAG #endif /* HAVE_PCAP_CREATE */ +#ifdef HAVE_PCAP_SET_TSTAMP_TYPE +#define j_FLAG "j:" +#define j_FLAG_USAGE " [ -j tstamptype ]" +#define J_FLAG "J" +#else /* PCAP_ERROR_TSTAMP_TYPE_NOTSUP */ +#define j_FLAG +#define j_FLAG_USAGE +#define J_FLAG +#endif /* PCAP_ERROR_TSTAMP_TYPE_NOTSUP */ + #ifdef HAVE_PCAP_FINDALLDEVS #ifndef HAVE_PCAP_IF_T #undef HAVE_PCAP_FINDALLDEVS @@ -507,6 +631,7 @@ main(int argc, char **argv) if(wsockinit() != 0) return 1; #endif /* WIN32 */ + jflag=-1; /* not set */ gndo->ndo_Oflag=1; gndo->ndo_Rflag=1; gndo->ndo_dlt=-1; @@ -533,9 +658,8 @@ main(int argc, char **argv) smiInit("tcpdump"); #endif - opterr = 0; while ( - (op = getopt(argc, argv, "aA" B_FLAG "c:C:d" D_FLAG "eE:fF:G:i:" I_FLAG "KlLm:M:nNOpqr:Rs:StT:u" U_FLAG "vw:W:xXy:Yz:Z:")) != -1) + (op = getopt(argc, argv, "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:G:hHi:" I_FLAG j_FLAG J_FLAG "KlLm:M:nNOpqr:Rs:StT:u" U_FLAG "vw:W:xXy:Yz:Z:")) != -1) switch (op) { case 'a': @@ -546,6 +670,10 @@ main(int argc, char **argv) ++Aflag; break; + case 'b': + ++bflag; + break; + #if defined(HAVE_PCAP_CREATE) || defined(WIN32) case 'B': Bflag = atoi(optarg)*1024; @@ -624,6 +752,14 @@ main(int argc, char **argv) } break; + case 'h': + usage(); + break; + + case 'H': + ++Hflag; + break; + case 'i': if (optarg[0] == '0' && optarg[1] == 0) error("Invalid adapter index"); @@ -646,11 +782,17 @@ main(int argc, char **argv) if (pcap_findalldevs(&devpointer, ebuf) < 0) error("%s", ebuf); else { - for (i = 0; i < devnum-1; i++){ - devpointer = devpointer->next; - if (devpointer == NULL) - error("Invalid adapter index"); - } + /* + * Look for the devnum-th entry + * in the list of devices + * (1-based). + */ + for (i = 0; + i < devnum-1 && devpointer != NULL; + i++, devpointer = devpointer->next) + ; + if (devpointer == NULL) + error("Invalid adapter index"); } device = devpointer->name; break; @@ -665,6 +807,18 @@ main(int argc, char **argv) break; #endif /* HAVE_PCAP_CREATE */ +#ifdef HAVE_PCAP_SET_TSTAMP_TYPE + case 'j': + jflag = pcap_tstamp_type_name_to_val(optarg); + if (jflag < 0) + error("invalid time stamp type %s", optarg); + break; + + case 'J': + Jflag++; + break; +#endif + case 'l': #ifdef WIN32 /* @@ -708,7 +862,7 @@ main(int argc, char **argv) #ifndef HAVE_LIBCRYPTO warning("crypto code not compiled in"); #endif - tcpmd5secret = optarg; + sigsecret = optarg; break; case 'n': @@ -745,10 +899,10 @@ main(int argc, char **argv) snaplen = strtol(optarg, &end, 0); if (optarg == end || *end != '\0' - || snaplen < 0 || snaplen > 65535) + || snaplen < 0 || snaplen > MAXIMUM_SNAPLEN) error("invalid snaplen %s", optarg); else if (snaplen == 0) - snaplen = 65535; + snaplen = MAXIMUM_SNAPLEN; break; } @@ -779,6 +933,8 @@ main(int argc, char **argv) packettype = PT_TFTP; else if (strcasecmp(optarg, "aodv") == 0) packettype = PT_AODV; + else if (strcasecmp(optarg, "carp") == 0) + packettype = PT_CARP; else error("unknown packet type `%s'", optarg); break; @@ -957,18 +1113,29 @@ main(int argc, char **argv) pd = pcap_create(device, ebuf); if (pd == NULL) error("%s", ebuf); +#ifdef HAVE_PCAP_SET_TSTAMP_TYPE + if (Jflag) + show_tstamp_types_and_exit(device, pd); +#endif + /* + * Is this an interface that supports monitor mode? + */ + if (pcap_can_set_rfmon(pd) == 1) + supports_monitor_mode = 1; + else + supports_monitor_mode = 0; status = pcap_set_snaplen(pd, snaplen); if (status != 0) - error("%s: pcap_set_snaplen failed: %s", + error("%s: Can't set snapshot length: %s", device, pcap_statustostr(status)); status = pcap_set_promisc(pd, !pflag); if (status != 0) - error("%s: pcap_set_promisc failed: %s", + error("%s: Can't set promiscuous mode: %s", device, pcap_statustostr(status)); if (Iflag) { status = pcap_set_rfmon(pd, 1); if (status != 0) - error("%s: pcap_set_rfmon failed: %s", + error("%s: Can't set monitor mode: %s", device, pcap_statustostr(status)); } status = pcap_set_timeout(pd, 1000); @@ -978,9 +1145,17 @@ main(int argc, char **argv) if (Bflag != 0) { status = pcap_set_buffer_size(pd, Bflag); if (status != 0) - error("%s: pcap_set_buffer_size failed: %s", + error("%s: Can't set buffer size: %s", device, pcap_statustostr(status)); } +#ifdef HAVE_PCAP_SET_TSTAMP_TYPE + if (jflag != -1) { + status = pcap_set_tstamp_type(pd, jflag); + if (status < 0) + error("%s: Can't set time stamp type: %s", + device, pcap_statustostr(status)); + } +#endif status = pcap_activate(pd); if (status < 0) { /* @@ -1035,7 +1210,7 @@ main(int argc, char **argv) } #endif /* !defined(HAVE_PCAP_CREATE) && defined(WIN32) */ if (Lflag) - show_dlts_and_exit(pd); + show_dlts_and_exit(device, pd); if (gndo->ndo_dlt >= 0) { #ifdef HAVE_PCAP_SET_DATALINK if (pcap_set_datalink(pd, gndo->ndo_dlt) < 0) @@ -1073,6 +1248,7 @@ main(int argc, char **argv) if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0) error("%s", pcap_geterr(pd)); + free(cmdbuf); if (dflag) { bpf_dump(&fcode, dflag); pcap_close(pd); @@ -1085,14 +1261,40 @@ main(int argc, char **argv) (void)setsignal(SIGPIPE, cleanup); (void)setsignal(SIGTERM, cleanup); (void)setsignal(SIGINT, cleanup); - (void)setsignal(SIGCHLD, child_cleanup); #endif /* WIN32 */ +#if defined(HAVE_FORK) || defined(HAVE_VFORK) + (void)setsignal(SIGCHLD, child_cleanup); +#endif /* Cooperate with nohup(1) */ #ifndef WIN32 if ((oldhandler = setsignal(SIGHUP, cleanup)) != SIG_DFL) (void)setsignal(SIGHUP, oldhandler); #endif /* WIN32 */ +#ifndef WIN32 + /* + * If a user name was specified with "-Z", attempt to switch to + * that user's UID. This would probably be used with sudo, + * to allow tcpdump to be run in a special restricted + * account (if you just want to allow users to open capture + * devices, and can't just give users that permission, + * you'd make tcpdump set-UID or set-GID). + * + * Tcpdump doesn't necessarily write only to one savefile; + * the general only way to allow a -Z instance to write to + * savefiles as the user under whose UID it's run, rather + * than as the user specified with -Z, would thus be to switch + * to the original user ID before opening a capture file and + * then switch back to the -Z user ID after opening the savefile. + * Switching to the -Z user ID only after opening the first + * savefile doesn't handle the general case. + */ + if (getuid() == 0 || geteuid() == 0) { + if (username || chroot_dir) + droproot(username, chroot_dir); + } +#endif /* WIN32 */ + if (pcap_setfilter(pd, &fcode) < 0) error("%s", pcap_geterr(pd)); if (WFileName) { @@ -1122,30 +1324,31 @@ main(int argc, char **argv) callback = dump_packet; pcap_userdata = (u_char *)p; } +#ifdef HAVE_PCAP_DUMP_FLUSH + if (Uflag) + pcap_dump_flush(p); +#endif } else { type = pcap_datalink(pd); - printinfo.printer = lookup_printer(type); - if (printinfo.printer == NULL) { - gndo->ndo_dltname = pcap_datalink_val_to_name(type); - if (gndo->ndo_dltname != NULL) - error("unsupported data link type %s", - gndo->ndo_dltname); - else - error("unsupported data link type %d", type); - } + printinfo.ndo_type = 1; + printinfo.ndo = gndo; + printinfo.p.ndo_printer = lookup_ndo_printer(type); + if (printinfo.p.ndo_printer == NULL) { + printinfo.p.printer = lookup_printer(type); + printinfo.ndo_type = 0; + if (printinfo.p.printer == NULL) { + gndo->ndo_dltname = pcap_datalink_val_to_name(type); + if (gndo->ndo_dltname != NULL) + error("packet printing is not supported for link type %s: use -w", + gndo->ndo_dltname); + else + error("packet printing is not supported for link type %d: use -w", type); + } + } callback = print_packet; pcap_userdata = (u_char *)&printinfo; } -#ifndef WIN32 - /* - * We cannot do this earlier, because we want to be able to open - * the file (if done) for writing before giving up permissions. - */ - if (getuid() == 0 || geteuid() == 0) { - if (username || chroot_dir) - droproot(username, chroot_dir); - } -#endif /* WIN32 */ + #ifdef SIGINFO /* * We can't get statistics when reading from a file rather @@ -1274,19 +1477,24 @@ cleanup(int signo _U_) On windows, we do not use a fork, so we do not care less about waiting a child processes to die */ -#ifndef WIN32 +#if defined(HAVE_FORK) || defined(HAVE_VFORK) static RETSIGTYPE child_cleanup(int signo _U_) { wait(NULL); } -#endif /* WIN32 */ +#endif /* HAVE_FORK && HAVE_VFORK */ static void info(register int verbose) { struct pcap_stat stat; + /* + * Older versions of libpcap didn't set ps_ifdrop on some + * platforms; initialize it to 0 to handle that. + */ + stat.ps_ifdrop = 0; if (pcap_stats(pd, &stat) < 0) { (void)fprintf(stderr, "pcap_stats: %s\n", pcap_geterr(pd)); infoprint = 0; @@ -1296,25 +1504,41 @@ info(register int verbose) if (!verbose) fprintf(stderr, "%s: ", program_name); - (void)fprintf(stderr, "%u packets captured", packets_captured); + (void)fprintf(stderr, "%u packet%s captured", packets_captured, + PLURAL_SUFFIX(packets_captured)); if (!verbose) fputs(", ", stderr); else putc('\n', stderr); - (void)fprintf(stderr, "%d packets received by filter", stat.ps_recv); + (void)fprintf(stderr, "%u packet%s received by filter", stat.ps_recv, + PLURAL_SUFFIX(stat.ps_recv)); if (!verbose) fputs(", ", stderr); else putc('\n', stderr); - (void)fprintf(stderr, "%d packets dropped by kernel\n", stat.ps_drop); + (void)fprintf(stderr, "%u packet%s dropped by kernel", stat.ps_drop, + PLURAL_SUFFIX(stat.ps_drop)); + if (stat.ps_ifdrop != 0) { + if (!verbose) + fputs(", ", stderr); + else + putc('\n', stderr); + (void)fprintf(stderr, "%u packet%s dropped by interface\n", + stat.ps_ifdrop, PLURAL_SUFFIX(stat.ps_ifdrop)); + } else + putc('\n', stderr); infoprint = 0; } -#ifndef WIN32 +#if defined(HAVE_FORK) || defined(HAVE_VFORK) static void compress_savefile(const char *filename) { +# ifdef HAVE_FORK if (fork()) +# else + if (vfork()) +# endif return; /* * Set to lowest priority so that this doesn't disturb the capture @@ -1324,21 +1548,26 @@ compress_savefile(const char *filename) #else setpriority(PRIO_PROCESS, 0, 19); #endif - if (execlp(zflag, zflag, filename, NULL) == -1) + if (execlp(zflag, zflag, filename, (char *)NULL) == -1) fprintf(stderr, "compress_savefile:execlp(%s, %s): %s\n", zflag, filename, strerror(errno)); +# ifdef HAVE_FORK + exit(1); +# else + _exit(1); +# endif } -#else /* WIN32 */ +#else /* HAVE_FORK && HAVE_VFORK */ static void compress_savefile(const char *filename) { fprintf(stderr, - "compress_savefile failed. Functionality not implemented under windows\n"); + "compress_savefile failed. Functionality not implemented under your system\n"); } -#endif /* WIN32 */ +#endif /* HAVE_FORK && HAVE_VFORK */ static void dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) @@ -1502,7 +1731,12 @@ print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) */ snapend = sp + h->caplen; - hdrlen = (*print_info->printer)(h, sp); + if(print_info->ndo_type) { + hdrlen = (*print_info->p.ndo_printer)(print_info->ndo, h, sp); + } else { + hdrlen = (*print_info->p.printer)(h, sp); + } + if (Xflag) { /* * Print the raw packet data in hex and ASCII. @@ -1672,17 +1906,17 @@ usage(void) #endif /* WIN32 */ #endif /* HAVE_PCAP_LIB_VERSION */ (void)fprintf(stderr, -"Usage: %s [-aAd" D_FLAG "ef" I_FLAG "KlLnNOpqRStu" U_FLAG "vxX]" B_FLAG_USAGE " [ -c count ]\n", program_name); +"Usage: %s [-aAbd" D_FLAG "efhH" I_FLAG J_FLAG "KlLnNOpqRStu" U_FLAG "vxX]" B_FLAG_USAGE " [ -c count ]\n", program_name); (void)fprintf(stderr, "\t\t[ -C file_size ] [ -E algo:secret ] [ -F file ] [ -G seconds ]\n"); (void)fprintf(stderr, -"\t\t[ -i interface ] [ -M secret ] [ -r file ]\n"); +"\t\t[ -i interface ]" j_FLAG_USAGE " [ -M secret ]\n"); (void)fprintf(stderr, -"\t\t[ -s snaplen ] [ -T type ] [ -w file ] [ -W filecount ]\n"); +"\t\t[ -r file ] [ -s snaplen ] [ -T type ] [ -w file ]\n"); (void)fprintf(stderr, -"\t\t[ -y datalinktype ] [ -z command ] [ -Z user ]\n"); +"\t\t[ -W filecount ] [ -y datalinktype ] [ -z command ]\n"); (void)fprintf(stderr, -"\t\t[ expression ]\n"); +"\t\t[ -Z user ] [ expression ]\n"); exit(1); } diff --git a/contrib/tcpdump/tftp.h b/contrib/tcpdump/tftp.h index 6285404fc7..6a092e0af5 100644 --- a/contrib/tcpdump/tftp.h +++ b/contrib/tcpdump/tftp.h @@ -1,4 +1,4 @@ -/* @(#) $Header: /tcpdump/master/tcpdump/tftp.h,v 1.1.4.1 2008-04-11 16:44:17 gianluca Exp $ (LBL) */ +/* @(#) $Header: /tcpdump/master/tcpdump/tftp.h,v 1.2 2008-04-11 16:47:38 gianluca Exp $ (LBL) */ /* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. diff --git a/contrib/tcpdump/timed.h b/contrib/tcpdump/timed.h index 15135e7372..f8d5a11368 100644 --- a/contrib/tcpdump/timed.h +++ b/contrib/tcpdump/timed.h @@ -1,4 +1,4 @@ -/* @(#) $Header: /tcpdump/master/tcpdump/timed.h,v 1.5.6.1 2008-02-05 19:46:58 guy Exp $ (LBL) */ +/* @(#) $Header: /tcpdump/master/tcpdump/timed.h,v 1.6 2008-02-05 19:46:19 guy Exp $ (LBL) */ /* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. diff --git a/contrib/tcpdump/token.h b/contrib/tcpdump/token.h index b1d92a3f1a..73a8271154 100644 --- a/contrib/tcpdump/token.h +++ b/contrib/tcpdump/token.h @@ -34,12 +34,12 @@ #define FRAME_TYPE(trp) (((trp)->token_fc & 0xC0) >> 6) #define TOKEN_FC_LLC 1 -#define BROADCAST(trp) ((ntohs((trp)->token_rcf) & 0xE000) >> 13) -#define RIF_LENGTH(trp) ((ntohs((trp)->token_rcf) & 0x1f00) >> 8) -#define DIRECTION(trp) ((ntohs((trp)->token_rcf) & 0x0080) >> 7) -#define LARGEST_FRAME(trp) ((ntohs((trp)->token_rcf) & 0x0070) >> 4) -#define RING_NUMBER(trp, x) ((ntohs((trp)->token_rseg[x]) & 0xfff0) >> 4) -#define BRIDGE_NUMBER(trp, x) ((ntohs((trp)->token_rseg[x]) & 0x000f)) +#define BROADCAST(trp) ((EXTRACT_16BITS(&(trp)->token_rcf) & 0xE000) >> 13) +#define RIF_LENGTH(trp) ((EXTRACT_16BITS(&(trp)->token_rcf) & 0x1f00) >> 8) +#define DIRECTION(trp) ((EXTRACT_16BITS(&(trp)->token_rcf) & 0x0080) >> 7) +#define LARGEST_FRAME(trp) ((EXTRACT_16BITS(&(trp)->token_rcf) & 0x0070) >> 4) +#define RING_NUMBER(trp, x) ((EXTRACT_16BITS(&(trp)->token_rseg[x]) & 0xfff0) >> 4) +#define BRIDGE_NUMBER(trp, x) ((EXTRACT_16BITS(&(trp)->token_rseg[x]) & 0x000f)) #define SEGMENT_COUNT(trp) ((int)((RIF_LENGTH(trp) - 2) / 2)) struct token_header { diff --git a/contrib/tcpdump/udp.h b/contrib/tcpdump/udp.h index fb45d68f7b..ad1d8506dd 100644 --- a/contrib/tcpdump/udp.h +++ b/contrib/tcpdump/udp.h @@ -90,4 +90,6 @@ struct udphdr { #define RIPNG_PORT 521 /*XXX*/ #define DHCP6_SERV_PORT 546 /*XXX*/ #define DHCP6_CLI_PORT 547 /*XXX*/ +#define BABEL_PORT 6696 +#define BABEL_PORT_OLD 6697 #endif diff --git a/contrib/tcpdump/util.c b/contrib/tcpdump/util.c index 6b723e543c..a2ef36d70b 100644 --- a/contrib/tcpdump/util.c +++ b/contrib/tcpdump/util.c @@ -328,7 +328,7 @@ bittok2str_internal(register const struct tok *lp, register const char *fmt, register int rotbit; /* this is the bit we rotate through all bitpositions */ register int tokval; - while (lp->s != NULL && lp != NULL) { + while (lp != NULL && lp->s != NULL) { tokval=lp->v; /* load our first value */ rotbit=1; while (rotbit != 0) { @@ -415,7 +415,7 @@ tok2strary_internal(register const char **lp, int n, register const char *fmt, */ int -mask2plen (u_int32_t mask) +mask2plen(u_int32_t mask) { u_int32_t bitmasks[33] = { 0x00000000, @@ -439,6 +439,35 @@ mask2plen (u_int32_t mask) return (prefix_len); } +#ifdef INET6 +int +mask62plen(const u_char *mask) +{ + u_char bitmasks[9] = { + 0x00, + 0x80, 0xc0, 0xe0, 0xf0, + 0xf8, 0xfc, 0xfe, 0xff + }; + int byte; + int cidr_len = 0; + + for (byte = 0; byte < 16; byte++) { + u_int bits; + + for (bits = 0; bits < (sizeof (bitmasks) / sizeof (bitmasks[0])); bits++) { + if (mask[byte] == bitmasks[bits]) { + cidr_len += bits; + break; + } + } + + if (mask[byte] != 0xff) + break; + } + return (cidr_len); +} +#endif /* INET6 */ + /* VARARGS */ void error(const char *fmt, ...) diff --git a/contrib/tcpdump/vfprintf.c b/contrib/tcpdump/vfprintf.c deleted file mode 100644 index 6f8407af69..0000000000 --- a/contrib/tcpdump/vfprintf.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 1995 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that: (1) source code distributions - * retain the above copyright notice and this paragraph in its entirety, (2) - * distributions including binary code include the above copyright notice and - * this paragraph in its entirety in the documentation or other materials - * provided with the distribution, and (3) all advertising materials mentioning - * features or use of this software display the following acknowledgement: - * ``This product includes software developed by the University of California, - * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of - * the University nor the names of its contributors may be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/vfprintf.c,v 1.6 2003-11-16 09:36:45 guy Exp $ (LBL)"; -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include -#include -#include -#include - -#include "interface.h" - -/* - * Stock 4.3 doesn't have vfprintf. - * This routine is due to Chris Torek. - */ -vfprintf(f, fmt, args) - FILE *f; - char *fmt; - va_list args; -{ - int ret; - - if ((f->_flag & _IOWRT) == 0) { - if (f->_flag & _IORW) - f->_flag |= _IOWRT; - else - return EOF; - } - ret = _doprnt(fmt, args, f); - return ferror(f) ? EOF : ret; -} -- 2.41.0