From ed775ee718148819f0ec9481195b31f346fbe774 Mon Sep 17 00:00:00 2001 From: Antonio Huete Jimenez Date: Sun, 20 Nov 2022 02:32:01 +0100 Subject: [PATCH] vendor/TCPDUMP: Import libpcap 4.99.1 Most significant changes: - CVE-2018-16301: For the -F option handle large input files safely. - Improve the contents, wording and formatting of the man page. - Print unsupported link-layer protocol packets in hex. - Add support for new network protocols and DLTs - BGP: Fix overwrites of global 'astostr' temporary buffer - ARP: fix overwrites of static buffer in q922_string(). See full change log in: https://git.tcpdump.org/tcpdump/blob/HEAD:/CHANGES --- contrib/tcpdump/CHANGES | 121 +- contrib/tcpdump/LICENSE | 6 +- contrib/tcpdump/README.DELETED | 29 - contrib/tcpdump/README.md | 99 +- contrib/tcpdump/VERSION | 2 +- contrib/tcpdump/addrtoname.c | 517 +- contrib/tcpdump/addrtoname.h | 81 +- contrib/tcpdump/addrtostr.c | 8 +- contrib/tcpdump/af.c | 4 +- contrib/tcpdump/af.h | 2 +- contrib/tcpdump/ah.h | 46 +- contrib/tcpdump/appletalk.h | 60 +- contrib/tcpdump/ascii_strcasecmp.c | 6 +- contrib/tcpdump/checksum.c | 10 +- contrib/tcpdump/compiler-tests.h | 151 + contrib/tcpdump/cpack.c | 103 +- contrib/tcpdump/cpack.h | 33 +- contrib/tcpdump/ethertype.h | 24 +- contrib/tcpdump/extract.h | 757 ++- contrib/tcpdump/{ether.h => fptype.c} | 35 +- contrib/tcpdump/{ether.h => fptype.h} | 25 +- contrib/tcpdump/ftmacros.h | 122 + contrib/tcpdump/funcattrs.h | 54 +- contrib/tcpdump/getservent.h | 67 + contrib/tcpdump/gmpls.c | 4 +- contrib/tcpdump/gmt2local.h | 25 - contrib/tcpdump/in_cksum.c | 12 +- contrib/tcpdump/interface.h | 18 +- contrib/tcpdump/ip.h | 6 +- contrib/tcpdump/ip6.h | 87 +- contrib/tcpdump/ipproto.c | 10 +- contrib/tcpdump/ipproto.h | 13 +- contrib/tcpdump/l2vpn.c | 8 +- contrib/tcpdump/machdep.c | 24 +- contrib/tcpdump/nameser.h | 159 +- contrib/tcpdump/netdissect-alloc.c | 62 + .../{print-ftp.c => netdissect-alloc.h} | 31 +- contrib/tcpdump/netdissect-ctype.h | 56 + contrib/tcpdump/netdissect-stdinc.h | 357 +- contrib/tcpdump/netdissect.c | 94 +- contrib/tcpdump/netdissect.h | 549 ++- contrib/tcpdump/nfs.h | 163 +- contrib/tcpdump/nfsfh.h | 2 +- contrib/tcpdump/nlpid.c | 4 +- contrib/tcpdump/ntp.c | 85 + contrib/tcpdump/{gmt2local.c => ntp.h} | 74 +- contrib/tcpdump/openflow.h | 51 +- contrib/tcpdump/ospf.h | 148 +- contrib/tcpdump/oui.c | 33 +- contrib/tcpdump/oui.h | 32 +- contrib/tcpdump/parsenfsfh.c | 162 +- contrib/tcpdump/ppp.h | 8 +- contrib/tcpdump/print-802_11.c | 1739 ++++--- contrib/tcpdump/print-802_15_4.c | 2583 +++++++++- contrib/tcpdump/print-ah.c | 57 +- contrib/tcpdump/print-ahcp.c | 277 +- contrib/tcpdump/print-aodv.c | 388 +- contrib/tcpdump/print-aoe.c | 257 +- contrib/tcpdump/print-ap1394.c | 46 +- contrib/tcpdump/print-arcnet.c | 162 +- contrib/tcpdump/print-arista.c | 92 + contrib/tcpdump/print-arp.c | 259 +- contrib/tcpdump/print-ascii.c | 124 +- contrib/tcpdump/print-atalk.c | 462 +- contrib/tcpdump/print-atm.c | 193 +- contrib/tcpdump/print-babel.c | 504 +- contrib/tcpdump/print-bcm-li.c | 130 + contrib/tcpdump/print-beep.c | 23 +- contrib/tcpdump/print-bfd.c | 215 +- contrib/tcpdump/print-bgp.c | 4330 +++++++++-------- contrib/tcpdump/print-bootp.c | 561 +-- contrib/tcpdump/print-brcmtag.c | 151 + contrib/tcpdump/print-bt.c | 44 +- contrib/tcpdump/print-calm-fast.c | 52 +- contrib/tcpdump/print-carp.c | 37 +- contrib/tcpdump/print-cdp.c | 596 ++- contrib/tcpdump/print-cfm.c | 310 +- contrib/tcpdump/print-chdlc.c | 94 +- contrib/tcpdump/print-cip.c | 47 +- contrib/tcpdump/print-cnfp.c | 456 +- contrib/tcpdump/print-dccp.c | 365 +- contrib/tcpdump/print-decnet.c | 680 ++- contrib/tcpdump/print-dhcp6.c | 373 +- contrib/tcpdump/print-domain.c | 873 +++- contrib/tcpdump/print-dsa.c | 219 + contrib/tcpdump/print-dtp.c | 86 +- contrib/tcpdump/print-dvmrp.c | 341 +- contrib/tcpdump/print-eap.c | 194 +- contrib/tcpdump/print-egp.c | 224 +- contrib/tcpdump/print-eigrp.c | 472 +- contrib/tcpdump/print-enc.c | 94 +- contrib/tcpdump/print-esp.c | 512 +- contrib/tcpdump/print-ether.c | 486 +- contrib/tcpdump/print-fddi.c | 93 +- contrib/tcpdump/print-forces.c | 737 ++- contrib/tcpdump/print-fr.c | 386 +- contrib/tcpdump/print-frag6.c | 38 +- contrib/tcpdump/print-ftp.c | 11 +- contrib/tcpdump/print-geneve.c | 81 +- contrib/tcpdump/print-geonet.c | 123 +- contrib/tcpdump/print-gre.c | 210 +- contrib/tcpdump/print-hncp.c | 331 +- contrib/tcpdump/print-hsrp.c | 88 +- contrib/tcpdump/print-http.c | 11 +- contrib/tcpdump/print-icmp.c | 452 +- contrib/tcpdump/print-icmp6.c | 1337 ++--- contrib/tcpdump/print-igmp.c | 232 +- contrib/tcpdump/print-igrp.c | 126 +- contrib/tcpdump/print-ip-demux.c | 231 + contrib/tcpdump/print-ip.c | 566 +-- contrib/tcpdump/print-ip6.c | 366 +- contrib/tcpdump/print-ip6opts.c | 188 +- contrib/tcpdump/print-ipcomp.c | 31 +- contrib/tcpdump/print-ipfc.c | 50 +- contrib/tcpdump/print-ipnet.c | 51 +- contrib/tcpdump/print-ipoib.c | 125 + contrib/tcpdump/print-ipx.c | 191 +- contrib/tcpdump/print-isakmp.c | 1421 +++--- contrib/tcpdump/print-isoclns.c | 2757 ++++++----- contrib/tcpdump/print-juniper.c | 711 +-- contrib/tcpdump/print-krb.c | 111 +- contrib/tcpdump/print-l2tp.c | 291 +- contrib/tcpdump/print-lane.c | 52 +- contrib/tcpdump/print-ldp.c | 304 +- contrib/tcpdump/print-lisp.c | 151 +- contrib/tcpdump/print-llc.c | 124 +- contrib/tcpdump/print-lldp.c | 641 +-- contrib/tcpdump/print-lmp.c | 601 ++- contrib/tcpdump/print-loopback.c | 81 +- contrib/tcpdump/print-lspping.c | 543 +-- contrib/tcpdump/print-lwapp.c | 172 +- contrib/tcpdump/print-lwres.c | 426 +- contrib/tcpdump/print-m3ua.c | 96 +- contrib/tcpdump/print-macsec.c | 256 + contrib/tcpdump/print-medsa.c | 196 - contrib/tcpdump/print-mobile.c | 35 +- contrib/tcpdump/print-mobility.c | 170 +- contrib/tcpdump/print-mpcp.c | 146 +- contrib/tcpdump/print-mpls.c | 108 +- contrib/tcpdump/print-mptcp.c | 277 +- contrib/tcpdump/print-msdp.c | 64 +- contrib/tcpdump/print-msnlb.c | 27 +- contrib/tcpdump/print-nflog.c | 177 +- contrib/tcpdump/print-nfs.c | 1419 +++--- contrib/tcpdump/print-nsh.c | 233 +- contrib/tcpdump/print-ntp.c | 467 +- contrib/tcpdump/print-null.c | 45 +- contrib/tcpdump/print-olsr.c | 285 +- contrib/tcpdump/print-openflow-1.0.c | 2478 +++++----- contrib/tcpdump/print-openflow-1.3.c | 1209 +++++ contrib/tcpdump/print-openflow.c | 214 +- contrib/tcpdump/print-ospf.c | 769 ++- contrib/tcpdump/print-ospf6.c | 517 +- contrib/tcpdump/print-otv.c | 36 +- contrib/tcpdump/print-pflog.c | 72 +- contrib/tcpdump/print-pgm.c | 543 +-- contrib/tcpdump/print-pim.c | 667 +-- contrib/tcpdump/print-pktap.c | 94 +- contrib/tcpdump/print-ppi.c | 108 +- contrib/tcpdump/print-ppp.c | 841 ++-- contrib/tcpdump/print-pppoe.c | 81 +- contrib/tcpdump/print-pptp.c | 729 ++- contrib/tcpdump/print-ptp.c | 620 +++ contrib/tcpdump/print-radius.c | 886 +++- contrib/tcpdump/print-raw.c | 12 +- contrib/tcpdump/print-resp.c | 104 +- contrib/tcpdump/print-rip.c | 425 +- contrib/tcpdump/print-ripng.c | 122 +- contrib/tcpdump/print-rpki-rtr.c | 147 +- contrib/tcpdump/print-rrcp.c | 81 +- contrib/tcpdump/print-rsvp.c | 1179 ++--- contrib/tcpdump/print-rt6.c | 96 +- contrib/tcpdump/print-rtsp.c | 11 +- contrib/tcpdump/print-rx.c | 1382 +++--- contrib/tcpdump/print-sctp.c | 382 +- contrib/tcpdump/print-sflow.c | 647 ++- contrib/tcpdump/print-sip.c | 8 +- contrib/tcpdump/print-sl.c | 161 +- contrib/tcpdump/print-sll.c | 311 +- contrib/tcpdump/print-slow.c | 363 +- contrib/tcpdump/print-smb.c | 759 ++- contrib/tcpdump/print-smtp.c | 11 +- contrib/tcpdump/print-snmp.c | 395 +- contrib/tcpdump/print-someip.c | 142 + contrib/tcpdump/print-ssh.c | 99 + contrib/tcpdump/print-stp.c | 347 +- contrib/tcpdump/print-sunatm.c | 26 +- contrib/tcpdump/print-sunrpc.c | 77 +- contrib/tcpdump/print-symantec.c | 52 +- contrib/tcpdump/print-syslog.c | 72 +- contrib/tcpdump/print-tcp.c | 501 +- contrib/tcpdump/print-telnet.c | 73 +- contrib/tcpdump/print-tftp.c | 71 +- contrib/tcpdump/print-timed.c | 111 +- contrib/tcpdump/print-tipc.c | 181 +- contrib/tcpdump/print-token.c | 94 +- contrib/tcpdump/print-udld.c | 115 +- contrib/tcpdump/print-udp.c | 547 ++- .../{print-smtp.c => print-unsupported.c} | 20 +- contrib/tcpdump/print-usb.c | 186 +- contrib/tcpdump/print-vjc.c | 34 +- contrib/tcpdump/print-vqp.c | 105 +- contrib/tcpdump/print-vrrp.c | 82 +- contrib/tcpdump/print-vsock.c | 262 + contrib/tcpdump/print-vtp.c | 181 +- contrib/tcpdump/print-vxlan-gpe.c | 67 +- contrib/tcpdump/print-vxlan.c | 41 +- contrib/tcpdump/print-wb.c | 365 +- contrib/tcpdump/print-zep.c | 178 + contrib/tcpdump/print-zephyr.c | 125 +- contrib/tcpdump/print-zeromq.c | 83 +- contrib/tcpdump/print.c | 409 +- contrib/tcpdump/print.h | 5 +- contrib/tcpdump/rpc_auth.h | 11 +- contrib/tcpdump/rpc_msg.h | 24 +- contrib/tcpdump/rpl.h | 174 - contrib/tcpdump/setsignal.c | 90 - contrib/tcpdump/setsignal.h | 25 - contrib/tcpdump/signature.c | 21 +- contrib/tcpdump/smb.h | 6 +- contrib/tcpdump/smbutil.c | 522 +- .../{print-ftp.c => status-exit-codes.h} | 32 +- contrib/tcpdump/strtoaddr.c | 20 +- contrib/tcpdump/tcp.h | 29 +- contrib/tcpdump/tcpdump.1.in | 317 +- contrib/tcpdump/tcpdump.c | 1203 +++-- contrib/tcpdump/timeval-operations.h | 23 +- contrib/tcpdump/udp.h | 118 +- contrib/tcpdump/util-print.c | 590 ++- contrib/tcpdump/{ether.h => varattrs.h} | 52 +- 230 files changed, 38460 insertions(+), 28097 deletions(-) delete mode 100644 contrib/tcpdump/README.DELETED create mode 100644 contrib/tcpdump/compiler-tests.h copy contrib/tcpdump/{ether.h => fptype.c} (76%) copy contrib/tcpdump/{ether.h => fptype.h} (76%) create mode 100644 contrib/tcpdump/ftmacros.h create mode 100644 contrib/tcpdump/getservent.h delete mode 100644 contrib/tcpdump/gmt2local.h create mode 100644 contrib/tcpdump/netdissect-alloc.c copy contrib/tcpdump/{print-ftp.c => netdissect-alloc.h} (59%) create mode 100644 contrib/tcpdump/netdissect-ctype.h create mode 100644 contrib/tcpdump/ntp.c rename contrib/tcpdump/{gmt2local.c => ntp.h} (51%) create mode 100644 contrib/tcpdump/print-arista.c create mode 100644 contrib/tcpdump/print-bcm-li.c create mode 100644 contrib/tcpdump/print-brcmtag.c create mode 100644 contrib/tcpdump/print-dsa.c create mode 100644 contrib/tcpdump/print-ip-demux.c create mode 100644 contrib/tcpdump/print-ipoib.c create mode 100644 contrib/tcpdump/print-macsec.c delete mode 100644 contrib/tcpdump/print-medsa.c create mode 100644 contrib/tcpdump/print-openflow-1.3.c create mode 100644 contrib/tcpdump/print-ptp.c create mode 100644 contrib/tcpdump/print-someip.c create mode 100644 contrib/tcpdump/print-ssh.c copy contrib/tcpdump/{print-smtp.c => print-unsupported.c} (63%) create mode 100644 contrib/tcpdump/print-vsock.c create mode 100644 contrib/tcpdump/print-zep.c delete mode 100644 contrib/tcpdump/rpl.h delete mode 100644 contrib/tcpdump/setsignal.c delete mode 100644 contrib/tcpdump/setsignal.h copy contrib/tcpdump/{print-ftp.c => status-exit-codes.h} (56%) rename contrib/tcpdump/{ether.h => varattrs.h} (61%) diff --git a/contrib/tcpdump/CHANGES b/contrib/tcpdump/CHANGES index f09be3446a..bdd7b8b01f 100644 --- a/contrib/tcpdump/CHANGES +++ b/contrib/tcpdump/CHANGES @@ -1,3 +1,105 @@ +Wednesday, June 9, 2021 by gharris + Summary for 4.99.1 tcpdump release: + Source code: + Squelch some compiler warnings + ICMP: Update the snapend for some nested IP packets. + MACsec: Update the snapend thus the ICV field is not payload + for the caller. + EIGRP: Fix packet header fields + SMB: Disable printer by default in CMake builds + OLSR: Print the protocol name even if the packet is invalid + MSDP: Print ": " before the protocol name + ESP: Remove padding, padding length and next header from the buffer + DHCPv6: Update the snapend for nested DHCPv6 packets + OpenFlow 1.0: Get snapend right for nested frames. + TCP: Update the snapend before decoding a MPTCP option + Ethernet, IEEE 802.15.4, IP, L2TP, TCP, ZEP: Add bounds checks + ForCES: Refine SPARSEDATA-TLV length check. + ASCII/hex: Use nd_trunc_longjmp() in truncation cases + GeoNet: Add a ND_TCHECK_LEN() call + Replace ND_TCHECK_/memcpy() pairs with GET_CPY_BYTES(). + BGP: Fix overwrites of global 'astostr' temporary buffer + ARP: fix overwrites of static buffer in q922_string(). + Frame Relay: have q922_string() handle errors better. + Building and testing: + Rebuild configure script when building release + Fix "make clean" for out-of-tree autotools builds + CMake: add stuff from CMAKE_PREFIX_PATH to PKG_CONFIG_PATH. + Documentation: + man: Update a reference as www.cifs.org is gone. [skip ci] + man: Update DNS sections + Solaris: + Fix a compile error with Sun C + +Wednesday, December 30, 2020, by mcr@sandelman.ca, denis and fxl. + Summary for 4.99.0 tcpdump release + Improve the contents, wording and formatting of the man page. + Print unsupported link-layer protocol packets in hex. + Add support for new network protocols and DLTs: Arista, Autosar SOME/IP, + Broadcom LI and Ethernet switches tag, IEEE 802.15.9, IP-over-InfiniBand + (IPoIB), Linux SLL2, Linux vsockmon, MACsec, Marvell Distributed Switch + Architecture, OpenFlow 1.3, Precision Time Protocol (PTP), SSH, WHOIS, + ZigBee Encapsulation Protocol (ZEP). + Make protocol-specific updates for: AH, DHCP, DNS, ESP, FRF.16, HNCP, + ICMP6, IEEE 802.15.4, IPv6, IS-IS, Linux SLL, LLDP, LSP ping, MPTCP, NFS, + NSH, NTP, OSPF, OSPF6, PGM, PIM, PPTP, RADIUS, RSVP, Rx, SMB, UDLD, + VXLAN-GPE. + User interface: + Make SLL2 the default for Linux "any" pseudo-device. + Add --micro and --nano shorthands. + Add --count to print a counter only instead of decoding. + Add --print, to cause packet printing even with -w. + Add support for remote capture if libpcap supports it. + Display the "wireless" flag and connection status. + Flush the output packet buffer on a SIGUSR2. + Add the snapshot length to the "reading from file ..." message. + Fix local time printing (DST offset in timestamps). + Allow -C arguments > 2^31-1 GB if they can fit into a long. + Handle very large -f files by rejecting them. + Report periodic stats only when safe to do so. + Print the number of packets captured only as often as necessary. + With no -s, or with -s 0, don't specify the snapshot length with newer + versions of libpcap. + Improve version and usage message printing. + Building and testing: + Install into bindir, not sbindir. + autoconf: replace --with-system-libpcap with --disable-local-libpcap. + Require the compiler to support C99. + Better detect and use various C compilers and their features. + Add CMake as the second build system. + Make out-of-tree builds more reliable. + Use pkg-config to detect libpcap if available. + Improve Windows support. + Add more tests and improve the scripts that run them. + Test both with "normal" and "x87" floating-point. + Eliminate dependency on libdnet. + FreeBSD: + Print a proper error message about monitor mode VAP. + Use libcasper if available. + Fix failure to capture on RDMA device. + Include the correct capsicum header. + Source code: + Start the transition to longjmp() for packet truncation handling. + Introduce new helper functions, including GET_*(), nd_print_protocol(), + nd_print_invalid(), nd_print_trunc(), nd_trunc_longjmp() and others. + Put integer signedness right in many cases. + Introduce nd_uint*, nd_mac_addr, nd_ipv4 and nd_ipv6 types to fix + alignment issues, especially on SPARC. + Fix many C compiler, Coverity, UBSan and cppcheck warnings. + Fix issues detected with AddressSanitizer. + Remove many workarounds for older compilers and OSes. + Add a sanity check on packet header length. + Add and remove plenty of bounds checks. + Clean up pcap_findalldevs() call to find the first interface. + Use a short timeout, rather than immediate mode, for text output. + Handle DLT_ENC files *not* written on the same OS and byte-order host. + Add, and use, macros to do locale-independent case mapping. + Use a table instead of getprotobynumber(). + Get rid of ND_UNALIGNED and ND_TCHECK(). + Make roundup2() generally available. + Resync SMI list against Wireshark. + Fix many typos. + Friday, September 20, 2019, by mcr@sandelman.ca A huge thank you to Denis, Francois-Xavier and Guy who did much of the heavy lifting. Summary for 4.9.3 tcpdump release @@ -66,8 +168,6 @@ Sunday September 3, 2017 denis@ovsienko.info CVE-2017-12991 (BGP) CVE-2017-12992 (RIPng) CVE-2017-12993 (Juniper) - CVE-2017-11542 (PIMv1) - CVE-2017-11541 (safeputs) CVE-2017-12994 (BGP) CVE-2017-12996 (PIMv2) CVE-2017-12998 (ISO IS-IS) @@ -393,7 +493,7 @@ Wednesday Jul. 2, 2014 mcr@sandelman.ca a number of unaligned access faults fixed -A flag does not consider CR to be printable anymore fx.lebail took over coverity baby sitting - default snapshot size increased to 256K for accomodate USB captures + default snapshot size increased to 256K for accommodate USB captures WARNING: this release contains a lot of very worthwhile code churn. Wednesday Jan. 15, 2014 guy@alum.mit.edu @@ -533,7 +633,7 @@ 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 + Fix TCP flags output description, and some typos, in the man page Add a -h flag, and only attempt to recognize 802.11s mesh headers if it's set @@ -628,7 +728,7 @@ Wed. July 23, 2007. mcr@xelerance.com. Summary for 3.9.7 libpcap release NFS: from NetBSD; don't interpret the reply as a possible NFS reply if it got MSG_DENIED. BGP: don't print TLV values that didn't fit, from www.digit-labs.org. - revised INSTALL.txt about libpcap dependancy. + revised INSTALL.txt about libpcap dependency. Wed. April 25, 2007. ken@xelerance.com. Summary for 3.9.6 tcpdump release Update man page to reflect changes to libpcap @@ -648,7 +748,7 @@ Wed. April 25, 2007. ken@xelerance.com. Summary for 3.9.6 tcpdump release Add support for CFM Link-trace msg, Link-trace-Reply msg, Sender-ID tlv, private tlv, port, interface status Add support for unidirectional link detection as per - http://www.ietf.org/internet-drafts/draft-foschiano-udld-02.txt + https://tools.ietf.org/id/draft-foschiano-udld-02.txt Add support for the olsr protocol as per RFC 3626 plus the LQ extensions from olsr.org Add support for variable-length checksum in DCCP, as per section 9 of @@ -753,7 +853,7 @@ Tue. March 30, 2004. mcr@sandelman.ottawa.on.ca. Summary for 3.8.3 release Mon. March 29, 2004. mcr@sandelman.ottawa.on.ca. Summary for 3.8.2 release Fixes for print-isakmp.c CVE: CAN-2004-0183, CAN-2004-0184 - http://www.rapid7.com/advisories/R7-0017.html + https://web.archive.org/web/20160328035955/https://www.rapid7.com/resources/advisories/R7-0017.jsp IP-over-IEEE1394 printing. some MINGW32 changes. updates for autoconf 2.5 @@ -826,7 +926,6 @@ Tuesday, February 25, 2003. fenner@research.att.com. 3.7.2 release 2.100.3 to be misrepresented as 4.20.3 . Monday, January 21, 2002. mcr@sandelman.ottawa.on.ca. Summary for 3.7 release -see http://www.tcpdump.org/cvs-log/2002-01-21.10:16:48.html for commit log. keyword "ipx" added. Better OSI/802.2 support on Linux. IEEE 802.11 support, from clenahan@fortresstech.com, achirica@ttd.net. @@ -894,7 +993,7 @@ Tuesday January 9, 2001. mcr@sandelman.ottawa.on.ca. Summary for 3.6 release libpcap changes provide for exchanging capture files between systems. Save files now have well known PACKET_ values instead of - depending upon system dependant mappings of DLT_* types. + depending upon system dependent mappings of DLT_* types. Support for computing/checking IP and UDP/TCP checksums. @@ -1205,7 +1304,7 @@ v3.1 Thu Jun 13 20:59:32 PDT 1996 - Print out a little more information for sun rpc packets. -- Add suport for Kerberos 4 thanks to John Hawkinson (jhawk@mit.edu). +- Add support for Kerberos 4 thanks to John Hawkinson (jhawk@mit.edu). - Fixed the Fix EXTRACT_SHORT() and EXTRACT_LONG() macros (which were wrong on little endian machines). @@ -1370,7 +1469,7 @@ v2.2 Fri May 22 17:19:41 PDT 1992 v2.1 Tue Jan 28 11:00:14 PST 1992 -- Internal release (never publically exported). +- Internal release (never publicly exported). v2.0.1 Sun Jan 26 21:10:10 PDT diff --git a/contrib/tcpdump/LICENSE b/contrib/tcpdump/LICENSE index dea5f7d54d..a10474d54a 100644 --- a/contrib/tcpdump/LICENSE +++ b/contrib/tcpdump/LICENSE @@ -1,9 +1,9 @@ License: BSD - + 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 @@ -13,7 +13,7 @@ are met: 3. The names of the authors 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. diff --git a/contrib/tcpdump/README.DELETED b/contrib/tcpdump/README.DELETED deleted file mode 100644 index cb75e4cf01..0000000000 --- a/contrib/tcpdump/README.DELETED +++ /dev/null @@ -1,29 +0,0 @@ -CONTRIBUTING -CREDITS -INSTALL.txt -Makefile-devel-adds -Makefile.in -PLATFORMS -README -Readme.Win32 -aclocal.m4 -atime.awk -bpf_dump.c -config.guess -config.h.in -config.sub -configure -configure.ac -getopt_long.h -install-sh -lbl/ -makemib -missing/ -mkdep -packetdat.awk -pcap_dump_ftell.c -send-ack.awk -stime.awk -tests/ -vfprintf.c -win32/ diff --git a/contrib/tcpdump/README.md b/contrib/tcpdump/README.md index a1fba9bca6..48445ae4c1 100644 --- a/contrib/tcpdump/README.md +++ b/contrib/tcpdump/README.md @@ -1,79 +1,78 @@ -# tcpdump +# TCPDUMP 4.x.y by [The Tcpdump Group](https://www.tcpdump.org/) -[![Build -Status](https://travis-ci.org/the-tcpdump-group/tcpdump.png)](https://travis-ci.org/the-tcpdump-group/tcpdump) - -To report a security issue please send an e-mail to security@tcpdump.org. +**To report a security issue please send an e-mail to security@tcpdump.org.** To report bugs and other problems, contribute patches, request a -feature, provide generic feedback etc please see the file -CONTRIBUTING in the tcpdump source tree root. - -TCPDUMP 4.x.y -Now maintained by "The Tcpdump Group" -See www.tcpdump.org - -Anonymous Git is available via: +feature, provide generic feedback etc please see the +[guidelines for contributing](CONTRIBUTING) in the tcpdump source tree root. - git clone git://bpf.tcpdump.org/tcpdump +Anonymous Git is available via -formerly from Lawrence Berkeley National Laboratory - Network Research Group - ftp://ftp.ee.lbl.gov/old/tcpdump.tar.Z (3.4) + https://github.com/the-tcpdump-group/tcpdump.git This directory contains source code for tcpdump, a tool for network -monitoring and data acquisition. This software was originally -developed by the Network Research Group at the Lawrence Berkeley -National Laboratory. The original distribution is available via -anonymous ftp to `ftp.ee.lbl.gov`, in `tcpdump.tar.Z`. More recent -development is performed at tcpdump.org, http://www.tcpdump.org/ +monitoring and data acquisition. +Over the past few years, tcpdump has been steadily improved by the +excellent contributions from the Internet community (just browse +through the [change log](CHANGES)). We are grateful for all the input. + +### Supported platforms +In many operating systems tcpdump is available as a native package or port, +which simplifies installation of updates and long-term maintenance. However, +the native packages are sometimes a few versions behind and to try a more +recent snapshot it will take to compile tcpdump from the source code. + +tcpdump compiles and works on at least the following platforms: + +* AIX +* DragonFly BSD +* FreeBSD +* Haiku +* HP-UX 11i +* GNU/Linux +* {Mac} OS X / macOS +* NetBSD +* OpenBSD +* OpenWrt +* Solaris +* Windows (requires WinPcap or Npcap, and Visual Studio with CMake) + +### Dependency on libpcap Tcpdump uses libpcap, a system-independent interface for user-level packet capture. Before building tcpdump, you must first retrieve and -build libpcap, also originally from LBL and now being maintained by -tcpdump.org; see http://www.tcpdump.org/ . +build libpcap. Once libpcap is built (either install it or make sure it's in -`../libpcap`), you can build tcpdump using the procedure in the `INSTALL.txt` -file. +`../libpcap`), you can build tcpdump using the procedure in the +[installation guide](INSTALL.txt). +### Origins of tcpdump The program is loosely based on SMI's "etherfind" although none of the etherfind code remains. It was originally written by Van Jacobson as -part of an ongoing research project to investigate and improve tcp and -internet gateway performance. The parts of the program originally +part of an ongoing research project to investigate and improve TCP and +Internet gateway performance. The parts of the program originally taken from Sun's etherfind were later re-written by Steven McCanne of LBL. To insure that there would be no vestige of proprietary code in tcpdump, Steve wrote these pieces from the specification given by the manual entry, with no access to the source of tcpdump or etherfind. +```text +formerly from Lawrence Berkeley National Laboratory + Network Research Group + ftp://ftp.ee.lbl.gov/old/tcpdump.tar.Z (3.4) +``` -Over the past few years, tcpdump has been steadily improved by the -excellent contributions from the Internet community (just browse -through the `CHANGES` file). We are grateful for all the input. - +### See also Richard Stevens gives an excellent treatment of the Internet protocols in his book *"TCP/IP Illustrated, Volume 1"*. If you want to learn more about tcpdump and how to interpret its output, pick up this book. -Some tools for viewing and analyzing tcpdump trace files are available -from the Internet Traffic Archive: - -* http://www.sigcomm.org/ITA/ - -Another tool that tcpdump users might find useful is tcpslice: - -* https://github.com/the-tcpdump-group/tcpslice - +Another tool that tcpdump users might find useful is +[tcpslice](https://github.com/the-tcpdump-group/tcpslice). It is a program that can be used to extract portions of tcpdump binary -trace files. See the above distribution for further details and -documentation. - -Current versions can be found at www.tcpdump.org. - - - The TCPdump team - -original text by: Steve McCanne, Craig Leres, Van Jacobson +trace files. -------------------------------------- +### The original LBL README by Steve McCanne, Craig Leres and Van Jacobson ``` This directory also contains some short awk programs intended as examples of ways to reduce tcpdump data when you're tracking diff --git a/contrib/tcpdump/VERSION b/contrib/tcpdump/VERSION index c01c413359..6cda52163b 100644 --- a/contrib/tcpdump/VERSION +++ b/contrib/tcpdump/VERSION @@ -1 +1 @@ -4.9.3 +4.99.1 diff --git a/contrib/tcpdump/addrtoname.c b/contrib/tcpdump/addrtoname.c index 15e57411f5..58ced4f9b5 100644 --- a/contrib/tcpdump/addrtoname.c +++ b/contrib/tcpdump/addrtoname.c @@ -23,35 +23,86 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#ifdef HAVE_CASPER +#include +#include +#endif /* HAVE_CASPER */ -#ifdef USE_ETHER_NTOHOST -#ifdef HAVE_NETINET_IF_ETHER_H -struct mbuf; /* Squelch compiler warnings on some platforms for */ -struct rtentry; /* declarations in */ -#include /* for "struct ifnet" in "struct arpcom" on Solaris */ -#include -#endif /* HAVE_NETINET_IF_ETHER_H */ -#ifdef NETINET_ETHER_H_DECLARES_ETHER_NTOHOST -#include -#endif /* NETINET_ETHER_H_DECLARES_ETHER_NTOHOST */ - -#if !defined(HAVE_DECL_ETHER_NTOHOST) || !HAVE_DECL_ETHER_NTOHOST -#ifndef HAVE_STRUCT_ETHER_ADDR -struct ether_addr { - unsigned char ether_addr_octet[6]; -}; -#endif -extern int ether_ntohost(char *, const struct ether_addr *); -#endif +#include "netdissect-stdinc.h" -#endif /* USE_ETHER_NTOHOST */ +#ifdef _WIN32 + /* + * We have our own ether_ntohost(), reading from the system's + * Ethernet address file. + */ + #include "missing/win_ether_ntohost.h" +#else + #ifdef USE_ETHER_NTOHOST + #if defined(NET_ETHERNET_H_DECLARES_ETHER_NTOHOST) + /* + * OK, just include . + */ + #include + #elif defined(NETINET_ETHER_H_DECLARES_ETHER_NTOHOST) + /* + * OK, just include + */ + #include + #elif defined(SYS_ETHERNET_H_DECLARES_ETHER_NTOHOST) + /* + * OK, just include + */ + #include + #elif defined(ARPA_INET_H_DECLARES_ETHER_NTOHOST) + /* + * OK, just include + */ + #include + #elif defined(NETINET_IF_ETHER_H_DECLARES_ETHER_NTOHOST) + /* + * OK, include , after all the other stuff we + * need to include or define for its benefit. + */ + #define NEED_NETINET_IF_ETHER_H + #else + /* + * We'll have to declare it ourselves. + * If defines struct ether_addr, include + * it. Otherwise, define it ourselves. + */ + #ifdef HAVE_STRUCT_ETHER_ADDR + #define NEED_NETINET_IF_ETHER_H + #else /* HAVE_STRUCT_ETHER_ADDR */ + struct ether_addr { + /* Beware FreeBSD calls this "octet". */ + unsigned char ether_addr_octet[MAC_ADDR_LEN]; + }; + #endif /* HAVE_STRUCT_ETHER_ADDR */ + #endif /* what declares ether_ntohost() */ + + #ifdef NEED_NETINET_IF_ETHER_H + #include /* Needed on some platforms */ + #include /* Needed on some platforms */ + #include + #endif /* NEED_NETINET_IF_ETHER_H */ + + #ifndef HAVE_DECL_ETHER_NTOHOST + /* + * No header declares it, so declare it ourselves. + */ + extern int ether_ntohost(char *, const struct ether_addr *); + #endif /* !defined(HAVE_DECL_ETHER_NTOHOST) */ + #endif /* USE_ETHER_NTOHOST */ +#endif /* _WIN32 */ #include #include +#ifndef HAVE_GETSERVENT +#include +#endif #include #include #include @@ -62,18 +113,13 @@ extern int ether_ntohost(char *, const struct ether_addr *); #include "addrtostr.h" #include "ethertype.h" #include "llc.h" -#include "setsignal.h" #include "extract.h" #include "oui.h" -#ifndef ETHER_ADDR_LEN -#define ETHER_ADDR_LEN 6 -#endif - /* * hash tables for whatever-to-name translations * - * ndo_error() called on strdup(3) failure + * ndo_error() called on strdup(3) failure with S_ERR_ND_MEM_ALLOC status */ #define HASHNAMESIZE 4096 @@ -132,7 +178,7 @@ win32_gethostbyaddr(const char *addr, int len, int type) #endif /* _WIN32 */ struct h6namemem { - struct in6_addr addr; + nd_ipv6 addr; char *name; struct h6namemem *nxt; }; @@ -178,25 +224,25 @@ static struct protoidmem protoidtable[HASHNAMESIZE]; const char * intoa(uint32_t addr) { - register char *cp; - register u_int byte; - register int n; + char *cp; + u_int byte; + int n; static char buf[sizeof(".xxx.xxx.xxx.xxx")]; - NTOHL(addr); + addr = ntohl(addr); cp = buf + sizeof(buf); *--cp = '\0'; n = 4; do { byte = addr & 0xff; - *--cp = byte % 10 + '0'; + *--cp = (char)(byte % 10) + '0'; byte /= 10; if (byte > 0) { - *--cp = byte % 10 + '0'; + *--cp = (char)(byte % 10) + '0'; byte /= 10; if (byte > 0) - *--cp = byte + '0'; + *--cp = (char)byte + '0'; } *--cp = '.'; addr >>= 8; @@ -207,14 +253,16 @@ intoa(uint32_t addr) static uint32_t f_netmask; static uint32_t f_localnet; +#ifdef HAVE_CASPER +extern cap_channel_t *capdns; +#endif /* * Return a name for the IP address pointed to by ap. This address * is assumed to be in network byte order. * - * NOTE: ap is *NOT* necessarily part of the packet data (not even if - * this is being called with the "ipaddr_string()" macro), so you - * *CANNOT* use the ND_TCHECK{2}/ND_TTEST{2} macros on it. Furthermore, + * NOTE: ap is *NOT* necessarily part of the packet data, so you + * *CANNOT* use the ND_TCHECK_* or ND_TTEST_* macros on it. Furthermore, * even in cases where it *is* part of the packet data, the caller * would still have to check for a null return value, even if it's * just printing the return value with "%s" - not all versions of @@ -228,9 +276,9 @@ static uint32_t f_localnet; * also needs to check whether they're present in the packet buffer. */ const char * -getname(netdissect_options *ndo, const u_char *ap) +ipaddr_string(netdissect_options *ndo, const u_char *ap) { - register struct hostent *hp; + struct hostent *hp; uint32_t addr; struct hnamemem *p; @@ -252,14 +300,20 @@ getname(netdissect_options *ndo, const u_char *ap) */ if (!ndo->ndo_nflag && (addr & f_netmask) == f_localnet) { - hp = gethostbyaddr((char *)&addr, 4, AF_INET); +#ifdef HAVE_CASPER + if (capdns != NULL) { + hp = cap_gethostbyaddr(capdns, (char *)&addr, 4, + AF_INET); + } else +#endif + hp = gethostbyaddr((char *)&addr, 4, AF_INET); if (hp) { char *dotp; p->name = strdup(hp->h_name); if (p->name == NULL) - (*ndo->ndo_error)(ndo, - "getname: strdup(hp->h_name)"); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, + "%s: strdup(hp->h_name)", __func__); if (ndo->ndo_Nflag) { /* Remove domain qualifications */ dotp = strchr(p->name, '.'); @@ -271,7 +325,8 @@ getname(netdissect_options *ndo, const u_char *ap) } p->name = strdup(intoa(addr)); if (p->name == NULL) - (*ndo->ndo_error)(ndo, "getname: strdup(intoa(addr))"); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, + "%s: strdup(intoa(addr))", __func__); return (p->name); } @@ -280,18 +335,18 @@ getname(netdissect_options *ndo, const u_char *ap) * is assumed to be in network byte order. */ const char * -getname6(netdissect_options *ndo, const u_char *ap) +ip6addr_string(netdissect_options *ndo, const u_char *ap) { - register struct hostent *hp; + struct hostent *hp; union { - struct in6_addr addr; + nd_ipv6 addr; struct for_hash_addr { char fill[14]; uint16_t d; } addra; } addr; struct h6namemem *p; - register const char *cp; + const char *cp; char ntop_buf[INET6_ADDRSTRLEN]; memcpy(&addr, ap, sizeof(addr)); @@ -300,21 +355,28 @@ getname6(netdissect_options *ndo, const u_char *ap) if (memcmp(&p->addr, &addr, sizeof(addr)) == 0) return (p->name); } - p->addr = addr.addr; + memcpy(p->addr, addr.addr, sizeof(nd_ipv6)); p->nxt = newh6namemem(ndo); /* * Do not print names if -n was given. */ if (!ndo->ndo_nflag) { - hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET6); +#ifdef HAVE_CASPER + if (capdns != NULL) { + hp = cap_gethostbyaddr(capdns, (char *)&addr, + sizeof(addr), AF_INET6); + } else +#endif + hp = gethostbyaddr((char *)&addr, sizeof(addr), + AF_INET6); if (hp) { char *dotp; p->name = strdup(hp->h_name); if (p->name == NULL) - (*ndo->ndo_error)(ndo, - "getname6: strdup(hp->h_name)"); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, + "%s: strdup(hp->h_name)", __func__); if (ndo->ndo_Nflag) { /* Remove domain qualifications */ dotp = strchr(p->name, '.'); @@ -327,19 +389,54 @@ getname6(netdissect_options *ndo, const u_char *ap) cp = addrtostr6(ap, ntop_buf, sizeof(ntop_buf)); p->name = strdup(cp); if (p->name == NULL) - (*ndo->ndo_error)(ndo, "getname6: strdup(cp)"); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, + "%s: strdup(cp)", __func__); return (p->name); } -static const char hex[16] = "0123456789abcdef"; +static const char hex[16] = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' +}; +/* + * Convert an octet to two hex digits. + * + * Coverity appears either: + * + * not to believe the C standard when it asserts that a uint8_t is + * exactly 8 bits in size; + * + * not to believe that an unsigned type of exactly 8 bits has a value + * in the range of 0 to 255; + * + * not to believe that, for a range of unsigned values, if you shift + * one of those values right by 4 bits, the maximum result value is + * the maximum value shifted right by 4 bits, with no stray 1's shifted + * in; + * + * not to believe that 255 >> 4 is 15; + * + * so it gets upset that we're taking a "tainted" unsigned value, shifting + * it right 4 bits, and using it as an index into a 16-element array. + * + * So we do a stupid pointless masking of the result of the shift with + * 0xf, to hammer the point home to Coverity. + */ +static inline char * +octet_to_hex(char *cp, uint8_t octet) +{ + *cp++ = hex[(octet >> 4) & 0xf]; + *cp++ = hex[(octet >> 0) & 0xf]; + return (cp); +} /* Find the hash node that corresponds the ether address 'ep' */ -static inline struct enamemem * +static struct enamemem * lookup_emem(netdissect_options *ndo, const u_char *ep) { - register u_int i, j, k; + u_int i, j, k; struct enamemem *tp; k = (ep[0] << 8) | ep[1]; @@ -354,12 +451,12 @@ lookup_emem(netdissect_options *ndo, const u_char *ep) return tp; else tp = tp->e_nxt; - tp->e_addr0 = i; - tp->e_addr1 = j; - tp->e_addr2 = k; + tp->e_addr0 = (u_short)i; + tp->e_addr1 = (u_short)j; + tp->e_addr2 = (u_short)k; tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp)); if (tp->e_nxt == NULL) - (*ndo->ndo_error)(ndo, "lookup_emem: calloc"); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, "%s: calloc", __func__); return tp; } @@ -369,12 +466,12 @@ lookup_emem(netdissect_options *ndo, const u_char *ep) * with length 'nlen' */ -static inline struct bsnamemem * -lookup_bytestring(netdissect_options *ndo, register const u_char *bs, +static struct bsnamemem * +lookup_bytestring(netdissect_options *ndo, const u_char *bs, const unsigned int nlen) { struct bsnamemem *tp; - register u_int i, j, k; + u_int i, j, k; if (nlen >= 6) { k = (bs[0] << 8) | bs[1]; @@ -398,30 +495,32 @@ lookup_bytestring(netdissect_options *ndo, register const u_char *bs, else tp = tp->bs_nxt; - tp->bs_addr0 = i; - tp->bs_addr1 = j; - tp->bs_addr2 = k; + tp->bs_addr0 = (u_short)i; + tp->bs_addr1 = (u_short)j; + tp->bs_addr2 = (u_short)k; tp->bs_bytes = (u_char *) calloc(1, nlen); if (tp->bs_bytes == NULL) - (*ndo->ndo_error)(ndo, "lookup_bytestring: calloc"); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, + "%s: calloc", __func__); memcpy(tp->bs_bytes, bs, nlen); tp->bs_nbytes = nlen; tp->bs_nxt = (struct bsnamemem *)calloc(1, sizeof(*tp)); if (tp->bs_nxt == NULL) - (*ndo->ndo_error)(ndo, "lookup_bytestring: calloc"); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, + "%s: calloc", __func__); return tp; } /* Find the hash node that corresponds the NSAP 'nsap' */ -static inline struct enamemem * -lookup_nsap(netdissect_options *ndo, register const u_char *nsap, - register u_int nsap_length) +static struct enamemem * +lookup_nsap(netdissect_options *ndo, const u_char *nsap, + u_int nsap_length) { - register u_int i, j, k; + u_int i, j, k; struct enamemem *tp; const u_char *ensap; @@ -445,27 +544,27 @@ lookup_nsap(netdissect_options *ndo, register const u_char *nsap, return tp; else tp = tp->e_nxt; - tp->e_addr0 = i; - tp->e_addr1 = j; - tp->e_addr2 = k; + tp->e_addr0 = (u_short)i; + tp->e_addr1 = (u_short)j; + tp->e_addr2 = (u_short)k; tp->e_nsap = (u_char *)malloc(nsap_length + 1); if (tp->e_nsap == NULL) - (*ndo->ndo_error)(ndo, "lookup_nsap: malloc"); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, "%s: malloc", __func__); tp->e_nsap[0] = (u_char)nsap_length; /* guaranteed < ISONSAP_MAX_LENGTH */ memcpy((char *)&tp->e_nsap[1], (const char *)nsap, nsap_length); tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp)); if (tp->e_nxt == NULL) - (*ndo->ndo_error)(ndo, "lookup_nsap: calloc"); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, "%s: calloc", __func__); return tp; } /* Find the hash node that corresponds the protoid 'pi'. */ -static inline struct protoidmem * +static struct protoidmem * lookup_protoid(netdissect_options *ndo, const u_char *pi) { - register u_int i, j; + u_int i, j; struct protoidmem *tp; /* 5 octets won't be aligned */ @@ -480,20 +579,20 @@ lookup_protoid(netdissect_options *ndo, const u_char *pi) else tp = tp->p_nxt; tp->p_oui = i; - tp->p_proto = j; + tp->p_proto = (u_short)j; tp->p_nxt = (struct protoidmem *)calloc(1, sizeof(*tp)); if (tp->p_nxt == NULL) - (*ndo->ndo_error)(ndo, "lookup_protoid: calloc"); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, "%s: calloc", __func__); return tp; } const char * -etheraddr_string(netdissect_options *ndo, register const u_char *ep) +etheraddr_string(netdissect_options *ndo, const uint8_t *ep) { - register int i; - register char *cp; - register struct enamemem *tp; + int i; + char *cp; + struct enamemem *tp; int oui; char buf[BUFSIZE]; @@ -503,24 +602,29 @@ etheraddr_string(netdissect_options *ndo, register const u_char *ep) #ifdef USE_ETHER_NTOHOST if (!ndo->ndo_nflag) { char buf2[BUFSIZE]; + /* + * This is a non-const copy of ep for ether_ntohost(), which + * has its second argument non-const in OpenBSD. Also saves a + * type cast. + */ + struct ether_addr ea; - if (ether_ntohost(buf2, (const struct ether_addr *)ep) == 0) { + memcpy (&ea, ep, MAC_ADDR_LEN); + if (ether_ntohost(buf2, &ea) == 0) { tp->e_name = strdup(buf2); if (tp->e_name == NULL) - (*ndo->ndo_error)(ndo, - "etheraddr_string: strdup(buf2)"); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, + "%s: strdup(buf2)", __func__); return (tp->e_name); } } #endif cp = buf; - oui = EXTRACT_24BITS(ep); - *cp++ = hex[*ep >> 4 ]; - *cp++ = hex[*ep++ & 0xf]; + oui = EXTRACT_BE_U_3(ep); + cp = octet_to_hex(cp, *ep++); for (i = 5; --i >= 0;) { *cp++ = ':'; - *cp++ = hex[*ep >> 4 ]; - *cp++ = hex[*ep++ & 0xf]; + cp = octet_to_hex(cp, *ep++); } if (!ndo->ndo_nflag) { @@ -530,17 +634,18 @@ etheraddr_string(netdissect_options *ndo, register const u_char *ep) *cp = '\0'; tp->e_name = strdup(buf); if (tp->e_name == NULL) - (*ndo->ndo_error)(ndo, "etheraddr_string: strdup(buf)"); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, + "%s: strdup(buf)", __func__); return (tp->e_name); } const char * -le64addr_string(netdissect_options *ndo, const u_char *ep) +le64addr_string(netdissect_options *ndo, const uint8_t *ep) { const unsigned int len = 8; - register u_int i; - register char *cp; - register struct bsnamemem *tp; + u_int i; + char *cp; + struct bsnamemem *tp; char buf[BUFSIZE]; tp = lookup_bytestring(ndo, ep, len); @@ -549,8 +654,7 @@ le64addr_string(netdissect_options *ndo, const u_char *ep) cp = buf; for (i = len; i > 0 ; --i) { - *cp++ = hex[*(ep + i - 1) >> 4]; - *cp++ = hex[*(ep + i - 1) & 0xf]; + cp = octet_to_hex(cp, *(ep + i - 1)); *cp++ = ':'; } cp --; @@ -559,23 +663,24 @@ le64addr_string(netdissect_options *ndo, const u_char *ep) tp->bs_name = strdup(buf); if (tp->bs_name == NULL) - (*ndo->ndo_error)(ndo, "le64addr_string: strdup(buf)"); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, + "%s: strdup(buf)", __func__); return (tp->bs_name); } const char * -linkaddr_string(netdissect_options *ndo, const u_char *ep, +linkaddr_string(netdissect_options *ndo, const uint8_t *ep, const unsigned int type, const unsigned int len) { - register u_int i; - register char *cp; - register struct bsnamemem *tp; + u_int i; + char *cp; + struct bsnamemem *tp; if (len == 0) return (""); - if (type == LINKADDR_ETHER && len == ETHER_ADDR_LEN) + if (type == LINKADDR_ETHER && len == MAC_ADDR_LEN) return (etheraddr_string(ndo, ep)); if (type == LINKADDR_FRELAY) @@ -587,83 +692,25 @@ linkaddr_string(netdissect_options *ndo, const u_char *ep, tp->bs_name = cp = (char *)malloc(len*3); if (tp->bs_name == NULL) - (*ndo->ndo_error)(ndo, "linkaddr_string: malloc"); - *cp++ = hex[*ep >> 4]; - *cp++ = hex[*ep++ & 0xf]; + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, + "%s: malloc", __func__); + cp = octet_to_hex(cp, *ep++); for (i = len-1; i > 0 ; --i) { *cp++ = ':'; - *cp++ = hex[*ep >> 4]; - *cp++ = hex[*ep++ & 0xf]; + cp = octet_to_hex(cp, *ep++); } *cp = '\0'; return (tp->bs_name); } -const char * -etherproto_string(netdissect_options *ndo, u_short port) -{ - register char *cp; - register struct hnamemem *tp; - register uint32_t i = port; - char buf[sizeof("0000")]; - - for (tp = &eprototable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) - if (tp->addr == i) - return (tp->name); - - tp->addr = i; - tp->nxt = newhnamemem(ndo); - - cp = buf; - NTOHS(port); - *cp++ = hex[port >> 12 & 0xf]; - *cp++ = hex[port >> 8 & 0xf]; - *cp++ = hex[port >> 4 & 0xf]; - *cp++ = hex[port & 0xf]; - *cp++ = '\0'; - tp->name = strdup(buf); - if (tp->name == NULL) - (*ndo->ndo_error)(ndo, "etherproto_string: strdup(buf)"); - return (tp->name); -} - -const char * -protoid_string(netdissect_options *ndo, register const u_char *pi) -{ - register u_int i, j; - register char *cp; - register struct protoidmem *tp; - char buf[sizeof("00:00:00:00:00")]; - - tp = lookup_protoid(ndo, pi); - if (tp->p_name) - return tp->p_name; - - cp = buf; - if ((j = *pi >> 4) != 0) - *cp++ = hex[j]; - *cp++ = hex[*pi++ & 0xf]; - for (i = 4; (int)--i >= 0;) { - *cp++ = ':'; - if ((j = *pi >> 4) != 0) - *cp++ = hex[j]; - *cp++ = hex[*pi++ & 0xf]; - } - *cp = '\0'; - tp->p_name = strdup(buf); - if (tp->p_name == NULL) - (*ndo->ndo_error)(ndo, "protoid_string: strdup(buf)"); - return (tp->p_name); -} - #define ISONSAP_MAX_LENGTH 20 const char * -isonsap_string(netdissect_options *ndo, const u_char *nsap, - register u_int nsap_length) +isonsap_string(netdissect_options *ndo, const uint8_t *nsap, + u_int nsap_length) { - register u_int nsap_idx; - register char *cp; - register struct enamemem *tp; + u_int nsap_idx; + char *cp; + struct enamemem *tp; if (nsap_length < 1 || nsap_length > ISONSAP_MAX_LENGTH) return ("isonsap_string: illegal length"); @@ -674,14 +721,14 @@ isonsap_string(netdissect_options *ndo, const u_char *nsap, tp->e_name = cp = (char *)malloc(sizeof("xx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xx")); if (cp == NULL) - (*ndo->ndo_error)(ndo, "isonsap_string: malloc"); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, + "%s: malloc", __func__); for (nsap_idx = 0; nsap_idx < nsap_length; nsap_idx++) { - *cp++ = hex[*nsap >> 4]; - *cp++ = hex[*nsap++ & 0xf]; + cp = octet_to_hex(cp, *nsap++); if (((nsap_idx & 1) == 0) && (nsap_idx + 1 < nsap_length)) { - *cp++ = '.'; + *cp++ = '.'; } } *cp = '\0'; @@ -691,8 +738,8 @@ isonsap_string(netdissect_options *ndo, const u_char *nsap, const char * tcpport_string(netdissect_options *ndo, u_short port) { - register struct hnamemem *tp; - register uint32_t i = port; + struct hnamemem *tp; + uint32_t i = port; char buf[sizeof("00000")]; for (tp = &tporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) @@ -705,15 +752,16 @@ tcpport_string(netdissect_options *ndo, u_short port) (void)snprintf(buf, sizeof(buf), "%u", i); tp->name = strdup(buf); if (tp->name == NULL) - (*ndo->ndo_error)(ndo, "tcpport_string: strdup(buf)"); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, + "%s: strdup(buf)", __func__); return (tp->name); } const char * -udpport_string(netdissect_options *ndo, register u_short port) +udpport_string(netdissect_options *ndo, u_short port) { - register struct hnamemem *tp; - register uint32_t i = port; + struct hnamemem *tp; + uint32_t i = port; char buf[sizeof("00000")]; for (tp = &uporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) @@ -726,16 +774,17 @@ udpport_string(netdissect_options *ndo, register u_short port) (void)snprintf(buf, sizeof(buf), "%u", i); tp->name = strdup(buf); if (tp->name == NULL) - (*ndo->ndo_error)(ndo, "udpport_string: strdup(buf)"); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, + "%s: strdup(buf)", __func__); return (tp->name); } const char * ipxsap_string(netdissect_options *ndo, u_short port) { - register char *cp; - register struct hnamemem *tp; - register uint32_t i = port; + char *cp; + struct hnamemem *tp; + uint32_t i = port; char buf[sizeof("0000")]; for (tp = &ipxsaptable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) @@ -746,7 +795,7 @@ ipxsap_string(netdissect_options *ndo, u_short port) tp->nxt = newhnamemem(ndo); cp = buf; - NTOHS(port); + port = ntohs(port); *cp++ = hex[port >> 12 & 0xf]; *cp++ = hex[port >> 8 & 0xf]; *cp++ = hex[port >> 4 & 0xf]; @@ -754,7 +803,8 @@ ipxsap_string(netdissect_options *ndo, u_short port) *cp++ = '\0'; tp->name = strdup(buf); if (tp->name == NULL) - (*ndo->ndo_error)(ndo, "ipxsap_string: strdup(buf)"); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, + "%s: strdup(buf)", __func__); return (tp->name); } @@ -762,8 +812,8 @@ static void init_servarray(netdissect_options *ndo) { struct servent *sv; - register struct hnamemem *table; - register int i; + struct hnamemem *table; + int i; char buf[sizeof("0000000000")]; while ((sv = getservent()) != NULL) { @@ -784,7 +834,8 @@ init_servarray(netdissect_options *ndo) } else table->name = strdup(sv->s_name); if (table->name == NULL) - (*ndo->ndo_error)(ndo, "init_servarray: strdup"); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, + "%s: strdup", __func__); table->addr = port; table->nxt = newhnamemem(ndo); @@ -796,34 +847,26 @@ static const struct eproto { const char *s; u_short p; } eproto_db[] = { - { "pup", ETHERTYPE_PUP }, - { "xns", ETHERTYPE_NS }, + { "aarp", ETHERTYPE_AARP }, + { "arp", ETHERTYPE_ARP }, + { "atalk", ETHERTYPE_ATALK }, + { "decnet", ETHERTYPE_DN }, { "ip", ETHERTYPE_IP }, { "ip6", ETHERTYPE_IPV6 }, - { "arp", ETHERTYPE_ARP }, - { "rarp", ETHERTYPE_REVARP }, - { "sprite", ETHERTYPE_SPRITE }, + { "lat", ETHERTYPE_LAT }, + { "loopback", ETHERTYPE_LOOPBACK }, { "mopdl", ETHERTYPE_MOPDL }, { "moprc", ETHERTYPE_MOPRC }, - { "decnet", ETHERTYPE_DN }, - { "lat", ETHERTYPE_LAT }, + { "rarp", ETHERTYPE_REVARP }, { "sca", ETHERTYPE_SCA }, - { "lanbridge", ETHERTYPE_LANBRIDGE }, - { "vexp", ETHERTYPE_VEXP }, - { "vprod", ETHERTYPE_VPROD }, - { "atalk", ETHERTYPE_ATALK }, - { "atalkarp", ETHERTYPE_AARP }, - { "loopback", ETHERTYPE_LOOPBACK }, - { "decdts", ETHERTYPE_DECDTS }, - { "decdns", ETHERTYPE_DECDNS }, { (char *)0, 0 } }; static void init_eprotoarray(netdissect_options *ndo) { - register int i; - register struct hnamemem *table; + int i; + struct hnamemem *table; for (i = 0; eproto_db[i].s; i++) { int j = htons(eproto_db[i].p) & (HASHNAMESIZE-1); @@ -855,8 +898,8 @@ static const struct protoidlist { static void init_protoidarray(netdissect_options *ndo) { - register int i; - register struct protoidmem *tp; + int i; + struct protoidmem *tp; const struct protoidlist *pl; u_char protoid[5]; @@ -870,8 +913,8 @@ init_protoidarray(netdissect_options *ndo) tp = lookup_protoid(ndo, protoid); tp->p_name = strdup(eproto_db[i].s); if (tp->p_name == NULL) - (*ndo->ndo_error)(ndo, - "init_protoidarray: strdup(eproto_db[i].s)"); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, + "%s: strdup(eproto_db[i].s)", __func__); } /* Hardwire some SNAP proto ID names */ for (pl = protoidlist; pl->name != NULL; ++pl) { @@ -885,7 +928,7 @@ init_protoidarray(netdissect_options *ndo) } static const struct etherlist { - const u_char addr[6]; + const nd_mac_addr addr; const char *name; } etherlist[] = { {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, "Broadcast" }, @@ -909,13 +952,13 @@ static const struct etherlist { static void init_etherarray(netdissect_options *ndo) { - register const struct etherlist *el; - register struct enamemem *tp; + const struct etherlist *el; + struct enamemem *tp; #ifdef USE_ETHER_NTOHOST char name[256]; #else - register struct pcap_etherent *ep; - register FILE *fp; + struct pcap_etherent *ep; + FILE *fp; /* Suck in entire ethers file */ fp = fopen(PCAP_ETHERS_FILE, "r"); @@ -924,8 +967,8 @@ init_etherarray(netdissect_options *ndo) tp = lookup_emem(ndo, ep->addr); tp->e_name = strdup(ep->name); if (tp->e_name == NULL) - (*ndo->ndo_error)(ndo, - "init_etherarray: strdup(ep->addr)"); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, + "%s: strdup(ep->addr)", __func__); } (void)fclose(fp); } @@ -942,11 +985,14 @@ init_etherarray(netdissect_options *ndo) /* * Use YP/NIS version of name if available. */ - if (ether_ntohost(name, (const struct ether_addr *)el->addr) == 0) { + /* Same workaround as in etheraddr_string(). */ + struct ether_addr ea; + memcpy (&ea, el->addr, MAC_ADDR_LEN); + if (ether_ntohost(name, &ea) == 0) { tp->e_name = strdup(name); if (tp->e_name == NULL) - (*ndo->ndo_error)(ndo, - "init_etherarray: strdup(name)"); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, + "%s: strdup(name)", __func__); continue; } #endif @@ -954,7 +1000,10 @@ init_etherarray(netdissect_options *ndo) } } -static const struct tok ipxsap_db[] = { +static const struct ipxsap_ent { + uint16_t v; + const char *s; +} ipxsap_db[] = { { 0x0000, "Unknown" }, { 0x0001, "User" }, { 0x0002, "User Group" }, @@ -1174,11 +1223,11 @@ static const struct tok ipxsap_db[] = { static void init_ipxsaparray(netdissect_options *ndo) { - register int i; - register struct hnamemem *table; + int i; + struct hnamemem *table; for (i = 0; ipxsap_db[i].s != NULL; i++) { - int j = htons(ipxsap_db[i].v) & (HASHNAMESIZE-1); + u_int j = htons(ipxsap_db[i].v) & (HASHNAMESIZE-1); table = &ipxsaptable[j]; while (table->name) table = table->nxt; @@ -1217,7 +1266,7 @@ init_addrtoname(netdissect_options *ndo, uint32_t localnet, uint32_t mask) const char * dnaddr_string(netdissect_options *ndo, u_short dnaddr) { - register struct hnamemem *tp; + struct hnamemem *tp; for (tp = &dnaddrtable[dnaddr & (HASHNAMESIZE-1)]; tp->nxt != NULL; tp = tp->nxt) @@ -1235,7 +1284,7 @@ dnaddr_string(netdissect_options *ndo, u_short dnaddr) struct hnamemem * newhnamemem(netdissect_options *ndo) { - register struct hnamemem *p; + struct hnamemem *p; static struct hnamemem *ptr = NULL; static u_int num = 0; @@ -1243,7 +1292,8 @@ newhnamemem(netdissect_options *ndo) num = 64; ptr = (struct hnamemem *)calloc(num, sizeof (*ptr)); if (ptr == NULL) - (*ndo->ndo_error)(ndo, "newhnamemem: calloc"); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, + "%s: calloc", __func__); } --num; p = ptr++; @@ -1254,7 +1304,7 @@ newhnamemem(netdissect_options *ndo) struct h6namemem * newh6namemem(netdissect_options *ndo) { - register struct h6namemem *p; + struct h6namemem *p; static struct h6namemem *ptr = NULL; static u_int num = 0; @@ -1262,7 +1312,8 @@ newh6namemem(netdissect_options *ndo) num = 64; ptr = (struct h6namemem *)calloc(num, sizeof (*ptr)); if (ptr == NULL) - (*ndo->ndo_error)(ndo, "newh6namemem: calloc"); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, + "%s: calloc", __func__); } --num; p = ptr++; diff --git a/contrib/tcpdump/addrtoname.h b/contrib/tcpdump/addrtoname.h index fe8b6bbe54..94b41d7bee 100644 --- a/contrib/tcpdump/addrtoname.h +++ b/contrib/tcpdump/addrtoname.h @@ -19,8 +19,10 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ +#include "extract.h" + /* - * Definitions to let us compile most of the IPv6 code even on systems + * Definition to let us compile most of the IPv6 code even on systems * without IPv6 support. */ #ifndef INET6_ADDRSTRLEN @@ -39,18 +41,16 @@ enum { #define BUFSIZE 128 -extern const char *linkaddr_string(netdissect_options *, const u_char *, const unsigned int, const unsigned int); -extern const char *etheraddr_string(netdissect_options *, const u_char *); -extern const char *le64addr_string(netdissect_options *, const u_char *); -extern const char *etherproto_string(netdissect_options *, u_short); +extern const char *linkaddr_string(netdissect_options *, const uint8_t *, const unsigned int, const unsigned int); +extern const char *etheraddr_string(netdissect_options *, const uint8_t *); +extern const char *le64addr_string(netdissect_options *, const uint8_t *); extern const char *tcpport_string(netdissect_options *, u_short); extern const char *udpport_string(netdissect_options *, u_short); -extern const char *isonsap_string(netdissect_options *, const u_char *, register u_int); +extern const char *isonsap_string(netdissect_options *, const uint8_t *, u_int); extern const char *dnaddr_string(netdissect_options *, u_short); -extern const char *protoid_string(netdissect_options *, const u_char *); extern const char *ipxsap_string(netdissect_options *, u_short); -extern const char *getname(netdissect_options *, const u_char *); -extern const char *getname6(netdissect_options *, const u_char *); +extern const char *ipaddr_string(netdissect_options *, const u_char *); +extern const char *ip6addr_string(netdissect_options *, const u_char *); extern const char *intoa(uint32_t); extern void init_addrtoname(netdissect_options *, uint32_t, uint32_t); @@ -58,5 +58,64 @@ extern struct hnamemem *newhnamemem(netdissect_options *); extern struct h6namemem *newh6namemem(netdissect_options *); extern const char * ieee8021q_tci_string(const uint16_t); -#define ipaddr_string(ndo, p) getname(ndo, (const u_char *)(p)) -#define ip6addr_string(ndo, p) getname6(ndo, (const u_char *)(p)) +/* macro(s) and inline function(s) with setjmp/longjmp logic to call + * the X_string() function(s) after bounds checking. + * The macro(s) must be used on a packet buffer pointer. + */ + +static inline const char * +get_linkaddr_string(netdissect_options *ndo, const uint8_t *p, + const unsigned int type, const unsigned int len) +{ + if (!ND_TTEST_LEN(p, len)) + nd_trunc_longjmp(ndo); + return linkaddr_string(ndo, p, type, len); +} + +static inline const char * +get_etheraddr_string(netdissect_options *ndo, const uint8_t *p) +{ + if (!ND_TTEST_LEN(p, MAC_ADDR_LEN)) + nd_trunc_longjmp(ndo); + return etheraddr_string(ndo, p); +} + +static inline const char * +get_le64addr_string(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_8(p)) + nd_trunc_longjmp(ndo); + return le64addr_string(ndo, p); +} + +static inline const char * +get_isonsap_string(netdissect_options *ndo, const uint8_t *nsap, + u_int nsap_length) +{ + if (!ND_TTEST_LEN(nsap, nsap_length)) + nd_trunc_longjmp(ndo); + return isonsap_string(ndo, nsap, nsap_length); +} + +static inline const char * +get_ipaddr_string(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_4(p)) + nd_trunc_longjmp(ndo); + return ipaddr_string(ndo, p); +} + +static inline const char * +get_ip6addr_string(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_16(p)) + nd_trunc_longjmp(ndo); + return ip6addr_string(ndo, p); +} + +#define GET_LINKADDR_STRING(p, type, len) get_linkaddr_string(ndo, (const u_char *)(p), type, len) +#define GET_ETHERADDR_STRING(p) get_etheraddr_string(ndo, (const u_char *)(p)) +#define GET_LE64ADDR_STRING(p) get_le64addr_string(ndo, (const u_char *)(p)) +#define GET_ISONSAP_STRING(nsap, nsap_length) get_isonsap_string(ndo, (const u_char *)(nsap), nsap_length) +#define GET_IPADDR_STRING(p) get_ipaddr_string(ndo, (const u_char *)(p)) +#define GET_IP6ADDR_STRING(p) get_ip6addr_string(ndo, (const u_char *)(p)) diff --git a/contrib/tcpdump/addrtostr.c b/contrib/tcpdump/addrtostr.c index 6b06767594..62cc298ae2 100644 --- a/contrib/tcpdump/addrtostr.c +++ b/contrib/tcpdump/addrtostr.c @@ -37,10 +37,10 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "addrtostr.h" #include @@ -127,7 +127,7 @@ addrtostr6 (const void *src, char *dst, size_t size) best.base = -1; cur.len = 0; cur.base = -1; - for (i = 0; i < (int)(IN6ADDRSZ / INT16SZ); i++) + for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { if (words[i] == 0) { @@ -160,7 +160,7 @@ addrtostr6 (const void *src, char *dst, size_t size) *dp++ = c; \ space_left--; \ } - for (i = 0; i < (int)(IN6ADDRSZ / INT16SZ); i++) + for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { /* Are we inside the best run of 0x00's? */ diff --git a/contrib/tcpdump/af.c b/contrib/tcpdump/af.c index 704e2f0ace..1153f102b4 100644 --- a/contrib/tcpdump/af.c +++ b/contrib/tcpdump/af.c @@ -16,10 +16,10 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "af.h" diff --git a/contrib/tcpdump/af.h b/contrib/tcpdump/af.h index 6365b12620..b9fec8e635 100644 --- a/contrib/tcpdump/af.h +++ b/contrib/tcpdump/af.h @@ -52,4 +52,4 @@ extern const struct tok bsd_af_values[]; #define BSD_AFNUM_IPX 23 #define BSD_AFNUM_INET6_BSD 24 /* NetBSD, OpenBSD, BSD/OS, Npcap */ #define BSD_AFNUM_INET6_FREEBSD 28 /* FreeBSD */ -#define BSD_AFNUM_INET6_DARWIN 30 /* OS X, iOS, other Darwin-based OSes */ +#define BSD_AFNUM_INET6_DARWIN 30 /* macOS, iOS, other Darwin-based OSes */ diff --git a/contrib/tcpdump/ah.h b/contrib/tcpdump/ah.h index d87a087e1a..c60c56353f 100644 --- a/contrib/tcpdump/ah.h +++ b/contrib/tcpdump/ah.h @@ -31,27 +31,37 @@ */ /* - * RFC1826/2402 authentication header. + * RFC4302 authentication header. */ -#ifndef _NETINET6_AH_H_ -#define _NETINET6_AH_H_ +#ifndef ND_AH_H_ +#define ND_AH_H_ -struct ah { - uint8_t ah_nxt; /* Next Header */ - uint8_t ah_len; /* Length of data, in 32bit */ - uint16_t ah_reserve; /* Reserved for future use */ - uint32_t ah_spi; /* Security parameter index */ - /* variable size, 32bit bound*/ /* Authentication data */ -}; +/* + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Next Header | Payload Len | RESERVED | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Security Parameters Index (SPI) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Sequence Number Field | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * + Integrity Check Value-ICV (variable) | + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Figure 1. AH Format + */ -struct newah { - uint8_t ah_nxt; /* Next Header */ - uint8_t ah_len; /* Length of data + 1, in 32bit */ - uint16_t ah_reserve; /* Reserved for future use */ - uint32_t ah_spi; /* Security parameter index */ - uint32_t ah_seq; /* Sequence number field */ - /* variable size, 32bit bound*/ /* Authentication data */ +struct ah { + nd_uint8_t ah_nxt; /* Next Header */ + nd_uint8_t ah_len; /* Payload Len in 32bit words minus 2 */ + nd_uint16_t ah_reserved; /* Reserved for future use */ + nd_uint32_t ah_spi; /* Security Parameters Index */ + nd_uint32_t ah_seq; /* Sequence Number Field */ + /* variable size, 32bit bound*/ /* Integrity Check Value-ICV */ }; -#endif /*_NETINET6_AH_H_*/ +#endif /* ND_AH_H_ */ diff --git a/contrib/tcpdump/appletalk.h b/contrib/tcpdump/appletalk.h index 3fbcbce00e..ef4013f13d 100644 --- a/contrib/tcpdump/appletalk.h +++ b/contrib/tcpdump/appletalk.h @@ -22,9 +22,9 @@ */ struct LAP { - uint8_t dst; - uint8_t src; - uint8_t type; + nd_uint8_t dst; + nd_uint8_t src; + nd_uint8_t type; }; #define lapShortDDP 1 /* short DDP type */ #define lapDDP 2 /* DDP type */ @@ -33,22 +33,22 @@ struct LAP { /* Datagram Delivery Protocol */ struct atDDP { - uint16_t length; - uint16_t checksum; - uint16_t dstNet; - uint16_t srcNet; - uint8_t dstNode; - uint8_t srcNode; - uint8_t dstSkt; - uint8_t srcSkt; - uint8_t type; + nd_uint16_t length; + nd_uint16_t checksum; + nd_uint16_t dstNet; + nd_uint16_t srcNet; + nd_uint8_t dstNode; + nd_uint8_t srcNode; + nd_uint8_t dstSkt; + nd_uint8_t srcSkt; + nd_uint8_t type; }; struct atShortDDP { - uint16_t length; - uint8_t dstSkt; - uint8_t srcSkt; - uint8_t type; + nd_uint16_t length; + nd_uint8_t dstSkt; + nd_uint8_t srcSkt; + nd_uint8_t type; }; #define ddpMaxWKS 0x7F @@ -72,10 +72,10 @@ struct atShortDDP { /* AppleTalk Transaction Protocol */ struct atATP { - uint8_t control; - uint8_t bitmap; - uint16_t transID; - int32_t userData; + nd_uint8_t control; + nd_uint8_t bitmap; + nd_uint16_t transID; + nd_uint32_t userData; }; #define atpReqCode 0x40 @@ -93,8 +93,8 @@ struct atATP { /* AppleTalk Echo Protocol */ struct atEcho { - uint8_t echoFunction; - uint8_t *echoData; + nd_uint8_t echoFunction; + nd_uint8_t echoData[1]; /* Should be [], C99-style */ }; #define echoSkt 4 /* the echoer socket */ @@ -106,15 +106,15 @@ struct atEcho { /* Name Binding Protocol */ struct atNBP { - uint8_t control; - uint8_t id; + nd_uint8_t control; + nd_uint8_t id; }; struct atNBPtuple { - uint16_t net; - uint8_t node; - uint8_t skt; - uint8_t enumerator; + nd_uint16_t net; + nd_uint8_t node; + nd_uint8_t skt; + nd_uint8_t enumerator; }; #define nbpBrRq 0x10 @@ -140,8 +140,8 @@ struct atNBPtuple { /* Zone Information Protocol */ struct zipHeader { - uint8_t command; - uint8_t netcount; + nd_uint8_t command; + nd_uint8_t netcount; }; #define zipHeaderSize 2 diff --git a/contrib/tcpdump/ascii_strcasecmp.c b/contrib/tcpdump/ascii_strcasecmp.c index b8decf141b..090f75869e 100644 --- a/contrib/tcpdump/ascii_strcasecmp.c +++ b/contrib/tcpdump/ascii_strcasecmp.c @@ -58,7 +58,7 @@ static const unsigned char charmap[] = { int ascii_strcasecmp(const char *s1, const char *s2) { - register const unsigned char *cm = charmap, + const unsigned char *cm = charmap, *us1 = (const unsigned char *)s1, *us2 = (const unsigned char *)s2; @@ -69,9 +69,9 @@ ascii_strcasecmp(const char *s1, const char *s2) } int -ascii_strncasecmp(const char *s1, const char *s2, register size_t n) +ascii_strncasecmp(const char *s1, const char *s2, size_t n) { - register const unsigned char *cm = charmap, + const unsigned char *cm = charmap, *us1 = (const unsigned char *)s1, *us2 = (const unsigned char *)s2; diff --git a/contrib/tcpdump/checksum.c b/contrib/tcpdump/checksum.c index a48a147f35..e6e84a2510 100644 --- a/contrib/tcpdump/checksum.c +++ b/contrib/tcpdump/checksum.c @@ -18,10 +18,10 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include #include @@ -90,8 +90,8 @@ static void init_crc10_table(void) { #define CRC10_POLYNOMIAL 0x633 - register int i, j; - register uint16_t accum; + int i, j; + uint16_t accum; uint16_t verify_crc10_table[256]; for ( i = 0; i < 256; i++ ) @@ -112,7 +112,7 @@ init_crc10_table(void) uint16_t verify_crc10_cksum(uint16_t accum, const u_char *p, int length) { - register int i; + int i; for ( i = 0; i < length; i++ ) { diff --git a/contrib/tcpdump/compiler-tests.h b/contrib/tcpdump/compiler-tests.h new file mode 100644 index 0000000000..4793b71997 --- /dev/null +++ b/contrib/tcpdump/compiler-tests.h @@ -0,0 +1,151 @@ +/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ +/* + * 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 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 Computer Systems + * Engineering Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory 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. + */ + +#ifndef nd_compiler_tests_h +#define nd_compiler_tests_h + +/* + * This was introduced by Clang: + * + * https://clang.llvm.org/docs/LanguageExtensions.html#has-attribute + * + * in some version (which version?); it has been picked up by GCC 5.0. + */ +#ifndef __has_attribute + /* + * It's a macro, so you can check whether it's defined to check + * whether it's supported. + * + * If it's not, define it to always return 0, so that we move on to + * the fallback checks. + */ + #define __has_attribute(x) 0 +#endif + +/* + * Note that the C90 spec's "6.8.1 Conditional inclusion" and the + * C99 spec's and C11 spec's "6.10.1 Conditional inclusion" say: + * + * Prior to evaluation, macro invocations in the list of preprocessing + * tokens that will become the controlling constant expression are + * replaced (except for those macro names modified by the defined unary + * operator), just as in normal text. If the token "defined" is + * generated as a result of this replacement process or use of the + * "defined" unary operator does not match one of the two specified + * forms prior to macro replacement, the behavior is undefined. + * + * so you shouldn't use defined() in a #define that's used in #if or + * #elif. Some versions of Clang, for example, will warn about this. + * + * Instead, we check whether the pre-defined macros for particular + * compilers are defined and, if not, define the "is this version XXX + * or a later version of this compiler" macros as 0. + */ + +/* + * Check whether this is GCC major.minor or a later release, or some + * compiler that claims to be "just like GCC" of that version or a + * later release. + */ + +#if ! defined(__GNUC__) +#define ND_IS_AT_LEAST_GNUC_VERSION(major, minor) 0 +#else +#define ND_IS_AT_LEAST_GNUC_VERSION(major, minor) \ + (__GNUC__ > (major) || \ + (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))) +#endif + +/* + * Check whether this is Sun C/SunPro C/Oracle Studio major.minor + * or a later release. + * + * The version number in __SUNPRO_C is encoded in hex BCD, with the + * uppermost hex digit being the major version number, the next + * one or two hex digits being the minor version number, and + * the last digit being the patch version. + * + * It represents the *compiler* version, not the product version; + * see + * + * https://sourceforge.net/p/predef/wiki/Compilers/ + * + * for a partial mapping, which we assume continues for later + * 12.x product releases. + */ + +#if ! defined(__SUNPRO_C) +#define ND_IS_AT_LEAST_SUNC_VERSION(major,minor) 0 +#else +#define ND_SUNPRO_VERSION_TO_BCD(major, minor) \ + (((minor) >= 10) ? \ + (((major) << 12) | (((minor)/10) << 8) | (((minor)%10) << 4)) : \ + (((major) << 8) | ((minor) << 4))) +#define ND_IS_AT_LEAST_SUNC_VERSION(major,minor) \ + (__SUNPRO_C >= ND_SUNPRO_VERSION_TO_BCD((major), (minor))) +#endif + +/* + * Check whether this is IBM XL C major.minor or a later release. + * + * The version number in __xlC__ has the major version in the + * upper 8 bits and the minor version in the lower 8 bits. + */ + +#if ! defined(__xlC__) +#define ND_IS_AT_LEAST_XL_C_VERSION(major,minor) 0 +#else +#define ND_IS_AT_LEAST_XL_C_VERSION(major, minor) \ + (__xlC__ >= (((major) << 8) | (minor))) +#endif + +/* + * Check whether this is HP aC++/HP C major.minor or a later release. + * + * The version number in __HP_aCC is encoded in zero-padded decimal BCD, + * with the "A." stripped off, the uppermost two decimal digits being + * the major version number, the next two decimal digits being the minor + * version number, and the last two decimal digits being the patch version. + * (Strip off the A., remove the . between the major and minor version + * number, and add two digits of patch.) + */ + +#if ! defined(__HP_aCC) +#define ND_IS_AT_LEAST_HP_C_VERSION(major,minor) 0 +#else +#define ND_IS_AT_LEAST_HP_C_VERSION(major,minor) \ + (__HP_aCC >= ((major)*10000 + (minor)*100)) +#endif + +#endif /* nd_funcattrs_h */ diff --git a/contrib/tcpdump/cpack.c b/contrib/tcpdump/cpack.c index e37d813d39..9be7b47d85 100644 --- a/contrib/tcpdump/cpack.c +++ b/contrib/tcpdump/cpack.c @@ -28,18 +28,20 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif #include #include -#include +#include "netdissect-stdinc.h" -#include "cpack.h" +#include "netdissect.h" #include "extract.h" +#include "cpack.h" + const uint8_t * -cpack_next_boundary(const uint8_t *buf, const uint8_t *p, size_t alignment) +nd_cpack_next_boundary(const uint8_t *buf, const uint8_t *p, size_t alignment) { size_t misalignment = (size_t)(p - buf) % alignment; @@ -54,12 +56,12 @@ cpack_next_boundary(const uint8_t *buf, const uint8_t *p, size_t alignment) * return a pointer to the boundary. */ const uint8_t * -cpack_align_and_reserve(struct cpack_state *cs, size_t wordsize) +nd_cpack_align_and_reserve(struct cpack_state *cs, size_t wordsize) { const uint8_t *next; /* Ensure alignment. */ - next = cpack_next_boundary(cs->c_buf, cs->c_next, wordsize); + next = nd_cpack_next_boundary(cs->c_buf, cs->c_next, wordsize); /* Too little space for wordsize bytes? */ if (next - cs->c_buf + wordsize > cs->c_len) @@ -70,7 +72,7 @@ cpack_align_and_reserve(struct cpack_state *cs, size_t wordsize) /* Advance by N bytes without returning them. */ int -cpack_advance(struct cpack_state *cs, const size_t toskip) +nd_cpack_advance(struct cpack_state *cs, const size_t toskip) { /* No space left? */ if (cs->c_next - cs->c_buf + toskip > cs->c_len) @@ -80,7 +82,7 @@ cpack_advance(struct cpack_state *cs, const size_t toskip) } int -cpack_init(struct cpack_state *cs, const uint8_t *buf, size_t buflen) +nd_cpack_init(struct cpack_state *cs, const uint8_t *buf, size_t buflen) { memset(cs, 0, sizeof(*cs)); @@ -93,63 +95,126 @@ cpack_init(struct cpack_state *cs, const uint8_t *buf, size_t buflen) /* Unpack a 64-bit unsigned integer. */ int -cpack_uint64(struct cpack_state *cs, uint64_t *u) +nd_cpack_uint64(netdissect_options *ndo, struct cpack_state *cs, uint64_t *u) { const uint8_t *next; - if ((next = cpack_align_and_reserve(cs, sizeof(*u))) == NULL) + if ((next = nd_cpack_align_and_reserve(cs, sizeof(*u))) == NULL) return -1; - *u = EXTRACT_LE_64BITS(next); + *u = GET_LE_U_8(next); /* Move pointer past the uint64_t. */ cs->c_next = next + sizeof(*u); return 0; } +/* Unpack a 64-bit signed integer. */ +int +nd_cpack_int64(netdissect_options *ndo, struct cpack_state *cs, int64_t *u) +{ + const uint8_t *next; + + if ((next = nd_cpack_align_and_reserve(cs, sizeof(*u))) == NULL) + return -1; + + *u = GET_LE_S_8(next); + + /* Move pointer past the int64_t. */ + cs->c_next = next + sizeof(*u); + return 0; +} + /* Unpack a 32-bit unsigned integer. */ int -cpack_uint32(struct cpack_state *cs, uint32_t *u) +nd_cpack_uint32(netdissect_options *ndo, struct cpack_state *cs, uint32_t *u) { const uint8_t *next; - if ((next = cpack_align_and_reserve(cs, sizeof(*u))) == NULL) + if ((next = nd_cpack_align_and_reserve(cs, sizeof(*u))) == NULL) return -1; - *u = EXTRACT_LE_32BITS(next); + *u = GET_LE_U_4(next); /* Move pointer past the uint32_t. */ cs->c_next = next + sizeof(*u); return 0; } +/* Unpack a 32-bit signed integer. */ +int +nd_cpack_int32(netdissect_options *ndo, struct cpack_state *cs, int32_t *u) +{ + const uint8_t *next; + + if ((next = nd_cpack_align_and_reserve(cs, sizeof(*u))) == NULL) + return -1; + + *u = GET_LE_S_4(next); + + /* Move pointer past the int32_t. */ + cs->c_next = next + sizeof(*u); + return 0; +} + /* Unpack a 16-bit unsigned integer. */ int -cpack_uint16(struct cpack_state *cs, uint16_t *u) +nd_cpack_uint16(netdissect_options *ndo, struct cpack_state *cs, uint16_t *u) { const uint8_t *next; - if ((next = cpack_align_and_reserve(cs, sizeof(*u))) == NULL) + if ((next = nd_cpack_align_and_reserve(cs, sizeof(*u))) == NULL) return -1; - *u = EXTRACT_LE_16BITS(next); + *u = GET_LE_U_2(next); /* Move pointer past the uint16_t. */ cs->c_next = next + sizeof(*u); return 0; } +/* Unpack a 16-bit signed integer. */ +int +nd_cpack_int16(netdissect_options *ndo, struct cpack_state *cs, int16_t *u) +{ + const uint8_t *next; + + if ((next = nd_cpack_align_and_reserve(cs, sizeof(*u))) == NULL) + return -1; + + *u = GET_LE_S_2(next); + + /* Move pointer past the int16_t. */ + cs->c_next = next + sizeof(*u); + return 0; +} + /* Unpack an 8-bit unsigned integer. */ int -cpack_uint8(struct cpack_state *cs, uint8_t *u) +nd_cpack_uint8(netdissect_options *ndo, struct cpack_state *cs, uint8_t *u) { /* No space left? */ if ((size_t)(cs->c_next - cs->c_buf) >= cs->c_len) return -1; - *u = *cs->c_next; + *u = GET_U_1(cs->c_next); /* Move pointer past the uint8_t. */ cs->c_next++; return 0; } + +/* Unpack an 8-bit signed integer. */ +int +nd_cpack_int8(netdissect_options *ndo, struct cpack_state *cs, int8_t *u) +{ + /* No space left? */ + if ((size_t)(cs->c_next - cs->c_buf) >= cs->c_len) + return -1; + + *u = GET_S_1(cs->c_next); + + /* Move pointer past the int8_t. */ + cs->c_next++; + return 0; +} diff --git a/contrib/tcpdump/cpack.h b/contrib/tcpdump/cpack.h index 3072e0c374..4e89300cc2 100644 --- a/contrib/tcpdump/cpack.h +++ b/contrib/tcpdump/cpack.h @@ -27,8 +27,10 @@ * OF SUCH DAMAGE. */ -#ifndef _CPACK_H -#define _CPACK_H +#ifndef ND_CPACK_H +#define ND_CPACK_H + +#include "netdissect.h" struct cpack_state { const uint8_t *c_buf; @@ -36,21 +38,20 @@ struct cpack_state { size_t c_len; }; -int cpack_init(struct cpack_state *, const uint8_t *, size_t); - -int cpack_uint8(struct cpack_state *, uint8_t *); -int cpack_uint16(struct cpack_state *, uint16_t *); -int cpack_uint32(struct cpack_state *, uint32_t *); -int cpack_uint64(struct cpack_state *, uint64_t *); +int nd_cpack_init(struct cpack_state *, const uint8_t *, size_t); -const uint8_t *cpack_next_boundary(const uint8_t *buf, const uint8_t *p, size_t alignment); -const uint8_t *cpack_align_and_reserve(struct cpack_state *cs, size_t wordsize); +int nd_cpack_uint8(netdissect_options *, struct cpack_state *, uint8_t *); +int nd_cpack_int8(netdissect_options *, struct cpack_state *, int8_t *); +int nd_cpack_uint16(netdissect_options *, struct cpack_state *, uint16_t *); +int nd_cpack_int16(netdissect_options *, struct cpack_state *, int16_t *); +int nd_cpack_uint32(netdissect_options *, struct cpack_state *, uint32_t *); +int nd_cpack_int32(netdissect_options *, struct cpack_state *, int32_t *); +int nd_cpack_uint64(netdissect_options *, struct cpack_state *, uint64_t *); +int nd_cpack_int64(netdissect_options *, struct cpack_state *, int64_t *); -#define cpack_int8(__s, __p) cpack_uint8((__s), (uint8_t*)(__p)) -#define cpack_int16(__s, __p) cpack_uint16((__s), (uint16_t*)(__p)) -#define cpack_int32(__s, __p) cpack_uint32((__s), (uint32_t*)(__p)) -#define cpack_int64(__s, __p) cpack_uint64((__s), (uint64_t*)(__p)) +const uint8_t *nd_cpack_next_boundary(const uint8_t *buf, const uint8_t *p, size_t alignment); +const uint8_t *nd_cpack_align_and_reserve(struct cpack_state *cs, size_t wordsize); -extern int cpack_advance(struct cpack_state *, const size_t); +extern int nd_cpack_advance(struct cpack_state *, const size_t); -#endif /* _CPACK_H */ +#endif /* ND_CPACK_H */ diff --git a/contrib/tcpdump/ethertype.h b/contrib/tcpdump/ethertype.h index 2aa53a0882..a757a39c2f 100644 --- a/contrib/tcpdump/ethertype.h +++ b/contrib/tcpdump/ethertype.h @@ -19,6 +19,13 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ +/* + * Maximum length of the length field in an Ethernet header; any value + * greater than this is not a length value, so it's either an Ethernet + * type or an invalid value. + */ +#define MAX_ETHERNET_LENGTH_VAL 1500 + /* * Ethernet types. * @@ -106,8 +113,8 @@ #endif /* see: - http://en.wikipedia.org/wiki/IEEE_802.1Q - and http://en.wikipedia.org/wiki/QinQ + https://en.wikipedia.org/wiki/IEEE_802.1Q + and https://en.wikipedia.org/wiki/QinQ */ #ifndef ETHERTYPE_8021Q9100 #define ETHERTYPE_8021Q9100 0x9100 @@ -118,6 +125,9 @@ #ifndef ETHERTYPE_8021QinQ #define ETHERTYPE_8021QinQ 0x88a8 #endif +#ifndef ETHERTYPE_MACSEC +#define ETHERTYPE_MACSEC 0x88e5 +#endif #ifndef ETHERTYPE_IPX #define ETHERTYPE_IPX 0x8137 #endif @@ -145,6 +155,9 @@ #ifndef ETHERTYPE_PPPOES #define ETHERTYPE_PPPOES 0x8864 #endif +#ifndef ETHERTYPE_NSH +#define ETHERTYPE_NSH 0x894F +#endif #ifndef ETHERTYPE_PPPOED2 #define ETHERTYPE_PPPOED2 0x3c12 #endif @@ -169,6 +182,9 @@ #ifndef ETHERTYPE_AOE #define ETHERTYPE_AOE 0x88a2 #endif +#ifndef ETHERTYPE_PTP +#define ETHERTYPE_PTP 0x88f7 +#endif #ifndef ETHERTYPE_LOOPBACK #define ETHERTYPE_LOOPBACK 0x9000 #endif @@ -196,8 +212,8 @@ #ifndef ETHERTYPE_GEONET #define ETHERTYPE_GEONET 0x8947 /* ETSI GeoNetworking (Official IEEE registration from Jan 2013) */ #endif -#ifndef ETHERTYPE_MEDSA -#define ETHERTYPE_MEDSA 0xdada /* Marvel Distributed Switch Architecture */ +#ifndef ETHERTYPE_ARISTA +#define ETHERTYPE_ARISTA 0xd28b /* Arista Networks vendor specific EtherType */ #endif extern const struct tok ethertype_values[]; diff --git a/contrib/tcpdump/extract.h b/contrib/tcpdump/extract.h index 5969c22574..2ea7763a6e 100644 --- a/contrib/tcpdump/extract.h +++ b/contrib/tcpdump/extract.h @@ -19,18 +19,24 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ +#ifndef EXTRACT_H +#define EXTRACT_H + +#include + /* - * For 8-bit values; provided for the sake of completeness. Byte order + * For 8-bit values; needed to fetch a one-byte value. Byte order * isn't relevant, and alignment isn't an issue. */ -#define EXTRACT_8BITS(p) (*(p)) -#define EXTRACT_LE_8BITS(p) (*(p)) +#define EXTRACT_U_1(p) ((uint8_t)(*(p))) +#define EXTRACT_S_1(p) ((int8_t)(*(p))) /* * Inline functions or macros to extract possibly-unaligned big-endian * integral values. */ #include "funcattrs.h" +#include "netdissect.h" /* * If we have versions of GCC or Clang that support an __attribute__ @@ -62,19 +68,81 @@ #define UNALIGNED_OK #endif -#ifdef LBL_ALIGN +#if (defined(__i386__) || defined(_M_IX86) || defined(__X86__) || defined(__x86_64__) || defined(_M_X64)) || \ + (defined(__m68k__) && (!defined(__mc68000__) && !defined(__mc68010__))) || \ + (defined(__ppc__) || defined(__ppc64__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PPC64)) || \ + (defined(__s390__) || defined(__s390x__) || defined(__zarch__)) +/* + * The processor natively handles unaligned loads, so we can just + * cast the pointer and fetch through it. + * + * XXX - are those all the x86 tests we need? + * XXX - are those the only 68k tests we need not to generated + * unaligned accesses if the target is the 68000 or 68010? + * XXX - are there any tests we don't need, because some definitions are for + * compilers that also predefine the GCC symbols? + * XXX - do we need to test for both 32-bit and 64-bit versions of those + * architectures in all cases? + */ +UNALIGNED_OK static inline uint16_t +EXTRACT_BE_U_2(const void *p) +{ + return ((uint16_t)ntohs(*(const uint16_t *)(p))); +} + +UNALIGNED_OK static inline int16_t +EXTRACT_BE_S_2(const void *p) +{ + return ((int16_t)ntohs(*(const int16_t *)(p))); +} + +UNALIGNED_OK static inline uint32_t +EXTRACT_BE_U_4(const void *p) +{ + return ((uint32_t)ntohl(*(const uint32_t *)(p))); +} + +UNALIGNED_OK static inline int32_t +EXTRACT_BE_S_4(const void *p) +{ + return ((int32_t)ntohl(*(const int32_t *)(p))); +} + +UNALIGNED_OK static inline uint64_t +EXTRACT_BE_U_8(const void *p) +{ + return ((uint64_t)(((uint64_t)ntohl(*((const uint32_t *)(p) + 0))) << 32 | + ((uint64_t)ntohl(*((const uint32_t *)(p) + 1))) << 0)); + +} + +UNALIGNED_OK static inline int64_t +EXTRACT_BE_S_8(const void *p) +{ + return ((int64_t)(((int64_t)ntohl(*((const uint32_t *)(p) + 0))) << 32 | + ((uint64_t)ntohl(*((const uint32_t *)(p) + 1))) << 0)); + +} + /* - * The processor doesn't natively handle unaligned loads. + * Extract an IPv4 address, which is in network byte order, and not + * necessarily aligned, and provide the result in host byte order. */ -#if defined(__GNUC__) && defined(HAVE___ATTRIBUTE__) && \ +UNALIGNED_OK static inline uint32_t +EXTRACT_IPV4_TO_HOST_ORDER(const void *p) +{ + return ((uint32_t)ntohl(*(const uint32_t *)(p))); +} +#elif ND_IS_AT_LEAST_GNUC_VERSION(2,0) && \ (defined(__alpha) || defined(__alpha__) || \ defined(__mips) || defined(__mips__)) - /* -* This is a GCC-compatible compiler and we have __attribute__, which - * we assume that mean we have __attribute__((packed)), and this is - * MIPS or Alpha, which has instructions that can help when doing - * unaligned loads. + * This is MIPS or Alpha, which don't natively handle unaligned loads, + * but which have instructions that can help when doing unaligned + * loads, and this is GCC 2.0 or later or a compiler that claims to + * be GCC 2.0 or later, which we assume that mean we have + * __attribute__((packed)), which we can use to convince the compiler + * to generate those instructions. * * Declare packed structures containing a uint16_t and a uint32_t, * cast the pointer to point to one of those, and fetch through it; @@ -84,7 +152,7 @@ * * We do this in case the compiler can generate code using those * instructions to do an unaligned load and pass stuff to "ntohs()" or - * "ntohl()", which might be better than than the code to fetch the + * "ntohl()", which might be better than the code to fetch the * bytes one at a time and assemble them. (That might not be the * case on a little-endian platform, such as DEC's MIPS machines and * Alpha machines, where "ntohs()" and "ntohl()" might not be done @@ -124,46 +192,101 @@ typedef struct { uint16_t val; } __attribute__((packed)) unaligned_uint16_t; +typedef struct { + int16_t val; +} __attribute__((packed)) unaligned_int16_t; + typedef struct { uint32_t val; } __attribute__((packed)) unaligned_uint32_t; +typedef struct { + int32_t val; +} __attribute__((packed)) unaligned_int32_t; + UNALIGNED_OK static inline uint16_t -EXTRACT_16BITS(const void *p) +EXTRACT_BE_U_2(const void *p) { return ((uint16_t)ntohs(((const unaligned_uint16_t *)(p))->val)); } +UNALIGNED_OK static inline int16_t +EXTRACT_BE_S_2(const void *p) +{ + return ((int16_t)ntohs(((const unaligned_int16_t *)(p))->val)); +} + UNALIGNED_OK static inline uint32_t -EXTRACT_32BITS(const void *p) +EXTRACT_BE_U_4(const void *p) { return ((uint32_t)ntohl(((const unaligned_uint32_t *)(p))->val)); } +UNALIGNED_OK static inline int32_t +EXTRACT_BE_S_4(const void *p) +{ + return ((int32_t)ntohl(((const unaligned_int32_t *)(p))->val)); +} + UNALIGNED_OK static inline uint64_t -EXTRACT_64BITS(const void *p) +EXTRACT_BE_U_8(const void *p) { return ((uint64_t)(((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 0)->val)) << 32 | ((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 1)->val)) << 0)); } -#else /* have to do it a byte at a time */ +UNALIGNED_OK static inline int64_t +EXTRACT_BE_S_8(const void *p) +{ + return ((int64_t)(((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 0)->val)) << 32 | + ((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 1)->val)) << 0)); +} + /* - * This isn't a GCC-compatible compiler, we don't have __attribute__, + * Extract an IPv4 address, which is in network byte order, and not + * necessarily aligned, and provide the result in host byte order. + */ +UNALIGNED_OK static inline uint32_t +EXTRACT_IPV4_TO_HOST_ORDER(const void *p) +{ + return ((uint32_t)ntohl(((const unaligned_uint32_t *)(p))->val)); +} +#else +/* + * This architecture doesn't natively support unaligned loads, and either + * this isn't a GCC-compatible compiler, we don't have __attribute__, * or we do but we don't know of any better way with this instruction * set to do unaligned loads, so do unaligned loads of big-endian * quantities the hard way - fetch the bytes one at a time and * assemble them. + * + * XXX - ARM is a special case. ARMv1 through ARMv5 didn't suppory + * unaligned loads; ARMv6 and later support it *but* have a bit in + * the system control register that the OS can set and that causes + * unaligned loads to fault rather than succeeding. + * + * At least some OSes may set that flag, so we do *not* treat ARM + * as supporting unaligned loads. If your OS supports them on ARM, + * and you want to use them, please update the tests in the #if above + * to check for ARM *and* for your OS. */ -#define EXTRACT_16BITS(p) \ +#define EXTRACT_BE_U_2(p) \ ((uint16_t)(((uint16_t)(*((const uint8_t *)(p) + 0)) << 8) | \ ((uint16_t)(*((const uint8_t *)(p) + 1)) << 0))) -#define EXTRACT_32BITS(p) \ +#define EXTRACT_BE_S_2(p) \ + ((int16_t)(((uint16_t)(*((const uint8_t *)(p) + 0)) << 8) | \ + ((uint16_t)(*((const uint8_t *)(p) + 1)) << 0))) +#define EXTRACT_BE_U_4(p) \ ((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 24) | \ ((uint32_t)(*((const uint8_t *)(p) + 1)) << 16) | \ ((uint32_t)(*((const uint8_t *)(p) + 2)) << 8) | \ ((uint32_t)(*((const uint8_t *)(p) + 3)) << 0))) -#define EXTRACT_64BITS(p) \ +#define EXTRACT_BE_S_4(p) \ + ((int32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 24) | \ + ((uint32_t)(*((const uint8_t *)(p) + 1)) << 16) | \ + ((uint32_t)(*((const uint8_t *)(p) + 2)) << 8) | \ + ((uint32_t)(*((const uint8_t *)(p) + 3)) << 0))) +#define EXTRACT_BE_U_8(p) \ ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 56) | \ ((uint64_t)(*((const uint8_t *)(p) + 1)) << 48) | \ ((uint64_t)(*((const uint8_t *)(p) + 2)) << 40) | \ @@ -172,47 +295,133 @@ EXTRACT_64BITS(const void *p) ((uint64_t)(*((const uint8_t *)(p) + 5)) << 16) | \ ((uint64_t)(*((const uint8_t *)(p) + 6)) << 8) | \ ((uint64_t)(*((const uint8_t *)(p) + 7)) << 0))) -#endif /* must special-case unaligned accesses */ -#else /* LBL_ALIGN */ +#define EXTRACT_BE_S_8(p) \ + ((int64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 56) | \ + ((uint64_t)(*((const uint8_t *)(p) + 1)) << 48) | \ + ((uint64_t)(*((const uint8_t *)(p) + 2)) << 40) | \ + ((uint64_t)(*((const uint8_t *)(p) + 3)) << 32) | \ + ((uint64_t)(*((const uint8_t *)(p) + 4)) << 24) | \ + ((uint64_t)(*((const uint8_t *)(p) + 5)) << 16) | \ + ((uint64_t)(*((const uint8_t *)(p) + 6)) << 8) | \ + ((uint64_t)(*((const uint8_t *)(p) + 7)) << 0))) + /* - * The processor natively handles unaligned loads, so we can just - * cast the pointer and fetch through it. + * Extract an IPv4 address, which is in network byte order, and not + * necessarily aligned, and provide the result in host byte order. */ -static inline uint16_t UNALIGNED_OK -EXTRACT_16BITS(const void *p) +#define EXTRACT_IPV4_TO_HOST_ORDER(p) \ + ((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 24) | \ + ((uint32_t)(*((const uint8_t *)(p) + 1)) << 16) | \ + ((uint32_t)(*((const uint8_t *)(p) + 2)) << 8) | \ + ((uint32_t)(*((const uint8_t *)(p) + 3)) << 0))) +#endif /* unaligned access checks */ + +/* + * Extract numerical values in *host* byte order. (Some metadata + * headers are in the byte order of the host that wrote the file, + * and libpcap translate them to the byte order of the host + * reading the file. This means that if a program on that host + * reads with libpcap and writes to a new file, the new file will + * be written in the byte order of the host writing the file. Thus, + * the magic number in pcap files and byte-order magic in pcapng + * files can be used to determine the byte order in those metadata + * headers.) + * + * XXX - on platforms that can do unaligned accesses, just cast and + * dereference the pointer. + */ +static inline uint16_t +EXTRACT_HE_U_2(const void *p) { - return ((uint16_t)ntohs(*(const uint16_t *)(p))); + uint16_t val; + + UNALIGNED_MEMCPY(&val, p, sizeof(uint16_t)); + return val; } -static inline uint32_t UNALIGNED_OK -EXTRACT_32BITS(const void *p) +static inline int16_t +EXTRACT_HE_S_2(const void *p) { - return ((uint32_t)ntohl(*(const uint32_t *)(p))); + int16_t val; + + UNALIGNED_MEMCPY(&val, p, sizeof(int16_t)); + return val; } -static inline uint64_t UNALIGNED_OK -EXTRACT_64BITS(const void *p) +static inline uint32_t +EXTRACT_HE_U_4(const void *p) { - return ((uint64_t)(((uint64_t)ntohl(*((const uint32_t *)(p) + 0))) << 32 | - ((uint64_t)ntohl(*((const uint32_t *)(p) + 1))) << 0)); + uint32_t val; + UNALIGNED_MEMCPY(&val, p, sizeof(uint32_t)); + return val; } -#endif /* LBL_ALIGN */ +static inline int32_t +EXTRACT_HE_S_4(const void *p) +{ + int32_t val; + + UNALIGNED_MEMCPY(&val, p, sizeof(int32_t)); + return val; +} -#define EXTRACT_24BITS(p) \ +/* + * Extract an IPv4 address, which is in network byte order, and which + * is not necessarily aligned on a 4-byte boundary, and provide the + * result in network byte order. + * + * This works the same way regardless of the host's byte order. + */ +static inline uint32_t +EXTRACT_IPV4_TO_NETWORK_ORDER(const void *p) +{ + uint32_t addr; + + UNALIGNED_MEMCPY(&addr, p, sizeof(uint32_t)); + return addr; +} + +/* + * Non-power-of-2 sizes. + */ +#define EXTRACT_BE_U_3(p) \ ((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 16) | \ ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ ((uint32_t)(*((const uint8_t *)(p) + 2)) << 0))) -#define EXTRACT_40BITS(p) \ +#define EXTRACT_BE_S_3(p) \ + (((*((const uint8_t *)(p) + 0)) & 0x80) ? \ + ((int32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 16) | \ + ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ + ((uint32_t)(*((const uint8_t *)(p) + 2)) << 0))) : \ + ((int32_t)(0xFF000000U | \ + ((uint32_t)(*((const uint8_t *)(p) + 0)) << 16) | \ + ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ + ((uint32_t)(*((const uint8_t *)(p) + 2)) << 0)))) + +#define EXTRACT_BE_U_5(p) \ ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 32) | \ ((uint64_t)(*((const uint8_t *)(p) + 1)) << 24) | \ ((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \ ((uint64_t)(*((const uint8_t *)(p) + 3)) << 8) | \ ((uint64_t)(*((const uint8_t *)(p) + 4)) << 0))) -#define EXTRACT_48BITS(p) \ +#define EXTRACT_BE_S_5(p) \ + (((*((const uint8_t *)(p) + 0)) & 0x80) ? \ + ((int64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 32) | \ + ((uint64_t)(*((const uint8_t *)(p) + 1)) << 24) | \ + ((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \ + ((uint64_t)(*((const uint8_t *)(p) + 3)) << 8) | \ + ((uint64_t)(*((const uint8_t *)(p) + 4)) << 0))) : \ + ((int64_t)(INT64_T_CONSTANT(0xFFFFFF0000000000U) | \ + ((uint64_t)(*((const uint8_t *)(p) + 0)) << 32) | \ + ((uint64_t)(*((const uint8_t *)(p) + 1)) << 24) | \ + ((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \ + ((uint64_t)(*((const uint8_t *)(p) + 3)) << 8) | \ + ((uint64_t)(*((const uint8_t *)(p) + 4)) << 0)))) + +#define EXTRACT_BE_U_6(p) \ ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 40) | \ ((uint64_t)(*((const uint8_t *)(p) + 1)) << 32) | \ ((uint64_t)(*((const uint8_t *)(p) + 2)) << 24) | \ @@ -220,7 +429,23 @@ EXTRACT_64BITS(const void *p) ((uint64_t)(*((const uint8_t *)(p) + 4)) << 8) | \ ((uint64_t)(*((const uint8_t *)(p) + 5)) << 0))) -#define EXTRACT_56BITS(p) \ +#define EXTRACT_BE_S_6(p) \ + (((*((const uint8_t *)(p) + 0)) & 0x80) ? \ + ((int64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 40) | \ + ((uint64_t)(*((const uint8_t *)(p) + 1)) << 32) | \ + ((uint64_t)(*((const uint8_t *)(p) + 2)) << 24) | \ + ((uint64_t)(*((const uint8_t *)(p) + 3)) << 16) | \ + ((uint64_t)(*((const uint8_t *)(p) + 4)) << 8) | \ + ((uint64_t)(*((const uint8_t *)(p) + 5)) << 0))) : \ + ((int64_t)(INT64_T_CONSTANT(0xFFFFFFFF00000000U) | \ + ((uint64_t)(*((const uint8_t *)(p) + 0)) << 40) | \ + ((uint64_t)(*((const uint8_t *)(p) + 1)) << 32) | \ + ((uint64_t)(*((const uint8_t *)(p) + 2)) << 24) | \ + ((uint64_t)(*((const uint8_t *)(p) + 3)) << 16) | \ + ((uint64_t)(*((const uint8_t *)(p) + 4)) << 8) | \ + ((uint64_t)(*((const uint8_t *)(p) + 5)) << 0)))) + +#define EXTRACT_BE_U_7(p) \ ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 48) | \ ((uint64_t)(*((const uint8_t *)(p) + 1)) << 40) | \ ((uint64_t)(*((const uint8_t *)(p) + 2)) << 32) | \ @@ -229,23 +454,45 @@ EXTRACT_64BITS(const void *p) ((uint64_t)(*((const uint8_t *)(p) + 5)) << 8) | \ ((uint64_t)(*((const uint8_t *)(p) + 6)) << 0))) +#define EXTRACT_BE_S_7(p) \ + (((*((const uint8_t *)(p) + 0)) & 0x80) ? \ + ((int64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 48) | \ + ((uint64_t)(*((const uint8_t *)(p) + 1)) << 40) | \ + ((uint64_t)(*((const uint8_t *)(p) + 2)) << 32) | \ + ((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \ + ((uint64_t)(*((const uint8_t *)(p) + 4)) << 16) | \ + ((uint64_t)(*((const uint8_t *)(p) + 5)) << 8) | \ + ((uint64_t)(*((const uint8_t *)(p) + 6)) << 0))) : \ + ((int64_t)(INT64_T_CONSTANT(0xFFFFFFFFFF000000U) | \ + ((uint64_t)(*((const uint8_t *)(p) + 0)) << 48) | \ + ((uint64_t)(*((const uint8_t *)(p) + 1)) << 40) | \ + ((uint64_t)(*((const uint8_t *)(p) + 2)) << 32) | \ + ((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \ + ((uint64_t)(*((const uint8_t *)(p) + 4)) << 16) | \ + ((uint64_t)(*((const uint8_t *)(p) + 5)) << 8) | \ + ((uint64_t)(*((const uint8_t *)(p) + 6)) << 0)))) + /* * Macros to extract possibly-unaligned little-endian integral values. * XXX - do loads on little-endian machines that support unaligned loads? */ -#define EXTRACT_LE_16BITS(p) \ +#define EXTRACT_LE_U_2(p) \ ((uint16_t)(((uint16_t)(*((const uint8_t *)(p) + 1)) << 8) | \ ((uint16_t)(*((const uint8_t *)(p) + 0)) << 0))) -#define EXTRACT_LE_32BITS(p) \ +#define EXTRACT_LE_S_2(p) \ + ((int16_t)(((uint16_t)(*((const uint8_t *)(p) + 1)) << 8) | \ + ((uint16_t)(*((const uint8_t *)(p) + 0)) << 0))) +#define EXTRACT_LE_U_4(p) \ ((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 3)) << 24) | \ ((uint32_t)(*((const uint8_t *)(p) + 2)) << 16) | \ ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ ((uint32_t)(*((const uint8_t *)(p) + 0)) << 0))) -#define EXTRACT_LE_24BITS(p) \ - ((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 2)) << 16) | \ - ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ - ((uint32_t)(*((const uint8_t *)(p) + 0)) << 0))) -#define EXTRACT_LE_64BITS(p) \ +#define EXTRACT_LE_S_4(p) \ + ((int32_t)(((uint32_t)(*((const uint8_t *)(p) + 3)) << 24) | \ + ((uint32_t)(*((const uint8_t *)(p) + 2)) << 16) | \ + ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ + ((uint32_t)(*((const uint8_t *)(p) + 0)) << 0))) +#define EXTRACT_LE_U_8(p) \ ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 7)) << 56) | \ ((uint64_t)(*((const uint8_t *)(p) + 6)) << 48) | \ ((uint64_t)(*((const uint8_t *)(p) + 5)) << 40) | \ @@ -254,33 +501,415 @@ EXTRACT_64BITS(const void *p) ((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \ ((uint64_t)(*((const uint8_t *)(p) + 1)) << 8) | \ ((uint64_t)(*((const uint8_t *)(p) + 0)) << 0))) +#define EXTRACT_LE_S_8(p) \ + ((int64_t)(((uint64_t)(*((const uint8_t *)(p) + 7)) << 56) | \ + ((uint64_t)(*((const uint8_t *)(p) + 6)) << 48) | \ + ((uint64_t)(*((const uint8_t *)(p) + 5)) << 40) | \ + ((uint64_t)(*((const uint8_t *)(p) + 4)) << 32) | \ + ((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \ + ((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \ + ((uint64_t)(*((const uint8_t *)(p) + 1)) << 8) | \ + ((uint64_t)(*((const uint8_t *)(p) + 0)) << 0))) + +/* + * Non-power-of-2 sizes. + */ + +#define EXTRACT_LE_U_3(p) \ + ((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 2)) << 16) | \ + ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ + ((uint32_t)(*((const uint8_t *)(p) + 0)) << 0))) +#define EXTRACT_LE_S_3(p) \ + ((int32_t)(((uint32_t)(*((const uint8_t *)(p) + 2)) << 16) | \ + ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ + ((uint32_t)(*((const uint8_t *)(p) + 0)) << 0))) +#define EXTRACT_LE_U_5(p) \ + ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 4)) << 32) | \ + ((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \ + ((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \ + ((uint64_t)(*((const uint8_t *)(p) + 1)) << 8) | \ + ((uint64_t)(*((const uint8_t *)(p) + 0)) << 0))) +#define EXTRACT_LE_U_6(p) \ + ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 5)) << 40) | \ + ((uint64_t)(*((const uint8_t *)(p) + 4)) << 32) | \ + ((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \ + ((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \ + ((uint64_t)(*((const uint8_t *)(p) + 1)) << 8) | \ + ((uint64_t)(*((const uint8_t *)(p) + 0)) << 0))) +#define EXTRACT_LE_U_7(p) \ + ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 6)) << 48) | \ + ((uint64_t)(*((const uint8_t *)(p) + 5)) << 40) | \ + ((uint64_t)(*((const uint8_t *)(p) + 4)) << 32) | \ + ((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \ + ((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \ + ((uint64_t)(*((const uint8_t *)(p) + 1)) << 8) | \ + ((uint64_t)(*((const uint8_t *)(p) + 0)) << 0))) /* * Macros to check the presence of the values in question. */ -#define ND_TTEST_8BITS(p) ND_TTEST2(*(p), 1) -#define ND_TCHECK_8BITS(p) ND_TCHECK2(*(p), 1) +#define ND_TTEST_1(p) ND_TTEST_LEN((p), 1) +#define ND_TCHECK_1(p) ND_TCHECK_LEN((p), 1) + +#define ND_TTEST_2(p) ND_TTEST_LEN((p), 2) +#define ND_TCHECK_2(p) ND_TCHECK_LEN((p), 2) + +#define ND_TTEST_3(p) ND_TTEST_LEN((p), 3) +#define ND_TCHECK_3(p) ND_TCHECK_LEN((p), 3) + +#define ND_TTEST_4(p) ND_TTEST_LEN((p), 4) +#define ND_TCHECK_4(p) ND_TCHECK_LEN((p), 4) + +#define ND_TTEST_5(p) ND_TTEST_LEN((p), 5) +#define ND_TCHECK_5(p) ND_TCHECK_LEN((p), 5) + +#define ND_TTEST_6(p) ND_TTEST_LEN((p), 6) +#define ND_TCHECK_6(p) ND_TCHECK_LEN((p), 6) + +#define ND_TTEST_7(p) ND_TTEST_LEN((p), 7) +#define ND_TCHECK_7(p) ND_TCHECK_LEN((p), 7) + +#define ND_TTEST_8(p) ND_TTEST_LEN((p), 8) +#define ND_TCHECK_8(p) ND_TCHECK_LEN((p), 8) + +#define ND_TTEST_16(p) ND_TTEST_LEN((p), 16) +#define ND_TCHECK_16(p) ND_TCHECK_LEN((p), 16) + +static inline NORETURN void +nd_trunc_longjmp(netdissect_options *ndo) +{ + longjmp(ndo->ndo_early_end, ND_TRUNCATED); +} + +/* get_u_1 and get_s_1 */ + +static inline uint8_t +get_u_1(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_1(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_U_1(p); +} + +static inline int8_t +get_s_1(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_1(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_S_1(p); +} + +/* get_be_u_N */ + +static inline uint16_t +get_be_u_2(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_2(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_BE_U_2(p); +} + +static inline uint32_t +get_be_u_3(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_3(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_BE_U_3(p); +} + +static inline uint32_t +get_be_u_4(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_4(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_BE_U_4(p); +} + +static inline uint64_t +get_be_u_5(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_5(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_BE_U_5(p); +} + +static inline uint64_t +get_be_u_6(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_6(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_BE_U_6(p); +} + +static inline uint64_t +get_be_u_7(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_7(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_BE_U_7(p); +} + +static inline uint64_t +get_be_u_8(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_8(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_BE_U_8(p); +} + +/* get_be_s_N */ + +static inline int16_t +get_be_s_2(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_2(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_BE_S_2(p); +} + +static inline int32_t +get_be_s_3(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_3(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_BE_S_3(p); +} + +static inline int32_t +get_be_s_4(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_4(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_BE_S_4(p); +} + +static inline int64_t +get_be_s_5(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_5(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_BE_S_5(p); +} + +static inline int64_t +get_be_s_6(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_6(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_BE_S_6(p); +} + +static inline int64_t +get_be_s_7(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_7(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_BE_S_7(p); +} + +static inline int64_t +get_be_s_8(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_8(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_BE_S_8(p); +} + +/* get_he_u_N */ + +static inline uint16_t +get_he_u_2(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_2(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_HE_U_2(p); +} + +static inline uint32_t +get_he_u_4(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_4(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_HE_U_4(p); +} + +/* get_he_s_N */ + +static inline int16_t +get_he_s_2(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_2(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_HE_S_2(p); +} + +static inline int32_t +get_he_s_4(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_4(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_HE_S_4(p); +} + +/* get_le_u_N */ + +static inline uint16_t +get_le_u_2(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_2(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_LE_U_2(p); +} + +static inline uint32_t +get_le_u_3(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_3(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_LE_U_3(p); +} + +static inline uint32_t +get_le_u_4(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_4(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_LE_U_4(p); +} + +static inline uint64_t +get_le_u_5(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_5(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_LE_U_5(p); +} + +static inline uint64_t +get_le_u_6(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_6(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_LE_U_6(p); +} + +static inline uint64_t +get_le_u_7(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_7(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_LE_U_7(p); +} + +static inline uint64_t +get_le_u_8(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_8(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_LE_U_8(p); +} + +/* get_le_s_N */ + +static inline int16_t +get_le_s_2(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_2(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_LE_S_2(p); +} + +static inline int32_t +get_le_s_3(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_3(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_LE_S_3(p); +} + +static inline int32_t +get_le_s_4(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_4(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_LE_S_4(p); +} + +static inline int64_t +get_le_s_8(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_8(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_LE_S_8(p); +} + +/* get_ipv4_to_{host|network]_order */ + +static inline uint32_t +get_ipv4_to_host_order(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_4(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_IPV4_TO_HOST_ORDER(p); +} + +static inline uint32_t +get_ipv4_to_network_order(netdissect_options *ndo, const u_char *p) +{ + if (!ND_TTEST_4(p)) + nd_trunc_longjmp(ndo); + return EXTRACT_IPV4_TO_NETWORK_ORDER(p); +} + +static inline void +get_cpy_bytes(netdissect_options *ndo, u_char *dst, const u_char *p, size_t len) +{ + if (!ND_TTEST_LEN(p, len)) + nd_trunc_longjmp(ndo); + UNALIGNED_MEMCPY(dst, p, len); +} + +#define GET_U_1(p) get_u_1(ndo, (const u_char *)(p)) +#define GET_S_1(p) get_s_1(ndo, (const u_char *)(p)) + +#define GET_BE_U_2(p) get_be_u_2(ndo, (const u_char *)(p)) +#define GET_BE_U_3(p) get_be_u_3(ndo, (const u_char *)(p)) +#define GET_BE_U_4(p) get_be_u_4(ndo, (const u_char *)(p)) +#define GET_BE_U_5(p) get_be_u_5(ndo, (const u_char *)(p)) +#define GET_BE_U_6(p) get_be_u_6(ndo, (const u_char *)(p)) +#define GET_BE_U_7(p) get_be_u_7(ndo, (const u_char *)(p)) +#define GET_BE_U_8(p) get_be_u_8(ndo, (const u_char *)(p)) -#define ND_TTEST_16BITS(p) ND_TTEST2(*(p), 2) -#define ND_TCHECK_16BITS(p) ND_TCHECK2(*(p), 2) +#define GET_BE_S_2(p) get_be_s_2(ndo, (const u_char *)(p)) +#define GET_BE_S_3(p) get_be_s_3(ndo, (const u_char *)(p)) +#define GET_BE_S_4(p) get_be_s_4(ndo, (const u_char *)(p)) +#define GET_BE_S_5(p) get_be_s_5(ndo, (const u_char *)(p)) +#define GET_BE_S_6(p) get_be_s_6(ndo, (const u_char *)(p)) +#define GET_BE_S_7(p) get_be_s_7(ndo, (const u_char *)(p)) +#define GET_BE_S_8(p) get_be_s_8(ndo, (const u_char *)(p)) -#define ND_TTEST_24BITS(p) ND_TTEST2(*(p), 3) -#define ND_TCHECK_24BITS(p) ND_TCHECK2(*(p), 3) +#define GET_HE_U_2(p) get_he_u_2(ndo, (const u_char *)(p)) +#define GET_HE_U_4(p) get_he_u_4(ndo, (const u_char *)(p)) -#define ND_TTEST_32BITS(p) ND_TTEST2(*(p), 4) -#define ND_TCHECK_32BITS(p) ND_TCHECK2(*(p), 4) +#define GET_HE_S_2(p) get_he_s_2(ndo, (const u_char *)(p)) +#define GET_HE_S_4(p) get_he_s_4(ndo, (const u_char *)(p)) -#define ND_TTEST_40BITS(p) ND_TTEST2(*(p), 5) -#define ND_TCHECK_40BITS(p) ND_TCHECK2(*(p), 5) +#define GET_LE_U_2(p) get_le_u_2(ndo, (const u_char *)(p)) +#define GET_LE_U_3(p) get_le_u_3(ndo, (const u_char *)(p)) +#define GET_LE_U_4(p) get_le_u_4(ndo, (const u_char *)(p)) +#define GET_LE_U_5(p) get_le_u_5(ndo, (const u_char *)(p)) +#define GET_LE_U_6(p) get_le_u_6(ndo, (const u_char *)(p)) +#define GET_LE_U_7(p) get_le_u_7(ndo, (const u_char *)(p)) +#define GET_LE_U_8(p) get_le_u_8(ndo, (const u_char *)(p)) -#define ND_TTEST_48BITS(p) ND_TTEST2(*(p), 6) -#define ND_TCHECK_48BITS(p) ND_TCHECK2(*(p), 6) +#define GET_LE_S_2(p) get_le_s_2(ndo, (const u_char *)(p)) +#define GET_LE_S_3(p) get_le_s_3(ndo, (const u_char *)(p)) +#define GET_LE_S_4(p) get_le_s_4(ndo, (const u_char *)(p)) +#define GET_LE_S_8(p) get_le_s_8(ndo, (const u_char *)(p)) -#define ND_TTEST_56BITS(p) ND_TTEST2(*(p), 7) -#define ND_TCHECK_56BITS(p) ND_TCHECK2(*(p), 7) +#define GET_IPV4_TO_HOST_ORDER(p) get_ipv4_to_host_order(ndo, (const u_char *)(p)) +#define GET_IPV4_TO_NETWORK_ORDER(p) get_ipv4_to_network_order(ndo, (const u_char *)(p)) -#define ND_TTEST_64BITS(p) ND_TTEST2(*(p), 8) -#define ND_TCHECK_64BITS(p) ND_TCHECK2(*(p), 8) +#define GET_CPY_BYTES(dst, p, len) get_cpy_bytes(ndo, (u_char *)(dst), (const u_char *)(p), len) -#define ND_TTEST_128BITS(p) ND_TTEST2(*(p), 16) -#define ND_TCHECK_128BITS(p) ND_TCHECK2(*(p), 16) +#endif /* EXTRACT_H */ diff --git a/contrib/tcpdump/ether.h b/contrib/tcpdump/fptype.c similarity index 76% copy from contrib/tcpdump/ether.h copy to contrib/tcpdump/fptype.c index 6491678978..8a209bbb00 100644 --- a/contrib/tcpdump/ether.h +++ b/contrib/tcpdump/fptype.c @@ -29,29 +29,22 @@ * 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. - * - * @(#)if_ether.h 8.3 (Berkeley) 5/2/95 */ -#define ETHERMTU 1500 +#include -/* - * The number of bytes in an ethernet (MAC) address. - */ -#define ETHER_ADDR_LEN 6 +#include "netdissect-stdinc.h" -/* - * Structure of an Ethernet header. - */ -struct ether_header { - uint8_t ether_dhost[ETHER_ADDR_LEN]; - uint8_t ether_shost[ETHER_ADDR_LEN]; - uint16_t ether_length_type; -}; +#include "fptype.h" -/* - * Length of an Ethernet header; note that some compilers may pad - * "struct ether_header" to a multiple of 4 bytes, for example, so - * "sizeof (struct ether_header)" may not give the right answer. - */ -#define ETHER_HDRLEN 14 +void +float_type_check(uint32_t in) +{ + union { /* int to float conversion buffer */ + float f; + uint32_t i; + } f; + + f.i = in; + printf("%.3f\n", f.f*8/1000000); +} diff --git a/contrib/tcpdump/ether.h b/contrib/tcpdump/fptype.h similarity index 76% copy from contrib/tcpdump/ether.h copy to contrib/tcpdump/fptype.h index 6491678978..ad435bdd96 100644 --- a/contrib/tcpdump/ether.h +++ b/contrib/tcpdump/fptype.h @@ -29,29 +29,6 @@ * 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. - * - * @(#)if_ether.h 8.3 (Berkeley) 5/2/95 - */ - -#define ETHERMTU 1500 - -/* - * The number of bytes in an ethernet (MAC) address. */ -#define ETHER_ADDR_LEN 6 -/* - * Structure of an Ethernet header. - */ -struct ether_header { - uint8_t ether_dhost[ETHER_ADDR_LEN]; - uint8_t ether_shost[ETHER_ADDR_LEN]; - uint16_t ether_length_type; -}; - -/* - * Length of an Ethernet header; note that some compilers may pad - * "struct ether_header" to a multiple of 4 bytes, for example, so - * "sizeof (struct ether_header)" may not give the right answer. - */ -#define ETHER_HDRLEN 14 +extern void float_type_check(uint32_t); diff --git a/contrib/tcpdump/ftmacros.h b/contrib/tcpdump/ftmacros.h new file mode 100644 index 0000000000..3cd7505687 --- /dev/null +++ b/contrib/tcpdump/ftmacros.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) 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 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 Computer Systems + * Engineering Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory 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. + */ + +#ifndef ftmacros_h +#define ftmacros_h + +/* + * Define some feature test macros to make sure that everything we want + * to be declared gets declared. + * + * On some UN*Xes we need to force strtok_r() to be declared. + * We do *NOT* want to define _POSIX_C_SOURCE, as that tends + * to make non-POSIX APIs that we use unavailable. + * XXX - is there no portable way to say "please pollute the + * namespace to the maximum extent possible"? + */ +#if defined(sun) || defined(__sun) + #define __EXTENSIONS__ + + /* + * We also need to define _XPG4_2 in order to get + * the Single UNIX Specification version of + * recvmsg(). + */ + #define _XPG4_2 +#elif defined(_hpux) || defined(hpux) || defined(__hpux) + #define _REENTRANT + + /* + * We need this to get the versions of socket functions that + * use socklen_t. Define it only if it's not already defined, + * so we don't get redefiniton warnings. + */ + #ifndef _XOPEN_SOURCE_EXTENDED + #define _XOPEN_SOURCE_EXTENDED + #endif + + /* + * XXX - the list of PA-RISC options for GCC makes it sound as if + * building code that uses a particular vintage of UNIX API/ABI + * is complicated: + * + * https://gcc.gnu.org/onlinedocs/gcc/HPPA-Options.html + * + * See the description of the -munix flag. + * + * We probably want libpcap to work with programs built for any + * UN*X standard. I'm not sure whether that's possible and, if + * it is, what sort of stuff it'd have to do. + * + * It might also be a requirement that we build with a special + * flag to allow the library to be used with threaded code, at + * least with HP's C compiler; hopefully doing so won't make it + * *not* work with *un*-threaded code. + */ +#else + /* + * Turn on _GNU_SOURCE to get everything GNU libc has to offer, + * including asprintf(), if we're using GNU libc. + * + * Unfortunately, one thing it has to offer is a strerror_r() + * that's not POSIX-compliant, but we deal with that in + * pcap_fmt_errmsg_for_errno(). + * + * We don't limit this to, for example, Linux and Cygwin, because + * this might, for example, be GNU/HURD or one of Debian's kFreeBSD + * OSes ("GNU/FreeBSD"). + */ + #define _GNU_SOURCE + + /* + * We turn on both _DEFAULT_SOURCE and _BSD_SOURCE to try to get + * the BSD u_XXX types, such as u_int and u_short, defined. We + * define _DEFAULT_SOURCE first, so that newer versions of GNU libc + * don't whine about _BSD_SOURCE being deprecated; we still have + * to define _BSD_SOURCE to handle older versions of GNU libc that + * don't support _DEFAULT_SOURCE. + * + * But, if it's already defined, don't define it, so that we don't + * get a warning of it being redefined if it's defined as, for + * example, 1. + */ + #ifndef _DEFAULT_SOURCE + #define _DEFAULT_SOURCE + #endif + /* Avoid redefining _BSD_SOURCE if it's already defined as for ex. 1 */ + #ifndef _BSD_SOURCE + #define _BSD_SOURCE + #endif +#endif + +#endif diff --git a/contrib/tcpdump/funcattrs.h b/contrib/tcpdump/funcattrs.h index 63d3f5656c..f37e07e213 100644 --- a/contrib/tcpdump/funcattrs.h +++ b/contrib/tcpdump/funcattrs.h @@ -35,6 +35,8 @@ #ifndef lib_funcattrs_h #define lib_funcattrs_h +#include "compiler-tests.h" + /* * Attributes to apply to functions and their arguments, using various * compiler-specific extensions. @@ -43,7 +45,7 @@ /* * This was introduced by Clang: * - * http://clang.llvm.org/docs/LanguageExtensions.html#has-attribute + * https://clang.llvm.org/docs/LanguageExtensions.html#has-attribute * * in some version (which version?); it has been picked up by GCC 5.0. */ @@ -65,10 +67,10 @@ * declaration, as the MSVC version has to go before the declaration.) */ #if __has_attribute(noreturn) \ - || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)) \ - || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) \ - || (defined(__xlC__) && __xlC__ >= 0x0A01) \ - || (defined(__HP_aCC) && __HP_aCC >= 61000) + || ND_IS_AT_LEAST_GNUC_VERSION(2,5) \ + || ND_IS_AT_LEAST_SUNC_VERSION(5,9) \ + || ND_IS_AT_LEAST_XL_C_VERSION(10,1) \ + || ND_IS_AT_LEAST_HP_C_VERSION(6,10) /* * Compiler with support for __attribute((noreturn)), or GCC 2.5 and * later, or Solaris Studio 12 (Sun C 5.9) and later, or IBM XL C 10.1 @@ -76,13 +78,30 @@ * HP aCC A.06.10 and later. */ #define NORETURN __attribute((noreturn)) + + /* + * However, GCC didn't support that for function *pointers* until GCC + * 4.1.0; see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3481. + * + * Sun C/Oracle Studio C doesn't seem to support it, either. + */ + #if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) < 401)) \ + || (defined(__SUNPRO_C)) + #define NORETURN_FUNCPTR + #else + #define NORETURN_FUNCPTR __attribute((noreturn)) + #endif #elif defined(_MSC_VER) /* * MSVC. + * It doesn't allow __declspec(noreturn) to be applied to function + * pointers. */ #define NORETURN __declspec(noreturn) + #define NORETURN_FUNCPTR #else #define NORETURN + #define NORETURN_FUNCPTR #endif /* @@ -92,29 +111,36 @@ * string". */ #if __has_attribute(__format__) \ - || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203)) \ - || (defined(__xlC__) && __xlC__ >= 0x0A01) \ - || (defined(__HP_aCC) && __HP_aCC >= 61000) + || ND_IS_AT_LEAST_GNUC_VERSION(2,3) \ + || ND_IS_AT_LEAST_XL_C_VERSION(10,1) \ + || ND_IS_AT_LEAST_HP_C_VERSION(6,10) /* * Compiler with support for it, or GCC 2.3 and later, or IBM XL C 10.1 * and later (do any earlier versions of XL C support this?), * or HP aCC A.06.10 and later. */ #define PRINTFLIKE(x,y) __attribute__((__format__(__printf__,x,y))) + + /* + * However, GCC didn't support that for function *pointers* until GCC + * 4.1.0; see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3481. + */ + #if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) < 401)) + #define PRINTFLIKE_FUNCPTR(x,y) + #else + #define PRINTFLIKE_FUNCPTR(x,y) __attribute__((__format__(__printf__,x,y))) + #endif #else #define PRINTFLIKE(x,y) + #define PRINTFLIKE_FUNCPTR(x,y) #endif /* * For flagging arguments as format strings in MSVC. */ -#if _MSC_VER >= 1400 +#ifdef _MSC_VER #include - #if _MSC_VER > 1400 - #define FORMAT_STRING(p) _Printf_format_string_ p - #else - #define FORMAT_STRING(p) __format_string p - #endif + #define FORMAT_STRING(p) _Printf_format_string_ p #else #define FORMAT_STRING(p) p #endif diff --git a/contrib/tcpdump/getservent.h b/contrib/tcpdump/getservent.h new file mode 100644 index 0000000000..6fa5f361d1 --- /dev/null +++ b/contrib/tcpdump/getservent.h @@ -0,0 +1,67 @@ +/* +* Copyright (c) 1983, 1993 The Regents of the University of California. +* Copyright (c) 1993 Digital Equipment Corporation. +* Copyright (c) 2012 G. Vanem . +* Copyright (c) 2017 Ali Abdulkadir . +* 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. +*/ + +#ifndef ND_GETSERVENT_H +#define ND_GETSERVENT_H + +#ifdef _NETDB_H_ +/* Just in case... */ +#error netdb.h and getservent.h are incompatible +#else +#define _NETDB_H_ +#endif + +#ifdef _WIN32 +#define __PATH_SYSROOT "SYSTEMROOT" +#define __PATH_ETC_INET "\\System32\\drivers\\etc\\" +#define __PATH_SERVICES "services" +#else +/* +* The idea here is to be able to replace "PREFIX" in __PATH_SYSROOT with a variable +* that could, for example, point to an alternative install location. +*/ +#define __PATH_SYSROOT "PREFIX" +#define __PATH_ETC_INET "/etc/" +#define __PATH_SERVICES __PATH_ETC_INET"services" +#endif + +#define MAXALIASES 35 + +void endservent (void); +struct servent *getservent(void); +void setservent (int f); + +#endif /* ! ND_GETSERVENT_H */ diff --git a/contrib/tcpdump/gmpls.c b/contrib/tcpdump/gmpls.c index e527540ed0..f0646f1bd2 100644 --- a/contrib/tcpdump/gmpls.c +++ b/contrib/tcpdump/gmpls.c @@ -14,10 +14,10 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "gmpls.h" diff --git a/contrib/tcpdump/gmt2local.h b/contrib/tcpdump/gmt2local.h deleted file mode 100644 index 89254df9fe..0000000000 --- a/contrib/tcpdump/gmt2local.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 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 gmt2local_h -#define gmt2local_h - -int32_t gmt2local(time_t); -#endif diff --git a/contrib/tcpdump/in_cksum.c b/contrib/tcpdump/in_cksum.c index e9bed2287a..eb7c634f0a 100644 --- a/contrib/tcpdump/in_cksum.c +++ b/contrib/tcpdump/in_cksum.c @@ -36,10 +36,10 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +# include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" @@ -56,9 +56,9 @@ uint16_t in_cksum(const struct cksum_vec *vec, int veclen) { - register const uint16_t *w; - register int sum = 0; - register int mlen = 0; + const uint16_t *w; + int sum = 0; + int mlen = 0; int byte_swapped = 0; union { @@ -196,5 +196,5 @@ in_cksum_shouldbe(uint16_t sum, uint16_t computed_sum) shouldbe += ntohs(computed_sum); shouldbe = (shouldbe & 0xFFFF) + (shouldbe >> 16); shouldbe = (shouldbe & 0xFFFF) + (shouldbe >> 16); - return shouldbe; + return (uint16_t)shouldbe; } diff --git a/contrib/tcpdump/interface.h b/contrib/tcpdump/interface.h index 46d338b4af..d54172eef7 100644 --- a/contrib/tcpdump/interface.h +++ b/contrib/tcpdump/interface.h @@ -26,7 +26,7 @@ #include "os-proto.h" #endif -/* snprintf et al */ +#include "funcattrs.h" #include @@ -34,22 +34,6 @@ #include #endif -#if !defined(HAVE_SNPRINTF) -int snprintf(char *, size_t, const char *, ...) -#ifdef __ATTRIBUTE___FORMAT_OK - __attribute__((format(printf, 3, 4))) -#endif /* __ATTRIBUTE___FORMAT_OK */ - ; -#endif /* !defined(HAVE_SNPRINTF) */ - -#if !defined(HAVE_VSNPRINTF) -int vsnprintf(char *, size_t, const char *, va_list) -#ifdef __ATTRIBUTE___FORMAT_OK - __attribute__((format(printf, 3, 0))) -#endif /* __ATTRIBUTE___FORMAT_OK */ - ; -#endif /* !defined(HAVE_VSNPRINTF) */ - #ifndef HAVE_STRLCAT extern size_t strlcat(char *, const char *, size_t); #endif diff --git a/contrib/tcpdump/ip.h b/contrib/tcpdump/ip.h index 8179061ef1..ca87548fd0 100644 --- a/contrib/tcpdump/ip.h +++ b/contrib/tcpdump/ip.h @@ -51,13 +51,13 @@ */ struct ip { nd_uint8_t ip_vhl; /* header length, version */ -#define IP_V(ip) (((ip)->ip_vhl & 0xf0) >> 4) -#define IP_HL(ip) ((ip)->ip_vhl & 0x0f) +#define IP_V(ip) ((GET_U_1((ip)->ip_vhl) & 0xf0) >> 4) +#define IP_HL(ip) (GET_U_1((ip)->ip_vhl) & 0x0f) nd_uint8_t ip_tos; /* type of service */ nd_uint16_t ip_len; /* total length */ nd_uint16_t ip_id; /* identification */ nd_uint16_t ip_off; /* fragment offset field */ -#define IP_DF 0x4000 /* dont fragment flag */ +#define IP_DF 0x4000 /* don't fragment flag */ #define IP_MF 0x2000 /* more fragments flag */ #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ nd_uint8_t ip_ttl; /* time to live */ diff --git a/contrib/tcpdump/ip6.h b/contrib/tcpdump/ip6.h index 9a24ef143c..28725d05ef 100644 --- a/contrib/tcpdump/ip6.h +++ b/contrib/tcpdump/ip6.h @@ -65,8 +65,8 @@ * @(#)ip.h 8.1 (Berkeley) 6/10/93 */ -#ifndef _NETINET_IP6_H_ -#define _NETINET_IP6_H_ +#ifndef ND_IP6_H_ +#define ND_IP6_H_ /* * Definition for internet protocol version 6. @@ -76,19 +76,19 @@ struct ip6_hdr { union { struct ip6_hdrctl { - uint32_t ip6_un1_flow; /* 20 bits of flow-ID */ - uint16_t ip6_un1_plen; /* payload length */ - uint8_t ip6_un1_nxt; /* next header */ - uint8_t ip6_un1_hlim; /* hop limit */ + nd_uint32_t ip6_un1_flow; /* 20 bits of flow-ID */ + nd_uint16_t ip6_un1_plen; /* payload length */ + nd_uint8_t ip6_un1_nxt; /* next header */ + nd_uint8_t ip6_un1_hlim; /* hop limit */ } ip6_un1; - uint8_t ip6_un2_vfc; /* 4 bits version, top 4 bits class */ + nd_uint8_t ip6_un2_vfc; /* 4 bits version, top 4 bits class */ } ip6_ctlun; - struct in6_addr ip6_src; /* source address */ - struct in6_addr ip6_dst; /* destination address */ -} UNALIGNED; + nd_ipv6 ip6_src; /* source address */ + nd_ipv6 ip6_dst; /* destination address */ +}; #define ip6_vfc ip6_ctlun.ip6_un2_vfc -#define IP6_VERSION(ip6_hdr) (((ip6_hdr)->ip6_vfc & 0xf0) >> 4) +#define IP6_VERSION(ip6_hdr) ((GET_U_1((ip6_hdr)->ip6_vfc) & 0xf0) >> 4) #define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow #define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen #define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt @@ -98,36 +98,31 @@ struct ip6_hdr { /* in network endian */ #define IPV6_FLOWINFO_MASK ((uint32_t)htonl(0x0fffffff)) /* flow info (28 bits) */ #define IPV6_FLOWLABEL_MASK ((uint32_t)htonl(0x000fffff)) /* flow label (20 bits) */ -#if 1 -/* ECN bits proposed by Sally Floyd */ -#define IP6TOS_CE 0x01 /* congestion experienced */ -#define IP6TOS_ECT 0x02 /* ECN-capable transport */ -#endif /* * Extension Headers */ struct ip6_ext { - uint8_t ip6e_nxt; - uint8_t ip6e_len; -} UNALIGNED; + nd_uint8_t ip6e_nxt; + nd_uint8_t ip6e_len; +}; /* Hop-by-Hop options header */ struct ip6_hbh { - uint8_t ip6h_nxt; /* next header */ - uint8_t ip6h_len; /* length in units of 8 octets */ + nd_uint8_t ip6h_nxt; /* next header */ + nd_uint8_t ip6h_len; /* length in units of 8 octets */ /* followed by options */ -} UNALIGNED; +}; /* Destination options header */ struct ip6_dest { - uint8_t ip6d_nxt; /* next header */ - uint8_t ip6d_len; /* length in units of 8 octets */ + nd_uint8_t ip6d_nxt; /* next header */ + nd_uint8_t ip6d_len; /* length in units of 8 octets */ /* followed by options */ -} UNALIGNED; +}; -/* http://www.iana.org/assignments/ipv6-parameters/ipv6-parameters.xhtml */ +/* https://www.iana.org/assignments/ipv6-parameters/ipv6-parameters.xhtml */ /* Option types and related macros */ #define IP6OPT_PAD1 0x00 /* 00 0 00000 */ @@ -165,15 +160,16 @@ struct ip6_dest { /* Routing header */ struct ip6_rthdr { - uint8_t ip6r_nxt; /* next header */ - uint8_t ip6r_len; /* length in units of 8 octets */ - uint8_t ip6r_type; /* routing type */ - uint8_t ip6r_segleft; /* segments left */ + nd_uint8_t ip6r_nxt; /* next header */ + nd_uint8_t ip6r_len; /* length in units of 8 octets */ + nd_uint8_t ip6r_type; /* routing type */ + nd_uint8_t ip6r_segleft; /* segments left */ /* followed by routing type specific data */ -} UNALIGNED; +}; #define IPV6_RTHDR_TYPE_0 0 #define IPV6_RTHDR_TYPE_2 2 +#define IPV6_RTHDR_TYPE_4 4 /* Type 0 Routing header */ /* Also used for Type 2 */ @@ -183,19 +179,34 @@ struct ip6_rthdr0 { nd_uint8_t ip6r0_type; /* always zero */ nd_uint8_t ip6r0_segleft; /* segments left */ nd_uint32_t ip6r0_reserved; /* reserved field */ - struct in6_addr ip6r0_addr[1]; /* up to 23 addresses */ + nd_ipv6 ip6r0_addr[1]; /* up to 23 addresses */ +}; + +/** + * Type 4 Routing header + * known as Segment Routing Header 'SRH' + */ +struct ip6_srh { + nd_uint8_t srh_nxt; /* next header */ + nd_uint8_t srh_len; /* length in units of 8 octets */ + nd_uint8_t srh_type; /* Routing Type 4 */ + nd_uint8_t srh_segleft; /* segments left */ + nd_uint8_t srh_last_ent; /* Last Entry*/ + nd_uint8_t srh_flags; /* Flags */ + nd_uint16_t srh_tag; /* Tag */ + nd_ipv6 srh_segments[1]; /* SRH segments list*/ }; /* Fragment header */ struct ip6_frag { - uint8_t ip6f_nxt; /* next header */ - uint8_t ip6f_reserved; /* reserved field */ - uint16_t ip6f_offlg; /* offset, reserved, and flag */ - uint32_t ip6f_ident; /* identification */ -} UNALIGNED; + nd_uint8_t ip6f_nxt; /* next header */ + nd_uint8_t ip6f_reserved; /* reserved field */ + nd_uint16_t ip6f_offlg; /* offset, reserved, and flag */ + nd_uint32_t ip6f_ident; /* identification */ +}; #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 */ -#endif /* not _NETINET_IP6_H_ */ +#endif /* not ND_IP6_H_ */ diff --git a/contrib/tcpdump/ipproto.c b/contrib/tcpdump/ipproto.c index 16328f4d98..a3b0714a5a 100644 --- a/contrib/tcpdump/ipproto.c +++ b/contrib/tcpdump/ipproto.c @@ -14,10 +14,10 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "ipproto.h" @@ -46,11 +46,11 @@ const struct tok ipproto_values[] = { { IPPROTO_OSPF, "OSPF" }, { IPPROTO_PIM, "PIM" }, { IPPROTO_IPCOMP, "Compressed IP" }, - { IPPROTO_VRRP, "VRRP" }, + { IPPROTO_VRRP, "VRRP" }, /* See also CARP. */ { IPPROTO_PGM, "PGM" }, { IPPROTO_SCTP, "SCTP" }, { IPPROTO_MOBILITY, "Mobility" }, - { IPPROTO_CARP, "CARP" }, + { IPPROTO_ETHERNET, "Ethernet" }, { 0, NULL } }; @@ -356,7 +356,7 @@ static const char *netdb_protocol_names[256] = { /* The function enforces the array index to be 8-bit. */ const char * -netdb_protoname (const nd_uint8_t protoid) +netdb_protoname (const uint8_t protoid) { return netdb_protocol_names[protoid]; } diff --git a/contrib/tcpdump/ipproto.h b/contrib/tcpdump/ipproto.h index ed327857bc..baec4bdc24 100644 --- a/contrib/tcpdump/ipproto.h +++ b/contrib/tcpdump/ipproto.h @@ -36,7 +36,7 @@ */ extern const struct tok ipproto_values[]; -extern const char *netdb_protoname (const nd_uint8_t); +extern const char *netdb_protoname (const uint8_t); #ifndef IPPROTO_IP #define IPPROTO_IP 0 /* dummy for IP */ @@ -104,8 +104,7 @@ extern const char *netdb_protoname (const nd_uint8_t); #ifndef IPPROTO_MOBILITY_OLD /* * The current Protocol Numbers list says that the IP protocol number for - * mobility headers is 135; it cites draft-ietf-mobileip-ipv6-24, but - * that draft doesn't actually give a number. + * mobility headers is 135; it cites RFC 6275 (obsoletes RFC 3775). * * It appears that 62 used to be used, even though that's assigned to * a protocol called CFTP; however, the only reference for CFTP is a @@ -130,10 +129,7 @@ extern const char *netdb_protoname (const nd_uint8_t); #define IPPROTO_IPCOMP 108 #endif #ifndef IPPROTO_VRRP -#define IPPROTO_VRRP 112 -#endif -#ifndef IPPROTO_CARP -#define IPPROTO_CARP 112 +#define IPPROTO_VRRP 112 /* See also CARP. */ #endif #ifndef IPPROTO_PGM #define IPPROTO_PGM 113 @@ -144,3 +140,6 @@ extern const char *netdb_protoname (const nd_uint8_t); #ifndef IPPROTO_MOBILITY #define IPPROTO_MOBILITY 135 #endif +#ifndef IPPROTO_ETHERNET +#define IPPROTO_ETHERNET 143 /* TEMPORARY - registered 2020-01-31, expires 2021-01-31 */ +#endif diff --git a/contrib/tcpdump/l2vpn.c b/contrib/tcpdump/l2vpn.c index b0f6682a51..9111cf6d25 100644 --- a/contrib/tcpdump/l2vpn.c +++ b/contrib/tcpdump/l2vpn.c @@ -14,10 +14,10 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "l2vpn.h" @@ -26,7 +26,7 @@ * * RFC 6624 * - * http://www.iana.org/assignments/bgp-parameters/bgp-parameters.xhtml#bgp-l2-encapsulation-types-registry + * https://www.iana.org/assignments/bgp-parameters/bgp-parameters.xhtml#bgp-l2-encapsulation-types-registry */ const struct tok l2vpn_encaps_values[] = { { 0, "Reserved"}, @@ -61,7 +61,7 @@ const struct tok l2vpn_encaps_values[] = { * * RFC 4446 * - * http://www.iana.org/assignments/pwe3-parameters/pwe3-parameters.xhtml#pwe3-parameters-2 + * https://www.iana.org/assignments/pwe3-parameters/pwe3-parameters.xhtml#pwe3-parameters-2 */ const struct tok mpls_pw_types_values[] = { { 0x0000, "Reserved"}, diff --git a/contrib/tcpdump/machdep.c b/contrib/tcpdump/machdep.c index 1f08616113..2578b73c0c 100644 --- a/contrib/tcpdump/machdep.c +++ b/contrib/tcpdump/machdep.c @@ -20,34 +20,18 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -/* - * XXX - all we need, on platforms other than DEC OSF/1 (a/k/a Digital UNIX, - * a/k/a Tru64 UNIX), is "size_t", which is a standard C type; what do we - * need to do to get it defined? This is clearly wrong, as we shouldn't - * have to include UNIX or Windows system header files to get it. - */ -#include - -#ifndef HAVE___ATTRIBUTE__ -#define __attribute__(x) -#endif /* HAVE___ATTRIBUTE__ */ +#include #ifdef __osf__ +#include #include #include - -#if !defined(HAVE_SNPRINTF) -int snprintf(char *, size_t, const char *, ...) -#ifdef __ATTRIBUTE___FORMAT_OK - __attribute__((format(printf, 3, 4))) -#endif /* __ATTRIBUTE___FORMAT_OK */ - ; -#endif /* !defined(HAVE_SNPRINTF) */ #endif /* __osf__ */ +#include "varattrs.h" #include "machdep.h" /* diff --git a/contrib/tcpdump/nameser.h b/contrib/tcpdump/nameser.h index e075f09228..526c60cab3 100644 --- a/contrib/tcpdump/nameser.h +++ b/contrib/tcpdump/nameser.h @@ -175,7 +175,7 @@ #define T_UID 101 /* user ID */ #define T_GID 102 /* group ID */ #define T_UNSPEC 103 /* Unspecified format (binary data) */ -#define T_UNSPECA 104 /* "unspecified ascii". Ugly MIT hack */ +#define T_UNSPECA 104 /* "unspecified ASCII". Ugly MIT hack */ /* Query type values which do not appear in resource records */ #define T_TKEY 249 /* Transaction Key [RFC2930] */ #define T_TSIG 250 /* Transaction Signature [RFC2845] */ @@ -184,6 +184,7 @@ #define T_MAILB 253 /* transfer mailbox records */ #define T_MAILA 254 /* transfer mail agent records */ #define T_ANY 255 /* wildcard match */ +#define T_URI 256 /* uri records [RFC7553] */ /* * Values for class field @@ -197,6 +198,64 @@ #define C_QU 0x8000 /* mDNS QU flag in queries */ #define C_CACHE_FLUSH 0x8000 /* mDNS cache flush flag in replies */ +/* + * Values for EDNS option types + */ +#define E_LLQ 1 /* long lived queries protocol */ +#define E_UL 2 /* dynamic dns update leases */ +#define E_NSID 3 /* name server identifier */ +#define E_DAU 5 /* signal DNSSEC algorithm understood */ +#define E_DHU 6 /* signal DS hash understood */ +#define E_N3U 7 /* signal NSEC3 hash understood */ +#define E_ECS 8 /* EDNS client subnet */ +#define E_EXPIRE 9 /* zone expiration */ +#define E_COOKIE 10 /* DNS cookies */ +#define E_KEEPALIVE 11 /* TCP keepalive */ +#define E_PADDING 12 /* pad DNS messages */ +#define E_CHAIN 13 /* chain DNS queries */ +#define E_KEYTAG 14 /* EDNS key tag */ +#define E_CLIENTTAG 16 /* EDNS client tag */ +#define E_SERVERTAG 17 /* EDNS server tag */ + +/* + * Values for DNSSEC Algorithms + * https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml + */ + +#define A_DELETE 0 +#define A_RSAMD5 1 +#define A_DH 2 +#define A_DSA 3 +#define A_RSASHA1 5 +#define A_DSA_NSEC3_SHA1 6 +#define A_RSASHA1_NSEC3_SHA1 7 +#define A_RSASHA256 8 +#define A_RSASHA512 10 +#define A_ECC_GOST 12 +#define A_ECDSAP256SHA256 13 +#define A_ECDSAP384SHA384 14 +#define A_ED25519 15 +#define A_ED448 16 +#define A_INDIRECT 252 +#define A_PRIVATEDNS 253 +#define A_PRIVATEOID 254 + +/* + * Values for NSEC3 algorithms + * https://www.iana.org/assignments/dnssec-nsec3-parameters/dnssec-nsec3-parameters.xhtml + */ +#define NSEC_SHA1 1 + +/* + * Values for delegation signer algorithms + * https://www.iana.org/assignments/ds-rr-types/ds-rr-types.xhtml + */ +#define DS_SHA1 1 +#define DS_SHA256 2 +#define DS_GOST 3 +#define DS_SHA384 4 + + /* * Status return codes for T_UNSPEC conversion routines */ @@ -210,91 +269,35 @@ * Structure for query header. */ typedef struct { - uint16_t id; /* query identification number */ - uint8_t flags1; /* first byte of flags */ - uint8_t flags2; /* second byte of flags */ - uint16_t qdcount; /* number of question entries */ - uint16_t ancount; /* number of answer entries */ - uint16_t nscount; /* number of authority entries */ - uint16_t arcount; /* number of resource entries */ -} HEADER; + nd_uint16_t id; /* query identification number */ + nd_uint16_t flags; /* QR, Opcode, AA, TC, RD, RA, RCODE */ + nd_uint16_t qdcount; /* number of question entries */ + nd_uint16_t ancount; /* number of answer entries */ + nd_uint16_t nscount; /* number of authority entries */ + nd_uint16_t arcount; /* number of resource entries */ +} dns_header_t; /* * Macros for subfields of flag fields. */ -#define DNS_QR(np) ((np)->flags1 & 0x80) /* response flag */ -#define DNS_OPCODE(np) ((((np)->flags1) >> 3) & 0xF) /* purpose of message */ -#define DNS_AA(np) ((np)->flags1 & 0x04) /* authoritative answer */ -#define DNS_TC(np) ((np)->flags1 & 0x02) /* truncated message */ -#define DNS_RD(np) ((np)->flags1 & 0x01) /* recursion desired */ - -#define DNS_RA(np) ((np)->flags2 & 0x80) /* recursion available */ -#define DNS_AD(np) ((np)->flags2 & 0x20) /* authentic data from named */ -#define DNS_CD(np) ((np)->flags2 & 0x10) /* checking disabled by resolver */ -#define DNS_RCODE(np) ((np)->flags2 & 0xF) /* response code */ +#define DNS_QR(flags) ((flags) & 0x8000) /* response flag */ +#define DNS_OPCODE(flags) (((flags) >> 11) & 0xF) /* purpose of message */ +#define DNS_AA(flags) (flags & 0x0400) /* authoritative answer */ +#define DNS_TC(flags) (flags & 0x0200) /* truncated message */ +#define DNS_RD(flags) (flags & 0x0100) /* recursion desired */ +#define DNS_RA(flags) (flags & 0x0080) /* recursion available */ +#define DNS_AD(flags) (flags & 0x0020) /* authentic data from named */ +#define DNS_CD(flags) (flags & 0x0010) /* checking disabled by resolver */ +#define DNS_RCODE(flags) (flags & 0x000F) /* response code */ /* * Defines for handling compressed domain names, EDNS0 labels, etc. */ -#define INDIR_MASK 0xc0 /* 11.... */ -#define EDNS0_MASK 0x40 /* 01.... */ +#define TYPE_MASK 0xc0 /* mask for the type bits of the item */ +#define TYPE_INDIR 0xc0 /* 11.... - pointer */ +#define TYPE_RESERVED 0x80 /* 10.... - reserved */ +#define TYPE_EDNS0 0x40 /* 01.... - EDNS(0) label */ +#define TYPE_LABEL 0x00 /* 00.... - regular label */ # define EDNS0_ELT_BITLABEL 0x01 -/* - * Structure for passing resource records around. - */ -struct rrec { - int16_t r_zone; /* zone number */ - int16_t r_class; /* class number */ - int16_t r_type; /* type number */ - uint32_t r_ttl; /* time to live */ - int r_size; /* size of data area */ - char *r_data; /* pointer to data */ -}; - -/* - * Inline versions of get/put short/long. Pointer is advanced. - * We also assume that a "uint16_t" holds 2 "chars" - * and that a "uint32_t" holds 4 "chars". - * - * These macros demonstrate the property of C whereby it can be - * portable or it can be elegant but never both. - */ -#define GETSHORT(s, cp) { \ - register u_char *t_cp = (u_char *)(cp); \ - (s) = ((uint16_t)t_cp[0] << 8) | (uint16_t)t_cp[1]; \ - (cp) += 2; \ -} - -#define GETLONG(l, cp) { \ - register u_char *t_cp = (u_char *)(cp); \ - (l) = (((uint32_t)t_cp[0]) << 24) \ - | (((uint32_t)t_cp[1]) << 16) \ - | (((uint32_t)t_cp[2]) << 8) \ - | (((uint32_t)t_cp[3])); \ - (cp) += 4; \ -} - -#define PUTSHORT(s, cp) { \ - register uint16_t t_s = (uint16_t)(s); \ - register u_char *t_cp = (u_char *)(cp); \ - *t_cp++ = t_s >> 8; \ - *t_cp = t_s; \ - (cp) += 2; \ -} - -/* - * Warning: PUTLONG --no-longer-- destroys its first argument. if you - * were depending on this "feature", you will lose. - */ -#define PUTLONG(l, cp) { \ - register uint32_t t_l = (uint32_t)(l); \ - register u_char *t_cp = (u_char *)(cp); \ - *t_cp++ = t_l >> 24; \ - *t_cp++ = t_l >> 16; \ - *t_cp++ = t_l >> 8; \ - *t_cp = t_l; \ - (cp) += 4; \ -} - #endif /* !_NAMESER_H_ */ diff --git a/contrib/tcpdump/netdissect-alloc.c b/contrib/tcpdump/netdissect-alloc.c new file mode 100644 index 0000000000..bbae56ee83 --- /dev/null +++ b/contrib/tcpdump/netdissect-alloc.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2018 The TCPDUMP project + * 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, 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. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include "netdissect-alloc.h" + +/* + * nd_free_all() is intended to be used after a packet printing + */ + +/* Add a memory chunk in allocation linked list */ +void +nd_add_alloc_list(netdissect_options *ndo, nd_mem_chunk_t *chunkp) +{ + if (ndo->ndo_last_mem_p == NULL) /* first memory allocation */ + chunkp->prev_mem_p = NULL; + else /* previous memory allocation */ + chunkp->prev_mem_p = ndo->ndo_last_mem_p; + ndo->ndo_last_mem_p = chunkp; +} + +/* malloc replacement, with tracking in a linked list */ +void * +nd_malloc(netdissect_options *ndo, size_t size) +{ + nd_mem_chunk_t *chunkp = malloc(sizeof(nd_mem_chunk_t) + size); + if (chunkp == NULL) + return NULL; + nd_add_alloc_list(ndo, chunkp); + return chunkp + 1; +} + +/* Free chunks in allocation linked list from last to first */ +void +nd_free_all(netdissect_options *ndo) +{ + nd_mem_chunk_t *current, *previous; + current = ndo->ndo_last_mem_p; + while (current != NULL) { + previous = current->prev_mem_p; + free(current); + current = previous; + } + ndo->ndo_last_mem_p = NULL; +} diff --git a/contrib/tcpdump/print-ftp.c b/contrib/tcpdump/netdissect-alloc.h similarity index 59% copy from contrib/tcpdump/print-ftp.c copy to contrib/tcpdump/netdissect-alloc.h index a1dd60709a..aa28a36889 100644 --- a/contrib/tcpdump/print-ftp.c +++ b/contrib/tcpdump/netdissect-alloc.h @@ -1,4 +1,7 @@ /* + * Copyright (c) 2018 The TCPDUMP project + * 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 @@ -11,22 +14,20 @@ * FOR A PARTICULAR PURPOSE. */ -/* \summary: File Transfer Protocol (FTP) printer */ +#ifndef netdissect_alloc_h +#define netdissect_alloc_h -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include +#include +#include "netdissect-stdinc.h" +#include "netdissect.h" -#include -#include +typedef struct nd_mem_chunk { + void *prev_mem_p; + /* variable size data */ +} nd_mem_chunk_t; -#include "netdissect.h" -#include "extract.h" +void nd_add_alloc_list(netdissect_options *, nd_mem_chunk_t *); +void * nd_malloc(netdissect_options *, size_t); +void nd_free_all(netdissect_options *); -void -ftp_print(netdissect_options *ndo, const u_char *pptr, u_int len) -{ - txtproto_print(ndo, pptr, len, "ftp", NULL, 0); -} +#endif /* netdissect_alloc_h */ diff --git a/contrib/tcpdump/netdissect-ctype.h b/contrib/tcpdump/netdissect-ctype.h new file mode 100644 index 0000000000..ae4a3ce0a5 --- /dev/null +++ b/contrib/tcpdump/netdissect-ctype.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 1988-1997 + * The Regents of the University of California. All rights reserved. + * + * Copyright (c) 1998-2012 Michael Richardson + * 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, (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 netdissect_ctype_h +#define netdissect_ctype_h + +/* + * Locale-independent macros for testing character properties and + * stripping the 8th bit from characters. + * + * Byte values outside the ASCII range are considered unprintable, so + * both ND_ASCII_ISPRINT() and ND_ASCII_ISGRAPH() return "false" for them. + * + * Assumed to be handed a value between 0 and 255, i.e. don't hand them + * a char, as those might be in the range -128 to 127. + */ +#define ND_ISASCII(c) (!((c) & 0x80)) /* value is an ASCII code point */ +#define ND_ASCII_ISPRINT(c) ((c) >= 0x20 && (c) <= 0x7E) +#define ND_ASCII_ISGRAPH(c) ((c) > 0x20 && (c) <= 0x7E) +#define ND_ASCII_ISDIGIT(c) ((c) >= '0' && (c) <= '9') +#define ND_TOASCII(c) ((c) & 0x7F) + +/* + * Locale-independent macros for coverting to upper or lower case. + * + * Byte values outside the ASCII range are not converted. Byte values + * *in* the ASCII range are converted to byte values in the ASCII range; + * in particular, 'i' is upper-cased to 'I" and 'I' is lower-cased to 'i', + * even in Turkish locales. + */ +#define ND_ASCII_TOLOWER(c) (((c) >= 'A' && (c) <= 'Z') ? (c) - 'A' + 'a' : (c)) +#define ND_ASCII_TOUPPER(c) (((c) >= 'a' && (c) <= 'z') ? (c) - 'a' + 'A' : (c)) + +#endif /* netdissect-ctype.h */ + diff --git a/contrib/tcpdump/netdissect-stdinc.h b/contrib/tcpdump/netdissect-stdinc.h index 8282c58462..0523620f39 100644 --- a/contrib/tcpdump/netdissect-stdinc.h +++ b/contrib/tcpdump/netdissect-stdinc.h @@ -39,120 +39,160 @@ #ifndef netdissect_stdinc_h #define netdissect_stdinc_h +#include "ftmacros.h" + #include +#include "compiler-tests.h" + +#include "varattrs.h" + +/* + * If we're compiling with Visual Studio, make sure we have at least + * VS 2015 or later, so we have sufficient C99 support. + * + * XXX - verify that we have at least C99 support on UN*Xes? + * + * What about MinGW or various DOS toolchains? We're currently assuming + * sufficient C99 support there. + */ +#if defined(_MSC_VER) + /* + * Make sure we have VS 2015 or later. + */ + #if _MSC_VER < 1900 + #error "Building tcpdump requires VS 2015 or later" + #endif +#endif + +/* + * Get the C99 types, and the PRI[doux]64 format strings, defined. + */ +#ifdef HAVE_PCAP_PCAP_INTTYPES_H + /* + * We have pcap/pcap-inttypes.h; use that, as it'll do all the + * work, and won't cause problems if a file includes this file + * and later includes a pcap header file that also includes + * pcap/pcap-inttypes.h. + */ + #include +#else + /* + * OK, we don't have pcap/pcap-inttypes.h, so we'll have to + * do the work ourselves, but at least we don't have to + * worry about other headers including it and causing + * clashes. + */ + + /* + * Include to get the integer types and PRi[doux]64 values + * defined. + * + * If the compiler is MSVC, we require VS 2015 or newer, so we + * have - and support for %zu in the formatted + * printing functions. + * + * If the compiler is MinGW, we assume we have - and + * support for %zu in the formatted printing functions. + * + * If the target is UN*X, we assume we have a C99-or-later development + * environment, and thus have - and support for %zu in + * the formatted printing functions. + * + * If the target is MS-DOS, we assume we have - and support + * for %zu in the formatted printing functions. + */ + #include + + #if defined(_MSC_VER) + /* + * Suppress definition of intN_t in bittypes.h, which might be included + * by in older versions of WinPcap. + * (Yes, HAVE_U_INTn_T, as the definition guards are UN*X-oriented.) + */ + #define HAVE_U_INT8_T + #define HAVE_U_INT16_T + #define HAVE_U_INT32_T + #define HAVE_U_INT64_T + #endif +#endif /* HAVE_PCAP_PCAP_INTTYPES_H */ + #ifdef _WIN32 /* * Includes and definitions for Windows. */ -#include #include #include #include -#include #include #include #include #include -#ifndef uint8_t -#define uint8_t unsigned char -#endif - -#ifndef int8_t -#define int8_t signed char -#endif - -#ifndef uint16_t -#define uint16_t unsigned short -#endif - -#ifndef int16_t -#define int16_t signed short -#endif - -#ifndef uint32_t -#define uint32_t unsigned int -#endif - -#ifndef int32_t -#define int32_t signed int -#endif - -#ifdef _MSC_EXTENSIONS - -#ifndef uint64_t -#define uint64_t unsigned _int64 -#endif - -#ifndef int64_t -#define int64_t _int64 -#endif - -#ifndef PRId64 -#define PRId64 "I64d" -#endif - -#ifndef PRIo64 -#define PRIo64 "I64o" -#endif - -#ifndef PRIu64 -#define PRIu64 "I64u" -#endif - -#ifndef PRIx64 -#define PRIx64 "I64x" -#endif - -#else /* _MSC_EXTENSIONS */ - -#ifndef uint64_t -#define uint64_t unsigned long long -#endif - -#ifndef int64_t -#define int64_t long long -#endif - -#ifndef PRId64 -#define PRId64 "lld" -#endif - -#ifndef PRIo64 -#define PRIo64 "llo" -#endif - -#ifndef PRIu64 -#define PRIu64 "llu" -#endif +#ifdef _MSC_VER + /* + * Compiler is MSVC. + * + * We require VS 2015 or newer, so we have strtoll(). Use that for + * strtoint64_t(). + */ + #define strtoint64_t strtoll + + /* + * And we have LL as a suffix for constants, so use that. + */ + #define INT64_T_CONSTANT(constant) (constant##LL) +#else + /* + * Non-Microsoft compiler. + * + * XXX - should we use strtoll or should we use _strtoi64()? + */ + #define strtoint64_t strtoll -#ifndef PRIx64 -#define PRIx64 "llx" + /* + * Assume LL works. + */ + #define INT64_T_CONSTANT(constant) (constant##LL) #endif -#endif /* _MSC_EXTENSIONS */ - -/* - * Suppress definition of intN_t in bittypes.h, as included by - * on Windows. - * (Yes, HAVE_U_INTn_T, as the definition guards are UN*X-oriented, and - * we check for u_intN_t in the UN*X configure script.) - */ -#define HAVE_U_INT8_T -#define HAVE_U_INT16_T -#define HAVE_U_INT32_T -#define HAVE_U_INT64_T - #ifdef _MSC_VER -#define stat _stat -#define open _open -#define fstat _fstat -#define read _read -#define close _close -#define O_RDONLY _O_RDONLY + /* + * Microsoft tries to avoid polluting the C namespace with UN*Xisms, + * by adding a preceding underscore; we *want* the UN*Xisms, so add + * #defines to let us use them. + */ + #define isatty _isatty + #define stat _stat + #define strdup _strdup + #define open _open + #define read _read + #define close _close + #define O_RDONLY _O_RDONLY + + /* + * We define our_fstat64 as _fstati64, and define our_statb as + * struct _stati64, so we get 64-bit file sizes. + */ + #define our_fstat _fstati64 + #define our_statb struct _stati64 + + /* + * If has been included, and _DEBUG is defined, and + * __STDC__ is zero, will define strdup() to call + * _strdup_dbg(). So if it's already defined, don't redefine + * it. + */ + #ifndef strdup + #define strdup _strdup + #endif + + /* + * Windows doesn't have ssize_t; routines such as _read() return int. + */ + typedef int ssize_t; #endif /* _MSC_VER */ /* @@ -162,7 +202,7 @@ #define inline __inline #endif -#ifdef AF_INET6 +#if defined(AF_INET6) && !defined(HAVE_OS_IPV6_SUPPORT) #define HAVE_OS_IPV6_SUPPORT #endif @@ -181,9 +221,6 @@ typedef char* caddr_t; #endif /* caddr_t */ #define MAXHOSTNAMELEN 64 -#define snprintf _snprintf -#define vsnprintf _vsnprintf -#define RETSIGTYPE void #else /* _WIN32 */ @@ -191,68 +228,40 @@ typedef char* caddr_t; * Includes and definitions for various flavors of UN*X. */ -#include #include #include -#if HAVE_INTTYPES_H -#include -#elif HAVE_STDINT_H -#include -#endif #include #include /* concession to AIX */ #include #include #include -#ifdef TIME_WITH_SYS_TIME #include -#endif #include -#endif /* _WIN32 */ +/* + * We should have large file support enabled, if it's available, + * so just use fstat as our_fstat and struct stat as our_statb. + */ +#define our_fstat fstat +#define our_statb struct stat -#ifndef HAVE___ATTRIBUTE__ -#define __attribute__(x) -#endif +/* + * Assume all UN*Xes have strtoll(), and use it for strtoint64_t(). + */ +#define strtoint64_t strtoll /* - * 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)). + * Assume LL works. */ -#if !(defined(_MSC_VER) && defined(UNALIGNED)) -/* MSVC may have its own macro defined with the same name and purpose. */ -#undef UNALIGNED -#define UNALIGNED __attribute__((packed)) -#endif +#define INT64_T_CONSTANT(constant) (constant##LL) +#endif /* _WIN32 */ + +/* + * Function attributes, for various compilers. + */ +#include "funcattrs.h" /* * fopen() read and write modes for text files and binary files. @@ -275,8 +284,8 @@ typedef char* caddr_t; * an 80386, so, for example, it avoids the bswap instruction added in * the 80486. * - * (We don't use them on OS X; Apple provides their own, which *doesn't* - * avoid the bswap instruction, as OS X only supports machines that + * (We don't use them on macOS; Apple provides their own, which *doesn't* + * avoid the bswap instruction, as macOS only supports machines that * have it.) */ #if defined(__GNUC__) && defined(__i386__) && !defined(__APPLE__) && !defined(__ntohl) @@ -361,7 +370,20 @@ struct in6_addr { #define DIAG_JOINSTR(x,y) XSTRINGIFY(x ## y) #define DIAG_DO_PRAGMA(x) _Pragma (#x) -#if defined(__GNUC__) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 402 +/* + * The current clang compilers also define __GNUC__ and __GNUC_MINOR__ + * thus we need to test the clang case before the GCC one + */ +#if defined(__clang__) +# if (__clang_major__ * 100) + __clang_minor__ >= 208 +# define DIAG_PRAGMA(x) DIAG_DO_PRAGMA(clang diagnostic x) +# define DIAG_OFF(x) DIAG_PRAGMA(push) DIAG_PRAGMA(ignored DIAG_JOINSTR(-W,x)) +# define DIAG_ON(x) DIAG_PRAGMA(pop) +# else +# define DIAG_OFF(x) +# define DIAG_ON(x) +# endif +#elif defined(__GNUC__) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 402 # define DIAG_PRAGMA(x) DIAG_DO_PRAGMA(GCC diagnostic x) # if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406 # define DIAG_OFF(x) DIAG_PRAGMA(push) DIAG_PRAGMA(ignored DIAG_JOINSTR(-W,x)) @@ -370,15 +392,20 @@ struct in6_addr { # define DIAG_OFF(x) DIAG_PRAGMA(ignored DIAG_JOINSTR(-W,x)) # define DIAG_ON(x) DIAG_PRAGMA(warning DIAG_JOINSTR(-W,x)) # endif -#elif defined(__clang__) && ((__clang_major__ * 100) + __clang_minor__ >= 208) -# define DIAG_PRAGMA(x) DIAG_DO_PRAGMA(clang diagnostic x) -# define DIAG_OFF(x) DIAG_PRAGMA(push) DIAG_PRAGMA(ignored DIAG_JOINSTR(-W,x)) -# define DIAG_ON(x) DIAG_PRAGMA(pop) #else # define DIAG_OFF(x) # define DIAG_ON(x) #endif +/* Use for clang specific warnings */ +#ifdef __clang__ +# define DIAG_OFF_CLANG(x) DIAG_OFF(x) +# define DIAG_ON_CLANG(x) DIAG_ON(x) +#else +# define DIAG_OFF_CLANG(x) +# define DIAG_ON_CLANG(x) +#endif + /* * For dealing with APIs which are only deprecated in OSX (like the OpenSSL API) */ @@ -395,15 +422,25 @@ struct in6_addr { */ /* - * Function attributes, for various compilers. + * Statement attributes, for various compilers. + * + * This was introduced sufficiently recently that compilers implementing + * it also implement __has_attribute() (for example, GCC 5.0 and later + * have __has_attribute(), and the "fallthrough" attribute was introduced + * in GCC 7). + * + * Unfortunately, Clang does this wrong - a statement + * + * __attribute__ ((fallthrough)); + * + * produces bogus -Wmissing-declaration "declaration does not declare + * anything" warnings (dear Clang: that's not a declaration, it's an + * empty statement). GCC, however, has no trouble with this. */ -#include "funcattrs.h" - -#ifndef min -#define min(a,b) ((a)>(b)?(b):(a)) -#endif -#ifndef max -#define max(a,b) ((b)>(a)?(b):(a)) -#endif +#if __has_attribute(fallthrough) && !defined(__clang__) +# define ND_FALL_THROUGH __attribute__ ((fallthrough)) +#else +# define ND_FALL_THROUGH +#endif /* __has_attribute(fallthrough) */ #endif /* netdissect_stdinc_h */ diff --git a/contrib/tcpdump/netdissect.c b/contrib/tcpdump/netdissect.c index 0215c83b7f..7e46d6aa3d 100644 --- a/contrib/tcpdump/netdissect.c +++ b/contrib/tcpdump/netdissect.c @@ -23,13 +23,14 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include #include +#include #ifdef USE_LIBSMI #include @@ -144,3 +145,92 @@ nd_smi_version_string(void) return (NULL); #endif } + + +int +nd_push_buffer(netdissect_options *ndo, u_char *new_buffer, + const u_char *new_packetp, const u_char *new_snapend) +{ + struct netdissect_saved_packet_info *ndspi; + + ndspi = (struct netdissect_saved_packet_info *)malloc(sizeof(struct netdissect_saved_packet_info)); + if (ndspi == NULL) + return (0); /* fail */ + ndspi->ndspi_buffer = new_buffer; + ndspi->ndspi_packetp = ndo->ndo_packetp; + ndspi->ndspi_snapend = ndo->ndo_snapend; + ndspi->ndspi_prev = ndo->ndo_packet_info_stack; + + ndo->ndo_packetp = new_packetp; + ndo->ndo_snapend = new_snapend; + ndo->ndo_packet_info_stack = ndspi; + + return (1); /* success */ +} + +/* + * Set a new snapshot end to the minimum of the existing snapshot end + * and the new snapshot end. + */ +int +nd_push_snapend(netdissect_options *ndo, const u_char *new_snapend) +{ + struct netdissect_saved_packet_info *ndspi; + + ndspi = (struct netdissect_saved_packet_info *)malloc(sizeof(struct netdissect_saved_packet_info)); + if (ndspi == NULL) + return (0); /* fail */ + ndspi->ndspi_buffer = NULL; /* no new buffer */ + ndspi->ndspi_packetp = ndo->ndo_packetp; + ndspi->ndspi_snapend = ndo->ndo_snapend; + ndspi->ndspi_prev = ndo->ndo_packet_info_stack; + + /* No new packet pointer, either */ + if (new_snapend < ndo->ndo_snapend) + ndo->ndo_snapend = new_snapend; + ndo->ndo_packet_info_stack = ndspi; + + return (1); /* success */ +} + +/* + * Change an already-pushed snapshot end. This may increase the + * snapshot end, as it may be used, for example, for a Jumbo Payload + * option in IPv6. It must not increase it past the snapshot length + * atop which the current one was pushed, however. + */ +void +nd_change_snapend(netdissect_options *ndo, const u_char *new_snapend) +{ + struct netdissect_saved_packet_info *ndspi; + + ndspi = ndo->ndo_packet_info_stack; + if (ndspi->ndspi_prev != NULL) { + if (new_snapend <= ndspi->ndspi_prev->ndspi_snapend) + ndo->ndo_snapend = new_snapend; + } else { + if (new_snapend < ndo->ndo_snapend) + ndo->ndo_snapend = new_snapend; + } +} + +void +nd_pop_packet_info(netdissect_options *ndo) +{ + struct netdissect_saved_packet_info *ndspi; + + ndspi = ndo->ndo_packet_info_stack; + ndo->ndo_packetp = ndspi->ndspi_packetp; + ndo->ndo_snapend = ndspi->ndspi_snapend; + ndo->ndo_packet_info_stack = ndspi->ndspi_prev; + + free(ndspi->ndspi_buffer); + free(ndspi); +} + +void +nd_pop_all_packet_info(netdissect_options *ndo) +{ + while (ndo->ndo_packet_info_stack != NULL) + nd_pop_packet_info(ndo); +} diff --git a/contrib/tcpdump/netdissect.h b/contrib/tcpdump/netdissect.h index 02f196cdcb..0e6557fed9 100644 --- a/contrib/tcpdump/netdissect.h +++ b/contrib/tcpdump/netdissect.h @@ -29,10 +29,8 @@ #include "os-proto.h" #endif #include - -#ifndef HAVE___ATTRIBUTE__ -#define __attribute__(x) -#endif +#include +#include "status-exit-codes.h" /* * Data types corresponding to multi-byte integral values within data @@ -41,7 +39,11 @@ * use the EXTRACT_ macros to extract them (which you should be doing * *anyway*, so as not to assume a particular byte order or alignment * in your code). + * + * We even want EXTRACT_U_1 used for 8-bit integral values, so we + * define nd_uint8_t and nd_int8_t as arrays as well. */ +typedef unsigned char nd_uint8_t[1]; typedef unsigned char nd_uint16_t[2]; typedef unsigned char nd_uint24_t[3]; typedef unsigned char nd_uint32_t[4]; @@ -50,26 +52,67 @@ typedef unsigned char nd_uint48_t[6]; typedef unsigned char nd_uint56_t[7]; typedef unsigned char nd_uint64_t[8]; +typedef signed char nd_int8_t[1]; + /* - * Use this for IPv4 addresses. It's defined as an array of octets, so - * that it's not aligned on its "natural" boundary, and it's defined as - * a structure in the hopes that this makes it harder to naively use - * EXTRACT_32BITS() to extract the value - in many cases you just want - * to use UNALIGNED_MEMCPY() to copy its value, so that it remains in - * network byte order. + * "unsigned char" so that sign extension isn't done on the + * individual bytes while they're being assembled. */ -typedef struct { - unsigned char bytes[4]; -} nd_ipv4; +typedef unsigned char nd_int32_t[4]; +typedef unsigned char nd_int64_t[8]; + +#define FMAXINT (4294967296.0) /* floating point rep. of MAXINT */ /* - * Data types corresponding to single-byte integral values, for - * completeness. + * Use this for IPv4 addresses and netmasks. + * + * It's defined as an array of octets, so that it's not guaranteed to + * be aligned on its "natural" boundary (in some packet formats, it + * *isn't* so aligned). We have separate EXTRACT_ calls for them; + * sometimes you want the host-byte-order value, other times you want + * the network-byte-order value. + * + * Don't use EXTRACT_BE_U_4() on them, use EXTRACT_IPV4_TO_HOST_ORDER() + * if you want them in host byte order and EXTRACT_IPV4_TO_NETWORK_ORDER() + * if you want them in network byte order (which you want with system APIs + * that expect network-order IPv4 addresses, such as inet_ntop()). + * + * If, on your little-endian machine (e.g., an "IBM-compatible PC", no matter + * what the OS, or an Intel Mac, no matter what the OS), you get the wrong + * answer, and you've used EXTRACT_BE_U_4(), do *N*O*T* "fix" this by using + * EXTRACT_LE_U_4(), fix it by using EXTRACT_IPV4_TO_NETWORK_ORDER(), + * otherwise you're breaking the result on big-endian machines (e.g., + * most PowerPC/Power ISA machines, System/390 and z/Architecture, SPARC, + * etc.). + * + * Yes, people do this; that's why Wireshark has tvb_get_ipv4(), to extract + * an IPv4 address from a packet data buffer; it was introduced in reaction + * to somebody who *had* done that. */ -typedef unsigned char nd_uint8_t; -typedef signed char nd_int8_t; +typedef unsigned char nd_ipv4[4]; -/* snprintf et al */ +/* + * Use this for IPv6 addresses and netmasks. + */ +typedef unsigned char nd_ipv6[16]; + +/* + * Use this for MAC addresses. + */ +#define MAC_ADDR_LEN 6U /* length of MAC addresses */ +typedef unsigned char nd_mac_addr[MAC_ADDR_LEN]; + +/* + * Use this for blobs of bytes; make them arrays of nd_byte. + */ +typedef unsigned char nd_byte; + +/* + * Round up x to a multiple of y; y must be a power of 2. + */ +#ifndef roundup2 +#define roundup2(x, y) (((x)+((u_int)((y)-1)))&(~((u_int)((y)-1)))) +#endif #include #include @@ -77,20 +120,6 @@ typedef signed char nd_int8_t; #include "ip.h" /* struct ip for nextproto4_cksum() */ #include "ip6.h" /* struct ip6 for nextproto6_cksum() */ -extern int32_t thiszone; /* seconds offset from gmt to local time */ -/* invalid string to print '(invalid)' for malformed or corrupted packets */ -extern const char istr[]; - -#if !defined(HAVE_SNPRINTF) -int snprintf (char *str, size_t sz, FORMAT_STRING(const char *format), ...) - PRINTFLIKE(3, 4); -#endif /* !defined(HAVE_SNPRINTF) */ - -#if !defined(HAVE_VSNPRINTF) -int vsnprintf (char *str, size_t sz, FORMAT_STRING(const char *format), - va_list ap) PRINTFLIKE(3, 0); -#endif /* !defined(HAVE_VSNPRINTF) */ - #ifndef HAVE_STRLCAT extern size_t strlcat (char *, const char *, size_t); #endif @@ -137,13 +166,42 @@ typedef struct netdissect_options netdissect_options; #define IF_PRINTER_ARGS (netdissect_options *, const struct pcap_pkthdr *, const u_char *) -typedef u_int (*if_printer) IF_PRINTER_ARGS; +typedef void (*if_printer) IF_PRINTER_ARGS; + +/* + * In case the data in a buffer needs to be processed by being decrypted, + * decompressed, etc. before it's dissected, we can't process it in place, + * we have to allocate a new buffer for the processed data. + * + * We keep a stack of those buffers; when we allocate a new buffer, we + * push the current one onto a stack, and when we're done with the new + * buffer, we free the current buffer and pop the previous one off the + * stack. + * + * A buffer has a beginnning and end pointer, and a link to the previous + * buffer on the stack. + * + * In other cases, we temporarily adjust the snapshot end to reflect a + * packet-length field in the packet data and, when finished dissecting + * that part of the packet, restore the old snapshot end. We keep that + * on the stack with null buffer pointer, meaning there's nothing to + * free. + */ +struct netdissect_saved_packet_info { + u_char *ndspi_buffer; /* pointer to allocated buffer data */ + const u_char *ndspi_packetp; /* saved beginning of data */ + const u_char *ndspi_snapend; /* saved end of data */ + struct netdissect_saved_packet_info *ndspi_prev; /* previous buffer on the stack */ +}; + +/* 'val' value(s) for longjmp */ +#define ND_TRUNCATED 1 struct netdissect_options { 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 */ + int ndo_Kflag; /* don't check IP, TCP or UDP checksums */ int ndo_nflag; /* leave addresses as numbers */ int ndo_Nflag; /* remove domains from printed host names */ int ndo_qflag; /* quick (shorter) output */ @@ -152,11 +210,14 @@ struct netdissect_options { int ndo_uflag; /* Print undecoded NFS handles */ int ndo_vflag; /* verbosity level */ int ndo_xflag; /* print packet in hex */ - int ndo_Xflag; /* print packet in hex/ascii */ - int ndo_Aflag; /* print packet only in ascii observing TAB, + int ndo_Xflag; /* print packet in hex/ASCII */ + int ndo_Aflag; /* print packet only in ASCII observing TAB, * LF, CR and SPACE as graphical chars */ int ndo_Hflag; /* dissect 802.11s draft mesh standard */ + const char *ndo_protocol; /* protocol */ + jmp_buf ndo_early_end; /* jmp_buf for setjmp()/longjmp() */ + void *ndo_last_mem_p; /* pointer to the last allocated memory chunk */ int ndo_packet_number; /* print a packet number in the beginning of line */ int ndo_suppress_default_print; /* don't use default_print() for unknown packet types */ int ndo_tstamp_precision; /* requested time stamp precision */ @@ -171,44 +232,44 @@ struct netdissect_options { int ndo_packettype; /* as specified by -T */ int ndo_snaplen; + int ndo_ll_hdr_len; /* link-layer header length */ /*global pointers to beginning and end of current packet (during printing) */ const u_char *ndo_packetp; const u_char *ndo_snapend; + /* stack of saved packet boundary and buffer information */ + struct netdissect_saved_packet_info *ndo_packet_info_stack; + /* pointer to the if_printer function */ if_printer ndo_if_printer; /* pointer to void function to output stuff */ void (*ndo_default_print)(netdissect_options *, - register const u_char *bp, register u_int length); + const u_char *bp, u_int length); /* pointer to function to do regular output */ int (*ndo_printf)(netdissect_options *, const char *fmt, ...) -#ifdef __ATTRIBUTE___FORMAT_OK_FOR_FUNCTION_POINTERS - __attribute__ ((format (printf, 2, 3))) -#endif - ; + PRINTFLIKE_FUNCPTR(2, 3); /* pointer to function to output errors */ - void (*ndo_error)(netdissect_options *, - const char *fmt, ...) -#ifdef __ATTRIBUTE___NORETURN_OK_FOR_FUNCTION_POINTERS - __attribute__ ((noreturn)) -#endif /* __ATTRIBUTE___NORETURN_OK_FOR_FUNCTION_POINTERS */ -#ifdef __ATTRIBUTE___FORMAT_OK_FOR_FUNCTION_POINTERS - __attribute__ ((format (printf, 2, 3))) -#endif /* __ATTRIBUTE___FORMAT_OK_FOR_FUNCTION_POINTERS */ - ; + void NORETURN_FUNCPTR (*ndo_error)(netdissect_options *, + status_exit_codes_t status, + const char *fmt, ...) + PRINTFLIKE_FUNCPTR(3, 4); /* pointer to function to output warnings */ void (*ndo_warning)(netdissect_options *, const char *fmt, ...) -#ifdef __ATTRIBUTE___FORMAT_OK_FOR_FUNCTION_POINTERS - __attribute__ ((format (printf, 2, 3))) -#endif - ; + PRINTFLIKE_FUNCPTR(2, 3); }; +extern int nd_push_buffer(netdissect_options *, u_char *, const u_char *, + const u_char *); +extern int nd_push_snapend(netdissect_options *, const u_char *); +extern void nd_change_snapend(netdissect_options *, const u_char *); +extern void nd_pop_packet_info(netdissect_options *); +extern void nd_pop_all_packet_info(netdissect_options *); + #define PT_VAT 1 /* Visual Audio Tool */ #define PT_WB 2 /* distributed White Board */ #define PT_RPC 3 /* Remote Procedure Call */ @@ -226,13 +287,12 @@ struct netdissect_options { #define PT_PGM_ZMTP1 15 /* ZMTP/1.0 inside PGM (native or UDP-encapsulated) */ #define PT_LMP 16 /* Link Management Protocol */ #define PT_RESP 17 /* RESP */ +#define PT_PTP 18 /* PTP */ +#define PT_SOMEIP 19 /* Autosar SOME/IP Protocol */ +#define PT_DOMAIN 20 /* Domain Name System (DNS) */ -#ifndef min -#define min(a,b) ((a)>(b)?(b):(a)) -#endif -#ifndef max -#define max(a,b) ((b)>(a)?(b):(a)) -#endif +#define ND_MIN(a,b) ((a)>(b)?(b):(a)) +#define ND_MAX(a,b) ((b)>(a)?(b):(a)) /* For source or destination ports tests (UDP, TCP, ...) */ #define IS_SRC_OR_DST_PORT(p) (sport == (p) || dport == (p)) @@ -247,7 +307,7 @@ struct netdissect_options { * 1) big enough for maximum-size Linux loopback packets (65549) * and some USB packets captured with USBPcap: * - * http://desowin.org/usbpcap/ + * https://desowin.org/usbpcap/ * * (> 131072, < 262144) * @@ -258,27 +318,16 @@ struct netdissect_options { * savefile header to control the size of the buffer they allocate, * so a size of, say, 2^31-1 might not work well. * - * XXX - does it need to be bigger still? + * XXX - does it need to be bigger still? Note that, for versions of + * libpcap with pcap_create()/pcap_activate(), if no -s flag is specified + * or -s 0 is specified, we won't set the snapshot length at all, and will + * let libpcap choose a snapshot length; newer versions may choose a bigger + * value than 262144 for D-Bus, for example. */ #define MAXIMUM_SNAPLEN 262144 /* - * The default snapshot length is the maximum. - */ -#define DEFAULT_SNAPLEN MAXIMUM_SNAPLEN - -#define ESRC(ep) ((ep)->ether_shost) -#define EDST(ep) ((ep)->ether_dhost) - -#ifndef NTOHL -#define NTOHL(x) (x) = ntohl(x) -#define NTOHS(x) (x) = ntohs(x) -#define HTONL(x) (x) = htonl(x) -#define HTONS(x) (x) = htons(x) -#endif - -/* - * True if "l" bytes of "var" were captured. + * True if "l" bytes from "p" were captured. * * The "ndo->ndo_snapend - (l) <= ndo->ndo_snapend" checks to make sure * "l" isn't so large that "ndo->ndo_snapend - (l)" underflows. @@ -294,7 +343,7 @@ struct netdissect_options { * you subtract a positive integer from a pointer, the result is * guaranteed to be less than the original pointer value). See * - * http://www.kb.cert.org/vuls/id/162289 + * https://www.kb.cert.org/vuls/id/162289 */ /* @@ -304,21 +353,36 @@ struct netdissect_options { */ #define IS_NOT_NEGATIVE(x) (((x) > 0) || ((x) == 0)) -#define ND_TTEST2(var, l) \ +#define ND_TTEST_LEN(p, l) \ (IS_NOT_NEGATIVE(l) && \ ((uintptr_t)ndo->ndo_snapend - (l) <= (uintptr_t)ndo->ndo_snapend && \ - (uintptr_t)&(var) <= (uintptr_t)ndo->ndo_snapend - (l))) + (uintptr_t)(p) <= (uintptr_t)ndo->ndo_snapend - (l))) -/* True if "var" was captured */ -#define ND_TTEST(var) ND_TTEST2(var, sizeof(var)) +/* True if "*(p)" was captured */ +#define ND_TTEST_SIZE(p) ND_TTEST_LEN(p, sizeof(*(p))) -/* Bail if "l" bytes of "var" were not captured */ -#define ND_TCHECK2(var, l) if (!ND_TTEST2(var, l)) goto trunc +/* Bail out if "l" bytes from "p" were not captured */ +#ifdef ND_LONGJMP_FROM_TCHECK +#define ND_TCHECK_LEN(p, l) if (!ND_TTEST_LEN(p, l)) nd_trunc_longjmp(ndo) +#else +#define ND_TCHECK_LEN(p, l) if (!ND_TTEST_LEN(p, l)) goto trunc +#endif -/* Bail if "var" was not captured */ -#define ND_TCHECK(var) ND_TCHECK2(var, sizeof(var)) +/* Bail out if "*(p)" was not captured */ +#define ND_TCHECK_SIZE(p) ND_TCHECK_LEN(p, sizeof(*(p))) -#define ND_PRINT(STUFF) (*ndo->ndo_printf)STUFF +/* + * Number of bytes between two pointers. + */ +#define ND_BYTES_BETWEEN(p1, p2) ((u_int)(((const uint8_t *)(p1)) - (const uint8_t *)(p2))) + +/* + * Number of bytes remaining in the captured data, starting at the + * byte pointed to by the argument. + */ +#define ND_BYTES_AVAILABLE_AFTER(p) ND_BYTES_BETWEEN(ndo->ndo_snapend, (p)) + +#define ND_PRINT(...) (ndo->ndo_printf)(ndo, __VA_ARGS__) #define ND_DEFAULTPRINT(ap, length) (*ndo->ndo_default_print)(ndo, ap, length) extern void ts_print(netdissect_options *, const struct timeval *); @@ -326,10 +390,10 @@ extern void signed_relts_print(netdissect_options *, int32_t); extern void unsigned_relts_print(netdissect_options *, uint32_t); extern void fn_print_char(netdissect_options *, u_char); -extern int fn_print(netdissect_options *, const u_char *, const u_char *); -extern u_int fn_printztn(netdissect_options *ndo, const u_char *, u_int, const u_char *); -extern int fn_printn(netdissect_options *, const u_char *, u_int, const u_char *); -extern int fn_printzp(netdissect_options *, const u_char *, u_int, const u_char *); +extern void fn_print_str(netdissect_options *, const u_char *); +extern u_int nd_printztn(netdissect_options *, const u_char *, u_int, const u_char *); +extern int nd_printn(netdissect_options *, const u_char *, u_int, const u_char *); +extern void nd_printjnp(netdissect_options *, const u_char *, u_int); /* * Flags for txtproto_print(). @@ -337,23 +401,32 @@ extern int fn_printzp(netdissect_options *, const u_char *, u_int, const u_char #define RESP_CODE_SECOND_TOKEN 0x00000001 /* response code is second token in response line */ extern void txtproto_print(netdissect_options *, const u_char *, u_int, - const char *, const char **, u_int); - + const char **, u_int); + +#if (defined(__i386__) || defined(_M_IX86) || defined(__X86__) || defined(__x86_64__) || defined(_M_X64)) || \ + (defined(__arm__) || defined(_M_ARM) || defined(__aarch64__)) || \ + (defined(__m68k__) && (!defined(__mc68000__) && !defined(__mc68010__))) || \ + (defined(__ppc__) || defined(__ppc64__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PPC64)) || \ + (defined(__s390__) || defined(__s390x__) || defined(__zarch__)) || \ + defined(__vax__) /* - * Locale-independent macros for testing character properties and - * stripping the 8th bit from characters. Assumed to be handed - * a value between 0 and 255, i.e. don't hand them a char, as - * those might be in the range -128 to 127. + * The procesor natively handles unaligned loads, so just use memcpy() + * and memcmp(), to enable those optimizations. + * + * XXX - are those all the x86 tests we need? + * XXX - do we need to worry about ARMv1 through ARMv5, which didn't + * support unaligned loads, and, if so, do we need to worry about all + * of them, or just some of them, e.g. ARMv5? + * XXX - are those the only 68k tests we need not to generated + * unaligned accesses if the target is the 68000 or 68010? + * XXX - are there any tests we don't need, because some definitions are for + * compilers that also predefine the GCC symbols? + * XXX - do we need to test for both 32-bit and 64-bit versions of those + * architectures in all cases? */ -#define ND_ISASCII(c) (!((c) & 0x80)) /* value is an ASCII code point */ -#define ND_ISPRINT(c) ((c) >= 0x20 && (c) <= 0x7E) -#define ND_ISGRAPH(c) ((c) > 0x20 && (c) <= 0x7E) -#define ND_TOASCII(c) ((c) & 0x7F) - -extern void safeputchar(netdissect_options *, const u_char); -extern void safeputs(netdissect_options *, const u_char *, const u_int); - -#ifdef LBL_ALIGN +#define UNALIGNED_MEMCPY(p, q, l) memcpy((p), (q), (l)) +#define UNALIGNED_MEMCMP(p, q, l) memcmp((p), (q), (l)) +#else /* * The processor doesn't natively handle unaligned loads, * and the compiler might "helpfully" optimize memcpy() @@ -369,13 +442,6 @@ extern void unaligned_memcpy(void *, const void *, size_t); extern int unaligned_memcmp(const void *, const void *, size_t); #define UNALIGNED_MEMCPY(p, q, l) unaligned_memcpy((p), (q), (l)) #define UNALIGNED_MEMCMP(p, q, l) unaligned_memcmp((p), (q), (l)) -#else -/* - * The procesor natively handles unaligned loads, so just use memcpy() - * and memcmp(), to enable those optimizations. - */ -#define UNALIGNED_MEMCPY(p, q, l) memcpy((p), (q), (l)) -#define UNALIGNED_MEMCMP(p, q, l) memcmp((p), (q), (l)) #endif #define PLURAL_SUFFIX(n) \ @@ -384,66 +450,85 @@ extern int unaligned_memcmp(const void *, const void *, size_t); extern const char *tok2strary_internal(const char **, int, const char *, int); #define tok2strary(a,f,i) tok2strary_internal(a, sizeof(a)/sizeof(a[0]),f,i) +struct uint_tokary +{ + u_int uintval; + const struct tok *tokary; +}; + +extern const struct tok *uint2tokary_internal(const struct uint_tokary[], const size_t, const u_int); +#define uint2tokary(a, i) uint2tokary_internal(a, sizeof(a)/sizeof(a[0]), i) + extern if_printer lookup_printer(int); +#define ND_DEBUG {printf(" [%s:%d %s] ", __FILE__, __LINE__, __func__); fflush(stdout);} + /* The DLT printer routines */ -extern u_int ap1394_if_print IF_PRINTER_ARGS; -extern u_int arcnet_if_print IF_PRINTER_ARGS; -extern u_int arcnet_linux_if_print IF_PRINTER_ARGS; -extern u_int atm_if_print IF_PRINTER_ARGS; -extern u_int bt_if_print IF_PRINTER_ARGS; -extern u_int chdlc_if_print IF_PRINTER_ARGS; -extern u_int cip_if_print IF_PRINTER_ARGS; -extern u_int enc_if_print IF_PRINTER_ARGS; -extern u_int ether_if_print IF_PRINTER_ARGS; -extern u_int fddi_if_print IF_PRINTER_ARGS; -extern u_int fr_if_print IF_PRINTER_ARGS; -extern u_int ieee802_11_if_print IF_PRINTER_ARGS; -extern u_int ieee802_11_radio_avs_if_print IF_PRINTER_ARGS; -extern u_int ieee802_11_radio_if_print IF_PRINTER_ARGS; -extern u_int ieee802_15_4_if_print IF_PRINTER_ARGS; -extern u_int ipfc_if_print IF_PRINTER_ARGS; -extern u_int ipnet_if_print IF_PRINTER_ARGS; -extern u_int juniper_atm1_print IF_PRINTER_ARGS; -extern u_int juniper_atm2_print IF_PRINTER_ARGS; -extern u_int juniper_chdlc_print IF_PRINTER_ARGS; -extern u_int juniper_es_print IF_PRINTER_ARGS; -extern u_int juniper_ether_print IF_PRINTER_ARGS; -extern u_int juniper_frelay_print IF_PRINTER_ARGS; -extern u_int juniper_ggsn_print IF_PRINTER_ARGS; -extern u_int juniper_mfr_print IF_PRINTER_ARGS; -extern u_int juniper_mlfr_print IF_PRINTER_ARGS; -extern u_int juniper_mlppp_print IF_PRINTER_ARGS; -extern u_int juniper_monitor_print IF_PRINTER_ARGS; -extern u_int juniper_ppp_print IF_PRINTER_ARGS; -extern u_int juniper_pppoe_atm_print IF_PRINTER_ARGS; -extern u_int juniper_pppoe_print IF_PRINTER_ARGS; -extern u_int juniper_services_print IF_PRINTER_ARGS; -extern u_int lane_if_print IF_PRINTER_ARGS; -extern u_int ltalk_if_print IF_PRINTER_ARGS; -extern u_int mfr_if_print IF_PRINTER_ARGS; -extern u_int netanalyzer_if_print IF_PRINTER_ARGS; -extern u_int netanalyzer_transparent_if_print IF_PRINTER_ARGS; -extern u_int nflog_if_print IF_PRINTER_ARGS; -extern u_int null_if_print IF_PRINTER_ARGS; -extern u_int pflog_if_print IF_PRINTER_ARGS; -extern u_int pktap_if_print IF_PRINTER_ARGS; -extern u_int ppi_if_print IF_PRINTER_ARGS; -extern u_int ppp_bsdos_if_print IF_PRINTER_ARGS; -extern u_int ppp_hdlc_if_print IF_PRINTER_ARGS; -extern u_int ppp_if_print IF_PRINTER_ARGS; -extern u_int pppoe_if_print IF_PRINTER_ARGS; -extern u_int prism_if_print IF_PRINTER_ARGS; -extern u_int raw_if_print IF_PRINTER_ARGS; -extern u_int sl_bsdos_if_print IF_PRINTER_ARGS; -extern u_int sl_if_print IF_PRINTER_ARGS; -extern u_int sll_if_print IF_PRINTER_ARGS; -extern u_int sunatm_if_print IF_PRINTER_ARGS; -extern u_int symantec_if_print IF_PRINTER_ARGS; -extern u_int token_if_print IF_PRINTER_ARGS; -extern u_int usb_linux_48_byte_print IF_PRINTER_ARGS; -extern u_int usb_linux_64_byte_print IF_PRINTER_ARGS; +extern void ap1394_if_print IF_PRINTER_ARGS; +extern void arcnet_if_print IF_PRINTER_ARGS; +extern void arcnet_linux_if_print IF_PRINTER_ARGS; +extern void atm_if_print IF_PRINTER_ARGS; +extern void bt_if_print IF_PRINTER_ARGS; +extern void brcm_tag_if_print IF_PRINTER_ARGS; +extern void brcm_tag_prepend_if_print IF_PRINTER_ARGS; +extern void chdlc_if_print IF_PRINTER_ARGS; +extern void cip_if_print IF_PRINTER_ARGS; +extern void dsa_if_print IF_PRINTER_ARGS; +extern void edsa_if_print IF_PRINTER_ARGS; +extern void enc_if_print IF_PRINTER_ARGS; +extern void ether_if_print IF_PRINTER_ARGS; +extern void fddi_if_print IF_PRINTER_ARGS; +extern void fr_if_print IF_PRINTER_ARGS; +extern void ieee802_11_if_print IF_PRINTER_ARGS; +extern void ieee802_11_radio_avs_if_print IF_PRINTER_ARGS; +extern void ieee802_11_radio_if_print IF_PRINTER_ARGS; +extern void ieee802_15_4_if_print IF_PRINTER_ARGS; +extern void ieee802_15_4_tap_if_print IF_PRINTER_ARGS; +extern void ipfc_if_print IF_PRINTER_ARGS; +extern void ipoib_if_print IF_PRINTER_ARGS; +extern void ipnet_if_print IF_PRINTER_ARGS; +extern void juniper_atm1_if_print IF_PRINTER_ARGS; +extern void juniper_atm2_if_print IF_PRINTER_ARGS; +extern void juniper_chdlc_if_print IF_PRINTER_ARGS; +extern void juniper_es_if_print IF_PRINTER_ARGS; +extern void juniper_ether_if_print IF_PRINTER_ARGS; +extern void juniper_frelay_if_print IF_PRINTER_ARGS; +extern void juniper_ggsn_if_print IF_PRINTER_ARGS; +extern void juniper_mfr_if_print IF_PRINTER_ARGS; +extern void juniper_mlfr_if_print IF_PRINTER_ARGS; +extern void juniper_mlppp_if_print IF_PRINTER_ARGS; +extern void juniper_monitor_if_print IF_PRINTER_ARGS; +extern void juniper_ppp_if_print IF_PRINTER_ARGS; +extern void juniper_pppoe_atm_if_print IF_PRINTER_ARGS; +extern void juniper_pppoe_if_print IF_PRINTER_ARGS; +extern void juniper_services_if_print IF_PRINTER_ARGS; +extern void ltalk_if_print IF_PRINTER_ARGS; +extern void mfr_if_print IF_PRINTER_ARGS; +extern void netanalyzer_if_print IF_PRINTER_ARGS; +extern void netanalyzer_transparent_if_print IF_PRINTER_ARGS; +extern void nflog_if_print IF_PRINTER_ARGS; +extern void null_if_print IF_PRINTER_ARGS; +extern void pflog_if_print IF_PRINTER_ARGS; +extern void pktap_if_print IF_PRINTER_ARGS; +extern void ppi_if_print IF_PRINTER_ARGS; +extern void ppp_bsdos_if_print IF_PRINTER_ARGS; +extern void ppp_hdlc_if_print IF_PRINTER_ARGS; +extern void ppp_if_print IF_PRINTER_ARGS; +extern void pppoe_if_print IF_PRINTER_ARGS; +extern void prism_if_print IF_PRINTER_ARGS; +extern void raw_if_print IF_PRINTER_ARGS; +extern void sl_bsdos_if_print IF_PRINTER_ARGS; +extern void sl_if_print IF_PRINTER_ARGS; +extern void sll_if_print IF_PRINTER_ARGS; +extern void sll2_if_print IF_PRINTER_ARGS; +extern void sunatm_if_print IF_PRINTER_ARGS; +extern void symantec_if_print IF_PRINTER_ARGS; +extern void token_if_print IF_PRINTER_ARGS; +extern void unsupported_if_print IF_PRINTER_ARGS; +extern void usb_linux_48_byte_if_print IF_PRINTER_ARGS; +extern void usb_linux_64_byte_if_print IF_PRINTER_ARGS; +extern void vsock_if_print IF_PRINTER_ARGS; /* * Structure passed to some printers to allow them to print @@ -463,50 +548,53 @@ struct lladdr_info { /* The printer routines. */ extern void aarp_print(netdissect_options *, const u_char *, u_int); -extern int ah_print(netdissect_options *, register const u_char *); -extern void ahcp_print(netdissect_options *, const u_char *, const u_int); +extern int ah_print(netdissect_options *, const u_char *); +extern void ahcp_print(netdissect_options *, const u_char *, u_int); extern void aodv_print(netdissect_options *, const u_char *, u_int, int); extern void aoe_print(netdissect_options *, const u_char *, const u_int); +extern int arista_ethertype_print(netdissect_options *,const u_char *, u_int); extern void arp_print(netdissect_options *, const u_char *, u_int, u_int); extern void ascii_print(netdissect_options *, const u_char *, u_int); extern void atalk_print(netdissect_options *, const u_char *, u_int); extern void atm_print(netdissect_options *, u_int, u_int, u_int, const u_char *, u_int, u_int); extern void babel_print(netdissect_options *, const u_char *, u_int); +extern void bcm_li_print(netdissect_options *, const u_char *, u_int); extern void beep_print(netdissect_options *, const u_char *, u_int); extern void bfd_print(netdissect_options *, const u_char *, u_int, u_int); -extern void bgp_print(netdissect_options *, const u_char *, int); -extern char *bgp_vpn_rd_print (netdissect_options *, const u_char *); +extern void bgp_print(netdissect_options *, const u_char *, u_int); +extern const char *bgp_vpn_rd_print(netdissect_options *, const u_char *); extern void bootp_print(netdissect_options *, const u_char *, u_int); extern void calm_fast_print(netdissect_options *, const u_char *, u_int, const struct lladdr_info *); -extern void carp_print(netdissect_options *, const u_char *, u_int, int); -extern void cdp_print(netdissect_options *, const u_char *, u_int, u_int); +extern void carp_print(netdissect_options *, const u_char *, u_int, u_int); +extern void cdp_print(netdissect_options *, const u_char *, u_int); extern void cfm_print(netdissect_options *, const u_char *, u_int); -extern u_int chdlc_print(netdissect_options *, register const u_char *, u_int); +extern u_int chdlc_print(netdissect_options *, const u_char *, u_int); extern void cisco_autorp_print(netdissect_options *, const u_char *, u_int); extern void cnfp_print(netdissect_options *, const u_char *); extern void dccp_print(netdissect_options *, const u_char *, const u_char *, u_int); extern void decnet_print(netdissect_options *, const u_char *, u_int, u_int); extern void dhcp6_print(netdissect_options *, const u_char *, u_int); -extern int dstopt_print(netdissect_options *, const u_char *); +extern int dstopt_process(netdissect_options *, const u_char *); extern void dtp_print(netdissect_options *, const u_char *, u_int); extern void dvmrp_print(netdissect_options *, const u_char *, u_int); extern void eap_print(netdissect_options *, const u_char *, u_int); +extern void eapol_print(netdissect_options *, const u_char *); extern void egp_print(netdissect_options *, const u_char *, u_int); extern void eigrp_print(netdissect_options *, const u_char *, u_int); -extern int esp_print(netdissect_options *, const u_char *, const int, const u_char *, int *, int *); +extern void esp_print(netdissect_options *, const u_char *, u_int, const u_char *, u_int, int, u_int); extern u_int ether_print(netdissect_options *, const u_char *, u_int, u_int, void (*)(netdissect_options *, const u_char *), const u_char *); +extern u_int ether_switch_tag_print(netdissect_options *, const u_char *, u_int, u_int, void (*)(netdissect_options *, const u_char *), u_int); extern int ethertype_print(netdissect_options *, u_short, const u_char *, u_int, u_int, const struct lladdr_info *, const struct lladdr_info *); extern u_int fddi_print(netdissect_options *, const u_char *, u_int, u_int); extern void forces_print(netdissect_options *, const u_char *, u_int); -extern u_int fr_print(netdissect_options *, register const u_char *, u_int); +extern u_int fr_print(netdissect_options *, const u_char *, u_int); extern int frag6_print(netdissect_options *, const u_char *, const u_char *); extern void ftp_print(netdissect_options *, const u_char *, u_int); extern void geneve_print(netdissect_options *, const u_char *, u_int); extern void geonet_print(netdissect_options *, const u_char *, u_int, const struct lladdr_info *); extern void gre_print(netdissect_options *, const u_char *, u_int); -extern int hbhopt_print(netdissect_options *, const u_char *); +extern int hbhopt_process(netdissect_options *, const u_char *, int *, uint32_t *); extern void hex_and_ascii_print(netdissect_options *, const char *, const u_char *, u_int); -extern void hex_and_ascii_print_with_offset(netdissect_options *, const char *, const u_char *, u_int, u_int); extern void hex_print(netdissect_options *, const char *ident, const u_char *cp, u_int); extern void hex_print_with_offset(netdissect_options *, const char *ident, const u_char *cp, u_int, u_int); extern void hncp_print(netdissect_options *, const u_char *, u_int); @@ -514,18 +602,18 @@ extern void hsrp_print(netdissect_options *, const u_char *, u_int); extern void http_print(netdissect_options *, const u_char *, u_int); extern void icmp6_print(netdissect_options *, const u_char *, u_int, const u_char *, int); extern void icmp_print(netdissect_options *, const u_char *, u_int, const u_char *, int); +extern u_int ieee802_15_4_print(netdissect_options *, const u_char *, u_int); extern u_int ieee802_11_radio_print(netdissect_options *, const u_char *, u_int, u_int); extern void igmp_print(netdissect_options *, const u_char *, u_int); extern void igrp_print(netdissect_options *, const u_char *, u_int); extern void ip6_print(netdissect_options *, const u_char *, u_int); extern void ipN_print(netdissect_options *, const u_char *, u_int); extern void ip_print(netdissect_options *, const u_char *, u_int); -extern void ip_print_inner(netdissect_options *, const u_char *, u_int, u_int nh, const u_char *); -extern void ipcomp_print(netdissect_options *, register const u_char *); +extern void ipcomp_print(netdissect_options *, const u_char *); extern void ipx_netbios_print(netdissect_options *, const u_char *, u_int); extern void ipx_print(netdissect_options *, const u_char *, u_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 *, u_int, const u_char *); +extern void isakmp_rfc3948_print(netdissect_options *, const u_char *, u_int, const u_char *, int, int, u_int); extern void isoclns_print(netdissect_options *, const u_char *, u_int); extern void krb_print(netdissect_options *, const u_char *); extern void l2tp_print(netdissect_options *, const u_char *, u_int); @@ -536,14 +624,16 @@ extern u_int llap_print(netdissect_options *, const u_char *, u_int); extern int llc_print(netdissect_options *, const u_char *, u_int, u_int, const struct lladdr_info *, const struct lladdr_info *); extern void lldp_print(netdissect_options *, const u_char *, u_int); extern void lmp_print(netdissect_options *, const u_char *, u_int); -extern void loopback_print(netdissect_options *, const u_char *, const u_int); +extern void loopback_print(netdissect_options *, const u_char *, u_int); extern void lspping_print(netdissect_options *, const u_char *, u_int); extern void lwapp_control_print(netdissect_options *, const u_char *, u_int, int); extern void lwapp_data_print(netdissect_options *, const u_char *, u_int); extern void lwres_print(netdissect_options *, const u_char *, u_int); extern void m3ua_print(netdissect_options *, const u_char *, const u_int); -extern void medsa_print(netdissect_options *, const u_char *, u_int, u_int, const struct lladdr_info *, const struct lladdr_info *); -extern u_int mfr_print(netdissect_options *, register const u_char *, u_int); +extern int macsec_print(netdissect_options *, const u_char **, + u_int *, u_int *, u_int *, const struct lladdr_info *, + const struct lladdr_info *); +extern u_int mfr_print(netdissect_options *, const u_char *, u_int); extern void mobile_print(netdissect_options *, const u_char *, u_int); extern int mobility_print(netdissect_options *, const u_char *, const u_char *); extern void mpcp_print(netdissect_options *, const u_char *, u_int); @@ -551,33 +641,34 @@ extern void mpls_print(netdissect_options *, const u_char *, u_int); extern int mptcp_print(netdissect_options *, const u_char *, u_int, u_char); extern void msdp_print(netdissect_options *, const u_char *, u_int); extern void msnlb_print(netdissect_options *, const u_char *); -extern void nbt_tcp_print(netdissect_options *, const u_char *, int); -extern void nbt_udp137_print(netdissect_options *, const u_char *, int); -extern void nbt_udp138_print(netdissect_options *, const u_char *, int); -extern void netbeui_print(netdissect_options *, u_short, const u_char *, int); +extern void nbt_tcp_print(netdissect_options *, const u_char *, u_int); +extern void nbt_udp137_print(netdissect_options *, const u_char *, u_int); +extern void nbt_udp138_print(netdissect_options *, const u_char *, u_int); +extern void netbeui_print(netdissect_options *, u_short, const u_char *, u_int); extern void nfsreply_print(netdissect_options *, const u_char *, u_int, const u_char *); -extern void nfsreply_print_noaddr(netdissect_options *, const u_char *, u_int, const u_char *); -extern void nfsreq_print_noaddr(netdissect_options *, const u_char *, u_int, const u_char *); -extern const u_char * ns_nprint (netdissect_options *, register const u_char *, register const u_char *); -extern void ns_print(netdissect_options *, const u_char *, u_int, int); -extern void nsh_print(netdissect_options *ndo, const u_char *bp, u_int len); +extern void nfsreply_noaddr_print(netdissect_options *, const u_char *, u_int, const u_char *); +extern void nfsreq_noaddr_print(netdissect_options *, const u_char *, u_int, const u_char *); +extern const u_char *fqdn_print(netdissect_options *, const u_char *, const u_char *); +extern void domain_print(netdissect_options *, const u_char *, u_int, int, int); +extern void nsh_print(netdissect_options *, const u_char *, u_int); extern void ntp_print(netdissect_options *, const u_char *, u_int); extern void oam_print(netdissect_options *, const u_char *, u_int, u_int); extern void olsr_print(netdissect_options *, const u_char *, u_int, int); -extern void openflow_print(netdissect_options *, const u_char *, const u_int); +extern void openflow_print(netdissect_options *, const u_char *, u_int); extern void ospf6_print(netdissect_options *, const u_char *, u_int); extern void ospf_print(netdissect_options *, const u_char *, u_int, const u_char *); -extern int ospf_print_grace_lsa(netdissect_options *, const uint8_t *, u_int); -extern int ospf_print_te_lsa(netdissect_options *, const uint8_t *, u_int); +extern int ospf_grace_lsa_print(netdissect_options *, const u_char *, u_int); +extern int ospf_te_lsa_print(netdissect_options *, const u_char *, u_int); extern void otv_print(netdissect_options *, const u_char *, u_int); extern void pgm_print(netdissect_options *, const u_char *, u_int, const u_char *); extern void pim_print(netdissect_options *, const u_char *, u_int, const u_char *); extern void pimv1_print(netdissect_options *, const u_char *, u_int); -extern u_int ppp_print(netdissect_options *, register const u_char *, u_int); +extern u_int ppp_print(netdissect_options *, const u_char *, u_int); extern u_int pppoe_print(netdissect_options *, const u_char *, u_int); extern void pptp_print(netdissect_options *, const u_char *); -extern int print_unknown_data(netdissect_options *, const u_char *, const char *, int); -extern char *q922_string(netdissect_options *, const u_char *, u_int); +extern void ptp_print(netdissect_options *, const u_char *, u_int); +extern int print_unknown_data(netdissect_options *, const u_char *, const char *, u_int); +extern const char *q922_string(netdissect_options *, const u_char *, u_int); extern void q933_print(netdissect_options *, const u_char *, u_int); extern void radius_print(netdissect_options *, const u_char *, u_int); extern void resp_print(netdissect_options *, const u_char *, u_int); @@ -588,18 +679,18 @@ extern void rrcp_print(netdissect_options *, const u_char *, u_int, const struct extern void rsvp_print(netdissect_options *, const u_char *, u_int); extern int rt6_print(netdissect_options *, const u_char *, const u_char *); extern void rtsp_print(netdissect_options *, const u_char *, u_int); -extern void rx_print(netdissect_options *, register const u_char *, int, int, int, const u_char *); +extern void rx_print(netdissect_options *, const u_char *, u_int, uint16_t, uint16_t, const u_char *); extern void sctp_print(netdissect_options *, const u_char *, const u_char *, u_int); extern void sflow_print(netdissect_options *, const u_char *, u_int); +extern void ssh_print(netdissect_options *, const u_char *, u_int); extern void sip_print(netdissect_options *, const u_char *, u_int); extern void slow_print(netdissect_options *, const u_char *, u_int); -extern void smb_print_data(netdissect_options *, const unsigned char *, int); -extern void smb_tcp_print(netdissect_options *, const u_char *, int); +extern void smb_tcp_print(netdissect_options *, const u_char *, u_int); extern void smtp_print(netdissect_options *, const u_char *, u_int); extern int snap_print(netdissect_options *, const u_char *, u_int, u_int, const struct lladdr_info *, const struct lladdr_info *, u_int); extern void snmp_print(netdissect_options *, const u_char *, u_int); extern void stp_print(netdissect_options *, const u_char *, u_int); -extern void sunrpcrequest_print(netdissect_options *, const u_char *, u_int, const u_char *); +extern void sunrpc_print(netdissect_options *, const u_char *, u_int, const u_char *); extern void syslog_print(netdissect_options *, const u_char *, u_int); extern void tcp_print(netdissect_options *, const u_char *, u_int, const u_char *, int); extern void telnet_print(netdissect_options *, const u_char *, u_int); @@ -608,17 +699,19 @@ extern void timed_print(netdissect_options *, const u_char *); extern void tipc_print(netdissect_options *, const u_char *, u_int, u_int); extern u_int token_print(netdissect_options *, const u_char *, u_int, u_int); extern void udld_print(netdissect_options *, const u_char *, u_int); -extern void udp_print(netdissect_options *, const u_char *, u_int, const u_char *, int); -extern int vjc_print(netdissect_options *, register const char *, u_short); -extern void vqp_print(netdissect_options *, register const u_char *, register u_int); +extern void udp_print(netdissect_options *, const u_char *, u_int, const u_char *, int, u_int); +extern int vjc_print(netdissect_options *, const u_char *, u_short); +extern void vqp_print(netdissect_options *, const u_char *, u_int); extern void vrrp_print(netdissect_options *, const u_char *, u_int, const u_char *, int); -extern void vtp_print(netdissect_options *, const u_char *, u_int); -extern void vxlan_gpe_print(netdissect_options *ndo, const u_char *bp, u_int len); +extern void vtp_print(netdissect_options *, const u_char *, const u_int); +extern void vxlan_gpe_print(netdissect_options *, const u_char *, u_int); extern void vxlan_print(netdissect_options *, const u_char *, u_int); -extern void wb_print(netdissect_options *, const void *, u_int); -extern void zephyr_print(netdissect_options *, const u_char *, int); +extern void wb_print(netdissect_options *, const u_char *, u_int); +extern void zep_print(netdissect_options *, const u_char *, u_int); +extern void zephyr_print(netdissect_options *, const u_char *, u_int); extern void zmtp1_print(netdissect_options *, const u_char *, u_int); -extern void zmtp1_print_datagram(netdissect_options *, const u_char *, const u_int); +extern void zmtp1_datagram_print(netdissect_options *, const u_char *, const u_int); +extern void someip_print(netdissect_options *, const u_char *, const u_int); /* checksum routines */ extern void init_checksum(void); @@ -632,26 +725,32 @@ struct cksum_vec { extern uint16_t in_cksum(const struct cksum_vec *, int); extern uint16_t in_cksum_shouldbe(uint16_t, uint16_t); -extern int nextproto4_cksum(netdissect_options *, const struct ip *, const uint8_t *, u_int, u_int, u_int); +/* IP protocol demuxing routines */ +extern void ip_demux_print(netdissect_options *, const u_char *, u_int, u_int, int, u_int, uint8_t, const u_char *); + +extern uint16_t nextproto4_cksum(netdissect_options *, const struct ip *, const uint8_t *, u_int, u_int, uint8_t); /* in print-ip6.c */ -extern int nextproto6_cksum(netdissect_options *, const struct ip6_hdr *, const uint8_t *, u_int, u_int, u_int); +extern uint16_t nextproto6_cksum(netdissect_options *, const struct ip6_hdr *, const uint8_t *, u_int, u_int, uint8_t); /* Utilities */ +extern void nd_print_trunc(netdissect_options *); +extern void nd_print_protocol(netdissect_options *); +extern void nd_print_protocol_caps(netdissect_options *); +extern void nd_print_invalid(netdissect_options *); + extern int mask2plen(uint32_t); extern int mask62plen(const u_char *); extern const char *dnnum_string(netdissect_options *, u_short); -extern char *smb_errstr(int, int); -extern const char *nt_errstr(uint32_t); - -extern int decode_prefix4(netdissect_options *, const u_char *, u_int, char *, u_int); -extern int decode_prefix6(netdissect_options *, const u_char *, u_int, char *, u_int); +extern int decode_prefix4(netdissect_options *, const u_char *, u_int, char *, size_t); +extern int decode_prefix6(netdissect_options *, const u_char *, u_int, char *, size_t); -extern void esp_print_decodesecret(netdissect_options *); -extern int esp_print_decrypt_buffer_by_ikev2(netdissect_options *, int, - u_char spii[8], u_char spir[8], +extern void esp_decodesecret_print(netdissect_options *); +extern int esp_decrypt_buffer_by_ikev2_print(netdissect_options *, int, + const u_char spii[8], + const u_char spir[8], const u_char *, const u_char *); #endif /* netdissect_h */ diff --git a/contrib/tcpdump/nfs.h b/contrib/tcpdump/nfs.h index da7bc508db..76747f18c5 100644 --- a/contrib/tcpdump/nfs.h +++ b/contrib/tcpdump/nfs.h @@ -118,7 +118,6 @@ #define NFSX_V3FHMAX 64 /* max. allowed by protocol */ #define NFSX_V3FATTR 84 #define NFSX_V3SATTR 60 /* max. all fields filled in */ -#define NFSX_V3SRVSATTR (sizeof (struct nfsv3_sattr)) #define NFSX_V3POSTOPATTR (NFSX_V3FATTR + NFSX_UNSIGNED) #define NFSX_V3WCCDATA (NFSX_V3POSTOPATTR + 8 * NFSX_UNSIGNED) #define NFSX_V3COOKIEVERF 8 @@ -139,7 +138,6 @@ NFSX_V2FATTR) #define NFSX_WCCDATA(v3) ((v3) ? NFSX_V3WCCDATA : 0) #define NFSX_WCCORFATTR(v3) ((v3) ? NFSX_V3WCCDATA : NFSX_V2FATTR) -#define NFSX_SATTR(v3) ((v3) ? NFSX_V3SATTR : NFSX_V2SATTR) #define NFSX_COOKIEVERF(v3) ((v3) ? NFSX_V3COOKIEVERF : 0) #define NFSX_WRITEVERF(v3) ((v3) ? NFSX_V3WRITEVERF : 0) #define NFSX_READDIR(v3) ((v3) ? (5 * NFSX_UNSIGNED) : \ @@ -248,7 +246,15 @@ typedef enum { NFNON=0, NFREG=1, NFDIR=2, NFBLK=3, NFCHR=4, NFLNK=5, NFSOCK=6, NFFIFO=7 } nfs_type; -/* Structs for common parts of the rpc's */ +/* + * Structs for common parts of the rpc's + * + * NOTE: these structures are not always overlaid directly on the + * packet data - sometimes we declare a local variable of that type, + * and fill it up with fields extracted using byte pointers - so we + * don't use nd_ types for their members. + */ + /* * File Handle (32 bytes for version 2), variable up to 64 for version 3. * File Handles of up to NFS_SMALLFH in size are stored directly in the @@ -266,32 +272,23 @@ union nfsfh { typedef union nfsfh nfsfh_t; struct nfsv2_time { - uint32_t nfsv2_sec; - uint32_t nfsv2_usec; + nd_uint32_t nfsv2_sec; + nd_uint32_t nfsv2_usec; }; typedef struct nfsv2_time nfstime2; struct nfsv3_time { - uint32_t nfsv3_sec; - uint32_t nfsv3_nsec; + nd_uint32_t nfsv3_sec; + nd_uint32_t nfsv3_nsec; }; typedef struct nfsv3_time nfstime3; -/* - * Quads are defined as arrays of 2 longs to ensure dense packing for the - * protocol and to facilitate xdr conversion. - */ -struct nfs_uquad { - uint32_t nfsuquad[2]; -}; -typedef struct nfs_uquad nfsuint64; - /* * NFS Version 3 special file number. */ struct nfsv3_spec { - uint32_t specdata1; - uint32_t specdata2; + nd_uint32_t specdata1; + nd_uint32_t specdata2; }; typedef struct nfsv3_spec nfsv3spec; @@ -305,32 +302,32 @@ typedef struct nfsv3_spec nfsv3spec; * NFSX_FATTR(v3) macro. */ struct nfs_fattr { - uint32_t fa_type; - uint32_t fa_mode; - uint32_t fa_nlink; - uint32_t fa_uid; - uint32_t fa_gid; + nd_uint32_t fa_type; + nd_uint32_t fa_mode; + nd_uint32_t fa_nlink; + nd_uint32_t fa_uid; + nd_uint32_t fa_gid; union { struct { - uint32_t nfsv2fa_size; - uint32_t nfsv2fa_blocksize; - uint32_t nfsv2fa_rdev; - uint32_t nfsv2fa_blocks; - uint32_t nfsv2fa_fsid; - uint32_t nfsv2fa_fileid; - nfstime2 nfsv2fa_atime; - nfstime2 nfsv2fa_mtime; - nfstime2 nfsv2fa_ctime; + nd_uint32_t nfsv2fa_size; + nd_uint32_t nfsv2fa_blocksize; + nd_uint32_t nfsv2fa_rdev; + nd_uint32_t nfsv2fa_blocks; + nd_uint32_t nfsv2fa_fsid; + nd_uint32_t nfsv2fa_fileid; + nfstime2 nfsv2fa_atime; + nfstime2 nfsv2fa_mtime; + nfstime2 nfsv2fa_ctime; } fa_nfsv2; struct { - nfsuint64 nfsv3fa_size; - nfsuint64 nfsv3fa_used; - nfsv3spec nfsv3fa_rdev; - nfsuint64 nfsv3fa_fsid; - nfsuint64 nfsv3fa_fileid; - nfstime3 nfsv3fa_atime; - nfstime3 nfsv3fa_mtime; - nfstime3 nfsv3fa_ctime; + nd_uint64_t nfsv3fa_size; + nd_uint64_t nfsv3fa_used; + nfsv3spec nfsv3fa_rdev; + nd_uint64_t nfsv3fa_fsid; + nd_uint64_t nfsv3fa_fileid; + nfstime3 nfsv3fa_atime; + nfstime3 nfsv3fa_mtime; + nfstime3 nfsv3fa_ctime; } fa_nfsv3; } fa_un; }; @@ -355,49 +352,31 @@ struct nfs_fattr { #define fa3_ctime fa_un.fa_nfsv3.nfsv3fa_ctime struct nfsv2_sattr { - uint32_t sa_mode; - uint32_t sa_uid; - uint32_t sa_gid; - uint32_t sa_size; - nfstime2 sa_atime; - nfstime2 sa_mtime; -}; - -/* - * NFS Version 3 sattr structure for the new node creation case. - */ -struct nfsv3_sattr { - uint32_t sa_modeset; - uint32_t sa_mode; - uint32_t sa_uidset; - uint32_t sa_uid; - uint32_t sa_gidset; - uint32_t sa_gid; - uint32_t sa_sizeset; - uint32_t sa_size; - uint32_t sa_atimetype; - nfstime3 sa_atime; - uint32_t sa_mtimetype; - nfstime3 sa_mtime; + nd_uint32_t sa_mode; + nd_uint32_t sa_uid; + nd_uint32_t sa_gid; + nd_uint32_t sa_size; + nfstime2 sa_atime; + nfstime2 sa_mtime; }; struct nfs_statfs { union { struct { - uint32_t nfsv2sf_tsize; - uint32_t nfsv2sf_bsize; - uint32_t nfsv2sf_blocks; - uint32_t nfsv2sf_bfree; - uint32_t nfsv2sf_bavail; + nd_uint32_t nfsv2sf_tsize; + nd_uint32_t nfsv2sf_bsize; + nd_uint32_t nfsv2sf_blocks; + nd_uint32_t nfsv2sf_bfree; + nd_uint32_t nfsv2sf_bavail; } sf_nfsv2; struct { - nfsuint64 nfsv3sf_tbytes; - nfsuint64 nfsv3sf_fbytes; - nfsuint64 nfsv3sf_abytes; - nfsuint64 nfsv3sf_tfiles; - nfsuint64 nfsv3sf_ffiles; - nfsuint64 nfsv3sf_afiles; - uint32_t nfsv3sf_invarsec; + nd_uint64_t nfsv3sf_tbytes; + nd_uint64_t nfsv3sf_fbytes; + nd_uint64_t nfsv3sf_abytes; + nd_uint64_t nfsv3sf_tfiles; + nd_uint64_t nfsv3sf_ffiles; + nd_uint64_t nfsv3sf_afiles; + nd_uint32_t nfsv3sf_invarsec; } sf_nfsv3; } sf_un; }; @@ -416,23 +395,23 @@ struct nfs_statfs { #define sf_invarsec sf_un.sf_nfsv3.nfsv3sf_invarsec struct nfsv3_fsinfo { - uint32_t fs_rtmax; - uint32_t fs_rtpref; - uint32_t fs_rtmult; - uint32_t fs_wtmax; - uint32_t fs_wtpref; - uint32_t fs_wtmult; - uint32_t fs_dtpref; - nfsuint64 fs_maxfilesize; - nfstime3 fs_timedelta; - uint32_t fs_properties; + nd_uint32_t fs_rtmax; + nd_uint32_t fs_rtpref; + nd_uint32_t fs_rtmult; + nd_uint32_t fs_wtmax; + nd_uint32_t fs_wtpref; + nd_uint32_t fs_wtmult; + nd_uint32_t fs_dtpref; + nd_uint64_t fs_maxfilesize; + nfstime3 fs_timedelta; + nd_uint32_t fs_properties; }; struct nfsv3_pathconf { - uint32_t pc_linkmax; - uint32_t pc_namemax; - uint32_t pc_notrunc; - uint32_t pc_chownrestricted; - uint32_t pc_caseinsensitive; - uint32_t pc_casepreserving; + nd_uint32_t pc_linkmax; + nd_uint32_t pc_namemax; + nd_uint32_t pc_notrunc; + nd_uint32_t pc_chownrestricted; + nd_uint32_t pc_caseinsensitive; + nd_uint32_t pc_casepreserving; }; diff --git a/contrib/tcpdump/nfsfh.h b/contrib/tcpdump/nfsfh.h index 5cf8fc4417..bf378bbf6c 100644 --- a/contrib/tcpdump/nfsfh.h +++ b/contrib/tcpdump/nfsfh.h @@ -63,4 +63,4 @@ typedef struct { #define fsid_eq(a,b) ((a.fsid_code == b.fsid_code) &&\ dev_eq(a.Fsid_dev, b.Fsid_dev)) -extern void Parse_fh(const unsigned char *, u_int, my_fsid *, uint32_t *, const char **, const char **, int); +extern void Parse_fh(netdissect_options *, const unsigned char *, u_int, my_fsid *, uint32_t *, const char **, const char **, int); diff --git a/contrib/tcpdump/nlpid.c b/contrib/tcpdump/nlpid.c index 991ea3c69f..59f6e598aa 100644 --- a/contrib/tcpdump/nlpid.c +++ b/contrib/tcpdump/nlpid.c @@ -14,10 +14,10 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "nlpid.h" diff --git a/contrib/tcpdump/ntp.c b/contrib/tcpdump/ntp.c new file mode 100644 index 0000000000..4d17932ffd --- /dev/null +++ b/contrib/tcpdump/ntp.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 1990, 1991, 1992, 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. + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "ntp.h" + +#include "extract.h" + +#define JAN_1970 INT64_T_CONSTANT(2208988800) /* 1970 - 1900 in seconds */ + +void +p_ntp_time(netdissect_options *ndo, + const struct l_fixedpt *lfp) +{ + uint32_t i; + uint32_t uf; + uint32_t f; + double ff; + + i = GET_BE_U_4(lfp->int_part); + uf = GET_BE_U_4(lfp->fraction); + ff = uf; + if (ff < 0.0) /* some compilers are buggy */ + ff += FMAXINT; + ff = ff / FMAXINT; /* shift radix point by 32 bits */ + f = (uint32_t)(ff * 1000000000.0); /* treat fraction as parts per billion */ + ND_PRINT("%u.%09u", i, f); + +#ifdef HAVE_STRFTIME + /* + * print the UTC time in human-readable format. + */ + if (i) { + int64_t seconds_64bit = (int64_t)i - JAN_1970; + time_t seconds; + struct tm *tm; + char time_buf[128]; + + seconds = (time_t)seconds_64bit; + if (seconds != seconds_64bit) { + /* + * It doesn't fit into a time_t, so we can't hand it + * to gmtime. + */ + ND_PRINT(" (unrepresentable)"); + } else { + tm = gmtime(&seconds); + if (tm == NULL) { + /* + * gmtime() can't handle it. + * (Yes, that might happen with some version of + * Microsoft's C library.) + */ + ND_PRINT(" (unrepresentable)"); + } else { + /* use ISO 8601 (RFC3339) format */ + strftime(time_buf, sizeof (time_buf), "%Y-%m-%dT%H:%M:%SZ", tm); + ND_PRINT(" (%s)", time_buf); + } + } + } +#endif +} diff --git a/contrib/tcpdump/gmt2local.c b/contrib/tcpdump/ntp.h similarity index 51% rename from contrib/tcpdump/gmt2local.c rename to contrib/tcpdump/ntp.h index d6cd93b853..78644e2821 100644 --- a/contrib/tcpdump/gmt2local.c +++ b/contrib/tcpdump/ntp.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 + * Copyright (c) 1990, 1991, 1992, 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 @@ -17,50 +17,38 @@ * 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 "netdissect-stdinc.h" -#ifdef HAVE_OS_PROTO_H -#include "os-proto.h" -#endif - -#include "gmt2local.h" +#include "netdissect.h" /* - * Returns the difference between gmt and local time in seconds. - * Use gmtime() and localtime() to keep things simple. - */ -int32_t -gmt2local(time_t t) -{ - register int dt, dir; - register struct tm *gmt, *loc; - struct tm sgmt; - - if (t == 0) - t = time(NULL); - gmt = &sgmt; - *gmt = *gmtime(&t); - loc = localtime(&t); - dt = (loc->tm_hour - gmt->tm_hour) * 60 * 60 + - (loc->tm_min - gmt->tm_min) * 60; - - /* - * If the year or julian day is different, we span 00:00 GMT - * and must add or subtract a day. Check the year first to - * avoid problems when the julian day wraps. - */ - dir = loc->tm_year - gmt->tm_year; - if (dir == 0) - dir = loc->tm_yday - gmt->tm_yday; - dt += dir * 24 * 60 * 60; - - return (dt); -} + * Structure definitions for NTP fixed point values + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Integer Part | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Fraction Part | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Integer Part | Fraction Part | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ +struct l_fixedpt { + nd_uint32_t int_part; + nd_uint32_t fraction; +}; + +struct s_fixedpt { + nd_uint16_t int_part; + nd_uint16_t fraction; +}; + +void p_ntp_time(netdissect_options *, const struct l_fixedpt *); diff --git a/contrib/tcpdump/openflow.h b/contrib/tcpdump/openflow.h index 31ef03c425..2d56d154a2 100644 --- a/contrib/tcpdump/openflow.h +++ b/contrib/tcpdump/openflow.h @@ -30,7 +30,25 @@ /* for netdissect_options */ #include "netdissect.h" -#define OF_HEADER_LEN 8 +#define OF_FWD(n) { \ + cp += (n); \ + len -= (n); \ +} + +#define OF_CHK_FWD(n) { \ + ND_TCHECK_LEN(cp, (n)); \ + cp += (n); \ + len -= (n); \ +} + +#define OF_VER_1_0 0x01U +#define OF_VER_1_1 0x02U +#define OF_VER_1_2 0x03U +#define OF_VER_1_3 0x04U +#define OF_VER_1_4 0x05U +#define OF_VER_1_5 0x06U + +#define OF_HEADER_FIXLEN 8U #define ONF_EXP_ONF 0x4f4e4600 #define ONF_EXP_BUTE 0xff000001 @@ -40,12 +58,33 @@ #define ONF_EXP_WMOB 0xff000005 #define ONF_EXP_FABS 0xff000006 #define ONF_EXP_OTRANS 0xff000007 +#define ONF_EXP_NBLNCTU 0xff000008 +#define ONF_EXP_MPCE 0xff000009 +#define ONF_EXP_MPLSTPSPTN 0xff00000a extern const struct tok onf_exp_str[]; +extern const char * of_vendor_name(const uint32_t); +extern void of_bitmap_print(netdissect_options *ndo, + const struct tok *, const uint32_t, const uint32_t); +extern void of_data_print(netdissect_options *ndo, + const u_char *, const u_int); + /* - * Routines to print packets for various versions of OpenFlow. + * Routines to handle various versions of OpenFlow. */ -extern const u_char *of10_header_body_print(netdissect_options *ndo, - const u_char *, const u_char *, - const uint8_t, const uint16_t, const uint32_t); -extern const char * of_vendor_name(const uint32_t); + +struct of_msgtypeinfo { + /* Should not be NULL. */ + const char *name; + /* May be NULL to mean "message body printing is not implemented". */ + void (*decoder)(netdissect_options *ndo, const u_char *, const u_int); + enum { + REQ_NONE, /* Message body length may be anything. */ + REQ_FIXLEN, /* Message body length must be == req_value. */ + REQ_MINLEN, /* Message body length must be >= req_value. */ + } req_what; + uint16_t req_value; +}; + +extern const struct of_msgtypeinfo *of10_identify_msgtype(const uint8_t); +extern const struct of_msgtypeinfo *of13_identify_msgtype(const uint8_t); diff --git a/contrib/tcpdump/ospf.h b/contrib/tcpdump/ospf.h index b47aaf6931..a4e90c8cfd 100644 --- a/contrib/tcpdump/ospf.h +++ b/contrib/tcpdump/ospf.h @@ -20,7 +20,6 @@ * * OSPF support contributed by Jeffrey Honig (jch@mitchell.cit.cornell.edu) */ -#define OSPF_TYPE_UMD 0 /* UMd's special monitoring packets */ #define OSPF_TYPE_HELLO 1 /* Hello */ #define OSPF_TYPE_DD 2 /* Database Description */ #define OSPF_TYPE_LS_REQ 3 /* Link State Request */ @@ -35,11 +34,10 @@ * */ -#define OSPF_OPTION_T 0x01 /* T bit: TOS support */ -#define OSPF_OPTION_E 0x02 /* E bit: External routes advertised */ +#define OSPF_OPTION_MT 0x01 /* MT bit: multi-topology */ +#define OSPF_OPTION_E 0x02 /* E bit: External routes advertised */ #define OSPF_OPTION_MC 0x04 /* MC bit: Multicast capable */ #define OSPF_OPTION_NP 0x08 /* N/P bit: NSSA capable */ -#define OSPF_OPTION_EA 0x10 /* EA bit: External Attribute capable */ #define OSPF_OPTION_L 0x10 /* L bit: Packet contains LLS data block */ #define OSPF_OPTION_DC 0x20 /* DC bit: Demand circuit capable */ #define OSPF_OPTION_O 0x40 /* O bit: Opaque LSA capable */ @@ -148,14 +146,14 @@ * TOS metric struct (will be 0 or more in router links update) */ struct tos_metric { - uint8_t tos_type; - uint8_t reserved; - uint8_t tos_metric[2]; + nd_uint8_t tos_type; + nd_uint8_t reserved; + nd_uint16_t tos_metric; }; struct tos_link { - uint8_t link_type; - uint8_t link_tos_count; - uint8_t tos_metric[2]; + nd_uint8_t link_type; + nd_uint8_t link_tos_count; + nd_uint16_t tos_metric; }; union un_tos { struct tos_link link; @@ -164,20 +162,20 @@ union un_tos { /* link state advertisement header */ struct lsa_hdr { - uint16_t ls_age; - uint8_t ls_options; - uint8_t ls_type; + nd_uint16_t ls_age; + nd_uint8_t ls_options; + nd_uint8_t ls_type; union { - struct in_addr lsa_id; + nd_ipv4 lsa_id; struct { /* opaque LSAs change the LSA-ID field */ - uint8_t opaque_type; - uint8_t opaque_id[3]; + nd_uint8_t opaque_type; + nd_uint24_t opaque_id; } opaque_field; } un_lsa_id; - struct in_addr ls_router; - uint32_t ls_seq; - uint16_t ls_chksum; - uint16_t ls_length; + nd_ipv4 ls_router; + nd_uint32_t ls_seq; + nd_uint16_t ls_chksum; + nd_uint16_t ls_length; }; /* link state advertisement */ @@ -188,68 +186,68 @@ struct lsa { union { /* Router links advertisements */ struct { - uint8_t rla_flags; - uint8_t rla_zero[1]; - uint16_t rla_count; + nd_uint8_t rla_flags; + nd_byte rla_zero; + nd_uint16_t rla_count; struct rlalink { - struct in_addr link_id; - struct in_addr link_data; + nd_ipv4 link_id; + nd_ipv4 link_data; union un_tos un_tos; } rla_link[1]; /* may repeat */ } un_rla; /* Network links advertisements */ struct { - struct in_addr nla_mask; - struct in_addr nla_router[1]; /* may repeat */ + nd_ipv4 nla_mask; + nd_ipv4 nla_router[1]; /* may repeat */ } un_nla; /* Summary links advertisements */ struct { - struct in_addr sla_mask; - uint32_t sla_tosmetric[1]; /* may repeat */ + nd_ipv4 sla_mask; + nd_uint32_t sla_tosmetric[1]; /* may repeat */ } un_sla; /* AS external links advertisements */ struct { - struct in_addr asla_mask; + nd_ipv4 asla_mask; struct aslametric { - uint32_t asla_tosmetric; - struct in_addr asla_forward; - struct in_addr asla_tag; + nd_uint32_t asla_tosmetric; + nd_ipv4 asla_forward; + nd_ipv4 asla_tag; } asla_metric[1]; /* may repeat */ } un_asla; /* Multicast group membership */ struct mcla { - uint32_t mcla_vtype; - struct in_addr mcla_vid; + nd_uint32_t mcla_vtype; + nd_ipv4 mcla_vid; } un_mcla[1]; /* Opaque TE LSA */ struct { - uint16_t type; - uint16_t length; - uint8_t data[1]; /* may repeat */ - } un_te_lsa_tlv; + nd_uint16_t type; + nd_uint16_t length; + nd_byte data[1]; /* may repeat */ + } un_te_lsa_tlv[1]; /* may repeat */ /* Opaque Grace LSA */ struct { - uint16_t type; - uint16_t length; - uint8_t data[1]; /* may repeat */ - } un_grace_tlv; + nd_uint16_t type; + nd_uint16_t length; + nd_byte data[1]; /* may repeat */ + } un_grace_tlv[1]; /* may repeat */ /* Opaque Router information LSA */ struct { - uint16_t type; - uint16_t length; - uint8_t data[1]; /* may repeat */ - } un_ri_tlv; + nd_uint16_t type; + nd_uint16_t length; + nd_byte data[1]; /* may repeat */ + } un_ri_tlv[1]; /* may repeat */ /* Unknown LSA */ struct unknown { - uint8_t data[1]; /* may repeat */ + nd_byte data[1]; /* may repeat */ } un_unknown[1]; } lsa_un; @@ -261,54 +259,54 @@ struct lsa { * the main header */ struct ospfhdr { - uint8_t ospf_version; - uint8_t ospf_type; - uint16_t ospf_len; - struct in_addr ospf_routerid; - struct in_addr ospf_areaid; - uint16_t ospf_chksum; - uint16_t ospf_authtype; - uint8_t ospf_authdata[OSPF_AUTH_SIZE]; + nd_uint8_t ospf_version; + nd_uint8_t ospf_type; + nd_uint16_t ospf_len; + nd_ipv4 ospf_routerid; + nd_ipv4 ospf_areaid; + nd_uint16_t ospf_chksum; + nd_uint16_t ospf_authtype; + nd_byte ospf_authdata[OSPF_AUTH_SIZE]; union { /* Hello packet */ struct { - struct in_addr hello_mask; - uint16_t hello_helloint; - uint8_t hello_options; - uint8_t hello_priority; - uint32_t hello_deadint; - struct in_addr hello_dr; - struct in_addr hello_bdr; - struct in_addr hello_neighbor[1]; /* may repeat */ + nd_ipv4 hello_mask; + nd_uint16_t hello_helloint; + nd_uint8_t hello_options; + nd_uint8_t hello_priority; + nd_uint32_t hello_deadint; + nd_ipv4 hello_dr; + nd_ipv4 hello_bdr; + nd_ipv4 hello_neighbor[1]; /* may repeat */ } un_hello; /* Database Description packet */ struct { - uint16_t db_ifmtu; - uint8_t db_options; - uint8_t db_flags; - uint32_t db_seq; + nd_uint16_t db_ifmtu; + nd_uint8_t db_options; + nd_uint8_t db_flags; + nd_uint32_t db_seq; struct lsa_hdr db_lshdr[1]; /* may repeat */ } un_db; /* Link State Request */ struct lsr { - uint8_t ls_type[4]; + nd_uint32_t ls_type; union { - struct in_addr ls_stateid; + nd_ipv4 ls_stateid; struct { /* opaque LSAs change the LSA-ID field */ - uint8_t opaque_type; - uint8_t opaque_id[3]; + nd_uint8_t opaque_type; + nd_uint24_t opaque_id; } opaque_field; } un_ls_stateid; - struct in_addr ls_router; + nd_ipv4 ls_router; } un_lsr[1]; /* may repeat */ /* Link State Update */ struct { - uint32_t lsu_count; - struct lsa lsu_lsa[1]; /* may repeat */ + nd_uint32_t lsu_count; + struct lsa lsu_lsa[1]; /* may repeat */ } un_lsu; /* Link State Acknowledgement */ diff --git a/contrib/tcpdump/oui.c b/contrib/tcpdump/oui.c index 56cd12706d..25d08e213e 100644 --- a/contrib/tcpdump/oui.c +++ b/contrib/tcpdump/oui.c @@ -14,10 +14,10 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "oui.h" @@ -48,6 +48,9 @@ const struct tok oui_values[] = { { OUI_ONLAB, "Open Networking Lab" }, { OUI_FREESCALE, "Freescale" }, { OUI_NETRONOME, "Netronome" }, + { OUI_BROADCOM, "Broadcom" }, + { OUI_PMC_SIERRA, "PMC-Sierra" }, + { OUI_ERICSSON, "Ericsson" }, { 0, NULL } }; @@ -68,6 +71,8 @@ const struct tok smi_values[] = { { SMI_HEWLETT_PACKARD, "Hewlett Packard"}, { SMI_SUN_MICROSYSTEMS, "Sun Microsystems"}, { SMI_MERIT, "Merit"}, + { SMI_AT_AND_T, "AT&T"}, + { SMI_MOTOROLA, "Motorola"}, { SMI_SHIVA, "Shiva"}, { SMI_ERICSSON, "Ericsson AB"}, { SMI_CISCO_VPN5000, "Cisco VPN 5000"}, @@ -81,24 +86,46 @@ const struct tok smi_values[] = { { SMI_REDBACK, "Redback"}, { SMI_JUNIPER, "Juniper Networks"}, { SMI_APTIS, "Aptis"}, + { SMI_DT_AG, "Deutsche Telekom AG"}, + { SMI_IXIA, "Ixia Communications"}, { SMI_CISCO_VPN3000, "Cisco VPN 3000"}, { SMI_COSINE, "CoSine Communications"}, { SMI_NETSCREEN, "Netscreen"}, { SMI_SHASTA, "Shasta"}, { SMI_NOMADIX, "Nomadix"}, + { SMI_T_MOBILE, "T-Mobile"}, + { SMI_BROADBAND_FORUM, "The Broadband Forum"}, + { SMI_ZTE, "ZTE"}, { SMI_SIEMENS, "Siemens"}, { SMI_CABLELABS, "CableLabs"}, { SMI_UNISPHERE, "Unisphere Networks"}, { SMI_CISCO_BBSM, "Cisco BBSM"}, { SMI_THE3GPP2, "3rd Generation Partnership Project 2 (3GPP2)"}, + { SMI_SKT_TELECOM, "SK Telecom"}, { SMI_IP_UNPLUGGED, "ipUnplugged"}, { SMI_ISSANNI, "Issanni Communications"}, + { SMI_NETSCALER, "Netscaler"}, + { SMI_DE_TE_MOBIL, "T-Mobile"}, { SMI_QUINTUM, "Quintum"}, { SMI_INTERLINK, "Interlink"}, + { SMI_CNCTC, "CNCTC"}, + { SMI_STARENT_NETWORKS, "Starent Networks"}, { SMI_COLUBRIS, "Colubris"}, - { SMI_COLUMBIA_UNIVERSITY, "Columbia University"}, { SMI_THE3GPP, "3GPP"}, { SMI_GEMTEK_SYSTEMS, "Gemtek-Systems"}, + { SMI_BARRACUDA, "Barracuda Networks"}, + { SMI_ERICSSON_PKT_CORE, "Ericsson AB - Packet Core Networks"}, + { SMI_DACOM, "dacom"}, + { SMI_COLUMBIA_UNIVERSITY, "Columbia University"}, + { SMI_FORTINET, "Fortinet"}, + { SMI_VERIZON, "Verizon Wireless"}, + { SMI_PLIXER, "Plixer"}, { SMI_WIFI_ALLIANCE, "Wi-Fi Alliance"}, + { SMI_T_SYSTEMS_NOVA, "T-Systems Nova"}, + { SMI_CHINATELECOM_GUANZHOU, "China Telecom - Guangzhou Research Institute"}, + { SMI_GIGAMON, "Gigamon Systems"}, + { SMI_CACE, "CACE Technologies"}, + { SMI_NTOP, "ntop"}, + { SMI_ERICSSON_CANADA_INC, "Ericsson Canada"}, { 0, NULL} }; diff --git a/contrib/tcpdump/oui.h b/contrib/tcpdump/oui.h index a9f732a7ca..3c824756b6 100644 --- a/contrib/tcpdump/oui.h +++ b/contrib/tcpdump/oui.h @@ -40,12 +40,15 @@ extern const struct tok smi_values[]; #define OUI_ONLAB 0xa42305 /* Open Networking Lab */ #define OUI_FREESCALE 0x00049f /* Freescale */ #define OUI_NETRONOME 0x0015ad /* Netronome */ +#define OUI_BROADCOM 0x001018 /* Broadcom */ +#define OUI_PMC_SIERRA 0x00e004 /* PMC-Sierra */ +#define OUI_ERICSSON 0xd0f0db /* Ericsson */ /* * These are SMI Network Management Private Enterprise Codes for * organizations; see * - * http://www.iana.org/assignments/enterprise-numbers + * https://www.iana.org/assignments/enterprise-numbers * * for a list. * @@ -57,6 +60,8 @@ extern const struct tok smi_values[]; #define SMI_HEWLETT_PACKARD 11 #define SMI_SUN_MICROSYSTEMS 42 #define SMI_MERIT 61 +#define SMI_AT_AND_T 74 +#define SMI_MOTOROLA 161 #define SMI_SHIVA 166 #define SMI_ERICSSON 193 #define SMI_CISCO_VPN5000 255 @@ -70,22 +75,45 @@ extern const struct tok smi_values[]; #define SMI_REDBACK 2352 #define SMI_JUNIPER 2636 #define SMI_APTIS 2637 +#define SMI_DT_AG 2937 +#define SMI_IXIA 3054 #define SMI_CISCO_VPN3000 3076 #define SMI_COSINE 3085 #define SMI_SHASTA 3199 #define SMI_NETSCREEN 3224 #define SMI_NOMADIX 3309 +#define SMI_T_MOBILE 3414 +#define SMI_BROADBAND_FORUM 3561 +#define SMI_ZTE 3902 #define SMI_SIEMENS 4329 #define SMI_CABLELABS 4491 #define SMI_UNISPHERE 4874 #define SMI_CISCO_BBSM 5263 #define SMI_THE3GPP2 5535 +#define SMI_SKT_TELECOM 5806 #define SMI_IP_UNPLUGGED 5925 #define SMI_ISSANNI 5948 +#define SMI_NETSCALER 5951 +#define SMI_DE_TE_MOBIL 6490 #define SMI_QUINTUM 6618 #define SMI_INTERLINK 6728 +#define SMI_CNCTC 7951 +#define SMI_STARENT_NETWORKS 8164 #define SMI_COLUBRIS 8744 -#define SMI_COLUMBIA_UNIVERSITY 11862 #define SMI_THE3GPP 10415 #define SMI_GEMTEK_SYSTEMS 10529 +#define SMI_BARRACUDA 10704 +#define SMI_ERICSSON_PKT_CORE 10923 +#define SMI_DACOM 11665 +#define SMI_COLUMBIA_UNIVERSITY 11862 +#define SMI_FORTINET 12356 +#define SMI_VERIZON 12951 +#define SMI_PLIXER 13745 #define SMI_WIFI_ALLIANCE 14122 +#define SMI_T_SYSTEMS_NOVA 16787 +#define SMI_CHINATELECOM_GUANZHOU 20942 +#define SMI_GIGAMON 26866 +#define SMI_CACE 32622 +/* Greater than 32,767 need to be tagged unsigned. */ +#define SMI_NTOP 35632u +#define SMI_ERICSSON_CANADA_INC 46098u diff --git a/contrib/tcpdump/parsenfsfh.c b/contrib/tcpdump/parsenfsfh.c index 8f48e774d7..cd9436992d 100644 --- a/contrib/tcpdump/parsenfsfh.c +++ b/contrib/tcpdump/parsenfsfh.c @@ -41,15 +41,18 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include #include +#include "netdissect-ctype.h" + #include "netdissect.h" +#include "extract.h" #include "nfsfh.h" /* @@ -76,42 +79,16 @@ #define FHT_HPUX9 11 #define FHT_BSD44 12 -#ifdef ultrix -/* Nasty hack to keep the Ultrix C compiler from emitting bogus warnings */ -#define XFF(x) ((uint32_t)(x)) -#else -#define XFF(x) (x) -#endif - -#define make_uint32(msb,b,c,lsb)\ - (XFF(lsb) + (XFF(c)<<8) + (XFF(b)<<16) + (XFF(msb)<<24)) - -#define make_uint24(msb,b, lsb)\ - (XFF(lsb) + (XFF(b)<<8) + (XFF(msb)<<16)) - -#define make_uint16(msb,lsb)\ - (XFF(lsb) + (XFF(msb)<<8)) - -#ifdef __alpha - /* or other 64-bit systems */ -#define make_uint48(msb,b,c,d,e,lsb)\ - ((lsb) + ((e)<<8) + ((d)<<16) + ((c)<<24) + ((b)<<32) + ((msb)<<40)) -#else - /* on 32-bit systems ignore high-order bits */ -#define make_uint48(msb,b,c,d,e,lsb)\ - ((lsb) + ((e)<<8) + ((d)<<16) + ((c)<<24)) -#endif - -static int is_UCX(const unsigned char *, u_int); +static int is_UCX(netdissect_options *, const unsigned char *, u_int); void -Parse_fh(register const unsigned char *fh, u_int len, my_fsid *fsidp, - uint32_t *inop, +Parse_fh(netdissect_options *ndo, const unsigned char *fh, u_int len, + my_fsid *fsidp, uint32_t *inop, const char **osnamep, /* if non-NULL, return OS name here */ const char **fsnamep, /* if non-NULL, return server fs name here (for VMS) */ int ourself) /* true if file handle was generated on this host */ { - register const unsigned char *fhp = fh; + const unsigned char *fhp = fh; uint32_t temp; int fhtype = FHT_UNKNOWN; u_int i; @@ -154,10 +131,10 @@ Parse_fh(register const unsigned char *fh, u_int len, my_fsid *fsidp, /* * This is basically a big decision tree */ - else if ((fhp[0] == 0) && (fhp[1] == 0)) { + else if ((GET_U_1(fhp) == 0) && (GET_U_1(fhp + 1) == 0)) { /* bytes[0,1] == (0,0); rules out Ultrix, IRIX5, SUNOS5 */ /* probably rules out HP-UX, AIX unless they allow major=0 */ - if ((fhp[2] == 0) && (fhp[3] == 0)) { + if ((GET_U_1(fhp + 2) == 0) && (GET_U_1(fhp + 3) == 0)) { /* bytes[2,3] == (0,0); must be Auspex */ /* XXX or could be Ultrix+MASSBUS "hp" disk? */ fhtype = FHT_AUSPEX; @@ -167,16 +144,16 @@ Parse_fh(register const unsigned char *fh, u_int len, my_fsid *fsidp, * bytes[2,3] != (0,0); rules out Auspex, could be * DECOSF, SUNOS4, or IRIX4 */ - if ((fhp[4] != 0) && (fhp[5] == 0) && - (fhp[8] == 12) && (fhp[9] == 0)) { + if ((GET_U_1(fhp + 4) != 0) && (GET_U_1(fhp + 5) == 0) && + (GET_U_1(fhp + 8) == 12) && (GET_U_1(fhp + 9) == 0)) { /* seems to be DECOSF, with minor == 0 */ fhtype = FHT_DECOSF; } else { /* could be SUNOS4 or IRIX4 */ /* XXX the test of fhp[5] == 8 could be wrong */ - if ((fhp[4] == 0) && (fhp[5] == 8) && (fhp[6] == 0) && - (fhp[7] == 0)) { + if ((GET_U_1(fhp + 4) == 0) && (GET_U_1(fhp + 5) == 8) && (GET_U_1(fhp + 6) == 0) && + (GET_U_1(fhp + 7) == 0)) { /* looks like a length, not a file system typecode */ fhtype = FHT_IRIX4; } @@ -193,24 +170,24 @@ Parse_fh(register const unsigned char *fh, u_int len, my_fsid *fsidp, * could be IRIX5, DECOSF, UCX, Ultrix, SUNOS5 * could be AIX, HP-UX */ - if ((fhp[2] == 0) && (fhp[3] == 0)) { + if ((GET_U_1(fhp + 2) == 0) && (GET_U_1(fhp + 3) == 0)) { /* * bytes[2,3] == (0,0); rules out OSF, probably not UCX * (unless the exported device name is just one letter!), * could be Ultrix, IRIX5, AIX, or SUNOS5 * might be HP-UX (depends on their values for minor devs) */ - if ((fhp[6] == 0) && (fhp[7] == 0)) { + if ((GET_U_1(fhp + 6) == 0) && (GET_U_1(fhp + 7) == 0)) { fhtype = FHT_BSD44; } /*XXX we probably only need to test of these two bytes */ - else if ((len >= 24/4) && (fhp[21] == 0) && (fhp[23] == 0)) { + else if ((len >= 24/4) && (GET_U_1(fhp + 21) == 0) && (GET_U_1(fhp + 23) == 0)) { fhtype = FHT_ULTRIX; } else { /* Could be SUNOS5/IRIX5, maybe AIX */ /* XXX no obvious difference between SUNOS5 and IRIX5 */ - if (fhp[9] == 10) + if (GET_U_1(fhp + 9) == 10) fhtype = FHT_SUNOS5; /* XXX what about AIX? */ } @@ -220,17 +197,17 @@ Parse_fh(register const unsigned char *fh, u_int len, my_fsid *fsidp, * bytes[2,3] != (0,0); rules out Ultrix, could be * DECOSF, SUNOS5, IRIX5, AIX, HP-UX, or UCX */ - if ((fhp[8] == 12) && (fhp[9] == 0)) { + if ((GET_U_1(fhp + 8) == 12) && (GET_U_1(fhp + 9) == 0)) { fhtype = FHT_DECOSF; } - else if ((fhp[8] == 0) && (fhp[9] == 10)) { + else if ((GET_U_1(fhp + 8) == 0) && (GET_U_1(fhp + 9) == 10)) { /* could be SUNOS5/IRIX5, AIX, HP-UX */ - if ((fhp[7] == 0) && (fhp[6] == 0) && - (fhp[5] == 0) && (fhp[4] == 0)) { + if ((GET_U_1(fhp + 7) == 0) && (GET_U_1(fhp + 6) == 0) && + (GET_U_1(fhp + 5) == 0) && (GET_U_1(fhp + 4) == 0)) { /* XXX is this always true of HP-UX? */ fhtype = FHT_HPUX9; } - else if (fhp[7] == 2) { + else if (GET_U_1(fhp + 7) == 2) { /* This would be MNT_NFS on AIX, which is impossible */ fhtype = FHT_SUNOS5; /* or maybe IRIX5 */ } @@ -245,7 +222,7 @@ Parse_fh(register const unsigned char *fh, u_int len, my_fsid *fsidp, } } else { - if (is_UCX(fhp, len)) { + if (is_UCX(ndo, fhp, len)) { fhtype = FHT_VMSUCX; } else { @@ -260,57 +237,57 @@ Parse_fh(register const unsigned char *fh, u_int len, my_fsid *fsidp, switch (fhtype) { case FHT_AUSPEX: - fsidp->Fsid_dev.Minor = fhp[7]; - fsidp->Fsid_dev.Major = fhp[6]; + fsidp->Fsid_dev.Minor = GET_U_1(fhp + 7); + fsidp->Fsid_dev.Major = GET_U_1(fhp + 6); fsidp->fsid_code = 0; - *inop = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); + *inop = GET_BE_U_4(fhp + 12); if (osnamep) *osnamep = "Auspex"; break; case FHT_BSD44: - fsidp->Fsid_dev.Minor = fhp[0]; - fsidp->Fsid_dev.Major = fhp[1]; + fsidp->Fsid_dev.Minor = GET_U_1(fhp); + fsidp->Fsid_dev.Major = GET_U_1(fhp + 1); fsidp->fsid_code = 0; - *inop = make_uint32(fhp[15], fhp[14], fhp[13], fhp[12]); + *inop = GET_LE_U_4(fhp + 12); if (osnamep) *osnamep = "BSD 4.4"; break; case FHT_DECOSF: - fsidp->fsid_code = make_uint32(fhp[7], fhp[6], fhp[5], fhp[4]); + fsidp->fsid_code = GET_LE_U_4(fhp + 4); /* XXX could ignore 3 high-order bytes */ - temp = make_uint32(fhp[3], fhp[2], fhp[1], fhp[0]); + temp = GET_LE_U_4(fhp); fsidp->Fsid_dev.Minor = temp & 0xFFFFF; fsidp->Fsid_dev.Major = (temp>>20) & 0xFFF; - *inop = make_uint32(fhp[15], fhp[14], fhp[13], fhp[12]); + *inop = GET_LE_U_4(fhp + 12); if (osnamep) *osnamep = "OSF"; break; case FHT_IRIX4: - fsidp->Fsid_dev.Minor = fhp[3]; - fsidp->Fsid_dev.Major = fhp[2]; + fsidp->Fsid_dev.Minor = GET_U_1(fhp + 3); + fsidp->Fsid_dev.Major = GET_U_1(fhp + 2); fsidp->fsid_code = 0; - *inop = make_uint32(fhp[8], fhp[9], fhp[10], fhp[11]); + *inop = GET_BE_U_4(fhp + 8); if (osnamep) *osnamep = "IRIX4"; break; case FHT_IRIX5: - fsidp->Fsid_dev.Minor = make_uint16(fhp[2], fhp[3]); - fsidp->Fsid_dev.Major = make_uint16(fhp[0], fhp[1]); - fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); + fsidp->Fsid_dev.Minor = GET_BE_U_2(fhp + 2); + fsidp->Fsid_dev.Major = GET_BE_U_2(fhp); + fsidp->fsid_code = GET_BE_U_4(fhp + 4); - *inop = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); + *inop = GET_BE_U_4(fhp + 12); if (osnamep) *osnamep = "IRIX5"; @@ -328,24 +305,24 @@ Parse_fh(register const unsigned char *fh, u_int len, my_fsid *fsidp, #endif case FHT_SUNOS4: - fsidp->Fsid_dev.Minor = fhp[3]; - fsidp->Fsid_dev.Major = fhp[2]; - fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); + fsidp->Fsid_dev.Minor = GET_U_1(fhp + 3); + fsidp->Fsid_dev.Major = GET_U_1(fhp + 2); + fsidp->fsid_code = GET_BE_U_4(fhp + 4); - *inop = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); + *inop = GET_BE_U_4(fhp + 12); if (osnamep) *osnamep = "SUNOS4"; break; case FHT_SUNOS5: - temp = make_uint16(fhp[0], fhp[1]); + temp = GET_BE_U_2(fhp); fsidp->Fsid_dev.Major = (temp>>2) & 0x3FFF; - temp = make_uint24(fhp[1], fhp[2], fhp[3]); + temp = GET_BE_U_3(fhp + 1); fsidp->Fsid_dev.Minor = temp & 0x3FFFF; - fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); + fsidp->fsid_code = GET_BE_U_4(fhp + 4); - *inop = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); + *inop = GET_BE_U_4(fhp + 12); if (osnamep) *osnamep = "SUNOS5"; @@ -353,10 +330,10 @@ Parse_fh(register const unsigned char *fh, u_int len, my_fsid *fsidp, case FHT_ULTRIX: fsidp->fsid_code = 0; - fsidp->Fsid_dev.Minor = fhp[0]; - fsidp->Fsid_dev.Major = fhp[1]; + fsidp->Fsid_dev.Minor = GET_U_1(fhp); + fsidp->Fsid_dev.Major = GET_U_1(fhp + 1); - temp = make_uint32(fhp[7], fhp[6], fhp[5], fhp[4]); + temp = GET_LE_U_4(fhp + 4); *inop = temp; if (osnamep) *osnamep = "Ultrix"; @@ -381,34 +358,36 @@ Parse_fh(register const unsigned char *fh, u_int len, my_fsid *fsidp, } /* VMS file ID is: (RVN, FidHi, FidLo) */ - *inop = make_uint32(fhp[26], fhp[27], fhp[23], fhp[22]); + *inop = (((uint32_t) GET_U_1(fhp + 26)) << 24) | + (((uint32_t) GET_U_1(fhp + 27)) << 16) | + (GET_LE_U_2(fhp + 22) << 0); /* Caller must save (and null-terminate?) this value */ if (fsnamep) - *fsnamep = (const char *)&(fhp[1]); + *fsnamep = (const char *)(fhp + 1); if (osnamep) *osnamep = "VMS"; break; case FHT_AIX32: - fsidp->Fsid_dev.Minor = make_uint16(fhp[2], fhp[3]); - fsidp->Fsid_dev.Major = make_uint16(fhp[0], fhp[1]); - fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); + fsidp->Fsid_dev.Minor = GET_BE_U_2(fhp + 2); + fsidp->Fsid_dev.Major = GET_BE_U_2(fhp); + fsidp->fsid_code = GET_BE_U_4(fhp + 4); - *inop = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); + *inop = GET_BE_U_4(fhp + 12); if (osnamep) *osnamep = "AIX32"; break; case FHT_HPUX9: - fsidp->Fsid_dev.Major = fhp[0]; - temp = make_uint24(fhp[1], fhp[2], fhp[3]); + fsidp->Fsid_dev.Major = GET_U_1(fhp); + temp = GET_BE_U_3(fhp + 1); fsidp->Fsid_dev.Minor = temp; - fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); + fsidp->fsid_code = GET_BE_U_4(fhp + 4); - *inop = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); + *inop = GET_BE_U_4(fhp + 12); if (osnamep) *osnamep = "HPUX9"; @@ -418,12 +397,13 @@ Parse_fh(register const unsigned char *fh, u_int len, my_fsid *fsidp, #ifdef DEBUG /* XXX debugging */ for (i = 0; i < len*4; i++) - (void)fprintf(stderr, "%x.", fhp[i]); + (void)fprintf(stderr, "%x.", GET_U_1(fhp + i)); (void)fprintf(stderr, "\n"); #endif /* Save the actual handle, so it can be display with -u */ for (i = 0; i < len*4 && i*2 < sizeof(fsidp->Opaque_Handle) - 1; i++) - (void)snprintf(&(fsidp->Opaque_Handle[i*2]), 3, "%.2X", fhp[i]); + (void)snprintf(&(fsidp->Opaque_Handle[i*2]), 3, "%.2X", + GET_U_1(fhp + i)); fsidp->Opaque_Handle[i*2] = '\0'; /* XXX for now, give "bogus" values to aid debugging */ @@ -451,9 +431,9 @@ Parse_fh(register const unsigned char *fh, u_int len, my_fsid *fsidp, * (3) followed by string of nulls */ static int -is_UCX(const unsigned char *fhp, u_int len) +is_UCX(netdissect_options *ndo, const unsigned char *fhp, u_int len) { - register u_int i; + u_int i; int seen_null = 0; /* @@ -464,13 +444,13 @@ is_UCX(const unsigned char *fhp, u_int len) return(0); for (i = 1; i < 14; i++) { - if (ND_ISPRINT(fhp[i])) { + if (ND_ASCII_ISPRINT(GET_U_1(fhp + i))) { if (seen_null) return(0); else continue; } - else if (fhp[i] == 0) { + else if (GET_U_1(fhp + i) == 0) { seen_null = 1; continue; } diff --git a/contrib/tcpdump/ppp.h b/contrib/tcpdump/ppp.h index 9d53423f3b..830fad9d8e 100644 --- a/contrib/tcpdump/ppp.h +++ b/contrib/tcpdump/ppp.h @@ -19,8 +19,8 @@ #define PPP_ADDRESS 0xff /* The address byte value */ #define PPP_CONTROL 0x03 /* The control byte value */ -#define PPP_WITHDIRECTION_IN 0x00 /* non-standard for DLT_PPP_WITHDIRECTION */ -#define PPP_WITHDIRECTION_OUT 0x01 /* non-standard for DLT_PPP_WITHDIRECTION */ +#define PPP_PPPD_IN 0x00 /* non-standard for DLT_PPP_PPPD */ +#define PPP_PPPD_OUT 0x01 /* non-standard for DLT_PPP_PPPD */ /* Protocol numbers */ #define PPP_IP 0x0021 /* Raw IP */ @@ -34,9 +34,9 @@ #define PPP_BRPDU 0x0031 /* Bridging PDU */ #define PPP_STII 0x0033 /* Stream Protocol (ST-II) */ #define PPP_VINES 0x0035 /* Banyan Vines */ -#define PPP_ML 0x003d /* Multi-Link PPP */ +#define PPP_ML 0x003d /* Multi-Link PPP */ #define PPP_IPV6 0x0057 /* IPv6 */ -#define PPP_COMP 0x00fd /* Compressed Datagram */ +#define PPP_COMP 0x00fd /* Compressed Datagram */ #define PPP_HELLO 0x0201 /* 802.1d Hello Packets */ #define PPP_LUXCOM 0x0231 /* Luxcom */ diff --git a/contrib/tcpdump/print-802_11.c b/contrib/tcpdump/print-802_11.c index 50a3e9f596..e901752a37 100644 --- a/contrib/tcpdump/print-802_11.c +++ b/contrib/tcpdump/print-802_11.c @@ -23,10 +23,10 @@ /* \summary: IEEE 802.11 printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include @@ -75,22 +75,22 @@ #define T_DATA 0x2 /* data */ #define T_RESV 0x3 /* reserved */ -#define ST_ASSOC_REQUEST 0x0 -#define ST_ASSOC_RESPONSE 0x1 -#define ST_REASSOC_REQUEST 0x2 -#define ST_REASSOC_RESPONSE 0x3 -#define ST_PROBE_REQUEST 0x4 -#define ST_PROBE_RESPONSE 0x5 -/* RESERVED 0x6 */ -/* RESERVED 0x7 */ -#define ST_BEACON 0x8 +#define ST_ASSOC_REQUEST 0x0 +#define ST_ASSOC_RESPONSE 0x1 +#define ST_REASSOC_REQUEST 0x2 +#define ST_REASSOC_RESPONSE 0x3 +#define ST_PROBE_REQUEST 0x4 +#define ST_PROBE_RESPONSE 0x5 +/* RESERVED 0x6 */ +/* RESERVED 0x7 */ +#define ST_BEACON 0x8 #define ST_ATIM 0x9 #define ST_DISASSOC 0xA #define ST_AUTH 0xB #define ST_DEAUTH 0xC #define ST_ACTION 0xD -/* RESERVED 0xE */ -/* RESERVED 0xF */ +/* RESERVED 0xE */ +/* RESERVED 0xF */ static const struct tok st_str[] = { { ST_ASSOC_REQUEST, "Assoc Request" }, @@ -174,12 +174,12 @@ static const struct tok ctrl_str[] = { #define FC_ORDER(fc) ((fc) & 0x8000) struct mgmt_header_t { - uint16_t fc; - uint16_t duration; - uint8_t da[IEEE802_11_DA_LEN]; - uint8_t sa[IEEE802_11_SA_LEN]; - uint8_t bssid[IEEE802_11_BSSID_LEN]; - uint16_t seq_ctrl; + nd_uint16_t fc; + nd_uint16_t duration; + nd_mac_addr da; + nd_mac_addr sa; + nd_mac_addr bssid; + nd_uint16_t seq_ctrl; }; #define MGMT_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ @@ -215,7 +215,7 @@ struct fh_t { uint8_t length; uint16_t dwell_time; uint8_t hop_set; - uint8_t hop_pattern; + uint8_t hop_pattern; uint8_t hop_index; }; @@ -231,7 +231,7 @@ struct cf_t { uint8_t count; uint8_t period; uint16_t max_duration; - uint16_t dur_remaing; + uint16_t dur_remaining; }; struct tim_t { @@ -243,38 +243,38 @@ struct tim_t { uint8_t bitmap[251]; }; -#define E_SSID 0 -#define E_RATES 1 -#define E_FH 2 -#define E_DS 3 -#define E_CF 4 -#define E_TIM 5 -#define E_IBSS 6 -/* reserved 7 */ -/* reserved 8 */ -/* reserved 9 */ -/* reserved 10 */ -/* reserved 11 */ -/* reserved 12 */ -/* reserved 13 */ -/* reserved 14 */ -/* reserved 15 */ -/* reserved 16 */ - -#define E_CHALLENGE 16 -/* reserved 17 */ -/* reserved 18 */ -/* reserved 19 */ -/* reserved 16 */ -/* reserved 16 */ +#define E_SSID 0 +#define E_RATES 1 +#define E_FH 2 +#define E_DS 3 +#define E_CF 4 +#define E_TIM 5 +#define E_IBSS 6 +/* reserved 7 */ +/* reserved 8 */ +/* reserved 9 */ +/* reserved 10 */ +/* reserved 11 */ +/* reserved 12 */ +/* reserved 13 */ +/* reserved 14 */ +/* reserved 15 */ +/* reserved 16 */ + +#define E_CHALLENGE 16 +/* reserved 17 */ +/* reserved 18 */ +/* reserved 19 */ +/* reserved 16 */ +/* reserved 16 */ struct mgmt_body_t { - uint8_t timestamp[IEEE802_11_TSTAMP_LEN]; - uint16_t beacon_interval; - uint16_t listen_interval; - uint16_t status_code; - uint16_t aid; + uint8_t timestamp[IEEE802_11_TSTAMP_LEN]; + uint16_t beacon_interval; + uint16_t listen_interval; + uint16_t status_code; + uint16_t aid; u_char ap[IEEE802_11_AP_LEN]; uint16_t reason_code; uint16_t auth_alg; @@ -285,7 +285,7 @@ struct mgmt_body_t { int ssid_present; struct ssid_t ssid; int rates_present; - struct rates_t rates; + struct rates_t rates; int ds_present; struct ds_t ds; int cf_present; @@ -297,11 +297,11 @@ struct mgmt_body_t { }; struct ctrl_control_wrapper_hdr_t { - uint16_t fc; - uint16_t duration; - uint8_t addr1[IEEE802_11_ADDR1_LEN]; - uint16_t carried_fc[IEEE802_11_CARRIED_FC_LEN]; - uint16_t ht_control[IEEE802_11_HT_CONTROL_LEN]; + nd_uint16_t fc; + nd_uint16_t duration; + nd_mac_addr addr1; + nd_uint16_t carried_fc[IEEE802_11_CARRIED_FC_LEN]; + nd_uint16_t ht_control[IEEE802_11_HT_CONTROL_LEN]; }; #define CTRL_CONTROL_WRAPPER_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ @@ -310,76 +310,76 @@ struct ctrl_control_wrapper_hdr_t { IEEE802_11_HT_CONTROL_LEN) struct ctrl_rts_hdr_t { - uint16_t fc; - uint16_t duration; - uint8_t ra[IEEE802_11_RA_LEN]; - uint8_t ta[IEEE802_11_TA_LEN]; + nd_uint16_t fc; + nd_uint16_t duration; + nd_mac_addr ra; + nd_mac_addr ta; }; #define CTRL_RTS_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ IEEE802_11_RA_LEN+IEEE802_11_TA_LEN) struct ctrl_cts_hdr_t { - uint16_t fc; - uint16_t duration; - uint8_t ra[IEEE802_11_RA_LEN]; + nd_uint16_t fc; + nd_uint16_t duration; + nd_mac_addr ra; }; #define CTRL_CTS_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN) struct ctrl_ack_hdr_t { - uint16_t fc; - uint16_t duration; - uint8_t ra[IEEE802_11_RA_LEN]; + nd_uint16_t fc; + nd_uint16_t duration; + nd_mac_addr ra; }; #define CTRL_ACK_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN) struct ctrl_ps_poll_hdr_t { - uint16_t fc; - uint16_t aid; - uint8_t bssid[IEEE802_11_BSSID_LEN]; - uint8_t ta[IEEE802_11_TA_LEN]; + nd_uint16_t fc; + nd_uint16_t aid; + nd_mac_addr bssid; + nd_mac_addr ta; }; #define CTRL_PS_POLL_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_AID_LEN+\ IEEE802_11_BSSID_LEN+IEEE802_11_TA_LEN) struct ctrl_end_hdr_t { - uint16_t fc; - uint16_t duration; - uint8_t ra[IEEE802_11_RA_LEN]; - uint8_t bssid[IEEE802_11_BSSID_LEN]; + nd_uint16_t fc; + nd_uint16_t duration; + nd_mac_addr ra; + nd_mac_addr bssid; }; #define CTRL_END_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ IEEE802_11_RA_LEN+IEEE802_11_BSSID_LEN) struct ctrl_end_ack_hdr_t { - uint16_t fc; - uint16_t duration; - uint8_t ra[IEEE802_11_RA_LEN]; - uint8_t bssid[IEEE802_11_BSSID_LEN]; + nd_uint16_t fc; + nd_uint16_t duration; + nd_mac_addr ra; + nd_mac_addr bssid; }; #define CTRL_END_ACK_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ IEEE802_11_RA_LEN+IEEE802_11_BSSID_LEN) struct ctrl_ba_hdr_t { - uint16_t fc; - uint16_t duration; - uint8_t ra[IEEE802_11_RA_LEN]; + nd_uint16_t fc; + nd_uint16_t duration; + nd_mac_addr ra; }; #define CTRL_BA_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN) struct ctrl_bar_hdr_t { - uint16_t fc; - uint16_t dur; - uint8_t ra[IEEE802_11_RA_LEN]; - uint8_t ta[IEEE802_11_TA_LEN]; - uint16_t ctl; - uint16_t seq; + nd_uint16_t fc; + nd_uint16_t dur; + nd_mac_addr ra; + nd_mac_addr ta; + nd_uint16_t ctl; + nd_uint16_t seq; }; #define CTRL_BAR_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ @@ -387,12 +387,12 @@ struct ctrl_bar_hdr_t { IEEE802_11_CTL_LEN+IEEE802_11_SEQ_LEN) struct meshcntl_t { - uint8_t flags; - uint8_t ttl; - uint8_t seq[4]; - uint8_t addr4[6]; - uint8_t addr5[6]; - uint8_t addr6[6]; + nd_uint8_t flags; + nd_uint8_t ttl; + nd_uint32_t seq; + nd_mac_addr addr4; + nd_mac_addr addr5; + nd_mac_addr addr6; }; #define IV_IV(iv) ((iv) & 0xFFFFFF) @@ -401,13 +401,13 @@ struct meshcntl_t { #define PRINT_SSID(p) \ if (p.ssid_present) { \ - ND_PRINT((ndo, " (")); \ - fn_print(ndo, p.ssid.ssid, NULL); \ - ND_PRINT((ndo, ")")); \ + ND_PRINT(" ("); \ + fn_print_str(ndo, p.ssid.ssid); \ + ND_PRINT(")"); \ } #define PRINT_RATE(_sep, _r, _suf) \ - ND_PRINT((ndo, "%s%2.1f%s", _sep, (.5 * ((_r) & 0x7f)), _suf)) + ND_PRINT("%s%2.1f%s", _sep, (.5 * ((_r) & 0x7f)), _suf) #define PRINT_RATES(p) \ if (p.rates_present) { \ int z; \ @@ -418,14 +418,14 @@ struct meshcntl_t { sep = " "; \ } \ if (p.rates.length != 0) \ - ND_PRINT((ndo, " Mbit]")); \ + ND_PRINT(" Mbit]"); \ } #define PRINT_DS_CHANNEL(p) \ if (p.ds_present) \ - ND_PRINT((ndo, " CH: %u", p.ds.channel)); \ - ND_PRINT((ndo, "%s", \ - CAPABILITY_PRIVACY(p.capability_info) ? ", PRIVACY" : "")); + ND_PRINT(" CH: %u", p.ds.channel); \ + ND_PRINT("%s", \ + CAPABILITY_PRIVACY(p.capability_info) ? ", PRIVACY" : ""); #define MAX_MCS_INDEX 76 @@ -440,514 +440,613 @@ struct meshcntl_t { */ 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, }, + { /* 20 Mhz */ { 6.5f, /* SGI */ 7.2f, }, + /* 40 Mhz */ { 13.5f, /* SGI */ 15.0f, }, }, /* MCS 1 */ - { /* 20 Mhz */ { 13.0, /* SGI */ 14.4, }, - /* 40 Mhz */ { 27.0, /* SGI */ 30.0, }, + { /* 20 Mhz */ { 13.0f, /* SGI */ 14.4f, }, + /* 40 Mhz */ { 27.0f, /* SGI */ 30.0f, }, }, /* MCS 2 */ - { /* 20 Mhz */ { 19.5, /* SGI */ 21.7, }, - /* 40 Mhz */ { 40.5, /* SGI */ 45.0, }, + { /* 20 Mhz */ { 19.5f, /* SGI */ 21.7f, }, + /* 40 Mhz */ { 40.5f, /* SGI */ 45.0f, }, }, /* MCS 3 */ - { /* 20 Mhz */ { 26.0, /* SGI */ 28.9, }, - /* 40 Mhz */ { 54.0, /* SGI */ 60.0, }, + { /* 20 Mhz */ { 26.0f, /* SGI */ 28.9f, }, + /* 40 Mhz */ { 54.0f, /* SGI */ 60.0f, }, }, /* MCS 4 */ - { /* 20 Mhz */ { 39.0, /* SGI */ 43.3, }, - /* 40 Mhz */ { 81.0, /* SGI */ 90.0, }, + { /* 20 Mhz */ { 39.0f, /* SGI */ 43.3f, }, + /* 40 Mhz */ { 81.0f, /* SGI */ 90.0f, }, }, /* MCS 5 */ - { /* 20 Mhz */ { 52.0, /* SGI */ 57.8, }, - /* 40 Mhz */ { 108.0, /* SGI */ 120.0, }, + { /* 20 Mhz */ { 52.0f, /* SGI */ 57.8f, }, + /* 40 Mhz */ { 108.0f, /* SGI */ 120.0f, }, }, /* MCS 6 */ - { /* 20 Mhz */ { 58.5, /* SGI */ 65.0, }, - /* 40 Mhz */ { 121.5, /* SGI */ 135.0, }, + { /* 20 Mhz */ { 58.5f, /* SGI */ 65.0f, }, + /* 40 Mhz */ { 121.5f, /* SGI */ 135.0f, }, }, /* MCS 7 */ - { /* 20 Mhz */ { 65.0, /* SGI */ 72.2, }, - /* 40 Mhz */ { 135.0, /* SGI */ 150.0, }, + { /* 20 Mhz */ { 65.0f, /* SGI */ 72.2f, }, + /* 40 Mhz */ { 135.0f, /* SGI */ 150.0f, }, }, /* MCS 8 */ - { /* 20 Mhz */ { 13.0, /* SGI */ 14.4, }, - /* 40 Mhz */ { 27.0, /* SGI */ 30.0, }, + { /* 20 Mhz */ { 13.0f, /* SGI */ 14.4f, }, + /* 40 Mhz */ { 27.0f, /* SGI */ 30.0f, }, }, /* MCS 9 */ - { /* 20 Mhz */ { 26.0, /* SGI */ 28.9, }, - /* 40 Mhz */ { 54.0, /* SGI */ 60.0, }, + { /* 20 Mhz */ { 26.0f, /* SGI */ 28.9f, }, + /* 40 Mhz */ { 54.0f, /* SGI */ 60.0f, }, }, /* MCS 10 */ - { /* 20 Mhz */ { 39.0, /* SGI */ 43.3, }, - /* 40 Mhz */ { 81.0, /* SGI */ 90.0, }, + { /* 20 Mhz */ { 39.0f, /* SGI */ 43.3f, }, + /* 40 Mhz */ { 81.0f, /* SGI */ 90.0f, }, }, /* MCS 11 */ - { /* 20 Mhz */ { 52.0, /* SGI */ 57.8, }, - /* 40 Mhz */ { 108.0, /* SGI */ 120.0, }, + { /* 20 Mhz */ { 52.0f, /* SGI */ 57.8f, }, + /* 40 Mhz */ { 108.0f, /* SGI */ 120.0f, }, }, /* MCS 12 */ - { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, }, - /* 40 Mhz */ { 162.0, /* SGI */ 180.0, }, + { /* 20 Mhz */ { 78.0f, /* SGI */ 86.7f, }, + /* 40 Mhz */ { 162.0f, /* SGI */ 180.0f, }, }, /* MCS 13 */ - { /* 20 Mhz */ { 104.0, /* SGI */ 115.6, }, - /* 40 Mhz */ { 216.0, /* SGI */ 240.0, }, + { /* 20 Mhz */ { 104.0f, /* SGI */ 115.6f, }, + /* 40 Mhz */ { 216.0f, /* SGI */ 240.0f, }, }, /* MCS 14 */ - { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, }, - /* 40 Mhz */ { 243.0, /* SGI */ 270.0, }, + { /* 20 Mhz */ { 117.0f, /* SGI */ 130.0f, }, + /* 40 Mhz */ { 243.0f, /* SGI */ 270.0f, }, }, /* MCS 15 */ - { /* 20 Mhz */ { 130.0, /* SGI */ 144.4, }, - /* 40 Mhz */ { 270.0, /* SGI */ 300.0, }, + { /* 20 Mhz */ { 130.0f, /* SGI */ 144.4f, }, + /* 40 Mhz */ { 270.0f, /* SGI */ 300.0f, }, }, /* MCS 16 */ - { /* 20 Mhz */ { 19.5, /* SGI */ 21.7, }, - /* 40 Mhz */ { 40.5, /* SGI */ 45.0, }, + { /* 20 Mhz */ { 19.5f, /* SGI */ 21.7f, }, + /* 40 Mhz */ { 40.5f, /* SGI */ 45.0f, }, }, /* MCS 17 */ - { /* 20 Mhz */ { 39.0, /* SGI */ 43.3, }, - /* 40 Mhz */ { 81.0, /* SGI */ 90.0, }, + { /* 20 Mhz */ { 39.0f, /* SGI */ 43.3f, }, + /* 40 Mhz */ { 81.0f, /* SGI */ 90.0f, }, }, /* MCS 18 */ - { /* 20 Mhz */ { 58.5, /* SGI */ 65.0, }, - /* 40 Mhz */ { 121.5, /* SGI */ 135.0, }, + { /* 20 Mhz */ { 58.5f, /* SGI */ 65.0f, }, + /* 40 Mhz */ { 121.5f, /* SGI */ 135.0f, }, }, /* MCS 19 */ - { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, }, - /* 40 Mhz */ { 162.0, /* SGI */ 180.0, }, + { /* 20 Mhz */ { 78.0f, /* SGI */ 86.7f, }, + /* 40 Mhz */ { 162.0f, /* SGI */ 180.0f, }, }, /* MCS 20 */ - { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, }, - /* 40 Mhz */ { 243.0, /* SGI */ 270.0, }, + { /* 20 Mhz */ { 117.0f, /* SGI */ 130.0f, }, + /* 40 Mhz */ { 243.0f, /* SGI */ 270.0f, }, }, /* MCS 21 */ - { /* 20 Mhz */ { 156.0, /* SGI */ 173.3, }, - /* 40 Mhz */ { 324.0, /* SGI */ 360.0, }, + { /* 20 Mhz */ { 156.0f, /* SGI */ 173.3f, }, + /* 40 Mhz */ { 324.0f, /* SGI */ 360.0f, }, }, /* MCS 22 */ - { /* 20 Mhz */ { 175.5, /* SGI */ 195.0, }, - /* 40 Mhz */ { 364.5, /* SGI */ 405.0, }, + { /* 20 Mhz */ { 175.5f, /* SGI */ 195.0f, }, + /* 40 Mhz */ { 364.5f, /* SGI */ 405.0f, }, }, /* MCS 23 */ - { /* 20 Mhz */ { 195.0, /* SGI */ 216.7, }, - /* 40 Mhz */ { 405.0, /* SGI */ 450.0, }, + { /* 20 Mhz */ { 195.0f, /* SGI */ 216.7f, }, + /* 40 Mhz */ { 405.0f, /* SGI */ 450.0f, }, }, /* MCS 24 */ - { /* 20 Mhz */ { 26.0, /* SGI */ 28.9, }, - /* 40 Mhz */ { 54.0, /* SGI */ 60.0, }, + { /* 20 Mhz */ { 26.0f, /* SGI */ 28.9f, }, + /* 40 Mhz */ { 54.0f, /* SGI */ 60.0f, }, }, /* MCS 25 */ - { /* 20 Mhz */ { 52.0, /* SGI */ 57.8, }, - /* 40 Mhz */ { 108.0, /* SGI */ 120.0, }, + { /* 20 Mhz */ { 52.0f, /* SGI */ 57.8f, }, + /* 40 Mhz */ { 108.0f, /* SGI */ 120.0f, }, }, /* MCS 26 */ - { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, }, - /* 40 Mhz */ { 162.0, /* SGI */ 180.0, }, + { /* 20 Mhz */ { 78.0f, /* SGI */ 86.7f, }, + /* 40 Mhz */ { 162.0f, /* SGI */ 180.0f, }, }, /* MCS 27 */ - { /* 20 Mhz */ { 104.0, /* SGI */ 115.6, }, - /* 40 Mhz */ { 216.0, /* SGI */ 240.0, }, + { /* 20 Mhz */ { 104.0f, /* SGI */ 115.6f, }, + /* 40 Mhz */ { 216.0f, /* SGI */ 240.0f, }, }, /* MCS 28 */ - { /* 20 Mhz */ { 156.0, /* SGI */ 173.3, }, - /* 40 Mhz */ { 324.0, /* SGI */ 360.0, }, + { /* 20 Mhz */ { 156.0f, /* SGI */ 173.3f, }, + /* 40 Mhz */ { 324.0f, /* SGI */ 360.0f, }, }, /* MCS 29 */ - { /* 20 Mhz */ { 208.0, /* SGI */ 231.1, }, - /* 40 Mhz */ { 432.0, /* SGI */ 480.0, }, + { /* 20 Mhz */ { 208.0f, /* SGI */ 231.1f, }, + /* 40 Mhz */ { 432.0f, /* SGI */ 480.0f, }, }, /* MCS 30 */ - { /* 20 Mhz */ { 234.0, /* SGI */ 260.0, }, - /* 40 Mhz */ { 486.0, /* SGI */ 540.0, }, + { /* 20 Mhz */ { 234.0f, /* SGI */ 260.0f, }, + /* 40 Mhz */ { 486.0f, /* SGI */ 540.0f, }, }, /* MCS 31 */ - { /* 20 Mhz */ { 260.0, /* SGI */ 288.9, }, - /* 40 Mhz */ { 540.0, /* SGI */ 600.0, }, + { /* 20 Mhz */ { 260.0f, /* SGI */ 288.9f, }, + /* 40 Mhz */ { 540.0f, /* SGI */ 600.0f, }, }, /* MCS 32 */ - { /* 20 Mhz */ { 0.0, /* SGI */ 0.0, }, /* not valid */ - /* 40 Mhz */ { 6.0, /* SGI */ 6.7, }, + { /* 20 Mhz */ { 0.0f, /* SGI */ 0.0f, }, /* not valid */ + /* 40 Mhz */ { 6.0f, /* SGI */ 6.7f, }, }, /* MCS 33 */ - { /* 20 Mhz */ { 39.0, /* SGI */ 43.3, }, - /* 40 Mhz */ { 81.0, /* SGI */ 90.0, }, + { /* 20 Mhz */ { 39.0f, /* SGI */ 43.3f, }, + /* 40 Mhz */ { 81.0f, /* SGI */ 90.0f, }, }, /* MCS 34 */ - { /* 20 Mhz */ { 52.0, /* SGI */ 57.8, }, - /* 40 Mhz */ { 108.0, /* SGI */ 120.0, }, + { /* 20 Mhz */ { 52.0f, /* SGI */ 57.8f, }, + /* 40 Mhz */ { 108.0f, /* SGI */ 120.0f, }, }, /* MCS 35 */ - { /* 20 Mhz */ { 65.0, /* SGI */ 72.2, }, - /* 40 Mhz */ { 135.0, /* SGI */ 150.0, }, + { /* 20 Mhz */ { 65.0f, /* SGI */ 72.2f, }, + /* 40 Mhz */ { 135.0f, /* SGI */ 150.0f, }, }, /* MCS 36 */ - { /* 20 Mhz */ { 58.5, /* SGI */ 65.0, }, - /* 40 Mhz */ { 121.5, /* SGI */ 135.0, }, + { /* 20 Mhz */ { 58.5f, /* SGI */ 65.0f, }, + /* 40 Mhz */ { 121.5f, /* SGI */ 135.0f, }, }, /* MCS 37 */ - { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, }, - /* 40 Mhz */ { 162.0, /* SGI */ 180.0, }, + { /* 20 Mhz */ { 78.0f, /* SGI */ 86.7f, }, + /* 40 Mhz */ { 162.0f, /* SGI */ 180.0f, }, }, /* MCS 38 */ - { /* 20 Mhz */ { 97.5, /* SGI */ 108.3, }, - /* 40 Mhz */ { 202.5, /* SGI */ 225.0, }, + { /* 20 Mhz */ { 97.5f, /* SGI */ 108.3f, }, + /* 40 Mhz */ { 202.5f, /* SGI */ 225.0f, }, }, /* MCS 39 */ - { /* 20 Mhz */ { 52.0, /* SGI */ 57.8, }, - /* 40 Mhz */ { 108.0, /* SGI */ 120.0, }, + { /* 20 Mhz */ { 52.0f, /* SGI */ 57.8f, }, + /* 40 Mhz */ { 108.0f, /* SGI */ 120.0f, }, }, /* MCS 40 */ - { /* 20 Mhz */ { 65.0, /* SGI */ 72.2, }, - /* 40 Mhz */ { 135.0, /* SGI */ 150.0, }, + { /* 20 Mhz */ { 65.0f, /* SGI */ 72.2f, }, + /* 40 Mhz */ { 135.0f, /* SGI */ 150.0f, }, }, /* MCS 41 */ - { /* 20 Mhz */ { 65.0, /* SGI */ 72.2, }, - /* 40 Mhz */ { 135.0, /* SGI */ 150.0, }, + { /* 20 Mhz */ { 65.0f, /* SGI */ 72.2f, }, + /* 40 Mhz */ { 135.0f, /* SGI */ 150.0f, }, }, /* MCS 42 */ - { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, }, - /* 40 Mhz */ { 162.0, /* SGI */ 180.0, }, + { /* 20 Mhz */ { 78.0f, /* SGI */ 86.7f, }, + /* 40 Mhz */ { 162.0f, /* SGI */ 180.0f, }, }, /* MCS 43 */ - { /* 20 Mhz */ { 91.0, /* SGI */ 101.1, }, - /* 40 Mhz */ { 189.0, /* SGI */ 210.0, }, + { /* 20 Mhz */ { 91.0f, /* SGI */ 101.1f, }, + /* 40 Mhz */ { 189.0f, /* SGI */ 210.0f, }, }, /* MCS 44 */ - { /* 20 Mhz */ { 91.0, /* SGI */ 101.1, }, - /* 40 Mhz */ { 189.0, /* SGI */ 210.0, }, + { /* 20 Mhz */ { 91.0f, /* SGI */ 101.1f, }, + /* 40 Mhz */ { 189.0f, /* SGI */ 210.0f, }, }, /* MCS 45 */ - { /* 20 Mhz */ { 104.0, /* SGI */ 115.6, }, - /* 40 Mhz */ { 216.0, /* SGI */ 240.0, }, + { /* 20 Mhz */ { 104.0f, /* SGI */ 115.6f, }, + /* 40 Mhz */ { 216.0f, /* SGI */ 240.0f, }, }, /* MCS 46 */ - { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, }, - /* 40 Mhz */ { 162.0, /* SGI */ 180.0, }, + { /* 20 Mhz */ { 78.0f, /* SGI */ 86.7f, }, + /* 40 Mhz */ { 162.0f, /* SGI */ 180.0f, }, }, /* MCS 47 */ - { /* 20 Mhz */ { 97.5, /* SGI */ 108.3, }, - /* 40 Mhz */ { 202.5, /* SGI */ 225.0, }, + { /* 20 Mhz */ { 97.5f, /* SGI */ 108.3f, }, + /* 40 Mhz */ { 202.5f, /* SGI */ 225.0f, }, }, /* MCS 48 */ - { /* 20 Mhz */ { 97.5, /* SGI */ 108.3, }, - /* 40 Mhz */ { 202.5, /* SGI */ 225.0, }, + { /* 20 Mhz */ { 97.5f, /* SGI */ 108.3f, }, + /* 40 Mhz */ { 202.5f, /* SGI */ 225.0f, }, }, /* MCS 49 */ - { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, }, - /* 40 Mhz */ { 243.0, /* SGI */ 270.0, }, + { /* 20 Mhz */ { 117.0f, /* SGI */ 130.0f, }, + /* 40 Mhz */ { 243.0f, /* SGI */ 270.0f, }, }, /* MCS 50 */ - { /* 20 Mhz */ { 136.5, /* SGI */ 151.7, }, - /* 40 Mhz */ { 283.5, /* SGI */ 315.0, }, + { /* 20 Mhz */ { 136.5f, /* SGI */ 151.7f, }, + /* 40 Mhz */ { 283.5f, /* SGI */ 315.0f, }, }, /* MCS 51 */ - { /* 20 Mhz */ { 136.5, /* SGI */ 151.7, }, - /* 40 Mhz */ { 283.5, /* SGI */ 315.0, }, + { /* 20 Mhz */ { 136.5f, /* SGI */ 151.7f, }, + /* 40 Mhz */ { 283.5f, /* SGI */ 315.0f, }, }, /* MCS 52 */ - { /* 20 Mhz */ { 156.0, /* SGI */ 173.3, }, - /* 40 Mhz */ { 324.0, /* SGI */ 360.0, }, + { /* 20 Mhz */ { 156.0f, /* SGI */ 173.3f, }, + /* 40 Mhz */ { 324.0f, /* SGI */ 360.0f, }, }, /* MCS 53 */ - { /* 20 Mhz */ { 65.0, /* SGI */ 72.2, }, - /* 40 Mhz */ { 135.0, /* SGI */ 150.0, }, + { /* 20 Mhz */ { 65.0f, /* SGI */ 72.2f, }, + /* 40 Mhz */ { 135.0f, /* SGI */ 150.0f, }, }, /* MCS 54 */ - { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, }, - /* 40 Mhz */ { 162.0, /* SGI */ 180.0, }, + { /* 20 Mhz */ { 78.0f, /* SGI */ 86.7f, }, + /* 40 Mhz */ { 162.0f, /* SGI */ 180.0f, }, }, /* MCS 55 */ - { /* 20 Mhz */ { 91.0, /* SGI */ 101.1, }, - /* 40 Mhz */ { 189.0, /* SGI */ 210.0, }, + { /* 20 Mhz */ { 91.0f, /* SGI */ 101.1f, }, + /* 40 Mhz */ { 189.0f, /* SGI */ 210.0f, }, }, /* MCS 56 */ - { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, }, - /* 40 Mhz */ { 162.0, /* SGI */ 180.0, }, + { /* 20 Mhz */ { 78.0f, /* SGI */ 86.7f, }, + /* 40 Mhz */ { 162.0f, /* SGI */ 180.0f, }, }, /* MCS 57 */ - { /* 20 Mhz */ { 91.0, /* SGI */ 101.1, }, - /* 40 Mhz */ { 189.0, /* SGI */ 210.0, }, + { /* 20 Mhz */ { 91.0f, /* SGI */ 101.1f, }, + /* 40 Mhz */ { 189.0f, /* SGI */ 210.0f, }, }, /* MCS 58 */ - { /* 20 Mhz */ { 104.0, /* SGI */ 115.6, }, - /* 40 Mhz */ { 216.0, /* SGI */ 240.0, }, + { /* 20 Mhz */ { 104.0f, /* SGI */ 115.6f, }, + /* 40 Mhz */ { 216.0f, /* SGI */ 240.0f, }, }, /* MCS 59 */ - { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, }, - /* 40 Mhz */ { 243.0, /* SGI */ 270.0, }, + { /* 20 Mhz */ { 117.0f, /* SGI */ 130.0f, }, + /* 40 Mhz */ { 243.0f, /* SGI */ 270.0f, }, }, /* MCS 60 */ - { /* 20 Mhz */ { 104.0, /* SGI */ 115.6, }, - /* 40 Mhz */ { 216.0, /* SGI */ 240.0, }, + { /* 20 Mhz */ { 104.0f, /* SGI */ 115.6f, }, + /* 40 Mhz */ { 216.0f, /* SGI */ 240.0f, }, }, /* MCS 61 */ - { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, }, - /* 40 Mhz */ { 243.0, /* SGI */ 270.0, }, + { /* 20 Mhz */ { 117.0f, /* SGI */ 130.0f, }, + /* 40 Mhz */ { 243.0f, /* SGI */ 270.0f, }, }, /* MCS 62 */ - { /* 20 Mhz */ { 130.0, /* SGI */ 144.4, }, - /* 40 Mhz */ { 270.0, /* SGI */ 300.0, }, + { /* 20 Mhz */ { 130.0f, /* SGI */ 144.4f, }, + /* 40 Mhz */ { 270.0f, /* SGI */ 300.0f, }, }, /* MCS 63 */ - { /* 20 Mhz */ { 130.0, /* SGI */ 144.4, }, - /* 40 Mhz */ { 270.0, /* SGI */ 300.0, }, + { /* 20 Mhz */ { 130.0f, /* SGI */ 144.4f, }, + /* 40 Mhz */ { 270.0f, /* SGI */ 300.0f, }, }, /* MCS 64 */ - { /* 20 Mhz */ { 143.0, /* SGI */ 158.9, }, - /* 40 Mhz */ { 297.0, /* SGI */ 330.0, }, + { /* 20 Mhz */ { 143.0f, /* SGI */ 158.9f, }, + /* 40 Mhz */ { 297.0f, /* SGI */ 330.0f, }, }, /* MCS 65 */ - { /* 20 Mhz */ { 97.5, /* SGI */ 108.3, }, - /* 40 Mhz */ { 202.5, /* SGI */ 225.0, }, + { /* 20 Mhz */ { 97.5f, /* SGI */ 108.3f, }, + /* 40 Mhz */ { 202.5f, /* SGI */ 225.0f, }, }, /* MCS 66 */ - { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, }, - /* 40 Mhz */ { 243.0, /* SGI */ 270.0, }, + { /* 20 Mhz */ { 117.0f, /* SGI */ 130.0f, }, + /* 40 Mhz */ { 243.0f, /* SGI */ 270.0f, }, }, /* MCS 67 */ - { /* 20 Mhz */ { 136.5, /* SGI */ 151.7, }, - /* 40 Mhz */ { 283.5, /* SGI */ 315.0, }, + { /* 20 Mhz */ { 136.5f, /* SGI */ 151.7f, }, + /* 40 Mhz */ { 283.5f, /* SGI */ 315.0f, }, }, /* MCS 68 */ - { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, }, - /* 40 Mhz */ { 243.0, /* SGI */ 270.0, }, + { /* 20 Mhz */ { 117.0f, /* SGI */ 130.0f, }, + /* 40 Mhz */ { 243.0f, /* SGI */ 270.0f, }, }, /* MCS 69 */ - { /* 20 Mhz */ { 136.5, /* SGI */ 151.7, }, - /* 40 Mhz */ { 283.5, /* SGI */ 315.0, }, + { /* 20 Mhz */ { 136.5f, /* SGI */ 151.7f, }, + /* 40 Mhz */ { 283.5f, /* SGI */ 315.0f, }, }, /* MCS 70 */ - { /* 20 Mhz */ { 156.0, /* SGI */ 173.3, }, - /* 40 Mhz */ { 324.0, /* SGI */ 360.0, }, + { /* 20 Mhz */ { 156.0f, /* SGI */ 173.3f, }, + /* 40 Mhz */ { 324.0f, /* SGI */ 360.0f, }, }, /* MCS 71 */ - { /* 20 Mhz */ { 175.5, /* SGI */ 195.0, }, - /* 40 Mhz */ { 364.5, /* SGI */ 405.0, }, + { /* 20 Mhz */ { 175.5f, /* SGI */ 195.0f, }, + /* 40 Mhz */ { 364.5f, /* SGI */ 405.0f, }, }, /* MCS 72 */ - { /* 20 Mhz */ { 156.0, /* SGI */ 173.3, }, - /* 40 Mhz */ { 324.0, /* SGI */ 360.0, }, + { /* 20 Mhz */ { 156.0f, /* SGI */ 173.3f, }, + /* 40 Mhz */ { 324.0f, /* SGI */ 360.0f, }, }, /* MCS 73 */ - { /* 20 Mhz */ { 175.5, /* SGI */ 195.0, }, - /* 40 Mhz */ { 364.5, /* SGI */ 405.0, }, + { /* 20 Mhz */ { 175.5f, /* SGI */ 195.0f, }, + /* 40 Mhz */ { 364.5f, /* SGI */ 405.0f, }, }, /* MCS 74 */ - { /* 20 Mhz */ { 195.0, /* SGI */ 216.7, }, - /* 40 Mhz */ { 405.0, /* SGI */ 450.0, }, + { /* 20 Mhz */ { 195.0f, /* SGI */ 216.7f, }, + /* 40 Mhz */ { 405.0f, /* SGI */ 450.0f, }, }, /* MCS 75 */ - { /* 20 Mhz */ { 195.0, /* SGI */ 216.7, }, - /* 40 Mhz */ { 405.0, /* SGI */ 450.0, }, + { /* 20 Mhz */ { 195.0f, /* SGI */ 216.7f, }, + /* 40 Mhz */ { 405.0f, /* SGI */ 450.0f, }, }, /* MCS 76 */ - { /* 20 Mhz */ { 214.5, /* SGI */ 238.3, }, - /* 40 Mhz */ { 445.5, /* SGI */ 495.0, }, + { /* 20 Mhz */ { 214.5f, /* SGI */ 238.3f, }, + /* 40 Mhz */ { 445.5f, /* SGI */ 495.0f, }, }, }; static const char *auth_alg_text[]={"Open System","Shared Key","EAP"}; -#define NUM_AUTH_ALGS (sizeof auth_alg_text / sizeof auth_alg_text[0]) +#define NUM_AUTH_ALGS (sizeof(auth_alg_text) / sizeof(auth_alg_text[0])) static const char *status_text[] = { "Successful", /* 0 */ "Unspecified failure", /* 1 */ - "Reserved", /* 2 */ - "Reserved", /* 3 */ + "TDLS wakeup schedule rejected but alternative schedule " + "provided", /* 2 */ + "TDLS wakeup schedule rejected",/* 3 */ "Reserved", /* 4 */ - "Reserved", /* 5 */ - "Reserved", /* 6 */ - "Reserved", /* 7 */ + "Security disabled", /* 5 */ + "Unacceptable lifetime", /* 6 */ + "Not in same BSS", /* 7 */ "Reserved", /* 8 */ "Reserved", /* 9 */ "Cannot Support all requested capabilities in the Capability " - "Information field", /* 10 */ + "Information field", /* 10 */ "Reassociation denied due to inability to confirm that association " "exists", /* 11 */ - "Association denied due to reason outside the scope of the " + "Association denied due to reason outside the scope of this " "standard", /* 12 */ - "Responding station does not support the specified authentication " - "algorithm ", /* 13 */ + "Responding STA 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 */ + "sequence", /* 16 */ + "Association denied because AP is unable to handle " + "additional associated STAs", /* 17 */ + "Association denied due to requesting STA not supporting " + "all of the data rates in the BSSBasicRateSet parameter, " + "the Basic HT-MCS Set field of the HT Operation " + "parameter, or the Basic VHT-MCS and NSS Set field in " + "the VHT Operation parameter", /* 18 */ + "Association denied due to requesting STA not supporting " + "the short preamble option", /* 19 */ + "Reserved", /* 20 */ + "Reserved", /* 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 due to requesting STA not supporting " + "the Short Slot Time option", /* 25 */ + "Reserved", /* 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 */ + "R0KH unreachable", /* 28 */ + "Association denied because the requesting STA does not " + "support the phased coexistence operation (PCO) " + "transition time required by the AP", /* 29 */ + "Association request rejected temporarily; try again " + "later", /* 30 */ + "Robust management frame policy violation", /* 31 */ "Unspecified, QoS-related failure", /* 32 */ - "Association denied due to QAP having insufficient bandwidth " - "to handle another QSTA", /* 33 */ + "Association denied because QoS AP or PCP has " + "insufficient bandwidth to handle another QoS " + "STA", /* 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 */ + "Association (with QoS BSS) denied because the requesting STA " + "does not support the QoS facility", /* 35 */ + "Reserved", /* 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. " - "Try again 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 */ + "The allocation or TS has not been created because the request " + "cannot be honored; however, a suggested TSPEC/DMG TSPEC is " + "provided so that the initiating STA can attempt to set " + "another allocation or TS with the suggested changes to the " + "TSPEC/DMG TSPEC", /* 39 */ + "Invalid element, i.e., an element defined in this standard " + "for which the content does not meet the specifications in " + "Clause 9", /* 40 */ + "Invalid group cipher", /* 41 */ + "Invalid pairwise cipher", /* 42 */ + "Invalid AKMP", /* 43 */ + "Unsupported RSNE version", /* 44 */ + "Invalid RSNE capabilities", /* 45 */ + "Cipher suite rejected because of security policy", /* 46 */ + "The TS or allocation has not been created; however, the " + "HC or PCP might be capable of creating a TS or " + "allocation, 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 */ - + "The Destination STA is not present within this BSS", /* 49 */ + "The Destination STA is not a QoS STA", /* 50 */ + + "Association denied because the listen interval is " + "too large", /* 51 */ + "Invalid FT Action frame count", /* 52 */ + "Invalid pairwise master key identifier (PMKID)", /* 53 */ + "Invalid MDE", /* 54 */ + "Invalid FTE", /* 55 */ + "Requested TCLAS processing is not supported by the AP " + "or PCP", /* 56 */ + "The AP or PCP has insufficient TCLAS processing " + "resources to satisfy the request", /* 57 */ + "The TS has not been created because the request " + "cannot be honored; however, the HC or PCP suggests " + "that the STA transition to a different BSS to set up " + "the TS", /* 58 */ + "GAS Advertisement Protocol not supported", /* 59 */ + "No outstanding GAS request", /* 60 */ + "GAS Response not received from the Advertisement " + "Server", /* 61 */ + "STA timed out waiting for GAS Query Response", /* 62 */ + "LARGE GAS Response is larger than query response " + "length limit", /* 63 */ + "Request refused because home network does not support " + "request", /* 64 */ + "Advertisement Server in the network is not currently " + "reachable", /* 65 */ + "Reserved", /* 66 */ + "Request refused due to permissions received via SSPN " + "interface", /* 67 */ + "Request refused because the AP or PCP does not " + "support unauthenticated access", /* 68 */ + "Reserved", /* 69 */ + "Reserved", /* 70 */ + "Reserved", /* 71 */ + "Invalid contents of RSNE", /* 72 */ + "U-APSD coexistence is not supported", /* 73 */ + "Requested U-APSD coexistence mode is not supported", /* 74 */ + "Requested Interval/Duration value cannot be " + "supported with U-APSD coexistence", /* 75 */ + "Authentication is rejected because an Anti-Clogging " + "Token is required", /* 76 */ + "Authentication is rejected because the offered " + "finite cyclic group is not supported", /* 77 */ + "The TBTT adjustment request has not been successful " + "because the STA could not find an alternative TBTT", /* 78 */ + "Transmission failure", /* 79 */ + "Requested TCLAS Not Supported", /* 80 */ + "TCLAS Resources Exhausted", /* 81 */ + "Rejected with Suggested BSS transition", /* 82 */ + "Reject with recommended schedule", /* 83 */ + "Reject because no wakeup schedule specified", /* 84 */ + "Success, the destination STA is in power save mode", /* 85 */ + "FST pending, in process of admitting FST session", /* 86 */ + "Performing FST now", /* 87 */ + "FST pending, gap(s) in block ack window", /* 88 */ + "Reject because of U-PID setting", /* 89 */ + "Reserved", /* 90 */ + "Reserved", /* 91 */ + "(Re)Association refused for some external reason", /* 92 */ + "(Re)Association refused because of memory limits " + "at the AP", /* 93 */ + "(Re)Association refused because emergency services " + "are not supported at the AP", /* 94 */ + "GAS query response not yet received", /* 95 */ + "Reject since the request is for transition to a " + "frequency band subject to DSE procedures and " + "FST Initiator is a dependent STA", /* 96 */ + "Requested TCLAS processing has been terminated by " + "the AP", /* 97 */ + "The TS schedule conflicts with an existing " + "schedule; an alternative schedule is provided", /* 98 */ + "The association has been denied; however, one or " + "more Multi-band elements are included that can " + "be used by the receiving STA to join the BSS", /* 99 */ + "The request failed due to a reservation conflict", /* 100 */ + "The request failed due to exceeded MAF limit", /* 101 */ + "The request failed due to exceeded MCCA track " + "limit", /* 102 */ + "Association denied because the information in the" + "Spectrum Management field is unacceptable", /* 103 */ + "Association denied because the requesting STA " + "does not support VHT features", /* 104 */ + "Enablement denied", /* 105 */ + "Enablement denied due to restriction from an " + "authorized GDB", /* 106 */ + "Authorization deenabled", /* 107 */ }; -#define NUM_STATUSES (sizeof status_text / sizeof status_text[0]) +#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) " + "Previous authentication no longer valid", /* 2 */ + "Deauthenticated because sending STA 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 " + " associated STAs", /* 5 */ + "Class 2 frame received from nonauthenticated STA", /* 6 */ + "Class 3 frame received from nonassociated STA", /* 7 */ + "Disassociated because sending STA is leaving " "(or has left) BSS", /* 8 */ - "Station requesting (re)association is not authenticated with " - "responding station", /* 9 */ + "STA requesting (re)association is not authenticated with " + "responding STA", /* 9 */ "Disassociated because the information in the Power Capability " "element is unacceptable", /* 10 */ - "Disassociated because the information in the SupportedChannels " + "Disassociated because the information in the Supported Channels " "element is unacceptable", /* 11 */ - "Invalid Information Element", /* 12 */ - "Reserved", /* 13 */ - "Michael MIC failure", /* 14 */ + "Disassociated due to BSS transition management", /* 12 */ + "Invalid element, i.e., an element defined in this standard for " + "which the content does not meet the specifications " + "in Clause 9", /* 13 */ + "Message integrity code (MIC) failure", /* 14 */ "4-Way Handshake timeout", /* 15 */ - "Group key update timeout", /* 16 */ + "Group key handshake 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 */ + "Request/Probe Response/Beacon frame", /* 17 */ + "Invalid group cipher", /* 18 */ + "Invalid pairwise cipher", /* 19 */ + "Invalid AKMP", /* 20 */ + "Unsupported RSNE version", /* 21 */ + "Invalid RSNE capabilities", /* 22 */ + "IEEE 802.1X authentication failed", /* 23 */ + "Cipher suite rejected because of the security policy", /* 24 */ + "TDLS direct-link teardown due to TDLS peer STA " + "unreachable via the TDLS direct link", /* 25 */ + "TDLS direct-link teardown for unspecified reason", /* 26 */ + "Disassociated because session terminated by SSP request",/* 27 */ + "Disassociated because of lack of SSP roaming agreement",/* 28 */ + "Requested service rejected because of SSP cipher suite or " + "AKM requirement", /* 29 */ + "Requested service not authorized in this location", /* 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 " @@ -956,7 +1055,7 @@ static const char *reason_text[] = { "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 " + "acknowledged, but are not acknowledged due to AP transmissions " "and/or poor channel conditions", /* 34 */ "Disassociated because STA is transmitting outside the limits " "of its TXOPs", /* 35 */ @@ -973,31 +1072,71 @@ static const char *reason_text[] = { "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 */ + "In a DLS Teardown frame: The teardown was initiated by the " + "DLS peer. In a Disassociation frame: Disassociated because " + "authorized access limit reached", /* 46 */ + "In a DLS Teardown frame: The teardown was initiated by the " + "AP. In a Disassociation frame: Disassociated due to external " + "service requirements", /* 47 */ + "Invalid FT Action frame count", /* 48 */ + "Invalid pairwise master key identifier (PMKID)", /* 49 */ + "Invalid MDE", /* 50 */ + "Invalid FTE", /* 51 */ + "Mesh peering canceled for unknown reasons", /* 52 */ + "The mesh STA has reached the supported maximum number of " + "peer mesh STAs", /* 53 */ + "The received information violates the Mesh Configuration " + "policy configured in the mesh STA profile", /* 54 */ + "The mesh STA has received a Mesh Peering Close frame " + "requesting to close the mesh peering", /* 55 */ + "The mesh STA has resent dot11MeshMaxRetries Mesh " + "Peering Open frames, without receiving a Mesh Peering " + "Confirm frame", /* 56 */ + "The confirmTimer for the mesh peering instance times out", /* 57 */ + "The mesh STA fails to unwrap the GTK or the values in the " + "wrapped contents do not match", /* 58 */ + "The mesh STA receives inconsistent information about the " + "mesh parameters between mesh peering Management frames", /* 59 */ + "The mesh STA fails the authenticated mesh peering exchange " + "because due to failure in selecting either the pairwise " + "ciphersuite or group ciphersuite", /* 60 */ + "The mesh STA does not have proxy information for this " + "external destination", /* 61 */ + "The mesh STA does not have forwarding information for this " + "destination", /* 62 */ + "The mesh STA determines that the link to the next hop of an " + "active path in its forwarding information is no longer " + "usable", /* 63 */ + "The Deauthentication frame was sent because the MAC " + "address of the STA already exists in the mesh BSS", /* 64 */ + "The mesh STA performs channel switch to meet regulatory " + "requirements", /* 65 */ + "The mesh STA performs channel switching with unspecified " + "reason", /* 66 */ }; -#define NUM_REASONS (sizeof reason_text / sizeof reason_text[0]) +#define NUM_REASONS (sizeof(reason_text) / sizeof(reason_text[0])) static int wep_print(netdissect_options *ndo, - const u_char *p) + const u_char *p) { uint32_t iv; - if (!ND_TTEST2(*p, IEEE802_11_IV_LEN + IEEE802_11_KID_LEN)) - return 0; - iv = EXTRACT_LE_32BITS(p); + ND_TCHECK_LEN(p, IEEE802_11_IV_LEN + IEEE802_11_KID_LEN); + iv = GET_LE_U_4(p); - ND_PRINT((ndo, " IV:%3x Pad %x KeyID %x", IV_IV(iv), IV_PAD(iv), - IV_KEYID(iv))); + ND_PRINT(" IV:%3x Pad %x KeyID %x", IV_IV(iv), IV_PAD(iv), + IV_KEYID(iv)); return 1; +trunc: + return 0; } static int parse_elements(netdissect_options *ndo, - struct mgmt_body_t *pbody, const u_char *p, int offset, - u_int length) + struct mgmt_body_t *pbody, const u_char *p, int offset, + u_int length) { u_int elementlen; struct ssid_t ssid; @@ -1019,19 +1158,17 @@ parse_elements(netdissect_options *ndo, while (length != 0) { /* Make sure we at least have the element ID and length. */ - if (!ND_TTEST2(*(p + offset), 2)) - return 0; + ND_TCHECK_2(p + offset); if (length < 2) - return 0; - elementlen = *(p + offset + 1); + goto trunc; + elementlen = GET_U_1(p + offset + 1); /* Make sure we have the entire element. */ - if (!ND_TTEST2(*(p + offset + 2), elementlen)) - return 0; + ND_TCHECK_LEN(p + offset + 2, elementlen); if (length < elementlen + 2) - return 0; + goto trunc; - switch (*(p + offset)) { + switch (GET_U_1(p + offset)) { case E_SSID: memcpy(&ssid, p + offset, 2); offset += 2; @@ -1087,7 +1224,7 @@ parse_elements(netdissect_options *ndo, offset += 2; length -= 2; if (rates.length != 0) { - if (rates.length > sizeof rates.rate) + if (rates.length > sizeof(rates.rate)) return 0; memcpy(&rates.rate, p + offset, rates.length); offset += rates.length; @@ -1123,7 +1260,7 @@ parse_elements(netdissect_options *ndo, length -= ds.length; break; } - ds.channel = *(p + offset); + ds.channel = GET_U_1(p + offset); offset += 1; length -= 1; /* @@ -1166,12 +1303,12 @@ parse_elements(netdissect_options *ndo, memcpy(&tim, p + offset, 2); offset += 2; length -= 2; - if (tim.length <= 3) { + if (tim.length <= 3U) { offset += tim.length; length -= tim.length; break; } - if (tim.length - 3 > (int)sizeof tim.bitmap) + if (tim.length - 3U > sizeof(tim.bitmap)) return 0; memcpy(&tim.count, p + offset, 3); offset += 3; @@ -1194,8 +1331,8 @@ parse_elements(netdissect_options *ndo, break; default: #if 0 - ND_PRINT((ndo, "(1) unhandled element_id (%d) ", - *(p + offset))); + ND_PRINT("(1) unhandled element_id (%u) ", + GET_U_1(p + offset)); #endif offset += 2 + elementlen; length -= 2 + elementlen; @@ -1205,6 +1342,8 @@ parse_elements(netdissect_options *ndo, /* No problems found. */ return 1; +trunc: + return 0; } /********************************************************************************* @@ -1213,7 +1352,7 @@ parse_elements(netdissect_options *ndo, static int handle_beacon(netdissect_options *ndo, - const u_char *p, u_int length) + const u_char *p, u_int length) { struct mgmt_body_t pbody; int offset = 0; @@ -1221,19 +1360,18 @@ handle_beacon(netdissect_options *ndo, memset(&pbody, 0, sizeof(pbody)); - if (!ND_TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN + - IEEE802_11_CAPINFO_LEN)) - return 0; + ND_TCHECK_LEN(p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN + + IEEE802_11_CAPINFO_LEN); if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN + IEEE802_11_CAPINFO_LEN) - return 0; + goto trunc; 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); + pbody.beacon_interval = GET_LE_U_2(p + offset); offset += IEEE802_11_BCNINT_LEN; length -= IEEE802_11_BCNINT_LEN; - pbody.capability_info = EXTRACT_LE_16BITS(p+offset); + pbody.capability_info = GET_LE_U_2(p + offset); offset += IEEE802_11_CAPINFO_LEN; length -= IEEE802_11_CAPINFO_LEN; @@ -1241,16 +1379,18 @@ handle_beacon(netdissect_options *ndo, PRINT_SSID(pbody); PRINT_RATES(pbody); - ND_PRINT((ndo, " %s", - CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS")); + ND_PRINT(" %s", + CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS"); PRINT_DS_CHANNEL(pbody); return ret; +trunc: + return 0; } static int handle_assoc_request(netdissect_options *ndo, - const u_char *p, u_int length) + const u_char *p, u_int length) { struct mgmt_body_t pbody; int offset = 0; @@ -1258,14 +1398,13 @@ handle_assoc_request(netdissect_options *ndo, memset(&pbody, 0, sizeof(pbody)); - if (!ND_TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN)) - return 0; + ND_TCHECK_LEN(p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN); if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN) - return 0; - pbody.capability_info = EXTRACT_LE_16BITS(p); + goto trunc; + pbody.capability_info = GET_LE_U_2(p); offset += IEEE802_11_CAPINFO_LEN; length -= IEEE802_11_CAPINFO_LEN; - pbody.listen_interval = EXTRACT_LE_16BITS(p+offset); + pbody.listen_interval = GET_LE_U_2(p + offset); offset += IEEE802_11_LISTENINT_LEN; length -= IEEE802_11_LISTENINT_LEN; @@ -1274,11 +1413,13 @@ handle_assoc_request(netdissect_options *ndo, PRINT_SSID(pbody); PRINT_RATES(pbody); return ret; +trunc: + return 0; } static int handle_assoc_response(netdissect_options *ndo, - const u_char *p, u_int length) + const u_char *p, u_int length) { struct mgmt_body_t pbody; int offset = 0; @@ -1286,36 +1427,37 @@ handle_assoc_response(netdissect_options *ndo, memset(&pbody, 0, sizeof(pbody)); - if (!ND_TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN + - IEEE802_11_AID_LEN)) - return 0; + ND_TCHECK_LEN(p, IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN + + IEEE802_11_AID_LEN); if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN + IEEE802_11_AID_LEN) - return 0; - pbody.capability_info = EXTRACT_LE_16BITS(p); + goto trunc; + pbody.capability_info = GET_LE_U_2(p); offset += IEEE802_11_CAPINFO_LEN; length -= IEEE802_11_CAPINFO_LEN; - pbody.status_code = EXTRACT_LE_16BITS(p+offset); + pbody.status_code = GET_LE_U_2(p + offset); offset += IEEE802_11_STATUS_LEN; length -= IEEE802_11_STATUS_LEN; - pbody.aid = EXTRACT_LE_16BITS(p+offset); + pbody.aid = GET_LE_U_2(p + offset); offset += IEEE802_11_AID_LEN; length -= IEEE802_11_AID_LEN; ret = parse_elements(ndo, &pbody, p, offset, length); - ND_PRINT((ndo, " AID(%x) :%s: %s", ((uint16_t)(pbody.aid << 2 )) >> 2 , + ND_PRINT(" AID(%x) :%s: %s", ((uint16_t)(pbody.aid << 2 )) >> 2 , CAPABILITY_PRIVACY(pbody.capability_info) ? " PRIVACY " : "", (pbody.status_code < NUM_STATUSES ? status_text[pbody.status_code] - : "n/a"))); + : "n/a")); return ret; +trunc: + return 0; } static int handle_reassoc_request(netdissect_options *ndo, - const u_char *p, u_int length) + const u_char *p, u_int length) { struct mgmt_body_t pbody; int offset = 0; @@ -1323,16 +1465,15 @@ handle_reassoc_request(netdissect_options *ndo, memset(&pbody, 0, sizeof(pbody)); - if (!ND_TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN + - IEEE802_11_AP_LEN)) - return 0; + ND_TCHECK_LEN(p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN + + IEEE802_11_AP_LEN); if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN + IEEE802_11_AP_LEN) - return 0; - pbody.capability_info = EXTRACT_LE_16BITS(p); + goto trunc; + pbody.capability_info = GET_LE_U_2(p); offset += IEEE802_11_CAPINFO_LEN; length -= IEEE802_11_CAPINFO_LEN; - pbody.listen_interval = EXTRACT_LE_16BITS(p+offset); + pbody.listen_interval = GET_LE_U_2(p + offset); offset += IEEE802_11_LISTENINT_LEN; length -= IEEE802_11_LISTENINT_LEN; memcpy(&pbody.ap, p+offset, IEEE802_11_AP_LEN); @@ -1342,22 +1483,24 @@ handle_reassoc_request(netdissect_options *ndo, ret = parse_elements(ndo, &pbody, p, offset, length); PRINT_SSID(pbody); - ND_PRINT((ndo, " AP : %s", etheraddr_string(ndo, pbody.ap ))); + ND_PRINT(" AP : %s", etheraddr_string(ndo, pbody.ap )); return ret; +trunc: + return 0; } static int handle_reassoc_response(netdissect_options *ndo, - const u_char *p, u_int length) + const u_char *p, u_int length) { - /* Same as a Association Reponse */ + /* Same as a Association Response */ return handle_assoc_response(ndo, p, length); } static int handle_probe_request(netdissect_options *ndo, - const u_char *p, u_int length) + const u_char *p, u_int length) { struct mgmt_body_t pbody; int offset = 0; @@ -1375,7 +1518,7 @@ handle_probe_request(netdissect_options *ndo, static int handle_probe_response(netdissect_options *ndo, - const u_char *p, u_int length) + const u_char *p, u_int length) { struct mgmt_body_t pbody; int offset = 0; @@ -1383,19 +1526,18 @@ handle_probe_response(netdissect_options *ndo, memset(&pbody, 0, sizeof(pbody)); - if (!ND_TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN + - IEEE802_11_CAPINFO_LEN)) - return 0; + ND_TCHECK_LEN(p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN + + IEEE802_11_CAPINFO_LEN); if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN + IEEE802_11_CAPINFO_LEN) - return 0; + goto trunc; 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); + pbody.beacon_interval = GET_LE_U_2(p + offset); offset += IEEE802_11_BCNINT_LEN; length -= IEEE802_11_BCNINT_LEN; - pbody.capability_info = EXTRACT_LE_16BITS(p+offset); + pbody.capability_info = GET_LE_U_2(p + offset); offset += IEEE802_11_CAPINFO_LEN; length -= IEEE802_11_CAPINFO_LEN; @@ -1406,6 +1548,8 @@ handle_probe_response(netdissect_options *ndo, PRINT_DS_CHANNEL(pbody); return ret; +trunc: + return 0; } static int @@ -1417,29 +1561,30 @@ handle_atim(void) static int handle_disassoc(netdissect_options *ndo, - const u_char *p, u_int length) + const u_char *p, u_int length) { struct mgmt_body_t pbody; memset(&pbody, 0, sizeof(pbody)); - if (!ND_TTEST2(*p, IEEE802_11_REASON_LEN)) - return 0; + ND_TCHECK_LEN(p, IEEE802_11_REASON_LEN); if (length < IEEE802_11_REASON_LEN) - return 0; - pbody.reason_code = EXTRACT_LE_16BITS(p); + goto trunc; + pbody.reason_code = GET_LE_U_2(p); - ND_PRINT((ndo, ": %s", + ND_PRINT(": %s", (pbody.reason_code < NUM_REASONS) ? reason_text[pbody.reason_code] - : "Reserved")); + : "Reserved"); return 1; +trunc: + return 0; } static int handle_auth(netdissect_options *ndo, - const u_char *p, u_int length) + const u_char *p, u_int length) { struct mgmt_body_t pbody; int offset = 0; @@ -1447,17 +1592,16 @@ handle_auth(netdissect_options *ndo, memset(&pbody, 0, sizeof(pbody)); - if (!ND_TTEST2(*p, 6)) - return 0; + ND_TCHECK_6(p); if (length < 6) - return 0; - pbody.auth_alg = EXTRACT_LE_16BITS(p); + goto trunc; + pbody.auth_alg = GET_LE_U_2(p); offset += 2; length -= 2; - pbody.auth_trans_seq_num = EXTRACT_LE_16BITS(p + offset); + pbody.auth_trans_seq_num = GET_LE_U_2(p + offset); offset += 2; length -= 2; - pbody.status_code = EXTRACT_LE_16BITS(p + offset); + pbody.status_code = GET_LE_U_2(p + offset); offset += 2; length -= 2; @@ -1466,148 +1610,144 @@ handle_auth(netdissect_options *ndo, if ((pbody.auth_alg == 1) && ((pbody.auth_trans_seq_num == 2) || (pbody.auth_trans_seq_num == 3))) { - ND_PRINT((ndo, " (%s)-%x [Challenge Text] %s", + ND_PRINT(" (%s)-%x [Challenge Text] %s", (pbody.auth_alg < NUM_AUTH_ALGS) ? auth_alg_text[pbody.auth_alg] : "Reserved", pbody.auth_trans_seq_num, ((pbody.auth_trans_seq_num % 2) - ? ((pbody.status_code < NUM_STATUSES) + ? ((pbody.status_code < NUM_STATUSES) ? status_text[pbody.status_code] - : "n/a") : ""))); + : "n/a") : "")); return ret; } - ND_PRINT((ndo, " (%s)-%x: %s", + ND_PRINT(" (%s)-%x: %s", (pbody.auth_alg < NUM_AUTH_ALGS) ? auth_alg_text[pbody.auth_alg] : "Reserved", pbody.auth_trans_seq_num, (pbody.auth_trans_seq_num % 2) - ? ((pbody.status_code < NUM_STATUSES) + ? ((pbody.status_code < NUM_STATUSES) ? status_text[pbody.status_code] - : "n/a") - : "")); + : "n/a") + : ""); return ret; +trunc: + return 0; } static int handle_deauth(netdissect_options *ndo, - const uint8_t *src, const u_char *p, u_int length) + const uint8_t *src, const u_char *p, u_int length) { struct mgmt_body_t pbody; const char *reason = NULL; memset(&pbody, 0, sizeof(pbody)); - if (!ND_TTEST2(*p, IEEE802_11_REASON_LEN)) - return 0; + ND_TCHECK_LEN(p, IEEE802_11_REASON_LEN); if (length < IEEE802_11_REASON_LEN) - return 0; - pbody.reason_code = EXTRACT_LE_16BITS(p); + goto trunc; + pbody.reason_code = GET_LE_U_2(p); reason = (pbody.reason_code < NUM_REASONS) ? reason_text[pbody.reason_code] : "Reserved"; if (ndo->ndo_eflag) { - ND_PRINT((ndo, ": %s", reason)); + ND_PRINT(": %s", reason); } else { - ND_PRINT((ndo, " (%s): %s", etheraddr_string(ndo, src), reason)); + ND_PRINT(" (%s): %s", GET_ETHERADDR_STRING(src), reason); } return 1; +trunc: + return 0; } #define PRINT_HT_ACTION(v) (\ - (v) == 0 ? ND_PRINT((ndo, "TxChWidth")) : \ - (v) == 1 ? ND_PRINT((ndo, "MIMOPwrSave")) : \ - ND_PRINT((ndo, "Act#%d", (v))) \ -) + (v) == 0 ? ND_PRINT("TxChWidth"): \ + (v) == 1 ? ND_PRINT("MIMOPwrSave"): \ + ND_PRINT("Act#%u", (v))) #define PRINT_BA_ACTION(v) (\ - (v) == 0 ? ND_PRINT((ndo, "ADDBA Request")) : \ - (v) == 1 ? ND_PRINT((ndo, "ADDBA Response")) : \ - (v) == 2 ? ND_PRINT((ndo, "DELBA")) : \ - ND_PRINT((ndo, "Act#%d", (v))) \ -) + (v) == 0 ? ND_PRINT("ADDBA Request"): \ + (v) == 1 ? ND_PRINT("ADDBA Response"): \ + (v) == 2 ? ND_PRINT("DELBA"): \ + ND_PRINT("Act#%u", (v))) #define PRINT_MESHLINK_ACTION(v) (\ - (v) == 0 ? ND_PRINT((ndo, "Request")) : \ - (v) == 1 ? ND_PRINT((ndo, "Report")) : \ - ND_PRINT((ndo, "Act#%d", (v))) \ -) + (v) == 0 ? ND_PRINT("Request"): \ + (v) == 1 ? ND_PRINT("Report"): \ + ND_PRINT("Act#%u", (v))) #define PRINT_MESHPEERING_ACTION(v) (\ - (v) == 0 ? ND_PRINT((ndo, "Open")) : \ - (v) == 1 ? ND_PRINT((ndo, "Confirm")) : \ - (v) == 2 ? ND_PRINT((ndo, "Close")) : \ - ND_PRINT((ndo, "Act#%d", (v))) \ -) + (v) == 0 ? ND_PRINT("Open"): \ + (v) == 1 ? ND_PRINT("Confirm"): \ + (v) == 2 ? ND_PRINT("Close"): \ + ND_PRINT("Act#%u", (v))) #define PRINT_MESHPATH_ACTION(v) (\ - (v) == 0 ? ND_PRINT((ndo, "Request")) : \ - (v) == 1 ? ND_PRINT((ndo, "Report")) : \ - (v) == 2 ? ND_PRINT((ndo, "Error")) : \ - (v) == 3 ? ND_PRINT((ndo, "RootAnnouncement")) : \ - ND_PRINT((ndo, "Act#%d", (v))) \ -) + (v) == 0 ? ND_PRINT("Request"): \ + (v) == 1 ? ND_PRINT("Report"): \ + (v) == 2 ? ND_PRINT("Error"): \ + (v) == 3 ? ND_PRINT("RootAnnouncement"): \ + ND_PRINT("Act#%u", (v))) #define PRINT_MESH_ACTION(v) (\ - (v) == 0 ? ND_PRINT((ndo, "MeshLink")) : \ - (v) == 1 ? ND_PRINT((ndo, "HWMP")) : \ - (v) == 2 ? ND_PRINT((ndo, "Gate Announcement")) : \ - (v) == 3 ? ND_PRINT((ndo, "Congestion Control")) : \ - (v) == 4 ? ND_PRINT((ndo, "MCCA Setup Request")) : \ - (v) == 5 ? ND_PRINT((ndo, "MCCA Setup Reply")) : \ - (v) == 6 ? ND_PRINT((ndo, "MCCA Advertisement Request")) : \ - (v) == 7 ? ND_PRINT((ndo, "MCCA Advertisement")) : \ - (v) == 8 ? ND_PRINT((ndo, "MCCA Teardown")) : \ - (v) == 9 ? ND_PRINT((ndo, "TBTT Adjustment Request")) : \ - (v) == 10 ? ND_PRINT((ndo, "TBTT Adjustment Response")) : \ - ND_PRINT((ndo, "Act#%d", (v))) \ -) + (v) == 0 ? ND_PRINT("MeshLink"): \ + (v) == 1 ? ND_PRINT("HWMP"): \ + (v) == 2 ? ND_PRINT("Gate Announcement"): \ + (v) == 3 ? ND_PRINT("Congestion Control"): \ + (v) == 4 ? ND_PRINT("MCCA Setup Request"): \ + (v) == 5 ? ND_PRINT("MCCA Setup Reply"): \ + (v) == 6 ? ND_PRINT("MCCA Advertisement Request"): \ + (v) == 7 ? ND_PRINT("MCCA Advertisement"): \ + (v) == 8 ? ND_PRINT("MCCA Teardown"): \ + (v) == 9 ? ND_PRINT("TBTT Adjustment Request"): \ + (v) == 10 ? ND_PRINT("TBTT Adjustment Response"): \ + ND_PRINT("Act#%u", (v))) #define PRINT_MULTIHOP_ACTION(v) (\ - (v) == 0 ? ND_PRINT((ndo, "Proxy Update")) : \ - (v) == 1 ? ND_PRINT((ndo, "Proxy Update Confirmation")) : \ - ND_PRINT((ndo, "Act#%d", (v))) \ -) + (v) == 0 ? ND_PRINT("Proxy Update"): \ + (v) == 1 ? ND_PRINT("Proxy Update Confirmation"): \ + ND_PRINT("Act#%u", (v))) #define PRINT_SELFPROT_ACTION(v) (\ - (v) == 1 ? ND_PRINT((ndo, "Peering Open")) : \ - (v) == 2 ? ND_PRINT((ndo, "Peering Confirm")) : \ - (v) == 3 ? ND_PRINT((ndo, "Peering Close")) : \ - (v) == 4 ? ND_PRINT((ndo, "Group Key Inform")) : \ - (v) == 5 ? ND_PRINT((ndo, "Group Key Acknowledge")) : \ - ND_PRINT((ndo, "Act#%d", (v))) \ -) + (v) == 1 ? ND_PRINT("Peering Open"): \ + (v) == 2 ? ND_PRINT("Peering Confirm"): \ + (v) == 3 ? ND_PRINT("Peering Close"): \ + (v) == 4 ? ND_PRINT("Group Key Inform"): \ + (v) == 5 ? ND_PRINT("Group Key Acknowledge"): \ + ND_PRINT("Act#%u", (v))) static int handle_action(netdissect_options *ndo, - const uint8_t *src, const u_char *p, u_int length) + const uint8_t *src, const u_char *p, u_int length) { - if (!ND_TTEST2(*p, 2)) - return 0; + ND_TCHECK_2(p); if (length < 2) - return 0; + goto trunc; if (ndo->ndo_eflag) { - ND_PRINT((ndo, ": ")); + ND_PRINT(": "); } else { - ND_PRINT((ndo, " (%s): ", etheraddr_string(ndo, src))); + ND_PRINT(" (%s): ", GET_ETHERADDR_STRING(src)); } - switch (p[0]) { - case 0: ND_PRINT((ndo, "Spectrum Management Act#%d", p[1])); break; - case 1: ND_PRINT((ndo, "QoS Act#%d", p[1])); break; - case 2: ND_PRINT((ndo, "DLS Act#%d", p[1])); break; - case 3: ND_PRINT((ndo, "BA ")); PRINT_BA_ACTION(p[1]); break; - case 7: ND_PRINT((ndo, "HT ")); PRINT_HT_ACTION(p[1]); break; - case 13: ND_PRINT((ndo, "MeshAction ")); PRINT_MESH_ACTION(p[1]); break; + switch (GET_U_1(p)) { + case 0: ND_PRINT("Spectrum Management Act#%u", GET_U_1(p + 1)); break; + case 1: ND_PRINT("QoS Act#%u", GET_U_1(p + 1)); break; + case 2: ND_PRINT("DLS Act#%u", GET_U_1(p + 1)); break; + case 3: ND_PRINT("BA "); PRINT_BA_ACTION(GET_U_1(p + 1)); break; + case 7: ND_PRINT("HT "); PRINT_HT_ACTION(GET_U_1(p + 1)); break; + case 13: ND_PRINT("MeshAction "); PRINT_MESH_ACTION(GET_U_1(p + 1)); break; case 14: - ND_PRINT((ndo, "MultiohopAction ")); - PRINT_MULTIHOP_ACTION(p[1]); break; + ND_PRINT("MultiohopAction "); + PRINT_MULTIHOP_ACTION(GET_U_1(p + 1)); break; case 15: - ND_PRINT((ndo, "SelfprotectAction ")); - PRINT_SELFPROT_ACTION(p[1]); break; - case 127: ND_PRINT((ndo, "Vendor Act#%d", p[1])); break; + ND_PRINT("SelfprotectAction "); + PRINT_SELFPROT_ACTION(GET_U_1(p + 1)); break; + case 127: ND_PRINT("Vendor Act#%u", GET_U_1(p + 1)); break; default: - ND_PRINT((ndo, "Reserved(%d) Act#%d", p[0], p[1])); + ND_PRINT("Reserved(%u) Act#%u", GET_U_1(p), GET_U_1(p + 1)); break; } return 1; +trunc: + return 0; } @@ -1618,9 +1758,9 @@ handle_action(netdissect_options *ndo, static int mgmt_body_print(netdissect_options *ndo, - uint16_t fc, const uint8_t *src, const u_char *p, u_int length) + uint16_t fc, const uint8_t *src, const u_char *p, u_int length) { - ND_PRINT((ndo, "%s", tok2str(st_str, "Unhandled Management subtype(%x)", FC_SUBTYPE(fc)))); + ND_PRINT("%s", tok2str(st_str, "Unhandled Management subtype(%x)", FC_SUBTYPE(fc))); /* There may be a problem w/ AP not having this bit set */ if (FC_PROTECTED(fc)) @@ -1662,73 +1802,67 @@ mgmt_body_print(netdissect_options *ndo, static int ctrl_body_print(netdissect_options *ndo, - uint16_t fc, const u_char *p) + uint16_t fc, const u_char *p) { - ND_PRINT((ndo, "%s", tok2str(ctrl_str, "Unknown Ctrl Subtype", FC_SUBTYPE(fc)))); + ND_PRINT("%s", tok2str(ctrl_str, "Unknown Ctrl Subtype", FC_SUBTYPE(fc))); switch (FC_SUBTYPE(fc)) { case CTRL_CONTROL_WRAPPER: /* XXX - requires special handling */ break; case CTRL_BAR: - if (!ND_TTEST2(*p, CTRL_BAR_HDRLEN)) - return 0; + ND_TCHECK_LEN(p, CTRL_BAR_HDRLEN); if (!ndo->ndo_eflag) - ND_PRINT((ndo, " RA:%s TA:%s CTL(%x) SEQ(%u) ", - etheraddr_string(ndo, ((const struct ctrl_bar_hdr_t *)p)->ra), - etheraddr_string(ndo, ((const struct ctrl_bar_hdr_t *)p)->ta), - EXTRACT_LE_16BITS(&(((const struct ctrl_bar_hdr_t *)p)->ctl)), - EXTRACT_LE_16BITS(&(((const struct ctrl_bar_hdr_t *)p)->seq)))); + ND_PRINT(" RA:%s TA:%s CTL(%x) SEQ(%u) ", + GET_ETHERADDR_STRING(((const struct ctrl_bar_hdr_t *)p)->ra), + GET_ETHERADDR_STRING(((const struct ctrl_bar_hdr_t *)p)->ta), + GET_LE_U_2(((const struct ctrl_bar_hdr_t *)p)->ctl), + GET_LE_U_2(((const struct ctrl_bar_hdr_t *)p)->seq)); break; case CTRL_BA: - if (!ND_TTEST2(*p, CTRL_BA_HDRLEN)) - return 0; + ND_TCHECK_LEN(p, CTRL_BA_HDRLEN); if (!ndo->ndo_eflag) - ND_PRINT((ndo, " RA:%s ", - etheraddr_string(ndo, ((const struct ctrl_ba_hdr_t *)p)->ra))); + ND_PRINT(" RA:%s ", + GET_ETHERADDR_STRING(((const struct ctrl_ba_hdr_t *)p)->ra)); break; case CTRL_PS_POLL: - if (!ND_TTEST2(*p, CTRL_PS_POLL_HDRLEN)) - return 0; - ND_PRINT((ndo, " AID(%x)", - EXTRACT_LE_16BITS(&(((const struct ctrl_ps_poll_hdr_t *)p)->aid)))); + ND_TCHECK_LEN(p, CTRL_PS_POLL_HDRLEN); + ND_PRINT(" AID(%x)", + GET_LE_U_2(((const struct ctrl_ps_poll_hdr_t *)p)->aid)); break; case CTRL_RTS: - if (!ND_TTEST2(*p, CTRL_RTS_HDRLEN)) - return 0; + ND_TCHECK_LEN(p, CTRL_RTS_HDRLEN); if (!ndo->ndo_eflag) - ND_PRINT((ndo, " TA:%s ", - etheraddr_string(ndo, ((const struct ctrl_rts_hdr_t *)p)->ta))); + ND_PRINT(" TA:%s ", + GET_ETHERADDR_STRING(((const struct ctrl_rts_hdr_t *)p)->ta)); break; case CTRL_CTS: - if (!ND_TTEST2(*p, CTRL_CTS_HDRLEN)) - return 0; + ND_TCHECK_LEN(p, CTRL_CTS_HDRLEN); if (!ndo->ndo_eflag) - ND_PRINT((ndo, " RA:%s ", - etheraddr_string(ndo, ((const struct ctrl_cts_hdr_t *)p)->ra))); + ND_PRINT(" RA:%s ", + GET_ETHERADDR_STRING(((const struct ctrl_cts_hdr_t *)p)->ra)); break; case CTRL_ACK: - if (!ND_TTEST2(*p, CTRL_ACK_HDRLEN)) - return 0; + ND_TCHECK_LEN(p, CTRL_ACK_HDRLEN); if (!ndo->ndo_eflag) - ND_PRINT((ndo, " RA:%s ", - etheraddr_string(ndo, ((const struct ctrl_ack_hdr_t *)p)->ra))); + ND_PRINT(" RA:%s ", + GET_ETHERADDR_STRING(((const struct ctrl_ack_hdr_t *)p)->ra)); break; case CTRL_CF_END: - if (!ND_TTEST2(*p, CTRL_END_HDRLEN)) - return 0; + ND_TCHECK_LEN(p, CTRL_END_HDRLEN); if (!ndo->ndo_eflag) - ND_PRINT((ndo, " RA:%s ", - etheraddr_string(ndo, ((const struct ctrl_end_hdr_t *)p)->ra))); + ND_PRINT(" RA:%s ", + GET_ETHERADDR_STRING(((const struct ctrl_end_hdr_t *)p)->ra)); break; case CTRL_END_ACK: - if (!ND_TTEST2(*p, CTRL_END_ACK_HDRLEN)) - return 0; + ND_TCHECK_LEN(p, CTRL_END_ACK_HDRLEN); if (!ndo->ndo_eflag) - ND_PRINT((ndo, " RA:%s ", - etheraddr_string(ndo, ((const struct ctrl_end_ack_hdr_t *)p)->ra))); + ND_PRINT(" RA:%s ", + GET_ETHERADDR_STRING(((const struct ctrl_end_ack_hdr_t *)p)->ra)); break; } return 1; +trunc: + return 0; } /* @@ -1746,7 +1880,7 @@ ctrl_body_print(netdissect_options *ndo, */ static void get_data_src_dst_mac(uint16_t fc, const u_char *p, const uint8_t **srcp, - const uint8_t **dstp) + const uint8_t **dstp) { #define ADDR1 (p + 4) #define ADDR2 (p + 10) @@ -1803,19 +1937,19 @@ data_header_print(netdissect_options *ndo, uint16_t fc, const u_char *p) if (DATA_FRAME_IS_CF_ACK(subtype) || DATA_FRAME_IS_CF_POLL(subtype) || DATA_FRAME_IS_QOS(subtype)) { - ND_PRINT((ndo, "CF ")); + ND_PRINT("CF "); if (DATA_FRAME_IS_CF_ACK(subtype)) { if (DATA_FRAME_IS_CF_POLL(subtype)) - ND_PRINT((ndo, "Ack/Poll")); + ND_PRINT("Ack/Poll"); else - ND_PRINT((ndo, "Ack")); + ND_PRINT("Ack"); } else { if (DATA_FRAME_IS_CF_POLL(subtype)) - ND_PRINT((ndo, "Poll")); + ND_PRINT("Poll"); } if (DATA_FRAME_IS_QOS(subtype)) - ND_PRINT((ndo, "+QoS")); - ND_PRINT((ndo, " ")); + ND_PRINT("+QoS"); + ND_PRINT(" "); } #define ADDR1 (p + 4) @@ -1824,21 +1958,21 @@ data_header_print(netdissect_options *ndo, uint16_t fc, const u_char *p) #define ADDR4 (p + 24) if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) { - ND_PRINT((ndo, "DA:%s SA:%s BSSID:%s ", - etheraddr_string(ndo, ADDR1), etheraddr_string(ndo, ADDR2), - etheraddr_string(ndo, ADDR3))); + ND_PRINT("DA:%s SA:%s BSSID:%s ", + GET_ETHERADDR_STRING(ADDR1), GET_ETHERADDR_STRING(ADDR2), + GET_ETHERADDR_STRING(ADDR3)); } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) { - ND_PRINT((ndo, "DA:%s BSSID:%s SA:%s ", - etheraddr_string(ndo, ADDR1), etheraddr_string(ndo, ADDR2), - etheraddr_string(ndo, ADDR3))); + ND_PRINT("DA:%s BSSID:%s SA:%s ", + GET_ETHERADDR_STRING(ADDR1), GET_ETHERADDR_STRING(ADDR2), + GET_ETHERADDR_STRING(ADDR3)); } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) { - ND_PRINT((ndo, "BSSID:%s SA:%s DA:%s ", - etheraddr_string(ndo, ADDR1), etheraddr_string(ndo, ADDR2), - etheraddr_string(ndo, ADDR3))); + ND_PRINT("BSSID:%s SA:%s DA:%s ", + GET_ETHERADDR_STRING(ADDR1), GET_ETHERADDR_STRING(ADDR2), + GET_ETHERADDR_STRING(ADDR3)); } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) { - ND_PRINT((ndo, "RA:%s TA:%s DA:%s SA:%s ", - etheraddr_string(ndo, ADDR1), etheraddr_string(ndo, ADDR2), - etheraddr_string(ndo, ADDR3), etheraddr_string(ndo, ADDR4))); + ND_PRINT("RA:%s TA:%s DA:%s SA:%s ", + GET_ETHERADDR_STRING(ADDR1), GET_ETHERADDR_STRING(ADDR2), + GET_ETHERADDR_STRING(ADDR3), GET_ETHERADDR_STRING(ADDR4)); } #undef ADDR1 @@ -1852,9 +1986,9 @@ mgmt_header_print(netdissect_options *ndo, const u_char *p) { const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p; - ND_PRINT((ndo, "BSSID:%s DA:%s SA:%s ", - etheraddr_string(ndo, (hp)->bssid), etheraddr_string(ndo, (hp)->da), - etheraddr_string(ndo, (hp)->sa))); + ND_PRINT("BSSID:%s DA:%s SA:%s ", + GET_ETHERADDR_STRING((hp)->bssid), GET_ETHERADDR_STRING((hp)->da), + GET_ETHERADDR_STRING((hp)->sa)); } static void @@ -1862,43 +1996,43 @@ ctrl_header_print(netdissect_options *ndo, uint16_t fc, const u_char *p) { switch (FC_SUBTYPE(fc)) { case CTRL_BAR: - ND_PRINT((ndo, " RA:%s TA:%s CTL(%x) SEQ(%u) ", - etheraddr_string(ndo, ((const struct ctrl_bar_hdr_t *)p)->ra), - etheraddr_string(ndo, ((const struct ctrl_bar_hdr_t *)p)->ta), - EXTRACT_LE_16BITS(&(((const struct ctrl_bar_hdr_t *)p)->ctl)), - EXTRACT_LE_16BITS(&(((const struct ctrl_bar_hdr_t *)p)->seq)))); + ND_PRINT(" RA:%s TA:%s CTL(%x) SEQ(%u) ", + GET_ETHERADDR_STRING(((const struct ctrl_bar_hdr_t *)p)->ra), + GET_ETHERADDR_STRING(((const struct ctrl_bar_hdr_t *)p)->ta), + GET_LE_U_2(((const struct ctrl_bar_hdr_t *)p)->ctl), + GET_LE_U_2(((const struct ctrl_bar_hdr_t *)p)->seq)); break; case CTRL_BA: - ND_PRINT((ndo, "RA:%s ", - etheraddr_string(ndo, ((const struct ctrl_ba_hdr_t *)p)->ra))); + ND_PRINT("RA:%s ", + GET_ETHERADDR_STRING(((const struct ctrl_ba_hdr_t *)p)->ra)); break; case CTRL_PS_POLL: - ND_PRINT((ndo, "BSSID:%s TA:%s ", - etheraddr_string(ndo, ((const struct ctrl_ps_poll_hdr_t *)p)->bssid), - etheraddr_string(ndo, ((const struct ctrl_ps_poll_hdr_t *)p)->ta))); + ND_PRINT("BSSID:%s TA:%s ", + GET_ETHERADDR_STRING(((const struct ctrl_ps_poll_hdr_t *)p)->bssid), + GET_ETHERADDR_STRING(((const struct ctrl_ps_poll_hdr_t *)p)->ta)); break; case CTRL_RTS: - ND_PRINT((ndo, "RA:%s TA:%s ", - etheraddr_string(ndo, ((const struct ctrl_rts_hdr_t *)p)->ra), - etheraddr_string(ndo, ((const struct ctrl_rts_hdr_t *)p)->ta))); + ND_PRINT("RA:%s TA:%s ", + GET_ETHERADDR_STRING(((const struct ctrl_rts_hdr_t *)p)->ra), + GET_ETHERADDR_STRING(((const struct ctrl_rts_hdr_t *)p)->ta)); break; case CTRL_CTS: - ND_PRINT((ndo, "RA:%s ", - etheraddr_string(ndo, ((const struct ctrl_cts_hdr_t *)p)->ra))); + ND_PRINT("RA:%s ", + GET_ETHERADDR_STRING(((const struct ctrl_cts_hdr_t *)p)->ra)); break; case CTRL_ACK: - ND_PRINT((ndo, "RA:%s ", - etheraddr_string(ndo, ((const struct ctrl_ack_hdr_t *)p)->ra))); + ND_PRINT("RA:%s ", + GET_ETHERADDR_STRING(((const struct ctrl_ack_hdr_t *)p)->ra)); break; case CTRL_CF_END: - ND_PRINT((ndo, "RA:%s BSSID:%s ", - etheraddr_string(ndo, ((const struct ctrl_end_hdr_t *)p)->ra), - etheraddr_string(ndo, ((const struct ctrl_end_hdr_t *)p)->bssid))); + ND_PRINT("RA:%s BSSID:%s ", + GET_ETHERADDR_STRING(((const struct ctrl_end_hdr_t *)p)->ra), + GET_ETHERADDR_STRING(((const struct ctrl_end_hdr_t *)p)->bssid)); break; case CTRL_END_ACK: - ND_PRINT((ndo, "RA:%s BSSID:%s ", - etheraddr_string(ndo, ((const struct ctrl_end_ack_hdr_t *)p)->ra), - etheraddr_string(ndo, ((const struct ctrl_end_ack_hdr_t *)p)->bssid))); + ND_PRINT("RA:%s BSSID:%s ", + GET_ETHERADDR_STRING(((const struct ctrl_end_ack_hdr_t *)p)->ra), + GET_ETHERADDR_STRING(((const struct ctrl_end_ack_hdr_t *)p)->bssid)); break; default: /* We shouldn't get here - we should already have quit */ @@ -1908,7 +2042,7 @@ ctrl_header_print(netdissect_options *ndo, uint16_t fc, const u_char *p) static int extract_header_length(netdissect_options *ndo, - uint16_t fc) + uint16_t fc) { int len; @@ -1936,7 +2070,7 @@ extract_header_length(netdissect_options *ndo, case CTRL_END_ACK: return CTRL_END_ACK_HDRLEN; default: - ND_PRINT((ndo, "unknown 802.11 ctrl frame subtype (%d)", FC_SUBTYPE(fc))); + ND_PRINT("unknown 802.11 ctrl frame subtype (%u)", FC_SUBTYPE(fc)); return 0; } case T_DATA: @@ -1945,15 +2079,15 @@ extract_header_length(netdissect_options *ndo, len += 2; return len; default: - ND_PRINT((ndo, "unknown 802.11 frame type (%d)", FC_TYPE(fc))); + ND_PRINT("unknown 802.11 frame type (%u)", FC_TYPE(fc)); return 0; } } static int -extract_mesh_header_length(const u_char *p) +extract_mesh_header_length(netdissect_options *ndo, const u_char *p) { - return (p[0] &~ 3) ? 0 : 6*(1 + (p[0] & 3)); + return (GET_U_1(p) &~ 3) ? 0 : 6*(1 + (GET_U_1(p) & 3)); } /* @@ -1961,41 +2095,40 @@ extract_mesh_header_length(const u_char *p) */ static void ieee_802_11_hdr_print(netdissect_options *ndo, - uint16_t fc, const u_char *p, u_int hdrlen, - u_int meshdrlen) + uint16_t fc, const u_char *p, u_int hdrlen, + u_int meshdrlen) { if (ndo->ndo_vflag) { if (FC_MORE_DATA(fc)) - ND_PRINT((ndo, "More Data ")); + ND_PRINT("More Data "); if (FC_MORE_FLAG(fc)) - ND_PRINT((ndo, "More Fragments ")); + ND_PRINT("More Fragments "); if (FC_POWER_MGMT(fc)) - ND_PRINT((ndo, "Pwr Mgmt ")); + ND_PRINT("Pwr Mgmt "); if (FC_RETRY(fc)) - ND_PRINT((ndo, "Retry ")); + ND_PRINT("Retry "); if (FC_ORDER(fc)) - ND_PRINT((ndo, "Strictly Ordered ")); + ND_PRINT("Strictly Ordered "); if (FC_PROTECTED(fc)) - ND_PRINT((ndo, "Protected ")); + ND_PRINT("Protected "); if (FC_TYPE(fc) != T_CTRL || FC_SUBTYPE(fc) != CTRL_PS_POLL) - ND_PRINT((ndo, "%dus ", - EXTRACT_LE_16BITS( - &((const struct mgmt_header_t *)p)->duration))); + ND_PRINT("%uus ", + GET_LE_U_2(((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; + (const struct meshcntl_t *)(p + hdrlen - meshdrlen); + u_int ae = GET_U_1(mc->flags) & 3; - ND_PRINT((ndo, "MeshData (AE %d TTL %u seq %u", ae, mc->ttl, - EXTRACT_LE_32BITS(mc->seq))); + ND_PRINT("MeshData (AE %u TTL %u seq %u", ae, + GET_U_1(mc->ttl), GET_LE_U_4(mc->seq)); if (ae > 0) - ND_PRINT((ndo, " A4:%s", etheraddr_string(ndo, mc->addr4))); + ND_PRINT(" A4:%s", GET_ETHERADDR_STRING(mc->addr4)); if (ae > 1) - ND_PRINT((ndo, " A5:%s", etheraddr_string(ndo, mc->addr5))); + ND_PRINT(" A5:%s", GET_ETHERADDR_STRING(mc->addr5)); if (ae > 2) - ND_PRINT((ndo, " A6:%s", etheraddr_string(ndo, mc->addr6))); - ND_PRINT((ndo, ") ")); + ND_PRINT(" A6:%s", GET_ETHERADDR_STRING(mc->addr6)); + ND_PRINT(") "); } switch (FC_TYPE(fc)) { @@ -2013,26 +2146,21 @@ ieee_802_11_hdr_print(netdissect_options *ndo, } } -#ifndef roundup2 -#define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */ -#endif - -static const char tstr[] = "[|802.11]"; - static u_int ieee802_11_print(netdissect_options *ndo, - const u_char *p, u_int length, u_int orig_caplen, int pad, - u_int fcslen) + const u_char *p, u_int length, u_int orig_caplen, int pad, + u_int fcslen) { uint16_t fc; u_int caplen, hdrlen, meshdrlen; struct lladdr_info src, dst; int llc_hdrlen; + ndo->ndo_protocol = "802.11"; caplen = orig_caplen; /* Remove FCS, if present */ if (length < fcslen) { - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return caplen; } length -= fcslen; @@ -2044,11 +2172,11 @@ ieee802_11_print(netdissect_options *ndo, } if (caplen < IEEE802_11_FC_LEN) { - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return orig_caplen; } - fc = EXTRACT_LE_16BITS(p); + fc = GET_LE_U_2(p); hdrlen = extract_header_length(ndo, fc); if (hdrlen == 0) { /* Unknown frame type or control frame subtype; quit. */ @@ -2058,17 +2186,17 @@ ieee802_11_print(netdissect_options *ndo, hdrlen = roundup2(hdrlen, 4); if (ndo->ndo_Hflag && FC_TYPE(fc) == T_DATA && DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) { - if (caplen < hdrlen + 1) { - ND_PRINT((ndo, "%s", tstr)); + if(!ND_TTEST_1(p + hdrlen)) { + nd_print_trunc(ndo); return hdrlen; } - meshdrlen = extract_mesh_header_length(p+hdrlen); + meshdrlen = extract_mesh_header_length(ndo, p + hdrlen); hdrlen += meshdrlen; } else meshdrlen = 0; if (caplen < hdrlen) { - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return hdrlen; } @@ -2088,13 +2216,13 @@ ieee802_11_print(netdissect_options *ndo, case T_MGMT: get_mgmt_src_dst_mac(p - hdrlen, &src.addr, &dst.addr); if (!mgmt_body_print(ndo, fc, src.addr, p, length)) { - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return hdrlen; } break; case T_CTRL: if (!ctrl_body_print(ndo, fc, p - hdrlen)) { - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return hdrlen; } break; @@ -2103,9 +2231,9 @@ ieee802_11_print(netdissect_options *ndo, return hdrlen; /* no-data frame */ /* There may be a problem w/ AP not having this bit set */ if (FC_PROTECTED(fc)) { - ND_PRINT((ndo, "Data")); + ND_PRINT("Data"); if (!wep_print(ndo, p)) { - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return hdrlen; } } else { @@ -2137,11 +2265,12 @@ ieee802_11_print(netdissect_options *ndo, * 'h->len' is the length of the packet off the wire, and 'h->caplen' * is the number of bytes actually captured. */ -u_int +void ieee802_11_if_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, const u_char *p) + const struct pcap_pkthdr *h, const u_char *p) { - return ieee802_11_print(ndo, p, h->len, h->caplen, 0, 0); + ndo->ndo_protocol = "802.11"; + ndo->ndo_ll_hdr_len += ieee802_11_print(ndo, p, h->len, h->caplen, 0, 0); } @@ -2198,18 +2327,18 @@ ieee802_11_if_print(netdissect_options *ndo, * Note well: all radiotap fields are little-endian. */ struct ieee80211_radiotap_header { - uint8_t it_version; /* Version 0. Only increases + nd_uint8_t it_version; /* Version 0. Only increases * for drastic changes, * introduction of compatible * new fields does not count. */ - uint8_t it_pad; - uint16_t it_len; /* length of the whole + nd_uint8_t it_pad; + nd_uint16_t it_len; /* length of the whole * header in bytes, including * it_version, it_pad, * it_len, and data fields. */ - uint32_t it_present; /* A bitmap telling which + nd_uint32_t it_present; /* A bitmap telling which * fields are present. Set bit 31 * (0x80000000) to extend the * bitmap by another 32 bits. @@ -2244,14 +2373,14 @@ struct ieee80211_radiotap_header { * 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) + * IEEE80211_RADIOTAP_DBM_ANTSIGNAL int8_t decibels from + * one milliwatt (dBm) * * RF signal power at the antenna, decibel difference from * one milliwatt. * - * IEEE80211_RADIOTAP_DBM_ANTNOISE int8_t decibels from - * one milliwatt (dBm) + * IEEE80211_RADIOTAP_DBM_ANTNOISE int8_t decibels from + * one milliwatt (dBm) * * RF noise power at the antenna, decibel difference from one * milliwatt. @@ -2285,8 +2414,8 @@ struct ieee80211_radiotap_header { * set at factory calibration. 0 is max power. Monotonically * nondecreasing with lower power levels. * - * IEEE80211_RADIOTAP_DBM_TX_POWER int8_t decibels from - * one milliwatt (dBm) + * IEEE80211_RADIOTAP_DBM_TX_POWER int8_t decibels from + * one milliwatt (dBm) * * Transmit power expressed as dBm (decibels from a 1 milliwatt * reference). This is the absolute power level measured at @@ -2306,10 +2435,10 @@ struct ieee80211_radiotap_header { * * Properties of received frames. See flags defined below. * - * IEEE80211_RADIOTAP_XCHANNEL uint32_t bitmap - * uint16_t MHz - * uint8_t channel number - * uint8_t .5 dBm + * IEEE80211_RADIOTAP_XCHANNEL uint32_t bitmap + * uint16_t MHz + * uint8_t channel number + * uint8_t .5 dBm * * Extended channel specification: flags (see below) followed by * frequency in MHz, the corresponding IEEE channel number, and @@ -2317,9 +2446,9 @@ struct ieee80211_radiotap_header { * units. This property supersedes IEEE80211_RADIOTAP_CHANNEL * and only one of the two should be present. * - * IEEE80211_RADIOTAP_MCS uint8_t known - * uint8_t flags - * uint8_t mcs + * IEEE80211_RADIOTAP_MCS uint8_t known + * uint8_t flags + * uint8_t mcs * * Bitset indicating which fields have known values, followed * by bitset of flag values, followed by the MCS rate index as @@ -2336,8 +2465,8 @@ struct ieee80211_radiotap_header { * * IEEE80211_RADIOTAP_VENDOR_NAMESPACE * uint8_t OUI[3] - * uint8_t subspace - * uint16_t length + * uint8_t subspace + * uint16_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 @@ -2390,15 +2519,15 @@ enum ieee80211_radiotap_type { /* Useful combinations of channel characteristics, borrowed from Ethereal */ #define IEEE80211_CHAN_A \ - (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM) + (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM) #define IEEE80211_CHAN_B \ - (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK) + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK) #define IEEE80211_CHAN_G \ - (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN) + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN) #define IEEE80211_CHAN_TA \ - (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO) + (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO) #define IEEE80211_CHAN_TG \ - (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN | IEEE80211_CHAN_TURBO) + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN | IEEE80211_CHAN_TURBO) /* For IEEE80211_RADIOTAP_FLAGS */ @@ -2513,54 +2642,54 @@ enum ieee80211_radiotap_type { static void print_chaninfo(netdissect_options *ndo, - uint16_t freq, int flags, int presentflags) + uint16_t freq, uint32_t flags, uint32_t presentflags) { - ND_PRINT((ndo, "%u MHz", freq)); + ND_PRINT("%u MHz", freq); if (presentflags & (1 << IEEE80211_RADIOTAP_MCS)) { /* * We have the MCS field, so this is 11n, regardless * of what the channel flags say. */ - ND_PRINT((ndo, " 11n")); + ND_PRINT(" 11n"); } else { if (IS_CHAN_FHSS(flags)) - ND_PRINT((ndo, " FHSS")); + ND_PRINT(" FHSS"); if (IS_CHAN_A(flags)) { if (flags & IEEE80211_CHAN_HALF) - ND_PRINT((ndo, " 11a/10Mhz")); + ND_PRINT(" 11a/10Mhz"); else if (flags & IEEE80211_CHAN_QUARTER) - ND_PRINT((ndo, " 11a/5Mhz")); + ND_PRINT(" 11a/5Mhz"); else - ND_PRINT((ndo, " 11a")); + ND_PRINT(" 11a"); } if (IS_CHAN_ANYG(flags)) { if (flags & IEEE80211_CHAN_HALF) - ND_PRINT((ndo, " 11g/10Mhz")); + ND_PRINT(" 11g/10Mhz"); else if (flags & IEEE80211_CHAN_QUARTER) - ND_PRINT((ndo, " 11g/5Mhz")); + ND_PRINT(" 11g/5Mhz"); else - ND_PRINT((ndo, " 11g")); + ND_PRINT(" 11g"); } else if (IS_CHAN_B(flags)) - ND_PRINT((ndo, " 11b")); + ND_PRINT(" 11b"); if (flags & IEEE80211_CHAN_TURBO) - ND_PRINT((ndo, " Turbo")); + ND_PRINT(" Turbo"); } /* * These apply to 11n. */ if (flags & IEEE80211_CHAN_HT20) - ND_PRINT((ndo, " ht/20")); + ND_PRINT(" ht/20"); else if (flags & IEEE80211_CHAN_HT40D) - ND_PRINT((ndo, " ht/40-")); + ND_PRINT(" ht/40-"); else if (flags & IEEE80211_CHAN_HT40U) - ND_PRINT((ndo, " ht/40+")); - ND_PRINT((ndo, " ")); + ND_PRINT(" ht/40+"); + ND_PRINT(" "); } static int print_radiotap_field(netdissect_options *ndo, - struct cpack_state *s, uint32_t bit, uint8_t *flagsp, - uint32_t presentflags) + struct cpack_state *s, uint32_t bit, uint8_t *flagsp, + uint32_t presentflags) { u_int i; int rc; @@ -2570,43 +2699,43 @@ print_radiotap_field(netdissect_options *ndo, case IEEE80211_RADIOTAP_TSFT: { uint64_t tsft; - rc = cpack_uint64(s, &tsft); + rc = nd_cpack_uint64(ndo, s, &tsft); if (rc != 0) goto trunc; - ND_PRINT((ndo, "%" PRIu64 "us tsft ", tsft)); + ND_PRINT("%" PRIu64 "us tsft ", tsft); break; } case IEEE80211_RADIOTAP_FLAGS: { uint8_t flagsval; - rc = cpack_uint8(s, &flagsval); + rc = nd_cpack_uint8(ndo, s, &flagsval); if (rc != 0) goto trunc; *flagsp = flagsval; if (flagsval & IEEE80211_RADIOTAP_F_CFP) - ND_PRINT((ndo, "cfp ")); + ND_PRINT("cfp "); if (flagsval & IEEE80211_RADIOTAP_F_SHORTPRE) - ND_PRINT((ndo, "short preamble ")); + ND_PRINT("short preamble "); if (flagsval & IEEE80211_RADIOTAP_F_WEP) - ND_PRINT((ndo, "wep ")); + ND_PRINT("wep "); if (flagsval & IEEE80211_RADIOTAP_F_FRAG) - ND_PRINT((ndo, "fragmented ")); + ND_PRINT("fragmented "); if (flagsval & IEEE80211_RADIOTAP_F_BADFCS) - ND_PRINT((ndo, "bad-fcs ")); + ND_PRINT("bad-fcs "); break; } case IEEE80211_RADIOTAP_RATE: { uint8_t rate; - rc = cpack_uint8(s, &rate); + rc = nd_cpack_uint8(ndo, s, &rate); if (rc != 0) goto trunc; /* * 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?) + * macOS, NetBSD, OpenBSD, and DragonFly BSD?) * * This is an issue either for proprietary extensions * to 11a or 11g, which do exist, or for 11n @@ -2641,9 +2770,9 @@ print_radiotap_field(netdissect_options *ndo, * information from Flags, at least on * FreeBSD? */ - ND_PRINT((ndo, "MCS %u ", rate & 0x7f)); + ND_PRINT("MCS %u ", rate & 0x7f); } else - ND_PRINT((ndo, "%2.1f Mb/s ", .5 * rate)); + ND_PRINT("%2.1f Mb/s ", .5 * rate); break; } @@ -2651,10 +2780,10 @@ print_radiotap_field(netdissect_options *ndo, uint16_t frequency; uint16_t flags; - rc = cpack_uint16(s, &frequency); + rc = nd_cpack_uint16(ndo, s, &frequency); if (rc != 0) goto trunc; - rc = cpack_uint16(s, &flags); + rc = nd_cpack_uint16(ndo, s, &flags); if (rc != 0) goto trunc; /* @@ -2671,110 +2800,110 @@ print_radiotap_field(netdissect_options *ndo, uint8_t hopset; uint8_t hoppat; - rc = cpack_uint8(s, &hopset); + rc = nd_cpack_uint8(ndo, s, &hopset); if (rc != 0) goto trunc; - rc = cpack_uint8(s, &hoppat); + rc = nd_cpack_uint8(ndo, s, &hoppat); if (rc != 0) goto trunc; - ND_PRINT((ndo, "fhset %d fhpat %d ", hopset, hoppat)); + ND_PRINT("fhset %u fhpat %u ", hopset, hoppat); break; } case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: { int8_t dbm_antsignal; - rc = cpack_int8(s, &dbm_antsignal); + rc = nd_cpack_int8(ndo, s, &dbm_antsignal); if (rc != 0) goto trunc; - ND_PRINT((ndo, "%ddBm signal ", dbm_antsignal)); + ND_PRINT("%ddBm signal ", dbm_antsignal); break; } case IEEE80211_RADIOTAP_DBM_ANTNOISE: { int8_t dbm_antnoise; - rc = cpack_int8(s, &dbm_antnoise); + rc = nd_cpack_int8(ndo, s, &dbm_antnoise); if (rc != 0) goto trunc; - ND_PRINT((ndo, "%ddBm noise ", dbm_antnoise)); + ND_PRINT("%ddBm noise ", dbm_antnoise); break; } case IEEE80211_RADIOTAP_LOCK_QUALITY: { uint16_t lock_quality; - rc = cpack_uint16(s, &lock_quality); + rc = nd_cpack_uint16(ndo, s, &lock_quality); if (rc != 0) goto trunc; - ND_PRINT((ndo, "%u sq ", lock_quality)); + ND_PRINT("%u sq ", lock_quality); break; } case IEEE80211_RADIOTAP_TX_ATTENUATION: { - uint16_t tx_attenuation; + int16_t tx_attenuation; - rc = cpack_uint16(s, &tx_attenuation); + rc = nd_cpack_int16(ndo, s, &tx_attenuation); if (rc != 0) goto trunc; - ND_PRINT((ndo, "%d tx power ", -(int)tx_attenuation)); + ND_PRINT("%d tx power ", -tx_attenuation); break; } case IEEE80211_RADIOTAP_DB_TX_ATTENUATION: { - uint8_t db_tx_attenuation; + int8_t db_tx_attenuation; - rc = cpack_uint8(s, &db_tx_attenuation); + rc = nd_cpack_int8(ndo, s, &db_tx_attenuation); if (rc != 0) goto trunc; - ND_PRINT((ndo, "%ddB tx attenuation ", -(int)db_tx_attenuation)); + ND_PRINT("%ddB tx attenuation ", -db_tx_attenuation); break; } case IEEE80211_RADIOTAP_DBM_TX_POWER: { int8_t dbm_tx_power; - rc = cpack_int8(s, &dbm_tx_power); + rc = nd_cpack_int8(ndo, s, &dbm_tx_power); if (rc != 0) goto trunc; - ND_PRINT((ndo, "%ddBm tx power ", dbm_tx_power)); + ND_PRINT("%ddBm tx power ", dbm_tx_power); break; } case IEEE80211_RADIOTAP_ANTENNA: { uint8_t antenna; - rc = cpack_uint8(s, &antenna); + rc = nd_cpack_uint8(ndo, s, &antenna); if (rc != 0) goto trunc; - ND_PRINT((ndo, "antenna %u ", antenna)); + ND_PRINT("antenna %u ", antenna); break; } case IEEE80211_RADIOTAP_DB_ANTSIGNAL: { uint8_t db_antsignal; - rc = cpack_uint8(s, &db_antsignal); + rc = nd_cpack_uint8(ndo, s, &db_antsignal); if (rc != 0) goto trunc; - ND_PRINT((ndo, "%ddB signal ", db_antsignal)); + ND_PRINT("%udB signal ", db_antsignal); break; } case IEEE80211_RADIOTAP_DB_ANTNOISE: { uint8_t db_antnoise; - rc = cpack_uint8(s, &db_antnoise); + rc = nd_cpack_uint8(ndo, s, &db_antnoise); if (rc != 0) goto trunc; - ND_PRINT((ndo, "%ddB noise ", db_antnoise)); + ND_PRINT("%udB noise ", db_antnoise); break; } case IEEE80211_RADIOTAP_RX_FLAGS: { uint16_t rx_flags; - rc = cpack_uint16(s, &rx_flags); + rc = nd_cpack_uint16(ndo, s, &rx_flags); if (rc != 0) goto trunc; /* Do nothing for now */ @@ -2787,16 +2916,16 @@ print_radiotap_field(netdissect_options *ndo, uint8_t channel; uint8_t maxpower; - rc = cpack_uint32(s, &flags); + rc = nd_cpack_uint32(ndo, s, &flags); if (rc != 0) goto trunc; - rc = cpack_uint16(s, &frequency); + rc = nd_cpack_uint16(ndo, s, &frequency); if (rc != 0) goto trunc; - rc = cpack_uint8(s, &channel); + rc = nd_cpack_uint8(ndo, s, &channel); if (rc != 0) goto trunc; - rc = cpack_uint8(s, &maxpower); + rc = nd_cpack_uint8(ndo, s, &maxpower); if (rc != 0) goto trunc; print_chaninfo(ndo, frequency, flags, presentflags); @@ -2815,13 +2944,13 @@ print_radiotap_field(netdissect_options *ndo, }; float htrate; - rc = cpack_uint8(s, &known); + rc = nd_cpack_uint8(ndo, s, &known); if (rc != 0) goto trunc; - rc = cpack_uint8(s, &flags); + rc = nd_cpack_uint8(ndo, s, &flags); if (rc != 0) goto trunc; - rc = cpack_uint8(s, &mcs_index); + rc = nd_cpack_uint8(ndo, s, &mcs_index); if (rc != 0) goto trunc; if (known & IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN) { @@ -2839,9 +2968,9 @@ print_radiotap_field(netdissect_options *ndo, * up the rate. */ htrate = - ieee80211_float_htrates \ - [mcs_index] \ - [((flags & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK) == IEEE80211_RADIOTAP_MCS_BANDWIDTH_40 ? 1 : 0)] \ + ieee80211_float_htrates + [mcs_index] + [((flags & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK) == IEEE80211_RADIOTAP_MCS_BANDWIDTH_40 ? 1 : 0)] [((flags & IEEE80211_RADIOTAP_MCS_SHORT_GI) ? 1 : 0)]; } else { /* @@ -2862,37 +2991,37 @@ print_radiotap_field(netdissect_options *ndo, * We have the rate. * Print it. */ - ND_PRINT((ndo, "%.1f Mb/s MCS %u ", htrate, mcs_index)); + ND_PRINT("%.1f Mb/s MCS %u ", htrate, mcs_index); } else { /* * We at least have the MCS index. * Print it. */ - ND_PRINT((ndo, "MCS %u ", mcs_index)); + ND_PRINT("MCS %u ", mcs_index); } } if (known & IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN) { - ND_PRINT((ndo, "%s ", - ht_bandwidth[flags & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK])); + ND_PRINT("%s ", + ht_bandwidth[flags & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK]); } if (known & IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN) { - ND_PRINT((ndo, "%s GI ", + ND_PRINT("%s GI ", (flags & IEEE80211_RADIOTAP_MCS_SHORT_GI) ? - "short" : "long")); + "short" : "long"); } if (known & IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN) { - ND_PRINT((ndo, "%s ", + ND_PRINT("%s ", (flags & IEEE80211_RADIOTAP_MCS_HT_GREENFIELD) ? - "greenfield" : "mixed")); + "greenfield" : "mixed"); } if (known & IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN) { - ND_PRINT((ndo, "%s FEC ", + ND_PRINT("%s FEC ", (flags & IEEE80211_RADIOTAP_MCS_FEC_LDPC) ? - "LDPC" : "BCC")); + "LDPC" : "BCC"); } if (known & IEEE80211_RADIOTAP_MCS_STBC_KNOWN) { - ND_PRINT((ndo, "RX-STBC%u ", - (flags & IEEE80211_RADIOTAP_MCS_STBC_MASK) >> IEEE80211_RADIOTAP_MCS_STBC_SHIFT)); + ND_PRINT("RX-STBC%u ", + (flags & IEEE80211_RADIOTAP_MCS_STBC_MASK) >> IEEE80211_RADIOTAP_MCS_STBC_SHIFT); } break; } @@ -2903,16 +3032,16 @@ print_radiotap_field(netdissect_options *ndo, uint8_t delim_crc; uint8_t reserved; - rc = cpack_uint32(s, &reference_num); + rc = nd_cpack_uint32(ndo, s, &reference_num); if (rc != 0) goto trunc; - rc = cpack_uint16(s, &flags); + rc = nd_cpack_uint16(ndo, s, &flags); if (rc != 0) goto trunc; - rc = cpack_uint8(s, &delim_crc); + rc = nd_cpack_uint8(ndo, s, &delim_crc); if (rc != 0) goto trunc; - rc = cpack_uint8(s, &reserved); + rc = nd_cpack_uint8(ndo, s, &reserved); if (rc != 0) goto trunc; /* Do nothing for now */ @@ -2962,27 +3091,27 @@ print_radiotap_field(netdissect_options *ndo, "unknown (31)" }; - rc = cpack_uint16(s, &known); + rc = nd_cpack_uint16(ndo, s, &known); if (rc != 0) goto trunc; - rc = cpack_uint8(s, &flags); + rc = nd_cpack_uint8(ndo, s, &flags); if (rc != 0) goto trunc; - rc = cpack_uint8(s, &bandwidth); + rc = nd_cpack_uint8(ndo, s, &bandwidth); if (rc != 0) goto trunc; for (i = 0; i < 4; i++) { - rc = cpack_uint8(s, &mcs_nss[i]); + rc = nd_cpack_uint8(ndo, s, &mcs_nss[i]); if (rc != 0) goto trunc; } - rc = cpack_uint8(s, &coding); + rc = nd_cpack_uint8(ndo, s, &coding); if (rc != 0) goto trunc; - rc = cpack_uint8(s, &group_id); + rc = nd_cpack_uint8(ndo, s, &group_id); if (rc != 0) goto trunc; - rc = cpack_uint16(s, &partial_aid); + rc = nd_cpack_uint16(ndo, s, &partial_aid); if (rc != 0) goto trunc; for (i = 0; i < 4; i++) { @@ -2993,19 +3122,19 @@ print_radiotap_field(netdissect_options *ndo, if (nss == 0) continue; - ND_PRINT((ndo, "User %u MCS %u ", i, mcs)); - ND_PRINT((ndo, "%s FEC ", + ND_PRINT("User %u MCS %u ", i, mcs); + ND_PRINT("%s FEC ", (coding & (IEEE80211_RADIOTAP_CODING_LDPC_USERn << i)) ? - "LDPC" : "BCC")); + "LDPC" : "BCC"); } if (known & IEEE80211_RADIOTAP_VHT_BANDWIDTH_KNOWN) { - ND_PRINT((ndo, "%s ", - vht_bandwidth[bandwidth & IEEE80211_RADIOTAP_VHT_BANDWIDTH_MASK])); + ND_PRINT("%s ", + vht_bandwidth[bandwidth & IEEE80211_RADIOTAP_VHT_BANDWIDTH_MASK]); } if (known & IEEE80211_RADIOTAP_VHT_GUARD_INTERVAL_KNOWN) { - ND_PRINT((ndo, "%s GI ", + ND_PRINT("%s GI ", (flags & IEEE80211_RADIOTAP_VHT_SHORT_GI) ? - "short" : "long")); + "short" : "long"); } break; } @@ -3015,22 +3144,22 @@ print_radiotap_field(netdissect_options *ndo, * size we do not know, so we cannot * proceed. Just print the bit number. */ - ND_PRINT((ndo, "[bit %u] ", bit)); + ND_PRINT("[bit %u] ", bit); return -1; } return 0; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return rc; } static int print_in_radiotap_namespace(netdissect_options *ndo, - struct cpack_state *s, uint8_t *flags, - uint32_t presentflags, int bit0) + struct cpack_state *s, uint8_t *flags, + uint32_t presentflags, int bit0) { #define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x))) #define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x))) @@ -3077,16 +3206,16 @@ print_in_radiotap_namespace(netdissect_options *ndo, u_int ieee802_11_radio_print(netdissect_options *ndo, - const u_char *p, u_int length, u_int caplen) + const u_char *p, u_int length, u_int caplen) { #define BIT(n) (1U << n) #define IS_EXTENDED(__p) \ - (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0 + (GET_LE_U_4(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0 struct cpack_state cpacker; const struct ieee80211_radiotap_header *hdr; uint32_t presentflags; - const uint32_t *presentp, *last_presentp; + const nd_uint32_t *presentp, *last_presentp; int vendor_namespace; uint8_t vendor_oui[3]; uint8_t vendor_subnamespace; @@ -3097,21 +3226,22 @@ ieee802_11_radio_print(netdissect_options *ndo, int pad; u_int fcslen; + ndo->ndo_protocol = "802.11_radio"; if (caplen < sizeof(*hdr)) { - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return caplen; } hdr = (const struct ieee80211_radiotap_header *)p; - len = EXTRACT_LE_16BITS(&hdr->it_len); + len = GET_LE_U_2(hdr->it_len); if (len < sizeof(*hdr)) { /* * The length is the length of the entire header, so * it must be as large as the fixed-length part of * the header. */ - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return caplen; } @@ -3119,20 +3249,20 @@ ieee802_11_radio_print(netdissect_options *ndo, * If we don't have the entire radiotap header, just give up. */ if (caplen < len) { - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return caplen; } - cpack_init(&cpacker, (const uint8_t *)hdr, len); /* align against header start */ - cpack_advance(&cpacker, sizeof(*hdr)); /* includes the 1st bitmap */ + nd_cpack_init(&cpacker, (const uint8_t *)hdr, len); /* align against header start */ + nd_cpack_advance(&cpacker, sizeof(*hdr)); /* includes the 1st bitmap */ for (last_presentp = &hdr->it_present; (const u_char*)(last_presentp + 1) <= p + len && IS_EXTENDED(last_presentp); last_presentp++) - cpack_advance(&cpacker, sizeof(hdr->it_present)); /* more bitmaps */ + nd_cpack_advance(&cpacker, sizeof(hdr->it_present)); /* more bitmaps */ /* are there more bitmap extensions than bytes in header? */ if ((const u_char*)(last_presentp + 1) > p + len) { - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return caplen; } @@ -3152,7 +3282,7 @@ ieee802_11_radio_print(netdissect_options *ndo, fcslen = 0; for (presentp = &hdr->it_present; presentp <= last_presentp; presentp++) { - presentflags = EXTRACT_LE_32BITS(presentp); + presentflags = GET_LE_U_4(presentp); /* * If this is a vendor namespace, we don't handle it. @@ -3164,7 +3294,7 @@ ieee802_11_radio_print(netdissect_options *ndo, * it'd be added here; use vendor_oui and * vendor_subnamespace to interpret the fields. */ - if (cpack_advance(&cpacker, skip_length) != 0) { + if (nd_cpack_advance(&cpacker, skip_length) != 0) { /* * Ran out of space in the packet. */ @@ -3227,28 +3357,28 @@ ieee802_11_radio_print(netdissect_options *ndo, */ bit0 = 0; vendor_namespace = 1; - if ((cpack_align_and_reserve(&cpacker, 2)) == NULL) { - ND_PRINT((ndo, "%s", tstr)); + if ((nd_cpack_align_and_reserve(&cpacker, 2)) == NULL) { + nd_print_trunc(ndo); break; } - if (cpack_uint8(&cpacker, &vendor_oui[0]) != 0) { - ND_PRINT((ndo, "%s", tstr)); + if (nd_cpack_uint8(ndo, &cpacker, &vendor_oui[0]) != 0) { + nd_print_trunc(ndo); break; } - if (cpack_uint8(&cpacker, &vendor_oui[1]) != 0) { - ND_PRINT((ndo, "%s", tstr)); + if (nd_cpack_uint8(ndo, &cpacker, &vendor_oui[1]) != 0) { + nd_print_trunc(ndo); break; } - if (cpack_uint8(&cpacker, &vendor_oui[2]) != 0) { - ND_PRINT((ndo, "%s", tstr)); + if (nd_cpack_uint8(ndo, &cpacker, &vendor_oui[2]) != 0) { + nd_print_trunc(ndo); break; } - if (cpack_uint8(&cpacker, &vendor_subnamespace) != 0) { - ND_PRINT((ndo, "%s", tstr)); + if (nd_cpack_uint8(ndo, &cpacker, &vendor_subnamespace) != 0) { + nd_print_trunc(ndo); break; } - if (cpack_uint16(&cpacker, &skip_length) != 0) { - ND_PRINT((ndo, "%s", tstr)); + if (nd_cpack_uint16(ndo, &cpacker, &skip_length) != 0) { + nd_print_trunc(ndo); break; } break; @@ -3278,29 +3408,30 @@ ieee802_11_radio_print(netdissect_options *ndo, } static u_int -ieee802_11_avs_radio_print(netdissect_options *ndo, - const u_char *p, u_int length, u_int caplen) +ieee802_11_radio_avs_print(netdissect_options *ndo, + const u_char *p, u_int length, u_int caplen) { uint32_t caphdr_len; + ndo->ndo_protocol = "802.11_radio_avs"; if (caplen < 8) { - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return caplen; } - caphdr_len = EXTRACT_32BITS(p + 4); + caphdr_len = GET_BE_U_4(p + 4); if (caphdr_len < 8) { /* * Yow! The capture header length is claimed not * to be large enough to include even the version * cookie or capture header length! */ - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return caplen; } if (caplen < caphdr_len) { - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return caplen; } @@ -3327,42 +3458,51 @@ ieee802_11_avs_radio_print(netdissect_options *ndo, * the AVS header, and the first 4 bytes of the header are used to * indicate whether it's a Prism header or an AVS header). */ -u_int +void prism_if_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, const u_char *p) + const struct pcap_pkthdr *h, const u_char *p) { u_int caplen = h->caplen; u_int length = h->len; uint32_t msgcode; + ndo->ndo_protocol = "prism"; if (caplen < 4) { - ND_PRINT((ndo, "%s", tstr)); - return caplen; + nd_print_trunc(ndo); + ndo->ndo_ll_hdr_len += caplen; + return; } - msgcode = EXTRACT_32BITS(p); + msgcode = GET_BE_U_4(p); if (msgcode == WLANCAP_MAGIC_COOKIE_V1 || - msgcode == WLANCAP_MAGIC_COOKIE_V2) - return ieee802_11_avs_radio_print(ndo, p, length, caplen); + msgcode == WLANCAP_MAGIC_COOKIE_V2) { + ndo->ndo_ll_hdr_len += ieee802_11_radio_avs_print(ndo, p, length, caplen); + return; + } if (caplen < PRISM_HDR_LEN) { - ND_PRINT((ndo, "%s", tstr)); - return caplen; + nd_print_trunc(ndo); + ndo->ndo_ll_hdr_len += caplen; + return; } - return PRISM_HDR_LEN + ieee802_11_print(ndo, p + PRISM_HDR_LEN, - length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN, 0, 0); + p += PRISM_HDR_LEN; + length -= PRISM_HDR_LEN; + caplen -= PRISM_HDR_LEN; + ndo->ndo_ll_hdr_len += PRISM_HDR_LEN; + ndo->ndo_ll_hdr_len += ieee802_11_print(ndo, p, length, caplen, 0, 0); } /* * For DLT_IEEE802_11_RADIO; like DLT_IEEE802_11, but with an extra * header, containing information such as radio information. */ -u_int +void ieee802_11_radio_if_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, const u_char *p) + const struct pcap_pkthdr *h, const u_char *p) { - return ieee802_11_radio_print(ndo, p, h->len, h->caplen); + ndo->ndo_protocol = "802.11_radio"; + ndo->ndo_ll_hdr_len += ieee802_11_radio_print(ndo, p, h->len, h->caplen); } /* @@ -3370,9 +3510,10 @@ ieee802_11_radio_if_print(netdissect_options *ndo, * extra header, containing information such as radio information, * which we currently ignore. */ -u_int +void ieee802_11_radio_avs_if_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, const u_char *p) + const struct pcap_pkthdr *h, const u_char *p) { - return ieee802_11_avs_radio_print(ndo, p, h->len, h->caplen); + ndo->ndo_protocol = "802.11_radio_avs"; + ndo->ndo_ll_hdr_len += ieee802_11_radio_avs_print(ndo, p, h->len, h->caplen); } diff --git a/contrib/tcpdump/print-802_15_4.c b/contrib/tcpdump/print-802_15_4.c index 1c77da8af1..5687d4556d 100644 --- a/contrib/tcpdump/print-802_15_4.c +++ b/contrib/tcpdump/print-802_15_4.c @@ -23,201 +23,2516 @@ /* \summary: IEEE 802.15.4 printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "addrtoname.h" #include "extract.h" +#define CHECK_BIT(num,bit) (((num) >> (bit)) & 0x1) + +#define BROKEN_6TISCH_PAN_ID_COMPRESSION 0 + +/* Frame types from Table 7-1 of 802.15.4-2015 */ static const char *ftypes[] = { "Beacon", /* 0 */ - "Data", /* 1 */ + "Data", /* 1 */ "ACK", /* 2 */ "Command", /* 3 */ - "Reserved (0x4)", /* 4 */ - "Reserved (0x5)", /* 5 */ - "Reserved (0x6)", /* 6 */ - "Reserved (0x7)", /* 7 */ + "Reserved", /* 4 */ + "Multipurpose", /* 5 */ + "Fragment", /* 6 */ + "Extended" /* 7 */ +}; + +/* Element IDs for Header IEs from Table 7-7 of 802.15.4-2015 */ +static const char *h_ie_names[] = { + "Vendor Specific Header IE", /* 0x00 */ + "Reserved 0x01", /* 0x01 */ + "Reserved 0x02", /* 0x02 */ + "Reserved 0x03", /* 0x03 */ + "Reserved 0x04", /* 0x04 */ + "Reserved 0x05", /* 0x05 */ + "Reserved 0x06", /* 0x06 */ + "Reserved 0x07", /* 0x07 */ + "Reserved 0x08", /* 0x08 */ + "Reserved 0x09", /* 0x09 */ + "Reserved 0x0a", /* 0x0a */ + "Reserved 0x0b", /* 0x0b */ + "Reserved 0x0c", /* 0x0c */ + "Reserved 0x0d", /* 0x0d */ + "Reserved 0x0e", /* 0x0e */ + "Reserved 0x0f", /* 0x0f */ + "Reserved 0x10", /* 0x10 */ + "Reserved 0x11", /* 0x11 */ + "Reserved 0x12", /* 0x12 */ + "Reserved 0x13", /* 0x13 */ + "Reserved 0x14", /* 0x14 */ + "Reserved 0x15", /* 0x15 */ + "Reserved 0x16", /* 0x16 */ + "Reserved 0x17", /* 0x17 */ + "Reserved 0x18", /* 0x18 */ + "Reserved 0x19", /* 0x19 */ + "LE CSL IE", /* 0x1a */ + "LE RIT IE", /* 0x1b */ + "DSME PAN descriptor IE", /* 0x1c */ + "Rendezvous Time IE", /* 0x1d */ + "Time Correction IE", /* 0x1e */ + "Reserved 0x1f", /* 0x1f */ + "Reserved 0x20", /* 0x20 */ + "Extended DSME PAN descriptor IE", /* 0x21 */ + "Fragment Sequence Context Description IE", /* 0x22 */ + "Simplified Superframe Specification IE", /* 0x23 */ + "Simplified GTS Specification IE", /* 0x24 */ + "LECIM Capabilities IE", /* 0x25 */ + "TRLE Descriptor IE", /* 0x26 */ + "RCC Capabilities IE", /* 0x27 */ + "RCCN Descriptor IE", /* 0x28 */ + "Global Time IE", /* 0x29 */ + "Omnibus Header IE", /* 0x2a */ + "DA IE", /* 0x2b */ + "Reserved 0x2c", /* 0x2c */ + "Reserved 0x2d", /* 0x2d */ + "Reserved 0x2e", /* 0x2e */ + "Reserved 0x2f", /* 0x2f */ + "Reserved 0x30", /* 0x30 */ + "Reserved 0x31", /* 0x31 */ + "Reserved 0x32", /* 0x32 */ + "Reserved 0x33", /* 0x33 */ + "Reserved 0x34", /* 0x34 */ + "Reserved 0x35", /* 0x35 */ + "Reserved 0x36", /* 0x36 */ + "Reserved 0x37", /* 0x37 */ + "Reserved 0x38", /* 0x38 */ + "Reserved 0x39", /* 0x39 */ + "Reserved 0x3a", /* 0x3a */ + "Reserved 0x3b", /* 0x3b */ + "Reserved 0x3c", /* 0x3c */ + "Reserved 0x3d", /* 0x3d */ + "Reserved 0x3e", /* 0x3e */ + "Reserved 0x3f", /* 0x3f */ + "Reserved 0x40", /* 0x40 */ + "Reserved 0x41", /* 0x41 */ + "Reserved 0x42", /* 0x42 */ + "Reserved 0x43", /* 0x43 */ + "Reserved 0x44", /* 0x44 */ + "Reserved 0x45", /* 0x45 */ + "Reserved 0x46", /* 0x46 */ + "Reserved 0x47", /* 0x47 */ + "Reserved 0x48", /* 0x48 */ + "Reserved 0x49", /* 0x49 */ + "Reserved 0x4a", /* 0x4a */ + "Reserved 0x4b", /* 0x4b */ + "Reserved 0x4c", /* 0x4c */ + "Reserved 0x4d", /* 0x4d */ + "Reserved 0x4e", /* 0x4e */ + "Reserved 0x4f", /* 0x4f */ + "Reserved 0x50", /* 0x50 */ + "Reserved 0x51", /* 0x51 */ + "Reserved 0x52", /* 0x52 */ + "Reserved 0x53", /* 0x53 */ + "Reserved 0x54", /* 0x54 */ + "Reserved 0x55", /* 0x55 */ + "Reserved 0x56", /* 0x56 */ + "Reserved 0x57", /* 0x57 */ + "Reserved 0x58", /* 0x58 */ + "Reserved 0x59", /* 0x59 */ + "Reserved 0x5a", /* 0x5a */ + "Reserved 0x5b", /* 0x5b */ + "Reserved 0x5c", /* 0x5c */ + "Reserved 0x5d", /* 0x5d */ + "Reserved 0x5e", /* 0x5e */ + "Reserved 0x5f", /* 0x5f */ + "Reserved 0x60", /* 0x60 */ + "Reserved 0x61", /* 0x61 */ + "Reserved 0x62", /* 0x62 */ + "Reserved 0x63", /* 0x63 */ + "Reserved 0x64", /* 0x64 */ + "Reserved 0x65", /* 0x65 */ + "Reserved 0x66", /* 0x66 */ + "Reserved 0x67", /* 0x67 */ + "Reserved 0x68", /* 0x68 */ + "Reserved 0x69", /* 0x69 */ + "Reserved 0x6a", /* 0x6a */ + "Reserved 0x6b", /* 0x6b */ + "Reserved 0x6c", /* 0x6c */ + "Reserved 0x6d", /* 0x6d */ + "Reserved 0x6e", /* 0x6e */ + "Reserved 0x6f", /* 0x6f */ + "Reserved 0x70", /* 0x70 */ + "Reserved 0x71", /* 0x71 */ + "Reserved 0x72", /* 0x72 */ + "Reserved 0x73", /* 0x73 */ + "Reserved 0x74", /* 0x74 */ + "Reserved 0x75", /* 0x75 */ + "Reserved 0x76", /* 0x76 */ + "Reserved 0x77", /* 0x77 */ + "Reserved 0x78", /* 0x78 */ + "Reserved 0x79", /* 0x79 */ + "Reserved 0x7a", /* 0x7a */ + "Reserved 0x7b", /* 0x7b */ + "Reserved 0x7c", /* 0x7c */ + "Reserved 0x7d", /* 0x7d */ + "Header Termination 1 IE", /* 0x7e */ + "Header Termination 2 IE" /* 0x7f */ +}; + +/* Payload IE Group IDs from Table 7-15 of 802.15.4-2015 */ +static const char *p_ie_names[] = { + "ESDU IE", /* 0x00 */ + "MLME IE", /* 0x01 */ + "Vendor Specific Nested IE", /* 0x02 */ + "Multiplexed IE (802.15.9)", /* 0x03 */ + "Omnibus Payload Group IE", /* 0x04 */ + "IETF IE", /* 0x05 */ + "Reserved 0x06", /* 0x06 */ + "Reserved 0x07", /* 0x07 */ + "Reserved 0x08", /* 0x08 */ + "Reserved 0x09", /* 0x09 */ + "Reserved 0x0a", /* 0x0a */ + "Reserved 0x0b", /* 0x0b */ + "Reserved 0x0c", /* 0x0c */ + "Reserved 0x0d", /* 0x0d */ + "Reserved 0x0e", /* 0x0e */ + "List termination" /* 0x0f */ +}; + +/* Sub-ID for short format from Table 7-16 of 802.15.4-2015 */ +static const char *p_mlme_short_names[] = { + "Reserved for long format 0x0", /* 0x00 */ + "Reserved for long format 0x1", /* 0x01 */ + "Reserved for long format 0x2", /* 0x02 */ + "Reserved for long format 0x3", /* 0x03 */ + "Reserved for long format 0x4", /* 0x04 */ + "Reserved for long format 0x5", /* 0x05 */ + "Reserved for long format 0x6", /* 0x06 */ + "Reserved for long format 0x7", /* 0x07 */ + "Reserved for long format 0x8", /* 0x08 */ + "Reserved for long format 0x9", /* 0x09 */ + "Reserved for long format 0xa", /* 0x0a */ + "Reserved for long format 0xb", /* 0x0b */ + "Reserved for long format 0xc", /* 0x0c */ + "Reserved for long format 0xd", /* 0x0d */ + "Reserved for long format 0xe", /* 0x0e */ + "Reserved for long format 0xf", /* 0x0f */ + "Reserved 0x10", /* 0x10 */ + "Reserved 0x11", /* 0x11 */ + "Reserved 0x12", /* 0x12 */ + "Reserved 0x13", /* 0x13 */ + "Reserved 0x14", /* 0x14 */ + "Reserved 0x15", /* 0x15 */ + "Reserved 0x16", /* 0x16 */ + "Reserved 0x17", /* 0x17 */ + "Reserved 0x18", /* 0x18 */ + "Reserved 0x19", /* 0x19 */ + "TSCH Synchronization IE", /* 0x1a */ + "TSCH Slotframe and Link IE", /* 0x1b */ + "TSCH Timeslot IE", /* 0x1c */ + "Hopping timing IE", /* 0x1d */ + "Enhanced Beacon Filter IE", /* 0x1e */ + "MAC Metrics IE", /* 0x1f */ + "All MAC Metrics IE", /* 0x20 */ + "Coexistence Specification IE", /* 0x21 */ + "SUN Device Capabilities IE", /* 0x22 */ + "SUN FSK Generic PHY IE", /* 0x23 */ + "Mode Switch Parameter IE", /* 0x24 */ + "PHY Parameter Change IE", /* 0x25 */ + "O-QPSK PHY Mode IE", /* 0x26 */ + "PCA Allocation IE", /* 0x27 */ + "LECIM DSSS Operating Mode IE", /* 0x28 */ + "LECIM FSK Operating Mode IE", /* 0x29 */ + "Reserved 0x2a", /* 0x2a */ + "TVWS PHY Operating Mode Description IE", /* 0x2b */ + "TVWS Device Capabilities IE", /* 0x2c */ + "TVWS Device Category IE", /* 0x2d */ + "TVWS Device Identiication IE", /* 0x2e */ + "TVWS Device Location IE", /* 0x2f */ + "TVWS Channel Information Query IE", /* 0x30 */ + "TVWS Channel Information Source IE", /* 0x31 */ + "CTM IE", /* 0x32 */ + "Timestamp IE", /* 0x33 */ + "Timestamp Difference IE", /* 0x34 */ + "TMCTP Specification IE", /* 0x35 */ + "RCC PHY Operating Mode IE", /* 0x36 */ + "Reserved 0x37", /* 0x37 */ + "Reserved 0x38", /* 0x38 */ + "Reserved 0x39", /* 0x39 */ + "Reserved 0x3a", /* 0x3a */ + "Reserved 0x3b", /* 0x3b */ + "Reserved 0x3c", /* 0x3c */ + "Reserved 0x3d", /* 0x3d */ + "Reserved 0x3e", /* 0x3e */ + "Reserved 0x3f", /* 0x3f */ + "Reserved 0x40", /* 0x40 */ + "Reserved 0x41", /* 0x41 */ + "Reserved 0x42", /* 0x42 */ + "Reserved 0x43", /* 0x43 */ + "Reserved 0x44", /* 0x44 */ + "Reserved 0x45", /* 0x45 */ + "Reserved 0x46", /* 0x46 */ + "Reserved 0x47", /* 0x47 */ + "Reserved 0x48", /* 0x48 */ + "Reserved 0x49", /* 0x49 */ + "Reserved 0x4a", /* 0x4a */ + "Reserved 0x4b", /* 0x4b */ + "Reserved 0x4c", /* 0x4c */ + "Reserved 0x4d", /* 0x4d */ + "Reserved 0x4e", /* 0x4e */ + "Reserved 0x4f", /* 0x4f */ + "Reserved 0x50", /* 0x50 */ + "Reserved 0x51", /* 0x51 */ + "Reserved 0x52", /* 0x52 */ + "Reserved 0x53", /* 0x53 */ + "Reserved 0x54", /* 0x54 */ + "Reserved 0x55", /* 0x55 */ + "Reserved 0x56", /* 0x56 */ + "Reserved 0x57", /* 0x57 */ + "Reserved 0x58", /* 0x58 */ + "Reserved 0x59", /* 0x59 */ + "Reserved 0x5a", /* 0x5a */ + "Reserved 0x5b", /* 0x5b */ + "Reserved 0x5c", /* 0x5c */ + "Reserved 0x5d", /* 0x5d */ + "Reserved 0x5e", /* 0x5e */ + "Reserved 0x5f", /* 0x5f */ + "Reserved 0x60", /* 0x60 */ + "Reserved 0x61", /* 0x61 */ + "Reserved 0x62", /* 0x62 */ + "Reserved 0x63", /* 0x63 */ + "Reserved 0x64", /* 0x64 */ + "Reserved 0x65", /* 0x65 */ + "Reserved 0x66", /* 0x66 */ + "Reserved 0x67", /* 0x67 */ + "Reserved 0x68", /* 0x68 */ + "Reserved 0x69", /* 0x69 */ + "Reserved 0x6a", /* 0x6a */ + "Reserved 0x6b", /* 0x6b */ + "Reserved 0x6c", /* 0x6c */ + "Reserved 0x6d", /* 0x6d */ + "Reserved 0x6e", /* 0x6e */ + "Reserved 0x6f", /* 0x6f */ + "Reserved 0x70", /* 0x70 */ + "Reserved 0x71", /* 0x71 */ + "Reserved 0x72", /* 0x72 */ + "Reserved 0x73", /* 0x73 */ + "Reserved 0x74", /* 0x74 */ + "Reserved 0x75", /* 0x75 */ + "Reserved 0x76", /* 0x76 */ + "Reserved 0x77", /* 0x77 */ + "Reserved 0x78", /* 0x78 */ + "Reserved 0x79", /* 0x79 */ + "Reserved 0x7a", /* 0x7a */ + "Reserved 0x7b", /* 0x7b */ + "Reserved 0x7c", /* 0x7c */ + "Reserved 0x7d", /* 0x7d */ + "Reserved 0x7e", /* 0x7e */ + "Reserved 0x7f" /* 0x7f */ +}; + +/* Sub-ID for long format from Table 7-17 of 802.15.4-2015 */ +static const char *p_mlme_long_names[] = { + "Reserved 0x00", /* 0x00 */ + "Reserved 0x01", /* 0x01 */ + "Reserved 0x02", /* 0x02 */ + "Reserved 0x03", /* 0x03 */ + "Reserved 0x04", /* 0x04 */ + "Reserved 0x05", /* 0x05 */ + "Reserved 0x06", /* 0x06 */ + "Reserved 0x07", /* 0x07 */ + "Vendor Specific MLME Nested IE", /* 0x08 */ + "Channel Hopping IE", /* 0x09 */ + "Reserved 0x0a", /* 0x0a */ + "Reserved 0x0b", /* 0x0b */ + "Reserved 0x0c", /* 0x0c */ + "Reserved 0x0d", /* 0x0d */ + "Reserved 0x0e", /* 0x0e */ + "Reserved 0x0f" /* 0x0f */ +}; + +/* MAC commands from Table 7-49 of 802.15.4-2015 */ +static const char *mac_c_names[] = { + "Reserved 0x00", /* 0x00 */ + "Association Request command", /* 0x01 */ + "Association Response command", /* 0x02 */ + "Disassociation Notification command", /* 0x03 */ + "Data Request command", /* 0x04 */ + "PAN ID Conflict Notification command", /* 0x05 */ + "Orphan Notification command", /* 0x06 */ + "Beacon Request command", /* 0x07 */ + "Coordinator realignment command", /* 0x08 */ + "GTS request command", /* 0x09 */ + "TRLE Management Request command", /* 0x0a */ + "TRLE Management Response command", /* 0x0b */ + "Reserved 0x0c", /* 0x0c */ + "Reserved 0x0d", /* 0x0d */ + "Reserved 0x0e", /* 0x0e */ + "Reserved 0x0f", /* 0x0f */ + "Reserved 0x10", /* 0x10 */ + "Reserved 0x11", /* 0x11 */ + "Reserved 0x12", /* 0x12 */ + "DSME Association Request command", /* 0x13 */ + "DSME Association Response command", /* 0x14 */ + "DSME GTS Request command", /* 0x15 */ + "DSME GTS Response command", /* 0x16 */ + "DSME GTS Notify command", /* 0x17 */ + "DSME Information Request command", /* 0x18 */ + "DSME Information Response command", /* 0x19 */ + "DSME Beacon Allocation Notification command", /* 0x1a */ + "DSME Beacon Collision Notification command", /* 0x1b */ + "DSME Link Report command", /* 0x1c */ + "Reserved 0x1d", /* 0x1d */ + "Reserved 0x1e", /* 0x1e */ + "Reserved 0x1f", /* 0x1f */ + "RIT Data Request command", /* 0x20 */ + "DBS Request command", /* 0x21 */ + "DBS Response command", /* 0x22 */ + "RIT Data Response command", /* 0x23 */ + "Vendor Specific command", /* 0x24 */ + "Reserved 0x25", /* 0x25 */ + "Reserved 0x26", /* 0x26 */ + "Reserved 0x27", /* 0x27 */ + "Reserved 0x28", /* 0x28 */ + "Reserved 0x29", /* 0x29 */ + "Reserved 0x2a", /* 0x2a */ + "Reserved 0x2b", /* 0x2b */ + "Reserved 0x2c", /* 0x2c */ + "Reserved 0x2d", /* 0x2d */ + "Reserved 0x2e", /* 0x2e */ + "Reserved 0x2f" /* 0x2f */ }; /* * Frame Control subfields. */ -#define FC_FRAME_TYPE(fc) ((fc) & 0x7) -#define FC_SECURITY_ENABLED 0x0008 -#define FC_FRAME_PENDING 0x0010 -#define FC_ACK_REQUEST 0x0020 -#define FC_PAN_ID_COMPRESSION 0x0040 -#define FC_DEST_ADDRESSING_MODE(fc) (((fc) >> 10) & 0x3) -#define FC_FRAME_VERSION(fc) (((fc) >> 12) & 0x3) -#define FC_SRC_ADDRESSING_MODE(fc) (((fc) >> 14) & 0x3) +#define FC_FRAME_TYPE(fc) ((fc) & 0x7) +#define FC_FRAME_VERSION(fc) (((fc) >> 12) & 0x3) -#define FC_ADDRESSING_MODE_NONE 0x00 -#define FC_ADDRESSING_MODE_RESERVED 0x01 -#define FC_ADDRESSING_MODE_SHORT 0x02 -#define FC_ADDRESSING_MODE_LONG 0x03 +#define FC_ADDRESSING_MODE_NONE 0x00 +#define FC_ADDRESSING_MODE_RESERVED 0x01 +#define FC_ADDRESSING_MODE_SHORT 0x02 +#define FC_ADDRESSING_MODE_LONG 0x03 -u_int -ieee802_15_4_if_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, const u_char *p) +/* + * IEEE 802.15.4 CRC 16 function. This is using CCITT polynomical of 0x1021, + * but the initial value is 0, and the bits are reversed for both in and out. + * See secton 7.2.10 of 802.15.4-2015 for more information. + */ +static uint16_t +ieee802_15_4_crc16(netdissect_options *ndo, const u_char *p, + u_int data_len) { - u_int caplen = h->caplen; - u_int hdrlen; - uint16_t fc; - uint8_t seq; - uint16_t panid = 0; + uint16_t crc; + u_char x, y; - if (caplen < 3) { - ND_PRINT((ndo, "[|802.15.4]")); - return caplen; + crc = 0x0000; /* Note, initial value is 0x0000 not 0xffff. */ + + while (data_len != 0){ + y = GET_U_1(p); + p++; + /* Reverse bits on input */ + y = (((y & 0xaa) >> 1) | ((y & 0x55) << 1)); + y = (((y & 0xcc) >> 2) | ((y & 0x33) << 2)); + y = (((y & 0xf0) >> 4) | ((y & 0x0f) << 4)); + /* Update CRC */ + x = crc >> 8 ^ y; + x ^= x >> 4; + crc = ((uint16_t)(crc << 8)) ^ + ((uint16_t)(x << 12)) ^ + ((uint16_t)(x << 5)) ^ + ((uint16_t)x); + data_len--; } - hdrlen = 3; + /* Reverse bits on output */ + crc = (((crc & 0xaaaa) >> 1) | ((crc & 0x5555) << 1)); + crc = (((crc & 0xcccc) >> 2) | ((crc & 0x3333) << 2)); + crc = (((crc & 0xf0f0) >> 4) | ((crc & 0x0f0f) << 4)); + crc = (((crc & 0xff00) >> 8) | ((crc & 0x00ff) << 8)); + return crc; +} - fc = EXTRACT_LE_16BITS(p); - seq = EXTRACT_LE_8BITS(p + 2); +/* + * Reverses the bits of the 32-bit word. + */ +static uint32_t +ieee802_15_4_reverse32(uint32_t x) +{ + x = ((x & 0x55555555) << 1) | ((x >> 1) & 0x55555555); + x = ((x & 0x33333333) << 2) | ((x >> 2) & 0x33333333); + x = ((x & 0x0F0F0F0F) << 4) | ((x >> 4) & 0x0F0F0F0F); + x = (x << 24) | ((x & 0xFF00) << 8) | + ((x >> 8) & 0xFF00) | (x >> 24); + return x; +} - p += 3; - caplen -= 3; +/* + * IEEE 802.15.4 CRC 32 function. This is using ANSI X3.66-1979 polynomical of + * 0x04C11DB7, but the initial value is 0, and the bits are reversed for both + * in and out. See secton 7.2.10 of 802.15.4-2015 for more information. + */ +static uint32_t +ieee802_15_4_crc32(netdissect_options *ndo, const u_char *p, + u_int data_len) +{ + uint32_t crc, byte; + int b; - ND_PRINT((ndo,"IEEE 802.15.4 %s packet ", ftypes[FC_FRAME_TYPE(fc)])); - if (ndo->ndo_vflag) - ND_PRINT((ndo,"seq %02x ", seq)); + crc = 0x00000000; /* Note, initial value is 0x00000000 not 0xffffffff */ - /* - * Destination address and PAN ID, if present. - */ - switch (FC_DEST_ADDRESSING_MODE(fc)) { - case FC_ADDRESSING_MODE_NONE: - if (fc & FC_PAN_ID_COMPRESSION) { - /* - * PAN ID compression; this requires that both - * the source and destination addresses be present, - * but the destination address is missing. - */ - ND_PRINT((ndo, "[|802.15.4]")); - return hdrlen; + while (data_len != 0){ + byte = GET_U_1(p); + p++; + /* Reverse bits on input */ + byte = ieee802_15_4_reverse32(byte); + /* Update CRC */ + for(b = 0; b <= 7; b++) { + if ((int) (crc ^ byte) < 0) + crc = (crc << 1) ^ 0x04C11DB7; + else + crc = crc << 1; + byte = byte << 1; } - if (ndo->ndo_vflag) - ND_PRINT((ndo,"none ")); + data_len--; + } + /* Reverse bits on output */ + crc = ieee802_15_4_reverse32(crc); + return crc; +} + +/* + * Find out the address length based on the address type. See table 7-3 of + * 802.15.4-2015. Returns the address length. + */ +static int +ieee802_15_4_addr_len(uint16_t addr_type) +{ + switch (addr_type) { + case FC_ADDRESSING_MODE_NONE: /* None. */ + return 0; break; - case FC_ADDRESSING_MODE_RESERVED: - if (ndo->ndo_vflag) - ND_PRINT((ndo,"reserved destination addressing mode")); - return hdrlen; - case FC_ADDRESSING_MODE_SHORT: + case FC_ADDRESSING_MODE_RESERVED: /* Reserved, there used to be 8-bit + * address type in one amendment, but + * that and the feature using it was + * removed during 802.15.4-2015 + * maintenance process. */ + return -1; + break; + case FC_ADDRESSING_MODE_SHORT: /* Short. */ + return 2; + break; + case FC_ADDRESSING_MODE_LONG: /* Extended. */ + return 8; + break; + } + return 0; +} + +/* + * Print out the ieee 802.15.4 address. + */ +static void +ieee802_15_4_print_addr(netdissect_options *ndo, const u_char *p, + int dst_addr_len) +{ + switch (dst_addr_len) { + case 0: + ND_PRINT("none"); + break; + case 2: + ND_PRINT("%04x", GET_LE_U_2(p)); + break; + case 8: + ND_PRINT("%s", GET_LE64ADDR_STRING(p)); + break; + } +} + +/* + * Beacon frame superframe specification structure. Used in the old Beacon + * frames, and in the DSME PAN Descriptor IE. See section 7.3.1.3 of the + * 802.15.4-2015. + */ +static void +ieee802_15_4_print_superframe_specification(netdissect_options *ndo, + uint16_t ss) +{ + if (ndo->ndo_vflag < 1) { + return; + } + ND_PRINT("\n\tBeacon order = %d, Superframe order = %d, ", + (ss & 0xf), ((ss >> 4) & 0xf)); + ND_PRINT("Final CAP Slot = %d", + ((ss >> 8) & 0xf)); + if (CHECK_BIT(ss, 12)) { ND_PRINT(", BLE enabled"); } + if (CHECK_BIT(ss, 14)) { ND_PRINT(", PAN Coordinator"); } + if (CHECK_BIT(ss, 15)) { ND_PRINT(", Association Permit"); } +} + +/* + * Beacon frame gts info structure. Used in the old Beacon frames, and + * in the DSME PAN Descriptor IE. See section 7.3.1.4 of 802.15.4-2015. + * + * Returns number of byts consumed from the packet or -1 in case of error. + */ +static int +ieee802_15_4_print_gts_info(netdissect_options *ndo, + const u_char *p, + u_int data_len) +{ + uint8_t gts_spec, gts_cnt; + u_int len; + int i; + + gts_spec = GET_U_1(p); + gts_cnt = gts_spec & 0x7; + + if (gts_cnt == 0) { + if (ndo->ndo_vflag > 0) { + ND_PRINT("\n\tGTS Descriptor Count = %d, ", gts_cnt); + } + return 1; + } + len = 1 + 1 + gts_cnt * 3; + + if (data_len < len) { + ND_PRINT(" [ERROR: Truncated GTS Info List]"); + return -1; + } + if (ndo->ndo_vflag < 2) { + return len; + } + ND_PRINT("GTS Descriptor Count = %d, ", gts_cnt); + ND_PRINT("GTS Directions Mask = %02x, [ ", + GET_U_1(p + 1) & 0x7f); + + for(i = 0; i < gts_cnt; i++) { + ND_PRINT("[ "); + ieee802_15_4_print_addr(ndo, p + 2 + i * 3, 2); + ND_PRINT(", Start slot = %d, Length = %d ] ", + GET_U_1(p + 2 + i * 3 + 1) & 0x0f, + (GET_U_1(p + 2 + i * 3 + 1) >> 4) & 0x0f); + } + ND_PRINT("]"); + return len; +} + +/* + * Beacon frame pending address structure. Used in the old Beacon frames, and + * in the DSME PAN Descriptor IE. See section 7.3.1.5 of 802.15.4-2015. + * + * Returns number of byts consumed from the packet or -1 in case of error. + */ +static int16_t +ieee802_15_4_print_pending_addresses(netdissect_options *ndo, + const u_char *p, + u_int data_len) +{ + uint8_t pas, s_cnt, e_cnt, len, i; + + pas = GET_U_1(p); + s_cnt = pas & 0x7; + e_cnt = (pas >> 4) & 0x7; + len = 1 + s_cnt * 2 + e_cnt * 8; + if (ndo->ndo_vflag > 0) { + ND_PRINT("\n\tPending address list, " + "# short addresses = %d, # extended addresses = %d", + s_cnt, e_cnt); + } + if (data_len < len) { + ND_PRINT(" [ERROR: Pending address list truncated]"); + return -1; + } + if (ndo->ndo_vflag < 2) { + return len; + } + if (s_cnt != 0) { + ND_PRINT(", Short address list = [ "); + for(i = 0; i < s_cnt; i++) { + ieee802_15_4_print_addr(ndo, p + 1 + i * 2, 2); + ND_PRINT(" "); + } + ND_PRINT("]"); + } + if (e_cnt != 0) { + ND_PRINT(", Extended address list = [ "); + for(i = 0; i < e_cnt; i++) { + ieee802_15_4_print_addr(ndo, p + 1 + s_cnt * 2 + + i * 8, 8); + ND_PRINT(" "); + } + ND_PRINT("]"); + } + return len; +} + +/* + * Print header ie content. + */ +static void +ieee802_15_4_print_header_ie(netdissect_options *ndo, + const u_char *p, + uint16_t ie_len, + int element_id) +{ + int i; + + switch (element_id) { + case 0x00: /* Vendor Specific Header IE */ + if (ie_len < 3) { + ND_PRINT("[ERROR: Vendor OUI missing]"); + } else { + ND_PRINT("OUI = 0x%02x%02x%02x, ", GET_U_1(p), + GET_U_1(p + 1), GET_U_1(p + 2)); + ND_PRINT("Data = "); + for(i = 3; i < ie_len; i++) { + ND_PRINT("%02x ", GET_U_1(p + i)); + } + } + break; + case 0x1a: /* LE CSL IE */ + if (ie_len < 4) { + ND_PRINT("[ERROR: Truncated CSL IE]"); + } else { + ND_PRINT("CSL Phase = %d, CSL Period = %d", + GET_LE_U_2(p), GET_LE_U_2(p + 2)); + if (ie_len >= 6) { + ND_PRINT(", Rendezvous time = %d", + GET_LE_U_2(p + 4)); + } + if (ie_len != 4 && ie_len != 6) { + ND_PRINT(" [ERROR: CSL IE length wrong]"); + } + } + break; + case 0x1b: /* LE RIT IE */ + if (ie_len < 4) { + ND_PRINT("[ERROR: Truncated RIT IE]"); + } else { + ND_PRINT("Time to First Listen = %d, # of Repeat Listen = %d, Repeat Listen Interval = %d", + GET_U_1(p), + GET_U_1(p + 1), + GET_LE_U_2(p + 2)); + } + break; + case 0x1c: /* DSME PAN Descriptor IE */ + /*FALLTHROUGH*/ + case 0x21: /* Extended DSME PAN descriptor IE */ + if (ie_len < 2) { + ND_PRINT("[ERROR: Truncated DSME PAN IE]"); + } else { + uint16_t ss, ptr, ulen; + int16_t len; + int hopping_present; + + hopping_present = 0; + + ss = GET_LE_U_2(p); + ieee802_15_4_print_superframe_specification(ndo, ss); + if (ie_len < 3) { + ND_PRINT("[ERROR: Truncated before pending addresses field]"); + break; + } + ptr = 2; + len = ieee802_15_4_print_pending_addresses(ndo, + p + ptr, + ie_len - + ptr); + if (len < 0) { + break; + } + ptr += len; + + if (element_id == 0x21) { + /* Extended version. */ + if (ie_len < ptr + 2) { + ND_PRINT("[ERROR: Truncated before DSME Superframe Specification]"); + break; + } + ss = GET_LE_U_2(p + ptr); + ptr += 2; + ND_PRINT("Multi-superframe Order = %d", ss & 0xff); + ND_PRINT(", %s", ((ss & 0x100) ? + "Channel hopping mode" : + "Channel adaptation mode")); + if (ss & 0x400) { + ND_PRINT(", CAP reduction enabled"); + } + if (ss & 0x800) { + ND_PRINT(", Deferred beacon enabled"); + } + if (ss & 0x1000) { + ND_PRINT(", Hopping Sequence Present"); + hopping_present = 1; + } + } else { + if (ie_len < ptr + 1) { + ND_PRINT("[ERROR: Truncated before DSME Superframe Specification]"); + break; + } + ss = GET_U_1(p + ptr); + ptr++; + ND_PRINT("Multi-superframe Order = %d", + ss & 0x0f); + ND_PRINT(", %s", ((ss & 0x10) ? + "Channel hopping mode" : + "Channel adaptation mode")); + if (ss & 0x40) { + ND_PRINT(", CAP reduction enabled"); + } + if (ss & 0x80) { + ND_PRINT(", Deferred beacon enabled"); + } + } + if (ie_len < ptr + 8) { + ND_PRINT(" [ERROR: Truncated before Time synchronization specification]"); + break; + } + ND_PRINT("Beacon timestamp = %" PRIu64 ", offset = %d", + GET_LE_U_6(p + ptr), + GET_LE_U_2(p + ptr + 6)); + ptr += 8; + if (ie_len < ptr + 4) { + ND_PRINT(" [ERROR: Truncated before Beacon Bitmap]"); + break; + } + + ulen = GET_LE_U_2(p + ptr + 2); + ND_PRINT("SD Index = %d, Bitmap len = %d, ", + GET_LE_U_2(p + ptr), ulen); + ptr += 4; + if (ie_len < ptr + ulen) { + ND_PRINT(" [ERROR: Truncated in SD bitmap]"); + break; + } + ND_PRINT(" SD Bitmap = "); + for(i = 0; i < ulen; i++) { + ND_PRINT("%02x ", GET_U_1(p + ptr + i)); + } + ptr += ulen; + + if (ie_len < ptr + 5) { + ND_PRINT(" [ERROR: Truncated before Channel hopping specification]"); + break; + } + + ulen = GET_LE_U_2(p + ptr + 4); + ND_PRINT("Hopping Seq ID = %d, PAN Coordinator BSN = %d, " + "Channel offset = %d, Bitmap length = %d, ", + GET_U_1(p + ptr), + GET_U_1(p + ptr + 1), + GET_LE_U_2(p + ptr + 2), + ulen); + ptr += 5; + if (ie_len < ptr + ulen) { + ND_PRINT(" [ERROR: Truncated in Channel offset bitmap]"); + break; + } + ND_PRINT(" Channel offset bitmap = "); + for(i = 0; i < ulen; i++) { + ND_PRINT("%02x ", GET_U_1(p + ptr + i)); + } + ptr += ulen; + if (hopping_present) { + if (ie_len < ptr + 1) { + ND_PRINT(" [ERROR: Truncated in Hopping Sequence length]"); + break; + } + ulen = GET_U_1(p + ptr); + ptr++; + ND_PRINT("Hopping Seq length = %d [ ", ulen); + + /* The specification is not clear how the + hopping sequence is encoded, I assume two + octet unsigned integers for each channel. */ + + if (ie_len < ptr + ulen * 2) { + ND_PRINT(" [ERROR: Truncated in Channel offset bitmap]"); + break; + } + for(i = 0; i < ulen; i++) { + ND_PRINT("%02x ", + GET_LE_U_2(p + ptr + i * 2)); + } + ND_PRINT("]"); + ptr += ulen * 2; + } + } + break; + case 0x1d: /* Rendezvous Tome IE */ + if (ie_len != 4) { + ND_PRINT("[ERROR: Length != 2]"); + } else { + uint16_t r_time, w_u_interval; + r_time = GET_LE_U_2(p); + w_u_interval = GET_LE_U_2(p + 2); + + ND_PRINT("Rendezvous time = %d, Wake-up Interval = %d", + r_time, w_u_interval); + } + break; + case 0x1e: /* Time correction IE */ + if (ie_len != 2) { + ND_PRINT("[ERROR: Length != 2]"); + } else { + uint16_t val; + int16_t timecorr; + + val = GET_LE_U_2(p); + if (val & 0x8000) { ND_PRINT("Negative "); } + val &= 0xfff; + val <<= 4; + timecorr = val; + timecorr >>= 4; + + ND_PRINT("Ack time correction = %d, ", timecorr); + } + break; + case 0x22: /* Frament Sequence Content Description IE */ + /* XXX Not implemented */ + case 0x23: /* Simplified Superframe Specification IE */ + /* XXX Not implemented */ + case 0x24: /* Simplified GTS Specification IE */ + /* XXX Not implemented */ + case 0x25: /* LECIM Capabilities IE */ + /* XXX Not implemented */ + case 0x26: /* TRLE Descriptor IE */ + /* XXX Not implemented */ + case 0x27: /* RCC Capabilities IE */ + /* XXX Not implemented */ + case 0x28: /* RCCN Descriptor IE */ + /* XXX Not implemented */ + case 0x29: /* Global Time IE */ + /* XXX Not implemented */ + case 0x2b: /* DA IE */ + /* XXX Not implemented */ + default: + ND_PRINT("IE Data = "); + for(i = 0; i < ie_len; i++) { + ND_PRINT("%02x ", GET_U_1(p + i)); + } + break; + } +} + +/* + * Parse and print Header IE list. See 7.4.2 of 802.15.4-2015 for + * more information. + * + * Returns number of byts consumed from the packet or -1 in case of error. + */ +static int +ieee802_15_4_print_header_ie_list(netdissect_options *ndo, + const u_char *p, + u_int caplen, + int *payload_ie_present) +{ + int len, ie, element_id, i; + uint16_t ie_len; + + *payload_ie_present = 0; + len = 0; + do { if (caplen < 2) { - ND_PRINT((ndo, "[|802.15.4]")); - return hdrlen; + ND_PRINT("[ERROR: Truncated header IE]"); + return -1; + } + /* Extract IE Header */ + ie = GET_LE_U_2(p); + if (CHECK_BIT(ie, 15)) { + ND_PRINT("[ERROR: Header IE with type 1] "); + } + /* Get length and Element ID */ + ie_len = ie & 0x7f; + element_id = (ie >> 7) & 0xff; + if (element_id > 127) { + ND_PRINT("Reserved Element ID %02x, length = %d ", + element_id, ie_len); + } else { + if (ie_len == 0) { + ND_PRINT("\n\t%s [", h_ie_names[element_id]); + } else { + ND_PRINT("\n\t%s [ length = %d, ", + h_ie_names[element_id], ie_len); + } + } + if (caplen < ie_len) { + ND_PRINT("[ERROR: Truncated IE data]"); + return -1; } - panid = EXTRACT_LE_16BITS(p); + /* Skip header */ p += 2; - caplen -= 2; - hdrlen += 2; - if (caplen < 2) { - ND_PRINT((ndo, "[|802.15.4]")); - return hdrlen; + + /* Parse and print content. */ + if (ndo->ndo_vflag > 3 && ie_len != 0) { + ieee802_15_4_print_header_ie(ndo, p, + ie_len, element_id); + } else { + if (ie_len != 0) { + ND_PRINT("IE Data = "); + for(i = 0; i < ie_len; i++) { + ND_PRINT("%02x ", GET_U_1(p + i)); + } + } } - if (ndo->ndo_vflag) - ND_PRINT((ndo,"%04x:%04x ", panid, EXTRACT_LE_16BITS(p))); + ND_PRINT("] "); + len += 2 + ie_len; + p += ie_len; + caplen -= 2 + ie_len; + if (element_id == 0x7e) { + *payload_ie_present = 1; + break; + } + if (element_id == 0x7f) { + break; + } + } while (caplen > 0); + return len; +} + +/* + * Print MLME ie content. + */ +static void +ieee802_15_4_print_mlme_ie(netdissect_options *ndo, + const u_char *p, + uint16_t sub_ie_len, + int sub_id) +{ + int i, j; + uint16_t len; + + /* Note, as there is no overlap with the long and short + MLME sub IDs, we can just use one switch here. */ + switch (sub_id) { + case 0x08: /* Vendor Specific Nested IE */ + if (sub_ie_len < 3) { + ND_PRINT("[ERROR: Vendor OUI missing]"); + } else { + ND_PRINT("OUI = 0x%02x%02x%02x, ", + GET_U_1(p), + GET_U_1(p + 1), + GET_U_1(p + 2)); + ND_PRINT("Data = "); + for(i = 3; i < sub_ie_len; i++) { + ND_PRINT("%02x ", GET_U_1(p + i)); + } + } + break; + case 0x09: /* Channel Hopping IE */ + if (sub_ie_len < 1) { + ND_PRINT("[ERROR: Hopping sequence ID missing]"); + } else if (sub_ie_len == 1) { + ND_PRINT("Hopping Sequence ID = %d", GET_U_1(p)); + p++; + sub_ie_len--; + } else { + uint16_t channel_page, number_of_channels; + + ND_PRINT("Hopping Sequence ID = %d", GET_U_1(p)); + p++; + sub_ie_len--; + if (sub_ie_len < 7) { + ND_PRINT("[ERROR: IE truncated]"); + break; + } + channel_page = GET_U_1(p); + number_of_channels = GET_LE_U_2(p + 1); + ND_PRINT("Channel Page = %d, Number of Channels = %d, ", + channel_page, number_of_channels); + ND_PRINT("Phy Configuration = 0x%08x, ", + GET_LE_U_4(p + 3)); + p += 7; + sub_ie_len -= 7; + if (channel_page == 9 || channel_page == 10) { + len = (number_of_channels + 7) / 8; + if (sub_ie_len < len) { + ND_PRINT("[ERROR: IE truncated]"); + break; + } + ND_PRINT("Extended bitmap = 0x"); + for(i = 0; i < len; i++) { + ND_PRINT("%02x", GET_U_1(p + i)); + } + ND_PRINT(", "); + p += len; + sub_ie_len -= len; + } + if (sub_ie_len < 2) { + ND_PRINT("[ERROR: IE truncated]"); + break; + } + len = GET_LE_U_2(p); + p += 2; + sub_ie_len -= 2; + ND_PRINT("Hopping Seq length = %d [ ", len); + + if (sub_ie_len < len * 2) { + ND_PRINT(" [ERROR: IE truncated]"); + break; + } + for(i = 0; i < len; i++) { + ND_PRINT("%02x ", GET_LE_U_2(p + i * 2)); + } + ND_PRINT("]"); + p += len * 2; + sub_ie_len -= len * 2; + if (sub_ie_len < 2) { + ND_PRINT("[ERROR: IE truncated]"); + break; + } + ND_PRINT("Current hop = %d", GET_LE_U_2(p)); + } + + break; + case 0x1a: /* TSCH Synchronization IE. */ + if (sub_ie_len < 6) { + ND_PRINT("[ERROR: Length != 6]"); + } + ND_PRINT("ASN = %010" PRIx64 ", Join Metric = %d ", + GET_LE_U_5(p), GET_U_1(p + 5)); + break; + case 0x1b: /* TSCH Slotframe and Link IE. */ + { + int sf_num, off, links, opts; + + if (sub_ie_len < 1) { + ND_PRINT("[ERROR: Truncated IE]"); + break; + } + sf_num = GET_U_1(p); + ND_PRINT("Slotframes = %d ", sf_num); + off = 1; + for(i = 0; i < sf_num; i++) { + if (sub_ie_len < off + 4) { + ND_PRINT("[ERROR: Truncated IE before slotframes]"); + break; + } + links = GET_U_1(p + off + 3); + ND_PRINT("\n\t\t\t[ Handle %d, size = %d, links = %d ", + GET_U_1(p + off), + GET_LE_U_2(p + off + 1), + links); + off += 4; + for(j = 0; j < links; j++) { + if (sub_ie_len < off + 5) { + ND_PRINT("[ERROR: Truncated IE links]"); + break; + } + opts = GET_U_1(p + off + 4); + ND_PRINT("\n\t\t\t\t[ Timeslot = %d, Offset = %d, Options = ", + GET_LE_U_2(p + off), + GET_LE_U_2(p + off + 2)); + if (opts & 0x1) { ND_PRINT("TX "); } + if (opts & 0x2) { ND_PRINT("RX "); } + if (opts & 0x4) { ND_PRINT("Shared "); } + if (opts & 0x8) { + ND_PRINT("Timekeeping "); + } + if (opts & 0x10) { + ND_PRINT("Priority "); + } + off += 5; + ND_PRINT("] "); + } + ND_PRINT("] "); + } + } + break; + case 0x1c: /* TSCH Timeslot IE. */ + if (sub_ie_len == 1) { + ND_PRINT("Time slot ID = %d ", GET_U_1(p)); + } else if (sub_ie_len == 25) { + ND_PRINT("Time slot ID = %d, CCA Offset = %d, CCA = %d, TX Offset = %d, RX Offset = %d, RX Ack Delay = %d, TX Ack Delay = %d, RX Wait = %d, Ack Wait = %d, RX TX = %d, Max Ack = %d, Max TX = %d, Time slot Length = %d ", + GET_U_1(p), + GET_LE_U_2(p + 1), + GET_LE_U_2(p + 3), + GET_LE_U_2(p + 5), + GET_LE_U_2(p + 7), + GET_LE_U_2(p + 9), + GET_LE_U_2(p + 11), + GET_LE_U_2(p + 13), + GET_LE_U_2(p + 15), + GET_LE_U_2(p + 17), + GET_LE_U_2(p + 19), + GET_LE_U_2(p + 21), + GET_LE_U_2(p + 23)); + } else if (sub_ie_len == 27) { + ND_PRINT("Time slot ID = %d, CCA Offset = %d, CCA = %d, TX Offset = %d, RX Offset = %d, RX Ack Delay = %d, TX Ack Delay = %d, RX Wait = %d, Ack Wait = %d, RX TX = %d, Max Ack = %d, Max TX = %d, Time slot Length = %d ", + GET_U_1(p), + GET_LE_U_2(p + 1), + GET_LE_U_2(p + 3), + GET_LE_U_2(p + 5), + GET_LE_U_2(p + 7), + GET_LE_U_2(p + 9), + GET_LE_U_2(p + 11), + GET_LE_U_2(p + 13), + GET_LE_U_2(p + 15), + GET_LE_U_2(p + 17), + GET_LE_U_2(p + 19), + GET_LE_U_3(p + 21), + GET_LE_U_3(p + 24)); + } else { + ND_PRINT("[ERROR: Length not 1, 25, or 27]"); + ND_PRINT("\n\t\t\tIE Data = "); + for(i = 0; i < sub_ie_len; i++) { + ND_PRINT("%02x ", GET_U_1(p + i)); + } + } + break; + case 0x1d: /* Hopping timing IE */ + /* XXX Not implemented */ + case 0x1e: /* Enhanced Beacon Filter IE */ + /* XXX Not implemented */ + case 0x1f: /* MAC Metrics IE */ + /* XXX Not implemented */ + case 0x20: /* All MAC Metrics IE */ + /* XXX Not implemented */ + case 0x21: /* Coexistence Specification IE */ + /* XXX Not implemented */ + case 0x22: /* SUN Device Capabilities IE */ + /* XXX Not implemented */ + case 0x23: /* SUN FSK Generic PHY IE */ + /* XXX Not implemented */ + case 0x24: /* Mode Switch Parameter IE */ + /* XXX Not implemented */ + case 0x25: /* PHY Parameter Change IE */ + /* XXX Not implemented */ + case 0x26: /* O-QPSK PHY Mode IE */ + /* XXX Not implemented */ + case 0x27: /* PCA Allocation IE */ + /* XXX Not implemented */ + case 0x28: /* LECIM DSSS Operating Mode IE */ + /* XXX Not implemented */ + case 0x29: /* LECIM FSK Operating Mode IE */ + /* XXX Not implemented */ + case 0x2b: /* TVWS PHY Operating Mode Description IE */ + /* XXX Not implemented */ + case 0x2c: /* TVWS Device Capabilities IE */ + /* XXX Not implemented */ + case 0x2d: /* TVWS Device Category IE */ + /* XXX Not implemented */ + case 0x2e: /* TVWS Device Identification IE */ + /* XXX Not implemented */ + case 0x2f: /* TVWS Device Location IE */ + /* XXX Not implemented */ + case 0x30: /* TVWS Channel Information Query IE */ + /* XXX Not implemented */ + case 0x31: /* TVWS Channel Information Source IE */ + /* XXX Not implemented */ + case 0x32: /* CTM IE */ + /* XXX Not implemented */ + case 0x33: /* Timestamp IE */ + /* XXX Not implemented */ + case 0x34: /* Timestamp Difference IE */ + /* XXX Not implemented */ + case 0x35: /* TMCTP Specification IE */ + /* XXX Not implemented */ + case 0x36: /* TCC PHY Operating Mode IE */ + /* XXX Not implemented */ + default: + ND_PRINT("IE Data = "); + for(i = 0; i < sub_ie_len; i++) { + ND_PRINT("%02x ", GET_U_1(p + i)); + } + break; + } +} + +/* + * MLME IE list parsing and printing. See 7.4.3.2 of 802.15.4-2015 + * for more information. + */ +static void +ieee802_15_4_print_mlme_ie_list(netdissect_options *ndo, + const u_char *p, + uint16_t ie_len) +{ + int ie, sub_id, i, type; + uint16_t sub_ie_len; + + do { + if (ie_len < 2) { + ND_PRINT("[ERROR: Truncated MLME IE]"); + return; + } + /* Extract IE header */ + ie = GET_LE_U_2(p); + type = CHECK_BIT(ie, 15); + if (type) { + /* Long type */ + sub_ie_len = ie & 0x3ff; + sub_id = (ie >> 11) & 0x0f; + } else { + sub_ie_len = ie & 0xff; + sub_id = (ie >> 8) & 0x7f; + } + + /* Skip the IE header */ p += 2; - caplen -= 2; - hdrlen += 2; + + if (type == 0) { + ND_PRINT("\n\t\t%s [ length = %d, ", + p_mlme_short_names[sub_id], sub_ie_len); + } else { + ND_PRINT("\n\t\t%s [ length = %d, ", + p_mlme_long_names[sub_id], sub_ie_len); + } + + if (ie_len < sub_ie_len) { + ND_PRINT("[ERROR: Truncated IE data]"); + return; + } + if (sub_ie_len != 0) { + if (ndo->ndo_vflag > 3) { + ieee802_15_4_print_mlme_ie(ndo, p, sub_ie_len, sub_id); + } else if (ndo->ndo_vflag > 2) { + ND_PRINT("IE Data = "); + for(i = 0; i < sub_ie_len; i++) { + ND_PRINT("%02x ", GET_U_1(p + i)); + } + } + } + ND_PRINT("] "); + p += sub_ie_len; + ie_len -= 2 + sub_ie_len; + } while (ie_len > 0); +} + +/* + * Multiplexd IE (802.15.9) parsing and printing. + * + * Returns number of bytes consumed from packet or -1 in case of error. + */ +static void +ieee802_15_4_print_mpx_ie(netdissect_options *ndo, + const u_char *p, + uint16_t ie_len) +{ + int transfer_type, tid; + int fragment_number, data_start; + int i; + + data_start = 0; + if (ie_len < 1) { + ND_PRINT("[ERROR: Transaction control byte missing]"); + return; + } + + transfer_type = GET_U_1(p) & 0x7; + tid = GET_U_1(p) >> 3; + switch (transfer_type) { + case 0x00: /* Full upper layer frame. */ + case 0x01: /* Full upper layer frame with small Multiplex ID. */ + ND_PRINT("Type = Full upper layer fragment%s, ", + (transfer_type == 0x01 ? + " with small Multiplex ID" : "")); + if (transfer_type == 0x00) { + if (ie_len < 3) { + ND_PRINT("[ERROR: Multiplex ID missing]"); + return; + } + data_start = 3; + ND_PRINT("tid = 0x%02x, Multiplex ID = 0x%04x, ", + tid, GET_LE_U_2(p + 1)); + } else { + data_start = 1; + ND_PRINT("Multiplex ID = 0x%04x, ", tid); + } + break; + case 0x02: /* First, or middle, Fragments */ + case 0x04: /* Last fragment */ + if (ie_len < 2) { + ND_PRINT("[ERROR: fragment number missing]"); + return; + } + + fragment_number = GET_U_1(p + 1); + ND_PRINT("Type = %s, tid = 0x%02x, fragment = 0x%02x, ", + (transfer_type == 0x02 ? + (fragment_number == 0 ? + "First fragment" : "Middle fragment") : + "Last fragment"), tid, + fragment_number); + data_start = 2; + if (fragment_number == 0) { + int total_size, multiplex_id; + + if (ie_len < 6) { + ND_PRINT("[ERROR: Total upper layer size or multiplex ID missing]"); + return; + } + total_size = GET_LE_U_2(p + 2); + multiplex_id = GET_LE_U_2(p + 4); + ND_PRINT("Total upper layer size = 0x%04x, Multiplex ID = 0x%04x, ", + total_size, multiplex_id); + data_start = 6; + } + break; + case 0x06: /* Abort code */ + if (ie_len == 1) { + ND_PRINT("Type = Abort, tid = 0x%02x, no max size given", + tid); + } else if (ie_len == 3) { + ND_PRINT("Type = Abort, tid = 0x%02x, max size = 0x%04x", + tid, GET_LE_U_2(p + 1)); + } else { + ND_PRINT("Type = Abort, tid = 0x%02x, invalid length = %d (not 1 or 3)", + tid, ie_len); + ND_PRINT("Abort data = "); + for(i = 1; i < ie_len; i++) { + ND_PRINT("%02x ", GET_U_1(p + i)); + } + } + return; + /* NOTREACHED */ break; - case FC_ADDRESSING_MODE_LONG: + case 0x03: /* Reserved */ + case 0x05: /* Reserved */ + case 0x07: /* Reserved */ + ND_PRINT("Type = %d (Reserved), tid = 0x%02x, ", + transfer_type, tid); + data_start = 1; + break; + } + + ND_PRINT("Upper layer data = "); + for(i = data_start; i < ie_len; i++) { + ND_PRINT("%02x ", GET_U_1(p + i)); + } +} + +/* + * Payload IE list parsing and printing. See 7.4.3 of 802.15.4-2015 + * for more information. + * + * Returns number of byts consumed from the packet or -1 in case of error. + */ +static int +ieee802_15_4_print_payload_ie_list(netdissect_options *ndo, + const u_char *p, + u_int caplen) +{ + int len, ie, group_id, i; + uint16_t ie_len; + + len = 0; + do { if (caplen < 2) { - ND_PRINT((ndo, "[|802.15.4]")); - return hdrlen; + ND_PRINT("[ERROR: Truncated header IE]"); + return -1; + } + /* Extract IE header */ + ie = GET_LE_U_2(p); + if ((CHECK_BIT(ie, 15)) == 0) { + ND_PRINT("[ERROR: Payload IE with type 0] "); } - panid = EXTRACT_LE_16BITS(p); + ie_len = ie & 0x3ff; + group_id = (ie >> 11) & 0x0f; + + /* Skip the IE header */ p += 2; - caplen -= 2; - hdrlen += 2; + if (ie_len == 0) { + ND_PRINT("\n\t%s [", p_ie_names[group_id]); + } else { + ND_PRINT("\n\t%s [ length = %d, ", + p_ie_names[group_id], ie_len); + } + if (caplen < ie_len) { + ND_PRINT("[ERROR: Truncated IE data]"); + return -1; + } + if (ndo->ndo_vflag > 3 && ie_len != 0) { + switch (group_id) { + case 0x1: /* MLME IE */ + ieee802_15_4_print_mlme_ie_list(ndo, p, ie_len); + break; + case 0x2: /* Vendor Specific Nested IE */ + if (ie_len < 3) { + ND_PRINT("[ERROR: Vendor OUI missing]"); + } else { + ND_PRINT("OUI = 0x%02x%02x%02x, ", + GET_U_1(p), + GET_U_1(p + 1), + GET_U_1(p + 2)); + ND_PRINT("Data = "); + for(i = 3; i < ie_len; i++) { + ND_PRINT("%02x ", + GET_U_1(p + i)); + } + } + break; + case 0x3: /* Multiplexed IE (802.15.9) */ + ieee802_15_4_print_mpx_ie(ndo, p, ie_len); + break; + case 0x5: /* IETF IE */ + if (ie_len < 1) { + ND_PRINT("[ERROR: Subtype ID missing]"); + } else { + ND_PRINT("Subtype ID = 0x%02x, Subtype content = ", + GET_U_1(p)); + for(i = 1; i < ie_len; i++) { + ND_PRINT("%02x ", + GET_U_1(p + i)); + } + } + break; + default: + ND_PRINT("IE Data = "); + for(i = 0; i < ie_len; i++) { + ND_PRINT("%02x ", GET_U_1(p + i)); + } + break; + } + } else { + if (ie_len != 0) { + ND_PRINT("IE Data = "); + for(i = 0; i < ie_len; i++) { + ND_PRINT("%02x ", GET_U_1(p + i)); + } + } + } + ND_PRINT("]\n\t"); + len += 2 + ie_len; + p += ie_len; + caplen -= 2 + ie_len; + if (group_id == 0xf) { + break; + } + } while (caplen > 0); + return len; +} + +/* + * Parse and print auxiliary security header. + * + * Returns number of byts consumed from the packet or -1 in case of error. + */ +static int +ieee802_15_4_print_aux_sec_header(netdissect_options *ndo, + const u_char *p, + u_int caplen, + int *security_level) +{ + int sc, key_id_mode, len; + + if (caplen < 1) { + ND_PRINT("[ERROR: Truncated before Aux Security Header]"); + return -1; + } + sc = GET_U_1(p); + len = 1; + *security_level = sc & 0x7; + key_id_mode = (sc >> 3) & 0x3; + + caplen -= 1; + p += 1; + + if (ndo->ndo_vflag > 0) { + ND_PRINT("\n\tSecurity Level %d, Key Id Mode %d, ", + *security_level, key_id_mode); + } + if ((CHECK_BIT(sc, 5)) == 0) { + if (caplen < 4) { + ND_PRINT("[ERROR: Truncated before Frame Counter]"); + return -1; + } + if (ndo->ndo_vflag > 1) { + ND_PRINT("Frame Counter 0x%08x ", + GET_LE_U_4(p)); + } + p += 4; + caplen -= 4; + len += 4; + } + switch (key_id_mode) { + case 0x00: /* Implicit. */ + if (ndo->ndo_vflag > 1) { + ND_PRINT("Implicit"); + } + return len; + break; + case 0x01: /* Key Index, nothing to print here. */ + break; + case 0x02: /* PAN and Short address Key Source, and Key Index. */ + if (caplen < 4) { + ND_PRINT("[ERROR: Truncated before Key Source]"); + return -1; + } + if (ndo->ndo_vflag > 1) { + ND_PRINT("KeySource 0x%04x:%0x4x, ", + GET_LE_U_2(p), GET_LE_U_2(p + 2)); + } + p += 4; + caplen -= 4; + len += 4; + break; + case 0x03: /* Extended address and Key Index. */ if (caplen < 8) { - ND_PRINT((ndo, "[|802.15.4]")); - return hdrlen; + ND_PRINT("[ERROR: Truncated before Key Source]"); + return -1; } - if (ndo->ndo_vflag) - ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(ndo, p))); - p += 8; - caplen -= 8; - hdrlen += 8; + if (ndo->ndo_vflag > 1) { + ND_PRINT("KeySource %s, ", GET_LE64ADDR_STRING(p)); + } + p += 4; + caplen -= 4; + len += 4; break; } - if (ndo->ndo_vflag) - ND_PRINT((ndo,"< ")); + if (caplen < 1) { + ND_PRINT("[ERROR: Truncated before Key Index]"); + return -1; + } + if (ndo->ndo_vflag > 1) { + ND_PRINT("KeyIndex 0x%02x, ", GET_U_1(p)); + } + caplen -= 1; + p += 1; + len += 1; + return len; +} - /* - * Source address and PAN ID, if present. - */ - switch (FC_SRC_ADDRESSING_MODE(fc)) { - case FC_ADDRESSING_MODE_NONE: - if (ndo->ndo_vflag) - ND_PRINT((ndo,"none ")); +/* + * Print command data. + * + * Returns number of byts consumed from the packet or -1 in case of error. + */ +static int +ieee802_15_4_print_command_data(netdissect_options *ndo, + uint8_t command_id, + const u_char *p, + u_int caplen) +{ + u_int i; + + switch (command_id) { + case 0x01: /* Association Request */ + if (caplen != 1) { + ND_PRINT("Invalid Association request command length"); + return -1; + } else { + uint8_t cap_info; + cap_info = GET_U_1(p); + ND_PRINT("%s%s%s%s%s%s", + ((cap_info & 0x02) ? + "FFD, " : "RFD, "), + ((cap_info & 0x04) ? + "AC powered, " : ""), + ((cap_info & 0x08) ? + "Receiver on when idle, " : ""), + ((cap_info & 0x10) ? + "Fast association, " : ""), + ((cap_info & 0x40) ? + "Security supported, " : ""), + ((cap_info & 0x80) ? + "Allocate address, " : "")); + return caplen; + } + break; + case 0x02: /* Association Response */ + if (caplen != 3) { + ND_PRINT("Invalid Association response command length"); + return -1; + } else { + ND_PRINT("Short address = "); + ieee802_15_4_print_addr(ndo, p, 2); + switch (GET_U_1(p + 2)) { + case 0x00: + ND_PRINT(", Association successful"); + break; + case 0x01: + ND_PRINT(", PAN at capacity"); + break; + case 0x02: + ND_PRINT(", PAN access denied"); + break; + case 0x03: + ND_PRINT(", Hooping sequence offset duplication"); + break; + case 0x80: + ND_PRINT(", Fast association successful"); + break; + default: + ND_PRINT(", Status = 0x%02x", + GET_U_1(p + 2)); + break; + } + return caplen; + } break; - case FC_ADDRESSING_MODE_RESERVED: + case 0x03: /* Diassociation Notification command */ + if (caplen != 1) { + ND_PRINT("Invalid Disassociation Notification command length"); + return -1; + } else { + switch (GET_U_1(p)) { + case 0x00: + ND_PRINT("Reserved"); + break; + case 0x01: + ND_PRINT("Reason = The coordinator wishes the device to leave PAN"); + break; + case 0x02: + ND_PRINT("Reason = The device wishes to leave the PAN"); + break; + default: + ND_PRINT("Reason = 0x%02x", GET_U_1(p + 2)); + break; + } + return caplen; + } + + /* Following ones do not have any data. */ + case 0x04: /* Data Request command */ + case 0x05: /* PAN ID Conflict Notification command */ + case 0x06: /* Orphan Notification command */ + case 0x07: /* Beacon Request command */ + /* Should not have any data. */ + return 0; + case 0x08: /* Coordinator Realignment command */ + if (caplen < 7 || caplen > 8) { + ND_PRINT("Invalid Coordinator Realignment command length"); + return -1; + } else { + uint16_t channel, page; + + ND_PRINT("Pan ID = 0x%04x, Coordinator short address = ", + GET_LE_U_2(p)); + ieee802_15_4_print_addr(ndo, p + 2, 2); + channel = GET_U_1(p + 4); + + if (caplen == 8) { + page = GET_U_1(p + 7); + } else { + page = 0x80; + } + if (CHECK_BIT(page, 7)) { + /* No page present, instead we have msb of + channel in the page. */ + channel |= (page & 0x7f) << 8; + ND_PRINT(", Channel Number = %d", channel); + } else { + ND_PRINT(", Channel Number = %d, page = %d", + channel, page); + } + ND_PRINT(", Short address = "); + ieee802_15_4_print_addr(ndo, p + 5, 2); + return caplen; + } + break; + case 0x09: /* GTS Request command */ + if (caplen != 1) { + ND_PRINT("Invalid GTS Request command length"); + return -1; + } else { + uint8_t gts; + + gts = GET_U_1(p); + ND_PRINT("GTS Length = %d, %s, %s", + gts & 0xf, + (CHECK_BIT(gts, 4) ? + "Receive-only GTS" : "Transmit-only GTS"), + (CHECK_BIT(gts, 5) ? + "GTS allocation" : "GTS deallocations")); + return caplen; + } + break; + case 0x13: /* DSME Association Request command */ + /* XXX Not implemented */ + case 0x14: /* DSME Association Response command */ + /* XXX Not implemented */ + case 0x15: /* DSME GTS Request command */ + /* XXX Not implemented */ + case 0x16: /* DSME GTS Response command */ + /* XXX Not implemented */ + case 0x17: /* DSME GTS Notify command */ + /* XXX Not implemented */ + case 0x18: /* DSME Information Request command */ + /* XXX Not implemented */ + case 0x19: /* DSME Information Response command */ + /* XXX Not implemented */ + case 0x1a: /* DSME Beacon Allocation Notification command */ + /* XXX Not implemented */ + case 0x1b: /* DSME Beacon Collision Notification command */ + /* XXX Not implemented */ + case 0x1c: /* DSME Link Report command */ + /* XXX Not implemented */ + case 0x20: /* RIT Data Request command */ + /* XXX Not implemented */ + case 0x21: /* DBS Request command */ + /* XXX Not implemented */ + case 0x22: /* DBS Response command */ + /* XXX Not implemented */ + case 0x23: /* RIT Data Response command */ + /* XXX Not implemented */ + case 0x24: /* Vendor Specific command */ + /* XXX Not implemented */ + case 0x0a: /* TRLE Management Request command */ + /* XXX Not implemented */ + case 0x0b: /* TRLE Management Response command */ + /* XXX Not implemented */ + default: + ND_PRINT("Command Data = "); + for(i = 0; i < caplen; i++) { + ND_PRINT("%02x ", GET_U_1(p + i)); + } + break; + } + return 0; +} + +/* + * Parse and print frames following standard format. + * + * Returns FALSE in case of error. + */ +static u_int +ieee802_15_4_std_frames(netdissect_options *ndo, + const u_char *p, u_int caplen, + uint16_t fc) +{ + int len, frame_version, pan_id_comp; + int frame_type; + int src_pan, dst_pan, src_addr_len, dst_addr_len; + int security_level, miclen = 0; + int payload_ie_present; + uint8_t seq; + uint32_t fcs, crc_check; + const u_char *mic_start = NULL; + + payload_ie_present = 0; + + crc_check = 0; + /* Assume 2 octet FCS, the FCS length depends on the PHY, and we do not + know about that. */ + if (caplen < 4) { + /* Cannot have FCS, assume no FCS. */ + fcs = 0; + } else { + /* Test for 4 octet FCS. */ + fcs = GET_LE_U_4(p + caplen - 4); + crc_check = ieee802_15_4_crc32(ndo, p, caplen - 4); + if (crc_check == fcs) { + /* Remove FCS */ + caplen -= 4; + } else { + /* Test for 2 octet FCS. */ + fcs = GET_LE_U_2(p + caplen - 2); + crc_check = ieee802_15_4_crc16(ndo, p, caplen - 2); + if (crc_check == fcs) { + /* Remove FCS */ + caplen -= 2; + } else { + /* Wrong FCS, FCS might not be included in the + captured frame, do not remove it. */ + } + } + } + + /* Frame version. */ + frame_version = FC_FRAME_VERSION(fc); + frame_type = FC_FRAME_TYPE(fc); + ND_PRINT("v%d ", frame_version); + + if (ndo->ndo_vflag > 2) { + if (CHECK_BIT(fc, 3)) { ND_PRINT("Security Enabled, "); } + if (CHECK_BIT(fc, 4)) { ND_PRINT("Frame Pending, "); } + if (CHECK_BIT(fc, 5)) { ND_PRINT("AR, "); } + if (CHECK_BIT(fc, 6)) { ND_PRINT("PAN ID Compression, "); } + if (CHECK_BIT(fc, 8)) { ND_PRINT("Sequence Number Suppression, "); } + if (CHECK_BIT(fc, 9)) { ND_PRINT("IE present, "); } + } + + /* Check for the sequence number suppression. */ + if (CHECK_BIT(fc, 8)) { + /* Sequence number is suppressed. */ + if (frame_version < 2) { + /* Sequence number can only be suppressed for frame + version 2 or higher, this is invalid frame. */ + ND_PRINT("[ERROR: Sequence number suppressed on frames where version < 2]"); + } + if (ndo->ndo_vflag) + ND_PRINT("seq suppressed "); + p += 2; + caplen -= 2; + } else { + seq = GET_U_1(p + 2); + p += 3; + caplen -= 3; if (ndo->ndo_vflag) - ND_PRINT((ndo,"reserved source addressing mode")); + ND_PRINT("seq %02x ", seq); + } + + /* See which parts of addresses we have. */ + dst_addr_len = ieee802_15_4_addr_len((fc >> 10) & 0x3); + src_addr_len = ieee802_15_4_addr_len((fc >> 14) & 0x3); + if (src_addr_len < 0) { + ND_PRINT("[ERROR: Invalid src address mode]"); return 0; - case FC_ADDRESSING_MODE_SHORT: - if (!(fc & FC_PAN_ID_COMPRESSION)) { - /* - * The source PAN ID is not compressed out, so - * fetch it. (Otherwise, we'll use the destination - * PAN ID, fetched above.) - */ - if (caplen < 2) { - ND_PRINT((ndo, "[|802.15.4]")); - return hdrlen; + } + if (dst_addr_len < 0) { + ND_PRINT("[ERROR: Invalid dst address mode]"); + return 0; + } + src_pan = 0; + dst_pan = 0; + pan_id_comp = CHECK_BIT(fc, 6); + + /* The PAN ID Compression rules are complicated. */ + + /* First check old versions, where the rules are simple. */ + if (frame_version < 2) { + if (pan_id_comp) { + src_pan = 0; + dst_pan = 1; + if (dst_addr_len <= 0 || src_addr_len <= 0) { + /* Invalid frame, PAN ID Compression must be 0 + if only one address in the frame. */ + ND_PRINT("[ERROR: PAN ID Compression != 0, and only one address with frame version < 2]"); } - panid = EXTRACT_LE_16BITS(p); - p += 2; - caplen -= 2; - hdrlen += 2; + } else { + src_pan = 1; + dst_pan = 1; + } + if (dst_addr_len <= 0) { + dst_pan = 0; + } + if (src_addr_len <= 0) { + src_pan = 0; + } + } else { + /* Frame version 2 rules are more complicated, and they depend + on the address modes of the frame, generic rules are same, + but then there are some special cases. */ + if (pan_id_comp) { + src_pan = 0; + dst_pan = 1; + } else { + src_pan = 1; + dst_pan = 1; + } + if (dst_addr_len <= 0) { + dst_pan = 0; + } + if (src_addr_len <= 0) { + src_pan = 0; + } + if (pan_id_comp) { + if (src_addr_len == 0 && + dst_addr_len == 0) { + /* Both addresses are missing, but PAN ID + compression set, special case we have + destination PAN but no addresses. */ + dst_pan = 1; + } else if ((src_addr_len == 0 && + dst_addr_len > 0) || + (src_addr_len > 0 && + dst_addr_len == 0)) { + /* Only one address present, and PAN ID + compression is set, we do not have PAN id at + all. */ + dst_pan = 0; + src_pan = 0; + } else if (src_addr_len == 8 && + dst_addr_len == 8) { + /* Both addresses are Extended, and PAN ID + compression set, we do not have PAN ID at + all. */ + dst_pan = 0; + src_pan = 0; + } + } else { + /* Special cases where PAN ID Compression is not set. */ + if (src_addr_len == 8 && + dst_addr_len == 8) { + /* Both addresses are Extended, and PAN ID + compression not set, we do have only one PAN + ID (destination). */ + dst_pan = 1; + src_pan = 0; + } +#ifdef BROKEN_6TISCH_PAN_ID_COMPRESSION + if (src_addr_len == 8 && + dst_addr_len == 2) { + /* Special case for the broken 6tisch + implementations. */ + src_pan = 0; + } +#endif /* BROKEN_6TISCH_PAN_ID_COMPRESSION */ } + } + + /* Print dst PAN and address. */ + if (dst_pan) { if (caplen < 2) { - ND_PRINT((ndo, "[|802.15.4]")); - return hdrlen; + ND_PRINT("[ERROR: Truncated before dst_pan]"); + return 0; } - if (ndo->ndo_vflag) - ND_PRINT((ndo,"%04x:%04x ", panid, EXTRACT_LE_16BITS(p))); + ND_PRINT("%04x:", GET_LE_U_2(p)); + p += 2; + caplen -= 2; + } else { + ND_PRINT("-:"); + } + if (caplen < (u_int) dst_addr_len) { + ND_PRINT("[ERROR: Truncated before dst_addr]"); + return 0; + } + ieee802_15_4_print_addr(ndo, p, dst_addr_len); + p += dst_addr_len; + caplen -= dst_addr_len; + + ND_PRINT(" < "); + + /* Print src PAN and address. */ + if (src_pan) { + if (caplen < 2) { + ND_PRINT("[ERROR: Truncated before dst_pan]"); + return 0; + } + ND_PRINT("%04x:", GET_LE_U_2(p)); p += 2; caplen -= 2; - hdrlen += 2; - break; - case FC_ADDRESSING_MODE_LONG: - if (!(fc & FC_PAN_ID_COMPRESSION)) { - /* - * The source PAN ID is not compressed out, so - * fetch it. (Otherwise, we'll use the destination - * PAN ID, fetched above.) - */ + } else { + ND_PRINT("-:"); + } + if (caplen < (u_int) src_addr_len) { + ND_PRINT("[ERROR: Truncated before dst_addr]"); + return 0; + } + ieee802_15_4_print_addr(ndo, p, src_addr_len); + ND_PRINT(" "); + p += src_addr_len; + caplen -= src_addr_len; + if (CHECK_BIT(fc, 3)) { + /* + * XXX - if frame_version is 0, this is the 2003 + * spec, and you don't have the auxiliary security + * header, you have a frame counter and key index + * for the AES-CTR and AES-CCM security suites but + * not for the AES-CBC-MAC security suite. + */ + len = ieee802_15_4_print_aux_sec_header(ndo, p, caplen, + &security_level); + if (len < 0) { + return 0; + } + ND_TCHECK_LEN(p, len); + p += len; + caplen -= len; + } else { + security_level = 0; + } + + switch (security_level) { + case 0: /*FALLTHOUGH */ + case 4: + miclen = 0; + break; + case 1: /*FALLTHOUGH */ + case 5: + miclen = 4; + break; + case 2: /*FALLTHOUGH */ + case 6: + miclen = 8; + break; + case 3: /*FALLTHOUGH */ + case 7: + miclen = 16; + break; + } + + /* Remove MIC */ + if (miclen > 0) { + if (caplen < (u_int) miclen) { + ND_PRINT("[ERROR: Truncated before MIC]"); + return 0; + } + caplen -= miclen; + mic_start = p + caplen; + } + + /* Parse Information elements if present */ + if (CHECK_BIT(fc, 9)) { + /* Yes we have those. */ + len = ieee802_15_4_print_header_ie_list(ndo, p, caplen, + &payload_ie_present); + if (len < 0) { + return 0; + } + p += len; + caplen -= len; + } + + if (payload_ie_present) { + if (security_level >= 4) { + ND_PRINT("Payload IEs present, but encrypted, cannot print "); + } else { + len = ieee802_15_4_print_payload_ie_list(ndo, p, caplen); + if (len < 0) { + return 0; + } + p += len; + caplen -= len; + } + } + + /* Print MIC */ + if (ndo->ndo_vflag > 2 && miclen != 0) { + ND_PRINT("\n\tMIC "); + + for(len = 0; len < miclen; len++) { + ND_PRINT("%02x", GET_U_1(mic_start + len)); + } + ND_PRINT(" "); + } + + /* Print FCS */ + if (ndo->ndo_vflag > 2) { + if (crc_check == fcs) { + ND_PRINT("FCS %x ", fcs); + } else { + ND_PRINT("wrong FCS %x vs %x (assume no FCS stored) ", + fcs, crc_check); + } + } + + /* Payload print */ + switch (frame_type) { + case 0x00: /* Beacon */ + if (frame_version < 2) { if (caplen < 2) { - ND_PRINT((ndo, "[|802.15.4]")); - return hdrlen; + ND_PRINT("[ERROR: Truncated before beacon information]"); + break; + } else { + uint16_t ss; + + ss = GET_LE_U_2(p); + ieee802_15_4_print_superframe_specification(ndo, ss); + p += 2; + caplen -= 2; + + /* GTS */ + if (caplen < 1) { + ND_PRINT("[ERROR: Truncated before GTS info]"); + break; + } + + len = ieee802_15_4_print_gts_info(ndo, p, caplen); + if (len < 0) { + break; + } + + p += len; + caplen -= len; + + /* Pending Addresses */ + if (caplen < 1) { + ND_PRINT("[ERROR: Truncated before pending addresses]"); + break; + } + len = ieee802_15_4_print_pending_addresses(ndo, p, caplen); + if (len < 0) { + break; + } + ND_TCHECK_LEN(p, len); + p += len; + caplen -= len; + } + } + if (!ndo->ndo_suppress_default_print) + ND_DEFAULTPRINT(p, caplen); + + break; + case 0x01: /* Data */ + case 0x02: /* Acknowledgement */ + if (!ndo->ndo_suppress_default_print) + ND_DEFAULTPRINT(p, caplen); + break; + case 0x03: /* MAC Command */ + if (caplen < 1) { + ND_PRINT("[ERROR: Truncated before Command ID]"); + } else { + uint8_t command_id; + + command_id = GET_U_1(p); + if (command_id >= 0x30) { + ND_PRINT("Command ID = Reserved 0x%02x ", + command_id); + } else { + ND_PRINT("Command ID = %s ", + mac_c_names[command_id]); + } + p++; + caplen--; + if (caplen != 0) { + len = ieee802_15_4_print_command_data(ndo, command_id, p, caplen); + if (len >= 0) { + p += len; + caplen -= len; + } + } + } + if (!ndo->ndo_suppress_default_print) + ND_DEFAULTPRINT(p, caplen); + break; + } + return 1; +} + +/* + * Print and parse Multipurpose frames. + * + * Returns FALSE in case of error. + */ +static u_int +ieee802_15_4_mp_frame(netdissect_options *ndo, + const u_char *p, u_int caplen, + uint16_t fc) +{ + int len, frame_version, pan_id_present; + int src_addr_len, dst_addr_len; + int security_level, miclen = 0; + int ie_present, payload_ie_present, security_enabled; + uint8_t seq; + uint32_t fcs, crc_check; + const u_char *mic_start = NULL; + + pan_id_present = 0; + ie_present = 0; + payload_ie_present = 0; + security_enabled = 0; + crc_check = 0; + + /* Assume 2 octet FCS, the FCS length depends on the PHY, and we do not + know about that. */ + if (caplen < 3) { + /* Cannot have FCS, assume no FCS. */ + fcs = 0; + } else { + if (caplen > 4) { + /* Test for 4 octet FCS. */ + fcs = GET_LE_U_4(p + caplen - 4); + crc_check = ieee802_15_4_crc32(ndo, p, caplen - 4); + if (crc_check == fcs) { + /* Remove FCS */ + caplen -= 4; + } else { + fcs = GET_LE_U_2(p + caplen - 2); + crc_check = ieee802_15_4_crc16(ndo, p, caplen - 2); + if (crc_check == fcs) { + /* Remove FCS */ + caplen -= 2; + } + } + } else { + fcs = GET_LE_U_2(p + caplen - 2); + crc_check = ieee802_15_4_crc16(ndo, p, caplen - 2); + if (crc_check == fcs) { + /* Remove FCS */ + caplen -= 2; + } + } + } + + if (CHECK_BIT(fc, 3)) { + /* Long Frame Control */ + + /* Frame version. */ + frame_version = FC_FRAME_VERSION(fc); + ND_PRINT("v%d ", frame_version); + + pan_id_present = CHECK_BIT(fc, 8); + ie_present = CHECK_BIT(fc, 15); + security_enabled = CHECK_BIT(fc, 9); + + if (ndo->ndo_vflag > 2) { + if (security_enabled) { ND_PRINT("Security Enabled, "); } + if (CHECK_BIT(fc, 11)) { ND_PRINT("Frame Pending, "); } + if (CHECK_BIT(fc, 14)) { ND_PRINT("AR, "); } + if (pan_id_present) { ND_PRINT("PAN ID Present, "); } + if (CHECK_BIT(fc, 10)) { + ND_PRINT("Sequence Number Suppression, "); } - panid = EXTRACT_LE_16BITS(p); + if (ie_present) { ND_PRINT("IE present, "); } + } + + /* Check for the sequence number suppression. */ + if (CHECK_BIT(fc, 10)) { + /* Sequence number is suppressed, but long version. */ p += 2; caplen -= 2; - hdrlen += 2; - } - if (caplen < 8) { - ND_PRINT((ndo, "[|802.15.4]")); - return hdrlen; + } else { + seq = GET_U_1(p + 2); + p += 3; + caplen -= 3; + if (ndo->ndo_vflag) + ND_PRINT("seq %02x ", seq); } + } else { + /* Short format of header, but with seq no */ + seq = GET_U_1(p + 1); + p += 2; + caplen -= 2; if (ndo->ndo_vflag) - ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(ndo, p))); - p += 8; - caplen -= 8; - hdrlen += 8; + ND_PRINT("seq %02x ", seq); + } + + /* See which parts of addresses we have. */ + dst_addr_len = ieee802_15_4_addr_len((fc >> 4) & 0x3); + src_addr_len = ieee802_15_4_addr_len((fc >> 6) & 0x3); + if (src_addr_len < 0) { + ND_PRINT("[ERROR: Invalid src address mode]"); + return 0; + } + if (dst_addr_len < 0) { + ND_PRINT("[ERROR: Invalid dst address mode]"); + return 0; + } + + /* Print dst PAN and address. */ + if (pan_id_present) { + if (caplen < 2) { + ND_PRINT("[ERROR: Truncated before dst_pan]"); + return 0; + } + ND_PRINT("%04x:", GET_LE_U_2(p)); + p += 2; + caplen -= 2; + } else { + ND_PRINT("-:"); + } + if (caplen < (u_int) dst_addr_len) { + ND_PRINT("[ERROR: Truncated before dst_addr]"); + return 0; + } + ieee802_15_4_print_addr(ndo, p, dst_addr_len); + p += dst_addr_len; + caplen -= dst_addr_len; + + ND_PRINT(" < "); + + /* Print src PAN and address. */ + ND_PRINT(" -:"); + if (caplen < (u_int) src_addr_len) { + ND_PRINT("[ERROR: Truncated before dst_addr]"); + return 0; + } + ieee802_15_4_print_addr(ndo, p, src_addr_len); + ND_PRINT(" "); + p += src_addr_len; + caplen -= src_addr_len; + + if (security_enabled) { + len = ieee802_15_4_print_aux_sec_header(ndo, p, caplen, + &security_level); + if (len < 0) { + return 0; + } + ND_TCHECK_LEN(p, len); + p += len; + caplen -= len; + } else { + security_level = 0; + } + + switch (security_level) { + case 0: /*FALLTHOUGH */ + case 4: + miclen = 0; break; + case 1: /*FALLTHOUGH */ + case 5: + miclen = 4; + break; + case 2: /*FALLTHOUGH */ + case 6: + miclen = 8; + break; + case 3: /*FALLTHOUGH */ + case 7: + miclen = 16; + break; + } + + /* Remove MIC */ + if (miclen > 0) { + if (caplen < (u_int) miclen) { + ND_PRINT("[ERROR: Truncated before MIC]"); + return 0; + } + caplen -= miclen; + mic_start = p + caplen; + } + + /* Parse Information elements if present */ + if (ie_present) { + /* Yes we have those. */ + len = ieee802_15_4_print_header_ie_list(ndo, p, caplen, + &payload_ie_present); + if (len < 0) { + return 0; + } + p += len; + caplen -= len; + } + + if (payload_ie_present) { + if (security_level >= 4) { + ND_PRINT("Payload IEs present, but encrypted, cannot print "); + } else { + len = ieee802_15_4_print_payload_ie_list(ndo, p, + caplen); + if (len < 0) { + return 0; + } + p += len; + caplen -= len; + } + } + + /* Print MIC */ + if (ndo->ndo_vflag > 2 && miclen != 0) { + ND_PRINT("\n\tMIC "); + + for(len = 0; len < miclen; len++) { + ND_PRINT("%02x", GET_U_1(mic_start + len)); + } + ND_PRINT(" "); + } + + + /* Print FCS */ + if (ndo->ndo_vflag > 2) { + if (crc_check == fcs) { + ND_PRINT("FCS %x ", fcs); + } else { + ND_PRINT("wrong FCS %x vs %x (assume no FCS stored) ", + fcs, crc_check); + } } if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); - return hdrlen; + return 1; +} + +/* + * Print frag frame. + * + * Returns FALSE in case of error. + */ +static u_int +ieee802_15_4_frag_frame(netdissect_options *ndo _U_, + const u_char *p _U_, + u_int caplen _U_, + uint16_t fc _U_) +{ + /* Not implement yet, might be bit hard to implement, as the + * information to set up the fragment is coming in the previous frame + * in the Fragment Sequence Context Description IE, thus we need to + * store information from there, so we can use it here. */ + return 0; +} + +/* + * Internal call to dissector taking packet + len instead of pcap_pkthdr. + * + * Returns FALSE in case of error. + */ +u_int +ieee802_15_4_print(netdissect_options *ndo, + const u_char *p, u_int caplen) +{ + int frame_type; + uint16_t fc; + + ndo->ndo_protocol = "802.15.4"; + + if (caplen < 2) { + nd_print_trunc(ndo); + return caplen; + } + + fc = GET_LE_U_2(p); + + /* First we need to check the frame type to know how to parse the rest + of the FC. Frame type is the first 3 bit of the frame control field. + */ + + frame_type = FC_FRAME_TYPE(fc); + ND_PRINT("IEEE 802.15.4 %s packet ", ftypes[frame_type]); + + switch (frame_type) { + case 0x00: /* Beacon */ + case 0x01: /* Data */ + case 0x02: /* Acknowledgement */ + case 0x03: /* MAC Command */ + return ieee802_15_4_std_frames(ndo, p, caplen, fc); + break; + case 0x04: /* Reserved */ + return 0; + break; + case 0x05: /* Multipurpose */ + return ieee802_15_4_mp_frame(ndo, p, caplen, fc); + break; + case 0x06: /* Fragment or Frak */ + return ieee802_15_4_frag_frame(ndo, p, caplen, fc); + break; + case 0x07: /* Extended */ + return 0; + break; + } + return 0; +} + +/* + * Main function to print packets. + */ + +void +ieee802_15_4_if_print(netdissect_options *ndo, + const struct pcap_pkthdr *h, const u_char *p) +{ + u_int caplen = h->caplen; + ndo->ndo_protocol = "802.15.4"; + ndo->ndo_ll_hdr_len += ieee802_15_4_print(ndo, p, caplen); +} + +/* For DLT_IEEE802_15_4_TAP */ +/* https://github.com/jkcko/ieee802.15.4-tap */ +void +ieee802_15_4_tap_if_print(netdissect_options *ndo, + const struct pcap_pkthdr *h, const u_char *p) +{ + uint8_t version; + uint16_t length; + + ndo->ndo_protocol = "802.15.4_tap"; + if (h->caplen < 4) { + nd_print_trunc(ndo); + ndo->ndo_ll_hdr_len += h->caplen; + return; + } + + version = GET_U_1(p); + length = GET_LE_U_2(p + 2); + if (version != 0 || length < 4) { + nd_print_invalid(ndo); + return; + } + + if (h->caplen < length) { + nd_print_trunc(ndo); + ndo->ndo_ll_hdr_len += h->caplen; + return; + } + + ndo->ndo_ll_hdr_len += ieee802_15_4_print(ndo, p+length, h->caplen-length) + length; } diff --git a/contrib/tcpdump/print-ah.c b/contrib/tcpdump/print-ah.c index bec6f88f67..a3d05544c2 100644 --- a/contrib/tcpdump/print-ah.c +++ b/contrib/tcpdump/print-ah.c @@ -24,41 +24,52 @@ /* \summary: IPSEC Authentication Header printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include - -#include "ah.h" +#include "netdissect-stdinc.h" #include "netdissect.h" #include "extract.h" +#include "ah.h" + int -ah_print(netdissect_options *ndo, register const u_char *bp) +ah_print(netdissect_options *ndo, const u_char *bp) { - register const struct ah *ah; - int sumlen; + const struct ah *ah; + uint8_t ah_len; + u_int ah_hdr_len; + uint16_t reserved; + const u_char *p; + ndo->ndo_protocol = "ah"; ah = (const struct ah *)bp; - ND_TCHECK(*ah); - - sumlen = ah->ah_len << 2; + nd_print_protocol_caps(ndo); +/* + * RFC4302 + * + * 2.2. Payload Length + * + * This 8-bit field specifies the length of AH in 32-bit words (4-byte + * units), minus "2". + */ + ah_len = GET_U_1(ah->ah_len); + ah_hdr_len = (ah_len + 2) * 4; - ND_PRINT((ndo, "AH(spi=0x%08x", EXTRACT_32BITS(&ah->ah_spi))); + ND_PRINT("("); if (ndo->ndo_vflag) - ND_PRINT((ndo, ",sumlen=%d", sumlen)); - ND_TCHECK_32BITS(ah + 1); - ND_PRINT((ndo, ",seq=0x%x", EXTRACT_32BITS(ah + 1))); - if (!ND_TTEST2(*bp, sizeof(struct ah) + sumlen)) { - ND_PRINT((ndo, "[truncated]):")); - return -1; - } - ND_PRINT((ndo, "): ")); + ND_PRINT("length=%u(%u-bytes),", ah_len, ah_hdr_len); + reserved = GET_BE_U_2(ah->ah_reserved); + if (reserved) + ND_PRINT("reserved=0x%x[MustBeZero],", reserved); + ND_PRINT("spi=0x%08x,", GET_BE_U_4(ah->ah_spi)); + ND_PRINT("seq=0x%x,", GET_BE_U_4(ah->ah_seq)); + ND_PRINT("icv=0x"); + for (p = (const u_char *)(ah + 1); p < bp + ah_hdr_len; p++) + ND_PRINT("%02x", GET_U_1(p)); + ND_PRINT("): "); - return sizeof(struct ah) + sumlen; - trunc: - ND_PRINT((ndo, "[|AH]")); - return -1; + return ah_hdr_len; } diff --git a/contrib/tcpdump/print-ahcp.c b/contrib/tcpdump/print-ahcp.c index 067b506944..9859f76009 100644 --- a/contrib/tcpdump/print-ahcp.c +++ b/contrib/tcpdump/print-ahcp.c @@ -30,16 +30,16 @@ /* Based on draft-chroboczek-ahcp-00 and source code of ahcpd-0.53 */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" #include "addrtoname.h" -static const char tstr[] = " [|ahcp]"; #define AHCP_MAGIC_NUMBER 43 #define AHCP_VERSION_1 1 @@ -97,151 +97,130 @@ static const struct tok ahcp1_opt_str[] = { { 0, NULL } }; -static int -ahcp_time_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) +static void +ahcp_time_print(netdissect_options *ndo, + const u_char *cp, uint8_t len) { time_t t; struct tm *tm; char buf[BUFSIZE]; - if (cp + 4 != ep) + if (len != 4) goto invalid; - ND_TCHECK2(*cp, 4); - t = EXTRACT_32BITS(cp); + t = GET_BE_U_4(cp); if (NULL == (tm = gmtime(&t))) - ND_PRINT((ndo, ": gmtime() error")); + ND_PRINT(": gmtime() error"); else if (0 == strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm)) - ND_PRINT((ndo, ": strftime() error")); + ND_PRINT(": strftime() error"); else - ND_PRINT((ndo, ": %s UTC", buf)); - return 0; + ND_PRINT(": %s UTC", buf); + return; invalid: - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp, ep - cp); - return 0; -trunc: - ND_PRINT((ndo, "%s", tstr)); - return -1; + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } -static int -ahcp_seconds_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) +static void +ahcp_seconds_print(netdissect_options *ndo, + const u_char *cp, uint8_t len) { - if (cp + 4 != ep) + if (len != 4) goto invalid; - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, ": %us", EXTRACT_32BITS(cp))); - return 0; + ND_PRINT(": %us", GET_BE_U_4(cp)); + return; invalid: - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp, ep - cp); - return 0; -trunc: - ND_PRINT((ndo, "%s", tstr)); - return -1; + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } -static int -ahcp_ipv6_addresses_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) +static void +ahcp_ipv6_addresses_print(netdissect_options *ndo, + const u_char *cp, uint8_t len) { const char *sep = ": "; - while (cp < ep) { - if (cp + 16 > ep) + while (len) { + if (len < 16) goto invalid; - ND_TCHECK2(*cp, 16); - ND_PRINT((ndo, "%s%s", sep, ip6addr_string(ndo, cp))); + ND_PRINT("%s%s", sep, GET_IP6ADDR_STRING(cp)); cp += 16; + len -= 16; sep = ", "; } - return 0; + return; invalid: - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp, ep - cp); - return 0; -trunc: - ND_PRINT((ndo, "%s", tstr)); - return -1; + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } -static int -ahcp_ipv4_addresses_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) +static void +ahcp_ipv4_addresses_print(netdissect_options *ndo, + const u_char *cp, uint8_t len) { const char *sep = ": "; - while (cp < ep) { - if (cp + 4 > ep) + while (len) { + if (len < 4) goto invalid; - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, "%s%s", sep, ipaddr_string(ndo, cp))); + ND_PRINT("%s%s", sep, GET_IPADDR_STRING(cp)); cp += 4; + len -= 4; sep = ", "; } - return 0; + return; invalid: - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp, ep - cp); - return 0; -trunc: - ND_PRINT((ndo, "%s", tstr)); - return -1; + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } -static int -ahcp_ipv6_prefixes_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) +static void +ahcp_ipv6_prefixes_print(netdissect_options *ndo, + const u_char *cp, uint8_t len) { const char *sep = ": "; - while (cp < ep) { - if (cp + 17 > ep) + while (len) { + if (len < 17) goto invalid; - ND_TCHECK2(*cp, 17); - ND_PRINT((ndo, "%s%s/%u", sep, ip6addr_string(ndo, cp), *(cp + 16))); + ND_PRINT("%s%s/%u", sep, GET_IP6ADDR_STRING(cp), GET_U_1(cp + 16)); cp += 17; + len -= 17; sep = ", "; } - return 0; + return; invalid: - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp, ep - cp); - return 0; -trunc: - ND_PRINT((ndo, "%s", tstr)); - return -1; + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } -static int -ahcp_ipv4_prefixes_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) +static void +ahcp_ipv4_prefixes_print(netdissect_options *ndo, + const u_char *cp, uint8_t len) { const char *sep = ": "; - while (cp < ep) { - if (cp + 5 > ep) + while (len) { + if (len < 5) goto invalid; - ND_TCHECK2(*cp, 5); - ND_PRINT((ndo, "%s%s/%u", sep, ipaddr_string(ndo, cp), *(cp + 4))); + ND_PRINT("%s%s/%u", sep, GET_IPADDR_STRING(cp), GET_U_1(cp + 4)); cp += 5; + len -= 5; sep = ", "; } - return 0; + return; invalid: - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp, ep - cp); - return 0; -trunc: - ND_PRINT((ndo, "%s", tstr)); - return -1; + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } -/* Data decoders signal truncated data with -1. */ -static int -(* const data_decoders[AHCP1_OPT_MAX + 1])(netdissect_options *, const u_char *, const u_char *) = { +static void +(* const data_decoders[AHCP1_OPT_MAX + 1])(netdissect_options *, const u_char *, uint8_t) = { /* [AHCP1_OPT_PAD] = */ NULL, /* [AHCP1_OPT_MANDATORY] = */ NULL, /* [AHCP1_OPT_ORIGIN_TIME] = */ ahcp_time_print, @@ -259,153 +238,151 @@ static int }; static void -ahcp1_options_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) +ahcp1_options_print(netdissect_options *ndo, + const u_char *cp, uint16_t len) { - uint8_t option_no, option_len; + while (len) { + uint8_t option_no, option_len; - while (cp < ep) { /* Option no */ - ND_TCHECK2(*cp, 1); - option_no = *cp; + option_no = GET_U_1(cp); cp += 1; - ND_PRINT((ndo, "\n\t %s", tok2str(ahcp1_opt_str, "Unknown-%u", option_no))); + len -= 1; + ND_PRINT("\n\t %s", tok2str(ahcp1_opt_str, "Unknown-%u", option_no)); if (option_no == AHCP1_OPT_PAD || option_no == AHCP1_OPT_MANDATORY) continue; /* Length */ - if (cp + 1 > ep) + if (!len) goto invalid; - ND_TCHECK2(*cp, 1); - option_len = *cp; + option_len = GET_U_1(cp); cp += 1; - if (cp + option_len > ep) + len -= 1; + if (option_len > len) goto invalid; /* Value */ if (option_no <= AHCP1_OPT_MAX && data_decoders[option_no] != NULL) { - if (data_decoders[option_no](ndo, cp, cp + option_len) < 0) - break; /* truncated and already marked up */ + data_decoders[option_no](ndo, cp, option_len); } else { - ND_PRINT((ndo, " (Length %u)", option_len)); - ND_TCHECK2(*cp, option_len); + ND_PRINT(" (Length %u)", option_len); + ND_TCHECK_LEN(cp, option_len); } cp += option_len; + len -= option_len; } return; invalid: - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp, ep - cp); - return; -trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } static void -ahcp1_body_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) +ahcp1_body_print(netdissect_options *ndo, + const u_char *cp, u_int len) { uint8_t type, mbz; uint16_t body_len; - if (cp + AHCP1_BODY_MIN_LEN > ep) + if (len < AHCP1_BODY_MIN_LEN) goto invalid; /* Type */ - ND_TCHECK2(*cp, 1); - type = *cp; + type = GET_U_1(cp); cp += 1; + len -= 1; /* MBZ */ - ND_TCHECK2(*cp, 1); - mbz = *cp; + mbz = GET_U_1(cp); cp += 1; + len -= 1; /* Length */ - ND_TCHECK2(*cp, 2); - body_len = EXTRACT_16BITS(cp); + body_len = GET_BE_U_2(cp); cp += 2; + len -= 2; if (ndo->ndo_vflag) { - ND_PRINT((ndo, "\n\t%s", tok2str(ahcp1_msg_str, "Unknown-%u", type))); + ND_PRINT("\n\t%s", tok2str(ahcp1_msg_str, "Unknown-%u", type)); if (mbz != 0) - ND_PRINT((ndo, ", MBZ %u", mbz)); - ND_PRINT((ndo, ", Length %u", body_len)); + ND_PRINT(", MBZ %u", mbz); + ND_PRINT(", Length %u", body_len); } - if (cp + body_len > ep) + if (body_len > len) goto invalid; /* Options */ + /* Here use "body_len", not "len" (ignore any extra data). */ if (ndo->ndo_vflag >= 2) - ahcp1_options_print(ndo, cp, cp + body_len); /* not ep (ignore extra data) */ + ahcp1_options_print(ndo, cp, body_len); else - ND_TCHECK2(*cp, body_len); + ND_TCHECK_LEN(cp, body_len); return; invalid: - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp, ep - cp); - return; -trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); + } void -ahcp_print(netdissect_options *ndo, const u_char *cp, const u_int len) +ahcp_print(netdissect_options *ndo, + const u_char *cp, u_int len) { - const u_char *ep = cp + len; uint8_t version; - ND_PRINT((ndo, "AHCP")); + ndo->ndo_protocol = "ahcp"; + nd_print_protocol_caps(ndo); if (len < 2) goto invalid; /* Magic */ - ND_TCHECK2(*cp, 1); - if (*cp != AHCP_MAGIC_NUMBER) + if (GET_U_1(cp) != AHCP_MAGIC_NUMBER) goto invalid; cp += 1; + len -= 1; /* Version */ - ND_TCHECK2(*cp, 1); - version = *cp; + version = GET_U_1(cp); cp += 1; + len -= 1; switch (version) { case AHCP_VERSION_1: { - ND_PRINT((ndo, " Version 1")); - if (len < AHCP1_HEADER_FIX_LEN) + ND_PRINT(" Version 1"); + if (len < AHCP1_HEADER_FIX_LEN - 2) goto invalid; if (!ndo->ndo_vflag) { - ND_TCHECK2(*cp, AHCP1_HEADER_FIX_LEN - 2); + ND_TCHECK_LEN(cp, AHCP1_HEADER_FIX_LEN - 2); cp += AHCP1_HEADER_FIX_LEN - 2; + len -= AHCP1_HEADER_FIX_LEN - 2; } else { /* Hopcount */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, "\n\tHopcount %u", *cp)); + ND_PRINT("\n\tHopcount %u", GET_U_1(cp)); cp += 1; + len -= 1; /* Original Hopcount */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, ", Original Hopcount %u", *cp)); + ND_PRINT(", Original Hopcount %u", GET_U_1(cp)); cp += 1; + len -= 1; /* Nonce */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, ", Nonce 0x%08x", EXTRACT_32BITS(cp))); + ND_PRINT(", Nonce 0x%08x", GET_BE_U_4(cp)); cp += 4; + len -= 4; /* Source Id */ - ND_TCHECK2(*cp, 8); - ND_PRINT((ndo, ", Source Id %s", linkaddr_string(ndo, cp, 0, 8))); + ND_PRINT(", Source Id %s", GET_LINKADDR_STRING(cp, LINKADDR_OTHER, 8)); cp += 8; + len -= 8; /* Destination Id */ - ND_TCHECK2(*cp, 8); - ND_PRINT((ndo, ", Destination Id %s", linkaddr_string(ndo, cp, 0, 8))); + ND_PRINT(", Destination Id %s", GET_LINKADDR_STRING(cp, LINKADDR_OTHER, 8)); cp += 8; + len -= 8; } /* Body */ - ahcp1_body_print(ndo, cp, ep); + ahcp1_body_print(ndo, cp, len); break; } default: - ND_PRINT((ndo, " Version %u (unknown)", version)); + ND_PRINT(" Version %u (unknown)", version); + ND_TCHECK_LEN(cp, len); break; } return; invalid: - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp, ep - cp); - return; -trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } diff --git a/contrib/tcpdump/print-aodv.c b/contrib/tcpdump/print-aodv.c index fe75db863c..97421433f7 100644 --- a/contrib/tcpdump/print-aodv.c +++ b/contrib/tcpdump/print-aodv.c @@ -33,10 +33,10 @@ /* \summary: Ad hoc On-Demand Distance Vector (AODV) Routing printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "addrtoname.h" @@ -46,37 +46,37 @@ * RFC 3561 */ struct aodv_rreq { - uint8_t rreq_type; /* AODV message type (1) */ - uint8_t rreq_flags; /* various flags */ - uint8_t rreq_zero0; /* reserved, set to zero */ - uint8_t rreq_hops; /* number of hops from originator */ - uint32_t rreq_id; /* request ID */ - uint32_t rreq_da; /* destination IPv4 address */ - uint32_t rreq_ds; /* destination sequence number */ - uint32_t rreq_oa; /* originator IPv4 address */ - uint32_t rreq_os; /* originator sequence number */ + nd_uint8_t rreq_type; /* AODV message type (1) */ + nd_uint8_t rreq_flags; /* various flags */ + nd_uint8_t rreq_zero0; /* reserved, set to zero */ + nd_uint8_t rreq_hops; /* number of hops from originator */ + nd_uint32_t rreq_id; /* request ID */ + nd_ipv4 rreq_da; /* destination IPv4 address */ + nd_uint32_t rreq_ds; /* destination sequence number */ + nd_ipv4 rreq_oa; /* originator IPv4 address */ + nd_uint32_t rreq_os; /* originator sequence number */ }; struct aodv_rreq6 { - uint8_t rreq_type; /* AODV message type (1) */ - uint8_t rreq_flags; /* various flags */ - uint8_t rreq_zero0; /* reserved, set to zero */ - uint8_t rreq_hops; /* number of hops from originator */ - uint32_t rreq_id; /* request ID */ - struct in6_addr rreq_da; /* destination IPv6 address */ - uint32_t rreq_ds; /* destination sequence number */ - struct in6_addr rreq_oa; /* originator IPv6 address */ - uint32_t rreq_os; /* originator sequence number */ + nd_uint8_t rreq_type; /* AODV message type (1) */ + nd_uint8_t rreq_flags; /* various flags */ + nd_uint8_t rreq_zero0; /* reserved, set to zero */ + nd_uint8_t rreq_hops; /* number of hops from originator */ + nd_uint32_t rreq_id; /* request ID */ + nd_ipv6 rreq_da; /* destination IPv6 address */ + nd_uint32_t rreq_ds; /* destination sequence number */ + nd_ipv6 rreq_oa; /* originator IPv6 address */ + nd_uint32_t rreq_os; /* originator sequence number */ }; struct aodv_rreq6_draft_01 { - uint8_t rreq_type; /* AODV message type (16) */ - uint8_t rreq_flags; /* various flags */ - uint8_t rreq_zero0; /* reserved, set to zero */ - uint8_t rreq_hops; /* number of hops from originator */ - uint32_t rreq_id; /* request ID */ - uint32_t rreq_ds; /* destination sequence number */ - uint32_t rreq_os; /* originator sequence number */ - struct in6_addr rreq_da; /* destination IPv6 address */ - struct in6_addr rreq_oa; /* originator IPv6 address */ + nd_uint8_t rreq_type; /* AODV message type (16) */ + nd_uint8_t rreq_flags; /* various flags */ + nd_uint8_t rreq_zero0; /* reserved, set to zero */ + nd_uint8_t rreq_hops; /* number of hops from originator */ + nd_uint32_t rreq_id; /* request ID */ + nd_uint32_t rreq_ds; /* destination sequence number */ + nd_uint32_t rreq_os; /* originator sequence number */ + nd_ipv6 rreq_da; /* destination IPv6 address */ + nd_ipv6 rreq_oa; /* originator IPv6 address */ }; #define RREQ_JOIN 0x80 /* join (reserved for multicast */ @@ -87,34 +87,34 @@ struct aodv_rreq6_draft_01 { #define RREQ_FLAGS_MASK 0xF8 /* mask for rreq_flags */ struct aodv_rrep { - uint8_t rrep_type; /* AODV message type (2) */ - uint8_t rrep_flags; /* various flags */ - uint8_t rrep_ps; /* prefix size */ - uint8_t rrep_hops; /* number of hops from o to d */ - uint32_t rrep_da; /* destination IPv4 address */ - uint32_t rrep_ds; /* destination sequence number */ - uint32_t rrep_oa; /* originator IPv4 address */ - uint32_t rrep_life; /* lifetime of this route */ + nd_uint8_t rrep_type; /* AODV message type (2) */ + nd_uint8_t rrep_flags; /* various flags */ + nd_uint8_t rrep_ps; /* prefix size */ + nd_uint8_t rrep_hops; /* number of hops from o to d */ + nd_ipv4 rrep_da; /* destination IPv4 address */ + nd_uint32_t rrep_ds; /* destination sequence number */ + nd_ipv4 rrep_oa; /* originator IPv4 address */ + nd_uint32_t rrep_life; /* lifetime of this route */ }; struct aodv_rrep6 { - uint8_t rrep_type; /* AODV message type (2) */ - uint8_t rrep_flags; /* various flags */ - uint8_t rrep_ps; /* prefix size */ - uint8_t rrep_hops; /* number of hops from o to d */ - struct in6_addr rrep_da; /* destination IPv6 address */ - uint32_t rrep_ds; /* destination sequence number */ - struct in6_addr rrep_oa; /* originator IPv6 address */ - uint32_t rrep_life; /* lifetime of this route */ + nd_uint8_t rrep_type; /* AODV message type (2) */ + nd_uint8_t rrep_flags; /* various flags */ + nd_uint8_t rrep_ps; /* prefix size */ + nd_uint8_t rrep_hops; /* number of hops from o to d */ + nd_ipv6 rrep_da; /* destination IPv6 address */ + nd_uint32_t rrep_ds; /* destination sequence number */ + nd_ipv6 rrep_oa; /* originator IPv6 address */ + nd_uint32_t rrep_life; /* lifetime of this route */ }; struct aodv_rrep6_draft_01 { - uint8_t rrep_type; /* AODV message type (17) */ - uint8_t rrep_flags; /* various flags */ - uint8_t rrep_ps; /* prefix size */ - uint8_t rrep_hops; /* number of hops from o to d */ - uint32_t rrep_ds; /* destination sequence number */ - struct in6_addr rrep_da; /* destination IPv6 address */ - struct in6_addr rrep_oa; /* originator IPv6 address */ - uint32_t rrep_life; /* lifetime of this route */ + nd_uint8_t rrep_type; /* AODV message type (17) */ + nd_uint8_t rrep_flags; /* various flags */ + nd_uint8_t rrep_ps; /* prefix size */ + nd_uint8_t rrep_hops; /* number of hops from o to d */ + nd_uint32_t rrep_ds; /* destination sequence number */ + nd_ipv6 rrep_da; /* destination IPv6 address */ + nd_ipv6 rrep_oa; /* originator IPv6 address */ + nd_uint32_t rrep_life; /* lifetime of this route */ }; #define RREP_REPAIR 0x80 /* repair (reserved for multicast */ @@ -123,31 +123,31 @@ struct aodv_rrep6_draft_01 { #define RREP_PREFIX_MASK 0x1F /* mask for prefix size */ struct rerr_unreach { - uint32_t u_da; /* IPv4 address */ - uint32_t u_ds; /* sequence number */ + nd_ipv4 u_da; /* IPv4 address */ + nd_uint32_t u_ds; /* sequence number */ }; struct rerr_unreach6 { - struct in6_addr u_da; /* IPv6 address */ - uint32_t u_ds; /* sequence number */ + nd_ipv6 u_da; /* IPv6 address */ + nd_uint32_t u_ds; /* sequence number */ }; struct rerr_unreach6_draft_01 { - struct in6_addr u_da; /* IPv6 address */ - uint32_t u_ds; /* sequence number */ + nd_ipv6 u_da; /* IPv6 address */ + nd_uint32_t u_ds; /* sequence number */ }; struct aodv_rerr { - uint8_t rerr_type; /* AODV message type (3 or 18) */ - uint8_t rerr_flags; /* various flags */ - uint8_t rerr_zero0; /* reserved, set to zero */ - uint8_t rerr_dc; /* destination count */ + nd_uint8_t rerr_type; /* AODV message type (3 or 18) */ + nd_uint8_t rerr_flags; /* various flags */ + nd_uint8_t rerr_zero0; /* reserved, set to zero */ + nd_uint8_t rerr_dc; /* destination count */ }; #define RERR_NODELETE 0x80 /* don't delete the link */ #define RERR_FLAGS_MASK 0x80 /* mask for rerr_flags */ struct aodv_rrep_ack { - uint8_t ra_type; - uint8_t ra_zero0; + nd_uint8_t ra_type; + nd_uint8_t ra_zero0; }; #define AODV_RREQ 1 /* route request */ @@ -161,13 +161,13 @@ struct aodv_rrep_ack { #define AODV_V6_DRAFT_01_RREP_ACK 19 /* IPV6 route response acknowledgment */ struct aodv_ext { - uint8_t type; /* extension type */ - uint8_t length; /* extension length */ + nd_uint8_t type; /* extension type */ + nd_uint8_t length; /* extension length */ }; struct aodv_hello { struct aodv_ext eh; /* extension header */ - uint8_t interval[4]; /* expect my next hello in + nd_uint32_t interval; /* expect my next hello in * (n) ms * NOTE: this is not aligned */ }; @@ -180,29 +180,31 @@ aodv_extension(netdissect_options *ndo, { const struct aodv_hello *ah; - ND_TCHECK(*ep); - switch (ep->type) { + ND_TCHECK_SIZE(ep); + switch (GET_U_1(ep->type)) { case AODV_EXT_HELLO: ah = (const struct aodv_hello *)(const void *)ep; - ND_TCHECK(*ah); + ND_TCHECK_SIZE(ah); if (length < sizeof(struct aodv_hello)) goto trunc; - if (ep->length < 4) { - ND_PRINT((ndo, "\n\text HELLO - bad length %u", ep->length)); + if (GET_U_1(ep->length) < 4) { + ND_PRINT("\n\text HELLO - bad length %u", + GET_U_1(ep->length)); break; } - ND_PRINT((ndo, "\n\text HELLO %ld ms", - (unsigned long)EXTRACT_32BITS(&ah->interval))); + ND_PRINT("\n\text HELLO %u ms", + GET_BE_U_4(ah->interval)); break; default: - ND_PRINT((ndo, "\n\text %u %u", ep->type, ep->length)); + ND_PRINT("\n\text %u %u", GET_U_1(ep->type), + GET_U_1(ep->length)); break; } return; trunc: - ND_PRINT((ndo, " [|hello]")); + nd_print_trunc(ndo); } static void @@ -211,29 +213,29 @@ aodv_rreq(netdissect_options *ndo, const u_char *dat, u_int length) u_int i; const struct aodv_rreq *ap = (const struct aodv_rreq *)dat; - ND_TCHECK(*ap); + ND_TCHECK_SIZE(ap); if (length < sizeof(*ap)) goto trunc; - ND_PRINT((ndo, " rreq %u %s%s%s%s%shops %u id 0x%08lx\n" - "\tdst %s seq %lu src %s seq %lu", length, - ap->rreq_type & RREQ_JOIN ? "[J]" : "", - ap->rreq_type & RREQ_REPAIR ? "[R]" : "", - ap->rreq_type & RREQ_GRAT ? "[G]" : "", - ap->rreq_type & RREQ_DEST ? "[D]" : "", - ap->rreq_type & RREQ_UNKNOWN ? "[U] " : " ", - ap->rreq_hops, - (unsigned long)EXTRACT_32BITS(&ap->rreq_id), - ipaddr_string(ndo, &ap->rreq_da), - (unsigned long)EXTRACT_32BITS(&ap->rreq_ds), - ipaddr_string(ndo, &ap->rreq_oa), - (unsigned long)EXTRACT_32BITS(&ap->rreq_os))); + ND_PRINT(" rreq %u %s%s%s%s%shops %u id 0x%08x\n" + "\tdst %s seq %u src %s seq %u", length, + GET_U_1(ap->rreq_type) & RREQ_JOIN ? "[J]" : "", + GET_U_1(ap->rreq_type) & RREQ_REPAIR ? "[R]" : "", + GET_U_1(ap->rreq_type) & RREQ_GRAT ? "[G]" : "", + GET_U_1(ap->rreq_type) & RREQ_DEST ? "[D]" : "", + GET_U_1(ap->rreq_type) & RREQ_UNKNOWN ? "[U] " : " ", + GET_U_1(ap->rreq_hops), + GET_BE_U_4(ap->rreq_id), + GET_IPADDR_STRING(ap->rreq_da), + GET_BE_U_4(ap->rreq_ds), + GET_IPADDR_STRING(ap->rreq_oa), + GET_BE_U_4(ap->rreq_os)); i = length - sizeof(*ap); if (i >= sizeof(struct aodv_ext)) aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); return; trunc: - ND_PRINT((ndo, " [|rreq")); + nd_print_trunc(ndo); } static void @@ -242,26 +244,26 @@ aodv_rrep(netdissect_options *ndo, const u_char *dat, u_int length) u_int i; const struct aodv_rrep *ap = (const struct aodv_rrep *)dat; - ND_TCHECK(*ap); + ND_TCHECK_SIZE(ap); if (length < sizeof(*ap)) goto trunc; - ND_PRINT((ndo, " rrep %u %s%sprefix %u hops %u\n" - "\tdst %s dseq %lu src %s %lu ms", length, - ap->rrep_type & RREP_REPAIR ? "[R]" : "", - ap->rrep_type & RREP_ACK ? "[A] " : " ", - ap->rrep_ps & RREP_PREFIX_MASK, - ap->rrep_hops, - ipaddr_string(ndo, &ap->rrep_da), - (unsigned long)EXTRACT_32BITS(&ap->rrep_ds), - ipaddr_string(ndo, &ap->rrep_oa), - (unsigned long)EXTRACT_32BITS(&ap->rrep_life))); + ND_PRINT(" rrep %u %s%sprefix %u hops %u\n" + "\tdst %s dseq %u src %s %u ms", length, + GET_U_1(ap->rrep_type) & RREP_REPAIR ? "[R]" : "", + GET_U_1(ap->rrep_type) & RREP_ACK ? "[A] " : " ", + GET_U_1(ap->rrep_ps) & RREP_PREFIX_MASK, + GET_U_1(ap->rrep_hops), + GET_IPADDR_STRING(ap->rrep_da), + GET_BE_U_4(ap->rrep_ds), + GET_IPADDR_STRING(ap->rrep_oa), + GET_BE_U_4(ap->rrep_life)); i = length - sizeof(*ap); if (i >= sizeof(struct aodv_ext)) aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); return; trunc: - ND_PRINT((ndo, " [|rreq")); + nd_print_trunc(ndo); } static void @@ -271,27 +273,27 @@ aodv_rerr(netdissect_options *ndo, const u_char *dat, u_int length) const struct aodv_rerr *ap = (const struct aodv_rerr *)dat; const struct rerr_unreach *dp; - ND_TCHECK(*ap); + ND_TCHECK_SIZE(ap); if (length < sizeof(*ap)) goto trunc; - ND_PRINT((ndo, " rerr %s [items %u] [%u]:", - ap->rerr_flags & RERR_NODELETE ? "[D]" : "", - ap->rerr_dc, length)); + ND_PRINT(" rerr %s [items %u] [%u]:", + GET_U_1(ap->rerr_flags) & RERR_NODELETE ? "[D]" : "", + GET_U_1(ap->rerr_dc), length); dp = (const struct rerr_unreach *)(dat + sizeof(*ap)); i = length - sizeof(*ap); - for (dc = ap->rerr_dc; dc != 0; dc--) { - ND_TCHECK(*dp); + for (dc = GET_U_1(ap->rerr_dc); dc != 0; dc--) { + ND_TCHECK_SIZE(dp); if (i < sizeof(*dp)) goto trunc; - ND_PRINT((ndo, " {%s}(%ld)", ipaddr_string(ndo, &dp->u_da), - (unsigned long)EXTRACT_32BITS(&dp->u_ds))); + ND_PRINT(" {%s}(%u)", GET_IPADDR_STRING(dp->u_da), + GET_BE_U_4(dp->u_ds)); dp++; i -= sizeof(*dp); } return; trunc: - ND_PRINT((ndo, "[|rerr]")); + nd_print_trunc(ndo); } static void @@ -300,29 +302,29 @@ aodv_v6_rreq(netdissect_options *ndo, const u_char *dat, u_int length) u_int i; const struct aodv_rreq6 *ap = (const struct aodv_rreq6 *)dat; - ND_TCHECK(*ap); + ND_TCHECK_SIZE(ap); if (length < sizeof(*ap)) goto trunc; - ND_PRINT((ndo, " v6 rreq %u %s%s%s%s%shops %u id 0x%08lx\n" - "\tdst %s seq %lu src %s seq %lu", length, - ap->rreq_type & RREQ_JOIN ? "[J]" : "", - ap->rreq_type & RREQ_REPAIR ? "[R]" : "", - ap->rreq_type & RREQ_GRAT ? "[G]" : "", - ap->rreq_type & RREQ_DEST ? "[D]" : "", - ap->rreq_type & RREQ_UNKNOWN ? "[U] " : " ", - ap->rreq_hops, - (unsigned long)EXTRACT_32BITS(&ap->rreq_id), - ip6addr_string(ndo, &ap->rreq_da), - (unsigned long)EXTRACT_32BITS(&ap->rreq_ds), - ip6addr_string(ndo, &ap->rreq_oa), - (unsigned long)EXTRACT_32BITS(&ap->rreq_os))); + ND_PRINT(" v6 rreq %u %s%s%s%s%shops %u id 0x%08x\n" + "\tdst %s seq %u src %s seq %u", length, + GET_U_1(ap->rreq_type) & RREQ_JOIN ? "[J]" : "", + GET_U_1(ap->rreq_type) & RREQ_REPAIR ? "[R]" : "", + GET_U_1(ap->rreq_type) & RREQ_GRAT ? "[G]" : "", + GET_U_1(ap->rreq_type) & RREQ_DEST ? "[D]" : "", + GET_U_1(ap->rreq_type) & RREQ_UNKNOWN ? "[U] " : " ", + GET_U_1(ap->rreq_hops), + GET_BE_U_4(ap->rreq_id), + GET_IP6ADDR_STRING(ap->rreq_da), + GET_BE_U_4(ap->rreq_ds), + GET_IP6ADDR_STRING(ap->rreq_oa), + GET_BE_U_4(ap->rreq_os)); i = length - sizeof(*ap); if (i >= sizeof(struct aodv_ext)) aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); return; trunc: - ND_PRINT((ndo, " [|rreq")); + nd_print_trunc(ndo); } static void @@ -331,26 +333,26 @@ aodv_v6_rrep(netdissect_options *ndo, const u_char *dat, u_int length) u_int i; const struct aodv_rrep6 *ap = (const struct aodv_rrep6 *)dat; - ND_TCHECK(*ap); + ND_TCHECK_SIZE(ap); if (length < sizeof(*ap)) goto trunc; - ND_PRINT((ndo, " rrep %u %s%sprefix %u hops %u\n" - "\tdst %s dseq %lu src %s %lu ms", length, - ap->rrep_type & RREP_REPAIR ? "[R]" : "", - ap->rrep_type & RREP_ACK ? "[A] " : " ", - ap->rrep_ps & RREP_PREFIX_MASK, - ap->rrep_hops, - ip6addr_string(ndo, &ap->rrep_da), - (unsigned long)EXTRACT_32BITS(&ap->rrep_ds), - ip6addr_string(ndo, &ap->rrep_oa), - (unsigned long)EXTRACT_32BITS(&ap->rrep_life))); + ND_PRINT(" rrep %u %s%sprefix %u hops %u\n" + "\tdst %s dseq %u src %s %u ms", length, + GET_U_1(ap->rrep_type) & RREP_REPAIR ? "[R]" : "", + GET_U_1(ap->rrep_type) & RREP_ACK ? "[A] " : " ", + GET_U_1(ap->rrep_ps) & RREP_PREFIX_MASK, + GET_U_1(ap->rrep_hops), + GET_IP6ADDR_STRING(ap->rrep_da), + GET_BE_U_4(ap->rrep_ds), + GET_IP6ADDR_STRING(ap->rrep_oa), + GET_BE_U_4(ap->rrep_life)); i = length - sizeof(*ap); if (i >= sizeof(struct aodv_ext)) aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); return; trunc: - ND_PRINT((ndo, " [|rreq")); + nd_print_trunc(ndo); } static void @@ -360,27 +362,27 @@ aodv_v6_rerr(netdissect_options *ndo, const u_char *dat, u_int length) const struct aodv_rerr *ap = (const struct aodv_rerr *)dat; const struct rerr_unreach6 *dp6; - ND_TCHECK(*ap); + ND_TCHECK_SIZE(ap); if (length < sizeof(*ap)) goto trunc; - ND_PRINT((ndo, " rerr %s [items %u] [%u]:", - ap->rerr_flags & RERR_NODELETE ? "[D]" : "", - ap->rerr_dc, length)); + ND_PRINT(" rerr %s [items %u] [%u]:", + GET_U_1(ap->rerr_flags) & RERR_NODELETE ? "[D]" : "", + GET_U_1(ap->rerr_dc), length); dp6 = (const struct rerr_unreach6 *)(const void *)(ap + 1); i = length - sizeof(*ap); - for (dc = ap->rerr_dc; dc != 0; dc--) { - ND_TCHECK(*dp6); + for (dc = GET_U_1(ap->rerr_dc); dc != 0; dc--) { + ND_TCHECK_SIZE(dp6); if (i < sizeof(*dp6)) goto trunc; - ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da), - (unsigned long)EXTRACT_32BITS(&dp6->u_ds))); + ND_PRINT(" {%s}(%u)", GET_IP6ADDR_STRING(dp6->u_da), + GET_BE_U_4(dp6->u_ds)); dp6++; i -= sizeof(*dp6); } return; trunc: - ND_PRINT((ndo, "[|rerr]")); + nd_print_trunc(ndo); } static void @@ -389,29 +391,29 @@ aodv_v6_draft_01_rreq(netdissect_options *ndo, const u_char *dat, u_int length) u_int i; const struct aodv_rreq6_draft_01 *ap = (const struct aodv_rreq6_draft_01 *)dat; - ND_TCHECK(*ap); + ND_TCHECK_SIZE(ap); if (length < sizeof(*ap)) goto trunc; - ND_PRINT((ndo, " rreq %u %s%s%s%s%shops %u id 0x%08lx\n" - "\tdst %s seq %lu src %s seq %lu", length, - ap->rreq_type & RREQ_JOIN ? "[J]" : "", - ap->rreq_type & RREQ_REPAIR ? "[R]" : "", - ap->rreq_type & RREQ_GRAT ? "[G]" : "", - ap->rreq_type & RREQ_DEST ? "[D]" : "", - ap->rreq_type & RREQ_UNKNOWN ? "[U] " : " ", - ap->rreq_hops, - (unsigned long)EXTRACT_32BITS(&ap->rreq_id), - ip6addr_string(ndo, &ap->rreq_da), - (unsigned long)EXTRACT_32BITS(&ap->rreq_ds), - ip6addr_string(ndo, &ap->rreq_oa), - (unsigned long)EXTRACT_32BITS(&ap->rreq_os))); + ND_PRINT(" rreq %u %s%s%s%s%shops %u id 0x%08x\n" + "\tdst %s seq %u src %s seq %u", length, + GET_U_1(ap->rreq_type) & RREQ_JOIN ? "[J]" : "", + GET_U_1(ap->rreq_type) & RREQ_REPAIR ? "[R]" : "", + GET_U_1(ap->rreq_type) & RREQ_GRAT ? "[G]" : "", + GET_U_1(ap->rreq_type) & RREQ_DEST ? "[D]" : "", + GET_U_1(ap->rreq_type) & RREQ_UNKNOWN ? "[U] " : " ", + GET_U_1(ap->rreq_hops), + GET_BE_U_4(ap->rreq_id), + GET_IP6ADDR_STRING(ap->rreq_da), + GET_BE_U_4(ap->rreq_ds), + GET_IP6ADDR_STRING(ap->rreq_oa), + GET_BE_U_4(ap->rreq_os)); i = length - sizeof(*ap); if (i >= sizeof(struct aodv_ext)) aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); return; trunc: - ND_PRINT((ndo, " [|rreq")); + nd_print_trunc(ndo); } static void @@ -420,26 +422,26 @@ aodv_v6_draft_01_rrep(netdissect_options *ndo, const u_char *dat, u_int length) u_int i; const struct aodv_rrep6_draft_01 *ap = (const struct aodv_rrep6_draft_01 *)dat; - ND_TCHECK(*ap); + ND_TCHECK_SIZE(ap); if (length < sizeof(*ap)) goto trunc; - ND_PRINT((ndo, " rrep %u %s%sprefix %u hops %u\n" - "\tdst %s dseq %lu src %s %lu ms", length, - ap->rrep_type & RREP_REPAIR ? "[R]" : "", - ap->rrep_type & RREP_ACK ? "[A] " : " ", - ap->rrep_ps & RREP_PREFIX_MASK, - ap->rrep_hops, - ip6addr_string(ndo, &ap->rrep_da), - (unsigned long)EXTRACT_32BITS(&ap->rrep_ds), - ip6addr_string(ndo, &ap->rrep_oa), - (unsigned long)EXTRACT_32BITS(&ap->rrep_life))); + ND_PRINT(" rrep %u %s%sprefix %u hops %u\n" + "\tdst %s dseq %u src %s %u ms", length, + GET_U_1(ap->rrep_type) & RREP_REPAIR ? "[R]" : "", + GET_U_1(ap->rrep_type) & RREP_ACK ? "[A] " : " ", + GET_U_1(ap->rrep_ps) & RREP_PREFIX_MASK, + GET_U_1(ap->rrep_hops), + GET_IP6ADDR_STRING(ap->rrep_da), + GET_BE_U_4(ap->rrep_ds), + GET_IP6ADDR_STRING(ap->rrep_oa), + GET_BE_U_4(ap->rrep_life)); i = length - sizeof(*ap); if (i >= sizeof(struct aodv_ext)) aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); return; trunc: - ND_PRINT((ndo, " [|rreq")); + nd_print_trunc(ndo); } static void @@ -449,27 +451,27 @@ aodv_v6_draft_01_rerr(netdissect_options *ndo, const u_char *dat, u_int length) const struct aodv_rerr *ap = (const struct aodv_rerr *)dat; const struct rerr_unreach6_draft_01 *dp6; - ND_TCHECK(*ap); + ND_TCHECK_SIZE(ap); if (length < sizeof(*ap)) goto trunc; - ND_PRINT((ndo, " rerr %s [items %u] [%u]:", - ap->rerr_flags & RERR_NODELETE ? "[D]" : "", - ap->rerr_dc, length)); + ND_PRINT(" rerr %s [items %u] [%u]:", + GET_U_1(ap->rerr_flags) & RERR_NODELETE ? "[D]" : "", + GET_U_1(ap->rerr_dc), length); dp6 = (const struct rerr_unreach6_draft_01 *)(const void *)(ap + 1); i = length - sizeof(*ap); - for (dc = ap->rerr_dc; dc != 0; dc--) { - ND_TCHECK(*dp6); + for (dc = GET_U_1(ap->rerr_dc); dc != 0; dc--) { + ND_TCHECK_SIZE(dp6); if (i < sizeof(*dp6)) goto trunc; - ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da), - (unsigned long)EXTRACT_32BITS(&dp6->u_ds))); + ND_PRINT(" {%s}(%u)", GET_IP6ADDR_STRING(dp6->u_da), + GET_BE_U_4(dp6->u_ds)); dp6++; i -= sizeof(*dp6); } return; trunc: - ND_PRINT((ndo, "[|rerr]")); + nd_print_trunc(ndo); } void @@ -478,13 +480,13 @@ aodv_print(netdissect_options *ndo, { uint8_t msg_type; + ndo->ndo_protocol = "aodv"; /* * The message type is the first byte; make sure we have it * and then fetch it. */ - ND_TCHECK(*dat); - msg_type = *dat; - ND_PRINT((ndo, " aodv")); + msg_type = GET_U_1(dat); + ND_PRINT(" aodv"); switch (msg_type) { @@ -510,7 +512,7 @@ aodv_print(netdissect_options *ndo, break; case AODV_RREP_ACK: - ND_PRINT((ndo, " rrep-ack %u", length)); + ND_PRINT(" rrep-ack %u", length); break; case AODV_V6_DRAFT_01_RREQ: @@ -526,14 +528,10 @@ aodv_print(netdissect_options *ndo, break; case AODV_V6_DRAFT_01_RREP_ACK: - ND_PRINT((ndo, " rrep-ack %u", length)); + ND_PRINT(" rrep-ack %u", length); break; default: - ND_PRINT((ndo, " type %u %u", msg_type, length)); + ND_PRINT(" type %u %u", msg_type, length); } - return; - -trunc: - ND_PRINT((ndo, " [|aodv]")); } diff --git a/contrib/tcpdump/print-aoe.c b/contrib/tcpdump/print-aoe.c index fcb75264fc..0cd4299a7a 100644 --- a/contrib/tcpdump/print-aoe.c +++ b/contrib/tcpdump/print-aoe.c @@ -27,20 +27,21 @@ /* \summary: ATA over Ethernet (AoE) protocol printer */ -/* specification: http://brantleycoilecompany.com/AoEr11.pdf */ +/* specification: + * https://web.archive.org/web/20161025044402/http://brantleycoilecompany.com/AoEr11.pdf + */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" #include "addrtoname.h" -#include "ether.h" -static const char tstr[] = " [|aoe]"; #define AOE_V1 1 #define ATA_SECTOR_SIZE 512 @@ -71,8 +72,8 @@ static const struct tok cmdcode_str[] = { static const struct tok aoev1_flag_str[] = { { AOEV1_FLAG_R, "Response" }, { AOEV1_FLAG_E, "Error" }, - { 0x02, "MBZ-0x02" }, - { 0x01, "MBZ-0x01" }, + { 0x02, "MBZ-1" }, + { 0x01, "MBZ-0" }, { 0, NULL } }; @@ -91,13 +92,13 @@ static const struct tok aoev1_errcode_str[] = { #define AOEV1_AFLAG_A 0x02 #define AOEV1_AFLAG_W 0x01 -static const struct tok aoev1_aflag_str[] = { - { 0x08, "MBZ-0x08" }, +static const struct tok aoev1_aflag_bitmap_str[] = { + { 0x80, "MBZ-7" }, { AOEV1_AFLAG_E, "Ext48" }, - { 0x06, "MBZ-0x06" }, + { 0x20, "MBZ-5" }, { AOEV1_AFLAG_D, "Device" }, - { 0x04, "MBZ-0x04" }, - { 0x03, "MBZ-0x03" }, + { 0x08, "MBZ-3" }, + { 0x04, "MBZ-2" }, { AOEV1_AFLAG_A, "Async" }, { AOEV1_AFLAG_W, "Write" }, { 0, NULL } @@ -141,244 +142,231 @@ static const struct tok aoev1_rcmd_str[] = { static void aoev1_issue_print(netdissect_options *ndo, - const u_char *cp, const u_int len) + const u_char *cp, u_int len) { - const u_char *ep = cp + len; - if (len < AOEV1_ISSUE_ARG_LEN) goto invalid; /* AFlags */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, "\n\tAFlags: [%s]", bittok2str(aoev1_aflag_str, "none", *cp))); + ND_PRINT("\n\tAFlags: [%s]", + bittok2str(aoev1_aflag_bitmap_str, "none", GET_U_1(cp))); cp += 1; + len -= 1; /* Err/Feature */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, ", Err/Feature: %u", *cp)); + ND_PRINT(", Err/Feature: %u", GET_U_1(cp)); cp += 1; + len -= 1; /* Sector Count (not correlated with the length) */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, ", Sector Count: %u", *cp)); + ND_PRINT(", Sector Count: %u", GET_U_1(cp)); cp += 1; + len -= 1; /* Cmd/Status */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, ", Cmd/Status: %u", *cp)); + ND_PRINT(", Cmd/Status: %u", GET_U_1(cp)); cp += 1; + len -= 1; /* lba0 */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, "\n\tlba0: %u", *cp)); + ND_PRINT("\n\tlba0: %u", GET_U_1(cp)); cp += 1; + len -= 1; /* lba1 */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, ", lba1: %u", *cp)); + ND_PRINT(", lba1: %u", GET_U_1(cp)); cp += 1; + len -= 1; /* lba2 */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, ", lba2: %u", *cp)); + ND_PRINT(", lba2: %u", GET_U_1(cp)); cp += 1; + len -= 1; /* lba3 */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, ", lba3: %u", *cp)); + ND_PRINT(", lba3: %u", GET_U_1(cp)); cp += 1; + len -= 1; /* lba4 */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, ", lba4: %u", *cp)); + ND_PRINT(", lba4: %u", GET_U_1(cp)); cp += 1; + len -= 1; /* lba5 */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, ", lba5: %u", *cp)); + ND_PRINT(", lba5: %u", GET_U_1(cp)); cp += 1; + len -= 1; /* Reserved */ - ND_TCHECK2(*cp, 2); + ND_TCHECK_2(cp); cp += 2; + len -= 2; /* Data */ - if (len > AOEV1_ISSUE_ARG_LEN) - ND_PRINT((ndo, "\n\tData: %u bytes", len - AOEV1_ISSUE_ARG_LEN)); + if (len) + ND_PRINT("\n\tData: %u bytes", len); return; invalid: - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp, ep - cp); - return; -trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } static void aoev1_query_print(netdissect_options *ndo, - const u_char *cp, const u_int len) + const u_char *cp, u_int len) { - const u_char *ep = cp + len; uint16_t cslen; if (len < AOEV1_QUERY_ARG_LEN) goto invalid; /* Buffer Count */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, "\n\tBuffer Count: %u", EXTRACT_16BITS(cp))); + ND_PRINT("\n\tBuffer Count: %u", GET_BE_U_2(cp)); cp += 2; + len -= 2; /* Firmware Version */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, ", Firmware Version: %u", EXTRACT_16BITS(cp))); + ND_PRINT(", Firmware Version: %u", GET_BE_U_2(cp)); cp += 2; + len -= 2; /* Sector Count */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, ", Sector Count: %u", *cp)); + ND_PRINT(", Sector Count: %u", GET_U_1(cp)); cp += 1; + len -= 1; /* AoE/CCmd */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, ", AoE: %u, CCmd: %s", (*cp & 0xF0) >> 4, - tok2str(aoev1_ccmd_str, "Unknown (0x02x)", *cp & 0x0F))); + ND_PRINT(", AoE: %u, CCmd: %s", (GET_U_1(cp) & 0xF0) >> 4, + tok2str(aoev1_ccmd_str, "Unknown (0x02x)", GET_U_1(cp) & 0x0F)); cp += 1; + len -= 1; /* Config String Length */ - ND_TCHECK2(*cp, 2); - cslen = EXTRACT_16BITS(cp); + cslen = GET_BE_U_2(cp); cp += 2; - if (cslen > AOEV1_MAX_CONFSTR_LEN || AOEV1_QUERY_ARG_LEN + cslen > len) + len -= 2; + if (cslen > AOEV1_MAX_CONFSTR_LEN || cslen > len) goto invalid; /* Config String */ - ND_TCHECK2(*cp, cslen); if (cslen) { - ND_PRINT((ndo, "\n\tConfig String (length %u): ", cslen)); - if (fn_printn(ndo, cp, cslen, ndo->ndo_snapend)) - goto trunc; + ND_PRINT("\n\tConfig String (length %u): ", cslen); + (void)nd_printn(ndo, cp, cslen, NULL); } return; invalid: - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp, ep - cp); - return; -trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } static void aoev1_mac_print(netdissect_options *ndo, - const u_char *cp, const u_int len) + const u_char *cp, u_int len) { - const u_char *ep = cp + len; uint8_t dircount, i; if (len < AOEV1_MAC_ARG_LEN) goto invalid; /* Reserved */ - ND_TCHECK2(*cp, 1); cp += 1; + len -= 1; /* MCmd */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, "\n\tMCmd: %s", tok2str(aoev1_mcmd_str, "Unknown (0x%02x)", *cp))); + ND_PRINT("\n\tMCmd: %s", + tok2str(aoev1_mcmd_str, "Unknown (0x%02x)", GET_U_1(cp))); cp += 1; + len -= 1; /* MError */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, ", MError: %s", tok2str(aoev1_merror_str, "Unknown (0x%02x)", *cp))); + ND_PRINT(", MError: %s", + tok2str(aoev1_merror_str, "Unknown (0x%02x)", GET_U_1(cp))); cp += 1; + len -= 1; /* Dir Count */ - ND_TCHECK2(*cp, 1); - dircount = *cp; + dircount = GET_U_1(cp); cp += 1; - ND_PRINT((ndo, ", Dir Count: %u", dircount)); - if (AOEV1_MAC_ARG_LEN + dircount * 8 > len) + len -= 1; + ND_PRINT(", Dir Count: %u", dircount); + if (dircount * 8U > len) goto invalid; /* directives */ for (i = 0; i < dircount; i++) { /* Reserved */ - ND_TCHECK2(*cp, 1); cp += 1; + len -= 1; /* DCmd */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, "\n\t DCmd: %s", tok2str(aoev1_dcmd_str, "Unknown (0x%02x)", *cp))); + ND_PRINT("\n\t DCmd: %s", + tok2str(aoev1_dcmd_str, "Unknown (0x%02x)", GET_U_1(cp))); cp += 1; + len -= 1; /* Ethernet Address */ - ND_TCHECK2(*cp, ETHER_ADDR_LEN); - ND_PRINT((ndo, ", Ethernet Address: %s", etheraddr_string(ndo, cp))); - cp += ETHER_ADDR_LEN; + ND_PRINT(", Ethernet Address: %s", GET_ETHERADDR_STRING(cp)); + cp += MAC_ADDR_LEN; + len -= MAC_ADDR_LEN; } return; invalid: - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp, ep - cp); - return; -trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } static void aoev1_reserve_print(netdissect_options *ndo, - const u_char *cp, const u_int len) + const u_char *cp, u_int len) { - const u_char *ep = cp + len; uint8_t nmacs, i; - if (len < AOEV1_RESERVE_ARG_LEN || (len - AOEV1_RESERVE_ARG_LEN) % ETHER_ADDR_LEN) + if (len < AOEV1_RESERVE_ARG_LEN || (len - AOEV1_RESERVE_ARG_LEN) % MAC_ADDR_LEN) goto invalid; /* RCmd */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, "\n\tRCmd: %s", tok2str(aoev1_rcmd_str, "Unknown (0x%02x)", *cp))); + ND_PRINT("\n\tRCmd: %s", + tok2str(aoev1_rcmd_str, "Unknown (0x%02x)", GET_U_1(cp))); cp += 1; + len -= 1; /* NMacs (correlated with the length) */ - ND_TCHECK2(*cp, 1); - nmacs = *cp; + nmacs = GET_U_1(cp); cp += 1; - ND_PRINT((ndo, ", NMacs: %u", nmacs)); - if (AOEV1_RESERVE_ARG_LEN + nmacs * ETHER_ADDR_LEN != len) + len -= 1; + ND_PRINT(", NMacs: %u", nmacs); + if (nmacs * MAC_ADDR_LEN != len) goto invalid; /* addresses */ for (i = 0; i < nmacs; i++) { - ND_TCHECK2(*cp, ETHER_ADDR_LEN); - ND_PRINT((ndo, "\n\tEthernet Address %u: %s", i, etheraddr_string(ndo, cp))); - cp += ETHER_ADDR_LEN; + ND_PRINT("\n\tEthernet Address %u: %s", i, GET_ETHERADDR_STRING(cp)); + cp += MAC_ADDR_LEN; + len -= MAC_ADDR_LEN; } return; invalid: - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp, ep - cp); - return; -trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } /* cp points to the Ver/Flags octet */ static void aoev1_print(netdissect_options *ndo, - const u_char *cp, const u_int len) + const u_char *cp, u_int len) { - const u_char *ep = cp + len; uint8_t flags, command; - void (*cmd_decoder)(netdissect_options *, const u_char *, const u_int); + void (*cmd_decoder)(netdissect_options *, const u_char *, u_int); if (len < AOEV1_COMMON_HDR_LEN) goto invalid; /* Flags */ - ND_TCHECK2(*cp, 1); - flags = *cp & 0x0F; - ND_PRINT((ndo, ", Flags: [%s]", bittok2str(aoev1_flag_str, "none", flags))); + flags = GET_U_1(cp) & 0x0F; + ND_PRINT(", Flags: [%s]", bittok2str(aoev1_flag_str, "none", flags)); cp += 1; + len -= 1; if (! ndo->ndo_vflag) return; /* Error */ - ND_TCHECK2(*cp, 1); if (flags & AOEV1_FLAG_E) - ND_PRINT((ndo, "\n\tError: %s", tok2str(aoev1_errcode_str, "Invalid (%u)", *cp))); + ND_PRINT("\n\tError: %s", + tok2str(aoev1_errcode_str, "Invalid (%u)", GET_U_1(cp))); cp += 1; + len -= 1; /* Major */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, "\n\tMajor: 0x%04x", EXTRACT_16BITS(cp))); + ND_PRINT("\n\tMajor: 0x%04x", GET_BE_U_2(cp)); cp += 2; + len -= 2; /* Minor */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, ", Minor: 0x%02x", *cp)); + ND_PRINT(", Minor: 0x%02x", GET_U_1(cp)); cp += 1; + len -= 1; /* Command */ - ND_TCHECK2(*cp, 1); - command = *cp; + command = GET_U_1(cp); cp += 1; - ND_PRINT((ndo, ", Command: %s", tok2str(cmdcode_str, "Unknown (0x%02x)", command))); + len -= 1; + ND_PRINT(", Command: %s", tok2str(cmdcode_str, "Unknown (0x%02x)", command)); /* Tag */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, ", Tag: 0x%08x", EXTRACT_32BITS(cp))); + ND_PRINT(", Tag: 0x%08x", GET_BE_U_4(cp)); cp += 4; + len -= 4; /* Arg */ cmd_decoder = command == AOEV1_CMD_ISSUE_ATA_COMMAND ? aoev1_issue_print : @@ -387,33 +375,29 @@ aoev1_print(netdissect_options *ndo, command == AOEV1_CMD_RESERVE_RELEASE ? aoev1_reserve_print : NULL; if (cmd_decoder != NULL) - cmd_decoder(ndo, cp, len - AOEV1_COMMON_HDR_LEN); + cmd_decoder(ndo, cp, len); return; invalid: - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp, ep - cp); - return; -trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } void aoe_print(netdissect_options *ndo, const u_char *cp, const u_int len) { - const u_char *ep = cp + len; uint8_t ver; - ND_PRINT((ndo, "AoE length %u", len)); + ndo->ndo_protocol = "aoe"; + ND_PRINT("AoE length %u", len); if (len < 1) goto invalid; /* Ver/Flags */ - ND_TCHECK2(*cp, 1); - ver = (*cp & 0xF0) >> 4; + ver = (GET_U_1(cp) & 0xF0) >> 4; /* Don't advance cp yet: low order 4 bits are version-specific. */ - ND_PRINT((ndo, ", Ver %u", ver)); + ND_PRINT(", Ver %u", ver); switch (ver) { case AOE_V1: @@ -423,10 +407,7 @@ aoe_print(netdissect_options *ndo, return; invalid: - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp, ep - cp); - return; -trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } diff --git a/contrib/tcpdump/print-ap1394.c b/contrib/tcpdump/print-ap1394.c index 79401cba0e..b1988f2706 100644 --- a/contrib/tcpdump/print-ap1394.c +++ b/contrib/tcpdump/print-ap1394.c @@ -22,11 +22,12 @@ /* \summary: Apple IP-over-IEEE 1394 printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" #include "addrtoname.h" @@ -37,9 +38,9 @@ */ #define FIREWIRE_EUI64_LEN 8 struct firewire_header { - u_char firewire_dhost[FIREWIRE_EUI64_LEN]; - u_char firewire_shost[FIREWIRE_EUI64_LEN]; - u_short firewire_type; + nd_byte firewire_dhost[FIREWIRE_EUI64_LEN]; + nd_byte firewire_shost[FIREWIRE_EUI64_LEN]; + nd_uint16_t firewire_type; }; /* @@ -52,31 +53,31 @@ struct firewire_header { static const char * fwaddr_string(netdissect_options *ndo, const u_char *addr) { - return (linkaddr_string(ndo, addr, LINKADDR_IEEE1394, FIREWIRE_EUI64_LEN)); + return GET_LINKADDR_STRING(addr, LINKADDR_IEEE1394, FIREWIRE_EUI64_LEN); } -static inline void -ap1394_hdr_print(netdissect_options *ndo, register const u_char *bp, u_int length) +static void +ap1394_hdr_print(netdissect_options *ndo, const u_char *bp, u_int length) { - register const struct firewire_header *fp; + const struct firewire_header *fp; uint16_t firewire_type; fp = (const struct firewire_header *)bp; - ND_PRINT((ndo, "%s > %s", + ND_PRINT("%s > %s", fwaddr_string(ndo, fp->firewire_shost), - fwaddr_string(ndo, fp->firewire_dhost))); + fwaddr_string(ndo, fp->firewire_dhost)); - firewire_type = EXTRACT_16BITS(&fp->firewire_type); + firewire_type = GET_BE_U_2(fp->firewire_type); if (!ndo->ndo_qflag) { - ND_PRINT((ndo, ", ethertype %s (0x%04x)", + ND_PRINT(", ethertype %s (0x%04x)", tok2str(ethertype_values,"Unknown", firewire_type), - firewire_type)); + firewire_type); } else { - ND_PRINT((ndo, ", %s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", firewire_type))); + ND_PRINT(", %s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", firewire_type)); } - ND_PRINT((ndo, ", length %u: ", length)); + ND_PRINT(", length %u: ", length); } /* @@ -85,7 +86,7 @@ ap1394_hdr_print(netdissect_options *ndo, register const u_char *bp, u_int lengt * 'h->len' is the length of the packet off the wire, and 'h->caplen' * is the number of bytes actually captured. */ -u_int +void ap1394_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { u_int length = h->len; @@ -94,10 +95,9 @@ ap1394_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_ch u_short ether_type; struct lladdr_info src, dst; - if (caplen < FIREWIRE_HDRLEN) { - ND_PRINT((ndo, "[|ap1394]")); - return FIREWIRE_HDRLEN; - } + ndo->ndo_protocol = "ap1394"; + ND_TCHECK_LEN(p, FIREWIRE_HDRLEN); + ndo->ndo_ll_hdr_len += FIREWIRE_HDRLEN; if (ndo->ndo_eflag) ap1394_hdr_print(ndo, p, length); @@ -107,7 +107,7 @@ ap1394_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_ch fp = (const struct firewire_header *)p; p += FIREWIRE_HDRLEN; - ether_type = EXTRACT_16BITS(&fp->firewire_type); + ether_type = GET_BE_U_2(fp->firewire_type); src.addr = fp->firewire_shost; src.addr_string = fwaddr_string; dst.addr = fp->firewire_dhost; @@ -120,6 +120,4 @@ ap1394_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_ch if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); } - - return FIREWIRE_HDRLEN; } diff --git a/contrib/tcpdump/print-arcnet.c b/contrib/tcpdump/print-arcnet.c index abc19b8070..5f6aaf9c43 100644 --- a/contrib/tcpdump/print-arcnet.c +++ b/contrib/tcpdump/print-arcnet.c @@ -24,10 +24,10 @@ /* \summary: Attached Resource Computer NETwork (ARCNET) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "extract.h" @@ -41,22 +41,22 @@ * as given to interface code. */ struct arc_header { - uint8_t arc_shost; - uint8_t arc_dhost; - uint8_t arc_type; + nd_uint8_t arc_shost; + nd_uint8_t arc_dhost; + nd_uint8_t arc_type; /* * only present for newstyle encoding with LL fragmentation. * Don't use sizeof(anything), use ARC_HDR{,NEW}LEN instead. */ - uint8_t arc_flag; - uint16_t arc_seqid; + nd_uint8_t arc_flag; + nd_uint16_t arc_seqid; /* * only present in exception packets (arc_flag == 0xff) */ - uint8_t arc_type2; /* same as arc_type */ - uint8_t arc_flag2; /* real flag value */ - uint16_t arc_seqid2; /* real seqid value */ + nd_uint8_t arc_type2; /* same as arc_type */ + nd_uint8_t arc_flag2; /* real flag value */ + nd_uint16_t arc_seqid2; /* real seqid value */ }; #define ARC_HDRLEN 3 @@ -85,17 +85,17 @@ struct arc_header { * never presents packets that look like exception frames. */ struct arc_linux_header { - uint8_t arc_shost; - uint8_t arc_dhost; - uint16_t arc_offset; - uint8_t arc_type; + nd_uint8_t arc_shost; + nd_uint8_t arc_dhost; + nd_uint16_t arc_offset; + nd_uint8_t arc_type; /* * only present for newstyle encoding with LL fragmentation. * Don't use sizeof(anything), use ARC_LINUX_HDR{,NEW}LEN * instead. */ - uint8_t arc_flag; - uint16_t arc_seqid; + nd_uint8_t arc_flag; + nd_uint16_t arc_seqid; }; #define ARC_LINUX_HDRLEN 5 @@ -115,54 +115,61 @@ static const struct tok arctypemap[] = { { ARCTYPE_IPX, "ipx" }, { ARCTYPE_INET6, "ipv6" }, { ARCTYPE_DIAGNOSE, "diag" }, - { 0, 0 } + { 0, NULL } }; -static inline void +static void arcnet_print(netdissect_options *ndo, const u_char *bp, u_int length, int phds, - int flag, u_int seqid) + u_int flag, u_int seqid) { const struct arc_header *ap; const char *arctypename; - + ndo->ndo_protocol = "arcnet"; ap = (const struct arc_header *)bp; - if (ndo->ndo_qflag) { - ND_PRINT((ndo, "%02x %02x %d: ", - ap->arc_shost, - ap->arc_dhost, - length)); + ND_PRINT("%02x %02x %u: ", + GET_U_1(ap->arc_shost), + GET_U_1(ap->arc_dhost), + length); return; } - arctypename = tok2str(arctypemap, "%02x", ap->arc_type); + arctypename = tok2str(arctypemap, "%02x", GET_U_1(ap->arc_type)); if (!phds) { - ND_PRINT((ndo, "%02x %02x %s %d: ", - ap->arc_shost, ap->arc_dhost, arctypename, - length)); - return; + ND_PRINT("%02x %02x %s %u: ", + GET_U_1(ap->arc_shost), + GET_U_1(ap->arc_dhost), + arctypename, + length); + return; } if (flag == 0) { - ND_PRINT((ndo, "%02x %02x %s seqid %04x %d: ", - ap->arc_shost, ap->arc_dhost, arctypename, seqid, - length)); - return; + ND_PRINT("%02x %02x %s seqid %04x %u: ", + GET_U_1(ap->arc_shost), + GET_U_1(ap->arc_dhost), + arctypename, seqid, + length); + return; } if (flag & 1) - ND_PRINT((ndo, "%02x %02x %s seqid %04x " - "(first of %d fragments) %d: ", - ap->arc_shost, ap->arc_dhost, arctypename, seqid, - (flag + 3) / 2, length)); + ND_PRINT("%02x %02x %s seqid %04x " + "(first of %u fragments) %u: ", + GET_U_1(ap->arc_shost), + GET_U_1(ap->arc_dhost), + arctypename, seqid, + (flag + 3) / 2, length); else - ND_PRINT((ndo, "%02x %02x %s seqid %04x " - "(fragment %d) %d: ", - ap->arc_shost, ap->arc_dhost, arctypename, seqid, - flag/2 + 1, length)); + ND_PRINT("%02x %02x %s seqid %04x " + "(fragment %u) %u: ", + GET_U_1(ap->arc_shost), + GET_U_1(ap->arc_dhost), + arctypename, seqid, + flag/2 + 1, length); } /* @@ -171,24 +178,26 @@ arcnet_print(netdissect_options *ndo, const u_char *bp, u_int length, int phds, * 'h->len' is the length of the packet off the wire, and 'h->caplen' * is the number of bytes actually captured. */ -u_int +void arcnet_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { u_int caplen = h->caplen; u_int length = h->len; const struct arc_header *ap; - int phds, flag = 0, archdrlen = 0; + int phds; + u_int flag = 0, archdrlen = 0; u_int seqid = 0; u_char arc_type; - if (caplen < ARC_HDRLEN || length < ARC_HDRLEN) { - ND_PRINT((ndo, "[|arcnet]")); - return (caplen); + ndo->ndo_protocol = "arcnet"; + if (caplen < ARC_HDRLEN) { + ndo->ndo_ll_hdr_len += caplen; + nd_trunc_longjmp(ndo); } ap = (const struct arc_header *)p; - arc_type = ap->arc_type; + arc_type = GET_U_1(ap->arc_type); switch (arc_type) { default: @@ -203,24 +212,26 @@ arcnet_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_ch } if (phds) { - if (caplen < ARC_HDRNEWLEN || length < ARC_HDRNEWLEN) { + if (caplen < ARC_HDRNEWLEN) { arcnet_print(ndo, p, length, 0, 0, 0); - ND_PRINT((ndo, "[|phds]")); - return (caplen); + ND_PRINT(" phds"); + ndo->ndo_ll_hdr_len += caplen; + nd_trunc_longjmp(ndo); } - if (ap->arc_flag == 0xff) { - if (caplen < ARC_HDRNEWLEN_EXC || length < ARC_HDRNEWLEN_EXC) { + flag = GET_U_1(ap->arc_flag); + if (flag == 0xff) { + if (caplen < ARC_HDRNEWLEN_EXC) { arcnet_print(ndo, p, length, 0, 0, 0); - ND_PRINT((ndo, "[|phds extended]")); - return (caplen); + ND_PRINT(" phds extended"); + ndo->ndo_ll_hdr_len += caplen; + nd_trunc_longjmp(ndo); } - flag = ap->arc_flag2; - seqid = EXTRACT_16BITS(&ap->arc_seqid2); + flag = GET_U_1(ap->arc_flag2); + seqid = GET_BE_U_2(ap->arc_seqid2); archdrlen = ARC_HDRNEWLEN_EXC; } else { - flag = ap->arc_flag; - seqid = EXTRACT_16BITS(&ap->arc_seqid); + seqid = GET_BE_U_2(ap->arc_seqid); archdrlen = ARC_HDRNEWLEN; } } @@ -240,13 +251,14 @@ arcnet_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_ch /* * This is a middle fragment. */ - return (archdrlen); + ndo->ndo_ll_hdr_len += archdrlen; + return; } if (!arcnet_encap_print(ndo, arc_type, p, length, caplen)) ND_DEFAULTPRINT(p, caplen); - return (archdrlen); + ndo->ndo_ll_hdr_len += archdrlen; } /* @@ -259,7 +271,7 @@ arcnet_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_ch * reassembled packets rather than raw frames, and headers have an * extra "offset" field between the src/dest and packet type. */ -u_int +void arcnet_linux_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { u_int caplen = h->caplen; @@ -269,20 +281,21 @@ arcnet_linux_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, cons int archdrlen = 0; u_char arc_type; - if (caplen < ARC_LINUX_HDRLEN || length < ARC_LINUX_HDRLEN) { - ND_PRINT((ndo, "[|arcnet]")); - return (caplen); + ndo->ndo_protocol = "arcnet_linux"; + if (caplen < ARC_LINUX_HDRLEN) { + ndo->ndo_ll_hdr_len += caplen; + nd_trunc_longjmp(ndo); } ap = (const struct arc_linux_header *)p; - arc_type = ap->arc_type; + arc_type = GET_U_1(ap->arc_type); switch (arc_type) { default: archdrlen = ARC_LINUX_HDRNEWLEN; - if (caplen < ARC_LINUX_HDRNEWLEN || length < ARC_LINUX_HDRNEWLEN) { - ND_PRINT((ndo, "[|arcnet]")); - return (caplen); + if (caplen < ARC_LINUX_HDRNEWLEN) { + ndo->ndo_ll_hdr_len += caplen; + nd_trunc_longjmp(ndo); } break; case ARCTYPE_IP_OLD: @@ -305,7 +318,7 @@ arcnet_linux_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, cons if (!arcnet_encap_print(ndo, arc_type, p, length, caplen)) ND_DEFAULTPRINT(p, caplen); - return (archdrlen); + ndo->ndo_ll_hdr_len += archdrlen; } /* @@ -339,7 +352,7 @@ arcnet_encap_print(netdissect_options *ndo, u_char arctype, const u_char *p, case ARCTYPE_ATALK: /* XXX was this ever used? */ if (ndo->ndo_vflag) - ND_PRINT((ndo, "et1 ")); + ND_PRINT("et1 "); atalk_print(ndo, p, length); return (1); @@ -351,10 +364,3 @@ arcnet_encap_print(netdissect_options *ndo, u_char arctype, const u_char *p, return (0); } } - -/* - * Local Variables: - * c-style: bsd - * End: - */ - diff --git a/contrib/tcpdump/print-arista.c b/contrib/tcpdump/print-arista.c new file mode 100644 index 0000000000..0d1d5d912c --- /dev/null +++ b/contrib/tcpdump/print-arista.c @@ -0,0 +1,92 @@ +// Copyright (c) 2018 Arista Networks, Inc. All rights reserved. + +/* \summary: EtherType protocol for Arista Networks printer */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "netdissect-stdinc.h" + +#include "netdissect.h" +#include "extract.h" +#include "addrtoname.h" + +#define ARISTA_SUBTYPE_TIMESTAMP 0x01 + +#define ARISTA_TIMESTAMP_64_TAI 0x0010 +#define ARISTA_TIMESTAMP_64_UTC 0x0110 +#define ARISTA_TIMESTAMP_48_TAI 0x0020 +#define ARISTA_TIMESTAMP_48_UTC 0x0120 + +static const struct tok ts_version_name[] = { + { ARISTA_TIMESTAMP_64_TAI, "TAI(64-bit)" }, + { ARISTA_TIMESTAMP_64_UTC, "UTC(64-bit)" }, + { ARISTA_TIMESTAMP_48_TAI, "TAI(48-bit)" }, + { ARISTA_TIMESTAMP_48_UTC, "UTC(48-bit)" }, + { 0, NULL } +}; + +static inline void +arista_print_date_hms_time(netdissect_options *ndo, uint32_t seconds, + uint32_t nanoseconds) +{ + time_t ts; + struct tm *tm; + char buf[BUFSIZE]; + + ts = seconds + (nanoseconds / 1000000000); + if (NULL == (tm = gmtime(&ts))) + ND_PRINT(": gmtime() error"); + else if (0 == strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm)) + ND_PRINT(": strftime() error"); + else + ND_PRINT(": %s, %09u ns, ", buf, nanoseconds); +} + +int +arista_ethertype_print(netdissect_options *ndo, const u_char *bp, u_int len _U_) +{ + uint16_t subTypeId; + uint16_t version; + u_short bytesConsumed = 0; + u_short size = 0; + uint32_t seconds, nanoseconds; + + ndo->ndo_protocol = "arista"; + + subTypeId = GET_BE_U_2(bp); + bp += 2; + version = GET_BE_U_2(bp); + bp += 2; + bytesConsumed += 4; + + ND_PRINT("SubType: 0x%1x, Version: 0x%04x, ", subTypeId, version); + + // TapAgg Header Timestamping + if (subTypeId == ARISTA_SUBTYPE_TIMESTAMP) { + // Timestamp has 32-bit lsb in nanosec and remaining msb in sec + ND_PRINT("Timestamp %s", tok2str(ts_version_name, + "Unknown timestamp Version 0x%04x ", version)); + switch (version) { + case ARISTA_TIMESTAMP_64_TAI: + case ARISTA_TIMESTAMP_64_UTC: + seconds = GET_BE_U_4(bp); + nanoseconds = GET_BE_U_4(bp + 4); + arista_print_date_hms_time(ndo, seconds, nanoseconds); + bytesConsumed += size + 8; + break; + case ARISTA_TIMESTAMP_48_TAI: + case ARISTA_TIMESTAMP_48_UTC: + ND_PRINT(": Seconds %u,", GET_BE_U_2(bp)); + ND_PRINT(" Nanoseconds %u, ", GET_BE_U_4(bp + 2)); + bytesConsumed += size + 6; + break; + default: + return -1; + } + } else { + return -1; + } + return bytesConsumed; +} diff --git a/contrib/tcpdump/print-arp.c b/contrib/tcpdump/print-arp.c index 96727faa31..7d3efe74fa 100644 --- a/contrib/tcpdump/print-arp.c +++ b/contrib/tcpdump/print-arp.c @@ -22,20 +22,17 @@ /* \summary: Address Resolution Protocol (ARP) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include - -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "addrtoname.h" -#include "ether.h" #include "ethertype.h" #include "extract.h" -static const char tstr[] = "[|ARP]"; /* * Address Resolution Protocol. @@ -48,7 +45,7 @@ static const char tstr[] = "[|ARP]"; * specified. Field names used correspond to RFC 826. */ struct arp_pkthdr { - u_short ar_hrd; /* format of hardware address */ + nd_uint16_t ar_hrd; /* format of hardware address */ #define ARPHRD_ETHER 1 /* ethernet hardware format */ #define ARPHRD_IEEE802 6 /* token-ring hardware format */ #define ARPHRD_ARCNET 7 /* arcnet hardware format */ @@ -56,10 +53,11 @@ struct arp_pkthdr { #define ARPHRD_ATM2225 19 /* ATM (RFC 2225) */ #define ARPHRD_STRIP 23 /* Ricochet Starmode Radio hardware format */ #define ARPHRD_IEEE1394 24 /* IEEE 1394 (FireWire) hardware format */ - u_short ar_pro; /* format of protocol address */ - u_char ar_hln; /* length of hardware address */ - u_char ar_pln; /* length of protocol address */ - u_short ar_op; /* one of: */ +#define ARPHRD_INFINIBAND 32 /* InfiniBand RFC 4391 */ + nd_uint16_t ar_pro; /* format of protocol address */ + nd_uint8_t ar_hln; /* length of hardware address */ + nd_uint8_t ar_pln; /* length of protocol address */ + nd_uint16_t ar_op; /* one of: */ #define ARPOP_REQUEST 1 /* request to resolve address */ #define ARPOP_REPLY 2 /* response to previous request */ #define ARPOP_REVREQUEST 3 /* request protocol address given hardware */ @@ -73,24 +71,24 @@ struct arp_pkthdr { * according to the sizes above. */ #ifdef COMMENT_ONLY - u_char ar_sha[]; /* sender hardware address */ - u_char ar_spa[]; /* sender protocol address */ - u_char ar_tha[]; /* target hardware address */ - u_char ar_tpa[]; /* target protocol address */ + nd_byte ar_sha[]; /* sender hardware address */ + nd_byte ar_spa[]; /* sender protocol address */ + nd_byte ar_tha[]; /* target hardware address */ + nd_byte ar_tpa[]; /* target protocol address */ #endif #define ar_sha(ap) (((const u_char *)((ap)+1))+ 0) -#define ar_spa(ap) (((const u_char *)((ap)+1))+ (ap)->ar_hln) -#define ar_tha(ap) (((const u_char *)((ap)+1))+ (ap)->ar_hln+(ap)->ar_pln) -#define ar_tpa(ap) (((const u_char *)((ap)+1))+2*(ap)->ar_hln+(ap)->ar_pln) +#define ar_spa(ap) (((const u_char *)((ap)+1))+ GET_U_1((ap)->ar_hln)) +#define ar_tha(ap) (((const u_char *)((ap)+1))+ GET_U_1((ap)->ar_hln)+GET_U_1((ap)->ar_pln)) +#define ar_tpa(ap) (((const u_char *)((ap)+1))+2*GET_U_1((ap)->ar_hln)+GET_U_1((ap)->ar_pln)) }; #define ARP_HDRLEN 8 -#define HRD(ap) EXTRACT_16BITS(&(ap)->ar_hrd) -#define HRD_LEN(ap) ((ap)->ar_hln) -#define PROTO_LEN(ap) ((ap)->ar_pln) -#define OP(ap) EXTRACT_16BITS(&(ap)->ar_op) -#define PRO(ap) EXTRACT_16BITS(&(ap)->ar_pro) +#define HRD(ap) GET_BE_U_2((ap)->ar_hrd) +#define HRD_LEN(ap) GET_U_1((ap)->ar_hln) +#define PROTO_LEN(ap) GET_U_1((ap)->ar_pln) +#define OP(ap) GET_BE_U_2((ap)->ar_op) +#define PRO(ap) GET_BE_U_2((ap)->ar_pro) #define SHA(ap) (ar_sha(ap)) #define SPA(ap) (ar_spa(ap)) #define THA(ap) (ar_tha(ap)) @@ -116,6 +114,7 @@ static const struct tok arphrd_values[] = { { ARPHRD_STRIP, "Strip" }, { ARPHRD_IEEE1394, "IEEE 1394" }, { ARPHRD_ATM2225, "ATM" }, + { ARPHRD_INFINIBAND, "InfiniBand" }, { 0, NULL } }; @@ -129,39 +128,39 @@ static const struct tok arphrd_values[] = { * of an ATM number and an ATM subaddress. */ struct atmarp_pkthdr { - u_short aar_hrd; /* format of hardware address */ - u_short aar_pro; /* format of protocol address */ - u_char aar_shtl; /* length of source ATM number */ - u_char aar_sstl; /* length of source ATM subaddress */ + nd_uint16_t aar_hrd; /* format of hardware address */ + nd_uint16_t aar_pro; /* format of protocol address */ + nd_uint8_t aar_shtl; /* length of source ATM number */ + nd_uint8_t aar_sstl; /* length of source ATM subaddress */ #define ATMARP_IS_E164 0x40 /* bit in type/length for E.164 format */ #define ATMARP_LEN_MASK 0x3F /* length of {sub}address in type/length */ - u_short aar_op; /* same as regular ARP */ - u_char aar_spln; /* length of source protocol address */ - u_char aar_thtl; /* length of target ATM number */ - u_char aar_tstl; /* length of target ATM subaddress */ - u_char aar_tpln; /* length of target protocol address */ + nd_uint16_t aar_op; /* same as regular ARP */ + nd_uint8_t aar_spln; /* length of source protocol address */ + nd_uint8_t aar_thtl; /* length of target ATM number */ + nd_uint8_t aar_tstl; /* length of target ATM subaddress */ + nd_uint8_t aar_tpln; /* length of target protocol address */ /* * The remaining fields are variable in size, * according to the sizes above. */ #ifdef COMMENT_ONLY - u_char aar_sha[]; /* source ATM number */ - u_char aar_ssa[]; /* source ATM subaddress */ - u_char aar_spa[]; /* sender protocol address */ - u_char aar_tha[]; /* target ATM number */ - u_char aar_tsa[]; /* target ATM subaddress */ - u_char aar_tpa[]; /* target protocol address */ + nd_byte aar_sha[]; /* source ATM number */ + nd_byte aar_ssa[]; /* source ATM subaddress */ + nd_byte aar_spa[]; /* sender protocol address */ + nd_byte aar_tha[]; /* target ATM number */ + nd_byte aar_tsa[]; /* target ATM subaddress */ + nd_byte aar_tpa[]; /* target protocol address */ #endif -#define ATMHRD(ap) EXTRACT_16BITS(&(ap)->aar_hrd) -#define ATMSHRD_LEN(ap) ((ap)->aar_shtl & ATMARP_LEN_MASK) -#define ATMSSLN(ap) ((ap)->aar_sstl & ATMARP_LEN_MASK) -#define ATMSPROTO_LEN(ap) ((ap)->aar_spln) -#define ATMOP(ap) EXTRACT_16BITS(&(ap)->aar_op) -#define ATMPRO(ap) EXTRACT_16BITS(&(ap)->aar_pro) -#define ATMTHRD_LEN(ap) ((ap)->aar_thtl & ATMARP_LEN_MASK) -#define ATMTSLN(ap) ((ap)->aar_tstl & ATMARP_LEN_MASK) -#define ATMTPROTO_LEN(ap) ((ap)->aar_tpln) +#define ATMHRD(ap) GET_BE_U_2((ap)->aar_hrd) +#define ATMSHRD_LEN(ap) (GET_U_1((ap)->aar_shtl) & ATMARP_LEN_MASK) +#define ATMSSLN(ap) (GET_U_1((ap)->aar_sstl) & ATMARP_LEN_MASK) +#define ATMSPROTO_LEN(ap) GET_U_1((ap)->aar_spln) +#define ATMOP(ap) GET_BE_U_2((ap)->aar_op) +#define ATMPRO(ap) GET_BE_U_2((ap)->aar_pro) +#define ATMTHRD_LEN(ap) (GET_U_1((ap)->aar_thtl) & ATMARP_LEN_MASK) +#define ATMTSLN(ap) (GET_U_1((ap)->aar_tstl) & ATMARP_LEN_MASK) +#define ATMTPROTO_LEN(ap) GET_U_1((ap)->aar_tpln) #define aar_sha(ap) ((const u_char *)((ap)+1)) #define aar_ssa(ap) (aar_sha(ap) + ATMSHRD_LEN(ap)) #define aar_spa(ap) (aar_ssa(ap) + ATMSSLN(ap)) @@ -178,10 +177,10 @@ struct atmarp_pkthdr { #define ATMTPA(ap) (aar_tpa(ap)) static int -isnonzero(const u_char *a, size_t len) +isnonzero(netdissect_options *ndo, const u_char *a, size_t len) { while (len > 0) { - if (*a != 0) + if (GET_U_1(a) != 0) return (1); a++; len--; @@ -194,11 +193,11 @@ tpaddr_print_ip(netdissect_options *ndo, const struct arp_pkthdr *ap, u_short pro) { if (pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) - ND_PRINT((ndo, "")); + ND_PRINT(""); else if (PROTO_LEN(ap) != 4) - ND_PRINT((ndo, "")); + ND_PRINT(""); else - ND_PRINT((ndo, "%s", ipaddr_string(ndo, TPA(ap)))); + ND_PRINT("%s", GET_IPADDR_STRING(TPA(ap))); } static void @@ -206,11 +205,11 @@ spaddr_print_ip(netdissect_options *ndo, const struct arp_pkthdr *ap, u_short pro) { if (pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) - ND_PRINT((ndo, "")); + ND_PRINT(""); else if (PROTO_LEN(ap) != 4) - ND_PRINT((ndo, "")); + ND_PRINT(""); else - ND_PRINT((ndo, "%s", ipaddr_string(ndo, SPA(ap)))); + ND_PRINT("%s", GET_IPADDR_STRING(SPA(ap))); } static void @@ -219,12 +218,12 @@ atmarp_addr_print(netdissect_options *ndo, u_int srca_len) { if (ha_len == 0) - ND_PRINT((ndo, "")); + ND_PRINT(""); else { - ND_PRINT((ndo, "%s", linkaddr_string(ndo, ha, LINKADDR_ATM, ha_len))); + ND_PRINT("%s", GET_LINKADDR_STRING(ha, LINKADDR_ATM, ha_len)); if (srca_len != 0) - ND_PRINT((ndo, ",%s", - linkaddr_string(ndo, srca, LINKADDR_ATM, srca_len))); + ND_PRINT(",%s", + GET_LINKADDR_STRING(srca, LINKADDR_ATM, srca_len)); } } @@ -233,11 +232,11 @@ atmarp_tpaddr_print(netdissect_options *ndo, const struct atmarp_pkthdr *ap, u_short pro) { if (pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) - ND_PRINT((ndo, "")); + ND_PRINT(""); else if (ATMTPROTO_LEN(ap) != 4) - ND_PRINT((ndo, "")); + ND_PRINT(""); else - ND_PRINT((ndo, "%s", ipaddr_string(ndo, ATMTPA(ap)))); + ND_PRINT("%s", GET_IPADDR_STRING(ATMTPA(ap))); } static void @@ -245,11 +244,11 @@ atmarp_spaddr_print(netdissect_options *ndo, const struct atmarp_pkthdr *ap, u_short pro) { if (pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) - ND_PRINT((ndo, "")); + ND_PRINT(""); else if (ATMSPROTO_LEN(ap) != 4) - ND_PRINT((ndo, "")); + ND_PRINT(""); else - ND_PRINT((ndo, "%s", ipaddr_string(ndo, ATMSPA(ap)))); + ND_PRINT("%s", GET_IPADDR_STRING(ATMSPA(ap))); } static void @@ -260,70 +259,66 @@ atmarp_print(netdissect_options *ndo, u_short pro, hrd, op; ap = (const struct atmarp_pkthdr *)bp; - ND_TCHECK(*ap); + ND_TCHECK_SIZE(ap); hrd = ATMHRD(ap); pro = ATMPRO(ap); op = ATMOP(ap); - if (!ND_TTEST2(*aar_tpa(ap), ATMTPROTO_LEN(ap))) { - ND_PRINT((ndo, "%s", tstr)); - ND_DEFAULTPRINT((const u_char *)ap, length); - return; - } + ND_TCHECK_LEN(ATMTPA(ap), ATMTPROTO_LEN(ap)); if (!ndo->ndo_eflag) { - ND_PRINT((ndo, "ARP, ")); + ND_PRINT("ARP, "); } if ((pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) || ATMSPROTO_LEN(ap) != 4 || ATMTPROTO_LEN(ap) != 4 || ndo->ndo_vflag) { - ND_PRINT((ndo, "%s, %s (len %u/%u)", + ND_PRINT("%s, %s (len %u/%u)", tok2str(arphrd_values, "Unknown Hardware (%u)", hrd), tok2str(ethertype_values, "Unknown Protocol (0x%04x)", pro), ATMSPROTO_LEN(ap), - ATMTPROTO_LEN(ap))); + ATMTPROTO_LEN(ap)); - /* don't know know about the address formats */ + /* don't know about the address formats */ if (!ndo->ndo_vflag) { goto out; } } /* print operation */ - ND_PRINT((ndo, "%s%s ", + ND_PRINT("%s%s ", ndo->ndo_vflag ? ", " : "", - tok2str(arpop_values, "Unknown (%u)", op))); + tok2str(arpop_values, "Unknown (%u)", op)); switch (op) { case ARPOP_REQUEST: - ND_PRINT((ndo, "who-has ")); + ND_PRINT("who-has "); atmarp_tpaddr_print(ndo, ap, pro); if (ATMTHRD_LEN(ap) != 0) { - ND_PRINT((ndo, " (")); + ND_PRINT(" ("); atmarp_addr_print(ndo, ATMTHA(ap), ATMTHRD_LEN(ap), ATMTSA(ap), ATMTSLN(ap)); - ND_PRINT((ndo, ")")); + ND_PRINT(")"); } - ND_PRINT((ndo, " tell ")); + ND_PRINT(" tell "); atmarp_spaddr_print(ndo, ap, pro); break; case ARPOP_REPLY: atmarp_spaddr_print(ndo, ap, pro); - ND_PRINT((ndo, " is-at ")); + ND_PRINT(" is-at "); atmarp_addr_print(ndo, ATMSHA(ap), ATMSHRD_LEN(ap), ATMSSA(ap), ATMSSLN(ap)); break; case ARPOP_INVREQUEST: - ND_PRINT((ndo, "who-is ")); + ND_PRINT("who-is "); atmarp_addr_print(ndo, ATMTHA(ap), ATMTHRD_LEN(ap), ATMTSA(ap), ATMTSLN(ap)); - ND_PRINT((ndo, " tell ")); + ND_PRINT(" tell "); atmarp_addr_print(ndo, ATMSHA(ap), ATMSHRD_LEN(ap), ATMSSA(ap), ATMSSLN(ap)); break; @@ -331,12 +326,12 @@ atmarp_print(netdissect_options *ndo, case ARPOP_INVREPLY: atmarp_addr_print(ndo, ATMSHA(ap), ATMSHRD_LEN(ap), ATMSSA(ap), ATMSSLN(ap)); - ND_PRINT((ndo, "at ")); + ND_PRINT("at "); atmarp_spaddr_print(ndo, ap, pro); break; case ARPOP_NAK: - ND_PRINT((ndo, "for ")); + ND_PRINT("for "); atmarp_spaddr_print(ndo, ap, pro); break; @@ -346,11 +341,7 @@ atmarp_print(netdissect_options *ndo, } out: - ND_PRINT((ndo, ", length %u", length)); - return; - -trunc: - ND_PRINT((ndo, "%s", tstr)); + ND_PRINT(", length %u", length); } void @@ -360,8 +351,9 @@ arp_print(netdissect_options *ndo, const struct arp_pkthdr *ap; u_short pro, hrd, op, linkaddr; + ndo->ndo_protocol = "arp"; ap = (const struct arp_pkthdr *)bp; - ND_TCHECK(*ap); + ND_TCHECK_SIZE(ap); hrd = HRD(ap); pro = PRO(ap); @@ -371,7 +363,7 @@ arp_print(netdissect_options *ndo, /* if its ATM then call the ATM ARP printer for Frame-relay ARP most of the fields are similar to Ethernet so overload the Ethernet Printer - and set the linkaddr type for linkaddr_string(ndo, ) accordingly */ + and set the linkaddr type for GET_LINKADDR_STRING() accordingly */ switch(hrd) { case ARPHRD_ATM2225: @@ -385,14 +377,10 @@ arp_print(netdissect_options *ndo, break; } - if (!ND_TTEST2(*TPA(ap), PROTO_LEN(ap))) { - ND_PRINT((ndo, "%s", tstr)); - ND_DEFAULTPRINT((const u_char *)ap, length); - return; - } + ND_TCHECK_LEN(TPA(ap), PROTO_LEN(ap)); if (!ndo->ndo_eflag) { - ND_PRINT((ndo, "ARP, ")); + ND_PRINT("ARP, "); } /* print hardware type/len and proto type/len */ @@ -400,62 +388,78 @@ arp_print(netdissect_options *ndo, PROTO_LEN(ap) != 4 || HRD_LEN(ap) == 0 || ndo->ndo_vflag) { - ND_PRINT((ndo, "%s (len %u), %s (len %u)", + ND_PRINT("%s (len %u), %s (len %u)", tok2str(arphrd_values, "Unknown Hardware (%u)", hrd), HRD_LEN(ap), tok2str(ethertype_values, "Unknown Protocol (0x%04x)", pro), - PROTO_LEN(ap))); + PROTO_LEN(ap)); - /* don't know know about the address formats */ + /* don't know about the address formats */ if (!ndo->ndo_vflag) { goto out; } } /* print operation */ - ND_PRINT((ndo, "%s%s ", + ND_PRINT("%s%s ", ndo->ndo_vflag ? ", " : "", - tok2str(arpop_values, "Unknown (%u)", op))); + tok2str(arpop_values, "Unknown (%u)", op)); switch (op) { case ARPOP_REQUEST: - ND_PRINT((ndo, "who-has ")); + ND_PRINT("who-has "); tpaddr_print_ip(ndo, ap, pro); - if (isnonzero((const u_char *)THA(ap), HRD_LEN(ap))) - ND_PRINT((ndo, " (%s)", - linkaddr_string(ndo, THA(ap), linkaddr, HRD_LEN(ap)))); - ND_PRINT((ndo, " tell ")); + if (isnonzero(ndo, (const u_char *)THA(ap), HRD_LEN(ap))) + ND_PRINT(" (%s)", + GET_LINKADDR_STRING(THA(ap), linkaddr, HRD_LEN(ap))); + ND_PRINT(" tell "); spaddr_print_ip(ndo, ap, pro); break; case ARPOP_REPLY: spaddr_print_ip(ndo, ap, pro); - ND_PRINT((ndo, " is-at %s", - linkaddr_string(ndo, SHA(ap), linkaddr, HRD_LEN(ap)))); + ND_PRINT(" is-at %s", + GET_LINKADDR_STRING(SHA(ap), linkaddr, HRD_LEN(ap))); break; case ARPOP_REVREQUEST: - ND_PRINT((ndo, "who-is %s tell %s", - linkaddr_string(ndo, THA(ap), linkaddr, HRD_LEN(ap)), - linkaddr_string(ndo, SHA(ap), linkaddr, HRD_LEN(ap)))); + /* + * XXX - GET_LINKADDR_STRING() may return a pointer to + * a static buffer, so we only have one call to it per + * ND_PRINT() call. + * + * This should be done in a cleaner fashion. + */ + ND_PRINT("who-is %s", + GET_LINKADDR_STRING(THA(ap), linkaddr, HRD_LEN(ap))); + ND_PRINT(" tell %s", + GET_LINKADDR_STRING(SHA(ap), linkaddr, HRD_LEN(ap))); break; case ARPOP_REVREPLY: - ND_PRINT((ndo, "%s at ", - linkaddr_string(ndo, THA(ap), linkaddr, HRD_LEN(ap)))); + ND_PRINT("%s at ", + GET_LINKADDR_STRING(THA(ap), linkaddr, HRD_LEN(ap))); tpaddr_print_ip(ndo, ap, pro); break; case ARPOP_INVREQUEST: - ND_PRINT((ndo, "who-is %s tell %s", - linkaddr_string(ndo, THA(ap), linkaddr, HRD_LEN(ap)), - linkaddr_string(ndo, SHA(ap), linkaddr, HRD_LEN(ap)))); + /* + * XXX - GET_LINKADDR_STRING() may return a pointer to + * a static buffer, so we only have one call to it per + * ND_PRINT() call. + * + * This should be done in a cleaner fashion. + */ + ND_PRINT("who-is %s", + GET_LINKADDR_STRING(THA(ap), linkaddr, HRD_LEN(ap))); + ND_PRINT(" tell %s", + GET_LINKADDR_STRING(SHA(ap), linkaddr, HRD_LEN(ap))); break; case ARPOP_INVREPLY: - ND_PRINT((ndo,"%s at ", - linkaddr_string(ndo, SHA(ap), linkaddr, HRD_LEN(ap)))); + ND_PRINT("%s at ", + GET_LINKADDR_STRING(SHA(ap), linkaddr, HRD_LEN(ap))); spaddr_print_ip(ndo, ap, pro); break; @@ -465,16 +469,5 @@ arp_print(netdissect_options *ndo, } out: - ND_PRINT((ndo, ", length %u", length)); - - return; -trunc: - ND_PRINT((ndo, "%s", tstr)); + ND_PRINT(", length %u", length); } - -/* - * Local Variables: - * c-style: bsd - * End: - */ - diff --git a/contrib/tcpdump/print-ascii.c b/contrib/tcpdump/print-ascii.c index 4ef38a17a5..2f5fe8547f 100644 --- a/contrib/tcpdump/print-ascii.c +++ b/contrib/tcpdump/print-ascii.c @@ -39,13 +39,17 @@ /* \summary: ASCII packet dump printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" + #include +#include "netdissect-ctype.h" + #include "netdissect.h" +#include "extract.h" #define ASCII_LINELENGTH 300 #define HEXDUMP_BYTES_PER_LINE 16 @@ -59,14 +63,19 @@ ascii_print(netdissect_options *ndo, const u_char *cp, u_int length) { u_int caplength; - register u_char s; + u_char s; + int truncated = FALSE; - caplength = (ndo->ndo_snapend >= cp) ? ndo->ndo_snapend - cp : 0; - if (length > caplength) + ndo->ndo_protocol = "ascii"; + caplength = (ndo->ndo_snapend > cp) ? ND_BYTES_AVAILABLE_AFTER(cp) : 0; + if (length > caplength) { length = caplength; - ND_PRINT((ndo, "\n")); + truncated = TRUE; + } + ND_PRINT("\n"); while (length > 0) { - s = *cp++; + s = GET_U_1(cp); + cp++; length--; if (s == '\r') { /* @@ -78,72 +87,83 @@ ascii_print(netdissect_options *ndo, * * In the middle of a line, just print a '.'. */ - if (length > 1 && *cp != '\n') - ND_PRINT((ndo, ".")); + if (length > 1 && GET_U_1(cp) != '\n') + ND_PRINT("."); } else { - if (!ND_ISGRAPH(s) && + if (!ND_ASCII_ISGRAPH(s) && (s != '\t' && s != ' ' && s != '\n')) - ND_PRINT((ndo, ".")); + ND_PRINT("."); else - ND_PRINT((ndo, "%c", s)); + ND_PRINT("%c", s); } } + if (truncated) + nd_trunc_longjmp(ndo); } -void -hex_and_ascii_print_with_offset(netdissect_options *ndo, register const char *ident, - register const u_char *cp, register u_int length, register u_int oset) +static void +hex_and_ascii_print_with_offset(netdissect_options *ndo, const char *ident, + const u_char *cp, u_int length, u_int oset) { u_int caplength; - register u_int i; - register int s1, s2; - register int nshorts; + u_int i; + u_int s1, s2; + u_int nshorts; + int truncated = FALSE; char hexstuff[HEXDUMP_SHORTS_PER_LINE*HEXDUMP_HEXSTUFF_PER_SHORT+1], *hsp; char asciistuff[ASCII_LINELENGTH+1], *asp; - caplength = (ndo->ndo_snapend >= cp) ? ndo->ndo_snapend - cp : 0; - if (length > caplength) + caplength = (ndo->ndo_snapend > cp) ? ND_BYTES_AVAILABLE_AFTER(cp) : 0; + if (length > caplength) { length = caplength; + truncated = TRUE; + } nshorts = length / sizeof(u_short); i = 0; hsp = hexstuff; asp = asciistuff; - while (--nshorts >= 0) { - s1 = *cp++; - s2 = *cp++; + while (nshorts != 0) { + s1 = GET_U_1(cp); + cp++; + s2 = GET_U_1(cp); + cp++; (void)snprintf(hsp, sizeof(hexstuff) - (hsp - hexstuff), " %02x%02x", s1, s2); hsp += HEXDUMP_HEXSTUFF_PER_SHORT; - *(asp++) = (ND_ISGRAPH(s1) ? s1 : '.'); - *(asp++) = (ND_ISGRAPH(s2) ? s2 : '.'); + *(asp++) = (char)(ND_ASCII_ISGRAPH(s1) ? s1 : '.'); + *(asp++) = (char)(ND_ASCII_ISGRAPH(s2) ? s2 : '.'); i++; if (i >= HEXDUMP_SHORTS_PER_LINE) { *hsp = *asp = '\0'; - ND_PRINT((ndo, "%s0x%04x: %-*s %s", + ND_PRINT("%s0x%04x: %-*s %s", ident, oset, HEXDUMP_HEXSTUFF_PER_LINE, - hexstuff, asciistuff)); + hexstuff, asciistuff); i = 0; hsp = hexstuff; asp = asciistuff; oset += HEXDUMP_BYTES_PER_LINE; } + nshorts--; } if (length & 1) { - s1 = *cp++; + s1 = GET_U_1(cp); + cp++; (void)snprintf(hsp, sizeof(hexstuff) - (hsp - hexstuff), " %02x", s1); hsp += 3; - *(asp++) = (ND_ISGRAPH(s1) ? s1 : '.'); + *(asp++) = (char)(ND_ASCII_ISGRAPH(s1) ? s1 : '.'); ++i; } if (i > 0) { *hsp = *asp = '\0'; - ND_PRINT((ndo, "%s0x%04x: %-*s %s", + ND_PRINT("%s0x%04x: %-*s %s", ident, oset, HEXDUMP_HEXSTUFF_PER_LINE, - hexstuff, asciistuff)); + hexstuff, asciistuff); } + if (truncated) + nd_trunc_longjmp(ndo); } void -hex_and_ascii_print(netdissect_options *ndo, register const char *ident, - register const u_char *cp, register u_int length) +hex_and_ascii_print(netdissect_options *ndo, const char *ident, + const u_char *cp, u_int length) { hex_and_ascii_print_with_offset(ndo, ident, cp, length, 0); } @@ -157,36 +177,42 @@ hex_print_with_offset(netdissect_options *ndo, u_int oset) { u_int caplength; - register u_int i, s; - register int nshorts; + u_int i, s; + u_int nshorts; + int truncated = FALSE; - caplength = (ndo->ndo_snapend >= cp) ? ndo->ndo_snapend - cp : 0; - if (length > caplength) + caplength = (ndo->ndo_snapend > cp) ? ND_BYTES_AVAILABLE_AFTER(cp) : 0; + if (length > caplength) { length = caplength; - nshorts = (u_int) length / sizeof(u_short); + truncated = TRUE; + } + nshorts = length / sizeof(u_short); i = 0; - while (--nshorts >= 0) { + while (nshorts != 0) { if ((i++ % 8) == 0) { - ND_PRINT((ndo,"%s0x%04x: ", ident, oset)); + ND_PRINT("%s0x%04x: ", ident, oset); oset += HEXDUMP_BYTES_PER_LINE; } - s = *cp++; - ND_PRINT((ndo," %02x%02x", s, *cp++)); + s = GET_U_1(cp); + cp++; + ND_PRINT(" %02x%02x", s, GET_U_1(cp)); + cp++; + nshorts--; } if (length & 1) { if ((i % 8) == 0) - ND_PRINT((ndo,"%s0x%04x: ", ident, oset)); - ND_PRINT((ndo," %02x", *cp)); + ND_PRINT("%s0x%04x: ", ident, oset); + ND_PRINT(" %02x", GET_U_1(cp)); } + if (truncated) + nd_trunc_longjmp(ndo); } -/* - * just for completeness - */ void -hex_print(netdissect_options *ndo,const char *ident, const u_char *cp, u_int length) +hex_print(netdissect_options *ndo, + const char *ident, const u_char *cp, u_int length) { - hex_print_with_offset(ndo, ident, cp, length, 0); + hex_print_with_offset(ndo, ident, cp, length, 0); } #ifdef MAIN diff --git a/contrib/tcpdump/print-atalk.c b/contrib/tcpdump/print-atalk.c index 9d7d69d3d7..d9f86c7255 100644 --- a/contrib/tcpdump/print-atalk.c +++ b/contrib/tcpdump/print-atalk.c @@ -22,10 +22,10 @@ /* \summary: AppleTalk printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include #include @@ -36,7 +36,6 @@ #include "extract.h" #include "appletalk.h" -static const char tstr[] = "[|atalk]"; static const struct tok type2str[] = { { ddpRTMP, "rtmp" }, @@ -49,12 +48,12 @@ static const struct tok type2str[] = { }; struct aarp { - uint16_t htype, ptype; - uint8_t halen, palen; - uint16_t op; - uint8_t hsaddr[6]; + nd_uint16_t htype, ptype; + nd_uint8_t halen, palen; + nd_uint16_t op; + nd_mac_addr hsaddr; uint8_t psaddr[4]; - uint8_t hdaddr[6]; + nd_mac_addr hdaddr; uint8_t pdaddr[4]; }; @@ -67,24 +66,26 @@ static const struct atNBPtuple *nbp_tuple_print(netdissect_options *ndo, const s static const struct atNBPtuple *nbp_name_print(netdissect_options *, const struct atNBPtuple *, const u_char *); static const char *ataddr_string(netdissect_options *, u_short, u_char); -static void ddp_print(netdissect_options *, const u_char *, u_int, int, u_short, u_char, u_char); -static const char *ddpskt_string(netdissect_options *, int); +static void ddp_print(netdissect_options *, const u_char *, u_int, u_int, u_short, u_char, u_char); +static const char *ddpskt_string(netdissect_options *, u_int); /* * Print LLAP packets received on a physical LocalTalk interface. */ -u_int +void ltalk_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { u_int hdrlen; + ndo->ndo_protocol = "ltalk"; hdrlen = llap_print(ndo, p, h->len); if (hdrlen == 0) { /* Cut short by the snapshot length. */ - return (h->caplen); + ndo->ndo_ll_hdr_len += h->caplen; + return; } - return (hdrlen); + ndo->ndo_ll_hdr_len += hdrlen; } /* @@ -92,68 +93,74 @@ ltalk_if_print(netdissect_options *ndo, */ u_int llap_print(netdissect_options *ndo, - register const u_char *bp, u_int length) + const u_char *bp, u_int length) { - register const struct LAP *lp; - register const struct atDDP *dp; - register const struct atShortDDP *sdp; + const struct LAP *lp; + const struct atDDP *dp; + const struct atShortDDP *sdp; u_short snet; u_int hdrlen; + ndo->ndo_protocol = "llap"; if (length < sizeof(*lp)) { - ND_PRINT((ndo, " [|llap %u]", length)); + ND_PRINT(" [|llap %u]", length); return (length); } - if (!ND_TTEST2(*bp, sizeof(*lp))) { - ND_PRINT((ndo, " [|llap]")); + if (!ND_TTEST_LEN(bp, sizeof(*lp))) { + nd_print_trunc(ndo); return (0); /* cut short by the snapshot length */ } lp = (const struct LAP *)bp; bp += sizeof(*lp); length -= sizeof(*lp); hdrlen = sizeof(*lp); - switch (lp->type) { + switch (GET_U_1(lp->type)) { case lapShortDDP: if (length < ddpSSize) { - ND_PRINT((ndo, " [|sddp %u]", length)); + ND_PRINT(" [|sddp %u]", length); return (length); } - if (!ND_TTEST2(*bp, ddpSSize)) { - ND_PRINT((ndo, " [|sddp]")); + if (!ND_TTEST_LEN(bp, ddpSSize)) { + ND_PRINT(" [|sddp]"); return (0); /* cut short by the snapshot length */ } sdp = (const struct atShortDDP *)bp; - ND_PRINT((ndo, "%s.%s", - ataddr_string(ndo, 0, lp->src), ddpskt_string(ndo, sdp->srcSkt))); - ND_PRINT((ndo, " > %s.%s:", - ataddr_string(ndo, 0, lp->dst), ddpskt_string(ndo, sdp->dstSkt))); + ND_PRINT("%s.%s", + ataddr_string(ndo, 0, GET_U_1(lp->src)), + ddpskt_string(ndo, GET_U_1(sdp->srcSkt))); + ND_PRINT(" > %s.%s:", + ataddr_string(ndo, 0, GET_U_1(lp->dst)), + ddpskt_string(ndo, GET_U_1(sdp->dstSkt))); bp += ddpSSize; length -= ddpSSize; hdrlen += ddpSSize; - ddp_print(ndo, bp, length, sdp->type, 0, lp->src, sdp->srcSkt); + ddp_print(ndo, bp, length, GET_U_1(sdp->type), 0, + GET_U_1(lp->src), GET_U_1(sdp->srcSkt)); break; case lapDDP: if (length < ddpSize) { - ND_PRINT((ndo, " [|ddp %u]", length)); + ND_PRINT(" [|ddp %u]", length); return (length); } - if (!ND_TTEST2(*bp, ddpSize)) { - ND_PRINT((ndo, " [|ddp]")); + if (!ND_TTEST_LEN(bp, ddpSize)) { + ND_PRINT(" [|ddp]"); return (0); /* cut short by the snapshot length */ } dp = (const struct atDDP *)bp; - snet = EXTRACT_16BITS(&dp->srcNet); - ND_PRINT((ndo, "%s.%s", ataddr_string(ndo, snet, dp->srcNode), - ddpskt_string(ndo, dp->srcSkt))); - ND_PRINT((ndo, " > %s.%s:", - ataddr_string(ndo, EXTRACT_16BITS(&dp->dstNet), dp->dstNode), - ddpskt_string(ndo, dp->dstSkt))); + snet = GET_BE_U_2(dp->srcNet); + ND_PRINT("%s.%s", + ataddr_string(ndo, snet, GET_U_1(dp->srcNode)), + ddpskt_string(ndo, GET_U_1(dp->srcSkt))); + ND_PRINT(" > %s.%s:", + ataddr_string(ndo, GET_BE_U_2(dp->dstNet), GET_U_1(dp->dstNode)), + ddpskt_string(ndo, GET_U_1(dp->dstSkt))); bp += ddpSize; length -= ddpSize; hdrlen += ddpSize; - ddp_print(ndo, bp, length, dp->type, snet, dp->srcNode, dp->srcSkt); + ddp_print(ndo, bp, length, GET_U_1(dp->type), snet, + GET_U_1(dp->srcNode), GET_U_1(dp->srcSkt)); break; #ifdef notdef @@ -163,8 +170,9 @@ llap_print(netdissect_options *ndo, #endif default: - ND_PRINT((ndo, "%d > %d at-lap#%d %u", - lp->src, lp->dst, lp->type, length)); + ND_PRINT("%u > %u at-lap#%u %u", + GET_U_1(lp->src), GET_U_1(lp->dst), GET_U_1(lp->type), + length); break; } return (hdrlen); @@ -177,74 +185,77 @@ llap_print(netdissect_options *ndo, */ void atalk_print(netdissect_options *ndo, - register const u_char *bp, u_int length) + const u_char *bp, u_int length) { - register const struct atDDP *dp; + const struct atDDP *dp; u_short snet; + ndo->ndo_protocol = "atalk"; if(!ndo->ndo_eflag) - ND_PRINT((ndo, "AT ")); + ND_PRINT("AT "); if (length < ddpSize) { - ND_PRINT((ndo, " [|ddp %u]", length)); + ND_PRINT(" [|ddp %u]", length); return; } - if (!ND_TTEST2(*bp, ddpSize)) { - ND_PRINT((ndo, " [|ddp]")); + if (!ND_TTEST_LEN(bp, ddpSize)) { + ND_PRINT(" [|ddp]"); return; } dp = (const struct atDDP *)bp; - snet = EXTRACT_16BITS(&dp->srcNet); - ND_PRINT((ndo, "%s.%s", ataddr_string(ndo, snet, dp->srcNode), - ddpskt_string(ndo, dp->srcSkt))); - ND_PRINT((ndo, " > %s.%s: ", - ataddr_string(ndo, EXTRACT_16BITS(&dp->dstNet), dp->dstNode), - ddpskt_string(ndo, dp->dstSkt))); + snet = GET_BE_U_2(dp->srcNet); + ND_PRINT("%s.%s", ataddr_string(ndo, snet, GET_U_1(dp->srcNode)), + ddpskt_string(ndo, GET_U_1(dp->srcSkt))); + ND_PRINT(" > %s.%s: ", + ataddr_string(ndo, GET_BE_U_2(dp->dstNet), GET_U_1(dp->dstNode)), + ddpskt_string(ndo, GET_U_1(dp->dstSkt))); bp += ddpSize; length -= ddpSize; - ddp_print(ndo, bp, length, dp->type, snet, dp->srcNode, dp->srcSkt); + ddp_print(ndo, bp, length, GET_U_1(dp->type), snet, + GET_U_1(dp->srcNode), GET_U_1(dp->srcSkt)); } /* XXX should probably pass in the snap header and do checks like arp_print() */ void aarp_print(netdissect_options *ndo, - register const u_char *bp, u_int length) + const u_char *bp, u_int length) { - register const struct aarp *ap; + const struct aarp *ap; #define AT(member) ataddr_string(ndo, (ap->member[1]<<8)|ap->member[2],ap->member[3]) - ND_PRINT((ndo, "aarp ")); + ndo->ndo_protocol = "aarp"; + ND_PRINT("aarp "); ap = (const struct aarp *)bp; - if (!ND_TTEST(*ap)) { + if (!ND_TTEST_SIZE(ap)) { /* Just bail if we don't have the whole chunk. */ - ND_PRINT((ndo, " [|aarp]")); + nd_print_trunc(ndo); return; } if (length < sizeof(*ap)) { - ND_PRINT((ndo, " [|aarp %u]", length)); + ND_PRINT(" [|aarp %u]", length); return; } - if (EXTRACT_16BITS(&ap->htype) == 1 && - EXTRACT_16BITS(&ap->ptype) == ETHERTYPE_ATALK && - ap->halen == 6 && ap->palen == 4 ) - switch (EXTRACT_16BITS(&ap->op)) { + if (GET_BE_U_2(ap->htype) == 1 && + GET_BE_U_2(ap->ptype) == ETHERTYPE_ATALK && + GET_U_1(ap->halen) == MAC_ADDR_LEN && GET_U_1(ap->palen) == 4) + switch (GET_BE_U_2(ap->op)) { case 1: /* request */ - ND_PRINT((ndo, "who-has %s tell %s", AT(pdaddr), AT(psaddr))); + ND_PRINT("who-has %s tell %s", AT(pdaddr), AT(psaddr)); return; case 2: /* response */ - ND_PRINT((ndo, "reply %s is-at %s", AT(psaddr), etheraddr_string(ndo, ap->hsaddr))); + ND_PRINT("reply %s is-at %s", AT(psaddr), GET_ETHERADDR_STRING(ap->hsaddr)); return; case 3: /* probe (oy!) */ - ND_PRINT((ndo, "probe %s tell %s", AT(pdaddr), AT(psaddr))); + ND_PRINT("probe %s tell %s", AT(pdaddr), AT(psaddr)); return; } - ND_PRINT((ndo, "len %u op %u htype %u ptype %#x halen %u palen %u", - length, EXTRACT_16BITS(&ap->op), EXTRACT_16BITS(&ap->htype), - EXTRACT_16BITS(&ap->ptype), ap->halen, ap->palen)); + ND_PRINT("len %u op %u htype %u ptype %#x halen %u palen %u", + length, GET_BE_U_2(ap->op), GET_BE_U_2(ap->htype), + GET_BE_U_2(ap->ptype), GET_U_1(ap->halen), GET_U_1(ap->palen)); } /* @@ -252,8 +263,8 @@ aarp_print(netdissect_options *ndo, */ static void ddp_print(netdissect_options *ndo, - register const u_char *bp, register u_int length, register int t, - register u_short snet, register u_char snode, u_char skt) + const u_char *bp, u_int length, u_int t, + u_short snet, u_char snode, u_char skt) { switch (t) { @@ -271,114 +282,114 @@ ddp_print(netdissect_options *ndo, break; default: - ND_PRINT((ndo, " at-%s %d", tok2str(type2str, NULL, t), length)); + ND_PRINT(" at-%s %u", tok2str(type2str, NULL, t), length); break; } } static void atp_print(netdissect_options *ndo, - register const struct atATP *ap, u_int length) + const struct atATP *ap, u_int length) { - char c; + uint8_t control; uint32_t data; if ((const u_char *)(ap + 1) > ndo->ndo_snapend) { /* Just bail if we don't have the whole chunk. */ - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return; } if (length < sizeof(*ap)) { - ND_PRINT((ndo, " [|atp %u]", length)); + ND_PRINT(" [|atp %u]", length); return; } length -= sizeof(*ap); - switch (ap->control & 0xc0) { + control = GET_U_1(ap->control); + switch (control & 0xc0) { case atpReqCode: - ND_PRINT((ndo, " atp-req%s %d", - ap->control & atpXO? " " : "*", - EXTRACT_16BITS(&ap->transID))); + ND_PRINT(" atp-req%s %u", + control & atpXO? " " : "*", + GET_BE_U_2(ap->transID)); - atp_bitmap_print(ndo, ap->bitmap); + atp_bitmap_print(ndo, GET_U_1(ap->bitmap)); if (length != 0) - ND_PRINT((ndo, " [len=%u]", length)); + ND_PRINT(" [len=%u]", length); - switch (ap->control & (atpEOM|atpSTS)) { + switch (control & (atpEOM|atpSTS)) { case atpEOM: - ND_PRINT((ndo, " [EOM]")); + ND_PRINT(" [EOM]"); break; case atpSTS: - ND_PRINT((ndo, " [STS]")); + ND_PRINT(" [STS]"); break; case atpEOM|atpSTS: - ND_PRINT((ndo, " [EOM,STS]")); + ND_PRINT(" [EOM,STS]"); break; } break; case atpRspCode: - ND_PRINT((ndo, " atp-resp%s%d:%d (%u)", - ap->control & atpEOM? "*" : " ", - EXTRACT_16BITS(&ap->transID), ap->bitmap, length)); - switch (ap->control & (atpXO|atpSTS)) { + ND_PRINT(" atp-resp%s%u:%u (%u)", + control & atpEOM? "*" : " ", + GET_BE_U_2(ap->transID), GET_U_1(ap->bitmap), + length); + switch (control & (atpXO|atpSTS)) { case atpXO: - ND_PRINT((ndo, " [XO]")); + ND_PRINT(" [XO]"); break; case atpSTS: - ND_PRINT((ndo, " [STS]")); + ND_PRINT(" [STS]"); break; case atpXO|atpSTS: - ND_PRINT((ndo, " [XO,STS]")); + ND_PRINT(" [XO,STS]"); break; } break; case atpRelCode: - ND_PRINT((ndo, " atp-rel %d", EXTRACT_16BITS(&ap->transID))); + ND_PRINT(" atp-rel %u", GET_BE_U_2(ap->transID)); - atp_bitmap_print(ndo, ap->bitmap); + atp_bitmap_print(ndo, GET_U_1(ap->bitmap)); /* length should be zero */ if (length) - ND_PRINT((ndo, " [len=%u]", length)); + ND_PRINT(" [len=%u]", length); /* there shouldn't be any control flags */ - if (ap->control & (atpXO|atpEOM|atpSTS)) { - c = '['; - if (ap->control & atpXO) { - ND_PRINT((ndo, "%cXO", c)); + if (control & (atpXO|atpEOM|atpSTS)) { + char c = '['; + if (control & atpXO) { + ND_PRINT("%cXO", c); c = ','; } - if (ap->control & atpEOM) { - ND_PRINT((ndo, "%cEOM", c)); + if (control & atpEOM) { + ND_PRINT("%cEOM", c); c = ','; } - if (ap->control & atpSTS) { - ND_PRINT((ndo, "%cSTS", c)); - c = ','; + if (control & atpSTS) { + ND_PRINT("%cSTS", c); } - ND_PRINT((ndo, "]")); + ND_PRINT("]"); } break; default: - ND_PRINT((ndo, " atp-0x%x %d (%u)", ap->control, - EXTRACT_16BITS(&ap->transID), length)); + ND_PRINT(" atp-0x%x %u (%u)", control, + GET_BE_U_2(ap->transID), length); break; } - data = EXTRACT_32BITS(&ap->userData); + data = GET_BE_U_4(ap->userData); if (data != 0) - ND_PRINT((ndo, " 0x%x", data)); + ND_PRINT(" 0x%x", data); } static void atp_bitmap_print(netdissect_options *ndo, - register u_char bm) + u_char bm) { - register char c; - register int i; + u_int i; /* * The '& 0xff' below is needed for compilers that want to sign @@ -386,59 +397,62 @@ atp_bitmap_print(netdissect_options *ndo, * (gcc is smart enough to eliminate it, at least on the Sparc). */ if ((bm + 1) & (bm & 0xff)) { - c = '<'; + char c = '<'; for (i = 0; bm; ++i) { if (bm & 1) { - ND_PRINT((ndo, "%c%d", c, i)); + ND_PRINT("%c%u", c, i); c = ','; } bm >>= 1; } - ND_PRINT((ndo, ">")); + ND_PRINT(">"); } else { for (i = 0; bm; ++i) bm >>= 1; if (i > 1) - ND_PRINT((ndo, "<0-%d>", i - 1)); + ND_PRINT("<0-%u>", i - 1); else - ND_PRINT((ndo, "<0>")); + ND_PRINT("<0>"); } } static void nbp_print(netdissect_options *ndo, - register const struct atNBP *np, u_int length, register u_short snet, - register u_char snode, register u_char skt) + const struct atNBP *np, u_int length, u_short snet, + u_char snode, u_char skt) { - register const struct atNBPtuple *tp = + const struct atNBPtuple *tp = (const struct atNBPtuple *)((const u_char *)np + nbpHeaderSize); - int i; + uint8_t control; + u_int i; const u_char *ep; if (length < nbpHeaderSize) { - ND_PRINT((ndo, " truncated-nbp %u", length)); + ND_PRINT(" truncated-nbp %u", length); return; } length -= nbpHeaderSize; if (length < 8) { /* must be room for at least one tuple */ - ND_PRINT((ndo, " truncated-nbp %u", length + nbpHeaderSize)); + ND_PRINT(" truncated-nbp %u", length + nbpHeaderSize); return; } /* ep points to end of available data */ ep = ndo->ndo_snapend; if ((const u_char *)tp > ep) { - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return; } - switch (i = np->control & 0xf0) { + control = GET_U_1(np->control); + switch (i = (control & 0xf0)) { case nbpBrRq: case nbpLkUp: - ND_PRINT((ndo, i == nbpLkUp? " nbp-lkup %d:":" nbp-brRq %d:", np->id)); + ND_PRINT(i == nbpLkUp? " nbp-lkup %u:":" nbp-brRq %u:", + GET_U_1(np->id)); if ((const u_char *)(tp + 1) > ep) { - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return; } (void)nbp_name_print(ndo, tp, ep); @@ -447,106 +461,113 @@ nbp_print(netdissect_options *ndo, * be one tuple, the address must match the source * address and the enumerator should be zero. */ - if ((np->control & 0xf) != 1) - ND_PRINT((ndo, " [ntup=%d]", np->control & 0xf)); - if (tp->enumerator) - ND_PRINT((ndo, " [enum=%d]", tp->enumerator)); - if (EXTRACT_16BITS(&tp->net) != snet || - tp->node != snode || tp->skt != skt) - ND_PRINT((ndo, " [addr=%s.%d]", - ataddr_string(ndo, EXTRACT_16BITS(&tp->net), - tp->node), tp->skt)); + if ((control & 0xf) != 1) + ND_PRINT(" [ntup=%u]", control & 0xf); + if (GET_U_1(tp->enumerator)) + ND_PRINT(" [enum=%u]", GET_U_1(tp->enumerator)); + if (GET_BE_U_2(tp->net) != snet || + GET_U_1(tp->node) != snode || + GET_U_1(tp->skt) != skt) + ND_PRINT(" [addr=%s.%u]", + ataddr_string(ndo, GET_BE_U_2(tp->net), + GET_U_1(tp->node)), + GET_U_1(tp->skt)); break; case nbpLkUpReply: - ND_PRINT((ndo, " nbp-reply %d:", np->id)); + ND_PRINT(" nbp-reply %u:", GET_U_1(np->id)); /* print each of the tuples in the reply */ - for (i = np->control & 0xf; --i >= 0 && tp; ) + for (i = control & 0xf; i != 0 && tp; i--) tp = nbp_tuple_print(ndo, tp, ep, snet, snode, skt); break; default: - ND_PRINT((ndo, " nbp-0x%x %d (%u)", np->control, np->id, length)); + ND_PRINT(" nbp-0x%x %u (%u)", control, GET_U_1(np->id), + length); break; } } /* print a counted string */ -static const char * +static const u_char * print_cstring(netdissect_options *ndo, - register const char *cp, register const u_char *ep) + const u_char *cp, const u_char *ep) { - register u_int length; + u_int length; - if (cp >= (const char *)ep) { - ND_PRINT((ndo, "%s", tstr)); + if (cp >= ep) { + nd_print_trunc(ndo); return (0); } - length = *cp++; + length = GET_U_1(cp); + cp++; /* Spec says string can be at most 32 bytes long */ if (length > 32) { - ND_PRINT((ndo, "[len=%u]", length)); + ND_PRINT("[len=%u]", length); return (0); } - while ((int)--length >= 0) { - if (cp >= (const char *)ep) { - ND_PRINT((ndo, "%s", tstr)); + while (length != 0) { + if (cp >= ep) { + nd_print_trunc(ndo); return (0); } - ND_PRINT((ndo, "%c", *cp++)); + fn_print_char(ndo, GET_U_1(cp)); + cp++; + length--; } return (cp); } static const struct atNBPtuple * nbp_tuple_print(netdissect_options *ndo, - register const struct atNBPtuple *tp, register const u_char *ep, - register u_short snet, register u_char snode, register u_char skt) + const struct atNBPtuple *tp, const u_char *ep, + u_short snet, u_char snode, u_char skt) { - register const struct atNBPtuple *tpn; + const struct atNBPtuple *tpn; if ((const u_char *)(tp + 1) > ep) { - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return 0; } tpn = nbp_name_print(ndo, tp, ep); /* if the enumerator isn't 1, print it */ - if (tp->enumerator != 1) - ND_PRINT((ndo, "(%d)", tp->enumerator)); + if (GET_U_1(tp->enumerator) != 1) + ND_PRINT("(%u)", GET_U_1(tp->enumerator)); /* if the socket doesn't match the src socket, print it */ - if (tp->skt != skt) - ND_PRINT((ndo, " %d", tp->skt)); + if (GET_U_1(tp->skt) != skt) + ND_PRINT(" %u", GET_U_1(tp->skt)); /* if the address doesn't match the src address, it's an anomaly */ - if (EXTRACT_16BITS(&tp->net) != snet || tp->node != snode) - ND_PRINT((ndo, " [addr=%s]", - ataddr_string(ndo, EXTRACT_16BITS(&tp->net), tp->node))); + if (GET_BE_U_2(tp->net) != snet || + GET_U_1(tp->node) != snode) + ND_PRINT(" [addr=%s]", + ataddr_string(ndo, GET_BE_U_2(tp->net), GET_U_1(tp->node))); return (tpn); } static const struct atNBPtuple * nbp_name_print(netdissect_options *ndo, - const struct atNBPtuple *tp, register const u_char *ep) + const struct atNBPtuple *tp, const u_char *ep) { - register const char *cp = (const char *)tp + nbpTupleSize; + const u_char *cp = (const u_char *)tp + nbpTupleSize; - ND_PRINT((ndo, " ")); + ND_PRINT(" "); /* Object */ - ND_PRINT((ndo, "\"")); + ND_PRINT("\""); if ((cp = print_cstring(ndo, cp, ep)) != NULL) { /* Type */ - ND_PRINT((ndo, ":")); + ND_PRINT(":"); if ((cp = print_cstring(ndo, cp, ep)) != NULL) { /* Zone */ - ND_PRINT((ndo, "@")); + ND_PRINT("@"); if ((cp = print_cstring(ndo, cp, ep)) != NULL) - ND_PRINT((ndo, "\"")); + ND_PRINT("\""); } } return ((const struct atNBPtuple *)cp); @@ -556,7 +577,7 @@ nbp_name_print(netdissect_options *ndo, #define HASHNAMESIZE 4096 struct hnamemem { - int addr; + u_int addr; char *name; struct hnamemem *nxt; }; @@ -567,46 +588,64 @@ static const char * ataddr_string(netdissect_options *ndo, u_short atnet, u_char athost) { - register struct hnamemem *tp, *tp2; - register int i = (atnet << 8) | athost; + struct hnamemem *tp, *tp2; + u_int i = (atnet << 8) | athost; char nambuf[256+1]; static int first = 1; FILE *fp; /* - * if this is the first call, see if there's an AppleTalk - * number to name map file. + * Are we doing address to name resolution? */ - if (first && (first = 0, !ndo->ndo_nflag) - && (fp = fopen("/etc/atalk.names", "r"))) { - char line[256]; - int i1, i2; - - while (fgets(line, sizeof(line), fp)) { - if (line[0] == '\n' || line[0] == 0 || line[0] == '#') - continue; - if (sscanf(line, "%d.%d %256s", &i1, &i2, nambuf) == 3) - /* got a hostname. */ - i2 |= (i1 << 8); - else if (sscanf(line, "%d %256s", &i1, nambuf) == 2) - /* got a net name */ - i2 = (i1 << 8) | 255; - else - continue; - - for (tp = &hnametable[i2 & (HASHNAMESIZE-1)]; - tp->nxt; tp = tp->nxt) - ; - tp->addr = i2; - tp->nxt = newhnamemem(ndo); - tp->name = strdup(nambuf); - if (tp->name == NULL) - (*ndo->ndo_error)(ndo, - "ataddr_string: strdup(nambuf)"); + if (!ndo->ndo_nflag) { + /* + * Yes. Have we tried to open and read an AppleTalk + * number to name map file? + */ + if (!first) { + /* + * No; try to do so. + */ + first = 0; + fp = fopen("/etc/atalk.names", "r"); + if (fp != NULL) { + char line[256]; + u_int i1, i2; + + while (fgets(line, sizeof(line), fp)) { + if (line[0] == '\n' || line[0] == 0 || + line[0] == '#') + continue; + if (sscanf(line, "%u.%u %256s", &i1, + &i2, nambuf) == 3) + /* got a hostname. */ + i2 |= (i1 << 8); + else if (sscanf(line, "%u %256s", &i1, + nambuf) == 2) + /* got a net name */ + i2 = (i1 << 8) | 255; + else + continue; + + for (tp = &hnametable[i2 & (HASHNAMESIZE-1)]; + tp->nxt; tp = tp->nxt) + ; + tp->addr = i2; + tp->nxt = newhnamemem(ndo); + tp->name = strdup(nambuf); + if (tp->name == NULL) + (*ndo->ndo_error)(ndo, + S_ERR_ND_MEM_ALLOC, + "%s: strdup(nambuf)", __func__); + } + fclose(fp); + } } - fclose(fp); } + /* + * Now try to look up the address in the table. + */ for (tp = &hnametable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) if (tp->addr == i) return (tp->name); @@ -617,24 +656,25 @@ ataddr_string(netdissect_options *ndo, if (tp2->addr == i) { tp->addr = (atnet << 8) | athost; tp->nxt = newhnamemem(ndo); - (void)snprintf(nambuf, sizeof(nambuf), "%s.%d", + (void)snprintf(nambuf, sizeof(nambuf), "%s.%u", tp2->name, athost); tp->name = strdup(nambuf); if (tp->name == NULL) - (*ndo->ndo_error)(ndo, - "ataddr_string: strdup(nambuf)"); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, + "%s: strdup(nambuf)", __func__); return (tp->name); } tp->addr = (atnet << 8) | athost; tp->nxt = newhnamemem(ndo); if (athost != 255) - (void)snprintf(nambuf, sizeof(nambuf), "%d.%d", atnet, athost); + (void)snprintf(nambuf, sizeof(nambuf), "%u.%u", atnet, athost); else - (void)snprintf(nambuf, sizeof(nambuf), "%d", atnet); + (void)snprintf(nambuf, sizeof(nambuf), "%u", atnet); tp->name = strdup(nambuf); if (tp->name == NULL) - (*ndo->ndo_error)(ndo, "ataddr_string: strdup(nambuf)"); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, + "%s: strdup(nambuf)", __func__); return (tp->name); } @@ -649,13 +689,13 @@ static const struct tok skt2str[] = { static const char * ddpskt_string(netdissect_options *ndo, - register int skt) + u_int skt) { static char buf[8]; if (ndo->ndo_nflag) { - (void)snprintf(buf, sizeof(buf), "%d", skt); + (void)snprintf(buf, sizeof(buf), "%u", skt); return (buf); } - return (tok2str(skt2str, "%d", skt)); + return (tok2str(skt2str, "%u", skt)); } diff --git a/contrib/tcpdump/print-atm.c b/contrib/tcpdump/print-atm.c index bfaa9ea453..904fc4792e 100644 --- a/contrib/tcpdump/print-atm.c +++ b/contrib/tcpdump/print-atm.c @@ -22,11 +22,12 @@ /* \summary: Asynchronous Transfer Mode (ATM) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" #include "addrtoname.h" @@ -113,17 +114,18 @@ #define PROTO_POS 0 /* offset of protocol discriminator */ #define CALL_REF_POS 2 /* offset of call reference value */ #define MSG_TYPE_POS 5 /* offset of message type */ -#define MSG_LEN_POS 7 /* offset of mesage length */ +#if 0 +#define MSG_LEN_POS 7 /* offset of message length */ #define IE_BEGIN_POS 9 /* offset of first information element */ /* format of signalling messages */ #define TYPE_POS 0 #define LEN_POS 2 #define FIELD_BEGIN_POS 4 +#endif /* end of the original atmuni31.h */ -static const char tstr[] = "[|atm]"; #define OAM_CRC10_MASK 0x3ff #define OAM_PAYLOAD_LEN 48 @@ -194,23 +196,11 @@ static const struct tok oam_fm_loopback_indicator_values[] = { { 0, NULL } }; -static const struct tok *oam_functype_values[16] = { - NULL, - oam_fm_functype_values, /* 1 */ - oam_pm_functype_values, /* 2 */ - NULL, - NULL, - NULL, - NULL, - NULL, - oam_ad_functype_values, /* 8 */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL +static const struct uint_tokary oam_celltype2tokary[] = { + { OAM_CELLTYPE_FM, oam_fm_functype_values }, + { OAM_CELLTYPE_PM, oam_pm_functype_values }, + { OAM_CELLTYPE_AD, oam_ad_functype_values }, + /* uint2tokary() does not use array termination. */ }; /* @@ -244,7 +234,7 @@ atm_llc_print(netdissect_options *ndo, * 'h->len' is the length of the packet off the wire, and 'h->caplen' * is the number of bytes actually captured. */ -u_int +void atm_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { @@ -253,27 +243,21 @@ atm_if_print(netdissect_options *ndo, uint32_t llchdr; u_int hdrlen = 0; - if (caplen < 1 || length < 1) { - ND_PRINT((ndo, "%s", tstr)); - return (caplen); - } + ndo->ndo_protocol = "atm"; /* Cisco Style NLPID ? */ - if (*p == LLC_UI) { + if (GET_U_1(p) == LLC_UI) { if (ndo->ndo_eflag) - ND_PRINT((ndo, "CNLPID ")); + ND_PRINT("CNLPID "); + ndo->ndo_ll_hdr_len += 1; isoclns_print(ndo, p + 1, length - 1); - return hdrlen; + return; } /* * Must have at least a DSAP, an SSAP, and the first byte of the * control field. */ - if (caplen < 3 || length < 3) { - ND_PRINT((ndo, "%s", tstr)); - return (caplen); - } /* * Extract the presumed LLC header into a variable, for quick @@ -282,7 +266,7 @@ atm_if_print(netdissect_options *ndo, * packet nor an RFC 2684 routed NLPID-formatted PDU nor * an 802.2-but-no-SNAP IP packet. */ - llchdr = EXTRACT_24BITS(p); + llchdr = GET_BE_U_3(p); if (llchdr != LLC_UI_HDR(LLCSAP_SNAP) && llchdr != LLC_UI_HDR(LLCSAP_ISONS) && llchdr != LLC_UI_HDR(LLCSAP_IP)) { @@ -302,23 +286,21 @@ atm_if_print(netdissect_options *ndo, * packets? If so, could it be changed to use a * new DLT_IEEE802_6 value if we added it? */ - if (caplen < 20 || length < 20) { - ND_PRINT((ndo, "%s", tstr)); - return (caplen); - } if (ndo->ndo_eflag) - ND_PRINT((ndo, "%08x%08x %08x%08x ", - EXTRACT_32BITS(p), - EXTRACT_32BITS(p+4), - EXTRACT_32BITS(p+8), - EXTRACT_32BITS(p+12))); + ND_PRINT("%08x%08x %08x%08x ", + GET_BE_U_4(p), + GET_BE_U_4(p + 4), + GET_BE_U_4(p + 8), + GET_BE_U_4(p + 12)); + /* Always cover the full header. */ + ND_TCHECK_LEN(p, 20); p += 20; length -= 20; caplen -= 20; hdrlen += 20; } - hdrlen += atm_llc_print(ndo, p, length, caplen); - return (hdrlen); + ndo->ndo_ll_hdr_len += hdrlen; + ndo->ndo_ll_hdr_len += atm_llc_print(ndo, p, length, caplen); } /* @@ -349,16 +331,14 @@ sig_print(netdissect_options *ndo, { uint32_t call_ref; - ND_TCHECK(p[PROTO_POS]); - if (p[PROTO_POS] == Q2931) { + if (GET_U_1(p + PROTO_POS) == Q2931) { /* * protocol:Q.2931 for User to Network Interface * (UNI 3.1) signalling */ - ND_PRINT((ndo, "Q.2931")); - ND_TCHECK(p[MSG_TYPE_POS]); - ND_PRINT((ndo, ":%s ", - tok2str(msgtype2str, "msgtype#%d", p[MSG_TYPE_POS]))); + ND_PRINT("Q.2931"); + ND_PRINT(":%s ", + tok2str(msgtype2str, "msgtype#%u", GET_U_1(p + MSG_TYPE_POS))); /* * The call reference comes before the message type, @@ -366,16 +346,12 @@ sig_print(netdissect_options *ndo, * do from the caplen test above, we also know we have * the call reference. */ - call_ref = EXTRACT_24BITS(&p[CALL_REF_POS]); - ND_PRINT((ndo, "CALL_REF:0x%06x", call_ref)); + call_ref = GET_BE_U_3(p + CALL_REF_POS); + ND_PRINT("CALL_REF:0x%06x", call_ref); } else { - /* SCCOP with some unknown protocol atop it */ - ND_PRINT((ndo, "SSCOP, proto %d ", p[PROTO_POS])); + /* SSCOP with some unknown protocol atop it */ + ND_PRINT("SSCOP, proto %u ", GET_U_1(p + PROTO_POS)); } - return; - -trunc: - ND_PRINT((ndo, " %s", tstr)); } /* @@ -386,8 +362,9 @@ atm_print(netdissect_options *ndo, u_int vpi, u_int vci, u_int traftype, const u_char *p, u_int length, u_int caplen) { + ndo->ndo_protocol = "atm"; if (ndo->ndo_eflag) - ND_PRINT((ndo, "VPI:%u VCI:%u ", vpi, vci)); + ND_PRINT("VPI:%u VCI:%u ", vpi, vci); if (vpi == 0) { switch (vci) { @@ -397,7 +374,7 @@ atm_print(netdissect_options *ndo, return; case VCI_BCC: - ND_PRINT((ndo, "broadcast sig: ")); + ND_PRINT("broadcast sig: "); return; case VCI_OAMF4SC: /* fall through */ @@ -406,11 +383,11 @@ atm_print(netdissect_options *ndo, return; case VCI_METAC: - ND_PRINT((ndo, "meta: ")); + ND_PRINT("meta: "); return; case VCI_ILMIC: - ND_PRINT((ndo, "ilmi: ")); + ND_PRINT("ilmi: "); snmp_print(ndo, p, length); return; } @@ -433,85 +410,88 @@ atm_print(netdissect_options *ndo, } struct oam_fm_loopback_t { - uint8_t loopback_indicator; - uint8_t correlation_tag[4]; - uint8_t loopback_id[12]; - uint8_t source_id[12]; - uint8_t unused[16]; + nd_uint8_t loopback_indicator; + nd_uint32_t correlation_tag; + nd_byte loopback_id[12]; + nd_byte source_id[12]; + nd_byte unused[16]; }; struct oam_fm_ais_rdi_t { - uint8_t failure_type; - uint8_t failure_location[16]; - uint8_t unused[28]; + nd_uint8_t failure_type; + nd_byte failure_location[16]; + nd_byte unused[28]; }; void -oam_print (netdissect_options *ndo, - const u_char *p, u_int length, u_int hec) +oam_print(netdissect_options *ndo, + const u_char *p, u_int length, u_int hec) { uint32_t cell_header; uint16_t vpi, vci, cksum, cksum_shouldbe, idx; uint8_t cell_type, func_type, payload, clp; + const struct tok *oam_functype_str; union { const struct oam_fm_loopback_t *oam_fm_loopback; const struct oam_fm_ais_rdi_t *oam_fm_ais_rdi; } oam_ptr; - - ND_TCHECK(*(p+ATM_HDR_LEN_NOHEC+hec)); - cell_header = EXTRACT_32BITS(p+hec); - cell_type = ((*(p+ATM_HDR_LEN_NOHEC+hec))>>4) & 0x0f; - func_type = (*(p+ATM_HDR_LEN_NOHEC+hec)) & 0x0f; + ndo->ndo_protocol = "oam"; + cell_header = GET_BE_U_4(p + hec); + cell_type = (GET_U_1((p + ATM_HDR_LEN_NOHEC + hec)) >> 4) & 0x0f; + func_type = GET_U_1((p + ATM_HDR_LEN_NOHEC + hec)) & 0x0f; vpi = (cell_header>>20)&0xff; vci = (cell_header>>4)&0xffff; payload = (cell_header>>1)&0x7; clp = cell_header&0x1; - ND_PRINT((ndo, "%s, vpi %u, vci %u, payload [ %s ], clp %u, length %u", + ND_PRINT("%s, vpi %u, vci %u, payload [ %s ], clp %u, length %u", tok2str(oam_f_values, "OAM F5", vci), vpi, vci, tok2str(atm_pty_values, "Unknown", payload), - clp, length)); + clp, length); if (!ndo->ndo_vflag) { return; } - ND_PRINT((ndo, "\n\tcell-type %s (%u)", + ND_PRINT("\n\tcell-type %s (%u)", tok2str(oam_celltype_values, "unknown", cell_type), - cell_type)); + cell_type); - if (oam_functype_values[cell_type] == NULL) - ND_PRINT((ndo, ", func-type unknown (%u)", func_type)); + oam_functype_str = uint2tokary(oam_celltype2tokary, cell_type); + if (oam_functype_str == NULL) + ND_PRINT(", func-type unknown (%u)", func_type); else - ND_PRINT((ndo, ", func-type %s (%u)", - tok2str(oam_functype_values[cell_type],"none",func_type), - func_type)); + ND_PRINT(", func-type %s (%u)", + tok2str(oam_functype_str, "none", func_type), + func_type); p += ATM_HDR_LEN_NOHEC + hec; switch (cell_type << 4 | func_type) { case (OAM_CELLTYPE_FM << 4 | OAM_FM_FUNCTYPE_LOOPBACK): oam_ptr.oam_fm_loopback = (const struct oam_fm_loopback_t *)(p + OAM_CELLTYPE_FUNCTYPE_LEN); - ND_TCHECK(*oam_ptr.oam_fm_loopback); - ND_PRINT((ndo, "\n\tLoopback-Indicator %s, Correlation-Tag 0x%08x", + ND_TCHECK_SIZE(oam_ptr.oam_fm_loopback); + ND_PRINT("\n\tLoopback-Indicator %s, Correlation-Tag 0x%08x", tok2str(oam_fm_loopback_indicator_values, "Unknown", - oam_ptr.oam_fm_loopback->loopback_indicator & OAM_FM_LOOPBACK_INDICATOR_MASK), - EXTRACT_32BITS(&oam_ptr.oam_fm_loopback->correlation_tag))); - ND_PRINT((ndo, "\n\tLocation-ID ")); + GET_U_1(oam_ptr.oam_fm_loopback->loopback_indicator) & OAM_FM_LOOPBACK_INDICATOR_MASK), + GET_BE_U_4(oam_ptr.oam_fm_loopback->correlation_tag)); + ND_PRINT("\n\tLocation-ID "); for (idx = 0; idx < sizeof(oam_ptr.oam_fm_loopback->loopback_id); idx++) { if (idx % 2) { - ND_PRINT((ndo, "%04x ", EXTRACT_16BITS(&oam_ptr.oam_fm_loopback->loopback_id[idx]))); + ND_PRINT("%04x ", + GET_BE_U_2(&oam_ptr.oam_fm_loopback->loopback_id[idx])); } } - ND_PRINT((ndo, "\n\tSource-ID ")); + ND_PRINT("\n\tSource-ID "); for (idx = 0; idx < sizeof(oam_ptr.oam_fm_loopback->source_id); idx++) { if (idx % 2) { - ND_PRINT((ndo, "%04x ", EXTRACT_16BITS(&oam_ptr.oam_fm_loopback->source_id[idx]))); + ND_PRINT("%04x ", + GET_BE_U_2(&oam_ptr.oam_fm_loopback->source_id[idx])); } } break; @@ -519,12 +499,14 @@ oam_print (netdissect_options *ndo, case (OAM_CELLTYPE_FM << 4 | OAM_FM_FUNCTYPE_AIS): case (OAM_CELLTYPE_FM << 4 | OAM_FM_FUNCTYPE_RDI): oam_ptr.oam_fm_ais_rdi = (const struct oam_fm_ais_rdi_t *)(p + OAM_CELLTYPE_FUNCTYPE_LEN); - ND_TCHECK(*oam_ptr.oam_fm_ais_rdi); - ND_PRINT((ndo, "\n\tFailure-type 0x%02x", oam_ptr.oam_fm_ais_rdi->failure_type)); - ND_PRINT((ndo, "\n\tLocation-ID ")); + ND_TCHECK_SIZE(oam_ptr.oam_fm_ais_rdi); + ND_PRINT("\n\tFailure-type 0x%02x", + GET_U_1(oam_ptr.oam_fm_ais_rdi->failure_type)); + ND_PRINT("\n\tLocation-ID "); for (idx = 0; idx < sizeof(oam_ptr.oam_fm_ais_rdi->failure_location); idx++) { if (idx % 2) { - ND_PRINT((ndo, "%04x ", EXTRACT_16BITS(&oam_ptr.oam_fm_ais_rdi->failure_location[idx]))); + ND_PRINT("%04x ", + GET_BE_U_2(&oam_ptr.oam_fm_ais_rdi->failure_location[idx])); } } break; @@ -538,18 +520,11 @@ oam_print (netdissect_options *ndo, } /* crc10 checksum verification */ - ND_TCHECK2(*(p + OAM_CELLTYPE_FUNCTYPE_LEN + OAM_FUNCTION_SPECIFIC_LEN), 2); - cksum = EXTRACT_16BITS(p + OAM_CELLTYPE_FUNCTYPE_LEN + OAM_FUNCTION_SPECIFIC_LEN) + cksum = GET_BE_U_2(p + OAM_CELLTYPE_FUNCTYPE_LEN + OAM_FUNCTION_SPECIFIC_LEN) & OAM_CRC10_MASK; cksum_shouldbe = verify_crc10_cksum(0, p, OAM_PAYLOAD_LEN); - ND_PRINT((ndo, "\n\tcksum 0x%03x (%scorrect)", + ND_PRINT("\n\tcksum 0x%03x (%scorrect)", cksum, - cksum_shouldbe == 0 ? "" : "in")); - - return; - -trunc: - ND_PRINT((ndo, "[|oam]")); - return; + cksum_shouldbe == 0 ? "" : "in"); } diff --git a/contrib/tcpdump/print-babel.c b/contrib/tcpdump/print-babel.c index 0bb2483ade..d802a720f1 100644 --- a/contrib/tcpdump/print-babel.c +++ b/contrib/tcpdump/print-babel.c @@ -27,12 +27,21 @@ */ /* \summary: Babel Routing Protocol printer */ +/* Specifications: + * + * RFC 6126 + * RFC 7298 + * RFC 7557 + * draft-ietf-babel-rfc6126bis-17 + * draft-ietf-babel-hmac-10 + * draft-ietf-babel-source-specific-0 + */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include #include @@ -41,39 +50,37 @@ #include "addrtoname.h" #include "extract.h" -static const char tstr[] = "[|babel]"; - static void babel_print_v2(netdissect_options *, const u_char *cp, u_int length); void babel_print(netdissect_options *ndo, const u_char *cp, u_int length) { - ND_PRINT((ndo, "babel")); + ndo->ndo_protocol = "babel"; + ND_PRINT("babel"); - ND_TCHECK2(*cp, 4); + ND_TCHECK_4(cp); - if(cp[0] != 42) { - ND_PRINT((ndo, " invalid header")); + if(GET_U_1(cp) != 42) { + ND_PRINT(" invalid header"); return; } else { - ND_PRINT((ndo, " %d", cp[1])); + ND_PRINT(" %u", GET_U_1(cp + 1)); } - switch(cp[1]) { + switch(GET_U_1(cp + 1)) { case 2: babel_print_v2(ndo, cp, length); break; default: - ND_PRINT((ndo, " unknown version")); + ND_PRINT(" unknown version"); break; } return; trunc: - ND_PRINT((ndo, " %s", tstr)); - return; + nd_print_trunc(ndo); } /* TLVs */ @@ -86,13 +93,17 @@ babel_print(netdissect_options *ndo, #define MESSAGE_ROUTER_ID 6 #define MESSAGE_NH 7 #define MESSAGE_UPDATE 8 -#define MESSAGE_REQUEST 9 -#define MESSAGE_MH_REQUEST 10 +#define MESSAGE_ROUTE_REQUEST 9 +#define MESSAGE_SEQNO_REQUEST 10 #define MESSAGE_TSPC 11 #define MESSAGE_HMAC 12 -#define MESSAGE_UPDATE_SRC_SPECIFIC 13 -#define MESSAGE_REQUEST_SRC_SPECIFIC 14 -#define MESSAGE_MH_REQUEST_SRC_SPECIFIC 15 +#define MESSAGE_UPDATE_SRC_SPECIFIC 13 /* last appearance in draft-boutier-babel-source-specific-01 */ +#define MESSAGE_REQUEST_SRC_SPECIFIC 14 /* idem */ +#define MESSAGE_MH_REQUEST_SRC_SPECIFIC 15 /* idem */ +#define MESSAGE_MAC 16 +#define MESSAGE_PC 17 +#define MESSAGE_CHALLENGE_REQUEST 18 +#define MESSAGE_CHALLENGE_REPLY 19 /* sub-TLVs */ #define MESSAGE_SUB_PAD1 0 @@ -100,6 +111,12 @@ babel_print(netdissect_options *ndo, #define MESSAGE_SUB_DIVERSITY 2 #define MESSAGE_SUB_TIMESTAMP 3 +/* "Mandatory" bit in sub-TLV types */ +#define MANDATORY_MASK 0x80 + +/* Flags for the Hello TLV */ +#define UNICAST_MASK 0x8000 + /* Diversity sub-TLV channel codes */ static const struct tok diversity_str[] = { { 0, "reserved" }, @@ -108,11 +125,13 @@ static const struct tok diversity_str[] = { }; static const char * -format_id(const u_char *id) +format_id(netdissect_options *ndo, 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]); + GET_U_1(id), GET_U_1(id + 1), GET_U_1(id + 2), + GET_U_1(id + 3), GET_U_1(id + 4), GET_U_1(id + 5), + GET_U_1(id + 6), GET_U_1(id + 7)); buf[24] = '\0'; return buf; } @@ -124,6 +143,12 @@ static const char * format_prefix(netdissect_options *ndo, const u_char *prefix, unsigned char plen) { static char buf[50]; + + /* + * prefix points to a buffer on the stack into which the prefix has + * been placed, so we can't use GET_IPADDR_STRING() or + * GET_IP6ADDR_STRING() on it. + */ if(plen >= 96 && memcmp(prefix, v4prefix, 12) == 0) snprintf(buf, 50, "%s/%u", ipaddr_string(ndo, prefix + 12), plen - 96); else @@ -135,6 +160,11 @@ format_prefix(netdissect_options *ndo, const u_char *prefix, unsigned char plen) static const char * format_address(netdissect_options *ndo, const u_char *prefix) { + /* + * prefix points to a buffer on the stack into which the prefix has + * been placed, so we can't use GET_IPADDR_STRING() or + * GET_IP6ADDR_STRING() on it. + */ if(memcmp(prefix, v4prefix, 12) == 0) return ipaddr_string(ndo, prefix + 12); else @@ -249,7 +279,7 @@ network_address(int ae, const unsigned char *a, unsigned int len, * o Type 1 stands for PadN sub-TLV with the same encoding as the PadN TLV. * o Type 2 stands for Diversity sub-TLV, which propagates diversity routing * data. Its body is a variable-length sequence of 8-bit unsigned integers, - * each representing per-hop number of interferring radio channel for the + * each representing per-hop number of interfering radio channel for the * prefix. Channel 0 is invalid and must not be used in the sub-TLV, channel * 255 interferes with any other channel. * o Type 3 stands for Timestamp sub-TLV, used to compute RTT between @@ -274,128 +304,128 @@ subtlvs_print(netdissect_options *ndo, uint32_t t1, t2; while (cp < ep) { - subtype = *cp++; + subtype = GET_U_1(cp); + cp++; if(subtype == MESSAGE_SUB_PAD1) { - ND_PRINT((ndo, " sub-pad1")); + ND_PRINT(" sub-pad1"); continue; } + if ((MANDATORY_MASK & subtype) != 0) + ND_PRINT(" (M)"); if(cp == ep) goto invalid; - sublen = *cp++; + sublen = GET_U_1(cp); + cp++; if(cp + sublen > ep) goto invalid; switch(subtype) { case MESSAGE_SUB_PADN: - ND_PRINT((ndo, " sub-padn")); + ND_PRINT(" sub-padn"); cp += sublen; break; case MESSAGE_SUB_DIVERSITY: - ND_PRINT((ndo, " sub-diversity")); + ND_PRINT(" sub-diversity"); if (sublen == 0) { - ND_PRINT((ndo, " empty")); + ND_PRINT(" empty"); break; } sep = " "; - while(sublen--) { - ND_PRINT((ndo, "%s%s", sep, tok2str(diversity_str, "%u", *cp++))); + while (sublen) { + ND_PRINT("%s%s", sep, + tok2str(diversity_str, "%u", GET_U_1(cp))); + cp++; sep = "-"; + sublen--; } if(tlv_type != MESSAGE_UPDATE && tlv_type != MESSAGE_UPDATE_SRC_SPECIFIC) - ND_PRINT((ndo, " (bogus)")); + ND_PRINT(" (bogus)"); break; case MESSAGE_SUB_TIMESTAMP: - ND_PRINT((ndo, " sub-timestamp")); + ND_PRINT(" sub-timestamp"); if(tlv_type == MESSAGE_HELLO) { if(sublen < 4) goto invalid; - t1 = EXTRACT_32BITS(cp); - ND_PRINT((ndo, " %s", format_timestamp(t1))); + t1 = GET_BE_U_4(cp); + ND_PRINT(" %s", format_timestamp(t1)); } else if(tlv_type == MESSAGE_IHU) { if(sublen < 8) goto invalid; - t1 = EXTRACT_32BITS(cp); - ND_PRINT((ndo, " %s", format_timestamp(t1))); - t2 = EXTRACT_32BITS(cp + 4); - ND_PRINT((ndo, "|%s", format_timestamp(t2))); + t1 = GET_BE_U_4(cp); + ND_PRINT(" %s", format_timestamp(t1)); + t2 = GET_BE_U_4(cp + 4); + ND_PRINT("|%s", format_timestamp(t2)); } else - ND_PRINT((ndo, " (bogus)")); + ND_PRINT(" (bogus)"); cp += sublen; break; default: - ND_PRINT((ndo, " sub-unknown-0x%02x", subtype)); + ND_PRINT(" sub-unknown-0x%02x", subtype); cp += sublen; } /* switch */ } /* while */ return; invalid: - ND_PRINT((ndo, "%s", istr)); + nd_print_invalid(ndo); } #define ICHECK(i, l) \ - if ((i) + (l) > bodylen || (i) + (l) > length) goto invalid; + if ((i) + (l) > tlvs_length || (i) + (l) > packet_length_remaining) \ + goto invalid; -static void -babel_print_v2(netdissect_options *ndo, - const u_char *cp, u_int length) +static int +babel_print_v2_tlvs(netdissect_options *ndo, + const u_char *cp, u_int tlvs_length, + u_int packet_length_remaining) { 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}; - ND_TCHECK2(*cp, 4); - if (length < 4) - goto invalid; - bodylen = EXTRACT_16BITS(cp + 2); - ND_PRINT((ndo, " (%u)", bodylen)); - if (4U + bodylen > length) - goto invalid; - - /* Process the TLVs in the body */ i = 0; - while(i < bodylen) { + while(i < tlvs_length) { const u_char *message; - u_int type, len; + uint8_t type; + u_int len; - message = cp + 4 + i; + message = cp + i; - ND_TCHECK2(*message, 1); - if((type = message[0]) == MESSAGE_PAD1) { - ND_PRINT((ndo, ndo->ndo_vflag ? "\n\tPad 1" : " pad1")); + ICHECK(i, 1); + if((type = GET_U_1(message)) == MESSAGE_PAD1) { + ND_PRINT(ndo->ndo_vflag ? "\n\tPad 1" : " pad1"); i += 1; continue; } - ND_TCHECK2(*message, 2); ICHECK(i, 2); - len = message[1]; + ND_TCHECK_2(message); + len = GET_U_1(message + 1); - ND_TCHECK2(*message, 2 + len); ICHECK(i, 2 + len); + ND_TCHECK_LEN(message, 2 + len); switch(type) { case MESSAGE_PADN: { if (!ndo->ndo_vflag) - ND_PRINT((ndo, " padN")); + ND_PRINT(" padN"); else - ND_PRINT((ndo, "\n\tPad %d", len + 2)); + ND_PRINT("\n\tPad %u", len + 2); } break; case MESSAGE_ACK_REQ: { u_short nonce, interval; if (!ndo->ndo_vflag) - ND_PRINT((ndo, " ack-req")); + ND_PRINT(" ack-req"); else { - ND_PRINT((ndo, "\n\tAcknowledgment Request ")); + ND_PRINT("\n\tAcknowledgment Request "); if(len < 6) goto invalid; - nonce = EXTRACT_16BITS(message + 4); - interval = EXTRACT_16BITS(message + 6); - ND_PRINT((ndo, "%04x %s", nonce, format_interval(interval))); + nonce = GET_BE_U_2(message + 4); + interval = GET_BE_U_2(message + 6); + ND_PRINT("%04x %s", nonce, format_interval(interval)); } } break; @@ -403,26 +433,33 @@ babel_print_v2(netdissect_options *ndo, case MESSAGE_ACK: { u_short nonce; if (!ndo->ndo_vflag) - ND_PRINT((ndo, " ack")); + ND_PRINT(" ack"); else { - ND_PRINT((ndo, "\n\tAcknowledgment ")); + ND_PRINT("\n\tAcknowledgment "); if(len < 2) goto invalid; - nonce = EXTRACT_16BITS(message + 2); - ND_PRINT((ndo, "%04x", nonce)); + nonce = GET_BE_U_2(message + 2); + ND_PRINT("%04x", nonce); } } break; case MESSAGE_HELLO: { - u_short seqno, interval; + u_short seqno, interval, unicast; if (!ndo->ndo_vflag) - ND_PRINT((ndo, " hello")); + ND_PRINT(" hello"); else { - ND_PRINT((ndo, "\n\tHello ")); + ND_PRINT("\n\tHello "); if(len < 6) goto invalid; - seqno = EXTRACT_16BITS(message + 4); - interval = EXTRACT_16BITS(message + 6); - ND_PRINT((ndo, "seqno %u interval %s", seqno, format_interval(interval))); + unicast = (GET_BE_U_2(message + 2) & UNICAST_MASK); + seqno = GET_BE_U_2(message + 4); + interval = GET_BE_U_2(message + 6); + if(unicast) + ND_PRINT("(Unicast) "); + ND_PRINT("seqno %u ", seqno); + if(interval!=0) + ND_PRINT("interval %s", format_interval(interval)); + else + ND_PRINT("unscheduled"); /* Extra data. */ if(len > 6) subtlvs_print(ndo, message + 8, message + 2 + len, type); @@ -431,20 +468,24 @@ babel_print_v2(netdissect_options *ndo, break; case MESSAGE_IHU: { - unsigned short txcost, interval; + unsigned short rxcost, interval; if (!ndo->ndo_vflag) - ND_PRINT((ndo, " ihu")); + ND_PRINT(" ihu"); else { u_char address[16]; + u_char ae; int rc; - ND_PRINT((ndo, "\n\tIHU ")); + ND_PRINT("\n\tIHU "); if(len < 6) goto invalid; - txcost = EXTRACT_16BITS(message + 4); - interval = EXTRACT_16BITS(message + 6); - rc = network_address(message[2], message + 8, len - 6, address); - if(rc < 0) { ND_PRINT((ndo, "%s", tstr)); break; } - ND_PRINT((ndo, "%s txcost %u interval %s", - format_address(ndo, address), txcost, format_interval(interval))); + rxcost = GET_BE_U_2(message + 4); + interval = GET_BE_U_2(message + 6); + ae = GET_U_1(message + 2); + rc = network_address(ae, message + 8, + len - 6, address); + if(rc < 0) { nd_print_trunc(ndo); break; } + ND_PRINT("%s rxcost %u interval %s", + ae == 0 ? "any" : format_address(ndo, address), + rxcost, format_interval(interval)); /* Extra data. */ if((u_int)rc < len - 6) subtlvs_print(ndo, message + 8 + rc, message + 2 + len, @@ -455,64 +496,70 @@ babel_print_v2(netdissect_options *ndo, case MESSAGE_ROUTER_ID: { if (!ndo->ndo_vflag) - ND_PRINT((ndo, " router-id")); + ND_PRINT(" router-id"); else { - ND_PRINT((ndo, "\n\tRouter Id")); + ND_PRINT("\n\tRouter Id"); if(len < 10) goto invalid; - ND_PRINT((ndo, " %s", format_id(message + 4))); + ND_PRINT(" %s", format_id(ndo, message + 4)); } } break; case MESSAGE_NH: { if (!ndo->ndo_vflag) - ND_PRINT((ndo, " nh")); + ND_PRINT(" nh"); else { int rc; + u_char ae; u_char nh[16]; - ND_PRINT((ndo, "\n\tNext Hop")); + ND_PRINT("\n\tNext Hop"); if(len < 2) goto invalid; - rc = network_address(message[2], message + 4, len - 2, nh); + ae = GET_U_1(message + 2); + rc = network_address(ae, message + 4, + len - 2, nh); if(rc < 0) goto invalid; - ND_PRINT((ndo, " %s", format_address(ndo, nh))); + ND_PRINT(" %s", ae == 0 ? "invalid AE 0" : format_address(ndo, nh)); } } break; case MESSAGE_UPDATE: { if (!ndo->ndo_vflag) { - ND_PRINT((ndo, " update")); + ND_PRINT(" update"); if(len < 10) - ND_PRINT((ndo, "/truncated")); + goto invalid; else - ND_PRINT((ndo, "%s%s%s", - (message[3] & 0x80) ? "/prefix": "", - (message[3] & 0x40) ? "/id" : "", - (message[3] & 0x3f) ? "/unknown" : "")); + ND_PRINT("%s%s%s", + (GET_U_1(message + 3) & 0x80) ? "/prefix": "", + (GET_U_1(message + 3) & 0x40) ? "/id" : "", + (GET_U_1(message + 3) & 0x3f) ? "/unknown" : ""); } else { u_short interval, seqno, metric; - u_char plen; + u_char ae, plen; int rc; u_char prefix[16]; - ND_PRINT((ndo, "\n\tUpdate")); + ND_PRINT("\n\tUpdate"); if(len < 10) goto invalid; - plen = message[4] + (message[2] == 1 ? 96 : 0); - rc = network_prefix(message[2], message[4], message[5], + ae = GET_U_1(message + 2); + plen = GET_U_1(message + 4) + (GET_U_1(message + 2) == 1 ? 96 : 0); + rc = network_prefix(ae, + GET_U_1(message + 4), + GET_U_1(message + 5), message + 12, - message[2] == 1 ? v4_prefix : v6_prefix, + GET_U_1(message + 2) == 1 ? v4_prefix : v6_prefix, len - 10, prefix); if(rc < 0) goto invalid; - interval = EXTRACT_16BITS(message + 6); - seqno = EXTRACT_16BITS(message + 8); - metric = EXTRACT_16BITS(message + 10); - ND_PRINT((ndo, "%s%s%s %s metric %u seqno %u interval %s", - (message[3] & 0x80) ? "/prefix": "", - (message[3] & 0x40) ? "/id" : "", - (message[3] & 0x3f) ? "/unknown" : "", - format_prefix(ndo, prefix, plen), - metric, seqno, format_interval_update(interval))); - if(message[3] & 0x80) { - if(message[2] == 1) + interval = GET_BE_U_2(message + 6); + seqno = GET_BE_U_2(message + 8); + metric = GET_BE_U_2(message + 10); + ND_PRINT("%s%s%s %s metric %u seqno %u interval %s", + (GET_U_1(message + 3) & 0x80) ? "/prefix": "", + (GET_U_1(message + 3) & 0x40) ? "/id" : "", + (GET_U_1(message + 3) & 0x3f) ? "/unknown" : "", + ae == 0 ? "any" : format_prefix(ndo, prefix, plen), + metric, seqno, format_interval_update(interval)); + if(GET_U_1(message + 3) & 0x80) { + if(GET_U_1(message + 2) == 1) memcpy(v4_prefix, prefix, 16); else memcpy(v6_prefix, prefix, 16); @@ -524,86 +571,93 @@ babel_print_v2(netdissect_options *ndo, } break; - case MESSAGE_REQUEST: { + case MESSAGE_ROUTE_REQUEST: { if (!ndo->ndo_vflag) - ND_PRINT((ndo, " request")); + ND_PRINT(" route-request"); else { int rc; - u_char prefix[16], plen; - ND_PRINT((ndo, "\n\tRequest ")); + u_char prefix[16], ae, plen; + ND_PRINT("\n\tRoute Request "); if(len < 2) goto invalid; - plen = message[3] + (message[2] == 1 ? 96 : 0); - rc = network_prefix(message[2], message[3], 0, + ae = GET_U_1(message + 2); + plen = GET_U_1(message + 3) + (GET_U_1(message + 2) == 1 ? 96 : 0); + rc = network_prefix(ae, + GET_U_1(message + 3), 0, message + 4, NULL, len - 2, prefix); if(rc < 0) goto invalid; - ND_PRINT((ndo, "for %s", - message[2] == 0 ? "any" : format_prefix(ndo, prefix, plen))); + ND_PRINT("for %s", + ae == 0 ? "any" : format_prefix(ndo, prefix, plen)); } } break; - case MESSAGE_MH_REQUEST : { + case MESSAGE_SEQNO_REQUEST : { if (!ndo->ndo_vflag) - ND_PRINT((ndo, " mh-request")); + ND_PRINT(" seqno-request"); else { int rc; u_short seqno; - u_char prefix[16], plen; - ND_PRINT((ndo, "\n\tMH-Request ")); + u_char prefix[16], ae, plen; + ND_PRINT("\n\tSeqno Request "); if(len < 14) goto invalid; - seqno = EXTRACT_16BITS(message + 4); - rc = network_prefix(message[2], message[3], 0, + ae = GET_U_1(message + 2); + seqno = GET_BE_U_2(message + 4); + rc = network_prefix(ae, + GET_U_1(message + 3), 0, message + 16, NULL, len - 14, prefix); if(rc < 0) goto invalid; - plen = message[3] + (message[2] == 1 ? 96 : 0); - ND_PRINT((ndo, "(%u hops) for %s seqno %u id %s", - message[6], format_prefix(ndo, prefix, plen), - seqno, format_id(message + 8))); + plen = GET_U_1(message + 3) + (GET_U_1(message + 2) == 1 ? 96 : 0); + ND_PRINT("(%u hops) for %s seqno %u id %s", + GET_U_1(message + 6), + ae == 0 ? "invalid AE 0" : format_prefix(ndo, prefix, plen), + seqno, format_id(ndo, message + 8)); } } break; case MESSAGE_TSPC : if (!ndo->ndo_vflag) - ND_PRINT((ndo, " tspc")); + ND_PRINT(" tspc"); else { - ND_PRINT((ndo, "\n\tTS/PC ")); + ND_PRINT("\n\tTS/PC "); if(len < 6) goto invalid; - ND_PRINT((ndo, "timestamp %u packetcounter %u", EXTRACT_32BITS (message + 4), - EXTRACT_16BITS(message + 2))); + ND_PRINT("timestamp %u packetcounter %u", + GET_BE_U_4(message + 4), + GET_BE_U_2(message + 2)); } break; case MESSAGE_HMAC : { if (!ndo->ndo_vflag) - ND_PRINT((ndo, " hmac")); + ND_PRINT(" hmac"); else { unsigned j; - ND_PRINT((ndo, "\n\tHMAC ")); + ND_PRINT("\n\tHMAC "); if(len < 18) goto invalid; - ND_PRINT((ndo, "key-id %u digest-%u ", EXTRACT_16BITS(message + 2), len - 2)); + ND_PRINT("key-id %u digest-%u ", GET_BE_U_2(message + 2), + len - 2); for (j = 0; j < len - 2; j++) - ND_PRINT((ndo, "%02X", message[4 + j])); + ND_PRINT("%02X", GET_U_1(message + j + 4)); } } break; case MESSAGE_UPDATE_SRC_SPECIFIC : { if(!ndo->ndo_vflag) { - ND_PRINT((ndo, " ss-update")); + ND_PRINT(" ss-update"); } else { u_char prefix[16], src_prefix[16]; u_short interval, seqno, metric; u_char ae, plen, src_plen, omitted; int rc; int parsed_len = 10; - ND_PRINT((ndo, "\n\tSS-Update")); + ND_PRINT("\n\tSS-Update"); if(len < 10) goto invalid; - ae = message[2]; - src_plen = message[3]; - plen = message[4]; - omitted = message[5]; - interval = EXTRACT_16BITS(message + 6); - seqno = EXTRACT_16BITS(message + 8); - metric = EXTRACT_16BITS(message + 10); + ae = GET_U_1(message + 2); + src_plen = GET_U_1(message + 3); + plen = GET_U_1(message + 4); + omitted = GET_U_1(message + 5); + interval = GET_BE_U_2(message + 6); + seqno = GET_BE_U_2(message + 8); + metric = GET_BE_U_2(message + 10); rc = network_prefix(ae, plen, omitted, message + 2 + parsed_len, ae == 1 ? v4_prefix : v6_prefix, len - parsed_len, prefix); @@ -618,10 +672,10 @@ babel_print_v2(netdissect_options *ndo, src_plen += 96; parsed_len += rc; - ND_PRINT((ndo, " %s from", format_prefix(ndo, prefix, plen))); - ND_PRINT((ndo, " %s metric %u seqno %u interval %s", + ND_PRINT(" %s from", format_prefix(ndo, prefix, plen)); + ND_PRINT(" %s metric %u seqno %u interval %s", format_prefix(ndo, src_prefix, src_plen), - metric, seqno, format_interval_update(interval))); + metric, seqno, format_interval_update(interval)); /* extra data? */ if((u_int)parsed_len < len) subtlvs_print(ndo, message + 2 + parsed_len, @@ -632,15 +686,15 @@ babel_print_v2(netdissect_options *ndo, case MESSAGE_REQUEST_SRC_SPECIFIC : { if(!ndo->ndo_vflag) - ND_PRINT((ndo, " ss-request")); + ND_PRINT(" ss-request"); else { int rc, parsed_len = 3; u_char ae, plen, src_plen, prefix[16], src_prefix[16]; - ND_PRINT((ndo, "\n\tSS-Request ")); + ND_PRINT("\n\tSS-Request "); if(len < 3) goto invalid; - ae = message[2]; - plen = message[3]; - src_plen = message[4]; + ae = GET_U_1(message + 2); + plen = GET_U_1(message + 3); + src_plen = GET_U_1(message + 4); rc = network_prefix(ae, plen, 0, message + 2 + parsed_len, NULL, len - parsed_len, prefix); if(rc < 0) goto invalid; @@ -654,10 +708,10 @@ babel_print_v2(netdissect_options *ndo, src_plen += 96; parsed_len += rc; if(ae == 0) { - ND_PRINT((ndo, "for any")); + ND_PRINT("for any"); } else { - ND_PRINT((ndo, "for (%s, ", format_prefix(ndo, prefix, plen))); - ND_PRINT((ndo, "%s)", format_prefix(ndo, src_prefix, src_plen))); + ND_PRINT("for (%s, ", format_prefix(ndo, prefix, plen)); + ND_PRINT("%s)", format_prefix(ndo, src_prefix, src_plen)); } } } @@ -665,19 +719,19 @@ babel_print_v2(netdissect_options *ndo, case MESSAGE_MH_REQUEST_SRC_SPECIFIC : { if(!ndo->ndo_vflag) - ND_PRINT((ndo, " ss-mh-request")); + ND_PRINT(" ss-mh-request"); else { int rc, parsed_len = 14; u_short seqno; u_char ae, plen, src_plen, prefix[16], src_prefix[16], hopc; const u_char *router_id = NULL; - ND_PRINT((ndo, "\n\tSS-MH-Request ")); + ND_PRINT("\n\tSS-MH-Request "); if(len < 14) goto invalid; - ae = message[2]; - plen = message[3]; - seqno = EXTRACT_16BITS(message + 4); - hopc = message[6]; - src_plen = message[7]; + ae = GET_U_1(message + 2); + plen = GET_U_1(message + 3); + seqno = GET_BE_U_2(message + 4); + hopc = GET_U_1(message + 6); + src_plen = GET_U_1(message + 7); router_id = message + 8; rc = network_prefix(ae, plen, 0, message + 2 + parsed_len, NULL, len - parsed_len, prefix); @@ -690,30 +744,120 @@ babel_print_v2(netdissect_options *ndo, if(rc < 0) goto invalid; if(ae == 1) src_plen += 96; - ND_PRINT((ndo, "(%u hops) for (%s, ", - hopc, format_prefix(ndo, prefix, plen))); - ND_PRINT((ndo, "%s) seqno %u id %s", + ND_PRINT("(%u hops) for (%s, ", + hopc, format_prefix(ndo, prefix, plen)); + ND_PRINT("%s) seqno %u id %s", format_prefix(ndo, src_prefix, src_plen), - seqno, format_id(router_id))); + seqno, format_id(ndo, router_id)); + } + } + break; + + case MESSAGE_MAC: { + if (!ndo->ndo_vflag) + ND_PRINT(" mac"); + else { + ND_PRINT("\n\tMAC "); + ND_PRINT("len %u", len); + } + } + break; + + case MESSAGE_PC: { + if (!ndo->ndo_vflag) + ND_PRINT(" pc"); + else { + ND_PRINT("\n\tPC"); + if(len < 4) goto invalid; + ND_PRINT(" value %u", + GET_BE_U_4(message + 2)); + ND_PRINT(" index len %u", len-4); + } + } + break; + + case MESSAGE_CHALLENGE_REQUEST: { + if (!ndo->ndo_vflag) + ND_PRINT(" challenge_request"); + else { + ND_PRINT("\n\tChallenge Request"); + if(len > 192) goto invalid; + ND_PRINT(" len %u", len); + } + } + break; + + case MESSAGE_CHALLENGE_REPLY: { + if (!ndo->ndo_vflag) + ND_PRINT(" challenge_reply"); + else { + ND_PRINT("\n\tChallenge Reply"); + if (len > 192) goto invalid; + ND_PRINT(" len %u", len); } } break; default: if (!ndo->ndo_vflag) - ND_PRINT((ndo, " unknown")); + ND_PRINT(" unknown"); else - ND_PRINT((ndo, "\n\tUnknown message type %d", type)); + ND_PRINT("\n\tUnknown message type %u", type); } i += len + 2; } + + return 0; /* OK */ + +trunc: + return -1; /* packet truncated by capture process */ + +invalid: + return -2; /* packet is invalid */ +} + +static void +babel_print_v2(netdissect_options *ndo, + const u_char *cp, u_int length) +{ + u_short bodylen; + int ret; + + ND_TCHECK_4(cp); + if (length < 4) + goto invalid; + bodylen = GET_BE_U_2(cp + 2); + ND_PRINT(" (%u)", bodylen); + length -= 4; + cp += 4; + + /* Process the TLVs in the body */ + if (length < bodylen) + goto invalid; + ret = babel_print_v2_tlvs(ndo, cp, bodylen, length); + if (ret == -1) + goto trunc; + if (ret == -2) + goto invalid; + length -= bodylen; + cp += bodylen; + + /* If there's a trailer, process the TLVs in the trailer */ + if (length != 0) { + if(ndo->ndo_vflag) ND_PRINT("\n\t----"); + else ND_PRINT(" |"); + ret = babel_print_v2_tlvs(ndo, cp, length, length); + if (ret == -1) + goto trunc; + if (ret == -2) + goto invalid; + } return; trunc: - ND_PRINT((ndo, " %s", tstr)); + nd_print_trunc(ndo); return; invalid: - ND_PRINT((ndo, "%s", istr)); - return; + nd_print_invalid(ndo); } diff --git a/contrib/tcpdump/print-bcm-li.c b/contrib/tcpdump/print-bcm-li.c new file mode 100644 index 0000000000..12b1ebbe20 --- /dev/null +++ b/contrib/tcpdump/print-bcm-li.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 1990, 1991, 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. + */ + +/* \summary: Broadcom LI Printer */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "netdissect-stdinc.h" + +#define ND_LONGJMP_FROM_TCHECK +#include "netdissect.h" +#include "addrtoname.h" +#include "extract.h" + +#define BCM_LI_SHIM_LEN 4 + +static const struct tok bcm_li_direction_values[] = { + { 1, "unused" }, + { 2, "egress" }, + { 3, "ingress" }, + { 0, NULL} +}; + +#define BCM_LI_PKT_TYPE_UNDECIDED 4 +#define BCM_LI_PKT_TYPE_IPV4 5 +#define BCM_LI_PKT_TYPE_IPV6 6 +#define BCM_LI_PKT_TYPE_ETHERNET 7 + +static const struct tok bcm_li_pkt_type_values[] = { + { BCM_LI_PKT_TYPE_UNDECIDED, "undecided" }, + { BCM_LI_PKT_TYPE_IPV4, "ipv4" }, + { BCM_LI_PKT_TYPE_IPV6, "ipv6" }, + { BCM_LI_PKT_TYPE_ETHERNET, "ethernet" }, + { 0, NULL} +}; + +static const struct tok bcm_li_pkt_subtype_values[] = { + { 1, "single VLAN tag" }, + { 2, "double VLAN tag" }, + { 3, "untagged" }, + { 0, NULL} +}; + +void +bcm_li_print(netdissect_options *ndo, + const u_char *bp, u_int length) +{ + u_int shim, direction, pkt_type, pkt_subtype, li_id; + + ndo->ndo_protocol = "bcm_li"; + if (length < BCM_LI_SHIM_LEN) { + ND_PRINT(" (length %u < %u)", length, BCM_LI_SHIM_LEN); + goto invalid; + } + shim = GET_BE_U_4(bp); + + direction = (shim >> 29) & 0x7; + pkt_type = (shim >> 25) & 0xf; + pkt_subtype = (shim >> 22) & 0x7; + li_id = shim & 0x3fffff; + + length -= BCM_LI_SHIM_LEN; + bp += BCM_LI_SHIM_LEN; + + ND_PRINT("%sBCM-LI-SHIM: direction %s, pkt-type %s, pkt-subtype %s, li-id %u%s", + ndo->ndo_vflag ? "\n " : "", + tok2str(bcm_li_direction_values, "unknown", direction), + tok2str(bcm_li_pkt_type_values, "unknown", pkt_type), + tok2str(bcm_li_pkt_subtype_values, "unknown", pkt_subtype), + li_id, + ndo->ndo_vflag ? "\n ": ""); + + if (!ndo->ndo_vflag) { + ND_TCHECK_LEN(bp, length); + return; + } + + switch (pkt_type) { + case BCM_LI_PKT_TYPE_ETHERNET: + ether_print(ndo, bp, length, ND_BYTES_AVAILABLE_AFTER(bp), NULL, NULL); + break; + case BCM_LI_PKT_TYPE_IPV4: + ip_print(ndo, bp, length); + break; + case BCM_LI_PKT_TYPE_IPV6: + ip6_print(ndo, bp, length); + break; + case BCM_LI_PKT_TYPE_UNDECIDED: + + /* + * Guess IP version from first nibble. + */ + if ((GET_U_1(bp) >> 4) == 4) { + ip_print(ndo, bp, length); + } else if ((GET_U_1(bp) >> 4) == 6) { + ip6_print(ndo, bp, length); + } else { + ND_PRINT("unknown payload"); + } + break; + + default: + goto invalid; + } + + return; +invalid: + nd_print_invalid(ndo); +} + diff --git a/contrib/tcpdump/print-beep.c b/contrib/tcpdump/print-beep.c index 64a162d749..76017eaf89 100644 --- a/contrib/tcpdump/print-beep.c +++ b/contrib/tcpdump/print-beep.c @@ -12,10 +12,10 @@ /* \summary: Blocks Extensible Exchange Protocol (BEEP) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include @@ -31,7 +31,7 @@ static int l_strnstart(netdissect_options *ndo, const char *tstr1, u_int tl1, const char *str2, u_int l2) { - if (!ND_TTEST2(*str2, tl1)) { + if (!ND_TTEST_LEN(str2, tl1)) { /* * We don't have tl1 bytes worth of captured data * for the string, so we can't check for this @@ -49,20 +49,21 @@ void beep_print(netdissect_options *ndo, const u_char *bp, u_int length) { + ndo->ndo_protocol = "beep"; if (l_strnstart(ndo, "MSG", 4, (const char *)bp, length)) /* A REQuest */ - ND_PRINT((ndo, " BEEP MSG")); + ND_PRINT(" BEEP MSG"); else if (l_strnstart(ndo, "RPY ", 4, (const char *)bp, length)) - ND_PRINT((ndo, " BEEP RPY")); + ND_PRINT(" BEEP RPY"); else if (l_strnstart(ndo, "ERR ", 4, (const char *)bp, length)) - ND_PRINT((ndo, " BEEP ERR")); + ND_PRINT(" BEEP ERR"); else if (l_strnstart(ndo, "ANS ", 4, (const char *)bp, length)) - ND_PRINT((ndo, " BEEP ANS")); + ND_PRINT(" BEEP ANS"); else if (l_strnstart(ndo, "NUL ", 4, (const char *)bp, length)) - ND_PRINT((ndo, " BEEP NUL")); + ND_PRINT(" BEEP NUL"); else if (l_strnstart(ndo, "SEQ ", 4, (const char *)bp, length)) - ND_PRINT((ndo, " BEEP SEQ")); + ND_PRINT(" BEEP SEQ"); else if (l_strnstart(ndo, "END", 4, (const char *)bp, length)) - ND_PRINT((ndo, " BEEP END")); + ND_PRINT(" BEEP END"); else - ND_PRINT((ndo, " BEEP (payload or undecoded)")); + ND_PRINT(" BEEP (payload or undecoded)"); } diff --git a/contrib/tcpdump/print-bfd.c b/contrib/tcpdump/print-bfd.c index 0e766ca3a4..8c047357db 100644 --- a/contrib/tcpdump/print-bfd.c +++ b/contrib/tcpdump/print-bfd.c @@ -21,11 +21,12 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" @@ -72,15 +73,15 @@ */ struct bfd_header_t { - uint8_t version_diag; - uint8_t flags; - uint8_t detect_time_multiplier; - uint8_t length; - uint8_t my_discriminator[4]; - uint8_t your_discriminator[4]; - uint8_t desired_min_tx_interval[4]; - uint8_t required_min_rx_interval[4]; - uint8_t required_min_echo_interval[4]; + nd_uint8_t version_diag; + nd_uint8_t flags; + nd_uint8_t detect_time_multiplier; + nd_uint8_t length; + nd_uint32_t my_discriminator; + nd_uint32_t your_discriminator; + nd_uint32_t desired_min_tx_interval; + nd_uint32_t required_min_rx_interval; + nd_uint32_t required_min_echo_interval; }; /* @@ -94,10 +95,10 @@ struct bfd_header_t { */ struct bfd_auth_header_t { - uint8_t auth_type; - uint8_t auth_len; - uint8_t auth_data; - uint8_t dummy; /* minimun 4 bytes */ + nd_uint8_t auth_type; + nd_uint8_t auth_len; + nd_uint8_t auth_data; + nd_uint8_t dummy; /* minimum 4 bytes */ }; enum auth_type { @@ -142,6 +143,13 @@ static const struct tok bfd_diag_values[] = { { 0, NULL } }; +static const struct tok bfd_port_values[] = { + { BFD_CONTROL_PORT, "Control" }, + { BFD_MULTIHOP_PORT, "Multihop" }, + { BFD_LAG_PORT, "Lag" }, + { 0, NULL } +}; + #define BFD_FLAG_AUTH 0x04 static const struct tok bfd_v0_flag_values[] = { @@ -174,23 +182,25 @@ static const struct tok bfd_v1_state_values[] = { { 0, NULL } }; -static int -auth_print(netdissect_options *ndo, register const u_char *pptr) +static void +auth_print(netdissect_options *ndo, const u_char *pptr) { const struct bfd_auth_header_t *bfd_auth_header; + uint8_t auth_type, auth_len; int i; - pptr += sizeof (const struct bfd_header_t); + pptr += sizeof (struct bfd_header_t); bfd_auth_header = (const struct bfd_auth_header_t *)pptr; - ND_TCHECK(*bfd_auth_header); - ND_PRINT((ndo, "\n\tAuthentication: %s (%u), length: %u", - tok2str(bfd_v1_authentication_values,"Unknown",bfd_auth_header->auth_type), - bfd_auth_header->auth_type, - bfd_auth_header->auth_len)); + ND_TCHECK_SIZE(bfd_auth_header); + auth_type = GET_U_1(bfd_auth_header->auth_type); + auth_len = GET_U_1(bfd_auth_header->auth_len); + ND_PRINT("\n\tAuthentication: %s (%u), length: %u", + tok2str(bfd_v1_authentication_values,"Unknown",auth_type), + auth_type, auth_len); pptr += 2; - ND_PRINT((ndo, "\n\t Auth Key ID: %d", *pptr)); + ND_PRINT("\n\t Auth Key ID: %u", GET_U_1(pptr)); - switch(bfd_auth_header->auth_type) { + switch(auth_type) { case AUTH_PASSWORD: /* * Simple Password Authentication Section Format @@ -203,18 +213,16 @@ auth_print(netdissect_options *ndo, register const u_char *pptr) * | ... | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ - if (bfd_auth_header->auth_len < AUTH_PASSWORD_FIELD_MIN_LEN || - bfd_auth_header->auth_len > AUTH_PASSWORD_FIELD_MAX_LEN) { - ND_PRINT((ndo, "[invalid length %d]", - bfd_auth_header->auth_len)); + if (auth_len < AUTH_PASSWORD_FIELD_MIN_LEN || + auth_len > AUTH_PASSWORD_FIELD_MAX_LEN) { + ND_PRINT("[invalid length %u]", + auth_len); break; } pptr++; - ND_PRINT((ndo, ", Password: ")); + ND_PRINT(", Password: "); /* the length is equal to the password length plus three */ - if (fn_printn(ndo, pptr, bfd_auth_header->auth_len - 3, - ndo->ndo_snapend)) - goto trunc; + (void)nd_printn(ndo, pptr, auth_len - 3, NULL); break; case AUTH_MD5: case AUTH_MET_MD5: @@ -233,19 +241,18 @@ auth_print(netdissect_options *ndo, register const u_char *pptr) * | ... | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ - if (bfd_auth_header->auth_len != AUTH_MD5_FIELD_LEN) { - ND_PRINT((ndo, "[invalid length %d]", - bfd_auth_header->auth_len)); + if (auth_len != AUTH_MD5_FIELD_LEN) { + ND_PRINT("[invalid length %u]", + auth_len); break; } pptr += 2; - ND_TCHECK2(*pptr, 4); - ND_PRINT((ndo, ", Sequence Number: 0x%08x", EXTRACT_32BITS(pptr))); + ND_PRINT(", Sequence Number: 0x%08x", GET_BE_U_4(pptr)); pptr += 4; - ND_TCHECK2(*pptr, AUTH_MD5_HASH_LEN); - ND_PRINT((ndo, "\n\t Digest: ")); + ND_TCHECK_LEN(pptr, AUTH_MD5_HASH_LEN); + ND_PRINT("\n\t Digest: "); for(i = 0; i < AUTH_MD5_HASH_LEN; i++) - ND_PRINT((ndo, "%02x", pptr[i])); + ND_PRINT("%02x", GET_U_1(pptr + i)); break; case AUTH_SHA1: case AUTH_MET_SHA1: @@ -264,32 +271,30 @@ auth_print(netdissect_options *ndo, register const u_char *pptr) * | ... | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ - if (bfd_auth_header->auth_len != AUTH_SHA1_FIELD_LEN) { - ND_PRINT((ndo, "[invalid length %d]", - bfd_auth_header->auth_len)); + if (auth_len != AUTH_SHA1_FIELD_LEN) { + ND_PRINT("[invalid length %u]", + auth_len); break; } pptr += 2; - ND_TCHECK2(*pptr, 4); - ND_PRINT((ndo, ", Sequence Number: 0x%08x", EXTRACT_32BITS(pptr))); + ND_PRINT(", Sequence Number: 0x%08x", GET_BE_U_4(pptr)); pptr += 4; - ND_TCHECK2(*pptr, AUTH_SHA1_HASH_LEN); - ND_PRINT((ndo, "\n\t Hash: ")); + ND_TCHECK_LEN(pptr, AUTH_SHA1_HASH_LEN); + ND_PRINT("\n\t Hash: "); for(i = 0; i < AUTH_SHA1_HASH_LEN; i++) - ND_PRINT((ndo, "%02x", pptr[i])); + ND_PRINT("%02x", GET_U_1(pptr + i)); break; } - return 0; - -trunc: - return 1; } void -bfd_print(netdissect_options *ndo, register const u_char *pptr, - register u_int len, register u_int port) +bfd_print(netdissect_options *ndo, const u_char *pptr, + u_int len, u_int port) { - if (port == BFD_CONTROL_PORT) { + ndo->ndo_protocol = "bfd"; + if (port == BFD_CONTROL_PORT || + port == BFD_MULTIHOP_PORT || + port == BFD_LAG_PORT) { /* * Control packet. */ @@ -299,10 +304,10 @@ bfd_print(netdissect_options *ndo, register const u_char *pptr, uint8_t flags; bfd_header = (const struct bfd_header_t *)pptr; - ND_TCHECK(*bfd_header); - version_diag = bfd_header->version_diag; + ND_TCHECK_SIZE(bfd_header); + version_diag = GET_U_1(bfd_header->version_diag); version = BFD_EXTRACT_VERSION(version_diag); - flags = bfd_header->flags; + flags = GET_U_1(bfd_header->flags); switch (version) { @@ -310,33 +315,37 @@ bfd_print(netdissect_options *ndo, register const u_char *pptr, case 0: if (ndo->ndo_vflag < 1) { - ND_PRINT((ndo, "BFDv0, Control, Flags: [%s], length: %u", + ND_PRINT("BFDv0, Control, Flags: [%s], length: %u", bittok2str(bfd_v0_flag_values, "none", flags), - len)); + len); return; } - ND_PRINT((ndo, "BFDv0, length: %u\n\tControl, Flags: [%s], Diagnostic: %s (0x%02x)", + ND_PRINT("BFDv0, length: %u\n\tControl, Flags: [%s], Diagnostic: %s (0x%02x)", len, bittok2str(bfd_v0_flag_values, "none", flags), tok2str(bfd_diag_values,"unknown",BFD_EXTRACT_DIAG(version_diag)), - BFD_EXTRACT_DIAG(version_diag))); + BFD_EXTRACT_DIAG(version_diag)); - ND_PRINT((ndo, "\n\tDetection Timer Multiplier: %u (%u ms Detection time), BFD Length: %u", - bfd_header->detect_time_multiplier, - bfd_header->detect_time_multiplier * EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000, - bfd_header->length)); + ND_PRINT("\n\tDetection Timer Multiplier: %u (%u ms Detection time), BFD Length: %u", + GET_U_1(bfd_header->detect_time_multiplier), + GET_U_1(bfd_header->detect_time_multiplier) * GET_BE_U_4(bfd_header->desired_min_tx_interval)/1000, + GET_U_1(bfd_header->length)); - ND_PRINT((ndo, "\n\tMy Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->my_discriminator))); - ND_PRINT((ndo, ", Your Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->your_discriminator))); - ND_PRINT((ndo, "\n\t Desired min Tx Interval: %4u ms", EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000)); - ND_PRINT((ndo, "\n\t Required min Rx Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_rx_interval)/1000)); - ND_PRINT((ndo, "\n\t Required min Echo Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_echo_interval)/1000)); + ND_PRINT("\n\tMy Discriminator: 0x%08x", + GET_BE_U_4(bfd_header->my_discriminator)); + ND_PRINT(", Your Discriminator: 0x%08x", + GET_BE_U_4(bfd_header->your_discriminator)); + ND_PRINT("\n\t Desired min Tx Interval: %4u ms", + GET_BE_U_4(bfd_header->desired_min_tx_interval)/1000); + ND_PRINT("\n\t Required min Rx Interval: %4u ms", + GET_BE_U_4(bfd_header->required_min_rx_interval)/1000); + ND_PRINT("\n\t Required min Echo Interval: %4u ms", + GET_BE_U_4(bfd_header->required_min_echo_interval)/1000); if (flags & BFD_FLAG_AUTH) { - if (auth_print(ndo, pptr)) - goto trunc; + auth_print(ndo, pptr); } break; @@ -344,42 +353,48 @@ bfd_print(netdissect_options *ndo, register const u_char *pptr, case 1: if (ndo->ndo_vflag < 1) { - ND_PRINT((ndo, "BFDv1, Control, State %s, Flags: [%s], length: %u", + ND_PRINT("BFDv1, %s, State %s, Flags: [%s], length: %u", + tok2str(bfd_port_values, "unknown (%u)", port), tok2str(bfd_v1_state_values, "unknown (%u)", (flags & 0xc0) >> 6), bittok2str(bfd_v1_flag_values, "none", flags & 0x3f), - len)); + len); return; } - ND_PRINT((ndo, "BFDv1, length: %u\n\tControl, State %s, Flags: [%s], Diagnostic: %s (0x%02x)", + ND_PRINT("BFDv1, length: %u\n\t%s, State %s, Flags: [%s], Diagnostic: %s (0x%02x)", len, + tok2str(bfd_port_values, "unknown (%u)", port), tok2str(bfd_v1_state_values, "unknown (%u)", (flags & 0xc0) >> 6), bittok2str(bfd_v1_flag_values, "none", flags & 0x3f), tok2str(bfd_diag_values,"unknown",BFD_EXTRACT_DIAG(version_diag)), - BFD_EXTRACT_DIAG(version_diag))); + BFD_EXTRACT_DIAG(version_diag)); - ND_PRINT((ndo, "\n\tDetection Timer Multiplier: %u (%u ms Detection time), BFD Length: %u", - bfd_header->detect_time_multiplier, - bfd_header->detect_time_multiplier * EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000, - bfd_header->length)); + ND_PRINT("\n\tDetection Timer Multiplier: %u (%u ms Detection time), BFD Length: %u", + GET_U_1(bfd_header->detect_time_multiplier), + GET_U_1(bfd_header->detect_time_multiplier) * GET_BE_U_4(bfd_header->desired_min_tx_interval)/1000, + GET_U_1(bfd_header->length)); - ND_PRINT((ndo, "\n\tMy Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->my_discriminator))); - ND_PRINT((ndo, ", Your Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->your_discriminator))); - ND_PRINT((ndo, "\n\t Desired min Tx Interval: %4u ms", EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000)); - ND_PRINT((ndo, "\n\t Required min Rx Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_rx_interval)/1000)); - ND_PRINT((ndo, "\n\t Required min Echo Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_echo_interval)/1000)); + ND_PRINT("\n\tMy Discriminator: 0x%08x", + GET_BE_U_4(bfd_header->my_discriminator)); + ND_PRINT(", Your Discriminator: 0x%08x", + GET_BE_U_4(bfd_header->your_discriminator)); + ND_PRINT("\n\t Desired min Tx Interval: %4u ms", + GET_BE_U_4(bfd_header->desired_min_tx_interval)/1000); + ND_PRINT("\n\t Required min Rx Interval: %4u ms", + GET_BE_U_4(bfd_header->required_min_rx_interval)/1000); + ND_PRINT("\n\t Required min Echo Interval: %4u ms", + GET_BE_U_4(bfd_header->required_min_echo_interval)/1000); if (flags & BFD_FLAG_AUTH) { - if (auth_print(ndo, pptr)) - goto trunc; + auth_print(ndo, pptr); } break; default: - ND_PRINT((ndo, "BFDv%u, Control, length: %u", + ND_PRINT("BFDv%u, Control, length: %u", version, - len)); + len); if (ndo->ndo_vflag >= 1) { if(!print_unknown_data(ndo, pptr,"\n\t",len)) return; @@ -390,8 +405,8 @@ bfd_print(netdissect_options *ndo, register const u_char *pptr, /* * Echo packet. */ - ND_PRINT((ndo, "BFD, Echo, length: %u", - len)); + ND_PRINT("BFD, Echo, length: %u", + len); if (ndo->ndo_vflag >= 1) { if(!print_unknown_data(ndo, pptr,"\n\t",len)) return; @@ -400,22 +415,12 @@ bfd_print(netdissect_options *ndo, register const u_char *pptr, /* * Unknown packet type. */ - ND_PRINT((ndo, "BFD, unknown (%u), length: %u", + ND_PRINT("BFD, unknown (%u), length: %u", port, - len)); + len); if (ndo->ndo_vflag >= 1) { if(!print_unknown_data(ndo, pptr,"\n\t",len)) return; } } - return; - -trunc: - ND_PRINT((ndo, "[|BFD]")); } -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/print-bgp.c b/contrib/tcpdump/print-bgp.c index 7db3c6bb0f..c9051078fd 100644 --- a/contrib/tcpdump/print-bgp.c +++ b/contrib/tcpdump/print-bgp.c @@ -32,11 +32,13 @@ /* \summary: Border Gateway Protocol (BGP) printer */ +/* specification: RFC 4271 */ + #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include #include @@ -47,19 +49,17 @@ #include "af.h" #include "l2vpn.h" -static const char tstr[] = "[|BGP]"; - struct bgp { - uint8_t bgp_marker[16]; - uint16_t bgp_len; - uint8_t bgp_type; + nd_byte bgp_marker[16]; + nd_uint16_t bgp_len; + nd_uint8_t bgp_type; }; -#define BGP_SIZE 19 /* unaligned */ +#define BGP_SIZE 19 /* unaligned */ -#define BGP_OPEN 1 -#define BGP_UPDATE 2 -#define BGP_NOTIFICATION 3 -#define BGP_KEEPALIVE 4 +#define BGP_OPEN 1 +#define BGP_UPDATE 2 +#define BGP_NOTIFICATION 3 +#define BGP_KEEPALIVE 4 #define BGP_ROUTE_REFRESH 5 static const struct tok bgp_msg_values[] = { @@ -72,79 +72,79 @@ static const struct tok bgp_msg_values[] = { }; struct bgp_open { - uint8_t bgpo_marker[16]; - uint16_t bgpo_len; - uint8_t bgpo_type; - uint8_t bgpo_version; - uint16_t bgpo_myas; - uint16_t bgpo_holdtime; - uint32_t bgpo_id; - uint8_t bgpo_optlen; - /* options should follow */ + nd_byte bgpo_marker[16]; + nd_uint16_t bgpo_len; + nd_uint8_t bgpo_type; + nd_uint8_t bgpo_version; + nd_uint16_t bgpo_myas; + nd_uint16_t bgpo_holdtime; + nd_uint32_t bgpo_id; + nd_uint8_t bgpo_optlen; + /* options should follow */ }; -#define BGP_OPEN_SIZE 29 /* unaligned */ +#define BGP_OPEN_SIZE 29 /* unaligned */ struct bgp_opt { - uint8_t bgpopt_type; - uint8_t bgpopt_len; - /* variable length */ + nd_uint8_t bgpopt_type; + nd_uint8_t bgpopt_len; + /* variable length */ }; -#define BGP_OPT_SIZE 2 /* some compilers may pad to 4 bytes */ -#define BGP_CAP_HEADER_SIZE 2 /* some compilers may pad to 4 bytes */ +#define BGP_OPT_SIZE 2 /* some compilers may pad to 4 bytes */ +#define BGP_CAP_HEADER_SIZE 2 /* some compilers may pad to 4 bytes */ struct bgp_notification { - uint8_t bgpn_marker[16]; - uint16_t bgpn_len; - uint8_t bgpn_type; - uint8_t bgpn_major; - uint8_t bgpn_minor; + nd_byte bgpn_marker[16]; + nd_uint16_t bgpn_len; + nd_uint8_t bgpn_type; + nd_uint8_t bgpn_major; + nd_uint8_t bgpn_minor; }; -#define BGP_NOTIFICATION_SIZE 21 /* unaligned */ +#define BGP_NOTIFICATION_SIZE 21 /* unaligned */ struct bgp_route_refresh { - uint8_t bgp_marker[16]; - uint16_t len; - uint8_t type; - uint8_t afi[2]; /* the compiler messes this structure up */ - uint8_t res; /* when doing misaligned sequences of int8 and int16 */ - uint8_t safi; /* afi should be int16 - so we have to access it using */ -}; /* EXTRACT_16BITS(&bgp_route_refresh->afi) (sigh) */ + nd_byte bgp_marker[16]; + nd_uint16_t len; + nd_uint8_t type; /* No padding after this; afi is, in fact, not aligned */ + nd_uint16_t afi; + nd_uint8_t res; + nd_uint8_t safi; +}; #define BGP_ROUTE_REFRESH_SIZE 23 #define bgp_attr_lenlen(flags, p) \ - (((flags) & 0x10) ? 2 : 1) + (((flags) & 0x10) ? 2U : 1U) #define bgp_attr_len(flags, p) \ - (((flags) & 0x10) ? EXTRACT_16BITS(p) : *(p)) - -#define BGPTYPE_ORIGIN 1 -#define BGPTYPE_AS_PATH 2 -#define BGPTYPE_NEXT_HOP 3 -#define BGPTYPE_MULTI_EXIT_DISC 4 -#define BGPTYPE_LOCAL_PREF 5 -#define BGPTYPE_ATOMIC_AGGREGATE 6 -#define BGPTYPE_AGGREGATOR 7 -#define BGPTYPE_COMMUNITIES 8 /* RFC1997 */ -#define BGPTYPE_ORIGINATOR_ID 9 /* RFC4456 */ -#define BGPTYPE_CLUSTER_LIST 10 /* RFC4456 */ -#define BGPTYPE_DPA 11 /* deprecated, draft-ietf-idr-bgp-dpa */ -#define BGPTYPE_ADVERTISERS 12 /* deprecated RFC1863 */ -#define BGPTYPE_RCID_PATH 13 /* deprecated RFC1863 */ -#define BGPTYPE_MP_REACH_NLRI 14 /* RFC4760 */ -#define BGPTYPE_MP_UNREACH_NLRI 15 /* RFC4760 */ -#define BGPTYPE_EXTD_COMMUNITIES 16 /* RFC4360 */ -#define BGPTYPE_AS4_PATH 17 /* RFC6793 */ -#define BGPTYPE_AGGREGATOR4 18 /* RFC6793 */ -#define BGPTYPE_PMSI_TUNNEL 22 /* RFC6514 */ -#define BGPTYPE_TUNNEL_ENCAP 23 /* RFC5512 */ -#define BGPTYPE_TRAFFIC_ENG 24 /* RFC5543 */ -#define BGPTYPE_IPV6_EXTD_COMMUNITIES 25 /* RFC5701 */ -#define BGPTYPE_AIGP 26 /* RFC7311 */ -#define BGPTYPE_PE_DISTINGUISHER_LABEL 27 /* RFC6514 */ -#define BGPTYPE_ENTROPY_LABEL 28 /* RFC6790 */ -#define BGPTYPE_LARGE_COMMUNITY 32 /* draft-ietf-idr-large-community-05 */ -#define BGPTYPE_ATTR_SET 128 /* RFC6368 */ - -#define BGP_MP_NLRI_MINSIZE 3 /* End of RIB Marker detection */ + (((flags) & 0x10) ? GET_BE_U_2(p) : GET_U_1(p)) + +#define BGPTYPE_ORIGIN 1 +#define BGPTYPE_AS_PATH 2 +#define BGPTYPE_NEXT_HOP 3 +#define BGPTYPE_MULTI_EXIT_DISC 4 +#define BGPTYPE_LOCAL_PREF 5 +#define BGPTYPE_ATOMIC_AGGREGATE 6 +#define BGPTYPE_AGGREGATOR 7 +#define BGPTYPE_COMMUNITIES 8 /* RFC1997 */ +#define BGPTYPE_ORIGINATOR_ID 9 /* RFC4456 */ +#define BGPTYPE_CLUSTER_LIST 10 /* RFC4456 */ +#define BGPTYPE_DPA 11 /* deprecated, draft-ietf-idr-bgp-dpa */ +#define BGPTYPE_ADVERTISERS 12 /* deprecated RFC1863 */ +#define BGPTYPE_RCID_PATH 13 /* deprecated RFC1863 */ +#define BGPTYPE_MP_REACH_NLRI 14 /* RFC4760 */ +#define BGPTYPE_MP_UNREACH_NLRI 15 /* RFC4760 */ +#define BGPTYPE_EXTD_COMMUNITIES 16 /* RFC4360 */ +#define BGPTYPE_AS4_PATH 17 /* RFC6793 */ +#define BGPTYPE_AGGREGATOR4 18 /* RFC6793 */ +#define BGPTYPE_PMSI_TUNNEL 22 /* RFC6514 */ +#define BGPTYPE_TUNNEL_ENCAP 23 /* RFC5512 */ +#define BGPTYPE_TRAFFIC_ENG 24 /* RFC5543 */ +#define BGPTYPE_IPV6_EXTD_COMMUNITIES 25 /* RFC5701 */ +#define BGPTYPE_AIGP 26 /* RFC7311 */ +#define BGPTYPE_PE_DISTINGUISHER_LABEL 27 /* RFC6514 */ +#define BGPTYPE_ENTROPY_LABEL 28 /* RFC6790 */ +#define BGPTYPE_LARGE_COMMUNITY 32 /* draft-ietf-idr-large-community-05 */ +#define BGPTYPE_ATTR_SET 128 /* RFC6368 */ + +#define BGP_MP_NLRI_MINSIZE 3 /* End of RIB Marker detection */ static const struct tok bgp_attr_values[] = { { BGPTYPE_ORIGIN, "Origin"}, @@ -216,12 +216,14 @@ static const struct tok bgp_opt_values[] = { #define BGP_CAPCODE_ORF 3 /* RFC5291 */ #define BGP_CAPCODE_MR 4 /* RFC3107 */ #define BGP_CAPCODE_EXT_NH 5 /* RFC5549 */ +#define BGP_CAPCODE_ML 8 /* RFC8277 */ #define BGP_CAPCODE_RESTART 64 /* RFC4724 */ #define BGP_CAPCODE_AS_NEW 65 /* RFC6793 */ #define BGP_CAPCODE_DYN_CAP 67 /* draft-ietf-idr-dynamic-cap */ #define BGP_CAPCODE_MULTISESS 68 /* draft-ietf-idr-bgp-multisession */ #define BGP_CAPCODE_ADD_PATH 69 /* RFC7911 */ #define BGP_CAPCODE_ENH_RR 70 /* draft-keyur-bgp-enhanced-route-refresh */ +#define BGP_CAPCODE_LLGR 71 /* draft-uttaro-idr-bgp-persistence-05 */ #define BGP_CAPCODE_RR_CISCO 128 static const struct tok bgp_capcode_values[] = { @@ -230,12 +232,14 @@ static const struct tok bgp_capcode_values[] = { { BGP_CAPCODE_ORF, "Cooperative Route Filtering"}, { BGP_CAPCODE_MR, "Multiple Routes to a Destination"}, { BGP_CAPCODE_EXT_NH, "Extended Next Hop Encoding"}, + { BGP_CAPCODE_ML, "Multiple Labels"}, { BGP_CAPCODE_RESTART, "Graceful Restart"}, { BGP_CAPCODE_AS_NEW, "32-Bit AS Number"}, { BGP_CAPCODE_DYN_CAP, "Dynamic Capability"}, { BGP_CAPCODE_MULTISESS, "Multisession BGP"}, { BGP_CAPCODE_ADD_PATH, "Multiple Paths"}, { BGP_CAPCODE_ENH_RR, "Enhanced Route Refresh"}, + { BGP_CAPCODE_LLGR, "Long-lived Graceful Restart"}, { BGP_CAPCODE_RR_CISCO, "Route Refresh (Cisco)"}, { 0, NULL} }; @@ -261,11 +265,15 @@ static const struct tok bgp_notify_major_values[] = { /* draft-ietf-idr-cease-subcode-02 */ #define BGP_NOTIFY_MINOR_CEASE_MAXPRFX 1 +/* draft-ietf-idr-shutdown-07 */ +#define BGP_NOTIFY_MINOR_CEASE_SHUT 2 +#define BGP_NOTIFY_MINOR_CEASE_RESET 4 +#define BGP_NOTIFY_MINOR_CEASE_ADMIN_SHUTDOWN_LEN 128 static const struct tok bgp_notify_minor_cease_values[] = { { BGP_NOTIFY_MINOR_CEASE_MAXPRFX, "Maximum Number of Prefixes Reached"}, - { 2, "Administratively Shutdown"}, + { BGP_NOTIFY_MINOR_CEASE_SHUT, "Administrative Shutdown"}, { 3, "Peer Unconfigured"}, - { 4, "Administratively Reset"}, + { BGP_NOTIFY_MINOR_CEASE_RESET, "Administrative Reset"}, { 5, "Connection Rejected"}, { 6, "Other Configuration Change"}, { 7, "Connection Collision Resolution"}, @@ -306,6 +314,7 @@ static const struct tok bgp_notify_minor_update_values[] = { }; static const struct tok bgp_notify_minor_fsm_values[] = { + { 0, "Unspecified Error"}, { 1, "In OpenSent State"}, { 2, "In OpenConfirm State"}, { 3, "In Established State"}, @@ -373,6 +382,8 @@ static const struct tok bgp_aigp_values[] = { #define SAFNUM_VPLS 65 /* RFC6037 */ #define SAFNUM_MDT 66 +/* RFC7432 */ +#define SAFNUM_EVPN 70 /* RFC4364 */ #define SAFNUM_VPNUNICAST 128 /* RFC6513 */ @@ -392,6 +403,7 @@ static const struct tok bgp_safi_values[] = { { SAFNUM_TUNNEL, "Tunnel"}, { SAFNUM_VPLS, "VPLS"}, { SAFNUM_MDT, "MDT"}, + { SAFNUM_EVPN, "EVPN"}, { SAFNUM_VPNUNICAST, "labeled VPN Unicast"}, { SAFNUM_VPNMULTICAST, "labeled VPN Multicast"}, { SAFNUM_VPNUNIMULTICAST, "labeled VPN Unicast+Multicast"}, @@ -401,11 +413,11 @@ static const struct tok bgp_safi_values[] = { }; /* well-known community */ -#define BGP_COMMUNITY_NO_EXPORT 0xffffff01 -#define BGP_COMMUNITY_NO_ADVERT 0xffffff02 -#define BGP_COMMUNITY_NO_EXPORT_SUBCONFED 0xffffff03 +#define BGP_COMMUNITY_NO_EXPORT 0xffffff01 +#define BGP_COMMUNITY_NO_ADVERT 0xffffff02 +#define BGP_COMMUNITY_NO_EXPORT_SUBCONFED 0xffffff03 -/* Extended community type - draft-ietf-idr-bgp-ext-communities-05 */ +/* Extended community type - RFC 4360 */ #define BGP_EXT_COM_RT_0 0x0002 /* Route Target,Format AS(2bytes):AN(4bytes) */ #define BGP_EXT_COM_RT_1 0x0102 /* Route Target,Format IP address:AN(2bytes) */ #define BGP_EXT_COM_RT_2 0x0202 /* Route Target,Format AN(4bytes):local(2bytes) */ @@ -415,15 +427,16 @@ static const struct tok bgp_safi_values[] = { #define BGP_EXT_COM_LINKBAND 0x4004 /* Link Bandwidth,Format AS(2B):Bandwidth(4B) */ /* rfc2547 bgp-mpls-vpns */ #define BGP_EXT_COM_VPN_ORIGIN 0x0005 /* OSPF Domain ID / VPN of Origin - draft-rosen-vpns-ospf-bgp-mpls */ -#define BGP_EXT_COM_VPN_ORIGIN2 0x0105 /* duplicate - keep for backwards compatability */ -#define BGP_EXT_COM_VPN_ORIGIN3 0x0205 /* duplicate - keep for backwards compatability */ -#define BGP_EXT_COM_VPN_ORIGIN4 0x8005 /* duplicate - keep for backwards compatability */ +#define BGP_EXT_COM_VPN_ORIGIN2 0x0105 /* duplicate - keep for backwards compatibility */ +#define BGP_EXT_COM_VPN_ORIGIN3 0x0205 /* duplicate - keep for backwards compatibility */ +#define BGP_EXT_COM_VPN_ORIGIN4 0x8005 /* duplicate - keep for backwards compatibility */ #define BGP_EXT_COM_OSPF_RTYPE 0x0306 /* OSPF Route Type,Format Area(4B):RouteType(1B):Options(1B) */ -#define BGP_EXT_COM_OSPF_RTYPE2 0x8000 /* duplicate - keep for backwards compatability */ +#define BGP_EXT_COM_OSPF_RTYPE2 0x8000 /* duplicate - keep for backwards compatibility */ +#define BGP_EXT_COM_ENCAP 0x030c /* rfc5512 */ #define BGP_EXT_COM_OSPF_RID 0x0107 /* OSPF Router ID,Format RouterID(4B):Unused(2B) */ -#define BGP_EXT_COM_OSPF_RID2 0x8001 /* duplicate - keep for backwards compatability */ +#define BGP_EXT_COM_OSPF_RID2 0x8001 /* duplicate - keep for backwards compatibility */ #define BGP_EXT_COM_L2INFO 0x800a /* draft-kompella-ppvpn-l2vpn */ @@ -432,12 +445,12 @@ static const struct tok bgp_safi_values[] = { #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 -#define BGP_EXT_COM_EIGRP_METRIC_AS_DELAY 0x8801 -#define BGP_EXT_COM_EIGRP_METRIC_REL_NH_BW 0x8802 -#define BGP_EXT_COM_EIGRP_METRIC_LOAD_MTU 0x8803 -#define BGP_EXT_COM_EIGRP_EXT_REMAS_REMID 0x8804 +/* https://www.cisco.com/en/US/tech/tk436/tk428/technologies_tech_note09186a00801eb09a.shtml */ +#define BGP_EXT_COM_EIGRP_GEN 0x8800 +#define BGP_EXT_COM_EIGRP_METRIC_AS_DELAY 0x8801 +#define BGP_EXT_COM_EIGRP_METRIC_REL_NH_BW 0x8802 +#define BGP_EXT_COM_EIGRP_METRIC_LOAD_MTU 0x8803 +#define BGP_EXT_COM_EIGRP_EXT_REMAS_REMID 0x8804 #define BGP_EXT_COM_EIGRP_EXT_REMPROTO_REMMETRIC 0x8805 static const struct tok bgp_extd_comm_flag_values[] = { @@ -460,15 +473,16 @@ static const struct tok bgp_extd_comm_subtype_values[] = { { BGP_EXT_COM_VPN_ORIGIN4, "ospf-domain"}, { BGP_EXT_COM_OSPF_RTYPE, "ospf-route-type"}, { BGP_EXT_COM_OSPF_RTYPE2, "ospf-route-type"}, + { BGP_EXT_COM_ENCAP, "encapsulation"}, { BGP_EXT_COM_OSPF_RID, "ospf-router-id"}, { BGP_EXT_COM_OSPF_RID2, "ospf-router-id"}, { BGP_EXT_COM_L2INFO, "layer2-info"}, - { BGP_EXT_COM_EIGRP_GEN , "eigrp-general-route (flag, tag)" }, - { BGP_EXT_COM_EIGRP_METRIC_AS_DELAY , "eigrp-route-metric (AS, delay)" }, - { BGP_EXT_COM_EIGRP_METRIC_REL_NH_BW , "eigrp-route-metric (reliability, nexthop, bandwidth)" }, - { BGP_EXT_COM_EIGRP_METRIC_LOAD_MTU , "eigrp-route-metric (load, MTU)" }, - { BGP_EXT_COM_EIGRP_EXT_REMAS_REMID , "eigrp-external-route (remote-AS, remote-ID)" }, - { BGP_EXT_COM_EIGRP_EXT_REMPROTO_REMMETRIC , "eigrp-external-route (remote-proto, remote-metric)" }, + { BGP_EXT_COM_EIGRP_GEN, "eigrp-general-route (flag, tag)" }, + { BGP_EXT_COM_EIGRP_METRIC_AS_DELAY, "eigrp-route-metric (AS, delay)" }, + { BGP_EXT_COM_EIGRP_METRIC_REL_NH_BW, "eigrp-route-metric (reliability, nexthop, bandwidth)" }, + { BGP_EXT_COM_EIGRP_METRIC_LOAD_MTU, "eigrp-route-metric (load, MTU)" }, + { BGP_EXT_COM_EIGRP_EXT_REMAS_REMID, "eigrp-external-route (remote-AS, remote-ID)" }, + { 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"}, @@ -476,6 +490,46 @@ static const struct tok bgp_extd_comm_subtype_values[] = { { 0, NULL}, }; +/* RFC RFC5512 BGP Tunnel Encapsulation Attribute Tunnel Types */ +#define BGP_ENCAP_TUNNEL_L2TPV3_IP 1 +#define BGP_ENCAP_TUNNEL_GRE 2 +#define BGP_ENCAP_TUNNEL_TRANSMIT 3 +#define BGP_ENCAP_TUNNEL_IPSEC 4 +#define BGP_ENCAP_TUNNEL_IP_IPSEC 5 +#define BGP_ENCAP_TUNNEL_MPLS_IP 6 +#define BGP_ENCAP_TUNNEL_IP_IP 7 +#define BGP_ENCAP_TUNNEL_VXLAN 8 +#define BGP_ENCAP_TUNNEL_NVGRE 9 +#define BGP_ENCAP_TUNNEL_MPLS 10 +#define BGP_ENCAP_TUNNEL_MPLS_GRE 11 +#define BGP_ENCAP_TUNNEL_VXLAN_GPE 12 +#define BGP_ENCAP_TUNNEL_MPLS_UDP 13 +#define BGP_ENCAP_TUNNEL_IPV6 14 +#define BGP_ENCAP_TUNNEL_SR_TE 15 +#define BGP_ENCAP_TUNNEL_BARE 16 +#define BGP_ENCAP_TUNNEL_SR 17 + +static const struct tok bgp_extd_comm_encap_tunnel_values[] = { + { BGP_ENCAP_TUNNEL_L2TPV3_IP, "L2TPv3 over IP"}, + { BGP_ENCAP_TUNNEL_GRE, "GRE"}, + { BGP_ENCAP_TUNNEL_TRANSMIT, "Transmit Tunnel"}, + { BGP_ENCAP_TUNNEL_IPSEC, "IPsec"}, + { BGP_ENCAP_TUNNEL_IP_IPSEC, "IP in IP with IPsec"}, + { BGP_ENCAP_TUNNEL_MPLS_IP, "MPLS in IP with IPsec"}, + { BGP_ENCAP_TUNNEL_IP_IP, "IP in IP"}, + { BGP_ENCAP_TUNNEL_VXLAN, "VXLAN"}, + { BGP_ENCAP_TUNNEL_NVGRE, "NVGRE"}, + { BGP_ENCAP_TUNNEL_MPLS, "MPLS"}, + { BGP_ENCAP_TUNNEL_MPLS_GRE, "MPLS in GRE"}, + { BGP_ENCAP_TUNNEL_VXLAN_GPE, "VXLAN GPE"}, + { BGP_ENCAP_TUNNEL_MPLS_UDP, "MPLS in UDP"}, + { BGP_ENCAP_TUNNEL_IPV6, "IPv6"}, + { BGP_ENCAP_TUNNEL_SR_TE, "SR TE"}, + { BGP_ENCAP_TUNNEL_BARE, "Bare"}, + { BGP_ENCAP_TUNNEL_SR, "SR"}, + { 0, NULL}, +}; + /* OSPF codes for BGP_EXT_COM_OSPF_RTYPE draft-rosen-vpns-ospf-bgp-mpls */ #define BGP_OSPF_RTYPE_RTR 1 /* OSPF Router LSA */ #define BGP_OSPF_RTYPE_NET 2 /* OSPF Network LSA */ @@ -497,13 +551,13 @@ static const struct tok bgp_extd_comm_ospf_rtype_values[] = { /* ADD-PATH Send/Receive field values */ static const struct tok bgp_add_path_recvsend[] = { - { 1, "Receive" }, - { 2, "Send" }, - { 3, "Both" }, - { 0, NULL }, + { 1, "Receive" }, + { 2, "Send" }, + { 3, "Both" }, + { 0, NULL }, }; -static char astostr[20]; +#define AS_STR_SIZE sizeof("xxxxx.xxxxx") /* * as_printf @@ -516,109 +570,102 @@ static char astostr[20]; */ static char * as_printf(netdissect_options *ndo, - char *str, int size, u_int asnum) + char *str, size_t size, u_int asnum) { - if (!ndo->ndo_bflag || asnum <= 0xFFFF) { - snprintf(str, size, "%u", asnum); - } else { - snprintf(str, size, "%u.%u", asnum >> 16, asnum & 0xFFFF); - } - return str; + if (!ndo->ndo_bflag || asnum <= 0xFFFF) { + snprintf(str, size, "%u", asnum); + } else { + snprintf(str, size, "%u.%u", asnum >> 16, asnum & 0xFFFF); + } + return str; } #define ITEMCHECK(minlen) if (itemlen < minlen) goto badtlv; int decode_prefix4(netdissect_options *ndo, - const u_char *pptr, u_int itemlen, char *buf, u_int buflen) + const u_char *pptr, u_int itemlen, char *buf, size_t buflen) { - struct in_addr addr; - u_int plen, plenbytes; - - ND_TCHECK(pptr[0]); - ITEMCHECK(1); - plen = pptr[0]; - if (32 < plen) - return -1; - itemlen -= 1; - - memset(&addr, 0, sizeof(addr)); - plenbytes = (plen + 7) / 8; - ND_TCHECK2(pptr[1], plenbytes); - ITEMCHECK(plenbytes); - memcpy(&addr, &pptr[1], plenbytes); - if (plen % 8) { - ((u_char *)&addr)[plenbytes - 1] &= - ((0xff00 >> (plen % 8)) & 0xff); - } - snprintf(buf, buflen, "%s/%d", ipaddr_string(ndo, &addr), plen); - return 1 + plenbytes; - -trunc: - return -2; + nd_ipv4 addr; + u_int plen, plenbytes; + + ITEMCHECK(1); + plen = GET_U_1(pptr); + if (32 < plen) + return -1; + itemlen -= 1; + + memset(&addr, 0, sizeof(addr)); + plenbytes = (plen + 7) / 8; + ITEMCHECK(plenbytes); + GET_CPY_BYTES(&addr, pptr + 1, plenbytes); + if (plen % 8) { + ((u_char *)&addr)[plenbytes - 1] &= ((0xff00 >> (plen % 8)) & 0xff); + } + snprintf(buf, buflen, "%s/%u", ipaddr_string(ndo, (const u_char *)&addr), plen); + return 1 + plenbytes; badtlv: - return -3; + return -2; } static int decode_labeled_prefix4(netdissect_options *ndo, - const u_char *pptr, u_int itemlen, char *buf, u_int buflen) + const u_char *pptr, u_int itemlen, char *buf, + size_t buflen) { - struct in_addr addr; - u_int plen, plenbytes; - - /* prefix length and label = 4 bytes */ - ND_TCHECK2(pptr[0], 4); - ITEMCHECK(4); - plen = pptr[0]; /* get prefix length */ - - /* this is one of the weirdnesses of rfc3107 - the label length (actually the label + COS bits) - is added to the prefix length; - we also do only read out just one label - - there is no real application for advertisement of - stacked labels in a single BGP message - */ - - if (24 > plen) - return -1; - - plen-=24; /* adjust prefixlen - labellength */ - - if (32 < plen) - return -1; - itemlen -= 4; - - memset(&addr, 0, sizeof(addr)); - plenbytes = (plen + 7) / 8; - ND_TCHECK2(pptr[4], plenbytes); - ITEMCHECK(plenbytes); - memcpy(&addr, &pptr[4], plenbytes); - if (plen % 8) { - ((u_char *)&addr)[plenbytes - 1] &= - ((0xff00 >> (plen % 8)) & 0xff); - } - /* the label may get offsetted by 4 bits so lets shift it right */ - snprintf(buf, buflen, "%s/%d, label:%u %s", - ipaddr_string(ndo, &addr), - plen, - EXTRACT_24BITS(pptr+1)>>4, - ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); + nd_ipv4 addr; + u_int plen, plenbytes; + + /* prefix length and label = 4 bytes */ + ND_TCHECK_4(pptr); + ITEMCHECK(4); + plen = GET_U_1(pptr); /* get prefix length */ + + /* this is one of the weirdnesses of rfc3107 + the label length (actually the label + COS bits) + is added to the prefix length; + we also do only read out just one label - + there is no real application for advertisement of + stacked labels in a single BGP message + */ + + if (24 > plen) + return -1; + + plen-=24; /* adjust prefixlen - labellength */ + + if (32 < plen) + return -1; + itemlen -= 4; + + memset(&addr, 0, sizeof(addr)); + plenbytes = (plen + 7) / 8; + ITEMCHECK(plenbytes); + GET_CPY_BYTES(&addr, pptr + 4, plenbytes); + if (plen % 8) { + ((u_char *)&addr)[plenbytes - 1] &= ((0xff00 >> (plen % 8)) & 0xff); + } + /* the label may get offsetted by 4 bits so lets shift it right */ + snprintf(buf, buflen, "%s/%u, label:%u %s", + ipaddr_string(ndo, (const u_char *)&addr), + plen, + GET_BE_U_3(pptr + 1)>>4, + ((GET_U_1(pptr + 3) & 1) == 0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); - return 4 + plenbytes; + return 4 + plenbytes; trunc: - return -2; + return -2; badtlv: - return -3; + return -3; } /* * bgp_vpn_ip_print * - * print an ipv4 or ipv6 address into a buffer dependend on address length. + * print an ipv4 or ipv6 address into a buffer dependent on address length. */ static char * bgp_vpn_ip_print(netdissect_options *ndo, @@ -630,13 +677,11 @@ bgp_vpn_ip_print(netdissect_options *ndo, char *pos = addr; switch(addr_length) { - case (sizeof(struct in_addr) << 3): /* 32 */ - ND_TCHECK2(pptr[0], sizeof(struct in_addr)); - snprintf(pos, sizeof(addr), "%s", ipaddr_string(ndo, pptr)); + case (sizeof(nd_ipv4) << 3): /* 32 */ + snprintf(pos, sizeof(addr), "%s", GET_IPADDR_STRING(pptr)); break; - case (sizeof(struct in6_addr) << 3): /* 128 */ - ND_TCHECK2(pptr[0], sizeof(struct in6_addr)); - snprintf(pos, sizeof(addr), "%s", ip6addr_string(ndo, pptr)); + case (sizeof(nd_ipv6) << 3): /* 128 */ + snprintf(pos, sizeof(addr), "%s", GET_IP6ADDR_STRING(pptr)); break; default: snprintf(pos, sizeof(addr), "bogus address length %u", addr_length); @@ -644,7 +689,6 @@ bgp_vpn_ip_print(netdissect_options *ndo, } pos += strlen(pos); -trunc: *(pos) = '\0'; return (addr); } @@ -667,9 +711,9 @@ trunc: * * return the number of bytes read from the wire. */ -static int +static u_int bgp_vpn_sg_print(netdissect_options *ndo, - const u_char *pptr, char *buf, u_int buflen) + const u_char *pptr, char *buf, size_t buflen) { uint8_t addr_length; u_int total_length, offset; @@ -677,30 +721,30 @@ bgp_vpn_sg_print(netdissect_options *ndo, total_length = 0; /* Source address length, encoded in bits */ - ND_TCHECK2(pptr[0], 1); - addr_length = *pptr++; + addr_length = GET_U_1(pptr); + pptr++; /* Source address */ - ND_TCHECK2(pptr[0], (addr_length >> 3)); + ND_TCHECK_LEN(pptr, (addr_length >> 3)); total_length += (addr_length >> 3) + 1; - offset = strlen(buf); + offset = (u_int)strlen(buf); if (addr_length) { snprintf(buf + offset, buflen - offset, ", Source %s", - bgp_vpn_ip_print(ndo, pptr, addr_length)); + bgp_vpn_ip_print(ndo, pptr, addr_length)); pptr += (addr_length >> 3); } /* Group address length, encoded in bits */ - ND_TCHECK2(pptr[0], 1); - addr_length = *pptr++; + addr_length = GET_U_1(pptr); + pptr++; /* Group address */ - ND_TCHECK2(pptr[0], (addr_length >> 3)); + ND_TCHECK_LEN(pptr, (addr_length >> 3)); total_length += (addr_length >> 3) + 1; - offset = strlen(buf); + offset = (u_int)strlen(buf); if (addr_length) { snprintf(buf + offset, buflen - offset, ", Group %s", - bgp_vpn_ip_print(ndo, pptr, addr_length)); + bgp_vpn_ip_print(ndo, pptr, addr_length)); pptr += (addr_length >> 3); } @@ -708,40 +752,44 @@ trunc: return (total_length); } -/* RDs and RTs share the same semantics - * we use bgp_vpn_rd_print for - * printing route targets inside a NLRI */ -char * +/* Print an RFC 4364 Route Distinguisher */ +const char * bgp_vpn_rd_print(netdissect_options *ndo, const u_char *pptr) { - /* allocate space for the largest possible string */ - static char rd[sizeof("xxxxxxxxxx:xxxxx (xxx.xxx.xxx.xxx:xxxxx)")]; + /* allocate space for the largest possible string */ + static char rd[sizeof("xxxxx.xxxxx:xxxxx (xxx.xxx.xxx.xxx:xxxxx)")]; char *pos = rd; + /* allocate space for the largest possible string */ + char astostr[AS_STR_SIZE]; /* ok lets load the RD format */ - switch (EXTRACT_16BITS(pptr)) { + switch (GET_BE_U_2(pptr)) { - /* 2-byte-AS:number fmt*/ case 0: + /* 2-byte-AS:number fmt */ snprintf(pos, sizeof(rd) - (pos - rd), "%u:%u (= %u.%u.%u.%u)", - EXTRACT_16BITS(pptr+2), - EXTRACT_32BITS(pptr+4), - *(pptr+4), *(pptr+5), *(pptr+6), *(pptr+7)); + GET_BE_U_2(pptr + 2), + GET_BE_U_4(pptr + 4), + GET_U_1(pptr + 4), GET_U_1(pptr + 5), + GET_U_1(pptr + 6), GET_U_1(pptr + 7)); break; - /* IP-address:AS fmt*/ case 1: + /* IP-address:AS fmt */ snprintf(pos, sizeof(rd) - (pos - rd), "%u.%u.%u.%u:%u", - *(pptr+2), *(pptr+3), *(pptr+4), *(pptr+5), EXTRACT_16BITS(pptr+6)); + GET_U_1(pptr + 2), GET_U_1(pptr + 3), + GET_U_1(pptr + 4), GET_U_1(pptr + 5), + GET_BE_U_2(pptr + 6)); break; - /* 4-byte-AS:number fmt*/ case 2: - snprintf(pos, sizeof(rd) - (pos - rd), "%s:%u (%u.%u.%u.%u:%u)", - as_printf(ndo, astostr, sizeof(astostr), EXTRACT_32BITS(pptr+2)), - EXTRACT_16BITS(pptr+6), *(pptr+2), *(pptr+3), *(pptr+4), - *(pptr+5), EXTRACT_16BITS(pptr+6)); + /* 4-byte-AS:number fmt */ + snprintf(pos, sizeof(rd) - (pos - rd), "%s:%u (%u.%u.%u.%u:%u)", + as_printf(ndo, astostr, sizeof(astostr), GET_BE_U_4(pptr + 2)), + GET_BE_U_2(pptr + 6), GET_U_1(pptr + 2), + GET_U_1(pptr + 3), GET_U_1(pptr + 4), + GET_U_1(pptr + 5), GET_BE_U_2(pptr + 6)); break; default: snprintf(pos, sizeof(rd) - (pos - rd), "unknown RD format"); @@ -752,99 +800,282 @@ bgp_vpn_rd_print(netdissect_options *ndo, return (rd); } -static int -decode_rt_routing_info(netdissect_options *ndo, - const u_char *pptr, char *buf, u_int buflen) +/* + * Print an RFC 4360 Extended Community. + */ +static void +bgp_extended_community_print(netdissect_options *ndo, + const u_char *pptr) { - uint8_t route_target[8]; - u_int plen; - char asbuf[sizeof(astostr)]; /* bgp_vpn_rd_print() overwrites astostr */ + union { /* copy buffer for bandwidth values */ + float f; + uint32_t i; + } bw; + /* allocate space for the largest possible string */ + char astostr[AS_STR_SIZE]; + + switch (GET_BE_U_2(pptr)) { + + case BGP_EXT_COM_RT_0: + case BGP_EXT_COM_RO_0: + case BGP_EXT_COM_L2VPN_RT_0: + ND_PRINT("%u:%u (= %s)", + GET_BE_U_2(pptr + 2), + GET_BE_U_4(pptr + 4), + GET_IPADDR_STRING(pptr+4)); + 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: + ND_PRINT("%s:%u", + GET_IPADDR_STRING(pptr+2), + GET_BE_U_2(pptr + 6)); + break; - /* NLRI "prefix length" from RFC 2858 Section 4. */ - ND_TCHECK(pptr[0]); - plen = pptr[0]; /* get prefix length */ + case BGP_EXT_COM_RT_2: + case BGP_EXT_COM_RO_2: + ND_PRINT("%s:%u", + as_printf(ndo, astostr, sizeof(astostr), + GET_BE_U_4(pptr + 2)), GET_BE_U_2(pptr + 6)); + break; - /* NLRI "prefix" (ibid), valid lengths are { 0, 32, 33, ..., 96 } bits. - * RFC 4684 Section 4 defines the layout of "origin AS" and "route - * target" fields inside the "prefix" depending on its length. - */ - if (0 == plen) { - /* Without "origin AS", without "route target". */ - snprintf(buf, buflen, "default route target"); - return 1; - } + case BGP_EXT_COM_LINKBAND: + bw.i = GET_BE_U_4(pptr + 2); + ND_PRINT("bandwidth: %.3f Mbps", + bw.f*8/1000000); + break; + + case BGP_EXT_COM_VPN_ORIGIN: + case BGP_EXT_COM_VPN_ORIGIN2: + case BGP_EXT_COM_VPN_ORIGIN3: + case BGP_EXT_COM_VPN_ORIGIN4: + case BGP_EXT_COM_OSPF_RID: + case BGP_EXT_COM_OSPF_RID2: + ND_PRINT("%s", GET_IPADDR_STRING(pptr+2)); + break; + + case BGP_EXT_COM_OSPF_RTYPE: + case BGP_EXT_COM_OSPF_RTYPE2: + ND_PRINT("area:%s, router-type:%s, metric-type:%s%s", + GET_IPADDR_STRING(pptr+2), + tok2str(bgp_extd_comm_ospf_rtype_values, + "unknown (0x%02x)", + GET_U_1((pptr + 6))), + (GET_U_1(pptr + 7) & BGP_OSPF_RTYPE_METRIC_TYPE) ? "E2" : "", + ((GET_U_1(pptr + 6) == BGP_OSPF_RTYPE_EXT) || (GET_U_1(pptr + 6) == BGP_OSPF_RTYPE_NSSA)) ? "E1" : ""); + break; + + case BGP_EXT_COM_L2INFO: + ND_PRINT("%s Control Flags [0x%02x]:MTU %u", + tok2str(l2vpn_encaps_values, + "unknown encaps", + GET_U_1((pptr + 2))), + GET_U_1((pptr + 3)), + GET_BE_U_2(pptr + 4)); + break; - if (32 > plen) - return -1; + case BGP_EXT_COM_SOURCE_AS: + ND_PRINT("AS %u", GET_BE_U_2(pptr + 2)); + break; - /* With at least "origin AS", possibly with "route target". */ - ND_TCHECK_32BITS(pptr + 1); - as_printf(ndo, asbuf, sizeof(asbuf), EXTRACT_32BITS(pptr + 1)); + case BGP_EXT_COM_ENCAP: + ND_PRINT("Tunnel type: %s", tok2str(bgp_extd_comm_encap_tunnel_values, + "unknown encaps", + GET_BE_U_2(pptr + 6))); + break; - plen-=32; /* adjust prefix length */ + default: + ND_PRINT("%02x%02x%02x%02x%02x%02x", + GET_U_1(pptr + 2), + GET_U_1(pptr + 3), + GET_U_1(pptr + 4), + GET_U_1(pptr + 5), + GET_U_1(pptr + 6), + GET_U_1(pptr + 7)); + break; + } +} - if (64 < plen) - return -1; +/* + * RFC4684 (Section 4)/RFC2858 (Section 4). + * RTC membership prefix is structured as follows + * [prefix-len] [origin-as] [route-target] + * The route-target is encoded as RT ext-comms. + * Prefix-len may be 0, 32..96 + * + * Note that pptr is not packet data - it is + * a buffer owned by our caller - therefore GET_* + * macros can not be used. + */ +static char * +bgp_rt_prefix_print(netdissect_options *ndo, + const u_char *pptr, + u_int plen) +{ + /* allocate space for the largest possible string */ + char rtc_prefix_in_hex[20] = ""; + u_int rtc_prefix_in_hex_len = 0; + static char output[61]; /* max response string */ + /* allocate space for the largest possible string */ + char astostr[AS_STR_SIZE]; + uint16_t ec_type = 0; + u_int octet_count; + u_int i; + + if (plen == 0) { + snprintf(output, sizeof(output), "route-target: 0:0/0"); + return (output); + } - /* From now on (plen + 7) / 8 evaluates to { 0, 1, 2, ..., 8 } - * and gives the number of octets in the variable-length "route - * target" field inside this NLRI "prefix". Look for it. + /* hex representation of the prefix */ + octet_count = (plen+7)/8; + for (i=0; i> (plen % 8)) & 0xff); - } - snprintf(buf, buflen, "origin AS: %s, route target %s", - asbuf, - bgp_vpn_rd_print(ndo, (u_char *)&route_target)); + snprintf(output, sizeof(output), "route-target: partial-type: (%s/%d)", + rtc_prefix_in_hex, plen); + return (output); + } + + /* + * get the ext-comm type + * Note: pptr references a static 8 octet buffer with unused bits set to 0, + * hense EXTRACT_*() macros are safe. + */ + ec_type = EXTRACT_BE_U_2(pptr); + switch (ec_type) { + case BGP_EXT_COM_RT_0: + /* 2-byte-AS:number fmt */ + snprintf(output, sizeof(output), "route-target: %u:%u/%d (%s)", + EXTRACT_BE_U_2(pptr+2), + EXTRACT_BE_U_4(pptr+4), + plen, rtc_prefix_in_hex); + break; - return 5 + (plen + 7) / 8; + case BGP_EXT_COM_RT_1: + /* IP-address:AS fmt */ + snprintf(output, sizeof(output), "route-target: %u.%u.%u.%u:%u/%d (%s)", + *(pptr+2), *(pptr+3), *(pptr+4), *(pptr+5), + EXTRACT_BE_U_2(pptr+6), plen, rtc_prefix_in_hex); + break; -trunc: - return -2; + case BGP_EXT_COM_RT_2: + /* 4-byte-AS:number fmt */ + snprintf(output, sizeof(output), "route-target: %s:%u/%d (%s)", + as_printf(ndo, astostr, sizeof(astostr), EXTRACT_BE_U_4(pptr+2)), + EXTRACT_BE_U_2(pptr+6), plen, rtc_prefix_in_hex); + break; + + default: + snprintf(output, sizeof(output), "route target: unknown-type(%04x) (%s/%d)", + ec_type, + rtc_prefix_in_hex, plen); + break; + } + return (output); } +/* RFC 4684 */ static int -decode_labeled_vpn_prefix4(netdissect_options *ndo, - const u_char *pptr, char *buf, u_int buflen) +decode_rt_routing_info(netdissect_options *ndo, + const u_char *pptr) { - struct in_addr addr; - u_int plen; + uint8_t route_target[8]; + u_int plen; + /* allocate space for the largest possible string */ + char astostr[AS_STR_SIZE]; + u_int num_octets; + + /* NLRI "prefix length" from RFC 2858 Section 4. */ + plen = GET_U_1(pptr); /* get prefix length */ + + /* NLRI "prefix" (ibid), valid lengths are { 0, 32, 33, ..., 96 } bits. + * RFC 4684 Section 4 defines the layout of "origin AS" and "route + * target" fields inside the "prefix" depending on its length. + */ + if (0 == plen) { + /* Without "origin AS", without "route target". */ + ND_PRINT("\n\t default route target"); + return 1; + } - ND_TCHECK(pptr[0]); - plen = pptr[0]; /* get prefix length */ + if (32 > plen) { + ND_PRINT("\n\t (illegal prefix length)"); + return -1; + } - if ((24+64) > plen) - return -1; + /* With at least "origin AS", possibly with "route target". */ + as_printf(ndo, astostr, sizeof(astostr), GET_BE_U_4(pptr + 1)); - plen-=(24+64); /* adjust prefixlen - labellength - RD len*/ + plen -= 32; /* adjust prefix length */ - if (32 < plen) - return -1; + if (64 < plen) { + ND_PRINT("\n\t (illegal prefix length)"); + return -1; + } - memset(&addr, 0, sizeof(addr)); - ND_TCHECK2(pptr[12], (plen + 7) / 8); - memcpy(&addr, &pptr[12], (plen + 7) / 8); - if (plen % 8) { - ((u_char *)&addr)[(plen + 7) / 8 - 1] &= - ((0xff00 >> (plen % 8)) & 0xff); - } - /* the label may get offsetted by 4 bits so lets shift it right */ - snprintf(buf, buflen, "RD: %s, %s/%d, label:%u %s", - bgp_vpn_rd_print(ndo, pptr+4), - ipaddr_string(ndo, &addr), - plen, - EXTRACT_24BITS(pptr+1)>>4, - ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); + /* From now on (plen + 7) / 8 evaluates to { 0, 1, 2, ..., 8 } + * and gives the number of octets in the variable-length "route + * target" field inside this NLRI "prefix". Look for it. + */ + memset(&route_target, 0, sizeof(route_target)); + num_octets = (plen + 7) / 8; + GET_CPY_BYTES(&route_target, pptr + 5, num_octets); + /* If mask-len is not on octet boundary, ensure all extra bits are 0 */ + if (plen % 8) { + ((u_char *)&route_target)[num_octets - 1] &= + ((0xff00 >> (plen % 8)) & 0xff); + } + ND_PRINT("\n\t origin AS: %s, %s", + astostr, + bgp_rt_prefix_print(ndo, (u_char *)&route_target, plen)); - return 12 + (plen + 7) / 8; + return 5 + num_octets; +} -trunc: - return -2; +static int +decode_labeled_vpn_prefix4(netdissect_options *ndo, + const u_char *pptr, char *buf, size_t buflen) +{ + nd_ipv4 addr; + u_int plen; + + plen = GET_U_1(pptr); /* get prefix length */ + + if ((24+64) > plen) + return -1; + + plen -= (24+64); /* adjust prefixlen - labellength - RD len*/ + + if (32 < plen) + return -1; + + memset(&addr, 0, sizeof(addr)); + GET_CPY_BYTES(&addr, pptr + 12, (plen + 7) / 8); + if (plen % 8) { + ((u_char *)&addr)[(plen + 7) / 8 - 1] &= + ((0xff00 >> (plen % 8)) & 0xff); + } + /* the label may get offsetted by 4 bits so lets shift it right */ + snprintf(buf, buflen, "RD: %s, %s/%u, label:%u %s", + bgp_vpn_rd_print(ndo, pptr+4), + ipaddr_string(ndo, (const u_char *)&addr), + plen, + GET_BE_U_3(pptr + 1)>>4, + ((GET_U_1(pptr + 3) & 1) == 0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); + + return 12 + (plen + 7) / 8; } /* @@ -861,40 +1092,33 @@ trunc: static int decode_mdt_vpn_nlri(netdissect_options *ndo, - const u_char *pptr, char *buf, u_int buflen) + const u_char *pptr, char *buf, size_t buflen) { - const u_char *rd; const u_char *vpn_ip; - ND_TCHECK(pptr[0]); - /* if the NLRI is not predefined length, quit.*/ - if (*pptr != MDT_VPN_NLRI_LEN * 8) - return -1; + if (GET_U_1(pptr) != MDT_VPN_NLRI_LEN * 8) + return -1; pptr++; /* RD */ - ND_TCHECK2(pptr[0], 8); + ND_TCHECK_8(pptr); rd = pptr; - pptr+=8; + pptr += 8; /* IPv4 address */ - ND_TCHECK2(pptr[0], sizeof(struct in_addr)); vpn_ip = pptr; - pptr+=sizeof(struct in_addr); + pptr += sizeof(nd_ipv4); /* MDT Group Address */ - ND_TCHECK2(pptr[0], sizeof(struct in_addr)); - snprintf(buf, buflen, "RD: %s, VPN IP Address: %s, MC Group Address: %s", - bgp_vpn_rd_print(ndo, rd), ipaddr_string(ndo, vpn_ip), ipaddr_string(ndo, pptr)); + bgp_vpn_rd_print(ndo, rd), GET_IPADDR_STRING(vpn_ip), GET_IPADDR_STRING(pptr)); return MDT_VPN_NLRI_LEN + 1; trunc: - -return -2; + return -2; } #define BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI 1 @@ -918,89 +1142,93 @@ static const struct tok bgp_multicast_vpn_route_type_values[] = { static int decode_multicast_vpn(netdissect_options *ndo, - const u_char *pptr, char *buf, u_int buflen) + const u_char *pptr, char *buf, size_t buflen) { - uint8_t route_type, route_length, addr_length, sg_length; - u_int offset; - - ND_TCHECK2(pptr[0], 2); - route_type = *pptr++; - route_length = *pptr++; - - snprintf(buf, buflen, "Route-Type: %s (%u), length: %u", - tok2str(bgp_multicast_vpn_route_type_values, - "Unknown", route_type), - route_type, route_length); - - switch(route_type) { - case BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI: - ND_TCHECK2(pptr[0], BGP_VPN_RD_LEN); - offset = strlen(buf); - snprintf(buf + offset, buflen - offset, ", RD: %s, Originator %s", - bgp_vpn_rd_print(ndo, pptr), - bgp_vpn_ip_print(ndo, pptr + BGP_VPN_RD_LEN, - (route_length - BGP_VPN_RD_LEN) << 3)); - break; - case BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI: - ND_TCHECK2(pptr[0], BGP_VPN_RD_LEN + 4); - offset = strlen(buf); - snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s", - bgp_vpn_rd_print(ndo, pptr), - as_printf(ndo, astostr, sizeof(astostr), - EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN))); - break; + /* allocate space for the largest possible string */ + char astostr[AS_STR_SIZE]; + uint8_t route_type, route_length; + u_int addr_length, sg_length; + u_int offset; + + route_type = GET_U_1(pptr); + pptr++; + route_length = GET_U_1(pptr); + pptr++; - case BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI: - ND_TCHECK2(pptr[0], BGP_VPN_RD_LEN); - offset = strlen(buf); - snprintf(buf + offset, buflen - offset, ", RD: %s", - bgp_vpn_rd_print(ndo, pptr)); - pptr += BGP_VPN_RD_LEN; + snprintf(buf, buflen, "Route-Type: %s (%u), length: %u", + tok2str(bgp_multicast_vpn_route_type_values, + "Unknown", route_type), + route_type, route_length); + + switch(route_type) { + case BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI: + ND_TCHECK_LEN(pptr, BGP_VPN_RD_LEN); + offset = (u_int)strlen(buf); + snprintf(buf + offset, buflen - offset, ", RD: %s, Originator %s", + bgp_vpn_rd_print(ndo, pptr), + bgp_vpn_ip_print(ndo, pptr + BGP_VPN_RD_LEN, + (route_length - BGP_VPN_RD_LEN) << 3)); + break; + case BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI: + ND_TCHECK_LEN(pptr, BGP_VPN_RD_LEN + 4); + offset = (u_int)strlen(buf); + snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s", + bgp_vpn_rd_print(ndo, pptr), + as_printf(ndo, astostr, sizeof(astostr), + GET_BE_U_4(pptr + BGP_VPN_RD_LEN))); + break; - sg_length = bgp_vpn_sg_print(ndo, pptr, buf, buflen); - addr_length = route_length - sg_length; + case BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI: + ND_TCHECK_LEN(pptr, BGP_VPN_RD_LEN); + offset = (u_int)strlen(buf); + snprintf(buf + offset, buflen - offset, ", RD: %s", + bgp_vpn_rd_print(ndo, pptr)); + pptr += BGP_VPN_RD_LEN; - ND_TCHECK2(pptr[0], addr_length); - offset = strlen(buf); - snprintf(buf + offset, buflen - offset, ", Originator %s", - bgp_vpn_ip_print(ndo, pptr, addr_length << 3)); - break; + sg_length = bgp_vpn_sg_print(ndo, pptr, buf, buflen); + addr_length = route_length - sg_length; - case BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE: - ND_TCHECK2(pptr[0], BGP_VPN_RD_LEN); - offset = strlen(buf); - snprintf(buf + offset, buflen - offset, ", RD: %s", - bgp_vpn_rd_print(ndo, pptr)); - pptr += BGP_VPN_RD_LEN; + ND_TCHECK_LEN(pptr, addr_length); + offset = (u_int)strlen(buf); + snprintf(buf + offset, buflen - offset, ", Originator %s", + bgp_vpn_ip_print(ndo, pptr, addr_length << 3)); + break; - bgp_vpn_sg_print(ndo, pptr, buf, buflen); - break; + case BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE: + ND_TCHECK_LEN(pptr, BGP_VPN_RD_LEN); + offset = (u_int)strlen(buf); + snprintf(buf + offset, buflen - offset, ", RD: %s", + bgp_vpn_rd_print(ndo, pptr)); + pptr += BGP_VPN_RD_LEN; - case BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN: /* fall through */ - case BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN: - ND_TCHECK2(pptr[0], BGP_VPN_RD_LEN + 4); - offset = strlen(buf); - snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s", - bgp_vpn_rd_print(ndo, pptr), - as_printf(ndo, astostr, sizeof(astostr), - EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN))); - pptr += BGP_VPN_RD_LEN + 4; - - bgp_vpn_sg_print(ndo, pptr, buf, buflen); - break; + bgp_vpn_sg_print(ndo, pptr, buf, buflen); + break; - /* - * no per route-type printing yet. - */ - case BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF: - default: - break; - } + case BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN: /* fall through */ + case BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN: + ND_TCHECK_LEN(pptr, BGP_VPN_RD_LEN + 4); + offset = (u_int)strlen(buf); + snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s", + bgp_vpn_rd_print(ndo, pptr), + as_printf(ndo, astostr, sizeof(astostr), + GET_BE_U_4(pptr + BGP_VPN_RD_LEN))); + pptr += BGP_VPN_RD_LEN + 4; + + bgp_vpn_sg_print(ndo, pptr, buf, buflen); + break; + + /* + * no per route-type printing yet. + */ + case BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF: + default: + break; + } - return route_length + 2; + return route_length + 2; trunc: - return -2; + return -2; } /* @@ -1020,285 +1248,284 @@ trunc: buflen=0; \ else { \ buflen-=stringlen; \ - buf+=stringlen; \ + buf+=stringlen; \ } static int decode_labeled_vpn_l2(netdissect_options *ndo, - const u_char *pptr, char *buf, u_int buflen) + const u_char *pptr, char *buf, size_t buflen) { - int plen,tlen,stringlen,tlv_type,tlv_len,ttlv_len; - - ND_TCHECK2(pptr[0], 2); - plen=EXTRACT_16BITS(pptr); - tlen=plen; - pptr+=2; - /* 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 */ - ND_TCHECK2(pptr[0],12); - buf[0]='\0'; - stringlen=snprintf(buf, buflen, "RD: %s, BGPNH: %s", - bgp_vpn_rd_print(ndo, pptr), - ipaddr_string(ndo, pptr+8) - ); - UPDATE_BUF_BUFLEN(buf, buflen, stringlen); - pptr+=12; - tlen-=12; - return plen; - } else if (plen>17) { - /* assume old format */ - /* RD, ID, LBLKOFF, LBLBASE */ - - ND_TCHECK2(pptr[0],15); - buf[0]='\0'; - stringlen=snprintf(buf, buflen, "RD: %s, CE-ID: %u, Label-Block Offset: %u, Label Base %u", - bgp_vpn_rd_print(ndo, 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, stringlen); - pptr+=15; - tlen-=15; - - /* ok now the variable part - lets read out TLVs*/ - while (tlen>0) { - if (tlen < 3) - return -1; - ND_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) { - stringlen=snprintf(buf,buflen, "\n\t\tcircuit status vector (%u) length: %u: 0x", - tlv_type, - tlv_len); - UPDATE_BUF_BUFLEN(buf, buflen, stringlen); - } - ttlv_len=ttlv_len/8+1; /* how many bytes do we need to read ? */ - while (ttlv_len>0) { - ND_TCHECK(pptr[0]); - if (buflen!=0) { - stringlen=snprintf(buf,buflen, "%02x",*pptr++); - UPDATE_BUF_BUFLEN(buf, buflen, stringlen); - } - ttlv_len--; - } - break; - default: - if (buflen!=0) { - stringlen=snprintf(buf,buflen, "\n\t\tunknown TLV #%u, length: %u", - tlv_type, - tlv_len); - UPDATE_BUF_BUFLEN(buf, buflen, stringlen); - } - 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; + u_int plen, tlen, tlv_type, tlv_len, ttlv_len; + int stringlen; + + plen = GET_BE_U_2(pptr); + tlen = plen; + pptr += 2; + /* 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 */ + ND_TCHECK_LEN(pptr, 12); + buf[0] = '\0'; + stringlen = snprintf(buf, buflen, "RD: %s, BGPNH: %s", + bgp_vpn_rd_print(ndo, pptr), + GET_IPADDR_STRING(pptr+8)); + UPDATE_BUF_BUFLEN(buf, buflen, stringlen); + pptr += 12; + tlen -= 12; + return plen + 2; + } else if (plen > 17) { + /* assume old format */ + /* RD, ID, LBLKOFF, LBLBASE */ + + ND_TCHECK_LEN(pptr, 15); + buf[0] = '\0'; + stringlen = snprintf(buf, buflen, "RD: %s, CE-ID: %u, Label-Block Offset: %u, Label Base %u", + bgp_vpn_rd_print(ndo, pptr), + GET_BE_U_2(pptr + 8), + GET_BE_U_2(pptr + 10), + GET_BE_U_3(pptr + 12)>>4); /* the label is offsetted by 4 bits so lets shift it right */ + UPDATE_BUF_BUFLEN(buf, buflen, stringlen); + pptr += 15; + tlen -= 15; + + /* ok now the variable part - lets read out TLVs*/ + while (tlen != 0) { + if (tlen < 3) { + if (buflen != 0) { + stringlen=snprintf(buf,buflen, "\n\t\tran past the end"); + UPDATE_BUF_BUFLEN(buf, buflen, stringlen); + } + return plen + 2; + } + tlv_type = GET_U_1(pptr); + pptr++; + tlv_len = GET_BE_U_2(pptr); /* length, in *bits* */ + ttlv_len = (tlv_len + 7)/8; /* length, in *bytes* */ + pptr += 2; + + switch(tlv_type) { + case 1: + if (buflen != 0) { + stringlen=snprintf(buf,buflen, "\n\t\tcircuit status vector (%u) length: %u: 0x", + tlv_type, + tlv_len); + UPDATE_BUF_BUFLEN(buf, buflen, stringlen); + } + while (ttlv_len != 0) { + if (tlen < 1) { + if (buflen != 0) { + stringlen=snprintf(buf,buflen, " (ran past the end)"); + UPDATE_BUF_BUFLEN(buf, buflen, stringlen); + } + return plen + 2; + } + ND_TCHECK_1(pptr); + if (buflen != 0) { + stringlen=snprintf(buf,buflen, "%02x", + GET_U_1(pptr)); + pptr++; + UPDATE_BUF_BUFLEN(buf, buflen, stringlen); + } + ttlv_len--; + tlen--; + } + break; + default: + if (buflen != 0) { + stringlen=snprintf(buf,buflen, "\n\t\tunknown TLV #%u, length: %u", + tlv_type, + tlv_len); + UPDATE_BUF_BUFLEN(buf, buflen, stringlen); + } + if (tlen < ttlv_len) { + if (buflen != 0) { + stringlen=snprintf(buf,buflen, " (ran past the end)"); + UPDATE_BUF_BUFLEN(buf, buflen, stringlen); + } + return plen + 2; + } + tlen -= ttlv_len; + break; + } } + return plen + 2; + } else { + /* complain bitterly ? */ + /* fall through */ + goto trunc; + } trunc: - return -2; + return -2; } int decode_prefix6(netdissect_options *ndo, - const u_char *pd, u_int itemlen, char *buf, u_int buflen) + const u_char *pd, u_int itemlen, char *buf, size_t buflen) { - struct in6_addr addr; - u_int plen, plenbytes; - - ND_TCHECK(pd[0]); - ITEMCHECK(1); - plen = pd[0]; - if (128 < plen) - return -1; - itemlen -= 1; - - memset(&addr, 0, sizeof(addr)); - plenbytes = (plen + 7) / 8; - ND_TCHECK2(pd[1], plenbytes); - ITEMCHECK(plenbytes); - memcpy(&addr, &pd[1], plenbytes); - if (plen % 8) { - addr.s6_addr[plenbytes - 1] &= - ((0xff00 >> (plen % 8)) & 0xff); - } - snprintf(buf, buflen, "%s/%d", ip6addr_string(ndo, &addr), plen); - return 1 + plenbytes; - -trunc: - return -2; + nd_ipv6 addr; + u_int plen, plenbytes; + + ITEMCHECK(1); + plen = GET_U_1(pd); + if (128 < plen) + return -1; + itemlen -= 1; + + memset(&addr, 0, sizeof(addr)); + plenbytes = (plen + 7) / 8; + ITEMCHECK(plenbytes); + GET_CPY_BYTES(&addr, pd + 1, plenbytes); + if (plen % 8) { + addr[plenbytes - 1] &= + ((0xff00 >> (plen % 8)) & 0xff); + } + snprintf(buf, buflen, "%s/%u", ip6addr_string(ndo, (const u_char *)&addr), plen); + return 1 + plenbytes; badtlv: - return -3; + return -2; } static int decode_labeled_prefix6(netdissect_options *ndo, - const u_char *pptr, u_int itemlen, char *buf, u_int buflen) + const u_char *pptr, u_int itemlen, char *buf, size_t buflen) { - struct in6_addr addr; - u_int plen, plenbytes; - - /* prefix length and label = 4 bytes */ - ND_TCHECK2(pptr[0], 4); - ITEMCHECK(4); - plen = pptr[0]; /* get prefix length */ - - if (24 > plen) - return -1; - - plen-=24; /* adjust prefixlen - labellength */ - - if (128 < plen) - return -1; - itemlen -= 4; - - memset(&addr, 0, sizeof(addr)); - plenbytes = (plen + 7) / 8; - ND_TCHECK2(pptr[4], plenbytes); - memcpy(&addr, &pptr[4], plenbytes); - if (plen % 8) { - addr.s6_addr[plenbytes - 1] &= - ((0xff00 >> (plen % 8)) & 0xff); - } - /* the label may get offsetted by 4 bits so lets shift it right */ - snprintf(buf, buflen, "%s/%d, label:%u %s", - ip6addr_string(ndo, &addr), - plen, - EXTRACT_24BITS(pptr+1)>>4, - ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); + nd_ipv6 addr; + u_int plen, plenbytes; + + /* prefix length and label = 4 bytes */ + ND_TCHECK_4(pptr); + ITEMCHECK(4); + plen = GET_U_1(pptr); /* get prefix length */ + + if (24 > plen) + return -1; + + plen -= 24; /* adjust prefixlen - labellength */ + + if (128 < plen) + return -1; + itemlen -= 4; + + memset(&addr, 0, sizeof(addr)); + plenbytes = (plen + 7) / 8; + GET_CPY_BYTES(&addr, pptr + 4, plenbytes); + if (plen % 8) { + addr[plenbytes - 1] &= + ((0xff00 >> (plen % 8)) & 0xff); + } + /* the label may get offsetted by 4 bits so lets shift it right */ + snprintf(buf, buflen, "%s/%u, label:%u %s", + ip6addr_string(ndo, (const u_char *)&addr), + plen, + GET_BE_U_3(pptr + 1)>>4, + ((GET_U_1(pptr + 3) & 1) == 0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); - return 4 + plenbytes; + return 4 + plenbytes; trunc: - return -2; + return -2; badtlv: - return -3; + return -3; } static int decode_labeled_vpn_prefix6(netdissect_options *ndo, - const u_char *pptr, char *buf, u_int buflen) + const u_char *pptr, char *buf, size_t buflen) { - struct in6_addr addr; - u_int plen; - - ND_TCHECK(pptr[0]); - plen = pptr[0]; /* get prefix length */ - - if ((24+64) > plen) - return -1; + nd_ipv6 addr; + u_int plen; - plen-=(24+64); /* adjust prefixlen - labellength - RD len*/ + plen = GET_U_1(pptr); /* get prefix length */ - if (128 < plen) - return -1; + if ((24+64) > plen) + return -1; - memset(&addr, 0, sizeof(addr)); - ND_TCHECK2(pptr[12], (plen + 7) / 8); - memcpy(&addr, &pptr[12], (plen + 7) / 8); - if (plen % 8) { - addr.s6_addr[(plen + 7) / 8 - 1] &= - ((0xff00 >> (plen % 8)) & 0xff); - } - /* the label may get offsetted by 4 bits so lets shift it right */ - snprintf(buf, buflen, "RD: %s, %s/%d, label:%u %s", - bgp_vpn_rd_print(ndo, pptr+4), - ip6addr_string(ndo, &addr), - plen, - EXTRACT_24BITS(pptr+1)>>4, - ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); + plen -= (24+64); /* adjust prefixlen - labellength - RD len*/ - return 12 + (plen + 7) / 8; + if (128 < plen) + return -1; -trunc: - return -2; + memset(&addr, 0, sizeof(addr)); + GET_CPY_BYTES(&addr, pptr + 12, (plen + 7) / 8); + if (plen % 8) { + addr[(plen + 7) / 8 - 1] &= + ((0xff00 >> (plen % 8)) & 0xff); + } + /* the label may get offsetted by 4 bits so lets shift it right */ + snprintf(buf, buflen, "RD: %s, %s/%u, label:%u %s", + bgp_vpn_rd_print(ndo, pptr+4), + ip6addr_string(ndo, (const u_char *)&addr), + plen, + GET_BE_U_3(pptr + 1)>>4, + ((GET_U_1(pptr + 3) & 1) == 0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); + + return 12 + (plen + 7) / 8; } static int decode_clnp_prefix(netdissect_options *ndo, - const u_char *pptr, char *buf, u_int buflen) + const u_char *pptr, char *buf, size_t buflen) { - uint8_t addr[19]; - u_int plen; + uint8_t addr[19]; + u_int plen; - ND_TCHECK(pptr[0]); - plen = pptr[0]; /* get prefix length */ + plen = GET_U_1(pptr); /* get prefix length */ - if (152 < plen) - return -1; + if (152 < plen) + return -1; - memset(&addr, 0, sizeof(addr)); - ND_TCHECK2(pptr[4], (plen + 7) / 8); - memcpy(&addr, &pptr[4], (plen + 7) / 8); - if (plen % 8) { - addr[(plen + 7) / 8 - 1] &= - ((0xff00 >> (plen % 8)) & 0xff); - } - snprintf(buf, buflen, "%s/%d", - isonsap_string(ndo, addr,(plen + 7) / 8), - plen); - - return 1 + (plen + 7) / 8; + memset(&addr, 0, sizeof(addr)); + GET_CPY_BYTES(&addr, pptr + 4, (plen + 7) / 8); + if (plen % 8) { + addr[(plen + 7) / 8 - 1] &= + ((0xff00 >> (plen % 8)) & 0xff); + } + /* Cannot use GET_ISONSAP_STRING (not packet buffer pointer) */ + snprintf(buf, buflen, "%s/%u", + isonsap_string(ndo, addr,(plen + 7) / 8), + plen); -trunc: - return -2; + return 1 + (plen + 7) / 8; } static int decode_labeled_vpn_clnp_prefix(netdissect_options *ndo, - const u_char *pptr, char *buf, u_int buflen) + const u_char *pptr, char *buf, size_t buflen) { - uint8_t addr[19]; - u_int plen; - - ND_TCHECK(pptr[0]); - plen = pptr[0]; /* get prefix length */ + uint8_t addr[19]; + u_int plen; - if ((24+64) > plen) - return -1; + plen = GET_U_1(pptr); /* get prefix length */ - plen-=(24+64); /* adjust prefixlen - labellength - RD len*/ + if ((24+64) > plen) + return -1; - if (152 < plen) - return -1; - - memset(&addr, 0, sizeof(addr)); - ND_TCHECK2(pptr[12], (plen + 7) / 8); - memcpy(&addr, &pptr[12], (plen + 7) / 8); - if (plen % 8) { - addr[(plen + 7) / 8 - 1] &= - ((0xff00 >> (plen % 8)) & 0xff); - } - /* the label may get offsetted by 4 bits so lets shift it right */ - snprintf(buf, buflen, "RD: %s, %s/%d, label:%u %s", - bgp_vpn_rd_print(ndo, pptr+4), - isonsap_string(ndo, addr,(plen + 7) / 8), - plen, - EXTRACT_24BITS(pptr+1)>>4, - ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); + plen -= (24+64); /* adjust prefixlen - labellength - RD len*/ - return 12 + (plen + 7) / 8; + if (152 < plen) + return -1; -trunc: - return -2; + memset(&addr, 0, sizeof(addr)); + GET_CPY_BYTES(&addr, pptr + 12, (plen + 7) / 8); + if (plen % 8) { + addr[(plen + 7) / 8 - 1] &= ((0xff00 >> (plen % 8)) & 0xff); + } + /* the label may get offsetted by 4 bits so lets shift it right */ + /* Cannot use GET_ISONSAP_STRING (not packet buffer pointer) */ + snprintf(buf, buflen, "RD: %s, %s/%u, label:%u %s", + bgp_vpn_rd_print(ndo, pptr+4), + isonsap_string(ndo, addr,(plen + 7) / 8), + plen, + GET_BE_U_3(pptr + 1)>>4, + ((GET_U_1(pptr + 3) & 1) == 0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); + + return 12 + (plen + 7) / 8; } /* @@ -1308,9 +1535,9 @@ trunc: * both Old speakers that do not support 4 byte AS, and the new speakers that do * support, exchange AS-Path with the same path-attribute type value 0x02. */ -static int +static u_int bgp_attr_get_as_size(netdissect_options *ndo, - uint8_t bgpa_type, const u_char *pptr, int len) + uint8_t bgpa_type, const u_char *pptr, u_int len) { const u_char *tptr = pptr; @@ -1328,16 +1555,13 @@ bgp_attr_get_as_size(netdissect_options *ndo, * each. */ while (tptr < pptr + len) { - ND_TCHECK(tptr[0]); - /* * If we do not find a valid segment type, our guess might be wrong. */ - if (tptr[0] < BGP_AS_SEG_TYPE_MIN || tptr[0] > BGP_AS_SEG_TYPE_MAX) { + if (GET_U_1(tptr) < BGP_AS_SEG_TYPE_MIN || GET_U_1(tptr) > BGP_AS_SEG_TYPE_MAX) { goto trunc; } - ND_TCHECK(tptr[1]); - tptr += 2 + tptr[1] * 2; + tptr += 2 + GET_U_1(tptr + 1) * 2; } /* @@ -1356,1523 +1580,1587 @@ trunc: * so that calller can try to decode each AS as of 4 bytes. If indeed * there was not enough data, it will crib and end the parse anyways. */ - return 4; + return 4; } +/* + * The only way to know that a BGP UPDATE message is using add path is + * by checking if the capability is in the OPEN message which we may have missed. + * So this function checks if it is possible that the update could contain add path + * and if so it checks that standard BGP doesn't make sense. + */ static int -bgp_attr_print(netdissect_options *ndo, - u_int atype, const u_char *pptr, u_int len, const unsigned attr_set_level) +check_add_path(netdissect_options *ndo, const u_char *pptr, u_int length, + u_int max_prefix_length) { - int i; - uint16_t af; - uint8_t safi, snpa, nhlen; - union { /* copy buffer for bandwidth values */ - float f; - uint32_t i; - } bw; - int advance; - u_int tlen; - const u_char *tptr; - char buf[MAXHOSTNAMELEN + 100]; - int as_size; - - tptr = pptr; - tlen=len; - - switch (atype) { - case BGPTYPE_ORIGIN: - if (len != 1) - ND_PRINT((ndo, "invalid len")); - else { - ND_TCHECK(*tptr); - ND_PRINT((ndo, "%s", tok2str(bgp_origin_values, - "Unknown Origin Typecode", - tptr[0]))); - } - break; + u_int offset, prefix_length; + + if (length < 5) { + return 0; + } + /* + * Scan through the NLRI information under the assumpetion that + * it doesn't have path IDs. + */ + for (offset = 0; offset < length;) { + offset += 4; + if (!ND_TTEST_1(pptr + offset)) { + /* We ran out of captured data; quit scanning. */ + break; + } + prefix_length = GET_U_1(pptr + offset); /* - * Process AS4 byte path and AS2 byte path attributes here. + * Add 4 to cover the path id + * and check the prefix length isn't greater than 32/128. */ - case BGPTYPE_AS4_PATH: - case BGPTYPE_AS_PATH: - if (len % 2) { - ND_PRINT((ndo, "invalid len")); - break; - } - if (!len) { - ND_PRINT((ndo, "empty")); - break; - } + if (prefix_length > max_prefix_length) { + return 0; + } + /* Add 1 for the prefix_length byte and prefix_length to cover the address */ + offset += 1 + ((prefix_length + 7) / 8); + } + /* check we haven't gone past the end of the section */ + if (offset > length) { + return 0; + } - /* - * BGP updates exchanged between New speakers that support 4 - * byte AS, ASs are always encoded in 4 bytes. There is no - * definitive way to find this, just by the packet's - * contents. So, check for packet's TLV's sanity assuming - * 2 bytes first, and it does not pass, assume that ASs are - * encoded in 4 bytes format and move on. - */ - as_size = bgp_attr_get_as_size(ndo, atype, pptr, len); - - while (tptr < pptr + len) { - ND_TCHECK(tptr[0]); - ND_PRINT((ndo, "%s", tok2str(bgp_as_path_segment_open_values, - "?", tptr[0]))); - ND_TCHECK(tptr[1]); - for (i = 0; i < tptr[1] * as_size; i += as_size) { - ND_TCHECK2(tptr[2 + i], as_size); - ND_PRINT((ndo, "%s ", - as_printf(ndo, astostr, sizeof(astostr), - as_size == 2 ? - EXTRACT_16BITS(&tptr[2 + i]) : - EXTRACT_32BITS(&tptr[2 + i])))); - } - ND_TCHECK(tptr[0]); - ND_PRINT((ndo, "%s", tok2str(bgp_as_path_segment_close_values, - "?", tptr[0]))); - ND_TCHECK(tptr[1]); - tptr += 2 + tptr[1] * as_size; - } - break; - case BGPTYPE_NEXT_HOP: - if (len != 4) - ND_PRINT((ndo, "invalid len")); - else { - ND_TCHECK2(tptr[0], 4); - ND_PRINT((ndo, "%s", ipaddr_string(ndo, tptr))); - } - break; - case BGPTYPE_MULTI_EXIT_DISC: - case BGPTYPE_LOCAL_PREF: - if (len != 4) - ND_PRINT((ndo, "invalid len")); - else { - ND_TCHECK2(tptr[0], 4); - ND_PRINT((ndo, "%u", EXTRACT_32BITS(tptr))); - } - break; - case BGPTYPE_ATOMIC_AGGREGATE: - if (len != 0) - ND_PRINT((ndo, "invalid len")); - break; - 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) { - ND_PRINT((ndo, "invalid len")); - break; + /* check it's not standard BGP */ + for (offset = 0; offset < length; ) { + if (!ND_TTEST_1(pptr + offset)) { + /* We ran out of captured data; quit scanning. */ + break; + } + prefix_length = GET_U_1(pptr + offset); + /* + * If the prefix_length is zero (0.0.0.0/0) + * and since it's not the only address (length >= 5) + * then it is add-path + */ + if (prefix_length < 1 || prefix_length > max_prefix_length) { + return 1; + } + offset += 1 + ((prefix_length + 7) / 8); + } + if (offset > length) { + return 1; + } + + /* assume not add-path by default */ + return 0; +} + +static int +bgp_mp_af_print(netdissect_options *ndo, + const u_char *tptr, u_int tlen, + uint16_t *afp, uint8_t *safip) +{ + uint16_t af; + uint8_t safi; + + af = GET_BE_U_2(tptr); + *afp = af; + safi = GET_U_1(tptr + 2); + *safip = safi; + + ND_PRINT("\n\t AFI: %s (%u), %sSAFI: %s (%u)", + tok2str(af_values, "Unknown AFI", af), + af, + (safi>128) ? "vendor specific " : "", /* 128 is meanwhile wellknown */ + tok2str(bgp_safi_values, "Unknown SAFI", safi), + safi); + + switch(af<<8 | safi) { + case (AFNUM_INET<<8 | SAFNUM_UNICAST): + case (AFNUM_INET<<8 | SAFNUM_MULTICAST): + case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST): + case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): + case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO): + case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST): + 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): + case (AFNUM_INET6<<8 | SAFNUM_UNICAST): + case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): + case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): + case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): + case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST): + case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): + case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): + case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): + case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): + case (AFNUM_VPLS<<8 | SAFNUM_VPLS): + break; + default: + ND_TCHECK_LEN(tptr, tlen); + ND_PRINT("\n\t no AFI %u / SAFI %u decoder", af, safi); + if (ndo->ndo_vflag <= 1) + print_unknown_data(ndo, tptr, "\n\t ", tlen); + return -1; + } + return 0; +trunc: + return -2; +} + +static int +bgp_nlri_print(netdissect_options *ndo, uint16_t af, uint8_t safi, + const u_char *tptr, u_int len, + char *buf, size_t buflen, + int add_path4, int add_path6) +{ + int advance; + u_int path_id = 0; + + switch (af<<8 | safi) { + case (AFNUM_INET<<8 | SAFNUM_UNICAST): + case (AFNUM_INET<<8 | SAFNUM_MULTICAST): + case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST): + if (add_path4) { + path_id = GET_BE_U_4(tptr); + tptr += 4; } - ND_TCHECK2(tptr[0], len); - if (len == 6) { - ND_PRINT((ndo, " AS #%s, origin %s", - as_printf(ndo, astostr, sizeof(astostr), EXTRACT_16BITS(tptr)), - ipaddr_string(ndo, tptr + 2))); - } else { - ND_PRINT((ndo, " AS #%s, origin %s", - as_printf(ndo, astostr, sizeof(astostr), - EXTRACT_32BITS(tptr)), ipaddr_string(ndo, tptr + 4))); + advance = decode_prefix4(ndo, tptr, len, buf, buflen); + if (advance == -1) + ND_PRINT("\n\t (illegal prefix length)"); + else if (advance == -2) + break; /* bytes left, but not enough */ + else + ND_PRINT("\n\t %s", buf); + if (add_path4) { + ND_PRINT(" Path Id: %u", path_id); + advance += 4; } break; - case BGPTYPE_AGGREGATOR4: - if (len != 8) { - ND_PRINT((ndo, "invalid len")); - break; - } - ND_TCHECK2(tptr[0], 8); - ND_PRINT((ndo, " AS #%s, origin %s", - as_printf(ndo, astostr, sizeof(astostr), EXTRACT_32BITS(tptr)), - ipaddr_string(ndo, tptr + 4))); - break; - case BGPTYPE_COMMUNITIES: - if (len % 4) { - ND_PRINT((ndo, "invalid len")); - break; - } - while (tlen>0) { - uint32_t comm; - ND_TCHECK2(tptr[0], 4); - comm = EXTRACT_32BITS(tptr); - switch (comm) { - case BGP_COMMUNITY_NO_EXPORT: - ND_PRINT((ndo, " NO_EXPORT")); - break; - case BGP_COMMUNITY_NO_ADVERT: - ND_PRINT((ndo, " NO_ADVERTISE")); - break; - case BGP_COMMUNITY_NO_EXPORT_SUBCONFED: - ND_PRINT((ndo, " NO_EXPORT_SUBCONFED")); - break; - default: - ND_PRINT((ndo, "%u:%u%s", - (comm >> 16) & 0xffff, - comm & 0xffff, - (tlen>4) ? ", " : "")); - break; - } - tlen -=4; - tptr +=4; - } - break; - case BGPTYPE_ORIGINATOR_ID: - if (len != 4) { - ND_PRINT((ndo, "invalid len")); - break; - } - ND_TCHECK2(tptr[0], 4); - ND_PRINT((ndo, "%s",ipaddr_string(ndo, tptr))); + case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): + advance = decode_labeled_prefix4(ndo, tptr, len, buf, buflen); + if (advance == -1) + ND_PRINT("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else if (advance == -3) + break; /* bytes left, but not enough */ + else + ND_PRINT("\n\t %s", buf); break; - case BGPTYPE_CLUSTER_LIST: - if (len % 4) { - ND_PRINT((ndo, "invalid len")); - break; - } - while (tlen>0) { - ND_TCHECK2(tptr[0], 4); - ND_PRINT((ndo, "%s%s", - ipaddr_string(ndo, tptr), - (tlen>4) ? ", " : "")); - tlen -=4; - tptr +=4; - } + case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST): + advance = decode_labeled_vpn_prefix4(ndo, tptr, buf, buflen); + if (advance == -1) + ND_PRINT("\n\t (illegal prefix length)"); + else + ND_PRINT("\n\t %s", buf); + break; + case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO): + advance = decode_rt_routing_info(ndo, tptr); + break; + case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): /* fall through */ + case (AFNUM_INET6<<8 | SAFNUM_MULTICAST_VPN): + advance = decode_multicast_vpn(ndo, tptr, buf, buflen); + if (advance == -1) + ND_PRINT("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + ND_PRINT("\n\t %s", buf); break; - case BGPTYPE_MP_REACH_NLRI: - ND_TCHECK2(tptr[0], 3); - af = EXTRACT_16BITS(tptr); - safi = tptr[2]; - - ND_PRINT((ndo, "\n\t AFI: %s (%u), %sSAFI: %s (%u)", - tok2str(af_values, "Unknown AFI", af), - af, - (safi>128) ? "vendor specific " : "", /* 128 is meanwhile wellknown */ - tok2str(bgp_safi_values, "Unknown SAFI", safi), - safi)); - switch(af<<8 | safi) { - case (AFNUM_INET<<8 | SAFNUM_UNICAST): - case (AFNUM_INET<<8 | SAFNUM_MULTICAST): - case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST): - case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): - case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO): - case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST): - 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): - case (AFNUM_INET6<<8 | SAFNUM_UNICAST): - case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): - case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): - case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): - case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST): - case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST): - case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST): - case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): - case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): - case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): - case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST): - case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST): - case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST): - case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): - case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): - case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): - case (AFNUM_VPLS<<8 | SAFNUM_VPLS): - break; - default: - ND_TCHECK2(tptr[0], tlen); - ND_PRINT((ndo, "\n\t no AFI %u / SAFI %u decoder", af, safi)); - if (ndo->ndo_vflag <= 1) - print_unknown_data(ndo, tptr, "\n\t ", tlen); - goto done; - break; + case (AFNUM_INET<<8 | SAFNUM_MDT): + advance = decode_mdt_vpn_nlri(ndo, tptr, buf, buflen); + if (advance == -1) + ND_PRINT("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + ND_PRINT("\n\t %s", buf); + break; + case (AFNUM_INET6<<8 | SAFNUM_UNICAST): + case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): + case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): + if (add_path6) { + path_id = GET_BE_U_4(tptr); + tptr += 4; } - - tptr +=3; - - ND_TCHECK(tptr[0]); - nhlen = tptr[0]; - tlen = nhlen; - tptr++; - - if (tlen) { - int nnh = 0; - ND_PRINT((ndo, "\n\t nexthop: ")); - while (tlen > 0) { - if ( nnh++ > 0 ) { - ND_PRINT((ndo, ", " )); - } - switch(af<<8 | safi) { - case (AFNUM_INET<<8 | SAFNUM_UNICAST): - case (AFNUM_INET<<8 | SAFNUM_MULTICAST): - case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST): - case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): - case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO): - case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): - case (AFNUM_INET<<8 | SAFNUM_MDT): - if (tlen < (int)sizeof(struct in_addr)) { - ND_PRINT((ndo, "invalid len")); - tlen = 0; - } else { - ND_TCHECK2(tptr[0], sizeof(struct in_addr)); - ND_PRINT((ndo, "%s",ipaddr_string(ndo, tptr))); - tlen -= sizeof(struct in_addr); - tptr += sizeof(struct in_addr); - } - break; - case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST): - case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST): - case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST): - if (tlen < (int)(sizeof(struct in_addr)+BGP_VPN_RD_LEN)) { - ND_PRINT((ndo, "invalid len")); - tlen = 0; - } else { - ND_TCHECK2(tptr[0], sizeof(struct in_addr)+BGP_VPN_RD_LEN); - ND_PRINT((ndo, "RD: %s, %s", - bgp_vpn_rd_print(ndo, tptr), - ipaddr_string(ndo, tptr+BGP_VPN_RD_LEN))); - tlen -= (sizeof(struct in_addr)+BGP_VPN_RD_LEN); - tptr += (sizeof(struct in_addr)+BGP_VPN_RD_LEN); - } - break; - case (AFNUM_INET6<<8 | SAFNUM_UNICAST): - case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): - case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): - case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): - if (tlen < (int)sizeof(struct in6_addr)) { - ND_PRINT((ndo, "invalid len")); - tlen = 0; - } else { - ND_TCHECK2(tptr[0], sizeof(struct in6_addr)); - ND_PRINT((ndo, "%s", ip6addr_string(ndo, tptr))); - tlen -= sizeof(struct in6_addr); - tptr += sizeof(struct in6_addr); - } - break; - case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST): - case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST): - case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST): - if (tlen < (int)(sizeof(struct in6_addr)+BGP_VPN_RD_LEN)) { - ND_PRINT((ndo, "invalid len")); - tlen = 0; - } else { - ND_TCHECK2(tptr[0], sizeof(struct in6_addr)+BGP_VPN_RD_LEN); - ND_PRINT((ndo, "RD: %s, %s", - bgp_vpn_rd_print(ndo, tptr), - ip6addr_string(ndo, tptr+BGP_VPN_RD_LEN))); - tlen -= (sizeof(struct in6_addr)+BGP_VPN_RD_LEN); - tptr += (sizeof(struct in6_addr)+BGP_VPN_RD_LEN); - } - break; - case (AFNUM_VPLS<<8 | SAFNUM_VPLS): - case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): - case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): - case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): - if (tlen < (int)sizeof(struct in_addr)) { - ND_PRINT((ndo, "invalid len")); - tlen = 0; - } else { - ND_TCHECK2(tptr[0], sizeof(struct in_addr)); - ND_PRINT((ndo, "%s", ipaddr_string(ndo, tptr))); - tlen -= (sizeof(struct in_addr)); - tptr += (sizeof(struct in_addr)); - } - break; - case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): - case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): - case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): - ND_TCHECK2(tptr[0], tlen); - ND_PRINT((ndo, "%s", isonsap_string(ndo, tptr, tlen))); - tptr += tlen; - tlen = 0; - break; - - case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST): - case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST): - case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST): - if (tlen < BGP_VPN_RD_LEN+1) { - ND_PRINT((ndo, "invalid len")); - tlen = 0; - } else { - ND_TCHECK2(tptr[0], tlen); - ND_PRINT((ndo, "RD: %s, %s", - bgp_vpn_rd_print(ndo, tptr), - isonsap_string(ndo, tptr+BGP_VPN_RD_LEN,tlen-BGP_VPN_RD_LEN))); - /* rfc986 mapped IPv4 address ? */ - if (tlen == BGP_VPN_RD_LEN + 4 + sizeof(struct in_addr) - && EXTRACT_32BITS(tptr+BGP_VPN_RD_LEN) == 0x47000601) - ND_PRINT((ndo, " = %s", ipaddr_string(ndo, tptr+BGP_VPN_RD_LEN+4))); - /* rfc1888 mapped IPv6 address ? */ - else if (tlen == BGP_VPN_RD_LEN + 3 + sizeof(struct in6_addr) - && EXTRACT_24BITS(tptr+BGP_VPN_RD_LEN) == 0x350000) - ND_PRINT((ndo, " = %s", ip6addr_string(ndo, tptr+BGP_VPN_RD_LEN+3))); - tptr += tlen; - tlen = 0; - } - break; - default: - ND_TCHECK2(tptr[0], tlen); - ND_PRINT((ndo, "no AFI %u/SAFI %u decoder", af, safi)); - if (ndo->ndo_vflag <= 1) - print_unknown_data(ndo, tptr, "\n\t ", tlen); - tptr += tlen; - tlen = 0; - goto done; - break; - } - } - } - ND_PRINT((ndo, ", nh-length: %u", nhlen)); - tptr += tlen; - - ND_TCHECK(tptr[0]); - snpa = tptr[0]; - tptr++; - - if (snpa) { - ND_PRINT((ndo, "\n\t %u SNPA", snpa)); - for (/*nothing*/; snpa > 0; snpa--) { - ND_TCHECK(tptr[0]); - ND_PRINT((ndo, "\n\t %d bytes", tptr[0])); - tptr += tptr[0] + 1; - } - } else { - ND_PRINT((ndo, ", no SNPA")); - } - - while (tptr < pptr + len) { - switch (af<<8 | safi) { - case (AFNUM_INET<<8 | SAFNUM_UNICAST): - case (AFNUM_INET<<8 | SAFNUM_MULTICAST): - case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST): - advance = decode_prefix4(ndo, tptr, len, buf, sizeof(buf)); - if (advance == -1) - ND_PRINT((ndo, "\n\t (illegal prefix length)")); - else if (advance == -2) - goto trunc; - else if (advance == -3) - break; /* bytes left, but not enough */ - else - ND_PRINT((ndo, "\n\t %s", buf)); - break; - case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): - advance = decode_labeled_prefix4(ndo, tptr, len, buf, sizeof(buf)); - if (advance == -1) - ND_PRINT((ndo, "\n\t (illegal prefix length)")); - else if (advance == -2) - goto trunc; - else if (advance == -3) - break; /* bytes left, but not enough */ - else - ND_PRINT((ndo, "\n\t %s", buf)); - break; - case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST): - case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST): - case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST): - advance = decode_labeled_vpn_prefix4(ndo, tptr, buf, sizeof(buf)); - if (advance == -1) - ND_PRINT((ndo, "\n\t (illegal prefix length)")); - else if (advance == -2) - goto trunc; - else - ND_PRINT((ndo, "\n\t %s", buf)); - break; - case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO): - advance = decode_rt_routing_info(ndo, tptr, buf, sizeof(buf)); - if (advance == -1) - ND_PRINT((ndo, "\n\t (illegal prefix length)")); - else if (advance == -2) - goto trunc; - else - ND_PRINT((ndo, "\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(ndo, tptr, buf, sizeof(buf)); - if (advance == -1) - ND_PRINT((ndo, "\n\t (illegal prefix length)")); - else if (advance == -2) - goto trunc; - else - ND_PRINT((ndo, "\n\t %s", buf)); - break; - - case (AFNUM_INET<<8 | SAFNUM_MDT): - advance = decode_mdt_vpn_nlri(ndo, tptr, buf, sizeof(buf)); - if (advance == -1) - ND_PRINT((ndo, "\n\t (illegal prefix length)")); - else if (advance == -2) - goto trunc; - else - ND_PRINT((ndo, "\n\t %s", buf)); - break; - case (AFNUM_INET6<<8 | SAFNUM_UNICAST): - case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): - case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): - advance = decode_prefix6(ndo, tptr, len, buf, sizeof(buf)); - if (advance == -1) - ND_PRINT((ndo, "\n\t (illegal prefix length)")); - else if (advance == -2) - goto trunc; - else if (advance == -3) - break; /* bytes left, but not enough */ - else - ND_PRINT((ndo, "\n\t %s", buf)); - break; - case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): - advance = decode_labeled_prefix6(ndo, tptr, len, buf, sizeof(buf)); - if (advance == -1) - ND_PRINT((ndo, "\n\t (illegal prefix length)")); - else if (advance == -2) - goto trunc; - else if (advance == -3) - break; /* bytes left, but not enough */ - else - ND_PRINT((ndo, "\n\t %s", buf)); - break; - case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST): - case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST): - case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST): - advance = decode_labeled_vpn_prefix6(ndo, tptr, buf, sizeof(buf)); - if (advance == -1) - ND_PRINT((ndo, "\n\t (illegal prefix length)")); - else if (advance == -2) - goto trunc; - else - ND_PRINT((ndo, "\n\t %s", buf)); - break; - case (AFNUM_VPLS<<8 | SAFNUM_VPLS): - case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): - case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): - case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): - advance = decode_labeled_vpn_l2(ndo, tptr, buf, sizeof(buf)); - if (advance == -1) - ND_PRINT((ndo, "\n\t (illegal length)")); - else if (advance == -2) - goto trunc; - else - ND_PRINT((ndo, "\n\t %s", buf)); - break; - case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): - case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): - case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): - advance = decode_clnp_prefix(ndo, tptr, buf, sizeof(buf)); - if (advance == -1) - ND_PRINT((ndo, "\n\t (illegal prefix length)")); - else if (advance == -2) - goto trunc; - else - ND_PRINT((ndo, "\n\t %s", buf)); - break; - case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST): - case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST): - case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST): - advance = decode_labeled_vpn_clnp_prefix(ndo, tptr, buf, sizeof(buf)); - if (advance == -1) - ND_PRINT((ndo, "\n\t (illegal prefix length)")); - else if (advance == -2) - goto trunc; - else - ND_PRINT((ndo, "\n\t %s", buf)); - break; - default: - ND_TCHECK2(*tptr,tlen); - ND_PRINT((ndo, "\n\t no AFI %u / SAFI %u decoder", af, safi)); - if (ndo->ndo_vflag <= 1) - print_unknown_data(ndo, tptr, "\n\t ", tlen); - advance = 0; - tptr = pptr + len; - break; - } - if (advance < 0) - break; - tptr += advance; - } - done: - break; - - case BGPTYPE_MP_UNREACH_NLRI: - ND_TCHECK2(tptr[0], BGP_MP_NLRI_MINSIZE); - af = EXTRACT_16BITS(tptr); - safi = tptr[2]; - - ND_PRINT((ndo, "\n\t AFI: %s (%u), %sSAFI: %s (%u)", - tok2str(af_values, "Unknown AFI", af), - af, - (safi>128) ? "vendor specific " : "", /* 128 is meanwhile wellknown */ - tok2str(bgp_safi_values, "Unknown SAFI", safi), - safi)); - - if (len == BGP_MP_NLRI_MINSIZE) - ND_PRINT((ndo, "\n\t End-of-Rib Marker (empty NLRI)")); - - tptr += 3; - - while (tptr < pptr + len) { - switch (af<<8 | safi) { - case (AFNUM_INET<<8 | SAFNUM_UNICAST): - case (AFNUM_INET<<8 | SAFNUM_MULTICAST): - case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST): - advance = decode_prefix4(ndo, tptr, len, buf, sizeof(buf)); - if (advance == -1) - ND_PRINT((ndo, "\n\t (illegal prefix length)")); - else if (advance == -2) - goto trunc; - else if (advance == -3) - break; /* bytes left, but not enough */ - else - ND_PRINT((ndo, "\n\t %s", buf)); - break; - case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): - advance = decode_labeled_prefix4(ndo, tptr, len, buf, sizeof(buf)); - if (advance == -1) - ND_PRINT((ndo, "\n\t (illegal prefix length)")); - else if (advance == -2) - goto trunc; - else if (advance == -3) - break; /* bytes left, but not enough */ - else - ND_PRINT((ndo, "\n\t %s", buf)); - break; - case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST): - case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST): - case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST): - advance = decode_labeled_vpn_prefix4(ndo, tptr, buf, sizeof(buf)); - if (advance == -1) - ND_PRINT((ndo, "\n\t (illegal prefix length)")); - else if (advance == -2) - goto trunc; - else - ND_PRINT((ndo, "\n\t %s", buf)); - break; - case (AFNUM_INET6<<8 | SAFNUM_UNICAST): - case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): - case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): - advance = decode_prefix6(ndo, tptr, len, buf, sizeof(buf)); - if (advance == -1) - ND_PRINT((ndo, "\n\t (illegal prefix length)")); - else if (advance == -2) - goto trunc; - else if (advance == -3) - break; /* bytes left, but not enough */ - else - ND_PRINT((ndo, "\n\t %s", buf)); - break; - case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): - advance = decode_labeled_prefix6(ndo, tptr, len, buf, sizeof(buf)); - if (advance == -1) - ND_PRINT((ndo, "\n\t (illegal prefix length)")); - else if (advance == -2) - goto trunc; - else if (advance == -3) - break; /* bytes left, but not enough */ - else - ND_PRINT((ndo, "\n\t %s", buf)); - break; - case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST): - case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST): - case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST): - advance = decode_labeled_vpn_prefix6(ndo, tptr, buf, sizeof(buf)); - if (advance == -1) - ND_PRINT((ndo, "\n\t (illegal prefix length)")); - else if (advance == -2) - goto trunc; - else - ND_PRINT((ndo, "\n\t %s", buf)); - break; - case (AFNUM_VPLS<<8 | SAFNUM_VPLS): - case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): - case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): - case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): - advance = decode_labeled_vpn_l2(ndo, tptr, buf, sizeof(buf)); - if (advance == -1) - ND_PRINT((ndo, "\n\t (illegal length)")); - else if (advance == -2) - goto trunc; - else - ND_PRINT((ndo, "\n\t %s", buf)); - break; - case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): - case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): - case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): - advance = decode_clnp_prefix(ndo, tptr, buf, sizeof(buf)); - if (advance == -1) - ND_PRINT((ndo, "\n\t (illegal prefix length)")); - else if (advance == -2) - goto trunc; - else - ND_PRINT((ndo, "\n\t %s", buf)); - break; - case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST): - case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST): - case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST): - advance = decode_labeled_vpn_clnp_prefix(ndo, tptr, buf, sizeof(buf)); - if (advance == -1) - ND_PRINT((ndo, "\n\t (illegal prefix length)")); - else if (advance == -2) - goto trunc; - else - ND_PRINT((ndo, "\n\t %s", buf)); - break; - case (AFNUM_INET<<8 | SAFNUM_MDT): - advance = decode_mdt_vpn_nlri(ndo, tptr, buf, sizeof(buf)); - if (advance == -1) - ND_PRINT((ndo, "\n\t (illegal prefix length)")); - else if (advance == -2) - goto trunc; - else - ND_PRINT((ndo, "\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(ndo, tptr, buf, sizeof(buf)); - if (advance == -1) - ND_PRINT((ndo, "\n\t (illegal prefix length)")); - else if (advance == -2) - goto trunc; - else - ND_PRINT((ndo, "\n\t %s", buf)); - break; - default: - ND_TCHECK2(*(tptr-3),tlen); - ND_PRINT((ndo, "no AFI %u / SAFI %u decoder", af, safi)); - if (ndo->ndo_vflag <= 1) - print_unknown_data(ndo, tptr-3, "\n\t ", tlen); - advance = 0; - tptr = pptr + len; - break; - } - if (advance < 0) - break; - tptr += advance; - } - break; - case BGPTYPE_EXTD_COMMUNITIES: - if (len % 8) { - ND_PRINT((ndo, "invalid len")); - break; - } - while (tlen>0) { - uint16_t extd_comm; - - ND_TCHECK2(tptr[0], 2); - extd_comm=EXTRACT_16BITS(tptr); - - ND_PRINT((ndo, "\n\t %s (0x%04x), Flags [%s]", - tok2str(bgp_extd_comm_subtype_values, - "unknown extd community typecode", - extd_comm), - extd_comm, - bittok2str(bgp_extd_comm_flag_values, "none", extd_comm))); - - ND_TCHECK2(*(tptr+2), 6); - switch(extd_comm) { - case BGP_EXT_COM_RT_0: - case BGP_EXT_COM_RO_0: - case BGP_EXT_COM_L2VPN_RT_0: - ND_PRINT((ndo, ": %u:%u (= %s)", - EXTRACT_16BITS(tptr+2), - EXTRACT_32BITS(tptr+4), - ipaddr_string(ndo, tptr+4))); - 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: - ND_PRINT((ndo, ": %s:%u", - ipaddr_string(ndo, tptr+2), - EXTRACT_16BITS(tptr+6))); - break; - case BGP_EXT_COM_RT_2: - case BGP_EXT_COM_RO_2: - ND_PRINT((ndo, ": %s:%u", - as_printf(ndo, astostr, sizeof(astostr), - EXTRACT_32BITS(tptr+2)), EXTRACT_16BITS(tptr+6))); - break; - case BGP_EXT_COM_LINKBAND: - bw.i = EXTRACT_32BITS(tptr+2); - ND_PRINT((ndo, ": bandwidth: %.3f Mbps", - bw.f*8/1000000)); - break; - case BGP_EXT_COM_VPN_ORIGIN: - case BGP_EXT_COM_VPN_ORIGIN2: - case BGP_EXT_COM_VPN_ORIGIN3: - case BGP_EXT_COM_VPN_ORIGIN4: - case BGP_EXT_COM_OSPF_RID: - case BGP_EXT_COM_OSPF_RID2: - ND_PRINT((ndo, "%s", ipaddr_string(ndo, tptr+2))); - break; - case BGP_EXT_COM_OSPF_RTYPE: - case BGP_EXT_COM_OSPF_RTYPE2: - ND_PRINT((ndo, ": area:%s, router-type:%s, metric-type:%s%s", - ipaddr_string(ndo, tptr+2), - tok2str(bgp_extd_comm_ospf_rtype_values, - "unknown (0x%02x)", - *(tptr+6)), - (*(tptr+7) & BGP_OSPF_RTYPE_METRIC_TYPE) ? "E2" : "", - ((*(tptr+6) == BGP_OSPF_RTYPE_EXT) || (*(tptr+6) == BGP_OSPF_RTYPE_NSSA)) ? "E1" : "")); - break; - case BGP_EXT_COM_L2INFO: - ND_PRINT((ndo, ": %s Control Flags [0x%02x]:MTU %u", - tok2str(l2vpn_encaps_values, - "unknown encaps", - *(tptr+2)), - *(tptr+3), - EXTRACT_16BITS(tptr+4))); - break; - case BGP_EXT_COM_SOURCE_AS: - ND_PRINT((ndo, ": AS %u", EXTRACT_16BITS(tptr+2))); - break; - default: - ND_TCHECK2(*tptr,8); - print_unknown_data(ndo, tptr, "\n\t ", 8); - break; - } - tlen -=8; - tptr +=8; + advance = decode_prefix6(ndo, tptr, len, buf, buflen); + if (advance == -1) + ND_PRINT("\n\t (illegal prefix length)"); + else if (advance == -2) + break; /* bytes left, but not enough */ + else + ND_PRINT("\n\t %s", buf); + if (add_path6) { + ND_PRINT(" Path Id: %u", path_id); + advance += 4; } break; + case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): + advance = decode_labeled_prefix6(ndo, tptr, len, buf, buflen); + if (advance == -1) + ND_PRINT("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else if (advance == -3) + break; /* bytes left, but not enough */ + else + ND_PRINT("\n\t %s", buf); + break; + case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST): + advance = decode_labeled_vpn_prefix6(ndo, tptr, buf, buflen); + if (advance == -1) + ND_PRINT("\n\t (illegal prefix length)"); + else + ND_PRINT("\n\t %s", buf); + break; + case (AFNUM_VPLS<<8 | SAFNUM_VPLS): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): + advance = decode_labeled_vpn_l2(ndo, tptr, buf, buflen); + if (advance == -1) + ND_PRINT("\n\t (illegal length)"); + else if (advance == -2) + goto trunc; + else + ND_PRINT("\n\t %s", buf); + break; + case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): + case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): + case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): + advance = decode_clnp_prefix(ndo, tptr, buf, buflen); + if (advance == -1) + ND_PRINT("\n\t (illegal prefix length)"); + else + ND_PRINT("\n\t %s", buf); + break; + case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST): + advance = decode_labeled_vpn_clnp_prefix(ndo, tptr, buf, buflen); + if (advance == -1) + ND_PRINT("\n\t (illegal prefix length)"); + else + ND_PRINT("\n\t %s", buf); + break; + default: + /* + * This should not happen, we should have been protected + * by bgp_mp_af_print()'s return value. + */ + ND_PRINT("\n\t ERROR: no AFI %u / SAFI %u decoder", af, safi); + advance = -4; + break; + } + return advance; +trunc: /* we rely on the caller to recognize -2 return value */ + return -2; +} - case BGPTYPE_PMSI_TUNNEL: - { - uint8_t tunnel_type, flags; - - ND_TCHECK2(tptr[0], 5); - tunnel_type = *(tptr+1); - flags = *tptr; - tlen = len; - - ND_PRINT((ndo, "\n\t Tunnel-type %s (%u), Flags [%s], MPLS Label %u", - tok2str(bgp_pmsi_tunnel_values, "Unknown", tunnel_type), - tunnel_type, - bittok2str(bgp_pmsi_flag_values, "none", flags), - EXTRACT_24BITS(tptr+2)>>4)); - - tptr +=5; - tlen -= 5; - - switch (tunnel_type) { - case BGP_PMSI_TUNNEL_PIM_SM: /* fall through */ - case BGP_PMSI_TUNNEL_PIM_BIDIR: - ND_TCHECK2(tptr[0], 8); - ND_PRINT((ndo, "\n\t Sender %s, P-Group %s", - ipaddr_string(ndo, tptr), - ipaddr_string(ndo, tptr+4))); - break; +static int +bgp_attr_print(netdissect_options *ndo, + uint8_t atype, const u_char *pptr, u_int len, + const unsigned attr_set_level) +{ + /* allocate space for the largest possible string */ + char astostr[AS_STR_SIZE]; + u_int i; + uint16_t af; + uint8_t safi, snpa, nhlen; + int advance; + u_int tlen; + const u_char *tptr; + char buf[MAXHOSTNAMELEN + 100]; + u_int as_size; + int add_path4, add_path6; + int ret; + + tptr = pptr; + tlen = len; + + switch (atype) { + case BGPTYPE_ORIGIN: + if (len != 1) + ND_PRINT("invalid len"); + else { + ND_PRINT("%s", tok2str(bgp_origin_values, + "Unknown Origin Typecode", + GET_U_1(tptr))); + } + break; + + /* + * Process AS4 byte path and AS2 byte path attributes here. + */ + case BGPTYPE_AS4_PATH: + case BGPTYPE_AS_PATH: + if (len % 2) { + ND_PRINT("invalid len"); + break; + } + if (!len) { + ND_PRINT("empty"); + break; + } + + /* + * BGP updates exchanged between New speakers that support 4 + * byte AS, ASs are always encoded in 4 bytes. There is no + * definitive way to find this, just by the packet's + * contents. So, check for packet's TLV's sanity assuming + * 2 bytes first, and it does not pass, assume that ASs are + * encoded in 4 bytes format and move on. + */ + as_size = bgp_attr_get_as_size(ndo, atype, pptr, len); + + while (tptr < pptr + len) { + ND_PRINT("%s", tok2str(bgp_as_path_segment_open_values, + "?", GET_U_1(tptr))); + for (i = 0; i < GET_U_1(tptr + 1) * as_size; i += as_size) { + ND_TCHECK_LEN(tptr + 2 + i, as_size); + ND_PRINT("%s ", + as_printf(ndo, astostr, sizeof(astostr), + as_size == 2 ? + GET_BE_U_2(tptr + i + 2) : + GET_BE_U_4(tptr + i + 2))); + } + ND_PRINT("%s", tok2str(bgp_as_path_segment_close_values, + "?", GET_U_1(tptr))); + tptr += 2 + GET_U_1(tptr + 1) * as_size; + } + break; + case BGPTYPE_NEXT_HOP: + if (len != 4) + ND_PRINT("invalid len"); + else { + ND_PRINT("%s", GET_IPADDR_STRING(tptr)); + } + break; + case BGPTYPE_MULTI_EXIT_DISC: + case BGPTYPE_LOCAL_PREF: + if (len != 4) + ND_PRINT("invalid len"); + else { + ND_PRINT("%u", GET_BE_U_4(tptr)); + } + break; + case BGPTYPE_ATOMIC_AGGREGATE: + if (len != 0) + ND_PRINT("invalid len"); + break; + 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) { + ND_PRINT("invalid len"); + break; + } + ND_TCHECK_LEN(tptr, len); + if (len == 6) { + ND_PRINT(" AS #%s, origin %s", + as_printf(ndo, astostr, sizeof(astostr), GET_BE_U_2(tptr)), + GET_IPADDR_STRING(tptr + 2)); + } else { + ND_PRINT(" AS #%s, origin %s", + as_printf(ndo, astostr, sizeof(astostr), + GET_BE_U_4(tptr)), GET_IPADDR_STRING(tptr + 4)); + } + break; + case BGPTYPE_AGGREGATOR4: + if (len != 8) { + ND_PRINT("invalid len"); + break; + } + ND_PRINT(" AS #%s, origin %s", + as_printf(ndo, astostr, sizeof(astostr), GET_BE_U_4(tptr)), + GET_IPADDR_STRING(tptr + 4)); + break; + case BGPTYPE_COMMUNITIES: + if (len % 4) { + ND_PRINT("invalid len"); + break; + } + while (tlen != 0) { + uint32_t comm; + ND_TCHECK_4(tptr); + if (tlen < 4) + goto trunc; + comm = GET_BE_U_4(tptr); + switch (comm) { + case BGP_COMMUNITY_NO_EXPORT: + ND_PRINT(" NO_EXPORT"); + break; + case BGP_COMMUNITY_NO_ADVERT: + ND_PRINT(" NO_ADVERTISE"); + break; + case BGP_COMMUNITY_NO_EXPORT_SUBCONFED: + ND_PRINT(" NO_EXPORT_SUBCONFED"); + break; + default: + ND_PRINT("%u:%u%s", + (comm >> 16) & 0xffff, + comm & 0xffff, + (tlen>4) ? ", " : ""); + break; + } + tlen -=4; + tptr +=4; + } + break; + case BGPTYPE_ORIGINATOR_ID: + if (len != 4) { + ND_PRINT("invalid len"); + break; + } + ND_PRINT("%s",GET_IPADDR_STRING(tptr)); + break; + case BGPTYPE_CLUSTER_LIST: + if (len % 4) { + ND_PRINT("invalid len"); + break; + } + while (tlen != 0) { + if (tlen < 4) + goto trunc; + ND_PRINT("%s%s", + GET_IPADDR_STRING(tptr), + (tlen>4) ? ", " : ""); + tlen -=4; + tptr +=4; + } + break; + case BGPTYPE_MP_REACH_NLRI: + ND_TCHECK_3(tptr); + if (tlen < 3) + goto trunc; + ret = bgp_mp_af_print(ndo, tptr, tlen, &af, &safi); + if (ret == -2) + goto trunc; + if (ret < 0) + break; - case BGP_PMSI_TUNNEL_PIM_SSM: - ND_TCHECK2(tptr[0], 8); - ND_PRINT((ndo, "\n\t Root-Node %s, P-Group %s", - ipaddr_string(ndo, tptr), - ipaddr_string(ndo, tptr+4))); + tptr += 3; + tlen -= 3; + + ND_TCHECK_1(tptr); + if (tlen < 1) + goto trunc; + nhlen = GET_U_1(tptr); + tptr++; + tlen--; + + if (nhlen) { + u_int nnh = 0; + uint8_t tnhlen = nhlen; + if (tlen < tnhlen) + goto trunc; + ND_PRINT("\n\t nexthop: "); + while (tnhlen != 0) { + if (nnh++ > 0) { + ND_PRINT(", " ); + } + switch(af<<8 | safi) { + case (AFNUM_INET<<8 | SAFNUM_UNICAST): + case (AFNUM_INET<<8 | SAFNUM_MULTICAST): + case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST): + case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): + case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO): + case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): + case (AFNUM_INET<<8 | SAFNUM_MDT): + if (tnhlen < sizeof(nd_ipv4)) { + ND_PRINT("invalid len"); + tptr += tnhlen; + tlen -= tnhlen; + tnhlen = 0; + } else { + ND_PRINT("%s",GET_IPADDR_STRING(tptr)); + tptr += sizeof(nd_ipv4); + tnhlen -= sizeof(nd_ipv4); + tlen -= sizeof(nd_ipv4); + } + break; + case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST): + if (tnhlen < sizeof(nd_ipv4)+BGP_VPN_RD_LEN) { + ND_PRINT("invalid len"); + tptr += tnhlen; + tlen -= tnhlen; + tnhlen = 0; + } else { + ND_PRINT("RD: %s, %s", + bgp_vpn_rd_print(ndo, tptr), + GET_IPADDR_STRING(tptr+BGP_VPN_RD_LEN)); + tptr += (sizeof(nd_ipv4)+BGP_VPN_RD_LEN); + tlen -= (sizeof(nd_ipv4)+BGP_VPN_RD_LEN); + tnhlen -= (sizeof(nd_ipv4)+BGP_VPN_RD_LEN); + } break; - case BGP_PMSI_TUNNEL_INGRESS: - ND_TCHECK2(tptr[0], 4); - ND_PRINT((ndo, "\n\t Tunnel-Endpoint %s", - ipaddr_string(ndo, tptr))); + case (AFNUM_INET6<<8 | SAFNUM_UNICAST): + case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): + case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): + case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): + if (tnhlen < sizeof(nd_ipv6)) { + ND_PRINT("invalid len"); + tptr += tnhlen; + tlen -= tnhlen; + tnhlen = 0; + } else { + ND_PRINT("%s", GET_IP6ADDR_STRING(tptr)); + tptr += sizeof(nd_ipv6); + tlen -= sizeof(nd_ipv6); + tnhlen -= sizeof(nd_ipv6); + } + break; + case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST): + if (tnhlen < sizeof(nd_ipv6)+BGP_VPN_RD_LEN) { + ND_PRINT("invalid len"); + tptr += tnhlen; + tlen -= tnhlen; + tnhlen = 0; + } else { + ND_PRINT("RD: %s, %s", + bgp_vpn_rd_print(ndo, tptr), + GET_IP6ADDR_STRING(tptr+BGP_VPN_RD_LEN)); + tptr += (sizeof(nd_ipv6)+BGP_VPN_RD_LEN); + tlen -= (sizeof(nd_ipv6)+BGP_VPN_RD_LEN); + tnhlen -= (sizeof(nd_ipv6)+BGP_VPN_RD_LEN); + } break; - case BGP_PMSI_TUNNEL_LDP_P2MP: /* fall through */ - case BGP_PMSI_TUNNEL_LDP_MP2MP: - ND_TCHECK2(tptr[0], 8); - ND_PRINT((ndo, "\n\t Root-Node %s, LSP-ID 0x%08x", - ipaddr_string(ndo, tptr), - EXTRACT_32BITS(tptr+4))); + case (AFNUM_VPLS<<8 | SAFNUM_VPLS): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): + if (tnhlen < sizeof(nd_ipv4)) { + ND_PRINT("invalid len"); + tptr += tnhlen; + tlen -= tnhlen; + tnhlen = 0; + } else { + ND_PRINT("%s", GET_IPADDR_STRING(tptr)); + tptr += (sizeof(nd_ipv4)); + tlen -= (sizeof(nd_ipv4)); + tnhlen -= (sizeof(nd_ipv4)); + } break; - case BGP_PMSI_TUNNEL_RSVP_P2MP: - ND_TCHECK2(tptr[0], 8); - ND_PRINT((ndo, "\n\t Extended-Tunnel-ID %s, P2MP-ID 0x%08x", - ipaddr_string(ndo, tptr), - EXTRACT_32BITS(tptr+4))); + case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): + case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): + case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): + ND_PRINT("%s", GET_ISONSAP_STRING(tptr, tnhlen)); + tptr += tnhlen; + tlen -= tnhlen; + tnhlen = 0; break; - default: - if (ndo->ndo_vflag <= 1) { - print_unknown_data(ndo, tptr, "\n\t ", tlen); + + case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST): + if (tnhlen < BGP_VPN_RD_LEN+1) { + ND_PRINT("invalid len"); + tptr += tnhlen; + tlen -= tnhlen; + tnhlen = 0; + } else { + ND_TCHECK_LEN(tptr, tnhlen); + ND_PRINT("RD: %s, %s", + bgp_vpn_rd_print(ndo, tptr), + GET_ISONSAP_STRING(tptr+BGP_VPN_RD_LEN,tnhlen-BGP_VPN_RD_LEN)); + /* rfc986 mapped IPv4 address ? */ + if (GET_BE_U_4(tptr + BGP_VPN_RD_LEN) == 0x47000601) + ND_PRINT(" = %s", GET_IPADDR_STRING(tptr+BGP_VPN_RD_LEN+4)); + /* rfc1888 mapped IPv6 address ? */ + else if (GET_BE_U_3(tptr + BGP_VPN_RD_LEN) == 0x350000) + ND_PRINT(" = %s", GET_IP6ADDR_STRING(tptr+BGP_VPN_RD_LEN+3)); + tptr += tnhlen; + tlen -= tnhlen; + tnhlen = 0; } + break; + default: + /* + * bgp_mp_af_print() should have saved us from + * an unsupported AFI/SAFI. + */ + ND_PRINT("ERROR: no AFI %u/SAFI %u nexthop decoder", af, safi); + tptr += tnhlen; + tlen -= tnhlen; + tnhlen = 0; + goto done; + break; } + } + } + ND_PRINT(", nh-length: %u", nhlen); + + /* As per RFC 2858; this is reserved in RFC 4760 */ + if (tlen < 1) + goto trunc; + snpa = GET_U_1(tptr); + tptr++; + tlen--; + + if (snpa) { + ND_PRINT("\n\t %u SNPA", snpa); + for (/*nothing*/; snpa != 0; snpa--) { + uint8_t snpalen; + if (tlen < 1) + goto trunc; + snpalen = GET_U_1(tptr); + ND_PRINT("\n\t %u bytes", snpalen); + tptr++; + tlen--; + if (tlen < snpalen) + goto trunc; + ND_TCHECK_LEN(tptr, snpalen); + tptr += snpalen; + tlen -= snpalen; + } + } else { + ND_PRINT(", no SNPA"); + } + + add_path4 = check_add_path(ndo, tptr, (len-ND_BYTES_BETWEEN(tptr, pptr)), 32); + add_path6 = check_add_path(ndo, tptr, (len-ND_BYTES_BETWEEN(tptr, pptr)), 128); + + while (tptr < pptr + len) { + advance = bgp_nlri_print(ndo, af, safi, tptr, len, buf, sizeof(buf), + add_path4, add_path6); + if (advance == -2) + goto trunc; + if (advance < 0) + break; + tptr += advance; + } + break; + + case BGPTYPE_MP_UNREACH_NLRI: + ND_TCHECK_LEN(tptr, BGP_MP_NLRI_MINSIZE); + ret = bgp_mp_af_print(ndo, tptr, tlen, &af, &safi); + if (ret == -2) + goto trunc; + if (ret < 0) + break; + + if (len == BGP_MP_NLRI_MINSIZE) + ND_PRINT("\n\t End-of-Rib Marker (empty NLRI)"); + + tptr += 3; + + add_path4 = check_add_path(ndo, tptr, (len-ND_BYTES_BETWEEN(tptr, pptr)), 32); + add_path6 = check_add_path(ndo, tptr, (len-ND_BYTES_BETWEEN(tptr, pptr)), 128); + + while (tptr < pptr + len) { + advance = bgp_nlri_print(ndo, af, safi, tptr, len, buf, sizeof(buf), + add_path4, add_path6); + if (advance == -2) + goto trunc; + if (advance < 0) break; + tptr += advance; + } + break; + case BGPTYPE_EXTD_COMMUNITIES: + if (len % 8) { + ND_PRINT("invalid len"); + break; + } + while (tlen != 0) { + uint16_t extd_comm; + + ND_TCHECK_2(tptr); + if (tlen < 2) + goto trunc; + extd_comm=GET_BE_U_2(tptr); + + ND_PRINT("\n\t %s (0x%04x), Flags [%s]", + tok2str(bgp_extd_comm_subtype_values, + "unknown extd community typecode", + extd_comm), + extd_comm, + bittok2str(bgp_extd_comm_flag_values, "none", extd_comm)); + + ND_TCHECK_8(tptr); + if (tlen < 8) + goto trunc; + ND_PRINT(": "); + bgp_extended_community_print(ndo, tptr); + tlen -= 8; + tptr += 8; } - case BGPTYPE_AIGP: - { - uint8_t type; - uint16_t length; + break; - tlen = len; + case BGPTYPE_PMSI_TUNNEL: + { + uint8_t tunnel_type, flags; - while (tlen >= 3) { + ND_TCHECK_5(tptr); + if (tlen < 5) + goto trunc; + flags = GET_U_1(tptr); + tunnel_type = GET_U_1(tptr + 1); + + ND_PRINT("\n\t Tunnel-type %s (%u), Flags [%s], MPLS Label %u", + tok2str(bgp_pmsi_tunnel_values, "Unknown", tunnel_type), + tunnel_type, + bittok2str(bgp_pmsi_flag_values, "none", flags), + GET_BE_U_3(tptr + 2)>>4); + + tptr +=5; + tlen -= 5; + + switch (tunnel_type) { + case BGP_PMSI_TUNNEL_PIM_SM: /* fall through */ + case BGP_PMSI_TUNNEL_PIM_BIDIR: + ND_PRINT("\n\t Sender %s, P-Group %s", + GET_IPADDR_STRING(tptr), + GET_IPADDR_STRING(tptr+4)); + break; - ND_TCHECK2(tptr[0], 3); + case BGP_PMSI_TUNNEL_PIM_SSM: + ND_PRINT("\n\t Root-Node %s, P-Group %s", + GET_IPADDR_STRING(tptr), + GET_IPADDR_STRING(tptr+4)); + break; + case BGP_PMSI_TUNNEL_INGRESS: + ND_PRINT("\n\t Tunnel-Endpoint %s", + GET_IPADDR_STRING(tptr)); + break; + case BGP_PMSI_TUNNEL_LDP_P2MP: /* fall through */ + case BGP_PMSI_TUNNEL_LDP_MP2MP: + ND_PRINT("\n\t Root-Node %s, LSP-ID 0x%08x", + GET_IPADDR_STRING(tptr), + GET_BE_U_4(tptr + 4)); + break; + case BGP_PMSI_TUNNEL_RSVP_P2MP: + ND_PRINT("\n\t Extended-Tunnel-ID %s, P2MP-ID 0x%08x", + GET_IPADDR_STRING(tptr), + GET_BE_U_4(tptr + 4)); + break; + default: + if (ndo->ndo_vflag <= 1) { + print_unknown_data(ndo, tptr, "\n\t ", tlen); + } + } + break; + } + case BGPTYPE_AIGP: + { + uint8_t type; + uint16_t length; - type = *tptr; - length = EXTRACT_16BITS(tptr+1); - tptr += 3; - tlen -= 3; + while (tlen >= 3) { + type = GET_U_1(tptr); + length = GET_BE_U_2(tptr + 1); + tptr += 3; + tlen -= 3; - ND_PRINT((ndo, "\n\t %s TLV (%u), length %u", - tok2str(bgp_aigp_values, "Unknown", type), - type, length)); + ND_PRINT("\n\t %s TLV (%u), length %u", + tok2str(bgp_aigp_values, "Unknown", type), + type, length); - if (length < 3) - goto trunc; - length -= 3; + if (length < 3) + goto trunc; + length -= 3; - /* - * Check if we can read the TLV data. - */ - ND_TCHECK2(tptr[3], length); - - switch (type) { - - case BGP_AIGP_TLV: - if (length < 8) - goto trunc; - ND_PRINT((ndo, ", metric %" PRIu64, - EXTRACT_64BITS(tptr))); - break; - - default: - if (ndo->ndo_vflag <= 1) { - print_unknown_data(ndo, tptr,"\n\t ", length); - } - } - - tptr += length; - tlen -= length; - } - break; - } - case BGPTYPE_ATTR_SET: - ND_TCHECK2(tptr[0], 4); - if (len < 4) - goto trunc; - ND_PRINT((ndo, "\n\t Origin AS: %s", - as_printf(ndo, astostr, sizeof(astostr), EXTRACT_32BITS(tptr)))); - tptr+=4; - len -=4; - - while (len) { - u_int aflags, alenlen, alen; - - ND_TCHECK2(tptr[0], 2); - if (len < 2) - goto trunc; - aflags = *tptr; - atype = *(tptr + 1); - tptr += 2; - len -= 2; - alenlen = bgp_attr_lenlen(aflags, tptr); - ND_TCHECK2(tptr[0], alenlen); - if (len < alenlen) - goto trunc; - alen = bgp_attr_len(aflags, tptr); - tptr += alenlen; - len -= alenlen; - - ND_PRINT((ndo, "\n\t %s (%u), length: %u", - tok2str(bgp_attr_values, - "Unknown Attribute", atype), - atype, - alen)); - - if (aflags) { - ND_PRINT((ndo, ", Flags [%s%s%s%s", - aflags & 0x80 ? "O" : "", - aflags & 0x40 ? "T" : "", - aflags & 0x20 ? "P" : "", - aflags & 0x10 ? "E" : "")); - if (aflags & 0xf) - ND_PRINT((ndo, "+%x", aflags & 0xf)); - ND_PRINT((ndo, "]: ")); - } - /* The protocol encoding per se allows ATTR_SET to be nested as many times - * as the message can accommodate. This printer used to be able to recurse - * into ATTR_SET contents until the stack exhaustion, but now there is a - * limit on that (if live protocol exchange goes that many levels deep, - * something is probably wrong anyway). Feel free to refine this value if - * you can find the spec with respective normative text. - */ - if (attr_set_level == 10) - ND_PRINT((ndo, "(too many nested levels, not recursing)")); - else if (!bgp_attr_print(ndo, atype, tptr, alen, attr_set_level + 1)) - return 0; - tptr += alen; - len -= alen; - } + /* + * Check if we can read the TLV data. + */ + ND_TCHECK_LEN(tptr + 3, length); + if (tlen < length) + goto trunc; + + switch (type) { + + case BGP_AIGP_TLV: + if (length < 8) + goto trunc; + ND_PRINT(", metric %" PRIu64, + GET_BE_U_8(tptr)); break; - case BGPTYPE_LARGE_COMMUNITY: - if (len == 0 || len % 12) { - ND_PRINT((ndo, "invalid len")); - break; - } - ND_PRINT((ndo, "\n\t ")); - while (len > 0) { - ND_TCHECK2(*tptr, 12); - ND_PRINT((ndo, "%u:%u:%u%s", - EXTRACT_32BITS(tptr), - EXTRACT_32BITS(tptr + 4), - EXTRACT_32BITS(tptr + 8), - (len > 12) ? ", " : "")); - tptr += 12; - len -= 12; - } - break; - default: - ND_TCHECK2(*pptr,len); - ND_PRINT((ndo, "\n\t no Attribute %u decoder", atype)); /* we have no decoder for the attribute */ - if (ndo->ndo_vflag <= 1) - print_unknown_data(ndo, pptr, "\n\t ", len); + default: + if (ndo->ndo_vflag <= 1) { + print_unknown_data(ndo, tptr,"\n\t ", length); + } + } + + tptr += length; + tlen -= length; + } + break; + } + case BGPTYPE_ATTR_SET: + ND_TCHECK_4(tptr); + if (len < 4) + goto trunc; + ND_PRINT("\n\t Origin AS: %s", + as_printf(ndo, astostr, sizeof(astostr), GET_BE_U_4(tptr))); + tptr += 4; + len -= 4; + + while (len) { + u_int aflags, alenlen, alen; + + ND_TCHECK_2(tptr); + if (len < 2) { + ND_PRINT(" [path attr too short]"); + tptr += len; + break; + } + aflags = GET_U_1(tptr); + atype = GET_U_1(tptr + 1); + tptr += 2; + len -= 2; + alenlen = bgp_attr_lenlen(aflags, tptr); + ND_TCHECK_LEN(tptr, alenlen); + if (len < alenlen) { + ND_PRINT(" [path attr too short]"); + tptr += len; + break; + } + alen = bgp_attr_len(aflags, tptr); + tptr += alenlen; + len -= alenlen; + + ND_PRINT("\n\t %s (%u), length: %u", + tok2str(bgp_attr_values, + "Unknown Attribute", atype), + atype, + alen); + + if (aflags) { + ND_PRINT(", Flags [%s%s%s%s", + aflags & 0x80 ? "O" : "", + aflags & 0x40 ? "T" : "", + aflags & 0x20 ? "P" : "", + aflags & 0x10 ? "E" : ""); + if (aflags & 0xf) + ND_PRINT("+%x", aflags & 0xf); + ND_PRINT("]"); + } + ND_PRINT(": "); + if (len < alen) { + ND_PRINT(" [path attr too short]"); + tptr += len; + break; + } + /* + * The protocol encoding per se allows ATTR_SET to be nested + * as many times as the message can accommodate. This printer + * used to be able to recurse into ATTR_SET contents until the + * stack exhaustion, but now there is a limit on that (if live + * protocol exchange goes that many levels deep, something is + * probably wrong anyway). Feel free to refine this value if + * you can find the spec with respective normative text. + */ + if (attr_set_level == 10) + ND_PRINT("(too many nested levels, not recursing)"); + else if (!bgp_attr_print(ndo, atype, tptr, alen, attr_set_level + 1)) + return 0; + tptr += alen; + len -= alen; + } + break; + + case BGPTYPE_LARGE_COMMUNITY: + if (len == 0 || len % 12) { + ND_PRINT("invalid len"); break; - } - if (ndo->ndo_vflag > 1 && len) { /* omit zero length attributes*/ - ND_TCHECK2(*pptr,len); - print_unknown_data(ndo, pptr, "\n\t ", len); } - return 1; + ND_PRINT("\n\t "); + while (len != 0) { + ND_PRINT("%u:%u:%u%s", + GET_BE_U_4(tptr), + GET_BE_U_4(tptr + 4), + GET_BE_U_4(tptr + 8), + (len > 12) ? ", " : ""); + tptr += 12; + /* + * len will always be a multiple of 12, as per the above, + * so this will never underflow. + */ + len -= 12; + } + break; + default: + ND_TCHECK_LEN(pptr, len); + ND_PRINT("\n\t no Attribute %u decoder", atype); /* we have no decoder for the attribute */ + if (ndo->ndo_vflag <= 1) + print_unknown_data(ndo, pptr, "\n\t ", len); + break; + } +done: + if (ndo->ndo_vflag > 1 && len) { /* omit zero length attributes*/ + ND_TCHECK_LEN(pptr, len); + print_unknown_data(ndo, pptr, "\n\t ", len); + } + return 1; trunc: - return 0; + return 0; } static void bgp_capabilities_print(netdissect_options *ndo, - const u_char *opt, int caps_len) + const u_char *opt, u_int caps_len) { - int cap_type, cap_len, tcap_len, cap_offset; - int i = 0; - - while (i < caps_len) { - ND_TCHECK2(opt[i], BGP_CAP_HEADER_SIZE); - cap_type=opt[i]; - cap_len=opt[i+1]; - tcap_len=cap_len; - ND_PRINT((ndo, "\n\t %s (%u), length: %u", - tok2str(bgp_capcode_values, "Unknown", - cap_type), - cap_type, - cap_len)); - ND_TCHECK2(opt[i+2], cap_len); - switch (cap_type) { - case BGP_CAPCODE_MP: - /* AFI (16 bits), Reserved (8 bits), SAFI (8 bits) */ - ND_TCHECK_8BITS(opt + i + 5); - ND_PRINT((ndo, "\n\t\tAFI %s (%u), SAFI %s (%u)", - tok2str(af_values, "Unknown", - EXTRACT_16BITS(opt+i+2)), - EXTRACT_16BITS(opt+i+2), - tok2str(bgp_safi_values, "Unknown", - opt[i+5]), - opt[i+5])); - break; - case BGP_CAPCODE_RESTART: - /* Restart Flags (4 bits), Restart Time in seconds (12 bits) */ - ND_TCHECK_16BITS(opt + i + 2); - ND_PRINT((ndo, "\n\t\tRestart Flags: [%s], Restart Time %us", - ((opt[i+2])&0x80) ? "R" : "none", - EXTRACT_16BITS(opt+i+2)&0xfff)); - tcap_len-=2; - cap_offset=4; - while(tcap_len>=4) { - ND_TCHECK_8BITS(opt + i + cap_offset + 3); - ND_PRINT((ndo, "\n\t\t AFI %s (%u), SAFI %s (%u), Forwarding state preserved: %s", - tok2str(af_values,"Unknown", - EXTRACT_16BITS(opt+i+cap_offset)), - EXTRACT_16BITS(opt+i+cap_offset), - tok2str(bgp_safi_values,"Unknown", - opt[i+cap_offset+2]), - opt[i+cap_offset+2], - ((opt[i+cap_offset+3])&0x80) ? "yes" : "no" )); - tcap_len-=4; - cap_offset+=4; - } - break; - case BGP_CAPCODE_RR: - case BGP_CAPCODE_RR_CISCO: - break; - case BGP_CAPCODE_AS_NEW: - - /* - * Extract the 4 byte AS number encoded. - */ - if (cap_len == 4) { - ND_PRINT((ndo, "\n\t\t 4 Byte AS %s", - as_printf(ndo, astostr, sizeof(astostr), - EXTRACT_32BITS(opt + i + 2)))); - } - break; - case BGP_CAPCODE_ADD_PATH: - cap_offset=2; - if (tcap_len == 0) { - ND_PRINT((ndo, " (bogus)")); /* length */ - break; - } - while (tcap_len > 0) { - if (tcap_len < 4) { - ND_PRINT((ndo, "\n\t\t(invalid)")); - break; - } - ND_PRINT((ndo, "\n\t\tAFI %s (%u), SAFI %s (%u), Send/Receive: %s", - tok2str(af_values,"Unknown",EXTRACT_16BITS(opt+i+cap_offset)), - EXTRACT_16BITS(opt+i+cap_offset), - tok2str(bgp_safi_values,"Unknown",opt[i+cap_offset+2]), - opt[i+cap_offset+2], - tok2str(bgp_add_path_recvsend,"Bogus (0x%02x)",opt[i+cap_offset+3]) - )); - tcap_len-=4; - cap_offset+=4; - } - break; - default: - ND_PRINT((ndo, "\n\t\tno decoder for Capability %u", - cap_type)); - if (ndo->ndo_vflag <= 1) - print_unknown_data(ndo, &opt[i+2], "\n\t\t", cap_len); + /* allocate space for the largest possible string */ + char astostr[AS_STR_SIZE]; + u_int cap_type, cap_len, tcap_len, cap_offset; + u_int i = 0; + + while (i < caps_len) { + ND_TCHECK_LEN(opt + i, BGP_CAP_HEADER_SIZE); + cap_type=GET_U_1(opt + i); + cap_len=GET_U_1(opt + i + 1); + ND_PRINT("\n\t %s (%u), length: %u", + tok2str(bgp_capcode_values, "Unknown", cap_type), + cap_type, + cap_len); + ND_TCHECK_LEN(opt + 2 + i, cap_len); + switch (cap_type) { + case BGP_CAPCODE_MP: + /* AFI (16 bits), Reserved (8 bits), SAFI (8 bits) */ + if (cap_len < 4) { + ND_PRINT(" (too short, < 4)"); + return; + } + ND_PRINT("\n\t\tAFI %s (%u), SAFI %s (%u)", + tok2str(af_values, "Unknown", GET_BE_U_2(opt + i + 2)), + GET_BE_U_2(opt + i + 2), + tok2str(bgp_safi_values, "Unknown", GET_U_1(opt + i + 5)), + GET_U_1(opt + i + 5)); + break; + case BGP_CAPCODE_ML: + cap_offset = 2; + tcap_len = cap_len; + while (tcap_len >= 4) { + ND_PRINT( "\n\t\tAFI %s (%u), SAFI %s (%u), Count: %u", + tok2str(af_values, "Unknown", + GET_BE_U_2(opt + i + cap_offset)), + GET_BE_U_2(opt + i + cap_offset), + tok2str(bgp_safi_values, "Unknown", + GET_U_1(opt + i + cap_offset + 2)), + GET_U_1(opt + i + cap_offset + 2), + GET_U_1(opt + i + cap_offset + 3)); + tcap_len -= 4; + cap_offset += 4; + } + break; + case BGP_CAPCODE_RESTART: + /* Restart Flags (4 bits), Restart Time in seconds (12 bits) */ + if (cap_len < 2) { + ND_PRINT(" (too short, < 2)"); + return; + } + tcap_len=cap_len; + ND_PRINT("\n\t\tRestart Flags: [%s], Restart Time %us", + ((GET_U_1(opt + i + 2))&0x80) ? "R" : "none", + GET_BE_U_2(opt + i + 2)&0xfff); + tcap_len-=2; + cap_offset=4; + while(tcap_len>=4) { + ND_PRINT("\n\t\t AFI %s (%u), SAFI %s (%u), Forwarding state preserved: %s", + tok2str(af_values,"Unknown", + GET_BE_U_2(opt + i + cap_offset)), + GET_BE_U_2(opt + i + cap_offset), + tok2str(bgp_safi_values,"Unknown", + GET_U_1(opt + i + cap_offset + 2)), + GET_U_1(opt + (i + cap_offset + 2)), + ((GET_U_1(opt + (i + cap_offset + 3)))&0x80) ? "yes" : "no" ); + tcap_len -= 4; + cap_offset += 4; + } + break; + case BGP_CAPCODE_RR: + case BGP_CAPCODE_LLGR: + case BGP_CAPCODE_RR_CISCO: + break; + case BGP_CAPCODE_AS_NEW: + /* + * Extract the 4 byte AS number encoded. + */ + if (cap_len < 4) { + ND_PRINT(" (too short, < 4)"); + return; + } + ND_PRINT("\n\t\t 4 Byte AS %s", + as_printf(ndo, astostr, sizeof(astostr), + GET_BE_U_4(opt + i + 2))); + break; + case BGP_CAPCODE_ADD_PATH: + if (cap_len == 0) { + ND_PRINT(" (bogus)"); /* length */ + break; + } + tcap_len=cap_len; + cap_offset=2; + while (tcap_len != 0) { + if (tcap_len < 4) { + nd_print_invalid(ndo); break; } - if (ndo->ndo_vflag > 1 && cap_len > 0) { - print_unknown_data(ndo, &opt[i+2], "\n\t\t", cap_len); - } - i += BGP_CAP_HEADER_SIZE + cap_len; + ND_PRINT("\n\t\tAFI %s (%u), SAFI %s (%u), Send/Receive: %s", + tok2str(af_values,"Unknown",GET_BE_U_2(opt + i + cap_offset)), + GET_BE_U_2(opt + i + cap_offset), + tok2str(bgp_safi_values,"Unknown",GET_U_1(opt + i + cap_offset + 2)), + GET_U_1(opt + (i + cap_offset + 2)), + tok2str(bgp_add_path_recvsend,"Bogus (0x%02x)",GET_U_1(opt + i + cap_offset + 3)) + ); + tcap_len -= 4; + cap_offset += 4; + } + break; + default: + ND_PRINT("\n\t\tno decoder for Capability %u", + cap_type); + if (ndo->ndo_vflag <= 1) + print_unknown_data(ndo, opt + i + 2, "\n\t\t", + cap_len); + break; } - return; + if (ndo->ndo_vflag > 1 && cap_len != 0) { + print_unknown_data(ndo, opt + i + 2, "\n\t\t", cap_len); + } + i += BGP_CAP_HEADER_SIZE + cap_len; + } + return; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); } static void bgp_open_print(netdissect_options *ndo, - const u_char *dat, int length) + const u_char *dat, u_int length) { - struct bgp_open bgpo; - struct bgp_opt bgpopt; - const u_char *opt; - int i; - - ND_TCHECK2(dat[0], BGP_OPEN_SIZE); - memcpy(&bgpo, dat, BGP_OPEN_SIZE); - - ND_PRINT((ndo, "\n\t Version %d, ", bgpo.bgpo_version)); - ND_PRINT((ndo, "my AS %s, ", - as_printf(ndo, astostr, sizeof(astostr), ntohs(bgpo.bgpo_myas)))); - ND_PRINT((ndo, "Holdtime %us, ", ntohs(bgpo.bgpo_holdtime))); - ND_PRINT((ndo, "ID %s", ipaddr_string(ndo, &bgpo.bgpo_id))); - ND_PRINT((ndo, "\n\t Optional parameters, length: %u", bgpo.bgpo_optlen)); - - /* some little sanity checking */ - if (length < bgpo.bgpo_optlen+BGP_OPEN_SIZE) - return; - - /* ugly! */ - opt = &((const struct bgp_open *)dat)->bgpo_optlen; - opt++; - - i = 0; - while (i < bgpo.bgpo_optlen) { - ND_TCHECK2(opt[i], BGP_OPT_SIZE); - memcpy(&bgpopt, &opt[i], BGP_OPT_SIZE); - if (i + 2 + bgpopt.bgpopt_len > bgpo.bgpo_optlen) { - ND_PRINT((ndo, "\n\t Option %d, length: %u", bgpopt.bgpopt_type, bgpopt.bgpopt_len)); - break; - } - - ND_PRINT((ndo, "\n\t Option %s (%u), length: %u", - tok2str(bgp_opt_values,"Unknown", - bgpopt.bgpopt_type), - bgpopt.bgpopt_type, - bgpopt.bgpopt_len)); - - /* now let's decode the options we know*/ - switch(bgpopt.bgpopt_type) { - - case BGP_OPT_CAP: - bgp_capabilities_print(ndo, &opt[i+BGP_OPT_SIZE], - bgpopt.bgpopt_len); - break; - - case BGP_OPT_AUTH: - default: - ND_PRINT((ndo, "\n\t no decoder for option %u", - bgpopt.bgpopt_type)); - break; - } - i += BGP_OPT_SIZE + bgpopt.bgpopt_len; - } - return; + /* allocate space for the largest possible string */ + char astostr[AS_STR_SIZE]; + const struct bgp_open *bgp_open_header; + u_int optslen; + const struct bgp_opt *bgpopt; + const u_char *opt; + u_int i; + + ND_TCHECK_LEN(dat, BGP_OPEN_SIZE); + if (length < BGP_OPEN_SIZE) + goto trunc; + + bgp_open_header = (const struct bgp_open *)dat; + + ND_PRINT("\n\t Version %u, ", + GET_U_1(bgp_open_header->bgpo_version)); + ND_PRINT("my AS %s, ", + as_printf(ndo, astostr, sizeof(astostr), GET_BE_U_2(bgp_open_header->bgpo_myas))); + ND_PRINT("Holdtime %us, ", + GET_BE_U_2(bgp_open_header->bgpo_holdtime)); + ND_PRINT("ID %s", GET_IPADDR_STRING(bgp_open_header->bgpo_id)); + optslen = GET_U_1(bgp_open_header->bgpo_optlen); + ND_PRINT("\n\t Optional parameters, length: %u", optslen); + + opt = dat + BGP_OPEN_SIZE; + length -= BGP_OPEN_SIZE; + + i = 0; + while (i < optslen) { + uint8_t opt_type, opt_len; + + ND_TCHECK_LEN(opt + i, BGP_OPT_SIZE); + if (length < BGP_OPT_SIZE + i) + goto trunc; + bgpopt = (const struct bgp_opt *)(opt + i); + opt_type = GET_U_1(bgpopt->bgpopt_type); + opt_len = GET_U_1(bgpopt->bgpopt_len); + if (BGP_OPT_SIZE + i + opt_len > optslen) { + ND_PRINT("\n\t Option %u, length: %u, goes past the end of the options", + opt_type, opt_len); + break; + } + + ND_PRINT("\n\t Option %s (%u), length: %u", + tok2str(bgp_opt_values,"Unknown",opt_type), + opt_type, + opt_len); + + /* now let's decode the options we know*/ + switch(opt_type) { + + case BGP_OPT_CAP: + bgp_capabilities_print(ndo, opt + BGP_OPT_SIZE + i, + opt_len); + break; + + case BGP_OPT_AUTH: + default: + ND_PRINT("\n\t no decoder for option %u", + opt_type); + break; + } + i += BGP_OPT_SIZE + opt_len; + } + return; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); } static void bgp_update_print(netdissect_options *ndo, - const u_char *dat, int length) + const u_char *dat, u_int length) { - struct bgp bgp; - const u_char *p; - int withdrawn_routes_len; - int len; - int i; - - ND_TCHECK2(dat[0], BGP_SIZE); - if (length < BGP_SIZE) - goto trunc; - memcpy(&bgp, dat, BGP_SIZE); - p = dat + BGP_SIZE; /*XXX*/ - length -= BGP_SIZE; - - /* Unfeasible routes */ - ND_TCHECK2(p[0], 2); - if (length < 2) - goto trunc; - withdrawn_routes_len = EXTRACT_16BITS(p); - p += 2; - length -= 2; - if (withdrawn_routes_len) { - /* - * Without keeping state from the original NLRI message, - * it's not possible to tell if this a v4 or v6 route, - * so only try to decode it if we're not v6 enabled. - */ - ND_TCHECK2(p[0], withdrawn_routes_len); - if (length < withdrawn_routes_len) - goto trunc; - ND_PRINT((ndo, "\n\t Withdrawn routes: %d bytes", withdrawn_routes_len)); - p += withdrawn_routes_len; - length -= withdrawn_routes_len; - } - - ND_TCHECK2(p[0], 2); - if (length < 2) - goto trunc; - len = EXTRACT_16BITS(p); - p += 2; - length -= 2; - - if (withdrawn_routes_len == 0 && len == 0 && length == 0) { - /* No withdrawn routes, no path attributes, no NLRI */ - ND_PRINT((ndo, "\n\t End-of-Rib Marker (empty NLRI)")); - return; + const u_char *p; + u_int withdrawn_routes_len; + char buf[MAXHOSTNAMELEN + 100]; + int wpfx; + u_int len; + int i; + int add_path; + u_int path_id = 0; + + ND_TCHECK_LEN(dat, BGP_SIZE); + if (length < BGP_SIZE) + goto trunc; + p = dat + BGP_SIZE; + length -= BGP_SIZE; + + /* Unfeasible routes */ + ND_TCHECK_2(p); + if (length < 2) + goto trunc; + withdrawn_routes_len = GET_BE_U_2(p); + p += 2; + length -= 2; + if (withdrawn_routes_len > 1) { + /* + * Without keeping state from the original NLRI message, + * it's not possible to tell if this a v4 or v6 route, + * so only try to decode it if we're not v6 enabled. + */ + ND_TCHECK_LEN(p, withdrawn_routes_len); + if (length < withdrawn_routes_len) + goto trunc; + ND_PRINT("\n\t Withdrawn routes:"); + add_path = check_add_path(ndo, p, withdrawn_routes_len, 32); + while (withdrawn_routes_len != 0) { + if (add_path) { + if (withdrawn_routes_len < 4) { + p += withdrawn_routes_len; + length -= withdrawn_routes_len; + break; + } + path_id = GET_BE_U_4(p); + p += 4; + length -= 4; + withdrawn_routes_len -= 4; + } + wpfx = decode_prefix4(ndo, p, withdrawn_routes_len, buf, sizeof(buf)); + if (wpfx == -1) { + ND_PRINT("\n\t (illegal prefix length)"); + break; + } else if (wpfx == -2) + goto trunc; /* bytes left, but not enough */ + else { + ND_PRINT("\n\t %s", buf); + if (add_path) { + ND_PRINT(" Path Id: %u", path_id); + } + p += wpfx; + length -= wpfx; + withdrawn_routes_len -= wpfx; + } } + } else { + ND_TCHECK_LEN(p, withdrawn_routes_len); + if (length < withdrawn_routes_len) + goto trunc; + p += withdrawn_routes_len; + length -= withdrawn_routes_len; + } - if (len) { - /* do something more useful!*/ - while (len) { - int aflags, atype, alenlen, alen; - - ND_TCHECK2(p[0], 2); - if (len < 2) - goto trunc; - if (length < 2) - goto trunc; - aflags = *p; - atype = *(p + 1); - p += 2; - len -= 2; - length -= 2; - alenlen = bgp_attr_lenlen(aflags, p); - ND_TCHECK2(p[0], alenlen); - if (len < alenlen) - goto trunc; - if (length < alenlen) - goto trunc; - alen = bgp_attr_len(aflags, p); - p += alenlen; - len -= alenlen; - length -= alenlen; - - ND_PRINT((ndo, "\n\t %s (%u), length: %u", - tok2str(bgp_attr_values, "Unknown Attribute", - atype), - atype, - alen)); - - if (aflags) { - ND_PRINT((ndo, ", Flags [%s%s%s%s", - aflags & 0x80 ? "O" : "", - aflags & 0x40 ? "T" : "", - aflags & 0x20 ? "P" : "", - aflags & 0x10 ? "E" : "")); - if (aflags & 0xf) - ND_PRINT((ndo, "+%x", aflags & 0xf)); - ND_PRINT((ndo, "]: ")); - } - if (len < alen) - goto trunc; - if (length < alen) - goto trunc; - if (!bgp_attr_print(ndo, atype, p, alen, 0)) - goto trunc; - p += alen; - len -= alen; - length -= alen; - } - } + ND_TCHECK_2(p); + if (length < 2) + goto trunc; + len = GET_BE_U_2(p); + p += 2; + length -= 2; - if (length) { - /* - * XXX - what if they're using the "Advertisement of - * Multiple Paths in BGP" feature: - * - * https://datatracker.ietf.org/doc/draft-ietf-idr-add-paths/ - * - * http://tools.ietf.org/html/draft-ietf-idr-add-paths-06 - */ - ND_PRINT((ndo, "\n\t Updated routes:")); - while (length) { - char buf[MAXHOSTNAMELEN + 100]; - i = decode_prefix4(ndo, p, length, buf, sizeof(buf)); - if (i == -1) { - ND_PRINT((ndo, "\n\t (illegal prefix length)")); - break; - } else if (i == -2) - goto trunc; - else if (i == -3) - goto trunc; /* bytes left, but not enough */ - else { - ND_PRINT((ndo, "\n\t %s", buf)); - p += i; - length -= i; - } - } - } - return; + if (withdrawn_routes_len == 0 && len == 0 && length == 0) { + /* No withdrawn routes, no path attributes, no NLRI */ + ND_PRINT("\n\t End-of-Rib Marker (empty NLRI)"); + return; + } + + if (len) { + /* do something more useful!*/ + while (len) { + uint8_t aflags, atype, alenlen; + uint16_t alen; + + ND_TCHECK_2(p); + if (length < 2) + goto trunc; + if (len < 2) { + ND_PRINT("\n\t [path attrs too short]"); + p += len; + length -= len; + break; + } + aflags = GET_U_1(p); + atype = GET_U_1(p + 1); + p += 2; + len -= 2; + length -= 2; + alenlen = bgp_attr_lenlen(aflags, p); + ND_TCHECK_LEN(p, alenlen); + if (length < alenlen) + goto trunc; + if (len < alenlen) { + ND_PRINT("\n\t [path attrs too short]"); + p += len; + length -= len; + break; + } + alen = bgp_attr_len(aflags, p); + p += alenlen; + len -= alenlen; + length -= alenlen; + + ND_PRINT("\n\t %s (%u), length: %u", + tok2str(bgp_attr_values, "Unknown Attribute", atype), + atype, + alen); + + if (aflags) { + ND_PRINT(", Flags [%s%s%s%s", + aflags & 0x80 ? "O" : "", + aflags & 0x40 ? "T" : "", + aflags & 0x20 ? "P" : "", + aflags & 0x10 ? "E" : ""); + if (aflags & 0xf) + ND_PRINT("+%x", aflags & 0xf); + ND_PRINT("]: "); + } + if (len < alen) { + ND_PRINT(" [path attrs too short]"); + p += len; + length -= len; + break; + } + if (length < alen) + goto trunc; + if (!bgp_attr_print(ndo, atype, p, alen, 0)) + goto trunc; + p += alen; + len -= alen; + length -= alen; + } + } + + if (length) { + add_path = check_add_path(ndo, p, length, 32); + ND_PRINT("\n\t Updated routes:"); + while (length != 0) { + if (add_path) { + ND_TCHECK_4(p); + if (length < 4) + goto trunc; + path_id = GET_BE_U_4(p); + p += 4; + length -= 4; + } + i = decode_prefix4(ndo, p, length, buf, sizeof(buf)); + if (i == -1) { + ND_PRINT("\n\t (illegal prefix length)"); + break; + } else if (i == -2) + goto trunc; /* bytes left, but not enough */ + else { + ND_PRINT("\n\t %s", buf); + if (add_path) { + ND_PRINT(" Path Id: %u", path_id); + } + p += i; + length -= i; + } + } + } + return; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); } static void bgp_notification_print(netdissect_options *ndo, - const u_char *dat, int length) + const u_char *dat, u_int length) { - struct bgp_notification bgpn; - const u_char *tptr; - - ND_TCHECK2(dat[0], BGP_NOTIFICATION_SIZE); - memcpy(&bgpn, dat, BGP_NOTIFICATION_SIZE); + const struct bgp_notification *bgp_notification_header; + const u_char *tptr; + uint8_t bgpn_major, bgpn_minor; + uint8_t shutdown_comm_length; + uint8_t remainder_offset; + + ND_TCHECK_LEN(dat, BGP_NOTIFICATION_SIZE); + if (lengthbgpn_major); + bgpn_minor = GET_U_1(bgp_notification_header->bgpn_minor); - ND_PRINT((ndo, ", %s (%u)", - tok2str(bgp_notify_major_values, "Unknown Error", - bgpn.bgpn_major), - bgpn.bgpn_major)); + ND_PRINT(", %s (%u)", + tok2str(bgp_notify_major_values, "Unknown Error", + bgpn_major), + bgpn_major); - switch (bgpn.bgpn_major) { + switch (bgpn_major) { - case BGP_NOTIFY_MAJOR_MSG: - ND_PRINT((ndo, ", subcode %s (%u)", - tok2str(bgp_notify_minor_msg_values, "Unknown", - bgpn.bgpn_minor), - bgpn.bgpn_minor)); - break; - case BGP_NOTIFY_MAJOR_OPEN: - ND_PRINT((ndo, ", subcode %s (%u)", - tok2str(bgp_notify_minor_open_values, "Unknown", - bgpn.bgpn_minor), - bgpn.bgpn_minor)); - break; - case BGP_NOTIFY_MAJOR_UPDATE: - ND_PRINT((ndo, ", subcode %s (%u)", - tok2str(bgp_notify_minor_update_values, "Unknown", - bgpn.bgpn_minor), - bgpn.bgpn_minor)); - break; - case BGP_NOTIFY_MAJOR_FSM: - ND_PRINT((ndo, " subcode %s (%u)", - tok2str(bgp_notify_minor_fsm_values, "Unknown", - bgpn.bgpn_minor), - bgpn.bgpn_minor)); - break; - case BGP_NOTIFY_MAJOR_CAP: - ND_PRINT((ndo, " subcode %s (%u)", - tok2str(bgp_notify_minor_cap_values, "Unknown", - bgpn.bgpn_minor), - bgpn.bgpn_minor)); - break; - case BGP_NOTIFY_MAJOR_CEASE: - ND_PRINT((ndo, ", subcode %s (%u)", - tok2str(bgp_notify_minor_cease_values, "Unknown", - bgpn.bgpn_minor), - bgpn.bgpn_minor)); - - /* draft-ietf-idr-cease-subcode-02 mentions optionally 7 bytes - * for the maxprefix subtype, which may contain AFI, SAFI and MAXPREFIXES - */ - if(bgpn.bgpn_minor == BGP_NOTIFY_MINOR_CEASE_MAXPRFX && length >= BGP_NOTIFICATION_SIZE + 7) { - tptr = dat + BGP_NOTIFICATION_SIZE; - ND_TCHECK2(*tptr, 7); - ND_PRINT((ndo, ", AFI %s (%u), SAFI %s (%u), Max Prefixes: %u", - tok2str(af_values, "Unknown", - EXTRACT_16BITS(tptr)), - EXTRACT_16BITS(tptr), - tok2str(bgp_safi_values, "Unknown", *(tptr+2)), - *(tptr+2), - EXTRACT_32BITS(tptr+3))); - } - break; - default: - break; + case BGP_NOTIFY_MAJOR_MSG: + ND_PRINT(", subcode %s (%u)", + tok2str(bgp_notify_minor_msg_values, "Unknown", + bgpn_minor), + bgpn_minor); + break; + case BGP_NOTIFY_MAJOR_OPEN: + ND_PRINT(", subcode %s (%u)", + tok2str(bgp_notify_minor_open_values, "Unknown", + bgpn_minor), + bgpn_minor); + break; + case BGP_NOTIFY_MAJOR_UPDATE: + ND_PRINT(", subcode %s (%u)", + tok2str(bgp_notify_minor_update_values, "Unknown", + bgpn_minor), + bgpn_minor); + break; + case BGP_NOTIFY_MAJOR_FSM: + ND_PRINT(" subcode %s (%u)", + tok2str(bgp_notify_minor_fsm_values, "Unknown", + bgpn_minor), + bgpn_minor); + break; + case BGP_NOTIFY_MAJOR_CAP: + ND_PRINT(" subcode %s (%u)", + tok2str(bgp_notify_minor_cap_values, "Unknown", + bgpn_minor), + bgpn_minor); + break; + case BGP_NOTIFY_MAJOR_CEASE: + ND_PRINT(", subcode %s (%u)", + tok2str(bgp_notify_minor_cease_values, "Unknown", + bgpn_minor), + bgpn_minor); + + /* draft-ietf-idr-cease-subcode-02 mentions optionally 7 bytes + * for the maxprefix subtype, which may contain AFI, SAFI and MAXPREFIXES + */ + if(bgpn_minor == BGP_NOTIFY_MINOR_CEASE_MAXPRFX && length >= BGP_NOTIFICATION_SIZE + 7) { + tptr = dat + BGP_NOTIFICATION_SIZE; + ND_PRINT(", AFI %s (%u), SAFI %s (%u), Max Prefixes: %u", + tok2str(af_values, "Unknown", GET_BE_U_2(tptr)), + GET_BE_U_2(tptr), + tok2str(bgp_safi_values, "Unknown", GET_U_1((tptr + 2))), + GET_U_1((tptr + 2)), + GET_BE_U_4(tptr + 3)); } + /* + * draft-ietf-idr-shutdown describes a method to send a communication + * intended for human consumption regarding the Administrative Shutdown + */ + if ((bgpn_minor == BGP_NOTIFY_MINOR_CEASE_SHUT || + bgpn_minor == BGP_NOTIFY_MINOR_CEASE_RESET) && + length >= BGP_NOTIFICATION_SIZE + 1) { + tptr = dat + BGP_NOTIFICATION_SIZE; + shutdown_comm_length = GET_U_1(tptr); + remainder_offset = 0; + /* garbage, hexdump it all */ + if (shutdown_comm_length > BGP_NOTIFY_MINOR_CEASE_ADMIN_SHUTDOWN_LEN || + shutdown_comm_length > length - (BGP_NOTIFICATION_SIZE + 1)) { + ND_PRINT(", invalid Shutdown Communication length"); + } + else if (shutdown_comm_length == 0) { + ND_PRINT(", empty Shutdown Communication"); + remainder_offset += 1; + } + /* a proper shutdown communication */ + else { + ND_TCHECK_LEN(tptr + 1, shutdown_comm_length); + ND_PRINT(", Shutdown Communication (length: %u): \"", shutdown_comm_length); + (void)nd_printn(ndo, tptr+1, shutdown_comm_length, NULL); + ND_PRINT("\""); + remainder_offset += shutdown_comm_length + 1; + } + /* if there is trailing data, hexdump it */ + if(length - (remainder_offset + BGP_NOTIFICATION_SIZE) > 0) { + ND_PRINT(", Data: (length: %u)", length - (remainder_offset + BGP_NOTIFICATION_SIZE)); + hex_print(ndo, "\n\t\t", tptr + remainder_offset, length - (remainder_offset + BGP_NOTIFICATION_SIZE)); + } + } + break; + default: + break; + } - return; + return; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); } static void bgp_route_refresh_print(netdissect_options *ndo, - const u_char *pptr, int len) + const u_char *pptr, u_int len) { - const struct bgp_route_refresh *bgp_route_refresh_header; + const struct bgp_route_refresh *bgp_route_refresh_header; - ND_TCHECK2(pptr[0], BGP_ROUTE_REFRESH_SIZE); + ND_TCHECK_LEN(pptr, BGP_ROUTE_REFRESH_SIZE); - /* some little sanity checking */ - if (lenafi)), - EXTRACT_16BITS(&bgp_route_refresh_header->afi), - tok2str(bgp_safi_values,"Unknown", - bgp_route_refresh_header->safi), - bgp_route_refresh_header->safi)); + ND_PRINT("\n\t AFI %s (%u), SAFI %s (%u)", + tok2str(af_values,"Unknown", + GET_BE_U_2(bgp_route_refresh_header->afi)), + GET_BE_U_2(bgp_route_refresh_header->afi), + tok2str(bgp_safi_values,"Unknown", + GET_U_1(bgp_route_refresh_header->safi)), + GET_U_1(bgp_route_refresh_header->safi)); - if (ndo->ndo_vflag > 1) { - ND_TCHECK2(*pptr, len); - print_unknown_data(ndo, pptr, "\n\t ", len); - } + if (ndo->ndo_vflag > 1) { + ND_TCHECK_LEN(pptr, len); + print_unknown_data(ndo, pptr, "\n\t ", len); + } - return; + return; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); } static int -bgp_header_print(netdissect_options *ndo, - const u_char *dat, int length) +bgp_pdu_print(netdissect_options *ndo, + const u_char *dat, u_int length) { - struct bgp bgp; - - ND_TCHECK2(dat[0], BGP_SIZE); - memcpy(&bgp, dat, BGP_SIZE); - ND_PRINT((ndo, "\n\t%s Message (%u), length: %u", - tok2str(bgp_msg_values, "Unknown", bgp.bgp_type), - bgp.bgp_type, - length)); - - switch (bgp.bgp_type) { - case BGP_OPEN: - bgp_open_print(ndo, dat, length); - break; - case BGP_UPDATE: - bgp_update_print(ndo, dat, length); - break; - case BGP_NOTIFICATION: - bgp_notification_print(ndo, dat, length); - break; - case BGP_KEEPALIVE: - break; - case BGP_ROUTE_REFRESH: - bgp_route_refresh_print(ndo, dat, length); - break; - default: - /* we have no decoder for the BGP message */ - ND_TCHECK2(*dat, length); - ND_PRINT((ndo, "\n\t no Message %u decoder", bgp.bgp_type)); - print_unknown_data(ndo, dat, "\n\t ", length); - break; - } - return 1; + const struct bgp *bgp_header; + uint8_t bgp_type; + + ND_TCHECK_LEN(dat, BGP_SIZE); + bgp_header = (const struct bgp *)dat; + bgp_type = GET_U_1(bgp_header->bgp_type); + + ND_PRINT("\n\t%s Message (%u), length: %u", + tok2str(bgp_msg_values, "Unknown", bgp_type), + bgp_type, + length); + + switch (bgp_type) { + case BGP_OPEN: + bgp_open_print(ndo, dat, length); + break; + case BGP_UPDATE: + bgp_update_print(ndo, dat, length); + break; + case BGP_NOTIFICATION: + bgp_notification_print(ndo, dat, length); + break; + case BGP_KEEPALIVE: + break; + case BGP_ROUTE_REFRESH: + bgp_route_refresh_print(ndo, dat, length); + break; + default: + /* we have no decoder for the BGP message */ + ND_TCHECK_LEN(dat, length); + ND_PRINT("\n\t no Message %u decoder", bgp_type); + print_unknown_data(ndo, dat, "\n\t ", length); + break; + } + return 1; trunc: - ND_PRINT((ndo, "%s", tstr)); - return 0; + nd_print_trunc(ndo); + return 0; } void bgp_print(netdissect_options *ndo, - const u_char *dat, int length) + const u_char *dat, u_int length _U_) { - const u_char *p; - const u_char *ep; - const u_char *start; - const u_char marker[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - }; - struct bgp bgp; - uint16_t hlen; - - ep = dat + length; - if (ndo->ndo_snapend < dat + length) - ep = ndo->ndo_snapend; - - ND_PRINT((ndo, ": BGP")); - - if (ndo->ndo_vflag < 1) /* lets be less chatty */ - return; + const u_char *p; + const u_char *ep = ndo->ndo_snapend; + const u_char *start; + const u_char marker[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + }; + const struct bgp *bgp_header; + uint16_t hlen; + + ndo->ndo_protocol = "bgp"; + ND_PRINT(": BGP"); + + if (ndo->ndo_vflag < 1) /* lets be less chatty */ + return; - p = dat; - start = p; - while (p < ep) { - if (!ND_TTEST2(p[0], 1)) - break; - if (p[0] != 0xff) { - p++; - continue; - } - - if (!ND_TTEST2(p[0], sizeof(marker))) - break; - if (memcmp(p, marker, sizeof(marker)) != 0) { - p++; - continue; - } - - /* found BGP header */ - ND_TCHECK2(p[0], BGP_SIZE); /*XXX*/ - memcpy(&bgp, p, BGP_SIZE); - - if (start != p) - ND_PRINT((ndo, " %s", tstr)); - - hlen = ntohs(bgp.bgp_len); - if (hlen < BGP_SIZE) { - ND_PRINT((ndo, "\n[|BGP Bogus header length %u < %u]", hlen, - BGP_SIZE)); - break; - } - - if (ND_TTEST2(p[0], hlen)) { - if (!bgp_header_print(ndo, p, hlen)) - return; - p += hlen; - start = p; - } else { - ND_PRINT((ndo, "\n[|BGP %s]", - tok2str(bgp_msg_values, - "Unknown Message Type", - bgp.bgp_type))); - break; - } - } + p = dat; + start = p; + while (p < ep) { + if (!ND_TTEST_1(p)) + break; + if (GET_U_1(p) != 0xff) { + p++; + continue; + } + + if (!ND_TTEST_LEN(p, sizeof(marker))) + break; + if (memcmp(p, marker, sizeof(marker)) != 0) { + p++; + continue; + } - return; + /* found BGP header */ + ND_TCHECK_LEN(p, BGP_SIZE); + bgp_header = (const struct bgp *)p; + + if (start != p) + nd_print_trunc(ndo); + + hlen = GET_BE_U_2(bgp_header->bgp_len); + if (hlen < BGP_SIZE) { + ND_PRINT("\nmessage length %u < %u", hlen, BGP_SIZE); + nd_print_invalid(ndo); + break; + } + + if (ND_TTEST_LEN(p, hlen)) { + if (!bgp_pdu_print(ndo, p, hlen)) + return; + p += hlen; + start = p; + } else { + ND_PRINT("\n[|BGP %s]", + tok2str(bgp_msg_values, + "Unknown Message Type", + GET_U_1(bgp_header->bgp_type))); + break; + } + } + + return; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); } - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 4 - * End: - */ diff --git a/contrib/tcpdump/print-bootp.c b/contrib/tcpdump/print-bootp.c index c076f42507..f84b77cad2 100644 --- a/contrib/tcpdump/print-bootp.c +++ b/contrib/tcpdump/print-bootp.c @@ -22,10 +22,10 @@ /* \summary: BOOTP and IPv4 DHCP printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include @@ -33,7 +33,6 @@ #include "addrtoname.h" #include "extract.h" -static const char tstr[] = " [|bootp]"; /* * Bootstrap Protocol (BOOTP). RFC951 and RFC1048. @@ -56,23 +55,23 @@ static const char tstr[] = " [|bootp]"; */ struct bootp { - uint8_t bp_op; /* packet opcode type */ - uint8_t bp_htype; /* hardware addr type */ - uint8_t bp_hlen; /* hardware addr length */ - uint8_t bp_hops; /* gateway hops */ - uint32_t bp_xid; /* transaction ID */ - uint16_t bp_secs; /* seconds since boot began */ - uint16_t bp_flags; /* flags - see bootp_flag_values[] + nd_uint8_t bp_op; /* packet opcode type */ + nd_uint8_t bp_htype; /* hardware addr type */ + nd_uint8_t bp_hlen; /* hardware addr length */ + nd_uint8_t bp_hops; /* gateway hops */ + nd_uint32_t bp_xid; /* transaction ID */ + nd_uint16_t bp_secs; /* seconds since boot began */ + nd_uint16_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 */ - struct in_addr bp_giaddr; /* gateway IP address */ - uint8_t bp_chaddr[16]; /* client hardware address */ - uint8_t bp_sname[64]; /* server host name */ - uint8_t bp_file[128]; /* boot file name */ - uint8_t bp_vend[64]; /* vendor-specific area */ -} UNALIGNED; + nd_ipv4 bp_ciaddr; /* client IP address */ + nd_ipv4 bp_yiaddr; /* 'your' IP address */ + nd_ipv4 bp_siaddr; /* server IP address */ + nd_ipv4 bp_giaddr; /* gateway IP address */ + nd_byte bp_chaddr[16]; /* client hardware address */ + nd_byte bp_sname[64]; /* server host name */ + nd_byte bp_file[128]; /* boot file name */ + nd_byte bp_vend[64]; /* vendor-specific area */ +}; #define BOOTPREPLY 2 #define BOOTPREQUEST 1 @@ -196,32 +195,26 @@ struct bootp { #define TAG_CLASSLESS_STA_RT_MS ((uint8_t) 249) /* RFC 5859 - TFTP Server Address Option for DHCPv4 */ #define TAG_TFTP_SERVER_ADDRESS ((uint8_t) 150) -/* ftp://ftp.isi.edu/.../assignments/bootp-dhcp-extensions */ +/* https://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xhtml */ #define TAG_SLP_NAMING_AUTH ((uint8_t) 80) #define TAG_CLIENT_FQDN ((uint8_t) 81) #define TAG_AGENT_CIRCUIT ((uint8_t) 82) #define TAG_AGENT_REMOTE ((uint8_t) 83) -#define TAG_AGENT_MASK ((uint8_t) 84) #define TAG_TZ_STRING ((uint8_t) 88) #define TAG_FQDN_OPTION ((uint8_t) 89) #define TAG_AUTH ((uint8_t) 90) -#define TAG_VINES_SERVERS ((uint8_t) 91) -#define TAG_SERVER_RANK ((uint8_t) 92) +#define TAG_CLIENT_LAST_TRANSACTION_TIME ((uint8_t) 91) +#define TAG_ASSOCIATED_IP ((uint8_t) 92) #define TAG_CLIENT_ARCH ((uint8_t) 93) #define TAG_CLIENT_NDI ((uint8_t) 94) #define TAG_CLIENT_GUID ((uint8_t) 97) #define TAG_LDAP_URL ((uint8_t) 95) -#define TAG_6OVER4 ((uint8_t) 96) /* RFC 4833, TZ codes */ #define TAG_TZ_PCODE ((uint8_t) 100) #define TAG_TZ_TCODE ((uint8_t) 101) -#define TAG_IPX_COMPAT ((uint8_t) 110) #define TAG_NETINFO_PARENT ((uint8_t) 112) #define TAG_NETINFO_PARENT_TAG ((uint8_t) 113) #define TAG_URL ((uint8_t) 114) -#define TAG_FAILOVER ((uint8_t) 115) -#define TAG_EXTENDED_REQUEST ((uint8_t) 126) -#define TAG_EXTENDED_OPTION ((uint8_t) 127) #define TAG_MUDURL ((uint8_t) 161) /* DHCP Message types (values for TAG_DHCP_MESSAGE option) */ @@ -233,21 +226,27 @@ struct bootp { #define DHCPNAK 6 #define DHCPRELEASE 7 #define DHCPINFORM 8 +/* Defined in RFC4388 */ +#define DHCPLEASEQUERY 10 +#define DHCPLEASEUNASSIGNED 11 +#define DHCPLEASEUNKNOWN 12 +#define DHCPLEASEACTIVE 13 + /* * "vendor" data permitted for CMU bootp clients. */ struct cmu_vend { - uint8_t v_magic[4]; /* magic number */ - uint32_t v_flags; /* flags/opcodes, etc. */ - struct in_addr v_smask; /* Subnet mask */ - struct in_addr v_dgate; /* Default gateway */ - struct in_addr v_dns1, v_dns2; /* Domain name servers */ - struct in_addr v_ins1, v_ins2; /* IEN-116 name servers */ - struct in_addr v_ts1, v_ts2; /* Time servers */ - uint8_t v_unused[24]; /* currently unused */ -} UNALIGNED; + nd_byte v_magic[4]; /* magic number */ + nd_uint32_t v_flags; /* flags/opcodes, etc. */ + nd_ipv4 v_smask; /* Subnet mask */ + nd_ipv4 v_dgate; /* Default gateway */ + nd_ipv4 v_dns1, v_dns2; /* Domain name servers */ + nd_ipv4 v_ins1, v_ins2; /* IEN-116 name servers */ + nd_ipv4 v_ts1, v_ts2; /* Time servers */ + nd_byte v_unused[24]; /* currently unused */ +}; /* v_flags values */ @@ -281,104 +280,97 @@ static const struct tok bootp_op_values[] = { */ void bootp_print(netdissect_options *ndo, - register const u_char *cp, u_int length) + const u_char *cp, u_int length) { - register const struct bootp *bp; + const struct bootp *bp; static const u_char vm_cmu[4] = VM_CMU; static const u_char vm_rfc1048[4] = VM_RFC1048; + uint8_t bp_op, bp_htype, bp_hlen; + ndo->ndo_protocol = "bootp"; bp = (const struct bootp *)cp; - ND_TCHECK(bp->bp_op); - - ND_PRINT((ndo, "BOOTP/DHCP, %s", - tok2str(bootp_op_values, "unknown (0x%02x)", bp->bp_op))); - - ND_TCHECK(bp->bp_hlen); - if (bp->bp_htype == 1 && bp->bp_hlen == 6 && bp->bp_op == BOOTPREQUEST) { - ND_TCHECK2(bp->bp_chaddr[0], 6); - ND_PRINT((ndo, " from %s", etheraddr_string(ndo, bp->bp_chaddr))); + bp_op = GET_U_1(bp->bp_op); + ND_PRINT("BOOTP/DHCP, %s", + tok2str(bootp_op_values, "unknown (0x%02x)", bp_op)); + + bp_htype = GET_U_1(bp->bp_htype); + bp_hlen = GET_U_1(bp->bp_hlen); + if (bp_htype == 1 && bp_hlen == MAC_ADDR_LEN && bp_op == BOOTPREQUEST) { + ND_PRINT(" from %s", GET_ETHERADDR_STRING(bp->bp_chaddr)); } - ND_PRINT((ndo, ", length %u", length)); + ND_PRINT(", length %u", length); if (!ndo->ndo_vflag) return; - ND_TCHECK(bp->bp_secs); + ND_TCHECK_2(bp->bp_secs); /* The usual hardware address type is 1 (10Mb Ethernet) */ - if (bp->bp_htype != 1) - ND_PRINT((ndo, ", htype %d", bp->bp_htype)); + if (bp_htype != 1) + ND_PRINT(", htype %u", bp_htype); /* The usual length for 10Mb Ethernet address is 6 bytes */ - if (bp->bp_htype != 1 || bp->bp_hlen != 6) - ND_PRINT((ndo, ", hlen %d", bp->bp_hlen)); + if (bp_htype != 1 || bp_hlen != MAC_ADDR_LEN) + ND_PRINT(", hlen %u", bp_hlen); /* Only print interesting fields */ - if (bp->bp_hops) - ND_PRINT((ndo, ", hops %d", bp->bp_hops)); - if (EXTRACT_32BITS(&bp->bp_xid)) - ND_PRINT((ndo, ", xid 0x%x", EXTRACT_32BITS(&bp->bp_xid))); - if (EXTRACT_16BITS(&bp->bp_secs)) - ND_PRINT((ndo, ", secs %d", EXTRACT_16BITS(&bp->bp_secs))); - - ND_TCHECK(bp->bp_flags); - ND_PRINT((ndo, ", Flags [%s]", - bittok2str(bootp_flag_values, "none", EXTRACT_16BITS(&bp->bp_flags)))); + if (GET_U_1(bp->bp_hops)) + ND_PRINT(", hops %u", GET_U_1(bp->bp_hops)); + if (GET_BE_U_4(bp->bp_xid)) + ND_PRINT(", xid 0x%x", GET_BE_U_4(bp->bp_xid)); + if (GET_BE_U_2(bp->bp_secs)) + ND_PRINT(", secs %u", GET_BE_U_2(bp->bp_secs)); + + ND_PRINT(", Flags [%s]", + bittok2str(bootp_flag_values, "none", GET_BE_U_2(bp->bp_flags))); if (ndo->ndo_vflag > 1) - ND_PRINT((ndo, " (0x%04x)", EXTRACT_16BITS(&bp->bp_flags))); + ND_PRINT(" (0x%04x)", GET_BE_U_2(bp->bp_flags)); /* Client's ip address */ - ND_TCHECK(bp->bp_ciaddr); - if (EXTRACT_32BITS(&bp->bp_ciaddr.s_addr)) - ND_PRINT((ndo, "\n\t Client-IP %s", ipaddr_string(ndo, &bp->bp_ciaddr))); + if (GET_IPV4_TO_NETWORK_ORDER(bp->bp_ciaddr)) + ND_PRINT("\n\t Client-IP %s", GET_IPADDR_STRING(bp->bp_ciaddr)); /* 'your' ip address (bootp client) */ - ND_TCHECK(bp->bp_yiaddr); - if (EXTRACT_32BITS(&bp->bp_yiaddr.s_addr)) - ND_PRINT((ndo, "\n\t Your-IP %s", ipaddr_string(ndo, &bp->bp_yiaddr))); + if (GET_IPV4_TO_NETWORK_ORDER(bp->bp_yiaddr)) + ND_PRINT("\n\t Your-IP %s", GET_IPADDR_STRING(bp->bp_yiaddr)); /* Server's ip address */ - ND_TCHECK(bp->bp_siaddr); - if (EXTRACT_32BITS(&bp->bp_siaddr.s_addr)) - ND_PRINT((ndo, "\n\t Server-IP %s", ipaddr_string(ndo, &bp->bp_siaddr))); + if (GET_IPV4_TO_NETWORK_ORDER(bp->bp_siaddr)) + ND_PRINT("\n\t Server-IP %s", GET_IPADDR_STRING(bp->bp_siaddr)); /* Gateway's ip address */ - ND_TCHECK(bp->bp_giaddr); - if (EXTRACT_32BITS(&bp->bp_giaddr.s_addr)) - ND_PRINT((ndo, "\n\t Gateway-IP %s", ipaddr_string(ndo, &bp->bp_giaddr))); + if (GET_IPV4_TO_NETWORK_ORDER(bp->bp_giaddr)) + ND_PRINT("\n\t Gateway-IP %s", GET_IPADDR_STRING(bp->bp_giaddr)); /* Client's Ethernet address */ - if (bp->bp_htype == 1 && bp->bp_hlen == 6) { - ND_TCHECK2(bp->bp_chaddr[0], 6); - ND_PRINT((ndo, "\n\t Client-Ethernet-Address %s", etheraddr_string(ndo, bp->bp_chaddr))); + if (bp_htype == 1 && bp_hlen == MAC_ADDR_LEN) { + ND_PRINT("\n\t Client-Ethernet-Address %s", GET_ETHERADDR_STRING(bp->bp_chaddr)); } - ND_TCHECK2(bp->bp_sname[0], 1); /* check first char only */ - if (*bp->bp_sname) { - ND_PRINT((ndo, "\n\t sname \"")); - if (fn_printztn(ndo, bp->bp_sname, (u_int)sizeof bp->bp_sname, - ndo->ndo_snapend) == 0) { - ND_PRINT((ndo, "\"")); - ND_PRINT((ndo, "%s", tstr + 1)); + if (GET_U_1(bp->bp_sname)) { /* get first char only */ + ND_PRINT("\n\t sname \""); + if (nd_printztn(ndo, bp->bp_sname, (u_int)sizeof(bp->bp_sname), + ndo->ndo_snapend) == 0) { + ND_PRINT("\""); + nd_print_trunc(ndo); return; } - ND_PRINT((ndo, "\"")); + ND_PRINT("\""); } - ND_TCHECK2(bp->bp_file[0], 1); /* check first char only */ - if (*bp->bp_file) { - ND_PRINT((ndo, "\n\t file \"")); - if (fn_printztn(ndo, bp->bp_file, (u_int)sizeof bp->bp_file, - ndo->ndo_snapend) == 0) { - ND_PRINT((ndo, "\"")); - ND_PRINT((ndo, "%s", tstr + 1)); + if (GET_U_1(bp->bp_file)) { /* get first char only */ + ND_PRINT("\n\t file \""); + if (nd_printztn(ndo, bp->bp_file, (u_int)sizeof(bp->bp_file), + ndo->ndo_snapend) == 0) { + ND_PRINT("\""); + nd_print_trunc(ndo); return; } - ND_PRINT((ndo, "\"")); + ND_PRINT("\""); } /* Decode the vendor buffer */ - ND_TCHECK2(bp->bp_vend[0], 4); + ND_TCHECK_4(bp->bp_vend); if (memcmp((const char *)bp->bp_vend, vm_rfc1048, sizeof(uint32_t)) == 0) rfc1048_print(ndo, bp->bp_vend); @@ -388,15 +380,14 @@ bootp_print(netdissect_options *ndo, else { uint32_t ul; - ND_TCHECK_32BITS(&bp->bp_vend); - ul = EXTRACT_32BITS(&bp->bp_vend); + ul = GET_BE_U_4(bp->bp_vend); if (ul != 0) - ND_PRINT((ndo, "\n\t Vendor-#0x%x", ul)); + ND_PRINT("\n\t Vendor-#0x%x", ul); } return; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); } /* @@ -406,9 +397,9 @@ trunc: * l - long (32 bits) * L - unsigned long (32 bits) * s - short (16 bits) - * b - period-seperated decimal bytes (variable length) - * x - colon-seperated hex bytes (variable length) - * a - ascii string (variable length) + * b - period-separated decimal bytes (variable length) + * x - colon-separated hex bytes (variable length) + * a - ASCII string (variable length) * B - on/off (8 bits) * $ - special (explicit code to handle) */ @@ -426,7 +417,7 @@ static const struct tok tag2str[] = { { TAG_LPR_SERVER, "iLPR-Server" }, /* lpr server (RFC1179) */ { TAG_IMPRESS_SERVER, "iIM" }, /* impress servers (Imagen) */ { TAG_RLP_SERVER, "iRL" }, /* resource location (RFC887) */ - { TAG_HOSTNAME, "aHostname" }, /* ascii hostname */ + { TAG_HOSTNAME, "aHostname" }, /* ASCII hostname */ { TAG_BOOTSIZE, "sBS" }, /* 512 byte blocks */ { TAG_END, " END" }, /* RFC1497 tags */ @@ -510,36 +501,28 @@ static const struct tok tag2str[] = { { TAG_CLASSLESS_STA_RT_MS, "$Classless-Static-Route-Microsoft" }, /* RFC 5859 - TFTP Server Address Option for DHCPv4 */ { TAG_TFTP_SERVER_ADDRESS, "iTFTP-Server-Address" }, -/* http://www.iana.org/assignments/bootp-dhcp-extensions/index.htm */ +/* https://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xhtml#options */ { TAG_SLP_NAMING_AUTH, "aSLP-NA" }, { TAG_CLIENT_FQDN, "$FQDN" }, { TAG_AGENT_CIRCUIT, "$Agent-Information" }, { TAG_AGENT_REMOTE, "bARMT" }, - { TAG_AGENT_MASK, "bAMSK" }, { TAG_TZ_STRING, "aTZSTR" }, { TAG_FQDN_OPTION, "bFQDNS" }, /* XXX 'b' */ { TAG_AUTH, "bAUTH" }, /* XXX 'b' */ - { TAG_VINES_SERVERS, "iVINES" }, - { TAG_SERVER_RANK, "sRANK" }, + { TAG_CLIENT_LAST_TRANSACTION_TIME, "LLast-Transaction-Time" }, + { TAG_ASSOCIATED_IP, "iAssociated-IP" }, { TAG_CLIENT_ARCH, "sARCH" }, { TAG_CLIENT_NDI, "bNDI" }, /* XXX 'b' */ { TAG_CLIENT_GUID, "bGUID" }, /* XXX 'b' */ { TAG_LDAP_URL, "aLDAP" }, - { TAG_6OVER4, "i6o4" }, { TAG_TZ_PCODE, "aPOSIX-TZ" }, { TAG_TZ_TCODE, "aTZ-Name" }, - { TAG_IPX_COMPAT, "bIPX" }, /* XXX 'b' */ { TAG_NETINFO_PARENT, "iNI" }, { TAG_NETINFO_PARENT_TAG, "aNITAG" }, { TAG_URL, "aURL" }, - { TAG_FAILOVER, "bFAIL" }, /* XXX 'b' */ { TAG_MUDURL, "aMUD-URL" }, { 0, NULL } }; -/* 2-byte extended tags */ -static const struct tok xtag2str[] = { - { 0, NULL } -}; /* DHCP "options overload" types */ static const struct tok oo2str[] = { @@ -570,14 +553,18 @@ static const struct tok arp2str[] = { }; static const struct tok dhcp_msg_values[] = { - { DHCPDISCOVER, "Discover" }, - { DHCPOFFER, "Offer" }, - { DHCPREQUEST, "Request" }, - { DHCPDECLINE, "Decline" }, - { DHCPACK, "ACK" }, - { DHCPNAK, "NACK" }, - { DHCPRELEASE, "Release" }, - { DHCPINFORM, "Inform" }, + { DHCPDISCOVER, "Discover" }, + { DHCPOFFER, "Offer" }, + { DHCPREQUEST, "Request" }, + { DHCPDECLINE, "Decline" }, + { DHCPACK, "ACK" }, + { DHCPNAK, "NACK" }, + { DHCPRELEASE, "Release" }, + { DHCPINFORM, "Inform" }, + { DHCPLEASEQUERY, "LeaseQuery" }, + { DHCPLEASEUNASSIGNED, "LeaseUnassigned" }, + { DHCPLEASEUNKNOWN, "LeaseUnknown" }, + { DHCPLEASEACTIVE, "LeaseActive" }, { 0, NULL } }; @@ -594,104 +581,80 @@ static const struct tok agent_suboption_values[] = { static void rfc1048_print(netdissect_options *ndo, - register const u_char *bp) + const u_char *bp) { - register uint16_t tag; - register u_int len; - register const char *cp; - register char c; + uint16_t tag; + u_int len; + const char *cp; + char c; int first, idx; - uint32_t ul; - uint16_t us; - uint8_t uc, subopt, suboptlen; + uint8_t subopt, suboptlen; - ND_PRINT((ndo, "\n\t Vendor-rfc1048 Extensions")); + ND_PRINT("\n\t Vendor-rfc1048 Extensions"); /* Step over magic cookie */ - ND_PRINT((ndo, "\n\t Magic Cookie 0x%08x", EXTRACT_32BITS(bp))); + ND_PRINT("\n\t Magic Cookie 0x%08x", GET_BE_U_4(bp)); bp += sizeof(int32_t); /* Loop while we there is a tag left in the buffer */ - while (ND_TTEST2(*bp, 1)) { - tag = *bp++; + while (ND_TTEST_1(bp)) { + tag = GET_U_1(bp); + bp++; if (tag == TAG_PAD && ndo->ndo_vflag < 3) continue; if (tag == TAG_END && ndo->ndo_vflag < 3) return; - if (tag == TAG_EXTENDED_OPTION) { - ND_TCHECK2(*(bp + 1), 2); - tag = EXTRACT_16BITS(bp + 1); - /* XXX we don't know yet if the IANA will - * preclude overlap of 1-byte and 2-byte spaces. - * If not, we need to offset tag after this step. - */ - cp = tok2str(xtag2str, "?xT%u", tag); - } else - cp = tok2str(tag2str, "?T%u", tag); + cp = tok2str(tag2str, "?Unknown", tag); c = *cp++; if (tag == TAG_PAD || tag == TAG_END) len = 0; else { /* Get the length; check for truncation */ - ND_TCHECK2(*bp, 1); - len = *bp++; + len = GET_U_1(bp); + bp++; } - ND_PRINT((ndo, "\n\t %s Option %u, length %u%s", cp, tag, len, - len > 0 ? ": " : "")); + ND_PRINT("\n\t %s (%u), length %u%s", cp, tag, len, + len > 0 ? ": " : ""); if (tag == TAG_PAD && ndo->ndo_vflag > 2) { u_int ntag = 1; - while (ND_TTEST2(*bp, 1) && *bp == TAG_PAD) { + while (ND_TTEST_1(bp) && + GET_U_1(bp) == TAG_PAD) { bp++; ntag++; } if (ntag > 1) - ND_PRINT((ndo, ", occurs %u", ntag)); + ND_PRINT(", occurs %u", ntag); } - if (!ND_TTEST2(*bp, len)) { - ND_PRINT((ndo, "[|rfc1048 %u]", len)); - return; - } + ND_TCHECK_LEN(bp, len); if (tag == TAG_DHCP_MESSAGE && len == 1) { - uc = *bp++; - ND_PRINT((ndo, "%s", tok2str(dhcp_msg_values, "Unknown (%u)", uc))); + ND_PRINT("%s", + tok2str(dhcp_msg_values, "Unknown (%u)", GET_U_1(bp))); + bp++; continue; } if (tag == TAG_PARM_REQUEST) { idx = 0; - while (len-- > 0) { - uc = *bp++; - cp = tok2str(tag2str, "?Option %u", uc); + while (len > 0) { + uint8_t innertag = GET_U_1(bp); + bp++; + len--; + cp = tok2str(tag2str, "?Unknown", innertag); if (idx % 4 == 0) - ND_PRINT((ndo, "\n\t ")); + ND_PRINT("\n\t "); else - ND_PRINT((ndo, ", ")); - ND_PRINT((ndo, "%s", cp + 1)); + ND_PRINT(", "); + ND_PRINT("%s (%u)", cp + 1, innertag); idx++; } continue; } - if (tag == TAG_EXTENDED_REQUEST) { - first = 1; - while (len > 1) { - len -= 2; - us = EXTRACT_16BITS(bp); - bp += 2; - cp = tok2str(xtag2str, "?xT%u", us); - if (!first) - ND_PRINT((ndo, "+")); - ND_PRINT((ndo, "%s", cp + 1)); - first = 0; - } - continue; - } - /* Print data */ if (c == '?') { /* Base default formats for unknown tags on data size */ @@ -706,13 +669,13 @@ rfc1048_print(netdissect_options *ndo, switch (c) { case 'a': - /* ascii strings */ - ND_PRINT((ndo, "\"")); - if (fn_printn(ndo, bp, len, ndo->ndo_snapend)) { - ND_PRINT((ndo, "\"")); + /* ASCII strings */ + ND_PRINT("\""); + if (nd_printn(ndo, bp, len, ndo->ndo_snapend)) { + ND_PRINT("\""); goto trunc; } - ND_PRINT((ndo, "\"")); + ND_PRINT("\""); bp += len; len = 0; break; @@ -721,48 +684,44 @@ rfc1048_print(netdissect_options *ndo, case 'l': case 'L': /* ip addresses/32-bit words */ - while (len >= sizeof(ul)) { + while (len >= 4) { if (!first) - ND_PRINT((ndo, ",")); - ul = EXTRACT_32BITS(bp); - if (c == 'i') { - ul = htonl(ul); - ND_PRINT((ndo, "%s", ipaddr_string(ndo, &ul))); - } else if (c == 'L') - ND_PRINT((ndo, "%d", ul)); + ND_PRINT(","); + if (c == 'i') + ND_PRINT("%s", GET_IPADDR_STRING(bp)); + else if (c == 'L') + ND_PRINT("%d", GET_BE_S_4(bp)); else - ND_PRINT((ndo, "%u", ul)); - bp += sizeof(ul); - len -= sizeof(ul); + ND_PRINT("%u", GET_BE_U_4(bp)); + bp += 4; + len -= 4; first = 0; } break; case 'p': /* IP address pairs */ - while (len >= 2*sizeof(ul)) { + while (len >= 2*4) { if (!first) - ND_PRINT((ndo, ",")); - memcpy((char *)&ul, (const char *)bp, sizeof(ul)); - ND_PRINT((ndo, "(%s:", ipaddr_string(ndo, &ul))); - bp += sizeof(ul); - memcpy((char *)&ul, (const char *)bp, sizeof(ul)); - ND_PRINT((ndo, "%s)", ipaddr_string(ndo, &ul))); - bp += sizeof(ul); - len -= 2*sizeof(ul); + ND_PRINT(","); + ND_PRINT("(%s:", GET_IPADDR_STRING(bp)); + bp += 4; + len -= 4; + ND_PRINT("%s)", GET_IPADDR_STRING(bp)); + bp += 4; + len -= 4; first = 0; } break; case 's': /* shorts */ - while (len >= sizeof(us)) { + while (len >= 2) { if (!first) - ND_PRINT((ndo, ",")); - us = EXTRACT_16BITS(bp); - ND_PRINT((ndo, "%u", us)); - bp += sizeof(us); - len -= sizeof(us); + ND_PRINT(","); + ND_PRINT("%u", GET_BE_U_2(bp)); + bp += 2; + len -= 2; first = 0; } break; @@ -770,17 +729,19 @@ rfc1048_print(netdissect_options *ndo, case 'B': /* boolean */ while (len > 0) { + uint8_t bool_value; if (!first) - ND_PRINT((ndo, ",")); - switch (*bp) { + ND_PRINT(","); + bool_value = GET_U_1(bp); + switch (bool_value) { case 0: - ND_PRINT((ndo, "N")); + ND_PRINT("N"); break; case 1: - ND_PRINT((ndo, "Y")); + ND_PRINT("Y"); break; default: - ND_PRINT((ndo, "%u?", *bp)); + ND_PRINT("%u?", bool_value); break; } ++bp; @@ -794,12 +755,14 @@ rfc1048_print(netdissect_options *ndo, default: /* Bytes */ while (len > 0) { + uint8_t byte_value; if (!first) - ND_PRINT((ndo, c == 'x' ? ":" : ".")); + ND_PRINT(c == 'x' ? ":" : "."); + byte_value = GET_U_1(bp); if (c == 'x') - ND_PRINT((ndo, "%02x", *bp)); + ND_PRINT("%02x", byte_value); else - ND_PRINT((ndo, "%u", *bp)); + ND_PRINT("%u", byte_value); ++bp; --len; first = 0; @@ -813,45 +776,53 @@ rfc1048_print(netdissect_options *ndo, case TAG_NETBIOS_NODE: /* this option should be at least 1 byte long */ if (len < 1) { - ND_PRINT((ndo, "ERROR: length < 1 bytes")); + ND_PRINT("[ERROR: length < 1 bytes]"); break; } - tag = *bp++; + tag = GET_U_1(bp); + ++bp; --len; - ND_PRINT((ndo, "%s", tok2str(nbo2str, NULL, tag))); + ND_PRINT("%s", tok2str(nbo2str, NULL, tag)); break; case TAG_OPT_OVERLOAD: /* this option should be at least 1 byte long */ if (len < 1) { - ND_PRINT((ndo, "ERROR: length < 1 bytes")); + ND_PRINT("[ERROR: length < 1 bytes]"); break; } - tag = *bp++; + tag = GET_U_1(bp); + ++bp; --len; - ND_PRINT((ndo, "%s", tok2str(oo2str, NULL, tag))); + ND_PRINT("%s", tok2str(oo2str, NULL, tag)); break; case TAG_CLIENT_FQDN: /* this option should be at least 3 bytes long */ if (len < 3) { - ND_PRINT((ndo, "ERROR: length < 3 bytes")); + ND_PRINT("[ERROR: length < 3 bytes]"); bp += len; len = 0; break; } - if (*bp) - ND_PRINT((ndo, "[%s] ", client_fqdn_flags(*bp))); + if (GET_U_1(bp) & 0xf0) { + ND_PRINT("[ERROR: MBZ nibble 0x%x != 0] ", + (GET_U_1(bp) & 0xf0) >> 4); + } + if (GET_U_1(bp) & 0x0f) + ND_PRINT("[%s] ", + client_fqdn_flags(GET_U_1(bp))); bp++; - if (*bp || *(bp+1)) - ND_PRINT((ndo, "%u/%u ", *bp, *(bp+1))); + if (GET_U_1(bp) || GET_U_1(bp + 1)) + ND_PRINT("%u/%u ", GET_U_1(bp), + GET_U_1(bp + 1)); bp += 2; - ND_PRINT((ndo, "\"")); - if (fn_printn(ndo, bp, len - 3, ndo->ndo_snapend)) { - ND_PRINT((ndo, "\"")); + ND_PRINT("\""); + if (nd_printn(ndo, bp, len - 3, ndo->ndo_snapend)) { + ND_PRINT("\""); goto trunc; } - ND_PRINT((ndo, "\"")); + ND_PRINT("\""); bp += len - 3; len = 0; break; @@ -862,27 +833,28 @@ rfc1048_print(netdissect_options *ndo, /* this option should be at least 1 byte long */ if (len < 1) { - ND_PRINT((ndo, "ERROR: length < 1 bytes")); + ND_PRINT("[ERROR: length < 1 bytes]"); break; } - type = *bp++; + type = GET_U_1(bp); + bp++; len--; if (type == 0) { - ND_PRINT((ndo, "\"")); - if (fn_printn(ndo, bp, len, ndo->ndo_snapend)) { - ND_PRINT((ndo, "\"")); + ND_PRINT("\""); + if (nd_printn(ndo, bp, len, ndo->ndo_snapend)) { + ND_PRINT("\""); goto trunc; } - ND_PRINT((ndo, "\"")); + ND_PRINT("\""); bp += len; len = 0; break; } else { - ND_PRINT((ndo, "%s ", tok2str(arp2str, "hardware-type %u,", type))); + ND_PRINT("%s ", tok2str(arp2str, "hardware-type %u,", type)); while (len > 0) { if (!first) - ND_PRINT((ndo, ":")); - ND_PRINT((ndo, "%02x", *bp)); + ND_PRINT(":"); + ND_PRINT("%02x", GET_U_1(bp)); ++bp; --len; first = 0; @@ -893,28 +865,29 @@ rfc1048_print(netdissect_options *ndo, case TAG_AGENT_CIRCUIT: while (len >= 2) { - subopt = *bp++; - suboptlen = *bp++; + subopt = GET_U_1(bp); + suboptlen = GET_U_1(bp + 1); + bp += 2; len -= 2; if (suboptlen > len) { - ND_PRINT((ndo, "\n\t %s SubOption %u, length %u: length goes past end of option", + ND_PRINT("\n\t %s SubOption %u, length %u: length goes past end of option", tok2str(agent_suboption_values, "Unknown", subopt), subopt, - suboptlen)); + suboptlen); bp += len; len = 0; break; } - ND_PRINT((ndo, "\n\t %s SubOption %u, length %u: ", + ND_PRINT("\n\t %s SubOption %u, length %u: ", tok2str(agent_suboption_values, "Unknown", subopt), subopt, - suboptlen)); + suboptlen); switch (subopt) { case AGENT_SUBOPTION_CIRCUIT_ID: /* fall through */ case AGENT_SUBOPTION_REMOTE_ID: case AGENT_SUBOPTION_SUBSCRIBER_ID: - if (fn_printn(ndo, bp, suboptlen, ndo->ndo_snapend)) + if (nd_printn(ndo, bp, suboptlen, ndo->ndo_snapend)) goto trunc; break; @@ -934,19 +907,20 @@ rfc1048_print(netdissect_options *ndo, /* this option should be at least 5 bytes long */ if (len < 5) { - ND_PRINT((ndo, "ERROR: length < 5 bytes")); + ND_PRINT("[ERROR: length < 5 bytes]"); bp += len; len = 0; break; } while (len > 0) { if (!first) - ND_PRINT((ndo, ",")); - mask_width = *bp++; + ND_PRINT(","); + mask_width = GET_U_1(bp); + bp++; len--; /* mask_width <= 32 */ if (mask_width > 32) { - ND_PRINT((ndo, "[ERROR: Mask width (%d) > 32]", mask_width)); + ND_PRINT("[ERROR: Mask width (%u) > 32]", mask_width); bp += len; len = 0; break; @@ -954,27 +928,28 @@ rfc1048_print(netdissect_options *ndo, significant_octets = (mask_width + 7) / 8; /* significant octets + router(4) */ if (len < significant_octets + 4) { - ND_PRINT((ndo, "[ERROR: Remaining length (%u) < %u bytes]", len, significant_octets + 4)); + ND_PRINT("[ERROR: Remaining length (%u) < %u bytes]", len, significant_octets + 4); bp += len; len = 0; break; } - ND_PRINT((ndo, "(")); + ND_PRINT("("); if (mask_width == 0) - ND_PRINT((ndo, "default")); + ND_PRINT("default"); else { for (i = 0; i < significant_octets ; i++) { if (i > 0) - ND_PRINT((ndo, ".")); - ND_PRINT((ndo, "%d", *bp++)); + ND_PRINT("."); + ND_PRINT("%u", + GET_U_1(bp)); + bp++; } for (i = significant_octets ; i < 4 ; i++) - ND_PRINT((ndo, ".0")); - ND_PRINT((ndo, "/%d", mask_width)); + ND_PRINT(".0"); + ND_PRINT("/%u", mask_width); } - memcpy((char *)&ul, (const char *)bp, sizeof(ul)); - ND_PRINT((ndo, ":%s)", ipaddr_string(ndo, &ul))); - bp += sizeof(ul); + ND_PRINT(":%s)", GET_IPADDR_STRING(bp)); + bp += 4; len -= (significant_octets + 4); first = 0; } @@ -987,35 +962,36 @@ rfc1048_print(netdissect_options *ndo, first = 1; if (len < 2) { - ND_PRINT((ndo, "ERROR: length < 2 bytes")); + ND_PRINT("[ERROR: length < 2 bytes]"); bp += len; len = 0; break; } while (len > 0) { - suboptlen = *bp++; + suboptlen = GET_U_1(bp); + bp++; len--; - ND_PRINT((ndo, "\n\t ")); - ND_PRINT((ndo, "instance#%u: ", suboptnumber)); + ND_PRINT("\n\t "); + ND_PRINT("instance#%u: ", suboptnumber); if (suboptlen == 0) { - ND_PRINT((ndo, "ERROR: suboption length must be non-zero")); + ND_PRINT("[ERROR: suboption length must be non-zero]"); bp += len; len = 0; break; } if (len < suboptlen) { - ND_PRINT((ndo, "ERROR: invalid option")); + ND_PRINT("[ERROR: invalid option]"); bp += len; len = 0; break; } - ND_PRINT((ndo, "\"")); - if (fn_printn(ndo, bp, suboptlen, ndo->ndo_snapend)) { - ND_PRINT((ndo, "\"")); + ND_PRINT("\""); + if (nd_printn(ndo, bp, suboptlen, ndo->ndo_snapend)) { + ND_PRINT("\""); goto trunc; } - ND_PRINT((ndo, "\"")); - ND_PRINT((ndo, ", length %d", suboptlen)); + ND_PRINT("\""); + ND_PRINT(", length %u", suboptlen); suboptnumber++; len -= suboptlen; bp += suboptlen; @@ -1024,8 +1000,8 @@ rfc1048_print(netdissect_options *ndo, } default: - ND_PRINT((ndo, "[unknown special tag %u, size %u]", - tag, len)); + ND_PRINT("[unknown special tag %u, size %u]", + tag, len); bp += len; len = 0; break; @@ -1034,34 +1010,36 @@ rfc1048_print(netdissect_options *ndo, } /* Data left over? */ if (len) { - ND_PRINT((ndo, "\n\t trailing data length %u", len)); + ND_PRINT("\n\t trailing data length %u", len); bp += len; } } return; trunc: - ND_PRINT((ndo, "|[rfc1048]")); + nd_print_trunc(ndo); } +#define PRINTCMUADDR(m, s) { ND_TCHECK_4(cmu->m); \ + if (GET_IPV4_TO_NETWORK_ORDER(cmu->m) != 0) \ + ND_PRINT(" %s:%s", s, GET_IPADDR_STRING(cmu->m)); } + static void cmu_print(netdissect_options *ndo, - register const u_char *bp) + const u_char *bp) { - register const struct cmu_vend *cmu; - -#define PRINTCMUADDR(m, s) { ND_TCHECK(cmu->m); \ - if (cmu->m.s_addr != 0) \ - ND_PRINT((ndo, " %s:%s", s, ipaddr_string(ndo, &cmu->m.s_addr))); } + const struct cmu_vend *cmu; + uint8_t v_flags; - ND_PRINT((ndo, " vend-cmu")); + ND_PRINT(" vend-cmu"); cmu = (const struct cmu_vend *)bp; /* Only print if there are unknown bits */ - ND_TCHECK(cmu->v_flags); - if ((cmu->v_flags & ~(VF_SMASK)) != 0) - ND_PRINT((ndo, " F:0x%x", cmu->v_flags)); + ND_TCHECK_4(cmu->v_flags); + v_flags = GET_U_1(cmu->v_flags); + if ((v_flags & ~(VF_SMASK)) != 0) + ND_PRINT(" F:0x%x", v_flags); PRINTCMUADDR(v_dgate, "DG"); - PRINTCMUADDR(v_smask, cmu->v_flags & VF_SMASK ? "SM" : "SM*"); + PRINTCMUADDR(v_smask, v_flags & VF_SMASK ? "SM" : "SM*"); PRINTCMUADDR(v_dns1, "NS1"); PRINTCMUADDR(v_dns2, "NS2"); PRINTCMUADDR(v_ins1, "IEN1"); @@ -1071,10 +1049,11 @@ cmu_print(netdissect_options *ndo, return; trunc: - ND_PRINT((ndo, "%s", tstr)); -#undef PRINTCMUADDR + nd_print_trunc(ndo); } +#undef PRINTCMUADDR + static char * client_fqdn_flags(u_int flags) { diff --git a/contrib/tcpdump/print-brcmtag.c b/contrib/tcpdump/print-brcmtag.c new file mode 100644 index 0000000000..efc6a1eefa --- /dev/null +++ b/contrib/tcpdump/print-brcmtag.c @@ -0,0 +1,151 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 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. + */ + +/* \summary: Broadcom Ethernet switches tag (4 bytes) printer */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "netdissect-stdinc.h" + +#define ND_LONGJMP_FROM_TCHECK +#include "netdissect.h" +#include "ethertype.h" +#include "addrtoname.h" +#include "extract.h" + +#define ETHER_TYPE_LEN 2 + +#define BRCM_TAG_LEN 4 +#define BRCM_OPCODE_SHIFT 5 +#define BRCM_OPCODE_MASK 0x7 + +/* Ingress fields */ +#define BRCM_IG_TC_SHIFT 2 +#define BRCM_IG_TC_MASK 0x7 +#define BRCM_IG_TE_MASK 0x3 +#define BRCM_IG_TS_SHIFT 7 +#define BRCM_IG_DSTMAP_MASK 0x1ff + +/* Egress fields */ +#define BRCM_EG_CID_MASK 0xff +#define BRCM_EG_RC_MASK 0xff +#define BRCM_EG_RC_RSVD (3 << 6) +#define BRCM_EG_RC_EXCEPTION (1 << 5) +#define BRCM_EG_RC_PROT_SNOOP (1 << 4) +#define BRCM_EG_RC_PROT_TERM (1 << 3) +#define BRCM_EG_RC_SWITCH (1 << 2) +#define BRCM_EG_RC_MAC_LEARN (1 << 1) +#define BRCM_EG_RC_MIRROR (1 << 0) +#define BRCM_EG_TC_SHIFT 5 +#define BRCM_EG_TC_MASK 0x7 +#define BRCM_EG_PID_MASK 0x1f + +static const struct tok brcm_tag_te_values[] = { + { 0, "None" }, + { 1, "Untag" }, + { 2, "Header"}, + { 3, "Reserved" }, + { 0, NULL } +}; + +static const struct tok brcm_tag_rc_values[] = { + { 1, "mirror" }, + { 2, "MAC learning" }, + { 4, "switching" }, + { 8, "prot term" }, + { 16, "prot snoop" }, + { 32, "exception" }, + { 0, NULL } +}; + +static void +brcm_tag_print(netdissect_options *ndo, const u_char *bp) +{ + uint8_t tag[BRCM_TAG_LEN]; + uint16_t dst_map; + unsigned int i; + + for (i = 0; i < BRCM_TAG_LEN; i++) + tag[i] = GET_U_1(bp + i); + + ND_PRINT("BRCM tag OP: %s", tag[0] ? "IG" : "EG"); + if (tag[0] & (1 << BRCM_OPCODE_SHIFT)) { + /* Ingress Broadcom tag */ + ND_PRINT(", TC: %d", (tag[1] >> BRCM_IG_TC_SHIFT) & + BRCM_IG_TC_MASK); + ND_PRINT(", TE: %s", + tok2str(brcm_tag_te_values, "unknown", + (tag[1] & BRCM_IG_TE_MASK))); + ND_PRINT(", TS: %d", tag[1] >> BRCM_IG_TS_SHIFT); + dst_map = (uint16_t)tag[2] << 8 | tag[3]; + ND_PRINT(", DST map: 0x%04x", dst_map & BRCM_IG_DSTMAP_MASK); + } else { + /* Egress Broadcom tag */ + ND_PRINT(", CID: %d", tag[1]); + ND_PRINT(", RC: %s", tok2str(brcm_tag_rc_values, + "reserved", tag[2])); + ND_PRINT(", TC: %d", (tag[3] >> BRCM_EG_TC_SHIFT) & + BRCM_EG_TC_MASK); + ND_PRINT(", port: %d", tag[3] & BRCM_EG_PID_MASK); + } + ND_PRINT(", "); +} + +void +brcm_tag_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, + const u_char *p) +{ + u_int caplen = h->caplen; + u_int length = h->len; + + ndo->ndo_protocol = "brcm-tag"; + ndo->ndo_ll_hdr_len += + ether_switch_tag_print(ndo, p, length, caplen, + brcm_tag_print, BRCM_TAG_LEN); +} + +void +brcm_tag_prepend_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, + const u_char *p) +{ + u_int caplen = h->caplen; + u_int length = h->len; + + ndo->ndo_protocol = "brcm-tag-prepend"; + ND_TCHECK_LEN(p, BRCM_TAG_LEN); + ndo->ndo_ll_hdr_len += BRCM_TAG_LEN; + + if (ndo->ndo_eflag) { + /* Print the prepended Broadcom tag. */ + brcm_tag_print(ndo, p); + } + p += BRCM_TAG_LEN; + length -= BRCM_TAG_LEN; + caplen -= BRCM_TAG_LEN; + + /* + * Now print the Ethernet frame following it. + */ + ndo->ndo_ll_hdr_len += + ether_print(ndo, p, length, caplen, NULL, NULL); +} diff --git a/contrib/tcpdump/print-bt.c b/contrib/tcpdump/print-bt.c index b37f8fa0e3..131bc71196 100644 --- a/contrib/tcpdump/print-bt.c +++ b/contrib/tcpdump/print-bt.c @@ -20,52 +20,52 @@ /* \summary: Bluetooth printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" -#if defined(DLT_BLUETOOTH_HCI_H4_WITH_PHDR) && defined(HAVE_PCAP_BLUETOOTH_H) -#include +#ifdef DLT_BLUETOOTH_HCI_H4_WITH_PHDR + +/* + * Header prepended by libpcap to each bluetooth h4 frame; + * the direction field is in network byte order. + */ +typedef struct _bluetooth_h4_header { + nd_uint32_t direction; /* if first bit is set direction is incoming */ +} bluetooth_h4_header; + +#define BT_HDRLEN sizeof(bluetooth_h4_header) -#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 +void bt_if_print(netdissect_options *ndo, 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; + const bluetooth_h4_header* hdr = (const bluetooth_h4_header*)p; - if (caplen < BT_HDRLEN) { - ND_PRINT((ndo, "[|bt]")); - return (BT_HDRLEN); - } + ndo->ndo_protocol = "bluetooth"; + nd_print_protocol(ndo); + ND_TCHECK_LEN(p, BT_HDRLEN); + ndo->ndo_ll_hdr_len += BT_HDRLEN; caplen -= BT_HDRLEN; length -= BT_HDRLEN; p += BT_HDRLEN; if (ndo->ndo_eflag) - ND_PRINT((ndo, "hci length %d, direction %s, ", length, (EXTRACT_32BITS(&hdr->direction)&0x1)?"in":"out")); + ND_PRINT(", hci length %u, direction %s", length, + (GET_BE_U_4(hdr->direction)&0x1) ? "in" : "out"); if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); - - return (BT_HDRLEN); } #endif - - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/print-calm-fast.c b/contrib/tcpdump/print-calm-fast.c index c9be008cc2..1220d867ec 100644 --- a/contrib/tcpdump/print-calm-fast.c +++ b/contrib/tcpdump/print-calm-fast.c @@ -18,12 +18,14 @@ /* \summary: Communication access for land mobiles (CALM) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" +#include "extract.h" #include "addrtoname.h" /* @@ -39,37 +41,31 @@ void calm_fast_print(netdissect_options *ndo, const u_char *bp, u_int length, const struct lladdr_info *src) { - int srcNwref; - int dstNwref; + ndo->ndo_protocol = "calm_fast"; - ND_TCHECK2(*bp, 2); - if (length < 2) - goto trunc; - srcNwref = bp[0]; - dstNwref = bp[1]; - length -= 2; - bp += 2; - - ND_PRINT((ndo, "CALM FAST")); + ND_PRINT("CALM FAST"); if (src != NULL) - ND_PRINT((ndo, " src:%s", (src->addr_string)(ndo, src->addr))); - ND_PRINT((ndo, "; ")); - ND_PRINT((ndo, "SrcNwref:%d; ", srcNwref)); - ND_PRINT((ndo, "DstNwref:%d; ", dstNwref)); + ND_PRINT(" src:%s", (src->addr_string)(ndo, src->addr)); + ND_PRINT("; "); + + if (length < 2) { + ND_PRINT(" (length %u < 2)", length); + goto invalid; + } + + ND_PRINT("SrcNwref:%u; ", GET_U_1(bp)); + length -= 1; + bp += 1; + + ND_PRINT("DstNwref:%u; ", GET_U_1(bp)); + length -= 1; + bp += 1; if (ndo->ndo_vflag) ND_DEFAULTPRINT(bp, length); return; -trunc: - ND_PRINT((ndo, "[|calm fast]")); - return; +invalid: + nd_print_invalid(ndo); + ND_TCHECK_LEN(bp, length); } - - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/print-carp.c b/contrib/tcpdump/print-carp.c index c650d181b0..75f506685f 100644 --- a/contrib/tcpdump/print-carp.c +++ b/contrib/tcpdump/print-carp.c @@ -37,47 +37,42 @@ /* \summary: Common Address Redundancy Protocol (CARP) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" /* for checksum structure and functions */ #include "extract.h" void -carp_print(netdissect_options *ndo, register const u_char *bp, register u_int len, int ttl) +carp_print(netdissect_options *ndo, const u_char *bp, u_int len, u_int ttl) { - int version, type; + u_int version, type; const char *type_s; - ND_TCHECK(bp[0]); - version = (bp[0] & 0xf0) >> 4; - type = bp[0] & 0x0f; + ndo->ndo_protocol = "carp"; + version = (GET_U_1(bp) & 0xf0) >> 4; + type = GET_U_1(bp) & 0x0f; if (type == 1) type_s = "advertise"; else type_s = "unknown"; - ND_PRINT((ndo, "CARPv%d-%s %d: ", version, type_s, len)); + ND_PRINT("CARPv%u-%s %u: ", version, type_s, len); if (ttl != 255) - ND_PRINT((ndo, "[ttl=%d!] ", ttl)); + ND_PRINT("[ttl=%u!] ", ttl); if (version != 2 || type != 1) return; - ND_TCHECK(bp[2]); - ND_TCHECK(bp[5]); - ND_PRINT((ndo, "vhid=%d advbase=%d advskew=%d authlen=%d ", - bp[1], bp[5], bp[2], bp[3])); + ND_PRINT("vhid=%u advbase=%u advskew=%u authlen=%u ", + GET_U_1(bp + 1), GET_U_1(bp + 5), GET_U_1(bp + 2), + GET_U_1(bp + 3)); if (ndo->ndo_vflag) { struct cksum_vec vec[1]; vec[0].ptr = (const uint8_t *)bp; vec[0].len = len; - if (ND_TTEST2(bp[0], len) && in_cksum(vec, 1)) - ND_PRINT((ndo, " (bad carp cksum %x!)", - EXTRACT_16BITS(&bp[6]))); + if (ND_TTEST_LEN(bp, len) && in_cksum(vec, 1)) + ND_PRINT(" (bad carp cksum %x!)", + GET_BE_U_2(bp + 6)); } - ND_PRINT((ndo, "counter=%" PRIu64, EXTRACT_64BITS(&bp[8]))); - - return; -trunc: - ND_PRINT((ndo, "[|carp]")); + ND_PRINT("counter=%" PRIu64, GET_BE_U_8(bp + 8)); } diff --git a/contrib/tcpdump/print-cdp.c b/contrib/tcpdump/print-cdp.c index 6f8f356736..9f5c24bca6 100644 --- a/contrib/tcpdump/print-cdp.c +++ b/contrib/tcpdump/print-cdp.c @@ -21,25 +21,25 @@ * Code by Gert Doering, SpaceNet GmbH, gert@space.net * * Reference documentation: - * http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm + * https://web.archive.org/web/20000914194913/http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.pdf */ /* \summary: Cisco Discovery Protocol (CDP) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "addrtoname.h" #include "extract.h" #include "nlpid.h" -static const char tstr[] = "[|cdp]"; #define CDP_HEADER_LEN 4 #define CDP_HEADER_VERSION_OFFSET 0 @@ -50,31 +50,6 @@ static const char tstr[] = "[|cdp]"; #define CDP_TLV_TYPE_OFFSET 0 #define CDP_TLV_LEN_OFFSET 2 -static const struct tok cdp_tlv_values[] = { - { 0x01, "Device-ID"}, - { 0x02, "Address"}, - { 0x03, "Port-ID"}, - { 0x04, "Capability"}, - { 0x05, "Version String"}, - { 0x06, "Platform"}, - { 0x07, "Prefixes"}, - { 0x08, "Protocol-Hello option"}, - { 0x09, "VTP Management Domain"}, - { 0x0a, "Native VLAN ID"}, - { 0x0b, "Duplex"}, - { 0x0e, "ATA-186 VoIP VLAN request"}, - { 0x0f, "ATA-186 VoIP VLAN assignment"}, - { 0x10, "power consumption"}, - { 0x11, "MTU"}, - { 0x12, "AVVID trust bitmap"}, - { 0x13, "AVVID untrusted ports CoS"}, - { 0x14, "System Name"}, - { 0x15, "System Object ID (not decoded)"}, - { 0x16, "Management Addresses"}, - { 0x17, "Physical Location"}, - { 0, NULL} -}; - static const struct tok cdp_capability_values[] = { { 0x01, "Router" }, { 0x02, "Transparent Bridge" }, @@ -86,182 +61,268 @@ static const struct tok cdp_capability_values[] = { { 0, NULL } }; -static int cdp_print_addr(netdissect_options *, const u_char *, int); -static int cdp_print_prefixes(netdissect_options *, const u_char *, int); -static unsigned long cdp_get_number(const u_char *, int); +static void cdp_print_addr(netdissect_options *, const u_char *, u_int); +static void cdp_print_prefixes(netdissect_options *, const u_char *, u_int); -void -cdp_print(netdissect_options *ndo, - const u_char *pptr, u_int length, u_int caplen) +static void +cdp_print_string(netdissect_options *ndo, + const u_char *cp, const u_int len) { - int type, len, i, j; - const u_char *tptr; + ND_PRINT("'"); + (void)nd_printn(ndo, cp, len, NULL); + ND_PRINT("'"); +} - if (caplen < CDP_HEADER_LEN) { - ND_PRINT((ndo, "%s", tstr)); - return; +static void +cdp_print_power(netdissect_options *ndo, + const u_char *cp, const u_int len) +{ + u_int val = 0; + + switch (len) { + case 1: + val = GET_U_1(cp); + break; + case 2: + val = GET_BE_U_2(cp); + break; + case 3: + val = GET_BE_U_3(cp); + break; } + ND_PRINT("%1.2fW", val / 1000.0); +} - tptr = pptr; /* temporary pointer */ +static void +cdp_print_capability(netdissect_options *ndo, + const u_char *cp, const u_int len _U_) +{ + uint32_t val = GET_BE_U_4(cp); + + ND_PRINT("(0x%08x): %s", val, + bittok2str(cdp_capability_values, "none", val)); +} + +/* Rework the version string to get a nice indentation. */ +static void +cdp_print_version(netdissect_options *ndo, + const u_char *cp, const u_int len) +{ + unsigned i; + + ND_PRINT("\n\t "); + for (i = 0; i < len; i++) { + u_char c = GET_U_1(cp + i); + + if (c == '\n') + ND_PRINT("\n\t "); + else + fn_print_char(ndo, c); + } +} + +static void +cdp_print_uint16(netdissect_options *ndo, + const u_char *cp, const u_int len _U_) +{ + ND_PRINT("%u", GET_BE_U_2(cp)); +} + +static void +cdp_print_duplex(netdissect_options *ndo, + const u_char *cp, const u_int len _U_) +{ + ND_PRINT("%s", GET_U_1(cp) ? "full": "half"); +} + +/* https://www.cisco.com/c/en/us/td/docs/voice_ip_comm/cata/186/2_12_m/english/release/notes/186rn21m.html +* plus more details from other sources +* +* There are apparently versions of the request with both +* 2 bytes and 3 bytes of value. The 3 bytes of value +* appear to be a 1-byte application type followed by a +* 2-byte VLAN ID; the 2 bytes of value are unknown +* (they're 0x20 0x00 in some captures I've seen; that +* is not a valid VLAN ID, as VLAN IDs are 12 bits). +* +* The replies all appear to be 3 bytes long. +*/ +static void +cdp_print_ata186(netdissect_options *ndo, + const u_char *cp, const u_int len) +{ + if (len == 2) + ND_PRINT("unknown 0x%04x", GET_BE_U_2(cp)); + else + ND_PRINT("app %u, vlan %u", GET_U_1(cp), GET_BE_U_2(cp + 1)); +} + +static void +cdp_print_mtu(netdissect_options *ndo, + const u_char *cp, const u_int len _U_) +{ + ND_PRINT("%u bytes", GET_BE_U_4(cp)); +} + +static void +cdp_print_uint8x(netdissect_options *ndo, + const u_char *cp, const u_int len _U_) +{ + ND_PRINT("0x%02x", GET_U_1(cp)); +} + +static void +cdp_print_phys_loc(netdissect_options *ndo, + const u_char *cp, const u_int len) +{ + ND_PRINT("0x%02x", GET_U_1(cp)); + if (len > 1) { + ND_PRINT("/"); + (void)nd_printn(ndo, cp + 1, len - 1, NULL); + } +} + +struct cdp_tlvinfo { + const char *name; + void (*printer)(netdissect_options *ndo, const u_char *, u_int); + int min_len, max_len; +}; - ND_TCHECK2(*tptr, CDP_HEADER_LEN); - ND_PRINT((ndo, "CDPv%u, ttl: %us", *(tptr + CDP_HEADER_VERSION_OFFSET), - *(tptr + CDP_HEADER_TTL_OFFSET))); +#define T_DEV_ID 0x01 +#define T_MAX 0x17 +static const struct cdp_tlvinfo cdptlvs[T_MAX + 1] = { + /* 0x00 */ + [ T_DEV_ID ] = { "Device-ID", cdp_print_string, -1, -1 }, + [ 0x02 ] = { "Address", cdp_print_addr, -1, -1 }, + [ 0x03 ] = { "Port-ID", cdp_print_string, -1, -1 }, + [ 0x04 ] = { "Capability", cdp_print_capability, 4, 4 }, + [ 0x05 ] = { "Version String", cdp_print_version, -1, -1 }, + [ 0x06 ] = { "Platform", cdp_print_string, -1, -1 }, + [ 0x07 ] = { "Prefixes", cdp_print_prefixes, -1, -1 }, + /* not documented */ + [ 0x08 ] = { "Protocol-Hello option", NULL, -1, -1 }, + /* CDPv2 */ + [ 0x09 ] = { "VTP Management Domain", cdp_print_string, -1, -1 }, + /* CDPv2 */ + [ 0x0a ] = { "Native VLAN ID", cdp_print_uint16, 2, 2 }, + /* CDPv2 */ + [ 0x0b ] = { "Duplex", cdp_print_duplex, 1, 1 }, + /* 0x0c */ + /* 0x0d */ + /* incomplete doc. */ + [ 0x0e ] = { "ATA-186 VoIP VLAN assignment", cdp_print_ata186, 3, 3 }, + /* incomplete doc. */ + [ 0x0f ] = { "ATA-186 VoIP VLAN request", cdp_print_ata186, 2, 3 }, + /* not documented */ + [ 0x10 ] = { "power consumption", cdp_print_power, 1, 3 }, + /* not documented */ + [ 0x11 ] = { "MTU", cdp_print_mtu, 4, 4 }, + /* not documented */ + [ 0x12 ] = { "AVVID trust bitmap", cdp_print_uint8x, 1, 1 }, + /* not documented */ + [ 0x13 ] = { "AVVID untrusted ports CoS", cdp_print_uint8x, 1, 1 }, + /* not documented */ + [ 0x14 ] = { "System Name", cdp_print_string, -1, -1 }, + /* not documented */ + [ 0x15 ] = { "System Object ID (not decoded)", NULL, -1, -1 }, + [ 0x16 ] = { "Management Addresses", cdp_print_addr, 4, -1 }, + /* not documented */ + [ 0x17 ] = { "Physical Location", cdp_print_phys_loc, 1, -1 }, +}; + +void +cdp_print(netdissect_options *ndo, + const u_char *tptr, u_int length) +{ + u_int orig_length = length; + uint16_t checksum; + + ndo->ndo_protocol = "cdp"; + + if (length < CDP_HEADER_LEN) { + ND_PRINT(" (packet length %u < %u)", length, CDP_HEADER_LEN); + goto invalid; + } + ND_PRINT("CDPv%u, ttl: %us", + GET_U_1(tptr + CDP_HEADER_VERSION_OFFSET), + GET_U_1(tptr + CDP_HEADER_TTL_OFFSET)); + checksum = GET_BE_U_2(tptr + CDP_HEADER_CHECKSUM_OFFSET); if (ndo->ndo_vflag) - ND_PRINT((ndo, ", checksum: 0x%04x (unverified), length %u", EXTRACT_16BITS(tptr+CDP_HEADER_CHECKSUM_OFFSET), length)); + ND_PRINT(", checksum: 0x%04x (unverified), length %u", + checksum, orig_length); tptr += CDP_HEADER_LEN; - - while (tptr < (pptr+length)) { - ND_TCHECK2(*tptr, CDP_TLV_HEADER_LEN); /* read out Type and Length */ - type = EXTRACT_16BITS(tptr+CDP_TLV_TYPE_OFFSET); - len = EXTRACT_16BITS(tptr+CDP_TLV_LEN_OFFSET); /* object length includes the 4 bytes header length */ + length -= CDP_HEADER_LEN; + + while (length) { + u_int type, len; + const struct cdp_tlvinfo *info; + const char *name; + u_char covered = 0; + + if (length < CDP_TLV_HEADER_LEN) { + ND_PRINT(" (remaining packet length %u < %u)", + length, CDP_TLV_HEADER_LEN); + goto invalid; + } + type = GET_BE_U_2(tptr + CDP_TLV_TYPE_OFFSET); + len = GET_BE_U_2(tptr + CDP_TLV_LEN_OFFSET); /* object length includes the 4 bytes header length */ + info = type <= T_MAX ? &cdptlvs[type] : NULL; + name = (info && info->name) ? info->name : "unknown field type"; if (len < CDP_TLV_HEADER_LEN) { - if (ndo->ndo_vflag) - ND_PRINT((ndo, "\n\t%s (0x%02x), TLV length: %u byte%s (too short)", - tok2str(cdp_tlv_values,"unknown field type", type), - type, - len, - PLURAL_SUFFIX(len))); /* plural */ - else - ND_PRINT((ndo, ", %s TLV length %u too short", - tok2str(cdp_tlv_values,"unknown field type", type), - len)); - break; + if (ndo->ndo_vflag) + ND_PRINT("\n\t%s (0x%02x), TLV length: %u byte%s (too short)", + name, type, len, PLURAL_SUFFIX(len)); + else + ND_PRINT(", %s TLV length %u too short", + name, len); + goto invalid; + } + if (len > length) { + ND_PRINT(" (TLV length %u > %u)", len, length); + goto invalid; } tptr += CDP_TLV_HEADER_LEN; + length -= CDP_TLV_HEADER_LEN; len -= CDP_TLV_HEADER_LEN; - ND_TCHECK2(*tptr, len); - - if (ndo->ndo_vflag || type == 1) { /* in non-verbose mode just print Device-ID */ - - if (ndo->ndo_vflag) - ND_PRINT((ndo, "\n\t%s (0x%02x), value length: %u byte%s: ", - tok2str(cdp_tlv_values,"unknown field type", type), - type, - len, - PLURAL_SUFFIX(len))); /* plural */ - - switch (type) { - - case 0x01: /* Device-ID */ - if (!ndo->ndo_vflag) - ND_PRINT((ndo, ", Device-ID ")); - ND_PRINT((ndo, "'")); - (void)fn_printn(ndo, tptr, len, NULL); - ND_PRINT((ndo, "'")); - break; - case 0x02: /* Address */ - if (cdp_print_addr(ndo, tptr, len) < 0) - goto trunc; - break; - case 0x03: /* Port-ID */ - ND_PRINT((ndo, "'")); - (void)fn_printn(ndo, tptr, len, NULL); - ND_PRINT((ndo, "'")); - break; - case 0x04: /* Capabilities */ - if (len < 4) - goto trunc; - ND_PRINT((ndo, "(0x%08x): %s", - EXTRACT_32BITS(tptr), - bittok2str(cdp_capability_values, "none", EXTRACT_32BITS(tptr)))); - break; - case 0x05: /* Version */ - ND_PRINT((ndo, "\n\t ")); - for (i=0;i 1) { - ND_PRINT((ndo, "/")); - (void)fn_printn(ndo, tptr + 1, len - 1, NULL); + /* In non-verbose mode just print Device-ID. */ + if (!ndo->ndo_vflag && type == T_DEV_ID) + ND_PRINT(", Device-ID "); + else if (ndo->ndo_vflag) + ND_PRINT("\n\t%s (0x%02x), value length: %u byte%s: ", + name, type, len, PLURAL_SUFFIX(len)); + + if (info) { + if ((info->min_len > 0 && len < (unsigned)info->min_len) || + (info->max_len > 0 && len > (unsigned)info->max_len)) + ND_PRINT(" (malformed TLV)"); + else if (ndo->ndo_vflag || type == T_DEV_ID) { + if (info->printer) + info->printer(ndo, tptr, len); + else + ND_TCHECK_LEN(tptr, len); + /* + * When the type is defined without a printer, + * do not print the hex dump. + */ + covered = 1; } - break; - default: + } + + if (!covered) { + ND_TCHECK_LEN(tptr, len); print_unknown_data(ndo, tptr, "\n\t ", len); - break; - } } - tptr = tptr+len; + tptr += len; + length -= len; } if (ndo->ndo_vflag < 1) - ND_PRINT((ndo, ", length %u", caplen)); + ND_PRINT(", length %u", orig_length); return; -trunc: - ND_PRINT((ndo, "%s", tstr)); +invalid: + nd_print_invalid(ndo); + ND_TCHECK_LEN(tptr, length); } /* @@ -275,130 +336,137 @@ trunc: #define PT_NLPID 1 /* OSI NLPID */ #define PT_IEEE_802_2 2 /* IEEE 802.2 LLC header */ -static int +static void cdp_print_addr(netdissect_options *ndo, - const u_char * p, int l) + const u_char * p, u_int l) { - int pt, pl, al, num; - const u_char *endp = p + l; + u_int num; static const u_char prot_ipv6[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x86, 0xdd }; - ND_TCHECK2(*p, 4); - if (p + 4 > endp) - goto trunc; - num = EXTRACT_32BITS(p); + if (l < 4) { + ND_PRINT(" (not enough space for num)"); + goto invalid; + } + num = GET_BE_U_4(p); p += 4; + l -= 4; + + while (num) { + u_int pt, pl, al; - while (p < endp && num >= 0) { - ND_TCHECK2(*p, 2); - if (p + 2 > endp) - goto trunc; - pt = p[0]; /* type of "protocol" field */ - pl = p[1]; /* length of "protocol" field */ + if (l < 2) { + ND_PRINT(" (not enough space for PT+PL)"); + goto invalid; + } + pt = GET_U_1(p); /* type of "protocol" field */ + pl = GET_U_1(p + 1); /* length of "protocol" field */ p += 2; + l -= 2; - ND_TCHECK2(p[pl], 2); - if (p + pl + 2 > endp) - goto trunc; - al = EXTRACT_16BITS(&p[pl]); /* address length */ + if (l < pl + 2) { + ND_PRINT(" (not enough space for P+AL)"); + goto invalid; + } + /* Skip the protocol for now. */ + al = GET_BE_U_2(p + pl); /* address length */ - if (pt == PT_NLPID && pl == 1 && *p == NLPID_IP && al == 4) { + if (pt == PT_NLPID && pl == 1 && GET_U_1(p) == NLPID_IP && + al == 4) { /* * IPv4: protocol type = NLPID, protocol length = 1 * (1-byte NLPID), protocol = 0xcc (NLPID for IPv4), * address length = 4 */ - p += 3; - - ND_TCHECK2(*p, 4); - if (p + 4 > endp) - goto trunc; - ND_PRINT((ndo, "IPv4 (%u) %s", num, ipaddr_string(ndo, p))); - p += 4; + p += pl + 2; + l -= pl + 2; + /* p is just beyond al now. */ + if (l < al) { + ND_PRINT(" (not enough space for A)"); + goto invalid; + } + ND_PRINT("IPv4 (%u) %s", num, GET_IPADDR_STRING(p)); + p += al; + l -= al; } else if (pt == PT_IEEE_802_2 && pl == 8 && - memcmp(p, prot_ipv6, 8) == 0 && al == 16) { + memcmp(p, prot_ipv6, 8) == 0 && al == 16) { /* * IPv6: protocol type = IEEE 802.2 header, * protocol length = 8 (size of LLC+SNAP header), * protocol = LLC+SNAP header with the IPv6 * Ethertype, address length = 16 */ - p += 10; - ND_TCHECK2(*p, al); - if (p + al > endp) - goto trunc; - - ND_PRINT((ndo, "IPv6 (%u) %s", num, ip6addr_string(ndo, p))); + p += pl + 2; + l -= pl + 2; + /* p is just beyond al now. */ + if (l < al) { + ND_PRINT(" (not enough space for A)"); + goto invalid; + } + ND_PRINT("IPv6 (%u) %s", num, GET_IP6ADDR_STRING(p)); p += al; + l -= al; } else { /* * Generic case: just print raw data */ - ND_TCHECK2(*p, pl); - if (p + pl > endp) - goto trunc; - ND_PRINT((ndo, "pt=0x%02x, pl=%d, pb=", *(p - 2), pl)); - while (pl-- > 0) - ND_PRINT((ndo, " %02x", *p++)); - ND_TCHECK2(*p, 2); - if (p + 2 > endp) - goto trunc; - al = (*p << 8) + *(p + 1); - ND_PRINT((ndo, ", al=%d, a=", al)); + ND_PRINT("pt=0x%02x, pl=%u, pb=", pt, pl); + while (pl != 0) { + ND_PRINT(" %02x", GET_U_1(p)); + p++; + l--; + pl--; + } + ND_PRINT(", al=%u, a=", al); p += 2; - ND_TCHECK2(*p, al); - if (p + al > endp) - goto trunc; - while (al-- > 0) - ND_PRINT((ndo, " %02x", *p++)); + l -= 2; + /* p is just beyond al now. */ + if (l < al) { + ND_PRINT(" (not enough space for A)"); + goto invalid; + } + while (al != 0) { + ND_PRINT(" %02x", GET_U_1(p)); + p++; + l--; + al--; + } } num--; if (num) - ND_PRINT((ndo, " ")); + ND_PRINT(" "); } + if (l) + ND_PRINT(" (%u bytes of stray data)", l); + return; - return 0; - -trunc: - return -1; +invalid: + ND_TCHECK_LEN(p, l); } - -static int +static void cdp_print_prefixes(netdissect_options *ndo, - const u_char * p, int l) + const u_char * p, u_int l) { - if (l % 5) - goto trunc; + if (l % 5) { + ND_PRINT(" [length %u is not a multiple of 5]", l); + goto invalid; + } - ND_PRINT((ndo, " IPv4 Prefixes (%d):", l / 5)); + ND_PRINT(" IPv4 Prefixes (%u):", l / 5); while (l > 0) { - ND_PRINT((ndo, " %u.%u.%u.%u/%u", p[0], p[1], p[2], p[3], p[4])); + ND_PRINT(" %u.%u.%u.%u/%u", + GET_U_1(p), GET_U_1(p + 1), GET_U_1(p + 2), + GET_U_1(p + 3), GET_U_1(p + 4)); l -= 5; p += 5; } + return; - return 0; - -trunc: - return -1; -} - -/* read in a -byte number, MSB first - * (of course this can handle max sizeof(long)) - */ -static unsigned long cdp_get_number(const u_char * p, int l) -{ - unsigned long res=0; - while( l>0 ) - { - res = (res<<8) + *p; - p++; l--; - } - return res; +invalid: + ND_TCHECK_LEN(p, l); } diff --git a/contrib/tcpdump/print-cfm.c b/contrib/tcpdump/print-cfm.c index bad4add337..e950719e69 100644 --- a/contrib/tcpdump/print-cfm.c +++ b/contrib/tcpdump/print-cfm.c @@ -18,29 +18,27 @@ /* \summary: IEEE 802.1ag Connectivity Fault Management (CFM) protocols printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include - -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "extract.h" -#include "ether.h" #include "addrtoname.h" #include "oui.h" #include "af.h" + struct cfm_common_header_t { - uint8_t mdlevel_version; - uint8_t opcode; - uint8_t flags; - uint8_t first_tlv_offset; + nd_uint8_t mdlevel_version; + nd_uint8_t opcode; + nd_uint8_t flags; + nd_uint8_t first_tlv_offset; }; #define CFM_VERSION 0 -#define CFM_EXTRACT_VERSION(x) (((x)&0x1f)) +#define CFM_EXTRACT_VERSION(x) ((x)&0x1f) #define CFM_EXTRACT_MD_LEVEL(x) (((x)&0xe0)>>5) #define CFM_OPCODE_CCM 1 @@ -50,7 +48,7 @@ struct cfm_common_header_t { #define CFM_OPCODE_LTM 5 static const struct tok cfm_opcode_values[] = { - { CFM_OPCODE_CCM, "Continouity Check Message"}, + { CFM_OPCODE_CCM, "Continuity Check Message"}, { CFM_OPCODE_LBR, "Loopback Reply"}, { CFM_OPCODE_LBM, "Loopback Message"}, { CFM_OPCODE_LTR, "Linktrace Reply"}, @@ -62,22 +60,22 @@ static const struct tok cfm_opcode_values[] = { * Message Formats. */ struct cfm_ccm_t { - uint8_t sequence[4]; - uint8_t ma_epi[2]; - uint8_t names[48]; - uint8_t itu_t_y_1731[16]; + nd_uint32_t sequence; + nd_uint16_t ma_epi; + nd_byte names[48]; + nd_byte itu_t_y_1731[16]; }; /* * Timer Bases for the CCM Interval field. * Expressed in units of seconds. */ -static const float ccm_interval_base[8] = {0, 0.003333, 0.01, 0.1, 1, 10, 60, 600}; +static const float ccm_interval_base[8] = {0.0f, 0.003333f, 0.01f, 0.1f, 1.0f, 10.0f, 60.0f, 600.0f}; #define CCM_INTERVAL_MIN_MULTIPLIER 3.25 #define CCM_INTERVAL_MAX_MULTIPLIER 3.5 #define CFM_CCM_RDI_FLAG 0x80 -#define CFM_EXTRACT_CCM_INTERVAL(x) (((x)&0x07)) +#define CFM_EXTRACT_CCM_INTERVAL(x) ((x)&0x07) #define CFM_CCM_MD_FORMAT_8021 0 #define CFM_CCM_MD_FORMAT_NONE 1 @@ -110,14 +108,14 @@ static const struct tok cfm_ma_nameformat_values[] = { }; struct cfm_lbm_t { - uint8_t transaction_id[4]; + nd_uint32_t transaction_id; }; struct cfm_ltm_t { - uint8_t transaction_id[4]; - uint8_t ttl; - uint8_t original_mac[ETHER_ADDR_LEN]; - uint8_t target_mac[ETHER_ADDR_LEN]; + nd_uint32_t transaction_id; + nd_uint8_t ttl; + nd_mac_addr original_mac; + nd_mac_addr target_mac; }; static const struct tok cfm_ltm_flag_values[] = { @@ -126,9 +124,9 @@ static const struct tok cfm_ltm_flag_values[] = { }; struct cfm_ltr_t { - uint8_t transaction_id[4]; - uint8_t ttl; - uint8_t replay_action; + nd_uint32_t transaction_id; + nd_uint8_t ttl; + nd_uint8_t replay_action; }; static const struct tok cfm_ltr_flag_values[] = { @@ -172,8 +170,8 @@ static const struct tok cfm_tlv_values[] = { */ struct cfm_tlv_header_t { - uint8_t type; - uint8_t length[2]; + nd_uint8_t type; + nd_uint16_t length; }; /* FIXME define TLV formats */ @@ -217,25 +215,25 @@ static const struct tok cfm_tlv_senderid_chassisid_values[] = { static int cfm_network_addr_print(netdissect_options *ndo, - register const u_char *tptr, const u_int length) + const u_char *tptr, const u_int length) { u_int network_addr_type; u_int hexdump = FALSE; /* - * Altough AFIs are tpically 2 octects wide, + * Although AFIs are typically 2 octets wide, * 802.1ab specifies that this field width - * is only once octet + * is only one octet. */ if (length < 1) { - ND_PRINT((ndo, "\n\t Network Address Type (invalid, no data")); + ND_PRINT("\n\t Network Address Type (invalid, no data"); return hexdump; } /* The calling function must make any due ND_TCHECK calls. */ - network_addr_type = *tptr; - ND_PRINT((ndo, "\n\t Network Address Type %s (%u)", + network_addr_type = GET_U_1(tptr); + ND_PRINT("\n\t Network Address Type %s (%u)", tok2str(af_values, "Unknown", network_addr_type), - network_addr_type)); + network_addr_type); /* * Resolve the passed in Address. @@ -243,20 +241,20 @@ cfm_network_addr_print(netdissect_options *ndo, switch(network_addr_type) { case AFNUM_INET: if (length != 1 + 4) { - ND_PRINT((ndo, "(invalid IPv4 address length %u)", length - 1)); + ND_PRINT("(invalid IPv4 address length %u)", length - 1); hexdump = TRUE; break; } - ND_PRINT((ndo, ", %s", ipaddr_string(ndo, tptr + 1))); + ND_PRINT(", %s", GET_IPADDR_STRING(tptr + 1)); break; case AFNUM_INET6: if (length != 1 + 16) { - ND_PRINT((ndo, "(invalid IPv6 address length %u)", length - 1)); + ND_PRINT("(invalid IPv6 address length %u)", length - 1); hexdump = TRUE; break; } - ND_PRINT((ndo, ", %s", ip6addr_string(ndo, tptr + 1))); + ND_PRINT(", %s", GET_IP6ADDR_STRING(tptr + 1)); break; default: @@ -269,9 +267,10 @@ cfm_network_addr_print(netdissect_options *ndo, void cfm_print(netdissect_options *ndo, - register const u_char *pptr, register u_int length) + const u_char *pptr, u_int length) { const struct cfm_common_header_t *cfm_common_header; + uint8_t mdlevel_version, opcode, flags, first_tlv_offset; const struct cfm_tlv_header_t *cfm_tlv_header; const uint8_t *tptr, *tlv_ptr; const uint8_t *namesp; @@ -290,26 +289,29 @@ cfm_print(netdissect_options *ndo, const struct cfm_ltr_t *cfm_ltr; } msg_ptr; + ndo->ndo_protocol = "cfm"; tptr=pptr; cfm_common_header = (const struct cfm_common_header_t *)pptr; if (length < sizeof(*cfm_common_header)) goto tooshort; - ND_TCHECK(*cfm_common_header); + ND_TCHECK_SIZE(cfm_common_header); /* * Sanity checking of the header. */ - if (CFM_EXTRACT_VERSION(cfm_common_header->mdlevel_version) != CFM_VERSION) { - ND_PRINT((ndo, "CFMv%u not supported, length %u", - CFM_EXTRACT_VERSION(cfm_common_header->mdlevel_version), length)); + mdlevel_version = GET_U_1(cfm_common_header->mdlevel_version); + if (CFM_EXTRACT_VERSION(mdlevel_version) != CFM_VERSION) { + ND_PRINT("CFMv%u not supported, length %u", + CFM_EXTRACT_VERSION(mdlevel_version), length); return; } - ND_PRINT((ndo, "CFMv%u %s, MD Level %u, length %u", - CFM_EXTRACT_VERSION(cfm_common_header->mdlevel_version), - tok2str(cfm_opcode_values, "unknown (%u)", cfm_common_header->opcode), - CFM_EXTRACT_MD_LEVEL(cfm_common_header->mdlevel_version), - length)); + opcode = GET_U_1(cfm_common_header->opcode); + ND_PRINT("CFMv%u %s, MD Level %u, length %u", + CFM_EXTRACT_VERSION(mdlevel_version), + tok2str(cfm_opcode_values, "unknown (%u)", opcode), + CFM_EXTRACT_MD_LEVEL(mdlevel_version), + length); /* * In non-verbose mode just print the opcode and md-level. @@ -318,51 +320,53 @@ cfm_print(netdissect_options *ndo, return; } - ND_PRINT((ndo, "\n\tFirst TLV offset %u", cfm_common_header->first_tlv_offset)); + flags = GET_U_1(cfm_common_header->flags); + first_tlv_offset = GET_U_1(cfm_common_header->first_tlv_offset); + ND_PRINT("\n\tFirst TLV offset %u", first_tlv_offset); - tptr += sizeof(const struct cfm_common_header_t); + tptr += sizeof(struct cfm_common_header_t); tlen = length - sizeof(struct cfm_common_header_t); /* * Sanity check the first TLV offset. */ - if (cfm_common_header->first_tlv_offset > tlen) { - ND_PRINT((ndo, " (too large, must be <= %u)", tlen)); + if (first_tlv_offset > tlen) { + ND_PRINT(" (too large, must be <= %u)", tlen); return; } - switch (cfm_common_header->opcode) { + switch (opcode) { case CFM_OPCODE_CCM: msg_ptr.cfm_ccm = (const struct cfm_ccm_t *)tptr; - if (cfm_common_header->first_tlv_offset < sizeof(*msg_ptr.cfm_ccm)) { - ND_PRINT((ndo, " (too small 1, must be >= %lu)", - (unsigned long) sizeof(*msg_ptr.cfm_ccm))); + if (first_tlv_offset < sizeof(*msg_ptr.cfm_ccm)) { + ND_PRINT(" (too small 1, must be >= %zu)", + sizeof(*msg_ptr.cfm_ccm)); return; } if (tlen < sizeof(*msg_ptr.cfm_ccm)) goto tooshort; - ND_TCHECK(*msg_ptr.cfm_ccm); + ND_TCHECK_SIZE(msg_ptr.cfm_ccm); - ccm_interval = CFM_EXTRACT_CCM_INTERVAL(cfm_common_header->flags); - ND_PRINT((ndo, ", Flags [CCM Interval %u%s]", + ccm_interval = CFM_EXTRACT_CCM_INTERVAL(flags); + ND_PRINT(", Flags [CCM Interval %u%s]", ccm_interval, - cfm_common_header->flags & CFM_CCM_RDI_FLAG ? - ", RDI" : "")); + flags & CFM_CCM_RDI_FLAG ? + ", RDI" : ""); /* * Resolve the CCM interval field. */ if (ccm_interval) { - ND_PRINT((ndo, "\n\t CCM Interval %.3fs" + ND_PRINT("\n\t CCM Interval %.3fs" ", min CCM Lifetime %.3fs, max CCM Lifetime %.3fs", ccm_interval_base[ccm_interval], ccm_interval_base[ccm_interval] * CCM_INTERVAL_MIN_MULTIPLIER, - ccm_interval_base[ccm_interval] * CCM_INTERVAL_MAX_MULTIPLIER)); + ccm_interval_base[ccm_interval] * CCM_INTERVAL_MAX_MULTIPLIER); } - ND_PRINT((ndo, "\n\t Sequence Number 0x%08x, MA-End-Point-ID 0x%04x", - EXTRACT_32BITS(msg_ptr.cfm_ccm->sequence), - EXTRACT_16BITS(msg_ptr.cfm_ccm->ma_epi))); + ND_PRINT("\n\t Sequence Number 0x%08x, MA-End-Point-ID 0x%04x", + GET_BE_U_4(msg_ptr.cfm_ccm->sequence), + GET_BE_U_2(msg_ptr.cfm_ccm->ma_epi)); namesp = msg_ptr.cfm_ccm->names; names_data_remaining = sizeof(msg_ptr.cfm_ccm->names); @@ -370,42 +374,41 @@ cfm_print(netdissect_options *ndo, /* * Resolve the MD fields. */ - md_nameformat = *namesp; + md_nameformat = GET_U_1(namesp); namesp++; names_data_remaining--; /* We know this is != 0 */ if (md_nameformat != CFM_CCM_MD_FORMAT_NONE) { - md_namelength = *namesp; + md_namelength = GET_U_1(namesp); namesp++; names_data_remaining--; /* We know this is !=0 */ - ND_PRINT((ndo, "\n\t MD Name Format %s (%u), MD Name length %u", + ND_PRINT("\n\t MD Name Format %s (%u), MD Name length %u", tok2str(cfm_md_nameformat_values, "Unknown", md_nameformat), md_nameformat, - md_namelength)); + md_namelength); /* * -3 for the MA short name format and length and one byte * of MA short name. */ if (md_namelength > names_data_remaining - 3) { - ND_PRINT((ndo, " (too large, must be <= %u)", names_data_remaining - 2)); + ND_PRINT(" (too large, must be <= %u)", names_data_remaining - 2); return; } md_name = namesp; - ND_PRINT((ndo, "\n\t MD Name: ")); + ND_PRINT("\n\t MD Name: "); switch (md_nameformat) { case CFM_CCM_MD_FORMAT_DNS: case CFM_CCM_MD_FORMAT_CHAR: - safeputs(ndo, md_name, md_namelength); + nd_printjnp(ndo, md_name, md_namelength); break; case CFM_CCM_MD_FORMAT_MAC: - if (md_namelength == 6) { - ND_PRINT((ndo, "\n\t MAC %s", etheraddr_string(ndo, - md_name))); + if (md_namelength == MAC_ADDR_LEN) { + ND_PRINT("\n\t MAC %s", GET_ETHERADDR_STRING(md_name)); } else { - ND_PRINT((ndo, "\n\t MAC (length invalid)")); + ND_PRINT("\n\t MAC (length invalid)"); } break; @@ -418,38 +421,38 @@ cfm_print(netdissect_options *ndo, namesp += md_namelength; names_data_remaining -= md_namelength; } else { - ND_PRINT((ndo, "\n\t MD Name Format %s (%u)", + ND_PRINT("\n\t MD Name Format %s (%u)", tok2str(cfm_md_nameformat_values, "Unknown", md_nameformat), - md_nameformat)); + md_nameformat); } /* * Resolve the MA fields. */ - ma_nameformat = *namesp; + ma_nameformat = GET_U_1(namesp); namesp++; names_data_remaining--; /* We know this is != 0 */ - ma_namelength = *namesp; + ma_namelength = GET_U_1(namesp); namesp++; names_data_remaining--; /* We know this is != 0 */ - ND_PRINT((ndo, "\n\t MA Name-Format %s (%u), MA name length %u", + ND_PRINT("\n\t MA Name-Format %s (%u), MA name length %u", tok2str(cfm_ma_nameformat_values, "Unknown", ma_nameformat), ma_nameformat, - ma_namelength)); + ma_namelength); if (ma_namelength > names_data_remaining) { - ND_PRINT((ndo, " (too large, must be <= %u)", names_data_remaining)); + ND_PRINT(" (too large, must be <= %u)", names_data_remaining); return; } ma_name = namesp; - ND_PRINT((ndo, "\n\t MA Name: ")); + ND_PRINT("\n\t MA Name: "); switch (ma_nameformat) { case CFM_CCM_MA_FORMAT_CHAR: - safeputs(ndo, ma_name, ma_namelength); + nd_printjnp(ndo, ma_name, ma_namelength); break; /* FIXME add printers for those MA formats - hexdump for now */ @@ -464,50 +467,50 @@ cfm_print(netdissect_options *ndo, case CFM_OPCODE_LTM: msg_ptr.cfm_ltm = (const struct cfm_ltm_t *)tptr; - if (cfm_common_header->first_tlv_offset < sizeof(*msg_ptr.cfm_ltm)) { - ND_PRINT((ndo, " (too small 4, must be >= %lu)", - (unsigned long) sizeof(*msg_ptr.cfm_ltm))); + if (first_tlv_offset < sizeof(*msg_ptr.cfm_ltm)) { + ND_PRINT(" (too small 4, must be >= %zu)", + sizeof(*msg_ptr.cfm_ltm)); return; } if (tlen < sizeof(*msg_ptr.cfm_ltm)) goto tooshort; - ND_TCHECK(*msg_ptr.cfm_ltm); + ND_TCHECK_SIZE(msg_ptr.cfm_ltm); - ND_PRINT((ndo, ", Flags [%s]", - bittok2str(cfm_ltm_flag_values, "none", cfm_common_header->flags))); + ND_PRINT(", Flags [%s]", + bittok2str(cfm_ltm_flag_values, "none", flags)); - ND_PRINT((ndo, "\n\t Transaction-ID 0x%08x, ttl %u", - EXTRACT_32BITS(msg_ptr.cfm_ltm->transaction_id), - msg_ptr.cfm_ltm->ttl)); + ND_PRINT("\n\t Transaction-ID 0x%08x, ttl %u", + GET_BE_U_4(msg_ptr.cfm_ltm->transaction_id), + GET_U_1(msg_ptr.cfm_ltm->ttl)); - ND_PRINT((ndo, "\n\t Original-MAC %s, Target-MAC %s", - etheraddr_string(ndo, msg_ptr.cfm_ltm->original_mac), - etheraddr_string(ndo, msg_ptr.cfm_ltm->target_mac))); + ND_PRINT("\n\t Original-MAC %s, Target-MAC %s", + GET_ETHERADDR_STRING(msg_ptr.cfm_ltm->original_mac), + GET_ETHERADDR_STRING(msg_ptr.cfm_ltm->target_mac)); break; case CFM_OPCODE_LTR: msg_ptr.cfm_ltr = (const struct cfm_ltr_t *)tptr; - if (cfm_common_header->first_tlv_offset < sizeof(*msg_ptr.cfm_ltr)) { - ND_PRINT((ndo, " (too small 5, must be >= %lu)", - (unsigned long) sizeof(*msg_ptr.cfm_ltr))); + if (first_tlv_offset < sizeof(*msg_ptr.cfm_ltr)) { + ND_PRINT(" (too small 5, must be >= %zu)", + sizeof(*msg_ptr.cfm_ltr)); return; } if (tlen < sizeof(*msg_ptr.cfm_ltr)) goto tooshort; - ND_TCHECK(*msg_ptr.cfm_ltr); + ND_TCHECK_SIZE(msg_ptr.cfm_ltr); - ND_PRINT((ndo, ", Flags [%s]", - bittok2str(cfm_ltr_flag_values, "none", cfm_common_header->flags))); + ND_PRINT(", Flags [%s]", + bittok2str(cfm_ltr_flag_values, "none", flags)); - ND_PRINT((ndo, "\n\t Transaction-ID 0x%08x, ttl %u", - EXTRACT_32BITS(msg_ptr.cfm_ltr->transaction_id), - msg_ptr.cfm_ltr->ttl)); + ND_PRINT("\n\t Transaction-ID 0x%08x, ttl %u", + GET_BE_U_4(msg_ptr.cfm_ltr->transaction_id), + GET_U_1(msg_ptr.cfm_ltr->ttl)); - ND_PRINT((ndo, "\n\t Replay-Action %s (%u)", + ND_PRINT("\n\t Replay-Action %s (%u)", tok2str(cfm_ltr_replay_action_values, "Unknown", - msg_ptr.cfm_ltr->replay_action), - msg_ptr.cfm_ltr->replay_action)); + GET_U_1(msg_ptr.cfm_ltr->replay_action)), + GET_U_1(msg_ptr.cfm_ltr->replay_action)); break; /* @@ -518,23 +521,22 @@ cfm_print(netdissect_options *ndo, case CFM_OPCODE_LBM: default: print_unknown_data(ndo, tptr, "\n\t ", - tlen - cfm_common_header->first_tlv_offset); + tlen - first_tlv_offset); break; } - tptr += cfm_common_header->first_tlv_offset; - tlen -= cfm_common_header->first_tlv_offset; + tptr += first_tlv_offset; + tlen -= first_tlv_offset; while (tlen > 0) { cfm_tlv_header = (const struct cfm_tlv_header_t *)tptr; /* Enough to read the tlv type ? */ - ND_TCHECK2(*tptr, 1); - cfm_tlv_type=cfm_tlv_header->type; + cfm_tlv_type = GET_U_1(cfm_tlv_header->type); - ND_PRINT((ndo, "\n\t%s TLV (0x%02x)", + ND_PRINT("\n\t%s TLV (0x%02x)", tok2str(cfm_tlv_values, "Unknown", cfm_tlv_type), - cfm_tlv_type)); + cfm_tlv_type); if (cfm_tlv_type == CFM_TLV_END) { /* Length is "Not present if the Type field is 0." */ @@ -544,10 +546,10 @@ cfm_print(netdissect_options *ndo, /* do we have the full tlv header ? */ if (tlen < sizeof(struct cfm_tlv_header_t)) goto tooshort; - ND_TCHECK2(*tptr, sizeof(struct cfm_tlv_header_t)); - cfm_tlv_len=EXTRACT_16BITS(&cfm_tlv_header->length); + ND_TCHECK_LEN(tptr, sizeof(struct cfm_tlv_header_t)); + cfm_tlv_len=GET_BE_U_2(cfm_tlv_header->length); - ND_PRINT((ndo, ", length %u", cfm_tlv_len)); + ND_PRINT(", length %u", cfm_tlv_len); tptr += sizeof(struct cfm_tlv_header_t); tlen -= sizeof(struct cfm_tlv_header_t); @@ -556,39 +558,39 @@ cfm_print(netdissect_options *ndo, /* do we have the full tlv ? */ if (tlen < cfm_tlv_len) goto tooshort; - ND_TCHECK2(*tptr, cfm_tlv_len); + ND_TCHECK_LEN(tptr, cfm_tlv_len); hexdump = FALSE; switch(cfm_tlv_type) { case CFM_TLV_PORT_STATUS: if (cfm_tlv_len < 1) { - ND_PRINT((ndo, " (too short, must be >= 1)")); + ND_PRINT(" (too short, must be >= 1)"); return; } - ND_PRINT((ndo, ", Status: %s (%u)", - tok2str(cfm_tlv_port_status_values, "Unknown", *tptr), - *tptr)); + ND_PRINT(", Status: %s (%u)", + tok2str(cfm_tlv_port_status_values, "Unknown", GET_U_1(tptr)), + GET_U_1(tptr)); break; case CFM_TLV_INTERFACE_STATUS: if (cfm_tlv_len < 1) { - ND_PRINT((ndo, " (too short, must be >= 1)")); + ND_PRINT(" (too short, must be >= 1)"); return; } - ND_PRINT((ndo, ", Status: %s (%u)", - tok2str(cfm_tlv_interface_status_values, "Unknown", *tptr), - *tptr)); + ND_PRINT(", Status: %s (%u)", + tok2str(cfm_tlv_interface_status_values, "Unknown", GET_U_1(tptr)), + GET_U_1(tptr)); break; case CFM_TLV_PRIVATE: if (cfm_tlv_len < 4) { - ND_PRINT((ndo, " (too short, must be >= 4)")); + ND_PRINT(" (too short, must be >= 4)"); return; } - ND_PRINT((ndo, ", Vendor: %s (%u), Sub-Type %u", - tok2str(oui_values,"Unknown", EXTRACT_24BITS(tptr)), - EXTRACT_24BITS(tptr), - *(tptr + 3))); + ND_PRINT(", Vendor: %s (%u), Sub-Type %u", + tok2str(oui_values,"Unknown", GET_BE_U_3(tptr)), + GET_BE_U_3(tptr), + GET_U_1(tptr + 3)); hexdump = TRUE; break; @@ -598,7 +600,7 @@ cfm_print(netdissect_options *ndo, u_int mgmt_addr_length; if (cfm_tlv_len < 1) { - ND_PRINT((ndo, " (too short, must be >= 1)")); + ND_PRINT(" (too short, must be >= 1)"); goto next_tlv; } @@ -606,7 +608,7 @@ cfm_print(netdissect_options *ndo, * Get the Chassis ID length and check it. * IEEE 802.1Q-2014 Section 21.5.3.1 */ - chassis_id_length = *tptr; + chassis_id_length = GET_U_1(tptr); tptr++; tlen--; cfm_tlv_len--; @@ -618,32 +620,32 @@ cfm_print(netdissect_options *ndo, * IEEE 802.1AB-2016 Section 8.5.2.2: chassis ID subtype */ if (cfm_tlv_len < 1) { - ND_PRINT((ndo, "\n\t (TLV too short)")); + ND_PRINT("\n\t (TLV too short)"); goto next_tlv; } - chassis_id_type = *tptr; + chassis_id_type = GET_U_1(tptr); cfm_tlv_len--; - ND_PRINT((ndo, "\n\t Chassis-ID Type %s (%u), Chassis-ID length %u", + ND_PRINT("\n\t Chassis-ID Type %s (%u), Chassis-ID length %u", tok2str(cfm_tlv_senderid_chassisid_values, "Unknown", chassis_id_type), chassis_id_type, - chassis_id_length)); + chassis_id_length); if (cfm_tlv_len < chassis_id_length) { - ND_PRINT((ndo, "\n\t (TLV too short)")); + ND_PRINT("\n\t (TLV too short)"); goto next_tlv; } /* IEEE 802.1Q-2014 Section 21.5.3.3: Chassis ID */ switch (chassis_id_type) { case CFM_CHASSIS_ID_MAC_ADDRESS: - if (chassis_id_length != ETHER_ADDR_LEN) { - ND_PRINT((ndo, " (invalid MAC address length)")); + if (chassis_id_length != MAC_ADDR_LEN) { + ND_PRINT(" (invalid MAC address length)"); hexdump = TRUE; break; } - ND_PRINT((ndo, "\n\t MAC %s", etheraddr_string(ndo, tptr + 1))); + ND_PRINT("\n\t MAC %s", GET_ETHERADDR_STRING(tptr + 1)); break; case CFM_CHASSIS_ID_NETWORK_ADDRESS: @@ -655,7 +657,7 @@ cfm_print(netdissect_options *ndo, case CFM_CHASSIS_ID_LOCAL: case CFM_CHASSIS_ID_CHASSIS_COMPONENT: case CFM_CHASSIS_ID_PORT_COMPONENT: - safeputs(ndo, tptr + 1, chassis_id_length); + nd_printjnp(ndo, tptr + 1, chassis_id_length); break; default: @@ -680,15 +682,15 @@ cfm_print(netdissect_options *ndo, } /* Here mgmt_addr_length stands for the management domain length. */ - mgmt_addr_length = *tptr; + mgmt_addr_length = GET_U_1(tptr); tptr++; tlen--; cfm_tlv_len--; - ND_PRINT((ndo, "\n\t Management Address Domain Length %u", mgmt_addr_length)); + ND_PRINT("\n\t Management Address Domain Length %u", mgmt_addr_length); if (mgmt_addr_length) { /* IEEE 802.1Q-2014 Section 21.5.3.5: Management Address Domain */ if (cfm_tlv_len < mgmt_addr_length) { - ND_PRINT((ndo, "\n\t (TLV too short)")); + ND_PRINT("\n\t (TLV too short)"); goto next_tlv; } cfm_tlv_len -= mgmt_addr_length; @@ -704,21 +706,21 @@ cfm_print(netdissect_options *ndo, * This field is present if Management Address Domain Length is not 0. */ if (cfm_tlv_len < 1) { - ND_PRINT((ndo, " (Management Address Length is missing)")); + ND_PRINT(" (Management Address Length is missing)"); hexdump = TRUE; break; } /* Here mgmt_addr_length stands for the management address length. */ - mgmt_addr_length = *tptr; + mgmt_addr_length = GET_U_1(tptr); tptr++; tlen--; cfm_tlv_len--; - ND_PRINT((ndo, "\n\t Management Address Length %u", mgmt_addr_length)); + ND_PRINT("\n\t Management Address Length %u", mgmt_addr_length); if (mgmt_addr_length) { /* IEEE 802.1Q-2014 Section 21.5.3.7: Management Address */ if (cfm_tlv_len < mgmt_addr_length) { - ND_PRINT((ndo, "\n\t (TLV too short)")); + ND_PRINT("\n\t (TLV too short)"); return; } cfm_tlv_len -= mgmt_addr_length; @@ -756,9 +758,9 @@ next_tlv: return; tooshort: - ND_PRINT((ndo, "\n\t\t packet is too short")); + ND_PRINT("\n\t\t packet is too short"); return; trunc: - ND_PRINT((ndo, "\n\t\t packet exceeded snapshot")); + nd_print_trunc(ndo); } diff --git a/contrib/tcpdump/print-chdlc.c b/contrib/tcpdump/print-chdlc.c index 24acfbd2e8..235675da42 100644 --- a/contrib/tcpdump/print-chdlc.c +++ b/contrib/tcpdump/print-chdlc.c @@ -22,16 +22,17 @@ /* \summary: Cisco HDLC printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "addrtoname.h" #include "ethertype.h" #include "extract.h" #include "chdlc.h" +#include "nlpid.h" static void chdlc_slarp_print(netdissect_options *, const u_char *, u_int); @@ -43,28 +44,29 @@ static const struct tok chdlc_cast_values[] = { /* Standard CHDLC printer */ -u_int -chdlc_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, register const u_char *p) +void +chdlc_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { - return chdlc_print(ndo, p, h->len); + ndo->ndo_protocol = "chdlc"; + ndo->ndo_ll_hdr_len += chdlc_print(ndo, p, h->len); } u_int -chdlc_print(netdissect_options *ndo, register const u_char *p, u_int length) +chdlc_print(netdissect_options *ndo, const u_char *p, u_int length) { u_int proto; const u_char *bp = p; + ndo->ndo_protocol = "chdlc"; if (length < CHDLC_HDRLEN) goto trunc; - ND_TCHECK2(*p, CHDLC_HDRLEN); - proto = EXTRACT_16BITS(&p[2]); + proto = GET_BE_U_2(p + 2); if (ndo->ndo_eflag) { - ND_PRINT((ndo, "%s, ethertype %s (0x%04x), length %u: ", - tok2str(chdlc_cast_values, "0x%02x", p[0]), + ND_PRINT("%s, ethertype %s (0x%04x), length %u: ", + tok2str(chdlc_cast_values, "0x%02x", GET_U_1(p)), tok2str(ethertype_values, "Unknown", proto), proto, - length)); + length); } length -= CHDLC_HDRLEN; @@ -80,11 +82,6 @@ chdlc_print(netdissect_options *ndo, register const u_char *p, u_int length) case CHDLC_TYPE_SLARP: chdlc_slarp_print(ndo, p, length); break; -#if 0 - case CHDLC_TYPE_CDP: - chdlc_cdp_print(p, length); - break; -#endif case ETHERTYPE_MPLS: case ETHERTYPE_MPLS_MULTI: mpls_print(ndo, p, length); @@ -93,32 +90,31 @@ chdlc_print(netdissect_options *ndo, register const u_char *p, u_int length) /* is the fudge byte set ? lets verify by spotting ISO headers */ if (length < 2) goto trunc; - ND_TCHECK_16BITS(p); - if (*(p+1) == 0x81 || - *(p+1) == 0x82 || - *(p+1) == 0x83) + if (GET_U_1(p + 1) == NLPID_CLNP || + GET_U_1(p + 1) == NLPID_ESIS || + GET_U_1(p + 1) == NLPID_ISIS) isoclns_print(ndo, p + 1, length - 1); else isoclns_print(ndo, p, length); break; default: if (!ndo->ndo_eflag) - ND_PRINT((ndo, "unknown CHDLC protocol (0x%04x)", proto)); + ND_PRINT("unknown CHDLC protocol (0x%04x)", proto); break; } return (CHDLC_HDRLEN); trunc: - ND_PRINT((ndo, "[|chdlc]")); - return ndo->ndo_snapend - bp; + nd_print_trunc(ndo); + return (ND_BYTES_AVAILABLE_AFTER(bp)); } /* * The fixed-length portion of a SLARP packet. */ struct cisco_slarp { - uint8_t code[4]; + nd_uint32_t code; #define SLARP_REQUEST 0 #define SLARP_REPLY 1 #define SLARP_KEEPALIVE 2 @@ -128,9 +124,9 @@ struct cisco_slarp { uint8_t mask[4]; } addr; struct { - uint8_t myseq[4]; - uint8_t yourseq[4]; - uint8_t rel[2]; + nd_uint32_t myseq; + nd_uint32_t yourseq; + nd_uint16_t rel; } keep; } un; }; @@ -144,67 +140,59 @@ chdlc_slarp_print(netdissect_options *ndo, const u_char *cp, u_int length) const struct cisco_slarp *slarp; u_int sec,min,hrs,days; - ND_PRINT((ndo, "SLARP (length: %u), ",length)); + ndo->ndo_protocol = "chdlc_slarp"; + ND_PRINT("SLARP (length: %u), ",length); if (length < SLARP_MIN_LEN) goto trunc; slarp = (const struct cisco_slarp *)cp; - ND_TCHECK2(*slarp, SLARP_MIN_LEN); - switch (EXTRACT_32BITS(&slarp->code)) { + ND_TCHECK_LEN(slarp, SLARP_MIN_LEN); + switch (GET_BE_U_4(slarp->code)) { case SLARP_REQUEST: - ND_PRINT((ndo, "request")); + ND_PRINT("request"); /* * At least according to William "Chops" Westfield's * message in * - * http://www.nethelp.no/net/cisco-hdlc.txt + * https://web.archive.org/web/20190725151313/www.nethelp.no/net/cisco-hdlc.txt * * the address and mask aren't used in requests - * they're just zero. */ break; case SLARP_REPLY: - ND_PRINT((ndo, "reply %s/%s", - ipaddr_string(ndo, &slarp->un.addr.addr), - ipaddr_string(ndo, &slarp->un.addr.mask))); + ND_PRINT("reply %s/%s", + GET_IPADDR_STRING(slarp->un.addr.addr), + GET_IPADDR_STRING(slarp->un.addr.mask)); break; case SLARP_KEEPALIVE: - ND_PRINT((ndo, "keepalive: mineseen=0x%08x, yourseen=0x%08x, reliability=0x%04x", - EXTRACT_32BITS(&slarp->un.keep.myseq), - EXTRACT_32BITS(&slarp->un.keep.yourseq), - EXTRACT_16BITS(&slarp->un.keep.rel))); + ND_PRINT("keepalive: mineseen=0x%08x, yourseen=0x%08x, reliability=0x%04x", + GET_BE_U_4(slarp->un.keep.myseq), + GET_BE_U_4(slarp->un.keep.yourseq), + GET_BE_U_2(slarp->un.keep.rel)); if (length >= SLARP_MAX_LEN) { /* uptime-stamp is optional */ cp += SLARP_MIN_LEN; - ND_TCHECK2(*cp, 4); - sec = EXTRACT_32BITS(cp) / 1000; + sec = GET_BE_U_4(cp) / 1000; min = sec / 60; sec -= min * 60; hrs = min / 60; min -= hrs * 60; days = hrs / 24; hrs -= days * 24; - ND_PRINT((ndo, ", link uptime=%ud%uh%um%us",days,hrs,min,sec)); + ND_PRINT(", link uptime=%ud%uh%um%us",days,hrs,min,sec); } break; default: - ND_PRINT((ndo, "0x%02x unknown", EXTRACT_32BITS(&slarp->code))); + ND_PRINT("0x%02x unknown", GET_BE_U_4(slarp->code)); if (ndo->ndo_vflag <= 1) print_unknown_data(ndo,cp+4,"\n\t",length-4); break; } if (SLARP_MAX_LEN < length && ndo->ndo_vflag) - ND_PRINT((ndo, ", (trailing junk: %d bytes)", length - SLARP_MAX_LEN)); + ND_PRINT(", (trailing junk: %u bytes)", length - SLARP_MAX_LEN); if (ndo->ndo_vflag > 1) print_unknown_data(ndo,cp+4,"\n\t",length-4); return; trunc: - ND_PRINT((ndo, "[|slarp]")); + nd_print_trunc(ndo); } - - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/print-cip.c b/contrib/tcpdump/print-cip.c index a123b69f51..b8ef77fd2f 100644 --- a/contrib/tcpdump/print-cip.c +++ b/contrib/tcpdump/print-cip.c @@ -20,16 +20,17 @@ * */ -/* \summary: Classical-IP over ATM printer */ +/* \summary: Linux Classical IP over ATM printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif #include -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "addrtoname.h" @@ -41,43 +42,29 @@ static const unsigned char rfcllc[] = { 0x00, 0x00 }; -static inline void -cip_print(netdissect_options *ndo, u_int length) -{ - /* - * There is no MAC-layer header, so just print the length. - */ - ND_PRINT((ndo, "%u: ", length)); -} - /* * This is the top level routine of the printer. 'p' points * to the LLC/SNAP or raw 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 +void cip_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { u_int caplen = h->caplen; u_int length = h->len; - size_t cmplen; int llc_hdrlen; - cmplen = sizeof(rfcllc); - if (cmplen > caplen) - cmplen = caplen; - if (cmplen > length) - cmplen = length; + ndo->ndo_protocol = "cip"; if (ndo->ndo_eflag) - cip_print(ndo, length); + /* + * There is no MAC-layer header, so just print the length. + */ + ND_PRINT("%u: ", length); - if (cmplen == 0) { - ND_PRINT((ndo, "[|cip]")); - return 0; - } - if (memcmp(rfcllc, p, cmplen) == 0) { + ND_TCHECK_LEN(p, sizeof(rfcllc)); + if (memcmp(rfcllc, p, sizeof(rfcllc)) == 0) { /* * LLC header is present. Try to print it & higher layers. */ @@ -96,13 +83,5 @@ cip_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char ip_print(ndo, p, length); } - return (llc_hdrlen); + ndo->ndo_ll_hdr_len += llc_hdrlen; } - - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/print-cnfp.c b/contrib/tcpdump/print-cnfp.c index 7e7d835ced..101148fa86 100644 --- a/contrib/tcpdump/print-cnfp.c +++ b/contrib/tcpdump/print-cnfp.c @@ -37,17 +37,16 @@ * * See * - * http://www.cisco.com/c/en/us/td/docs/net_mgmt/netflow_collection_engine/3-6/user/guide/format.html#wp1005892 + * https://www.cisco.com/c/en/us/td/docs/net_mgmt/netflow_collection_engine/3-6/user/guide/format.html#wp1005892 */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include -#include #include "netdissect.h" #include "addrtoname.h" @@ -57,136 +56,137 @@ #include "ipproto.h" struct nfhdr_v1 { - uint16_t version; /* version number */ - uint16_t count; /* # of records */ - uint32_t msys_uptime; - uint32_t utc_sec; - uint32_t utc_nsec; + nd_uint16_t version; /* version number */ + nd_uint16_t count; /* # of records */ + nd_uint32_t msys_uptime; + nd_uint32_t utc_sec; + nd_uint32_t utc_nsec; }; struct nfrec_v1 { - struct in_addr src_ina; - struct in_addr dst_ina; - struct in_addr nhop_ina; - uint16_t input; /* SNMP index of input interface */ - uint16_t output; /* SNMP index of output interface */ - uint32_t packets; /* packets in the flow */ - uint32_t octets; /* layer 3 octets in the packets of the flow */ - uint32_t start_time; /* sys_uptime value at start of flow */ - uint32_t last_time; /* sys_uptime value when last packet of flow was received */ - uint16_t srcport; /* TCP/UDP source port or equivalent */ - uint16_t dstport; /* TCP/UDP source port or equivalent */ - uint16_t pad1; /* pad */ - uint8_t proto; /* IP protocol type */ - uint8_t tos; /* IP type of service */ - uint8_t tcp_flags; /* cumulative OR of TCP flags */ - uint8_t pad[3]; /* padding */ - uint32_t reserved; /* unused */ + nd_ipv4 src_ina; + nd_ipv4 dst_ina; + nd_ipv4 nhop_ina; + nd_uint16_t input; /* SNMP index of input interface */ + nd_uint16_t output; /* SNMP index of output interface */ + nd_uint32_t packets; /* packets in the flow */ + nd_uint32_t octets; /* layer 3 octets in the packets of the flow */ + nd_uint32_t start_time; /* sys_uptime value at start of flow */ + nd_uint32_t last_time; /* sys_uptime value when last packet of flow was received */ + nd_uint16_t srcport; /* TCP/UDP source port or equivalent */ + nd_uint16_t dstport; /* TCP/UDP source port or equivalent */ + nd_byte pad1[2]; /* pad */ + nd_uint8_t proto; /* IP protocol type */ + nd_uint8_t tos; /* IP type of service */ + nd_uint8_t tcp_flags; /* cumulative OR of TCP flags */ + nd_byte pad[3]; /* padding */ + nd_uint32_t reserved; /* unused */ }; struct nfhdr_v5 { - uint16_t version; /* version number */ - uint16_t count; /* # of records */ - uint32_t msys_uptime; - uint32_t utc_sec; - uint32_t utc_nsec; - uint32_t sequence; /* flow sequence number */ - uint8_t engine_type; /* type of flow-switching engine */ - uint8_t engine_id; /* slot number of the flow-switching engine */ - uint16_t sampling_interval; /* sampling mode and interval */ + nd_uint16_t version; /* version number */ + nd_uint16_t count; /* # of records */ + nd_uint32_t msys_uptime; + nd_uint32_t utc_sec; + nd_uint32_t utc_nsec; + nd_uint32_t sequence; /* flow sequence number */ + nd_uint8_t engine_type; /* type of flow-switching engine */ + nd_uint8_t engine_id; /* slot number of the flow-switching engine */ + nd_uint16_t sampling_interval; /* sampling mode and interval */ }; struct nfrec_v5 { - struct in_addr src_ina; - struct in_addr dst_ina; - struct in_addr nhop_ina; - uint16_t input; /* SNMP index of input interface */ - uint16_t output; /* SNMP index of output interface */ - uint32_t packets; /* packets in the flow */ - uint32_t octets; /* layer 3 octets in the packets of the flow */ - uint32_t start_time; /* sys_uptime value at start of flow */ - uint32_t last_time; /* sys_uptime value when last packet of flow was received */ - uint16_t srcport; /* TCP/UDP source port or equivalent */ - uint16_t dstport; /* TCP/UDP source port or equivalent */ - uint8_t pad1; /* pad */ - uint8_t tcp_flags; /* cumulative OR of TCP flags */ - uint8_t proto; /* IP protocol type */ - uint8_t tos; /* IP type of service */ - uint16_t src_as; /* AS number of the source */ - uint16_t dst_as; /* AS number of the destination */ - uint8_t src_mask; /* source address mask bits */ - uint8_t dst_mask; /* destination address prefix mask bits */ - uint16_t pad2; - struct in_addr peer_nexthop; /* v6: IP address of the nexthop within the peer (FIB)*/ + nd_ipv4 src_ina; + nd_ipv4 dst_ina; + nd_ipv4 nhop_ina; + nd_uint16_t input; /* SNMP index of input interface */ + nd_uint16_t output; /* SNMP index of output interface */ + nd_uint32_t packets; /* packets in the flow */ + nd_uint32_t octets; /* layer 3 octets in the packets of the flow */ + nd_uint32_t start_time; /* sys_uptime value at start of flow */ + nd_uint32_t last_time; /* sys_uptime value when last packet of flow was received */ + nd_uint16_t srcport; /* TCP/UDP source port or equivalent */ + nd_uint16_t dstport; /* TCP/UDP source port or equivalent */ + nd_byte pad1; /* pad */ + nd_uint8_t tcp_flags; /* cumulative OR of TCP flags */ + nd_uint8_t proto; /* IP protocol type */ + nd_uint8_t tos; /* IP type of service */ + nd_uint16_t src_as; /* AS number of the source */ + nd_uint16_t dst_as; /* AS number of the destination */ + nd_uint8_t src_mask; /* source address mask bits */ + nd_uint8_t dst_mask; /* destination address prefix mask bits */ + nd_byte pad2[2]; + nd_ipv4 peer_nexthop; /* v6: IP address of the nexthop within the peer (FIB)*/ }; struct nfhdr_v6 { - uint16_t version; /* version number */ - uint16_t count; /* # of records */ - uint32_t msys_uptime; - uint32_t utc_sec; - uint32_t utc_nsec; - uint32_t sequence; /* v5 flow sequence number */ - uint32_t reserved; /* v5 only */ + nd_uint16_t version; /* version number */ + nd_uint16_t count; /* # of records */ + nd_uint32_t msys_uptime; + nd_uint32_t utc_sec; + nd_uint32_t utc_nsec; + nd_uint32_t sequence; /* v5 flow sequence number */ + nd_uint32_t reserved; /* v5 only */ }; struct nfrec_v6 { - struct in_addr src_ina; - struct in_addr dst_ina; - struct in_addr nhop_ina; - uint16_t input; /* SNMP index of input interface */ - uint16_t output; /* SNMP index of output interface */ - uint32_t packets; /* packets in the flow */ - uint32_t octets; /* layer 3 octets in the packets of the flow */ - uint32_t start_time; /* sys_uptime value at start of flow */ - uint32_t last_time; /* sys_uptime value when last packet of flow was received */ - uint16_t srcport; /* TCP/UDP source port or equivalent */ - uint16_t dstport; /* TCP/UDP source port or equivalent */ - uint8_t pad1; /* pad */ - uint8_t tcp_flags; /* cumulative OR of TCP flags */ - uint8_t proto; /* IP protocol type */ - uint8_t tos; /* IP type of service */ - uint16_t src_as; /* AS number of the source */ - uint16_t dst_as; /* AS number of the destination */ - uint8_t src_mask; /* source address mask bits */ - uint8_t dst_mask; /* destination address prefix mask bits */ - uint16_t flags; - struct in_addr peer_nexthop; /* v6: IP address of the nexthop within the peer (FIB)*/ + nd_ipv4 src_ina; + nd_ipv4 dst_ina; + nd_ipv4 nhop_ina; + nd_uint16_t input; /* SNMP index of input interface */ + nd_uint16_t output; /* SNMP index of output interface */ + nd_uint32_t packets; /* packets in the flow */ + nd_uint32_t octets; /* layer 3 octets in the packets of the flow */ + nd_uint32_t start_time; /* sys_uptime value at start of flow */ + nd_uint32_t last_time; /* sys_uptime value when last packet of flow was received */ + nd_uint16_t srcport; /* TCP/UDP source port or equivalent */ + nd_uint16_t dstport; /* TCP/UDP source port or equivalent */ + nd_byte pad1; /* pad */ + nd_uint8_t tcp_flags; /* cumulative OR of TCP flags */ + nd_uint8_t proto; /* IP protocol type */ + nd_uint8_t tos; /* IP type of service */ + nd_uint16_t src_as; /* AS number of the source */ + nd_uint16_t dst_as; /* AS number of the destination */ + nd_uint8_t src_mask; /* source address mask bits */ + nd_uint8_t dst_mask; /* destination address prefix mask bits */ + nd_uint16_t flags; + nd_ipv4 peer_nexthop; /* v6: IP address of the nexthop within the peer (FIB)*/ }; static void cnfp_v1_print(netdissect_options *ndo, const u_char *cp) { - register const struct nfhdr_v1 *nh; - register const struct nfrec_v1 *nr; + const struct nfhdr_v1 *nh; + const struct nfrec_v1 *nr; const char *p_name; - int nrecs, ver; + uint8_t proto; + u_int nrecs, ver; #if 0 time_t t; #endif nh = (const struct nfhdr_v1 *)cp; - ND_TCHECK(*nh); + ND_TCHECK_SIZE(nh); - ver = EXTRACT_16BITS(&nh->version); - nrecs = EXTRACT_32BITS(&nh->count); + ver = GET_BE_U_2(nh->version); + nrecs = GET_BE_U_4(nh->count); #if 0 /* * This is seconds since the UN*X epoch, and is followed by * nanoseconds. XXX - format it, rather than just dumping the * raw seconds-since-the-Epoch. */ - t = EXTRACT_32BITS(&nh->utc_sec); + t = GET_BE_U_4(nh->utc_sec); #endif - ND_PRINT((ndo, "NetFlow v%x, %u.%03u uptime, %u.%09u, ", ver, - EXTRACT_32BITS(&nh->msys_uptime)/1000, - EXTRACT_32BITS(&nh->msys_uptime)%1000, - EXTRACT_32BITS(&nh->utc_sec), EXTRACT_32BITS(&nh->utc_nsec))); + ND_PRINT("NetFlow v%x, %u.%03u uptime, %u.%09u, ", ver, + GET_BE_U_4(nh->msys_uptime)/1000, + GET_BE_U_4(nh->msys_uptime)%1000, + GET_BE_U_4(nh->utc_sec), GET_BE_U_4(nh->utc_nsec)); nr = (const struct nfrec_v1 *)&nh[1]; - ND_PRINT((ndo, "%2u recs", nrecs)); + ND_PRINT("%2u recs", nrecs); for (; nrecs != 0; nr++, nrecs--) { char buf[20]; @@ -195,88 +195,94 @@ cnfp_v1_print(netdissect_options *ndo, const u_char *cp) /* * Make sure we have the entire record. */ - ND_TCHECK(*nr); - ND_PRINT((ndo, "\n started %u.%03u, last %u.%03u", - EXTRACT_32BITS(&nr->start_time)/1000, - EXTRACT_32BITS(&nr->start_time)%1000, - EXTRACT_32BITS(&nr->last_time)/1000, - EXTRACT_32BITS(&nr->last_time)%1000)); + ND_TCHECK_SIZE(nr); + ND_PRINT("\n started %u.%03u, last %u.%03u", + GET_BE_U_4(nr->start_time)/1000, + GET_BE_U_4(nr->start_time)%1000, + GET_BE_U_4(nr->last_time)/1000, + GET_BE_U_4(nr->last_time)%1000); asbuf[0] = buf[0] = '\0'; - ND_PRINT((ndo, "\n %s%s%s:%u ", intoa(nr->src_ina.s_addr), buf, asbuf, - EXTRACT_16BITS(&nr->srcport))); - - ND_PRINT((ndo, "> %s%s%s:%u ", intoa(nr->dst_ina.s_addr), buf, asbuf, - EXTRACT_16BITS(&nr->dstport))); - - ND_PRINT((ndo, ">> %s\n ", intoa(nr->nhop_ina.s_addr))); - - if (!ndo->ndo_nflag && (p_name = netdb_protoname(nr->proto)) != NULL) - ND_PRINT((ndo, "%s ", p_name)); + ND_PRINT("\n %s%s%s:%u ", + intoa(GET_IPV4_TO_NETWORK_ORDER(nr->src_ina)), + buf, asbuf, + GET_BE_U_2(nr->srcport)); + + ND_PRINT("> %s%s%s:%u ", + intoa(GET_IPV4_TO_NETWORK_ORDER(nr->dst_ina)), + buf, asbuf, + GET_BE_U_2(nr->dstport)); + + ND_PRINT(">> %s\n ", + intoa(GET_IPV4_TO_NETWORK_ORDER(nr->nhop_ina))); + + proto = GET_U_1(nr->proto); + if (!ndo->ndo_nflag && (p_name = netdb_protoname(proto)) != NULL) + ND_PRINT("%s ", p_name); else - ND_PRINT((ndo, "%u ", nr->proto)); + ND_PRINT("%u ", proto); /* tcp flags for tcp only */ - if (nr->proto == IPPROTO_TCP) { - int flags; - flags = nr->tcp_flags; - ND_PRINT((ndo, "%s%s%s%s%s%s%s", + if (proto == IPPROTO_TCP) { + u_int flags; + flags = GET_U_1(nr->tcp_flags); + ND_PRINT("%s%s%s%s%s%s%s", flags & TH_FIN ? "F" : "", flags & TH_SYN ? "S" : "", flags & TH_RST ? "R" : "", flags & TH_PUSH ? "P" : "", flags & TH_ACK ? "A" : "", flags & TH_URG ? "U" : "", - flags ? " " : "")); + flags ? " " : ""); } buf[0]='\0'; - ND_PRINT((ndo, "tos %u, %u (%u octets) %s", - nr->tos, - EXTRACT_32BITS(&nr->packets), - EXTRACT_32BITS(&nr->octets), buf)); + ND_PRINT("tos %u, %u (%u octets) %s", + GET_U_1(nr->tos), + GET_BE_U_4(nr->packets), + GET_BE_U_4(nr->octets), buf); } return; trunc: - ND_PRINT((ndo, "[|cnfp]")); - return; + nd_print_trunc(ndo); } static void cnfp_v5_print(netdissect_options *ndo, const u_char *cp) { - register const struct nfhdr_v5 *nh; - register const struct nfrec_v5 *nr; + const struct nfhdr_v5 *nh; + const struct nfrec_v5 *nr; const char *p_name; - int nrecs, ver; + uint8_t proto; + u_int nrecs, ver; #if 0 time_t t; #endif nh = (const struct nfhdr_v5 *)cp; - ND_TCHECK(*nh); + ND_TCHECK_SIZE(nh); - ver = EXTRACT_16BITS(&nh->version); - nrecs = EXTRACT_32BITS(&nh->count); + ver = GET_BE_U_2(nh->version); + nrecs = GET_BE_U_4(nh->count); #if 0 /* * This is seconds since the UN*X epoch, and is followed by * nanoseconds. XXX - format it, rather than just dumping the * raw seconds-since-the-Epoch. */ - t = EXTRACT_32BITS(&nh->utc_sec); + t = GET_BE_U_4(nh->utc_sec); #endif - ND_PRINT((ndo, "NetFlow v%x, %u.%03u uptime, %u.%09u, ", ver, - EXTRACT_32BITS(&nh->msys_uptime)/1000, - EXTRACT_32BITS(&nh->msys_uptime)%1000, - EXTRACT_32BITS(&nh->utc_sec), EXTRACT_32BITS(&nh->utc_nsec))); + ND_PRINT("NetFlow v%x, %u.%03u uptime, %u.%09u, ", ver, + GET_BE_U_4(nh->msys_uptime)/1000, + GET_BE_U_4(nh->msys_uptime)%1000, + GET_BE_U_4(nh->utc_sec), GET_BE_U_4(nh->utc_nsec)); - ND_PRINT((ndo, "#%u, ", EXTRACT_32BITS(&nh->sequence))); + ND_PRINT("#%u, ", GET_BE_U_4(nh->sequence)); nr = (const struct nfrec_v5 *)&nh[1]; - ND_PRINT((ndo, "%2u recs", nrecs)); + ND_PRINT("%2u recs", nrecs); for (; nrecs != 0; nr++, nrecs--) { char buf[20]; @@ -285,94 +291,100 @@ cnfp_v5_print(netdissect_options *ndo, const u_char *cp) /* * Make sure we have the entire record. */ - ND_TCHECK(*nr); - ND_PRINT((ndo, "\n started %u.%03u, last %u.%03u", - EXTRACT_32BITS(&nr->start_time)/1000, - EXTRACT_32BITS(&nr->start_time)%1000, - EXTRACT_32BITS(&nr->last_time)/1000, - EXTRACT_32BITS(&nr->last_time)%1000)); + ND_TCHECK_SIZE(nr); + ND_PRINT("\n started %u.%03u, last %u.%03u", + GET_BE_U_4(nr->start_time)/1000, + GET_BE_U_4(nr->start_time)%1000, + GET_BE_U_4(nr->last_time)/1000, + GET_BE_U_4(nr->last_time)%1000); asbuf[0] = buf[0] = '\0'; - snprintf(buf, sizeof(buf), "/%u", nr->src_mask); + snprintf(buf, sizeof(buf), "/%u", GET_U_1(nr->src_mask)); snprintf(asbuf, sizeof(asbuf), ":%u", - EXTRACT_16BITS(&nr->src_as)); - ND_PRINT((ndo, "\n %s%s%s:%u ", intoa(nr->src_ina.s_addr), buf, asbuf, - EXTRACT_16BITS(&nr->srcport))); + GET_BE_U_2(nr->src_as)); + ND_PRINT("\n %s%s%s:%u ", + intoa(GET_IPV4_TO_NETWORK_ORDER(nr->src_ina)), + buf, asbuf, + GET_BE_U_2(nr->srcport)); - snprintf(buf, sizeof(buf), "/%d", nr->dst_mask); + snprintf(buf, sizeof(buf), "/%u", GET_U_1(nr->dst_mask)); snprintf(asbuf, sizeof(asbuf), ":%u", - EXTRACT_16BITS(&nr->dst_as)); - ND_PRINT((ndo, "> %s%s%s:%u ", intoa(nr->dst_ina.s_addr), buf, asbuf, - EXTRACT_16BITS(&nr->dstport))); - - ND_PRINT((ndo, ">> %s\n ", intoa(nr->nhop_ina.s_addr))); - - if (!ndo->ndo_nflag && (p_name = netdb_protoname(nr->proto)) != NULL) - ND_PRINT((ndo, "%s ", p_name)); + GET_BE_U_2(nr->dst_as)); + ND_PRINT("> %s%s%s:%u ", + intoa(GET_IPV4_TO_NETWORK_ORDER(nr->dst_ina)), + buf, asbuf, + GET_BE_U_2(nr->dstport)); + + ND_PRINT(">> %s\n ", + intoa(GET_IPV4_TO_NETWORK_ORDER(nr->nhop_ina))); + + proto = GET_U_1(nr->proto); + if (!ndo->ndo_nflag && (p_name = netdb_protoname(proto)) != NULL) + ND_PRINT("%s ", p_name); else - ND_PRINT((ndo, "%u ", nr->proto)); + ND_PRINT("%u ", proto); /* tcp flags for tcp only */ - if (nr->proto == IPPROTO_TCP) { - int flags; - flags = nr->tcp_flags; - ND_PRINT((ndo, "%s%s%s%s%s%s%s", + if (proto == IPPROTO_TCP) { + u_int flags; + flags = GET_U_1(nr->tcp_flags); + ND_PRINT("%s%s%s%s%s%s%s", flags & TH_FIN ? "F" : "", flags & TH_SYN ? "S" : "", flags & TH_RST ? "R" : "", flags & TH_PUSH ? "P" : "", flags & TH_ACK ? "A" : "", flags & TH_URG ? "U" : "", - flags ? " " : "")); + flags ? " " : ""); } buf[0]='\0'; - ND_PRINT((ndo, "tos %u, %u (%u octets) %s", - nr->tos, - EXTRACT_32BITS(&nr->packets), - EXTRACT_32BITS(&nr->octets), buf)); + ND_PRINT("tos %u, %u (%u octets) %s", + GET_U_1(nr->tos), + GET_BE_U_4(nr->packets), + GET_BE_U_4(nr->octets), buf); } return; trunc: - ND_PRINT((ndo, "[|cnfp]")); - return; + nd_print_trunc(ndo); } static void cnfp_v6_print(netdissect_options *ndo, const u_char *cp) { - register const struct nfhdr_v6 *nh; - register const struct nfrec_v6 *nr; + const struct nfhdr_v6 *nh; + const struct nfrec_v6 *nr; const char *p_name; - int nrecs, ver; + uint8_t proto; + u_int nrecs, ver; #if 0 time_t t; #endif nh = (const struct nfhdr_v6 *)cp; - ND_TCHECK(*nh); + ND_TCHECK_SIZE(nh); - ver = EXTRACT_16BITS(&nh->version); - nrecs = EXTRACT_32BITS(&nh->count); + ver = GET_BE_U_2(nh->version); + nrecs = GET_BE_U_4(nh->count); #if 0 /* * This is seconds since the UN*X epoch, and is followed by * nanoseconds. XXX - format it, rather than just dumping the * raw seconds-since-the-Epoch. */ - t = EXTRACT_32BITS(&nh->utc_sec); + t = GET_BE_U_4(nh->utc_sec); #endif - ND_PRINT((ndo, "NetFlow v%x, %u.%03u uptime, %u.%09u, ", ver, - EXTRACT_32BITS(&nh->msys_uptime)/1000, - EXTRACT_32BITS(&nh->msys_uptime)%1000, - EXTRACT_32BITS(&nh->utc_sec), EXTRACT_32BITS(&nh->utc_nsec))); + ND_PRINT("NetFlow v%x, %u.%03u uptime, %u.%09u, ", ver, + GET_BE_U_4(nh->msys_uptime)/1000, + GET_BE_U_4(nh->msys_uptime)%1000, + GET_BE_U_4(nh->utc_sec), GET_BE_U_4(nh->utc_nsec)); - ND_PRINT((ndo, "#%u, ", EXTRACT_32BITS(&nh->sequence))); + ND_PRINT("#%u, ", GET_BE_U_4(nh->sequence)); nr = (const struct nfrec_v6 *)&nh[1]; - ND_PRINT((ndo, "%2u recs", nrecs)); + ND_PRINT("%2u recs", nrecs); for (; nrecs != 0; nr++, nrecs--) { char buf[20]; @@ -381,61 +393,66 @@ cnfp_v6_print(netdissect_options *ndo, const u_char *cp) /* * Make sure we have the entire record. */ - ND_TCHECK(*nr); - ND_PRINT((ndo, "\n started %u.%03u, last %u.%03u", - EXTRACT_32BITS(&nr->start_time)/1000, - EXTRACT_32BITS(&nr->start_time)%1000, - EXTRACT_32BITS(&nr->last_time)/1000, - EXTRACT_32BITS(&nr->last_time)%1000)); + ND_TCHECK_SIZE(nr); + ND_PRINT("\n started %u.%03u, last %u.%03u", + GET_BE_U_4(nr->start_time)/1000, + GET_BE_U_4(nr->start_time)%1000, + GET_BE_U_4(nr->last_time)/1000, + GET_BE_U_4(nr->last_time)%1000); asbuf[0] = buf[0] = '\0'; - snprintf(buf, sizeof(buf), "/%u", nr->src_mask); + snprintf(buf, sizeof(buf), "/%u", GET_U_1(nr->src_mask)); snprintf(asbuf, sizeof(asbuf), ":%u", - EXTRACT_16BITS(&nr->src_as)); - ND_PRINT((ndo, "\n %s%s%s:%u ", intoa(nr->src_ina.s_addr), buf, asbuf, - EXTRACT_16BITS(&nr->srcport))); + GET_BE_U_2(nr->src_as)); + ND_PRINT("\n %s%s%s:%u ", + intoa(GET_IPV4_TO_NETWORK_ORDER(nr->src_ina)), + buf, asbuf, + GET_BE_U_2(nr->srcport)); - snprintf(buf, sizeof(buf), "/%d", nr->dst_mask); + snprintf(buf, sizeof(buf), "/%u", GET_U_1(nr->dst_mask)); snprintf(asbuf, sizeof(asbuf), ":%u", - EXTRACT_16BITS(&nr->dst_as)); - ND_PRINT((ndo, "> %s%s%s:%u ", intoa(nr->dst_ina.s_addr), buf, asbuf, - EXTRACT_16BITS(&nr->dstport))); - - ND_PRINT((ndo, ">> %s\n ", intoa(nr->nhop_ina.s_addr))); - - if (!ndo->ndo_nflag && (p_name = netdb_protoname(nr->proto)) != NULL) - ND_PRINT((ndo, "%s ", p_name)); + GET_BE_U_2(nr->dst_as)); + ND_PRINT("> %s%s%s:%u ", + intoa(GET_IPV4_TO_NETWORK_ORDER(nr->dst_ina)), + buf, asbuf, + GET_BE_U_2(nr->dstport)); + + ND_PRINT(">> %s\n ", + intoa(GET_IPV4_TO_NETWORK_ORDER(nr->nhop_ina))); + + proto = GET_U_1(nr->proto); + if (!ndo->ndo_nflag && (p_name = netdb_protoname(proto)) != NULL) + ND_PRINT("%s ", p_name); else - ND_PRINT((ndo, "%u ", nr->proto)); + ND_PRINT("%u ", proto); /* tcp flags for tcp only */ - if (nr->proto == IPPROTO_TCP) { - int flags; - flags = nr->tcp_flags; - ND_PRINT((ndo, "%s%s%s%s%s%s%s", + if (proto == IPPROTO_TCP) { + u_int flags; + flags = GET_U_1(nr->tcp_flags); + ND_PRINT("%s%s%s%s%s%s%s", flags & TH_FIN ? "F" : "", flags & TH_SYN ? "S" : "", flags & TH_RST ? "R" : "", flags & TH_PUSH ? "P" : "", flags & TH_ACK ? "A" : "", flags & TH_URG ? "U" : "", - flags ? " " : "")); + flags ? " " : ""); } buf[0]='\0'; snprintf(buf, sizeof(buf), "(%u<>%u encaps)", - (EXTRACT_16BITS(&nr->flags) >> 8) & 0xff, - (EXTRACT_16BITS(&nr->flags)) & 0xff); - ND_PRINT((ndo, "tos %u, %u (%u octets) %s", - nr->tos, - EXTRACT_32BITS(&nr->packets), - EXTRACT_32BITS(&nr->octets), buf)); + (GET_BE_U_2(nr->flags) >> 8) & 0xff, + (GET_BE_U_2(nr->flags)) & 0xff); + ND_PRINT("tos %u, %u (%u octets) %s", + GET_U_1(nr->tos), + GET_BE_U_4(nr->packets), + GET_BE_U_4(nr->octets), buf); } return; trunc: - ND_PRINT((ndo, "[|cnfp]")); - return; + nd_print_trunc(ndo); } void @@ -446,8 +463,8 @@ cnfp_print(netdissect_options *ndo, const u_char *cp) /* * First 2 bytes are the version number. */ - ND_TCHECK2(*cp, 2); - ver = EXTRACT_16BITS(cp); + ndo->ndo_protocol = "cnfp"; + ver = GET_BE_U_2(cp); switch (ver) { case 1: @@ -463,12 +480,7 @@ cnfp_print(netdissect_options *ndo, const u_char *cp) break; default: - ND_PRINT((ndo, "NetFlow v%x", ver)); + ND_PRINT("NetFlow v%x", ver); break; } - return; - -trunc: - ND_PRINT((ndo, "[|cnfp]")); - return; } diff --git a/contrib/tcpdump/print-dccp.c b/contrib/tcpdump/print-dccp.c index bc3feb7c12..9714c3c069 100644 --- a/contrib/tcpdump/print-dccp.c +++ b/contrib/tcpdump/print-dccp.c @@ -9,14 +9,13 @@ /* \summary: Datagram Congestion Control Protocol (DCCP) printer */ +/* specification: RFC 4340 */ + #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include - -#include -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "addrtoname.h" @@ -42,14 +41,14 @@ * @dccph_seq - 24-bit sequence number */ struct dccp_hdr { - uint16_t dccph_sport, + nd_uint16_t dccph_sport, dccph_dport; - uint8_t dccph_doff; - uint8_t dccph_ccval_cscov; - uint16_t dccph_checksum; - uint8_t dccph_xtr; - uint8_t dccph_seq[3]; -} UNALIGNED; + nd_uint8_t dccph_doff; + nd_uint8_t dccph_ccval_cscov; + nd_uint16_t dccph_checksum; + nd_uint8_t dccph_xtr; + nd_uint24_t dccph_seq; +}; /** * struct dccp_hdr_ext - generic part of DCCP packet header, with a 48-bit @@ -66,41 +65,41 @@ struct dccp_hdr { * @dccph_seq - 48-bit sequence number */ struct dccp_hdr_ext { - uint16_t dccph_sport, + nd_uint16_t dccph_sport, dccph_dport; - uint8_t dccph_doff; - uint8_t dccph_ccval_cscov; - uint16_t dccph_checksum; - uint8_t dccph_xtr; - uint8_t reserved; - uint8_t dccph_seq[6]; -} UNALIGNED; + nd_uint8_t dccph_doff; + nd_uint8_t dccph_ccval_cscov; + nd_uint16_t dccph_checksum; + nd_uint8_t dccph_xtr; + nd_uint8_t reserved; + nd_uint48_t dccph_seq; +}; -#define DCCPH_CCVAL(dh) (((dh)->dccph_ccval_cscov >> 4) & 0xF) -#define DCCPH_CSCOV(dh) (((dh)->dccph_ccval_cscov) & 0xF) +#define DCCPH_CCVAL(dh) ((GET_U_1((dh)->dccph_ccval_cscov) >> 4) & 0xF) +#define DCCPH_CSCOV(dh) (GET_U_1((dh)->dccph_ccval_cscov) & 0xF) -#define DCCPH_X(dh) ((dh)->dccph_xtr & 1) -#define DCCPH_TYPE(dh) (((dh)->dccph_xtr >> 1) & 0xF) +#define DCCPH_X(dh) (GET_U_1((dh)->dccph_xtr) & 1) +#define DCCPH_TYPE(dh) ((GET_U_1((dh)->dccph_xtr) >> 1) & 0xF) /** - * struct dccp_hdr_request - Conection initiation request header + * struct dccp_hdr_request - Connection initiation request header * * @dccph_req_service - Service to which the client app wants to connect */ struct dccp_hdr_request { - uint32_t dccph_req_service; -} UNALIGNED; + nd_uint32_t dccph_req_service; +}; /** - * struct dccp_hdr_response - Conection initiation response header + * struct dccp_hdr_response - Connection initiation response header * * @dccph_resp_ack - 48 bit ack number, contains GSR * @dccph_resp_service - Echoes the Service Code on a received DCCP-Request */ struct dccp_hdr_response { - uint8_t dccph_resp_ack[8]; /* always 8 bytes */ - uint32_t dccph_resp_service; -} UNALIGNED; + nd_uint64_t dccph_resp_ack; /* always 8 bytes, first 2 reserved */ + nd_uint32_t dccph_resp_service; +}; /** * struct dccp_hdr_reset - Unconditionally shut down a connection @@ -109,10 +108,12 @@ struct dccp_hdr_response { * @dccph_reset_service - Echoes the Service Code on a received DCCP-Request */ struct dccp_hdr_reset { - uint8_t dccph_reset_ack[8]; /* always 8 bytes */ - uint8_t dccph_reset_code, - dccph_reset_data[3]; -} UNALIGNED; + nd_uint64_t dccph_reset_ack; /* always 8 bytes, first 2 reserved */ + nd_uint8_t dccph_reset_code; + nd_uint8_t dccph_reset_data1; + nd_uint8_t dccph_reset_data2; + nd_uint8_t dccph_reset_data3; +}; enum dccp_pkt_type { DCCP_PKT_REQUEST = 0, @@ -157,7 +158,6 @@ enum dccp_reset_codes { __DCCP_RESET_CODE_LAST }; -static const char tstr[] = "[|dccp]"; static const char *dccp_reset_codes[] = { "unspecified", @@ -187,28 +187,30 @@ static const char *dccp_feature_nums[] = { "check data checksum", }; -static inline u_int dccp_csum_coverage(const struct dccp_hdr* dh, u_int len) +static u_int +dccp_csum_coverage(netdissect_options *ndo, + const struct dccp_hdr* dh, u_int len) { u_int cov; if (DCCPH_CSCOV(dh) == 0) return len; - cov = (dh->dccph_doff + DCCPH_CSCOV(dh) - 1) * sizeof(uint32_t); + cov = (GET_U_1(dh->dccph_doff) + DCCPH_CSCOV(dh) - 1) * sizeof(uint32_t); return (cov > len)? len : cov; } -static int dccp_cksum(netdissect_options *ndo, const struct ip *ip, +static uint16_t dccp_cksum(netdissect_options *ndo, const struct ip *ip, const struct dccp_hdr *dh, u_int len) { return nextproto4_cksum(ndo, ip, (const uint8_t *)(const void *)dh, len, - dccp_csum_coverage(dh, len), IPPROTO_DCCP); + dccp_csum_coverage(ndo, dh, len), IPPROTO_DCCP); } -static int dccp6_cksum(netdissect_options *ndo, const struct ip6_hdr *ip6, +static uint16_t dccp6_cksum(netdissect_options *ndo, const struct ip6_hdr *ip6, const struct dccp_hdr *dh, u_int len) { return nextproto6_cksum(ndo, ip6, (const uint8_t *)(const void *)dh, len, - dccp_csum_coverage(dh, len), IPPROTO_DCCP); + dccp_csum_coverage(ndo, dh, len), IPPROTO_DCCP); } static const char *dccp_reset_code(uint8_t code) @@ -218,22 +220,24 @@ static const char *dccp_reset_code(uint8_t code) return dccp_reset_codes[code]; } -static uint64_t dccp_seqno(const u_char *bp) +static uint64_t +dccp_seqno(netdissect_options *ndo, const u_char *bp) { const struct dccp_hdr *dh = (const struct dccp_hdr *)bp; uint64_t seqno; if (DCCPH_X(dh) != 0) { const struct dccp_hdr_ext *dhx = (const struct dccp_hdr_ext *)bp; - seqno = EXTRACT_48BITS(dhx->dccph_seq); + seqno = GET_BE_U_6(dhx->dccph_seq); } else { - seqno = EXTRACT_24BITS(dh->dccph_seq); + seqno = GET_BE_U_3(dh->dccph_seq); } return seqno; } -static inline unsigned int dccp_basic_hdr_len(const struct dccp_hdr *dh) +static unsigned int +dccp_basic_hdr_len(netdissect_options *ndo, const struct dccp_hdr *dh) { return DCCPH_X(dh) ? sizeof(struct dccp_hdr_ext) : sizeof(struct dccp_hdr); } @@ -241,32 +245,29 @@ static inline unsigned int dccp_basic_hdr_len(const struct dccp_hdr *dh) static void dccp_print_ack_no(netdissect_options *ndo, const u_char *bp) { const struct dccp_hdr *dh = (const struct dccp_hdr *)bp; - const u_char *ackp = bp + dccp_basic_hdr_len(dh); + const u_char *ackp = bp + dccp_basic_hdr_len(ndo, dh); uint64_t ackno; if (DCCPH_X(dh) != 0) { - ND_TCHECK2(*ackp, 8); - ackno = EXTRACT_48BITS(ackp + 2); + ackno = GET_BE_U_6(ackp + 2); } else { - ND_TCHECK2(*ackp, 4); - ackno = EXTRACT_24BITS(ackp + 1); + ackno = GET_BE_U_3(ackp + 1); } - ND_PRINT((ndo, "(ack=%" PRIu64 ") ", ackno)); -trunc: - return; + ND_PRINT("(ack=%" PRIu64 ") ", ackno); } -static int dccp_print_option(netdissect_options *, const u_char *, u_int); +static u_int dccp_print_option(netdissect_options *, const u_char *, u_int); /** * dccp_print - show dccp packet * @bp - beginning of dccp packet * @data2 - beginning of enclosing - * @len - lenght of ip packet + * @len - length of ip packet */ -void dccp_print(netdissect_options *ndo, const u_char *bp, const u_char *data2, - u_int len) +void +dccp_print(netdissect_options *ndo, const u_char *bp, const u_char *data2, + u_int len) { const struct dccp_hdr *dh; const struct ip *ip; @@ -277,6 +278,7 @@ void dccp_print(netdissect_options *ndo, const u_char *bp, const u_char *data2, u_int fixed_hdrlen; uint8_t dccph_type; + ndo->ndo_protocol = "dccp"; dh = (const struct dccp_hdr *)bp; ip = (const struct ip *)data2; @@ -287,74 +289,72 @@ void dccp_print(netdissect_options *ndo, const u_char *bp, const u_char *data2, /* make sure we have enough data to look at the X bit */ cp = (const u_char *)(dh + 1); - if (cp > ndo->ndo_snapend) { - ND_PRINT((ndo, "[Invalid packet|dccp]")); - return; - } + if (cp > ndo->ndo_snapend) + goto trunc; if (len < sizeof(struct dccp_hdr)) { - ND_PRINT((ndo, "truncated-dccp - %u bytes missing!", - len - (u_int)sizeof(struct dccp_hdr))); + ND_PRINT("truncated-dccp - %zu bytes missing!", + sizeof(struct dccp_hdr) - len); return; } /* get the length of the generic header */ - fixed_hdrlen = dccp_basic_hdr_len(dh); + fixed_hdrlen = dccp_basic_hdr_len(ndo, dh); if (len < fixed_hdrlen) { - ND_PRINT((ndo, "truncated-dccp - %u bytes missing!", - len - fixed_hdrlen)); + ND_PRINT("truncated-dccp - %u bytes missing!", + fixed_hdrlen - len); return; } - ND_TCHECK2(*dh, fixed_hdrlen); + ND_TCHECK_LEN(dh, fixed_hdrlen); - sport = EXTRACT_16BITS(&dh->dccph_sport); - dport = EXTRACT_16BITS(&dh->dccph_dport); - hlen = dh->dccph_doff * 4; + sport = GET_BE_U_2(dh->dccph_sport); + dport = GET_BE_U_2(dh->dccph_dport); + hlen = GET_U_1(dh->dccph_doff) * 4; if (ip6) { - ND_PRINT((ndo, "%s.%d > %s.%d: ", - ip6addr_string(ndo, &ip6->ip6_src), sport, - ip6addr_string(ndo, &ip6->ip6_dst), dport)); + ND_PRINT("%s.%u > %s.%u: ", + GET_IP6ADDR_STRING(ip6->ip6_src), sport, + GET_IP6ADDR_STRING(ip6->ip6_dst), dport); } else { - ND_PRINT((ndo, "%s.%d > %s.%d: ", - ipaddr_string(ndo, &ip->ip_src), sport, - ipaddr_string(ndo, &ip->ip_dst), dport)); + ND_PRINT("%s.%u > %s.%u: ", + GET_IPADDR_STRING(ip->ip_src), sport, + GET_IPADDR_STRING(ip->ip_dst), dport); } - ND_PRINT((ndo, "DCCP")); + nd_print_protocol_caps(ndo); if (ndo->ndo_qflag) { - ND_PRINT((ndo, " %d", len - hlen)); + ND_PRINT(" %u", len - hlen); if (hlen > len) { - ND_PRINT((ndo, " [bad hdr length %u - too long, > %u]", - hlen, len)); + ND_PRINT(" [bad hdr length %u - too long, > %u]", + hlen, len); } return; } /* other variables in generic header */ if (ndo->ndo_vflag) { - ND_PRINT((ndo, " (CCVal %d, CsCov %d, ", DCCPH_CCVAL(dh), DCCPH_CSCOV(dh))); + ND_PRINT(" (CCVal %u, CsCov %u, ", DCCPH_CCVAL(dh), DCCPH_CSCOV(dh)); } /* checksum calculation */ - if (ndo->ndo_vflag && ND_TTEST2(bp[0], len)) { + if (ndo->ndo_vflag && ND_TTEST_LEN(bp, len)) { uint16_t sum = 0, dccp_sum; - dccp_sum = EXTRACT_16BITS(&dh->dccph_checksum); - ND_PRINT((ndo, "cksum 0x%04x ", dccp_sum)); + dccp_sum = GET_BE_U_2(dh->dccph_checksum); + ND_PRINT("cksum 0x%04x ", dccp_sum); if (IP_V(ip) == 4) sum = dccp_cksum(ndo, ip, dh, len); else if (IP_V(ip) == 6) sum = dccp6_cksum(ndo, ip6, dh, len); if (sum != 0) - ND_PRINT((ndo, "(incorrect -> 0x%04x)",in_cksum_shouldbe(dccp_sum, sum))); + ND_PRINT("(incorrect -> 0x%04x)",in_cksum_shouldbe(dccp_sum, sum)); else - ND_PRINT((ndo, "(correct)")); + ND_PRINT("(correct)"); } if (ndo->ndo_vflag) - ND_PRINT((ndo, ")")); - ND_PRINT((ndo, " ")); + ND_PRINT(")"); + ND_PRINT(" "); dccph_type = DCCPH_TYPE(dh); switch (dccph_type) { @@ -363,15 +363,15 @@ void dccp_print(netdissect_options *ndo, const u_char *bp, const u_char *data2, (const struct dccp_hdr_request *)(bp + fixed_hdrlen); fixed_hdrlen += 4; if (len < fixed_hdrlen) { - ND_PRINT((ndo, "truncated-%s - %u bytes missing!", + ND_PRINT("truncated-%s - %u bytes missing!", tok2str(dccp_pkt_type_str, "", dccph_type), - len - fixed_hdrlen)); + fixed_hdrlen - len); return; } - ND_TCHECK(*dhr); - ND_PRINT((ndo, "%s (service=%d) ", + ND_TCHECK_SIZE(dhr); + ND_PRINT("%s (service=%u) ", tok2str(dccp_pkt_type_str, "", dccph_type), - EXTRACT_32BITS(&dhr->dccph_req_service))); + GET_BE_U_4(dhr->dccph_req_service)); break; } case DCCP_PKT_RESPONSE: { @@ -379,100 +379,100 @@ void dccp_print(netdissect_options *ndo, const u_char *bp, const u_char *data2, (const struct dccp_hdr_response *)(bp + fixed_hdrlen); fixed_hdrlen += 12; if (len < fixed_hdrlen) { - ND_PRINT((ndo, "truncated-%s - %u bytes missing!", + ND_PRINT("truncated-%s - %u bytes missing!", tok2str(dccp_pkt_type_str, "", dccph_type), - len - fixed_hdrlen)); + fixed_hdrlen - len); return; } - ND_TCHECK(*dhr); - ND_PRINT((ndo, "%s (service=%d) ", + ND_TCHECK_SIZE(dhr); + ND_PRINT("%s (service=%u) ", tok2str(dccp_pkt_type_str, "", dccph_type), - EXTRACT_32BITS(&dhr->dccph_resp_service))); + GET_BE_U_4(dhr->dccph_resp_service)); break; } case DCCP_PKT_DATA: - ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type))); + ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "", dccph_type)); break; case DCCP_PKT_ACK: { fixed_hdrlen += 8; if (len < fixed_hdrlen) { - ND_PRINT((ndo, "truncated-%s - %u bytes missing!", + ND_PRINT("truncated-%s - %u bytes missing!", tok2str(dccp_pkt_type_str, "", dccph_type), - len - fixed_hdrlen)); + fixed_hdrlen - len); return; } - ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type))); + ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "", dccph_type)); break; } case DCCP_PKT_DATAACK: { fixed_hdrlen += 8; if (len < fixed_hdrlen) { - ND_PRINT((ndo, "truncated-%s - %u bytes missing!", + ND_PRINT("truncated-%s - %u bytes missing!", tok2str(dccp_pkt_type_str, "", dccph_type), - len - fixed_hdrlen)); + fixed_hdrlen - len); return; } - ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type))); + ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "", dccph_type)); break; } case DCCP_PKT_CLOSEREQ: fixed_hdrlen += 8; if (len < fixed_hdrlen) { - ND_PRINT((ndo, "truncated-%s - %u bytes missing!", + ND_PRINT("truncated-%s - %u bytes missing!", tok2str(dccp_pkt_type_str, "", dccph_type), - len - fixed_hdrlen)); + fixed_hdrlen - len); return; } - ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type))); + ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "", dccph_type)); break; case DCCP_PKT_CLOSE: fixed_hdrlen += 8; if (len < fixed_hdrlen) { - ND_PRINT((ndo, "truncated-%s - %u bytes missing!", + ND_PRINT("truncated-%s - %u bytes missing!", tok2str(dccp_pkt_type_str, "", dccph_type), - len - fixed_hdrlen)); + fixed_hdrlen - len); return; } - ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type))); + ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "", dccph_type)); break; case DCCP_PKT_RESET: { const struct dccp_hdr_reset *dhr = (const struct dccp_hdr_reset *)(bp + fixed_hdrlen); fixed_hdrlen += 12; if (len < fixed_hdrlen) { - ND_PRINT((ndo, "truncated-%s - %u bytes missing!", + ND_PRINT("truncated-%s - %u bytes missing!", tok2str(dccp_pkt_type_str, "", dccph_type), - len - fixed_hdrlen)); + fixed_hdrlen - len); return; } - ND_TCHECK(*dhr); - ND_PRINT((ndo, "%s (code=%s) ", + ND_TCHECK_SIZE(dhr); + ND_PRINT("%s (code=%s) ", tok2str(dccp_pkt_type_str, "", dccph_type), - dccp_reset_code(dhr->dccph_reset_code))); + dccp_reset_code(GET_U_1(dhr->dccph_reset_code))); break; } case DCCP_PKT_SYNC: fixed_hdrlen += 8; if (len < fixed_hdrlen) { - ND_PRINT((ndo, "truncated-%s - %u bytes missing!", + ND_PRINT("truncated-%s - %u bytes missing!", tok2str(dccp_pkt_type_str, "", dccph_type), - len - fixed_hdrlen)); + fixed_hdrlen - len); return; } - ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type))); + ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "", dccph_type)); break; case DCCP_PKT_SYNCACK: fixed_hdrlen += 8; if (len < fixed_hdrlen) { - ND_PRINT((ndo, "truncated-%s - %u bytes missing!", + ND_PRINT("truncated-%s - %u bytes missing!", tok2str(dccp_pkt_type_str, "", dccph_type), - len - fixed_hdrlen)); + fixed_hdrlen - len); return; } - ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type))); + ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "", dccph_type)); break; default: - ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "unknown-type-%u", dccph_type))); + ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "unknown-type-%u", dccph_type)); break; } @@ -483,13 +483,13 @@ void dccp_print(netdissect_options *ndo, const u_char *bp, const u_char *data2, if (ndo->ndo_vflag < 2) return; - ND_PRINT((ndo, "seq %" PRIu64, dccp_seqno(bp))); + ND_PRINT("seq %" PRIu64, dccp_seqno(ndo, bp)); /* process options */ if (hlen > fixed_hdrlen){ u_int optlen; cp = bp + fixed_hdrlen; - ND_PRINT((ndo, " <")); + ND_PRINT(" <"); hlen -= fixed_hdrlen; while(1){ @@ -500,14 +500,13 @@ void dccp_print(netdissect_options *ndo, const u_char *bp, const u_char *data2, break; hlen -= optlen; cp += optlen; - ND_PRINT((ndo, ", ")); + ND_PRINT(", "); } - ND_PRINT((ndo, ">")); + ND_PRINT(">"); } return; trunc: - ND_PRINT((ndo, "%s", tstr)); - return; + nd_print_trunc(ndo); } static const struct tok dccp_option_values[] = { @@ -530,97 +529,102 @@ static const struct tok dccp_option_values[] = { { 0, NULL } }; -static int +static u_int dccp_print_option(netdissect_options *ndo, const u_char *option, u_int hlen) { uint8_t optlen, i; - ND_TCHECK(*option); - - if (*option >= 32) { - ND_TCHECK(*(option+1)); - optlen = *(option +1); + if (GET_U_1(option) >= 32) { + optlen = GET_U_1(option + 1); if (optlen < 2) { - if (*option >= 128) - ND_PRINT((ndo, "CCID option %u optlen too short", *option)); + if (GET_U_1(option) >= 128) + ND_PRINT("CCID option %u optlen too short", + GET_U_1(option)); else - ND_PRINT((ndo, "%s optlen too short", - tok2str(dccp_option_values, "Option %u", *option))); + ND_PRINT("%s optlen too short", + tok2str(dccp_option_values, "Option %u", GET_U_1(option))); return 0; } } else optlen = 1; if (hlen < optlen) { - if (*option >= 128) - ND_PRINT((ndo, "CCID option %u optlen goes past header length", - *option)); + if (GET_U_1(option) >= 128) + ND_PRINT("CCID option %u optlen goes past header length", + GET_U_1(option)); else - ND_PRINT((ndo, "%s optlen goes past header length", - tok2str(dccp_option_values, "Option %u", *option))); + ND_PRINT("%s optlen goes past header length", + tok2str(dccp_option_values, "Option %u", GET_U_1(option))); return 0; } - ND_TCHECK2(*option, optlen); + ND_TCHECK_LEN(option, optlen); - if (*option >= 128) { - ND_PRINT((ndo, "CCID option %d", *option)); + if (GET_U_1(option) >= 128) { + ND_PRINT("CCID option %u", GET_U_1(option)); switch (optlen) { case 4: - ND_PRINT((ndo, " %u", EXTRACT_16BITS(option + 2))); + ND_PRINT(" %u", GET_BE_U_2(option + 2)); break; case 6: - ND_PRINT((ndo, " %u", EXTRACT_32BITS(option + 2))); + ND_PRINT(" %u", GET_BE_U_4(option + 2)); break; default: break; } } else { - ND_PRINT((ndo, "%s", tok2str(dccp_option_values, "Option %u", *option))); - switch (*option) { + ND_PRINT("%s", + tok2str(dccp_option_values, "Option %u", GET_U_1(option))); + switch (GET_U_1(option)) { case 32: case 33: case 34: case 35: if (optlen < 3) { - ND_PRINT((ndo, " optlen too short")); + ND_PRINT(" optlen too short"); return optlen; } - if (*(option + 2) < 10){ - ND_PRINT((ndo, " %s", dccp_feature_nums[*(option + 2)])); + if (GET_U_1(option + 2) < 10){ + ND_PRINT(" %s", + dccp_feature_nums[GET_U_1(option + 2)]); for (i = 0; i < optlen - 3; i++) - ND_PRINT((ndo, " %d", *(option + 3 + i))); + ND_PRINT(" %u", + GET_U_1(option + 3 + i)); } break; case 36: if (optlen > 2) { - ND_PRINT((ndo, " 0x")); + ND_PRINT(" 0x"); for (i = 0; i < optlen - 2; i++) - ND_PRINT((ndo, "%02x", *(option + 2 + i))); + ND_PRINT("%02x", + GET_U_1(option + 2 + i)); } break; case 37: for (i = 0; i < optlen - 2; i++) - ND_PRINT((ndo, " %d", *(option + 2 + i))); + ND_PRINT(" %u", GET_U_1(option + 2 + i)); break; case 38: if (optlen > 2) { - ND_PRINT((ndo, " 0x")); + ND_PRINT(" 0x"); for (i = 0; i < optlen - 2; i++) - ND_PRINT((ndo, "%02x", *(option + 2 + i))); + ND_PRINT("%02x", + GET_U_1(option + 2 + i)); } break; case 39: if (optlen > 2) { - ND_PRINT((ndo, " 0x")); + ND_PRINT(" 0x"); for (i = 0; i < optlen - 2; i++) - ND_PRINT((ndo, "%02x", *(option + 2 + i))); + ND_PRINT("%02x", + GET_U_1(option + 2 + i)); } break; case 40: if (optlen > 2) { - ND_PRINT((ndo, " 0x")); + ND_PRINT(" 0x"); for (i = 0; i < optlen - 2; i++) - ND_PRINT((ndo, "%02x", *(option + 2 + i))); + ND_PRINT("%02x", + GET_U_1(option + 2 + i)); } break; case 41: @@ -633,9 +637,9 @@ dccp_print_option(netdissect_options *ndo, const u_char *option, u_int hlen) * Type=41 Length=6 */ if (optlen == 6) - ND_PRINT((ndo, " %u", EXTRACT_32BITS(option + 2))); + ND_PRINT(" %u", GET_BE_U_4(option + 2)); else - ND_PRINT((ndo, " [optlen != 6]")); + ND_PRINT(" [optlen != 6]"); break; case 42: /* @@ -658,34 +662,37 @@ dccp_print_option(netdissect_options *ndo, const u_char *option, u_int hlen) */ switch (optlen) { case 6: - ND_PRINT((ndo, " %u", EXTRACT_32BITS(option + 2))); + ND_PRINT(" %u", GET_BE_U_4(option + 2)); break; case 8: - ND_PRINT((ndo, " %u", EXTRACT_32BITS(option + 2))); - ND_PRINT((ndo, " (elapsed time %u)", EXTRACT_16BITS(option + 6))); + ND_PRINT(" %u", GET_BE_U_4(option + 2)); + ND_PRINT(" (elapsed time %u)", + GET_BE_U_2(option + 6)); break; case 10: - ND_PRINT((ndo, " %u", EXTRACT_32BITS(option + 2))); - ND_PRINT((ndo, " (elapsed time %u)", EXTRACT_32BITS(option + 6))); + ND_PRINT(" %u", GET_BE_U_4(option + 2)); + ND_PRINT(" (elapsed time %u)", + GET_BE_U_4(option + 6)); break; default: - ND_PRINT((ndo, " [optlen != 6 or 8 or 10]")); + ND_PRINT(" [optlen != 6 or 8 or 10]"); break; } break; case 43: if (optlen == 6) - ND_PRINT((ndo, " %u", EXTRACT_32BITS(option + 2))); + ND_PRINT(" %u", GET_BE_U_4(option + 2)); else if (optlen == 4) - ND_PRINT((ndo, " %u", EXTRACT_16BITS(option + 2))); + ND_PRINT(" %u", GET_BE_U_2(option + 2)); else - ND_PRINT((ndo, " [optlen != 4 or 6]")); + ND_PRINT(" [optlen != 4 or 6]"); break; case 44: if (optlen > 2) { - ND_PRINT((ndo, " ")); + ND_PRINT(" "); for (i = 0; i < optlen - 2; i++) - ND_PRINT((ndo, "%02x", *(option + 2 + i))); + ND_PRINT("%02x", + GET_U_1(option + 2 + i)); } break; } @@ -693,6 +700,6 @@ dccp_print_option(netdissect_options *ndo, const u_char *option, u_int hlen) return optlen; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return 0; } diff --git a/contrib/tcpdump/print-decnet.c b/contrib/tcpdump/print-decnet.c index 6e2c7913f5..6a6dd25982 100644 --- a/contrib/tcpdump/print-decnet.c +++ b/contrib/tcpdump/print-decnet.c @@ -22,48 +22,42 @@ /* \summary: DECnet printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include - -struct mbuf; -struct rtentry; +#include "netdissect-stdinc.h" #include #include -#include -#include "extract.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" +#include "extract.h" #include "addrtoname.h" -static const char tstr[] = "[|decnet]"; #ifndef _WIN32 -typedef uint8_t byte[1]; /* single byte field */ +typedef nd_uint8_t byte; /* single byte field */ #else /* * the keyword 'byte' generates conflicts in Windows */ -typedef unsigned char Byte[1]; /* single byte field */ +typedef nd_uint8_t Byte; /* single byte field */ #define byte Byte #endif /* _WIN32 */ -typedef uint8_t word[2]; /* 2 byte field */ -typedef uint8_t longword[4]; /* 4 bytes field */ +typedef nd_uint16_t word; /* 2 byte field */ +typedef nd_uint32_t longword; /* 4 bytes field */ /* * Definitions for DECNET Phase IV protocol headers */ -union etheraddress { - uint8_t dne_addr[6]; /* full ethernet address */ +typedef union { + nd_mac_addr dne_addr; /* full Ethernet address */ struct { - uint8_t dne_hiord[4]; /* DECnet HIORD prefix */ - uint8_t dne_nodeaddr[2]; /* DECnet node address */ + nd_byte dne_hiord[4]; /* DECnet HIORD prefix */ + nd_byte dne_nodeaddr[2]; /* DECnet node address */ } dne_remote; -}; - -typedef union etheraddress etheraddr; /* Ethernet address */ +} etheraddr; /* Ethernet address */ #define HIORD 0x000400aa /* high 32-bits of address (swapped) */ @@ -163,18 +157,6 @@ union routehdr /* * Define control message formats. */ -struct initmsgIII /* phase III initialization message */ - { - byte inIII_flags; /* route flags */ - word inIII_src; /* source node address */ - byte inIII_info; /* routing layer information */ - word inIII_blksize; /* maximum data link block size */ - byte inIII_vers; /* version number */ - byte inIII_eco; /* ECO number */ - byte inIII_ueco; /* user ECO number */ - byte inIII_rsvd; /* reserved image field */ - }; - struct initmsg /* initialization message */ { byte in_flags; /* route flags */ @@ -474,366 +456,339 @@ struct dcmsg /* disconnect confirm message */ /* Forwards */ static int print_decnet_ctlmsg(netdissect_options *, const union routehdr *, u_int, u_int); -static void print_t_info(netdissect_options *, int); -static int print_l1_routes(netdissect_options *, const char *, u_int); -static int print_l2_routes(netdissect_options *, const char *, u_int); -static void print_i_info(netdissect_options *, int); -static int print_elist(const char *, u_int); +static void print_t_info(netdissect_options *, u_int); +static void print_l1_routes(netdissect_options *, const u_char *, u_int); +static void print_l2_routes(netdissect_options *, const u_char *, u_int); +static void print_i_info(netdissect_options *, u_int); +static void print_elist(const u_char *, u_int); static int print_nsp(netdissect_options *, const u_char *, u_int); -static void print_reason(netdissect_options *, int); +static void print_reason(netdissect_options *, u_int); void decnet_print(netdissect_options *ndo, - register const u_char *ap, register u_int length, - register u_int caplen) + const u_char *ap, u_int length, + u_int caplen) { - register const union routehdr *rhp; - register int mflags; - int dst, src, hops; + const union routehdr *rhp; + u_int mflags; + uint16_t dst, src; + u_int hops; u_int nsplen, pktlen; const u_char *nspp; + ndo->ndo_protocol = "decnet"; if (length < sizeof(struct shorthdr)) { - ND_PRINT((ndo, "%s", tstr)); - return; + ND_PRINT(" (length %u < %zu)", length, sizeof(struct shorthdr)); + goto invalid; } - ND_TCHECK2(*ap, sizeof(short)); - pktlen = EXTRACT_LE_16BITS(ap); + pktlen = GET_LE_U_2(ap); if (pktlen < sizeof(struct shorthdr)) { - ND_PRINT((ndo, "%s", tstr)); - return; + ND_PRINT(" (pktlen %u < %zu)", pktlen, sizeof(struct shorthdr)); + goto invalid; } if (pktlen > length) { - ND_PRINT((ndo, "%s", tstr)); - return; + ND_PRINT(" (pktlen %u > %u)", pktlen, length); + goto invalid; } length = pktlen; - rhp = (const union routehdr *)&(ap[sizeof(short)]); - ND_TCHECK(rhp->rh_short.sh_flags); - mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags); + rhp = (const union routehdr *)(ap + sizeof(short)); + mflags = GET_U_1(rhp->rh_short.sh_flags); if (mflags & RMF_PAD) { /* pad bytes of some sort in front of message */ u_int padlen = mflags & RMF_PADMASK; if (ndo->ndo_vflag) - ND_PRINT((ndo, "[pad:%d] ", padlen)); + ND_PRINT("[pad:%u] ", padlen); if (length < padlen + 2) { - ND_PRINT((ndo, "%s", tstr)); - return; + ND_PRINT(" (length %u < %u)", length, padlen + 2); + goto invalid; } - ND_TCHECK2(ap[sizeof(short)], padlen); + ND_TCHECK_LEN(ap + sizeof(short), padlen); ap += padlen; length -= padlen; caplen -= padlen; - rhp = (const union routehdr *)&(ap[sizeof(short)]); - ND_TCHECK(rhp->rh_short.sh_flags); - mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags); + rhp = (const union routehdr *)(ap + sizeof(short)); + mflags = GET_U_1(rhp->rh_short.sh_flags); } if (mflags & RMF_FVER) { - ND_PRINT((ndo, "future-version-decnet")); - ND_DEFAULTPRINT(ap, min(length, caplen)); + ND_PRINT("future-version-decnet"); + ND_DEFAULTPRINT(ap, ND_MIN(length, caplen)); return; } /* is it a control message? */ if (mflags & RMF_CTLMSG) { if (!print_decnet_ctlmsg(ndo, rhp, length, caplen)) - goto trunc; + goto invalid; return; } switch (mflags & RMF_MASK) { case RMF_LONG: if (length < sizeof(struct longhdr)) { - ND_PRINT((ndo, "%s", tstr)); - return; + ND_PRINT(" (length %u < %zu)", length, sizeof(struct longhdr)); + goto invalid; } - ND_TCHECK(rhp->rh_long); + ND_TCHECK_SIZE(&rhp->rh_long); dst = - EXTRACT_LE_16BITS(rhp->rh_long.lg_dst.dne_remote.dne_nodeaddr); + GET_LE_U_2(rhp->rh_long.lg_dst.dne_remote.dne_nodeaddr); src = - EXTRACT_LE_16BITS(rhp->rh_long.lg_src.dne_remote.dne_nodeaddr); - hops = EXTRACT_LE_8BITS(rhp->rh_long.lg_visits); - nspp = &(ap[sizeof(short) + sizeof(struct longhdr)]); + GET_LE_U_2(rhp->rh_long.lg_src.dne_remote.dne_nodeaddr); + hops = GET_U_1(rhp->rh_long.lg_visits); + nspp = ap + sizeof(short) + sizeof(struct longhdr); nsplen = length - sizeof(struct longhdr); break; case RMF_SHORT: - ND_TCHECK(rhp->rh_short); - dst = EXTRACT_LE_16BITS(rhp->rh_short.sh_dst); - src = EXTRACT_LE_16BITS(rhp->rh_short.sh_src); - hops = (EXTRACT_LE_8BITS(rhp->rh_short.sh_visits) & VIS_MASK)+1; - nspp = &(ap[sizeof(short) + sizeof(struct shorthdr)]); + dst = GET_LE_U_2(rhp->rh_short.sh_dst); + src = GET_LE_U_2(rhp->rh_short.sh_src); + hops = (GET_U_1(rhp->rh_short.sh_visits) & VIS_MASK)+1; + nspp = ap + sizeof(short) + sizeof(struct shorthdr); nsplen = length - sizeof(struct shorthdr); break; default: - ND_PRINT((ndo, "unknown message flags under mask")); - ND_DEFAULTPRINT((const u_char *)ap, min(length, caplen)); + ND_PRINT("unknown message flags under mask"); + ND_DEFAULTPRINT((const u_char *)ap, ND_MIN(length, caplen)); return; } - ND_PRINT((ndo, "%s > %s %d ", - dnaddr_string(ndo, src), dnaddr_string(ndo, dst), pktlen)); + ND_PRINT("%s > %s %u ", + dnaddr_string(ndo, src), dnaddr_string(ndo, dst), pktlen); if (ndo->ndo_vflag) { if (mflags & RMF_RQR) - ND_PRINT((ndo, "RQR ")); + ND_PRINT("RQR "); if (mflags & RMF_RTS) - ND_PRINT((ndo, "RTS ")); + ND_PRINT("RTS "); if (mflags & RMF_IE) - ND_PRINT((ndo, "IE ")); - ND_PRINT((ndo, "%d hops ", hops)); + ND_PRINT("IE "); + ND_PRINT("%u hops ", hops); } if (!print_nsp(ndo, nspp, nsplen)) - goto trunc; + goto invalid; return; -trunc: - ND_PRINT((ndo, "%s", tstr)); - return; +invalid: + nd_print_invalid(ndo); } static int print_decnet_ctlmsg(netdissect_options *ndo, - register const union routehdr *rhp, u_int length, + const union routehdr *rhp, u_int length, u_int caplen) { /* Our caller has already checked for mflags */ - int mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags); - register const union controlmsg *cmp = (const union controlmsg *)rhp; - int src, dst, info, blksize, eco, ueco, hello, other, vers; - etheraddr srcea, rtea; - int priority; - const char *rhpx = (const char *)rhp; - int ret; + u_int mflags = GET_U_1(rhp->rh_short.sh_flags); + const union controlmsg *cmp = (const union controlmsg *)rhp; + uint16_t src, dst; + u_int info, blksize, eco, ueco, hello, other, vers; + u_int priority; + const u_char *rhpx = (const u_char *)rhp; switch (mflags & RMF_CTLMASK) { case RMF_INIT: - ND_PRINT((ndo, "init ")); + ND_PRINT("init "); if (length < sizeof(struct initmsg)) - goto trunc; - ND_TCHECK(cmp->cm_init); - src = EXTRACT_LE_16BITS(cmp->cm_init.in_src); - info = EXTRACT_LE_8BITS(cmp->cm_init.in_info); - blksize = EXTRACT_LE_16BITS(cmp->cm_init.in_blksize); - vers = EXTRACT_LE_8BITS(cmp->cm_init.in_vers); - eco = EXTRACT_LE_8BITS(cmp->cm_init.in_eco); - ueco = EXTRACT_LE_8BITS(cmp->cm_init.in_ueco); - hello = EXTRACT_LE_16BITS(cmp->cm_init.in_hello); + goto invalid; + ND_TCHECK_SIZE(&cmp->cm_init); + src = GET_LE_U_2(cmp->cm_init.in_src); + info = GET_U_1(cmp->cm_init.in_info); + blksize = GET_LE_U_2(cmp->cm_init.in_blksize); + vers = GET_U_1(cmp->cm_init.in_vers); + eco = GET_U_1(cmp->cm_init.in_eco); + ueco = GET_U_1(cmp->cm_init.in_ueco); + hello = GET_LE_U_2(cmp->cm_init.in_hello); print_t_info(ndo, info); - ND_PRINT((ndo, - "src %sblksize %d vers %d eco %d ueco %d hello %d", + ND_PRINT("src %sblksize %u vers %u eco %u ueco %u hello %u", dnaddr_string(ndo, src), blksize, vers, eco, ueco, - hello)); - ret = 1; + hello); break; case RMF_VER: - ND_PRINT((ndo, "verification ")); + ND_PRINT("verification "); if (length < sizeof(struct verifmsg)) - goto trunc; - ND_TCHECK(cmp->cm_ver); - src = EXTRACT_LE_16BITS(cmp->cm_ver.ve_src); - other = EXTRACT_LE_8BITS(cmp->cm_ver.ve_fcnval); - ND_PRINT((ndo, "src %s fcnval %o", dnaddr_string(ndo, src), other)); - ret = 1; + goto invalid; + src = GET_LE_U_2(cmp->cm_ver.ve_src); + other = GET_U_1(cmp->cm_ver.ve_fcnval); + ND_PRINT("src %s fcnval %o", dnaddr_string(ndo, src), other); break; case RMF_TEST: - ND_PRINT((ndo, "test ")); + ND_PRINT("test "); if (length < sizeof(struct testmsg)) - goto trunc; - ND_TCHECK(cmp->cm_test); - src = EXTRACT_LE_16BITS(cmp->cm_test.te_src); - other = EXTRACT_LE_8BITS(cmp->cm_test.te_data); - ND_PRINT((ndo, "src %s data %o", dnaddr_string(ndo, src), other)); - ret = 1; + goto invalid; + src = GET_LE_U_2(cmp->cm_test.te_src); + other = GET_U_1(cmp->cm_test.te_data); + ND_PRINT("src %s data %o", dnaddr_string(ndo, src), other); break; case RMF_L1ROUT: - ND_PRINT((ndo, "lev-1-routing ")); + ND_PRINT("lev-1-routing "); if (length < sizeof(struct l1rout)) - goto trunc; - ND_TCHECK(cmp->cm_l1rou); - src = EXTRACT_LE_16BITS(cmp->cm_l1rou.r1_src); - ND_PRINT((ndo, "src %s ", dnaddr_string(ndo, src))); - ret = print_l1_routes(ndo, &(rhpx[sizeof(struct l1rout)]), + goto invalid; + ND_TCHECK_SIZE(&cmp->cm_l1rou); + src = GET_LE_U_2(cmp->cm_l1rou.r1_src); + ND_PRINT("src %s ", dnaddr_string(ndo, src)); + print_l1_routes(ndo, &(rhpx[sizeof(struct l1rout)]), length - sizeof(struct l1rout)); break; case RMF_L2ROUT: - ND_PRINT((ndo, "lev-2-routing ")); + ND_PRINT("lev-2-routing "); if (length < sizeof(struct l2rout)) - goto trunc; - ND_TCHECK(cmp->cm_l2rout); - src = EXTRACT_LE_16BITS(cmp->cm_l2rout.r2_src); - ND_PRINT((ndo, "src %s ", dnaddr_string(ndo, src))); - ret = print_l2_routes(ndo, &(rhpx[sizeof(struct l2rout)]), + goto invalid; + ND_TCHECK_SIZE(&cmp->cm_l2rout); + src = GET_LE_U_2(cmp->cm_l2rout.r2_src); + ND_PRINT("src %s ", dnaddr_string(ndo, src)); + print_l2_routes(ndo, &(rhpx[sizeof(struct l2rout)]), length - sizeof(struct l2rout)); break; case RMF_RHELLO: - ND_PRINT((ndo, "router-hello ")); + ND_PRINT("router-hello "); if (length < sizeof(struct rhellomsg)) - goto trunc; - ND_TCHECK(cmp->cm_rhello); - vers = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_vers); - eco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_eco); - ueco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_ueco); - memcpy((char *)&srcea, (const char *)&(cmp->cm_rhello.rh_src), - sizeof(srcea)); - src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr); - info = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_info); - blksize = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_blksize); - priority = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_priority); - hello = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_hello); + goto invalid; + ND_TCHECK_SIZE(&cmp->cm_rhello); + vers = GET_U_1(cmp->cm_rhello.rh_vers); + eco = GET_U_1(cmp->cm_rhello.rh_eco); + ueco = GET_U_1(cmp->cm_rhello.rh_ueco); + src = + GET_LE_U_2(cmp->cm_rhello.rh_src.dne_remote.dne_nodeaddr); + info = GET_U_1(cmp->cm_rhello.rh_info); + blksize = GET_LE_U_2(cmp->cm_rhello.rh_blksize); + priority = GET_U_1(cmp->cm_rhello.rh_priority); + hello = GET_LE_U_2(cmp->cm_rhello.rh_hello); print_i_info(ndo, info); - ND_PRINT((ndo, - "vers %d eco %d ueco %d src %s blksize %d pri %d hello %d", + ND_PRINT("vers %u eco %u ueco %u src %s blksize %u pri %u hello %u", vers, eco, ueco, dnaddr_string(ndo, src), - blksize, priority, hello)); - ret = print_elist(&(rhpx[sizeof(struct rhellomsg)]), + blksize, priority, hello); + print_elist(&(rhpx[sizeof(struct rhellomsg)]), length - sizeof(struct rhellomsg)); break; case RMF_EHELLO: - ND_PRINT((ndo, "endnode-hello ")); + ND_PRINT("endnode-hello "); if (length < sizeof(struct ehellomsg)) - goto trunc; - ND_TCHECK(cmp->cm_ehello); - vers = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_vers); - eco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_eco); - ueco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_ueco); - memcpy((char *)&srcea, (const char *)&(cmp->cm_ehello.eh_src), - sizeof(srcea)); - src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr); - info = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_info); - blksize = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_blksize); + goto invalid; + vers = GET_U_1(cmp->cm_ehello.eh_vers); + eco = GET_U_1(cmp->cm_ehello.eh_eco); + ueco = GET_U_1(cmp->cm_ehello.eh_ueco); + src = + GET_LE_U_2(cmp->cm_ehello.eh_src.dne_remote.dne_nodeaddr); + info = GET_U_1(cmp->cm_ehello.eh_info); + blksize = GET_LE_U_2(cmp->cm_ehello.eh_blksize); /*seed*/ - memcpy((char *)&rtea, (const char *)&(cmp->cm_ehello.eh_router), - sizeof(rtea)); - dst = EXTRACT_LE_16BITS(rtea.dne_remote.dne_nodeaddr); - hello = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_hello); - other = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_data); + dst = + GET_LE_U_2(cmp->cm_ehello.eh_router.dne_remote.dne_nodeaddr); + hello = GET_LE_U_2(cmp->cm_ehello.eh_hello); + other = GET_U_1(cmp->cm_ehello.eh_data); print_i_info(ndo, info); - ND_PRINT((ndo, - "vers %d eco %d ueco %d src %s blksize %d rtr %s hello %d data %o", + ND_PRINT("vers %u eco %u ueco %u src %s blksize %u rtr %s hello %u data %o", vers, eco, ueco, dnaddr_string(ndo, src), - blksize, dnaddr_string(ndo, dst), hello, other)); - ret = 1; + blksize, dnaddr_string(ndo, dst), hello, other); break; default: - ND_PRINT((ndo, "unknown control message")); - ND_DEFAULTPRINT((const u_char *)rhp, min(length, caplen)); - ret = 1; + ND_PRINT("unknown control message"); + ND_DEFAULTPRINT((const u_char *)rhp, ND_MIN(length, caplen)); break; } - return (ret); + return (1); -trunc: +invalid: return (0); } static void print_t_info(netdissect_options *ndo, - int info) + u_int info) { - int ntype = info & 3; + u_int ntype = info & 3; switch (ntype) { - case 0: ND_PRINT((ndo, "reserved-ntype? ")); break; - case TI_L2ROUT: ND_PRINT((ndo, "l2rout ")); break; - case TI_L1ROUT: ND_PRINT((ndo, "l1rout ")); break; - case TI_ENDNODE: ND_PRINT((ndo, "endnode ")); break; + case 0: ND_PRINT("reserved-ntype? "); break; + case TI_L2ROUT: ND_PRINT("l2rout "); break; + case TI_L1ROUT: ND_PRINT("l1rout "); break; + case TI_ENDNODE: ND_PRINT("endnode "); break; } if (info & TI_VERIF) - ND_PRINT((ndo, "verif ")); + ND_PRINT("verif "); if (info & TI_BLOCK) - ND_PRINT((ndo, "blo ")); + ND_PRINT("blo "); } -static int +static void print_l1_routes(netdissect_options *ndo, - const char *rp, u_int len) + const u_char *rp, u_int len) { - int count; - int id; - int info; + u_int count; + u_int id; + u_int info; /* The last short is a checksum */ while (len > (3 * sizeof(short))) { - ND_TCHECK2(*rp, 3 * sizeof(short)); - count = EXTRACT_LE_16BITS(rp); + ND_TCHECK_LEN(rp, 3 * sizeof(short)); + count = GET_LE_U_2(rp); if (count > 1024) - return (1); /* seems to be bogus from here on */ + return; /* seems to be bogus from here on */ rp += sizeof(short); len -= sizeof(short); - id = EXTRACT_LE_16BITS(rp); + id = GET_LE_U_2(rp); rp += sizeof(short); len -= sizeof(short); - info = EXTRACT_LE_16BITS(rp); + info = GET_LE_U_2(rp); rp += sizeof(short); len -= sizeof(short); - ND_PRINT((ndo, "{ids %d-%d cost %d hops %d} ", id, id + count, - RI_COST(info), RI_HOPS(info))); + ND_PRINT("{ids %u-%u cost %u hops %u} ", id, id + count, + RI_COST(info), RI_HOPS(info)); } - return (1); - -trunc: - return (0); } -static int +static void print_l2_routes(netdissect_options *ndo, - const char *rp, u_int len) + const u_char *rp, u_int len) { - int count; - int area; - int info; + u_int count; + u_int area; + u_int info; /* The last short is a checksum */ while (len > (3 * sizeof(short))) { - ND_TCHECK2(*rp, 3 * sizeof(short)); - count = EXTRACT_LE_16BITS(rp); + ND_TCHECK_LEN(rp, 3 * sizeof(short)); + count = GET_LE_U_2(rp); if (count > 1024) - return (1); /* seems to be bogus from here on */ + return; /* seems to be bogus from here on */ rp += sizeof(short); len -= sizeof(short); - area = EXTRACT_LE_16BITS(rp); + area = GET_LE_U_2(rp); rp += sizeof(short); len -= sizeof(short); - info = EXTRACT_LE_16BITS(rp); + info = GET_LE_U_2(rp); rp += sizeof(short); len -= sizeof(short); - ND_PRINT((ndo, "{areas %d-%d cost %d hops %d} ", area, area + count, - RI_COST(info), RI_HOPS(info))); + ND_PRINT("{areas %u-%u cost %u hops %u} ", area, area + count, + RI_COST(info), RI_HOPS(info)); } - return (1); - -trunc: - return (0); } static void print_i_info(netdissect_options *ndo, - int info) + u_int info) { - int ntype = info & II_TYPEMASK; + u_int ntype = info & II_TYPEMASK; switch (ntype) { - case 0: ND_PRINT((ndo, "reserved-ntype? ")); break; - case II_L2ROUT: ND_PRINT((ndo, "l2rout ")); break; - case II_L1ROUT: ND_PRINT((ndo, "l1rout ")); break; - case II_ENDNODE: ND_PRINT((ndo, "endnode ")); break; + case 0: ND_PRINT("reserved-ntype? "); break; + case II_L2ROUT: ND_PRINT("l2rout "); break; + case II_L1ROUT: ND_PRINT("l1rout "); break; + case II_ENDNODE: ND_PRINT("endnode "); break; } if (info & II_VERIF) - ND_PRINT((ndo, "verif ")); + ND_PRINT("verif "); if (info & II_NOMCAST) - ND_PRINT((ndo, "nomcast ")); + ND_PRINT("nomcast "); if (info & II_BLOCK) - ND_PRINT((ndo, "blo ")); + ND_PRINT("blo "); } -static int -print_elist(const char *elp _U_, u_int len _U_) +static void +print_elist(const u_char *elp _U_, u_int len _U_) { /* Not enough examples available for me to debug this */ - return (1); } static int @@ -841,14 +796,15 @@ print_nsp(netdissect_options *ndo, const u_char *nspp, u_int nsplen) { const struct nsphdr *nsphp = (const struct nsphdr *)nspp; - int dst, src, flags; + u_int dst, src, flags; - if (nsplen < sizeof(struct nsphdr)) - goto trunc; - ND_TCHECK(*nsphp); - flags = EXTRACT_LE_8BITS(nsphp->nh_flags); - dst = EXTRACT_LE_16BITS(nsphp->nh_dst); - src = EXTRACT_LE_16BITS(nsphp->nh_src); + if (nsplen < sizeof(struct nsphdr)) { + ND_PRINT(" (nsplen %u < %zu)", nsplen, sizeof(struct nsphdr)); + goto invalid; + } + flags = GET_U_1(nsphp->nh_flags); + dst = GET_LE_U_2(nsphp->nh_dst); + src = GET_LE_U_2(nsphp->nh_src); switch (flags & NSP_TYPEMASK) { case MFT_DATA: @@ -857,199 +813,188 @@ print_nsp(netdissect_options *ndo, case MFS_MOM: case MFS_EOM: case MFS_BOM+MFS_EOM: - ND_PRINT((ndo, "data %d>%d ", src, dst)); + ND_PRINT("data %u>%u ", src, dst); { const struct seghdr *shp = (const struct seghdr *)nspp; - int ack; + u_int ack; u_int data_off = sizeof(struct minseghdr); if (nsplen < data_off) - goto trunc; - ND_TCHECK(shp->sh_seq[0]); - ack = EXTRACT_LE_16BITS(shp->sh_seq[0]); + goto invalid; + ack = GET_LE_U_2(shp->sh_seq[0]); if (ack & SGQ_ACK) { /* acknum field */ if ((ack & SGQ_NAK) == SGQ_NAK) - ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); + ND_PRINT("nak %u ", ack & SGQ_MASK); else - ND_PRINT((ndo, "ack %d ", ack & SGQ_MASK)); + ND_PRINT("ack %u ", ack & SGQ_MASK); data_off += sizeof(short); if (nsplen < data_off) - goto trunc; - ND_TCHECK(shp->sh_seq[1]); - ack = EXTRACT_LE_16BITS(shp->sh_seq[1]); + goto invalid; + ack = GET_LE_U_2(shp->sh_seq[1]); if (ack & SGQ_OACK) { /* ackoth field */ if ((ack & SGQ_ONAK) == SGQ_ONAK) - ND_PRINT((ndo, "onak %d ", ack & SGQ_MASK)); + ND_PRINT("onak %u ", ack & SGQ_MASK); else - ND_PRINT((ndo, "oack %d ", ack & SGQ_MASK)); + ND_PRINT("oack %u ", ack & SGQ_MASK); data_off += sizeof(short); if (nsplen < data_off) - goto trunc; - ND_TCHECK(shp->sh_seq[2]); - ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); + goto invalid; + ack = GET_LE_U_2(shp->sh_seq[2]); } } - ND_PRINT((ndo, "seg %d ", ack & SGQ_MASK)); + ND_PRINT("seg %u ", ack & SGQ_MASK); } break; case MFS_ILS+MFS_INT: - ND_PRINT((ndo, "intr ")); + ND_PRINT("intr "); { const struct seghdr *shp = (const struct seghdr *)nspp; - int ack; + u_int ack; u_int data_off = sizeof(struct minseghdr); if (nsplen < data_off) - goto trunc; - ND_TCHECK(shp->sh_seq[0]); - ack = EXTRACT_LE_16BITS(shp->sh_seq[0]); + goto invalid; + ack = GET_LE_U_2(shp->sh_seq[0]); if (ack & SGQ_ACK) { /* acknum field */ if ((ack & SGQ_NAK) == SGQ_NAK) - ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); + ND_PRINT("nak %u ", ack & SGQ_MASK); else - ND_PRINT((ndo, "ack %d ", ack & SGQ_MASK)); + ND_PRINT("ack %u ", ack & SGQ_MASK); data_off += sizeof(short); if (nsplen < data_off) - goto trunc; - ND_TCHECK(shp->sh_seq[1]); - ack = EXTRACT_LE_16BITS(shp->sh_seq[1]); + goto invalid; + ack = GET_LE_U_2(shp->sh_seq[1]); if (ack & SGQ_OACK) { /* ackdat field */ if ((ack & SGQ_ONAK) == SGQ_ONAK) - ND_PRINT((ndo, "nakdat %d ", ack & SGQ_MASK)); + ND_PRINT("nakdat %u ", ack & SGQ_MASK); else - ND_PRINT((ndo, "ackdat %d ", ack & SGQ_MASK)); + ND_PRINT("ackdat %u ", ack & SGQ_MASK); data_off += sizeof(short); if (nsplen < data_off) - goto trunc; - ND_TCHECK(shp->sh_seq[2]); - ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); + goto invalid; + ack = GET_LE_U_2(shp->sh_seq[2]); } } - ND_PRINT((ndo, "seg %d ", ack & SGQ_MASK)); + ND_PRINT("seg %u ", ack & SGQ_MASK); } break; case MFS_ILS: - ND_PRINT((ndo, "link-service %d>%d ", src, dst)); + ND_PRINT("link-service %u>%u ", src, dst); { const struct seghdr *shp = (const struct seghdr *)nspp; const struct lsmsg *lsmp = - (const struct lsmsg *)&(nspp[sizeof(struct seghdr)]); - int ack; - int lsflags, fcval; + (const struct lsmsg *)(nspp + sizeof(struct seghdr)); + u_int ack; + u_int lsflags, fcval; if (nsplen < sizeof(struct seghdr) + sizeof(struct lsmsg)) - goto trunc; - ND_TCHECK(shp->sh_seq[0]); - ack = EXTRACT_LE_16BITS(shp->sh_seq[0]); + goto invalid; + ack = GET_LE_U_2(shp->sh_seq[0]); if (ack & SGQ_ACK) { /* acknum field */ if ((ack & SGQ_NAK) == SGQ_NAK) - ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); + ND_PRINT("nak %u ", ack & SGQ_MASK); else - ND_PRINT((ndo, "ack %d ", ack & SGQ_MASK)); - ND_TCHECK(shp->sh_seq[1]); - ack = EXTRACT_LE_16BITS(shp->sh_seq[1]); + ND_PRINT("ack %u ", ack & SGQ_MASK); + ack = GET_LE_U_2(shp->sh_seq[1]); if (ack & SGQ_OACK) { /* ackdat field */ if ((ack & SGQ_ONAK) == SGQ_ONAK) - ND_PRINT((ndo, "nakdat %d ", ack & SGQ_MASK)); + ND_PRINT("nakdat %u ", ack & SGQ_MASK); else - ND_PRINT((ndo, "ackdat %d ", ack & SGQ_MASK)); - ND_TCHECK(shp->sh_seq[2]); - ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); + ND_PRINT("ackdat %u ", ack & SGQ_MASK); + ack = GET_LE_U_2(shp->sh_seq[2]); } } - ND_PRINT((ndo, "seg %d ", ack & SGQ_MASK)); - ND_TCHECK(*lsmp); - lsflags = EXTRACT_LE_8BITS(lsmp->ls_lsflags); - fcval = EXTRACT_LE_8BITS(lsmp->ls_fcval); + ND_PRINT("seg %u ", ack & SGQ_MASK); + lsflags = GET_U_1(lsmp->ls_lsflags); + fcval = GET_U_1(lsmp->ls_fcval); switch (lsflags & LSI_MASK) { case LSI_DATA: - ND_PRINT((ndo, "dat seg count %d ", fcval)); + ND_PRINT("dat seg count %u ", fcval); switch (lsflags & LSM_MASK) { case LSM_NOCHANGE: break; case LSM_DONOTSEND: - ND_PRINT((ndo, "donotsend-data ")); + ND_PRINT("donotsend-data "); break; case LSM_SEND: - ND_PRINT((ndo, "send-data ")); + ND_PRINT("send-data "); break; default: - ND_PRINT((ndo, "reserved-fcmod? %x", lsflags)); + ND_PRINT("reserved-fcmod? %x", lsflags); break; } break; case LSI_INTR: - ND_PRINT((ndo, "intr req count %d ", fcval)); + ND_PRINT("intr req count %u ", fcval); break; default: - ND_PRINT((ndo, "reserved-fcval-int? %x", lsflags)); + ND_PRINT("reserved-fcval-int? %x", lsflags); break; } } break; default: - ND_PRINT((ndo, "reserved-subtype? %x %d > %d", flags, src, dst)); + ND_PRINT("reserved-subtype? %x %u > %u", flags, src, dst); break; } break; case MFT_ACK: switch (flags & NSP_SUBMASK) { case MFS_DACK: - ND_PRINT((ndo, "data-ack %d>%d ", src, dst)); + ND_PRINT("data-ack %u>%u ", src, dst); { const struct ackmsg *amp = (const struct ackmsg *)nspp; - int ack; + u_int ack; if (nsplen < sizeof(struct ackmsg)) - goto trunc; - ND_TCHECK(*amp); - ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]); + goto invalid; + ND_TCHECK_SIZE(amp); + ack = GET_LE_U_2(amp->ak_acknum[0]); if (ack & SGQ_ACK) { /* acknum field */ if ((ack & SGQ_NAK) == SGQ_NAK) - ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); + ND_PRINT("nak %u ", ack & SGQ_MASK); else - ND_PRINT((ndo, "ack %d ", ack & SGQ_MASK)); - ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]); + ND_PRINT("ack %u ", ack & SGQ_MASK); + ack = GET_LE_U_2(amp->ak_acknum[1]); if (ack & SGQ_OACK) { /* ackoth field */ if ((ack & SGQ_ONAK) == SGQ_ONAK) - ND_PRINT((ndo, "onak %d ", ack & SGQ_MASK)); + ND_PRINT("onak %u ", ack & SGQ_MASK); else - ND_PRINT((ndo, "oack %d ", ack & SGQ_MASK)); + ND_PRINT("oack %u ", ack & SGQ_MASK); } } } break; case MFS_IACK: - ND_PRINT((ndo, "ils-ack %d>%d ", src, dst)); + ND_PRINT("ils-ack %u>%u ", src, dst); { const struct ackmsg *amp = (const struct ackmsg *)nspp; - int ack; + u_int ack; if (nsplen < sizeof(struct ackmsg)) - goto trunc; - ND_TCHECK(*amp); - ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]); + goto invalid; + ND_TCHECK_SIZE(amp); + ack = GET_LE_U_2(amp->ak_acknum[0]); if (ack & SGQ_ACK) { /* acknum field */ if ((ack & SGQ_NAK) == SGQ_NAK) - ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); + ND_PRINT("nak %u ", ack & SGQ_MASK); else - ND_PRINT((ndo, "ack %d ", ack & SGQ_MASK)); - ND_TCHECK(amp->ak_acknum[1]); - ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]); + ND_PRINT("ack %u ", ack & SGQ_MASK); + ack = GET_LE_U_2(amp->ak_acknum[1]); if (ack & SGQ_OACK) { /* ackdat field */ if ((ack & SGQ_ONAK) == SGQ_ONAK) - ND_PRINT((ndo, "nakdat %d ", ack & SGQ_MASK)); + ND_PRINT("nakdat %u ", ack & SGQ_MASK); else - ND_PRINT((ndo, "ackdat %d ", ack & SGQ_MASK)); + ND_PRINT("ackdat %u ", ack & SGQ_MASK); } } } break; case MFS_CACK: - ND_PRINT((ndo, "conn-ack %d", dst)); + ND_PRINT("conn-ack %u", dst); break; default: - ND_PRINT((ndo, "reserved-acktype? %x %d > %d", flags, src, dst)); + ND_PRINT("reserved-acktype? %x %u > %u", flags, src, dst); break; } break; @@ -1058,136 +1003,132 @@ print_nsp(netdissect_options *ndo, case MFS_CI: case MFS_RCI: if ((flags & NSP_SUBMASK) == MFS_CI) - ND_PRINT((ndo, "conn-initiate ")); + ND_PRINT("conn-initiate "); else - ND_PRINT((ndo, "retrans-conn-initiate ")); - ND_PRINT((ndo, "%d>%d ", src, dst)); + ND_PRINT("retrans-conn-initiate "); + ND_PRINT("%u>%u ", src, dst); { const struct cimsg *cimp = (const struct cimsg *)nspp; - int services, info, segsize; + u_int services, info, segsize; if (nsplen < sizeof(struct cimsg)) - goto trunc; - ND_TCHECK(*cimp); - services = EXTRACT_LE_8BITS(cimp->ci_services); - info = EXTRACT_LE_8BITS(cimp->ci_info); - segsize = EXTRACT_LE_16BITS(cimp->ci_segsize); + goto invalid; + services = GET_U_1(cimp->ci_services); + info = GET_U_1(cimp->ci_info); + segsize = GET_LE_U_2(cimp->ci_segsize); switch (services & COS_MASK) { case COS_NONE: break; case COS_SEGMENT: - ND_PRINT((ndo, "seg ")); + ND_PRINT("seg "); break; case COS_MESSAGE: - ND_PRINT((ndo, "msg ")); + ND_PRINT("msg "); break; } switch (info & COI_MASK) { case COI_32: - ND_PRINT((ndo, "ver 3.2 ")); + ND_PRINT("ver 3.2 "); break; case COI_31: - ND_PRINT((ndo, "ver 3.1 ")); + ND_PRINT("ver 3.1 "); break; case COI_40: - ND_PRINT((ndo, "ver 4.0 ")); + ND_PRINT("ver 4.0 "); break; case COI_41: - ND_PRINT((ndo, "ver 4.1 ")); + ND_PRINT("ver 4.1 "); break; } - ND_PRINT((ndo, "segsize %d ", segsize)); + ND_PRINT("segsize %u ", segsize); } break; case MFS_CC: - ND_PRINT((ndo, "conn-confirm %d>%d ", src, dst)); + ND_PRINT("conn-confirm %u>%u ", src, dst); { const struct ccmsg *ccmp = (const struct ccmsg *)nspp; - int services, info; + u_int services, info; u_int segsize, optlen; if (nsplen < sizeof(struct ccmsg)) - goto trunc; - ND_TCHECK(*ccmp); - services = EXTRACT_LE_8BITS(ccmp->cc_services); - info = EXTRACT_LE_8BITS(ccmp->cc_info); - segsize = EXTRACT_LE_16BITS(ccmp->cc_segsize); - optlen = EXTRACT_LE_8BITS(ccmp->cc_optlen); + goto invalid; + services = GET_U_1(ccmp->cc_services); + info = GET_U_1(ccmp->cc_info); + segsize = GET_LE_U_2(ccmp->cc_segsize); + optlen = GET_U_1(ccmp->cc_optlen); switch (services & COS_MASK) { case COS_NONE: break; case COS_SEGMENT: - ND_PRINT((ndo, "seg ")); + ND_PRINT("seg "); break; case COS_MESSAGE: - ND_PRINT((ndo, "msg ")); + ND_PRINT("msg "); break; } switch (info & COI_MASK) { case COI_32: - ND_PRINT((ndo, "ver 3.2 ")); + ND_PRINT("ver 3.2 "); break; case COI_31: - ND_PRINT((ndo, "ver 3.1 ")); + ND_PRINT("ver 3.1 "); break; case COI_40: - ND_PRINT((ndo, "ver 4.0 ")); + ND_PRINT("ver 4.0 "); break; case COI_41: - ND_PRINT((ndo, "ver 4.1 ")); + ND_PRINT("ver 4.1 "); break; } - ND_PRINT((ndo, "segsize %d ", segsize)); + ND_PRINT("segsize %u ", segsize); if (optlen) { - ND_PRINT((ndo, "optlen %d ", optlen)); + ND_PRINT("optlen %u ", optlen); } } break; case MFS_DI: - ND_PRINT((ndo, "disconn-initiate %d>%d ", src, dst)); + ND_PRINT("disconn-initiate %u>%u ", src, dst); { const struct dimsg *dimp = (const struct dimsg *)nspp; - int reason; + u_int reason; u_int optlen; if (nsplen < sizeof(struct dimsg)) - goto trunc; - ND_TCHECK(*dimp); - reason = EXTRACT_LE_16BITS(dimp->di_reason); - optlen = EXTRACT_LE_8BITS(dimp->di_optlen); + goto invalid; + reason = GET_LE_U_2(dimp->di_reason); + optlen = GET_U_1(dimp->di_optlen); print_reason(ndo, reason); if (optlen) { - ND_PRINT((ndo, "optlen %d ", optlen)); + ND_PRINT("optlen %u ", optlen); } } break; case MFS_DC: - ND_PRINT((ndo, "disconn-confirm %d>%d ", src, dst)); + ND_PRINT("disconn-confirm %u>%u ", src, dst); { const struct dcmsg *dcmp = (const struct dcmsg *)nspp; - int reason; + u_int reason; - ND_TCHECK(*dcmp); - reason = EXTRACT_LE_16BITS(dcmp->dc_reason); + reason = GET_LE_U_2(dcmp->dc_reason); print_reason(ndo, reason); } break; default: - ND_PRINT((ndo, "reserved-ctltype? %x %d > %d", flags, src, dst)); + ND_PRINT("reserved-ctltype? %x %u > %u", flags, src, dst); break; } break; default: - ND_PRINT((ndo, "reserved-type? %x %d > %d", flags, src, dst)); + ND_PRINT("reserved-type? %x %u > %u", flags, src, dst); break; } return (1); -trunc: +invalid: return (0); } @@ -1219,9 +1160,9 @@ static const struct tok reason2str[] = { static void print_reason(netdissect_options *ndo, - register int reason) + u_int reason) { - ND_PRINT((ndo, "%s ", tok2str(reason2str, "reason-%d", reason))); + ND_PRINT("%s ", tok2str(reason2str, "reason-%u", reason)); } const char * @@ -1229,12 +1170,13 @@ dnnum_string(netdissect_options *ndo, u_short dnaddr) { char *str; size_t siz; - int area = (u_short)(dnaddr & AREAMASK) >> AREASHIFT; - int node = dnaddr & NODEMASK; + u_int area = (u_short)(dnaddr & AREAMASK) >> AREASHIFT; + u_int node = dnaddr & NODEMASK; + /* malloc() return used by the 'dnaddrtable' hash table: do not free() */ str = (char *)malloc(siz = sizeof("00.0000")); if (str == NULL) - (*ndo->ndo_error)(ndo, "dnnum_string: malloc"); - snprintf(str, siz, "%d.%d", area, node); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, "%s: malloc", __func__); + snprintf(str, siz, "%u.%u", area, node); return(str); } diff --git a/contrib/tcpdump/print-dhcp6.c b/contrib/tcpdump/print-dhcp6.c index cbb6d84a05..6b0dc21335 100644 --- a/contrib/tcpdump/print-dhcp6.c +++ b/contrib/tcpdump/print-dhcp6.c @@ -44,13 +44,10 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include - -#include -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "addrtoname.h" @@ -105,21 +102,19 @@ static const struct tok dh6_msgtype_str[] = { /* DHCP6 base packet format */ struct dhcp6 { union { - nd_uint8_t m; - nd_uint32_t x; + nd_uint8_t msgtype; + nd_uint32_t xid; } dh6_msgtypexid; /* options follow */ }; -#define dh6_msgtype dh6_msgtypexid.m -#define dh6_xid dh6_msgtypexid.x #define DH6_XIDMASK 0x00ffffff /* DHCPv6 relay messages */ struct dhcp6_relay { nd_uint8_t dh6relay_msgtype; nd_uint8_t dh6relay_hcnt; - nd_uint8_t dh6relay_linkaddr[16]; /* XXX: badly aligned */ - nd_uint8_t dh6relay_peeraddr[16]; + nd_ipv6 dh6relay_linkaddr; /* XXX: badly aligned */ + nd_ipv6 dh6relay_peeraddr; /* options follow */ }; @@ -282,15 +277,19 @@ dhcp6opt_print(netdissect_options *ndo, { const struct dhcp6opt *dh6o; const u_char *tp; - size_t i; + u_int i; uint16_t opttype; - size_t optlen; + uint16_t optlen; uint8_t auth_proto; + uint8_t auth_alg; + uint8_t auth_rdm; u_int authinfolen, authrealmlen; - int remain_len; /* Length of remaining options */ - int label_len; /* Label length */ + u_int remain_len; /* Length of remaining options */ + u_int label_len; /* Label length */ uint16_t subopt_code; uint16_t subopt_len; + uint8_t dh6_reconf_type; + uint8_t dh6_lq_query_type; if (cp == ep) return; @@ -298,160 +297,180 @@ dhcp6opt_print(netdissect_options *ndo, if (ep < cp + sizeof(*dh6o)) goto trunc; dh6o = (const struct dhcp6opt *)cp; - ND_TCHECK(*dh6o); - optlen = EXTRACT_16BITS(&dh6o->dh6opt_len); + ND_TCHECK_SIZE(dh6o); + optlen = GET_BE_U_2(dh6o->dh6opt_len); if (ep < cp + sizeof(*dh6o) + optlen) goto trunc; - opttype = EXTRACT_16BITS(&dh6o->dh6opt_type); - ND_PRINT((ndo, " (%s", tok2str(dh6opt_str, "opt_%u", opttype))); - ND_TCHECK2(*(cp + sizeof(*dh6o)), optlen); + opttype = GET_BE_U_2(dh6o->dh6opt_type); + ND_PRINT(" (%s", tok2str(dh6opt_str, "opt_%u", opttype)); + ND_TCHECK_LEN(cp + sizeof(*dh6o), optlen); switch (opttype) { case DH6OPT_CLIENTID: case DH6OPT_SERVERID: if (optlen < 2) { /*(*/ - ND_PRINT((ndo, " ?)")); + ND_PRINT(" ?)"); break; } tp = (const u_char *)(dh6o + 1); - switch (EXTRACT_16BITS(tp)) { + switch (GET_BE_U_2(tp)) { case 1: if (optlen >= 2 + 6) { - ND_PRINT((ndo, " hwaddr/time type %u time %u ", - EXTRACT_16BITS(&tp[2]), - EXTRACT_32BITS(&tp[4]))); + ND_PRINT(" hwaddr/time type %u time %u ", + GET_BE_U_2(tp + 2), + GET_BE_U_4(tp + 4)); for (i = 8; i < optlen; i++) - ND_PRINT((ndo, "%02x", tp[i])); + ND_PRINT("%02x", + GET_U_1(tp + i)); /*(*/ - ND_PRINT((ndo, ")")); + ND_PRINT(")"); } else { /*(*/ - ND_PRINT((ndo, " ?)")); + ND_PRINT(" ?)"); } break; case 2: if (optlen >= 2 + 8) { - ND_PRINT((ndo, " vid ")); + ND_PRINT(" vid "); for (i = 2; i < 2 + 8; i++) - ND_PRINT((ndo, "%02x", tp[i])); + ND_PRINT("%02x", + GET_U_1(tp + i)); /*(*/ - ND_PRINT((ndo, ")")); + ND_PRINT(")"); } else { /*(*/ - ND_PRINT((ndo, " ?)")); + ND_PRINT(" ?)"); } break; case 3: if (optlen >= 2 + 2) { - ND_PRINT((ndo, " hwaddr type %u ", - EXTRACT_16BITS(&tp[2]))); + ND_PRINT(" hwaddr type %u ", + GET_BE_U_2(tp + 2)); for (i = 4; i < optlen; i++) - ND_PRINT((ndo, "%02x", tp[i])); + ND_PRINT("%02x", + GET_U_1(tp + i)); /*(*/ - ND_PRINT((ndo, ")")); + ND_PRINT(")"); } else { /*(*/ - ND_PRINT((ndo, " ?)")); + ND_PRINT(" ?)"); } break; default: - ND_PRINT((ndo, " type %d)", EXTRACT_16BITS(tp))); + ND_PRINT(" type %u)", GET_BE_U_2(tp)); break; } break; case DH6OPT_IA_ADDR: if (optlen < 24) { /*(*/ - ND_PRINT((ndo, " ?)")); + ND_PRINT(" ?)"); break; } tp = (const u_char *)(dh6o + 1); - ND_PRINT((ndo, " %s", ip6addr_string(ndo, &tp[0]))); - ND_PRINT((ndo, " pltime:%u vltime:%u", - EXTRACT_32BITS(&tp[16]), - EXTRACT_32BITS(&tp[20]))); + ND_PRINT(" %s", GET_IP6ADDR_STRING(tp)); + ND_PRINT(" pltime:%u vltime:%u", + GET_BE_U_4(tp + 16), + GET_BE_U_4(tp + 20)); if (optlen > 24) { /* there are sub-options */ dhcp6opt_print(ndo, tp + 24, tp + optlen); } - ND_PRINT((ndo, ")")); + ND_PRINT(")"); break; case DH6OPT_ORO: case DH6OPT_ERO: if (optlen % 2) { - ND_PRINT((ndo, " ?)")); + ND_PRINT(" ?)"); break; } tp = (const u_char *)(dh6o + 1); for (i = 0; i < optlen; i += 2) { - ND_PRINT((ndo, " %s", - tok2str(dh6opt_str, "opt_%u", EXTRACT_16BITS(&tp[i])))); + ND_PRINT(" %s", + tok2str(dh6opt_str, "opt_%u", GET_BE_U_2(tp + i))); } - ND_PRINT((ndo, ")")); + ND_PRINT(")"); break; case DH6OPT_PREFERENCE: if (optlen != 1) { - ND_PRINT((ndo, " ?)")); + ND_PRINT(" ?)"); break; } tp = (const u_char *)(dh6o + 1); - ND_PRINT((ndo, " %d)", *tp)); + ND_PRINT(" %u)", GET_U_1(tp)); break; case DH6OPT_ELAPSED_TIME: if (optlen != 2) { - ND_PRINT((ndo, " ?)")); + ND_PRINT(" ?)"); break; } tp = (const u_char *)(dh6o + 1); - ND_PRINT((ndo, " %d)", EXTRACT_16BITS(tp))); + ND_PRINT(" %u)", GET_BE_U_2(tp)); break; case DH6OPT_RELAY_MSG: - ND_PRINT((ndo, " (")); + { + const u_char *snapend_save; + + ND_PRINT(" ("); tp = (const u_char *)(dh6o + 1); + /* + * Update the snapend to the end of the option before + * calling recursively dhcp6_print() for the nested + * packet. Other options may be present after the + * nested DHCPv6 packet. This prevents that, in + * dhcp6_print(), for the nested DHCPv6 packet, the + * remaining length < remaining caplen. + */ + snapend_save = ndo->ndo_snapend; + ndo->ndo_snapend = ND_MIN(tp + optlen, ndo->ndo_snapend); dhcp6_print(ndo, tp, optlen); - ND_PRINT((ndo, ")")); + ndo->ndo_snapend = snapend_save; + ND_PRINT(")"); break; + } case DH6OPT_AUTH: if (optlen < 11) { - ND_PRINT((ndo, " ?)")); + ND_PRINT(" ?)"); break; } tp = (const u_char *)(dh6o + 1); - auth_proto = *tp; + auth_proto = GET_U_1(tp); switch (auth_proto) { case DH6OPT_AUTHPROTO_DELAYED: - ND_PRINT((ndo, " proto: delayed")); + ND_PRINT(" proto: delayed"); break; case DH6OPT_AUTHPROTO_RECONFIG: - ND_PRINT((ndo, " proto: reconfigure")); + ND_PRINT(" proto: reconfigure"); break; default: - ND_PRINT((ndo, " proto: %d", auth_proto)); + ND_PRINT(" proto: %u", auth_proto); break; } tp++; - switch (*tp) { + auth_alg = GET_U_1(tp); + switch (auth_alg) { case DH6OPT_AUTHALG_HMACMD5: /* XXX: may depend on the protocol */ - ND_PRINT((ndo, ", alg: HMAC-MD5")); + ND_PRINT(", alg: HMAC-MD5"); break; default: - ND_PRINT((ndo, ", alg: %d", *tp)); + ND_PRINT(", alg: %u", auth_alg); break; } tp++; - switch (*tp) { + auth_rdm = GET_U_1(tp); + switch (auth_rdm) { case DH6OPT_AUTHRDM_MONOCOUNTER: - ND_PRINT((ndo, ", RDM: mono")); + ND_PRINT(", RDM: mono"); break; default: - ND_PRINT((ndo, ", RDM: %d", *tp)); + ND_PRINT(", RDM: %u", auth_rdm); break; } tp++; - ND_PRINT((ndo, ", RD:")); + ND_PRINT(", RD:"); for (i = 0; i < 4; i++, tp += 2) - ND_PRINT((ndo, " %04x", EXTRACT_16BITS(tp))); + ND_PRINT(" %04x", GET_BE_U_2(tp)); /* protocol dependent part */ authinfolen = optlen - 11; @@ -460,50 +479,51 @@ dhcp6opt_print(netdissect_options *ndo, if (authinfolen == 0) break; if (authinfolen < 20) { - ND_PRINT((ndo, " ??")); + ND_PRINT(" ??"); break; } authrealmlen = authinfolen - 20; if (authrealmlen > 0) { - ND_PRINT((ndo, ", realm: ")); + ND_PRINT(", realm: "); } for (i = 0; i < authrealmlen; i++, tp++) - ND_PRINT((ndo, "%02x", *tp)); - ND_PRINT((ndo, ", key ID: %08x", EXTRACT_32BITS(tp))); + ND_PRINT("%02x", GET_U_1(tp)); + ND_PRINT(", key ID: %08x", GET_BE_U_4(tp)); tp += 4; - ND_PRINT((ndo, ", HMAC-MD5:")); + ND_PRINT(", HMAC-MD5:"); for (i = 0; i < 4; i++, tp+= 4) - ND_PRINT((ndo, " %08x", EXTRACT_32BITS(tp))); + ND_PRINT(" %08x", GET_BE_U_4(tp)); break; case DH6OPT_AUTHPROTO_RECONFIG: if (authinfolen != 17) { - ND_PRINT((ndo, " ??")); + ND_PRINT(" ??"); break; } - switch (*tp++) { + switch (GET_U_1(tp)) { case DH6OPT_AUTHRECONFIG_KEY: - ND_PRINT((ndo, " reconfig-key")); + ND_PRINT(" reconfig-key"); break; case DH6OPT_AUTHRECONFIG_HMACMD5: - ND_PRINT((ndo, " type: HMAC-MD5")); + ND_PRINT(" type: HMAC-MD5"); break; default: - ND_PRINT((ndo, " type: ??")); + ND_PRINT(" type: ??"); break; } - ND_PRINT((ndo, " value:")); + tp++; + ND_PRINT(" value:"); for (i = 0; i < 4; i++, tp+= 4) - ND_PRINT((ndo, " %08x", EXTRACT_32BITS(tp))); + ND_PRINT(" %08x", GET_BE_U_4(tp)); break; default: - ND_PRINT((ndo, " ??")); + ND_PRINT(" ??"); break; } - ND_PRINT((ndo, ")")); + ND_PRINT(")"); break; case DH6OPT_RAPID_COMMIT: /* nothing todo */ - ND_PRINT((ndo, ")")); + ND_PRINT(")"); break; case DH6OPT_INTERFACE_ID: case DH6OPT_SUBSCRIBER_ID: @@ -512,31 +532,32 @@ dhcp6opt_print(netdissect_options *ndo, * at most 10 characters. */ tp = (const u_char *)(dh6o + 1); - ND_PRINT((ndo, " ")); + ND_PRINT(" "); for (i = 0; i < optlen && i < 10; i++) - ND_PRINT((ndo, "%02x", tp[i])); - ND_PRINT((ndo, "...)")); + ND_PRINT("%02x", GET_U_1(tp + i)); + ND_PRINT("...)"); break; case DH6OPT_RECONF_MSG: if (optlen != 1) { - ND_PRINT((ndo, " ?)")); + ND_PRINT(" ?)"); break; } tp = (const u_char *)(dh6o + 1); - switch (*tp) { + dh6_reconf_type = GET_U_1(tp); + switch (dh6_reconf_type) { case DH6_RENEW: - ND_PRINT((ndo, " for renew)")); + ND_PRINT(" for renew)"); break; case DH6_INFORM_REQ: - ND_PRINT((ndo, " for inf-req)")); + ND_PRINT(" for inf-req)"); break; default: - ND_PRINT((ndo, " for ?\?\?(%02x))", *tp)); + ND_PRINT(" for ?\?\?(%02x))", dh6_reconf_type); break; } break; case DH6OPT_RECONF_ACCEPT: /* nothing todo */ - ND_PRINT((ndo, ")")); + ND_PRINT(")"); break; case DH6OPT_SIP_SERVER_A: case DH6OPT_DNS_SERVERS: @@ -547,124 +568,126 @@ dhcp6opt_print(netdissect_options *ndo, case DH6OPT_PANA_AGENT: case DH6OPT_LQ_CLIENT_LINK: if (optlen % 16) { - ND_PRINT((ndo, " ?)")); + ND_PRINT(" ?)"); break; } tp = (const u_char *)(dh6o + 1); for (i = 0; i < optlen; i += 16) - ND_PRINT((ndo, " %s", ip6addr_string(ndo, &tp[i]))); - ND_PRINT((ndo, ")")); + ND_PRINT(" %s", GET_IP6ADDR_STRING(tp + i)); + ND_PRINT(")"); break; case DH6OPT_SIP_SERVER_D: case DH6OPT_DOMAIN_LIST: tp = (const u_char *)(dh6o + 1); while (tp < cp + sizeof(*dh6o) + optlen) { - ND_PRINT((ndo, " ")); - if ((tp = ns_nprint(ndo, tp, cp + sizeof(*dh6o) + optlen)) == NULL) + ND_PRINT(" "); + if ((tp = fqdn_print(ndo, tp, cp + sizeof(*dh6o) + optlen)) == NULL) goto trunc; } - ND_PRINT((ndo, ")")); + ND_PRINT(")"); break; case DH6OPT_STATUS_CODE: if (optlen < 2) { - ND_PRINT((ndo, " ?)")); + ND_PRINT(" ?)"); break; } tp = (const u_char *)(dh6o + 1); - ND_PRINT((ndo, " %s)", dhcp6stcode(EXTRACT_16BITS(&tp[0])))); + ND_PRINT(" %s)", dhcp6stcode(GET_BE_U_2(tp))); break; case DH6OPT_IA_NA: case DH6OPT_IA_PD: if (optlen < 12) { - ND_PRINT((ndo, " ?)")); + ND_PRINT(" ?)"); break; } tp = (const u_char *)(dh6o + 1); - ND_PRINT((ndo, " IAID:%u T1:%u T2:%u", - EXTRACT_32BITS(&tp[0]), - EXTRACT_32BITS(&tp[4]), - EXTRACT_32BITS(&tp[8]))); + ND_PRINT(" IAID:%u T1:%u T2:%u", + GET_BE_U_4(tp), + GET_BE_U_4(tp + 4), + GET_BE_U_4(tp + 8)); if (optlen > 12) { /* there are sub-options */ dhcp6opt_print(ndo, tp + 12, tp + optlen); } - ND_PRINT((ndo, ")")); + ND_PRINT(")"); break; case DH6OPT_IA_TA: if (optlen < 4) { - ND_PRINT((ndo, " ?)")); + ND_PRINT(" ?)"); break; } tp = (const u_char *)(dh6o + 1); - ND_PRINT((ndo, " IAID:%u", EXTRACT_32BITS(tp))); + ND_PRINT(" IAID:%u", GET_BE_U_4(tp)); if (optlen > 4) { /* there are sub-options */ dhcp6opt_print(ndo, tp + 4, tp + optlen); } - ND_PRINT((ndo, ")")); + ND_PRINT(")"); break; case DH6OPT_IA_PD_PREFIX: if (optlen < 25) { - ND_PRINT((ndo, " ?)")); + ND_PRINT(" ?)"); break; } tp = (const u_char *)(dh6o + 1); - ND_PRINT((ndo, " %s/%d", ip6addr_string(ndo, &tp[9]), tp[8])); - ND_PRINT((ndo, " pltime:%u vltime:%u", - EXTRACT_32BITS(&tp[0]), - EXTRACT_32BITS(&tp[4]))); + ND_PRINT(" %s/%u", GET_IP6ADDR_STRING(tp + 9), + GET_U_1(tp + 8)); + ND_PRINT(" pltime:%u vltime:%u", + GET_BE_U_4(tp), + GET_BE_U_4(tp + 4)); if (optlen > 25) { /* there are sub-options */ dhcp6opt_print(ndo, tp + 25, tp + optlen); } - ND_PRINT((ndo, ")")); + ND_PRINT(")"); break; case DH6OPT_LIFETIME: case DH6OPT_CLT_TIME: if (optlen != 4) { - ND_PRINT((ndo, " ?)")); + ND_PRINT(" ?)"); break; } tp = (const u_char *)(dh6o + 1); - ND_PRINT((ndo, " %d)", EXTRACT_32BITS(tp))); + ND_PRINT(" %u)", GET_BE_U_4(tp)); break; case DH6OPT_REMOTE_ID: if (optlen < 4) { - ND_PRINT((ndo, " ?)")); + ND_PRINT(" ?)"); break; } tp = (const u_char *)(dh6o + 1); - ND_PRINT((ndo, " %d ", EXTRACT_32BITS(tp))); + ND_PRINT(" %u ", GET_BE_U_4(tp)); /* * Print hex dump first 10 characters. */ for (i = 4; i < optlen && i < 14; i++) - ND_PRINT((ndo, "%02x", tp[i])); - ND_PRINT((ndo, "...)")); + ND_PRINT("%02x", GET_U_1(tp + i)); + ND_PRINT("...)"); break; case DH6OPT_LQ_QUERY: if (optlen < 17) { - ND_PRINT((ndo, " ?)")); + ND_PRINT(" ?)"); break; } tp = (const u_char *)(dh6o + 1); - switch (*tp) { + dh6_lq_query_type = GET_U_1(tp); + switch (dh6_lq_query_type) { case 1: - ND_PRINT((ndo, " by-address")); + ND_PRINT(" by-address"); break; case 2: - ND_PRINT((ndo, " by-clientID")); + ND_PRINT(" by-clientID"); break; default: - ND_PRINT((ndo, " type_%d", (int)*tp)); + ND_PRINT(" type_%u", dh6_lq_query_type); break; } - ND_PRINT((ndo, " %s", ip6addr_string(ndo, &tp[1]))); + ND_PRINT(" %s", GET_IP6ADDR_STRING(tp + 1)); if (optlen > 17) { /* there are query-options */ dhcp6opt_print(ndo, tp + 17, tp + optlen); } - ND_PRINT((ndo, ")")); + ND_PRINT(")"); break; case DH6OPT_CLIENT_DATA: tp = (const u_char *)(dh6o + 1); @@ -672,96 +695,97 @@ dhcp6opt_print(netdissect_options *ndo, /* there are encapsulated options */ dhcp6opt_print(ndo, tp, tp + optlen); } - ND_PRINT((ndo, ")")); + ND_PRINT(")"); break; case DH6OPT_LQ_RELAY_DATA: if (optlen < 16) { - ND_PRINT((ndo, " ?)")); + ND_PRINT(" ?)"); break; } tp = (const u_char *)(dh6o + 1); - ND_PRINT((ndo, " %s ", ip6addr_string(ndo, &tp[0]))); + ND_PRINT(" %s ", GET_IP6ADDR_STRING(tp)); /* * Print hex dump first 10 characters. */ for (i = 16; i < optlen && i < 26; i++) - ND_PRINT((ndo, "%02x", tp[i])); - ND_PRINT((ndo, "...)")); + ND_PRINT("%02x", GET_U_1(tp + i)); + ND_PRINT("...)"); break; case DH6OPT_NTP_SERVER: if (optlen < 4) { - ND_PRINT((ndo, " ?)")); + ND_PRINT(" ?)"); break; } tp = (const u_char *)(dh6o + 1); while (tp < cp + sizeof(*dh6o) + optlen - 4) { - subopt_code = EXTRACT_16BITS(tp); + subopt_code = GET_BE_U_2(tp); tp += 2; - subopt_len = EXTRACT_16BITS(tp); + subopt_len = GET_BE_U_2(tp); tp += 2; if (tp + subopt_len > cp + sizeof(*dh6o) + optlen) goto trunc; - ND_PRINT((ndo, " subopt:%d", subopt_code)); + ND_PRINT(" subopt:%u", subopt_code); switch (subopt_code) { case DH6OPT_NTP_SUBOPTION_SRV_ADDR: case DH6OPT_NTP_SUBOPTION_MC_ADDR: if (subopt_len != 16) { - ND_PRINT((ndo, " ?")); + ND_PRINT(" ?"); break; } - ND_PRINT((ndo, " %s", ip6addr_string(ndo, &tp[0]))); + ND_PRINT(" %s", GET_IP6ADDR_STRING(tp)); break; case DH6OPT_NTP_SUBOPTION_SRV_FQDN: - ND_PRINT((ndo, " ")); - if (ns_nprint(ndo, tp, tp + subopt_len) == NULL) + ND_PRINT(" "); + if (fqdn_print(ndo, tp, tp + subopt_len) == NULL) goto trunc; break; default: - ND_PRINT((ndo, " ?")); + ND_PRINT(" ?"); break; } tp += subopt_len; } - ND_PRINT((ndo, ")")); + ND_PRINT(")"); break; case DH6OPT_AFTR_NAME: if (optlen < 3) { - ND_PRINT((ndo, " ?)")); + ND_PRINT(" ?)"); break; } tp = (const u_char *)(dh6o + 1); remain_len = optlen; - ND_PRINT((ndo, " ")); + ND_PRINT(" "); /* Encoding is described in section 3.1 of RFC 1035 */ - while (remain_len && *tp) { - label_len = *tp++; + while (remain_len && GET_U_1(tp)) { + label_len = GET_U_1(tp); + tp++; if (label_len < remain_len - 1) { - (void)fn_printn(ndo, tp, label_len, NULL); + nd_printjnp(ndo, tp, label_len); tp += label_len; remain_len -= (label_len + 1); - if(*tp) ND_PRINT((ndo, ".")); + if(GET_U_1(tp)) ND_PRINT("."); } else { - ND_PRINT((ndo, " ?")); + ND_PRINT(" ?"); break; } } - ND_PRINT((ndo, ")")); + ND_PRINT(")"); break; case DH6OPT_NEW_POSIX_TIMEZONE: /* all three of these options */ case DH6OPT_NEW_TZDB_TIMEZONE: /* are encoded similarly */ case DH6OPT_MUDURL: /* although GMT might not work */ if (optlen < 5) { - ND_PRINT((ndo, " ?)")); + ND_PRINT(" ?)"); break; } tp = (const u_char *)(dh6o + 1); - ND_PRINT((ndo, "=")); - (void)fn_printn(ndo, tp, (u_int)optlen, NULL); - ND_PRINT((ndo, ")")); + ND_PRINT(" "); + nd_printjnp(ndo, tp, optlen); + ND_PRINT(")"); break; default: - ND_PRINT((ndo, ")")); + ND_PRINT(")"); break; } @@ -770,7 +794,7 @@ dhcp6opt_print(netdissect_options *ndo, return; trunc: - ND_PRINT((ndo, "[|dhcp6ext]")); + nd_print_trunc(ndo); } /* @@ -782,51 +806,48 @@ dhcp6_print(netdissect_options *ndo, { const struct dhcp6 *dh6; const struct dhcp6_relay *dh6relay; + uint8_t msgtype; const u_char *ep; const u_char *extp; const char *name; - ND_PRINT((ndo, "dhcp6")); + ndo->ndo_protocol = "dhcp6"; + ND_PRINT("dhcp6"); - ep = (const u_char *)ndo->ndo_snapend; + ep = ndo->ndo_snapend; if (cp + length < ep) ep = cp + length; dh6 = (const struct dhcp6 *)cp; dh6relay = (const struct dhcp6_relay *)cp; - ND_TCHECK(dh6->dh6_xid); - name = tok2str(dh6_msgtype_str, "msgtype-%u", dh6->dh6_msgtype); + ND_TCHECK_4(dh6->dh6_msgtypexid.xid); + msgtype = GET_U_1(dh6->dh6_msgtypexid.msgtype); + name = tok2str(dh6_msgtype_str, "msgtype-%u", msgtype); if (!ndo->ndo_vflag) { - ND_PRINT((ndo, " %s", name)); + ND_PRINT(" %s", name); return; } /* XXX relay agent messages have to be handled differently */ - ND_PRINT((ndo, " %s (", name)); /*)*/ - if (dh6->dh6_msgtype != DH6_RELAY_FORW && - dh6->dh6_msgtype != DH6_RELAY_REPLY) { - ND_PRINT((ndo, "xid=%x", EXTRACT_32BITS(&dh6->dh6_xid) & DH6_XIDMASK)); + ND_PRINT(" %s (", name); /*)*/ + if (msgtype != DH6_RELAY_FORW && msgtype != DH6_RELAY_REPLY) { + ND_PRINT("xid=%x", + GET_BE_U_4(dh6->dh6_msgtypexid.xid) & DH6_XIDMASK); extp = (const u_char *)(dh6 + 1); dhcp6opt_print(ndo, extp, ep); } else { /* relay messages */ - struct in6_addr addr6; - - ND_TCHECK(dh6relay->dh6relay_peeraddr); - - memcpy(&addr6, dh6relay->dh6relay_linkaddr, sizeof (addr6)); - ND_PRINT((ndo, "linkaddr=%s", ip6addr_string(ndo, &addr6))); + ND_PRINT("linkaddr=%s", GET_IP6ADDR_STRING(dh6relay->dh6relay_linkaddr)); - memcpy(&addr6, dh6relay->dh6relay_peeraddr, sizeof (addr6)); - ND_PRINT((ndo, " peeraddr=%s", ip6addr_string(ndo, &addr6))); + ND_PRINT(" peeraddr=%s", GET_IP6ADDR_STRING(dh6relay->dh6relay_peeraddr)); dhcp6opt_print(ndo, (const u_char *)(dh6relay + 1), ep); } /*(*/ - ND_PRINT((ndo, ")")); + ND_PRINT(")"); return; trunc: - ND_PRINT((ndo, "[|dhcp6]")); + nd_print_trunc(ndo); } diff --git a/contrib/tcpdump/print-domain.c b/contrib/tcpdump/print-domain.c index e29a9b4b0f..c3c6fd8f3d 100644 --- a/contrib/tcpdump/print-domain.c +++ b/contrib/tcpdump/print-domain.c @@ -22,12 +22,10 @@ /* \summary: Domain Name System (DNS) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include - -#include "nameser.h" +#include "netdissect-stdinc.h" #include @@ -36,6 +34,8 @@ #include "addrtostr.h" #include "extract.h" +#include "nameser.h" + static const char *ns_ops[] = { "", " inv_q", " stat", " op3", " notify", " update", " op6", " op7", " op8", " updateA", " updateD", " updateDA", @@ -47,133 +47,175 @@ static const char *ns_resp[] = { " NotImp", " Refused", " YXDomain", " YXRRSet", " NXRRSet", " NotAuth", " NotZone", " Resp11", " Resp12", " Resp13", " Resp14", " NoChange", + " BadVers", "Resp17", " Resp18", " Resp19", + " Resp20", "Resp21", " Resp22", " BadCookie", }; +static const char * +ns_rcode(u_int rcode) { + static char buf[sizeof(" Resp4095")]; + + if (rcode < sizeof(ns_resp)/sizeof(ns_resp[0])) { + return (ns_resp[rcode]); + } + snprintf(buf, sizeof(buf), " Resp%u", rcode & 0xfff); + return (buf); +} + /* skip over a domain name */ static const u_char * ns_nskip(netdissect_options *ndo, - register const u_char *cp) + const u_char *cp) { - register u_char i; + u_char i; - if (!ND_TTEST2(*cp, 1)) + if (!ND_TTEST_1(cp)) return (NULL); - i = *cp++; + i = GET_U_1(cp); + cp++; while (i) { - if ((i & INDIR_MASK) == INDIR_MASK) + switch (i & TYPE_MASK) { + + case TYPE_INDIR: return (cp + 1); - if ((i & INDIR_MASK) == EDNS0_MASK) { + + case TYPE_EDNS0: { int bitlen, bytelen; - if ((i & ~INDIR_MASK) != EDNS0_ELT_BITLABEL) + if ((i & ~TYPE_MASK) != EDNS0_ELT_BITLABEL) return(NULL); /* unknown ELT */ - if (!ND_TTEST2(*cp, 1)) + if (!ND_TTEST_1(cp)) return (NULL); - if ((bitlen = *cp++) == 0) + if ((bitlen = GET_U_1(cp)) == 0) bitlen = 256; + cp++; bytelen = (bitlen + 7) / 8; cp += bytelen; - } else + } + break; + + case TYPE_RESERVED: + return (NULL); + + case TYPE_LABEL: cp += i; - if (!ND_TTEST2(*cp, 1)) + break; + } + if (!ND_TTEST_1(cp)) return (NULL); - i = *cp++; + i = GET_U_1(cp); + cp++; } return (cp); } -/* print a */ static const u_char * blabel_print(netdissect_options *ndo, const u_char *cp) { - int bitlen, slen, b; + u_int bitlen, slen, b; const u_char *bitp, *lim; - char tc; + uint8_t tc; - if (!ND_TTEST2(*cp, 1)) + if (!ND_TTEST_1(cp)) return(NULL); - if ((bitlen = *cp) == 0) + if ((bitlen = GET_U_1(cp)) == 0) bitlen = 256; slen = (bitlen + 3) / 4; lim = cp + 1 + slen; /* print the bit string as a hex string */ - ND_PRINT((ndo, "\\[x")); + ND_PRINT("\\[x"); for (bitp = cp + 1, b = bitlen; bitp < lim && b > 7; b -= 8, bitp++) { - ND_TCHECK(*bitp); - ND_PRINT((ndo, "%02x", *bitp)); + ND_PRINT("%02x", GET_U_1(bitp)); } if (b > 4) { - ND_TCHECK(*bitp); - tc = *bitp++; - ND_PRINT((ndo, "%02x", tc & (0xff << (8 - b)))); + tc = GET_U_1(bitp); + bitp++; + ND_PRINT("%02x", tc & (0xff << (8 - b))); } else if (b > 0) { - ND_TCHECK(*bitp); - tc = *bitp++; - ND_PRINT((ndo, "%1x", ((tc >> 4) & 0x0f) & (0x0f << (4 - b)))); + tc = GET_U_1(bitp); + bitp++; + ND_PRINT("%1x", ((tc >> 4) & 0x0f) & (0x0f << (4 - b))); } - ND_PRINT((ndo, "/%d]", bitlen)); + ND_PRINT("/%u]", bitlen); return lim; -trunc: - ND_PRINT((ndo, ".../%d]", bitlen)); - return NULL; } static int labellen(netdissect_options *ndo, const u_char *cp) { - register u_int i; + u_int i; - if (!ND_TTEST2(*cp, 1)) + if (!ND_TTEST_1(cp)) return(-1); - i = *cp; - if ((i & INDIR_MASK) == EDNS0_MASK) { - int bitlen, elt; - if ((elt = (i & ~INDIR_MASK)) != EDNS0_ELT_BITLABEL) { - ND_PRINT((ndo, "", elt)); + i = GET_U_1(cp); + switch (i & TYPE_MASK) { + + case TYPE_EDNS0: { + u_int bitlen, elt; + if ((elt = (i & ~TYPE_MASK)) != EDNS0_ELT_BITLABEL) { + ND_PRINT("", elt); return(-1); } - if (!ND_TTEST2(*(cp + 1), 1)) + if (!ND_TTEST_1(cp + 1)) return(-1); - if ((bitlen = *(cp + 1)) == 0) + if ((bitlen = GET_U_1(cp + 1)) == 0) bitlen = 256; return(((bitlen + 7) / 8) + 1); - } else + } + + case TYPE_INDIR: + case TYPE_LABEL: return(i); + + default: + /* + * TYPE_RESERVED, but we use default to suppress compiler + * warnings about falling out of the switch statement. + */ + ND_PRINT(""); + return(-1); + } } +/* print a */ const u_char * -ns_nprint(netdissect_options *ndo, - register const u_char *cp, register const u_char *bp) +fqdn_print(netdissect_options *ndo, + const u_char *cp, const u_char *bp) { - register u_int i, l; - register const u_char *rp = NULL; - register int compress = 0; - int elt; + u_int i, l; + const u_char *rp = NULL; + int compress = 0; + u_int elt; u_int offset, max_offset; + u_int name_chars = 0; if ((l = labellen(ndo, cp)) == (u_int)-1) return(NULL); - if (!ND_TTEST2(*cp, 1)) + if (!ND_TTEST_1(cp)) return(NULL); max_offset = (u_int)(cp - bp); - if (((i = *cp++) & INDIR_MASK) != INDIR_MASK) { + i = GET_U_1(cp); + cp++; + if ((i & TYPE_MASK) != TYPE_INDIR) { compress = 0; rp = cp + l; } - if (i != 0) + if (i != 0) { while (i && cp < ndo->ndo_snapend) { - if ((i & INDIR_MASK) == INDIR_MASK) { + switch (i & TYPE_MASK) { + + case TYPE_INDIR: if (!compress) { rp = cp + 1; compress = 1; } - if (!ND_TTEST2(*cp, 1)) + if (!ND_TTEST_1(cp)) return(NULL); - offset = (((i << 8) | *cp) & 0x3fff); + offset = (((i << 8) | GET_U_1(cp)) & 0x3fff); /* * This must move backwards in the packet. * No RFC explicitly says that, but BIND's @@ -185,20 +227,21 @@ ns_nprint(netdissect_options *ndo, * the packet). */ if (offset >= max_offset) { - ND_PRINT((ndo, "")); + ND_PRINT(""); return(NULL); } max_offset = offset; cp = bp + offset; - if ((l = labellen(ndo, cp)) == (u_int)-1) + if (!ND_TTEST_1(cp)) return(NULL); - if (!ND_TTEST2(*cp, 1)) + i = GET_U_1(cp); + if ((l = labellen(ndo, cp)) == (u_int)-1) return(NULL); - i = *cp++; + cp++; continue; - } - if ((i & INDIR_MASK) == EDNS0_MASK) { - elt = (i & ~INDIR_MASK); + + case TYPE_EDNS0: + elt = (i & ~TYPE_MASK); switch(elt) { case EDNS0_ELT_BITLABEL: if (blabel_print(ndo, cp) == NULL) @@ -206,45 +249,234 @@ ns_nprint(netdissect_options *ndo, break; default: /* unknown ELT */ - ND_PRINT((ndo, "", elt)); + ND_PRINT("", elt); return(NULL); } - } else { - if (fn_printn(ndo, cp, l, ndo->ndo_snapend)) - return(NULL); + break; + + case TYPE_RESERVED: + ND_PRINT(""); + return(NULL); + + case TYPE_LABEL: + if (name_chars + l <= MAXCDNAME) { + if (nd_printn(ndo, cp, l, ndo->ndo_snapend)) + return(NULL); + } else if (name_chars < MAXCDNAME) { + if (nd_printn(ndo, cp, + MAXCDNAME - name_chars, ndo->ndo_snapend)) + return(NULL); + } + name_chars += l; + break; } cp += l; - ND_PRINT((ndo, ".")); - if ((l = labellen(ndo, cp)) == (u_int)-1) + if (name_chars <= MAXCDNAME) + ND_PRINT("."); + name_chars++; + if (!ND_TTEST_1(cp)) return(NULL); - if (!ND_TTEST2(*cp, 1)) + i = GET_U_1(cp); + if ((l = labellen(ndo, cp)) == (u_int)-1) return(NULL); - i = *cp++; + cp++; if (!compress) rp += l + 1; } - else - ND_PRINT((ndo, ".")); + if (name_chars > MAXCDNAME) + ND_PRINT(""); + } else + ND_PRINT("."); return (rp); } /* print a */ static const u_char * ns_cprint(netdissect_options *ndo, - register const u_char *cp) + const u_char *cp) { - register u_int i; + u_int i; - if (!ND_TTEST2(*cp, 1)) + if (!ND_TTEST_1(cp)) return (NULL); - i = *cp++; - if (fn_printn(ndo, cp, i, ndo->ndo_snapend)) + i = GET_U_1(cp); + cp++; + if (nd_printn(ndo, cp, i, ndo->ndo_snapend)) return (NULL); return (cp + i); } -/* http://www.iana.org/assignments/dns-parameters */ +static void +print_eopt_ecs(netdissect_options *ndo, const u_char *cp, + u_int data_len) +{ + u_int family, addr_bits, src_len, scope_len; + + u_char padded[32]; + char addr[INET6_ADDRSTRLEN]; + + /* ecs option must at least contain family, src len, and scope len */ + if (data_len < 4) { + nd_print_invalid(ndo); + return; + } + + family = GET_BE_U_2(cp); + cp += 2; + src_len = GET_U_1(cp); + cp += 1; + scope_len = GET_U_1(cp); + cp += 1; + + if (family == 1) + addr_bits = 32; + else if (family == 2) + addr_bits = 128; + else { + nd_print_invalid(ndo); + return; + } + + if (data_len - 4 > (addr_bits / 8)) { + nd_print_invalid(ndo); + return; + } + /* checks for invalid ecs scope or source length */ + if (src_len > addr_bits || scope_len > addr_bits || ((src_len + 7) / 8) != (data_len - 4)) { + nd_print_invalid(ndo); + return; + } + + /* pad the truncated address from ecs with zeros */ + memset(padded, 0, sizeof(padded)); + memcpy(padded, cp, data_len - 4); + + + if (family == 1) + ND_PRINT("%s/%d/%d", addrtostr(padded, addr, INET_ADDRSTRLEN), + src_len, scope_len); + else + ND_PRINT("%s/%d/%d", addrtostr6(padded, addr, INET6_ADDRSTRLEN), + src_len, scope_len); + +} + +extern const struct tok edns_opt2str[]; +extern const struct tok dau_alg2str[]; +extern const struct tok dhu_alg2str[]; +extern const struct tok n3u_alg2str[]; + + +/* print an */ +static const u_char * +eopt_print(netdissect_options *ndo, + const u_char *cp) +{ + u_int opt, data_len, i; + + if (!ND_TTEST_2(cp)) + return (NULL); + opt = GET_BE_U_2(cp); + cp += 2; + ND_PRINT("%s", tok2str(edns_opt2str, "Opt%u", opt)); + if (!ND_TTEST_2(cp)) + return (NULL); + data_len = GET_BE_U_2(cp); + cp += 2; + + ND_TCHECK_LEN(cp, data_len); + + if (data_len > 0) { + ND_PRINT(" "); + switch (opt) { + + case E_ECS: + print_eopt_ecs(ndo, cp, data_len); + break; + case E_COOKIE: + if (data_len < 8 || (data_len > 8 && data_len < 16) || data_len > 40) + nd_print_invalid(ndo); + else { + for (i = 0; i < data_len; ++i) { + /* split client and server cookie */ + if (i == 8) + ND_PRINT(" "); + ND_PRINT("%02x", GET_U_1(cp + i)); + } + } + break; + case E_KEEPALIVE: + if (data_len != 2) + nd_print_invalid(ndo); + else + /* keepalive is in increments of 100ms. Convert to seconds */ + ND_PRINT("%0.1f sec", (GET_BE_U_2(cp) / 10.0)); + break; + case E_EXPIRE: + if (data_len != 4) + nd_print_invalid(ndo); + else + ND_PRINT("%u sec", GET_BE_U_4(cp)); + break; + case E_PADDING: + /* ignore contents and just print length */ + ND_PRINT("(%u)", data_len); + break; + case E_KEYTAG: + if (data_len % 2 != 0) + nd_print_invalid(ndo); + else + for (i = 0; i < data_len; i += 2) { + if (i > 0) + ND_PRINT(" "); + ND_PRINT("%u", GET_BE_U_2(cp + i)); + } + break; + case E_DAU: + for (i = 0; i < data_len; ++i) { + if (i > 0) + ND_PRINT(" "); + ND_PRINT("%s", tok2str(dau_alg2str, "Alg_%u", GET_U_1(cp + i))); + } + break; + case E_DHU: + for (i = 0; i < data_len; ++i) { + if (i > 0) + ND_PRINT(" "); + ND_PRINT("%s", tok2str(dhu_alg2str, "Alg_%u", GET_U_1(cp + i))); + } + break; + case E_N3U: + for (i = 0; i < data_len; ++i) { + if (i > 0) + ND_PRINT(" "); + ND_PRINT("%s", tok2str(n3u_alg2str, "Alg_%u", GET_U_1(cp + i))); + } + break; + case E_CHAIN: + fqdn_print(ndo, cp, cp + data_len); + break; + case E_NSID: + /* intentional fall-through. NSID is an undefined byte string */ + default: + for (i = 0; i < data_len; ++i) + ND_PRINT("%02x", GET_U_1(cp + i)); + break; + } + } + return (cp + data_len); + + trunc: + return (NULL); + +} + + + +extern const struct tok ns_type2str[]; + +/* https://www.iana.org/assignments/dns-parameters */ const struct tok ns_type2str[] = { { T_A, "A" }, /* RFC 1035 */ { T_NS, "NS" }, /* RFC 1035 */ @@ -307,9 +539,12 @@ const struct tok ns_type2str[] = { { T_MAILB, "MAILB" }, /* RFC 1035 */ { T_MAILA, "MAILA" }, /* RFC 1035 */ { T_ANY, "ANY" }, + { T_URI, "URI" }, /* RFC 7553 */ { 0, NULL } }; +extern const struct tok ns_class2str[]; + const struct tok ns_class2str[] = { { C_IN, "IN" }, /* Not used */ { C_CHAOS, "CHAOS" }, @@ -318,223 +553,291 @@ const struct tok ns_class2str[] = { { 0, NULL } }; +const struct tok edns_opt2str[] = { + { E_LLQ, "LLQ" }, + { E_UL, "UL" }, + { E_NSID, "NSID" }, + { E_DAU, "DAU" }, + { E_DHU, "DHU" }, + { E_N3U, "N3U" }, + { E_ECS, "ECS" }, + { E_EXPIRE, "EXPIRE" }, + { E_COOKIE, "COOKIE" }, + { E_KEEPALIVE, "KEEPALIVE" }, + { E_PADDING, "PADDING" }, + { E_CHAIN, "CHAIN" }, + { E_KEYTAG, "KEY-TAG" }, + { E_CLIENTTAG, "CLIENT-TAG" }, + { E_SERVERTAG, "SERVER-TAG" }, + { 0, NULL } +}; + +const struct tok dau_alg2str[] = { + { A_DELETE, "DELETE" }, + { A_RSAMD5, "RSAMD5" }, + { A_DH, "DH" }, + { A_DSA, "DS" }, + { A_RSASHA1, "RSASHA1" }, + { A_DSA_NSEC3_SHA1, "DSA-NSEC3-SHA1" }, + { A_RSASHA1_NSEC3_SHA1, "RSASHA1-NSEC3-SHA1" }, + { A_RSASHA256, "RSASHA256" }, + { A_RSASHA512, "RSASHA512" }, + { A_ECC_GOST, "ECC-GOST" }, + { A_ECDSAP256SHA256, "ECDSAP256SHA256" }, + { A_ECDSAP384SHA384, "ECDSAP384SHA384" }, + { A_ED25519, "ED25519" }, + { A_ED448, "ED448" }, + { A_INDIRECT, "INDIRECT" }, + { A_PRIVATEDNS, "PRIVATEDNS" }, + { A_PRIVATEOID, "PRIVATEOID" }, + { 0, NULL } +}; + +const struct tok dhu_alg2str[] = { + { DS_SHA1, "SHA-1" }, + { DS_SHA256,"SHA-256" }, + { DS_GOST, "GOST_R_34.11-94" }, + { DS_SHA384,"SHA-384" }, + { 0, NULL } +}; + +const struct tok n3u_alg2str[] = { + { NSEC_SHA1,"SHA-1" }, + { 0, NULL } +}; + /* print a query */ static const u_char * ns_qprint(netdissect_options *ndo, - register const u_char *cp, register const u_char *bp, int is_mdns) + const u_char *cp, const u_char *bp, int is_mdns) { - register const u_char *np = cp; - register u_int i, class; + const u_char *np = cp; + u_int i, class; cp = ns_nskip(ndo, cp); - if (cp == NULL || !ND_TTEST2(*cp, 4)) + if (cp == NULL || !ND_TTEST_4(cp)) return(NULL); /* print the qtype */ - i = EXTRACT_16BITS(cp); + i = GET_BE_U_2(cp); cp += 2; - ND_PRINT((ndo, " %s", tok2str(ns_type2str, "Type%d", i))); + ND_PRINT(" %s", tok2str(ns_type2str, "Type%u", i)); /* print the qclass (if it's not IN) */ - i = EXTRACT_16BITS(cp); + i = GET_BE_U_2(cp); cp += 2; if (is_mdns) class = (i & ~C_QU); else class = i; if (class != C_IN) - ND_PRINT((ndo, " %s", tok2str(ns_class2str, "(Class %d)", class))); + ND_PRINT(" %s", tok2str(ns_class2str, "(Class %u)", class)); if (is_mdns) { - ND_PRINT((ndo, i & C_QU ? " (QU)" : " (QM)")); + ND_PRINT(i & C_QU ? " (QU)" : " (QM)"); } - ND_PRINT((ndo, "? ")); - cp = ns_nprint(ndo, np, bp); + ND_PRINT("? "); + cp = fqdn_print(ndo, np, bp); return(cp ? cp + 4 : NULL); } /* print a reply */ static const u_char * ns_rprint(netdissect_options *ndo, - register const u_char *cp, register const u_char *bp, int is_mdns) + const u_char *cp, const u_char *bp, int is_mdns) { - register u_int i, class, opt_flags = 0; - register u_short typ, len; - register const u_char *rp; + u_int i, class, opt_flags = 0; + u_short typ, len; + const u_char *rp; if (ndo->ndo_vflag) { - ND_PRINT((ndo, " ")); - if ((cp = ns_nprint(ndo, cp, bp)) == NULL) + ND_PRINT(" "); + if ((cp = fqdn_print(ndo, cp, bp)) == NULL) return NULL; } else cp = ns_nskip(ndo, cp); - if (cp == NULL || !ND_TTEST2(*cp, 10)) + if (cp == NULL || !ND_TTEST_LEN(cp, 10)) return (ndo->ndo_snapend); /* print the type/qtype */ - typ = EXTRACT_16BITS(cp); + typ = GET_BE_U_2(cp); cp += 2; /* print the class (if it's not IN and the type isn't OPT) */ - i = EXTRACT_16BITS(cp); + i = GET_BE_U_2(cp); cp += 2; if (is_mdns) class = (i & ~C_CACHE_FLUSH); else class = i; if (class != C_IN && typ != T_OPT) - ND_PRINT((ndo, " %s", tok2str(ns_class2str, "(Class %d)", class))); + ND_PRINT(" %s", tok2str(ns_class2str, "(Class %u)", class)); if (is_mdns) { if (i & C_CACHE_FLUSH) - ND_PRINT((ndo, " (Cache flush)")); + ND_PRINT(" (Cache flush)"); } if (typ == T_OPT) { /* get opt flags */ cp += 2; - opt_flags = EXTRACT_16BITS(cp); + opt_flags = GET_BE_U_2(cp); /* ignore rest of ttl field */ cp += 2; } else if (ndo->ndo_vflag > 2) { /* print ttl */ - ND_PRINT((ndo, " [")); - unsigned_relts_print(ndo, EXTRACT_32BITS(cp)); - ND_PRINT((ndo, "]")); + ND_PRINT(" ["); + unsigned_relts_print(ndo, GET_BE_U_4(cp)); + ND_PRINT("]"); cp += 4; } else { /* ignore ttl */ cp += 4; } - len = EXTRACT_16BITS(cp); + len = GET_BE_U_2(cp); cp += 2; rp = cp + len; - ND_PRINT((ndo, " %s", tok2str(ns_type2str, "Type%d", typ))); + ND_PRINT(" %s", tok2str(ns_type2str, "Type%u", typ)); if (rp > ndo->ndo_snapend) return(NULL); switch (typ) { case T_A: - if (!ND_TTEST2(*cp, sizeof(struct in_addr))) + if (!ND_TTEST_LEN(cp, sizeof(nd_ipv4))) return(NULL); - ND_PRINT((ndo, " %s", intoa(htonl(EXTRACT_32BITS(cp))))); + ND_PRINT(" %s", intoa(GET_IPV4_TO_NETWORK_ORDER(cp))); break; case T_NS: case T_CNAME: case T_PTR: -#ifdef T_DNAME case T_DNAME: -#endif - ND_PRINT((ndo, " ")); - if (ns_nprint(ndo, cp, bp) == NULL) + ND_PRINT(" "); + if (fqdn_print(ndo, cp, bp) == NULL) return(NULL); break; case T_SOA: if (!ndo->ndo_vflag) break; - ND_PRINT((ndo, " ")); - if ((cp = ns_nprint(ndo, cp, bp)) == NULL) + ND_PRINT(" "); + if ((cp = fqdn_print(ndo, cp, bp)) == NULL) return(NULL); - ND_PRINT((ndo, " ")); - if ((cp = ns_nprint(ndo, cp, bp)) == NULL) + ND_PRINT(" "); + if ((cp = fqdn_print(ndo, cp, bp)) == NULL) return(NULL); - if (!ND_TTEST2(*cp, 5 * 4)) + if (!ND_TTEST_LEN(cp, 5 * 4)) return(NULL); - ND_PRINT((ndo, " %u", EXTRACT_32BITS(cp))); + ND_PRINT(" %u", GET_BE_U_4(cp)); cp += 4; - ND_PRINT((ndo, " %u", EXTRACT_32BITS(cp))); + ND_PRINT(" %u", GET_BE_U_4(cp)); cp += 4; - ND_PRINT((ndo, " %u", EXTRACT_32BITS(cp))); + ND_PRINT(" %u", GET_BE_U_4(cp)); cp += 4; - ND_PRINT((ndo, " %u", EXTRACT_32BITS(cp))); + ND_PRINT(" %u", GET_BE_U_4(cp)); cp += 4; - ND_PRINT((ndo, " %u", EXTRACT_32BITS(cp))); + ND_PRINT(" %u", GET_BE_U_4(cp)); cp += 4; break; case T_MX: - ND_PRINT((ndo, " ")); - if (!ND_TTEST2(*cp, 2)) + ND_PRINT(" "); + if (!ND_TTEST_2(cp)) return(NULL); - if (ns_nprint(ndo, cp + 2, bp) == NULL) + if (fqdn_print(ndo, cp + 2, bp) == NULL) return(NULL); - ND_PRINT((ndo, " %d", EXTRACT_16BITS(cp))); + ND_PRINT(" %u", GET_BE_U_2(cp)); break; case T_TXT: while (cp < rp) { - ND_PRINT((ndo, " \"")); + ND_PRINT(" \""); cp = ns_cprint(ndo, cp); if (cp == NULL) return(NULL); - ND_PRINT((ndo, "\"")); + ND_PRINT("\""); } break; case T_SRV: - ND_PRINT((ndo, " ")); - if (!ND_TTEST2(*cp, 6)) + ND_PRINT(" "); + if (!ND_TTEST_6(cp)) return(NULL); - if (ns_nprint(ndo, cp + 6, bp) == NULL) + if (fqdn_print(ndo, cp + 6, bp) == NULL) return(NULL); - ND_PRINT((ndo, ":%d %d %d", EXTRACT_16BITS(cp + 4), - EXTRACT_16BITS(cp), EXTRACT_16BITS(cp + 2))); + ND_PRINT(":%u %u %u", GET_BE_U_2(cp + 4), + GET_BE_U_2(cp), GET_BE_U_2(cp + 2)); break; case T_AAAA: { char ntop_buf[INET6_ADDRSTRLEN]; - if (!ND_TTEST2(*cp, sizeof(struct in6_addr))) + if (!ND_TTEST_LEN(cp, sizeof(nd_ipv6))) return(NULL); - ND_PRINT((ndo, " %s", - addrtostr6(cp, ntop_buf, sizeof(ntop_buf)))); + ND_PRINT(" %s", + addrtostr6(cp, ntop_buf, sizeof(ntop_buf))); break; } case T_A6: { - struct in6_addr a; + nd_ipv6 a; int pbit, pbyte; char ntop_buf[INET6_ADDRSTRLEN]; - if (!ND_TTEST2(*cp, 1)) + if (!ND_TTEST_1(cp)) return(NULL); - pbit = *cp; + pbit = GET_U_1(cp); pbyte = (pbit & ~7) / 8; if (pbit > 128) { - ND_PRINT((ndo, " %u(bad plen)", pbit)); + ND_PRINT(" %u(bad plen)", pbit); break; } else if (pbit < 128) { - if (!ND_TTEST2(*(cp + 1), sizeof(a) - pbyte)) - return(NULL); - memset(&a, 0, sizeof(a)); - memcpy(&a.s6_addr[pbyte], cp + 1, sizeof(a) - pbyte); - ND_PRINT((ndo, " %u %s", pbit, - addrtostr6(&a, ntop_buf, sizeof(ntop_buf)))); + memset(a, 0, sizeof(a)); + GET_CPY_BYTES(a + pbyte, cp + 1, sizeof(a) - pbyte); + ND_PRINT(" %u %s", pbit, + addrtostr6(&a, ntop_buf, sizeof(ntop_buf))); } if (pbit > 0) { - ND_PRINT((ndo, " ")); - if (ns_nprint(ndo, cp + 1 + sizeof(a) - pbyte, bp) == NULL) + ND_PRINT(" "); + if (fqdn_print(ndo, cp + 1 + sizeof(a) - pbyte, bp) == NULL) return(NULL); } break; } + case T_URI: + if (!ND_TTEST_LEN(cp, len)) + return(NULL); + ND_PRINT(" %u %u ", GET_BE_U_2(cp), GET_BE_U_2(cp + 2)); + if (nd_printn(ndo, cp + 4, len - 4, ndo->ndo_snapend)) + return(NULL); + break; + case T_OPT: - ND_PRINT((ndo, " UDPsize=%u", class)); + ND_PRINT(" UDPsize=%u", class); if (opt_flags & 0x8000) - ND_PRINT((ndo, " DO")); + ND_PRINT(" DO"); + if (cp < rp) { + ND_PRINT(" ["); + while (cp < rp) { + cp = eopt_print(ndo, cp); + if (cp == NULL) + return(NULL); + if (cp < rp) + ND_PRINT(","); + } + ND_PRINT("]"); + } break; case T_UNSPECA: /* One long string */ - if (!ND_TTEST2(*cp, len)) + if (!ND_TTEST_LEN(cp, len)) return(NULL); - if (fn_printn(ndo, cp, len, ndo->ndo_snapend)) + if (nd_printn(ndo, cp, len, ndo->ndo_snapend)) return(NULL); break; @@ -544,29 +847,29 @@ ns_rprint(netdissect_options *ndo, return(NULL); if (!ndo->ndo_vflag) break; - ND_PRINT((ndo, " ")); - if ((cp = ns_nprint(ndo, cp, bp)) == NULL) + ND_PRINT(" "); + if ((cp = fqdn_print(ndo, cp, bp)) == NULL) return(NULL); cp += 6; - if (!ND_TTEST2(*cp, 2)) + if (!ND_TTEST_2(cp)) return(NULL); - ND_PRINT((ndo, " fudge=%u", EXTRACT_16BITS(cp))); + ND_PRINT(" fudge=%u", GET_BE_U_2(cp)); cp += 2; - if (!ND_TTEST2(*cp, 2)) + if (!ND_TTEST_2(cp)) return(NULL); - ND_PRINT((ndo, " maclen=%u", EXTRACT_16BITS(cp))); - cp += 2 + EXTRACT_16BITS(cp); - if (!ND_TTEST2(*cp, 2)) + ND_PRINT(" maclen=%u", GET_BE_U_2(cp)); + cp += 2 + GET_BE_U_2(cp); + if (!ND_TTEST_2(cp)) return(NULL); - ND_PRINT((ndo, " origid=%u", EXTRACT_16BITS(cp))); + ND_PRINT(" origid=%u", GET_BE_U_2(cp)); cp += 2; - if (!ND_TTEST2(*cp, 2)) + if (!ND_TTEST_2(cp)) return(NULL); - ND_PRINT((ndo, " error=%u", EXTRACT_16BITS(cp))); + ND_PRINT(" error=%u", GET_BE_U_2(cp)); cp += 2; - if (!ND_TTEST2(*cp, 2)) + if (!ND_TTEST_2(cp)) return(NULL); - ND_PRINT((ndo, " otherlen=%u", EXTRACT_16BITS(cp))); + ND_PRINT(" otherlen=%u", GET_BE_U_2(cp)); cp += 2; } } @@ -574,49 +877,126 @@ ns_rprint(netdissect_options *ndo, } void -ns_print(netdissect_options *ndo, - register const u_char *bp, u_int length, int is_mdns) +domain_print(netdissect_options *ndo, + const u_char *bp, u_int length, int over_tcp, int is_mdns) { - register const HEADER *np; - register int qdcount, ancount, nscount, arcount; - register const u_char *cp; + const dns_header_t *np; + uint16_t flags, rcode, rdlen, type; + u_int qdcount, ancount, nscount, arcount; + u_int i; + const u_char *cp; uint16_t b2; + ndo->ndo_protocol = "domain"; + + if (over_tcp) { + /* + * The message is prefixed with a two byte length field + * which gives the message length, excluding the two byte + * length field. (RFC 1035 - 4.2.2. TCP usage) + */ + if (length < 2) { + ND_PRINT(" [DNS over TCP: length %u < 2]", length); + nd_print_invalid(ndo); + return; + } else { + length -= 2; /* excluding the two byte length field */ + if (GET_BE_U_2(bp) != length) { + ND_PRINT(" [prefix length(%u) != length(%u)]", + GET_BE_U_2(bp), length); + nd_print_invalid(ndo); + return; + } else { + bp += 2; + /* in over TCP case, we need to prepend a space + * (not needed in over UDP case) + */ + ND_PRINT(" "); + } + } + } + + np = (const dns_header_t *)bp; + if(length < sizeof(*np)) { - ND_PRINT((ndo, "domain")); - ND_PRINT((ndo, " [length %u < %zu]", length, sizeof(*np))); - ND_PRINT((ndo, " (invalid)")); + nd_print_protocol(ndo); + ND_PRINT(" [length %u < %zu]", length, sizeof(*np)); + nd_print_invalid(ndo); return; } - np = (const HEADER *)bp; - ND_TCHECK(*np); + ND_TCHECK_SIZE(np); + flags = GET_BE_U_2(np->flags); /* get the byte-order right */ - qdcount = EXTRACT_16BITS(&np->qdcount); - ancount = EXTRACT_16BITS(&np->ancount); - nscount = EXTRACT_16BITS(&np->nscount); - arcount = EXTRACT_16BITS(&np->arcount); + qdcount = GET_BE_U_2(np->qdcount); + ancount = GET_BE_U_2(np->ancount); + nscount = GET_BE_U_2(np->nscount); + arcount = GET_BE_U_2(np->arcount); + + /* find the opt record to extract extended rcode */ + cp = (const u_char *)(np + 1); + rcode = DNS_RCODE(flags); + for (i = 0; i < qdcount; i++) { + if ((cp = ns_nskip(ndo, cp)) == NULL) + goto print; + cp += 4; /* skip QTYPE and QCLASS */ + if (cp >= ndo->ndo_snapend) + goto print; + } + for (i = 0; i < ancount + nscount; i++) { + if ((cp = ns_nskip(ndo, cp)) == NULL) + goto print; + cp += 8; /* skip TYPE, CLASS and TTL */ + if (cp + 2 > ndo->ndo_snapend) + goto print; + rdlen = GET_BE_U_2(cp); + cp += 2 + rdlen; + if (cp >= ndo->ndo_snapend) + goto print; + } + for (i = 0; i < arcount; i++) { + if ((cp = ns_nskip(ndo, cp)) == NULL) + goto print; + if (cp + 2 > ndo->ndo_snapend) + goto print; + type = GET_BE_U_2(cp); + cp += 4; /* skip TYPE and CLASS */ + if (cp + 1 > ndo->ndo_snapend) + goto print; + if (type == T_OPT) { + rcode |= (GET_U_1(cp) << 4); + goto print; + } + cp += 4; + if (cp + 2 > ndo->ndo_snapend) + goto print; + rdlen = GET_BE_U_2(cp); + cp += 2 + rdlen; + if (cp >= ndo->ndo_snapend) + goto print; + } - if (DNS_QR(np)) { + print: + if (DNS_QR(flags)) { /* this is a response */ - ND_PRINT((ndo, "%d%s%s%s%s%s%s", - EXTRACT_16BITS(&np->id), - ns_ops[DNS_OPCODE(np)], - ns_resp[DNS_RCODE(np)], - DNS_AA(np)? "*" : "", - DNS_RA(np)? "" : "-", - DNS_TC(np)? "|" : "", - DNS_AD(np)? "$" : "")); + ND_PRINT("%u%s%s%s%s%s%s", + GET_BE_U_2(np->id), + ns_ops[DNS_OPCODE(flags)], + ns_rcode(rcode), + DNS_AA(flags)? "*" : "", + DNS_RA(flags)? "" : "-", + DNS_TC(flags)? "|" : "", + DNS_AD(flags)? "$" : ""); if (qdcount != 1) - ND_PRINT((ndo, " [%dq]", qdcount)); + ND_PRINT(" [%uq]", qdcount); /* Print QUESTION section on -vv */ cp = (const u_char *)(np + 1); - while (qdcount--) { - if (qdcount < EXTRACT_16BITS(&np->qdcount) - 1) - ND_PRINT((ndo, ",")); + for (i = 0; i < qdcount; i++) { + if (i != 0) + ND_PRINT(","); if (ndo->ndo_vflag > 1) { - ND_PRINT((ndo, " q:")); + ND_PRINT(" q:"); if ((cp = ns_qprint(ndo, cp, bp, is_mdns)) == NULL) goto trunc; } else { @@ -625,132 +1005,147 @@ ns_print(netdissect_options *ndo, cp += 4; /* skip QTYPE and QCLASS */ } } - ND_PRINT((ndo, " %d/%d/%d", ancount, nscount, arcount)); - if (ancount--) { + ND_PRINT(" %u/%u/%u", ancount, nscount, arcount); + if (ancount) { if ((cp = ns_rprint(ndo, cp, bp, is_mdns)) == NULL) goto trunc; - while (cp < ndo->ndo_snapend && ancount--) { - ND_PRINT((ndo, ",")); + ancount--; + while (cp < ndo->ndo_snapend && ancount) { + ND_PRINT(","); if ((cp = ns_rprint(ndo, cp, bp, is_mdns)) == NULL) goto trunc; + ancount--; } } - if (ancount > 0) + if (ancount) goto trunc; /* Print NS and AR sections on -vv */ if (ndo->ndo_vflag > 1) { - if (cp < ndo->ndo_snapend && nscount--) { - ND_PRINT((ndo, " ns:")); + if (cp < ndo->ndo_snapend && nscount) { + ND_PRINT(" ns:"); if ((cp = ns_rprint(ndo, cp, bp, is_mdns)) == NULL) goto trunc; - while (cp < ndo->ndo_snapend && nscount--) { - ND_PRINT((ndo, ",")); + nscount--; + while (cp < ndo->ndo_snapend && nscount) { + ND_PRINT(","); if ((cp = ns_rprint(ndo, cp, bp, is_mdns)) == NULL) goto trunc; + nscount--; } } - if (nscount > 0) + if (nscount) goto trunc; - if (cp < ndo->ndo_snapend && arcount--) { - ND_PRINT((ndo, " ar:")); + if (cp < ndo->ndo_snapend && arcount) { + ND_PRINT(" ar:"); if ((cp = ns_rprint(ndo, cp, bp, is_mdns)) == NULL) goto trunc; - while (cp < ndo->ndo_snapend && arcount--) { - ND_PRINT((ndo, ",")); + arcount--; + while (cp < ndo->ndo_snapend && arcount) { + ND_PRINT(","); if ((cp = ns_rprint(ndo, cp, bp, is_mdns)) == NULL) goto trunc; + arcount--; } } - if (arcount > 0) + if (arcount) goto trunc; } } else { /* this is a request */ - ND_PRINT((ndo, "%d%s%s%s", EXTRACT_16BITS(&np->id), ns_ops[DNS_OPCODE(np)], - DNS_RD(np) ? "+" : "", - DNS_CD(np) ? "%" : "")); + ND_PRINT("%u%s%s%s", GET_BE_U_2(np->id), + ns_ops[DNS_OPCODE(flags)], + DNS_RD(flags) ? "+" : "", + DNS_CD(flags) ? "%" : ""); /* any weirdness? */ - b2 = EXTRACT_16BITS(((const u_short *)np)+1); + b2 = GET_BE_U_2(((const u_short *)np) + 1); if (b2 & 0x6cf) - ND_PRINT((ndo, " [b2&3=0x%x]", b2)); + ND_PRINT(" [b2&3=0x%x]", b2); - if (DNS_OPCODE(np) == IQUERY) { + if (DNS_OPCODE(flags) == IQUERY) { if (qdcount) - ND_PRINT((ndo, " [%dq]", qdcount)); + ND_PRINT(" [%uq]", qdcount); if (ancount != 1) - ND_PRINT((ndo, " [%da]", ancount)); + ND_PRINT(" [%ua]", ancount); } else { if (ancount) - ND_PRINT((ndo, " [%da]", ancount)); + ND_PRINT(" [%ua]", ancount); if (qdcount != 1) - ND_PRINT((ndo, " [%dq]", qdcount)); + ND_PRINT(" [%uq]", qdcount); } if (nscount) - ND_PRINT((ndo, " [%dn]", nscount)); + ND_PRINT(" [%un]", nscount); if (arcount) - ND_PRINT((ndo, " [%dau]", arcount)); + ND_PRINT(" [%uau]", arcount); cp = (const u_char *)(np + 1); - if (qdcount--) { + if (qdcount) { cp = ns_qprint(ndo, cp, (const u_char *)np, is_mdns); if (!cp) goto trunc; - while (cp < ndo->ndo_snapend && qdcount--) { + qdcount--; + while (cp < ndo->ndo_snapend && qdcount) { cp = ns_qprint(ndo, (const u_char *)cp, (const u_char *)np, is_mdns); if (!cp) goto trunc; + qdcount--; } } - if (qdcount > 0) + if (qdcount) goto trunc; /* Print remaining sections on -vv */ if (ndo->ndo_vflag > 1) { - if (ancount--) { + if (ancount) { if ((cp = ns_rprint(ndo, cp, bp, is_mdns)) == NULL) goto trunc; - while (cp < ndo->ndo_snapend && ancount--) { - ND_PRINT((ndo, ",")); + ancount--; + while (cp < ndo->ndo_snapend && ancount) { + ND_PRINT(","); if ((cp = ns_rprint(ndo, cp, bp, is_mdns)) == NULL) goto trunc; + ancount--; } } - if (ancount > 0) + if (ancount) goto trunc; - if (cp < ndo->ndo_snapend && nscount--) { - ND_PRINT((ndo, " ns:")); + if (cp < ndo->ndo_snapend && nscount) { + ND_PRINT(" ns:"); if ((cp = ns_rprint(ndo, cp, bp, is_mdns)) == NULL) goto trunc; - while (nscount-- && cp < ndo->ndo_snapend) { - ND_PRINT((ndo, ",")); + nscount--; + while (cp < ndo->ndo_snapend && nscount) { + ND_PRINT(","); if ((cp = ns_rprint(ndo, cp, bp, is_mdns)) == NULL) goto trunc; + nscount--; } } if (nscount > 0) goto trunc; - if (cp < ndo->ndo_snapend && arcount--) { - ND_PRINT((ndo, " ar:")); + if (cp < ndo->ndo_snapend && arcount) { + ND_PRINT(" ar:"); if ((cp = ns_rprint(ndo, cp, bp, is_mdns)) == NULL) goto trunc; - while (cp < ndo->ndo_snapend && arcount--) { - ND_PRINT((ndo, ",")); + arcount--; + while (cp < ndo->ndo_snapend && arcount) { + ND_PRINT(","); if ((cp = ns_rprint(ndo, cp, bp, is_mdns)) == NULL) goto trunc; + arcount--; } } - if (arcount > 0) + if (arcount) goto trunc; } } - ND_PRINT((ndo, " (%d)", length)); + ND_PRINT(" (%u)", length); return; trunc: - ND_PRINT((ndo, "[|domain]")); + nd_print_trunc(ndo); } diff --git a/contrib/tcpdump/print-dsa.c b/contrib/tcpdump/print-dsa.c new file mode 100644 index 0000000000..e45dc53fbe --- /dev/null +++ b/contrib/tcpdump/print-dsa.c @@ -0,0 +1,219 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 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. + */ + +/* \summary: Marvell (Ethertype) Distributed Switch Architecture printer */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "netdissect-stdinc.h" + +#include "netdissect.h" +#include "ethertype.h" +#include "addrtoname.h" +#include "extract.h" + +/* + * Format of (Ethertyped or not) DSA tagged frames: + * + * 7 6 5 4 3 2 1 0 + * . . . . . . . . . + * 0 +---+---+---+---+---+---+---+---+ + * | Ether Destination Address | + * +6 +---+---+---+---+---+---+---+---+ + * | Ether Source Address | + * +6 +---+---+---+---+---+---+---+---+ +- + * | Prog. DSA Ether Type [15:8] | | (8-byte) EDSA Tag + * +1 +---+---+---+---+---+---+---+---+ | Contains a programmable Ether type, + * | Prog. DSA Ether Type [7:0] | | two reserved bytes (always 0), + * +1 +---+---+---+---+---+---+---+---+ | and a standard DSA tag. + * | Reserved (0x00 0x00) | | + * +2 +---+---+---+---+---+---+---+---+ | +- + * | Mode |b29| Src/Trg Dev | | | (4-byte) DSA Tag + * +1 +---+---+---+---+---+---+---+---+ | | Contains a DSA tag mode, + * |Src/Trg Port/Trunk |b18|b17|b16| | | source or target switch device, + * +1 +---+---+---+---+---+---+---+---+ | | source or target port or trunk, + * | PRI [2:0] |b12| VID [11:8] | | | and misc (IEEE and FPri) bits. + * +1 +---+---+---+---+---+---+---+---+ | | + * | VID [7:0] | | | + * +1 +---+---+---+---+---+---+---+---+ +- +- + * | Ether Length/Type | + * +2 +---+---+---+---+---+---+---+---+ + * . . . . . . . . . + * + * Mode: Forward, To_CPU, From_CPU, To_Sniffer + * b29: (Source or Target) IEEE Tag Mode + * b18: Forward's Src_Is_Trunk, To_CPU's Code[2], To_Sniffer's Rx_Sniff + * b17: To_CPU's Code[1] + * b16: Original frame's CFI + * b12: To_CPU's Code[0] + */ + +#define TOK(tag, byte, mask, shift) ((GET_U_1(&(((const u_char *) tag)[byte])) & (mask)) >> (shift)) + +#define DSA_LEN 4 +#define DSA_MODE(tag) TOK(tag, 0, 0xc0, 6) +#define DSA_MODE_TO_CPU 0x0 +#define DSA_MODE_FROM_CPU 0x1 +#define DSA_MODE_TO_SNIFFER 0x2 +#define DSA_MODE_FORWARD 0x3 +#define DSA_TAGGED(tag) TOK(tag, 0, 0x20, 5) +#define DSA_DEV(tag) TOK(tag, 0, 0x1f, 0) +#define DSA_PORT(tag) TOK(tag, 1, 0xf8, 3) +#define DSA_TRUNK(tag) TOK(tag, 1, 0x04, 2) +#define DSA_RX_SNIFF(tag) TOK(tag, 1, 0x04, 2) +#define DSA_CFI(tag) TOK(tag, 1, 0x01, 0) +#define DSA_PRI(tag) TOK(tag, 2, 0xe0, 5) +#define DSA_VID(tag) ((u_short)((TOK(tag, 2, 0xe0, 5) << 8) | (TOK(tag, 3, 0xff, 0)))) +#define DSA_CODE(tag) ((TOK(tag, 1, 0x06, 1) << 1) | TOK(tag, 2, 0x10, 4)) + +#define EDSA_LEN 8 + +static const struct tok dsa_mode_values[] = { + { DSA_MODE_TO_CPU, "To CPU" }, + { DSA_MODE_FROM_CPU, "From CPU" }, + { DSA_MODE_TO_SNIFFER, "To Sniffer"}, + { DSA_MODE_FORWARD, "Forward" }, + { 0, NULL } +}; + +static const struct tok dsa_code_values[] = { + { 0x0, "BPDU (MGMT) Trap" }, + { 0x1, "Frame2Reg" }, + { 0x2, "IGMP/MLD Trap" }, + { 0x3, "Policy Trap" }, + { 0x4, "ARP Mirror" }, + { 0x5, "Policy Mirror" }, + { 0, NULL } +}; + +static void +tag_common_print(netdissect_options *ndo, const u_char *p) +{ + if (ndo->ndo_eflag) { + ND_PRINT("mode %s, ", tok2str(dsa_mode_values, "unknown", DSA_MODE(p))); + + switch (DSA_MODE(p)) { + case DSA_MODE_FORWARD: + ND_PRINT("dev %u, %s %u, ", DSA_DEV(p), + DSA_TRUNK(p) ? "trunk" : "port", DSA_PORT(p)); + break; + case DSA_MODE_FROM_CPU: + ND_PRINT("target dev %u, port %u, ", + DSA_DEV(p), DSA_PORT(p)); + break; + case DSA_MODE_TO_CPU: + ND_PRINT("source dev %u, port %u, ", + DSA_DEV(p), DSA_PORT(p)); + ND_PRINT("code %s, ", + tok2str(dsa_code_values, "reserved", DSA_CODE(p))); + break; + case DSA_MODE_TO_SNIFFER: + ND_PRINT("source dev %u, port %u, ", + DSA_DEV(p), DSA_PORT(p)); + ND_PRINT("%s sniff, ", + DSA_RX_SNIFF(p) ? "ingress" : "egress"); + break; + default: + break; + } + + ND_PRINT("%s, ", DSA_TAGGED(p) ? "tagged" : "untagged"); + ND_PRINT("%s", DSA_CFI(p) ? "CFI, " : ""); + ND_PRINT("VID %u, ", DSA_VID(p)); + ND_PRINT("FPri %u, ", DSA_PRI(p)); + } else { + switch (DSA_MODE(p)) { + case DSA_MODE_FORWARD: + ND_PRINT("Forward %s %u.%u, ", + DSA_TRUNK(p) ? "trunk" : "port", + DSA_DEV(p), DSA_PORT(p)); + break; + case DSA_MODE_FROM_CPU: + ND_PRINT("CPU > port %u.%u, ", + DSA_DEV(p), DSA_PORT(p)); + break; + case DSA_MODE_TO_CPU: + ND_PRINT("port %u.%u > CPU, ", + DSA_DEV(p), DSA_PORT(p)); + break; + case DSA_MODE_TO_SNIFFER: + ND_PRINT("port %u.%u > %s Sniffer, ", + DSA_DEV(p), DSA_PORT(p), + DSA_RX_SNIFF(p) ? "Rx" : "Tx"); + break; + default: + break; + } + + ND_PRINT("VLAN %u%c, ", DSA_VID(p), DSA_TAGGED(p) ? 't' : 'u'); + } +} + +static void +dsa_tag_print(netdissect_options *ndo, const u_char *bp) +{ + if (ndo->ndo_eflag) + ND_PRINT("Marvell DSA "); + else + ND_PRINT("DSA "); + tag_common_print(ndo, bp); +} + +static void +edsa_tag_print(netdissect_options *ndo, const u_char *bp) +{ + const u_char *p = bp; + uint16_t edsa_etype; + + edsa_etype = GET_BE_U_2(p); + if (ndo->ndo_eflag) { + ND_PRINT("Marvell EDSA ethertype 0x%04x (%s), ", edsa_etype, + tok2str(ethertype_values, "Unknown", edsa_etype)); + ND_PRINT("rsvd %u %u, ", GET_U_1(p + 2), GET_U_1(p + 3)); + } else + ND_PRINT("EDSA 0x%04x, ", edsa_etype); + p += 4; + tag_common_print(ndo, p); +} + +void +dsa_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) +{ + u_int caplen = h->caplen; + u_int length = h->len; + + ndo->ndo_protocol = "dsa"; + ndo->ndo_ll_hdr_len += + ether_switch_tag_print(ndo, p, length, caplen, dsa_tag_print, DSA_LEN); +} + +void +edsa_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) +{ + u_int caplen = h->caplen; + u_int length = h->len; + + ndo->ndo_protocol = "edsa"; + ndo->ndo_ll_hdr_len += + ether_switch_tag_print(ndo, p, length, caplen, edsa_tag_print, EDSA_LEN); +} diff --git a/contrib/tcpdump/print-dtp.c b/contrib/tcpdump/print-dtp.c index 1d8c66a000..a1ae4ba4d5 100644 --- a/contrib/tcpdump/print-dtp.c +++ b/contrib/tcpdump/print-dtp.c @@ -18,16 +18,16 @@ /* \summary: Dynamic Trunking Protocol (DTP) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "addrtoname.h" #include "extract.h" -static const char tstr[] = " [|dtp]"; #define DTP_HEADER_LEN 1 #define DTP_DOMAIN_TLV 0x0001 @@ -36,29 +36,25 @@ static const char tstr[] = " [|dtp]"; #define DTP_NEIGHBOR_TLV 0x0004 static const struct tok dtp_tlv_values[] = { - { DTP_DOMAIN_TLV, "Domain TLV"}, - { DTP_STATUS_TLV, "Status TLV"}, - { DTP_DTP_TYPE_TLV, "DTP type TLV"}, - { DTP_NEIGHBOR_TLV, "Neighbor TLV"}, + { DTP_DOMAIN_TLV, "Domain" }, + { DTP_STATUS_TLV, "Status" }, + { DTP_DTP_TYPE_TLV, "DTP type" }, + { DTP_NEIGHBOR_TLV, "Neighbor" }, { 0, NULL} }; void -dtp_print (netdissect_options *ndo, const u_char *pptr, u_int length) +dtp_print(netdissect_options *ndo, const u_char *tptr, u_int length) { - int type, len; - const u_char *tptr; - - if (length < DTP_HEADER_LEN) - goto trunc; - - tptr = pptr; - - ND_TCHECK2(*tptr, DTP_HEADER_LEN); + ndo->ndo_protocol = "dtp"; + if (length < DTP_HEADER_LEN) { + ND_PRINT("[zero packet length]"); + goto invalid; + } - ND_PRINT((ndo, "DTPv%u, length %u", - (*tptr), - length)); + ND_PRINT("DTPv%u, length %u", + GET_U_1(tptr), + length); /* * In non-verbose mode, just print version. @@ -68,61 +64,59 @@ dtp_print (netdissect_options *ndo, const u_char *pptr, u_int length) } tptr += DTP_HEADER_LEN; + length -= DTP_HEADER_LEN; - while (tptr < (pptr+length)) { + while (length) { + uint16_t type, len; - ND_TCHECK2(*tptr, 4); - type = EXTRACT_16BITS(tptr); - len = EXTRACT_16BITS(tptr+2); + if (length < 4) { + ND_PRINT("[%u bytes remaining]", length); + goto invalid; + } + type = GET_BE_U_2(tptr); + len = GET_BE_U_2(tptr + 2); /* XXX: should not be but sometimes it is, see the test captures */ if (type == 0) return; - ND_PRINT((ndo, "\n\t%s (0x%04x) TLV, length %u", + ND_PRINT("\n\t%s (0x%04x) TLV, length %u", tok2str(dtp_tlv_values, "Unknown", type), - type, len)); + type, len); /* infinite loop check */ - if (len < 4) + if (len < 4 || len > length) { + ND_PRINT("[invalid TLV length %u]", len); goto invalid; - ND_TCHECK2(*tptr, len); + } switch (type) { case DTP_DOMAIN_TLV: - ND_PRINT((ndo, ", ")); - fn_printzp(ndo, tptr+4, len-4, pptr+length); + ND_PRINT(", "); + nd_printjnp(ndo, tptr+4, len-4); break; case DTP_STATUS_TLV: case DTP_DTP_TYPE_TLV: - if (len < 5) + if (len != 5) goto invalid; - ND_PRINT((ndo, ", 0x%x", *(tptr+4))); + ND_PRINT(", 0x%x", GET_U_1(tptr + 4)); break; case DTP_NEIGHBOR_TLV: - if (len < 10) + if (len != 10) goto invalid; - ND_PRINT((ndo, ", %s", etheraddr_string(ndo, tptr+4))); + ND_PRINT(", %s", GET_ETHERADDR_STRING(tptr+4)); break; default: + ND_TCHECK_LEN(tptr, len); break; } tptr += len; + length -= len; } - return; invalid: - ND_PRINT((ndo, "%s", istr)); - return; - trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_invalid(ndo); + ND_TCHECK_LEN(tptr, length); } - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 4 - * End: - */ diff --git a/contrib/tcpdump/print-dvmrp.c b/contrib/tcpdump/print-dvmrp.c index 36a8d5ba8e..7d7ca07555 100644 --- a/contrib/tcpdump/print-dvmrp.c +++ b/contrib/tcpdump/print-dvmrp.c @@ -22,10 +22,10 @@ /* \summary: Distance Vector Multicast Routing Protocol printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "extract.h" @@ -47,6 +47,18 @@ #define DVMRP_PRUNE 7 /* prune message */ #define DVMRP_GRAFT 8 /* graft message */ #define DVMRP_GRAFT_ACK 9 /* graft acknowledgement */ +static const struct tok dvmrp_msgtype_str[] = { + { DVMRP_PROBE, "Probe" }, + { DVMRP_REPORT, "Report" }, + { DVMRP_ASK_NEIGHBORS, "Ask-neighbors(old)" }, + { DVMRP_NEIGHBORS, "Neighbors(old)" }, + { DVMRP_ASK_NEIGHBORS2, "Ask-neighbors2" }, + { DVMRP_NEIGHBORS2, "Neighbors2" }, + { DVMRP_PRUNE, "Prune" }, + { DVMRP_GRAFT, "Graft" }, + { DVMRP_GRAFT_ACK, "Graft-ACK" }, + { 0, NULL } +}; /* * 'flags' byte values in DVMRP_NEIGHBORS2 reply. @@ -57,311 +69,264 @@ #define DVMRP_NF_DISABLED 0x20 /* administratively disabled */ #define DVMRP_NF_QUERIER 0x40 /* I am the subnet's querier */ -static int print_probe(netdissect_options *, const u_char *, const u_char *, u_int); -static int print_report(netdissect_options *, const u_char *, const u_char *, u_int); -static int print_neighbors(netdissect_options *, const u_char *, const u_char *, u_int); -static int print_neighbors2(netdissect_options *, const u_char *, const u_char *, u_int, uint8_t, uint8_t); -static int print_prune(netdissect_options *, const u_char *); -static int print_graft(netdissect_options *, const u_char *); -static int print_graft_ack(netdissect_options *, const u_char *); +static void print_probe(netdissect_options *, const u_char *, u_int); +static void print_report(netdissect_options *, const u_char *, u_int); +static void print_neighbors(netdissect_options *, const u_char *, u_int); +static void print_neighbors2(netdissect_options *, const u_char *, u_int, uint8_t, uint8_t); void dvmrp_print(netdissect_options *ndo, - register const u_char *bp, register u_int len) + const u_char *bp, u_int len) { - register const u_char *ep; - register u_char type; + u_char type; uint8_t major_version, minor_version; - ep = (const u_char *)ndo->ndo_snapend; - if (bp >= ep) - return; + ndo->ndo_protocol = "dvmrp"; + if (len < 8) { + ND_PRINT(" [length %u < 8]", len); + goto invalid; + } - ND_TCHECK(bp[1]); - type = bp[1]; + type = GET_U_1(bp + 1); /* Skip IGMP header */ bp += 8; len -= 8; + ND_PRINT(" %s", tok2str(dvmrp_msgtype_str, "[type %u]", type)); switch (type) { case DVMRP_PROBE: - ND_PRINT((ndo, " Probe")); if (ndo->ndo_vflag) { - if (print_probe(ndo, bp, ep, len) < 0) - goto trunc; + print_probe(ndo, bp, len); } break; case DVMRP_REPORT: - ND_PRINT((ndo, " Report")); if (ndo->ndo_vflag > 1) { - if (print_report(ndo, bp, ep, len) < 0) - goto trunc; + print_report(ndo, bp, len); } break; - case DVMRP_ASK_NEIGHBORS: - ND_PRINT((ndo, " Ask-neighbors(old)")); - break; - case DVMRP_NEIGHBORS: - ND_PRINT((ndo, " Neighbors(old)")); - if (print_neighbors(ndo, bp, ep, len) < 0) - goto trunc; - break; - - case DVMRP_ASK_NEIGHBORS2: - ND_PRINT((ndo, " Ask-neighbors2")); + print_neighbors(ndo, bp, len); break; case DVMRP_NEIGHBORS2: - ND_PRINT((ndo, " Neighbors2")); /* * extract version from IGMP group address field */ bp -= 4; - ND_TCHECK2(bp[0], 4); - major_version = *(bp + 3); - minor_version = *(bp + 2); + major_version = GET_U_1(bp + 3); + minor_version = GET_U_1(bp + 2); bp += 4; - if (print_neighbors2(ndo, bp, ep, len, major_version, - minor_version) < 0) - goto trunc; + print_neighbors2(ndo, bp, len, major_version, minor_version); break; case DVMRP_PRUNE: - ND_PRINT((ndo, " Prune")); - if (print_prune(ndo, bp) < 0) - goto trunc; + ND_PRINT(" src %s grp %s", GET_IPADDR_STRING(bp), GET_IPADDR_STRING(bp + 4)); + ND_PRINT(" timer "); + unsigned_relts_print(ndo, GET_BE_U_4(bp + 8)); break; case DVMRP_GRAFT: - ND_PRINT((ndo, " Graft")); - if (print_graft(ndo, bp) < 0) - goto trunc; + ND_PRINT(" src %s grp %s", GET_IPADDR_STRING(bp), GET_IPADDR_STRING(bp + 4)); break; case DVMRP_GRAFT_ACK: - ND_PRINT((ndo, " Graft-ACK")); - if (print_graft_ack(ndo, bp) < 0) - goto trunc; - break; - - default: - ND_PRINT((ndo, " [type %d]", type)); + ND_PRINT(" src %s grp %s", GET_IPADDR_STRING(bp), GET_IPADDR_STRING(bp + 4)); break; } return; -trunc: - ND_PRINT((ndo, "[|dvmrp]")); - return; +invalid: + nd_print_invalid(ndo); } -static int +static void print_report(netdissect_options *ndo, - register const u_char *bp, register const u_char *ep, - register u_int len) + const u_char *bp, + u_int len) { - register uint32_t mask, origin; - register int metric, done; - register u_int i, width; + uint32_t mask, origin; + u_int metric, done; + u_int i, width; while (len > 0) { if (len < 3) { - ND_PRINT((ndo, " [|]")); - return (0); + ND_PRINT(" [length %u < 3]", len); + goto invalid; } - ND_TCHECK2(bp[0], 3); - mask = (uint32_t)0xff << 24 | bp[0] << 16 | bp[1] << 8 | bp[2]; + mask = (uint32_t)0xff << 24 | GET_U_1(bp) << 16 | + GET_U_1(bp + 1) << 8 | GET_U_1(bp + 2); width = 1; - if (bp[0]) + if (GET_U_1(bp)) width = 2; - if (bp[1]) + if (GET_U_1(bp + 1)) width = 3; - if (bp[2]) + if (GET_U_1(bp + 2)) width = 4; - ND_PRINT((ndo, "\n\tMask %s", intoa(htonl(mask)))); + ND_PRINT("\n\tMask %s", intoa(htonl(mask))); bp += 3; len -= 3; do { - if (bp + width + 1 > ep) { - ND_PRINT((ndo, " [|]")); - return (0); - } if (len < width + 1) { - ND_PRINT((ndo, "\n\t [Truncated Report]")); - return (0); + ND_PRINT("\n\t [Truncated Report]"); + goto invalid; } origin = 0; for (i = 0; i < width; ++i) { - ND_TCHECK(*bp); - origin = origin << 8 | *bp++; + origin = origin << 8 | GET_U_1(bp); + bp++; } for ( ; i < 4; ++i) origin <<= 8; - ND_TCHECK(*bp); - metric = *bp++; + metric = GET_U_1(bp); + bp++; done = metric & 0x80; metric &= 0x7f; - ND_PRINT((ndo, "\n\t %s metric %d", intoa(htonl(origin)), - metric)); + ND_PRINT("\n\t %s metric %u", intoa(htonl(origin)), + metric); len -= width + 1; } while (!done); } - return (0); -trunc: - return (-1); + return; + +invalid: + nd_print_invalid(ndo); } -static int +static void print_probe(netdissect_options *ndo, - register const u_char *bp, register const u_char *ep, - register u_int len) + const u_char *bp, + u_int len) { - register uint32_t genid; - - ND_TCHECK2(bp[0], 4); - if ((len < 4) || ((bp + 4) > ep)) { - /* { (ctags) */ - ND_PRINT((ndo, " [|}")); - return (0); + if (len < 4) { + ND_PRINT(" [full length %u < 4]", len); + goto invalid; } - genid = EXTRACT_32BITS(bp); - bp += 4; - len -= 4; - ND_PRINT((ndo, ndo->ndo_vflag > 1 ? "\n\t" : " ")); - ND_PRINT((ndo, "genid %u", genid)); + ND_PRINT(ndo->ndo_vflag > 1 ? "\n\t" : " "); + ND_PRINT("genid %u", GET_BE_U_4(bp)); if (ndo->ndo_vflag < 2) - return (0); + return; - while ((len > 0) && (bp < ep)) { - ND_TCHECK2(bp[0], 4); - ND_PRINT((ndo, "\n\tneighbor %s", ipaddr_string(ndo, bp))); + bp += 4; + len -= 4; + while (len > 0) { + if (len < 4) { + ND_PRINT("[remaining length %u < 4]", len); + goto invalid; + } + ND_PRINT("\n\tneighbor %s", GET_IPADDR_STRING(bp)); bp += 4; len -= 4; } - return (0); -trunc: - return (-1); + return; + +invalid: + nd_print_invalid(ndo); } -static int +static void print_neighbors(netdissect_options *ndo, - register const u_char *bp, register const u_char *ep, - register u_int len) + const u_char *bp, + u_int len) { const u_char *laddr; - register u_char metric; - register u_char thresh; - register int ncount; + u_char metric; + u_char thresh; + int ncount; - while (len > 0 && bp < ep) { - ND_TCHECK2(bp[0], 7); + while (len > 0) { + if (len < 7) { + ND_PRINT(" [length %u < 7]", len); + goto invalid; + } laddr = bp; bp += 4; - metric = *bp++; - thresh = *bp++; - ncount = *bp++; + metric = GET_U_1(bp); + bp++; + thresh = GET_U_1(bp); + bp++; + ncount = GET_U_1(bp); + bp++; len -= 7; while (--ncount >= 0) { - ND_TCHECK2(bp[0], 4); - ND_PRINT((ndo, " [%s ->", ipaddr_string(ndo, laddr))); - ND_PRINT((ndo, " %s, (%d/%d)]", - ipaddr_string(ndo, bp), metric, thresh)); + if (len < 4) { + ND_PRINT(" [length %u < 4]", len); + goto invalid; + } + ND_PRINT(" [%s ->", GET_IPADDR_STRING(laddr)); + ND_PRINT(" %s, (%u/%u)]", + GET_IPADDR_STRING(bp), metric, thresh); bp += 4; len -= 4; } } - return (0); -trunc: - return (-1); + return; + +invalid: + nd_print_invalid(ndo); } -static int +static void print_neighbors2(netdissect_options *ndo, - register const u_char *bp, register const u_char *ep, - register u_int len, uint8_t major_version, + const u_char *bp, + u_int len, uint8_t major_version, uint8_t minor_version) { const u_char *laddr; - register u_char metric, thresh, flags; - register int ncount; + u_char metric, thresh, flags; + int ncount; - ND_PRINT((ndo, " (v %d.%d):", major_version, minor_version)); + ND_PRINT(" (v %u.%u):", major_version, minor_version); - while (len > 0 && bp < ep) { - ND_TCHECK2(bp[0], 8); + while (len > 0) { + if (len < 8) { + ND_PRINT(" [length %u < 8]", len); + goto invalid; + } laddr = bp; bp += 4; - metric = *bp++; - thresh = *bp++; - flags = *bp++; - ncount = *bp++; + metric = GET_U_1(bp); + bp++; + thresh = GET_U_1(bp); + bp++; + flags = GET_U_1(bp); + bp++; + ncount = GET_U_1(bp); + bp++; len -= 8; - while (--ncount >= 0 && (len >= 4) && (bp + 4) <= ep) { - ND_PRINT((ndo, " [%s -> ", ipaddr_string(ndo, laddr))); - ND_PRINT((ndo, "%s (%d/%d", ipaddr_string(ndo, bp), - metric, thresh)); + while (--ncount >= 0 && len > 0) { + if (len < 4) { + ND_PRINT(" [length %u < 4]", len); + goto invalid; + } + ND_PRINT(" [%s -> ", GET_IPADDR_STRING(laddr)); + ND_PRINT("%s (%u/%u", GET_IPADDR_STRING(bp), + metric, thresh); if (flags & DVMRP_NF_TUNNEL) - ND_PRINT((ndo, "/tunnel")); + ND_PRINT("/tunnel"); if (flags & DVMRP_NF_SRCRT) - ND_PRINT((ndo, "/srcrt")); + ND_PRINT("/srcrt"); if (flags & DVMRP_NF_QUERIER) - ND_PRINT((ndo, "/querier")); + ND_PRINT("/querier"); if (flags & DVMRP_NF_DISABLED) - ND_PRINT((ndo, "/disabled")); + ND_PRINT("/disabled"); if (flags & DVMRP_NF_DOWN) - ND_PRINT((ndo, "/down")); - ND_PRINT((ndo, ")]")); + ND_PRINT("/down"); + ND_PRINT(")]"); bp += 4; len -= 4; } if (ncount != -1) { - ND_PRINT((ndo, " [|]")); - return (0); + ND_PRINT(" [invalid ncount]"); + goto invalid; } } - return (0); -trunc: - return (-1); -} - -static int -print_prune(netdissect_options *ndo, - register const u_char *bp) -{ - ND_TCHECK2(bp[0], 12); - ND_PRINT((ndo, " src %s grp %s", ipaddr_string(ndo, bp), ipaddr_string(ndo, bp + 4))); - bp += 8; - ND_PRINT((ndo, " timer ")); - unsigned_relts_print(ndo, EXTRACT_32BITS(bp)); - return (0); -trunc: - return (-1); -} - -static int -print_graft(netdissect_options *ndo, - register const u_char *bp) -{ - ND_TCHECK2(bp[0], 8); - ND_PRINT((ndo, " src %s grp %s", ipaddr_string(ndo, bp), ipaddr_string(ndo, bp + 4))); - return (0); -trunc: - return (-1); -} + return; -static int -print_graft_ack(netdissect_options *ndo, - register const u_char *bp) -{ - ND_TCHECK2(bp[0], 8); - ND_PRINT((ndo, " src %s grp %s", ipaddr_string(ndo, bp), ipaddr_string(ndo, bp + 4))); - return (0); -trunc: - return (-1); +invalid: + nd_print_invalid(ndo); } diff --git a/contrib/tcpdump/print-eap.c b/contrib/tcpdump/print-eap.c index d76aea3395..b0542ad94b 100644 --- a/contrib/tcpdump/print-eap.c +++ b/contrib/tcpdump/print-eap.c @@ -21,10 +21,10 @@ /* \summary: Extensible Authentication Protocol (EAP) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "extract.h" @@ -36,9 +36,9 @@ #define EAP_FRAME_TYPE_ENCAP_ASF_ALERT 4 struct eap_frame_t { - unsigned char version; - unsigned char type; - unsigned char length[2]; + nd_uint8_t version; + nd_uint8_t type; + nd_uint16_t length; }; static const struct tok eap_frame_type_values[] = { @@ -52,9 +52,9 @@ static const struct tok eap_frame_type_values[] = { /* RFC 3748 */ struct eap_packet_t { - unsigned char code; - unsigned char id; - unsigned char length[2]; + nd_uint8_t code; + nd_uint8_t id; + nd_uint16_t length; }; #define EAP_REQUEST 1 @@ -148,71 +148,44 @@ static const struct tok eap_aka_subtype_values[] = { */ void eap_print(netdissect_options *ndo, - register const u_char *cp, + const u_char *cp, u_int length) { - const struct eap_frame_t *eap; - const u_char *tptr; - u_int tlen, type, subtype; - int count=0, len; + u_int type, subtype, len; + int count; - tptr = cp; - tlen = length; - eap = (const struct eap_frame_t *)cp; - ND_TCHECK(*eap); - - /* in non-verbose mode just lets print the basic info */ - if (ndo->ndo_vflag < 1) { - ND_PRINT((ndo, "%s (%u) v%u, len %u", - tok2str(eap_frame_type_values, "unknown", eap->type), - eap->type, - eap->version, - EXTRACT_16BITS(eap->length))); - return; + type = GET_U_1(cp); + len = GET_BE_U_2(cp + 2); + if(len != length) { + goto trunc; } - - ND_PRINT((ndo, "%s (%u) v%u, len %u", - tok2str(eap_frame_type_values, "unknown", eap->type), - eap->type, - eap->version, - EXTRACT_16BITS(eap->length))); - - tptr += sizeof(const struct eap_frame_t); - tlen -= sizeof(const struct eap_frame_t); - - switch (eap->type) { - case EAP_FRAME_TYPE_PACKET: - ND_TCHECK_8BITS(tptr); - type = *(tptr); - ND_TCHECK_16BITS(tptr+2); - len = EXTRACT_16BITS(tptr+2); - ND_PRINT((ndo, ", %s (%u), id %u, len %u", - tok2str(eap_code_values, "unknown", type), - type, - *(tptr+1), - len)); - - ND_TCHECK2(*tptr, len); - - if (type <= 2) { /* For EAP_REQUEST and EAP_RESPONSE only */ - ND_TCHECK_8BITS(tptr+4); - subtype = *(tptr+4); - ND_PRINT((ndo, "\n\t\t Type %s (%u)", - tok2str(eap_type_values, "unknown", subtype), - subtype)); - - switch (subtype) { + ND_PRINT("%s (%u), id %u, len %u", + tok2str(eap_code_values, "unknown", type), + type, + GET_U_1((cp + 1)), + len); + + ND_TCHECK_LEN(cp, len); + + if (type == EAP_REQUEST || type == EAP_RESPONSE) { + /* RFC 3748 Section 4.1 */ + subtype = GET_U_1(cp + 4); + ND_PRINT("\n\t\t Type %s (%u)", + tok2str(eap_type_values, "unknown", subtype), + subtype); + + switch (subtype) { case EAP_TYPE_IDENTITY: if (len - 5 > 0) { - ND_PRINT((ndo, ", Identity: ")); - safeputs(ndo, tptr + 5, len - 5); + ND_PRINT(", Identity: "); + nd_printjnp(ndo, cp + 5, len - 5); } break; case EAP_TYPE_NOTIFICATION: if (len - 5 > 0) { - ND_PRINT((ndo, ", Notification: ")); - safeputs(ndo, tptr + 5, len - 5); + ND_PRINT(", Notification: "); + nd_printjnp(ndo, cp + 5, len - 5); } break; @@ -224,42 +197,37 @@ eap_print(netdissect_options *ndo, * the desired authentication * type one octet per type */ - while (count < len) { - ND_TCHECK_8BITS(tptr+count); - ND_PRINT((ndo, " %s (%u),", - tok2str(eap_type_values, "unknown", *(tptr+count)), - *(tptr + count))); + while (count < (int)len) { + ND_PRINT(" %s (%u),", + tok2str(eap_type_values, "unknown", GET_U_1((cp + count))), + GET_U_1(cp + count)); count++; } break; case EAP_TYPE_TTLS: case EAP_TYPE_TLS: - ND_TCHECK_8BITS(tptr + 5); if (subtype == EAP_TYPE_TTLS) - ND_PRINT((ndo, " TTLSv%u", - EAP_TTLS_VERSION(*(tptr + 5)))); - ND_PRINT((ndo, " flags [%s] 0x%02x,", - bittok2str(eap_tls_flags_values, "none", *(tptr+5)), - *(tptr + 5))); - - if (EAP_TLS_EXTRACT_BIT_L(*(tptr+5))) { - ND_TCHECK_32BITS(tptr + 6); - ND_PRINT((ndo, " len %u", EXTRACT_32BITS(tptr + 6))); + ND_PRINT(" TTLSv%u", + EAP_TTLS_VERSION(GET_U_1((cp + 5)))); + ND_PRINT(" flags [%s] 0x%02x,", + bittok2str(eap_tls_flags_values, "none", GET_U_1((cp + 5))), + GET_U_1(cp + 5)); + + if (EAP_TLS_EXTRACT_BIT_L(GET_U_1(cp + 5))) { + ND_PRINT(" len %u", GET_BE_U_4(cp + 6)); } break; case EAP_TYPE_FAST: - ND_TCHECK_8BITS(tptr + 5); - ND_PRINT((ndo, " FASTv%u", - EAP_TTLS_VERSION(*(tptr + 5)))); - ND_PRINT((ndo, " flags [%s] 0x%02x,", - bittok2str(eap_tls_flags_values, "none", *(tptr+5)), - *(tptr + 5))); - - if (EAP_TLS_EXTRACT_BIT_L(*(tptr+5))) { - ND_TCHECK_32BITS(tptr + 6); - ND_PRINT((ndo, " len %u", EXTRACT_32BITS(tptr + 6))); + ND_PRINT(" FASTv%u", + EAP_TTLS_VERSION(GET_U_1((cp + 5)))); + ND_PRINT(" flags [%s] 0x%02x,", + bittok2str(eap_tls_flags_values, "none", GET_U_1((cp + 5))), + GET_U_1(cp + 5)); + + if (EAP_TLS_EXTRACT_BIT_L(GET_U_1(cp + 5))) { + ND_PRINT(" len %u", GET_BE_U_4(cp + 6)); } /* FIXME - TLV attributes follow */ @@ -267,10 +235,9 @@ eap_print(netdissect_options *ndo, case EAP_TYPE_AKA: case EAP_TYPE_SIM: - ND_TCHECK_8BITS(tptr + 5); - ND_PRINT((ndo, " subtype [%s] 0x%02x,", - tok2str(eap_aka_subtype_values, "unknown", *(tptr+5)), - *(tptr + 5))); + ND_PRINT(" subtype [%s] 0x%02x,", + tok2str(eap_aka_subtype_values, "unknown", GET_U_1((cp + 5))), + GET_U_1(cp + 5)); /* FIXME - TLV attributes follow */ break; @@ -282,10 +249,43 @@ eap_print(netdissect_options *ndo, case EAP_TYPE_EXPERIMENTAL: default: break; - } } - break; + } + return; +trunc: + nd_print_trunc(ndo); +} + +void +eapol_print(netdissect_options *ndo, + const u_char *cp) +{ + const struct eap_frame_t *eap; + u_int eap_type, eap_len; + + ndo->ndo_protocol = "eap"; + eap = (const struct eap_frame_t *)cp; + ND_TCHECK_SIZE(eap); + eap_type = GET_U_1(eap->type); + + ND_PRINT("%s (%u) v%u, len %u", + tok2str(eap_frame_type_values, "unknown", eap_type), + eap_type, + GET_U_1(eap->version), + GET_BE_U_2(eap->length)); + if (ndo->ndo_vflag < 1) + return; + cp += sizeof(struct eap_frame_t); + eap_len = GET_BE_U_2(eap->length); + + switch (eap_type) { + case EAP_FRAME_TYPE_PACKET: + if (eap_len == 0) + goto trunc; + ND_PRINT(", "); + eap_print(ndo, cp, eap_len); + return; case EAP_FRAME_TYPE_LOGOFF: case EAP_FRAME_TYPE_ENCAP_ASF_ALERT: default: @@ -294,11 +294,5 @@ eap_print(netdissect_options *ndo, return; trunc: - ND_PRINT((ndo, "\n\t[|EAP]")); + nd_print_trunc(ndo); } - -/* - * Local Variables: - * c-basic-offset: 4 - * End: - */ diff --git a/contrib/tcpdump/print-egp.c b/contrib/tcpdump/print-egp.c index 8fba9ce747..d20e5befe9 100644 --- a/contrib/tcpdump/print-egp.c +++ b/contrib/tcpdump/print-egp.c @@ -20,26 +20,28 @@ /* \summary: Exterior Gateway Protocol (EGP) printer */ +/* specification: RFC 827 */ + #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "addrtoname.h" #include "extract.h" struct egp_packet { - uint8_t egp_version; + nd_uint8_t egp_version; #define EGP_VERSION 2 - uint8_t egp_type; + nd_uint8_t egp_type; #define EGPT_ACQUIRE 3 #define EGPT_REACH 5 #define EGPT_POLL 2 #define EGPT_UPDATE 1 #define EGPT_ERROR 8 - uint8_t egp_code; + nd_uint8_t egp_code; #define EGPC_REQUEST 0 #define EGPC_CONFIRM 1 #define EGPC_REFUSE 2 @@ -47,7 +49,7 @@ struct egp_packet { #define EGPC_CEASEACK 4 #define EGPC_HELLO 0 #define EGPC_HEARDU 1 - uint8_t egp_status; + nd_uint8_t egp_status; #define EGPS_UNSPEC 0 #define EGPS_ACTIVE 1 #define EGPS_PASSIVE 2 @@ -60,13 +62,13 @@ struct egp_packet { #define EGPS_UP 1 #define EGPS_DOWN 2 #define EGPS_UNSOL 0x80 - uint16_t egp_checksum; - uint16_t egp_as; - uint16_t egp_sequence; + nd_uint16_t egp_checksum; + nd_uint16_t egp_as; + nd_uint16_t egp_sequence; union { - uint16_t egpu_hello; - uint8_t egpu_gws[2]; - uint16_t egpu_reason; + nd_uint16_t egpu_hello; + nd_uint8_t egpu_gws[2]; + nd_uint16_t egpu_reason; #define EGPR_UNSPEC 0 #define EGPR_BADHEAD 1 #define EGPR_BADDATA 2 @@ -80,8 +82,8 @@ struct egp_packet { #define egp_extgw egp_handg.egpu_gws[1] #define egp_reason egp_handg.egpu_reason union { - uint16_t egpu_poll; - uint32_t egpu_sourcenet; + nd_uint16_t egpu_poll; + nd_ipv4 egpu_sourcenet; } egp_pands; #define egp_poll egp_pands.egpu_poll #define egp_sourcenet egp_pands.egpu_sourcenet @@ -128,18 +130,18 @@ static const char *egp_reasons[] = { }; static void -egpnrprint(netdissect_options *ndo, - register const struct egp_packet *egp, u_int length) +egpnr_print(netdissect_options *ndo, + const struct egp_packet *egp, u_int length) { - register const uint8_t *cp; + const uint8_t *cp; uint32_t addr; - register uint32_t net; - register u_int netlen; - int gateways, distances, networks; - int t_gateways; + uint32_t net; + u_int netlen; + u_int gateways, distances, networks; + u_int intgw, extgw, t_gateways; const char *comma; - addr = egp->egp_sourcenet; + addr = GET_IPV4_TO_NETWORK_ORDER(egp->egp_sourcenet); if (IN_CLASSA(addr)) { net = addr & IN_CLASSA_NET; netlen = 1; @@ -156,139 +158,152 @@ egpnrprint(netdissect_options *ndo, cp = (const uint8_t *)(egp + 1); length -= sizeof(*egp); - t_gateways = egp->egp_intgw + egp->egp_extgw; + intgw = GET_U_1(egp->egp_intgw); + extgw = GET_U_1(egp->egp_extgw); + t_gateways = intgw + extgw; for (gateways = 0; gateways < t_gateways; ++gateways) { /* Pickup host part of gateway address */ addr = 0; if (length < 4 - netlen) goto trunc; - ND_TCHECK2(cp[0], 4 - netlen); + ND_TCHECK_LEN(cp, 4 - netlen); switch (netlen) { case 1: - addr = *cp++; + addr = GET_U_1(cp); + cp++; /* fall through */ case 2: - addr = (addr << 8) | *cp++; + addr = (addr << 8) | GET_U_1(cp); + cp++; /* fall through */ case 3: - addr = (addr << 8) | *cp++; + addr = (addr << 8) | GET_U_1(cp); + cp++; + break; } addr |= net; length -= 4 - netlen; if (length < 1) goto trunc; - ND_TCHECK2(cp[0], 1); - distances = *cp++; + distances = GET_U_1(cp); + cp++; length--; - ND_PRINT((ndo, " %s %s ", - gateways < (int)egp->egp_intgw ? "int" : "ext", - ipaddr_string(ndo, &addr))); + ND_PRINT(" %s %s ", + gateways < intgw ? "int" : "ext", + ipaddr_string(ndo, (const u_char *)&addr)); comma = ""; - ND_PRINT((ndo, "(")); - while (--distances >= 0) { + ND_PRINT("("); + while (distances != 0) { if (length < 2) goto trunc; - ND_TCHECK2(cp[0], 2); - ND_PRINT((ndo, "%sd%d:", comma, (int)*cp++)); + ND_PRINT("%sd%u:", comma, GET_U_1(cp)); + cp++; comma = ", "; - networks = *cp++; + networks = GET_U_1(cp); + cp++; length -= 2; - while (--networks >= 0) { + while (networks != 0) { /* Pickup network number */ if (length < 1) goto trunc; - ND_TCHECK2(cp[0], 1); - addr = (uint32_t)*cp++ << 24; + addr = ((uint32_t) GET_U_1(cp)) << 24; + cp++; length--; if (IN_CLASSB(addr)) { if (length < 1) goto trunc; - ND_TCHECK2(cp[0], 1); - addr |= (uint32_t)*cp++ << 16; + addr |= ((uint32_t) GET_U_1(cp)) << 16; + cp++; length--; } else if (!IN_CLASSA(addr)) { if (length < 2) goto trunc; - ND_TCHECK2(cp[0], 2); - addr |= (uint32_t)*cp++ << 16; - addr |= (uint32_t)*cp++ << 8; + addr |= ((uint32_t) GET_U_1(cp)) << 16; + cp++; + addr |= ((uint32_t) GET_U_1(cp)) << 8; + cp++; length -= 2; } - ND_PRINT((ndo, " %s", ipaddr_string(ndo, &addr))); + ND_PRINT(" %s", ipaddr_string(ndo, (const u_char *)&addr)); + networks--; } + distances--; } - ND_PRINT((ndo, ")")); + ND_PRINT(")"); } return; trunc: - ND_PRINT((ndo, "[|]")); + nd_print_trunc(ndo); } void egp_print(netdissect_options *ndo, - register const uint8_t *bp, register u_int length) + const uint8_t *bp, u_int length) { - register const struct egp_packet *egp; - register int status; - register int code; - register int type; + const struct egp_packet *egp; + u_int version; + u_int type; + u_int code; + u_int status; + ndo->ndo_protocol = "egp"; egp = (const struct egp_packet *)bp; - if (length < sizeof(*egp) || !ND_TTEST(*egp)) { - ND_PRINT((ndo, "[|egp]")); + if (length < sizeof(*egp) || !ND_TTEST_SIZE(egp)) { + nd_print_trunc(ndo); return; } + version = GET_U_1(egp->egp_version); if (!ndo->ndo_vflag) { - ND_PRINT((ndo, "EGPv%u, AS %u, seq %u, length %u", - egp->egp_version, - EXTRACT_16BITS(&egp->egp_as), - EXTRACT_16BITS(&egp->egp_sequence), - length)); + ND_PRINT("EGPv%u, AS %u, seq %u, length %u", + version, + GET_BE_U_2(egp->egp_as), + GET_BE_U_2(egp->egp_sequence), + length); return; } else - ND_PRINT((ndo, "EGPv%u, length %u", - egp->egp_version, - length)); + ND_PRINT("EGPv%u, length %u", + version, + length); - if (egp->egp_version != EGP_VERSION) { - ND_PRINT((ndo, "[version %d]", egp->egp_version)); + if (version != EGP_VERSION) { + ND_PRINT("[version %u]", version); return; } - type = egp->egp_type; - code = egp->egp_code; - status = egp->egp_status; + type = GET_U_1(egp->egp_type); + code = GET_U_1(egp->egp_code); + status = GET_U_1(egp->egp_status); switch (type) { case EGPT_ACQUIRE: - ND_PRINT((ndo, " acquire")); + ND_PRINT(" acquire"); switch (code) { case EGPC_REQUEST: case EGPC_CONFIRM: - ND_PRINT((ndo, " %s", egp_acquire_codes[code])); + ND_PRINT(" %s", egp_acquire_codes[code]); switch (status) { case EGPS_UNSPEC: case EGPS_ACTIVE: case EGPS_PASSIVE: - ND_PRINT((ndo, " %s", egp_acquire_status[status])); + ND_PRINT(" %s", egp_acquire_status[status]); break; default: - ND_PRINT((ndo, " [status %d]", status)); + ND_PRINT(" [status %u]", status); break; } - ND_PRINT((ndo, " hello:%d poll:%d", - EXTRACT_16BITS(&egp->egp_hello), - EXTRACT_16BITS(&egp->egp_poll))); + ND_PRINT(" hello:%u poll:%u", + GET_BE_U_2(egp->egp_hello), + GET_BE_U_2(egp->egp_poll)); break; case EGPC_REFUSE: case EGPC_CEASE: case EGPC_CEASEACK: - ND_PRINT((ndo, " %s", egp_acquire_codes[code])); + ND_PRINT(" %s", egp_acquire_codes[code]); switch (status ) { case EGPS_UNSPEC: case EGPS_NORES: @@ -296,17 +311,17 @@ egp_print(netdissect_options *ndo, case EGPS_GODOWN: case EGPS_PARAM: case EGPS_PROTO: - ND_PRINT((ndo, " %s", egp_acquire_status[status])); + ND_PRINT(" %s", egp_acquire_status[status]); break; default: - ND_PRINT((ndo, "[status %d]", status)); + ND_PRINT("[status %u]", status); break; } break; default: - ND_PRINT((ndo, "[code %d]", code)); + ND_PRINT("[code %u]", code); break; } break; @@ -316,61 +331,62 @@ egp_print(netdissect_options *ndo, case EGPC_HELLO: case EGPC_HEARDU: - ND_PRINT((ndo, " %s", egp_reach_codes[code])); + ND_PRINT(" %s", egp_reach_codes[code]); if (status <= EGPS_DOWN) - ND_PRINT((ndo, " state:%s", egp_status_updown[status])); + ND_PRINT(" state:%s", egp_status_updown[status]); else - ND_PRINT((ndo, " [status %d]", status)); + ND_PRINT(" [status %u]", status); break; default: - ND_PRINT((ndo, "[reach code %d]", code)); + ND_PRINT("[reach code %u]", code); break; } break; case EGPT_POLL: - ND_PRINT((ndo, " poll")); - if (egp->egp_status <= EGPS_DOWN) - ND_PRINT((ndo, " state:%s", egp_status_updown[status])); + ND_PRINT(" poll"); + if (status <= EGPS_DOWN) + ND_PRINT(" state:%s", egp_status_updown[status]); else - ND_PRINT((ndo, " [status %d]", status)); - ND_PRINT((ndo, " net:%s", ipaddr_string(ndo, &egp->egp_sourcenet))); + ND_PRINT(" [status %u]", status); + ND_PRINT(" net:%s", GET_IPADDR_STRING(egp->egp_sourcenet)); break; case EGPT_UPDATE: - ND_PRINT((ndo, " update")); + ND_PRINT(" update"); if (status & EGPS_UNSOL) { status &= ~EGPS_UNSOL; - ND_PRINT((ndo, " unsolicited")); + ND_PRINT(" unsolicited"); } if (status <= EGPS_DOWN) - ND_PRINT((ndo, " state:%s", egp_status_updown[status])); + ND_PRINT(" state:%s", egp_status_updown[status]); else - ND_PRINT((ndo, " [status %d]", status)); - ND_PRINT((ndo, " %s int %d ext %d", - ipaddr_string(ndo, &egp->egp_sourcenet), - egp->egp_intgw, - egp->egp_extgw)); + ND_PRINT(" [status %u]", status); + ND_PRINT(" %s int %u ext %u", + GET_IPADDR_STRING(egp->egp_sourcenet), + GET_U_1(egp->egp_intgw), + GET_U_1(egp->egp_extgw)); if (ndo->ndo_vflag) - egpnrprint(ndo, egp, length); + egpnr_print(ndo, egp, length); break; case EGPT_ERROR: - ND_PRINT((ndo, " error")); + ND_PRINT(" error"); if (status <= EGPS_DOWN) - ND_PRINT((ndo, " state:%s", egp_status_updown[status])); + ND_PRINT(" state:%s", egp_status_updown[status]); else - ND_PRINT((ndo, " [status %d]", status)); + ND_PRINT(" [status %u]", status); - if (EXTRACT_16BITS(&egp->egp_reason) <= EGPR_UVERSION) - ND_PRINT((ndo, " %s", egp_reasons[EXTRACT_16BITS(&egp->egp_reason)])); + if (GET_BE_U_2(egp->egp_reason) <= EGPR_UVERSION) + ND_PRINT(" %s", + egp_reasons[GET_BE_U_2(egp->egp_reason)]); else - ND_PRINT((ndo, " [reason %d]", EXTRACT_16BITS(&egp->egp_reason))); + ND_PRINT(" [reason %u]", GET_BE_U_2(egp->egp_reason)); break; default: - ND_PRINT((ndo, "[type %d]", type)); + ND_PRINT("[type %u]", type); break; } } diff --git a/contrib/tcpdump/print-eigrp.c b/contrib/tcpdump/print-eigrp.c index c9b35267f2..1bcdf1793e 100644 --- a/contrib/tcpdump/print-eigrp.c +++ b/contrib/tcpdump/print-eigrp.c @@ -16,11 +16,18 @@ /* \summary: Enhanced Interior Gateway Routing Protocol (EIGRP) printer */ +/* + * specification: + * + * https://web.archive.org/web/20190722221712/https://www.rhyshaden.com/eigrp.htm + * RFC 7868 + */ + #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include @@ -28,20 +35,16 @@ #include "extract.h" #include "addrtoname.h" -/* - * packet format documented at - * http://www.rhyshaden.com/eigrp.htm - * RFC 7868 - */ struct eigrp_common_header { - uint8_t version; - uint8_t opcode; - uint8_t checksum[2]; - uint8_t flags[4]; - uint8_t seq[4]; - uint8_t ack[4]; - uint8_t asn[4]; + nd_uint8_t version; + nd_uint8_t opcode; + nd_uint16_t checksum; + nd_uint32_t flags; + nd_uint32_t seq; + nd_uint32_t ack; + nd_uint16_t vrid; + nd_uint16_t asn; }; #define EIGRP_VERSION 2 @@ -66,12 +69,14 @@ static const struct tok eigrp_opcode_values[] = { static const struct tok eigrp_common_header_flag_values[] = { { 0x01, "Init" }, { 0x02, "Conditionally Received" }, + { 0x04, "Restart" }, + { 0x08, "End-of-Table" }, { 0, NULL} }; struct eigrp_tlv_header { - uint8_t type[2]; - uint8_t length[2]; + nd_uint16_t type; + nd_uint16_t length; }; #define EIGRP_TLV_GENERAL_PARM 0x0001 @@ -104,91 +109,91 @@ static const struct tok eigrp_tlv_values[] = { }; struct eigrp_tlv_general_parm_t { - uint8_t k1; - uint8_t k2; - uint8_t k3; - uint8_t k4; - uint8_t k5; - uint8_t res; - uint8_t holdtime[2]; + nd_uint8_t k1; + nd_uint8_t k2; + nd_uint8_t k3; + nd_uint8_t k4; + nd_uint8_t k5; + nd_uint8_t res; + nd_uint16_t holdtime; }; struct eigrp_tlv_sw_version_t { - uint8_t ios_major; - uint8_t ios_minor; - uint8_t eigrp_major; - uint8_t eigrp_minor; + nd_uint8_t ios_major; + nd_uint8_t ios_minor; + nd_uint8_t eigrp_major; + nd_uint8_t eigrp_minor; }; struct eigrp_tlv_ip_int_t { - uint8_t nexthop[4]; - uint8_t delay[4]; - uint8_t bandwidth[4]; - uint8_t mtu[3]; - uint8_t hopcount; - uint8_t reliability; - uint8_t load; - uint8_t reserved[2]; - uint8_t plen; - uint8_t destination; /* variable length [1-4] bytes encoding */ + nd_ipv4 nexthop; + nd_uint32_t delay; + nd_uint32_t bandwidth; + nd_uint24_t mtu; + nd_uint8_t hopcount; + nd_uint8_t reliability; + nd_uint8_t load; + nd_byte reserved[2]; + nd_uint8_t plen; + nd_uint8_t destination; /* variable length [1-4] bytes encoding */ }; struct eigrp_tlv_ip_ext_t { - uint8_t nexthop[4]; - uint8_t origin_router[4]; - uint8_t origin_as[4]; - uint8_t tag[4]; - uint8_t metric[4]; - uint8_t reserved[2]; - uint8_t proto_id; - uint8_t flags; - uint8_t delay[4]; - uint8_t bandwidth[4]; - uint8_t mtu[3]; - uint8_t hopcount; - uint8_t reliability; - uint8_t load; - uint8_t reserved2[2]; - uint8_t plen; - uint8_t destination; /* variable length [1-4] bytes encoding */ + nd_ipv4 nexthop; + nd_ipv4 origin_router; + nd_uint32_t origin_as; + nd_uint32_t tag; + nd_uint32_t metric; + nd_byte reserved[2]; + nd_uint8_t proto_id; + nd_uint8_t flags; + nd_uint32_t delay; + nd_uint32_t bandwidth; + nd_uint24_t mtu; + nd_uint8_t hopcount; + nd_uint8_t reliability; + nd_uint8_t load; + nd_byte reserved2[2]; + nd_uint8_t plen; + nd_uint8_t destination; /* variable length [1-4] bytes encoding */ }; struct eigrp_tlv_at_cable_setup_t { - uint8_t cable_start[2]; - uint8_t cable_end[2]; - uint8_t router_id[4]; + nd_uint16_t cable_start; + nd_uint16_t cable_end; + nd_uint32_t router_id; }; struct eigrp_tlv_at_int_t { - uint8_t nexthop[4]; - uint8_t delay[4]; - uint8_t bandwidth[4]; - uint8_t mtu[3]; - uint8_t hopcount; - uint8_t reliability; - uint8_t load; - uint8_t reserved[2]; - uint8_t cable_start[2]; - uint8_t cable_end[2]; + nd_byte nexthop[4]; + nd_uint32_t delay; + nd_uint32_t bandwidth; + nd_uint24_t mtu; + nd_uint8_t hopcount; + nd_uint8_t reliability; + nd_uint8_t load; + nd_byte reserved[2]; + nd_uint16_t cable_start; + nd_uint16_t cable_end; }; struct eigrp_tlv_at_ext_t { - uint8_t nexthop[4]; - uint8_t origin_router[4]; - uint8_t origin_as[4]; - uint8_t tag[4]; - uint8_t proto_id; - uint8_t flags; - uint8_t metric[2]; - uint8_t delay[4]; - uint8_t bandwidth[4]; - uint8_t mtu[3]; - uint8_t hopcount; - uint8_t reliability; - uint8_t load; - uint8_t reserved2[2]; - uint8_t cable_start[2]; - uint8_t cable_end[2]; + nd_byte nexthop[4]; + nd_uint32_t origin_router; + nd_uint32_t origin_as; + nd_uint32_t tag; + nd_uint8_t proto_id; + nd_uint8_t flags; + nd_uint16_t metric; + nd_uint32_t delay; + nd_uint32_t bandwidth; + nd_uint24_t mtu; + nd_uint8_t hopcount; + nd_uint8_t reliability; + nd_uint8_t load; + nd_byte reserved2[2]; + nd_uint16_t cable_start; + nd_uint16_t cable_end; }; static const struct tok eigrp_ext_proto_id_values[] = { @@ -207,7 +212,7 @@ static const struct tok eigrp_ext_proto_id_values[] = { }; void -eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int len) +eigrp_print(netdissect_options *ndo, const u_char *pptr, u_int len) { const struct eigrp_common_header *eigrp_com_header; const struct eigrp_tlv_header *eigrp_tlv_header; @@ -225,59 +230,62 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int const struct eigrp_tlv_at_ext_t *eigrp_tlv_at_ext; } tlv_ptr; + ndo->ndo_protocol = "eigrp"; tptr=pptr; eigrp_com_header = (const struct eigrp_common_header *)pptr; - ND_TCHECK(*eigrp_com_header); + ND_TCHECK_SIZE(eigrp_com_header); /* * Sanity checking of the header. */ - if (eigrp_com_header->version != EIGRP_VERSION) { - ND_PRINT((ndo, "EIGRP version %u packet not supported",eigrp_com_header->version)); - return; + if (GET_U_1(eigrp_com_header->version) != EIGRP_VERSION) { + ND_PRINT("EIGRP version %u packet not supported", + GET_U_1(eigrp_com_header->version)); + return; } /* in non-verbose mode just lets print the basic Message Type*/ if (ndo->ndo_vflag < 1) { - ND_PRINT((ndo, "EIGRP %s, length: %u", - tok2str(eigrp_opcode_values, "unknown (%u)",eigrp_com_header->opcode), - len)); + ND_PRINT("EIGRP %s, length: %u", + tok2str(eigrp_opcode_values, "unknown (%u)",GET_U_1(eigrp_com_header->opcode)), + len); return; } /* ok they seem to want to know everything - lets fully decode it */ if (len < sizeof(struct eigrp_common_header)) { - ND_PRINT((ndo, "EIGRP %s, length: %u (too short, < %u)", - tok2str(eigrp_opcode_values, "unknown (%u)",eigrp_com_header->opcode), - len, (u_int) sizeof(struct eigrp_common_header))); + ND_PRINT("EIGRP %s, length: %u (too short, < %zu)", + tok2str(eigrp_opcode_values, "unknown (%u)",GET_U_1(eigrp_com_header->opcode)), + len, sizeof(struct eigrp_common_header)); return; } tlen=len-sizeof(struct eigrp_common_header); - /* FIXME print other header info */ - ND_PRINT((ndo, "\n\tEIGRP v%u, opcode: %s (%u), chksum: 0x%04x, Flags: [%s]\n\tseq: 0x%08x, ack: 0x%08x, AS: %u, length: %u", - eigrp_com_header->version, - tok2str(eigrp_opcode_values, "unknown, type: %u",eigrp_com_header->opcode), - eigrp_com_header->opcode, - EXTRACT_16BITS(&eigrp_com_header->checksum), - tok2str(eigrp_common_header_flag_values, + ND_PRINT("\n\tEIGRP v%u, opcode: %s (%u), chksum: 0x%04x, Flags: [%s]" + "\n\tseq: 0x%08x, ack: 0x%08x, VRID: %u, AS: %u, length: %u", + GET_U_1(eigrp_com_header->version), + tok2str(eigrp_opcode_values, "unknown, type: %u",GET_U_1(eigrp_com_header->opcode)), + GET_U_1(eigrp_com_header->opcode), + GET_BE_U_2(eigrp_com_header->checksum), + bittok2str(eigrp_common_header_flag_values, "none", - EXTRACT_32BITS(&eigrp_com_header->flags)), - EXTRACT_32BITS(&eigrp_com_header->seq), - EXTRACT_32BITS(&eigrp_com_header->ack), - EXTRACT_32BITS(&eigrp_com_header->asn), - tlen)); + GET_BE_U_4(eigrp_com_header->flags)), + GET_BE_U_4(eigrp_com_header->seq), + GET_BE_U_4(eigrp_com_header->ack), + GET_BE_U_2(eigrp_com_header->vrid), + GET_BE_U_2(eigrp_com_header->asn), + tlen); - tptr+=sizeof(const struct eigrp_common_header); + tptr+=sizeof(struct eigrp_common_header); while(tlen>0) { /* did we capture enough for fully decoding the object header ? */ - ND_TCHECK2(*tptr, sizeof(struct eigrp_tlv_header)); + ND_TCHECK_LEN(tptr, sizeof(struct eigrp_tlv_header)); eigrp_tlv_header = (const struct eigrp_tlv_header *)tptr; - eigrp_tlv_len=EXTRACT_16BITS(&eigrp_tlv_header->length); - eigrp_tlv_type=EXTRACT_16BITS(&eigrp_tlv_header->type); + eigrp_tlv_len=GET_BE_U_2(eigrp_tlv_header->length); + eigrp_tlv_type=GET_BE_U_2(eigrp_tlv_header->type); if (eigrp_tlv_len < sizeof(struct eigrp_tlv_header) || @@ -286,212 +294,212 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int return; } - ND_PRINT((ndo, "\n\t %s TLV (0x%04x), length: %u", + ND_PRINT("\n\t %s TLV (0x%04x), length: %u", tok2str(eigrp_tlv_values, "Unknown", eigrp_tlv_type), eigrp_tlv_type, - eigrp_tlv_len)); + eigrp_tlv_len); if (eigrp_tlv_len < sizeof(struct eigrp_tlv_header)) { - ND_PRINT((ndo, " (too short, < %u)", - (u_int) sizeof(struct eigrp_tlv_header))); + ND_PRINT(" (too short, < %zu)", + sizeof(struct eigrp_tlv_header)); break; } tlv_tptr=tptr+sizeof(struct eigrp_tlv_header); tlv_tlen=eigrp_tlv_len-sizeof(struct eigrp_tlv_header); /* did we capture enough for fully decoding the object ? */ - ND_TCHECK2(*tptr, eigrp_tlv_len); + ND_TCHECK_LEN(tptr, eigrp_tlv_len); switch(eigrp_tlv_type) { case EIGRP_TLV_GENERAL_PARM: tlv_ptr.eigrp_tlv_general_parm = (const struct eigrp_tlv_general_parm_t *)tlv_tptr; if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_general_parm)) { - ND_PRINT((ndo, " (too short, < %u)", - (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_general_parm)))); + ND_PRINT(" (too short, < %zu)", + sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_general_parm)); break; } - ND_PRINT((ndo, "\n\t holdtime: %us, k1 %u, k2 %u, k3 %u, k4 %u, k5 %u", - EXTRACT_16BITS(tlv_ptr.eigrp_tlv_general_parm->holdtime), - tlv_ptr.eigrp_tlv_general_parm->k1, - tlv_ptr.eigrp_tlv_general_parm->k2, - tlv_ptr.eigrp_tlv_general_parm->k3, - tlv_ptr.eigrp_tlv_general_parm->k4, - tlv_ptr.eigrp_tlv_general_parm->k5)); + ND_PRINT("\n\t holdtime: %us, k1 %u, k2 %u, k3 %u, k4 %u, k5 %u", + GET_BE_U_2(tlv_ptr.eigrp_tlv_general_parm->holdtime), + GET_U_1(tlv_ptr.eigrp_tlv_general_parm->k1), + GET_U_1(tlv_ptr.eigrp_tlv_general_parm->k2), + GET_U_1(tlv_ptr.eigrp_tlv_general_parm->k3), + GET_U_1(tlv_ptr.eigrp_tlv_general_parm->k4), + GET_U_1(tlv_ptr.eigrp_tlv_general_parm->k5)); break; case EIGRP_TLV_SW_VERSION: tlv_ptr.eigrp_tlv_sw_version = (const struct eigrp_tlv_sw_version_t *)tlv_tptr; if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_sw_version)) { - ND_PRINT((ndo, " (too short, < %u)", - (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_sw_version)))); + ND_PRINT(" (too short, < %zu)", + sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_sw_version)); break; } - ND_PRINT((ndo, "\n\t IOS version: %u.%u, EIGRP version %u.%u", - tlv_ptr.eigrp_tlv_sw_version->ios_major, - tlv_ptr.eigrp_tlv_sw_version->ios_minor, - tlv_ptr.eigrp_tlv_sw_version->eigrp_major, - tlv_ptr.eigrp_tlv_sw_version->eigrp_minor)); + ND_PRINT("\n\t IOS version: %u.%u, EIGRP version %u.%u", + GET_U_1(tlv_ptr.eigrp_tlv_sw_version->ios_major), + GET_U_1(tlv_ptr.eigrp_tlv_sw_version->ios_minor), + GET_U_1(tlv_ptr.eigrp_tlv_sw_version->eigrp_major), + GET_U_1(tlv_ptr.eigrp_tlv_sw_version->eigrp_minor)); break; case EIGRP_TLV_IP_INT: tlv_ptr.eigrp_tlv_ip_int = (const struct eigrp_tlv_ip_int_t *)tlv_tptr; if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_ip_int)) { - ND_PRINT((ndo, " (too short, < %u)", - (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_ip_int)))); + ND_PRINT(" (too short, < %zu)", + sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_ip_int)); break; } - bit_length = tlv_ptr.eigrp_tlv_ip_int->plen; + bit_length = GET_U_1(tlv_ptr.eigrp_tlv_ip_int->plen); if (bit_length > 32) { - ND_PRINT((ndo, "\n\t illegal prefix length %u",bit_length)); + ND_PRINT("\n\t illegal prefix length %u",bit_length); break; } byte_length = (bit_length + 7) / 8; /* variable length encoding */ memset(prefix, 0, 4); - ND_TCHECK2(tlv_ptr.eigrp_tlv_ip_int->destination, byte_length); - memcpy(prefix,&tlv_ptr.eigrp_tlv_ip_int->destination,byte_length); - - ND_PRINT((ndo, "\n\t IPv4 prefix: %15s/%u, nexthop: ", - ipaddr_string(ndo, prefix), - bit_length)); - if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->nexthop) == 0) - ND_PRINT((ndo, "self")); + GET_CPY_BYTES(prefix, tlv_ptr.eigrp_tlv_ip_int->destination, byte_length); + + ND_PRINT("\n\t IPv4 prefix: %15s/%u, nexthop: ", + ipaddr_string(ndo, prefix), /* local buffer, not packet data; don't use GET_IPADDR_STRING() */ + bit_length); + if (GET_BE_U_4(tlv_ptr.eigrp_tlv_ip_int->nexthop) == 0) + ND_PRINT("self"); else - ND_PRINT((ndo, "%s",ipaddr_string(ndo, &tlv_ptr.eigrp_tlv_ip_int->nexthop))); - - ND_PRINT((ndo, "\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u", - (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->delay)/100), - EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->bandwidth), - EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_ip_int->mtu), - tlv_ptr.eigrp_tlv_ip_int->hopcount, - tlv_ptr.eigrp_tlv_ip_int->reliability, - tlv_ptr.eigrp_tlv_ip_int->load)); + ND_PRINT("%s", + GET_IPADDR_STRING(tlv_ptr.eigrp_tlv_ip_int->nexthop)); + + ND_PRINT("\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u", + (GET_BE_U_4(tlv_ptr.eigrp_tlv_ip_int->delay)/100), + GET_BE_U_4(tlv_ptr.eigrp_tlv_ip_int->bandwidth), + GET_BE_U_3(tlv_ptr.eigrp_tlv_ip_int->mtu), + GET_U_1(tlv_ptr.eigrp_tlv_ip_int->hopcount), + GET_U_1(tlv_ptr.eigrp_tlv_ip_int->reliability), + GET_U_1(tlv_ptr.eigrp_tlv_ip_int->load)); break; case EIGRP_TLV_IP_EXT: tlv_ptr.eigrp_tlv_ip_ext = (const struct eigrp_tlv_ip_ext_t *)tlv_tptr; if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_ip_ext)) { - ND_PRINT((ndo, " (too short, < %u)", - (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_ip_ext)))); + ND_PRINT(" (too short, < %zu)", + sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_ip_ext)); break; } - bit_length = tlv_ptr.eigrp_tlv_ip_ext->plen; + bit_length = GET_U_1(tlv_ptr.eigrp_tlv_ip_ext->plen); if (bit_length > 32) { - ND_PRINT((ndo, "\n\t illegal prefix length %u",bit_length)); + ND_PRINT("\n\t illegal prefix length %u",bit_length); break; } byte_length = (bit_length + 7) / 8; /* variable length encoding */ memset(prefix, 0, 4); - ND_TCHECK2(tlv_ptr.eigrp_tlv_ip_ext->destination, byte_length); - memcpy(prefix,&tlv_ptr.eigrp_tlv_ip_ext->destination,byte_length); - - ND_PRINT((ndo, "\n\t IPv4 prefix: %15s/%u, nexthop: ", - ipaddr_string(ndo, prefix), - bit_length)); - if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->nexthop) == 0) - ND_PRINT((ndo, "self")); + GET_CPY_BYTES(prefix, tlv_ptr.eigrp_tlv_ip_ext->destination, byte_length); + + ND_PRINT("\n\t IPv4 prefix: %15s/%u, nexthop: ", + ipaddr_string(ndo, prefix), /* local buffer, not packet data; don't use GET_IPADDR_STRING() */ + bit_length); + if (GET_BE_U_4(tlv_ptr.eigrp_tlv_ip_ext->nexthop) == 0) + ND_PRINT("self"); else - ND_PRINT((ndo, "%s",ipaddr_string(ndo, &tlv_ptr.eigrp_tlv_ip_ext->nexthop))); - - ND_PRINT((ndo, "\n\t origin-router %s, origin-as %u, origin-proto %s, flags [0x%02x], tag 0x%08x, metric %u", - ipaddr_string(ndo, tlv_ptr.eigrp_tlv_ip_ext->origin_router), - EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->origin_as), - tok2str(eigrp_ext_proto_id_values,"unknown",tlv_ptr.eigrp_tlv_ip_ext->proto_id), - tlv_ptr.eigrp_tlv_ip_ext->flags, - EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->tag), - EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->metric))); - - ND_PRINT((ndo, "\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u", - (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->delay)/100), - EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->bandwidth), - EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_ip_ext->mtu), - tlv_ptr.eigrp_tlv_ip_ext->hopcount, - tlv_ptr.eigrp_tlv_ip_ext->reliability, - tlv_ptr.eigrp_tlv_ip_ext->load)); + ND_PRINT("%s", + GET_IPADDR_STRING(tlv_ptr.eigrp_tlv_ip_ext->nexthop)); + + ND_PRINT("\n\t origin-router %s, origin-as %u, origin-proto %s, flags [0x%02x], tag 0x%08x, metric %u", + GET_IPADDR_STRING(tlv_ptr.eigrp_tlv_ip_ext->origin_router), + GET_BE_U_4(tlv_ptr.eigrp_tlv_ip_ext->origin_as), + tok2str(eigrp_ext_proto_id_values,"unknown",GET_U_1(tlv_ptr.eigrp_tlv_ip_ext->proto_id)), + GET_U_1(tlv_ptr.eigrp_tlv_ip_ext->flags), + GET_BE_U_4(tlv_ptr.eigrp_tlv_ip_ext->tag), + GET_BE_U_4(tlv_ptr.eigrp_tlv_ip_ext->metric)); + + ND_PRINT("\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u", + (GET_BE_U_4(tlv_ptr.eigrp_tlv_ip_ext->delay)/100), + GET_BE_U_4(tlv_ptr.eigrp_tlv_ip_ext->bandwidth), + GET_BE_U_3(tlv_ptr.eigrp_tlv_ip_ext->mtu), + GET_U_1(tlv_ptr.eigrp_tlv_ip_ext->hopcount), + GET_U_1(tlv_ptr.eigrp_tlv_ip_ext->reliability), + GET_U_1(tlv_ptr.eigrp_tlv_ip_ext->load)); break; case EIGRP_TLV_AT_CABLE_SETUP: tlv_ptr.eigrp_tlv_at_cable_setup = (const struct eigrp_tlv_at_cable_setup_t *)tlv_tptr; if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_at_cable_setup)) { - ND_PRINT((ndo, " (too short, < %u)", - (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_at_cable_setup)))); + ND_PRINT(" (too short, < %zu)", + sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_at_cable_setup)); break; } - ND_PRINT((ndo, "\n\t Cable-range: %u-%u, Router-ID %u", - EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->cable_start), - EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->cable_end), - EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->router_id))); + ND_PRINT("\n\t Cable-range: %u-%u, Router-ID %u", + GET_BE_U_2(tlv_ptr.eigrp_tlv_at_cable_setup->cable_start), + GET_BE_U_2(tlv_ptr.eigrp_tlv_at_cable_setup->cable_end), + GET_BE_U_4(tlv_ptr.eigrp_tlv_at_cable_setup->router_id)); break; case EIGRP_TLV_AT_INT: tlv_ptr.eigrp_tlv_at_int = (const struct eigrp_tlv_at_int_t *)tlv_tptr; if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_at_int)) { - ND_PRINT((ndo, " (too short, < %u)", - (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_at_int)))); + ND_PRINT(" (too short, < %zu)", + sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_at_int)); break; } - ND_PRINT((ndo, "\n\t Cable-Range: %u-%u, nexthop: ", - EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->cable_start), - EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->cable_end))); + ND_PRINT("\n\t Cable-Range: %u-%u, nexthop: ", + GET_BE_U_2(tlv_ptr.eigrp_tlv_at_int->cable_start), + GET_BE_U_2(tlv_ptr.eigrp_tlv_at_int->cable_end)); - if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop) == 0) - ND_PRINT((ndo, "self")); + if (GET_BE_U_4(tlv_ptr.eigrp_tlv_at_int->nexthop) == 0) + ND_PRINT("self"); else - ND_PRINT((ndo, "%u.%u", - EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop), - EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop[2]))); - - ND_PRINT((ndo, "\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u", - (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->delay)/100), - EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->bandwidth), - EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_at_int->mtu), - tlv_ptr.eigrp_tlv_at_int->hopcount, - tlv_ptr.eigrp_tlv_at_int->reliability, - tlv_ptr.eigrp_tlv_at_int->load)); + ND_PRINT("%u.%u", + GET_BE_U_2(&tlv_ptr.eigrp_tlv_at_int->nexthop[0]), + GET_BE_U_2(&tlv_ptr.eigrp_tlv_at_int->nexthop[2])); + + ND_PRINT("\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u", + (GET_BE_U_4(tlv_ptr.eigrp_tlv_at_int->delay)/100), + GET_BE_U_4(tlv_ptr.eigrp_tlv_at_int->bandwidth), + GET_BE_U_3(tlv_ptr.eigrp_tlv_at_int->mtu), + GET_U_1(tlv_ptr.eigrp_tlv_at_int->hopcount), + GET_U_1(tlv_ptr.eigrp_tlv_at_int->reliability), + GET_U_1(tlv_ptr.eigrp_tlv_at_int->load)); break; case EIGRP_TLV_AT_EXT: tlv_ptr.eigrp_tlv_at_ext = (const struct eigrp_tlv_at_ext_t *)tlv_tptr; if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_at_ext)) { - ND_PRINT((ndo, " (too short, < %u)", - (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_at_ext)))); + ND_PRINT(" (too short, < %zu)", + sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_at_ext)); break; } - ND_PRINT((ndo, "\n\t Cable-Range: %u-%u, nexthop: ", - EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->cable_start), - EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->cable_end))); + ND_PRINT("\n\t Cable-Range: %u-%u, nexthop: ", + GET_BE_U_2(tlv_ptr.eigrp_tlv_at_ext->cable_start), + GET_BE_U_2(tlv_ptr.eigrp_tlv_at_ext->cable_end)); - if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop) == 0) - ND_PRINT((ndo, "self")); + if (GET_BE_U_4(tlv_ptr.eigrp_tlv_at_ext->nexthop) == 0) + ND_PRINT("self"); else - ND_PRINT((ndo, "%u.%u", - EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop), - EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop[2]))); - - ND_PRINT((ndo, "\n\t origin-router %u, origin-as %u, origin-proto %s, flags [0x%02x], tag 0x%08x, metric %u", - EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->origin_router), - EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->origin_as), - tok2str(eigrp_ext_proto_id_values,"unknown",tlv_ptr.eigrp_tlv_at_ext->proto_id), - tlv_ptr.eigrp_tlv_at_ext->flags, - EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->tag), - EXTRACT_16BITS(tlv_ptr.eigrp_tlv_at_ext->metric))); - - ND_PRINT((ndo, "\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u", - (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->delay)/100), - EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->bandwidth), - EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_at_ext->mtu), - tlv_ptr.eigrp_tlv_at_ext->hopcount, - tlv_ptr.eigrp_tlv_at_ext->reliability, - tlv_ptr.eigrp_tlv_at_ext->load)); + ND_PRINT("%u.%u", + GET_BE_U_2(&tlv_ptr.eigrp_tlv_at_ext->nexthop[0]), + GET_BE_U_2(&tlv_ptr.eigrp_tlv_at_ext->nexthop[2])); + + ND_PRINT("\n\t origin-router %u, origin-as %u, origin-proto %s, flags [0x%02x], tag 0x%08x, metric %u", + GET_BE_U_4(tlv_ptr.eigrp_tlv_at_ext->origin_router), + GET_BE_U_4(tlv_ptr.eigrp_tlv_at_ext->origin_as), + tok2str(eigrp_ext_proto_id_values,"unknown",GET_U_1(tlv_ptr.eigrp_tlv_at_ext->proto_id)), + GET_U_1(tlv_ptr.eigrp_tlv_at_ext->flags), + GET_BE_U_4(tlv_ptr.eigrp_tlv_at_ext->tag), + GET_BE_U_2(tlv_ptr.eigrp_tlv_at_ext->metric)); + + ND_PRINT("\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u", + (GET_BE_U_4(tlv_ptr.eigrp_tlv_at_ext->delay)/100), + GET_BE_U_4(tlv_ptr.eigrp_tlv_at_ext->bandwidth), + GET_BE_U_3(tlv_ptr.eigrp_tlv_at_ext->mtu), + GET_U_1(tlv_ptr.eigrp_tlv_at_ext->hopcount), + GET_U_1(tlv_ptr.eigrp_tlv_at_ext->reliability), + GET_U_1(tlv_ptr.eigrp_tlv_at_ext->load)); break; /* @@ -520,5 +528,5 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int } return; trunc: - ND_PRINT((ndo, "\n\t\t packet exceeded snapshot")); + nd_print_trunc(ndo); } diff --git a/contrib/tcpdump/print-enc.c b/contrib/tcpdump/print-enc.c index d791b3f557..9f541c3ccc 100644 --- a/contrib/tcpdump/print-enc.c +++ b/contrib/tcpdump/print-enc.c @@ -24,13 +24,15 @@ /* \summary: OpenBSD IPsec encapsulation BPF layer printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" +#include "af.h" /* From $OpenBSD: if_enc.h,v 1.8 2001/06/25 05:14:00 angelos Exp $ */ /* @@ -74,65 +76,85 @@ #define M_AUTH 0x0800 /* packet was authenticated (AH) */ struct enchdr { - uint32_t af; - uint32_t spi; - uint32_t flags; + nd_uint32_t af; + nd_uint32_t spi; + nd_uint32_t flags; }; -#define ENC_PRINT_TYPE(wh, xf, nam) \ +#define ENC_PRINT_TYPE(wh, xf, name) \ if ((wh) & (xf)) { \ - ND_PRINT((ndo, "%s%s", nam, (wh) == (xf) ? "): " : ",")); \ + ND_PRINT("%s%s", name, (wh) == (xf) ? "): " : ","); \ (wh) &= ~(xf); \ } -u_int +/* + * Byte-swap a 32-bit number. + * ("htonl()" or "ntohl()" won't work - we want to byte-swap even on + * big-endian platforms.) + */ +#define SWAPLONG(y) \ +((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff)) + +void enc_if_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, register const u_char *p) + const struct pcap_pkthdr *h, const u_char *p) { - register u_int length = h->len; - register u_int caplen = h->caplen; - int flags; + u_int length = h->len; + u_int caplen = h->caplen; + u_int af, flags; const struct enchdr *hdr; - if (caplen < ENC_HDRLEN) { - ND_PRINT((ndo, "[|enc]")); - goto out; - } + ndo->ndo_protocol = "enc"; + ND_TCHECK_LEN(p, ENC_HDRLEN); + ndo->ndo_ll_hdr_len += ENC_HDRLEN; hdr = (const struct enchdr *)p; - flags = hdr->flags; + /* + * The address family and flags fields are in the byte order + * of the host that originally captured the traffic. + * + * To determine that, look at the address family. It's 32-bit, + * it is not likely ever to be > 65535 (I doubt there will + * ever be > 65535 address families and, so far, AF_ values have + * not been allocated very sparsely) so it should not have the + * upper 16 bits set, and it is not likely ever to be AF_UNSPEC, + * i.e. it's not likely ever to be 0, so if it's byte-swapped, + * it should have at least one of the upper 16 bits set. + * + * So if any of the upper 16 bits are set, we assume it, and + * the flags field, are byte-swapped. + * + * The SPI field is always in network byte order, i.e. big- + * endian. + */ + UNALIGNED_MEMCPY(&af, &hdr->af, sizeof (af)); + UNALIGNED_MEMCPY(&flags, &hdr->flags, sizeof (flags)); + if ((af & 0xFFFF0000) != 0) { + af = SWAPLONG(af); + flags = SWAPLONG(flags); + } + if (flags == 0) - ND_PRINT((ndo, "(unprotected): ")); + ND_PRINT("(unprotected): "); else - ND_PRINT((ndo, "(")); + ND_PRINT("("); ENC_PRINT_TYPE(flags, M_AUTH, "authentic"); ENC_PRINT_TYPE(flags, M_CONF, "confidential"); /* ENC_PRINT_TYPE(flags, M_TUNNEL, "tunnel"); */ - ND_PRINT((ndo, "SPI 0x%08x: ", EXTRACT_32BITS(&hdr->spi))); + ND_PRINT("SPI 0x%08x: ", GET_BE_U_4(hdr->spi)); length -= ENC_HDRLEN; caplen -= ENC_HDRLEN; p += ENC_HDRLEN; - switch (hdr->af) { - case AF_INET: + switch (af) { + case BSD_AFNUM_INET: ip_print(ndo, p, length); break; -#ifdef AF_INET6 - case AF_INET6: + case BSD_AFNUM_INET6_BSD: + case BSD_AFNUM_INET6_FREEBSD: + case BSD_AFNUM_INET6_DARWIN: ip6_print(ndo, p, length); break; -#endif } - -out: - return (ENC_HDRLEN); } - - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/print-esp.c b/contrib/tcpdump/print-esp.c index 6fabff1e8d..61c3e13bff 100644 --- a/contrib/tcpdump/print-esp.c +++ b/contrib/tcpdump/print-esp.c @@ -24,10 +24,10 @@ /* \summary: IPSEC Encapsulating Security Payload (ESP) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include #include @@ -45,10 +45,12 @@ #endif #include "netdissect.h" -#include "strtoaddr.h" #include "extract.h" +#ifdef HAVE_LIBCRYPTO +#include "strtoaddr.h" #include "ascii_strcasecmp.h" +#endif #include "ip.h" #include "ip6.h" @@ -87,8 +89,8 @@ */ struct newesp { - uint32_t esp_spi; /* ESP */ - uint32_t esp_seq; /* Sequence number */ + nd_uint32_t esp_spi; /* ESP */ + nd_uint32_t esp_seq; /* Sequence number */ /*variable size*/ /* (IV and) Payload data */ /*variable size*/ /* padding */ /*8bit*/ /* pad size */ @@ -99,8 +101,8 @@ struct newesp { #ifdef HAVE_LIBCRYPTO union inaddr_u { - struct in_addr in4; - struct in6_addr in6; + nd_ipv4 in4; + nd_ipv6 in6; }; struct sa_list { struct sa_list *next; @@ -111,7 +113,7 @@ struct sa_list { u_char spii[8]; /* for IKEv2 */ u_char spir[8]; const EVP_CIPHER *evp; - int ivlen; + u_int ivlen; int authlen; u_char authsecret[256]; int authsecret_len; @@ -145,14 +147,14 @@ EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) } #endif -#ifdef HAVE_EVP_CIPHERINIT_EX +#ifdef HAVE_EVP_DECRYPTINIT_EX /* - * Initialize the cipher by calling EVP_CipherInit_ex(), because - * calling EVP_CipherInit() will reset the cipher context, clearing + * Initialize the cipher by calling EVP_DecryptInit_ex(), because + * calling EVP_DecryptInit() will reset the cipher context, clearing * the cipher, so calling it twice, with the second call having a - * null cipher, will clear the already-set cipher. EVP_CipherInit_ex(), + * null cipher, will clear the already-set cipher. EVP_DecryptInit_ex(), * however, won't reset the cipher context, so you can use it to specify - * the IV oin a second call after a first call to EVP_CipherInit_ex() + * the IV in a second call after a first call to EVP_DecryptInit_ex() * to set the cipher and the key. * * XXX - is there some reason why we need to make two calls? @@ -160,39 +162,134 @@ EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) static int set_cipher_parameters(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, const unsigned char *key, - const unsigned char *iv, int enc) + const unsigned char *iv) { - return EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, enc); + return EVP_DecryptInit_ex(ctx, cipher, NULL, key, iv); } #else /* - * Initialize the cipher by calling EVP_CipherInit(), because we don't - * have EVP_CipherInit_ex(); we rely on it not trashing the context. + * Initialize the cipher by calling EVP_DecryptInit(), because we don't + * have EVP_DecryptInit_ex(); we rely on it not trashing the context. */ static int set_cipher_parameters(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, const unsigned char *key, - const unsigned char *iv, int enc) + const unsigned char *iv) { - return EVP_CipherInit(ctx, cipher, key, iv, enc); + return EVP_DecryptInit(ctx, cipher, key, iv); } #endif +static u_char * +do_decrypt(netdissect_options *ndo, const char *caller, struct sa_list *sa, + const u_char *iv, const u_char *ct, unsigned int ctlen) +{ + EVP_CIPHER_CTX *ctx; + unsigned int block_size; + unsigned int ptlen; + u_char *pt; + int len; + + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) { + /* + * Failed to initialize the cipher context. + * From a look at the OpenSSL code, this appears to + * mean "couldn't allocate memory for the cipher context"; + * note that we're not passing any parameters, so there's + * not much else it can mean. + */ + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, + "%s: can't allocate memory for cipher context", caller); + return NULL; + } + + if (set_cipher_parameters(ctx, sa->evp, sa->secret, NULL) < 0) { + EVP_CIPHER_CTX_free(ctx); + (*ndo->ndo_warning)(ndo, "%s: espkey init failed", caller); + return NULL; + } + if (set_cipher_parameters(ctx, NULL, NULL, iv) < 0) { + EVP_CIPHER_CTX_free(ctx); + (*ndo->ndo_warning)(ndo, "%s: IV init failed", caller); + return NULL; + } + + /* + * At least as I read RFC 5996 section 3.14 and RFC 4303 section 2.4, + * if the cipher has a block size of which the ciphertext's size must + * be a multiple, the payload must be padded to make that happen, so + * the ciphertext length must be a multiple of the block size. Fail + * if that's not the case. + */ + block_size = (unsigned int)EVP_CIPHER_CTX_block_size(ctx); + if ((ctlen % block_size) != 0) { + EVP_CIPHER_CTX_free(ctx); + (*ndo->ndo_warning)(ndo, + "%s: ciphertext size %u is not a multiple of the cipher block size %u", + caller, ctlen, block_size); + return NULL; + } + + /* + * Attempt to allocate a buffer for the decrypted data, because + * we can't decrypt on top of the input buffer. + */ + ptlen = ctlen; + pt = (u_char *)malloc(ptlen); + if (pt == NULL) { + EVP_CIPHER_CTX_free(ctx); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, + "%s: can't allocate memory for decryption buffer", caller); + return NULL; + } + + /* + * The size of the ciphertext handed to us is a multiple of the + * cipher block size, so we don't need to worry about padding. + */ + if (!EVP_CIPHER_CTX_set_padding(ctx, 0)) { + free(pt); + EVP_CIPHER_CTX_free(ctx); + (*ndo->ndo_warning)(ndo, + "%s: EVP_CIPHER_CTX_set_padding failed", caller); + return NULL; + } + if (!EVP_DecryptUpdate(ctx, pt, &len, ct, ctlen)) { + free(pt); + EVP_CIPHER_CTX_free(ctx); + (*ndo->ndo_warning)(ndo, "%s: EVP_DecryptUpdate failed", + caller); + return NULL; + } + EVP_CIPHER_CTX_free(ctx); + return pt; +} + /* - * this will adjust ndo_packetp and ndo_snapend to new buffer! + * This will allocate a new buffer containing the decrypted data. + * It returns 1 on success and 0 on failure. + * + * It will push the new buffer and the values of ndo->ndo_packetp and + * ndo->ndo_snapend onto the buffer stack, and change ndo->ndo_packetp + * and ndo->ndo_snapend to refer to the new buffer. + * + * Our caller must pop the buffer off the stack when it's finished + * dissecting anything in it and before it does any dissection of + * anything in the old buffer. That will free the new buffer. */ USES_APPLE_DEPRECATED_API -int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo, +int esp_decrypt_buffer_by_ikev2_print(netdissect_options *ndo, int initiator, - u_char spii[8], u_char spir[8], + const u_char spii[8], + const u_char spir[8], const u_char *buf, const u_char *end) { struct sa_list *sa; const u_char *iv; - unsigned int len; - EVP_CIPHER_CTX *ctx; - unsigned int block_size, buffer_size; - u_char *input_buffer, *output_buffer; + const u_char *ct; + unsigned int ctlen; + u_char *pt; /* initiator arg is any non-zero value */ if(initiator) initiator=1; @@ -215,63 +312,25 @@ int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo, */ end = end - sa->authlen; iv = buf; - buf = buf + sa->ivlen; - len = end-buf; + ct = iv + sa->ivlen; + ctlen = end-ct; - if(end <= buf) return 0; + if(end <= ct) return 0; - ctx = EVP_CIPHER_CTX_new(); - if (ctx == NULL) + pt = do_decrypt(ndo, "esp_decrypt_buffer_by_ikev2_print", sa, iv, + ct, ctlen); + if (pt == NULL) return 0; - if (set_cipher_parameters(ctx, sa->evp, sa->secret, NULL, 0) < 0) - (*ndo->ndo_warning)(ndo, "espkey init failed"); - set_cipher_parameters(ctx, NULL, NULL, iv, 0); - /* - * Allocate buffers for the encrypted and decrypted data. - * Both buffers' sizes must be a multiple of the cipher block - * size, and the output buffer must be separate from the input - * buffer. - */ - block_size = (unsigned int)EVP_CIPHER_CTX_block_size(ctx); - buffer_size = len + (block_size - len % block_size); - - /* - * Attempt to allocate the input buffer. - */ - input_buffer = (u_char *)malloc(buffer_size); - if (input_buffer == NULL) { - EVP_CIPHER_CTX_free(ctx); - (*ndo->ndo_error)(ndo, "can't allocate memory for encrypted data buffer"); - } - /* - * Copy the input data to the encrypted data buffer, and pad it - * with zeroes. - */ - memcpy(input_buffer, buf, len); - memset(input_buffer + len, 0, buffer_size - len); /* - * Attempt to allocate the output buffer. + * Switch to the output buffer for dissection, and save it + * on the buffer stack so it can be freed; our caller must + * pop it when done. */ - output_buffer = (u_char *)malloc(buffer_size); - if (output_buffer == NULL) { - free(input_buffer); - EVP_CIPHER_CTX_free(ctx); - (*ndo->ndo_error)(ndo, "can't allocate memory for decryption buffer"); + if (!nd_push_buffer(ndo, pt, pt, pt + ctlen)) { + free(pt); + return 0; } - EVP_Cipher(ctx, output_buffer, input_buffer, len); - EVP_CIPHER_CTX_free(ctx); - - /* - * XXX - of course this is wrong, because buf is a const buffer, - * but changing this would require a more complicated fix. - */ - memcpy(buf, output_buffer, len); - free(input_buffer); - free(output_buffer); - - ndo->ndo_packetp = buf; - ndo->ndo_snapend = end; return 1; } @@ -284,9 +343,11 @@ static void esp_print_addsa(netdissect_options *ndo, struct sa_list *nsa; + /* malloc() return used in a 'struct sa_list': do not free() */ nsa = (struct sa_list *)malloc(sizeof(struct sa_list)); if (nsa == NULL) - (*ndo->ndo_error)(ndo, "ran out of memory to allocate sa structure"); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, + "%s: malloc", __func__); *nsa = *sa; @@ -307,7 +368,8 @@ static u_int hexdigit(netdissect_options *ndo, char hex) else if (hex >= 'a' && hex <= 'f') return (hex - 'a' + 10); else { - (*ndo->ndo_error)(ndo, "invalid hex digit %c in espsecret\n", hex); + (*ndo->ndo_error)(ndo, S_ERR_ND_ESP_SECRET, + "invalid hex digit %c in espsecret\n", hex); } } @@ -333,7 +395,7 @@ int espprint_decode_hex(netdissect_options *ndo, len = strlen(hex) / 2; if (len > binbuf_len) { - (*ndo->ndo_warning)(ndo, "secret is too big: %d\n", len); + (*ndo->ndo_warning)(ndo, "secret is too big: %u\n", len); return 0; } @@ -392,6 +454,7 @@ espprint_decode_encalgo(netdissect_options *ndo, sa->evp = evp; sa->authlen = authlen; + /* This returns an int, but it should never be negative */ sa->ivlen = EVP_CIPHER_iv_length(evp); colon++; @@ -434,8 +497,8 @@ espprint_decode_authalgo(netdissect_options *ndo, } *colon = '\0'; - if(ascii_strcasecmp(colon,"sha1") == 0 || - ascii_strcasecmp(colon,"md5") == 0) { + if(ascii_strcasecmp(decode,"sha1") == 0 || + ascii_strcasecmp(decode,"md5") == 0) { sa->authlen = 12; } return 1; @@ -539,8 +602,9 @@ static void esp_print_decode_onesecret(netdissect_options *ndo, char *line, secretfile = fopen(filename, FOPEN_READ_TXT); if (secretfile == NULL) { - (*ndo->ndo_error)(ndo, "print_esp: can't open %s: %s\n", - filename, strerror(errno)); + (*ndo->ndo_error)(ndo, S_ERR_ND_OPEN_FILE, + "%s: can't open %s: %s\n", + __func__, filename, strerror(errno)); } while (fgets(fileline, sizeof(fileline)-1, secretfile) != NULL) { @@ -595,7 +659,7 @@ static void esp_print_decode_onesecret(netdissect_options *ndo, char *line, if (decode) { /* skip any blank spaces */ - while (isspace((unsigned char)*decode)) + while (*decode == ' ' || *decode == '\t' || *decode == '\r' || *decode == '\n') decode++; if(!espprint_decode_encalgo(ndo, decode, &sa1)) { @@ -621,7 +685,7 @@ static void esp_init(netdissect_options *ndo _U_) } USES_APPLE_RST -void esp_print_decodesecret(netdissect_options *ndo) +void esp_decodesecret_print(netdissect_options *ndo) { char *line; char *p; @@ -649,119 +713,101 @@ void esp_print_decodesecret(netdissect_options *ndo) #endif +#ifdef HAVE_LIBCRYPTO +#define USED_IF_LIBCRYPTO +#else +#define USED_IF_LIBCRYPTO _U_ +#endif + #ifdef HAVE_LIBCRYPTO USES_APPLE_DEPRECATED_API #endif -int +void esp_print(netdissect_options *ndo, - const u_char *bp, const int length, const u_char *bp2 -#ifndef HAVE_LIBCRYPTO - _U_ -#endif - , - int *nhdr -#ifndef HAVE_LIBCRYPTO - _U_ -#endif - , - int *padlen -#ifndef HAVE_LIBCRYPTO - _U_ -#endif - ) + const u_char *bp, u_int length, + const u_char *bp2 USED_IF_LIBCRYPTO, + u_int ver USED_IF_LIBCRYPTO, + int fragmented USED_IF_LIBCRYPTO, + u_int ttl_hl USED_IF_LIBCRYPTO) { - register const struct newesp *esp; - register const u_char *ep; + const struct newesp *esp; + const u_char *ep; #ifdef HAVE_LIBCRYPTO const struct ip *ip; struct sa_list *sa = NULL; const struct ip6_hdr *ip6 = NULL; - int advance; - int len; - u_char *secret; - int ivlen = 0; - const u_char *ivoff; - const u_char *p; - EVP_CIPHER_CTX *ctx; - unsigned int block_size, buffer_size; - u_char *input_buffer, *output_buffer; + const u_char *iv; + u_int ivlen; + u_int payloadlen; + const u_char *ct; + u_char *pt; + u_int padlen; + u_int nh; #endif + ndo->ndo_protocol = "esp"; esp = (const struct newesp *)bp; -#ifdef HAVE_LIBCRYPTO - secret = NULL; - advance = 0; -#endif - -#if 0 - /* keep secret out of a register */ - p = (u_char *)&secret; -#endif - /* 'ep' points to the end of available data. */ ep = ndo->ndo_snapend; if ((const u_char *)(esp + 1) >= ep) { - ND_PRINT((ndo, "[|ESP]")); - goto fail; + nd_print_trunc(ndo); + return; } - ND_PRINT((ndo, "ESP(spi=0x%08x", EXTRACT_32BITS(&esp->esp_spi))); - ND_PRINT((ndo, ",seq=0x%x)", EXTRACT_32BITS(&esp->esp_seq))); - ND_PRINT((ndo, ", length %u", length)); + ND_PRINT("ESP(spi=0x%08x", GET_BE_U_4(esp->esp_spi)); + ND_PRINT(",seq=0x%x)", GET_BE_U_4(esp->esp_seq)); + ND_PRINT(", length %u", length); -#ifndef HAVE_LIBCRYPTO - goto fail; -#else +#ifdef HAVE_LIBCRYPTO /* initiailize SAs */ if (ndo->ndo_sa_list_head == NULL) { if (!ndo->ndo_espsecret) - goto fail; + return; - esp_print_decodesecret(ndo); + esp_decodesecret_print(ndo); } if (ndo->ndo_sa_list_head == NULL) - goto fail; + return; ip = (const struct ip *)bp2; - switch (IP_V(ip)) { + switch (ver) { case 6: ip6 = (const struct ip6_hdr *)bp2; /* we do not attempt to decrypt jumbograms */ - if (!EXTRACT_16BITS(&ip6->ip6_plen)) - goto fail; + if (!GET_BE_U_2(ip6->ip6_plen)) + return; + /* XXX - check whether it's fragmented? */ /* if we can't get nexthdr, we do not need to decrypt it */ - len = sizeof(struct ip6_hdr) + EXTRACT_16BITS(&ip6->ip6_plen); /* 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 == EXTRACT_32BITS(&esp->esp_spi) && + if (sa->spi == GET_BE_U_4(esp->esp_spi) && sa->daddr_version == 6 && UNALIGNED_MEMCMP(&sa->daddr.in6, &ip6->ip6_dst, - sizeof(struct in6_addr)) == 0) { + sizeof(nd_ipv6)) == 0) { break; } } break; case 4: /* nexthdr & padding are in the last fragment */ - if (EXTRACT_16BITS(&ip->ip_off) & IP_MF) - goto fail; - len = EXTRACT_16BITS(&ip->ip_len); + if (fragmented) + return; /* 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 == EXTRACT_32BITS(&esp->esp_spi) && + if (sa->spi == GET_BE_U_4(esp->esp_spi) && sa->daddr_version == 4 && UNALIGNED_MEMCMP(&sa->daddr.in4, &ip->ip_dst, - sizeof(struct in_addr)) == 0) { + sizeof(nd_ipv4)) == 0) { break; } } break; default: - goto fail; + return; } /* if we didn't find the specific one, then look for @@ -772,107 +818,107 @@ esp_print(netdissect_options *ndo, /* if not found fail */ if (sa == NULL) - goto fail; - - /* if we can't get nexthdr, we do not need to decrypt it */ - if (ep - bp2 < len) - goto fail; - if (ep - bp2 > len) { - /* FCS included at end of frame (NetBSD 1.6 or later) */ - ep = bp2 + len; - } + return; /* pointer to the IV, if there is one */ - ivoff = (const u_char *)(esp + 1) + 0; + iv = (const u_char *)(esp + 1) + 0; /* length of the IV, if there is one; 0, if there isn't */ ivlen = sa->ivlen; - secret = sa->secret; + + /* + * Get a pointer to the ciphertext. + * + * p points to the beginning of the payload, i.e. to the + * initialization vector, so if we skip past the initialization + * vector, it points to the beginning of the ciphertext. + */ + ct = iv + ivlen; + + /* + * Make sure the authentication data/integrity check value length + * isn't bigger than the total amount of data available after + * the ESP header and initialization vector is removed and, + * if not, slice the authentication data/ICV off. + */ + if (ep - ct < sa->authlen) { + nd_print_trunc(ndo); + return; + } ep = ep - sa->authlen; - if (sa->evp) { - ctx = EVP_CIPHER_CTX_new(); - if (ctx != NULL) { - if (set_cipher_parameters(ctx, sa->evp, secret, NULL, 0) < 0) - (*ndo->ndo_warning)(ndo, "espkey init failed"); - - p = ivoff; - set_cipher_parameters(ctx, NULL, NULL, p, 0); - len = ep - (p + ivlen); - - /* - * Allocate buffers for the encrypted and decrypted - * data. Both buffers' sizes must be a multiple of - * the cipher block size, and the output buffer must - * be separate from the input buffer. - */ - block_size = (unsigned int)EVP_CIPHER_CTX_block_size(ctx); - buffer_size = len + (block_size - len % block_size); - - /* - * Attempt to allocate the input buffer. - */ - input_buffer = (u_char *)malloc(buffer_size); - if (input_buffer == NULL) { - EVP_CIPHER_CTX_free(ctx); - (*ndo->ndo_error)(ndo, "can't allocate memory for encrypted data buffer"); - } - /* - * Copy the input data to the encrypted data buffer, - * and pad it with zeroes. - */ - memcpy(input_buffer, p + ivlen, len); - memset(input_buffer + len, 0, buffer_size - len); - - /* - * Attempt to allocate the output buffer. - */ - output_buffer = (u_char *)malloc(buffer_size); - if (output_buffer == NULL) { - free(input_buffer); - EVP_CIPHER_CTX_free(ctx); - (*ndo->ndo_error)(ndo, "can't allocate memory for decryption buffer"); - } + /* + * Calculate the length of the ciphertext. ep points to + * the beginning of the authentication data/integrity check + * value, i.e. right past the end of the ciphertext; + */ + payloadlen = ep - ct; - EVP_Cipher(ctx, output_buffer, input_buffer, len); - free(input_buffer); - EVP_CIPHER_CTX_free(ctx); - /* - * XXX - of course this is wrong, because buf is a - * const buffer, but changing this would require a - * more complicated fix. - */ - memcpy(p + ivlen, output_buffer, len); - free(output_buffer); - advance = ivoff - (const u_char *)esp + ivlen; - } else - advance = sizeof(struct newesp); - } else - advance = sizeof(struct newesp); + if (sa->evp == NULL) + return; + + /* + * If the next header value is past the end of the available + * data, we won't be able to fetch it once we've decrypted + * the ciphertext, so there's no point in decrypting the data. + * + * Report it as truncation. + */ + if (!ND_TTEST_1(ep - 1)) { + nd_print_trunc(ndo); + return; + } + + pt = do_decrypt(ndo, "esp_print", sa, iv, ct, payloadlen); + if (pt == NULL) + return; + + /* + * Switch to the output buffer for dissection, and + * save it on the buffer stack so it can be freed. + */ + ep = pt + payloadlen; + if (!nd_push_buffer(ndo, pt, pt, ep)) { + free(pt); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, + "%s: can't push buffer on buffer stack", __func__); + } - /* sanity check for pad length */ - if (ep - bp < *(ep - 2)) - goto fail; + /* + * Sanity check for pad length; if it, plus 2 for the pad + * length and next header fields, is bigger than the ciphertext + * length (which is also the plaintext length), it's too big. + * + * XXX - the check can fail if the packet is corrupt *or* if + * it was not decrypted with the correct key, so that the + * "plaintext" is not what was being sent. + */ + padlen = GET_U_1(ep - 2); + if (padlen + 2 > payloadlen) { + nd_print_trunc(ndo); + return; + } - if (padlen) - *padlen = *(ep - 2) + 2; + /* Get the next header */ + nh = GET_U_1(ep - 1); - if (nhdr) - *nhdr = *(ep - 1); + ND_PRINT(": "); - ND_PRINT((ndo, ": ")); - return advance; -#endif + /* + * Don't put padding + padding length(1 byte) + next header(1 byte) + * in the buffer because they are not part of the plaintext to decode. + */ + nd_push_snapend(ndo, ep - (padlen + 2)); -fail: - return -1; + /* Now dissect the plaintext. */ + ip_demux_print(ndo, pt, payloadlen - (padlen + 2), ver, fragmented, + ttl_hl, nh, bp2); + + /* Pop the buffer, freeing it. */ + nd_pop_packet_info(ndo); + /* Pop the nd_push_snapend */ + nd_pop_packet_info(ndo); +#endif } #ifdef HAVE_LIBCRYPTO USES_APPLE_RST #endif - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/print-ether.c b/contrib/tcpdump/print-ether.c index 01dd113038..da95862b3c 100644 --- a/contrib/tcpdump/print-ether.c +++ b/contrib/tcpdump/print-ether.c @@ -22,16 +22,32 @@ /* \summary: Ethernet printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" #include "addrtoname.h" #include "ethertype.h" -#include "ether.h" + +/* + * Structure of an Ethernet header. + */ +struct ether_header { + nd_mac_addr ether_dhost; + nd_mac_addr ether_shost; + nd_uint16_t ether_length_type; +}; + +/* + * Length of an Ethernet header; note that some compilers may pad + * "struct ether_header" to a multiple of 4 bytes, for example, so + * "sizeof (struct ether_header)" may not give the right answer. + */ +#define ETHER_HDRLEN 14 const struct tok ethertype_values[] = { { ETHERTYPE_IP, "IPv4" }, @@ -42,6 +58,7 @@ const struct tok ethertype_values[] = { { ETHERTYPE_8021Q9100, "802.1Q-9100" }, { ETHERTYPE_8021QinQ, "802.1Q-QinQ" }, { ETHERTYPE_8021Q9200, "802.1Q-9200" }, + { ETHERTYPE_MACSEC, "802.1AE MACsec" }, { ETHERTYPE_VMAN, "VMAN" }, { ETHERTYPE_PUP, "PUP" }, { ETHERTYPE_ARP, "ARP"}, @@ -72,6 +89,7 @@ const struct tok ethertype_values[] = { { ETHERTYPE_RRCP, "RRCP" }, { ETHERTYPE_MS_NLB_HB, "MS NLB heartbeat" }, { ETHERTYPE_JUMBO, "Jumbo" }, + { ETHERTYPE_NSH, "NSH" }, { ETHERTYPE_LOOPBACK, "Loopback" }, { ETHERTYPE_ISO, "OSI" }, { ETHERTYPE_GRE_ISO, "GRE-OSI" }, @@ -84,141 +102,235 @@ const struct tok ethertype_values[] = { { ETHERTYPE_GEONET, "GeoNet"}, { ETHERTYPE_CALM_FAST, "CALM FAST"}, { ETHERTYPE_AOE, "AoE" }, - { ETHERTYPE_MEDSA, "MEDSA" }, + { ETHERTYPE_PTP, "PTP" }, + { ETHERTYPE_ARISTA, "Arista Vendor Specific Protocol" }, { 0, NULL} }; -static inline void -ether_hdr_print(netdissect_options *ndo, - const u_char *bp, u_int length) +static void +ether_addresses_print(netdissect_options *ndo, const u_char *src, + const u_char *dst) { - register const struct ether_header *ep; - uint16_t length_type; - - ep = (const struct ether_header *)bp; - - ND_PRINT((ndo, "%s > %s", - etheraddr_string(ndo, ESRC(ep)), - etheraddr_string(ndo, EDST(ep)))); - - length_type = EXTRACT_16BITS(&ep->ether_length_type); - if (!ndo->ndo_qflag) { - if (length_type <= ETHERMTU) { - ND_PRINT((ndo, ", 802.3")); - length = length_type; - } else - ND_PRINT((ndo, ", ethertype %s (0x%04x)", - tok2str(ethertype_values,"Unknown", length_type), - length_type)); - } else { - if (length_type <= ETHERMTU) { - ND_PRINT((ndo, ", 802.3")); - length = length_type; - } else - ND_PRINT((ndo, ", %s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", length_type))); - } + ND_PRINT("%s > %s, ", + GET_ETHERADDR_STRING(src), GET_ETHERADDR_STRING(dst)); +} - ND_PRINT((ndo, ", length %u: ", length)); +static void +ether_type_print(netdissect_options *ndo, uint16_t type) +{ + if (!ndo->ndo_qflag) + ND_PRINT("ethertype %s (0x%04x)", + tok2str(ethertype_values, "Unknown", type), type); + else + ND_PRINT("%s", + tok2str(ethertype_values, "Unknown Ethertype (0x%04x)", type)); } /* - * 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. + * Common code for printing Ethernet frames. * - * FIXME: caplen can and should be derived from ndo->ndo_snapend and p. + * It can handle Ethernet headers with extra tag information inserted + * after the destination and source addresses, as is inserted by some + * switch chips, and extra encapsulation header information before + * printing Ethernet header information (such as a LANE ID for ATM LANE). */ -u_int -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) +static u_int +ether_common_print(netdissect_options *ndo, const u_char *p, u_int length, + u_int caplen, + void (*print_switch_tag)(netdissect_options *ndo, const u_char *), + u_int switch_tag_len, + void (*print_encap_header)(netdissect_options *ndo, const u_char *), + const u_char *encap_header_arg) { - const struct ether_header *ep; + const struct ether_header *ehp; u_int orig_length; - u_short length_type; u_int hdrlen; + u_short length_type; + int printed_length; int llc_hdrlen; struct lladdr_info src, dst; - if (caplen < ETHER_HDRLEN) { - ND_PRINT((ndo, "[|ether]")); - return (caplen); + if (caplen < ETHER_HDRLEN + switch_tag_len) { + nd_print_trunc(ndo); + return caplen; } - if (length < ETHER_HDRLEN) { - ND_PRINT((ndo, "[|ether]")); - return (length); + if (length < ETHER_HDRLEN + switch_tag_len) { + nd_print_trunc(ndo); + return 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; + if (print_encap_header != NULL) + (*print_encap_header)(ndo, encap_header_arg); - length -= ETHER_HDRLEN; - caplen -= ETHER_HDRLEN; - ep = (const struct ether_header *)p; - p += ETHER_HDRLEN; - hdrlen = ETHER_HDRLEN; + orig_length = length; - src.addr = ESRC(ep); + /* + * Get the source and destination addresses, skip past them, + * and print them if we're printing the link-layer header. + */ + ehp = (const struct ether_header *)p; + src.addr = ehp->ether_shost; src.addr_string = etheraddr_string; - dst.addr = EDST(ep); + dst.addr = ehp->ether_dhost; dst.addr_string = etheraddr_string; - length_type = EXTRACT_16BITS(&ep->ether_length_type); + length -= 2*MAC_ADDR_LEN; + caplen -= 2*MAC_ADDR_LEN; + p += 2*MAC_ADDR_LEN; + hdrlen = 2*MAC_ADDR_LEN; + + if (ndo->ndo_eflag) + ether_addresses_print(ndo, src.addr, dst.addr); + + /* + * Print the switch tag, if we have one, and skip past it. + */ + if (print_switch_tag != NULL) + (*print_switch_tag)(ndo, p); + + length -= switch_tag_len; + caplen -= switch_tag_len; + p += switch_tag_len; + hdrlen += switch_tag_len; + + /* + * Get the length/type field, skip past it, and print it + * if we're printing the link-layer header. + */ recurse: + length_type = GET_BE_U_2(p); + + length -= 2; + caplen -= 2; + p += 2; + hdrlen += 2; + /* - * Is it (gag) an 802.3 encapsulation? + * Process 802.1AE MACsec headers. */ - if (length_type <= ETHERMTU) { - /* Try to print the LLC-layer header & higher layers */ - llc_hdrlen = llc_print(ndo, p, length, caplen, &src, &dst); - if (llc_hdrlen < 0) { - /* packet type not known, print raw packet */ + printed_length = 0; + if (length_type == ETHERTYPE_MACSEC) { + /* + * MACsec, aka IEEE 802.1AE-2006 + * Print the header, and try to print the payload if it's not encrypted + */ + if (ndo->ndo_eflag) { + ether_type_print(ndo, length_type); + ND_PRINT(", length %u: ", orig_length); + printed_length = 1; + } + + int ret = macsec_print(ndo, &p, &length, &caplen, &hdrlen, + &src, &dst); + + if (ret == 0) { + /* Payload is encrypted; print it as raw data. */ if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); - llc_hdrlen = -llc_hdrlen; + return hdrlen; + } else if (ret > 0) { + /* Problem printing the header; just quit. */ + return ret; + } else { + /* + * Keep processing type/length fields. + */ + length_type = GET_BE_U_2(p); + + length -= 2; + caplen -= 2; + p += 2; + hdrlen += 2; } - hdrlen += llc_hdrlen; - } else if (length_type == ETHERTYPE_8021Q || - length_type == ETHERTYPE_8021Q9100 || - length_type == ETHERTYPE_8021Q9200 || - length_type == ETHERTYPE_8021QinQ) { + } + + /* + * Process VLAN tag types. + */ + while (length_type == ETHERTYPE_8021Q || + length_type == ETHERTYPE_8021Q9100 || + length_type == ETHERTYPE_8021Q9200 || + length_type == ETHERTYPE_8021QinQ) { /* + * It has a VLAN tag. * Print VLAN information, and then go back and process * the enclosed type field. */ if (caplen < 4) { - ND_PRINT((ndo, "[|vlan]")); - return (hdrlen + caplen); + ndo->ndo_protocol = "vlan"; + nd_print_trunc(ndo); + return hdrlen + caplen; } if (length < 4) { - ND_PRINT((ndo, "[|vlan]")); - return (hdrlen + length); + ndo->ndo_protocol = "vlan"; + nd_print_trunc(ndo); + return hdrlen + length; } - if (ndo->ndo_eflag) { - uint16_t tag = EXTRACT_16BITS(p); - - ND_PRINT((ndo, "%s, ", ieee8021q_tci_string(tag))); + if (ndo->ndo_eflag) { + uint16_t tag = GET_BE_U_2(p); + + ether_type_print(ndo, length_type); + if (!printed_length) { + ND_PRINT(", length %u: ", orig_length); + printed_length = 1; + } else + ND_PRINT(", "); + ND_PRINT("%s, ", ieee8021q_tci_string(tag)); } - length_type = EXTRACT_16BITS(p + 2); - if (ndo->ndo_eflag && length_type > ETHERMTU) - ND_PRINT((ndo, "ethertype %s, ", tok2str(ethertype_values,"0x%04x", length_type))); + length_type = GET_BE_U_2(p + 2); p += 4; length -= 4; caplen -= 4; hdrlen += 4; - goto recurse; + } + + /* + * We now have the final length/type field. + */ + if (length_type <= MAX_ETHERNET_LENGTH_VAL) { + /* + * It's a length field, containing the length of the + * remaining payload; use it as such, as long as + * it's not too large (bigger than the actual payload). + */ + if (length_type < length) { + length = length_type; + if (caplen > length) + caplen = length; + } + + /* + * Cut off the snapshot length to the end of the + * payload. + */ + nd_push_snapend(ndo, p + length); + + if (ndo->ndo_eflag) { + ND_PRINT("802.3"); + if (!printed_length) + ND_PRINT(", length %u: ", length); + } + + /* + * An LLC header follows the length. Print that and + * higher layers. + */ + llc_hdrlen = llc_print(ndo, p, length, caplen, &src, &dst); + if (llc_hdrlen < 0) { + /* packet type not known, print raw packet */ + if (!ndo->ndo_suppress_default_print) + ND_DEFAULTPRINT(p, caplen); + llc_hdrlen = -llc_hdrlen; + } + hdrlen += llc_hdrlen; + nd_pop_packet_info(ndo); } else if (length_type == ETHERTYPE_JUMBO) { /* - * Alteon jumbo frames. + * It's a type field, with the type for Alteon jumbo frames. * See * - * http://tools.ietf.org/html/draft-ietf-isis-ext-eth-01 + * https://tools.ietf.org/html/draft-ietf-isis-ext-eth-01 * * which indicates that, following the type field, * there's an LLC header and payload. @@ -232,20 +344,103 @@ recurse: llc_hdrlen = -llc_hdrlen; } hdrlen += llc_hdrlen; + } else if (length_type == ETHERTYPE_ARISTA) { + if (caplen < 2) { + ND_PRINT("[|arista]"); + return hdrlen + caplen; + } + if (length < 2) { + ND_PRINT("[|arista]"); + return hdrlen + length; + } + ether_type_print(ndo, length_type); + ND_PRINT(", length %u: ", orig_length); + int bytesConsumed = arista_ethertype_print(ndo, p, length); + if (bytesConsumed > 0) { + p += bytesConsumed; + length -= bytesConsumed; + caplen -= bytesConsumed; + hdrlen += bytesConsumed; + goto recurse; + } else { + /* subtype/version not known, print raw packet */ + if (!ndo->ndo_eflag && length_type > MAX_ETHERNET_LENGTH_VAL) { + ether_addresses_print(ndo, src.addr, dst.addr); + ether_type_print(ndo, length_type); + ND_PRINT(", length %u: ", orig_length); + } + if (!ndo->ndo_suppress_default_print) + ND_DEFAULTPRINT(p, caplen); + } } else { + /* + * It's a type field with some other value. + */ + if (ndo->ndo_eflag) { + ether_type_print(ndo, length_type); + if (!printed_length) + ND_PRINT(", length %u: ", orig_length); + else + ND_PRINT(", "); + } if (ethertype_print(ndo, length_type, p, length, caplen, &src, &dst) == 0) { /* 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, (const u_char *)ep, orig_length); + /* + * We didn't print the full link-layer + * header, as -e wasn't specified, so + * print only the source and destination + * MAC addresses and the final Ethernet + * type. + */ + ether_addresses_print(ndo, src.addr, dst.addr); + ether_type_print(ndo, length_type); + ND_PRINT(", length %u: ", orig_length); } if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); } } - return (hdrlen); + return hdrlen; +} + +/* + * Print an Ethernet frame while specyfing a non-standard Ethernet header + * length. + * 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. + * + * FIXME: caplen can and should be derived from ndo->ndo_snapend and p. + */ +u_int +ether_switch_tag_print(netdissect_options *ndo, const u_char *p, u_int length, + u_int caplen, + void (*print_switch_tag)(netdissect_options *, const u_char *), + u_int switch_tag_len) +{ + return ether_common_print(ndo, p, length, caplen, print_switch_tag, + switch_tag_len, NULL, NULL); +} + +/* + * 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. + * + * FIXME: caplen can and should be derived from ndo->ndo_snapend and p. + */ +u_int +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) +{ + ndo->ndo_protocol = "ether"; + return ether_common_print(ndo, p, length, caplen, NULL, 0, + print_encap_header, encap_header_arg); } /* @@ -254,11 +449,13 @@ recurse: * of the packet off the wire, and 'h->caplen' is the number * of bytes actually captured. */ -u_int +void ether_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, - const u_char *p) + const u_char *p) { - return (ether_print(ndo, p, h->len, h->caplen, NULL, NULL)); + ndo->ndo_protocol = "ether"; + ndo->ndo_ll_hdr_len += + ether_print(ndo, p, h->len, h->caplen, NULL, NULL); } /* @@ -270,20 +467,20 @@ ether_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, * This is for DLT_NETANALYZER, which has a 4-byte pseudo-header * before the Ethernet header. */ -u_int +void netanalyzer_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, - const u_char *p) + const u_char *p) { /* * Fail if we don't have enough data for the Hilscher pseudo-header. */ - if (h->len < 4 || h->caplen < 4) { - ND_PRINT((ndo, "[|netanalyzer]")); - return (h->caplen); - } + ndo->ndo_protocol = "netanalyzer"; + ND_TCHECK_LEN(p, 4); /* Skip the pseudo-header. */ - return (4 + ether_print(ndo, p + 4, h->len - 4, h->caplen - 4, NULL, NULL)); + ndo->ndo_ll_hdr_len += 4; + ndo->ndo_ll_hdr_len += + ether_print(ndo, p + 4, h->len - 4, h->caplen - 4, NULL, NULL); } /* @@ -296,22 +493,22 @@ netanalyzer_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, * pseudo-header, a 7-byte Ethernet preamble, and a 1-byte Ethernet SOF * before the Ethernet header. */ -u_int +void netanalyzer_transparent_if_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, - const u_char *p) + 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) { - ND_PRINT((ndo, "[|netanalyzer-transparent]")); - return (h->caplen); - } + ndo->ndo_protocol = "netanalyzer_transparent"; + ND_TCHECK_LEN(p, 12); /* Skip the pseudo-header, preamble, and SOF. */ - return (12 + ether_print(ndo, p + 12, h->len - 12, h->caplen - 12, NULL, NULL)); + ndo->ndo_ll_hdr_len += 12; + ndo->ndo_ll_hdr_len += + ether_print(ndo, p + 12, h->len - 12, h->caplen - 12, NULL, NULL); } /* @@ -323,14 +520,14 @@ netanalyzer_transparent_if_print(netdissect_options *ndo, int ethertype_print(netdissect_options *ndo, - u_short ether_type, const u_char *p, - u_int length, u_int caplen, - const struct lladdr_info *src, const struct lladdr_info *dst) + u_short ether_type, const u_char *p, + u_int length, u_int caplen, + const struct lladdr_info *src, const struct lladdr_info *dst) { switch (ether_type) { case ETHERTYPE_IP: - ip_print(ndo, p, length); + ip_print(ndo, p, length); return (1); case ETHERTYPE_IPV6: @@ -339,7 +536,7 @@ ethertype_print(netdissect_options *ndo, case ETHERTYPE_ARP: case ETHERTYPE_REVARP: - arp_print(ndo, p, length, caplen); + arp_print(ndo, p, length, caplen); return (1); case ETHERTYPE_DN: @@ -348,7 +545,7 @@ ethertype_print(netdissect_options *ndo, case ETHERTYPE_ATALK: if (ndo->ndo_vflag) - ND_PRINT((ndo, "et1 ")); + ND_PRINT("et1 "); atalk_print(ndo, p, length); return (1); @@ -357,15 +554,19 @@ ethertype_print(netdissect_options *ndo, return (1); case ETHERTYPE_IPX: - ND_PRINT((ndo, "(NOV-ETHII) ")); + ND_PRINT("(NOV-ETHII) "); ipx_print(ndo, p, length); return (1); case ETHERTYPE_ISO: if (length == 0 || caplen == 0) { - ND_PRINT((ndo, " [|osi]")); + ndo->ndo_protocol = "isoclns"; + nd_print_trunc(ndo); return (1); } + /* At least one byte is required */ + /* FIXME: Reference for this byte? */ + ND_TCHECK_LEN(p, 1); isoclns_print(ndo, p + 1, length - 1); return(1); @@ -377,26 +578,26 @@ ethertype_print(netdissect_options *ndo, return (1); case ETHERTYPE_EAPOL: - eap_print(ndo, p, length); + eapol_print(ndo, p); return (1); case ETHERTYPE_RRCP: - rrcp_print(ndo, p, length, src, dst); + rrcp_print(ndo, p, length, src, dst); return (1); case ETHERTYPE_PPP: if (length) { - ND_PRINT((ndo, ": ")); + ND_PRINT(": "); ppp_print(ndo, p, length); } return (1); case ETHERTYPE_MPCP: - mpcp_print(ndo, p, length); + mpcp_print(ndo, p, length); return (1); case ETHERTYPE_SLOW: - slow_print(ndo, p, length); + slow_print(ndo, p, length); return (1); case ETHERTYPE_CFM: @@ -408,9 +609,13 @@ ethertype_print(netdissect_options *ndo, lldp_print(ndo, p, length); return (1); - case ETHERTYPE_LOOPBACK: + case ETHERTYPE_NSH: + nsh_print(ndo, p, length); + return (1); + + case ETHERTYPE_LOOPBACK: loopback_print(ndo, p, length); - return (1); + return (1); case ETHERTYPE_MPLS: case ETHERTYPE_MPLS_MULTI: @@ -425,21 +630,21 @@ ethertype_print(netdissect_options *ndo, msnlb_print(ndo, p); return (1); - case ETHERTYPE_GEONET_OLD: - case ETHERTYPE_GEONET: - geonet_print(ndo, p, length, src); - return (1); + case ETHERTYPE_GEONET_OLD: + case ETHERTYPE_GEONET: + geonet_print(ndo, p, length, src); + return (1); - case ETHERTYPE_CALM_FAST: - calm_fast_print(ndo, p, length, src); - return (1); + case ETHERTYPE_CALM_FAST: + calm_fast_print(ndo, p, length, src); + return (1); case ETHERTYPE_AOE: aoe_print(ndo, p, length); return (1); - case ETHERTYPE_MEDSA: - medsa_print(ndo, p, length, caplen, src, dst); + case ETHERTYPE_PTP: + ptp_print(ndo, p, length); return (1); case ETHERTYPE_LAT: @@ -452,12 +657,3 @@ ethertype_print(netdissect_options *ndo, return (0); } } - - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ - diff --git a/contrib/tcpdump/print-fddi.c b/contrib/tcpdump/print-fddi.c index 27803783b7..fb8d3ed57c 100644 --- a/contrib/tcpdump/print-fddi.c +++ b/contrib/tcpdump/print-fddi.c @@ -22,25 +22,25 @@ /* \summary: Fiber Distributed Data Interface (FDDI) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include #include "netdissect.h" +#include "extract.h" #include "addrtoname.h" -#include "ether.h" /* * Based on Ultrix if_fddi.h */ struct fddi_header { - u_char fddi_fc; /* frame control */ - u_char fddi_dhost[6]; - u_char fddi_shost[6]; + nd_uint8_t fddi_fc; /* frame control */ + nd_mac_addr fddi_dhost; + nd_mac_addr fddi_shost; }; /* @@ -158,78 +158,78 @@ static const u_char fddi_bit_swap[] = { /* * Print FDDI frame-control bits */ -static inline void +static void print_fddi_fc(netdissect_options *ndo, u_char fc) { switch (fc) { case FDDIFC_VOID: /* Void frame */ - ND_PRINT((ndo, "void ")); + ND_PRINT("void "); break; case FDDIFC_NRT: /* Nonrestricted token */ - ND_PRINT((ndo, "nrt ")); + ND_PRINT("nrt "); break; case FDDIFC_RT: /* Restricted token */ - ND_PRINT((ndo, "rt ")); + ND_PRINT("rt "); break; case FDDIFC_SMT_INFO: /* SMT Info */ - ND_PRINT((ndo, "info ")); + ND_PRINT("info "); break; case FDDIFC_SMT_NSA: /* SMT Next station adrs */ - ND_PRINT((ndo, "nsa ")); + ND_PRINT("nsa "); break; case FDDIFC_MAC_BEACON: /* MAC Beacon frame */ - ND_PRINT((ndo, "beacon ")); + ND_PRINT("beacon "); break; case FDDIFC_MAC_CLAIM: /* MAC Claim frame */ - ND_PRINT((ndo, "claim ")); + ND_PRINT("claim "); break; default: switch (fc & FDDIFC_CLFF) { case FDDIFC_MAC: - ND_PRINT((ndo, "mac%1x ", fc & FDDIFC_ZZZZ)); + ND_PRINT("mac%1x ", fc & FDDIFC_ZZZZ); break; case FDDIFC_SMT: - ND_PRINT((ndo, "smt%1x ", fc & FDDIFC_ZZZZ)); + ND_PRINT("smt%1x ", fc & FDDIFC_ZZZZ); break; case FDDIFC_LLC_ASYNC: - ND_PRINT((ndo, "async%1x ", fc & FDDIFC_ZZZZ)); + ND_PRINT("async%1x ", fc & FDDIFC_ZZZZ); break; case FDDIFC_LLC_SYNC: - ND_PRINT((ndo, "sync%1x ", fc & FDDIFC_ZZZZ)); + ND_PRINT("sync%1x ", fc & FDDIFC_ZZZZ); break; case FDDIFC_IMP_ASYNC: - ND_PRINT((ndo, "imp_async%1x ", fc & FDDIFC_ZZZZ)); + ND_PRINT("imp_async%1x ", fc & FDDIFC_ZZZZ); break; case FDDIFC_IMP_SYNC: - ND_PRINT((ndo, "imp_sync%1x ", fc & FDDIFC_ZZZZ)); + ND_PRINT("imp_sync%1x ", fc & FDDIFC_ZZZZ); break; default: - ND_PRINT((ndo, "%02x ", fc)); + ND_PRINT("%02x ", fc); break; } } } /* Extract src, dst addresses */ -static inline void +static void extract_fddi_addrs(const struct fddi_header *fddip, char *fsrc, char *fdst) { - register int i; + int i; if (fddi_bitswap) { /* @@ -250,10 +250,10 @@ extract_fddi_addrs(const struct fddi_header *fddip, char *fsrc, char *fdst) /* * Print the FDDI MAC header */ -static inline void +static void fddi_hdr_print(netdissect_options *ndo, - register const struct fddi_header *fddip, register u_int length, - register const u_char *fsrc, register const u_char *fdst) + const struct fddi_header *fddip, u_int length, + const u_char *fsrc, const u_char *fdst) { const char *srcname, *dstname; @@ -261,42 +261,46 @@ fddi_hdr_print(netdissect_options *ndo, dstname = etheraddr_string(ndo, fdst); if (!ndo->ndo_qflag) - print_fddi_fc(ndo, fddip->fddi_fc); - ND_PRINT((ndo, "%s > %s, length %u: ", + print_fddi_fc(ndo, GET_U_1(fddip->fddi_fc)); + ND_PRINT("%s > %s, length %u: ", srcname, dstname, - length)); + length); } -static inline void +static void fddi_smt_print(netdissect_options *ndo, const u_char *p _U_, u_int length _U_) { - ND_PRINT((ndo, "")); + ND_PRINT(""); } u_int fddi_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen) { const struct fddi_header *fddip = (const struct fddi_header *)p; - struct ether_header ehdr; + uint8_t fc; + nd_mac_addr srcmac, dstmac; struct lladdr_info src, dst; int llc_hdrlen; + ndo->ndo_protocol = "fddi"; if (caplen < FDDI_HDRLEN) { - ND_PRINT((ndo, "[|fddi]")); + nd_print_trunc(ndo); return (caplen); } + fc = GET_U_1(fddip->fddi_fc); + /* * Get the FDDI addresses into a canonical form */ - extract_fddi_addrs(fddip, (char *)ESRC(&ehdr), (char *)EDST(&ehdr)); + extract_fddi_addrs(fddip, (char *)srcmac, (char *)dstmac); if (ndo->ndo_eflag) - fddi_hdr_print(ndo, fddip, length, ESRC(&ehdr), EDST(&ehdr)); + fddi_hdr_print(ndo, fddip, length, srcmac, dstmac); - src.addr = ESRC(&ehdr); + src.addr = srcmac; src.addr_string = etheraddr_string; - dst.addr = EDST(&ehdr); + dst.addr = dstmac; dst.addr_string = etheraddr_string; /* Skip over FDDI MAC header */ @@ -305,7 +309,7 @@ fddi_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen) caplen -= FDDI_HDRLEN; /* Frame Control field determines interpretation of packet */ - if ((fddip->fddi_fc & FDDIFC_CLFF) == FDDIFC_LLC_ASYNC) { + if ((fc & FDDIFC_CLFF) == FDDIFC_LLC_ASYNC) { /* Try to print the LLC-layer header & higher layers */ llc_hdrlen = llc_print(ndo, p, length, caplen, &src, &dst); if (llc_hdrlen < 0) { @@ -317,14 +321,14 @@ fddi_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen) ND_DEFAULTPRINT(p, caplen); llc_hdrlen = -llc_hdrlen; } - } else if ((fddip->fddi_fc & FDDIFC_CLFF) == FDDIFC_SMT) { + } else if ((fc & FDDIFC_CLFF) == FDDIFC_SMT) { fddi_smt_print(ndo, p, caplen); llc_hdrlen = 0; } else { /* Some kinds of FDDI packet we cannot handle intelligently */ if (!ndo->ndo_eflag) - fddi_hdr_print(ndo, fddip, length + FDDI_HDRLEN, ESRC(&ehdr), - EDST(&ehdr)); + fddi_hdr_print(ndo, fddip, length + FDDI_HDRLEN, srcmac, + dstmac); if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); llc_hdrlen = 0; @@ -338,8 +342,9 @@ fddi_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen) * 'h->len' is the length of the packet off the wire, and 'h->caplen' * is the number of bytes actually captured. */ -u_int -fddi_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, register const u_char *p) +void +fddi_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { - return (fddi_print(ndo, p, h->len, h->caplen)); + ndo->ndo_protocol = "fddi"; + ndo->ndo_ll_hdr_len += fddi_print(ndo, p, h->len, h->caplen); } diff --git a/contrib/tcpdump/print-forces.c b/contrib/tcpdump/print-forces.c index de6c8264dd..e6b52d6b27 100644 --- a/contrib/tcpdump/print-forces.c +++ b/contrib/tcpdump/print-forces.c @@ -19,15 +19,14 @@ /* specification: RFC 5810 */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "extract.h" -static const char tstr[] = "[|forces]"; #define ForCES_VERS 1 #define ForCES_HDRL 24 @@ -66,7 +65,7 @@ struct tom_h { uint16_t flags; uint16_t op_msk; const char *s; - int (*print) (netdissect_options *ndo, register const u_char * pptr, register u_int len, + int (*print) (netdissect_options *ndo, const u_char * pptr, u_int len, uint16_t op_msk, int indent); }; @@ -86,7 +85,8 @@ enum { }; #define TOM_MAX_IND (_TOM_RSV_MAX - 1) -static inline int tom_valid(uint8_t tom) +static int +tom_valid(uint8_t tom) { if (tom > 0) { if (tom >= 0x7 && tom <= 0xe) @@ -100,7 +100,8 @@ static inline int tom_valid(uint8_t tom) return 0; } -static inline const char *ForCES_node(uint32_t node) +static const char * +ForCES_node(uint32_t node) { if (node <= 0x3FFFFFFF) return "FE"; @@ -154,23 +155,23 @@ static const struct tok ForCES_TPs[] = { */ struct forcesh { nd_uint8_t fm_vrsvd; /* version and reserved */ -#define ForCES_V(forcesh) ((forcesh)->fm_vrsvd >> 4) +#define ForCES_V(forcesh) (GET_U_1((forcesh)->fm_vrsvd) >> 4) nd_uint8_t fm_tom; /* type of message */ nd_uint16_t fm_len; /* total length * 4 bytes */ -#define ForCES_BLN(forcesh) ((uint32_t)(EXTRACT_16BITS(&(forcesh)->fm_len) << 2)) +#define ForCES_BLN(forcesh) ((uint32_t)(GET_BE_U_2((forcesh)->fm_len) << 2)) nd_uint32_t fm_sid; /* Source ID */ -#define ForCES_SID(forcesh) EXTRACT_32BITS(&(forcesh)->fm_sid) +#define ForCES_SID(forcesh) GET_BE_U_4((forcesh)->fm_sid) nd_uint32_t fm_did; /* Destination ID */ -#define ForCES_DID(forcesh) EXTRACT_32BITS(&(forcesh)->fm_did) +#define ForCES_DID(forcesh) GET_BE_U_4((forcesh)->fm_did) nd_uint8_t fm_cor[8]; /* correlator */ nd_uint32_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_ACK(forcesh) ((GET_BE_U_4((forcesh)->fm_flags)&0xC0000000) >> 30) +#define ForCES_PRI(forcesh) ((GET_BE_U_4((forcesh)->fm_flags)&0x38000000) >> 27) +#define ForCES_RS1(forcesh) ((GET_BE_U_4((forcesh)->fm_flags)&0x07000000) >> 24) +#define ForCES_EM(forcesh) ((GET_BE_U_4((forcesh)->fm_flags)&0x00C00000) >> 22) +#define ForCES_AT(forcesh) ((GET_BE_U_4((forcesh)->fm_flags)&0x00200000) >> 21) +#define ForCES_TP(forcesh) ((GET_BE_U_4((forcesh)->fm_flags)&0x00180000) >> 19) +#define ForCES_RS2(forcesh) ((GET_BE_U_4((forcesh)->fm_flags)&0x0007FFFF) >> 0) }; #define ForCES_HLN_VALID(fhl,tlen) ((tlen) >= ForCES_HDRL && \ @@ -188,7 +189,7 @@ static const struct tok ForCES_LFBs[] = { }; /* this is defined in RFC5810 section A.2 */ -/* http://www.iana.org/assignments/forces/forces.xhtml#oper-tlv-types */ +/* https://www.iana.org/assignments/forces/forces.xhtml#oper-tlv-types */ enum { F_OP_RSV = 0, F_OP_SET = 1, @@ -230,15 +231,15 @@ struct optlv_h { uint16_t flags; uint16_t op_msk; const char *s; - int (*print) (netdissect_options *ndo, register const u_char * pptr, register u_int len, + int (*print) (netdissect_options *ndo, const u_char * pptr, u_int len, uint16_t op_msk, int indent); }; -static int genoptlv_print(netdissect_options *, register const u_char * pptr, register u_int len, +static int genoptlv_print(netdissect_options *, const u_char * pptr, u_int len, uint16_t op_msk, int indent); -static int recpdoptlv_print(netdissect_options *, register const u_char * pptr, register u_int len, +static int recpdoptlv_print(netdissect_options *, const u_char * pptr, u_int len, uint16_t op_msk, int indent); -static int invoptlv_print(netdissect_options *, register const u_char * pptr, register u_int len, +static int invoptlv_print(netdissect_options *, const u_char * pptr, u_int len, uint16_t op_msk, int indent); #define OP_MIN_SIZ 8 @@ -276,9 +277,10 @@ static const struct optlv_h OPTLV_msg[F_OP_MAX + 1] = { /* F_OP_RTRCOMP */ {ZERO_TTLV, 0, " RTRCOMP", NULL}, }; -static inline const struct optlv_h *get_forces_optlv_h(uint16_t opt) +static const struct optlv_h * +get_forces_optlv_h(uint16_t opt) { - if (opt > F_OP_MAX || opt <= F_OP_RSV) + if (opt > F_OP_MAX || opt == F_OP_RSV) return &OPTLV_msg[F_OP_RSV]; return &OPTLV_msg[opt]; @@ -290,7 +292,8 @@ static inline const struct optlv_h *get_forces_optlv_h(uint16_t opt) #define IND_SUF 0x0 static char ind_buf[IND_SIZE]; -static inline char *indent_pr(int indent, int nlpref) +static char * +indent_pr(int indent, int nlpref) { int i = 0; char *r = ind_buf; @@ -311,14 +314,13 @@ static inline char *indent_pr(int indent, int nlpref) return r; } -static inline int op_valid(uint16_t op, uint16_t mask) +static int +op_valid(uint16_t op, uint16_t mask) { - int opb = 1 << (op - 1); - if (op == 0) return 0; - if (opb & mask) - return 1; + if (op <= F_OP_MAX) + return (1 << (op - 1)) & mask; /* works only for 0x0001 through 0x0010 */ /* I guess we should allow vendor operations? */ if (op >= 0x8000) return 1; @@ -359,7 +361,8 @@ static const struct tok ForCES_TLV[] = { }; #define TLV_HLN 4 -static inline int ttlv_valid(uint16_t ttlv) +static int +ttlv_valid(uint16_t ttlv) { if (ttlv > 0) { if (ttlv == 1 || ttlv == 0x1000) @@ -385,22 +388,18 @@ struct forces_tlv { nd_uint16_t length; }; -#define F_ALN_LEN(len) ( ((len)+ForCES_ALNL-1) & ~(ForCES_ALNL-1) ) +#define F_ALN_LEN(len) roundup2(len, ForCES_ALNL) #define GET_TOP_TLV(fhdr) ((const 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) ((const void*)(((const char*)(tlvp)) + TLV_SET_LEN(0))) -#define GO_NXT_TLV(tlv,rlen) ((rlen) -= F_ALN_LEN(EXTRACT_16BITS(&(tlv)->length)), \ +#define GO_NXT_TLV(tlv,rlen) ((rlen) -= F_ALN_LEN(GET_BE_U_2((tlv)->length)), \ (const struct forces_tlv*)(((const char*)(tlv)) \ - + F_ALN_LEN(EXTRACT_16BITS(&(tlv)->length)))) + + F_ALN_LEN(GET_BE_U_2((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) ((const void*)(((const char*)(ilvp)) + ILV_SET_LEN(0))) -#define GO_NXT_ILV(ilv,rlen) ((rlen) -= F_ALN_LEN(EXTRACT_32BITS(&(ilv)->length)), \ +#define GO_NXT_ILV(ilv,rlen) ((rlen) -= F_ALN_LEN(GET_BE_U_4((ilv)->length)), \ (const struct forces_ilv *)(((const char*)(ilv)) \ - + F_ALN_LEN(EXTRACT_32BITS(&(ilv)->length)))) + + F_ALN_LEN(GET_BE_U_4((ilv)->length)))) #define INVALID_RLEN 1 #define INVALID_STLN 2 #define INVALID_LTLN 3 @@ -414,41 +413,43 @@ static const struct tok ForCES_TLV_err[] = { {0, NULL} }; -static inline u_int tlv_valid(const struct forces_tlv *tlv, u_int rlen) +static u_int +tlv_valid(u_int tlvl, u_int rlen) { if (rlen < TLV_HDRL) return INVALID_RLEN; - if (EXTRACT_16BITS(&tlv->length) < TLV_HDRL) + if (tlvl < TLV_HDRL) return INVALID_STLN; - if (EXTRACT_16BITS(&tlv->length) > rlen) + if (tlvl > rlen) return INVALID_LTLN; - if (rlen < F_ALN_LEN(EXTRACT_16BITS(&tlv->length))) + if (rlen < F_ALN_LEN(tlvl)) return INVALID_ALEN; return 0; } -static inline int ilv_valid(const struct forces_ilv *ilv, u_int rlen) +static int +ilv_valid(netdissect_options *ndo, const struct forces_ilv *ilv, u_int rlen) { if (rlen < ILV_HDRL) return INVALID_RLEN; - if (EXTRACT_32BITS(&ilv->length) < ILV_HDRL) + if (GET_BE_U_4(ilv->length) < ILV_HDRL) return INVALID_STLN; - if (EXTRACT_32BITS(&ilv->length) > rlen) + if (GET_BE_U_4(ilv->length) > rlen) return INVALID_LTLN; - if (rlen < F_ALN_LEN(EXTRACT_32BITS(&ilv->length))) + if (rlen < F_ALN_LEN(GET_BE_U_4(ilv->length))) return INVALID_ALEN; return 0; } -static int lfbselect_print(netdissect_options *, register const u_char * pptr, register u_int len, +static int lfbselect_print(netdissect_options *, const u_char * pptr, u_int len, uint16_t op_msk, int indent); -static int redirect_print(netdissect_options *, register const u_char * pptr, register u_int len, +static int redirect_print(netdissect_options *, const u_char * pptr, u_int len, uint16_t op_msk, int indent); -static int asrtlv_print(netdissect_options *, register const u_char * pptr, register u_int len, +static int asrtlv_print(netdissect_options *, const u_char * pptr, u_int len, uint16_t op_msk, int indent); -static int asttlv_print(netdissect_options *, register const u_char * pptr, register u_int len, +static int asttlv_print(netdissect_options *, const u_char * pptr, u_int len, uint16_t op_msk, int indent); struct forces_lfbsh { @@ -484,7 +485,8 @@ static const struct tom_h ForCES_msg[TOM_MAX_IND + 1] = { {TOM_QUERYREP, TTLV_T2, CFG_QYR, "Query Response", lfbselect_print}, }; -static inline const struct tom_h *get_forces_tom(uint8_t tom) +static const struct tom_h * +get_forces_tom(uint8_t tom) { int i; for (i = TOM_RSV_I; i <= TOM_MAX_IND; i++) { @@ -500,7 +502,7 @@ struct pdata_ops { uint16_t flags; uint16_t op_msk; const char *s; - int (*print) (netdissect_options *, register const u_char * pptr, register u_int len, + int (*print) (netdissect_options *, const u_char * pptr, u_int len, uint16_t op_msk, int indent); }; @@ -515,26 +517,27 @@ enum { }; #define PD_MAX_IND (_TOM_RSV_MAX - 1) -static inline int pd_valid(uint16_t pd) +static int +pd_valid(uint16_t pd) { if (pd >= F_TLV_PDAT && pd <= F_TLV_REST) return 1; return 0; } -static inline void +static void chk_op_type(netdissect_options *ndo, uint16_t type, uint16_t msk, uint16_t omsk) { if (type != F_TLV_PDAT) { if (msk & B_KEYIN) { if (type != F_TLV_KEYI) { - ND_PRINT((ndo, "Based on flags expected KEYINFO TLV!\n")); + ND_PRINT("Based on flags expected KEYINFO TLV!\n"); } } else { if (!(msk & omsk)) { - ND_PRINT((ndo, "Illegal DATA encoding for type 0x%x programmed %x got %x \n", - type, omsk, msk)); + ND_PRINT("Illegal DATA encoding for type 0x%x programmed %x got %x\n", + type, omsk, msk); } } } @@ -551,13 +554,13 @@ struct res_val { nd_uint16_t resv2; }; -static int prestlv_print(netdissect_options *, register const u_char * pptr, register u_int len, +static int prestlv_print(netdissect_options *, const u_char * pptr, u_int len, uint16_t op_msk, int indent); -static int pkeyitlv_print(netdissect_options *, register const u_char * pptr, register u_int len, +static int pkeyitlv_print(netdissect_options *, const u_char * pptr, u_int len, uint16_t op_msk, int indent); -static int fdatatlv_print(netdissect_options *, register const u_char * pptr, register u_int len, +static int fdatatlv_print(netdissect_options *, const u_char * pptr, u_int len, uint16_t op_msk, int indent); -static int sdatatlv_print(netdissect_options *, register const u_char * pptr, register u_int len, +static int sdatatlv_print(netdissect_options *, const u_char * pptr, u_int len, uint16_t op_msk, int indent); static const struct pdata_ops ForCES_pdata[PD_MAX_IND + 1] = { @@ -570,7 +573,8 @@ static const struct pdata_ops ForCES_pdata[PD_MAX_IND + 1] = { {F_TLV_PDAT, 0, 0, "Inner PATH-DATA TLV", recpdoptlv_print}, }; -static inline const struct pdata_ops *get_forces_pd(uint16_t pd) +static const struct pdata_ops * +get_forces_pd(uint16_t pd) { int i; for (i = PD_RSV_I + 1; i <= PD_MAX_IND; i++) { @@ -643,13 +647,14 @@ static const struct tok ForCES_errs[] = { static int prestlv_print(netdissect_options *ndo, - register const u_char * pptr, register u_int len, + const u_char * pptr, u_int len, uint16_t op_msk _U_, int indent) { const struct forces_tlv *tlv = (const struct forces_tlv *)pptr; - register const u_char *tdp = (const u_char *) TLV_DATA(tlv); + const u_char *tdp = (const u_char *) TLV_DATA(tlv); const struct res_val *r = (const struct res_val *)tdp; u_int dlen; + uint8_t result; /* * pdatacnt_print() has ensured that len (the TLV length) @@ -657,36 +662,37 @@ prestlv_print(netdissect_options *ndo, */ dlen = len - TLV_HDRL; if (dlen != RESLEN) { - ND_PRINT((ndo, "illegal RESULT-TLV: %d bytes!\n", dlen)); + ND_PRINT("illegal RESULT-TLV: %u bytes!\n", dlen); return -1; } - ND_TCHECK(*r); - if (r->result >= 0x18 && r->result <= 0xFE) { - ND_PRINT((ndo, "illegal reserved result code: 0x%x!\n", r->result)); + ND_TCHECK_SIZE(r); + result = GET_U_1(r->result); + if (result >= 0x18 && result <= 0xFE) { + ND_PRINT("illegal reserved result code: 0x%x!\n", result); return -1; } if (ndo->ndo_vflag >= 3) { char *ib = indent_pr(indent, 0); - ND_PRINT((ndo, "%s Result: %s (code 0x%x)\n", ib, - tok2str(ForCES_errs, NULL, r->result), r->result)); + ND_PRINT("%s Result: %s (code 0x%x)\n", ib, + tok2str(ForCES_errs, NULL, result), result); } return 0; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return -1; } static int fdatatlv_print(netdissect_options *ndo, - register const u_char * pptr, register u_int len, + const u_char * pptr, u_int len, uint16_t op_msk _U_, int indent) { const struct forces_tlv *tlv = (const struct forces_tlv *)pptr; u_int rlen; - register const u_char *tdp = (const u_char *) TLV_DATA(tlv); + const u_char *tdp = (const u_char *) TLV_DATA(tlv); uint16_t type; /* @@ -694,29 +700,29 @@ fdatatlv_print(netdissect_options *ndo, * (the TLV length) >= TLV_HDRL. */ rlen = len - TLV_HDRL; - ND_TCHECK(*tlv); - type = EXTRACT_16BITS(&tlv->type); + ND_TCHECK_SIZE(tlv); + type = GET_BE_U_2(tlv->type); if (type != F_TLV_FULD) { - ND_PRINT((ndo, "Error: expecting FULLDATA!\n")); + ND_PRINT("Error: expecting FULLDATA!\n"); return -1; } if (ndo->ndo_vflag >= 3) { char *ib = indent_pr(indent + 2, 1); - ND_PRINT((ndo, "%s[", &ib[1])); - hex_print_with_offset(ndo, ib, tdp, rlen, 0); - ND_PRINT((ndo, "\n%s]\n", &ib[1])); + ND_PRINT("%s[", ib + 1); + hex_print(ndo, ib, tdp, rlen); + ND_PRINT("\n%s]", ib + 1); } return 0; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return -1; } static int sdatailv_print(netdissect_options *ndo, - register const u_char * pptr, register u_int len, + const u_char * pptr, u_int len, uint16_t op_msk _U_, int indent) { u_int rlen; @@ -724,50 +730,44 @@ sdatailv_print(netdissect_options *ndo, int invilv; if (len < ILV_HDRL) { - ND_PRINT((ndo, "Error: BAD SPARSEDATA-TLV!\n")); + ND_PRINT("Error: BAD SPARSEDATA-TLV!\n"); return -1; } rlen = len; indent += 1; while (rlen != 0) { #if 0 - ND_PRINT((ndo, "Jamal - outstanding length <%d>\n", rlen)); + ND_PRINT("Jamal - outstanding length <%u>\n", rlen); #endif char *ib = indent_pr(indent, 1); - register const u_char *tdp = (const u_char *) ILV_DATA(ilv); - ND_TCHECK(*ilv); - invilv = ilv_valid(ilv, rlen); + const u_char *tdp = (const u_char *) ILV_DATA(ilv); + invilv = ilv_valid(ndo, ilv, rlen); if (invilv) { - ND_PRINT((ndo, "%s[", &ib[1])); - hex_print_with_offset(ndo, ib, tdp, rlen, 0); - ND_PRINT((ndo, "\n%s]\n", &ib[1])); + ND_PRINT("Error: %s, rlen %u\n", + tok2str(ForCES_TLV_err, NULL, invilv), rlen); return -1; } if (ndo->ndo_vflag >= 3) { - int ilvl = EXTRACT_32BITS(&ilv->length); - ND_PRINT((ndo, "\n%s ILV: type %x length %d\n", &ib[1], - EXTRACT_32BITS(&ilv->type), ilvl)); - hex_print_with_offset(ndo, "\t\t[", tdp, ilvl-ILV_HDRL, 0); + u_int ilvl = GET_BE_U_4(ilv->length); + ND_PRINT("\n%s ILV: type %x length %u\n", ib + 1, + GET_BE_U_4(ilv->type), ilvl); + hex_print(ndo, "\t\t[", tdp, ilvl-ILV_HDRL); } ilv = GO_NXT_ILV(ilv, rlen); } return 0; - -trunc: - ND_PRINT((ndo, "%s", tstr)); - return -1; } static int sdatatlv_print(netdissect_options *ndo, - register const u_char * pptr, register u_int len, + const u_char * pptr, u_int len, uint16_t op_msk, int indent) { const struct forces_tlv *tlv = (const struct forces_tlv *)pptr; u_int rlen; - register const u_char *tdp = (const u_char *) TLV_DATA(tlv); + const u_char *tdp = (const u_char *) TLV_DATA(tlv); uint16_t type; /* @@ -775,45 +775,44 @@ sdatatlv_print(netdissect_options *ndo, * >= TLV_HDRL. */ rlen = len - TLV_HDRL; - ND_TCHECK(*tlv); - type = EXTRACT_16BITS(&tlv->type); + ND_TCHECK_SIZE(tlv); + type = GET_BE_U_2(tlv->type); if (type != F_TLV_SPAD) { - ND_PRINT((ndo, "Error: expecting SPARSEDATA!\n")); + ND_PRINT("Error: expecting SPARSEDATA!\n"); return -1; } return sdatailv_print(ndo, tdp, rlen, op_msk, indent); trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return -1; } static int pkeyitlv_print(netdissect_options *ndo, - register const u_char * pptr, register u_int len, + const u_char * pptr, u_int len, uint16_t op_msk, int indent) { const struct forces_tlv *tlv = (const struct forces_tlv *)pptr; - register const u_char *tdp = (const u_char *) TLV_DATA(tlv); - register const u_char *dp = tdp + 4; + const u_char *tdp = (const u_char *) TLV_DATA(tlv); + const u_char *dp = tdp + 4; const struct forces_tlv *kdtlv = (const struct forces_tlv *)dp; uint32_t id; char *ib = indent_pr(indent, 0); uint16_t type, tll; u_int invtlv; - ND_TCHECK(*tdp); - id = EXTRACT_32BITS(tdp); - ND_PRINT((ndo, "%sKeyinfo: Key 0x%x\n", ib, id)); - ND_TCHECK(*kdtlv); - type = EXTRACT_16BITS(&kdtlv->type); - invtlv = tlv_valid(kdtlv, len); + id = GET_BE_U_4(tdp); + ND_PRINT("%sKeyinfo: Key 0x%x\n", ib, id); + type = GET_BE_U_2(kdtlv->type); + tll = GET_BE_U_2(kdtlv->length); + invtlv = tlv_valid(tll, len); if (invtlv) { - ND_PRINT((ndo, "%s TLV type 0x%x len %d\n", + ND_PRINT("%s TLV type 0x%x len %u\n", tok2str(ForCES_TLV_err, NULL, invtlv), type, - EXTRACT_16BITS(&kdtlv->length))); + tll); return -1; } /* @@ -821,20 +820,16 @@ pkeyitlv_print(netdissect_options *ndo, * length is large enough but not too large (it doesn't * go past the end of the containing TLV). */ - tll = EXTRACT_16BITS(&kdtlv->length); + tll = GET_BE_U_2(kdtlv->length); dp = (const u_char *) TLV_DATA(kdtlv); return fdatatlv_print(ndo, dp, tll, op_msk, indent); - -trunc: - ND_PRINT((ndo, "%s", tstr)); - return -1; } #define PTH_DESC_SIZE 12 static int pdatacnt_print(netdissect_options *ndo, - register const u_char * pptr, register u_int len, + const u_char * pptr, u_int len, uint16_t IDcnt, uint16_t op_msk, int indent) { u_int i; @@ -842,15 +837,15 @@ pdatacnt_print(netdissect_options *ndo, char *ib = indent_pr(indent, 0); if ((op_msk & B_APPND) && ndo->ndo_vflag >= 3) { - ND_PRINT((ndo, "%sTABLE APPEND\n", ib)); + ND_PRINT("%sTABLE APPEND\n", ib); } for (i = 0; i < IDcnt; i++) { - ND_TCHECK2(*pptr, 4); + ND_TCHECK_4(pptr); if (len < 4) goto trunc; - id = EXTRACT_32BITS(pptr); + id = GET_BE_U_4(pptr); if (ndo->ndo_vflag >= 3) - ND_PRINT((ndo, "%sID#%02u: %d\n", ib, i + 1, id)); + ND_PRINT("%sID#%02u: %u\n", ib, i + 1, id); len -= 4; pptr += 4; } @@ -860,24 +855,24 @@ pdatacnt_print(netdissect_options *ndo, uint32_t starti, endi; if (len < PTH_DESC_SIZE) { - ND_PRINT((ndo, "pathlength %d with key/range too short %d\n", - len, PTH_DESC_SIZE)); + ND_PRINT("pathlength %u with key/range too short %u\n", + len, PTH_DESC_SIZE); return -1; } pptr += sizeof(struct forces_tlv); len -= sizeof(struct forces_tlv); - starti = EXTRACT_32BITS(pptr); + starti = GET_BE_U_4(pptr); pptr += 4; len -= 4; - endi = EXTRACT_32BITS(pptr); + endi = GET_BE_U_4(pptr); pptr += 4; len -= 4; if (ndo->ndo_vflag >= 3) - ND_PRINT((ndo, "%sTable range: [%d,%d]\n", ib, starti, endi)); + ND_PRINT("%sTable range: [%u,%u]\n", ib, starti, endi); } if (op_msk & B_KEYIN) { @@ -885,8 +880,8 @@ pdatacnt_print(netdissect_options *ndo, uint16_t tll; if (len < PTH_DESC_SIZE) { - ND_PRINT((ndo, "pathlength %d with key/range too short %d\n", - len, PTH_DESC_SIZE)); + ND_PRINT("pathlength %u with key/range too short %u\n", + len, PTH_DESC_SIZE); return -1; } @@ -898,15 +893,15 @@ pdatacnt_print(netdissect_options *ndo, pptr += sizeof(struct forces_tlv); len -= sizeof(struct forces_tlv); /* skip key content */ - tll = EXTRACT_16BITS(&keytlv->length); + tll = GET_BE_U_2(keytlv->length); if (tll < TLV_HDRL) { - ND_PRINT((ndo, "key content length %u < %u\n", - tll, TLV_HDRL)); + ND_PRINT("key content length %u < %u\n", + tll, TLV_HDRL); return -1; } tll -= TLV_HDRL; if (len < tll) { - ND_PRINT((ndo, "key content too short\n")); + ND_PRINT("key content too short\n"); return -1; } pptr += tll; @@ -918,18 +913,18 @@ pdatacnt_print(netdissect_options *ndo, if (len) { const struct forces_tlv *pdtlv = (const struct forces_tlv *)pptr; uint16_t type; - uint16_t tll; - int pad = 0; + uint16_t tlvl, tll; + u_int pad = 0; u_int aln; u_int invtlv; - ND_TCHECK(*pdtlv); - type = EXTRACT_16BITS(&pdtlv->type); - invtlv = tlv_valid(pdtlv, len); + type = GET_BE_U_2(pdtlv->type); + tlvl = GET_BE_U_2(pdtlv->length); + invtlv = tlv_valid(tlvl, len); if (invtlv) { - ND_PRINT((ndo, "%s Outstanding bytes %d for TLV type 0x%x TLV len %d\n", + ND_PRINT("%s Outstanding bytes %u for TLV type 0x%x TLV len %u\n", tok2str(ForCES_TLV_err, NULL, invtlv), len, type, - EXTRACT_16BITS(&pdtlv->length))); + tlvl); goto pd_err; } /* @@ -937,15 +932,14 @@ pdatacnt_print(netdissect_options *ndo, * 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)) { + tll = tlvl - TLV_HDRL; + aln = F_ALN_LEN(tlvl); + if (aln > tlvl) { if (aln > len) { - ND_PRINT((ndo, - "Invalid padded pathdata TLV type 0x%x len %d missing %d pad bytes\n", - type, EXTRACT_16BITS(&pdtlv->length), aln - len)); + ND_PRINT("Invalid padded pathdata TLV type 0x%x len %u missing %u pad bytes\n", + type, tlvl, aln - len); } else { - pad = aln - EXTRACT_16BITS(&pdtlv->length); + pad = aln - tlvl; } } if (pd_valid(type)) { @@ -953,11 +947,11 @@ pdatacnt_print(netdissect_options *ndo, if (ndo->ndo_vflag >= 3 && ops->v != F_TLV_PDAT) { if (pad) - ND_PRINT((ndo, "%s %s (Length %d DataLen %d pad %d Bytes)\n", - ib, ops->s, EXTRACT_16BITS(&pdtlv->length), tll, pad)); + ND_PRINT("%s %s (Length %u DataLen %u pad %u Bytes)\n", + ib, ops->s, tlvl, tll, pad); else - ND_PRINT((ndo, "%s %s (Length %d DataLen %d Bytes)\n", - ib, ops->s, EXTRACT_16BITS(&pdtlv->length), tll)); + ND_PRINT("%s %s (Length %u DataLen %u Bytes)\n", + ib, ops->s, tlvl, tll); } chk_op_type(ndo, type, op_msk, ops->op_msk); @@ -968,13 +962,13 @@ pdatacnt_print(netdissect_options *ndo, return -1; len -= (TLV_HDRL + pad + tll); } else { - ND_PRINT((ndo, "Invalid path data content type 0x%x len %d\n", - type, EXTRACT_16BITS(&pdtlv->length))); + ND_PRINT("Invalid path data content type 0x%x len %u\n", + type, tlvl); pd_err: - if (EXTRACT_16BITS(&pdtlv->length)) { - hex_print_with_offset(ndo, "Bad Data val\n\t [", - pptr, len, 0); - ND_PRINT((ndo, "]\n")); + if (tlvl) { + hex_print(ndo, "Bad Data val\n\t [", + pptr, len); + ND_PRINT("]\n"); return -1; } @@ -983,13 +977,13 @@ pd_err: return len; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return -1; } static int pdata_print(netdissect_options *ndo, - register const u_char * pptr, register u_int len, + const u_char * pptr, u_int len, uint16_t op_msk, int indent) { const struct pathdata_h *pdh = (const struct pathdata_h *)pptr; @@ -998,41 +992,42 @@ pdata_print(netdissect_options *ndo, int more_pd = 0; uint16_t idcnt = 0; - ND_TCHECK(*pdh); + ND_TCHECK_SIZE(pdh); if (len < sizeof(struct pathdata_h)) goto trunc; if (ndo->ndo_vflag >= 3) { - ND_PRINT((ndo, "\n%sPathdata: Flags 0x%x ID count %d\n", - ib, EXTRACT_16BITS(&pdh->pflags), EXTRACT_16BITS(&pdh->pIDcnt))); + ND_PRINT("\n%sPathdata: Flags 0x%x ID count %u\n", + ib, GET_BE_U_2(pdh->pflags), + GET_BE_U_2(pdh->pIDcnt)); } - if (EXTRACT_16BITS(&pdh->pflags) & F_SELKEY) { + if (GET_BE_U_2(pdh->pflags) & F_SELKEY) { op_msk |= B_KEYIN; } /* Table GET Range operation */ - if (EXTRACT_16BITS(&pdh->pflags) & F_SELTABRANGE) { + if (GET_BE_U_2(pdh->pflags) & F_SELTABRANGE) { op_msk |= B_TRNG; } /* Table SET append operation */ - if (EXTRACT_16BITS(&pdh->pflags) & F_TABAPPEND) { + if (GET_BE_U_2(pdh->pflags) & F_TABAPPEND) { op_msk |= B_APPND; } pptr += sizeof(struct pathdata_h); len -= sizeof(struct pathdata_h); - idcnt = EXTRACT_16BITS(&pdh->pIDcnt); + idcnt = GET_BE_U_2(pdh->pIDcnt); minsize = idcnt * 4; if (len < minsize) { - ND_PRINT((ndo, "\t\t\ttruncated IDs expected %uB got %uB\n", minsize, - len)); - hex_print_with_offset(ndo, "\t\t\tID Data[", pptr, len, 0); - ND_PRINT((ndo, "]\n")); + ND_PRINT("\t\t\ttruncated IDs expected %uB got %uB\n", minsize, + len); + hex_print(ndo, "\t\t\tID Data[", pptr, len); + ND_PRINT("]\n"); return -1; } if ((op_msk & B_TRNG) && (op_msk & B_KEYIN)) { - ND_PRINT((ndo, "\t\t\tIllegal to have both Table ranges and keys\n")); + ND_PRINT("\t\t\tIllegal to have both Table ranges and keys\n"); return -1; } @@ -1047,71 +1042,67 @@ pdata_print(netdissect_options *ndo, return 0; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return -1; } static int genoptlv_print(netdissect_options *ndo, - register const u_char * pptr, register u_int len, + const u_char * pptr, u_int len, uint16_t op_msk, int indent) { const struct forces_tlv *pdtlv = (const struct forces_tlv *)pptr; uint16_t type; - int tll; + u_int tlvl; u_int invtlv; char *ib = indent_pr(indent, 0); - ND_TCHECK(*pdtlv); - type = EXTRACT_16BITS(&pdtlv->type); - tll = EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL; - invtlv = tlv_valid(pdtlv, len); - ND_PRINT((ndo, "genoptlvprint - %s TLV type 0x%x len %d\n", - tok2str(ForCES_TLV, NULL, type), type, EXTRACT_16BITS(&pdtlv->length))); + type = GET_BE_U_2(pdtlv->type); + tlvl = GET_BE_U_2(pdtlv->length); + invtlv = tlv_valid(tlvl, len); + ND_PRINT("genoptlvprint - %s TLV type 0x%x len %u\n", + tok2str(ForCES_TLV, NULL, type), type, tlvl); 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 = (const u_char *) TLV_DATA(pdtlv); + const u_char *dp = (const u_char *) TLV_DATA(pdtlv); + if (!ttlv_valid(type)) { - ND_PRINT((ndo, "%s TLV type 0x%x len %d\n", + ND_PRINT("%s TLV type 0x%x len %u\n", tok2str(ForCES_TLV_err, NULL, invtlv), type, - EXTRACT_16BITS(&pdtlv->length))); + tlvl); return -1; } if (ndo->ndo_vflag >= 3) - ND_PRINT((ndo, "%s%s, length %d (data length %d Bytes)", + ND_PRINT("%s%s, length %u (data length %u Bytes)", ib, tok2str(ForCES_TLV, NULL, type), - EXTRACT_16BITS(&pdtlv->length), tll)); + tlvl, tlvl - TLV_HDRL); - return pdata_print(ndo, dp, tll, op_msk, indent + 1); + return pdata_print(ndo, dp, tlvl - TLV_HDRL, op_msk, indent + 1); } else { - ND_PRINT((ndo, "\t\t\tInvalid ForCES TLV type=%x", type)); + ND_PRINT("\t\t\tInvalid ForCES TLV type=%x", type); return -1; } - -trunc: - ND_PRINT((ndo, "%s", tstr)); - return -1; } static int recpdoptlv_print(netdissect_options *ndo, - register const u_char * pptr, register u_int len, + const u_char * pptr, u_int len, uint16_t op_msk, int indent) { const struct forces_tlv *pdtlv = (const struct forces_tlv *)pptr; - int tll; - u_int invtlv; - uint16_t type; - register const u_char *dp; - char *ib; while (len != 0) { - ND_TCHECK(*pdtlv); - invtlv = tlv_valid(pdtlv, len); + uint16_t type, tlvl; + u_int invtlv; + char *ib; + const u_char *dp; + + tlvl = GET_BE_U_2(pdtlv->length); + invtlv = tlv_valid(tlvl, len); if (invtlv) { break; } @@ -1122,46 +1113,41 @@ recpdoptlv_print(netdissect_options *ndo, * go past the end of the containing TLV). */ ib = indent_pr(indent, 0); - type = EXTRACT_16BITS(&pdtlv->type); + type = GET_BE_U_2(pdtlv->type); dp = (const u_char *) TLV_DATA(pdtlv); - tll = EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL; if (ndo->ndo_vflag >= 3) - ND_PRINT((ndo, "%s%s, length %d (data encapsulated %d Bytes)", + ND_PRINT("%s%s, length %u (data encapsulated %u Bytes)", ib, tok2str(ForCES_TLV, NULL, type), - EXTRACT_16BITS(&pdtlv->length), - EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL)); + tlvl, + tlvl - TLV_HDRL); - if (pdata_print(ndo, dp, tll, op_msk, indent + 1) == -1) + if (pdata_print(ndo, dp, tlvl - TLV_HDRL, op_msk, indent + 1) == -1) return -1; pdtlv = GO_NXT_TLV(pdtlv, len); } if (len) { - ND_PRINT((ndo, - "\n\t\tMessy PATHDATA TLV header, type (0x%x)\n\t\texcess of %d Bytes ", - EXTRACT_16BITS(&pdtlv->type), len - EXTRACT_16BITS(&pdtlv->length))); + ND_PRINT("\n\t\tMessy PATHDATA TLV header, type (0x%x)\n\t\texcess of %u Bytes ", + GET_BE_U_2(pdtlv->type), + len - GET_BE_U_2(pdtlv->length)); return -1; } return 0; - -trunc: - ND_PRINT((ndo, "%s", tstr)); - return -1; } static int invoptlv_print(netdissect_options *ndo, - register const u_char * pptr, register u_int len, + const u_char * pptr, u_int len, uint16_t op_msk _U_, int indent) { char *ib = indent_pr(indent, 1); if (ndo->ndo_vflag >= 3) { - ND_PRINT((ndo, "%sData[", &ib[1])); - hex_print_with_offset(ndo, ib, pptr, len, 0); - ND_PRINT((ndo, "%s]\n", ib)); + ND_PRINT("%sData[", ib + 1); + hex_print(ndo, ib, pptr, len); + ND_PRINT("%s]\n", ib); } return -1; } @@ -1171,30 +1157,29 @@ otlv_print(netdissect_options *ndo, const struct forces_tlv *otlv, uint16_t op_msk _U_, int indent) { int rc = 0; - register const u_char *dp = (const u_char *) TLV_DATA(otlv); + const u_char *dp = (const u_char *) TLV_DATA(otlv); uint16_t type; - int tll; + u_int tll; char *ib = indent_pr(indent, 0); const struct optlv_h *ops; /* - * lfbselect_print() has ensured that EXTRACT_16BITS(&otlv->length) + * lfbselect_print() has ensured that GET_BE_U_2(otlv->length) * >= TLV_HDRL. */ - ND_TCHECK(*otlv); - type = EXTRACT_16BITS(&otlv->type); - tll = EXTRACT_16BITS(&otlv->length) - TLV_HDRL; + type = GET_BE_U_2(otlv->type); + tll = GET_BE_U_2(otlv->length) - TLV_HDRL; ops = get_forces_optlv_h(type); if (ndo->ndo_vflag >= 3) { - ND_PRINT((ndo, "%sOper TLV %s(0x%x) length %d\n", ib, ops->s, type, - EXTRACT_16BITS(&otlv->length))); + ND_PRINT("%sOper TLV %s(0x%x) length %u\n", ib, ops->s, type, + GET_BE_U_2(otlv->length)); } /* rest of ops must at least have 12B {pathinfo} */ if (tll < OP_MIN_SIZ) { - ND_PRINT((ndo, "\t\tOper TLV %s(0x%x) length %d\n", ops->s, type, - EXTRACT_16BITS(&otlv->length))); - ND_PRINT((ndo, "\t\tTruncated data size %d minimum required %d\n", tll, - OP_MIN_SIZ)); + ND_PRINT("\t\tOper TLV %s(0x%x) length %u\n", ops->s, type, + GET_BE_U_2(otlv->length)); + ND_PRINT("\t\tTruncated data size %u minimum required %u\n", tll, + OP_MIN_SIZ); return invoptlv_print(ndo, dp, tll, ops->op_msk, indent); } @@ -1204,17 +1189,13 @@ otlv_print(netdissect_options *ndo, rc = ops->print(ndo, dp, tll, ops->op_msk, indent + 1); } return rc; - -trunc: - ND_PRINT((ndo, "%s", tstr)); - return -1; } #define ASTDLN 4 #define ASTMCD 255 static int asttlv_print(netdissect_options *ndo, - register const u_char * pptr, register u_int len, + const u_char * pptr, u_int len, uint16_t op_msk _U_, int indent) { uint32_t rescode; @@ -1227,52 +1208,47 @@ asttlv_print(netdissect_options *ndo, */ dlen = len - TLV_HDRL; if (dlen != ASTDLN) { - ND_PRINT((ndo, "illegal ASTresult-TLV: %d bytes!\n", dlen)); + ND_PRINT("illegal ASTresult-TLV: %u bytes!\n", dlen); return -1; } - ND_TCHECK2(*pptr, 4); - rescode = EXTRACT_32BITS(pptr); + rescode = GET_BE_U_4(pptr); if (rescode > ASTMCD) { - ND_PRINT((ndo, "illegal ASTresult result code: %d!\n", rescode)); + ND_PRINT("illegal ASTresult result code: %u!\n", rescode); return -1; } if (ndo->ndo_vflag >= 3) { - ND_PRINT((ndo, "Teardown reason:\n%s", ib)); + ND_PRINT("Teardown reason:\n%s", ib); switch (rescode) { case 0: - ND_PRINT((ndo, "Normal Teardown")); + ND_PRINT("Normal Teardown"); break; case 1: - ND_PRINT((ndo, "Loss of Heartbeats")); + ND_PRINT("Loss of Heartbeats"); break; case 2: - ND_PRINT((ndo, "Out of bandwidth")); + ND_PRINT("Out of bandwidth"); break; case 3: - ND_PRINT((ndo, "Out of Memory")); + ND_PRINT("Out of Memory"); break; case 4: - ND_PRINT((ndo, "Application Crash")); + ND_PRINT("Application Crash"); break; default: - ND_PRINT((ndo, "Unknown Teardown reason")); + ND_PRINT("Unknown Teardown reason"); break; } - ND_PRINT((ndo, "(%x)\n%s", rescode, ib)); + ND_PRINT("(%x)\n%s", rescode, ib); } return 0; - -trunc: - ND_PRINT((ndo, "%s", tstr)); - return -1; } #define ASRDLN 4 #define ASRMCD 3 static int asrtlv_print(netdissect_options *ndo, - register const u_char * pptr, register u_int len, + const u_char * pptr, u_int len, uint16_t op_msk _U_, int indent) { uint32_t rescode; @@ -1285,40 +1261,35 @@ asrtlv_print(netdissect_options *ndo, */ dlen = len - TLV_HDRL; if (dlen != ASRDLN) { /* id, instance, oper tlv */ - ND_PRINT((ndo, "illegal ASRresult-TLV: %d bytes!\n", dlen)); + ND_PRINT("illegal ASRresult-TLV: %u bytes!\n", dlen); return -1; } - ND_TCHECK2(*pptr, 4); - rescode = EXTRACT_32BITS(pptr); + rescode = GET_BE_U_4(pptr); if (rescode > ASRMCD) { - ND_PRINT((ndo, "illegal ASRresult result code: %d!\n", rescode)); + ND_PRINT("illegal ASRresult result code: %u!\n", rescode); return -1; } if (ndo->ndo_vflag >= 3) { - ND_PRINT((ndo, "\n%s", ib)); + ND_PRINT("\n%s", ib); switch (rescode) { case 0: - ND_PRINT((ndo, "Success ")); + ND_PRINT("Success "); break; case 1: - ND_PRINT((ndo, "FE ID invalid ")); + ND_PRINT("FE ID invalid "); break; case 2: - ND_PRINT((ndo, "permission denied ")); + ND_PRINT("permission denied "); break; default: - ND_PRINT((ndo, "Unknown ")); + ND_PRINT("Unknown "); break; } - ND_PRINT((ndo, "(%x)\n%s", rescode, ib)); + ND_PRINT("(%x)\n%s", rescode, ib); } return 0; - -trunc: - ND_PRINT((ndo, "%s", tstr)); - return -1; } #if 0 @@ -1327,13 +1298,13 @@ trunc: */ static int gentltlv_print(netdissect_options *ndo, - register const u_char * pptr _U_, register u_int len, + const u_char * pptr _U_, u_int len, uint16_t op_msk _U_, int indent _U_) { u_int dlen = len - TLV_HDRL; if (dlen < 4) { /* at least 32 bits must exist */ - ND_PRINT((ndo, "truncated TLV: %d bytes missing! ", 4 - dlen)); + ND_PRINT("truncated TLV: %u bytes missing! ", 4 - dlen); return -1; } return 0; @@ -1344,7 +1315,7 @@ gentltlv_print(netdissect_options *ndo, static int print_metailv(netdissect_options *ndo, - register const u_char * pptr, uint16_t op_msk _U_, int indent) + const u_char * pptr, uint16_t op_msk _U_, int indent) { u_int rlen; char *ib = indent_pr(indent, 0); @@ -1355,24 +1326,19 @@ print_metailv(netdissect_options *ndo, * print_metatlv() has ensured that len (what remains in the * ILV) >= ILV_HDRL. */ - rlen = EXTRACT_32BITS(&ilv->length) - ILV_HDRL; - ND_TCHECK(*ilv); - ND_PRINT((ndo, "%sMetaID 0x%x length %d\n", ib, EXTRACT_32BITS(&ilv->type), - EXTRACT_32BITS(&ilv->length))); + rlen = GET_BE_U_4(ilv->length) - ILV_HDRL; + ND_PRINT("%sMetaID 0x%x length %u\n", ib, GET_BE_U_4(ilv->type), + GET_BE_U_4(ilv->length)); if (ndo->ndo_vflag >= 3) { - hex_print_with_offset(ndo, "\t\t[", ILV_DATA(ilv), rlen, 0); - ND_PRINT((ndo, " ]\n")); + hex_print(ndo, "\t\t[", ILV_DATA(ilv), rlen); + ND_PRINT(" ]\n"); } return 0; - -trunc: - ND_PRINT((ndo, "%s", tstr)); - return -1; } static int print_metatlv(netdissect_options *ndo, - register const u_char * pptr, register u_int len, + const u_char * pptr, u_int len, uint16_t op_msk _U_, int indent) { u_int dlen; @@ -1387,10 +1353,9 @@ print_metatlv(netdissect_options *ndo, */ dlen = len - TLV_HDRL; rlen = dlen; - ND_PRINT((ndo, "\n%s METADATA length %d \n", ib, rlen)); + ND_PRINT("\n%s METADATA length %u\n", ib, rlen); while (rlen != 0) { - ND_TCHECK(*ilv); - invilv = ilv_valid(ilv, rlen); + invilv = ilv_valid(ndo, ilv, rlen); if (invilv) { break; } @@ -1405,16 +1370,12 @@ print_metatlv(netdissect_options *ndo, } return 0; - -trunc: - ND_PRINT((ndo, "%s", tstr)); - return -1; } static int print_reddata(netdissect_options *ndo, - register const u_char * pptr, register u_int len, + const u_char * pptr, u_int len, uint16_t op_msk _U_, int indent) { u_int dlen; @@ -1423,12 +1384,12 @@ print_reddata(netdissect_options *ndo, dlen = len - TLV_HDRL; rlen = dlen; - ND_PRINT((ndo, "\n%s Redirect Data length %d \n", ib, rlen)); + ND_PRINT("\n%s Redirect Data length %u\n", ib, rlen); if (ndo->ndo_vflag >= 3) { - ND_PRINT((ndo, "\t\t[")); - hex_print_with_offset(ndo, "\n\t\t", pptr, rlen, 0); - ND_PRINT((ndo, "\n\t\t]")); + ND_PRINT("\t\t["); + hex_print(ndo, "\n\t\t", pptr, rlen); + ND_PRINT("\n\t\t]"); } return 0; @@ -1436,7 +1397,7 @@ print_reddata(netdissect_options *ndo, static int redirect_print(netdissect_options *ndo, - register const u_char * pptr, register u_int len, + const u_char * pptr, u_int len, uint16_t op_msk _U_, int indent) { const struct forces_tlv *tlv = (const struct forces_tlv *)pptr; @@ -1450,18 +1411,21 @@ redirect_print(netdissect_options *ndo, */ dlen = len - TLV_HDRL; if (dlen <= RD_MIN) { - ND_PRINT((ndo, "\n\t\ttruncated Redirect TLV: %d bytes missing! ", - RD_MIN - dlen)); + ND_PRINT("\n\t\ttruncated Redirect TLV: %u bytes missing! ", + RD_MIN - dlen); return -1; } rlen = dlen; indent += 1; while (rlen != 0) { - ND_TCHECK(*tlv); - invtlv = tlv_valid(tlv, rlen); + uint16_t type, tlvl; + + type = GET_BE_U_2(tlv->type); + tlvl = GET_BE_U_2(tlv->length); + invtlv = tlv_valid(tlvl, rlen); if (invtlv) { - ND_PRINT((ndo, "Bad Redirect data\n")); + ND_PRINT("Bad Redirect data\n"); break; } @@ -1470,34 +1434,31 @@ redirect_print(netdissect_options *ndo, * 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) { + if (type == F_TLV_METD) { print_metatlv(ndo, (const u_char *) TLV_DATA(tlv), - EXTRACT_16BITS(&tlv->length), 0, indent); - } else if ((EXTRACT_16BITS(&tlv->type) == F_TLV_REDD)) { + tlvl, 0, + indent); + } else if (type == F_TLV_REDD) { print_reddata(ndo, (const u_char *) TLV_DATA(tlv), - EXTRACT_16BITS(&tlv->length), 0, indent); + tlvl, 0, + indent); } else { - ND_PRINT((ndo, "Unknown REDIRECT TLV 0x%x len %d\n", - EXTRACT_16BITS(&tlv->type), - EXTRACT_16BITS(&tlv->length))); + ND_PRINT("Unknown REDIRECT TLV 0x%x len %u\n", + type, + tlvl); } tlv = GO_NXT_TLV(tlv, rlen); } if (rlen) { - ND_PRINT((ndo, - "\n\t\tMessy Redirect TLV header, type (0x%x)\n\t\texcess of %d Bytes ", - EXTRACT_16BITS(&tlv->type), - rlen - EXTRACT_16BITS(&tlv->length))); + ND_PRINT("\n\t\tMessy Redirect TLV header, type (0x%x)\n\t\texcess of %u Bytes ", + GET_BE_U_2(tlv->type), + rlen - GET_BE_U_2(tlv->length)); return -1; } return 0; - -trunc: - ND_PRINT((ndo, "%s", tstr)); - return -1; } #define OP_OFF 8 @@ -1505,7 +1466,7 @@ trunc: static int lfbselect_print(netdissect_options *ndo, - register const u_char * pptr, register u_int len, + const u_char * pptr, u_int len, uint16_t op_msk, int indent) { const struct forces_lfbsh *lfbs; @@ -1521,8 +1482,8 @@ lfbselect_print(netdissect_options *ndo, */ dlen = len - TLV_HDRL; if (dlen <= OP_MIN) { /* id, instance, oper tlv header .. */ - ND_PRINT((ndo, "\n\t\ttruncated lfb selector: %d bytes missing! ", - OP_MIN - dlen)); + ND_PRINT("\n\t\ttruncated lfb selector: %u bytes missing! ", + OP_MIN - dlen); return -1; } @@ -1533,20 +1494,24 @@ lfbselect_print(netdissect_options *ndo, rlen = dlen - OP_OFF; lfbs = (const struct forces_lfbsh *)pptr; - ND_TCHECK(*lfbs); + ND_TCHECK_SIZE(lfbs); if (ndo->ndo_vflag >= 3) { - ND_PRINT((ndo, "\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))); + ND_PRINT("\n%s%s(Classid %x) instance %x\n", + ib, + tok2str(ForCES_LFBs, NULL, GET_BE_U_4(lfbs->class)), + GET_BE_U_4(lfbs->class), + GET_BE_U_4(lfbs->instance)); } otlv = (const struct forces_tlv *)(lfbs + 1); indent += 1; while (rlen != 0) { - ND_TCHECK(*otlv); - invtlv = tlv_valid(otlv, rlen); + uint16_t type, tlvl; + + type = GET_BE_U_2(otlv->type); + tlvl = GET_BE_U_2(otlv->length); + invtlv = tlv_valid(tlvl, rlen); if (invtlv) break; @@ -1555,43 +1520,42 @@ lfbselect_print(netdissect_options *ndo, * 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)) { + if (op_valid(type, op_msk)) { otlv_print(ndo, otlv, 0, indent); } else { if (ndo->ndo_vflag < 3) - ND_PRINT((ndo, "\n")); - ND_PRINT((ndo, - "\t\tINValid oper-TLV type 0x%x length %d for this ForCES message\n", - EXTRACT_16BITS(&otlv->type), EXTRACT_16BITS(&otlv->length))); + ND_PRINT("\n"); + ND_PRINT("\t\tINValid oper-TLV type 0x%x length %u for this ForCES message\n", + type, tlvl); invoptlv_print(ndo, (const u_char *)otlv, rlen, 0, indent); } otlv = GO_NXT_TLV(otlv, rlen); } if (rlen) { - ND_PRINT((ndo, - "\n\t\tMessy oper TLV header, type (0x%x)\n\t\texcess of %d Bytes ", - EXTRACT_16BITS(&otlv->type), rlen - EXTRACT_16BITS(&otlv->length))); + ND_PRINT("\n\t\tMessy oper TLV header, type (0x%x)\n\t\texcess of %u Bytes ", + GET_BE_U_2(otlv->type), + rlen - GET_BE_U_2(otlv->length)); return -1; } return 0; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return -1; } static int forces_type_print(netdissect_options *ndo, - register const u_char * pptr, const struct forcesh *fhdr _U_, - register u_int mlen, const struct tom_h *tops) + const u_char * pptr, const struct forcesh *fhdr _U_, + u_int mlen, const struct tom_h *tops) { const struct forces_tlv *tltlv; u_int rlen; u_int invtlv; int rc = 0; - int ttlv = 0; + u_int ttlv = 0; /* * forces_print() has already checked that mlen >= ForCES_HDRL @@ -1601,14 +1565,14 @@ forces_type_print(netdissect_options *ndo, if (rlen > TLV_HLN) { if (tops->flags & ZERO_TTLV) { - ND_PRINT((ndo, "<0x%x>Illegal Top level TLV!\n", tops->flags)); + ND_PRINT("<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) { - ND_PRINT((ndo, "\tTop level TLV Data missing!\n")); + ND_PRINT("\tTop level TLV Data missing!\n"); return -1; } } @@ -1623,8 +1587,11 @@ forces_type_print(netdissect_options *ndo, /*XXX: 15 top level tlvs will probably be fine You are nuts if you send more ;-> */ while (rlen != 0) { - ND_TCHECK(*tltlv); - invtlv = tlv_valid(tltlv, rlen); + uint16_t type, tlvl; + + type = GET_BE_U_2(tltlv->type); + tlvl = GET_BE_U_2(tltlv->length); + invtlv = tlv_valid(tlvl, rlen); if (invtlv) break; @@ -1633,20 +1600,21 @@ forces_type_print(netdissect_options *ndo, * 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))) { - ND_PRINT((ndo, "\n\tInvalid ForCES Top TLV type=0x%x", - EXTRACT_16BITS(&tltlv->type))); + if (!ttlv_valid(type)) { + ND_PRINT("\n\tInvalid ForCES Top TLV type=0x%x", + type); return -1; } if (ndo->ndo_vflag >= 3) - ND_PRINT((ndo, "\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)); + ND_PRINT("\t%s, length %u (data length %u Bytes)", + tok2str(ForCES_TLV, NULL, type), + tlvl, + tlvl - TLV_HDRL); rc = tops->print(ndo, (const u_char *) TLV_DATA(tltlv), - EXTRACT_16BITS(&tltlv->length), tops->op_msk, 9); + tlvl, + tops->op_msk, 9); if (rc < 0) { return -1; } @@ -1660,66 +1628,61 @@ forces_type_print(netdissect_options *ndo, * short, and didn't have *enough* TLVs in it? */ if (rlen) { - ND_PRINT((ndo, "\tMess TopTLV header: min %u, total %d advertised %d ", - TLV_HDRL, rlen, EXTRACT_16BITS(&tltlv->length))); + ND_PRINT("\tMess TopTLV header: min %u, total %u advertised %u ", + TLV_HDRL, rlen, GET_BE_U_2(tltlv->length)); return -1; } return 0; - -trunc: - ND_PRINT((ndo, "%s", tstr)); - return -1; } void forces_print(netdissect_options *ndo, - register const u_char * pptr, register u_int len) + const u_char * pptr, u_int len) { const struct forcesh *fhdr; u_int mlen; uint32_t flg_raw; + uint8_t tom; const struct tom_h *tops; int rc = 0; + ndo->ndo_protocol = "forces"; fhdr = (const struct forcesh *)pptr; - ND_TCHECK(*fhdr); - if (!tom_valid(fhdr->fm_tom)) { - ND_PRINT((ndo, "Invalid ForCES message type %d\n", fhdr->fm_tom)); + ND_TCHECK_SIZE(fhdr); + tom = GET_U_1(fhdr->fm_tom); + if (!tom_valid(tom)) { + ND_PRINT("Invalid ForCES message type %u\n", tom); goto error; } mlen = ForCES_BLN(fhdr); - tops = get_forces_tom(fhdr->fm_tom); + tops = get_forces_tom(tom); if (tops->v == TOM_RSVD) { - ND_PRINT((ndo, "\n\tUnknown ForCES message type=0x%x", fhdr->fm_tom)); + ND_PRINT("\n\tUnknown ForCES message type=0x%x", tom); goto error; } - ND_PRINT((ndo, "\n\tForCES %s ", tops->s)); + ND_PRINT("\n\tForCES %s ", tops->s); if (!ForCES_HLN_VALID(mlen, len)) { - ND_PRINT((ndo, - "Illegal ForCES pkt len - min %u, total recvd %d, advertised %d ", - ForCES_HDRL, len, ForCES_BLN(fhdr))); + ND_PRINT("Illegal ForCES pkt len - min %u, total recvd %u, advertised %u ", + ForCES_HDRL, len, ForCES_BLN(fhdr)); goto error; } - ND_TCHECK2(*(pptr + 20), 4); - flg_raw = EXTRACT_32BITS(pptr + 20); + flg_raw = GET_BE_U_4(pptr + 20); if (ndo->ndo_vflag >= 1) { - ND_PRINT((ndo, "\n\tForCES Version %d len %uB flags 0x%08x ", - ForCES_V(fhdr), mlen, flg_raw)); - ND_PRINT((ndo, - "\n\tSrcID 0x%x(%s) DstID 0x%x(%s) Correlator 0x%" PRIx64, + ND_PRINT("\n\tForCES Version %u len %uB flags 0x%08x ", + ForCES_V(fhdr), mlen, flg_raw); + ND_PRINT("\n\tSrcID 0x%x(%s) DstID 0x%x(%s) Correlator 0x%" PRIx64, ForCES_SID(fhdr), ForCES_node(ForCES_SID(fhdr)), ForCES_DID(fhdr), ForCES_node(ForCES_DID(fhdr)), - EXTRACT_64BITS(fhdr->fm_cor))); + GET_BE_U_8(fhdr->fm_cor)); } if (ndo->ndo_vflag >= 2) { - ND_PRINT((ndo, - "\n\tForCES flags:\n\t %s(0x%x), prio=%d, %s(0x%x),\n\t %s(0x%x), %s(0x%x)\n", + ND_PRINT("\n\tForCES flags:\n\t %s(0x%x), prio=%u, %s(0x%x),\n\t %s(0x%x), %s(0x%x)\n", tok2str(ForCES_ACKs, "ACKUnknown", ForCES_ACK(fhdr)), ForCES_ACK(fhdr), ForCES_PRI(fhdr), @@ -1728,33 +1691,25 @@ forces_print(netdissect_options *ndo, tok2str(ForCES_ATs, "ATUnknown", ForCES_AT(fhdr)), ForCES_AT(fhdr), tok2str(ForCES_TPs, "TPUnknown", ForCES_TP(fhdr)), - ForCES_TP(fhdr))); - ND_PRINT((ndo, - "\t Extra flags: rsv(b5-7) 0x%x rsv(b13-31) 0x%x\n", - ForCES_RS1(fhdr), ForCES_RS2(fhdr))); + ForCES_TP(fhdr)); + ND_PRINT("\t Extra flags: rsv(b5-7) 0x%x rsv(b13-31) 0x%x\n", + ForCES_RS1(fhdr), ForCES_RS2(fhdr)); } rc = forces_type_print(ndo, pptr, fhdr, mlen, tops); if (rc < 0) { error: - hex_print_with_offset(ndo, "\n\t[", pptr, len, 0); - ND_PRINT((ndo, "\n\t]")); + hex_print(ndo, "\n\t[", pptr, len); + ND_PRINT("\n\t]"); return; } if (ndo->ndo_vflag >= 4) { - ND_PRINT((ndo, "\n\t Raw ForCES message\n\t [")); - hex_print_with_offset(ndo, "\n\t ", pptr, len, 0); - ND_PRINT((ndo, "\n\t ]")); + ND_PRINT("\n\t Raw ForCES message\n\t ["); + hex_print(ndo, "\n\t ", pptr, len); + ND_PRINT("\n\t ]"); } - ND_PRINT((ndo, "\n")); return; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); } -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/print-fr.c b/contrib/tcpdump/print-fr.c index 8a1a53a491..f0d7fbeb12 100644 --- a/contrib/tcpdump/print-fr.c +++ b/contrib/tcpdump/print-fr.c @@ -22,10 +22,10 @@ /* \summary: Frame Relay printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include #include @@ -36,7 +36,6 @@ #include "llc.h" #include "nlpid.h" #include "extract.h" -#include "oui.h" static void frf15_print(netdissect_options *ndo, const u_char *, u_int); @@ -98,66 +97,72 @@ static const struct tok frf_flag_values[] = { * 0 on invalid address, -1 on truncated packet * save the flags dep. on address length */ -static int parse_q922_addr(netdissect_options *ndo, +static int parse_q922_header(netdissect_options *ndo, const u_char *p, u_int *dlci, - u_int *addr_len, uint8_t *flags, u_int length) + u_int *addr_len, uint32_t *flags, u_int length) { - if (!ND_TTEST(p[0]) || length < 1) + if (!ND_TTEST_1(p) || length < 1) return -1; - if ((p[0] & FR_EA_BIT)) + if ((GET_U_1(p) & FR_EA_BIT)) return 0; - if (!ND_TTEST(p[1]) || length < 2) + if (!ND_TTEST_1(p + 1) || length < 2) return -1; *addr_len = 2; - *dlci = ((p[0] & 0xFC) << 2) | ((p[1] & 0xF0) >> 4); + *dlci = ((GET_U_1(p) & 0xFC) << 2) | ((GET_U_1(p + 1) & 0xF0) >> 4); - flags[0] = p[0] & 0x02; /* populate the first flag fields */ - flags[1] = p[1] & 0x0c; - flags[2] = 0; /* clear the rest of the flags */ - flags[3] = 0; + *flags = ((GET_U_1(p) & 0x02) << 24) | /* CR flag */ + ((GET_U_1(p + 1) & 0x0e) << 16); /* FECN,BECN,DE flags */ - if (p[1] & FR_EA_BIT) + if (GET_U_1(p + 1) & FR_EA_BIT) return 1; /* 2-byte Q.922 address */ p += 2; length -= 2; - if (!ND_TTEST(p[0]) || length < 1) + if (!ND_TTEST_1(p) || length < 1) return -1; (*addr_len)++; /* 3- or 4-byte Q.922 address */ - if ((p[0] & FR_EA_BIT) == 0) { - *dlci = (*dlci << 7) | (p[0] >> 1); + if ((GET_U_1(p) & FR_EA_BIT) == 0) { + *dlci = (*dlci << 7) | (GET_U_1(p) >> 1); (*addr_len)++; /* 4-byte Q.922 address */ p++; length--; } - if (!ND_TTEST(p[0]) || length < 1) + if (!ND_TTEST_1(p) || length < 1) return -1; - if ((p[0] & FR_EA_BIT) == 0) + if ((GET_U_1(p) & FR_EA_BIT) == 0) return 0; /* more than 4 bytes of Q.922 address? */ - flags[3] = p[0] & 0x02; + *flags = *flags | (GET_U_1(p) & 0x02); /* SDLC flag */ - *dlci = (*dlci << 6) | (p[0] >> 2); + *dlci = (*dlci << 6) | (GET_U_1(p) >> 2); return 1; } -char * +const char * q922_string(netdissect_options *ndo, const u_char *p, u_int length) { static u_int dlci, addr_len; - static uint8_t flags[4]; - static char buffer[sizeof("DLCI xxxxxxxxxx")]; + static uint32_t flags; + static char buffer[sizeof("parse_q922_header() returned XXXXXXXXXXX")]; + int ret; memset(buffer, 0, sizeof(buffer)); - if (parse_q922_addr(ndo, p, &dlci, &addr_len, flags, length) == 1){ + ret = parse_q922_header(ndo, p, &dlci, &addr_len, &flags, length); + if (ret == 1) { snprintf(buffer, sizeof(buffer), "DLCI %u", dlci); + return buffer; + } else if (ret == 0) { + return ""; + } else if (ret == -1) { + return ""; + } else { + snprintf(buffer, sizeof(buffer), "parse_q922_header() returned %d", ret); + return buffer; } - - return buffer; } @@ -188,54 +193,54 @@ q922_string(netdissect_options *ndo, const u_char *p, u_int length) */ static void -fr_hdr_print(netdissect_options *ndo, - int length, u_int addr_len, u_int dlci, uint8_t *flags, uint16_t nlpid) +fr_hdr_print(netdissect_options *ndo, int length, u_int addr_len, + u_int dlci, uint32_t flags, uint16_t nlpid) { if (ndo->ndo_qflag) { - ND_PRINT((ndo, "Q.922, DLCI %u, length %u: ", + ND_PRINT("Q.922, DLCI %u, length %u: ", dlci, - length)); + length); } else { if (nlpid <= 0xff) /* if its smaller than 256 then its a NLPID */ - ND_PRINT((ndo, "Q.922, hdr-len %u, DLCI %u, Flags [%s], NLPID %s (0x%02x), length %u: ", + ND_PRINT("Q.922, hdr-len %u, DLCI %u, Flags [%s], NLPID %s (0x%02x), length %u: ", addr_len, dlci, - bittok2str(fr_header_flag_values, "none", EXTRACT_32BITS(flags)), + bittok2str(fr_header_flag_values, "none", flags), tok2str(nlpid_values,"unknown", nlpid), nlpid, - length)); + length); else /* must be an ethertype */ - ND_PRINT((ndo, "Q.922, hdr-len %u, DLCI %u, Flags [%s], cisco-ethertype %s (0x%04x), length %u: ", + ND_PRINT("Q.922, hdr-len %u, DLCI %u, Flags [%s], cisco-ethertype %s (0x%04x), length %u: ", addr_len, dlci, - bittok2str(fr_header_flag_values, "none", EXTRACT_32BITS(flags)), + bittok2str(fr_header_flag_values, "none", flags), tok2str(ethertype_values, "unknown", nlpid), nlpid, - length)); + length); } } -u_int +/* Frame Relay */ +void fr_if_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, register const u_char *p) + const struct pcap_pkthdr *h, const u_char *p) { - register u_int length = h->len; - register u_int caplen = h->caplen; - - ND_TCHECK2(*p, 4); /* minimum frame header length */ - - if ((length = fr_print(ndo, p, length)) == 0) - return (0); - else - return length; - trunc: - ND_PRINT((ndo, "[|fr]")); - return caplen; + u_int length = h->len; + u_int caplen = h->caplen; + + ndo->ndo_protocol = "fr"; + if (caplen < 4) { /* minimum frame header length */ + nd_print_trunc(ndo); + ndo->ndo_ll_hdr_len += caplen; + return; + } + + ndo->ndo_ll_hdr_len += fr_print(ndo, p, length); } u_int fr_print(netdissect_options *ndo, - register const u_char *p, u_int length) + const u_char *p, u_int length) { int ret; uint16_t extracted_ethertype; @@ -243,31 +248,32 @@ fr_print(netdissect_options *ndo, u_int addr_len; uint16_t nlpid; u_int hdr_len; - uint8_t flags[4]; + uint32_t flags; - ret = parse_q922_addr(ndo, p, &dlci, &addr_len, flags, length); + ndo->ndo_protocol = "fr"; + ret = parse_q922_header(ndo, p, &dlci, &addr_len, &flags, length); if (ret == -1) goto trunc; if (ret == 0) { - ND_PRINT((ndo, "Q.922, invalid address")); + ND_PRINT("Q.922, invalid address"); return 0; } - ND_TCHECK(p[addr_len]); + ND_TCHECK_1(p + addr_len); if (length < addr_len + 1) goto trunc; - if (p[addr_len] != LLC_UI && dlci != 0) { + if (GET_U_1(p + addr_len) != LLC_UI && dlci != 0) { /* * Let's figure out if we have Cisco-style encapsulation, * with an Ethernet type (Cisco HDLC type?) following the * address. */ - if (!ND_TTEST2(p[addr_len], 2) || length < addr_len + 2) { + if (!ND_TTEST_2(p + addr_len) || length < addr_len + 2) { /* no Ethertype */ - ND_PRINT((ndo, "UI %02x! ", p[addr_len])); + ND_PRINT("UI %02x! ", GET_U_1(p + addr_len)); } else { - extracted_ethertype = EXTRACT_16BITS(p+addr_len); + extracted_ethertype = GET_BE_U_2(p + addr_len); if (ndo->ndo_eflag) fr_hdr_print(ndo, length, addr_len, dlci, @@ -276,26 +282,26 @@ fr_print(netdissect_options *ndo, if (ethertype_print(ndo, extracted_ethertype, p+addr_len+ETHERTYPE_LEN, length-addr_len-ETHERTYPE_LEN, - ndo->ndo_snapend-p-addr_len-ETHERTYPE_LEN, + ND_BYTES_AVAILABLE_AFTER(p)-addr_len-ETHERTYPE_LEN, NULL, NULL) == 0) /* ether_type not known, probably it wasn't one */ - ND_PRINT((ndo, "UI %02x! ", p[addr_len])); + ND_PRINT("UI %02x! ", GET_U_1(p + addr_len)); else return addr_len + 2; } } - ND_TCHECK(p[addr_len+1]); + ND_TCHECK_1(p + addr_len + 1); if (length < addr_len + 2) goto trunc; - if (p[addr_len + 1] == 0) { + if (GET_U_1(p + addr_len + 1) == 0) { /* * Assume a pad byte after the control (UI) byte. * A pad byte should only be used with 3-byte Q.922. */ if (addr_len != 3) - ND_PRINT((ndo, "Pad! ")); + ND_PRINT("Pad! "); hdr_len = addr_len + 1 /* UI */ + 1 /* pad */ + 1 /* NLPID */; } else { /* @@ -303,14 +309,14 @@ fr_print(netdissect_options *ndo, * A pad byte should be used with 3-byte Q.922. */ if (addr_len == 3) - ND_PRINT((ndo, "No pad! ")); + ND_PRINT("No pad! "); hdr_len = addr_len + 1 /* UI */ + 1 /* NLPID */; } - ND_TCHECK(p[hdr_len - 1]); + ND_TCHECK_1(p + hdr_len - 1); if (length < hdr_len) goto trunc; - nlpid = p[hdr_len - 1]; + nlpid = GET_U_1(p + hdr_len - 1); if (ndo->ndo_eflag) fr_hdr_print(ndo, length, addr_len, dlci, flags, nlpid); @@ -333,7 +339,7 @@ fr_print(netdissect_options *ndo, break; case NLPID_SNAP: - if (snap_print(ndo, p, length, ndo->ndo_snapend - p, NULL, NULL, 0) == 0) { + if (snap_print(ndo, p, length, ND_BYTES_AVAILABLE_AFTER(p), NULL, NULL, 0) == 0) { /* ether_type not known, print raw packet */ if (!ndo->ndo_eflag) fr_hdr_print(ndo, length + hdr_len, hdr_len, @@ -365,28 +371,28 @@ fr_print(netdissect_options *ndo, return hdr_len; - trunc: - ND_PRINT((ndo, "[|fr]")); +trunc: + nd_print_trunc(ndo); return 0; } -u_int +/* Multi Link Frame Relay (FRF.16) */ +void mfr_if_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, register const u_char *p) + const struct pcap_pkthdr *h, const u_char *p) { - register u_int length = h->len; - register u_int caplen = h->caplen; - - ND_TCHECK2(*p, 2); /* minimum frame header length */ - - if ((length = mfr_print(ndo, p, length)) == 0) - return (0); - else - return length; - trunc: - ND_PRINT((ndo, "[|mfr]")); - return caplen; + u_int length = h->len; + u_int caplen = h->caplen; + + ndo->ndo_protocol = "mfr"; + if (caplen < 2) { /* minimum frame header length */ + nd_print_trunc(ndo); + ndo->ndo_ll_hdr_len += caplen; + return; + } + + ndo->ndo_ll_hdr_len += mfr_print(ndo, p, length); } @@ -435,7 +441,7 @@ struct ie_tlv_header_t { u_int mfr_print(netdissect_options *ndo, - register const u_char *p, u_int length) + const u_char *p, u_int length) { u_int tlen,idx,hdr_len = 0; uint16_t sequence_num; @@ -456,17 +462,20 @@ mfr_print(netdissect_options *ndo, * +----+----+----+----+----+----+----+----+ */ - ND_TCHECK2(*p, 4); /* minimum frame header length */ - if (length < 4) { - ND_PRINT((ndo, "Message too short (%u bytes)", length)); + ndo->ndo_protocol = "mfr"; + + if (length < 4) { /* minimum frame header length */ + ND_PRINT("[length %u < 4]", length); + nd_print_invalid(ndo); return length; } + ND_TCHECK_4(p); - if ((p[0] & MFR_BEC_MASK) == MFR_CTRL_FRAME && p[1] == 0) { - ND_PRINT((ndo, "FRF.16 Control, Flags [%s], %s, length %u", - bittok2str(frf_flag_values,"none",(p[0] & MFR_BEC_MASK)), - tok2str(mfr_ctrl_msg_values,"Unknown Message (0x%02x)",p[2]), - length)); + if ((GET_U_1(p) & MFR_BEC_MASK) == MFR_CTRL_FRAME && GET_U_1(p + 1) == 0) { + ND_PRINT("FRF.16 Control, Flags [%s], %s, length %u", + bittok2str(frf_flag_values,"none",(GET_U_1(p) & MFR_BEC_MASK)), + tok2str(mfr_ctrl_msg_values,"Unknown Message (0x%02x)",GET_U_1(p + 2)), + length); tptr = p + 3; tlen = length -3; hdr_len = 3; @@ -475,20 +484,20 @@ mfr_print(netdissect_options *ndo, return hdr_len; while (tlen>sizeof(struct ie_tlv_header_t)) { - ND_TCHECK2(*tptr, sizeof(struct ie_tlv_header_t)); - ie_type=tptr[0]; - ie_len=tptr[1]; + ND_TCHECK_LEN(tptr, sizeof(struct ie_tlv_header_t)); + ie_type=GET_U_1(tptr); + ie_len=GET_U_1(tptr + 1); - ND_PRINT((ndo, "\n\tIE %s (%u), length %u: ", + ND_PRINT("\n\tIE %s (%u), length %u: ", tok2str(mfr_ctrl_ie_values,"Unknown",ie_type), ie_type, - ie_len)); + ie_len); /* infinite loop check */ if (ie_type == 0 || ie_len <= sizeof(struct ie_tlv_header_t)) return hdr_len; - ND_TCHECK2(*tptr, ie_len); + ND_TCHECK_LEN(tptr, ie_len); tptr+=sizeof(struct ie_tlv_header_t); /* tlv len includes header */ ie_len-=sizeof(struct ie_tlv_header_t); @@ -499,17 +508,18 @@ mfr_print(netdissect_options *ndo, case MFR_CTRL_IE_MAGIC_NUM: /* FRF.16.1 Section 3.4.3 Magic Number Information Element */ if (ie_len != 4) { - ND_PRINT((ndo, "(invalid length)")); + ND_PRINT("[IE data length %d != 4]", ie_len); + nd_print_invalid(ndo); break; } - ND_PRINT((ndo, "0x%08x", EXTRACT_32BITS(tptr))); + ND_PRINT("0x%08x", GET_BE_U_4(tptr)); break; case MFR_CTRL_IE_BUNDLE_ID: /* same message format */ case MFR_CTRL_IE_LINK_ID: for (idx = 0; idx < ie_len && idx < MFR_ID_STRING_MAXLEN; idx++) { - if (*(tptr+idx) != 0) /* don't print null termination */ - safeputchar(ndo, *(tptr + idx)); + if (GET_U_1(tptr + idx) != 0) /* don't print null termination */ + fn_print_char(ndo, GET_U_1(tptr + idx)); else break; } @@ -521,6 +531,7 @@ mfr_print(netdissect_options *ndo, break; } /* fall through and hexdump if no unix timestamp */ + ND_FALL_THROUGH; /* * FIXME those are the defined IEs that lack a decoder @@ -550,38 +561,38 @@ mfr_print(netdissect_options *ndo, * * 7 6 5 4 3 2 1 0 * +----+----+----+----+----+----+----+----+ - * | B | E | C=0|seq. (high 4 bits) | EA | + * | B | E | C=0|seq. (high 4 bits) | EA | * +----+----+----+----+----+----+----+----+ * | sequence (low 8 bits) | * +----+----+----+----+----+----+----+----+ - * | DLCI (6 bits) | CR | EA | + * | DLCI (6 bits) | CR | EA | * +----+----+----+----+----+----+----+----+ * | DLCI (4 bits) |FECN|BECN| DE | EA | * +----+----+----+----+----+----+----+----+ */ - sequence_num = (p[0]&0x1e)<<7 | p[1]; + sequence_num = (GET_U_1(p)&0x1e)<<7 | GET_U_1(p + 1); /* whole packet or first fragment ? */ - if ((p[0] & MFR_BEC_MASK) == MFR_FRAG_FRAME || - (p[0] & MFR_BEC_MASK) == MFR_B_BIT) { - ND_PRINT((ndo, "FRF.16 Frag, seq %u, Flags [%s], ", + if ((GET_U_1(p) & MFR_BEC_MASK) == MFR_FRAG_FRAME || + (GET_U_1(p) & MFR_BEC_MASK) == MFR_B_BIT) { + ND_PRINT("FRF.16 Frag, seq %u, Flags [%s], ", sequence_num, - bittok2str(frf_flag_values,"none",(p[0] & MFR_BEC_MASK)))); + bittok2str(frf_flag_values,"none",(GET_U_1(p) & MFR_BEC_MASK))); hdr_len = 2; fr_print(ndo, p+hdr_len,length-hdr_len); return hdr_len; } /* must be a middle or the last fragment */ - ND_PRINT((ndo, "FRF.16 Frag, seq %u, Flags [%s]", + ND_PRINT("FRF.16 Frag, seq %u, Flags [%s]", sequence_num, - bittok2str(frf_flag_values,"none",(p[0] & MFR_BEC_MASK)))); + bittok2str(frf_flag_values,"none",(GET_U_1(p) & MFR_BEC_MASK))); print_unknown_data(ndo, p, "\n\t", length); return hdr_len; - trunc: - ND_PRINT((ndo, "[|mfr]")); +trunc: + nd_print_trunc(ndo); return length; } @@ -610,29 +621,28 @@ frf15_print(netdissect_options *ndo, if (length < 2) goto trunc; - ND_TCHECK2(*p, 2); - flags = p[0]&MFR_BEC_MASK; - sequence_num = (p[0]&0x1e)<<7 | p[1]; + flags = GET_U_1(p)&MFR_BEC_MASK; + sequence_num = (GET_U_1(p)&0x1e)<<7 | GET_U_1(p + 1); - ND_PRINT((ndo, "FRF.15, seq 0x%03x, Flags [%s],%s Fragmentation, length %u", + ND_PRINT("FRF.15, seq 0x%03x, Flags [%s],%s Fragmentation, length %u", sequence_num, bittok2str(frf_flag_values,"none",flags), - p[0]&FR_FRF15_FRAGTYPE ? "Interface" : "End-to-End", - length)); + GET_U_1(p)&FR_FRF15_FRAGTYPE ? "Interface" : "End-to-End", + length); /* TODO: * depending on all permutations of the B, E and C bit * dig as deep as we can - e.g. on the first (B) fragment * there is enough payload to print the IP header * on non (B) fragments it depends if the fragmentation - * model is end-to-end or interface based wether we want to print + * model is end-to-end or interface based whether we want to print * another Q.922 header */ return; trunc: - ND_PRINT((ndo, "[|frf.15]")); + nd_print_trunc(ndo); } /* @@ -808,12 +818,13 @@ q933_print(netdissect_options *ndo, u_int non_locking_shift; u_int unshift_codeset; - ND_PRINT((ndo, "%s", ndo->ndo_eflag ? "" : "Q.933")); + ndo->ndo_protocol = "q.933"; + ND_PRINT("%s", ndo->ndo_eflag ? "" : "Q.933"); - if (length == 0 || !ND_TTEST(*p)) { + if (length == 0 || !ND_TTEST_1(p)) { if (!ndo->ndo_eflag) - ND_PRINT((ndo, ", ")); - ND_PRINT((ndo, "length %u", length)); + ND_PRINT(", "); + ND_PRINT("length %u", length); goto trunc; } @@ -821,7 +832,7 @@ q933_print(netdissect_options *ndo, * Get the length of the call reference value. */ olen = length; /* preserve the original length for display */ - call_ref_length = (*p) & 0x0f; + call_ref_length = GET_U_1(p) & 0x0f; p++; length--; @@ -829,13 +840,13 @@ q933_print(netdissect_options *ndo, * Get the call reference value. */ for (i = 0; i < call_ref_length; i++) { - if (length == 0 || !ND_TTEST(*p)) { + if (length == 0 || !ND_TTEST_1(p)) { if (!ndo->ndo_eflag) - ND_PRINT((ndo, ", ")); - ND_PRINT((ndo, "length %u", olen)); + ND_PRINT(", "); + ND_PRINT("length %u", olen); goto trunc; } - call_ref[i] = *p; + call_ref[i] = GET_U_1(p); p++; length--; } @@ -843,13 +854,13 @@ q933_print(netdissect_options *ndo, /* * Get the message type. */ - if (length == 0 || !ND_TTEST(*p)) { + if (length == 0 || !ND_TTEST_1(p)) { if (!ndo->ndo_eflag) - ND_PRINT((ndo, ", ")); - ND_PRINT((ndo, "length %u", olen)); + ND_PRINT(", "); + ND_PRINT("length %u", olen); goto trunc; } - msgtype = *p; + msgtype = GET_U_1(p); p++; length--; @@ -859,13 +870,13 @@ q933_print(netdissect_options *ndo, non_locking_shift = 0; unshift_codeset = codeset; if (length != 0) { - if (!ND_TTEST(*p)) { + if (!ND_TTEST_1(p)) { if (!ndo->ndo_eflag) - ND_PRINT((ndo, ", ")); - ND_PRINT((ndo, "length %u", olen)); + ND_PRINT(", "); + ND_PRINT("length %u", olen); goto trunc; } - iecode = *p; + iecode = GET_U_1(p); if (IE_IS_SHIFT(iecode)) { /* * It's a shift. Skip over it. @@ -911,30 +922,29 @@ q933_print(netdissect_options *ndo, /* printing out header part */ if (!ndo->ndo_eflag) - ND_PRINT((ndo, ", ")); - ND_PRINT((ndo, "%s, codeset %u", is_ansi ? "ANSI" : "CCITT", codeset)); + ND_PRINT(", "); + ND_PRINT("%s, codeset %u", is_ansi ? "ANSI" : "CCITT", codeset); if (call_ref_length != 0) { - ND_TCHECK(p[0]); - if (call_ref_length > 1 || p[0] != 0) { + if (call_ref_length > 1 || GET_U_1(p) != 0) { /* * Not a dummy call reference. */ - ND_PRINT((ndo, ", Call Ref: 0x")); + ND_PRINT(", Call Ref: 0x"); for (i = 0; i < call_ref_length; i++) - ND_PRINT((ndo, "%02x", call_ref[i])); + ND_PRINT("%02x", call_ref[i]); } } if (ndo->ndo_vflag) { - ND_PRINT((ndo, ", %s (0x%02x), length %u", + ND_PRINT(", %s (0x%02x), length %u", tok2str(fr_q933_msg_values, "unknown message", msgtype), msgtype, - olen)); + olen); } else { - ND_PRINT((ndo, ", %s", + ND_PRINT(", %s", tok2str(fr_q933_msg_values, - "unknown message 0x%02x", msgtype))); + "unknown message 0x%02x", msgtype)); } /* Loop through the rest of the IEs */ @@ -960,13 +970,13 @@ q933_print(netdissect_options *ndo, /* * Get the first octet of the IE. */ - if (!ND_TTEST(*p)) { + if (!ND_TTEST_1(p)) { if (!ndo->ndo_vflag) { - ND_PRINT((ndo, ", length %u", olen)); + ND_PRINT(", length %u", olen); } goto trunc; } - iecode = *p; + iecode = GET_U_1(p); p++; length--; @@ -1003,13 +1013,13 @@ q933_print(netdissect_options *ndo, /* * No. Get the IE length. */ - if (length == 0 || !ND_TTEST(*p)) { + if (length == 0 || !ND_TTEST_1(p)) { if (!ndo->ndo_vflag) { - ND_PRINT((ndo, ", length %u", olen)); + ND_PRINT(", length %u", olen); } goto trunc; } - ielength = *p; + ielength = GET_U_1(p); p++; length--; @@ -1017,20 +1027,20 @@ q933_print(netdissect_options *ndo, * however some IEs (DLCI Status, Link Verify) * are also interesting in non-verbose mode */ if (ndo->ndo_vflag) { - ND_PRINT((ndo, "\n\t%s IE (0x%02x), length %u: ", + ND_PRINT("\n\t%s IE (0x%02x), length %u: ", tok2str(fr_q933_ie_codesets[codeset], "unknown", iecode), iecode, - ielength)); + ielength); } /* sanity checks */ if (iecode == 0 || ielength == 0) { return; } - if (length < ielength || !ND_TTEST2(*p, ielength)) { + if (length < ielength || !ND_TTEST_LEN(p, ielength)) { if (!ndo->ndo_vflag) { - ND_PRINT((ndo, ", length %u", olen)); + ND_PRINT(", length %u", olen); } goto trunc; } @@ -1064,12 +1074,12 @@ q933_print(netdissect_options *ndo, } } if (!ndo->ndo_vflag) { - ND_PRINT((ndo, ", length %u", olen)); + ND_PRINT(", length %u", olen); } return; trunc: - ND_PRINT((ndo, "[|q.933]")); + nd_print_trunc(ndo); } static int @@ -1084,15 +1094,15 @@ fr_q933_print_ie_codeset_0_5(netdissect_options *ndo, u_int iecode, case FR_LMI_CCITT_REPORT_TYPE_IE: if (ielength < 1) { if (!ndo->ndo_vflag) { - ND_PRINT((ndo, ", ")); + ND_PRINT(", "); } - ND_PRINT((ndo, "Invalid REPORT TYPE IE")); + ND_PRINT("Invalid REPORT TYPE IE"); return 1; } if (ndo->ndo_vflag) { - ND_PRINT((ndo, "%s (%u)", - tok2str(fr_lmi_report_type_ie_values,"unknown",p[0]), - p[0])); + ND_PRINT("%s (%u)", + tok2str(fr_lmi_report_type_ie_values,"unknown",GET_U_1(p)), + GET_U_1(p)); } return 1; @@ -1100,52 +1110,48 @@ fr_q933_print_ie_codeset_0_5(netdissect_options *ndo, u_int iecode, case FR_LMI_CCITT_LINK_VERIFY_IE: case FR_LMI_ANSI_LINK_VERIFY_IE_91: if (!ndo->ndo_vflag) { - ND_PRINT((ndo, ", ")); + ND_PRINT(", "); } if (ielength < 2) { - ND_PRINT((ndo, "Invalid LINK VERIFY IE")); + ND_PRINT("Invalid LINK VERIFY IE"); return 1; } - ND_PRINT((ndo, "TX Seq: %3d, RX Seq: %3d", p[0], p[1])); + ND_PRINT("TX Seq: %3d, RX Seq: %3d", GET_U_1(p), GET_U_1(p + 1)); return 1; case FR_LMI_ANSI_PVC_STATUS_IE: /* fall through */ case FR_LMI_CCITT_PVC_STATUS_IE: if (!ndo->ndo_vflag) { - ND_PRINT((ndo, ", ")); + ND_PRINT(", "); } /* now parse the DLCI information element. */ if ((ielength < 3) || - (p[0] & 0x80) || - ((ielength == 3) && !(p[1] & 0x80)) || - ((ielength == 4) && ((p[1] & 0x80) || !(p[2] & 0x80))) || - ((ielength == 5) && ((p[1] & 0x80) || (p[2] & 0x80) || - !(p[3] & 0x80))) || + (GET_U_1(p) & 0x80) || + ((ielength == 3) && !(GET_U_1(p + 1) & 0x80)) || + ((ielength == 4) && + ((GET_U_1(p + 1) & 0x80) || !(GET_U_1(p + 2) & 0x80))) || + ((ielength == 5) && + ((GET_U_1(p + 1) & 0x80) || (GET_U_1(p + 2) & 0x80) || + !(GET_U_1(p + 3) & 0x80))) || (ielength > 5) || - !(p[ielength - 1] & 0x80)) { - ND_PRINT((ndo, "Invalid DLCI in PVC STATUS IE")); + !(GET_U_1(p + ielength - 1) & 0x80)) { + ND_PRINT("Invalid DLCI in PVC STATUS IE"); return 1; } - dlci = ((p[0] & 0x3F) << 4) | ((p[1] & 0x78) >> 3); + dlci = ((GET_U_1(p) & 0x3F) << 4) | ((GET_U_1(p + 1) & 0x78) >> 3); if (ielength == 4) { - dlci = (dlci << 6) | ((p[2] & 0x7E) >> 1); + dlci = (dlci << 6) | ((GET_U_1(p + 2) & 0x7E) >> 1); } else if (ielength == 5) { - dlci = (dlci << 13) | (p[2] & 0x7F) | ((p[3] & 0x7E) >> 1); + dlci = (dlci << 13) | (GET_U_1(p + 2) & 0x7F) | ((GET_U_1(p + 3) & 0x7E) >> 1); } - ND_PRINT((ndo, "DLCI %u: status %s%s", dlci, - p[ielength - 1] & 0x8 ? "New, " : "", - p[ielength - 1] & 0x2 ? "Active" : "Inactive")); + ND_PRINT("DLCI %u: status %s%s", dlci, + GET_U_1(p + ielength - 1) & 0x8 ? "New, " : "", + GET_U_1(p + ielength - 1) & 0x2 ? "Active" : "Inactive"); return 1; } return 0; } -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/print-frag6.c b/contrib/tcpdump/print-frag6.c index fbcabc5b00..16e8a4b219 100644 --- a/contrib/tcpdump/print-frag6.c +++ b/contrib/tcpdump/print-frag6.c @@ -22,10 +22,10 @@ /* \summary: IPv6 fragmentation header printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "extract.h" @@ -33,38 +33,34 @@ #include "ip6.h" int -frag6_print(netdissect_options *ndo, register const u_char *bp, register const u_char *bp2) +frag6_print(netdissect_options *ndo, const u_char *bp, const u_char *bp2) { - register const struct ip6_frag *dp; - register const struct ip6_hdr *ip6; + const struct ip6_frag *dp; + const struct ip6_hdr *ip6; + ndo->ndo_protocol = "frag6"; dp = (const struct ip6_frag *)bp; ip6 = (const struct ip6_hdr *)bp2; - ND_TCHECK(*dp); - if (ndo->ndo_vflag) { - ND_PRINT((ndo, "frag (0x%08x:%d|%ld)", - EXTRACT_32BITS(&dp->ip6f_ident), - EXTRACT_16BITS(&dp->ip6f_offlg) & IP6F_OFF_MASK, - sizeof(struct ip6_hdr) + EXTRACT_16BITS(&ip6->ip6_plen) - - (long)(bp - bp2) - sizeof(struct ip6_frag))); + ND_PRINT("frag (0x%08x:%u|%zu)", + GET_BE_U_4(dp->ip6f_ident), + GET_BE_U_2(dp->ip6f_offlg) & IP6F_OFF_MASK, + sizeof(struct ip6_hdr) + GET_BE_U_2(ip6->ip6_plen) - + (bp - bp2) - sizeof(struct ip6_frag)); } else { - ND_PRINT((ndo, "frag (%d|%ld)", - EXTRACT_16BITS(&dp->ip6f_offlg) & IP6F_OFF_MASK, - sizeof(struct ip6_hdr) + EXTRACT_16BITS(&ip6->ip6_plen) - - (long)(bp - bp2) - sizeof(struct ip6_frag))); + ND_PRINT("frag (%u|%zu)", + GET_BE_U_2(dp->ip6f_offlg) & IP6F_OFF_MASK, + sizeof(struct ip6_hdr) + GET_BE_U_2(ip6->ip6_plen) - + (bp - bp2) - sizeof(struct ip6_frag)); } /* it is meaningless to decode non-first fragment */ - if ((EXTRACT_16BITS(&dp->ip6f_offlg) & IP6F_OFF_MASK) != 0) + if ((GET_BE_U_2(dp->ip6f_offlg) & IP6F_OFF_MASK) != 0) return -1; else { - ND_PRINT((ndo, " ")); + ND_PRINT(" "); return sizeof(struct ip6_frag); } -trunc: - ND_PRINT((ndo, "[|frag]")); - return -1; } diff --git a/contrib/tcpdump/print-ftp.c b/contrib/tcpdump/print-ftp.c index a1dd60709a..b55937bba1 100644 --- a/contrib/tcpdump/print-ftp.c +++ b/contrib/tcpdump/print-ftp.c @@ -14,19 +14,16 @@ /* \summary: File Transfer Protocol (FTP) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include - -#include -#include +#include "netdissect-stdinc.h" #include "netdissect.h" -#include "extract.h" void ftp_print(netdissect_options *ndo, const u_char *pptr, u_int len) { - txtproto_print(ndo, pptr, len, "ftp", NULL, 0); + ndo->ndo_protocol = "ftp"; + txtproto_print(ndo, pptr, len, NULL, 0); } diff --git a/contrib/tcpdump/print-geneve.c b/contrib/tcpdump/print-geneve.c index 40402ab420..0b7ff6e514 100644 --- a/contrib/tcpdump/print-geneve.c +++ b/contrib/tcpdump/print-geneve.c @@ -18,10 +18,10 @@ /* \summary: Generic Network Virtualization Encapsulation (Geneve) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "extract.h" @@ -109,19 +109,19 @@ geneve_opts_print(netdissect_options *ndo, const u_char *bp, u_int len) uint8_t opt_type; uint8_t opt_len; - ND_PRINT((ndo, "%s", sep)); + ND_PRINT("%s", sep); sep = ", "; - opt_class = EXTRACT_16BITS(bp); - opt_type = *(bp + 2); - opt_len = 4 + ((*(bp + 3) & OPT_LEN_MASK) * 4); + opt_class = GET_BE_U_2(bp); + opt_type = GET_U_1(bp + 2); + opt_len = 4 + ((GET_U_1(bp + 3) & OPT_LEN_MASK) * 4); - ND_PRINT((ndo, "class %s (0x%x) type 0x%x%s len %u", + ND_PRINT("class %s (0x%x) type 0x%x%s len %u", format_opt_class(opt_class), opt_class, opt_type, - opt_type & OPT_TYPE_CRITICAL ? "(C)" : "", opt_len)); + opt_type & OPT_TYPE_CRITICAL ? "(C)" : "", opt_len); if (opt_len > len) { - ND_PRINT((ndo, " [bad length]")); + ND_PRINT(" [bad length]"); return; } @@ -129,10 +129,10 @@ geneve_opts_print(netdissect_options *ndo, const u_char *bp, u_int len) const uint32_t *data = (const uint32_t *)(bp + 4); int i; - ND_PRINT((ndo, " data")); + ND_PRINT(" data"); for (i = 4; i < opt_len; i += 4) { - ND_PRINT((ndo, " %08x", EXTRACT_32BITS(data))); + ND_PRINT(" %08x", GET_BE_U_4(data)); data++; } } @@ -153,85 +153,92 @@ geneve_print(netdissect_options *ndo, const u_char *bp, u_int len) uint8_t reserved; u_int opts_len; - ND_PRINT((ndo, "Geneve")); + ndo->ndo_protocol = "geneve"; + ND_PRINT("Geneve"); - ND_TCHECK2(*bp, 8); + if (len < 8) { + ND_PRINT(" [length %u < 8]", len); + nd_print_invalid(ndo); + return; + } + + ND_TCHECK_8(bp); - ver_opt = *bp; + ver_opt = GET_U_1(bp); bp += 1; len -= 1; version = ver_opt >> VER_SHIFT; if (version != 0) { - ND_PRINT((ndo, " ERROR: unknown-version %u", version)); + ND_PRINT(" ERROR: unknown-version %u", version); return; } - flags = *bp; + flags = GET_U_1(bp); bp += 1; len -= 1; - prot = EXTRACT_16BITS(bp); + prot = GET_BE_U_2(bp); bp += 2; len -= 2; - vni = EXTRACT_24BITS(bp); + vni = GET_BE_U_3(bp); bp += 3; len -= 3; - reserved = *bp; + reserved = GET_U_1(bp); bp += 1; len -= 1; - ND_PRINT((ndo, ", Flags [%s]", - bittok2str_nosep(geneve_flag_values, "none", flags))); - ND_PRINT((ndo, ", vni 0x%x", vni)); + ND_PRINT(", Flags [%s]", + bittok2str_nosep(geneve_flag_values, "none", flags)); + ND_PRINT(", vni 0x%x", vni); if (reserved) - ND_PRINT((ndo, ", rsvd 0x%x", reserved)); + ND_PRINT(", rsvd 0x%x", reserved); if (ndo->ndo_eflag) - ND_PRINT((ndo, ", proto %s (0x%04x)", - tok2str(ethertype_values, "unknown", prot), prot)); + ND_PRINT(", proto %s (0x%04x)", + tok2str(ethertype_values, "unknown", prot), prot); opts_len = (ver_opt & HDR_OPTS_LEN_MASK) * 4; if (len < opts_len) { - ND_PRINT((ndo, " truncated-geneve - %u bytes missing", - opts_len - len)); + ND_PRINT(" truncated-geneve - %u bytes missing", + opts_len - len); return; } - ND_TCHECK2(*bp, opts_len); + ND_TCHECK_LEN(bp, opts_len); if (opts_len > 0) { - ND_PRINT((ndo, ", options [")); + ND_PRINT(", options ["); if (ndo->ndo_vflag) geneve_opts_print(ndo, bp, opts_len); else - ND_PRINT((ndo, "%u bytes", opts_len)); + ND_PRINT("%u bytes", opts_len); - ND_PRINT((ndo, "]")); + ND_PRINT("]"); } bp += opts_len; len -= opts_len; if (ndo->ndo_vflag < 1) - ND_PRINT((ndo, ": ")); + ND_PRINT(": "); else - ND_PRINT((ndo, "\n\t")); + ND_PRINT("\n\t"); - if (ethertype_print(ndo, prot, bp, len, ndo->ndo_snapend - bp, NULL, NULL) == 0) { + if (ethertype_print(ndo, prot, bp, len, ND_BYTES_AVAILABLE_AFTER(bp), NULL, NULL) == 0) { if (prot == ETHERTYPE_TEB) - ether_print(ndo, bp, len, ndo->ndo_snapend - bp, NULL, NULL); + ether_print(ndo, bp, len, ND_BYTES_AVAILABLE_AFTER(bp), NULL, NULL); else - ND_PRINT((ndo, "geneve-proto-0x%x", prot)); + ND_PRINT("geneve-proto-0x%x", prot); } return; trunc: - ND_PRINT((ndo, " [|geneve]")); + nd_print_trunc(ndo); } diff --git a/contrib/tcpdump/print-geonet.c b/contrib/tcpdump/print-geonet.c index 9da89bfe81..2f8046e6b9 100644 --- a/contrib/tcpdump/print-geonet.c +++ b/contrib/tcpdump/print-geonet.c @@ -18,11 +18,12 @@ /* \summary: ISO CALM FAST and ETSI GeoNetworking printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" #include "addrtoname.h" @@ -57,46 +58,34 @@ static const struct tok msg_type_values[] = { static void print_btp_body(netdissect_options *ndo, - const u_char *bp) + const u_char *bp) { - int version; - int msg_type; - const char *msg_type_str; + u_int msg_type; - /* Assuming ItsDpuHeader */ - version = bp[0]; - msg_type = bp[1]; - msg_type_str = tok2str(msg_type_values, "unknown (%u)", msg_type); + /* Assuming ItsPduHeader */ + ND_PRINT("; ItsPduHeader v:%u", GET_U_1(bp)); - ND_PRINT((ndo, "; ItsPduHeader v:%d t:%d-%s", version, msg_type, msg_type_str)); + msg_type = GET_U_1(bp + 1); + ND_PRINT(" t:%u-%s", msg_type, + tok2str(msg_type_values, "unknown (%u)", msg_type)); } +/* EN 302 636-5-1 V2.2.1 Section 7.2: BTP-A header */ static void print_btp(netdissect_options *ndo, - const u_char *bp) + const u_char *bp) { - uint16_t dest = EXTRACT_16BITS(bp+0); - uint16_t src = EXTRACT_16BITS(bp+2); - ND_PRINT((ndo, "; BTP Dst:%u Src:%u", dest, src)); + ND_PRINT("; BTP Dst:%u", GET_BE_U_2(bp + 0)); + ND_PRINT(" Src:%u", GET_BE_U_2(bp + 2)); } -static int +static void print_long_pos_vector(netdissect_options *ndo, - const u_char *bp) + const u_char *bp) { - uint32_t lat, lon; - - if (!ND_TTEST2(*bp, GEONET_ADDR_LEN)) - return (-1); - ND_PRINT((ndo, "GN_ADDR:%s ", linkaddr_string (ndo, bp, 0, GEONET_ADDR_LEN))); - - if (!ND_TTEST2(*(bp+12), 8)) - return (-1); - lat = EXTRACT_32BITS(bp+12); - ND_PRINT((ndo, "lat:%d ", lat)); - lon = EXTRACT_32BITS(bp+16); - ND_PRINT((ndo, "lon:%d", lon)); - return (0); + ND_PRINT("GN_ADDR:%s ", GET_LINKADDR_STRING(bp, LINKADDR_OTHER, GEONET_ADDR_LEN)); + ND_PRINT("lat:%u ", GET_BE_U_4(bp + 12)); + ND_PRINT("lon:%u", GET_BE_U_4(bp + 16)); } @@ -108,32 +97,34 @@ void geonet_print(netdissect_options *ndo, const u_char *bp, u_int length, const struct lladdr_info *src) { - int version; - int next_hdr; - int hdr_type; - int hdr_subtype; + u_int version; + u_int next_hdr; + u_int hdr_type; + u_int hdr_subtype; uint16_t payload_length; - int hop_limit; + u_int hop_limit; const char *next_hdr_txt = "Unknown"; const char *hdr_type_txt = "Unknown"; int hdr_size = -1; - ND_PRINT((ndo, "GeoNet ")); + ndo->ndo_protocol = "geonet"; + ND_PRINT("GeoNet "); if (src != NULL) - ND_PRINT((ndo, "src:%s", (src->addr_string)(ndo, src->addr))); - ND_PRINT((ndo, "; ")); + ND_PRINT("src:%s", (src->addr_string)(ndo, src->addr)); + ND_PRINT("; "); /* Process Common Header */ - if (length < 36) + if (length < 36) { + ND_PRINT(" (common header length %u < 36)", length); goto invalid; + } - ND_TCHECK2(*bp, 8); - version = bp[0] >> 4; - next_hdr = bp[0] & 0x0f; - hdr_type = bp[1] >> 4; - hdr_subtype = bp[1] & 0x0f; - payload_length = EXTRACT_16BITS(bp+4); - hop_limit = bp[7]; + version = GET_U_1(bp) >> 4; + next_hdr = GET_U_1(bp) & 0x0f; + hdr_type = GET_U_1(bp + 1) >> 4; + hdr_subtype = GET_U_1(bp + 1) & 0x0f; + payload_length = GET_BE_U_2(bp + 4); + hop_limit = GET_U_1(bp + 7); switch (next_hdr) { case 0: next_hdr_txt = "Any"; break; @@ -170,15 +161,15 @@ geonet_print(netdissect_options *ndo, const u_char *bp, u_int length, break; } - ND_PRINT((ndo, "v:%d ", version)); - ND_PRINT((ndo, "NH:%d-%s ", next_hdr, next_hdr_txt)); - ND_PRINT((ndo, "HT:%d-%d-%s ", hdr_type, hdr_subtype, hdr_type_txt)); - ND_PRINT((ndo, "HopLim:%d ", hop_limit)); - ND_PRINT((ndo, "Payload:%d ", payload_length)); - if (print_long_pos_vector(ndo, bp + 8) == -1) - goto trunc; + ND_PRINT("v:%u ", version); + ND_PRINT("NH:%u-%s ", next_hdr, next_hdr_txt); + ND_PRINT("HT:%u-%u-%s ", hdr_type, hdr_subtype, hdr_type_txt); + ND_PRINT("HopLim:%u ", hop_limit); + ND_PRINT("Payload:%u ", payload_length); + print_long_pos_vector(ndo, bp + 8); /* Skip Common Header */ + ND_TCHECK_LEN(bp, 36); length -= 36; bp += 36; @@ -230,9 +221,11 @@ geonet_print(netdissect_options *ndo, const u_char *bp, u_int length, /* Skip Extended headers */ if (hdr_size >= 0) { - if (length < (u_int)hdr_size) + if (length < (u_int)hdr_size) { + ND_PRINT(" (header size %d > %u)", hdr_size, length); goto invalid; - ND_TCHECK2(*bp, hdr_size); + } + ND_TCHECK_LEN(bp, hdr_size); length -= hdr_size; bp += hdr_size; switch (next_hdr) { @@ -240,9 +233,10 @@ geonet_print(netdissect_options *ndo, const u_char *bp, u_int length, break; case 1: case 2: /* BTP A/B */ - if (length < 4) + if (length < 4) { + ND_PRINT(" (BTP length %u < 4)", length); goto invalid; - ND_TCHECK2(*bp, 4); + } print_btp(ndo, bp); length -= 4; bp += 4; @@ -254,7 +248,6 @@ geonet_print(netdissect_options *ndo, const u_char *bp, u_int length, * or was that just not * reporting genuine errors? */ - ND_TCHECK2(*bp, 2); print_btp_body(ndo, bp); } break; @@ -269,18 +262,6 @@ geonet_print(netdissect_options *ndo, const u_char *bp, u_int length, return; invalid: - ND_PRINT((ndo, " Malformed (small) ")); + nd_print_invalid(ndo); /* XXX - print the remaining data as hex? */ - return; - -trunc: - ND_PRINT((ndo, "[|geonet]")); } - - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/print-gre.c b/contrib/tcpdump/print-gre.c index 0c13d2a757..b1a814298b 100644 --- a/contrib/tcpdump/print-gre.c +++ b/contrib/tcpdump/print-gre.c @@ -12,11 +12,6 @@ * 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 Jason L. Wright - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -39,26 +34,22 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include - -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "addrtostr.h" #include "extract.h" #include "ethertype.h" -static const char tstr[] = "[|gre]"; #define GRE_CP 0x8000 /* checksum present */ #define GRE_RP 0x4000 /* routing present */ #define GRE_KP 0x2000 /* key present */ #define GRE_SP 0x1000 /* sequence# present */ #define GRE_sP 0x0800 /* source routing */ -#define GRE_RECRS 0x0700 /* recursion count */ #define GRE_AP 0x0080 /* acknowledgment# present */ static const struct tok gre_flag_values[] = { @@ -67,11 +58,11 @@ static const struct tok gre_flag_values[] = { { GRE_KP, "key present"}, { GRE_SP, "sequence# present"}, { GRE_sP, "source routing present"}, - { GRE_RECRS, "recursion count"}, { GRE_AP, "ack present"}, { 0, NULL } }; +#define GRE_RECRS_MASK 0x0700 /* recursion count */ #define GRE_VERS_MASK 0x0007 /* protocol version */ /* source route entry types */ @@ -89,28 +80,28 @@ gre_print(netdissect_options *ndo, const u_char *bp, u_int length) { u_int len = length, vers; - ND_TCHECK2(*bp, 2); + ndo->ndo_protocol = "gre"; + ND_TCHECK_2(bp); if (len < 2) goto trunc; - vers = EXTRACT_16BITS(bp) & GRE_VERS_MASK; - ND_PRINT((ndo, "GREv%u",vers)); - - switch(vers) { - case 0: - gre_print_0(ndo, bp, len); - break; - case 1: - gre_print_1(ndo, bp, len); - break; + vers = GET_BE_U_2(bp) & GRE_VERS_MASK; + ND_PRINT("GREv%u",vers); + + switch(vers) { + case 0: + gre_print_0(ndo, bp, len); + break; + case 1: + gre_print_1(ndo, bp, len); + break; default: - ND_PRINT((ndo, " ERROR: unknown-version")); - break; - } - return; + ND_PRINT(" ERROR: unknown-version"); + break; + } + return; trunc: - ND_PRINT((ndo, "%s", tstr)); - return; + nd_print_trunc(ndo); } static void @@ -119,52 +110,53 @@ gre_print_0(netdissect_options *ndo, const u_char *bp, u_int length) u_int len = length; uint16_t flags, prot; - flags = EXTRACT_16BITS(bp); - if (ndo->ndo_vflag) - ND_PRINT((ndo, ", Flags [%s]", - bittok2str(gre_flag_values,"none",flags))); + /* 16 bits ND_TCHECKed in gre_print() */ + flags = GET_BE_U_2(bp); + if (ndo->ndo_vflag) + ND_PRINT(", Flags [%s]", + bittok2str(gre_flag_values,"none",flags)); len -= 2; bp += 2; - ND_TCHECK2(*bp, 2); + ND_TCHECK_2(bp); if (len < 2) goto trunc; - prot = EXTRACT_16BITS(bp); + prot = GET_BE_U_2(bp); len -= 2; bp += 2; if ((flags & GRE_CP) | (flags & GRE_RP)) { - ND_TCHECK2(*bp, 2); + ND_TCHECK_2(bp); if (len < 2) goto trunc; if (ndo->ndo_vflag) - ND_PRINT((ndo, ", sum 0x%x", EXTRACT_16BITS(bp))); + ND_PRINT(", sum 0x%x", GET_BE_U_2(bp)); bp += 2; len -= 2; - ND_TCHECK2(*bp, 2); + ND_TCHECK_2(bp); if (len < 2) goto trunc; - ND_PRINT((ndo, ", off 0x%x", EXTRACT_16BITS(bp))); + ND_PRINT(", off 0x%x", GET_BE_U_2(bp)); bp += 2; len -= 2; } if (flags & GRE_KP) { - ND_TCHECK2(*bp, 4); + ND_TCHECK_4(bp); if (len < 4) goto trunc; - ND_PRINT((ndo, ", key=0x%x", EXTRACT_32BITS(bp))); + ND_PRINT(", key=0x%x", GET_BE_U_4(bp)); bp += 4; len -= 4; } if (flags & GRE_SP) { - ND_TCHECK2(*bp, 4); + ND_TCHECK_4(bp); if (len < 4) goto trunc; - ND_PRINT((ndo, ", seq %u", EXTRACT_32BITS(bp))); + ND_PRINT(", seq %u", GET_BE_U_4(bp)); bp += 4; len -= 4; } @@ -175,12 +167,12 @@ gre_print_0(netdissect_options *ndo, const u_char *bp, u_int length) uint8_t sreoff; uint8_t srelen; - ND_TCHECK2(*bp, 4); + ND_TCHECK_4(bp); if (len < 4) goto trunc; - af = EXTRACT_16BITS(bp); - sreoff = *(bp + 2); - srelen = *(bp + 3); + af = GET_BE_U_2(bp); + sreoff = GET_U_1(bp + 2); + srelen = GET_U_1(bp + 3); bp += 4; len -= 4; @@ -197,21 +189,20 @@ gre_print_0(netdissect_options *ndo, const u_char *bp, u_int length) } } - if (ndo->ndo_eflag) - ND_PRINT((ndo, ", proto %s (0x%04x)", - tok2str(ethertype_values,"unknown",prot), - prot)); + if (ndo->ndo_eflag) + ND_PRINT(", proto %s (0x%04x)", + tok2str(ethertype_values,"unknown",prot), prot); - ND_PRINT((ndo, ", length %u",length)); + ND_PRINT(", length %u",length); - if (ndo->ndo_vflag < 1) - ND_PRINT((ndo, ": ")); /* put in a colon as protocol demarc */ - else - ND_PRINT((ndo, "\n\t")); /* if verbose go multiline */ + if (ndo->ndo_vflag < 1) + ND_PRINT(": "); /* put in a colon as protocol demarc */ + else + ND_PRINT("\n\t"); /* if verbose go multiline */ switch (prot) { case ETHERTYPE_IP: - ip_print(ndo, bp, len); + ip_print(ndo, bp, len); break; case ETHERTYPE_IPV6: ip6_print(ndo, bp, len); @@ -229,15 +220,15 @@ gre_print_0(netdissect_options *ndo, const u_char *bp, u_int length) isoclns_print(ndo, bp, len); break; case ETHERTYPE_TEB: - ether_print(ndo, bp, len, ndo->ndo_snapend - bp, NULL, NULL); + ether_print(ndo, bp, len, ND_BYTES_AVAILABLE_AFTER(bp), NULL, NULL); break; default: - ND_PRINT((ndo, "gre-proto-0x%x", prot)); + ND_PRINT("gre-proto-0x%x", prot); } return; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); } static void @@ -246,18 +237,19 @@ gre_print_1(netdissect_options *ndo, const u_char *bp, u_int length) u_int len = length; uint16_t flags, prot; - flags = EXTRACT_16BITS(bp); + /* 16 bits ND_TCHECKed in gre_print() */ + flags = GET_BE_U_2(bp); len -= 2; bp += 2; if (ndo->ndo_vflag) - ND_PRINT((ndo, ", Flags [%s]", - bittok2str(gre_flag_values,"none",flags))); + ND_PRINT(", Flags [%s]", + bittok2str(gre_flag_values,"none",flags)); - ND_TCHECK2(*bp, 2); + ND_TCHECK_2(bp); if (len < 2) goto trunc; - prot = EXTRACT_16BITS(bp); + prot = GET_BE_U_2(bp); len -= 2; bp += 2; @@ -265,84 +257,83 @@ gre_print_1(netdissect_options *ndo, const u_char *bp, u_int length) if (flags & GRE_KP) { uint32_t k; - ND_TCHECK2(*bp, 4); + ND_TCHECK_4(bp); if (len < 4) goto trunc; - k = EXTRACT_32BITS(bp); - ND_PRINT((ndo, ", call %d", k & 0xffff)); + k = GET_BE_U_4(bp); + ND_PRINT(", call %u", k & 0xffff); len -= 4; bp += 4; } if (flags & GRE_SP) { - ND_TCHECK2(*bp, 4); + ND_TCHECK_4(bp); if (len < 4) goto trunc; - ND_PRINT((ndo, ", seq %u", EXTRACT_32BITS(bp))); + ND_PRINT(", seq %u", GET_BE_U_4(bp)); bp += 4; len -= 4; } if (flags & GRE_AP) { - ND_TCHECK2(*bp, 4); + ND_TCHECK_4(bp); if (len < 4) goto trunc; - ND_PRINT((ndo, ", ack %u", EXTRACT_32BITS(bp))); + ND_PRINT(", ack %u", GET_BE_U_4(bp)); bp += 4; len -= 4; } if ((flags & GRE_SP) == 0) - ND_PRINT((ndo, ", no-payload")); + ND_PRINT(", no-payload"); - if (ndo->ndo_eflag) - ND_PRINT((ndo, ", proto %s (0x%04x)", - tok2str(ethertype_values,"unknown",prot), - prot)); + if (ndo->ndo_eflag) + ND_PRINT(", proto %s (0x%04x)", + tok2str(ethertype_values,"unknown",prot), prot); - ND_PRINT((ndo, ", length %u",length)); + ND_PRINT(", length %u",length); - if ((flags & GRE_SP) == 0) - return; + if ((flags & GRE_SP) == 0) + return; - if (ndo->ndo_vflag < 1) - ND_PRINT((ndo, ": ")); /* put in a colon as protocol demarc */ - else - ND_PRINT((ndo, "\n\t")); /* if verbose go multiline */ + if (ndo->ndo_vflag < 1) + ND_PRINT(": "); /* put in a colon as protocol demarc */ + else + ND_PRINT("\n\t"); /* if verbose go multiline */ switch (prot) { case ETHERTYPE_PPP: ppp_print(ndo, bp, len); break; default: - ND_PRINT((ndo, "gre-proto-0x%x", prot)); + ND_PRINT("gre-proto-0x%x", prot); break; } return; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); } static int gre_sre_print(netdissect_options *ndo, uint16_t af, uint8_t sreoff, - uint8_t srelen, const u_char *bp, u_int len) + uint8_t srelen, const u_char *bp, u_int len) { int ret; switch (af) { case GRESRE_IP: - ND_PRINT((ndo, ", (rtaf=ip")); + ND_PRINT(", (rtaf=ip"); ret = gre_sre_ip_print(ndo, sreoff, srelen, bp, len); - ND_PRINT((ndo, ")")); + ND_PRINT(")"); break; case GRESRE_ASN: - ND_PRINT((ndo, ", (rtaf=asn")); + ND_PRINT(", (rtaf=asn"); ret = gre_sre_asn_print(ndo, sreoff, srelen, bp, len); - ND_PRINT((ndo, ")")); + ND_PRINT(")"); break; default: - ND_PRINT((ndo, ", (rtaf=0x%x)", af)); + ND_PRINT(", (rtaf=0x%x)", af); ret = 1; } return (ret); @@ -350,73 +341,74 @@ gre_sre_print(netdissect_options *ndo, uint16_t af, uint8_t sreoff, static int gre_sre_ip_print(netdissect_options *ndo, uint8_t sreoff, uint8_t srelen, - const u_char *bp, u_int len) + const u_char *bp, u_int len) { const u_char *up = bp; char buf[INET_ADDRSTRLEN]; if (sreoff & 3) { - ND_PRINT((ndo, ", badoffset=%u", sreoff)); + ND_PRINT(", badoffset=%u", sreoff); return (1); } if (srelen & 3) { - ND_PRINT((ndo, ", badlength=%u", srelen)); + ND_PRINT(", badlength=%u", srelen); return (1); } if (sreoff >= srelen) { - ND_PRINT((ndo, ", badoff/len=%u/%u", sreoff, srelen)); + ND_PRINT(", badoff/len=%u/%u", sreoff, srelen); return (1); } while (srelen != 0) { - if (!ND_TTEST2(*bp, 4)) - return (0); + ND_TCHECK_4(bp); if (len < 4) return (0); addrtostr(bp, buf, sizeof(buf)); - ND_PRINT((ndo, " %s%s", - ((bp - up) == sreoff) ? "*" : "", buf)); + ND_PRINT(" %s%s", + ((bp - up) == sreoff) ? "*" : "", buf); bp += 4; len -= 4; srelen -= 4; } return (1); +trunc: + return 0; } static int gre_sre_asn_print(netdissect_options *ndo, uint8_t sreoff, uint8_t srelen, - const u_char *bp, u_int len) + const u_char *bp, u_int len) { const u_char *up = bp; if (sreoff & 1) { - ND_PRINT((ndo, ", badoffset=%u", sreoff)); + ND_PRINT(", badoffset=%u", sreoff); return (1); } if (srelen & 1) { - ND_PRINT((ndo, ", badlength=%u", srelen)); + ND_PRINT(", badlength=%u", srelen); return (1); } if (sreoff >= srelen) { - ND_PRINT((ndo, ", badoff/len=%u/%u", sreoff, srelen)); + ND_PRINT(", badoff/len=%u/%u", sreoff, srelen); return (1); } while (srelen != 0) { - if (!ND_TTEST2(*bp, 2)) - return (0); + ND_TCHECK_2(bp); if (len < 2) return (0); - ND_PRINT((ndo, " %s%x", - ((bp - up) == sreoff) ? "*" : "", - EXTRACT_16BITS(bp))); + ND_PRINT(" %s%x", + ((bp - up) == sreoff) ? "*" : "", GET_BE_U_2(bp)); bp += 2; len -= 2; srelen -= 2; } return (1); +trunc: + return 0; } diff --git a/contrib/tcpdump/print-hncp.c b/contrib/tcpdump/print-hncp.c index c20d1e1a42..b288160d6e 100644 --- a/contrib/tcpdump/print-hncp.c +++ b/contrib/tcpdump/print-hncp.c @@ -29,12 +29,11 @@ /* \summary: Home Networking Control Protocol (HNCP) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" -#include #include #include "netdissect.h" @@ -49,7 +48,8 @@ void hncp_print(netdissect_options *ndo, const u_char *cp, u_int length) { - ND_PRINT((ndo, "hncp (%d)", length)); + ndo->ndo_protocol = "hncp"; + ND_PRINT("hncp (%u)", length); hncp_print_rec(ndo, cp, length, 1); } @@ -145,7 +145,7 @@ static const struct tok dh6opt_str[] = { /* * Is an IPv6 address an IPv4-mapped address? */ -static inline int +static int is_ipv4_mapped_address(const u_char *addr) { /* The value of the prefix */ @@ -156,27 +156,28 @@ is_ipv4_mapped_address(const u_char *addr) } static const char * -format_nid(const u_char *data) +format_nid(netdissect_options *ndo, const u_char *data) { static char buf[4][sizeof("01:01:01:01")]; static int i = 0; i = (i + 1) % 4; snprintf(buf[i], sizeof(buf[i]), "%02x:%02x:%02x:%02x", - data[0], data[1], data[2], data[3]); + GET_U_1(data), GET_U_1(data + 1), GET_U_1(data + 2), + GET_U_1(data + 3)); return buf[i]; } static const char * -format_256(const u_char *data) +format_256(netdissect_options *ndo, const u_char *data) { static char buf[4][sizeof("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")]; static int i = 0; i = (i + 1) % 4; snprintf(buf[i], sizeof(buf[i]), "%016" PRIx64 "%016" PRIx64 "%016" PRIx64 "%016" PRIx64, - EXTRACT_64BITS(data), - EXTRACT_64BITS(data + 8), - EXTRACT_64BITS(data + 16), - EXTRACT_64BITS(data + 24) + GET_BE_U_8(data), + GET_BE_U_8(data + 8), + GET_BE_U_8(data + 16), + GET_BE_U_8(data + 24) ); return buf[i]; } @@ -195,9 +196,9 @@ static const char * format_ip6addr(netdissect_options *ndo, const u_char *cp) { if (is_ipv4_mapped_address(cp)) - return ipaddr_string(ndo, cp + IPV4_MAPPED_HEADING_LEN); + return GET_IPADDR_STRING(cp + IPV4_MAPPED_HEADING_LEN); else - return ip6addr_string(ndo, cp); + return GET_IP6ADDR_STRING(cp); } static int @@ -206,12 +207,12 @@ print_prefix(netdissect_options *ndo, const u_char *prefix, u_int max_length) int plenbytes; char buf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx::/128")]; - if (prefix[0] >= 96 && max_length >= IPV4_MAPPED_HEADING_LEN + 1 && - is_ipv4_mapped_address(&prefix[1])) { - struct in_addr addr; + if (GET_U_1(prefix) >= 96 && max_length >= IPV4_MAPPED_HEADING_LEN + 1 && + is_ipv4_mapped_address(prefix + 1)) { + nd_ipv4 addr; u_int plen; - plen = prefix[0]-96; + plen = GET_U_1(prefix) - 96; if (32 < plen) return -1; max_length -= 1; @@ -220,12 +221,12 @@ print_prefix(netdissect_options *ndo, const u_char *prefix, u_int max_length) plenbytes = (plen + 7) / 8; if (max_length < (u_int)plenbytes + IPV4_MAPPED_HEADING_LEN) return -3; - memcpy(&addr, &prefix[1 + IPV4_MAPPED_HEADING_LEN], plenbytes); + memcpy(&addr, prefix + IPV4_MAPPED_HEADING_LEN + 1, plenbytes); if (plen % 8) { ((u_char *)&addr)[plenbytes - 1] &= ((0xff00 >> (plen % 8)) & 0xff); } - snprintf(buf, sizeof(buf), "%s/%d", ipaddr_string(ndo, &addr), plen); + snprintf(buf, sizeof(buf), "%s/%u", ipaddr_string(ndo, (const u_char *)&addr), plen); plenbytes += 1 + IPV4_MAPPED_HEADING_LEN; } else { plenbytes = decode_prefix6(ndo, prefix, max_length, buf, sizeof(buf)); @@ -233,7 +234,7 @@ print_prefix(netdissect_options *ndo, const u_char *prefix, u_int max_length) return plenbytes; } - ND_PRINT((ndo, "%s", buf)); + ND_PRINT("%s", buf); return plenbytes; } @@ -243,22 +244,23 @@ print_dns_label(netdissect_options *ndo, { u_int length = 0; while (length < max_length) { - u_int lab_length = cp[length++]; + u_int lab_length = GET_U_1(cp + length); + length++; if (lab_length == 0) return (int)length; if (length > 1 && print) - safeputchar(ndo, '.'); + ND_PRINT("."); if (length+lab_length > max_length) { if (print) - safeputs(ndo, cp+length, max_length-length); + nd_printjnp(ndo, cp+length, max_length-length); break; } if (print) - safeputs(ndo, cp+length, lab_length); + nd_printjnp(ndo, cp+length, lab_length); length += lab_length; } if (print) - ND_PRINT((ndo, "[|DNS]")); + ND_PRINT("[|DNS]"); return -1; } @@ -267,7 +269,7 @@ dhcpv4_print(netdissect_options *ndo, const u_char *cp, u_int length, int indent) { u_int i, t; - const u_char *tlv, *value; + const uint8_t *tlv, *value; uint8_t type, optlen; i = 0; @@ -275,16 +277,16 @@ dhcpv4_print(netdissect_options *ndo, if (i + 2 > length) return -1; tlv = cp + i; - type = (uint8_t)tlv[0]; - optlen = (uint8_t)tlv[1]; + type = GET_U_1(tlv); + optlen = GET_U_1(tlv + 1); value = tlv + 2; - ND_PRINT((ndo, "\n")); + ND_PRINT("\n"); for (t = indent; t > 0; t--) - ND_PRINT((ndo, "\t")); + ND_PRINT("\t"); - ND_PRINT((ndo, "%s", tok2str(dh4opt_str, "Unknown", type))); - ND_PRINT((ndo," (%u)", optlen + 2 )); + ND_PRINT("%s", tok2str(dh4opt_str, "Unknown", type)); + ND_PRINT(" (%u)", optlen + 2 ); if (i + 2 + optlen > length) return -1; @@ -295,14 +297,14 @@ dhcpv4_print(netdissect_options *ndo, return -1; } for (t = 0; t < optlen; t += 4) - ND_PRINT((ndo, " %s", ipaddr_string(ndo, value + t))); + ND_PRINT(" %s", GET_IPADDR_STRING(value + t)); } break; case DH4OPT_DOMAIN_SEARCH: { const u_char *tp = value; while (tp < value + optlen) { - ND_PRINT((ndo, " ")); - if ((tp = ns_nprint(ndo, tp, value + optlen)) == NULL) + ND_PRINT(" "); + if ((tp = fqdn_print(ndo, tp, value + optlen)) == NULL) return -1; } } @@ -327,16 +329,16 @@ dhcpv6_print(netdissect_options *ndo, if (i + 4 > length) return -1; tlv = cp + i; - type = EXTRACT_16BITS(tlv); - optlen = EXTRACT_16BITS(tlv + 2); + type = GET_BE_U_2(tlv); + optlen = GET_BE_U_2(tlv + 2); value = tlv + 4; - ND_PRINT((ndo, "\n")); + ND_PRINT("\n"); for (t = indent; t > 0; t--) - ND_PRINT((ndo, "\t")); + ND_PRINT("\t"); - ND_PRINT((ndo, "%s", tok2str(dh6opt_str, "Unknown", type))); - ND_PRINT((ndo," (%u)", optlen + 4 )); + ND_PRINT("%s", tok2str(dh6opt_str, "Unknown", type)); + ND_PRINT(" (%u)", optlen + 4 ); if (i + 4 + optlen > length) return -1; @@ -344,18 +346,18 @@ dhcpv6_print(netdissect_options *ndo, case DH6OPT_DNS_SERVERS: case DH6OPT_SNTP_SERVERS: { if (optlen % 16 != 0) { - ND_PRINT((ndo, " %s", istr)); + nd_print_invalid(ndo); return -1; } for (t = 0; t < optlen; t += 16) - ND_PRINT((ndo, " %s", ip6addr_string(ndo, value + t))); + ND_PRINT(" %s", GET_IP6ADDR_STRING(value + t)); } break; case DH6OPT_DOMAIN_LIST: { const u_char *tp = value; while (tp < value + optlen) { - ND_PRINT((ndo, " ")); - if ((tp = ns_nprint(ndo, tp, value + optlen)) == NULL) + ND_PRINT(" "); + if ((tp = fqdn_print(ndo, tp, value + optlen)) == NULL) return -1; } } @@ -383,22 +385,22 @@ print_type_in_line(netdissect_options *ndo, *first_one = 0; if (indent > 1) { u_int t; - ND_PRINT((ndo, "\n")); + ND_PRINT("\n"); for (t = indent; t > 0; t--) - ND_PRINT((ndo, "\t")); + ND_PRINT("\t"); } else { - ND_PRINT((ndo, " ")); + ND_PRINT(" "); } } else { - ND_PRINT((ndo, ", ")); + ND_PRINT(", "); } - ND_PRINT((ndo, "%s", tok2str(type_values, "Easter Egg", type))); + ND_PRINT("%s", tok2str(type_values, "Easter Egg", type)); if (count > 1) - ND_PRINT((ndo, " (x%d)", count)); + ND_PRINT(" (x%d)", count); } } -void +static void hncp_print_rec(netdissect_options *ndo, const u_char *cp, u_int length, int indent) { @@ -410,7 +412,7 @@ hncp_print_rec(netdissect_options *ndo, uint32_t last_type_mask = 0xffffffffU; int last_type_count = -1; - const u_char *tlv, *value; + const uint8_t *tlv, *value; uint16_t type, bodylen; uint32_t type_mask; @@ -419,19 +421,19 @@ hncp_print_rec(netdissect_options *ndo, tlv = cp + i; if (!in_line) { - ND_PRINT((ndo, "\n")); + ND_PRINT("\n"); for (t = indent; t > 0; t--) - ND_PRINT((ndo, "\t")); + ND_PRINT("\t"); } - ND_TCHECK2(*tlv, 4); + ND_TCHECK_4(tlv); if (i + 4 > length) goto invalid; - type = EXTRACT_16BITS(tlv); - bodylen = EXTRACT_16BITS(tlv + 2); + type = GET_BE_U_2(tlv); + bodylen = GET_BE_U_2(tlv + 2); value = tlv + 4; - ND_TCHECK2(*value, bodylen); + ND_TCHECK_LEN(value, bodylen); if (i + bodylen + 4 > length) goto invalid; @@ -469,27 +471,27 @@ hncp_print_rec(netdissect_options *ndo, goto skip_multiline; } - ND_PRINT((ndo,"%s", tok2str(type_values, "Easter Egg (42)", type_mask) )); + ND_PRINT("%s", tok2str(type_values, "Easter Egg (42)", type_mask) ); if (type_mask > 0xffff) - ND_PRINT((ndo,": type=%u", type )); - ND_PRINT((ndo," (%u)", bodylen + 4 )); + ND_PRINT(": type=%u", type ); + ND_PRINT(" (%u)", bodylen + 4 ); switch (type_mask) { case DNCP_REQUEST_NETWORK_STATE: { if (bodylen != 0) - ND_PRINT((ndo, " %s", istr)); + nd_print_invalid(ndo); } break; case DNCP_REQUEST_NODE_STATE: { const char *node_identifier; if (bodylen != 4) { - ND_PRINT((ndo, " %s", istr)); + nd_print_invalid(ndo); break; } - node_identifier = format_nid(value); - ND_PRINT((ndo, " NID: %s", node_identifier)); + node_identifier = format_nid(ndo, value); + ND_PRINT(" NID: %s", node_identifier); } break; @@ -497,26 +499,26 @@ hncp_print_rec(netdissect_options *ndo, const char *node_identifier; uint32_t endpoint_identifier; if (bodylen != 8) { - ND_PRINT((ndo, " %s", istr)); + nd_print_invalid(ndo); break; } - node_identifier = format_nid(value); - endpoint_identifier = EXTRACT_32BITS(value + 4); - ND_PRINT((ndo, " NID: %s EPID: %08x", + node_identifier = format_nid(ndo, value); + endpoint_identifier = GET_BE_U_4(value + 4); + ND_PRINT(" NID: %s EPID: %08x", node_identifier, endpoint_identifier - )); + ); } break; case DNCP_NETWORK_STATE: { uint64_t hash; if (bodylen != 8) { - ND_PRINT((ndo, " %s", istr)); + nd_print_invalid(ndo); break; } - hash = EXTRACT_64BITS(value); - ND_PRINT((ndo, " hash: %016" PRIx64, hash)); + hash = GET_BE_U_8(value); + ND_PRINT(" hash: %016" PRIx64, hash); } break; @@ -525,19 +527,19 @@ hncp_print_rec(netdissect_options *ndo, uint32_t sequence_number; uint64_t hash; if (bodylen < 20) { - ND_PRINT((ndo, " %s", istr)); + nd_print_invalid(ndo); break; } - node_identifier = format_nid(value); - sequence_number = EXTRACT_32BITS(value + 4); - interval = format_interval(EXTRACT_32BITS(value + 8)); - hash = EXTRACT_64BITS(value + 12); - ND_PRINT((ndo, " NID: %s seqno: %u %s hash: %016" PRIx64, + node_identifier = format_nid(ndo, value); + sequence_number = GET_BE_U_4(value + 4); + interval = format_interval(GET_BE_U_4(value + 8)); + hash = GET_BE_U_8(value + 12); + ND_PRINT(" NID: %s seqno: %u %s hash: %016" PRIx64, node_identifier, sequence_number, interval, hash - )); + ); hncp_print_rec(ndo, value+20, bodylen-20, indent+1); } break; @@ -546,17 +548,17 @@ hncp_print_rec(netdissect_options *ndo, const char *peer_node_identifier; uint32_t peer_endpoint_identifier, endpoint_identifier; if (bodylen != 12) { - ND_PRINT((ndo, " %s", istr)); + nd_print_invalid(ndo); break; } - peer_node_identifier = format_nid(value); - peer_endpoint_identifier = EXTRACT_32BITS(value + 4); - endpoint_identifier = EXTRACT_32BITS(value + 8); - ND_PRINT((ndo, " Peer-NID: %s Peer-EPID: %08x Local-EPID: %08x", + peer_node_identifier = format_nid(ndo, value); + peer_endpoint_identifier = GET_BE_U_4(value + 4); + endpoint_identifier = GET_BE_U_4(value + 8); + ND_PRINT(" Peer-NID: %s Peer-EPID: %08x Local-EPID: %08x", peer_node_identifier, peer_endpoint_identifier, endpoint_identifier - )); + ); } break; @@ -564,27 +566,27 @@ hncp_print_rec(netdissect_options *ndo, uint32_t endpoint_identifier; const char *interval; if (bodylen < 8) { - ND_PRINT((ndo, " %s", istr)); + nd_print_invalid(ndo); break; } - endpoint_identifier = EXTRACT_32BITS(value); - interval = format_interval(EXTRACT_32BITS(value + 4)); - ND_PRINT((ndo, " EPID: %08x Interval: %s", + endpoint_identifier = GET_BE_U_4(value); + interval = format_interval(GET_BE_U_4(value + 4)); + ND_PRINT(" EPID: %08x Interval: %s", endpoint_identifier, interval - )); + ); } break; case DNCP_TRUST_VERDICT: { if (bodylen <= 36) { - ND_PRINT((ndo, " %s", istr)); + nd_print_invalid(ndo); break; } - ND_PRINT((ndo, " Verdict: %u Fingerprint: %s Common Name: ", - *value, - format_256(value + 4))); - safeputs(ndo, value + 36, bodylen - 36); + ND_PRINT(" Verdict: %u Fingerprint: %s Common Name: ", + GET_U_1(value), + format_256(ndo, value + 4)); + nd_printjnp(ndo, value + 36, bodylen - 36); } break; @@ -592,18 +594,18 @@ hncp_print_rec(netdissect_options *ndo, uint16_t capabilities; uint8_t M, P, H, L; if (bodylen < 5) { - ND_PRINT((ndo, " %s", istr)); + nd_print_invalid(ndo); break; } - capabilities = EXTRACT_16BITS(value + 2); + capabilities = GET_BE_U_2(value + 2); M = (uint8_t)((capabilities >> 12) & 0xf); P = (uint8_t)((capabilities >> 8) & 0xf); H = (uint8_t)((capabilities >> 4) & 0xf); L = (uint8_t)(capabilities & 0xf); - ND_PRINT((ndo, " M: %u P: %u H: %u L: %u User-agent: ", + ND_PRINT(" M: %u P: %u H: %u L: %u User-agent: ", M, P, H, L - )); - safeputs(ndo, value + 4, bodylen - 4); + ); + nd_printjnp(ndo, value + 4, bodylen - 4); } break; @@ -615,17 +617,17 @@ hncp_print_rec(netdissect_options *ndo, case HNCP_DELEGATED_PREFIX: { int l; - if (bodylen < 9 || bodylen < 9 + (value[8] + 7) / 8) { - ND_PRINT((ndo, " %s", istr)); + if (bodylen < 9 || bodylen < 9 + (GET_U_1(value + 8) + 7) / 8) { + nd_print_invalid(ndo); break; } - ND_PRINT((ndo, " VLSO: %s PLSO: %s Prefix: ", - format_interval(EXTRACT_32BITS(value)), - format_interval(EXTRACT_32BITS(value + 4)) - )); + ND_PRINT(" VLSO: %s PLSO: %s Prefix: ", + format_interval(GET_BE_U_4(value)), + format_interval(GET_BE_U_4(value + 4)) + ); l = print_prefix(ndo, value + 8, bodylen - 8); if (l == -1) { - ND_PRINT((ndo, "(length is invalid)")); + ND_PRINT("(length is invalid)"); break; } if (l < 0) { @@ -638,7 +640,7 @@ hncp_print_rec(netdissect_options *ndo, * IPv6", or -3, meaning "the prefix runs past * the end of the TLV". */ - ND_PRINT((ndo, " %s", istr)); + nd_print_invalid(ndo); break; } l += 8 + (-l & 3); @@ -652,22 +654,22 @@ hncp_print_rec(netdissect_options *ndo, uint8_t policy; int l; if (bodylen < 1) { - ND_PRINT((ndo, " %s", istr)); + nd_print_invalid(ndo); break; } - policy = value[0]; - ND_PRINT((ndo, " type: ")); + policy = GET_U_1(value); + ND_PRINT(" type: "); if (policy == 0) { if (bodylen != 1) { - ND_PRINT((ndo, " %s", istr)); + nd_print_invalid(ndo); break; } - ND_PRINT((ndo, "Internet connectivity")); + ND_PRINT("Internet connectivity"); } else if (policy >= 1 && policy <= 128) { - ND_PRINT((ndo, "Dest-Prefix: ")); + ND_PRINT("Dest-Prefix: "); l = print_prefix(ndo, value, bodylen); if (l == -1) { - ND_PRINT((ndo, "(length is invalid)")); + ND_PRINT("(length is invalid)"); break; } if (l < 0) { @@ -680,30 +682,30 @@ hncp_print_rec(netdissect_options *ndo, * IPv6", or -3, meaning "the prefix runs past * the end of the TLV". */ - ND_PRINT((ndo, " %s", istr)); + nd_print_invalid(ndo); break; } } else if (policy == 129) { - ND_PRINT((ndo, "DNS domain: ")); + ND_PRINT("DNS domain: "); print_dns_label(ndo, value+1, bodylen-1, 1); } else if (policy == 130) { - ND_PRINT((ndo, "Opaque UTF-8: ")); - safeputs(ndo, value + 1, bodylen - 1); + ND_PRINT("Opaque UTF-8: "); + nd_printjnp(ndo, value + 1, bodylen - 1); } else if (policy == 131) { if (bodylen != 1) { - ND_PRINT((ndo, " %s", istr)); + nd_print_invalid(ndo); break; } - ND_PRINT((ndo, "Restrictive assignment")); + ND_PRINT("Restrictive assignment"); } else if (policy >= 132) { - ND_PRINT((ndo, "Unknown (%u)", policy)); /* Reserved for future additions */ + ND_PRINT("Unknown (%u)", policy); /* Reserved for future additions */ } } break; case HNCP_DHCPV4_DATA: { if (bodylen == 0) { - ND_PRINT((ndo, " %s", istr)); + nd_print_invalid(ndo); break; } if (dhcpv4_print(ndo, value, bodylen, indent+1) != 0) @@ -713,11 +715,11 @@ hncp_print_rec(netdissect_options *ndo, case HNCP_DHCPV6_DATA: { if (bodylen == 0) { - ND_PRINT((ndo, " %s", istr)); + nd_print_invalid(ndo); break; } if (dhcpv6_print(ndo, value, bodylen, indent+1) != 0) { - ND_PRINT((ndo, " %s", istr)); + nd_print_invalid(ndo); break; } } @@ -726,18 +728,18 @@ hncp_print_rec(netdissect_options *ndo, case HNCP_ASSIGNED_PREFIX: { uint8_t prty; int l; - if (bodylen < 6 || bodylen < 6 + (value[5] + 7) / 8) { - ND_PRINT((ndo, " %s", istr)); + if (bodylen < 6 || bodylen < 6 + (GET_U_1(value + 5) + 7) / 8) { + nd_print_invalid(ndo); break; } - prty = (uint8_t)(value[4] & 0xf); - ND_PRINT((ndo, " EPID: %08x Prty: %u", - EXTRACT_32BITS(value), + prty = GET_U_1(value + 4) & 0xf; + ND_PRINT(" EPID: %08x Prty: %u", + GET_BE_U_4(value), prty - )); - ND_PRINT((ndo, " Prefix: ")); + ); + ND_PRINT(" Prefix: "); if ((l = print_prefix(ndo, value + 5, bodylen - 5)) < 0) { - ND_PRINT((ndo, " %s", istr)); + nd_print_invalid(ndo); break; } l += 5; @@ -752,15 +754,15 @@ hncp_print_rec(netdissect_options *ndo, uint32_t endpoint_identifier; const char *ip_address; if (bodylen < 20) { - ND_PRINT((ndo, " %s", istr)); + nd_print_invalid(ndo); break; } - endpoint_identifier = EXTRACT_32BITS(value); + endpoint_identifier = GET_BE_U_4(value); ip_address = format_ip6addr(ndo, value + 4); - ND_PRINT((ndo, " EPID: %08x IP Address: %s", + ND_PRINT(" EPID: %08x IP Address: %s", endpoint_identifier, ip_address - )); + ); hncp_print_rec(ndo, value + 20, bodylen - 20, indent+1); } @@ -770,19 +772,19 @@ hncp_print_rec(netdissect_options *ndo, const char *ip_address; int len; if (bodylen < 17) { - ND_PRINT((ndo, " %s", istr)); + nd_print_invalid(ndo); break; } ip_address = format_ip6addr(ndo, value); - ND_PRINT((ndo, " IP-Address: %s %c%c%c ", + ND_PRINT(" IP-Address: %s %c%c%c ", ip_address, - (value[16] & 4) ? 'l' : '-', - (value[16] & 2) ? 'b' : '-', - (value[16] & 1) ? 's' : '-' - )); + (GET_U_1(value + 16) & 4) ? 'l' : '-', + (GET_U_1(value + 16) & 2) ? 'b' : '-', + (GET_U_1(value + 16) & 1) ? 's' : '-' + ); len = print_dns_label(ndo, value+17, bodylen-17, 1); if (len < 0) { - ND_PRINT((ndo, " %s", istr)); + nd_print_invalid(ndo); break; } len += 17; @@ -794,10 +796,10 @@ hncp_print_rec(netdissect_options *ndo, case HNCP_DOMAIN_NAME: { if (bodylen == 0) { - ND_PRINT((ndo, " %s", istr)); + nd_print_invalid(ndo); break; } - ND_PRINT((ndo, " Domain: ")); + ND_PRINT(" Domain: "); print_dns_label(ndo, value, bodylen, 1); } break; @@ -805,26 +807,26 @@ hncp_print_rec(netdissect_options *ndo, case HNCP_NODE_NAME: { u_int l; if (bodylen < 17) { - ND_PRINT((ndo, " %s", istr)); + nd_print_invalid(ndo); break; } - l = value[16]; + l = GET_U_1(value + 16); if (bodylen < 17 + l) { - ND_PRINT((ndo, " %s", istr)); + nd_print_invalid(ndo); break; } - ND_PRINT((ndo, " IP-Address: %s Name: ", + ND_PRINT(" IP-Address: %s Name: ", format_ip6addr(ndo, value) - )); + ); if (l < 64) { - safeputchar(ndo, '"'); - safeputs(ndo, value + 17, l); - safeputchar(ndo, '"'); + ND_PRINT("\""); + nd_printjnp(ndo, value + 17, l); + ND_PRINT("\""); } else { - ND_PRINT((ndo, "%s", istr)); + nd_print_invalid(ndo); } l += 17; - l += -l & 3; + l = roundup2(l, 4); if (bodylen >= l) hncp_print_rec(ndo, value + l, bodylen - l, indent+1); } @@ -832,10 +834,10 @@ hncp_print_rec(netdissect_options *ndo, case HNCP_MANAGED_PSK: { if (bodylen < 32) { - ND_PRINT((ndo, " %s", istr)); + nd_print_invalid(ndo); break; } - ND_PRINT((ndo, " PSK: %s", format_256(value))); + ND_PRINT(" PSK: %s", format_256(ndo, value)); hncp_print_rec(ndo, value + 32, bodylen - 32, indent+1); } break; @@ -849,17 +851,16 @@ hncp_print_rec(netdissect_options *ndo, } skip_multiline: - i += 4 + bodylen + (-bodylen & 3); + i += 4 + roundup2(bodylen, 4); } print_type_in_line(ndo, last_type_mask, last_type_count, indent, &first_one); return; trunc: - ND_PRINT((ndo, "%s", "[|hncp]")); + nd_print_trunc(ndo); return; invalid: - ND_PRINT((ndo, "%s", istr)); - return; + nd_print_invalid(ndo); } diff --git a/contrib/tcpdump/print-hsrp.c b/contrib/tcpdump/print-hsrp.c index 35146460c8..3027826847 100644 --- a/contrib/tcpdump/print-hsrp.c +++ b/contrib/tcpdump/print-hsrp.c @@ -29,16 +29,17 @@ /* \summary: Cisco Hot Standby Router Protocol (HSRP) printer */ -/* Cisco Hot Standby Router Protocol (HSRP). */ +/* specification: RFC 2281 for version 1 */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "addrtoname.h" +#include "extract.h" /* HSRP op code types. */ static const char *op_code_str[] = { @@ -80,56 +81,53 @@ static const struct tok states[] = { /* HSRP protocol header. */ struct hsrp { - uint8_t hsrp_version; - uint8_t hsrp_op_code; - uint8_t hsrp_state; - uint8_t hsrp_hellotime; - uint8_t hsrp_holdtime; - uint8_t hsrp_priority; - uint8_t hsrp_group; - uint8_t hsrp_reserved; - uint8_t hsrp_authdata[HSRP_AUTH_SIZE]; - struct in_addr hsrp_virtaddr; + nd_uint8_t hsrp_version; + nd_uint8_t hsrp_op_code; + nd_uint8_t hsrp_state; + nd_uint8_t hsrp_hellotime; + nd_uint8_t hsrp_holdtime; + nd_uint8_t hsrp_priority; + nd_uint8_t hsrp_group; + nd_uint8_t hsrp_reserved; + nd_byte hsrp_authdata[HSRP_AUTH_SIZE]; + nd_ipv4 hsrp_virtaddr; }; void -hsrp_print(netdissect_options *ndo, register const uint8_t *bp, register u_int len) +hsrp_print(netdissect_options *ndo, const u_char *bp, u_int len) { const struct hsrp *hp = (const struct hsrp *) bp; + uint8_t version; - ND_TCHECK(hp->hsrp_version); - ND_PRINT((ndo, "HSRPv%d", hp->hsrp_version)); - if (hp->hsrp_version != 0) + ndo->ndo_protocol = "hsrp"; + version = GET_U_1(hp->hsrp_version); + ND_PRINT("HSRPv%u", version); + if (version != 0) return; - ND_TCHECK(hp->hsrp_op_code); - ND_PRINT((ndo, "-")); - ND_PRINT((ndo, "%s ", tok2strary(op_code_str, "unknown (%d)", hp->hsrp_op_code))); - ND_PRINT((ndo, "%d: ", len)); - ND_TCHECK(hp->hsrp_state); - ND_PRINT((ndo, "state=%s ", tok2str(states, "Unknown (%d)", hp->hsrp_state))); - ND_TCHECK(hp->hsrp_group); - ND_PRINT((ndo, "group=%d ", hp->hsrp_group)); - ND_TCHECK(hp->hsrp_reserved); - if (hp->hsrp_reserved != 0) { - ND_PRINT((ndo, "[reserved=%d!] ", hp->hsrp_reserved)); + ND_PRINT("-"); + ND_PRINT("%s ", + tok2strary(op_code_str, "unknown (%u)", GET_U_1(hp->hsrp_op_code))); + ND_PRINT("%u: ", len); + ND_PRINT("state=%s ", + tok2str(states, "Unknown (%u)", GET_U_1(hp->hsrp_state))); + ND_PRINT("group=%u ", GET_U_1(hp->hsrp_group)); + if (GET_U_1(hp->hsrp_reserved) != 0) { + ND_PRINT("[reserved=%u!] ", GET_U_1(hp->hsrp_reserved)); } - ND_TCHECK(hp->hsrp_virtaddr); - ND_PRINT((ndo, "addr=%s", ipaddr_string(ndo, &hp->hsrp_virtaddr))); + ND_PRINT("addr=%s", GET_IPADDR_STRING(hp->hsrp_virtaddr)); if (ndo->ndo_vflag) { - ND_PRINT((ndo, " hellotime=")); - unsigned_relts_print(ndo, hp->hsrp_hellotime); - ND_PRINT((ndo, " holdtime=")); - unsigned_relts_print(ndo, hp->hsrp_holdtime); - ND_PRINT((ndo, " priority=%d", hp->hsrp_priority)); - ND_PRINT((ndo, " auth=\"")); - if (fn_printn(ndo, hp->hsrp_authdata, sizeof(hp->hsrp_authdata), - ndo->ndo_snapend)) { - ND_PRINT((ndo, "\"")); - goto trunc; - } - ND_PRINT((ndo, "\"")); + ND_PRINT(" hellotime="); + unsigned_relts_print(ndo, GET_U_1(hp->hsrp_hellotime)); + ND_PRINT(" holdtime="); + unsigned_relts_print(ndo, GET_U_1(hp->hsrp_holdtime)); + ND_PRINT(" priority=%u", GET_U_1(hp->hsrp_priority)); + ND_PRINT(" auth=\""); + /* + * RFC 2281 Section 5.1 does not specify the encoding of + * Authentication Data explicitly, but zero padding can be + * inferred from the "recommended default value". + */ + nd_printjnp(ndo, hp->hsrp_authdata, HSRP_AUTH_SIZE); + ND_PRINT("\""); } - return; -trunc: - ND_PRINT((ndo, "[|hsrp]")); } diff --git a/contrib/tcpdump/print-http.c b/contrib/tcpdump/print-http.c index 0aec758182..6845d0d315 100644 --- a/contrib/tcpdump/print-http.c +++ b/contrib/tcpdump/print-http.c @@ -14,16 +14,12 @@ /* \summary: Hypertext Transfer Protocol (HTTP) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include - -#include -#include +#include "netdissect-stdinc.h" #include "netdissect.h" -#include "extract.h" /* * Includes WebDAV requests. @@ -73,5 +69,6 @@ static const char *httpcmds[] = { void http_print(netdissect_options *ndo, const u_char *pptr, u_int len) { - txtproto_print(ndo, pptr, len, "http", httpcmds, RESP_CODE_SECOND_TOKEN); + ndo->ndo_protocol = "http"; + txtproto_print(ndo, pptr, len, httpcmds, RESP_CODE_SECOND_TOKEN); } diff --git a/contrib/tcpdump/print-icmp.c b/contrib/tcpdump/print-icmp.c index 170d5438f2..77539225c8 100644 --- a/contrib/tcpdump/print-icmp.c +++ b/contrib/tcpdump/print-icmp.c @@ -22,10 +22,10 @@ /* \summary: Internet Control Message Protocol (ICMP) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include #include @@ -48,17 +48,17 @@ * Structure of an icmp header. */ struct icmp { - uint8_t icmp_type; /* type of message, see below */ - uint8_t icmp_code; /* type sub code */ - uint16_t icmp_cksum; /* ones complement cksum of struct */ + nd_uint8_t icmp_type; /* type of message, see below */ + nd_uint8_t icmp_code; /* type sub code */ + nd_uint16_t icmp_cksum; /* ones complement cksum of struct */ union { - uint8_t ih_pptr; /* ICMP_PARAMPROB */ - struct in_addr ih_gwaddr; /* ICMP_REDIRECT */ + nd_uint8_t ih_pptr; /* ICMP_PARAMPROB */ + nd_ipv4 ih_gwaddr; /* ICMP_REDIRECT */ struct ih_idseq { - uint16_t icd_id; - uint16_t icd_seq; + nd_uint16_t icd_id; + nd_uint16_t icd_seq; } ih_idseq; - uint32_t ih_void; + nd_uint32_t ih_void; } icmp_hun; #define icmp_pptr icmp_hun.ih_pptr #define icmp_gwaddr icmp_hun.ih_gwaddr @@ -67,16 +67,16 @@ struct icmp { #define icmp_void icmp_hun.ih_void union { struct id_ts { - uint32_t its_otime; - uint32_t its_rtime; - uint32_t its_ttime; + nd_uint32_t its_otime; + nd_uint32_t its_rtime; + nd_uint32_t its_ttime; } id_ts; struct id_ip { struct ip idi_ip; /* options and then 64 bits of data */ } id_ip; - uint32_t id_mask; - uint8_t id_data[1]; + nd_uint32_t id_mask; + nd_byte id_data[1]; } icmp_dun; #define icmp_otime icmp_dun.id_ts.its_otime #define icmp_rtime icmp_dun.id_ts.its_rtime @@ -92,7 +92,7 @@ struct icmp { /* * Lower bounds on packet lengths for various types. * For the error advice packets must first insure that the - * packet is large enought to contain the returned ip header. + * packet is large enough to contain the returned ip header. * Only then can we do the check to see if 64 bits of packet * data have been returned, since we need to check the returned * ip header length. @@ -202,67 +202,31 @@ static const struct tok icmp2str[] = { { 0, NULL } }; -/* Formats for most of the ICMP_UNREACH codes */ -static const struct tok unreach2str[] = { - { ICMP_UNREACH_NET, "net %s unreachable" }, - { ICMP_UNREACH_HOST, "host %s unreachable" }, - { ICMP_UNREACH_SRCFAIL, - "%s unreachable - source route failed" }, - { ICMP_UNREACH_NET_UNKNOWN, "net %s unreachable - unknown" }, - { ICMP_UNREACH_HOST_UNKNOWN, "host %s unreachable - unknown" }, - { ICMP_UNREACH_ISOLATED, - "%s unreachable - source host isolated" }, - { ICMP_UNREACH_NET_PROHIB, - "net %s unreachable - admin prohibited" }, - { ICMP_UNREACH_HOST_PROHIB, - "host %s unreachable - admin prohibited" }, - { ICMP_UNREACH_TOSNET, - "net %s unreachable - tos prohibited" }, - { ICMP_UNREACH_TOSHOST, - "host %s unreachable - tos prohibited" }, - { ICMP_UNREACH_FILTER_PROHIB, - "host %s unreachable - admin prohibited filter" }, - { ICMP_UNREACH_HOST_PRECEDENCE, - "host %s unreachable - host precedence violation" }, - { ICMP_UNREACH_PRECEDENCE_CUTOFF, - "host %s unreachable - precedence cutoff" }, - { 0, NULL } -}; - -/* Formats for the ICMP_REDIRECT codes */ -static const struct tok type2str[] = { - { ICMP_REDIRECT_NET, "redirect %s to net %s" }, - { ICMP_REDIRECT_HOST, "redirect %s to host %s" }, - { ICMP_REDIRECT_TOSNET, "redirect-tos %s to net %s" }, - { ICMP_REDIRECT_TOSHOST, "redirect-tos %s to host %s" }, - { 0, NULL } -}; - /* rfc1191 */ struct mtu_discovery { - uint16_t unused; - uint16_t nexthopmtu; + nd_uint16_t unused; + nd_uint16_t nexthopmtu; }; /* rfc1256 */ struct ih_rdiscovery { - uint8_t ird_addrnum; - uint8_t ird_addrsiz; - uint16_t ird_lifetime; + nd_uint8_t ird_addrnum; + nd_uint8_t ird_addrsiz; + nd_uint16_t ird_lifetime; }; struct id_rdiscovery { - uint32_t ird_addr; - uint32_t ird_pref; + nd_uint32_t ird_addr; + nd_uint32_t ird_pref; }; /* * draft-bonica-internet-icmp-08 * * The Destination Unreachable, Time Exceeded - * and Parameter Problem messages are slighly changed as per + * and Parameter Problem messages are slightly changed as per * the above draft. A new Length field gets added to give - * the caller an idea about the length of the piggypacked + * the caller an idea about the length of the piggybacked * IP packet before the MPLS extension header starts. * * The Length field represents length of the padded "original datagram" @@ -283,22 +247,22 @@ struct id_rdiscovery { */ struct icmp_ext_t { - uint8_t icmp_type; - uint8_t icmp_code; - uint8_t icmp_checksum[2]; - uint8_t icmp_reserved; - uint8_t icmp_length; - uint8_t icmp_reserved2[2]; - uint8_t icmp_ext_legacy_header[128]; /* extension header starts 128 bytes after ICMP header */ - uint8_t icmp_ext_version_res[2]; - uint8_t icmp_ext_checksum[2]; - uint8_t icmp_ext_data[1]; + nd_uint8_t icmp_type; + nd_uint8_t icmp_code; + nd_uint16_t icmp_checksum; + nd_byte icmp_reserved; + nd_uint8_t icmp_length; + nd_byte icmp_reserved2[2]; + nd_byte icmp_ext_legacy_header[128]; /* extension header starts 128 bytes after ICMP header */ + nd_byte icmp_ext_version_res[2]; + nd_uint16_t icmp_ext_checksum; + nd_byte icmp_ext_data[1]; }; struct icmp_mpls_ext_object_header_t { - uint8_t length[2]; - uint8_t class_num; - uint8_t ctype; + nd_uint16_t length; + nd_uint8_t class_num; + nd_uint8_t ctype; }; static const struct tok icmp_mpls_ext_obj_values[] = { @@ -332,130 +296,240 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * { char *cp; const struct icmp *dp; + uint8_t icmp_type, icmp_code; const struct icmp_ext_t *ext_dp; const struct ip *ip; - const char *str, *fmt; + const char *str; const struct ip *oip; + uint8_t ip_proto; const struct udphdr *ouh; const uint8_t *obj_tptr; uint32_t raw_label; - const u_char *snapend_save; 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; + u_int hlen, mtu, obj_tlen, obj_class_num, obj_ctype; + uint16_t dport; char buf[MAXHOSTNAMELEN + 100]; struct cksum_vec vec[1]; + ndo->ndo_protocol = "icmp"; dp = (const struct icmp *)bp; ext_dp = (const struct icmp_ext_t *)bp; ip = (const struct ip *)bp2; str = buf; - ND_TCHECK(dp->icmp_code); - switch (dp->icmp_type) { + icmp_type = GET_U_1(dp->icmp_type); + icmp_code = GET_U_1(dp->icmp_code); + switch (icmp_type) { case ICMP_ECHO: case ICMP_ECHOREPLY: - ND_TCHECK(dp->icmp_seq); (void)snprintf(buf, sizeof(buf), "echo %s, id %u, seq %u", - dp->icmp_type == ICMP_ECHO ? + icmp_type == ICMP_ECHO ? "request" : "reply", - EXTRACT_16BITS(&dp->icmp_id), - EXTRACT_16BITS(&dp->icmp_seq)); + GET_BE_U_2(dp->icmp_id), + GET_BE_U_2(dp->icmp_seq)); break; case ICMP_UNREACH: - ND_TCHECK(dp->icmp_ip.ip_dst); - switch (dp->icmp_code) { + switch (icmp_code) { + + case ICMP_UNREACH_NET: + (void)snprintf(buf, sizeof(buf), + "net %s unreachable", + GET_IPADDR_STRING(dp->icmp_ip.ip_dst)); + break; + + case ICMP_UNREACH_HOST: + (void)snprintf(buf, sizeof(buf), + "host %s unreachable", + GET_IPADDR_STRING(dp->icmp_ip.ip_dst)); + break; case ICMP_UNREACH_PROTOCOL: - ND_TCHECK(dp->icmp_ip.ip_p); (void)snprintf(buf, sizeof(buf), - "%s protocol %d unreachable", - ipaddr_string(ndo, &dp->icmp_ip.ip_dst), - dp->icmp_ip.ip_p); + "%s protocol %u unreachable", + GET_IPADDR_STRING(dp->icmp_ip.ip_dst), + GET_U_1(dp->icmp_ip.ip_p)); break; case ICMP_UNREACH_PORT: - ND_TCHECK(dp->icmp_ip.ip_p); + ND_TCHECK_1(dp->icmp_ip.ip_p); oip = &dp->icmp_ip; hlen = IP_HL(oip) * 4; ouh = (const struct udphdr *)(((const u_char *)oip) + hlen); - ND_TCHECK(ouh->uh_dport); - dport = EXTRACT_16BITS(&ouh->uh_dport); - switch (oip->ip_p) { + dport = GET_BE_U_2(ouh->uh_dport); + ip_proto = GET_U_1(oip->ip_p); + switch (ip_proto) { case IPPROTO_TCP: (void)snprintf(buf, sizeof(buf), "%s tcp port %s unreachable", - ipaddr_string(ndo, &oip->ip_dst), + GET_IPADDR_STRING(oip->ip_dst), tcpport_string(ndo, dport)); break; case IPPROTO_UDP: (void)snprintf(buf, sizeof(buf), "%s udp port %s unreachable", - ipaddr_string(ndo, &oip->ip_dst), + GET_IPADDR_STRING(oip->ip_dst), udpport_string(ndo, dport)); break; default: (void)snprintf(buf, sizeof(buf), "%s protocol %u port %u unreachable", - ipaddr_string(ndo, &oip->ip_dst), - oip->ip_p, dport); + GET_IPADDR_STRING(oip->ip_dst), + ip_proto, dport); break; } break; case ICMP_UNREACH_NEEDFRAG: { - register const struct mtu_discovery *mp; + const struct mtu_discovery *mp; mp = (const struct mtu_discovery *)(const u_char *)&dp->icmp_void; - mtu = EXTRACT_16BITS(&mp->nexthopmtu); + mtu = GET_BE_U_2(mp->nexthopmtu); if (mtu) { (void)snprintf(buf, sizeof(buf), - "%s unreachable - need to frag (mtu %d)", - ipaddr_string(ndo, &dp->icmp_ip.ip_dst), mtu); + "%s unreachable - need to frag (mtu %u)", + GET_IPADDR_STRING(dp->icmp_ip.ip_dst), mtu); } else { (void)snprintf(buf, sizeof(buf), "%s unreachable - need to frag", - ipaddr_string(ndo, &dp->icmp_ip.ip_dst)); + GET_IPADDR_STRING(dp->icmp_ip.ip_dst)); } } break; + case ICMP_UNREACH_SRCFAIL: + (void)snprintf(buf, sizeof(buf), + "%s unreachable - source route failed", + GET_IPADDR_STRING(dp->icmp_ip.ip_dst)); + break; + + case ICMP_UNREACH_NET_UNKNOWN: + (void)snprintf(buf, sizeof(buf), + "net %s unreachable - unknown", + GET_IPADDR_STRING(dp->icmp_ip.ip_dst)); + break; + + case ICMP_UNREACH_HOST_UNKNOWN: + (void)snprintf(buf, sizeof(buf), + "host %s unreachable - unknown", + GET_IPADDR_STRING(dp->icmp_ip.ip_dst)); + break; + + case ICMP_UNREACH_ISOLATED: + (void)snprintf(buf, sizeof(buf), + "%s unreachable - source host isolated", + GET_IPADDR_STRING(dp->icmp_ip.ip_dst)); + break; + + case ICMP_UNREACH_NET_PROHIB: + (void)snprintf(buf, sizeof(buf), + "net %s unreachable - admin prohibited", + GET_IPADDR_STRING(dp->icmp_ip.ip_dst)); + break; + + case ICMP_UNREACH_HOST_PROHIB: + (void)snprintf(buf, sizeof(buf), + "host %s unreachable - admin prohibited", + GET_IPADDR_STRING(dp->icmp_ip.ip_dst)); + break; + + case ICMP_UNREACH_TOSNET: + (void)snprintf(buf, sizeof(buf), + "net %s unreachable - tos prohibited", + GET_IPADDR_STRING(dp->icmp_ip.ip_dst)); + break; + + case ICMP_UNREACH_TOSHOST: + (void)snprintf(buf, sizeof(buf), + "host %s unreachable - tos prohibited", + GET_IPADDR_STRING(dp->icmp_ip.ip_dst)); + break; + + case ICMP_UNREACH_FILTER_PROHIB: + (void)snprintf(buf, sizeof(buf), + "host %s unreachable - admin prohibited filter", + GET_IPADDR_STRING(dp->icmp_ip.ip_dst)); + break; + + case ICMP_UNREACH_HOST_PRECEDENCE: + (void)snprintf(buf, sizeof(buf), + "host %s unreachable - host precedence violation", + GET_IPADDR_STRING(dp->icmp_ip.ip_dst)); + break; + + case ICMP_UNREACH_PRECEDENCE_CUTOFF: + (void)snprintf(buf, sizeof(buf), + "host %s unreachable - precedence cutoff", + GET_IPADDR_STRING(dp->icmp_ip.ip_dst)); + break; + default: - fmt = tok2str(unreach2str, "#%d %%s unreachable", - dp->icmp_code); - (void)snprintf(buf, sizeof(buf), fmt, - ipaddr_string(ndo, &dp->icmp_ip.ip_dst)); + (void)snprintf(buf, sizeof(buf), + "%s unreachable - #%u", + GET_IPADDR_STRING(dp->icmp_ip.ip_dst), + icmp_code); break; } break; case ICMP_REDIRECT: - ND_TCHECK(dp->icmp_ip.ip_dst); - fmt = tok2str(type2str, "redirect-#%d %%s to net %%s", - dp->icmp_code); - (void)snprintf(buf, sizeof(buf), fmt, - ipaddr_string(ndo, &dp->icmp_ip.ip_dst), - ipaddr_string(ndo, &dp->icmp_gwaddr)); + switch (icmp_code) { + + case ICMP_REDIRECT_NET: + (void)snprintf(buf, sizeof(buf), + "redirect %s to net %s", + GET_IPADDR_STRING(dp->icmp_ip.ip_dst), + GET_IPADDR_STRING(dp->icmp_gwaddr)); + break; + + case ICMP_REDIRECT_HOST: + (void)snprintf(buf, sizeof(buf), + "redirect %s to host %s", + GET_IPADDR_STRING(dp->icmp_ip.ip_dst), + GET_IPADDR_STRING(dp->icmp_gwaddr)); + break; + + case ICMP_REDIRECT_TOSNET: + (void)snprintf(buf, sizeof(buf), + "redirect-tos %s to net %s", + GET_IPADDR_STRING(dp->icmp_ip.ip_dst), + GET_IPADDR_STRING(dp->icmp_gwaddr)); + break; + + case ICMP_REDIRECT_TOSHOST: + (void)snprintf(buf, sizeof(buf), + "redirect-tos %s to host %s", + GET_IPADDR_STRING(dp->icmp_ip.ip_dst), + GET_IPADDR_STRING(dp->icmp_gwaddr)); + break; + + default: + (void)snprintf(buf, sizeof(buf), + "redirect-#%u %s to %s", icmp_code, + GET_IPADDR_STRING(dp->icmp_ip.ip_dst), + GET_IPADDR_STRING(dp->icmp_gwaddr)); + break; + } break; case ICMP_ROUTERADVERT: { - register const struct ih_rdiscovery *ihp; - register const struct id_rdiscovery *idp; + const struct ih_rdiscovery *ihp; + const struct id_rdiscovery *idp; u_int lifetime, num, size; (void)snprintf(buf, sizeof(buf), "router advertisement"); cp = buf + strlen(buf); ihp = (const struct ih_rdiscovery *)&dp->icmp_void; - ND_TCHECK(*ihp); + ND_TCHECK_SIZE(ihp); (void)strncpy(cp, " lifetime ", sizeof(buf) - (cp - buf)); cp = buf + strlen(buf); - lifetime = EXTRACT_16BITS(&ihp->ird_lifetime); + lifetime = GET_BE_U_2(ihp->ird_lifetime); if (lifetime < 60) { (void)snprintf(cp, sizeof(buf) - (cp - buf), "%u", lifetime); @@ -471,31 +545,32 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * } cp = buf + strlen(buf); - num = ihp->ird_addrnum; - (void)snprintf(cp, sizeof(buf) - (cp - buf), " %d:", num); + num = GET_U_1(ihp->ird_addrnum); + (void)snprintf(cp, sizeof(buf) - (cp - buf), " %u:", num); cp = buf + strlen(buf); - size = ihp->ird_addrsiz; + size = GET_U_1(ihp->ird_addrsiz); if (size != 2) { (void)snprintf(cp, sizeof(buf) - (cp - buf), - " [size %d]", size); + " [size %u]", size); break; } idp = (const struct id_rdiscovery *)&dp->icmp_data; - while (num-- > 0) { - ND_TCHECK(*idp); + while (num > 0) { + ND_TCHECK_SIZE(idp); (void)snprintf(cp, sizeof(buf) - (cp - buf), " {%s %u}", - ipaddr_string(ndo, &idp->ird_addr), - EXTRACT_32BITS(&idp->ird_pref)); + GET_IPADDR_STRING(idp->ird_addr), + GET_BE_U_4(idp->ird_pref)); cp = buf + strlen(buf); ++idp; + num--; } } break; case ICMP_TIMXCEED: - ND_TCHECK(dp->icmp_ip.ip_dst); - switch (dp->icmp_code) { + ND_TCHECK_4(dp->icmp_ip.ip_dst); + switch (icmp_code) { case ICMP_TIMXCEED_INTRANS: str = "time exceeded in-transit"; @@ -507,94 +582,104 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * default: (void)snprintf(buf, sizeof(buf), "time exceeded-#%u", - dp->icmp_code); + icmp_code); break; } break; case ICMP_PARAMPROB: - if (dp->icmp_code) + if (icmp_code) (void)snprintf(buf, sizeof(buf), - "parameter problem - code %u", dp->icmp_code); + "parameter problem - code %u", icmp_code); else { - ND_TCHECK(dp->icmp_pptr); (void)snprintf(buf, sizeof(buf), - "parameter problem - octet %u", dp->icmp_pptr); + "parameter problem - octet %u", + GET_U_1(dp->icmp_pptr)); } break; case ICMP_MASKREPLY: - ND_TCHECK(dp->icmp_mask); (void)snprintf(buf, sizeof(buf), "address mask is 0x%08x", - EXTRACT_32BITS(&dp->icmp_mask)); + GET_BE_U_4(dp->icmp_mask)); break; case ICMP_TSTAMP: - ND_TCHECK(dp->icmp_seq); (void)snprintf(buf, sizeof(buf), "time stamp query id %u seq %u", - EXTRACT_16BITS(&dp->icmp_id), - EXTRACT_16BITS(&dp->icmp_seq)); + GET_BE_U_2(dp->icmp_id), + GET_BE_U_2(dp->icmp_seq)); break; case ICMP_TSTAMPREPLY: - ND_TCHECK(dp->icmp_ttime); + ND_TCHECK_4(dp->icmp_ttime); (void)snprintf(buf, sizeof(buf), "time stamp reply id %u seq %u: org %s", - EXTRACT_16BITS(&dp->icmp_id), - EXTRACT_16BITS(&dp->icmp_seq), - icmp_tstamp_print(EXTRACT_32BITS(&dp->icmp_otime))); + GET_BE_U_2(dp->icmp_id), + GET_BE_U_2(dp->icmp_seq), + icmp_tstamp_print(GET_BE_U_4(dp->icmp_otime))); (void)snprintf(buf+strlen(buf),sizeof(buf)-strlen(buf),", recv %s", - icmp_tstamp_print(EXTRACT_32BITS(&dp->icmp_rtime))); + icmp_tstamp_print(GET_BE_U_4(dp->icmp_rtime))); (void)snprintf(buf+strlen(buf),sizeof(buf)-strlen(buf),", xmit %s", - icmp_tstamp_print(EXTRACT_32BITS(&dp->icmp_ttime))); + icmp_tstamp_print(GET_BE_U_4(dp->icmp_ttime))); break; default: - str = tok2str(icmp2str, "type-#%d", dp->icmp_type); + str = tok2str(icmp2str, "type-#%u", icmp_type); break; } - ND_PRINT((ndo, "ICMP %s, length %u", str, plen)); + ND_PRINT("ICMP %s, length %u", str, plen); if (ndo->ndo_vflag && !fragmented) { /* don't attempt checksumming if this is a frag */ - if (ND_TTEST2(*bp, plen)) { + if (ND_TTEST_LEN(bp, plen)) { uint16_t sum; vec[0].ptr = (const uint8_t *)(const void *)dp; vec[0].len = plen; sum = in_cksum(vec, 1); if (sum != 0) { - uint16_t icmp_sum; - ND_TCHECK_16BITS(&dp->icmp_cksum); - icmp_sum = EXTRACT_16BITS(&dp->icmp_cksum); - ND_PRINT((ndo, " (wrong icmp cksum %x (->%x)!)", + uint16_t icmp_sum = GET_BE_U_2(dp->icmp_cksum); + ND_PRINT(" (wrong icmp cksum %x (->%x)!)", icmp_sum, - in_cksum_shouldbe(icmp_sum, sum))); + in_cksum_shouldbe(icmp_sum, sum)); } } } /* * print the remnants of the IP packet. - * save the snaplength as this may get overidden in the IP printer. + * save the snaplength as this may get overridden in the IP printer. */ - if (ndo->ndo_vflag >= 1 && ICMP_ERRTYPE(dp->icmp_type)) { + if (ndo->ndo_vflag >= 1 && ICMP_ERRTYPE(icmp_type)) { + const u_char *snapend_save; + bp += 8; - ND_PRINT((ndo, "\n\t")); + ND_PRINT("\n\t"); ip = (const struct ip *)bp; - ndo->ndo_snaplen = ndo->ndo_snapend - bp; - snapend_save = ndo->ndo_snapend; - ND_TCHECK_16BITS(&ip->ip_len); - ip_print(ndo, bp, EXTRACT_16BITS(&ip->ip_len)); - ndo->ndo_snapend = snapend_save; + snapend_save = ndo->ndo_snapend; + /* + * Update the snapend because extensions (MPLS, ...) may be + * present after the IP packet. In this case the current + * (outer) packet's snapend is not what ip_print() needs to + * decode an IP packet nested in the middle of an ICMP payload. + * + * This prevents that, in ip_print(), for the nested IP packet, + * the remaining length < remaining caplen. + */ + ndo->ndo_snapend = ND_MIN(bp + GET_BE_U_2(ip->ip_len), + ndo->ndo_snapend); + ip_print(ndo, bp, GET_BE_U_2(ip->ip_len)); + ndo->ndo_snapend = snapend_save; } + /* ndo_protocol reassignment after ip_print() call */ + ndo->ndo_protocol = "icmp"; + /* * Attempt to decode the MPLS extensions only for some ICMP types. */ - if (ndo->ndo_vflag >= 1 && plen > ICMP_EXTD_MINLEN && ICMP_MPLS_EXT_TYPE(dp->icmp_type)) { + if (ndo->ndo_vflag >= 1 && plen > ICMP_EXTD_MINLEN && ICMP_MPLS_EXT_TYPE(icmp_type)) { - ND_TCHECK(*ext_dp); + ND_TCHECK_SIZE(ext_dp); /* * Check first if the mpls extension header shows a non-zero length. @@ -602,8 +687,8 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * * 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 && - ND_TTEST2(ext_dp->icmp_ext_version_res, plen - ICMP_EXTD_MINLEN)) { + if (GET_U_1(ext_dp->icmp_length) == 0 && + ND_TTEST_LEN(ext_dp->icmp_ext_version_res, plen - ICMP_EXTD_MINLEN)) { vec[0].ptr = (const uint8_t *)(const void *)&ext_dp->icmp_ext_version_res; vec[0].len = plen - ICMP_EXTD_MINLEN; if (in_cksum(vec, 1)) { @@ -611,26 +696,26 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * } } - ND_PRINT((ndo, "\n\tMPLS extension v%u", - ICMP_MPLS_EXT_EXTRACT_VERSION(*(ext_dp->icmp_ext_version_res)))); + ND_PRINT("\n\tMPLS extension v%u", + ICMP_MPLS_EXT_EXTRACT_VERSION(*(ext_dp->icmp_ext_version_res))); /* * Sanity checking of the header. */ if (ICMP_MPLS_EXT_EXTRACT_VERSION(*(ext_dp->icmp_ext_version_res)) != ICMP_MPLS_EXT_VERSION) { - ND_PRINT((ndo, " packet not supported")); + ND_PRINT(" packet not supported"); return; } hlen = plen - ICMP_EXTD_MINLEN; - if (ND_TTEST2(ext_dp->icmp_ext_version_res, hlen)) { + if (ND_TTEST_LEN(ext_dp->icmp_ext_version_res, hlen)) { vec[0].ptr = (const uint8_t *)(const void *)&ext_dp->icmp_ext_version_res; vec[0].len = hlen; - ND_PRINT((ndo, ", checksum 0x%04x (%scorrect), length %u", - EXTRACT_16BITS(ext_dp->icmp_ext_checksum), + ND_PRINT(", checksum 0x%04x (%scorrect), length %u", + GET_BE_U_2(ext_dp->icmp_ext_checksum), in_cksum(vec, 1) ? "in" : "", - hlen)); + hlen); } hlen -= 4; /* subtract common header size */ @@ -639,17 +724,17 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * while (hlen > sizeof(struct icmp_mpls_ext_object_header_t)) { icmp_mpls_ext_object_header = (const struct icmp_mpls_ext_object_header_t *)obj_tptr; - ND_TCHECK(*icmp_mpls_ext_object_header); - obj_tlen = EXTRACT_16BITS(icmp_mpls_ext_object_header->length); - obj_class_num = icmp_mpls_ext_object_header->class_num; - obj_ctype = icmp_mpls_ext_object_header->ctype; + ND_TCHECK_SIZE(icmp_mpls_ext_object_header); + obj_tlen = GET_BE_U_2(icmp_mpls_ext_object_header->length); + obj_class_num = GET_U_1(icmp_mpls_ext_object_header->class_num); + obj_ctype = GET_U_1(icmp_mpls_ext_object_header->ctype); obj_tptr += sizeof(struct icmp_mpls_ext_object_header_t); - ND_PRINT((ndo, "\n\t %s Object (%u), Class-Type: %u, length %u", + ND_PRINT("\n\t %s Object (%u), Class-Type: %u, length %u", tok2str(icmp_mpls_ext_obj_values,"unknown",obj_class_num), obj_class_num, obj_ctype, - obj_tlen)); + obj_tlen); hlen-=sizeof(struct icmp_mpls_ext_object_header_t); /* length field includes tlv header */ @@ -664,12 +749,11 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * case 1: switch(obj_ctype) { case 1: - ND_TCHECK2(*obj_tptr, 4); - raw_label = EXTRACT_32BITS(obj_tptr); - ND_PRINT((ndo, "\n\t label %u, exp %u", MPLS_LABEL(raw_label), MPLS_EXP(raw_label))); + raw_label = GET_BE_U_4(obj_tptr); + ND_PRINT("\n\t label %u, exp %u", MPLS_LABEL(raw_label), MPLS_EXP(raw_label)); if (MPLS_STACK(raw_label)) - ND_PRINT((ndo, ", [S]")); - ND_PRINT((ndo, ", ttl %u", MPLS_TTL(raw_label))); + ND_PRINT(", [S]"); + ND_PRINT(", ttl %u", MPLS_TTL(raw_label)); break; default: print_unknown_data(ndo, obj_tptr, "\n\t ", obj_tlen); @@ -694,11 +778,5 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * return; trunc: - ND_PRINT((ndo, "[|icmp]")); + nd_print_trunc(ndo); } -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/print-icmp6.c b/contrib/tcpdump/print-icmp6.c index 5cef0efabd..f16c1fa9d4 100644 --- a/contrib/tcpdump/print-icmp6.c +++ b/contrib/tcpdump/print-icmp6.c @@ -22,10 +22,10 @@ /* \summary: IPv6 Internet Control Message Protocol (ICMPv6) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include #include @@ -41,10 +41,6 @@ #include "udp.h" #include "ah.h" -static const char icmp6_tstr[] = " [|icmp6]"; -static const char rpl_tstr[] = " [|rpl]"; -static const char mldv2_tstr[] = " [|mldv2]"; - /* NetBSD: icmp6.h,v 1.13 2000/08/03 16:30:37 itojun Exp */ /* $KAME: icmp6.h,v 1.22 2000/08/03 15:25:16 jinmei Exp $ */ @@ -78,19 +74,21 @@ static const char mldv2_tstr[] = " [|mldv2]"; */ struct icmp6_hdr { - uint8_t icmp6_type; /* type field */ - uint8_t icmp6_code; /* code field */ - uint16_t icmp6_cksum; /* checksum field */ + nd_uint8_t icmp6_type; /* type field */ + nd_uint8_t icmp6_code; /* code field */ + nd_uint16_t icmp6_cksum; /* checksum field */ union { - uint32_t icmp6_un_data32[1]; /* type-specific field */ - uint16_t icmp6_un_data16[2]; /* type-specific field */ - uint8_t icmp6_un_data8[4]; /* type-specific field */ + nd_uint32_t icmp6_un_data32[1]; /* type-specific field */ + nd_uint16_t icmp6_un_data16[2]; /* type-specific field */ + nd_uint8_t icmp6_un_data8[4]; /* type-specific field */ + nd_byte icmp6_un_data[1]; /* type-specific field */ } icmp6_dataun; }; #define icmp6_data32 icmp6_dataun.icmp6_un_data32 #define icmp6_data16 icmp6_dataun.icmp6_un_data16 #define icmp6_data8 icmp6_dataun.icmp6_un_data8 +#define icmp6_data icmp6_dataun.icmp6_un_data #define icmp6_pptr icmp6_data32[0] /* parameter prob */ #define icmp6_mtu icmp6_data32[0] /* packet too big */ #define icmp6_id icmp6_data16[0] /* echo request/reply */ @@ -123,8 +121,8 @@ struct icmp6_hdr { #define ICMP6_WRUREPLY 140 /* who are you reply */ #define ICMP6_FQDN_QUERY 139 /* FQDN query */ #define ICMP6_FQDN_REPLY 140 /* FQDN reply */ -#define ICMP6_NI_QUERY 139 /* node information request */ -#define ICMP6_NI_REPLY 140 /* node information reply */ +#define ICMP6_NI_QUERY 139 /* node information request - RFC 4620 */ +#define ICMP6_NI_REPLY 140 /* node information reply - RFC 4620 */ #define IND_SOLICIT 141 /* inverse neighbor solicitation */ #define IND_ADVERT 142 /* inverse neighbor advertisement */ @@ -141,7 +139,7 @@ struct icmp6_hdr { #define ICMP6_MAXTYPE 201 #define ICMP6_DST_UNREACH_NOROUTE 0 /* no route to destination */ -#define ICMP6_DST_UNREACH_ADMIN 1 /* administratively prohibited */ +#define ICMP6_DST_UNREACH_ADMIN 1 /* administratively prohibited */ #define ICMP6_DST_UNREACH_NOTNEIGHBOR 2 /* not a neighbor(obsolete) */ #define ICMP6_DST_UNREACH_BEYONDSCOPE 2 /* beyond scope of source address */ #define ICMP6_DST_UNREACH_ADDR 3 /* address unreachable */ @@ -150,9 +148,10 @@ struct icmp6_hdr { #define ICMP6_TIME_EXCEED_TRANSIT 0 /* ttl==0 in transit */ #define ICMP6_TIME_EXCEED_REASSEMBLY 1 /* ttl==0 in reass */ -#define ICMP6_PARAMPROB_HEADER 0 /* erroneous header field */ +#define ICMP6_PARAMPROB_HEADER 0 /* erroneous header field */ #define ICMP6_PARAMPROB_NEXTHEADER 1 /* unrecognized next header */ #define ICMP6_PARAMPROB_OPTION 2 /* unrecognized option */ +#define ICMP6_PARAMPROB_FRAGHDRCHAIN 3 /* incomplete header chain */ #define ICMP6_INFOMSG_MASK 0x80 /* all informational messages */ @@ -177,7 +176,7 @@ struct icmp6_hdr { */ struct mld6_hdr { struct icmp6_hdr mld6_hdr; - struct in6_addr mld6_addr; /* multicast address */ + nd_ipv6 mld6_addr; /* multicast address */ }; #define mld6_type mld6_hdr.icmp6_type @@ -205,8 +204,8 @@ struct nd_router_solicit { /* router solicitation */ struct nd_router_advert { /* router advertisement */ struct icmp6_hdr nd_ra_hdr; - uint32_t nd_ra_reachable; /* reachable time */ - uint32_t nd_ra_retransmit; /* retransmit timer */ + nd_uint32_t nd_ra_reachable; /* reachable time */ + nd_uint32_t nd_ra_retransmit; /* retransmit timer */ /* could be followed by options */ }; @@ -218,6 +217,7 @@ struct nd_router_advert { /* router advertisement */ #define ND_RA_FLAG_MANAGED 0x80 #define ND_RA_FLAG_OTHER 0x40 #define ND_RA_FLAG_HOME_AGENT 0x20 +#define ND_RA_FLAG_IPV6ONLY 0x02 /* * Router preference values based on draft-draves-ipngwg-router-selection-01. @@ -234,7 +234,7 @@ struct nd_router_advert { /* router advertisement */ struct nd_neighbor_solicit { /* neighbor solicitation */ struct icmp6_hdr nd_ns_hdr; - struct in6_addr nd_ns_target; /*target address */ + nd_ipv6 nd_ns_target; /*target address */ /* could be followed by options */ }; @@ -245,7 +245,7 @@ struct nd_neighbor_solicit { /* neighbor solicitation */ struct nd_neighbor_advert { /* neighbor advertisement */ struct icmp6_hdr nd_na_hdr; - struct in6_addr nd_na_target; /* target address */ + nd_ipv6 nd_na_target; /* target address */ /* could be followed by options */ }; @@ -260,8 +260,8 @@ struct nd_neighbor_advert { /* neighbor advertisement */ struct nd_redirect { /* redirect */ struct icmp6_hdr nd_rd_hdr; - struct in6_addr nd_rd_target; /* target address */ - struct in6_addr nd_rd_dst; /* destination address */ + nd_ipv6 nd_rd_target; /* target address */ + nd_ipv6 nd_rd_dst; /* destination address */ /* could be followed by options */ }; @@ -271,8 +271,8 @@ struct nd_redirect { /* redirect */ #define nd_rd_reserved nd_rd_hdr.icmp6_data32[0] struct nd_opt_hdr { /* Neighbor discovery option header */ - uint8_t nd_opt_type; - uint8_t nd_opt_len; + nd_uint8_t nd_opt_type; + nd_uint8_t nd_opt_len; /* followed by option specific data*/ }; @@ -288,14 +288,14 @@ struct nd_opt_hdr { /* Neighbor discovery option header */ #define ND_OPT_DNSSL 31 struct nd_opt_prefix_info { /* prefix information */ - nd_uint8_t nd_opt_pi_type; - nd_uint8_t nd_opt_pi_len; - nd_uint8_t nd_opt_pi_prefix_len; - nd_uint8_t nd_opt_pi_flags_reserved; - nd_uint32_t nd_opt_pi_valid_time; - nd_uint32_t nd_opt_pi_preferred_time; - nd_uint32_t nd_opt_pi_reserved2; - struct in6_addr nd_opt_pi_prefix; + nd_uint8_t nd_opt_pi_type; + nd_uint8_t nd_opt_pi_len; + nd_uint8_t nd_opt_pi_prefix_len; + nd_uint8_t nd_opt_pi_flags_reserved; + nd_uint32_t nd_opt_pi_valid_time; + nd_uint32_t nd_opt_pi_preferred_time; + nd_uint32_t nd_opt_pi_reserved2; + nd_ipv6 nd_opt_pi_prefix; }; #define ND_OPT_PI_FLAG_ONLINK 0x80 @@ -303,57 +303,57 @@ struct nd_opt_prefix_info { /* prefix information */ #define ND_OPT_PI_FLAG_ROUTER 0x20 /*2292bis*/ struct nd_opt_rd_hdr { /* redirected header */ - uint8_t nd_opt_rh_type; - uint8_t nd_opt_rh_len; - uint16_t nd_opt_rh_reserved1; - uint32_t nd_opt_rh_reserved2; + nd_uint8_t nd_opt_rh_type; + nd_uint8_t nd_opt_rh_len; + nd_uint16_t nd_opt_rh_reserved1; + nd_uint32_t nd_opt_rh_reserved2; /* followed by IP header and data */ }; struct nd_opt_mtu { /* MTU option */ - uint8_t nd_opt_mtu_type; - uint8_t nd_opt_mtu_len; - uint16_t nd_opt_mtu_reserved; - uint32_t nd_opt_mtu_mtu; + nd_uint8_t nd_opt_mtu_type; + nd_uint8_t nd_opt_mtu_len; + nd_uint16_t nd_opt_mtu_reserved; + nd_uint32_t nd_opt_mtu_mtu; }; struct nd_opt_rdnss { /* RDNSS RFC 6106 5.1 */ - uint8_t nd_opt_rdnss_type; - uint8_t nd_opt_rdnss_len; - uint16_t nd_opt_rdnss_reserved; - uint32_t nd_opt_rdnss_lifetime; - struct in6_addr nd_opt_rdnss_addr[1]; /* variable-length */ + nd_uint8_t nd_opt_rdnss_type; + nd_uint8_t nd_opt_rdnss_len; + nd_uint16_t nd_opt_rdnss_reserved; + nd_uint32_t nd_opt_rdnss_lifetime; + nd_ipv6 nd_opt_rdnss_addr[1]; /* variable-length */ }; struct nd_opt_dnssl { /* DNSSL RFC 6106 5.2 */ - uint8_t nd_opt_dnssl_type; - uint8_t nd_opt_dnssl_len; - uint16_t nd_opt_dnssl_reserved; - uint32_t nd_opt_dnssl_lifetime; + nd_uint8_t nd_opt_dnssl_type; + nd_uint8_t nd_opt_dnssl_len; + nd_uint16_t nd_opt_dnssl_reserved; + nd_uint32_t nd_opt_dnssl_lifetime; /* followed by list of DNS search domains, variable-length */ }; struct nd_opt_advinterval { /* Advertisement interval option */ - uint8_t nd_opt_adv_type; - uint8_t nd_opt_adv_len; - uint16_t nd_opt_adv_reserved; - uint32_t nd_opt_adv_interval; + nd_uint8_t nd_opt_adv_type; + nd_uint8_t nd_opt_adv_len; + nd_uint16_t nd_opt_adv_reserved; + nd_uint32_t nd_opt_adv_interval; }; struct nd_opt_homeagent_info { /* Home Agent info */ - uint8_t nd_opt_hai_type; - uint8_t nd_opt_hai_len; - uint16_t nd_opt_hai_reserved; - int16_t nd_opt_hai_preference; - uint16_t nd_opt_hai_lifetime; + nd_uint8_t nd_opt_hai_type; + nd_uint8_t nd_opt_hai_len; + nd_uint16_t nd_opt_hai_reserved; + nd_uint16_t nd_opt_hai_preference; + nd_uint16_t nd_opt_hai_lifetime; }; struct nd_opt_route_info { /* route info */ - uint8_t nd_opt_rti_type; - uint8_t nd_opt_rti_len; - uint8_t nd_opt_rti_prefixlen; - uint8_t nd_opt_rti_flags; - uint32_t nd_opt_rti_lifetime; + nd_uint8_t nd_opt_rti_type; + nd_uint8_t nd_opt_rti_len; + nd_uint8_t nd_opt_rti_prefixlen; + nd_uint8_t nd_opt_rti_flags; + nd_uint32_t nd_opt_rti_lifetime; /* prefix follows */ }; @@ -362,12 +362,12 @@ struct nd_opt_route_info { /* route info */ */ struct icmp6_namelookup { - struct icmp6_hdr icmp6_nl_hdr; - uint8_t icmp6_nl_nonce[8]; - int32_t icmp6_nl_ttl; + struct icmp6_hdr icmp6_nl_hdr; + nd_byte icmp6_nl_nonce[8]; + nd_int32_t icmp6_nl_ttl; #if 0 - uint8_t icmp6_nl_len; - uint8_t icmp6_nl_name[3]; + nd_uint8_t icmp6_nl_len; + nd_byte icmp6_nl_name[3]; #endif /* could be followed by options */ }; @@ -377,7 +377,7 @@ struct icmp6_namelookup { */ struct icmp6_nodeinfo { struct icmp6_hdr icmp6_ni_hdr; - uint8_t icmp6_ni_nonce[8]; + nd_byte icmp6_ni_nonce[8]; /* could be followed by reply data */ }; @@ -388,7 +388,7 @@ struct icmp6_nodeinfo { #define ni_flags icmp6_ni_hdr.icmp6_data16[1] #define NI_QTYPE_NOOP 0 /* NOOP */ -#define NI_QTYPE_SUPTYPES 1 /* Supported Qtypes */ +#define NI_QTYPE_SUPTYPES 1 /* Supported Qtypes (drafts up to 09) */ #define NI_QTYPE_FQDN 2 /* FQDN (draft 04) */ #define NI_QTYPE_DNSNAME 2 /* DNS Name */ #define NI_QTYPE_NODEADDR 3 /* Node Addresses */ @@ -408,9 +408,9 @@ struct icmp6_nodeinfo { #define NI_NODEADDR_FLAG_ANYCAST ((uint16_t)htons(0x40)) /* just experimental. not in spec */ struct ni_reply_fqdn { - uint32_t ni_fqdn_ttl; /* TTL */ - uint8_t ni_fqdn_namelen; /* length in octets of the FQDN */ - uint8_t ni_fqdn_name[3]; /* XXX: alignment */ + nd_uint32_t ni_fqdn_ttl; /* TTL */ + nd_uint8_t ni_fqdn_namelen; /* length in octets of the FQDN */ + nd_byte ni_fqdn_name[3]; /* XXX: alignment */ }; /* @@ -418,10 +418,10 @@ struct ni_reply_fqdn { */ struct icmp6_router_renum { /* router renumbering header */ struct icmp6_hdr rr_hdr; - uint8_t rr_segnum; - uint8_t rr_flags; - uint16_t rr_maxdelay; - uint32_t rr_reserved; + nd_uint8_t rr_segnum; + nd_uint8_t rr_flags; + nd_uint16_t rr_maxdelay; + nd_uint32_t rr_reserved; }; #define ICMP6_RR_FLAGS_TEST 0x80 #define ICMP6_RR_FLAGS_REQRESULT 0x40 @@ -435,14 +435,14 @@ struct icmp6_router_renum { /* router renumbering header */ #define rr_seqnum rr_hdr.icmp6_data32[0] struct rr_pco_match { /* match prefix part */ - uint8_t rpm_code; - uint8_t rpm_len; - uint8_t rpm_ordinal; - uint8_t rpm_matchlen; - uint8_t rpm_minlen; - uint8_t rpm_maxlen; - uint16_t rpm_reserved; - struct in6_addr rpm_prefix; + nd_uint8_t rpm_code; + nd_uint8_t rpm_len; + nd_uint8_t rpm_ordinal; + nd_uint8_t rpm_matchlen; + nd_uint8_t rpm_minlen; + nd_uint8_t rpm_maxlen; + nd_uint16_t rpm_reserved; + nd_ipv6 rpm_prefix; }; #define RPM_PCO_ADD 1 @@ -451,14 +451,14 @@ struct rr_pco_match { /* match prefix part */ #define RPM_PCO_MAX 4 struct rr_pco_use { /* use prefix part */ - uint8_t rpu_uselen; - uint8_t rpu_keeplen; - uint8_t rpu_ramask; - uint8_t rpu_raflags; - uint32_t rpu_vltime; - uint32_t rpu_pltime; - uint32_t rpu_flags; - struct in6_addr rpu_prefix; + nd_uint8_t rpu_uselen; + nd_uint8_t rpu_keeplen; + nd_uint8_t rpu_ramask; + nd_uint8_t rpu_raflags; + nd_uint32_t rpu_vltime; + nd_uint32_t rpu_pltime; + nd_uint32_t rpu_flags; + nd_ipv6 rpu_prefix; }; #define ICMP6_RR_PCOUSE_RAFLAGS_ONLINK 0x80 #define ICMP6_RR_PCOUSE_RAFLAGS_AUTO 0x40 @@ -468,11 +468,11 @@ struct rr_pco_use { /* use prefix part */ #define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME ((uint32_t)htonl(0x40000000)) struct rr_result { /* router renumbering result message */ - uint16_t rrr_flags; - uint8_t rrr_ordinal; - uint8_t rrr_matchedlen; - uint32_t rrr_ifid; - struct in6_addr rrr_prefix; + nd_uint16_t rrr_flags; + nd_uint8_t rrr_ordinal; + nd_uint8_t rrr_matchedlen; + nd_uint32_t rrr_ifid; + nd_ipv6 rrr_prefix; }; /* network endian */ #define ICMP6_RR_RESULT_FLAGS_OOB ((uint16_t)htons(0x0002)) @@ -481,7 +481,7 @@ struct rr_result { /* router renumbering result message */ static const char *get_rtpref(u_int); static const char *get_lifetime(uint32_t); static void print_lladdr(netdissect_options *ndo, const u_char *, size_t); -static void icmp6_opt_print(netdissect_options *ndo, const u_char *, int); +static int icmp6_opt_print(netdissect_options *ndo, const u_char *, int); static void mld6_print(netdissect_options *ndo, const u_char *); static void mldv2_report_print(netdissect_options *ndo, const u_char *, u_int); static void mldv2_query_print(netdissect_options *ndo, const u_char *, u_int); @@ -494,7 +494,158 @@ static void icmp6_rrenum_print(netdissect_options *ndo, const u_char *, const u_ #define abs(a) ((0 < (a)) ? (a) : -(a)) #endif -#include "rpl.h" +/* + * DIO: Updated to RFC6550, as published in 2012: section 6. (page 30) + */ + +#define ND_RPL_MESSAGE 155 /* 0x9B */ + +enum ND_RPL_CODE { + ND_RPL_DAG_IS=0x00, + ND_RPL_DAG_IO=0x01, + ND_RPL_DAO =0x02, + ND_RPL_DAO_ACK=0x03, + ND_RPL_SEC_DAG_IS = 0x80, + ND_RPL_SEC_DAG_IO = 0x81, + ND_RPL_SEC_DAG = 0x82, + ND_RPL_SEC_DAG_ACK= 0x83, + ND_RPL_SEC_CONSIST= 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 */ +}; + +#define DAGID_LEN 16 + +/* section 6 of draft-ietf-roll-rpl-19 */ +struct nd_rpl_security { + nd_uint8_t rpl_sec_t_reserved; /* bit 7 is T-bit */ + nd_uint8_t rpl_sec_algo; + nd_uint16_t rpl_sec_kim_lvl_flags; /* bit 15/14, KIM */ + /* bit 10-8, LVL, bit 7-0 flags */ + nd_uint32_t rpl_sec_counter; +#if 0 + nd_byte rpl_sec_ki[0]; /* depends upon kim */ +#endif +}; + +/* section 6.2.1, DODAG Information Solication (DIS_IS) */ +struct nd_rpl_dis_is { + nd_uint8_t rpl_dis_flags; + nd_uint8_t rpl_dis_reserved; +#if 0 + nd_byte rpl_dis_options[0]; +#endif +}; + +/* section 6.3.1, DODAG Information Object (DIO) */ +struct nd_rpl_dio { + nd_uint8_t rpl_instanceid; + nd_uint8_t rpl_version; + nd_uint16_t rpl_dagrank; + nd_uint8_t rpl_mopprf; /* bit 7=G, 5-3=MOP, 2-0=PRF */ + nd_uint8_t rpl_dtsn; /* Dest. Advertisement Trigger Sequence Number */ + nd_uint8_t rpl_flags; /* no flags defined yet */ + nd_uint8_t rpl_resv1; + nd_byte rpl_dagid[DAGID_LEN]; +}; +#define RPL_DIO_GROUND_FLAG 0x80 +#define RPL_DIO_MOP_SHIFT 3 +#define RPL_DIO_MOP_MASK (7 << RPL_DIO_MOP_SHIFT) +#define RPL_DIO_PRF_SHIFT 0 +#define RPL_DIO_PRF_MASK (7 << RPL_DIO_PRF_SHIFT) +#define RPL_DIO_GROUNDED(X) ((X)&RPL_DIO_GROUND_FLAG) +#define RPL_DIO_MOP(X) (enum RPL_DIO_MOP)(((X)&RPL_DIO_MOP_MASK) >> RPL_DIO_MOP_SHIFT) +#define RPL_DIO_PRF(X) (((X)&RPL_DIO_PRF_MASK) >> RPL_DIO_PRF_SHIFT) + +enum RPL_DIO_MOP { + RPL_DIO_NONSTORING= 0x0, + RPL_DIO_STORING = 0x1, + RPL_DIO_NONSTORING_MULTICAST = 0x2, + RPL_DIO_STORING_MULTICAST = 0x3 +}; + +enum RPL_SUBOPT { + RPL_OPT_PAD1 = 0, + RPL_OPT_PADN = 1, + RPL_DIO_METRICS = 2, + RPL_DIO_ROUTINGINFO = 3, + RPL_DIO_CONFIG = 4, + RPL_DAO_RPLTARGET = 5, + RPL_DAO_TRANSITINFO = 6, + RPL_DIO_DESTPREFIX = 8, + RPL_DAO_RPLTARGET_DESC=9 +}; + +struct rpl_genoption { + nd_uint8_t rpl_dio_type; + nd_uint8_t rpl_dio_len; /* suboption length, not including type/len */ +}; +#define RPL_GENOPTION_LEN 2 + +#define RPL_DIO_LIFETIME_INFINITE 0xffffffff +#define RPL_DIO_LIFETIME_DISCONNECT 0 + +struct rpl_dio_destprefix { + nd_uint8_t rpl_dio_type; + nd_uint8_t rpl_dio_len; + nd_uint8_t rpl_dio_prefixlen; /* in bits */ + nd_uint8_t rpl_dio_prf; /* flags, including Route Preference */ + nd_uint32_t rpl_dio_prefixlifetime; /* in seconds */ +#if 0 + nd_byte rpl_dio_prefix[0]; /* variable number of bytes */ +#endif +}; + +/* section 6.4.1, DODAG Information Object (DIO) */ +struct nd_rpl_dao { + nd_uint8_t rpl_instanceid; + nd_uint8_t rpl_flags; /* bit 7=K, 6=D */ + nd_uint8_t rpl_resv; + nd_uint8_t rpl_daoseq; + nd_byte rpl_dagid[DAGID_LEN]; /* present when D set. */ +}; +#define ND_RPL_DAO_MIN_LEN 4 /* length without DAGID */ + +/* indicates if this DAO is to be acK'ed */ +#define RPL_DAO_K_SHIFT 7 +#define RPL_DAO_K_MASK (1 << RPL_DAO_K_SHIFT) +#define RPL_DAO_K(X) (((X)&RPL_DAO_K_MASK) >> RPL_DAO_K_SHIFT) + +/* indicates if the DAGID is present */ +#define RPL_DAO_D_SHIFT 6 +#define RPL_DAO_D_MASK (1 << RPL_DAO_D_SHIFT) +#define RPL_DAO_D(X) (((X)&RPL_DAO_D_MASK) >> RPL_DAO_D_SHIFT) + +struct rpl_dao_target { + nd_uint8_t rpl_dao_type; + nd_uint8_t rpl_dao_len; + nd_uint8_t rpl_dao_flags; /* unused */ + nd_uint8_t rpl_dao_prefixlen; /* in bits */ +#if 0 + nd_byte rpl_dao_prefix[0]; /* variable number of bytes */ +#endif +}; + +/* section 6.5.1, Destination Advertisement Object Acknowledgement (DAO-ACK) */ +struct nd_rpl_daoack { + nd_uint8_t rpl_instanceid; + nd_uint8_t rpl_flags; /* bit 7=D */ + nd_uint8_t rpl_daoseq; + nd_uint8_t rpl_status; + nd_byte rpl_dagid[DAGID_LEN]; /* present when D set. */ +}; +#define ND_RPL_DAOACK_MIN_LEN 4 /* length without DAGID */ +/* indicates if the DAGID is present */ +#define RPL_DAOACK_D_SHIFT 7 +#define RPL_DAOACK_D_MASK (1 << RPL_DAOACK_D_SHIFT) +#define RPL_DAOACK_D(X) (((X)&RPL_DAOACK_D_MASK) >> RPL_DAOACK_D_SHIFT) static const struct tok icmp6_type_values[] = { { ICMP6_DST_UNREACH, "destination unreachable"}, @@ -549,6 +700,7 @@ static const struct tok icmp6_opt_ra_flag_values[] = { { ND_RA_FLAG_MANAGED, "managed" }, { ND_RA_FLAG_OTHER, "other stateful"}, { ND_RA_FLAG_HOME_AGENT, "home agent"}, + { ND_RA_FLAG_IPV6ONLY, "ipv6 only"}, { 0, NULL } }; @@ -620,13 +772,14 @@ print_lladdr(netdissect_options *ndo, const uint8_t *p, size_t l) ep = p + l; while (l > 0 && q < ep) { if (q > p) - ND_PRINT((ndo,":")); - ND_PRINT((ndo,"%02x", *q++)); + ND_PRINT(":"); + ND_PRINT("%02x", GET_U_1(q)); + q++; l--; } } -static int icmp6_cksum(netdissect_options *ndo, const struct ip6_hdr *ip6, +static uint16_t icmp6_cksum(netdissect_options *ndo, const struct ip6_hdr *ip6, const struct icmp6_hdr *icp, u_int len) { return nextproto6_cksum(ndo, ip6, (const uint8_t *)(const void *)icp, len, len, @@ -642,7 +795,7 @@ static const struct tok rpl_mop_values[] = { }; static const struct tok rpl_subopt_values[] = { - { RPL_OPT_PAD0, "pad0"}, + { RPL_OPT_PAD1, "pad1"}, { RPL_OPT_PADN, "padN"}, { RPL_DIO_METRICS, "metrics"}, { RPL_DIO_ROUTINGINFO, "routinginfo"}, @@ -655,44 +808,41 @@ static const struct tok rpl_subopt_values[] = { }; static void -rpl_dio_printopt(netdissect_options *ndo, - const struct rpl_dio_genoption *opt, - u_int length) +rpl_printopts(netdissect_options *ndo, const uint8_t *opts, u_int length) { - if(length < RPL_DIO_GENOPTION_LEN) return; - length -= RPL_DIO_GENOPTION_LEN; - - ND_TCHECK(opt->rpl_dio_len); - - while((opt->rpl_dio_type == RPL_OPT_PAD0 && - (const u_char *)opt < ndo->ndo_snapend) || - ND_TTEST2(*opt,(opt->rpl_dio_len+2))) { - - unsigned int optlen = opt->rpl_dio_len+2; - if(opt->rpl_dio_type == RPL_OPT_PAD0) { + const struct rpl_genoption *opt; + uint8_t dio_type; + u_int optlen; + + while (length != 0) { + opt = (const struct rpl_genoption *)opts; + dio_type = GET_U_1(opt->rpl_dio_type); + if (dio_type == RPL_OPT_PAD1) { optlen = 1; - ND_PRINT((ndo, " opt:pad0")); + ND_PRINT(" opt:pad1"); } else { - ND_PRINT((ndo, " opt:%s len:%u ", - tok2str(rpl_subopt_values, "subopt:%u", opt->rpl_dio_type), - optlen)); - if(ndo->ndo_vflag > 2) { - unsigned int paylen = opt->rpl_dio_len; - if(paylen > length) paylen = length; + if (length < RPL_GENOPTION_LEN) + goto trunc; + optlen = GET_U_1(opt->rpl_dio_len)+RPL_GENOPTION_LEN; + ND_PRINT(" opt:%s len:%u ", + tok2str(rpl_subopt_values, "subopt:%u", dio_type), + optlen); + ND_TCHECK_LEN(opt, optlen); + if (length < optlen) + goto trunc; + if (ndo->ndo_vflag > 2) { hex_print(ndo, " ", - ((const uint8_t *)opt) + RPL_DIO_GENOPTION_LEN, /* content of DIO option */ - paylen); + opts + RPL_GENOPTION_LEN, /* content of DIO option */ + optlen - RPL_GENOPTION_LEN); } } - opt = (const struct rpl_dio_genoption *)(((const char *)opt) + optlen); + opts += optlen; length -= optlen; - ND_TCHECK(opt->rpl_dio_len); } return; trunc: - ND_PRINT((ndo, "%s", rpl_tstr)); - return; + nd_print_trunc(ndo); } static void @@ -702,26 +852,25 @@ rpl_dio_print(netdissect_options *ndo, const struct nd_rpl_dio *dio = (const struct nd_rpl_dio *)bp; const char *dagid_str; - ND_TCHECK(*dio); + ND_TCHECK_SIZE(dio); dagid_str = ip6addr_string (ndo, dio->rpl_dagid); - ND_PRINT((ndo, " [dagid:%s,seq:%u,instance:%u,rank:%u,%smop:%s,prf:%u]", + ND_PRINT(" [dagid:%s,seq:%u,instance:%u,rank:%u,%smop:%s,prf:%u]", dagid_str, - dio->rpl_dtsn, - dio->rpl_instanceid, - EXTRACT_16BITS(&dio->rpl_dagrank), - RPL_DIO_GROUNDED(dio->rpl_mopprf) ? "grounded,":"", - tok2str(rpl_mop_values, "mop%u", RPL_DIO_MOP(dio->rpl_mopprf)), - RPL_DIO_PRF(dio->rpl_mopprf))); + GET_U_1(dio->rpl_dtsn), + GET_U_1(dio->rpl_instanceid), + GET_BE_U_2(dio->rpl_dagrank), + RPL_DIO_GROUNDED(GET_U_1(dio->rpl_mopprf)) ? "grounded,":"", + tok2str(rpl_mop_values, "mop%u", RPL_DIO_MOP(GET_U_1(dio->rpl_mopprf))), + RPL_DIO_PRF(GET_U_1(dio->rpl_mopprf))); if(ndo->ndo_vflag > 1) { - const struct rpl_dio_genoption *opt = (const struct rpl_dio_genoption *)&dio[1]; - rpl_dio_printopt(ndo, opt, length); + rpl_printopts(ndo, bp + sizeof(struct nd_rpl_dio), + length - sizeof(struct nd_rpl_dio)); } return; trunc: - ND_PRINT((ndo, "%s", rpl_tstr)); - return; + nd_print_trunc(ndo); } static void @@ -730,15 +879,17 @@ rpl_dao_print(netdissect_options *ndo, { const struct nd_rpl_dao *dao = (const struct nd_rpl_dao *)bp; const char *dagid_str = ""; + uint8_t rpl_flags; - ND_TCHECK(*dao); + ND_TCHECK_SIZE(dao); if (length < ND_RPL_DAO_MIN_LEN) - goto tooshort; + goto tooshort; bp += ND_RPL_DAO_MIN_LEN; length -= ND_RPL_DAO_MIN_LEN; - if(RPL_DAO_D(dao->rpl_flags)) { - ND_TCHECK2(dao->rpl_dagid, DAGID_LEN); + rpl_flags = GET_U_1(dao->rpl_flags); + if(RPL_DAO_D(rpl_flags)) { + ND_TCHECK_LEN(dao->rpl_dagid, DAGID_LEN); if (length < DAGID_LEN) goto tooshort; dagid_str = ip6addr_string (ndo, dao->rpl_dagid); @@ -746,27 +897,25 @@ rpl_dao_print(netdissect_options *ndo, length -= DAGID_LEN; } - ND_PRINT((ndo, " [dagid:%s,seq:%u,instance:%u%s%s,%02x]", + ND_PRINT(" [dagid:%s,seq:%u,instance:%u%s%s,%02x]", dagid_str, - dao->rpl_daoseq, - dao->rpl_instanceid, - RPL_DAO_K(dao->rpl_flags) ? ",acK":"", - RPL_DAO_D(dao->rpl_flags) ? ",Dagid":"", - dao->rpl_flags)); + GET_U_1(dao->rpl_daoseq), + GET_U_1(dao->rpl_instanceid), + RPL_DAO_K(rpl_flags) ? ",acK":"", + RPL_DAO_D(rpl_flags) ? ",Dagid":"", + rpl_flags); if(ndo->ndo_vflag > 1) { - const struct rpl_dio_genoption *opt = (const struct rpl_dio_genoption *)bp; - rpl_dio_printopt(ndo, opt, length); + rpl_printopts(ndo, bp, length); } return; trunc: - ND_PRINT((ndo, "%s", rpl_tstr)); + nd_print_trunc(ndo); return; tooshort: - ND_PRINT((ndo," [|length too short]")); - return; + ND_PRINT(" [|length too short]"); } static void @@ -776,14 +925,14 @@ rpl_daoack_print(netdissect_options *ndo, const struct nd_rpl_daoack *daoack = (const struct nd_rpl_daoack *)bp; const char *dagid_str = ""; - ND_TCHECK2(*daoack, ND_RPL_DAOACK_MIN_LEN); + ND_TCHECK_LEN(daoack, ND_RPL_DAOACK_MIN_LEN); if (length < ND_RPL_DAOACK_MIN_LEN) - goto tooshort; + goto tooshort; bp += ND_RPL_DAOACK_MIN_LEN; length -= ND_RPL_DAOACK_MIN_LEN; - if(RPL_DAOACK_D(daoack->rpl_flags)) { - ND_TCHECK2(daoack->rpl_dagid, DAGID_LEN); + if(RPL_DAOACK_D(GET_U_1(daoack->rpl_flags))) { + ND_TCHECK_LEN(daoack->rpl_dagid, DAGID_LEN); if (length < DAGID_LEN) goto tooshort; dagid_str = ip6addr_string (ndo, daoack->rpl_dagid); @@ -791,80 +940,78 @@ rpl_daoack_print(netdissect_options *ndo, length -= DAGID_LEN; } - ND_PRINT((ndo, " [dagid:%s,seq:%u,instance:%u,status:%u]", + ND_PRINT(" [dagid:%s,seq:%u,instance:%u,status:%u]", dagid_str, - daoack->rpl_daoseq, - daoack->rpl_instanceid, - daoack->rpl_status)); + GET_U_1(daoack->rpl_daoseq), + GET_U_1(daoack->rpl_instanceid), + GET_U_1(daoack->rpl_status)); /* no officially defined options for DAOACK, but print any we find */ if(ndo->ndo_vflag > 1) { - const struct rpl_dio_genoption *opt = (const struct rpl_dio_genoption *)bp; - rpl_dio_printopt(ndo, opt, length); + rpl_printopts(ndo, bp, length); } return; trunc: - ND_PRINT((ndo, "%s", rpl_tstr)); + nd_print_trunc(ndo); return; tooshort: - ND_PRINT((ndo," [|dao-length too short]")); - return; + ND_PRINT(" [|dao-length too short]"); } static void rpl_print(netdissect_options *ndo, - const struct icmp6_hdr *hdr, + uint8_t icmp6_code, const u_char *bp, u_int length) { - int secured = hdr->icmp6_code & 0x80; - int basecode= hdr->icmp6_code & 0x7f; + int secured = icmp6_code & 0x80; + int basecode= icmp6_code & 0x7f; if(secured) { - ND_PRINT((ndo, ", (SEC) [worktodo]")); + ND_PRINT(", (SEC) [worktodo]"); /* XXX * the next header pointer needs to move forward to * skip the secure part. */ return; } else { - ND_PRINT((ndo, ", (CLR)")); + ND_PRINT(", (CLR)"); } switch(basecode) { case ND_RPL_DAG_IS: - ND_PRINT((ndo, "DODAG Information Solicitation")); + ND_PRINT("DODAG Information Solicitation"); if(ndo->ndo_vflag) { } break; case ND_RPL_DAG_IO: - ND_PRINT((ndo, "DODAG Information Object")); + ND_PRINT("DODAG Information Object"); if(ndo->ndo_vflag) { rpl_dio_print(ndo, bp, length); } break; case ND_RPL_DAO: - ND_PRINT((ndo, "Destination Advertisement Object")); + ND_PRINT("Destination Advertisement Object"); if(ndo->ndo_vflag) { rpl_dao_print(ndo, bp, length); } break; case ND_RPL_DAO_ACK: - ND_PRINT((ndo, "Destination Advertisement Object Ack")); + ND_PRINT("Destination Advertisement Object Ack"); if(ndo->ndo_vflag) { rpl_daoack_print(ndo, bp, length); } break; default: - ND_PRINT((ndo, "RPL message, unknown code %u",hdr->icmp6_code)); + ND_PRINT("RPL message, unknown code %u",icmp6_code); break; } return; #if 0 trunc: - ND_PRINT((ndo, "%s", rpl_tstr)); + nd_print_trunc(ndo); return; #endif @@ -876,85 +1023,92 @@ icmp6_print(netdissect_options *ndo, const u_char *bp, u_int length, const u_char *bp2, int fragmented) { const struct icmp6_hdr *dp; + uint8_t icmp6_type, icmp6_code; const struct ip6_hdr *ip; const struct ip6_hdr *oip; const struct udphdr *ouh; - int dport; + uint16_t dport; const u_char *ep; u_int prot; + ndo->ndo_protocol = "icmp6"; dp = (const struct icmp6_hdr *)bp; ip = (const struct ip6_hdr *)bp2; oip = (const struct ip6_hdr *)(dp + 1); /* 'ep' points to the end of available data. */ ep = ndo->ndo_snapend; - - ND_TCHECK(dp->icmp6_cksum); + if (length == 0) { + ND_PRINT("ICMP6, length 0"); + nd_print_invalid(ndo); + return; + } if (ndo->ndo_vflag && !fragmented) { uint16_t sum, udp_sum; - if (ND_TTEST2(bp[0], length)) { - udp_sum = EXTRACT_16BITS(&dp->icmp6_cksum); + if (ND_TTEST_LEN(bp, length)) { + udp_sum = GET_BE_U_2(dp->icmp6_cksum); sum = icmp6_cksum(ndo, ip, dp, length); if (sum != 0) - ND_PRINT((ndo,"[bad icmp6 cksum 0x%04x -> 0x%04x!] ", + ND_PRINT("[bad icmp6 cksum 0x%04x -> 0x%04x!] ", udp_sum, - in_cksum_shouldbe(udp_sum, sum))); + in_cksum_shouldbe(udp_sum, sum)); else - ND_PRINT((ndo,"[icmp6 sum ok] ")); + ND_PRINT("[icmp6 sum ok] "); } } - ND_PRINT((ndo,"ICMP6, %s", tok2str(icmp6_type_values,"unknown icmp6 type (%u)",dp->icmp6_type))); + icmp6_type = GET_U_1(dp->icmp6_type); + ND_PRINT("ICMP6, %s", tok2str(icmp6_type_values,"unknown icmp6 type (%u)",icmp6_type)); /* display cosmetics: print the packet length for printer that use the vflag now */ - if (ndo->ndo_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 )) - ND_PRINT((ndo,", length %u", length)); - - switch (dp->icmp6_type) { + if (ndo->ndo_vflag && (icmp6_type == ND_ROUTER_SOLICIT || + icmp6_type == ND_ROUTER_ADVERT || + icmp6_type == ND_NEIGHBOR_ADVERT || + icmp6_type == ND_NEIGHBOR_SOLICIT || + icmp6_type == ND_REDIRECT || + icmp6_type == ICMP6_HADISCOV_REPLY || + icmp6_type == ICMP6_MOBILEPREFIX_ADVERT )) + ND_PRINT(", length %u", length); + + icmp6_code = GET_U_1(dp->icmp6_code); + + switch (icmp6_type) { case ICMP6_DST_UNREACH: - ND_TCHECK(oip->ip6_dst); - ND_PRINT((ndo,", %s", tok2str(icmp6_dst_unreach_code_values,"unknown unreach code (%u)",dp->icmp6_code))); - switch (dp->icmp6_code) { + ND_PRINT(", %s", tok2str(icmp6_dst_unreach_code_values,"unknown unreach code (%u)",icmp6_code)); + switch (icmp6_code) { case ICMP6_DST_UNREACH_NOROUTE: /* fall through */ case ICMP6_DST_UNREACH_ADMIN: case ICMP6_DST_UNREACH_ADDR: - ND_PRINT((ndo," %s",ip6addr_string(ndo, &oip->ip6_dst))); + ND_PRINT(" %s",GET_IP6ADDR_STRING(oip->ip6_dst)); break; case ICMP6_DST_UNREACH_BEYONDSCOPE: - ND_PRINT((ndo," %s, source address %s", - ip6addr_string(ndo, &oip->ip6_dst), - ip6addr_string(ndo, &oip->ip6_src))); + ND_PRINT(" %s, source address %s", + GET_IP6ADDR_STRING(oip->ip6_dst), + GET_IP6ADDR_STRING(oip->ip6_src)); break; case ICMP6_DST_UNREACH_NOPORT: if ((ouh = get_upperlayer(ndo, (const u_char *)oip, &prot)) == NULL) goto trunc; - dport = EXTRACT_16BITS(&ouh->uh_dport); + dport = GET_BE_U_2(ouh->uh_dport); switch (prot) { case IPPROTO_TCP: - ND_PRINT((ndo,", %s tcp port %s", - ip6addr_string(ndo, &oip->ip6_dst), - tcpport_string(ndo, dport))); + ND_PRINT(", %s tcp port %s", + GET_IP6ADDR_STRING(oip->ip6_dst), + tcpport_string(ndo, dport)); break; case IPPROTO_UDP: - ND_PRINT((ndo,", %s udp port %s", - ip6addr_string(ndo, &oip->ip6_dst), - udpport_string(ndo, dport))); + ND_PRINT(", %s udp port %s", + GET_IP6ADDR_STRING(oip->ip6_dst), + udpport_string(ndo, dport)); break; default: - ND_PRINT((ndo,", %s protocol %d port %d unreachable", - ip6addr_string(ndo, &oip->ip6_dst), - oip->ip6_nxt, dport)); + ND_PRINT(", %s protocol %u port %u unreachable", + GET_IP6ADDR_STRING(oip->ip6_dst), + prot, dport); break; } break; @@ -967,55 +1121,60 @@ icmp6_print(netdissect_options *ndo, } break; case ICMP6_PACKET_TOO_BIG: - ND_TCHECK(dp->icmp6_mtu); - ND_PRINT((ndo,", mtu %u", EXTRACT_32BITS(&dp->icmp6_mtu))); + ND_PRINT(", mtu %u", GET_BE_U_4(dp->icmp6_mtu)); break; case ICMP6_TIME_EXCEEDED: - ND_TCHECK(oip->ip6_dst); - switch (dp->icmp6_code) { + switch (icmp6_code) { case ICMP6_TIME_EXCEED_TRANSIT: - ND_PRINT((ndo," for %s", - ip6addr_string(ndo, &oip->ip6_dst))); + ND_PRINT(" for %s", + GET_IP6ADDR_STRING(oip->ip6_dst)); break; case ICMP6_TIME_EXCEED_REASSEMBLY: - ND_PRINT((ndo," (reassembly)")); + ND_PRINT(" (reassembly)"); break; default: - ND_PRINT((ndo,", unknown code (%u)", dp->icmp6_code)); + ND_PRINT(", unknown code (%u)", icmp6_code); break; } break; case ICMP6_PARAM_PROB: - ND_TCHECK(oip->ip6_dst); - switch (dp->icmp6_code) { + ND_TCHECK_16(oip->ip6_dst); + switch (icmp6_code) { case ICMP6_PARAMPROB_HEADER: - ND_PRINT((ndo,", erroneous - octet %u", EXTRACT_32BITS(&dp->icmp6_pptr))); + ND_PRINT(", erroneous - octet %u", + GET_BE_U_4(dp->icmp6_pptr)); break; case ICMP6_PARAMPROB_NEXTHEADER: - ND_PRINT((ndo,", next header - octet %u", EXTRACT_32BITS(&dp->icmp6_pptr))); + ND_PRINT(", next header - octet %u", + GET_BE_U_4(dp->icmp6_pptr)); break; case ICMP6_PARAMPROB_OPTION: - ND_PRINT((ndo,", option - octet %u", EXTRACT_32BITS(&dp->icmp6_pptr))); + ND_PRINT(", option - octet %u", + GET_BE_U_4(dp->icmp6_pptr)); + break; + case ICMP6_PARAMPROB_FRAGHDRCHAIN: + ND_PRINT(", incomplete header chain - octet %u", + GET_BE_U_4(dp->icmp6_pptr)); break; default: - ND_PRINT((ndo,", code-#%d", - dp->icmp6_code)); + ND_PRINT(", code-#%u", + icmp6_code); break; } break; case ICMP6_ECHO_REQUEST: case ICMP6_ECHO_REPLY: - ND_TCHECK(dp->icmp6_seq); - ND_PRINT((ndo,", seq %u", EXTRACT_16BITS(&dp->icmp6_seq))); + ND_PRINT(", id %u, seq %u", GET_BE_U_2(dp->icmp6_id), + GET_BE_U_2(dp->icmp6_seq)); break; case ICMP6_MEMBERSHIP_QUERY: if (length == MLD_MINLEN) { mld6_print(ndo, (const u_char *)dp); } else if (length >= MLDV2_MINLEN) { - ND_PRINT((ndo," v2")); + ND_PRINT(" v2"); mldv2_query_print(ndo, (const u_char *)dp, length); } else { - ND_PRINT((ndo," unknown-version (len %u) ", length)); + ND_PRINT(" unknown-version (len %u) ", length); } break; case ICMP6_MEMBERSHIP_REPORT: @@ -1027,8 +1186,9 @@ icmp6_print(netdissect_options *ndo, case ND_ROUTER_SOLICIT: #define RTSOLLEN 8 if (ndo->ndo_vflag) { - icmp6_opt_print(ndo, (const u_char *)dp + RTSOLLEN, - length - RTSOLLEN); + if (icmp6_opt_print(ndo, (const u_char *)dp + RTSOLLEN, + length - RTSOLLEN) == -1) + goto trunc; } break; case ND_ROUTER_ADVERT: @@ -1037,30 +1197,30 @@ icmp6_print(netdissect_options *ndo, const struct nd_router_advert *p; p = (const struct nd_router_advert *)dp; - ND_TCHECK(p->nd_ra_retransmit); - ND_PRINT((ndo,"\n\thop limit %u, Flags [%s]" \ + ND_PRINT("\n\thop limit %u, Flags [%s]" ", pref %s, router lifetime %us, reachable time %ums, retrans timer %ums", - (u_int)p->nd_ra_curhoplimit, - bittok2str(icmp6_opt_ra_flag_values,"none",(p->nd_ra_flags_reserved)), - get_rtpref(p->nd_ra_flags_reserved), - EXTRACT_16BITS(&p->nd_ra_router_lifetime), - EXTRACT_32BITS(&p->nd_ra_reachable), - EXTRACT_32BITS(&p->nd_ra_retransmit))); - - icmp6_opt_print(ndo, (const u_char *)dp + RTADVLEN, - length - RTADVLEN); + GET_U_1(p->nd_ra_curhoplimit), + bittok2str(icmp6_opt_ra_flag_values,"none",GET_U_1(p->nd_ra_flags_reserved)), + get_rtpref(GET_U_1(p->nd_ra_flags_reserved)), + GET_BE_U_2(p->nd_ra_router_lifetime), + GET_BE_U_4(p->nd_ra_reachable), + GET_BE_U_4(p->nd_ra_retransmit)); + + if (icmp6_opt_print(ndo, (const u_char *)dp + RTADVLEN, + length - RTADVLEN) == -1) + goto trunc; } break; case ND_NEIGHBOR_SOLICIT: { const struct nd_neighbor_solicit *p; p = (const struct nd_neighbor_solicit *)dp; - ND_TCHECK(p->nd_ns_target); - ND_PRINT((ndo,", who has %s", ip6addr_string(ndo, &p->nd_ns_target))); + ND_PRINT(", who has %s", GET_IP6ADDR_STRING(p->nd_ns_target)); if (ndo->ndo_vflag) { #define NDSOLLEN 24 - icmp6_opt_print(ndo, (const u_char *)dp + NDSOLLEN, - length - NDSOLLEN); + if (icmp6_opt_print(ndo, (const u_char *)dp + NDSOLLEN, + length - NDSOLLEN) == -1) + goto trunc; } } break; @@ -1069,36 +1229,37 @@ icmp6_print(netdissect_options *ndo, const struct nd_neighbor_advert *p; p = (const struct nd_neighbor_advert *)dp; - ND_TCHECK(p->nd_na_target); - ND_PRINT((ndo,", tgt is %s", - ip6addr_string(ndo, &p->nd_na_target))); + ND_PRINT(", tgt is %s", + GET_IP6ADDR_STRING(p->nd_na_target)); if (ndo->ndo_vflag) { - ND_PRINT((ndo,", Flags [%s]", + ND_PRINT(", Flags [%s]", bittok2str(icmp6_nd_na_flag_values, "none", - EXTRACT_32BITS(&p->nd_na_flags_reserved)))); + GET_BE_U_4(p->nd_na_flags_reserved))); #define NDADVLEN 24 - icmp6_opt_print(ndo, (const u_char *)dp + NDADVLEN, - length - NDADVLEN); + if (icmp6_opt_print(ndo, (const u_char *)dp + NDADVLEN, + length - NDADVLEN) == -1) + goto trunc; #undef NDADVLEN } } break; case ND_REDIRECT: -#define RDR(i) ((const struct nd_redirect *)(i)) - ND_TCHECK(RDR(dp)->nd_rd_dst); - ND_PRINT((ndo,", %s", ip6addr_string(ndo, &RDR(dp)->nd_rd_dst))); - ND_TCHECK(RDR(dp)->nd_rd_target); - ND_PRINT((ndo," to %s", - ip6addr_string(ndo, &RDR(dp)->nd_rd_target))); + { + const struct nd_redirect *p; + + p = (const struct nd_redirect *)dp; + ND_PRINT(", %s", GET_IP6ADDR_STRING(p->nd_rd_dst)); + ND_PRINT(" to %s", GET_IP6ADDR_STRING(p->nd_rd_target)); #define REDIRECTLEN 40 if (ndo->ndo_vflag) { - icmp6_opt_print(ndo, (const u_char *)dp + REDIRECTLEN, - length - REDIRECTLEN); + if (icmp6_opt_print(ndo, (const u_char *)dp + REDIRECTLEN, + length - REDIRECTLEN) == -1) + goto trunc; +#undef REDIRECTLEN } + } break; -#undef REDIRECTLEN -#undef RDR case ICMP6_ROUTER_RENUMBERING: icmp6_rrenum_print(ndo, bp, ep); break; @@ -1114,55 +1275,57 @@ icmp6_print(netdissect_options *ndo, break; case ICMP6_MOBILEPREFIX_SOLICIT: /* fall through */ case ICMP6_HADISCOV_REQUEST: - ND_TCHECK(dp->icmp6_data16[0]); - ND_PRINT((ndo,", id 0x%04x", EXTRACT_16BITS(&dp->icmp6_data16[0]))); + ND_PRINT(", id 0x%04x", GET_BE_U_2(dp->icmp6_data16[0])); break; case ICMP6_HADISCOV_REPLY: if (ndo->ndo_vflag) { - const struct in6_addr *in6; const u_char *cp; + const u_char *p; - ND_TCHECK(dp->icmp6_data16[0]); - ND_PRINT((ndo,", id 0x%04x", EXTRACT_16BITS(&dp->icmp6_data16[0]))); + ND_PRINT(", id 0x%04x", + GET_BE_U_2(dp->icmp6_data16[0])); cp = (const u_char *)dp + length; - in6 = (const struct in6_addr *)(dp + 1); - for (; (const u_char *)in6 < cp; in6++) { - ND_TCHECK(*in6); - ND_PRINT((ndo,", %s", ip6addr_string(ndo, in6))); + p = (const u_char *)(dp + 1); + while (p < cp) { + ND_PRINT(", %s", GET_IP6ADDR_STRING(p)); + p += 16; } } break; case ICMP6_MOBILEPREFIX_ADVERT: if (ndo->ndo_vflag) { - ND_TCHECK(dp->icmp6_data16[0]); - ND_PRINT((ndo,", id 0x%04x", EXTRACT_16BITS(&dp->icmp6_data16[0]))); - ND_TCHECK(dp->icmp6_data16[1]); - if (dp->icmp6_data16[1] & 0xc0) - ND_PRINT((ndo," ")); - if (dp->icmp6_data16[1] & 0x80) - ND_PRINT((ndo,"M")); - if (dp->icmp6_data16[1] & 0x40) - ND_PRINT((ndo,"O")); + uint16_t flags; + + ND_PRINT(", id 0x%04x", + GET_BE_U_2(dp->icmp6_data16[0])); + flags = GET_BE_U_2(dp->icmp6_data16[1]); + if (flags & 0xc000) + ND_PRINT(" "); + if (flags & 0x8000) + ND_PRINT("M"); + if (flags & 0x4000) + ND_PRINT("O"); #define MPADVLEN 8 - icmp6_opt_print(ndo, (const u_char *)dp + MPADVLEN, - length - MPADVLEN); + if (icmp6_opt_print(ndo, (const u_char *)dp + MPADVLEN, + length - MPADVLEN) == -1) + goto trunc; } break; case ND_RPL_MESSAGE: /* plus 4, because struct icmp6_hdr contains 4 bytes of icmp payload */ - rpl_print(ndo, dp, &dp->icmp6_data8[0], length-sizeof(struct icmp6_hdr)+4); + rpl_print(ndo, icmp6_code, dp->icmp6_data, length-sizeof(struct icmp6_hdr)+4); break; default: - ND_PRINT((ndo,", length %u", length)); + ND_PRINT(", length %u", length); if (ndo->ndo_vflag <= 1) print_unknown_data(ndo, bp,"\n\t", length); return; } if (!ndo->ndo_vflag) - ND_PRINT((ndo,", length %u", length)); + ND_PRINT(", length %u", length); return; trunc: - ND_PRINT((ndo, "%s", icmp6_tstr)); + nd_print_trunc(ndo); } static const struct udphdr * @@ -1180,10 +1343,10 @@ get_upperlayer(netdissect_options *ndo, const u_char *bp, u_int *prot) /* 'ep' points to the end of available data. */ ep = ndo->ndo_snapend; - if (!ND_TTEST(ip6->ip6_nxt)) + if (!ND_TTEST_1(ip6->ip6_nxt)) return NULL; - nh = ip6->ip6_nxt; + nh = GET_U_1(ip6->ip6_nxt); hlen = sizeof(struct ip6_hdr); while (bp < ep) { @@ -1193,7 +1356,7 @@ get_upperlayer(netdissect_options *ndo, const u_char *bp, u_int *prot) case IPPROTO_UDP: case IPPROTO_TCP: uh = (const struct udphdr *)bp; - if (ND_TTEST(uh->uh_dport)) { + if (ND_TTEST_2(uh->uh_dport)) { *prot = nh; return(uh); } @@ -1205,29 +1368,29 @@ get_upperlayer(netdissect_options *ndo, const u_char *bp, u_int *prot) case IPPROTO_DSTOPTS: case IPPROTO_ROUTING: hbh = (const struct ip6_hbh *)bp; - if (!ND_TTEST(hbh->ip6h_len)) + if (!ND_TTEST_1(hbh->ip6h_len)) return(NULL); - nh = hbh->ip6h_nxt; - hlen = (hbh->ip6h_len + 1) << 3; + nh = GET_U_1(hbh->ip6h_nxt); + hlen = (GET_U_1(hbh->ip6h_len) + 1) << 3; break; case IPPROTO_FRAGMENT: /* this should be odd, but try anyway */ fragh = (const struct ip6_frag *)bp; - if (!ND_TTEST(fragh->ip6f_offlg)) + if (!ND_TTEST_2(fragh->ip6f_offlg)) return(NULL); /* fragments with non-zero offset are meaningless */ - if ((EXTRACT_16BITS(&fragh->ip6f_offlg) & IP6F_OFF_MASK) != 0) + if ((GET_BE_U_2(fragh->ip6f_offlg) & IP6F_OFF_MASK) != 0) return(NULL); - nh = fragh->ip6f_nxt; + nh = GET_U_1(fragh->ip6f_nxt); hlen = sizeof(struct ip6_frag); break; case IPPROTO_AH: ah = (const struct ah *)bp; - if (!ND_TTEST(ah->ah_len)) + if (!ND_TTEST_1(ah->ah_len)) return(NULL); - nh = ah->ah_nxt; - hlen = (ah->ah_len + 2) << 2; + nh = GET_U_1(ah->ah_nxt); + hlen = (GET_U_1(ah->ah_len) + 2) << 2; break; default: /* unknown or undecodable header */ @@ -1239,10 +1402,12 @@ get_upperlayer(netdissect_options *ndo, const u_char *bp, u_int *prot) return(NULL); /* should be notreached, though */ } -static void +static int icmp6_opt_print(netdissect_options *ndo, const u_char *bp, int resid) { const struct nd_opt_hdr *op; + uint8_t opt_type; + u_int opt_len; const struct nd_opt_prefix_info *opp; const struct nd_opt_mtu *opm; const struct nd_opt_rdnss *oprd; @@ -1251,13 +1416,10 @@ icmp6_opt_print(netdissect_options *ndo, const u_char *bp, int resid) const struct nd_opt_homeagent_info *oph; const struct nd_opt_route_info *opri; const u_char *cp, *ep, *domp; - struct in6_addr in6; - const struct in6_addr *in6p; + nd_ipv6 in6; size_t l; u_int i; -#define ECHECK(var) if ((const u_char *)&(var) > ep - sizeof(var)) return - cp = bp; /* 'ep' points to the end of available data. */ ep = ndo->ndo_snapend; @@ -1265,131 +1427,126 @@ icmp6_opt_print(netdissect_options *ndo, const u_char *bp, int resid) while (cp < ep) { op = (const struct nd_opt_hdr *)cp; - ECHECK(op->nd_opt_len); + ND_TCHECK_1(op->nd_opt_len); if (resid <= 0) - return; - if (op->nd_opt_len == 0) + return 0; + opt_type = GET_U_1(op->nd_opt_type); + opt_len = GET_U_1(op->nd_opt_len); + if (opt_len == 0) goto trunc; - if (cp + (op->nd_opt_len << 3) > ep) + if (cp + (opt_len << 3) > ep) goto trunc; - ND_PRINT((ndo,"\n\t %s option (%u), length %u (%u): ", - tok2str(icmp6_opt_values, "unknown", op->nd_opt_type), - op->nd_opt_type, - op->nd_opt_len << 3, - op->nd_opt_len)); + ND_PRINT("\n\t %s option (%u), length %u (%u): ", + tok2str(icmp6_opt_values, "unknown", opt_type), + opt_type, + opt_len << 3, + opt_len); - switch (op->nd_opt_type) { + switch (opt_type) { case ND_OPT_SOURCE_LINKADDR: - l = (op->nd_opt_len << 3) - 2; + l = (opt_len << 3) - 2; print_lladdr(ndo, cp + 2, l); break; case ND_OPT_TARGET_LINKADDR: - l = (op->nd_opt_len << 3) - 2; + l = (opt_len << 3) - 2; print_lladdr(ndo, cp + 2, l); break; case ND_OPT_PREFIX_INFORMATION: opp = (const struct nd_opt_prefix_info *)op; - ND_TCHECK(opp->nd_opt_pi_prefix); - ND_PRINT((ndo,"%s/%u%s, Flags [%s], valid time %s", - ip6addr_string(ndo, &opp->nd_opt_pi_prefix), - opp->nd_opt_pi_prefix_len, - (op->nd_opt_len != 4) ? "badlen" : "", - bittok2str(icmp6_opt_pi_flag_values, "none", opp->nd_opt_pi_flags_reserved), - get_lifetime(EXTRACT_32BITS(&opp->nd_opt_pi_valid_time)))); - ND_PRINT((ndo,", pref. time %s", get_lifetime(EXTRACT_32BITS(&opp->nd_opt_pi_preferred_time)))); + ND_PRINT("%s/%u%s, Flags [%s], valid time %s", + GET_IP6ADDR_STRING(opp->nd_opt_pi_prefix), + GET_U_1(opp->nd_opt_pi_prefix_len), + (opt_len != 4) ? "badlen" : "", + bittok2str(icmp6_opt_pi_flag_values, "none", GET_U_1(opp->nd_opt_pi_flags_reserved)), + get_lifetime(GET_BE_U_4(opp->nd_opt_pi_valid_time))); + ND_PRINT(", pref. time %s", + get_lifetime(GET_BE_U_4(opp->nd_opt_pi_preferred_time))); break; case ND_OPT_REDIRECTED_HEADER: - print_unknown_data(ndo, bp,"\n\t ",op->nd_opt_len<<3); + print_unknown_data(ndo, bp,"\n\t ",opt_len<<3); /* xxx */ break; case ND_OPT_MTU: opm = (const struct nd_opt_mtu *)op; - ND_TCHECK(opm->nd_opt_mtu_mtu); - ND_PRINT((ndo," %u%s", - EXTRACT_32BITS(&opm->nd_opt_mtu_mtu), - (op->nd_opt_len != 1) ? "bad option length" : "" )); + ND_PRINT(" %u%s", + GET_BE_U_4(opm->nd_opt_mtu_mtu), + (opt_len != 1) ? "bad option length" : "" ); break; case ND_OPT_RDNSS: oprd = (const struct nd_opt_rdnss *)op; - l = (op->nd_opt_len - 1) / 2; - ND_PRINT((ndo," lifetime %us,", - EXTRACT_32BITS(&oprd->nd_opt_rdnss_lifetime))); + l = (opt_len - 1) / 2; + ND_PRINT(" lifetime %us,", + GET_BE_U_4(oprd->nd_opt_rdnss_lifetime)); for (i = 0; i < l; i++) { - ND_TCHECK(oprd->nd_opt_rdnss_addr[i]); - ND_PRINT((ndo," addr: %s", - ip6addr_string(ndo, &oprd->nd_opt_rdnss_addr[i]))); + ND_PRINT(" addr: %s", + GET_IP6ADDR_STRING(oprd->nd_opt_rdnss_addr[i])); } break; case ND_OPT_DNSSL: opds = (const struct nd_opt_dnssl *)op; - ND_PRINT((ndo," lifetime %us, domain(s):", - EXTRACT_32BITS(&opds->nd_opt_dnssl_lifetime))); + ND_PRINT(" lifetime %us, domain(s):", + GET_BE_U_4(opds->nd_opt_dnssl_lifetime)); domp = cp + 8; /* domain names, variable-sized, RFC1035-encoded */ - while (domp < cp + (op->nd_opt_len << 3) && *domp != '\0') + while (domp < cp + (opt_len << 3) && GET_U_1(domp) != '\0') { - ND_PRINT((ndo, " ")); - if ((domp = ns_nprint (ndo, domp, bp)) == NULL) + ND_PRINT(" "); + if ((domp = fqdn_print(ndo, domp, bp)) == NULL) goto trunc; } break; case ND_OPT_ADVINTERVAL: opa = (const struct nd_opt_advinterval *)op; - ND_TCHECK(opa->nd_opt_adv_interval); - ND_PRINT((ndo," %ums", EXTRACT_32BITS(&opa->nd_opt_adv_interval))); + ND_PRINT(" %ums", + GET_BE_U_4(opa->nd_opt_adv_interval)); break; case ND_OPT_HOMEAGENT_INFO: oph = (const struct nd_opt_homeagent_info *)op; - ND_TCHECK(oph->nd_opt_hai_lifetime); - ND_PRINT((ndo," preference %u, lifetime %u", - EXTRACT_16BITS(&oph->nd_opt_hai_preference), - EXTRACT_16BITS(&oph->nd_opt_hai_lifetime))); + ND_PRINT(" preference %u, lifetime %u", + GET_BE_U_2(oph->nd_opt_hai_preference), + GET_BE_U_2(oph->nd_opt_hai_lifetime)); break; case ND_OPT_ROUTE_INFO: opri = (const struct nd_opt_route_info *)op; - ND_TCHECK(opri->nd_opt_rti_lifetime); + ND_TCHECK_4(opri->nd_opt_rti_lifetime); memset(&in6, 0, sizeof(in6)); - in6p = (const struct in6_addr *)(opri + 1); - switch (op->nd_opt_len) { + switch (opt_len) { case 1: break; case 2: - ND_TCHECK2(*in6p, 8); - memcpy(&in6, opri + 1, 8); + GET_CPY_BYTES(&in6, opri + 1, 8); break; case 3: - ND_TCHECK(*in6p); - memcpy(&in6, opri + 1, sizeof(in6)); + GET_CPY_BYTES(&in6, opri + 1, 16); break; default: goto trunc; } - ND_PRINT((ndo," %s/%u", ip6addr_string(ndo, &in6), - opri->nd_opt_rti_prefixlen)); - ND_PRINT((ndo,", pref=%s", get_rtpref(opri->nd_opt_rti_flags))); - ND_PRINT((ndo,", lifetime=%s", - get_lifetime(EXTRACT_32BITS(&opri->nd_opt_rti_lifetime)))); + ND_PRINT(" %s/%u", ip6addr_string(ndo, (const u_char *)&in6), + GET_U_1(opri->nd_opt_rti_prefixlen)); + ND_PRINT(", pref=%s", + get_rtpref(GET_U_1(opri->nd_opt_rti_flags))); + ND_PRINT(", lifetime=%s", + get_lifetime(GET_BE_U_4(opri->nd_opt_rti_lifetime))); break; default: if (ndo->ndo_vflag <= 1) { - print_unknown_data(ndo,cp+2,"\n\t ", (op->nd_opt_len << 3) - 2); /* skip option header */ - return; + print_unknown_data(ndo,cp+2,"\n\t ", (opt_len << 3) - 2); /* skip option header */ + return 0; } break; } /* do we want to see an additional hexdump ? */ if (ndo->ndo_vflag> 1) - print_unknown_data(ndo, cp+2,"\n\t ", (op->nd_opt_len << 3) - 2); /* skip option header */ + print_unknown_data(ndo, cp+2,"\n\t ", (opt_len << 3) - 2); /* skip option header */ - cp += op->nd_opt_len << 3; - resid -= op->nd_opt_len << 3; + cp += opt_len << 3; + resid -= opt_len << 3; } - return; + return 0; trunc: - ND_PRINT((ndo, "%s", icmp6_tstr)); - return; -#undef ECHECK + return -1; } static void @@ -1404,8 +1561,8 @@ mld6_print(netdissect_options *ndo, const u_char *bp) if ((const u_char *)mp + sizeof(*mp) > ep) return; - ND_PRINT((ndo,"max resp delay: %d ", EXTRACT_16BITS(&mp->mld6_maxdelay))); - ND_PRINT((ndo,"addr: %s", ip6addr_string(ndo, &mp->mld6_addr))); + ND_PRINT("max resp delay: %u ", GET_BE_U_2(mp->mld6_maxdelay)); + ND_PRINT("addr: %s", GET_IP6ADDR_STRING(mp->mld6_addr)); } static void @@ -1417,53 +1574,45 @@ mldv2_report_print(netdissect_options *ndo, const u_char *bp, u_int len) /* Minimum len is 8 */ if (len < 8) { - ND_PRINT((ndo," [invalid len %d]", len)); + ND_PRINT(" [invalid len %u]", len); return; } - ND_TCHECK(icp->icmp6_data16[1]); - ngroups = EXTRACT_16BITS(&icp->icmp6_data16[1]); - ND_PRINT((ndo,", %d group record(s)", ngroups)); + ngroups = GET_BE_U_2(icp->icmp6_data16[1]); + ND_PRINT(", %u group record(s)", ngroups); if (ndo->ndo_vflag > 0) { /* Print the group records */ group = 8; for (i = 0; i < ngroups; i++) { /* type(1) + auxlen(1) + numsrc(2) + grp(16) */ if (len < group + 20) { - ND_PRINT((ndo," [invalid number of groups]")); + ND_PRINT(" [invalid number of groups]"); return; } - ND_TCHECK2(bp[group + 4], sizeof(struct in6_addr)); - ND_PRINT((ndo," [gaddr %s", ip6addr_string(ndo, &bp[group + 4]))); - ND_PRINT((ndo," %s", tok2str(mldv2report2str, " [v2-report-#%d]", - bp[group]))); - nsrcs = (bp[group + 2] << 8) + bp[group + 3]; + ND_PRINT(" [gaddr %s", GET_IP6ADDR_STRING(bp + group + 4)); + ND_PRINT(" %s", tok2str(mldv2report2str, " [v2-report-#%u]", + GET_U_1(bp + group))); + nsrcs = GET_BE_U_2(bp + group + 2); /* Check the number of sources and print them */ - if (len < group + 20 + (nsrcs * sizeof(struct in6_addr))) { - ND_PRINT((ndo," [invalid number of sources %d]", nsrcs)); + if (len < group + 20 + (nsrcs * sizeof(nd_ipv6))) { + ND_PRINT(" [invalid number of sources %u]", nsrcs); return; } if (ndo->ndo_vflag == 1) - ND_PRINT((ndo,", %d source(s)", nsrcs)); + ND_PRINT(", %u source(s)", nsrcs); else { /* Print the sources */ - ND_PRINT((ndo," {")); + ND_PRINT(" {"); for (j = 0; j < nsrcs; j++) { - ND_TCHECK2(bp[group + 20 + j * sizeof(struct in6_addr)], - sizeof(struct in6_addr)); - ND_PRINT((ndo," %s", ip6addr_string(ndo, &bp[group + 20 + j * sizeof(struct in6_addr)]))); + ND_PRINT(" %s", GET_IP6ADDR_STRING(bp + group + 20 + (j * sizeof(nd_ipv6)))); } - ND_PRINT((ndo," }")); + ND_PRINT(" }"); } /* Next group record */ - group += 20 + nsrcs * sizeof(struct in6_addr); - ND_PRINT((ndo,"]")); + group += 20 + nsrcs * sizeof(nd_ipv6); + ND_PRINT("]"); } } - return; -trunc: - ND_PRINT((ndo, "%s", mldv2_tstr)); - return; } static void @@ -1471,65 +1620,56 @@ mldv2_query_print(netdissect_options *ndo, const u_char *bp, u_int len) { const struct icmp6_hdr *icp = (const struct icmp6_hdr *) bp; u_int mrc; - int mrt, qqi; + u_int mrt, qqi; u_int nsrcs; - register u_int i; + u_int i; /* Minimum len is 28 */ if (len < 28) { - ND_PRINT((ndo," [invalid len %d]", len)); + ND_PRINT(" [invalid len %u]", len); return; } - ND_TCHECK(icp->icmp6_data16[0]); - mrc = EXTRACT_16BITS(&icp->icmp6_data16[0]); + mrc = GET_BE_U_2(icp->icmp6_data16[0]); if (mrc < 32768) { mrt = mrc; } else { mrt = ((mrc & 0x0fff) | 0x1000) << (((mrc & 0x7000) >> 12) + 3); } if (ndo->ndo_vflag) { - ND_PRINT((ndo," [max resp delay=%d]", mrt)); + ND_PRINT(" [max resp delay=%u]", mrt); } - ND_TCHECK2(bp[8], sizeof(struct in6_addr)); - ND_PRINT((ndo," [gaddr %s", ip6addr_string(ndo, &bp[8]))); + ND_PRINT(" [gaddr %s", GET_IP6ADDR_STRING(bp + 8)); if (ndo->ndo_vflag) { - ND_TCHECK(bp[25]); - if (bp[24] & 0x08) { - ND_PRINT((ndo," sflag")); + if (GET_U_1(bp + 24) & 0x08) { + ND_PRINT(" sflag"); } - if (bp[24] & 0x07) { - ND_PRINT((ndo," robustness=%d", bp[24] & 0x07)); + if (GET_U_1(bp + 24) & 0x07) { + ND_PRINT(" robustness=%u", GET_U_1(bp + 24) & 0x07); } - if (bp[25] < 128) { - qqi = bp[25]; + if (GET_U_1(bp + 25) < 128) { + qqi = GET_U_1(bp + 25); } else { - qqi = ((bp[25] & 0x0f) | 0x10) << (((bp[25] & 0x70) >> 4) + 3); + qqi = ((GET_U_1(bp + 25) & 0x0f) | 0x10) << + (((GET_U_1(bp + 25) & 0x70) >> 4) + 3); } - ND_PRINT((ndo," qqi=%d", qqi)); + ND_PRINT(" qqi=%u", qqi); } - ND_TCHECK2(bp[26], 2); - nsrcs = EXTRACT_16BITS(&bp[26]); + nsrcs = GET_BE_U_2(bp + 26); if (nsrcs > 0) { - if (len < 28 + nsrcs * sizeof(struct in6_addr)) - ND_PRINT((ndo," [invalid number of sources]")); + if (len < 28 + nsrcs * sizeof(nd_ipv6)) + ND_PRINT(" [invalid number of sources]"); else if (ndo->ndo_vflag > 1) { - ND_PRINT((ndo," {")); + ND_PRINT(" {"); for (i = 0; i < nsrcs; i++) { - ND_TCHECK2(bp[28 + i * sizeof(struct in6_addr)], - sizeof(struct in6_addr)); - ND_PRINT((ndo," %s", ip6addr_string(ndo, &bp[28 + i * sizeof(struct in6_addr)]))); + ND_PRINT(" %s", GET_IP6ADDR_STRING(bp + 28 + (i * sizeof(nd_ipv6)))); } - ND_PRINT((ndo," }")); + ND_PRINT(" }"); } else - ND_PRINT((ndo,", %d source(s)", nsrcs)); + ND_PRINT(", %u source(s)", nsrcs); } - ND_PRINT((ndo,"]")); - return; -trunc: - ND_PRINT((ndo, "%s", mldv2_tstr)); - return; + ND_PRINT("]"); } static void @@ -1538,34 +1678,35 @@ dnsname_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) int i; /* DNS name decoding - no decompression */ - ND_PRINT((ndo,", \"")); + ND_PRINT(", \""); while (cp < ep) { - i = *cp++; + i = GET_U_1(cp); + cp++; if (i) { if (i > ep - cp) { - ND_PRINT((ndo,"???")); + ND_PRINT("???"); break; } while (i-- && cp < ep) { - safeputchar(ndo, *cp); + fn_print_char(ndo, GET_U_1(cp)); cp++; } - if (cp + 1 < ep && *cp) - ND_PRINT((ndo,".")); + if (cp + 1 < ep && GET_U_1(cp)) + ND_PRINT("."); } else { if (cp == ep) { /* FQDN */ - ND_PRINT((ndo,".")); - } else if (cp + 1 == ep && *cp == '\0') { + ND_PRINT("."); + } else if (cp + 1 == ep && GET_U_1(cp) == '\0') { /* truncated */ } else { /* invalid */ - ND_PRINT((ndo,"???")); + ND_PRINT("???"); } break; } } - ND_PRINT((ndo,"\"")); + ND_PRINT("\""); } static void @@ -1583,239 +1724,235 @@ icmp6_nodeinfo_print(netdissect_options *ndo, u_int icmp6len, const u_char *bp, ni6 = (const struct icmp6_nodeinfo *)bp; siz = ep - bp; - switch (ni6->ni_type) { + switch (GET_U_1(ni6->ni_type)) { case ICMP6_NI_QUERY: if (siz == sizeof(*dp) + 4) { /* KAME who-are-you */ - ND_PRINT((ndo," who-are-you request")); + ND_PRINT(" who-are-you request"); break; } - ND_PRINT((ndo," node information query")); + ND_PRINT(" node information query"); - ND_TCHECK2(*dp, sizeof(*ni6)); + ND_TCHECK_LEN(dp, sizeof(*ni6)); ni6 = (const struct icmp6_nodeinfo *)dp; - ND_PRINT((ndo," (")); /*)*/ - switch (EXTRACT_16BITS(&ni6->ni_qtype)) { + ND_PRINT(" ("); /*)*/ + switch (GET_BE_U_2(ni6->ni_qtype)) { case NI_QTYPE_NOOP: - ND_PRINT((ndo,"noop")); + ND_PRINT("noop"); break; case NI_QTYPE_SUPTYPES: - ND_PRINT((ndo,"supported qtypes")); - i = EXTRACT_16BITS(&ni6->ni_flags); + ND_PRINT("supported qtypes"); + i = GET_BE_U_2(ni6->ni_flags); if (i) - ND_PRINT((ndo," [%s]", (i & 0x01) ? "C" : "")); + ND_PRINT(" [%s]", (i & 0x01) ? "C" : ""); break; case NI_QTYPE_FQDN: - ND_PRINT((ndo,"DNS name")); + ND_PRINT("DNS name"); break; case NI_QTYPE_NODEADDR: - ND_PRINT((ndo,"node addresses")); - i = ni6->ni_flags; + ND_PRINT("node addresses"); + i = GET_BE_U_2(ni6->ni_flags); if (!i) break; /* NI_NODEADDR_FLAG_TRUNCATE undefined for query */ - ND_PRINT((ndo," [%s%s%s%s%s%s]", + ND_PRINT(" [%s%s%s%s%s%s]", (i & NI_NODEADDR_FLAG_ANYCAST) ? "a" : "", (i & NI_NODEADDR_FLAG_GLOBAL) ? "G" : "", (i & NI_NODEADDR_FLAG_SITELOCAL) ? "S" : "", (i & NI_NODEADDR_FLAG_LINKLOCAL) ? "L" : "", (i & NI_NODEADDR_FLAG_COMPAT) ? "C" : "", - (i & NI_NODEADDR_FLAG_ALL) ? "A" : "")); + (i & NI_NODEADDR_FLAG_ALL) ? "A" : ""); break; default: - ND_PRINT((ndo,"unknown")); + ND_PRINT("unknown"); break; } - if (ni6->ni_qtype == NI_QTYPE_NOOP || - ni6->ni_qtype == NI_QTYPE_SUPTYPES) { + if (GET_BE_U_2(ni6->ni_qtype) == NI_QTYPE_NOOP || + GET_BE_U_2(ni6->ni_qtype) == NI_QTYPE_SUPTYPES) { if (siz != sizeof(*ni6)) if (ndo->ndo_vflag) - ND_PRINT((ndo,", invalid len")); + ND_PRINT(", invalid len"); /*(*/ - ND_PRINT((ndo,")")); + ND_PRINT(")"); break; } /* XXX backward compat, icmp-name-lookup-03 */ if (siz == sizeof(*ni6)) { - ND_PRINT((ndo,", 03 draft")); + ND_PRINT(", 03 draft"); /*(*/ - ND_PRINT((ndo,")")); + ND_PRINT(")"); break; } - switch (ni6->ni_code) { + cp = (const u_char *)(ni6 + 1); + switch (GET_U_1(ni6->ni_code)) { case ICMP6_NI_SUBJ_IPV6: - if (!ND_TTEST2(*dp, - sizeof(*ni6) + sizeof(struct in6_addr))) + if (!ND_TTEST_LEN(dp, sizeof(*ni6) + sizeof(nd_ipv6))) break; - if (siz != sizeof(*ni6) + sizeof(struct in6_addr)) { + if (siz != sizeof(*ni6) + sizeof(nd_ipv6)) { if (ndo->ndo_vflag) - ND_PRINT((ndo,", invalid subject len")); + ND_PRINT(", invalid subject len"); break; } - ND_PRINT((ndo,", subject=%s", - ip6addr_string(ndo, ni6 + 1))); + ND_PRINT(", subject=%s", + GET_IP6ADDR_STRING(cp)); break; case ICMP6_NI_SUBJ_FQDN: - ND_PRINT((ndo,", subject=DNS name")); - cp = (const u_char *)(ni6 + 1); - if (cp[0] == ep - cp - 1) { + ND_PRINT(", subject=DNS name"); + if (GET_U_1(cp) == ep - cp - 1) { /* icmp-name-lookup-03, pascal string */ if (ndo->ndo_vflag) - ND_PRINT((ndo,", 03 draft")); + ND_PRINT(", 03 draft"); cp++; - ND_PRINT((ndo,", \"")); + ND_PRINT(", \""); while (cp < ep) { - safeputchar(ndo, *cp); + fn_print_char(ndo, GET_U_1(cp)); cp++; } - ND_PRINT((ndo,"\"")); + ND_PRINT("\""); } else dnsname_print(ndo, cp, ep); break; case ICMP6_NI_SUBJ_IPV4: - if (!ND_TTEST2(*dp, sizeof(*ni6) + sizeof(struct in_addr))) + if (!ND_TTEST_LEN(dp, sizeof(*ni6) + sizeof(nd_ipv4))) break; - if (siz != sizeof(*ni6) + sizeof(struct in_addr)) { + if (siz != sizeof(*ni6) + sizeof(nd_ipv4)) { if (ndo->ndo_vflag) - ND_PRINT((ndo,", invalid subject len")); + ND_PRINT(", invalid subject len"); break; } - ND_PRINT((ndo,", subject=%s", - ipaddr_string(ndo, ni6 + 1))); + ND_PRINT(", subject=%s", + GET_IPADDR_STRING(cp)); break; default: - ND_PRINT((ndo,", unknown subject")); + ND_PRINT(", unknown subject"); break; } /*(*/ - ND_PRINT((ndo,")")); + ND_PRINT(")"); break; case ICMP6_NI_REPLY: - if (icmp6len > siz) { - ND_PRINT((ndo,"[|icmp6: node information reply]")); - break; - } + if (icmp6len > siz) + goto trunc; needcomma = 0; - ND_TCHECK2(*dp, sizeof(*ni6)); + ND_TCHECK_LEN(dp, sizeof(*ni6)); ni6 = (const struct icmp6_nodeinfo *)dp; - ND_PRINT((ndo," node information reply")); - ND_PRINT((ndo," (")); /*)*/ - switch (ni6->ni_code) { + ND_PRINT(" node information reply"); + ND_PRINT(" ("); /*)*/ + switch (GET_U_1(ni6->ni_code)) { case ICMP6_NI_SUCCESS: if (ndo->ndo_vflag) { - ND_PRINT((ndo,"success")); + ND_PRINT("success"); needcomma++; } break; case ICMP6_NI_REFUSED: - ND_PRINT((ndo,"refused")); + ND_PRINT("refused"); needcomma++; if (siz != sizeof(*ni6)) if (ndo->ndo_vflag) - ND_PRINT((ndo,", invalid length")); + ND_PRINT(", invalid length"); break; case ICMP6_NI_UNKNOWN: - ND_PRINT((ndo,"unknown")); + ND_PRINT("unknown"); needcomma++; if (siz != sizeof(*ni6)) if (ndo->ndo_vflag) - ND_PRINT((ndo,", invalid length")); + ND_PRINT(", invalid length"); break; } - if (ni6->ni_code != ICMP6_NI_SUCCESS) { + if (GET_U_1(ni6->ni_code) != ICMP6_NI_SUCCESS) { /*(*/ - ND_PRINT((ndo,")")); + ND_PRINT(")"); break; } - switch (EXTRACT_16BITS(&ni6->ni_qtype)) { + switch (GET_BE_U_2(ni6->ni_qtype)) { case NI_QTYPE_NOOP: if (needcomma) - ND_PRINT((ndo,", ")); - ND_PRINT((ndo,"noop")); + ND_PRINT(", "); + ND_PRINT("noop"); if (siz != sizeof(*ni6)) if (ndo->ndo_vflag) - ND_PRINT((ndo,", invalid length")); + ND_PRINT(", invalid length"); break; case NI_QTYPE_SUPTYPES: if (needcomma) - ND_PRINT((ndo,", ")); - ND_PRINT((ndo,"supported qtypes")); - i = EXTRACT_16BITS(&ni6->ni_flags); + ND_PRINT(", "); + ND_PRINT("supported qtypes"); + i = GET_BE_U_2(ni6->ni_flags); if (i) - ND_PRINT((ndo," [%s]", (i & 0x01) ? "C" : "")); + ND_PRINT(" [%s]", (i & 0x01) ? "C" : ""); break; case NI_QTYPE_FQDN: if (needcomma) - ND_PRINT((ndo,", ")); - ND_PRINT((ndo,"DNS name")); + ND_PRINT(", "); + ND_PRINT("DNS name"); cp = (const u_char *)(ni6 + 1) + 4; - ND_TCHECK(cp[0]); - if (cp[0] == ep - cp - 1) { + if (GET_U_1(cp) == ep - cp - 1) { /* icmp-name-lookup-03, pascal string */ if (ndo->ndo_vflag) - ND_PRINT((ndo,", 03 draft")); + ND_PRINT(", 03 draft"); cp++; - ND_PRINT((ndo,", \"")); + ND_PRINT(", \""); while (cp < ep) { - safeputchar(ndo, *cp); + fn_print_char(ndo, GET_U_1(cp)); cp++; } - ND_PRINT((ndo,"\"")); + ND_PRINT("\""); } else dnsname_print(ndo, cp, ep); - if ((EXTRACT_16BITS(&ni6->ni_flags) & 0x01) != 0) - ND_PRINT((ndo," [TTL=%u]", EXTRACT_32BITS(ni6 + 1))); + if ((GET_BE_U_2(ni6->ni_flags) & 0x01) != 0) + ND_PRINT(" [TTL=%u]", GET_BE_U_4(ni6 + 1)); break; case NI_QTYPE_NODEADDR: if (needcomma) - ND_PRINT((ndo,", ")); - ND_PRINT((ndo,"node addresses")); + ND_PRINT(", "); + ND_PRINT("node addresses"); i = sizeof(*ni6); while (i < siz) { - if (i + sizeof(struct in6_addr) + sizeof(int32_t) > siz) + if (i + sizeof(uint32_t) + sizeof(nd_ipv6) > siz) break; - ND_PRINT((ndo," %s", ip6addr_string(ndo, bp + i))); - i += sizeof(struct in6_addr); - ND_PRINT((ndo,"(%d)", (int32_t)EXTRACT_32BITS(bp + i))); - i += sizeof(int32_t); + ND_PRINT(" %s(%u)", + GET_IP6ADDR_STRING(bp + i + sizeof(uint32_t)), + GET_BE_U_4(bp + i)); + i += sizeof(uint32_t) + sizeof(nd_ipv6); } - i = ni6->ni_flags; + i = GET_BE_U_2(ni6->ni_flags); if (!i) break; - ND_PRINT((ndo," [%s%s%s%s%s%s%s]", + ND_PRINT(" [%s%s%s%s%s%s%s]", (i & NI_NODEADDR_FLAG_ANYCAST) ? "a" : "", (i & NI_NODEADDR_FLAG_GLOBAL) ? "G" : "", (i & NI_NODEADDR_FLAG_SITELOCAL) ? "S" : "", (i & NI_NODEADDR_FLAG_LINKLOCAL) ? "L" : "", (i & NI_NODEADDR_FLAG_COMPAT) ? "C" : "", (i & NI_NODEADDR_FLAG_ALL) ? "A" : "", - (i & NI_NODEADDR_FLAG_TRUNCATE) ? "T" : "")); + (i & NI_NODEADDR_FLAG_TRUNCATE) ? "T" : ""); break; default: if (needcomma) - ND_PRINT((ndo,", ")); - ND_PRINT((ndo,"unknown")); + ND_PRINT(", "); + ND_PRINT("unknown"); break; } /*(*/ - ND_PRINT((ndo,")")); + ND_PRINT(")"); break; } return; trunc: - ND_PRINT((ndo, "%s", icmp6_tstr)); + nd_print_trunc(ndo); } static void @@ -1833,74 +1970,76 @@ icmp6_rrenum_print(netdissect_options *ndo, const u_char *bp, const u_char *ep) rr6 = (const struct icmp6_router_renum *)bp; cp = (const char *)(rr6 + 1); - ND_TCHECK(rr6->rr_reserved); - switch (rr6->rr_code) { + ND_TCHECK_4(rr6->rr_reserved); + switch (GET_U_1(rr6->rr_code)) { case ICMP6_ROUTER_RENUMBERING_COMMAND: - ND_PRINT((ndo,"router renum: command")); + ND_PRINT("router renum: command"); break; case ICMP6_ROUTER_RENUMBERING_RESULT: - ND_PRINT((ndo,"router renum: result")); + ND_PRINT("router renum: result"); break; case ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET: - ND_PRINT((ndo,"router renum: sequence number reset")); + ND_PRINT("router renum: sequence number reset"); break; default: - ND_PRINT((ndo,"router renum: code-#%d", rr6->rr_code)); + ND_PRINT("router renum: code-#%u", GET_U_1(rr6->rr_code)); break; } - ND_PRINT((ndo,", seq=%u", EXTRACT_32BITS(&rr6->rr_seqnum))); + ND_PRINT(", seq=%u", GET_BE_U_4(rr6->rr_seqnum)); if (ndo->ndo_vflag) { -#define F(x, y) ((rr6->rr_flags) & (x) ? (y) : "") - ND_PRINT((ndo,"[")); /*]*/ - if (rr6->rr_flags) { - ND_PRINT((ndo,"%s%s%s%s%s,", F(ICMP6_RR_FLAGS_TEST, "T"), + uint8_t rr_flags = GET_U_1(rr6->rr_flags); +#define F(x, y) (rr_flags & (x) ? (y) : "") + ND_PRINT("["); /*]*/ + if (rr_flags) { + ND_PRINT("%s%s%s%s%s,", F(ICMP6_RR_FLAGS_TEST, "T"), F(ICMP6_RR_FLAGS_REQRESULT, "R"), F(ICMP6_RR_FLAGS_FORCEAPPLY, "A"), F(ICMP6_RR_FLAGS_SPECSITE, "S"), - F(ICMP6_RR_FLAGS_PREVDONE, "P"))); + F(ICMP6_RR_FLAGS_PREVDONE, "P")); } - ND_PRINT((ndo,"seg=%u,", rr6->rr_segnum)); - ND_PRINT((ndo,"maxdelay=%u", EXTRACT_16BITS(&rr6->rr_maxdelay))); - if (rr6->rr_reserved) - ND_PRINT((ndo,"rsvd=0x%x", EXTRACT_32BITS(&rr6->rr_reserved))); + ND_PRINT("seg=%u,", GET_U_1(rr6->rr_segnum)); + ND_PRINT("maxdelay=%u", GET_BE_U_2(rr6->rr_maxdelay)); + if (GET_BE_U_4(rr6->rr_reserved)) + ND_PRINT("rsvd=0x%x", GET_BE_U_4(rr6->rr_reserved)); /*[*/ - ND_PRINT((ndo,"]")); + ND_PRINT("]"); #undef F } - if (rr6->rr_code == ICMP6_ROUTER_RENUMBERING_COMMAND) { + if (GET_U_1(rr6->rr_code) == ICMP6_ROUTER_RENUMBERING_COMMAND) { match = (const struct rr_pco_match *)cp; cp = (const char *)(match + 1); - ND_TCHECK(match->rpm_prefix); + ND_TCHECK_16(match->rpm_prefix); if (ndo->ndo_vflag > 1) - ND_PRINT((ndo,"\n\t")); + ND_PRINT("\n\t"); else - ND_PRINT((ndo," ")); - ND_PRINT((ndo,"match(")); /*)*/ - switch (match->rpm_code) { - case RPM_PCO_ADD: ND_PRINT((ndo,"add")); break; - case RPM_PCO_CHANGE: ND_PRINT((ndo,"change")); break; - case RPM_PCO_SETGLOBAL: ND_PRINT((ndo,"setglobal")); break; - default: ND_PRINT((ndo,"#%u", match->rpm_code)); break; + ND_PRINT(" "); + ND_PRINT("match("); /*)*/ + switch (GET_U_1(match->rpm_code)) { + case RPM_PCO_ADD: ND_PRINT("add"); break; + case RPM_PCO_CHANGE: ND_PRINT("change"); break; + case RPM_PCO_SETGLOBAL: ND_PRINT("setglobal"); break; + default: ND_PRINT("#%u", + GET_U_1(match->rpm_code)); break; } if (ndo->ndo_vflag) { - ND_PRINT((ndo,",ord=%u", match->rpm_ordinal)); - ND_PRINT((ndo,",min=%u", match->rpm_minlen)); - ND_PRINT((ndo,",max=%u", match->rpm_maxlen)); + ND_PRINT(",ord=%u", GET_U_1(match->rpm_ordinal)); + ND_PRINT(",min=%u", GET_U_1(match->rpm_minlen)); + ND_PRINT(",max=%u", GET_U_1(match->rpm_maxlen)); } - if (addrtostr6(&match->rpm_prefix, hbuf, sizeof(hbuf))) - ND_PRINT((ndo,",%s/%u", hbuf, match->rpm_matchlen)); + if (addrtostr6(match->rpm_prefix, hbuf, sizeof(hbuf))) + ND_PRINT(",%s/%u", hbuf, GET_U_1(match->rpm_matchlen)); else - ND_PRINT((ndo,",?/%u", match->rpm_matchlen)); + ND_PRINT(",?/%u", GET_U_1(match->rpm_matchlen)); /*(*/ - ND_PRINT((ndo,")")); + ND_PRINT(")"); - n = match->rpm_len - 3; + n = GET_U_1(match->rpm_len) - 3; if (n % 4) goto trunc; n /= 4; @@ -1908,54 +2047,50 @@ icmp6_rrenum_print(netdissect_options *ndo, const u_char *bp, const u_char *ep) use = (const struct rr_pco_use *)cp; cp = (const char *)(use + 1); - ND_TCHECK(use->rpu_prefix); + ND_TCHECK_16(use->rpu_prefix); if (ndo->ndo_vflag > 1) - ND_PRINT((ndo,"\n\t")); + ND_PRINT("\n\t"); else - ND_PRINT((ndo," ")); - ND_PRINT((ndo,"use(")); /*)*/ - if (use->rpu_flags) { -#define F(x, y) ((use->rpu_flags) & (x) ? (y) : "") - ND_PRINT((ndo,"%s%s,", + ND_PRINT(" "); + ND_PRINT("use("); /*)*/ + if (GET_U_1(use->rpu_flags)) { +#define F(x, y) (GET_U_1(use->rpu_flags) & (x) ? (y) : "") + ND_PRINT("%s%s,", F(ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME, "V"), - F(ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME, "P"))); + F(ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME, "P")); #undef F } if (ndo->ndo_vflag) { - ND_PRINT((ndo,"mask=0x%x,", use->rpu_ramask)); - ND_PRINT((ndo,"raflags=0x%x,", use->rpu_raflags)); - if (~use->rpu_vltime == 0) - ND_PRINT((ndo,"vltime=infty,")); + ND_PRINT("mask=0x%x,", + GET_U_1(use->rpu_ramask)); + ND_PRINT("raflags=0x%x,", + GET_U_1(use->rpu_raflags)); + if (GET_BE_U_4(use->rpu_vltime) == 0xffffffff) + ND_PRINT("vltime=infty,"); else - ND_PRINT((ndo,"vltime=%u,", - EXTRACT_32BITS(&use->rpu_vltime))); - if (~use->rpu_pltime == 0) - ND_PRINT((ndo,"pltime=infty,")); + ND_PRINT("vltime=%u,", + GET_BE_U_4(use->rpu_vltime)); + if (GET_BE_U_4(use->rpu_pltime) == 0xffffffff) + ND_PRINT("pltime=infty,"); else - ND_PRINT((ndo,"pltime=%u,", - EXTRACT_32BITS(&use->rpu_pltime))); + ND_PRINT("pltime=%u,", + GET_BE_U_4(use->rpu_pltime)); } - if (addrtostr6(&use->rpu_prefix, hbuf, sizeof(hbuf))) - ND_PRINT((ndo,"%s/%u/%u", hbuf, use->rpu_uselen, - use->rpu_keeplen)); + if (addrtostr6(use->rpu_prefix, hbuf, sizeof(hbuf))) + ND_PRINT("%s/%u/%u", hbuf, + GET_U_1(use->rpu_uselen), + GET_U_1(use->rpu_keeplen)); else - ND_PRINT((ndo,"?/%u/%u", use->rpu_uselen, - use->rpu_keeplen)); + ND_PRINT("?/%u/%u", GET_U_1(use->rpu_uselen), + GET_U_1(use->rpu_keeplen)); /*(*/ - ND_PRINT((ndo,")")); + ND_PRINT(")"); } } return; trunc: - ND_PRINT((ndo, "%s", icmp6_tstr)); + nd_print_trunc(ndo); } - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/print-igmp.c b/contrib/tcpdump/print-igmp.c index 0bb7f9762e..914e3d6b34 100644 --- a/contrib/tcpdump/print-igmp.c +++ b/contrib/tcpdump/print-igmp.c @@ -21,11 +21,19 @@ /* \summary: Internet Group Management Protocol (IGMP) printer */ +/* + * specification: + * + * RFC 2236 for IGMPv2 + * RFC 3376 for IGMPv3 + * draft-asaeda-mboned-mtrace-v2 for the mtrace message + */ + #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "addrtoname.h" @@ -35,7 +43,6 @@ #define IN_CLASSD(i) (((int32_t)(i) & 0xf0000000) == 0xe0000000) #endif -static const char tstr[] = "[|igmp]"; /* (following from ipmulti/mrouted/prune.h) */ @@ -43,31 +50,29 @@ static const char tstr[] = "[|igmp]"; * The packet format for a traceroute request. */ struct tr_query { - uint32_t tr_src; /* traceroute source */ - uint32_t tr_dst; /* traceroute destination */ - uint32_t tr_raddr; /* traceroute response address */ - uint32_t tr_rttlqid; /* response ttl and qid */ + nd_uint32_t tr_src; /* traceroute source */ + nd_uint32_t tr_dst; /* traceroute destination */ + nd_uint32_t tr_raddr; /* traceroute response address */ + nd_uint8_t tr_rttl; /* response ttl */ + nd_uint24_t tr_qid; /* qid */ }; -#define TR_GETTTL(x) (int)(((x) >> 24) & 0xff) -#define TR_GETQID(x) ((x) & 0x00ffffff) - /* * Traceroute response format. A traceroute response has a tr_query at the * beginning, followed by one tr_resp for each hop taken. */ struct tr_resp { - uint32_t tr_qarr; /* query arrival time */ - uint32_t tr_inaddr; /* incoming interface address */ - uint32_t tr_outaddr; /* outgoing interface address */ - uint32_t tr_rmtaddr; /* parent address in source tree */ - uint32_t tr_vifin; /* input packet count on interface */ - uint32_t tr_vifout; /* output packet count on interface */ - uint32_t tr_pktcnt; /* total incoming packets for src-grp */ - uint8_t tr_rproto; /* routing proto deployed on router */ - uint8_t tr_fttl; /* ttl required to forward on outvif */ - uint8_t tr_smask; /* subnet mask for src addr */ - uint8_t tr_rflags; /* forwarding error codes */ + nd_uint32_t tr_qarr; /* query arrival time */ + nd_uint32_t tr_inaddr; /* incoming interface address */ + nd_uint32_t tr_outaddr; /* outgoing interface address */ + nd_uint32_t tr_rmtaddr; /* parent address in source tree */ + nd_uint32_t tr_vifin; /* input packet count on interface */ + nd_uint32_t tr_vifout; /* output packet count on interface */ + nd_uint32_t tr_pktcnt; /* total incoming packets for src-grp */ + nd_uint8_t tr_rproto; /* routing proto deployed on router */ + nd_uint8_t tr_fttl; /* ttl required to forward on outvif */ + nd_uint8_t tr_smask; /* subnet mask for src addr */ + nd_uint8_t tr_rflags; /* forwarding error codes */ }; /* defs within mtrace */ @@ -104,238 +109,193 @@ static const struct tok igmpv3report2str[] = { static void print_mtrace(netdissect_options *ndo, - register const u_char *bp, register u_int len) -{ - register const struct tr_query *tr = (const struct tr_query *)(bp + 8); - - ND_TCHECK(*tr); - if (len < 8 + sizeof (struct tr_query)) { - ND_PRINT((ndo, " [invalid len %d]", len)); - return; - } - ND_PRINT((ndo, "mtrace %u: %s to %s reply-to %s", - TR_GETQID(EXTRACT_32BITS(&tr->tr_rttlqid)), - ipaddr_string(ndo, &tr->tr_src), ipaddr_string(ndo, &tr->tr_dst), - ipaddr_string(ndo, &tr->tr_raddr))); - if (IN_CLASSD(EXTRACT_32BITS(&tr->tr_raddr))) - ND_PRINT((ndo, " with-ttl %d", TR_GETTTL(EXTRACT_32BITS(&tr->tr_rttlqid)))); - return; -trunc: - ND_PRINT((ndo, "%s", tstr)); -} - -static void -print_mresp(netdissect_options *ndo, - register const u_char *bp, register u_int len) + const char *typename, + const u_char *bp, u_int len) { - register const struct tr_query *tr = (const struct tr_query *)(bp + 8); + const struct tr_query *tr = (const struct tr_query *)(bp + 8); - ND_TCHECK(*tr); if (len < 8 + sizeof (struct tr_query)) { - ND_PRINT((ndo, " [invalid len %d]", len)); + ND_PRINT(" [invalid len %u]", len); return; } - ND_PRINT((ndo, "mresp %lu: %s to %s reply-to %s", - (u_long)TR_GETQID(EXTRACT_32BITS(&tr->tr_rttlqid)), - ipaddr_string(ndo, &tr->tr_src), ipaddr_string(ndo, &tr->tr_dst), - ipaddr_string(ndo, &tr->tr_raddr))); - if (IN_CLASSD(EXTRACT_32BITS(&tr->tr_raddr))) - ND_PRINT((ndo, " with-ttl %d", TR_GETTTL(EXTRACT_32BITS(&tr->tr_rttlqid)))); - return; -trunc: - ND_PRINT((ndo, "%s", tstr)); + ND_PRINT("%s %u: %s to %s reply-to %s", + typename, + GET_BE_U_3(tr->tr_qid), + GET_IPADDR_STRING(tr->tr_src), GET_IPADDR_STRING(tr->tr_dst), + GET_IPADDR_STRING(tr->tr_raddr)); + if (IN_CLASSD(GET_BE_U_4(tr->tr_raddr))) + ND_PRINT(" with-ttl %u", GET_U_1(tr->tr_rttl)); } static void print_igmpv3_report(netdissect_options *ndo, - register const u_char *bp, register u_int len) + const u_char *bp, u_int len) { u_int group, nsrcs, ngroups; - register u_int i, j; + u_int i, j; /* Minimum len is 16, and should be a multiple of 4 */ if (len < 16 || len & 0x03) { - ND_PRINT((ndo, " [invalid len %d]", len)); + ND_PRINT(" [invalid len %u]", len); return; } - ND_TCHECK2(bp[6], 2); - ngroups = EXTRACT_16BITS(&bp[6]); - ND_PRINT((ndo, ", %d group record(s)", ngroups)); + ngroups = GET_BE_U_2(bp + 6); + ND_PRINT(", %u group record(s)", ngroups); if (ndo->ndo_vflag > 0) { /* Print the group records */ group = 8; for (i=0; indo_vflag == 1) - ND_PRINT((ndo, ", %d source(s)", nsrcs)); + ND_PRINT(", %u source(s)", nsrcs); else { /* Print the sources */ - ND_PRINT((ndo, " {")); + ND_PRINT(" {"); for (j=0; j> 4) + 3); } if (mrc != 100) { - ND_PRINT((ndo, " [max resp time ")); + ND_PRINT(" [max resp time "); if (mrt < 600) { - ND_PRINT((ndo, "%.1fs", mrt * 0.1)); + ND_PRINT("%.1fs", mrt * 0.1); } else { unsigned_relts_print(ndo, mrt / 10); } - ND_PRINT((ndo, "]")); + ND_PRINT("]"); } - ND_TCHECK2(bp[4], 4); - if (EXTRACT_32BITS(&bp[4]) == 0) + if (GET_BE_U_4(bp + 4) == 0) return; - ND_PRINT((ndo, " [gaddr %s", ipaddr_string(ndo, &bp[4]))); - ND_TCHECK2(bp[10], 2); - nsrcs = EXTRACT_16BITS(&bp[10]); + ND_PRINT(" [gaddr %s", GET_IPADDR_STRING(bp + 4)); + nsrcs = GET_BE_U_2(bp + 10); if (nsrcs > 0) { if (len < 12 + (nsrcs << 2)) - ND_PRINT((ndo, " [invalid number of sources]")); + ND_PRINT(" [invalid number of sources]"); else if (ndo->ndo_vflag > 1) { - ND_PRINT((ndo, " {")); + ND_PRINT(" {"); for (i=0; indo_protocol = "igmp"; if (ndo->ndo_qflag) { - ND_PRINT((ndo, "igmp")); + ND_PRINT("igmp"); return; } - ND_TCHECK(bp[0]); - switch (bp[0]) { + switch (GET_U_1(bp)) { case 0x11: - ND_PRINT((ndo, "igmp query")); + ND_PRINT("igmp query"); if (len >= 12) print_igmpv3_query(ndo, bp, len); else { - ND_TCHECK(bp[1]); - if (bp[1]) { - ND_PRINT((ndo, " v2")); - if (bp[1] != 100) - ND_PRINT((ndo, " [max resp time %d]", bp[1])); + if (GET_U_1(bp + 1)) { + ND_PRINT(" v2"); + if (GET_U_1(bp + 1) != 100) + ND_PRINT(" [max resp time %u]", GET_U_1(bp + 1)); } else - ND_PRINT((ndo, " v1")); - ND_TCHECK2(bp[4], 4); - if (EXTRACT_32BITS(&bp[4])) - ND_PRINT((ndo, " [gaddr %s]", ipaddr_string(ndo, &bp[4]))); + ND_PRINT(" v1"); + if (GET_BE_U_4(bp + 4)) + ND_PRINT(" [gaddr %s]", GET_IPADDR_STRING(bp + 4)); if (len != 8) - ND_PRINT((ndo, " [len %d]", len)); + ND_PRINT(" [len %u]", len); } break; case 0x12: - ND_TCHECK2(bp[4], 4); - ND_PRINT((ndo, "igmp v1 report %s", ipaddr_string(ndo, &bp[4]))); + ND_PRINT("igmp v1 report %s", GET_IPADDR_STRING(bp + 4)); if (len != 8) - ND_PRINT((ndo, " [len %d]", len)); + ND_PRINT(" [len %u]", len); break; case 0x16: - ND_TCHECK2(bp[4], 4); - ND_PRINT((ndo, "igmp v2 report %s", ipaddr_string(ndo, &bp[4]))); + ND_PRINT("igmp v2 report %s", GET_IPADDR_STRING(bp + 4)); break; case 0x22: - ND_PRINT((ndo, "igmp v3 report")); + ND_PRINT("igmp v3 report"); print_igmpv3_report(ndo, bp, len); break; case 0x17: - ND_TCHECK2(bp[4], 4); - ND_PRINT((ndo, "igmp leave %s", ipaddr_string(ndo, &bp[4]))); + ND_PRINT("igmp leave %s", GET_IPADDR_STRING(bp + 4)); break; case 0x13: - ND_PRINT((ndo, "igmp dvmrp")); + ND_PRINT("igmp dvmrp"); if (len < 8) - ND_PRINT((ndo, " [len %d]", len)); + ND_PRINT(" [len %u]", len); else dvmrp_print(ndo, bp, len); break; case 0x14: - ND_PRINT((ndo, "igmp pimv1")); + ND_PRINT("igmp pimv1"); pimv1_print(ndo, bp, len); break; case 0x1e: - print_mresp(ndo, bp, len); + print_mtrace(ndo, "mresp", bp, len); break; case 0x1f: - print_mtrace(ndo, bp, len); + print_mtrace(ndo, "mtrace", bp, len); break; default: - ND_PRINT((ndo, "igmp-%d", bp[0])); + ND_PRINT("igmp-%u", GET_U_1(bp)); break; } - if (ndo->ndo_vflag && len >= 4 && ND_TTEST2(bp[0], len)) { + if (ndo->ndo_vflag && len >= 4 && ND_TTEST_LEN(bp, len)) { /* Check the IGMP checksum */ vec[0].ptr = bp; vec[0].len = len; if (in_cksum(vec, 1)) - ND_PRINT((ndo, " bad igmp cksum %x!", EXTRACT_16BITS(&bp[2]))); + ND_PRINT(" bad igmp cksum %x!", GET_BE_U_2(bp + 2)); } - return; -trunc: - ND_PRINT((ndo, "%s", tstr)); } diff --git a/contrib/tcpdump/print-igrp.c b/contrib/tcpdump/print-igrp.c index b6eaf31201..0efc78af9e 100644 --- a/contrib/tcpdump/print-igrp.c +++ b/contrib/tcpdump/print-igrp.c @@ -24,10 +24,10 @@ /* \summary: Interior Gateway Routing Protocol (IGRP) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "extract.h" @@ -37,15 +37,15 @@ /* IGRP Header */ struct igrphdr { - uint8_t ig_vop; /* protocol version number / opcode */ + nd_uint8_t ig_vop; /* protocol version number / opcode */ #define IGRP_V(x) (((x) & 0xf0) >> 4) #define IGRP_OP(x) ((x) & 0x0f) - uint8_t ig_ed; /* edition number */ - uint16_t ig_as; /* autonomous system number */ - uint16_t ig_ni; /* number of subnet in local net */ - uint16_t ig_ns; /* number of networks in AS */ - uint16_t ig_nx; /* number of networks ouside AS */ - uint16_t ig_sum; /* checksum of IGRP header & data */ + nd_uint8_t ig_ed; /* edition number */ + nd_uint16_t ig_as; /* autonomous system number */ + nd_uint16_t ig_ni; /* number of subnet in local net */ + nd_uint16_t ig_ns; /* number of networks in AS */ + nd_uint16_t ig_nx; /* number of networks ouside AS */ + nd_uint16_t ig_sum; /* checksum of IGRP header & data */ }; #define IGRP_UPDATE 1 @@ -54,45 +54,32 @@ struct igrphdr { /* IGRP routing entry */ struct igrprte { - uint8_t igr_net[3]; /* 3 significant octets of IP address */ - uint8_t igr_dly[3]; /* delay in tens of microseconds */ - uint8_t igr_bw[3]; /* bandwidth in units of 1 kb/s */ - uint8_t igr_mtu[2]; /* MTU in octets */ - uint8_t igr_rel; /* percent packets successfully tx/rx */ - uint8_t igr_ld; /* percent of channel occupied */ - uint8_t igr_hct; /* hop count */ + nd_byte igr_net[3]; /* 3 significant octets of IP address */ + nd_uint24_t igr_dly; /* delay in tens of microseconds */ + nd_uint24_t igr_bw; /* bandwidth in units of 1 kb/s */ + nd_uint16_t igr_mtu; /* MTU in octets */ + nd_uint8_t igr_rel; /* percent packets successfully tx/rx */ + nd_uint8_t igr_ld; /* percent of channel occupied */ + nd_uint8_t igr_hct; /* hop count */ }; -#define IGRP_RTE_SIZE 14 /* don't believe sizeof ! */ +#define IGRP_RTE_SIZE 14 /* sizeof() is accurate now */ static void -igrp_entry_print(netdissect_options *ndo, register const struct igrprte *igr, - register int is_interior, register int is_exterior) +igrp_entry_print(netdissect_options *ndo, const struct igrprte *igr) { - register u_int delay, bandwidth; + u_int delay, bandwidth; u_int metric, mtu; - if (is_interior) - ND_PRINT((ndo, " *.%d.%d.%d", igr->igr_net[0], - igr->igr_net[1], igr->igr_net[2])); - else if (is_exterior) - ND_PRINT((ndo, " X%d.%d.%d.0", igr->igr_net[0], - igr->igr_net[1], igr->igr_net[2])); - else - ND_PRINT((ndo, " %d.%d.%d.0", igr->igr_net[0], - igr->igr_net[1], igr->igr_net[2])); - - delay = EXTRACT_24BITS(igr->igr_dly); - bandwidth = EXTRACT_24BITS(igr->igr_bw); - metric = bandwidth + delay; - if (metric > 0xffffff) - metric = 0xffffff; - mtu = EXTRACT_16BITS(igr->igr_mtu); - - ND_PRINT((ndo, " d=%d b=%d r=%d l=%d M=%d mtu=%d in %d hops", + delay = GET_BE_U_3(igr->igr_dly); + bandwidth = GET_BE_U_3(igr->igr_bw); + metric = ND_MIN(bandwidth + delay, 0xffffff); + mtu = GET_BE_U_2(igr->igr_mtu); + + ND_PRINT(" d=%u b=%u r=%u l=%u M=%u mtu=%u in %u hops", 10 * delay, bandwidth == 0 ? 0 : 10000000 / bandwidth, - igr->igr_rel, igr->igr_ld, metric, - mtu, igr->igr_hct)); + GET_U_1(igr->igr_rel), GET_U_1(igr->igr_ld), metric, + mtu, GET_U_1(igr->igr_hct)); } static const struct tok op2str[] = { @@ -102,54 +89,61 @@ static const struct tok op2str[] = { }; void -igrp_print(netdissect_options *ndo, register const u_char *bp, u_int length) +igrp_print(netdissect_options *ndo, const u_char *bp, u_int length) { - register const struct igrphdr *hdr; - register const u_char *cp; + const struct igrphdr *hdr; + const u_char *cp; u_int nint, nsys, next; + uint16_t cksum; + ndo->ndo_protocol = "igrp"; hdr = (const struct igrphdr *)bp; cp = (const u_char *)(hdr + 1); - ND_PRINT((ndo, "igrp:")); + ND_PRINT("igrp:"); /* Header */ - ND_TCHECK(*hdr); - nint = EXTRACT_16BITS(&hdr->ig_ni); - nsys = EXTRACT_16BITS(&hdr->ig_ns); - next = EXTRACT_16BITS(&hdr->ig_nx); - - ND_PRINT((ndo, " %s V%d edit=%d AS=%d (%d/%d/%d)", - tok2str(op2str, "op-#%d", IGRP_OP(hdr->ig_vop)), - IGRP_V(hdr->ig_vop), - hdr->ig_ed, - EXTRACT_16BITS(&hdr->ig_as), + nint = GET_BE_U_2(hdr->ig_ni); + nsys = GET_BE_U_2(hdr->ig_ns); + next = GET_BE_U_2(hdr->ig_nx); + + ND_PRINT(" %s V%u edit=%u AS=%u (%u/%u/%u)", + tok2str(op2str, "op-#%u", IGRP_OP(GET_U_1(hdr->ig_vop))), + IGRP_V(GET_U_1(hdr->ig_vop)), + GET_U_1(hdr->ig_ed), + GET_BE_U_2(hdr->ig_as), nint, nsys, - next)); + next); + cksum = GET_BE_U_2(hdr->ig_sum); + if (ndo->ndo_vflag) + ND_PRINT(" checksum=0x%04x", cksum); length -= sizeof(*hdr); while (length >= IGRP_RTE_SIZE) { + const struct igrprte *igr = (const struct igrprte *)cp; + uint8_t net0 = GET_U_1(&igr->igr_net[0]); + uint8_t net1 = GET_U_1(&igr->igr_net[1]); + uint8_t net2 = GET_U_1(&igr->igr_net[2]); + if (nint > 0) { - ND_TCHECK2(*cp, IGRP_RTE_SIZE); - igrp_entry_print(ndo, (const struct igrprte *)cp, 1, 0); + ND_PRINT(" *.%u.%u.%u", net0, net1, net2); + igrp_entry_print(ndo, igr); --nint; } else if (nsys > 0) { - ND_TCHECK2(*cp, IGRP_RTE_SIZE); - igrp_entry_print(ndo, (const struct igrprte *)cp, 0, 0); + ND_PRINT(" %u.%u.%u.0", net0, net1, net2); + igrp_entry_print(ndo, igr); --nsys; } else if (next > 0) { - ND_TCHECK2(*cp, IGRP_RTE_SIZE); - igrp_entry_print(ndo, (const struct igrprte *)cp, 0, 1); + ND_PRINT(" X%u.%u.%u.0", net0, net1, net2); + igrp_entry_print(ndo, igr); --next; } else { - ND_PRINT((ndo, " [extra bytes %d]", length)); + ND_PRINT(" [extra bytes %u]", length); break; } cp += IGRP_RTE_SIZE; length -= IGRP_RTE_SIZE; } - if (nint == 0 && nsys == 0 && next == 0) - return; -trunc: - ND_PRINT((ndo, " [|igrp]")); + if (nint || nsys || next || length) + nd_print_invalid(ndo); } diff --git a/contrib/tcpdump/print-ip-demux.c b/contrib/tcpdump/print-ip-demux.c new file mode 100644 index 0000000000..b111c6deb7 --- /dev/null +++ b/contrib/tcpdump/print-ip-demux.c @@ -0,0 +1,231 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 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. + */ + +/* \summary: IPv4/IPv6 payload printer */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "netdissect-stdinc.h" + +#include "netdissect.h" +#include "addrtoname.h" +#include "extract.h" + +#include "ip.h" +#include "ipproto.h" + +void +ip_demux_print(netdissect_options *ndo, + const u_char *bp, + u_int length, u_int ver, int fragmented, u_int ttl_hl, + uint8_t nh, const u_char *iph) +{ + int advance; + const char *p_name; + + advance = 0; + +again: + switch (nh) { + + case IPPROTO_AH: + if (!ND_TTEST_1(bp)) { + ndo->ndo_protocol = "ah"; + nd_print_trunc(ndo); + break; + } + nh = GET_U_1(bp); + advance = ah_print(ndo, bp); + if (advance <= 0) + break; + bp += advance; + length -= advance; + goto again; + + case IPPROTO_ESP: + { + esp_print(ndo, bp, length, iph, ver, fragmented, ttl_hl); + /* + * Either this has decrypted the payload and + * printed it, in which case there's nothing more + * to do, or it hasn't, in which case there's + * nothing more to do. + */ + break; + } + + case IPPROTO_IPCOMP: + { + ipcomp_print(ndo, bp); + /* + * Either this has decompressed the payload and + * printed it, in which case there's nothing more + * to do, or it hasn't, in which case there's + * nothing more to do. + */ + break; + } + + case IPPROTO_SCTP: + sctp_print(ndo, bp, iph, length); + break; + + case IPPROTO_DCCP: + dccp_print(ndo, bp, iph, length); + break; + + case IPPROTO_TCP: + tcp_print(ndo, bp, length, iph, fragmented); + break; + + case IPPROTO_UDP: + udp_print(ndo, bp, length, iph, fragmented, ttl_hl); + break; + + case IPPROTO_ICMP: + if (ver == 4) + icmp_print(ndo, bp, length, iph, fragmented); + else { + ND_PRINT("[%s requires IPv4]", + tok2str(ipproto_values,"unknown",nh)); + nd_print_invalid(ndo); + } + break; + + case IPPROTO_ICMPV6: + if (ver == 6) + icmp6_print(ndo, bp, length, iph, fragmented); + else { + ND_PRINT("[%s requires IPv6]", + tok2str(ipproto_values,"unknown",nh)); + nd_print_invalid(ndo); + } + break; + + case IPPROTO_PIGP: + /* + * XXX - the current IANA protocol number assignments + * page lists 9 as "any private interior gateway + * (used by Cisco for their IGRP)" and 88 as + * "EIGRP" from Cisco. + * + * Recent BSD headers define + * IP_PROTO_PIGP as 9 and IP_PROTO_IGRP as 88. + * We define IP_PROTO_PIGP as 9 and + * IP_PROTO_EIGRP as 88; those names better + * match was the current protocol number + * assignments say. + */ + igrp_print(ndo, bp, length); + break; + + case IPPROTO_EIGRP: + eigrp_print(ndo, bp, length); + break; + + case IPPROTO_ND: + ND_PRINT(" nd %u", length); + break; + + case IPPROTO_EGP: + egp_print(ndo, bp, length); + break; + + case IPPROTO_OSPF: + if (ver == 6) + ospf6_print(ndo, bp, length); + else + ospf_print(ndo, bp, length, iph); + break; + + case IPPROTO_IGMP: + if (ver == 4) + igmp_print(ndo, bp, length); + else { + ND_PRINT("[%s requires IPv4]", + tok2str(ipproto_values,"unknown",nh)); + nd_print_invalid(ndo); + } + break; + + case IPPROTO_IPV4: + /* ipv4-in-ip encapsulation */ + ip_print(ndo, bp, length); + break; + + case IPPROTO_IPV6: + /* ip6-in-ip encapsulation */ + ip6_print(ndo, bp, length); + break; + + case IPPROTO_RSVP: + rsvp_print(ndo, bp, length); + break; + + case IPPROTO_GRE: + gre_print(ndo, bp, length); + break; + + case IPPROTO_MOBILE: + mobile_print(ndo, bp, length); + break; + + case IPPROTO_PIM: + pim_print(ndo, bp, length, iph); + break; + + case IPPROTO_VRRP: + if (ndo->ndo_packettype == PT_CARP) { + carp_print(ndo, bp, length, ttl_hl); + } else { + vrrp_print(ndo, bp, length, iph, ttl_hl); + } + break; + + case IPPROTO_PGM: + pgm_print(ndo, bp, length, iph); + break; + + case IPPROTO_ETHERNET: + if (ver == 6) + ether_print(ndo, bp, length, ND_BYTES_AVAILABLE_AFTER(bp), NULL, NULL); + else { + ND_PRINT("[%s requires IPv6]", + tok2str(ipproto_values,"unknown",nh)); + nd_print_invalid(ndo); + } + break; + + case IPPROTO_NONE: + ND_PRINT("no next header"); + break; + + default: + if (ndo->ndo_nflag==0 && (p_name = netdb_protoname(nh)) != NULL) + ND_PRINT(" %s", p_name); + else + ND_PRINT(" ip-proto-%u", nh); + ND_PRINT(" %u", length); + break; + } +} diff --git a/contrib/tcpdump/print-ip.c b/contrib/tcpdump/print-ip.c index f8e02c1e79..a0df959188 100644 --- a/contrib/tcpdump/print-ip.c +++ b/contrib/tcpdump/print-ip.c @@ -22,12 +22,10 @@ /* \summary: IP printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include - -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "addrtoname.h" @@ -36,7 +34,6 @@ #include "ip.h" #include "ipproto.h" -static const char tstr[] = "[|ip]"; static const struct tok ip_option_values[] = { { IPOPT_EOL, "EOL" }, @@ -56,27 +53,26 @@ static const struct tok ip_option_values[] = { */ static int ip_printroute(netdissect_options *ndo, - register const u_char *cp, u_int length) + const u_char *cp, u_int length) { - register u_int ptr; - register u_int len; + u_int ptr; + u_int len; if (length < 3) { - ND_PRINT((ndo, " [bad length %u]", length)); + ND_PRINT(" [bad length %u]", length); return (0); } if ((length + 1) & 3) - ND_PRINT((ndo, " [bad length %u]", length)); - ND_TCHECK(cp[2]); - ptr = cp[2] - 1; + ND_PRINT(" [bad length %u]", length); + ptr = GET_U_1(cp + 2) - 1; if (ptr < 3 || ((ptr + 1) & 3) || ptr > length + 1) - ND_PRINT((ndo, " [bad ptr %u]", cp[2])); + ND_PRINT(" [bad ptr %u]", GET_U_1(cp + 2)); for (len = 3; len < length; len += 4) { - ND_TCHECK2(cp[len], 4); - ND_PRINT((ndo, " %s", ipaddr_string(ndo, &cp[len]))); + ND_TCHECK_4(cp + len); /* Needed to print the IP addresses */ + ND_PRINT(" %s", GET_IPADDR_STRING(cp + len)); if (ptr > len) - ND_PRINT((ndo, ",")); + ND_PRINT(","); } return (0); @@ -95,58 +91,58 @@ static uint32_t ip_finddst(netdissect_options *ndo, const struct ip *ip) { - int length; - int len; + u_int length; + u_int len; const u_char *cp; - uint32_t retval; cp = (const u_char *)(ip + 1); - length = (IP_HL(ip) << 2) - sizeof(struct ip); + length = IP_HL(ip) * 4; + if (length < sizeof(struct ip)) + goto trunc; + length -= sizeof(struct ip); - for (; length > 0; cp += len, length -= len) { + for (; length != 0; cp += len, length -= len) { int tt; - ND_TCHECK(*cp); - tt = *cp; + tt = GET_U_1(cp); if (tt == IPOPT_EOL) break; else if (tt == IPOPT_NOP) len = 1; else { - ND_TCHECK(cp[1]); - len = cp[1]; + len = GET_U_1(cp + 1); if (len < 2) break; } - ND_TCHECK2(*cp, len); + if (length < len) + goto trunc; + ND_TCHECK_LEN(cp, len); switch (tt) { case IPOPT_SSRR: case IPOPT_LSRR: if (len < 7) break; - UNALIGNED_MEMCPY(&retval, cp + len - 4, 4); - return retval; + return (GET_IPV4_TO_NETWORK_ORDER(cp + len - 4)); } } trunc: - UNALIGNED_MEMCPY(&retval, &ip->ip_dst, sizeof(uint32_t)); - return retval; + return (GET_IPV4_TO_NETWORK_ORDER(ip->ip_dst)); } /* * Compute a V4-style checksum by building a pseudoheader. */ -int +uint16_t nextproto4_cksum(netdissect_options *ndo, const struct ip *ip, const uint8_t *data, - u_int len, u_int covlen, u_int next_proto) + u_int len, u_int covlen, uint8_t next_proto) { struct phdr { uint32_t src; uint32_t dst; - u_char mbz; - u_char proto; + uint8_t mbz; + uint8_t proto; uint16_t len; } ph; struct cksum_vec vec[2]; @@ -155,9 +151,9 @@ nextproto4_cksum(netdissect_options *ndo, ph.len = htons((uint16_t)len); ph.mbz = 0; ph.proto = next_proto; - UNALIGNED_MEMCPY(&ph.src, &ip->ip_src, sizeof(uint32_t)); + ph.src = GET_IPV4_TO_NETWORK_ORDER(ip->ip_src); if (IP_HL(ip) == 5) - UNALIGNED_MEMCPY(&ph.dst, &ip->ip_dst, sizeof(uint32_t)); + ph.dst = GET_IPV4_TO_NETWORK_ORDER(ip->ip_dst); else ph.dst = ip_finddst(ndo, ip); @@ -170,48 +166,37 @@ nextproto4_cksum(netdissect_options *ndo, static int ip_printts(netdissect_options *ndo, - register const u_char *cp, u_int length) + const u_char *cp, u_int length) { - register u_int ptr; - register u_int len; - int hoplen; + u_int ptr; + u_int len; + u_int hoplen; const char *type; if (length < 4) { - ND_PRINT((ndo, "[bad length %u]", length)); + ND_PRINT("[bad length %u]", length); return (0); } - ND_PRINT((ndo, " TS{")); - hoplen = ((cp[3]&0xF) != IPOPT_TS_TSONLY) ? 8 : 4; + ND_PRINT(" TS{"); + hoplen = ((GET_U_1(cp + 3) & 0xF) != IPOPT_TS_TSONLY) ? 8 : 4; if ((length - 4) & (hoplen-1)) - ND_PRINT((ndo, "[bad length %u]", length)); - ND_TCHECK(cp[2]); - ptr = cp[2] - 1; + ND_PRINT("[bad length %u]", length); + ptr = GET_U_1(cp + 2) - 1; len = 0; if (ptr < 4 || ((ptr - 4) & (hoplen-1)) || ptr > length + 1) - ND_PRINT((ndo, "[bad ptr %u]", cp[2])); - ND_TCHECK(cp[3]); - switch (cp[3]&0xF) { + ND_PRINT("[bad ptr %u]", GET_U_1(cp + 2)); + switch (GET_U_1(cp + 3)&0xF) { case IPOPT_TS_TSONLY: - ND_PRINT((ndo, "TSONLY")); + ND_PRINT("TSONLY"); break; case IPOPT_TS_TSANDADDR: - ND_PRINT((ndo, "TS+ADDR")); + ND_PRINT("TS+ADDR"); break; - /* - * prespecified should really be 3, but some ones might send 2 - * instead, and the IPOPT_TS_PRESPEC constant can apparently - * have both values, so we have to hard-code it here. - */ - - case 2: - ND_PRINT((ndo, "PRESPEC2.0")); - break; - case 3: /* IPOPT_TS_PRESPEC */ - ND_PRINT((ndo, "PRESPEC")); + case IPOPT_TS_PRESPEC: + ND_PRINT("PRESPEC"); break; default: - ND_PRINT((ndo, "[bad ts type %d]", cp[3]&0xF)); + ND_PRINT("[bad ts type %u]", GET_U_1(cp + 3)&0xF); goto done; } @@ -219,19 +204,19 @@ ip_printts(netdissect_options *ndo, for (len = 4; len < length; len += hoplen) { if (ptr == len) type = " ^ "; - ND_TCHECK2(cp[len], hoplen); - ND_PRINT((ndo, "%s%d@%s", type, EXTRACT_32BITS(&cp[len+hoplen-4]), - hoplen!=8 ? "" : ipaddr_string(ndo, &cp[len]))); + ND_TCHECK_LEN(cp + len, hoplen); + ND_PRINT("%s%u@%s", type, GET_BE_U_4(cp + len + hoplen - 4), + hoplen!=8 ? "" : GET_IPADDR_STRING(cp + len)); type = " "; } done: - ND_PRINT((ndo, "%s", ptr == len ? " ^ " : "")); + ND_PRINT("%s", ptr == len ? " ^ " : ""); - if (cp[3]>>4) - ND_PRINT((ndo, " [%d hops not recorded]} ", cp[3]>>4)); + if (GET_U_1(cp + 3) >> 4) + ND_PRINT(" [%u hops not recorded]} ", GET_U_1(cp + 3)>>4); else - ND_PRINT((ndo, "}")); + ND_PRINT("}"); return (0); trunc: @@ -240,49 +225,48 @@ trunc: /* * print IP options. + If truncated return -1, else 0. */ -static void +static int ip_optprint(netdissect_options *ndo, - register const u_char *cp, u_int length) + const u_char *cp, u_int length) { - register u_int option_len; + u_int option_len; const char *sep = ""; for (; length > 0; cp += option_len, length -= option_len) { u_int option_code; - ND_PRINT((ndo, "%s", sep)); + ND_PRINT("%s", sep); sep = ","; - ND_TCHECK(*cp); - option_code = *cp; + option_code = GET_U_1(cp); - ND_PRINT((ndo, "%s", - tok2str(ip_option_values,"unknown %u",option_code))); + ND_PRINT("%s", + tok2str(ip_option_values,"unknown %u",option_code)); if (option_code == IPOPT_NOP || option_code == IPOPT_EOL) option_len = 1; else { - ND_TCHECK(cp[1]); - option_len = cp[1]; + option_len = GET_U_1(cp + 1); if (option_len < 2) { - ND_PRINT((ndo, " [bad length %u]", option_len)); - return; + ND_PRINT(" [bad length %u]", option_len); + return 0; } } if (option_len > length) { - ND_PRINT((ndo, " [bad length %u]", option_len)); - return; + ND_PRINT(" [bad length %u]", option_len); + return 0; } - ND_TCHECK2(*cp, option_len); + ND_TCHECK_LEN(cp, option_len); switch (option_code) { case IPOPT_EOL: - return; + return 0; case IPOPT_TS: if (ip_printts(ndo, cp, option_len) == -1) @@ -298,12 +282,12 @@ ip_optprint(netdissect_options *ndo, case IPOPT_RA: if (option_len < 4) { - ND_PRINT((ndo, " [bad length %u]", option_len)); + ND_PRINT(" [bad length %u]", option_len); break; } - ND_TCHECK(cp[3]); - if (EXTRACT_16BITS(&cp[2]) != 0) - ND_PRINT((ndo, " value %u", EXTRACT_16BITS(&cp[2]))); + ND_TCHECK_1(cp + 3); + if (GET_BE_U_2(cp + 2) != 0) + ND_PRINT(" value %u", GET_BE_U_2(cp + 2)); break; case IPOPT_NOP: /* nothing to print - fall through */ @@ -312,10 +296,10 @@ ip_optprint(netdissect_options *ndo, break; } } - return; + return 0; trunc: - ND_PRINT((ndo, "%s", tstr)); + return -1; } #define IP_RES 0x8000 @@ -327,205 +311,6 @@ static const struct tok ip_frag_values[] = { { 0, NULL } }; -struct ip_print_demux_state { - const struct ip *ip; - const u_char *cp; - u_int len, off; - u_char nh; - int advance; -}; - -static void -ip_print_demux(netdissect_options *ndo, - struct ip_print_demux_state *ipds) -{ - const char *p_name; - -again: - switch (ipds->nh) { - - case IPPROTO_AH: - if (!ND_TTEST(*ipds->cp)) { - ND_PRINT((ndo, "[|AH]")); - break; - } - ipds->nh = *ipds->cp; - ipds->advance = ah_print(ndo, ipds->cp); - if (ipds->advance <= 0) - break; - ipds->cp += ipds->advance; - ipds->len -= ipds->advance; - goto again; - - case IPPROTO_ESP: - { - int enh, padlen; - ipds->advance = esp_print(ndo, ipds->cp, ipds->len, - (const u_char *)ipds->ip, - &enh, &padlen); - if (ipds->advance <= 0) - break; - ipds->cp += ipds->advance; - ipds->len -= ipds->advance + padlen; - ipds->nh = enh & 0xff; - goto again; - } - - case IPPROTO_IPCOMP: - { - ipcomp_print(ndo, ipds->cp); - /* - * Either this has decompressed the payload and - * printed it, in which case there's nothing more - * to do, or it hasn't, in which case there's - * nothing more to do. - */ - break; - } - - case IPPROTO_SCTP: - sctp_print(ndo, ipds->cp, (const u_char *)ipds->ip, ipds->len); - break; - - case IPPROTO_DCCP: - dccp_print(ndo, ipds->cp, (const u_char *)ipds->ip, ipds->len); - break; - - case IPPROTO_TCP: - /* pass on the MF bit plus the offset to detect fragments */ - tcp_print(ndo, ipds->cp, ipds->len, (const u_char *)ipds->ip, - ipds->off & (IP_MF|IP_OFFMASK)); - break; - - case IPPROTO_UDP: - /* pass on the MF bit plus the offset to detect fragments */ - udp_print(ndo, ipds->cp, ipds->len, (const u_char *)ipds->ip, - ipds->off & (IP_MF|IP_OFFMASK)); - break; - - case IPPROTO_ICMP: - /* pass on the MF bit plus the offset to detect fragments */ - icmp_print(ndo, ipds->cp, ipds->len, (const u_char *)ipds->ip, - ipds->off & (IP_MF|IP_OFFMASK)); - break; - - case IPPROTO_PIGP: - /* - * XXX - the current IANA protocol number assignments - * page lists 9 as "any private interior gateway - * (used by Cisco for their IGRP)" and 88 as - * "EIGRP" from Cisco. - * - * Recent BSD headers define - * IP_PROTO_PIGP as 9 and IP_PROTO_IGRP as 88. - * We define IP_PROTO_PIGP as 9 and - * IP_PROTO_EIGRP as 88; those names better - * match was the current protocol number - * assignments say. - */ - igrp_print(ndo, ipds->cp, ipds->len); - break; - - case IPPROTO_EIGRP: - eigrp_print(ndo, ipds->cp, ipds->len); - break; - - case IPPROTO_ND: - ND_PRINT((ndo, " nd %d", ipds->len)); - break; - - case IPPROTO_EGP: - egp_print(ndo, ipds->cp, ipds->len); - break; - - case IPPROTO_OSPF: - ospf_print(ndo, ipds->cp, ipds->len, (const u_char *)ipds->ip); - break; - - case IPPROTO_IGMP: - igmp_print(ndo, ipds->cp, ipds->len); - break; - - case IPPROTO_IPV4: - /* DVMRP multicast tunnel (ip-in-ip encapsulation) */ - ip_print(ndo, ipds->cp, ipds->len); - if (! ndo->ndo_vflag) { - ND_PRINT((ndo, " (ipip-proto-4)")); - return; - } - break; - - case IPPROTO_IPV6: - /* ip6-in-ip encapsulation */ - ip6_print(ndo, ipds->cp, ipds->len); - break; - - case IPPROTO_RSVP: - rsvp_print(ndo, ipds->cp, ipds->len); - break; - - case IPPROTO_GRE: - /* do it */ - gre_print(ndo, ipds->cp, ipds->len); - break; - - case IPPROTO_MOBILE: - mobile_print(ndo, ipds->cp, ipds->len); - break; - - case IPPROTO_PIM: - pim_print(ndo, ipds->cp, ipds->len, (const u_char *)ipds->ip); - break; - - case IPPROTO_VRRP: - if (ndo->ndo_packettype == PT_CARP) { - if (ndo->ndo_vflag) - ND_PRINT((ndo, "carp %s > %s: ", - ipaddr_string(ndo, &ipds->ip->ip_src), - ipaddr_string(ndo, &ipds->ip->ip_dst))); - carp_print(ndo, ipds->cp, ipds->len, ipds->ip->ip_ttl); - } else { - if (ndo->ndo_vflag) - ND_PRINT((ndo, "vrrp %s > %s: ", - ipaddr_string(ndo, &ipds->ip->ip_src), - ipaddr_string(ndo, &ipds->ip->ip_dst))); - vrrp_print(ndo, ipds->cp, ipds->len, - (const u_char *)ipds->ip, ipds->ip->ip_ttl); - } - break; - - case IPPROTO_PGM: - pgm_print(ndo, ipds->cp, ipds->len, (const u_char *)ipds->ip); - break; - - default: - if (ndo->ndo_nflag==0 && (p_name = netdb_protoname(ipds->nh)) != NULL) - ND_PRINT((ndo, " %s", p_name)); - else - ND_PRINT((ndo, " ip-proto-%d", ipds->nh)); - ND_PRINT((ndo, " %d", ipds->len)); - break; - } -} - -void -ip_print_inner(netdissect_options *ndo, - const u_char *bp, - u_int length, u_int nh, - const u_char *bp2) -{ - struct ip_print_demux_state ipd; - - ipd.ip = (const struct ip *)bp2; - ipd.cp = bp; - ipd.len = length; - ipd.off = 0; - ipd.nh = nh; - ipd.advance = 0; - - ip_print_demux(ndo, &ipd); -} - /* * print an IP datagram. @@ -535,53 +320,56 @@ ip_print(netdissect_options *ndo, const u_char *bp, u_int length) { - struct ip_print_demux_state ipd; - struct ip_print_demux_state *ipds=&ipd; - const u_char *ipend; + const struct ip *ip; + u_int off; u_int hlen; + u_int len; struct cksum_vec vec[1]; + uint8_t ip_tos, ip_ttl, ip_proto; uint16_t sum, ip_sum; const char *p_name; + int truncated = 0; - ipds->ip = (const struct ip *)bp; - ND_TCHECK(ipds->ip->ip_vhl); - if (IP_V(ipds->ip) != 4) { /* print version and fail if != 4 */ - if (IP_V(ipds->ip) == 6) - ND_PRINT((ndo, "IP6, wrong link-layer encapsulation ")); + ndo->ndo_protocol = "ip"; + ip = (const struct ip *)bp; + if (IP_V(ip) != 4) { /* print version and fail if != 4 */ + if (IP_V(ip) == 6) + ND_PRINT("IP6, wrong link-layer encapsulation"); else - ND_PRINT((ndo, "IP%u ", IP_V(ipds->ip))); + ND_PRINT("IP%u", IP_V(ip)); + nd_print_invalid(ndo); return; } if (!ndo->ndo_eflag) - ND_PRINT((ndo, "IP ")); + ND_PRINT("IP "); - ND_TCHECK(*ipds->ip); + ND_TCHECK_SIZE(ip); if (length < sizeof (struct ip)) { - ND_PRINT((ndo, "truncated-ip %u", length)); + ND_PRINT("truncated-ip %u", length); return; } - hlen = IP_HL(ipds->ip) * 4; + hlen = IP_HL(ip) * 4; if (hlen < sizeof (struct ip)) { - ND_PRINT((ndo, "bad-hlen %u", hlen)); + ND_PRINT("bad-hlen %u", hlen); return; } - ipds->len = EXTRACT_16BITS(&ipds->ip->ip_len); - if (length < ipds->len) - ND_PRINT((ndo, "truncated-ip - %u bytes missing! ", - ipds->len - length)); - if (ipds->len < hlen) { + len = GET_BE_U_2(ip->ip_len); + if (length < len) + ND_PRINT("truncated-ip - %u bytes missing! ", + len - length); + if (len < hlen) { #ifdef GUESS_TSO - if (ipds->len) { - ND_PRINT((ndo, "bad-len %u", ipds->len)); + if (len) { + ND_PRINT("bad-len %u", len); return; } else { /* we guess that it is a TSO send */ - ipds->len = length; + len = length; } #else - ND_PRINT((ndo, "bad-len %u", ipds->len)); + ND_PRINT("bad-len %u", len); return; #endif /* GUESS_TSO */ } @@ -589,147 +377,159 @@ ip_print(netdissect_options *ndo, /* * Cut off the snapshot length to the end of the IP payload. */ - ipend = bp + ipds->len; - if (ipend < ndo->ndo_snapend) - ndo->ndo_snapend = ipend; + nd_push_snapend(ndo, bp + len); - ipds->len -= hlen; + len -= hlen; - ipds->off = EXTRACT_16BITS(&ipds->ip->ip_off); + off = GET_BE_U_2(ip->ip_off); + + ip_proto = GET_U_1(ip->ip_p); if (ndo->ndo_vflag) { - ND_PRINT((ndo, "(tos 0x%x", (int)ipds->ip->ip_tos)); + ip_tos = GET_U_1(ip->ip_tos); + ND_PRINT("(tos 0x%x", ip_tos); /* ECN bits */ - switch (ipds->ip->ip_tos & 0x03) { + switch (ip_tos & 0x03) { case 0: break; case 1: - ND_PRINT((ndo, ",ECT(1)")); + ND_PRINT(",ECT(1)"); break; case 2: - ND_PRINT((ndo, ",ECT(0)")); + ND_PRINT(",ECT(0)"); break; case 3: - ND_PRINT((ndo, ",CE")); + ND_PRINT(",CE"); break; } - if (ipds->ip->ip_ttl >= 1) - ND_PRINT((ndo, ", ttl %u", ipds->ip->ip_ttl)); + ip_ttl = GET_U_1(ip->ip_ttl); + if (ip_ttl >= 1) + ND_PRINT(", ttl %u", ip_ttl); /* * for the firewall guys, print id, offset. * On all but the last stick a "+" in the flags portion. * For unfragmented datagrams, note the don't fragment flag. */ + ND_PRINT(", id %u, offset %u, flags [%s], proto %s (%u)", + GET_BE_U_2(ip->ip_id), + (off & IP_OFFMASK) * 8, + bittok2str(ip_frag_values, "none", off & (IP_RES|IP_DF|IP_MF)), + tok2str(ipproto_values, "unknown", ip_proto), + ip_proto); - ND_PRINT((ndo, ", id %u, offset %u, flags [%s], proto %s (%u)", - EXTRACT_16BITS(&ipds->ip->ip_id), - (ipds->off & 0x1fff) * 8, - bittok2str(ip_frag_values, "none", ipds->off&0xe000), - tok2str(ipproto_values,"unknown",ipds->ip->ip_p), - ipds->ip->ip_p)); - - ND_PRINT((ndo, ", length %u", EXTRACT_16BITS(&ipds->ip->ip_len))); + ND_PRINT(", length %u", GET_BE_U_2(ip->ip_len)); if ((hlen - sizeof(struct ip)) > 0) { - ND_PRINT((ndo, ", options (")); - ip_optprint(ndo, (const u_char *)(ipds->ip + 1), hlen - sizeof(struct ip)); - ND_PRINT((ndo, ")")); + ND_PRINT(", options ("); + if (ip_optprint(ndo, (const u_char *)(ip + 1), + hlen - sizeof(struct ip)) == -1) { + ND_PRINT(" [truncated-option]"); + truncated = 1; + } + ND_PRINT(")"); } - if (!ndo->ndo_Kflag && (const u_char *)ipds->ip + hlen <= ndo->ndo_snapend) { - vec[0].ptr = (const uint8_t *)(const void *)ipds->ip; + if (!ndo->ndo_Kflag && (const u_char *)ip + hlen <= ndo->ndo_snapend) { + vec[0].ptr = (const uint8_t *)(const void *)ip; vec[0].len = hlen; sum = in_cksum(vec, 1); if (sum != 0) { - ip_sum = EXTRACT_16BITS(&ipds->ip->ip_sum); - ND_PRINT((ndo, ", bad cksum %x (->%x)!", ip_sum, - in_cksum_shouldbe(ip_sum, sum))); + ip_sum = GET_BE_U_2(ip->ip_sum); + ND_PRINT(", bad cksum %x (->%x)!", ip_sum, + in_cksum_shouldbe(ip_sum, sum)); } } - ND_PRINT((ndo, ")\n ")); + ND_PRINT(")\n "); + if (truncated) { + ND_PRINT("%s > %s: ", + GET_IPADDR_STRING(ip->ip_src), + GET_IPADDR_STRING(ip->ip_dst)); + nd_print_trunc(ndo); + nd_pop_packet_info(ndo); + return; + } } /* * If this is fragment zero, hand it to the next higher - * level protocol. + * level protocol. Let them know whether there are more + * fragments. */ - if ((ipds->off & 0x1fff) == 0) { - ipds->cp = (const u_char *)ipds->ip + hlen; - ipds->nh = ipds->ip->ip_p; - - if (ipds->nh != IPPROTO_TCP && ipds->nh != IPPROTO_UDP && - ipds->nh != IPPROTO_SCTP && ipds->nh != IPPROTO_DCCP) { - ND_PRINT((ndo, "%s > %s: ", - ipaddr_string(ndo, &ipds->ip->ip_src), - ipaddr_string(ndo, &ipds->ip->ip_dst))); + if ((off & IP_OFFMASK) == 0) { + uint8_t nh = GET_U_1(ip->ip_p); + + if (nh != IPPROTO_TCP && nh != IPPROTO_UDP && + nh != IPPROTO_SCTP && nh != IPPROTO_DCCP) { + ND_PRINT("%s > %s: ", + GET_IPADDR_STRING(ip->ip_src), + GET_IPADDR_STRING(ip->ip_dst)); } - ip_print_demux(ndo, ipds); + /* + * Do a bounds check before calling ip_demux_print(). + * At least the header data is required. + */ + if (!ND_TTEST_LEN((const u_char *)ip, hlen)) { + ND_PRINT(" [remaining caplen(%u) < header length(%u)]", + ND_BYTES_AVAILABLE_AFTER((const u_char *)ip), + hlen); + nd_trunc_longjmp(ndo); + } + ip_demux_print(ndo, (const u_char *)ip + hlen, len, 4, + off & IP_MF, GET_U_1(ip->ip_ttl), nh, bp); } else { /* * Ultra quiet now means that all this stuff should be * suppressed. */ - if (ndo->ndo_qflag > 1) + if (ndo->ndo_qflag > 1) { + nd_pop_packet_info(ndo); return; + } /* * This isn't the first frag, so we're missing the * next level protocol header. print the ip addr * and the protocol. */ - ND_PRINT((ndo, "%s > %s:", ipaddr_string(ndo, &ipds->ip->ip_src), - ipaddr_string(ndo, &ipds->ip->ip_dst))); - if (!ndo->ndo_nflag && (p_name = netdb_protoname(ipds->ip->ip_p)) != NULL) - ND_PRINT((ndo, " %s", p_name)); + ND_PRINT("%s > %s:", GET_IPADDR_STRING(ip->ip_src), + GET_IPADDR_STRING(ip->ip_dst)); + if (!ndo->ndo_nflag && (p_name = netdb_protoname(ip_proto)) != NULL) + ND_PRINT(" %s", p_name); else - ND_PRINT((ndo, " ip-proto-%d", ipds->ip->ip_p)); + ND_PRINT(" ip-proto-%u", ip_proto); } + nd_pop_packet_info(ndo); return; trunc: - ND_PRINT((ndo, "%s", tstr)); - return; + nd_print_trunc(ndo); } void -ipN_print(netdissect_options *ndo, register const u_char *bp, register u_int length) +ipN_print(netdissect_options *ndo, const u_char *bp, u_int length) { + ndo->ndo_protocol = "ipn"; if (length < 1) { - ND_PRINT((ndo, "truncated-ip %d", length)); + ND_PRINT("truncated-ip %u", length); return; } - ND_TCHECK(*bp); - switch (*bp & 0xF0) { + switch (GET_U_1(bp) & 0xF0) { case 0x40: - ip_print (ndo, bp, length); + ip_print(ndo, bp, length); break; case 0x60: - ip6_print (ndo, bp, length); + ip6_print(ndo, bp, length); break; default: - ND_PRINT((ndo, "unknown ip %d", (*bp & 0xF0) >> 4)); + ND_PRINT("unknown ip %u", (GET_U_1(bp) & 0xF0) >> 4); break; } - return; - -trunc: - ND_PRINT((ndo, "%s", tstr)); - return; } - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ - - diff --git a/contrib/tcpdump/print-ip6.c b/contrib/tcpdump/print-ip6.c index a634d7b831..525a284ecd 100644 --- a/contrib/tcpdump/print-ip6.c +++ b/contrib/tcpdump/print-ip6.c @@ -22,10 +22,10 @@ /* \summary: IPv6 printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include @@ -44,22 +44,23 @@ * calculation. */ static void -ip6_finddst(netdissect_options *ndo, struct in6_addr *dst, +ip6_finddst(netdissect_options *ndo, nd_ipv6 *dst, const struct ip6_hdr *ip6) { const u_char *cp; - int advance; + u_int advance; u_int nh; - const struct in6_addr *dst_addr; + const void *dst_addr; const struct ip6_rthdr *dp; const struct ip6_rthdr0 *dp0; - const struct in6_addr *addr; + const struct ip6_srh *srh; + const u_char *p; int i, len; cp = (const u_char *)ip6; advance = sizeof(struct ip6_hdr); - nh = ip6->ip6_nxt; - dst_addr = &ip6->ip6_dst; + nh = GET_U_1(ip6->ip6_nxt); + dst_addr = (const void *)ip6->ip6_dst; while (cp < ndo->ndo_snapend) { cp += advance; @@ -76,9 +77,8 @@ ip6_finddst(netdissect_options *ndo, struct in6_addr *dst, * the header, in units of 8 octets, excluding * the first 8 octets. */ - ND_TCHECK2(*cp, 2); - advance = (int)((*(cp + 1) + 1) << 3); - nh = *cp; + advance = (GET_U_1(cp + 1) + 1) << 3; + nh = GET_U_1(cp); break; case IPPROTO_FRAGMENT: @@ -87,9 +87,8 @@ ip6_finddst(netdissect_options *ndo, struct in6_addr *dst, * marked as reserved, and the header is always * the same size. */ - ND_TCHECK2(*cp, 1); advance = sizeof(struct ip6_frag); - nh = *cp; + nh = GET_U_1(cp); break; case IPPROTO_ROUTING: @@ -97,9 +96,9 @@ ip6_finddst(netdissect_options *ndo, struct in6_addr *dst, * OK, we found it. */ dp = (const struct ip6_rthdr *)cp; - ND_TCHECK(*dp); - len = dp->ip6r_len; - switch (dp->ip6r_type) { + ND_TCHECK_SIZE(dp); + len = GET_U_1(dp->ip6r_len); + switch (GET_U_1(dp->ip6r_type)) { case IPV6_RTHDR_TYPE_0: case IPV6_RTHDR_TYPE_2: /* Mobile IPv6 ID-20 */ @@ -107,15 +106,26 @@ ip6_finddst(netdissect_options *ndo, struct in6_addr *dst, if (len % 2 == 1) goto trunc; len >>= 1; - addr = &dp0->ip6r0_addr[0]; + p = (const u_char *) dp0->ip6r0_addr; for (i = 0; i < len; i++) { - if ((const u_char *)(addr + 1) > ndo->ndo_snapend) - goto trunc; - - dst_addr = addr; - addr++; + ND_TCHECK_16(p); + dst_addr = (const void *)p; + p += 16; } break; + case IPV6_RTHDR_TYPE_4: + /* IPv6 Segment Routing Header (SRH) */ + srh = (const struct ip6_srh *)dp; + if (len % 2 == 1) + goto trunc; + p = (const u_char *) srh->srh_segments; + /* + * The list of segments are encoded in the reverse order. + * Accordingly, the final DA is encoded in srh_segments[0] + */ + ND_TCHECK_16(p); + dst_addr = (const void *)p; + break; default: break; @@ -153,30 +163,32 @@ ip6_finddst(netdissect_options *ndo, struct in6_addr *dst, done: trunc: - UNALIGNED_MEMCPY(dst, dst_addr, sizeof(struct in6_addr)); + GET_CPY_BYTES(dst, dst_addr, sizeof(nd_ipv6)); } /* * Compute a V6-style checksum by building a pseudoheader. */ -int +uint16_t nextproto6_cksum(netdissect_options *ndo, const struct ip6_hdr *ip6, const uint8_t *data, - u_int len, u_int covlen, u_int next_proto) + u_int len, u_int covlen, uint8_t next_proto) { struct { - struct in6_addr ph_src; - struct in6_addr ph_dst; + nd_ipv6 ph_src; + nd_ipv6 ph_dst; uint32_t ph_len; uint8_t ph_zero[3]; uint8_t ph_nxt; } ph; struct cksum_vec vec[2]; + u_int nh; /* pseudo-header */ memset(&ph, 0, sizeof(ph)); - UNALIGNED_MEMCPY(&ph.ph_src, &ip6->ip6_src, sizeof (struct in6_addr)); - switch (ip6->ip6_nxt) { + GET_CPY_BYTES(&ph.ph_src, ip6->ip6_src, sizeof(nd_ipv6)); + nh = GET_U_1(ip6->ip6_nxt); + switch (nh) { case IPPROTO_HOPOPTS: case IPPROTO_DSTOPTS: @@ -193,7 +205,7 @@ nextproto6_cksum(netdissect_options *ndo, break; default: - UNALIGNED_MEMCPY(&ph.ph_dst, &ip6->ip6_dst, sizeof (struct in6_addr)); + GET_CPY_BYTES(&ph.ph_dst, ip6->ip6_dst, sizeof(nd_ipv6)); break; } ph.ph_len = htonl(len); @@ -213,103 +225,146 @@ nextproto6_cksum(netdissect_options *ndo, void ip6_print(netdissect_options *ndo, const u_char *bp, u_int length) { - register const struct ip6_hdr *ip6; - register int advance; + const struct ip6_hdr *ip6; + int advance; u_int len; - const u_char *ipend; - register const u_char *cp; - register u_int payload_len; - int nh; + u_int total_advance; + const u_char *cp; + uint32_t payload_len; + uint8_t nh; int fragmented = 0; u_int flow; + int found_extension_header; + int found_jumbo; + ndo->ndo_protocol = "ip6"; ip6 = (const struct ip6_hdr *)bp; - ND_TCHECK(*ip6); + ND_TCHECK_SIZE(ip6); if (length < sizeof (struct ip6_hdr)) { - ND_PRINT((ndo, "truncated-ip6 %u", length)); + ND_PRINT("truncated-ip6 %u", length); return; } if (!ndo->ndo_eflag) - ND_PRINT((ndo, "IP6 ")); + ND_PRINT("IP6 "); if (IP6_VERSION(ip6) != 6) { - ND_PRINT((ndo,"version error: %u != 6", IP6_VERSION(ip6))); + ND_PRINT("version error: %u != 6", IP6_VERSION(ip6)); return; } - payload_len = EXTRACT_16BITS(&ip6->ip6_plen); - len = payload_len + sizeof(struct ip6_hdr); - if (length < len) - ND_PRINT((ndo, "truncated-ip6 - %u bytes missing!", - len - length)); - + payload_len = GET_BE_U_2(ip6->ip6_plen); + /* + * RFC 1883 says: + * + * The Payload Length field in the IPv6 header must be set to zero + * in every packet that carries the Jumbo Payload option. If a + * packet is received with a valid Jumbo Payload option present and + * a non-zero IPv6 Payload Length field, an ICMP Parameter Problem + * message, Code 0, should be sent to the packet's source, pointing + * to the Option Type field of the Jumbo Payload option. + * + * Later versions of the IPv6 spec don't discuss the Jumbo Payload + * option. + * + * If the payload length is 0, we temporarily just set the total + * length to the remaining data in the packet (which, for Ethernet, + * could include frame padding, but if it's a Jumbo Payload frame, + * it shouldn't even be sendable over Ethernet, so we don't worry + * about that), so we can process the extension headers in order + * to *find* a Jumbo Payload hop-by-hop option and, when we've + * processed all the extension headers, check whether we found + * a Jumbo Payload option, and fail if we haven't. + */ + if (payload_len != 0) { + len = payload_len + sizeof(struct ip6_hdr); + if (length < len) + ND_PRINT("truncated-ip6 - %u bytes missing!", + len - length); + } else + len = length + sizeof(struct ip6_hdr); + + nh = GET_U_1(ip6->ip6_nxt); if (ndo->ndo_vflag) { - flow = EXTRACT_32BITS(&ip6->ip6_flow); - ND_PRINT((ndo, "(")); + flow = GET_BE_U_4(ip6->ip6_flow); + ND_PRINT("("); #if 0 /* rfc1883 */ if (flow & 0x0f000000) - ND_PRINT((ndo, "pri 0x%02x, ", (flow & 0x0f000000) >> 24)); + ND_PRINT("pri 0x%02x, ", (flow & 0x0f000000) >> 24); if (flow & 0x00ffffff) - ND_PRINT((ndo, "flowlabel 0x%06x, ", flow & 0x00ffffff)); + ND_PRINT("flowlabel 0x%06x, ", flow & 0x00ffffff); #else /* RFC 2460 */ if (flow & 0x0ff00000) - ND_PRINT((ndo, "class 0x%02x, ", (flow & 0x0ff00000) >> 20)); + ND_PRINT("class 0x%02x, ", (flow & 0x0ff00000) >> 20); if (flow & 0x000fffff) - ND_PRINT((ndo, "flowlabel 0x%05x, ", flow & 0x000fffff)); + ND_PRINT("flowlabel 0x%05x, ", flow & 0x000fffff); #endif - 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)); + ND_PRINT("hlim %u, next-header %s (%u) payload length: %u) ", + GET_U_1(ip6->ip6_hlim), + tok2str(ipproto_values,"unknown",nh), + nh, + payload_len); } /* * Cut off the snapshot length to the end of the IP payload. */ - ipend = bp + len; - if (ipend < ndo->ndo_snapend) - ndo->ndo_snapend = ipend; + nd_push_snapend(ndo, bp + len); cp = (const u_char *)ip6; advance = sizeof(struct ip6_hdr); - nh = ip6->ip6_nxt; + total_advance = 0; + /* Process extension headers */ + found_extension_header = 0; + found_jumbo = 0; while (cp < ndo->ndo_snapend && advance > 0) { if (len < (u_int)advance) goto trunc; cp += advance; len -= advance; + total_advance += advance; if (cp == (const u_char *)(ip6 + 1) && nh != IPPROTO_TCP && nh != IPPROTO_UDP && nh != IPPROTO_DCCP && nh != IPPROTO_SCTP) { - ND_PRINT((ndo, "%s > %s: ", ip6addr_string(ndo, &ip6->ip6_src), - ip6addr_string(ndo, &ip6->ip6_dst))); + ND_PRINT("%s > %s: ", GET_IP6ADDR_STRING(ip6->ip6_src), + GET_IP6ADDR_STRING(ip6->ip6_dst)); } switch (nh) { + case IPPROTO_HOPOPTS: - advance = hbhopt_print(ndo, cp); - if (advance < 0) + advance = hbhopt_process(ndo, cp, &found_jumbo, &payload_len); + if (advance < 0) { + nd_pop_packet_info(ndo); return; - nh = *cp; + } + found_extension_header = 1; + nh = GET_U_1(cp); break; + case IPPROTO_DSTOPTS: - advance = dstopt_print(ndo, cp); - if (advance < 0) + advance = dstopt_process(ndo, cp); + if (advance < 0) { + nd_pop_packet_info(ndo); return; - nh = *cp; + } + found_extension_header = 1; + nh = GET_U_1(cp); break; + case IPPROTO_FRAGMENT: advance = frag6_print(ndo, cp, (const u_char *)ip6); - if (advance < 0 || ndo->ndo_snapend <= cp + advance) + if (advance < 0 || ndo->ndo_snapend <= cp + advance) { + nd_pop_packet_info(ndo); return; - nh = *cp; + } + found_extension_header = 1; + nh = GET_U_1(cp); fragmented = 1; break; @@ -319,105 +374,110 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length) * XXX - we don't use "advance"; RFC 3775 says that * the next header field in a mobility header * should be IPPROTO_NONE, but speaks of - * the possiblity of a future extension in + * the possibility of a future extension in * which payload can be piggybacked atop a * mobility header. */ advance = mobility_print(ndo, cp, (const u_char *)ip6); - if (advance < 0) + if (advance < 0) { + nd_pop_packet_info(ndo); return; - nh = *cp; + } + found_extension_header = 1; + nh = GET_U_1(cp); + nd_pop_packet_info(ndo); return; + case IPPROTO_ROUTING: - ND_TCHECK(*cp); + ND_TCHECK_1(cp); advance = rt6_print(ndo, cp, (const u_char *)ip6); - if (advance < 0) - return; - nh = *cp; - break; - case IPPROTO_SCTP: - sctp_print(ndo, cp, (const u_char *)ip6, len); - return; - case IPPROTO_DCCP: - dccp_print(ndo, cp, (const u_char *)ip6, len); - return; - case IPPROTO_TCP: - tcp_print(ndo, cp, len, (const u_char *)ip6, fragmented); - return; - case IPPROTO_UDP: - udp_print(ndo, cp, len, (const u_char *)ip6, fragmented); - return; - case IPPROTO_ICMPV6: - icmp6_print(ndo, cp, len, (const u_char *)ip6, fragmented); - return; - case IPPROTO_AH: - advance = ah_print(ndo, cp); - if (advance < 0) - return; - nh = *cp; - break; - case IPPROTO_ESP: - { - int enh, padlen; - advance = esp_print(ndo, cp, len, (const u_char *)ip6, &enh, &padlen); - if (advance < 0) + if (advance < 0) { + nd_pop_packet_info(ndo); return; - nh = enh & 0xff; - len -= padlen; + } + found_extension_header = 1; + nh = GET_U_1(cp); break; - } - case IPPROTO_IPCOMP: - { - ipcomp_print(ndo, cp); + + default: /* - * Either this has decompressed the payload and - * printed it, in which case there's nothing more - * to do, or it hasn't, in which case there's - * nothing more to do. + * Not an extension header; hand off to the + * IP protocol demuxer. */ - advance = -1; - break; - } - - case IPPROTO_PIM: - pim_print(ndo, cp, len, (const u_char *)ip6); - return; - - case IPPROTO_OSPF: - ospf6_print(ndo, cp, len); - return; - - case IPPROTO_IPV6: - ip6_print(ndo, cp, len); - return; - - case IPPROTO_IPV4: - ip_print(ndo, cp, len); - return; - - case IPPROTO_PGM: - pgm_print(ndo, cp, len, (const u_char *)ip6); - return; - - case IPPROTO_GRE: - gre_print(ndo, cp, len); - return; - - case IPPROTO_RSVP: - rsvp_print(ndo, cp, len); - return; - - case IPPROTO_NONE: - ND_PRINT((ndo, "no next header")); - return; + if (found_jumbo) { + /* + * We saw a Jumbo Payload option. + * Set the length to the payload length + * plus the IPv6 header length, and + * change the snapshot length accordingly. + * + * But make sure it's not shorter than + * the total number of bytes we've + * processed so far. + */ + len = payload_len + sizeof(struct ip6_hdr); + if (len < total_advance) + goto trunc; + if (length < len) + ND_PRINT("truncated-ip6 - %u bytes missing!", + len - length); + nd_change_snapend(ndo, bp + len); + + /* + * Now subtract the length of the IPv6 + * header plus extension headers to get + * the payload length. + */ + len -= total_advance; + } else { + /* + * We didn't see a Jumbo Payload option; + * was the payload length zero? + */ + if (payload_len == 0) { + /* + * Yes. If we found an extension + * header, treat that as a truncated + * packet header, as there was + * no payload to contain an + * extension header. + */ + if (found_extension_header) + goto trunc; - default: - ND_PRINT((ndo, "ip-proto-%d %d", nh, len)); + /* + * OK, we didn't see any extnesion + * header, but that means we have + * no payload, so set the length + * to the IPv6 header length, + * and change the snapshot length + * accordingly. + */ + len = sizeof(struct ip6_hdr); + nd_change_snapend(ndo, bp + len); + + /* + * Now subtract the length of + * the IPv6 header plus extension + * headers (there weren't any, so + * that's just the IPv6 header + * length) to get the payload length. + */ + len -= total_advance; + } + } + ip_demux_print(ndo, cp, len, 6, fragmented, + GET_U_1(ip6->ip6_hlim), nh, bp); + nd_pop_packet_info(ndo); return; } + + /* ndo_protocol reassignment after xxx_print() calls */ + ndo->ndo_protocol = "ip6"; } + nd_pop_packet_info(ndo); return; trunc: - ND_PRINT((ndo, "[|ip6]")); + nd_print_trunc(ndo); } diff --git a/contrib/tcpdump/print-ip6opts.c b/contrib/tcpdump/print-ip6opts.c index 14768deb37..a78c76daa2 100644 --- a/contrib/tcpdump/print-ip6opts.c +++ b/contrib/tcpdump/print-ip6opts.c @@ -30,10 +30,10 @@ /* \summary: IPv6 header option printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "addrtoname.h" @@ -41,173 +41,225 @@ #include "ip6.h" -static void +static int ip6_sopt_print(netdissect_options *ndo, const u_char *bp, int len) { int i; int optlen; for (i = 0; i < len; i += optlen) { - if (bp[i] == IP6OPT_PAD1) + if (GET_U_1(bp + i) == IP6OPT_PAD1) optlen = 1; else { if (i + 1 < len) - optlen = bp[i + 1] + 2; + optlen = GET_U_1(bp + i + 1) + 2; else goto trunc; } if (i + optlen > len) goto trunc; - switch (bp[i]) { + switch (GET_U_1(bp + i)) { case IP6OPT_PAD1: - ND_PRINT((ndo, ", pad1")); + ND_PRINT(", pad1"); break; case IP6OPT_PADN: if (len - i < IP6OPT_MINLEN) { - ND_PRINT((ndo, ", padn: trunc")); + ND_PRINT(", padn: trunc"); goto trunc; } - ND_PRINT((ndo, ", padn")); + ND_PRINT(", padn"); break; default: if (len - i < IP6OPT_MINLEN) { - ND_PRINT((ndo, ", sopt_type %d: trunc)", bp[i])); + ND_PRINT(", sopt_type %u: trunc)", GET_U_1(bp + i)); goto trunc; } - ND_PRINT((ndo, ", sopt_type 0x%02x: len=%d", bp[i], bp[i + 1])); + ND_PRINT(", sopt_type 0x%02x: len=%u", GET_U_1(bp + i), + GET_U_1(bp + i + 1)); break; } } - return; + return 0; trunc: - ND_PRINT((ndo, "[trunc] ")); + return -1; } -static void -ip6_opt_print(netdissect_options *ndo, const u_char *bp, int len) +static int +ip6_opt_process(netdissect_options *ndo, const u_char *bp, int len, + int *found_jumbop, uint32_t *payload_len) { int i; int optlen = 0; + int found_jumbo = 0; + uint32_t jumbolen = 0; if (len == 0) - return; + return 0; for (i = 0; i < len; i += optlen) { - if (bp[i] == IP6OPT_PAD1) + if (GET_U_1(bp + i) == IP6OPT_PAD1) optlen = 1; else { if (i + 1 < len) - optlen = bp[i + 1] + 2; + optlen = GET_U_1(bp + i + 1) + 2; else goto trunc; } if (i + optlen > len) goto trunc; - switch (bp[i]) { + switch (GET_U_1(bp + i)) { case IP6OPT_PAD1: - ND_PRINT((ndo, "(pad1)")); + if (ndo->ndo_vflag) + ND_PRINT("(pad1)"); break; case IP6OPT_PADN: if (len - i < IP6OPT_MINLEN) { - ND_PRINT((ndo, "(padn: trunc)")); + ND_PRINT("(padn: trunc)"); goto trunc; } - ND_PRINT((ndo, "(padn)")); + if (ndo->ndo_vflag) + ND_PRINT("(padn)"); break; case IP6OPT_ROUTER_ALERT: if (len - i < IP6OPT_RTALERT_LEN) { - ND_PRINT((ndo, "(rtalert: trunc)")); + ND_PRINT("(rtalert: trunc)"); goto trunc; } - if (bp[i + 1] != IP6OPT_RTALERT_LEN - 2) { - ND_PRINT((ndo, "(rtalert: invalid len %d)", bp[i + 1])); + if (GET_U_1(bp + i + 1) != IP6OPT_RTALERT_LEN - 2) { + ND_PRINT("(rtalert: invalid len %u)", GET_U_1(bp + i + 1)); goto trunc; } - ND_PRINT((ndo, "(rtalert: 0x%04x) ", EXTRACT_16BITS(&bp[i + 2]))); + if (ndo->ndo_vflag) + ND_PRINT("(rtalert: 0x%04x) ", GET_BE_U_2(bp + i + 2)); break; case IP6OPT_JUMBO: if (len - i < IP6OPT_JUMBO_LEN) { - ND_PRINT((ndo, "(jumbo: trunc)")); + ND_PRINT("(jumbo: trunc)"); goto trunc; } - if (bp[i + 1] != IP6OPT_JUMBO_LEN - 2) { - ND_PRINT((ndo, "(jumbo: invalid len %d)", bp[i + 1])); + if (GET_U_1(bp + i + 1) != IP6OPT_JUMBO_LEN - 2) { + ND_PRINT("(jumbo: invalid len %u)", GET_U_1(bp + i + 1)); goto trunc; } - ND_PRINT((ndo, "(jumbo: %u) ", EXTRACT_32BITS(&bp[i + 2]))); + jumbolen = GET_BE_U_4(bp + i + 2); + if (found_jumbo) { + /* More than one Jumbo Payload option */ + if (ndo->ndo_vflag) + ND_PRINT("(jumbo: %u - already seen) ", jumbolen); + } else { + found_jumbo = 1; + if (payload_len == NULL) { + /* Not a hop-by-hop option - not valid */ + if (ndo->ndo_vflag) + ND_PRINT("(jumbo: %u - not a hop-by-hop option) ", jumbolen); + } else if (*payload_len != 0) { + /* Payload length was non-zero - not valid */ + if (ndo->ndo_vflag) + ND_PRINT("(jumbo: %u - payload len != 0) ", jumbolen); + } else { + /* + * This is a hop-by-hop option, and Payload length + * was zero in the IPv6 header. + */ + if (jumbolen < 65536) { + /* Too short */ + if (ndo->ndo_vflag) + ND_PRINT("(jumbo: %u - < 65536) ", jumbolen); + } else { + /* OK, this is valid */ + *found_jumbop = 1; + *payload_len = jumbolen; + if (ndo->ndo_vflag) + ND_PRINT("(jumbo: %u) ", jumbolen); + } + } + } break; case IP6OPT_HOME_ADDRESS: if (len - i < IP6OPT_HOMEADDR_MINLEN) { - ND_PRINT((ndo, "(homeaddr: trunc)")); + ND_PRINT("(homeaddr: trunc)"); goto trunc; } - if (bp[i + 1] < IP6OPT_HOMEADDR_MINLEN - 2) { - ND_PRINT((ndo, "(homeaddr: invalid len %d)", bp[i + 1])); + if (GET_U_1(bp + i + 1) < IP6OPT_HOMEADDR_MINLEN - 2) { + ND_PRINT("(homeaddr: invalid len %u)", GET_U_1(bp + i + 1)); goto trunc; } - ND_PRINT((ndo, "(homeaddr: %s", ip6addr_string(ndo, &bp[i + 2]))); - if (bp[i + 1] > IP6OPT_HOMEADDR_MINLEN - 2) { - ip6_sopt_print(ndo, &bp[i + IP6OPT_HOMEADDR_MINLEN], - (optlen - IP6OPT_HOMEADDR_MINLEN)); + if (ndo->ndo_vflag) { + ND_PRINT("(homeaddr: %s", GET_IP6ADDR_STRING(bp + i + 2)); + if (GET_U_1(bp + i + 1) > IP6OPT_HOMEADDR_MINLEN - 2) { + if (ip6_sopt_print(ndo, bp + i + IP6OPT_HOMEADDR_MINLEN, + (optlen - IP6OPT_HOMEADDR_MINLEN)) == -1) + goto trunc; + } + ND_PRINT(")"); } - ND_PRINT((ndo, ")")); break; default: if (len - i < IP6OPT_MINLEN) { - ND_PRINT((ndo, "(type %d: trunc)", bp[i])); + ND_PRINT("(type %u: trunc)", GET_U_1(bp + i)); goto trunc; } - ND_PRINT((ndo, "(opt_type 0x%02x: len=%d)", bp[i], bp[i + 1])); + if (ndo->ndo_vflag) + ND_PRINT("(opt_type 0x%02x: len=%u)", GET_U_1(bp + i), + GET_U_1(bp + i + 1)); break; } } - ND_PRINT((ndo, " ")); - return; + if (ndo->ndo_vflag) + ND_PRINT(" "); + return 0; trunc: - ND_PRINT((ndo, "[trunc] ")); + return -1; } int -hbhopt_print(netdissect_options *ndo, register const u_char *bp) +hbhopt_process(netdissect_options *ndo, const u_char *bp, int *found_jumbo, + uint32_t *jumbolen) { const struct ip6_hbh *dp = (const struct ip6_hbh *)bp; - int hbhlen = 0; - - ND_TCHECK(dp->ip6h_len); - hbhlen = (int)((dp->ip6h_len + 1) << 3); - ND_TCHECK2(*dp, hbhlen); - ND_PRINT((ndo, "HBH ")); - if (ndo->ndo_vflag) - ip6_opt_print(ndo, (const u_char *)dp + sizeof(*dp), hbhlen - sizeof(*dp)); + u_int hbhlen = 0; - return(hbhlen); + ndo->ndo_protocol = "hbhopt"; + hbhlen = (GET_U_1(dp->ip6h_len) + 1) << 3; + ND_TCHECK_LEN(dp, hbhlen); + ND_PRINT("HBH "); + if (ip6_opt_process(ndo, (const u_char *)dp + sizeof(*dp), + hbhlen - sizeof(*dp), found_jumbo, jumbolen) == -1) + goto trunc; + return hbhlen; - trunc: - ND_PRINT((ndo, "[|HBH]")); - return(-1); +trunc: + nd_print_trunc(ndo); + return -1; } int -dstopt_print(netdissect_options *ndo, register const u_char *bp) +dstopt_process(netdissect_options *ndo, const u_char *bp) { const struct ip6_dest *dp = (const struct ip6_dest *)bp; - int dstoptlen = 0; + u_int dstoptlen = 0; - ND_TCHECK(dp->ip6d_len); - dstoptlen = (int)((dp->ip6d_len + 1) << 3); - ND_TCHECK2(*dp, dstoptlen); - ND_PRINT((ndo, "DSTOPT ")); + ndo->ndo_protocol = "dstopt"; + dstoptlen = (GET_U_1(dp->ip6d_len) + 1) << 3; + ND_TCHECK_LEN(dp, dstoptlen); + ND_PRINT("DSTOPT "); if (ndo->ndo_vflag) { - ip6_opt_print(ndo, (const u_char *)dp + sizeof(*dp), - dstoptlen - sizeof(*dp)); + /* + * The Jumbo Payload option is a hop-by-hop option; we don't + * honor Jumbo Payload destination options, reporting them + * as invalid. + */ + if (ip6_opt_process(ndo, (const u_char *)dp + sizeof(*dp), + dstoptlen - sizeof(*dp), NULL, NULL) == -1) + goto trunc; } - return(dstoptlen); + return dstoptlen; - trunc: - ND_PRINT((ndo, "[|DSTOPT]")); - return(-1); +trunc: + nd_print_trunc(ndo); + return -1; } diff --git a/contrib/tcpdump/print-ipcomp.c b/contrib/tcpdump/print-ipcomp.c index 291caa97d8..c0c184ddc8 100644 --- a/contrib/tcpdump/print-ipcomp.c +++ b/contrib/tcpdump/print-ipcomp.c @@ -22,31 +22,31 @@ /* \summary: IP Payload Compression Protocol (IPComp) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include - -struct ipcomp { - uint8_t comp_nxt; /* Next Header */ - uint8_t comp_flags; /* Length of data, in 32bit */ - uint16_t comp_cpi; /* Compression parameter index */ -}; +#include "netdissect-stdinc.h" #include "netdissect.h" #include "extract.h" +struct ipcomp { + nd_uint8_t comp_nxt; /* Next Header */ + nd_uint8_t comp_flags; /* Length of data, in 32bit */ + nd_uint16_t comp_cpi; /* Compression parameter index */ +}; + void -ipcomp_print(netdissect_options *ndo, register const u_char *bp) +ipcomp_print(netdissect_options *ndo, const u_char *bp) { - register const struct ipcomp *ipcomp; + const struct ipcomp *ipcomp; uint16_t cpi; + ndo->ndo_protocol = "ipcomp"; ipcomp = (const struct ipcomp *)bp; - ND_TCHECK(*ipcomp); - cpi = EXTRACT_16BITS(&ipcomp->comp_cpi); + cpi = GET_BE_U_2(ipcomp->comp_cpi); - ND_PRINT((ndo, "IPComp(cpi=0x%04x)", cpi)); + ND_PRINT("IPComp(cpi=0x%04x)", cpi); /* * XXX - based on the CPI, we could decompress the packet here. @@ -61,9 +61,4 @@ ipcomp_print(netdissect_options *ndo, register const u_char *bp) * stops - there's nothing more it can do with a compressed * payload. */ - return; - -trunc: - ND_PRINT((ndo, "[|IPCOMP]")); - return; } diff --git a/contrib/tcpdump/print-ipfc.c b/contrib/tcpdump/print-ipfc.c index b8a08e9626..ab5a81312f 100644 --- a/contrib/tcpdump/print-ipfc.c +++ b/contrib/tcpdump/print-ipfc.c @@ -24,46 +24,45 @@ /* specification: RFC 2625 */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "addrtoname.h" -#include "ether.h" struct ipfc_header { - u_char ipfc_dhost[8]; - u_char ipfc_shost[8]; + nd_byte ipfc_dhost[2+MAC_ADDR_LEN]; + nd_byte ipfc_shost[2+MAC_ADDR_LEN]; }; #define IPFC_HDRLEN 16 /* Extract src, dst addresses */ -static inline void +static void extract_ipfc_addrs(const struct ipfc_header *ipfcp, char *ipfcsrc, - char *ipfcdst) + char *ipfcdst) { /* * We assume that, as per RFC 2625, the lower 48 bits of the * source and destination addresses are MAC addresses. */ - memcpy(ipfcdst, (const char *)&ipfcp->ipfc_dhost[2], 6); - memcpy(ipfcsrc, (const char *)&ipfcp->ipfc_shost[2], 6); + memcpy(ipfcdst, (const char *)&ipfcp->ipfc_dhost[2], MAC_ADDR_LEN); + memcpy(ipfcsrc, (const char *)&ipfcp->ipfc_shost[2], MAC_ADDR_LEN); } /* * Print the Network_Header */ -static inline void +static void ipfc_hdr_print(netdissect_options *ndo, - register const struct ipfc_header *ipfcp _U_, - register u_int length, register const u_char *ipfcsrc, - register const u_char *ipfcdst) + const struct ipfc_header *ipfcp _U_, u_int length, + const u_char *ipfcsrc, const u_char *ipfcdst) { const char *srcname, *dstname; @@ -85,32 +84,30 @@ ipfc_hdr_print(netdissect_options *ndo, * so, for captures following this specification, the upper 16 * bits should be 0x1000, followed by a MAC address. */ - ND_PRINT((ndo, "%s > %s, length %u: ", srcname, dstname, length)); + ND_PRINT("%s > %s, length %u: ", srcname, dstname, length); } static u_int ipfc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen) { const struct ipfc_header *ipfcp = (const struct ipfc_header *)p; - struct ether_header ehdr; + nd_mac_addr srcmac, dstmac; struct lladdr_info src, dst; int llc_hdrlen; - if (caplen < IPFC_HDRLEN) { - ND_PRINT((ndo, "[|ipfc]")); - return (caplen); - } + ndo->ndo_protocol = "ipfc"; + ND_TCHECK_LEN(p, IPFC_HDRLEN); /* * Get the network addresses into a canonical form */ - extract_ipfc_addrs(ipfcp, (char *)ESRC(&ehdr), (char *)EDST(&ehdr)); + extract_ipfc_addrs(ipfcp, (char *)srcmac, (char *)dstmac); if (ndo->ndo_eflag) - ipfc_hdr_print(ndo, ipfcp, length, ESRC(&ehdr), EDST(&ehdr)); + ipfc_hdr_print(ndo, ipfcp, length, srcmac, dstmac); - src.addr = ESRC(&ehdr); + src.addr = srcmac; src.addr_string = etheraddr_string; - dst.addr = EDST(&ehdr); + dst.addr = dstmac; dst.addr_string = etheraddr_string; /* Skip over Network_Header */ @@ -138,8 +135,9 @@ ipfc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen) * 'h->len' is the length of the packet off the wire, and 'h->caplen' * is the number of bytes actually captured. */ -u_int -ipfc_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, register const u_char *p) +void +ipfc_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { - return (ipfc_print(ndo, p, h->len, h->caplen)); + ndo->ndo_protocol = "ipfc"; + ndo->ndo_ll_hdr_len += ipfc_print(ndo, p, h->len, h->caplen); } diff --git a/contrib/tcpdump/print-ipnet.c b/contrib/tcpdump/print-ipnet.c index 89b0ffca03..eddcc1d754 100644 --- a/contrib/tcpdump/print-ipnet.c +++ b/contrib/tcpdump/print-ipnet.c @@ -1,15 +1,15 @@ /* \summary: Solaris DLT_IPNET printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" -static const char tstr[] = "[|ipnet]"; typedef struct ipnet_hdr { nd_uint8_t iph_version; @@ -33,32 +33,28 @@ static const struct tok ipnet_values[] = { { 0, NULL } }; -static inline void +static void ipnet_hdr_print(netdissect_options *ndo, const u_char *bp, u_int length) { const ipnet_hdr_t *hdr; hdr = (const ipnet_hdr_t *)bp; - ND_TCHECK(*hdr); - ND_PRINT((ndo, "%d > %d", EXTRACT_32BITS(hdr->iph_zsrc), - EXTRACT_32BITS(hdr->iph_zdst))); + ND_PRINT("%u > %u", GET_BE_U_4(hdr->iph_zsrc), + GET_BE_U_4(hdr->iph_zdst)); if (!ndo->ndo_qflag) { - ND_PRINT((ndo,", family %s (%d)", + ND_PRINT(", family %s (%u)", tok2str(ipnet_values, "Unknown", - EXTRACT_8BITS(&hdr->iph_family)), - EXTRACT_8BITS(&hdr->iph_family))); + GET_U_1(hdr->iph_family)), + GET_U_1(hdr->iph_family)); } else { - ND_PRINT((ndo,", %s", + ND_PRINT(", %s", tok2str(ipnet_values, "Unknown Ethertype (0x%04x)", - EXTRACT_8BITS(&hdr->iph_family)))); + GET_U_1(hdr->iph_family))); } - ND_PRINT((ndo, ", length %u: ", length)); - return; -trunc: - ND_PRINT((ndo, " %s", tstr)); + ND_PRINT(", length %u: ", length); } static void @@ -66,8 +62,8 @@ ipnet_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen { const ipnet_hdr_t *hdr; - if (caplen < sizeof(ipnet_hdr_t)) - goto trunc; + ND_TCHECK_LEN(p, sizeof(ipnet_hdr_t)); + ndo->ndo_ll_hdr_len += sizeof(ipnet_hdr_t); if (ndo->ndo_eflag) ipnet_hdr_print(ndo, p, length); @@ -77,8 +73,7 @@ ipnet_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen hdr = (const ipnet_hdr_t *)p; p += sizeof(ipnet_hdr_t); - ND_TCHECK2(hdr->iph_family, 1); - switch (EXTRACT_8BITS(&hdr->iph_family)) { + switch (GET_U_1(hdr->iph_family)) { case IPH_AF_INET: ip_print(ndo, p, length); @@ -97,9 +92,6 @@ ipnet_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen ND_DEFAULTPRINT(p, caplen); break; } - return; -trunc: - ND_PRINT((ndo, " %s", tstr)); } /* @@ -108,20 +100,11 @@ trunc: * 'h->len' is the length of the packet off the wire, and 'h->caplen' * is the number of bytes actually captured. */ -u_int +void ipnet_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { + ndo->ndo_protocol = "ipnet"; 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-ipoib.c b/contrib/tcpdump/print-ipoib.c new file mode 100644 index 0000000000..3d43123505 --- /dev/null +++ b/contrib/tcpdump/print-ipoib.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, + * 1997, 2000, 2011, 2012 + * 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. + */ +/* + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. + */ + +/* \summary: IP-over-InfiniBand (IPoIB) printer */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "netdissect-stdinc.h" + +#include "netdissect.h" +#include "extract.h" +#include "addrtoname.h" + + +extern const struct tok ethertype_values[]; + +#define IPOIB_HDRLEN 44 + +static inline void +ipoib_hdr_print(netdissect_options *ndo, const u_char *bp, u_int length) +{ + uint16_t ether_type; + + ether_type = GET_BE_U_2(bp + 40); + if (!ndo->ndo_qflag) { + ND_PRINT(", ethertype %s (0x%04x)", + tok2str(ethertype_values,"Unknown", ether_type), + ether_type); + } else { + ND_PRINT(", ethertype %s", + tok2str(ethertype_values,"Unknown", ether_type)); + } + + ND_PRINT(", length %u: ", length); +} + +/* + * Print an InfiniBand 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. + */ +static void +ipoib_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, + void (*print_encap_header)(const u_char *), const u_char *encap_header_arg) +{ + const u_char *orig_hdr = p; + u_int orig_length; + u_short ether_type; + + if (caplen < IPOIB_HDRLEN) { + nd_print_trunc(ndo); + ndo->ndo_ll_hdr_len += caplen; + return; + } + + if (length < IPOIB_HDRLEN) { + nd_print_trunc(ndo); + ndo->ndo_ll_hdr_len += length; + return; + } + + if (ndo->ndo_eflag) { + nd_print_protocol_caps(ndo); + if (print_encap_header != NULL) + (*print_encap_header)(encap_header_arg); + ipoib_hdr_print(ndo, p, length); + } + orig_length = length; + + ndo->ndo_ll_hdr_len += IPOIB_HDRLEN; + length -= IPOIB_HDRLEN; + caplen -= IPOIB_HDRLEN; + ether_type = GET_BE_U_2(p + 40); + p += IPOIB_HDRLEN; + + if (ethertype_print(ndo, ether_type, p, length, caplen, NULL, NULL) == 0) { + /* ether_type not known, print raw packet */ + if (!ndo->ndo_eflag) { + if (print_encap_header != NULL) + (*print_encap_header)(encap_header_arg); + ipoib_hdr_print(ndo, orig_hdr , orig_length); + } + + if (!ndo->ndo_suppress_default_print) + ND_DEFAULTPRINT(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. + */ +void +ipoib_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) +{ + ndo->ndo_protocol = "ipoib"; + ipoib_print(ndo, p, h->len, h->caplen, NULL, NULL); +} diff --git a/contrib/tcpdump/print-ipx.c b/contrib/tcpdump/print-ipx.c index d807a66ea5..c16a867344 100644 --- a/contrib/tcpdump/print-ipx.c +++ b/contrib/tcpdump/print-ipx.c @@ -24,13 +24,14 @@ /* \summary: Novell IPX printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "addrtoname.h" #include "extract.h" @@ -46,24 +47,24 @@ /* IPX transport header */ struct ipxHdr { - uint16_t cksum; /* Checksum */ - uint16_t length; /* Length, in bytes, including header */ - uint8_t tCtl; /* Transport Control (i.e. hop count) */ - uint8_t pType; /* Packet Type (i.e. level 2 protocol) */ - uint16_t dstNet[2]; /* destination net */ - uint8_t dstNode[6]; /* destination node */ - uint16_t dstSkt; /* destination socket */ - uint16_t srcNet[2]; /* source net */ - uint8_t srcNode[6]; /* source node */ - uint16_t srcSkt; /* source socket */ + nd_uint16_t cksum; /* Checksum */ + nd_uint16_t length; /* Length, in bytes, including header */ + nd_uint8_t tCtl; /* Transport Control (i.e. hop count) */ + nd_uint8_t pType; /* Packet Type (i.e. level 2 protocol) */ + nd_uint32_t dstNet; /* destination net */ + nd_mac_addr dstNode; /* destination node */ + nd_uint16_t dstSkt; /* destination socket */ + nd_uint32_t srcNet; /* source net */ + nd_mac_addr srcNode; /* source node */ + nd_uint16_t srcSkt; /* source socket */ }; #define ipxSize 30 -static const char *ipxaddr_string(uint32_t, const u_char *); +static const char *ipxaddr_string(netdissect_options *, uint32_t, const u_char *); static void ipx_decode(netdissect_options *, const struct ipxHdr *, const u_char *, u_int); -static void ipx_sap_print(netdissect_options *, const u_short *, u_int); -static void ipx_rip_print(netdissect_options *, const u_short *, u_int); +static void ipx_sap_print(netdissect_options *, const u_char *, u_int); +static void ipx_rip_print(netdissect_options *, const u_char *, u_int); /* * Print IPX datagram packets. @@ -73,35 +74,38 @@ ipx_print(netdissect_options *ndo, const u_char *p, u_int length) { const struct ipxHdr *ipx = (const struct ipxHdr *)p; + ndo->ndo_protocol = "ipx"; if (!ndo->ndo_eflag) - ND_PRINT((ndo, "IPX ")); + ND_PRINT("IPX "); - ND_TCHECK(ipx->srcSkt); - ND_PRINT((ndo, "%s.%04x > ", - ipxaddr_string(EXTRACT_32BITS(ipx->srcNet), ipx->srcNode), - EXTRACT_16BITS(&ipx->srcSkt))); + ND_PRINT("%s.%04x > ", + ipxaddr_string(ndo, GET_BE_U_4(ipx->srcNet), ipx->srcNode), + GET_BE_U_2(ipx->srcSkt)); - ND_PRINT((ndo, "%s.%04x: ", - ipxaddr_string(EXTRACT_32BITS(ipx->dstNet), ipx->dstNode), - EXTRACT_16BITS(&ipx->dstSkt))); + ND_PRINT("%s.%04x: ", + ipxaddr_string(ndo, GET_BE_U_4(ipx->dstNet), ipx->dstNode), + GET_BE_U_2(ipx->dstSkt)); /* take length from ipx header */ - ND_TCHECK(ipx->length); - length = EXTRACT_16BITS(&ipx->length); + length = GET_BE_U_2(ipx->length); + if (length < ipxSize) { + ND_PRINT("[length %u < %u]", length, ipxSize); + nd_print_invalid(ndo); + return; + } ipx_decode(ndo, ipx, p + ipxSize, length - ipxSize); - return; -trunc: - ND_PRINT((ndo, "[|ipx %d]", length)); } static const char * -ipxaddr_string(uint32_t net, const u_char *node) +ipxaddr_string(netdissect_options *ndo, uint32_t net, const u_char *node) { static char line[256]; snprintf(line, sizeof(line), "%08x.%02x:%02x:%02x:%02x:%02x:%02x", - net, node[0], node[1], node[2], node[3], node[4], node[5]); + net, GET_U_1(node), GET_U_1(node + 1), + GET_U_1(node + 2), GET_U_1(node + 3), + GET_U_1(node + 4), GET_U_1(node + 5)); return line; } @@ -109,30 +113,30 @@ ipxaddr_string(uint32_t net, const u_char *node) static void ipx_decode(netdissect_options *ndo, const struct ipxHdr *ipx, const u_char *datap, u_int length) { - register u_short dstSkt; + u_short dstSkt; - dstSkt = EXTRACT_16BITS(&ipx->dstSkt); + dstSkt = GET_BE_U_2(ipx->dstSkt); switch (dstSkt) { case IPX_SKT_NCP: - ND_PRINT((ndo, "ipx-ncp %d", length)); + ND_PRINT("ipx-ncp %u", length); break; case IPX_SKT_SAP: - ipx_sap_print(ndo, (const u_short *)datap, length); + ipx_sap_print(ndo, datap, length); break; case IPX_SKT_RIP: - ipx_rip_print(ndo, (const u_short *)datap, length); + ipx_rip_print(ndo, datap, length); break; case IPX_SKT_NETBIOS: - ND_PRINT((ndo, "ipx-netbios %d", length)); + ND_PRINT("ipx-netbios %u", length); #ifdef ENABLE_SMB ipx_netbios_print(ndo, datap, length); #endif break; case IPX_SKT_DIAGNOSTICS: - ND_PRINT((ndo, "ipx-diags %d", length)); + ND_PRINT("ipx-diags %u", length); break; case IPX_SKT_NWLINK_DGM: - ND_PRINT((ndo, "ipx-nwlink-dgm %d", length)); + ND_PRINT("ipx-nwlink-dgm %u", length); #ifdef ENABLE_SMB ipx_netbios_print(ndo, datap, length); #endif @@ -141,98 +145,121 @@ ipx_decode(netdissect_options *ndo, const struct ipxHdr *ipx, const u_char *data eigrp_print(ndo, datap, length); break; default: - ND_PRINT((ndo, "ipx-#%x %d", dstSkt, length)); + ND_PRINT("ipx-#%x %u", dstSkt, length); break; } } static void -ipx_sap_print(netdissect_options *ndo, const u_short *ipx, u_int length) +ipx_sap_print(netdissect_options *ndo, const u_char *ipx, u_int length) { int command, i; - ND_TCHECK(ipx[0]); - command = EXTRACT_16BITS(ipx); - ipx++; + command = GET_BE_U_2(ipx); + ipx += 2; length -= 2; switch (command) { case 1: case 3: if (command == 1) - ND_PRINT((ndo, "ipx-sap-req")); + ND_PRINT("ipx-sap-req"); else - ND_PRINT((ndo, "ipx-sap-nearest-req")); + ND_PRINT("ipx-sap-nearest-req"); - ND_TCHECK(ipx[0]); - ND_PRINT((ndo, " %s", ipxsap_string(ndo, htons(EXTRACT_16BITS(&ipx[0]))))); + ND_PRINT(" %s", ipxsap_string(ndo, htons(GET_BE_U_2(ipx)))); break; case 2: case 4: if (command == 2) - ND_PRINT((ndo, "ipx-sap-resp")); + ND_PRINT("ipx-sap-resp"); else - ND_PRINT((ndo, "ipx-sap-nearest-resp")); - - for (i = 0; i < 8 && length > 0; i++) { - ND_TCHECK(ipx[0]); - ND_PRINT((ndo, " %s '", ipxsap_string(ndo, htons(EXTRACT_16BITS(&ipx[0]))))); - if (fn_printzp(ndo, (const u_char *)&ipx[1], 48, ndo->ndo_snapend)) { - ND_PRINT((ndo, "'")); - goto trunc; + ND_PRINT("ipx-sap-nearest-resp"); + + for (i = 0; i < 8 && length != 0; i++) { + ND_TCHECK_2(ipx); + if (length < 2) + goto invalid; + ND_PRINT(" %s '", ipxsap_string(ndo, htons(GET_BE_U_2(ipx)))); + ipx += 2; + length -= 2; + if (length < 48) { + ND_PRINT("'"); + goto invalid; } - ND_TCHECK2(ipx[25], 10); - ND_PRINT((ndo, "' addr %s", - ipxaddr_string(EXTRACT_32BITS(&ipx[25]), (const u_char *)&ipx[27]))); - ipx += 32; - length -= 64; + nd_printjnp(ndo, ipx, 48); + ND_PRINT("'"); + ipx += 48; + length -= 48; + /* + * 10 bytes of IPX address. + */ + ND_TCHECK_LEN(ipx, 10); + if (length < 10) + goto invalid; + ND_PRINT(" addr %s", + ipxaddr_string(ndo, GET_BE_U_4(ipx), ipx + 4)); + ipx += 10; + length -= 10; + /* + * 2 bytes of socket and 2 bytes of number of intermediate + * networks. + */ + ND_TCHECK_4(ipx); + if (length < 4) + goto invalid; + ipx += 4; + length -= 4; } break; default: - ND_PRINT((ndo, "ipx-sap-?%x", command)); + ND_PRINT("ipx-sap-?%x", command); break; } return; -trunc: - ND_PRINT((ndo, "[|ipx %d]", length)); + +invalid: + nd_print_invalid(ndo); } static void -ipx_rip_print(netdissect_options *ndo, const u_short *ipx, u_int length) +ipx_rip_print(netdissect_options *ndo, const u_char *ipx, u_int length) { int command, i; - ND_TCHECK(ipx[0]); - command = EXTRACT_16BITS(ipx); - ipx++; + command = GET_BE_U_2(ipx); + ipx += 2; length -= 2; switch (command) { case 1: - ND_PRINT((ndo, "ipx-rip-req")); - if (length > 0) { - ND_TCHECK(ipx[3]); - ND_PRINT((ndo, " %08x/%d.%d", EXTRACT_32BITS(&ipx[0]), - EXTRACT_16BITS(&ipx[2]), EXTRACT_16BITS(&ipx[3]))); + ND_PRINT("ipx-rip-req"); + if (length != 0) { + if (length < 8) + goto invalid; + ND_PRINT(" %08x/%u.%u", GET_BE_U_4(ipx), + GET_BE_U_2(ipx + 4), GET_BE_U_2(ipx + 6)); } break; case 2: - ND_PRINT((ndo, "ipx-rip-resp")); - for (i = 0; i < 50 && length > 0; i++) { - ND_TCHECK(ipx[3]); - ND_PRINT((ndo, " %08x/%d.%d", EXTRACT_32BITS(&ipx[0]), - EXTRACT_16BITS(&ipx[2]), EXTRACT_16BITS(&ipx[3]))); + ND_PRINT("ipx-rip-resp"); + for (i = 0; i < 50 && length != 0; i++) { + if (length < 8) + goto invalid; + ND_PRINT(" %08x/%u.%u", GET_BE_U_4(ipx), + GET_BE_U_2(ipx + 4), GET_BE_U_2(ipx + 6)); - ipx += 4; + ipx += 8; length -= 8; } break; default: - ND_PRINT((ndo, "ipx-rip-?%x", command)); + ND_PRINT("ipx-rip-?%x", command); break; } return; -trunc: - ND_PRINT((ndo, "[|ipx %d]", length)); + +invalid: + nd_print_invalid(ndo); } diff --git a/contrib/tcpdump/print-isakmp.c b/contrib/tcpdump/print-isakmp.c index 951c8a7415..52bf1fda52 100644 --- a/contrib/tcpdump/print-isakmp.c +++ b/contrib/tcpdump/print-isakmp.c @@ -30,8 +30,10 @@ /* \summary: Internet Security Association and Key Management Protocol (ISAKMP) printer */ +/* specification: RFC 2407, RFC 2408, RFC 5996 */ + #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif /* The functions from print-esp.c used in this file are only defined when both @@ -41,10 +43,12 @@ #undef HAVE_LIBCRYPTO #endif -#include +#include "netdissect-stdinc.h" #include +#include "netdissect-ctype.h" + #include "netdissect.h" #include "addrtoname.h" #include "extract.h" @@ -53,10 +57,8 @@ #include "ip6.h" #include "ipproto.h" -/* refer to RFC 2408 */ - -typedef u_char cookie_t[8]; -typedef u_char msgid_t[4]; +typedef nd_byte cookie_t[8]; +typedef nd_byte msgid_t[4]; #define PORT_ISAKMP 500 @@ -79,16 +81,16 @@ typedef u_char msgid_t[4]; struct isakmp { cookie_t i_ck; /* Initiator Cookie */ cookie_t r_ck; /* Responder Cookie */ - uint8_t np; /* Next Payload Type */ - uint8_t vers; + nd_uint8_t np; /* Next Payload Type */ + nd_uint8_t vers; #define ISAKMP_VERS_MAJOR 0xf0 #define ISAKMP_VERS_MAJOR_SHIFT 4 #define ISAKMP_VERS_MINOR 0x0f #define ISAKMP_VERS_MINOR_SHIFT 0 - uint8_t etype; /* Exchange Type */ - uint8_t flags; /* Flags */ + nd_uint8_t etype; /* Exchange Type */ + nd_uint8_t flags; /* Flags */ msgid_t msgid; - uint32_t len; /* Length */ + nd_uint32_t len; /* Length */ }; /* Next Payload Type */ @@ -132,9 +134,9 @@ struct isakmp { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct isakmp_gen { - uint8_t np; /* Next Payload */ - uint8_t critical; /* bit 7 - critical, rest is RESERVED */ - uint16_t len; /* Payload Length */ + nd_uint8_t np; /* Next Payload */ + nd_uint8_t critical; /* bit 7 - critical, rest is RESERVED */ + nd_uint16_t len; /* Payload Length */ }; /* 3.3 Data Attributes @@ -148,9 +150,9 @@ struct isakmp_gen { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct isakmp_data { - uint16_t type; /* defined by DOI-spec, and Attribute Format */ - uint16_t lorv; /* if f equal 1, Attribute Length */ - /* if f equal 0, Attribute Value */ + nd_uint16_t type; /* defined by DOI-spec, and Attribute Format */ + nd_uint16_t lorv; /* if f equal 1, Attribute Length */ + /* if f equal 0, Attribute Value */ /* if f equal 1, Attribute Value */ }; @@ -168,8 +170,8 @@ struct isakmp_data { */ struct ikev1_pl_sa { struct isakmp_gen h; - uint32_t doi; /* Domain of Interpretation */ - uint32_t sit; /* Situation */ + nd_uint32_t doi; /* Domain of Interpretation */ + nd_uint32_t sit; /* Situation */ }; /* 3.5 Proposal Payload */ @@ -182,10 +184,10 @@ struct ikev1_pl_sa { */ struct ikev1_pl_p { struct isakmp_gen h; - uint8_t p_no; /* Proposal # */ - uint8_t prot_id; /* Protocol */ - uint8_t spi_size; /* SPI Size */ - uint8_t num_t; /* Number of Transforms */ + nd_uint8_t p_no; /* Proposal # */ + nd_uint8_t prot_id; /* Protocol */ + nd_uint8_t spi_size; /* SPI Size */ + nd_uint8_t num_t; /* Number of Transforms */ /* SPI */ }; @@ -198,9 +200,9 @@ struct ikev1_pl_p { */ struct ikev1_pl_t { struct isakmp_gen h; - uint8_t t_no; /* Transform # */ - uint8_t t_id; /* Transform-Id */ - uint16_t reserved; /* RESERVED2 */ + nd_uint8_t t_no; /* Transform # */ + nd_uint8_t t_id; /* Transform-Id */ + nd_byte reserved[2]; /* RESERVED2 */ /* SA Attributes */ }; @@ -215,8 +217,8 @@ struct ikev1_pl_ke { struct ikev1_pl_id { struct isakmp_gen h; union { - uint8_t id_type; /* ID Type */ - uint32_t doi_data; /* DOI Specific ID Data */ + nd_uint8_t id_type; /* ID Type */ + nd_uint32_t doi_data; /* DOI Specific ID Data */ } d; /* Identification Data */ }; @@ -224,8 +226,8 @@ struct ikev1_pl_id { /* 3.9 Certificate Payload */ struct ikev1_pl_cert { struct isakmp_gen h; - uint8_t encode; /* Cert Encoding */ - char cert; /* Certificate Data */ + nd_uint8_t encode; /* Cert Encoding */ + nd_uint8_t cert; /* Certificate Data */ /* This field indicates the type of certificate or certificate-related information contained in the @@ -236,7 +238,7 @@ struct ikev1_pl_cert { /* 3.10 Certificate Request Payload */ struct ikev1_pl_cr { struct isakmp_gen h; - uint8_t num_cert; /* # Cert. Types */ + nd_uint8_t num_cert; /* # Cert. Types */ /* Certificate Types (variable length) -- Contains a list of the types of certificates requested, @@ -271,10 +273,10 @@ struct ikev1_pl_nonce { /* 3.14 Notification Payload */ struct ikev1_pl_n { struct isakmp_gen h; - uint32_t doi; /* Domain of Interpretation */ - uint8_t prot_id; /* Protocol-ID */ - uint8_t spi_size; /* SPI Size */ - uint16_t type; /* Notify Message Type */ + nd_uint32_t doi; /* Domain of Interpretation */ + nd_uint8_t prot_id; /* Protocol-ID */ + nd_uint8_t spi_size; /* SPI Size */ + nd_uint16_t type; /* Notify Message Type */ /* SPI */ /* Notification Data */ }; @@ -311,43 +313,31 @@ struct ikev1_pl_n { /* 3.15 Delete Payload */ struct ikev1_pl_d { struct isakmp_gen h; - uint32_t doi; /* Domain of Interpretation */ - uint8_t prot_id; /* Protocol-Id */ - uint8_t spi_size; /* SPI Size */ - uint16_t num_spi; /* # of SPIs */ + nd_uint32_t doi; /* Domain of Interpretation */ + nd_uint8_t prot_id; /* Protocol-Id */ + nd_uint8_t spi_size; /* SPI Size */ + nd_uint16_t num_spi; /* # of SPIs */ /* SPI(es) */ }; -struct ikev1_ph1tab { - struct ikev1_ph1 *head; - struct ikev1_ph1 *tail; - int len; -}; - -struct isakmp_ph2tab { - struct ikev1_ph2 *head; - struct ikev1_ph2 *tail; - int len; -}; - /* IKEv2 (RFC4306) */ /* 3.3 Security Association Payload -- generic header */ /* 3.3.1. Proposal Substructure */ struct ikev2_p { struct isakmp_gen h; - uint8_t p_no; /* Proposal # */ - uint8_t prot_id; /* Protocol */ - uint8_t spi_size; /* SPI Size */ - uint8_t num_t; /* Number of Transforms */ + nd_uint8_t p_no; /* Proposal # */ + nd_uint8_t prot_id; /* Protocol */ + nd_uint8_t spi_size; /* SPI Size */ + nd_uint8_t num_t; /* Number of Transforms */ }; /* 3.3.2. Transform Substructure */ struct ikev2_t { struct isakmp_gen h; - uint8_t t_type; /* Transform Type (ENCR,PRF,INTEG,etc.*/ - uint8_t res2; /* reserved byte */ - uint16_t t_id; /* Transform ID */ + nd_uint8_t t_type; /* Transform Type (ENCR,PRF,INTEG,etc.*/ + nd_byte res2; /* reserved byte */ + nd_uint16_t t_id; /* Transform ID */ }; enum ikev2_t_type { @@ -361,8 +351,8 @@ enum ikev2_t_type { /* 3.4. Key Exchange Payload */ struct ikev2_ke { struct isakmp_gen h; - uint16_t ke_group; - uint16_t ke_res1; + nd_uint16_t ke_group; + nd_uint16_t ke_res1; /* KE data */ }; @@ -379,9 +369,9 @@ enum ikev2_id_type { }; struct ikev2_id { struct isakmp_gen h; - uint8_t type; /* ID type */ - uint8_t res1; - uint16_t res2; + nd_uint8_t type; /* ID type */ + nd_byte res1; + nd_byte res2[2]; /* SPI */ /* Notification Data */ }; @@ -389,9 +379,9 @@ struct ikev2_id { /* 3.10 Notification Payload */ struct ikev2_n { struct isakmp_gen h; - uint8_t prot_id; /* Protocol-ID */ - uint8_t spi_size; /* SPI Size */ - uint16_t type; /* Notify Message Type */ + nd_uint8_t prot_id; /* Protocol-ID */ + nd_uint8_t spi_size; /* SPI Size */ + nd_uint16_t type; /* Notify Message Type */ }; enum ikev2_n_type { @@ -431,8 +421,8 @@ struct notify_messages { /* 3.8 Authentication Payload */ struct ikev2_auth { struct isakmp_gen h; - uint8_t auth_method; /* Protocol-ID */ - uint8_t reserved[3]; + nd_uint8_t auth_method; /* Protocol-ID */ + nd_byte reserved[3]; /* authentication data */ }; @@ -540,21 +530,21 @@ struct oakley_sa { /* 4.6.1 Security Association Payload */ struct ipsecdoi_sa { struct isakmp_gen h; - uint32_t doi; /* Domain of Interpretation */ - uint32_t sit; /* Situation */ + nd_uint32_t doi; /* Domain of Interpretation */ + nd_uint32_t sit; /* Situation */ }; struct ipsecdoi_secrecy_h { - uint16_t len; - uint16_t reserved; + nd_uint16_t len; + nd_uint16_t reserved; }; /* 4.6.2.1 Identification Type Values */ struct ipsecdoi_id { struct isakmp_gen h; - uint8_t type; /* ID Type */ - uint8_t proto_id; /* Protocol ID */ - uint16_t port; /* Port */ + nd_uint8_t type; /* ID Type */ + nd_uint8_t proto_id; /* Protocol ID */ + nd_uint16_t port; /* Port */ /* Identification Data */ }; @@ -614,7 +604,7 @@ DECLARE_PRINTER(v2_cp); DECLARE_PRINTER(v2_eap); static const u_char *ikev2_e_print(netdissect_options *ndo, - struct isakmp *base, + const struct isakmp *base, u_char tpay, const struct isakmp_gen *ext, u_int item_len, @@ -630,25 +620,25 @@ static const u_char *ikev1_sub_print(netdissect_options *ndo,u_char, const struc const u_char *, uint32_t, uint32_t, uint32_t, int); static const u_char *ikev2_sub_print(netdissect_options *ndo, - struct isakmp *base, + const struct isakmp *base, u_char np, const struct isakmp_gen *ext, const u_char *ep, uint32_t phase, uint32_t doi, uint32_t proto, int depth); -static char *numstr(int); +static char *numstr(u_int); static void ikev1_print(netdissect_options *ndo, const u_char *bp, u_int length, - const u_char *bp2, struct isakmp *base); + const u_char *bp2, const struct isakmp *base); #define MAXINITIATORS 20 static int ninitiator = 0; union inaddr_u { - struct in_addr in4; - struct in6_addr in6; + nd_ipv4 in4; + nd_ipv6 in6; }; static struct { cookie_t initiator; @@ -741,7 +731,7 @@ static const char *etypestr[] = { #define CHECKLEN(p, np) \ if (ep < (const u_char *)(p)) { \ - ND_PRINT((ndo," [|%s]", NPSTR(np))); \ + ND_PRINT(" [|%s]", NPSTR(np)); \ goto done; \ } @@ -753,16 +743,18 @@ static const char *etypestr[] = { static int iszero(const u_char *p, size_t l) { - while (l--) { - if (*p++) + while (l != 0) { + if (*p) return 0; + p++; + l--; } return 1; } /* find cookie from initiator cache */ static int -cookie_find(cookie_t *in) +cookie_find(const cookie_t *in) { int i; @@ -776,7 +768,7 @@ cookie_find(cookie_t *in) /* record initiator */ static void -cookie_record(cookie_t *in, const u_char *bp2) +cookie_record(netdissect_options *ndo, const cookie_t *in, const u_char *bp2) { int i; const struct ip *ip; @@ -792,14 +784,18 @@ cookie_record(cookie_t *in, const u_char *bp2) switch (IP_V(ip)) { case 4: cookiecache[ninitiator].version = 4; - UNALIGNED_MEMCPY(&cookiecache[ninitiator].iaddr.in4, &ip->ip_src, sizeof(struct in_addr)); - UNALIGNED_MEMCPY(&cookiecache[ninitiator].raddr.in4, &ip->ip_dst, sizeof(struct in_addr)); + UNALIGNED_MEMCPY(&cookiecache[ninitiator].iaddr.in4, + ip->ip_src, sizeof(nd_ipv4)); + UNALIGNED_MEMCPY(&cookiecache[ninitiator].raddr.in4, + ip->ip_dst, sizeof(nd_ipv4)); break; case 6: ip6 = (const struct ip6_hdr *)bp2; cookiecache[ninitiator].version = 6; - UNALIGNED_MEMCPY(&cookiecache[ninitiator].iaddr.in6, &ip6->ip6_src, sizeof(struct in6_addr)); - UNALIGNED_MEMCPY(&cookiecache[ninitiator].raddr.in6, &ip6->ip6_dst, sizeof(struct in6_addr)); + UNALIGNED_MEMCPY(&cookiecache[ninitiator].iaddr.in6, + ip6->ip6_src, sizeof(nd_ipv6)); + UNALIGNED_MEMCPY(&cookiecache[ninitiator].raddr.in6, + ip6->ip6_dst, sizeof(nd_ipv6)); break; default: return; @@ -808,10 +804,10 @@ cookie_record(cookie_t *in, const u_char *bp2) ninitiator = (ninitiator + 1) % MAXINITIATORS; } -#define cookie_isinitiator(x, y) cookie_sidecheck((x), (y), 1) -#define cookie_isresponder(x, y) cookie_sidecheck((x), (y), 0) +#define cookie_isinitiator(ndo, x, y) cookie_sidecheck(ndo, (x), (y), 1) +#define cookie_isresponder(ndo, x, y) cookie_sidecheck(ndo, (x), (y), 0) static int -cookie_sidecheck(int i, const u_char *bp2, int initiator) +cookie_sidecheck(netdissect_options *ndo, int i, const u_char *bp2, int initiator) { const struct ip *ip; const struct ip6_hdr *ip6; @@ -822,10 +818,10 @@ cookie_sidecheck(int i, const u_char *bp2, int initiator) if (cookiecache[i].version != 4) return 0; if (initiator) { - if (UNALIGNED_MEMCMP(&ip->ip_src, &cookiecache[i].iaddr.in4, sizeof(struct in_addr)) == 0) + if (UNALIGNED_MEMCMP(ip->ip_src, &cookiecache[i].iaddr.in4, sizeof(nd_ipv4)) == 0) return 1; } else { - if (UNALIGNED_MEMCMP(&ip->ip_src, &cookiecache[i].raddr.in4, sizeof(struct in_addr)) == 0) + if (UNALIGNED_MEMCMP(ip->ip_src, &cookiecache[i].raddr.in4, sizeof(nd_ipv4)) == 0) return 1; } break; @@ -834,10 +830,10 @@ cookie_sidecheck(int i, const u_char *bp2, int initiator) return 0; ip6 = (const struct ip6_hdr *)bp2; if (initiator) { - if (UNALIGNED_MEMCMP(&ip6->ip6_src, &cookiecache[i].iaddr.in6, sizeof(struct in6_addr)) == 0) + if (UNALIGNED_MEMCMP(ip6->ip6_src, &cookiecache[i].iaddr.in6, sizeof(nd_ipv6)) == 0) return 1; } else { - if (UNALIGNED_MEMCMP(&ip6->ip6_src, &cookiecache[i].raddr.in6, sizeof(struct in6_addr)) == 0) + if (UNALIGNED_MEMCMP(ip6->ip6_src, &cookiecache[i].raddr.in6, sizeof(nd_ipv6)) == 0) return 1; } break; @@ -856,13 +852,13 @@ hexprint(netdissect_options *ndo, const uint8_t *loc, size_t len) p = loc; for (i = 0; i < len; i++) - ND_PRINT((ndo,"%02x", p[i] & 0xff)); + ND_PRINT("%02x", p[i] & 0xff); } static int rawprint(netdissect_options *ndo, const uint8_t *loc, size_t len) { - ND_TCHECK2(*loc, len); + ND_TCHECK_LEN(loc, len); hexprint(ndo, loc, len); return 1; @@ -879,8 +875,8 @@ static int ike_show_somedata(netdissect_options *ndo, { /* there is too much data, just show some of it */ const u_char *end = ep - 20; - int elen = 20; - int len = ep - cp; + size_t elen = 20; + size_t len = ep - cp; if(len > 10) { len = 10; } @@ -891,13 +887,13 @@ static int ike_show_somedata(netdissect_options *ndo, elen = ep - end; } - ND_PRINT((ndo," data=(")); + ND_PRINT(" data=("); if(!rawprint(ndo, (const uint8_t *)(cp), len)) goto trunc; - ND_PRINT((ndo, "...")); + ND_PRINT("..."); if(elen) { if(!rawprint(ndo, (const uint8_t *)(end), elen)) goto trunc; } - ND_PRINT((ndo,")")); + ND_PRINT(")"); return 1; trunc: @@ -915,48 +911,44 @@ ikev1_attrmap_print(netdissect_options *ndo, const u_char *p, const u_char *ep2, const struct attrmap *map, size_t nmap) { - int totlen; + u_int totlen; uint32_t t, v; - ND_TCHECK(p[0]); - if (p[0] & 0x80) + if (GET_U_1(p) & 0x80) totlen = 4; else { - ND_TCHECK_16BITS(&p[2]); - totlen = 4 + EXTRACT_16BITS(&p[2]); + totlen = 4 + GET_BE_U_2(p + 2); } if (ep2 < p + totlen) { - ND_PRINT((ndo,"[|attr]")); + ND_PRINT("[|attr]"); return ep2 + 1; } - ND_TCHECK_16BITS(&p[0]); - ND_PRINT((ndo,"(")); - t = EXTRACT_16BITS(&p[0]) & 0x7fff; + ND_PRINT("("); + t = GET_BE_U_2(p) & 0x7fff; if (map && t < nmap && map[t].type) - ND_PRINT((ndo,"type=%s ", map[t].type)); + ND_PRINT("type=%s ", map[t].type); else - ND_PRINT((ndo,"type=#%d ", t)); - if (p[0] & 0x80) { - ND_PRINT((ndo,"value=")); - ND_TCHECK_16BITS(&p[2]); - v = EXTRACT_16BITS(&p[2]); + ND_PRINT("type=#%u ", t); + if (GET_U_1(p) & 0x80) { + ND_PRINT("value="); + v = GET_BE_U_2(p + 2); if (map && t < nmap && v < map[t].nvalue && map[t].value[v]) - ND_PRINT((ndo,"%s", map[t].value[v])); + ND_PRINT("%s", map[t].value[v]); else { - if (!rawprint(ndo, (const uint8_t *)&p[2], 2)) { - ND_PRINT((ndo,")")); + if (!rawprint(ndo, (const uint8_t *)(p + 2), 2)) { + ND_PRINT(")"); goto trunc; } } } else { - ND_PRINT((ndo,"len=%d value=", totlen - 4)); - if (!rawprint(ndo, (const uint8_t *)&p[4], totlen - 4)) { - ND_PRINT((ndo,")")); + ND_PRINT("len=%u value=", totlen - 4); + if (!rawprint(ndo, (const uint8_t *)(p + 4), totlen - 4)) { + ND_PRINT(")"); goto trunc; } } - ND_PRINT((ndo,")")); + ND_PRINT(")"); return p + totlen; trunc: @@ -966,40 +958,37 @@ trunc: static const u_char * ikev1_attr_print(netdissect_options *ndo, const u_char *p, const u_char *ep2) { - int totlen; + u_int totlen; uint32_t t; - ND_TCHECK(p[0]); - if (p[0] & 0x80) + if (GET_U_1(p) & 0x80) totlen = 4; else { - ND_TCHECK_16BITS(&p[2]); - totlen = 4 + EXTRACT_16BITS(&p[2]); + totlen = 4 + GET_BE_U_2(p + 2); } if (ep2 < p + totlen) { - ND_PRINT((ndo,"[|attr]")); + ND_PRINT("[|attr]"); return ep2 + 1; } - ND_TCHECK_16BITS(&p[0]); - ND_PRINT((ndo,"(")); - t = EXTRACT_16BITS(&p[0]) & 0x7fff; - ND_PRINT((ndo,"type=#%d ", t)); - if (p[0] & 0x80) { - ND_PRINT((ndo,"value=")); - t = p[2]; - if (!rawprint(ndo, (const uint8_t *)&p[2], 2)) { - ND_PRINT((ndo,")")); + ND_PRINT("("); + t = GET_BE_U_2(p) & 0x7fff; + ND_PRINT("type=#%u ", t); + if (GET_U_1(p) & 0x80) { + ND_PRINT("value="); + t = GET_U_1(p + 2); + if (!rawprint(ndo, (const uint8_t *)(p + 2), 2)) { + ND_PRINT(")"); goto trunc; } } else { - ND_PRINT((ndo,"len=%d value=", totlen - 4)); - if (!rawprint(ndo, (const uint8_t *)&p[4], totlen - 4)) { - ND_PRINT((ndo,")")); + ND_PRINT("len=%u value=", totlen - 4); + if (!rawprint(ndo, (const uint8_t *)(p + 4), totlen - 4)) { + ND_PRINT(")"); goto trunc; } } - ND_PRINT((ndo,")")); + ND_PRINT(")"); return p + totlen; trunc: @@ -1014,55 +1003,52 @@ ikev1_sa_print(netdissect_options *ndo, u_char tpay _U_, uint32_t proto0, int depth) { const struct ikev1_pl_sa *p; - struct ikev1_pl_sa sa; uint32_t doi, sit, ident; const u_char *cp, *np; int t; - ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_SA))); + ND_PRINT("%s:", NPSTR(ISAKMP_NPTYPE_SA)); p = (const struct ikev1_pl_sa *)ext; - ND_TCHECK(*p); - UNALIGNED_MEMCPY(&sa, ext, sizeof(sa)); - doi = ntohl(sa.doi); - sit = ntohl(sa.sit); + ND_TCHECK_SIZE(p); + doi = GET_BE_U_4(p->doi); + sit = GET_BE_U_4(p->sit); if (doi != 1) { - ND_PRINT((ndo," doi=%d", doi)); - ND_PRINT((ndo," situation=%u", (uint32_t)ntohl(sa.sit))); + ND_PRINT(" doi=%u", doi); + ND_PRINT(" situation=%u", sit); return (const u_char *)(p + 1); } - ND_PRINT((ndo," doi=ipsec")); - ND_PRINT((ndo," situation=")); + ND_PRINT(" doi=ipsec"); + ND_PRINT(" situation="); t = 0; if (sit & 0x01) { - ND_PRINT((ndo,"identity")); + ND_PRINT("identity"); t++; } if (sit & 0x02) { - ND_PRINT((ndo,"%ssecrecy", t ? "+" : "")); + ND_PRINT("%ssecrecy", t ? "+" : ""); t++; } if (sit & 0x04) - ND_PRINT((ndo,"%sintegrity", t ? "+" : "")); + ND_PRINT("%sintegrity", t ? "+" : ""); - np = (const u_char *)ext + sizeof(sa); + np = (const u_char *)ext + sizeof(struct ikev1_pl_sa); if (sit != 0x01) { - ND_TCHECK2(*(ext + 1), sizeof(ident)); - UNALIGNED_MEMCPY(&ident, ext + 1, sizeof(ident)); - ND_PRINT((ndo," ident=%u", (uint32_t)ntohl(ident))); + ident = GET_BE_U_4(ext + 1); + ND_PRINT(" ident=%u", ident); np += sizeof(ident); } ext = (const struct isakmp_gen *)np; - ND_TCHECK(*ext); + ND_TCHECK_SIZE(ext); cp = ikev1_sub_print(ndo, ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0, depth); return cp; trunc: - ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_SA))); + ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_SA)); return NULL; } @@ -1073,31 +1059,32 @@ ikev1_p_print(netdissect_options *ndo, u_char tpay _U_, uint32_t proto0 _U_, int depth) { const struct ikev1_pl_p *p; - struct ikev1_pl_p prop; const u_char *cp; + uint8_t spi_size; - ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_P))); + ND_PRINT("%s:", NPSTR(ISAKMP_NPTYPE_P)); p = (const struct ikev1_pl_p *)ext; - ND_TCHECK(*p); - UNALIGNED_MEMCPY(&prop, ext, sizeof(prop)); - ND_PRINT((ndo," #%d protoid=%s transform=%d", - prop.p_no, PROTOIDSTR(prop.prot_id), prop.num_t)); - if (prop.spi_size) { - ND_PRINT((ndo," spi=")); - if (!rawprint(ndo, (const uint8_t *)(p + 1), prop.spi_size)) + ND_TCHECK_SIZE(p); + ND_PRINT(" #%u protoid=%s transform=%u", + GET_U_1(p->p_no), PROTOIDSTR(GET_U_1(p->prot_id)), + GET_U_1(p->num_t)); + spi_size = GET_U_1(p->spi_size); + if (spi_size) { + ND_PRINT(" spi="); + if (!rawprint(ndo, (const uint8_t *)(p + 1), spi_size)) goto trunc; } - ext = (const struct isakmp_gen *)((const u_char *)(p + 1) + prop.spi_size); - ND_TCHECK(*ext); + ext = (const struct isakmp_gen *)((const u_char *)(p + 1) + spi_size); + ND_TCHECK_SIZE(ext); cp = ikev1_sub_print(ndo, ISAKMP_NPTYPE_T, ext, ep, phase, doi0, - prop.prot_id, depth); + GET_U_1(p->prot_id), depth); return cp; trunc: - ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_P))); + ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_P)); return NULL; } @@ -1182,7 +1169,7 @@ static const struct attrmap ipsec_t_map[] = { }; static const struct attrmap encr_t_map[] = { - { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 0, 1 */ + { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 0, 1 */ { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 2, 3 */ { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 4, 5 */ { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 6, 7 */ @@ -1195,7 +1182,7 @@ static const struct attrmap encr_t_map[] = { static const struct attrmap oakley_t_map[] = { { NULL, 0, { NULL } }, { "enc", 8, { NULL, "1des", "idea", "blowfish", "rc5", - "3des", "cast", "aes", }, }, + "3des", "cast", "aes", }, }, { "hash", 7, { NULL, "md5", "sha1", "tiger", "sha2-256", "sha2-384", "sha2-512", }, }, { "auth", 6, { NULL, "preshared", "dss", "rsa sig", "rsa enc", @@ -1236,37 +1223,35 @@ ikev1_t_print(netdissect_options *ndo, u_char tpay _U_, uint32_t proto, int depth _U_) { const struct ikev1_pl_t *p; - struct ikev1_pl_t t; const u_char *cp; const char *idstr; const struct attrmap *map; size_t nmap; const u_char *ep2; - ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_T))); + ND_PRINT("%s:", NPSTR(ISAKMP_NPTYPE_T)); p = (const struct ikev1_pl_t *)ext; - ND_TCHECK(*p); - UNALIGNED_MEMCPY(&t, ext, sizeof(t)); + ND_TCHECK_SIZE(p); switch (proto) { case 1: - idstr = STR_OR_ID(t.t_id, ikev1_p_map); + idstr = STR_OR_ID(GET_U_1(p->t_id), ikev1_p_map); map = oakley_t_map; nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]); break; case 2: - idstr = STR_OR_ID(t.t_id, ah_p_map); + idstr = STR_OR_ID(GET_U_1(p->t_id), ah_p_map); map = ipsec_t_map; nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]); break; case 3: - idstr = STR_OR_ID(t.t_id, esp_p_map); + idstr = STR_OR_ID(GET_U_1(p->t_id), esp_p_map); map = ipsec_t_map; nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]); break; case 4: - idstr = STR_OR_ID(t.t_id, ipcomp_p_map); + idstr = STR_OR_ID(GET_U_1(p->t_id), ipcomp_p_map); map = ipsec_t_map; nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]); break; @@ -1278,9 +1263,9 @@ ikev1_t_print(netdissect_options *ndo, u_char tpay _U_, } if (idstr) - ND_PRINT((ndo," #%d id=%s ", t.t_no, idstr)); + ND_PRINT(" #%u id=%s ", GET_U_1(p->t_no), idstr); else - ND_PRINT((ndo," #%d id=%d ", t.t_no, t.t_id)); + ND_PRINT(" #%u id=%u ", GET_U_1(p->t_no), GET_U_1(p->t_id)); cp = (const u_char *)(p + 1); ep2 = (const u_char *)p + item_len; while (cp < ep && cp < ep2) { @@ -1292,35 +1277,35 @@ ikev1_t_print(netdissect_options *ndo, u_char tpay _U_, goto trunc; } if (ep < ep2) - ND_PRINT((ndo,"...")); + ND_PRINT("..."); return cp; trunc: - ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_T))); + ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_T)); return NULL; } static const u_char * ikev1_ke_print(netdissect_options *ndo, u_char tpay _U_, - const struct isakmp_gen *ext, u_int item_len _U_, + const struct isakmp_gen *ext, u_int item_len, const u_char *ep _U_, uint32_t phase _U_, uint32_t doi _U_, uint32_t proto _U_, int depth _U_) { - struct isakmp_gen e; - - ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_KE))); + ND_PRINT("%s:", NPSTR(ISAKMP_NPTYPE_KE)); - ND_TCHECK(*ext); - UNALIGNED_MEMCPY(&e, ext, sizeof(e)); - ND_PRINT((ndo," key len=%d", ntohs(e.len) - 4)); - if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { + ND_TCHECK_SIZE(ext); + /* + * Our caller has ensured that the length is >= 4. + */ + ND_PRINT(" key len=%u", item_len - 4); + if (2 < ndo->ndo_vflag && item_len > 4) { /* Print the entire payload in hex */ - ND_PRINT((ndo," ")); - if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4)) + ND_PRINT(" "); + if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4)) goto trunc; } - return (const u_char *)ext + ntohs(e.len); + return (const u_char *)ext + item_len; trunc: - ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_KE))); + ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_KE)); return NULL; } @@ -1332,7 +1317,6 @@ ikev1_id_print(netdissect_options *ndo, u_char tpay _U_, { #define USE_IPSECDOI_IN_PHASE1 1 const struct ikev1_pl_id *p; - struct ikev1_pl_id id; static const char *idtypestr[] = { "IPv4", "IPv4net", "IPv6", "IPv6net", }; @@ -1341,14 +1325,13 @@ ikev1_id_print(netdissect_options *ndo, u_char tpay _U_, "IPv6net", "IPv4range", "IPv6range", "ASN1 DN", "ASN1 GN", "keyid", }; - int len; + u_int len; const u_char *data; - ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_ID))); + ND_PRINT("%s:", NPSTR(ISAKMP_NPTYPE_ID)); p = (const struct ikev1_pl_id *)ext; - ND_TCHECK(*p); - UNALIGNED_MEMCPY(&id, ext, sizeof(id)); + ND_TCHECK_SIZE(p); if (sizeof(*p) < item_len) { data = (const u_char *)(p + 1); len = item_len - sizeof(*p); @@ -1358,16 +1341,17 @@ ikev1_id_print(netdissect_options *ndo, u_char tpay _U_, } #if 0 /*debug*/ - ND_PRINT((ndo," [phase=%d doi=%d proto=%d]", phase, doi, proto)); + ND_PRINT(" [phase=%u doi=%u proto=%u]", phase, doi, proto); #endif switch (phase) { #ifndef USE_IPSECDOI_IN_PHASE1 case 1: #endif default: - ND_PRINT((ndo," idtype=%s", STR_OR_ID(id.d.id_type, idtypestr))); - ND_PRINT((ndo," doi_data=%u", - (uint32_t)(ntohl(id.d.doi_data) & 0xffffff))); + ND_PRINT(" idtype=%s", + STR_OR_ID(GET_U_1(p->d.id_type), idtypestr)); + ND_PRINT(" doi_data=%u", + GET_BE_U_4(p->d.doi_data) & 0xffffff); break; #ifdef USE_IPSECDOI_IN_PHASE1 @@ -1376,39 +1360,40 @@ ikev1_id_print(netdissect_options *ndo, u_char tpay _U_, case 2: { const struct ipsecdoi_id *doi_p; - struct ipsecdoi_id doi_id; const char *p_name; + uint8_t type, proto_id; doi_p = (const struct ipsecdoi_id *)ext; - ND_TCHECK(*doi_p); - UNALIGNED_MEMCPY(&doi_id, ext, sizeof(doi_id)); - ND_PRINT((ndo," idtype=%s", STR_OR_ID(doi_id.type, ipsecidtypestr))); + ND_TCHECK_SIZE(doi_p); + type = GET_U_1(doi_p->type); + ND_PRINT(" idtype=%s", STR_OR_ID(type, ipsecidtypestr)); /* A protocol ID of 0 DOES NOT mean IPPROTO_IP! */ - if (!ndo->ndo_nflag && doi_id.proto_id && (p_name = netdb_protoname(doi_id.proto_id)) != NULL) - ND_PRINT((ndo," protoid=%s", p_name)); + proto_id = GET_U_1(doi_p->proto_id); + if (!ndo->ndo_nflag && proto_id && (p_name = netdb_protoname(proto_id)) != NULL) + ND_PRINT(" protoid=%s", p_name); else - ND_PRINT((ndo," protoid=%u", doi_id.proto_id)); - ND_PRINT((ndo," port=%d", ntohs(doi_id.port))); + ND_PRINT(" protoid=%u", proto_id); + ND_PRINT(" port=%u", GET_BE_U_2(doi_p->port)); if (!len) break; if (data == NULL) goto trunc; - ND_TCHECK2(*data, len); - switch (doi_id.type) { + ND_TCHECK_LEN(data, len); + switch (type) { case IPSECDOI_ID_IPV4_ADDR: if (len < 4) - ND_PRINT((ndo," len=%d [bad: < 4]", len)); + ND_PRINT(" len=%u [bad: < 4]", len); else - ND_PRINT((ndo," len=%d %s", len, ipaddr_string(ndo, data))); + ND_PRINT(" len=%u %s", len, GET_IPADDR_STRING(data)); len = 0; break; case IPSECDOI_ID_FQDN: case IPSECDOI_ID_USER_FQDN: { - int i; - ND_PRINT((ndo," len=%d ", len)); + u_int i; + ND_PRINT(" len=%u ", len); for (i = 0; i < len; i++) - safeputchar(ndo, data[i]); + fn_print_char(ndo, GET_U_1(data + i)); len = 0; break; } @@ -1416,58 +1401,71 @@ ikev1_id_print(netdissect_options *ndo, u_char tpay _U_, { const u_char *mask; if (len < 8) - ND_PRINT((ndo," len=%d [bad: < 8]", len)); + ND_PRINT(" len=%u [bad: < 8]", len); else { - mask = data + sizeof(struct in_addr); - ND_PRINT((ndo," len=%d %s/%u.%u.%u.%u", len, - ipaddr_string(ndo, data), - mask[0], mask[1], mask[2], mask[3])); + mask = data + sizeof(nd_ipv4); + ND_PRINT(" len=%u %s/%u.%u.%u.%u", len, + GET_IPADDR_STRING(data), + GET_U_1(mask), GET_U_1(mask + 1), + GET_U_1(mask + 2), + GET_U_1(mask + 3)); } len = 0; break; } case IPSECDOI_ID_IPV6_ADDR: if (len < 16) - ND_PRINT((ndo," len=%d [bad: < 16]", len)); + ND_PRINT(" len=%u [bad: < 16]", len); else - ND_PRINT((ndo," len=%d %s", len, ip6addr_string(ndo, data))); + ND_PRINT(" len=%u %s", len, GET_IP6ADDR_STRING(data)); len = 0; break; case IPSECDOI_ID_IPV6_ADDR_SUBNET: { const u_char *mask; if (len < 32) - ND_PRINT((ndo," len=%d [bad: < 32]", len)); + ND_PRINT(" len=%u [bad: < 32]", len); else { - mask = (const u_char *)(data + sizeof(struct in6_addr)); + mask = (const u_char *)(data + sizeof(nd_ipv6)); /*XXX*/ - ND_PRINT((ndo," len=%d %s/0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", len, - ip6addr_string(ndo, data), - mask[0], mask[1], mask[2], mask[3], - mask[4], mask[5], mask[6], mask[7], - mask[8], mask[9], mask[10], mask[11], - mask[12], mask[13], mask[14], mask[15])); + ND_PRINT(" len=%u %s/0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", len, + GET_IP6ADDR_STRING(data), + GET_U_1(mask), GET_U_1(mask + 1), + GET_U_1(mask + 2), + GET_U_1(mask + 3), + GET_U_1(mask + 4), + GET_U_1(mask + 5), + GET_U_1(mask + 6), + GET_U_1(mask + 7), + GET_U_1(mask + 8), + GET_U_1(mask + 9), + GET_U_1(mask + 10), + GET_U_1(mask + 11), + GET_U_1(mask + 12), + GET_U_1(mask + 13), + GET_U_1(mask + 14), + GET_U_1(mask + 15)); } len = 0; break; } case IPSECDOI_ID_IPV4_ADDR_RANGE: if (len < 8) - ND_PRINT((ndo," len=%d [bad: < 8]", len)); + ND_PRINT(" len=%u [bad: < 8]", len); else { - ND_PRINT((ndo," len=%d %s-%s", len, - ipaddr_string(ndo, data), - ipaddr_string(ndo, data + sizeof(struct in_addr)))); + ND_PRINT(" len=%u %s-%s", len, + GET_IPADDR_STRING(data), + GET_IPADDR_STRING(data + sizeof(nd_ipv4))); } len = 0; break; case IPSECDOI_ID_IPV6_ADDR_RANGE: if (len < 32) - ND_PRINT((ndo," len=%d [bad: < 32]", len)); + ND_PRINT(" len=%u [bad: < 32]", len); else { - ND_PRINT((ndo," len=%d %s-%s", len, - ip6addr_string(ndo, data), - ip6addr_string(ndo, data + sizeof(struct in6_addr)))); + ND_PRINT(" len=%u %s-%s", len, + GET_IP6ADDR_STRING(data), + GET_IP6ADDR_STRING(data + sizeof(nd_ipv6))); } len = 0; break; @@ -1480,16 +1478,16 @@ ikev1_id_print(netdissect_options *ndo, u_char tpay _U_, } } if (data && len) { - ND_PRINT((ndo," len=%d", len)); + ND_PRINT(" len=%u", len); if (2 < ndo->ndo_vflag) { - ND_PRINT((ndo," ")); + ND_PRINT(" "); if (!rawprint(ndo, (const uint8_t *)data, len)) goto trunc; } } return (const u_char *)ext + item_len; trunc: - ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_ID))); + ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_ID)); return NULL; } @@ -1501,29 +1499,30 @@ ikev1_cert_print(netdissect_options *ndo, u_char tpay _U_, uint32_t proto0 _U_, int depth _U_) { const struct ikev1_pl_cert *p; - struct ikev1_pl_cert cert; static const char *certstr[] = { "none", "pkcs7", "pgp", "dns", "x509sign", "x509ke", "kerberos", "crl", "arl", "spki", "x509attr", }; - ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_CERT))); + ND_PRINT("%s:", NPSTR(ISAKMP_NPTYPE_CERT)); p = (const struct ikev1_pl_cert *)ext; - ND_TCHECK(*p); - UNALIGNED_MEMCPY(&cert, ext, sizeof(cert)); - ND_PRINT((ndo," len=%d", item_len - 4)); - ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr))); + ND_TCHECK_SIZE(p); + /* + * Our caller has ensured that the length is >= 4. + */ + ND_PRINT(" len=%u", item_len - 4); + ND_PRINT(" type=%s", STR_OR_ID(GET_U_1(p->encode), certstr)); if (2 < ndo->ndo_vflag && 4 < item_len) { /* Print the entire payload in hex */ - ND_PRINT((ndo," ")); + ND_PRINT(" "); if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4)) goto trunc; } return (const u_char *)ext + item_len; trunc: - ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_CERT))); + ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_CERT)); return NULL; } @@ -1534,114 +1533,112 @@ ikev1_cr_print(netdissect_options *ndo, u_char tpay _U_, uint32_t proto0 _U_, int depth _U_) { const struct ikev1_pl_cert *p; - struct ikev1_pl_cert cert; static const char *certstr[] = { "none", "pkcs7", "pgp", "dns", "x509sign", "x509ke", "kerberos", "crl", "arl", "spki", "x509attr", }; - ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_CR))); + ND_PRINT("%s:", NPSTR(ISAKMP_NPTYPE_CR)); p = (const struct ikev1_pl_cert *)ext; - ND_TCHECK(*p); - UNALIGNED_MEMCPY(&cert, ext, sizeof(cert)); - ND_PRINT((ndo," len=%d", item_len - 4)); - ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr))); + ND_TCHECK_SIZE(p); + /* + * Our caller has ensured that the length is >= 4. + */ + ND_PRINT(" len=%u", item_len - 4); + ND_PRINT(" type=%s", STR_OR_ID(GET_U_1(p->encode), certstr)); if (2 < ndo->ndo_vflag && 4 < item_len) { /* Print the entire payload in hex */ - ND_PRINT((ndo," ")); + ND_PRINT(" "); if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4)) goto trunc; } return (const u_char *)ext + item_len; trunc: - ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_CR))); + ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_CR)); return NULL; } static const u_char * ikev1_hash_print(netdissect_options *ndo, u_char tpay _U_, - const struct isakmp_gen *ext, u_int item_len _U_, + const struct isakmp_gen *ext, u_int item_len, const u_char *ep _U_, uint32_t phase _U_, uint32_t doi _U_, uint32_t proto _U_, int depth _U_) { - struct isakmp_gen e; + ND_PRINT("%s:", NPSTR(ISAKMP_NPTYPE_HASH)); - ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_HASH))); - - ND_TCHECK(*ext); - UNALIGNED_MEMCPY(&e, ext, sizeof(e)); - ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); - if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { + ND_TCHECK_SIZE(ext); + /* + * Our caller has ensured that the length is >= 4. + */ + ND_PRINT(" len=%u", item_len - 4); + if (2 < ndo->ndo_vflag && 4 < item_len) { /* Print the entire payload in hex */ - ND_PRINT((ndo," ")); - if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4)) + ND_PRINT(" "); + if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4)) goto trunc; } - return (const u_char *)ext + ntohs(e.len); + return (const u_char *)ext + item_len; trunc: - ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_HASH))); + ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_HASH)); return NULL; } static const u_char * ikev1_sig_print(netdissect_options *ndo, u_char tpay _U_, - const struct isakmp_gen *ext, u_int item_len _U_, + const struct isakmp_gen *ext, u_int item_len, const u_char *ep _U_, uint32_t phase _U_, uint32_t doi _U_, uint32_t proto _U_, int depth _U_) { - struct isakmp_gen e; - - ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_SIG))); + ND_PRINT("%s:", NPSTR(ISAKMP_NPTYPE_SIG)); - ND_TCHECK(*ext); - UNALIGNED_MEMCPY(&e, ext, sizeof(e)); - ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); - if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { + ND_TCHECK_SIZE(ext); + /* + * Our caller has ensured that the length is >= 4. + */ + ND_PRINT(" len=%u", item_len - 4); + if (2 < ndo->ndo_vflag && 4 < item_len) { /* Print the entire payload in hex */ - ND_PRINT((ndo," ")); - if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4)) + ND_PRINT(" "); + if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4)) goto trunc; } - return (const u_char *)ext + ntohs(e.len); + return (const u_char *)ext + item_len; trunc: - ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_SIG))); + ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_SIG)); return NULL; } static const u_char * ikev1_nonce_print(netdissect_options *ndo, u_char tpay _U_, const struct isakmp_gen *ext, - u_int item_len _U_, + u_int item_len, const u_char *ep, uint32_t phase _U_, uint32_t doi _U_, uint32_t proto _U_, int depth _U_) { - struct isakmp_gen e; - - ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_NONCE))); + ND_PRINT("%s:", NPSTR(ISAKMP_NPTYPE_NONCE)); - ND_TCHECK(*ext); - UNALIGNED_MEMCPY(&e, ext, sizeof(e)); + ND_TCHECK_SIZE(ext); /* * Our caller has ensured that the length is >= 4. */ - ND_PRINT((ndo," n len=%u", ntohs(e.len) - 4)); - if (ntohs(e.len) > 4) { + ND_PRINT(" n len=%u", item_len - 4); + if (item_len > 4) { if (ndo->ndo_vflag > 2) { - ND_PRINT((ndo, " ")); - if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4)) + ND_PRINT(" "); + if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4)) goto trunc; } else if (ndo->ndo_vflag > 1) { - ND_PRINT((ndo, " ")); + ND_PRINT(" "); if (!ike_show_somedata(ndo, (const u_char *)(ext + 1), ep)) goto trunc; } } - return (const u_char *)ext + ntohs(e.len); + return (const u_char *)ext + item_len; trunc: - ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_NONCE))); + ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_NONCE)); return NULL; } @@ -1652,11 +1649,12 @@ ikev1_n_print(netdissect_options *ndo, u_char tpay _U_, uint32_t proto0 _U_, int depth _U_) { const struct ikev1_pl_n *p; - struct ikev1_pl_n n; const u_char *cp; const u_char *ep2; uint32_t doi; uint32_t proto; + uint16_t type; + uint8_t spi_size; static const char *notify_error_str[] = { NULL, "INVALID-PAYLOAD-TYPE", "DOI-NOT-SUPPORTED", "SITUATION-NOT-SUPPORTED", @@ -1703,76 +1701,78 @@ ikev1_n_print(netdissect_options *ndo, u_char tpay _U_, #define IPSEC_NOTIFY_STATUS_STR(x) \ STR_OR_ID((u_int)((x) - 24576), ipsec_notify_status_str) - ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_N))); + ND_PRINT("%s:", NPSTR(ISAKMP_NPTYPE_N)); p = (const struct ikev1_pl_n *)ext; - ND_TCHECK(*p); - UNALIGNED_MEMCPY(&n, ext, sizeof(n)); - doi = ntohl(n.doi); - proto = n.prot_id; + ND_TCHECK_SIZE(p); + doi = GET_BE_U_4(p->doi); + proto = GET_U_1(p->prot_id); if (doi != 1) { - ND_PRINT((ndo," doi=%d", doi)); - ND_PRINT((ndo," proto=%d", proto)); - if (ntohs(n.type) < 8192) - ND_PRINT((ndo," type=%s", NOTIFY_ERROR_STR(ntohs(n.type)))); - else if (ntohs(n.type) < 16384) - ND_PRINT((ndo," type=%s", numstr(ntohs(n.type)))); - else if (ntohs(n.type) < 24576) - ND_PRINT((ndo," type=%s", NOTIFY_STATUS_STR(ntohs(n.type)))); + ND_PRINT(" doi=%u", doi); + ND_PRINT(" proto=%u", proto); + type = GET_BE_U_2(p->type); + if (type < 8192) + ND_PRINT(" type=%s", NOTIFY_ERROR_STR(type)); + else if (type < 16384) + ND_PRINT(" type=%s", numstr(type)); + else if (type < 24576) + ND_PRINT(" type=%s", NOTIFY_STATUS_STR(type)); else - ND_PRINT((ndo," type=%s", numstr(ntohs(n.type)))); - if (n.spi_size) { - ND_PRINT((ndo," spi=")); - if (!rawprint(ndo, (const uint8_t *)(p + 1), n.spi_size)) + ND_PRINT(" type=%s", numstr(type)); + spi_size = GET_U_1(p->spi_size); + if (spi_size) { + ND_PRINT(" spi="); + if (!rawprint(ndo, (const uint8_t *)(p + 1), spi_size)) goto trunc; } - return (const u_char *)(p + 1) + n.spi_size; - } - - ND_PRINT((ndo," doi=ipsec")); - ND_PRINT((ndo," proto=%s", PROTOIDSTR(proto))); - if (ntohs(n.type) < 8192) - ND_PRINT((ndo," type=%s", NOTIFY_ERROR_STR(ntohs(n.type)))); - else if (ntohs(n.type) < 16384) - ND_PRINT((ndo," type=%s", IPSEC_NOTIFY_ERROR_STR(ntohs(n.type)))); - else if (ntohs(n.type) < 24576) - ND_PRINT((ndo," type=%s", NOTIFY_STATUS_STR(ntohs(n.type)))); - else if (ntohs(n.type) < 32768) - ND_PRINT((ndo," type=%s", IPSEC_NOTIFY_STATUS_STR(ntohs(n.type)))); + return (const u_char *)(p + 1) + spi_size; + } + + ND_PRINT(" doi=ipsec"); + ND_PRINT(" proto=%s", PROTOIDSTR(proto)); + type = GET_BE_U_2(p->type); + if (type < 8192) + ND_PRINT(" type=%s", NOTIFY_ERROR_STR(type)); + else if (type < 16384) + ND_PRINT(" type=%s", IPSEC_NOTIFY_ERROR_STR(type)); + else if (type < 24576) + ND_PRINT(" type=%s", NOTIFY_STATUS_STR(type)); + else if (type < 32768) + ND_PRINT(" type=%s", IPSEC_NOTIFY_STATUS_STR(type)); else - ND_PRINT((ndo," type=%s", numstr(ntohs(n.type)))); - if (n.spi_size) { - ND_PRINT((ndo," spi=")); - if (!rawprint(ndo, (const uint8_t *)(p + 1), n.spi_size)) + ND_PRINT(" type=%s", numstr(type)); + spi_size = GET_U_1(p->spi_size); + if (spi_size) { + ND_PRINT(" spi="); + if (!rawprint(ndo, (const uint8_t *)(p + 1), spi_size)) goto trunc; } - cp = (const u_char *)(p + 1) + n.spi_size; + cp = (const u_char *)(p + 1) + spi_size; ep2 = (const u_char *)p + item_len; if (cp < ep) { - switch (ntohs(n.type)) { + switch (type) { case IPSECDOI_NTYPE_RESPONDER_LIFETIME: { const struct attrmap *map = oakley_t_map; size_t nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]); - ND_PRINT((ndo," attrs=(")); + ND_PRINT(" attrs=("); while (cp < ep && cp < ep2) { cp = ikev1_attrmap_print(ndo, cp, ep2, map, nmap); if (cp == NULL) { - ND_PRINT((ndo,")")); + ND_PRINT(")"); goto trunc; } } - ND_PRINT((ndo,")")); + ND_PRINT(")"); break; } case IPSECDOI_NTYPE_REPLAY_STATUS: - ND_PRINT((ndo," status=(")); - ND_TCHECK_32BITS(cp); - ND_PRINT((ndo,"replay detection %sabled", - EXTRACT_32BITS(cp) ? "en" : "dis")); - ND_PRINT((ndo,")")); + ND_PRINT(" status=("); + ND_PRINT("replay detection %sabled", + GET_BE_U_4(cp) ? "en" : "dis"); + ND_PRINT(")"); break; default: /* @@ -1780,10 +1780,10 @@ ikev1_n_print(netdissect_options *ndo, u_char tpay _U_, * draft-ietf-ipsec-notifymsg-04. */ if (ndo->ndo_vflag > 3) { - ND_PRINT((ndo," data=(")); + ND_PRINT(" data=("); if (!rawprint(ndo, (const uint8_t *)(cp), ep - cp)) goto trunc; - ND_PRINT((ndo,")")); + ND_PRINT(")"); } else { if (!ike_show_somedata(ndo, cp, ep)) goto trunc; @@ -1793,7 +1793,7 @@ ikev1_n_print(netdissect_options *ndo, u_char tpay _U_, } return (const u_char *)ext + item_len; trunc: - ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_N))); + ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_N)); return NULL; } @@ -1804,66 +1804,68 @@ ikev1_d_print(netdissect_options *ndo, u_char tpay _U_, uint32_t proto0 _U_, int depth _U_) { const struct ikev1_pl_d *p; - struct ikev1_pl_d d; const uint8_t *q; uint32_t doi; uint32_t proto; - int i; + uint8_t spi_size; + uint16_t num_spi; + u_int i; - ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_D))); + ND_PRINT("%s:", NPSTR(ISAKMP_NPTYPE_D)); p = (const struct ikev1_pl_d *)ext; - ND_TCHECK(*p); - UNALIGNED_MEMCPY(&d, ext, sizeof(d)); - doi = ntohl(d.doi); - proto = d.prot_id; + ND_TCHECK_SIZE(p); + doi = GET_BE_U_4(p->doi); + proto = GET_U_1(p->prot_id); if (doi != 1) { - ND_PRINT((ndo," doi=%u", doi)); - ND_PRINT((ndo," proto=%u", proto)); + ND_PRINT(" doi=%u", doi); + ND_PRINT(" proto=%u", proto); } else { - ND_PRINT((ndo," doi=ipsec")); - ND_PRINT((ndo," proto=%s", PROTOIDSTR(proto))); - } - ND_PRINT((ndo," spilen=%u", d.spi_size)); - ND_PRINT((ndo," nspi=%u", ntohs(d.num_spi))); - ND_PRINT((ndo," spi=")); + ND_PRINT(" doi=ipsec"); + ND_PRINT(" proto=%s", PROTOIDSTR(proto)); + } + spi_size = GET_U_1(p->spi_size); + ND_PRINT(" spilen=%u", spi_size); + num_spi = GET_BE_U_2(p->num_spi); + ND_PRINT(" nspi=%u", num_spi); + ND_PRINT(" spi="); q = (const uint8_t *)(p + 1); - for (i = 0; i < ntohs(d.num_spi); i++) { + for (i = 0; i < num_spi; i++) { if (i != 0) - ND_PRINT((ndo,",")); - if (!rawprint(ndo, (const uint8_t *)q, d.spi_size)) + ND_PRINT(","); + if (!rawprint(ndo, (const uint8_t *)q, spi_size)) goto trunc; - q += d.spi_size; + q += spi_size; } return q; trunc: - ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_D))); + ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_D)); return NULL; } static const u_char * ikev1_vid_print(netdissect_options *ndo, u_char tpay _U_, const struct isakmp_gen *ext, - u_int item_len _U_, const u_char *ep _U_, + u_int item_len, const u_char *ep _U_, uint32_t phase _U_, uint32_t doi _U_, uint32_t proto _U_, int depth _U_) { - struct isakmp_gen e; - - ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_VID))); + ND_PRINT("%s:", NPSTR(ISAKMP_NPTYPE_VID)); - ND_TCHECK(*ext); - UNALIGNED_MEMCPY(&e, ext, sizeof(e)); - ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); - if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { + ND_TCHECK_SIZE(ext); + /* + * Our caller has ensured that the length is >= 4. + */ + ND_PRINT(" len=%u", item_len - 4); + if (2 < ndo->ndo_vflag && 4 < item_len) { /* Print the entire payload in hex */ - ND_PRINT((ndo," ")); - if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4)) + ND_PRINT(" "); + if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4)) goto trunc; } - return (const u_char *)ext + ntohs(e.len); + return (const u_char *)ext + item_len; trunc: - ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_VID))); + ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_VID)); return NULL; } @@ -1874,31 +1876,33 @@ trunc: /************************************************************/ static void -ikev2_pay_print(netdissect_options *ndo, const char *payname, int critical) +ikev2_pay_print(netdissect_options *ndo, const char *payname, uint8_t critical) { - ND_PRINT((ndo,"%s%s:", payname, critical&0x80 ? "[C]" : "")); + ND_PRINT("%s%s:", payname, critical&0x80 ? "[C]" : ""); } static const u_char * ikev2_gen_print(netdissect_options *ndo, u_char tpay, - const struct isakmp_gen *ext) + const struct isakmp_gen *ext, u_int item_len) { - struct isakmp_gen e; + const struct isakmp_gen *p = (const struct isakmp_gen *)ext; - ND_TCHECK(*ext); - UNALIGNED_MEMCPY(&e, ext, sizeof(e)); - ikev2_pay_print(ndo, NPSTR(tpay), e.critical); + ND_TCHECK_SIZE(ext); + ikev2_pay_print(ndo, NPSTR(tpay), GET_U_1(p->critical)); - ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); - if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { + /* + * Our caller has ensured that the length is >= 4. + */ + ND_PRINT(" len=%u", item_len - 4); + if (2 < ndo->ndo_vflag && 4 < item_len) { /* Print the entire payload in hex */ - ND_PRINT((ndo," ")); - if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4)) + ND_PRINT(" "); + if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4)) goto trunc; } - return (const u_char *)ext + ntohs(e.len); + return (const u_char *)ext + item_len; trunc: - ND_PRINT((ndo," [|%s]", NPSTR(tpay))); + ND_PRINT(" [|%s]", NPSTR(tpay)); return NULL; } @@ -1908,8 +1912,8 @@ ikev2_t_print(netdissect_options *ndo, int tcount, const u_char *ep) { const struct ikev2_t *p; - struct ikev2_t t; uint16_t t_id; + uint8_t t_type; const u_char *cp; const char *idstr; const struct attrmap *map; @@ -1917,16 +1921,16 @@ ikev2_t_print(netdissect_options *ndo, int tcount, const u_char *ep2; p = (const struct ikev2_t *)ext; - ND_TCHECK(*p); - UNALIGNED_MEMCPY(&t, ext, sizeof(t)); - ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_T), t.h.critical); + ND_TCHECK_SIZE(p); + ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_T), GET_U_1(p->h.critical)); - t_id = ntohs(t.t_id); + t_id = GET_BE_U_2(p->t_id); map = NULL; nmap = 0; - switch (t.t_type) { + t_type = GET_U_1(p->t_type); + switch (t_type) { case IV2_T_ENCR: idstr = STR_OR_ID(t_id, esp_p_map); map = encr_t_map; @@ -1955,13 +1959,13 @@ ikev2_t_print(netdissect_options *ndo, int tcount, } if (idstr) - ND_PRINT((ndo," #%u type=%s id=%s ", tcount, - STR_OR_ID(t.t_type, ikev2_t_type_map), - idstr)); + ND_PRINT(" #%u type=%s id=%s ", tcount, + STR_OR_ID(t_type, ikev2_t_type_map), + idstr); else - ND_PRINT((ndo," #%u type=%s id=%u ", tcount, - STR_OR_ID(t.t_type, ikev2_t_type_map), - t.t_id)); + ND_PRINT(" #%u type=%s id=%u ", tcount, + STR_OR_ID(t_type, ikev2_t_type_map), + t_id); cp = (const u_char *)(p + 1); ep2 = (const u_char *)p + item_len; while (cp < ep && cp < ep2) { @@ -1973,10 +1977,10 @@ ikev2_t_print(netdissect_options *ndo, int tcount, goto trunc; } if (ep < ep2) - ND_PRINT((ndo,"...")); + ND_PRINT("..."); return cp; trunc: - ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_T))); + ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_T)); return NULL; } @@ -1986,51 +1990,49 @@ ikev2_p_print(netdissect_options *ndo, u_char tpay _U_, int pcount _U_, const u_char *ep, int depth) { const struct ikev2_p *p; - struct ikev2_p prop; u_int prop_length; + uint8_t spi_size; const u_char *cp; int i; int tcount; u_char np; - struct isakmp_gen e; u_int item_len; p = (const struct ikev2_p *)ext; - ND_TCHECK(*p); - UNALIGNED_MEMCPY(&prop, ext, sizeof(prop)); + ND_TCHECK_SIZE(p); - ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_P), prop.h.critical); + ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_P), GET_U_1(p->h.critical)); /* * ikev2_sa_print() guarantees that this is >= 4. */ prop_length = oprop_length - 4; - ND_PRINT((ndo," #%u protoid=%s transform=%d len=%u", - prop.p_no, PROTOIDSTR(prop.prot_id), - prop.num_t, oprop_length)); + ND_PRINT(" #%u protoid=%s transform=%u len=%u", + GET_U_1(p->p_no), PROTOIDSTR(GET_U_1(p->prot_id)), + GET_U_1(p->num_t), oprop_length); cp = (const u_char *)(p + 1); - if (prop.spi_size) { - if (prop_length < prop.spi_size) + spi_size = GET_U_1(p->spi_size); + if (spi_size) { + if (prop_length < spi_size) goto toolong; - ND_PRINT((ndo," spi=")); - if (!rawprint(ndo, (const uint8_t *)cp, prop.spi_size)) + ND_PRINT(" spi="); + if (!rawprint(ndo, (const uint8_t *)cp, spi_size)) goto trunc; - cp += prop.spi_size; - prop_length -= prop.spi_size; + cp += spi_size; + prop_length -= spi_size; } /* * Print the transforms. */ tcount = 0; - for (np = ISAKMP_NPTYPE_T; np != 0; np = e.np) { + for (np = ISAKMP_NPTYPE_T; np != 0; np = GET_U_1(ext->np)) { tcount++; ext = (const struct isakmp_gen *)cp; if (prop_length < sizeof(*ext)) goto toolong; - ND_TCHECK(*ext); - UNALIGNED_MEMCPY(&e, ext, sizeof(e)); + ND_TCHECK_SIZE(ext); /* * Since we can't have a payload length of less than 4 bytes, @@ -2038,19 +2040,19 @@ ikev2_p_print(netdissect_options *ndo, u_char tpay _U_, int pcount _U_, * or truncated, otherwise we could loop forever processing * zero-length items or otherwise misdissect the packet. */ - item_len = ntohs(e.len); + item_len = GET_BE_U_2(ext->len); if (item_len <= 4) goto trunc; if (prop_length < item_len) goto toolong; - ND_TCHECK2(*cp, item_len); + ND_TCHECK_LEN(cp, item_len); depth++; - ND_PRINT((ndo,"\n")); + ND_PRINT("\n"); for (i = 0; i < depth; i++) - ND_PRINT((ndo," ")); - ND_PRINT((ndo,"(")); + ND_PRINT(" "); + ND_PRINT("("); if (np == ISAKMP_NPTYPE_T) { cp = ikev2_t_print(ndo, tcount, ext, item_len, ep); if (cp == NULL) { @@ -2058,10 +2060,10 @@ ikev2_p_print(netdissect_options *ndo, u_char tpay _U_, int pcount _U_, return NULL; } } else { - ND_PRINT((ndo, "%s", NPSTR(np))); + ND_PRINT("%s", NPSTR(np)); cp += item_len; } - ND_PRINT((ndo,")")); + ND_PRINT(")"); depth--; prop_length -= item_len; } @@ -2071,10 +2073,10 @@ toolong: * Skip the rest of the proposal. */ cp += prop_length; - ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_P))); + ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_P)); return cp; trunc: - ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_P))); + ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_P)); return NULL; } @@ -2086,7 +2088,6 @@ ikev2_sa_print(netdissect_options *ndo, u_char tpay, uint32_t proto _U_, int depth) { const struct isakmp_gen *ext; - struct isakmp_gen e; u_int sa_length; const u_char *cp; int i; @@ -2094,29 +2095,27 @@ ikev2_sa_print(netdissect_options *ndo, u_char tpay, u_char np; u_int item_len; - ND_TCHECK(*ext1); - UNALIGNED_MEMCPY(&e, ext1, sizeof(e)); - ikev2_pay_print(ndo, "sa", e.critical); + ND_TCHECK_SIZE(ext1); + ikev2_pay_print(ndo, "sa", GET_U_1(ext1->critical)); /* * ikev2_sub0_print() guarantees that this is >= 4. */ - osa_length= ntohs(e.len); + osa_length= GET_BE_U_2(ext1->len); sa_length = osa_length - 4; - ND_PRINT((ndo," len=%d", sa_length)); + ND_PRINT(" len=%u", sa_length); /* * Print the payloads. */ cp = (const u_char *)(ext1 + 1); pcount = 0; - for (np = ISAKMP_NPTYPE_P; np != 0; np = e.np) { + for (np = ISAKMP_NPTYPE_P; np != 0; np = GET_U_1(ext->np)) { pcount++; ext = (const struct isakmp_gen *)cp; if (sa_length < sizeof(*ext)) goto toolong; - ND_TCHECK(*ext); - UNALIGNED_MEMCPY(&e, ext, sizeof(e)); + ND_TCHECK_SIZE(ext); /* * Since we can't have a payload length of less than 4 bytes, @@ -2124,19 +2123,19 @@ ikev2_sa_print(netdissect_options *ndo, u_char tpay, * or truncated, otherwise we could loop forever processing * zero-length items or otherwise misdissect the packet. */ - item_len = ntohs(e.len); + item_len = GET_BE_U_2(ext->len); if (item_len <= 4) goto trunc; if (sa_length < item_len) goto toolong; - ND_TCHECK2(*cp, item_len); + ND_TCHECK_LEN(cp, item_len); depth++; - ND_PRINT((ndo,"\n")); + ND_PRINT("\n"); for (i = 0; i < depth; i++) - ND_PRINT((ndo," ")); - ND_PRINT((ndo,"(")); + ND_PRINT(" "); + ND_PRINT("("); if (np == ISAKMP_NPTYPE_P) { cp = ikev2_p_print(ndo, np, pcount, ext, item_len, ep, depth); @@ -2145,10 +2144,10 @@ ikev2_sa_print(netdissect_options *ndo, u_char tpay, return NULL; } } else { - ND_PRINT((ndo, "%s", NPSTR(np))); + ND_PRINT("%s", NPSTR(np)); cp += item_len; } - ND_PRINT((ndo,")")); + ND_PRINT(")"); depth--; sa_length -= item_len; } @@ -2158,113 +2157,114 @@ toolong: * Skip the rest of the SA. */ cp += sa_length; - ND_PRINT((ndo," [|%s]", NPSTR(tpay))); + ND_PRINT(" [|%s]", NPSTR(tpay)); return cp; trunc: - ND_PRINT((ndo," [|%s]", NPSTR(tpay))); + ND_PRINT(" [|%s]", NPSTR(tpay)); return NULL; } static const u_char * ikev2_ke_print(netdissect_options *ndo, u_char tpay, const struct isakmp_gen *ext, - u_int item_len _U_, const u_char *ep _U_, + u_int item_len, const u_char *ep _U_, uint32_t phase _U_, uint32_t doi _U_, uint32_t proto _U_, int depth _U_) { - struct ikev2_ke ke; const struct ikev2_ke *k; k = (const struct ikev2_ke *)ext; - ND_TCHECK(*k); - UNALIGNED_MEMCPY(&ke, ext, sizeof(ke)); - ikev2_pay_print(ndo, NPSTR(tpay), ke.h.critical); + ND_TCHECK_SIZE(k); + ikev2_pay_print(ndo, NPSTR(tpay), GET_U_1(k->h.critical)); - ND_PRINT((ndo," len=%u group=%s", ntohs(ke.h.len) - 8, - STR_OR_ID(ntohs(ke.ke_group), dh_p_map))); + if (item_len < 8) { + ND_PRINT(" len=%u < 8", item_len); + return (const u_char *)ext + item_len; + } + ND_PRINT(" len=%u group=%s", item_len - 8, + STR_OR_ID(GET_BE_U_2(k->ke_group), dh_p_map)); - if (2 < ndo->ndo_vflag && 8 < ntohs(ke.h.len)) { - ND_PRINT((ndo," ")); - if (!rawprint(ndo, (const uint8_t *)(k + 1), ntohs(ke.h.len) - 8)) + if (2 < ndo->ndo_vflag && 8 < item_len) { + ND_PRINT(" "); + if (!rawprint(ndo, (const uint8_t *)(k + 1), item_len - 8)) goto trunc; } - return (const u_char *)ext + ntohs(ke.h.len); + return (const u_char *)ext + item_len; trunc: - ND_PRINT((ndo," [|%s]", NPSTR(tpay))); + ND_PRINT(" [|%s]", NPSTR(tpay)); return NULL; } static const u_char * ikev2_ID_print(netdissect_options *ndo, u_char tpay, const struct isakmp_gen *ext, - u_int item_len _U_, const u_char *ep _U_, + u_int item_len, const u_char *ep _U_, uint32_t phase _U_, uint32_t doi _U_, uint32_t proto _U_, int depth _U_) { const struct ikev2_id *idp; - struct ikev2_id id; - int id_len, idtype_len, i; + u_int idtype_len, i; unsigned int dumpascii, dumphex; const unsigned char *typedata; idp = (const struct ikev2_id *)ext; - ND_TCHECK(*idp); - UNALIGNED_MEMCPY(&id, ext, sizeof(id)); - ikev2_pay_print(ndo, NPSTR(tpay), id.h.critical); - - id_len = ntohs(id.h.len); + ND_TCHECK_SIZE(idp); + ikev2_pay_print(ndo, NPSTR(tpay), GET_U_1(idp->h.critical)); - ND_PRINT((ndo," len=%d", id_len - 4)); - if (2 < ndo->ndo_vflag && 4 < id_len) { + /* + * Our caller has ensured that the length is >= 4. + */ + ND_PRINT(" len=%u", item_len - 4); + if (2 < ndo->ndo_vflag && 4 < item_len) { /* Print the entire payload in hex */ - ND_PRINT((ndo," ")); - if (!rawprint(ndo, (const uint8_t *)(ext + 1), id_len - 4)) + ND_PRINT(" "); + if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4)) goto trunc; } - idtype_len =id_len - sizeof(struct ikev2_id); + idtype_len =item_len - sizeof(struct ikev2_id); dumpascii = 0; dumphex = 0; typedata = (const unsigned char *)(ext)+sizeof(struct ikev2_id); - switch(id.type) { + switch(GET_U_1(idp->type)) { case ID_IPV4_ADDR: - ND_PRINT((ndo, " ipv4:")); + ND_PRINT(" ipv4:"); dumphex=1; break; case ID_FQDN: - ND_PRINT((ndo, " fqdn:")); + ND_PRINT(" fqdn:"); dumpascii=1; break; case ID_RFC822_ADDR: - ND_PRINT((ndo, " rfc822:")); + ND_PRINT(" rfc822:"); dumpascii=1; break; case ID_IPV6_ADDR: - ND_PRINT((ndo, " ipv6:")); + ND_PRINT(" ipv6:"); dumphex=1; break; case ID_DER_ASN1_DN: - ND_PRINT((ndo, " dn:")); + ND_PRINT(" dn:"); dumphex=1; break; case ID_DER_ASN1_GN: - ND_PRINT((ndo, " gn:")); + ND_PRINT(" gn:"); dumphex=1; break; case ID_KEY_ID: - ND_PRINT((ndo, " keyid:")); + ND_PRINT(" keyid:"); dumphex=1; break; } if(dumpascii) { - ND_TCHECK2(*typedata, idtype_len); + ND_TCHECK_LEN(typedata, idtype_len); for(i=0; ih.critical)); /* * Our caller has ensured that the length is >= 4. */ - ND_PRINT((ndo," len=%u method=%s", len-4, - STR_OR_ID(a.auth_method, v2_auth))); - if (len > 4) { + ND_PRINT(" len=%u method=%s", item_len-4, + STR_OR_ID(GET_U_1(p->auth_method), v2_auth)); + if (item_len > 4) { if (ndo->ndo_vflag > 1) { - ND_PRINT((ndo, " authdata=(")); - if (!rawprint(ndo, (const uint8_t *)authdata, len - sizeof(a))) + ND_PRINT(" authdata=("); + if (!rawprint(ndo, (const uint8_t *)authdata, item_len - sizeof(struct ikev2_auth))) goto trunc; - ND_PRINT((ndo, ") ")); + ND_PRINT(") "); } else if (ndo->ndo_vflag) { if (!ike_show_somedata(ndo, authdata, ep)) goto trunc; } } - return (const u_char *)ext + len; + return (const u_char *)ext + item_len; trunc: - ND_PRINT((ndo," [|%s]", NPSTR(tpay))); + ND_PRINT(" [|%s]", NPSTR(tpay)); return NULL; } static const u_char * ikev2_nonce_print(netdissect_options *ndo, u_char tpay, const struct isakmp_gen *ext, - u_int item_len _U_, const u_char *ep, + u_int item_len, const u_char *ep, uint32_t phase _U_, uint32_t doi _U_, uint32_t proto _U_, int depth _U_) { - struct isakmp_gen e; - - ND_TCHECK(*ext); - UNALIGNED_MEMCPY(&e, ext, sizeof(e)); - ikev2_pay_print(ndo, "nonce", e.critical); + ND_TCHECK_SIZE(ext); + ikev2_pay_print(ndo, "nonce", GET_U_1(ext->critical)); - ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); - if (1 < ndo->ndo_vflag && 4 < ntohs(e.len)) { - ND_PRINT((ndo," nonce=(")); - if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4)) + /* + * Our caller has ensured that the length is >= 4. + */ + ND_PRINT(" len=%u", item_len - 4); + if (1 < ndo->ndo_vflag && 4 < item_len) { + ND_PRINT(" nonce=("); + if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4)) goto trunc; - ND_PRINT((ndo,") ")); - } else if(ndo->ndo_vflag && 4 < ntohs(e.len)) { + ND_PRINT(") "); + } else if(ndo->ndo_vflag && 4 < item_len) { if(!ike_show_somedata(ndo, (const u_char *)(ext+1), ep)) goto trunc; } - return (const u_char *)ext + ntohs(e.len); + return (const u_char *)ext + item_len; trunc: - ND_PRINT((ndo," [|%s]", NPSTR(tpay))); + ND_PRINT(" [|%s]", NPSTR(tpay)); return NULL; } @@ -2378,24 +2376,23 @@ ikev2_n_print(netdissect_options *ndo, u_char tpay _U_, uint32_t proto _U_, int depth _U_) { const struct ikev2_n *p; - struct ikev2_n n; + uint16_t type; + uint8_t spi_size; const u_char *cp; u_char showspi, showsomedata; const char *notify_name; - uint32_t type; p = (const struct ikev2_n *)ext; - ND_TCHECK(*p); - UNALIGNED_MEMCPY(&n, ext, sizeof(n)); - ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_N), n.h.critical); + ND_TCHECK_SIZE(p); + ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_N), GET_U_1(p->h.critical)); showspi = 1; showsomedata=0; notify_name=NULL; - ND_PRINT((ndo," prot_id=%s", PROTOIDSTR(n.prot_id))); + ND_PRINT(" prot_id=%s", PROTOIDSTR(GET_U_1(p->prot_id))); - type = ntohs(n.type); + type = GET_BE_U_2(p->type); /* notify space is annoying sparse */ switch(type) { @@ -2543,25 +2540,26 @@ ikev2_n_print(netdissect_options *ndo, u_char tpay _U_, } if(notify_name) { - ND_PRINT((ndo," type=%u(%s)", type, notify_name)); + ND_PRINT(" type=%u(%s)", type, notify_name); } - if (showspi && n.spi_size) { - ND_PRINT((ndo," spi=")); - if (!rawprint(ndo, (const uint8_t *)(p + 1), n.spi_size)) + spi_size = GET_U_1(p->spi_size); + if (showspi && spi_size) { + ND_PRINT(" spi="); + if (!rawprint(ndo, (const uint8_t *)(p + 1), spi_size)) goto trunc; } - cp = (const u_char *)(p + 1) + n.spi_size; + cp = (const u_char *)(p + 1) + spi_size; if (cp < ep) { if (ndo->ndo_vflag > 3 || (showsomedata && ep-cp < 30)) { - ND_PRINT((ndo," data=(")); + ND_PRINT(" data=("); if (!rawprint(ndo, (const uint8_t *)(cp), ep - cp)) goto trunc; - ND_PRINT((ndo,")")); + ND_PRINT(")"); } else if (showsomedata) { if (!ike_show_somedata(ndo, cp, ep)) goto trunc; @@ -2570,63 +2568,66 @@ ikev2_n_print(netdissect_options *ndo, u_char tpay _U_, return (const u_char *)ext + item_len; trunc: - ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_N))); + ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_N)); return NULL; } static const u_char * ikev2_d_print(netdissect_options *ndo, u_char tpay, const struct isakmp_gen *ext, - u_int item_len _U_, const u_char *ep _U_, + u_int item_len, const u_char *ep _U_, uint32_t phase _U_, uint32_t doi _U_, uint32_t proto _U_, int depth _U_) { - return ikev2_gen_print(ndo, tpay, ext); + return ikev2_gen_print(ndo, tpay, ext, item_len); } static const u_char * ikev2_vid_print(netdissect_options *ndo, u_char tpay, const struct isakmp_gen *ext, - u_int item_len _U_, const u_char *ep _U_, + u_int item_len, const u_char *ep _U_, uint32_t phase _U_, uint32_t doi _U_, uint32_t proto _U_, int depth _U_) { - struct isakmp_gen e; const u_char *vid; - int i, len; + u_int i, len; - ND_TCHECK(*ext); - UNALIGNED_MEMCPY(&e, ext, sizeof(e)); - ikev2_pay_print(ndo, NPSTR(tpay), e.critical); - ND_PRINT((ndo," len=%d vid=", ntohs(e.len) - 4)); + ND_TCHECK_SIZE(ext); + ikev2_pay_print(ndo, NPSTR(tpay), GET_U_1(ext->critical)); + + /* + * Our caller has ensured that the length is >= 4. + */ + ND_PRINT(" len=%u vid=", item_len - 4); vid = (const u_char *)(ext+1); - len = ntohs(e.len) - 4; - ND_TCHECK2(*vid, len); + len = item_len - 4; + ND_TCHECK_LEN(vid, len); for(i=0; indo_vflag && 4 < len) { /* Print the entire payload in hex */ - ND_PRINT((ndo," ")); - if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4)) + ND_PRINT(" "); + if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4)) goto trunc; } - return (const u_char *)ext + ntohs(e.len); + return (const u_char *)ext + item_len; trunc: - ND_PRINT((ndo," [|%s]", NPSTR(tpay))); + ND_PRINT(" [|%s]", NPSTR(tpay)); return NULL; } static const u_char * ikev2_TS_print(netdissect_options *ndo, u_char tpay, const struct isakmp_gen *ext, - u_int item_len _U_, const u_char *ep _U_, + u_int item_len, const u_char *ep _U_, uint32_t phase _U_, uint32_t doi _U_, uint32_t proto _U_, int depth _U_) { - return ikev2_gen_print(ndo, tpay, ext); + return ikev2_gen_print(ndo, tpay, ext, item_len); } static const u_char * @@ -2634,10 +2635,10 @@ ikev2_e_print(netdissect_options *ndo, #ifndef HAVE_LIBCRYPTO _U_ #endif - struct isakmp *base, + const struct isakmp *base, u_char tpay, const struct isakmp_gen *ext, - u_int item_len _U_, const u_char *ep _U_, + u_int item_len, const u_char *ep _U_, #ifndef HAVE_LIBCRYPTO _U_ #endif @@ -2655,38 +2656,48 @@ ikev2_e_print(netdissect_options *ndo, #endif int depth) { - struct isakmp_gen e; const u_char *dat; - volatile int dlen; + u_int dlen; +#ifdef HAVE_LIBCRYPTO + uint8_t np; +#endif - ND_TCHECK(*ext); - UNALIGNED_MEMCPY(&e, ext, sizeof(e)); - ikev2_pay_print(ndo, NPSTR(tpay), e.critical); + ND_TCHECK_SIZE(ext); + ikev2_pay_print(ndo, NPSTR(tpay), GET_U_1(ext->critical)); - dlen = ntohs(e.len)-4; + dlen = item_len-4; - ND_PRINT((ndo," len=%d", dlen)); + ND_PRINT(" len=%u", dlen); if (2 < ndo->ndo_vflag && 4 < dlen) { - ND_PRINT((ndo," ")); + ND_PRINT(" "); if (!rawprint(ndo, (const uint8_t *)(ext + 1), dlen)) goto trunc; } dat = (const u_char *)(ext+1); - ND_TCHECK2(*dat, dlen); + ND_TCHECK_LEN(dat, dlen); #ifdef HAVE_LIBCRYPTO - /* try to decypt it! */ - if(esp_print_decrypt_buffer_by_ikev2(ndo, - base->flags & ISAKMP_FLAG_I, + np = GET_U_1(ext->np); + + /* try to decrypt it! */ + if(esp_decrypt_buffer_by_ikev2_print(ndo, + GET_U_1(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); + ikev2_sub_print(ndo, base, np, ext, + ndo->ndo_snapend, phase, doi, proto, depth+1); + + /* + * esp_decrypt_buffer_by_ikev2_print pushed information + * on the buffer stack; we're done with the buffer, so + * pop it (which frees the buffer) + */ + nd_pop_packet_info(ndo); } #endif @@ -2696,28 +2707,28 @@ ikev2_e_print(netdissect_options *ndo, */ return NULL; trunc: - ND_PRINT((ndo," [|%s]", NPSTR(tpay))); + ND_PRINT(" [|%s]", NPSTR(tpay)); return NULL; } static const u_char * ikev2_cp_print(netdissect_options *ndo, u_char tpay, const struct isakmp_gen *ext, - u_int item_len _U_, const u_char *ep _U_, + u_int item_len, const u_char *ep _U_, uint32_t phase _U_, uint32_t doi _U_, uint32_t proto _U_, int depth _U_) { - return ikev2_gen_print(ndo, tpay, ext); + return ikev2_gen_print(ndo, tpay, ext, item_len); } static const u_char * ikev2_eap_print(netdissect_options *ndo, u_char tpay, const struct isakmp_gen *ext, - u_int item_len _U_, const u_char *ep _U_, + u_int item_len, const u_char *ep _U_, uint32_t phase _U_, uint32_t doi _U_, uint32_t proto _U_, int depth _U_) { - return ikev2_gen_print(ndo, tpay, ext); + return ikev2_gen_print(ndo, tpay, ext, item_len); } static const u_char * @@ -2727,12 +2738,10 @@ ike_sub0_print(netdissect_options *ndo, uint32_t phase, uint32_t doi, uint32_t proto, int depth) { const u_char *cp; - struct isakmp_gen e; u_int item_len; cp = (const u_char *)ext; - ND_TCHECK(*ext); - UNALIGNED_MEMCPY(&e, ext, sizeof(e)); + ND_TCHECK_SIZE(ext); /* * Since we can't have a payload length of less than 4 bytes, @@ -2740,7 +2749,7 @@ ike_sub0_print(netdissect_options *ndo, * or truncated, otherwise we could loop forever processing * zero-length items or otherwise misdissect the packet. */ - item_len = ntohs(e.len); + item_len = GET_BE_U_2(ext->len); if (item_len <= 4) return NULL; @@ -2751,13 +2760,13 @@ ike_sub0_print(netdissect_options *ndo, */ cp = (*npfunc[np])(ndo, np, ext, item_len, ep, phase, doi, proto, depth); } else { - ND_PRINT((ndo,"%s", NPSTR(np))); + ND_PRINT("%s", NPSTR(np)); cp += item_len; } return cp; trunc: - ND_PRINT((ndo," [|isakmp]")); + nd_print_trunc(ndo); return NULL; } @@ -2768,23 +2777,23 @@ ikev1_sub_print(netdissect_options *ndo, { const u_char *cp; int i; - struct isakmp_gen e; + u_int item_len; cp = (const u_char *)ext; while (np) { - ND_TCHECK(*ext); - UNALIGNED_MEMCPY(&e, ext, sizeof(e)); + ND_TCHECK_SIZE(ext); - ND_TCHECK2(*ext, ntohs(e.len)); + item_len = GET_BE_U_2(ext->len); + ND_TCHECK_LEN(ext, item_len); depth++; - ND_PRINT((ndo,"\n")); + ND_PRINT("\n"); for (i = 0; i < depth; i++) - ND_PRINT((ndo," ")); - ND_PRINT((ndo,"(")); + ND_PRINT(" "); + ND_PRINT("("); cp = ike_sub0_print(ndo, np, ext, ep, phase, doi, proto, depth); - ND_PRINT((ndo,")")); + ND_PRINT(")"); depth--; if (cp == NULL) { @@ -2792,110 +2801,111 @@ ikev1_sub_print(netdissect_options *ndo, return NULL; } - np = e.np; + np = GET_U_1(ext->np); ext = (const struct isakmp_gen *)cp; } return cp; trunc: - ND_PRINT((ndo," [|%s]", NPSTR(np))); + ND_PRINT(" [|%s]", NPSTR(np)); return NULL; } static char * -numstr(int x) +numstr(u_int x) { static char buf[20]; - snprintf(buf, sizeof(buf), "#%d", x); + snprintf(buf, sizeof(buf), "#%u", x); return buf; } static void ikev1_print(netdissect_options *ndo, const u_char *bp, u_int length, - const u_char *bp2, struct isakmp *base) + const u_char *bp2, const struct isakmp *base) { const struct isakmp *p; const u_char *ep; + u_int flags; u_char np; int i; - int phase; + u_int phase; p = (const struct isakmp *)bp; ep = ndo->ndo_snapend; - phase = (EXTRACT_32BITS(base->msgid) == 0) ? 1 : 2; + phase = (GET_BE_U_4(base->msgid) == 0) ? 1 : 2; if (phase == 1) - ND_PRINT((ndo," phase %d", phase)); + ND_PRINT(" phase %u", phase); else - ND_PRINT((ndo," phase %d/others", phase)); + ND_PRINT(" phase %u/others", phase); i = cookie_find(&base->i_ck); if (i < 0) { if (iszero((const u_char *)&base->r_ck, sizeof(base->r_ck))) { /* the first packet */ - ND_PRINT((ndo," I")); + ND_PRINT(" I"); if (bp2) - cookie_record(&base->i_ck, bp2); + cookie_record(ndo, &base->i_ck, bp2); } else - ND_PRINT((ndo," ?")); + ND_PRINT(" ?"); } else { - if (bp2 && cookie_isinitiator(i, bp2)) - ND_PRINT((ndo," I")); - else if (bp2 && cookie_isresponder(i, bp2)) - ND_PRINT((ndo," R")); + if (bp2 && cookie_isinitiator(ndo, i, bp2)) + ND_PRINT(" I"); + else if (bp2 && cookie_isresponder(ndo, i, bp2)) + ND_PRINT(" R"); else - ND_PRINT((ndo," ?")); + ND_PRINT(" ?"); } - ND_PRINT((ndo," %s", ETYPESTR(base->etype))); - if (base->flags) { - ND_PRINT((ndo,"[%s%s]", base->flags & ISAKMP_FLAG_E ? "E" : "", - base->flags & ISAKMP_FLAG_C ? "C" : "")); + ND_PRINT(" %s", ETYPESTR(GET_U_1(base->etype))); + flags = GET_U_1(base->flags); + if (flags) { + ND_PRINT("[%s%s]", flags & ISAKMP_FLAG_E ? "E" : "", + flags & ISAKMP_FLAG_C ? "C" : ""); } if (ndo->ndo_vflag) { const struct isakmp_gen *ext; - ND_PRINT((ndo,":")); + ND_PRINT(":"); + + np = GET_U_1(base->np); /* regardless of phase... */ - if (base->flags & ISAKMP_FLAG_E) { + if (flags & ISAKMP_FLAG_E) { /* * encrypted, nothing we can do right now. * we hope to decrypt the packet in the future... */ - ND_PRINT((ndo," [encrypted %s]", NPSTR(base->np))); + ND_PRINT(" [encrypted %s]", NPSTR(np)); goto done; } - CHECKLEN(p + 1, base->np); - np = base->np; + CHECKLEN(p + 1, np); ext = (const struct isakmp_gen *)(p + 1); ikev1_sub_print(ndo, np, ext, ep, phase, 0, 0, 0); } done: if (ndo->ndo_vflag) { - if (ntohl(base->len) != length) { - ND_PRINT((ndo," (len mismatch: isakmp %u/ip %u)", - (uint32_t)ntohl(base->len), length)); + if (GET_BE_U_4(base->len) != length) { + ND_PRINT(" (len mismatch: isakmp %u/ip %u)", + GET_BE_U_4(base->len), length); } } } static const u_char * -ikev2_sub0_print(netdissect_options *ndo, struct isakmp *base, +ikev2_sub0_print(netdissect_options *ndo, const struct isakmp *base, u_char np, const struct isakmp_gen *ext, const u_char *ep, uint32_t phase, uint32_t doi, uint32_t proto, int depth) { const u_char *cp; - struct isakmp_gen e; u_int item_len; cp = (const u_char *)ext; - ND_TCHECK(*ext); - UNALIGNED_MEMCPY(&e, ext, sizeof(e)); + ND_TCHECK_SIZE(ext); /* * Since we can't have a payload length of less than 4 bytes, @@ -2903,7 +2913,7 @@ ikev2_sub0_print(netdissect_options *ndo, struct isakmp *base, * or truncated, otherwise we could loop forever processing * zero-length items or otherwise misdissect the packet. */ - item_len = ntohs(e.len); + item_len = GET_BE_U_2(ext->len); if (item_len <= 4) return NULL; @@ -2918,41 +2928,39 @@ ikev2_sub0_print(netdissect_options *ndo, struct isakmp *base, cp = (*npfunc[np])(ndo, np, ext, item_len, ep, phase, doi, proto, depth); } else { - ND_PRINT((ndo,"%s", NPSTR(np))); + ND_PRINT("%s", NPSTR(np)); cp += item_len; } return cp; trunc: - ND_PRINT((ndo," [|isakmp]")); + nd_print_trunc(ndo); return NULL; } static const u_char * ikev2_sub_print(netdissect_options *ndo, - struct isakmp *base, + const struct isakmp *base, u_char np, const struct isakmp_gen *ext, const u_char *ep, uint32_t phase, uint32_t doi, uint32_t proto, int depth) { const u_char *cp; int i; - struct isakmp_gen e; cp = (const u_char *)ext; while (np) { - ND_TCHECK(*ext); - UNALIGNED_MEMCPY(&e, ext, sizeof(e)); + ND_TCHECK_SIZE(ext); - ND_TCHECK2(*ext, ntohs(e.len)); + ND_TCHECK_LEN(ext, GET_BE_U_2(ext->len)); depth++; - ND_PRINT((ndo,"\n")); + ND_PRINT("\n"); for (i = 0; i < depth; i++) - ND_PRINT((ndo," ")); - ND_PRINT((ndo,"(")); + ND_PRINT(" "); + ND_PRINT("("); cp = ikev2_sub0_print(ndo, base, np, ext, ep, phase, doi, proto, depth); - ND_PRINT((ndo,")")); + ND_PRINT(")"); depth--; if (cp == NULL) { @@ -2960,69 +2968,71 @@ ikev2_sub_print(netdissect_options *ndo, return NULL; } - np = e.np; + np = GET_U_1(ext->np); ext = (const struct isakmp_gen *)cp; } return cp; trunc: - ND_PRINT((ndo," [|%s]", NPSTR(np))); + ND_PRINT(" [|%s]", NPSTR(np)); return NULL; } static void ikev2_print(netdissect_options *ndo, const u_char *bp, u_int length, - const u_char *bp2 _U_, struct isakmp *base) + const u_char *bp2 _U_, const struct isakmp *base) { const struct isakmp *p; const u_char *ep; + uint8_t flags; u_char np; - int phase; + u_int phase; p = (const struct isakmp *)bp; ep = ndo->ndo_snapend; - phase = (EXTRACT_32BITS(base->msgid) == 0) ? 1 : 2; + phase = (GET_BE_U_4(base->msgid) == 0) ? 1 : 2; if (phase == 1) - ND_PRINT((ndo, " parent_sa")); + ND_PRINT(" parent_sa"); else - ND_PRINT((ndo, " child_sa ")); + ND_PRINT(" child_sa "); - ND_PRINT((ndo, " %s", ETYPESTR(base->etype))); - if (base->flags) { - ND_PRINT((ndo, "[%s%s%s]", - base->flags & ISAKMP_FLAG_I ? "I" : "", - base->flags & ISAKMP_FLAG_V ? "V" : "", - base->flags & ISAKMP_FLAG_R ? "R" : "")); + ND_PRINT(" %s", ETYPESTR(GET_U_1(base->etype))); + flags = GET_U_1(base->flags); + if (flags) { + ND_PRINT("[%s%s%s]", + flags & ISAKMP_FLAG_I ? "I" : "", + flags & ISAKMP_FLAG_V ? "V" : "", + flags & ISAKMP_FLAG_R ? "R" : ""); } if (ndo->ndo_vflag) { const struct isakmp_gen *ext; - ND_PRINT((ndo, ":")); + ND_PRINT(":"); + + np = GET_U_1(base->np); /* regardless of phase... */ - if (base->flags & ISAKMP_FLAG_E) { + if (flags & ISAKMP_FLAG_E) { /* * encrypted, nothing we can do right now. * we hope to decrypt the packet in the future... */ - ND_PRINT((ndo, " [encrypted %s]", NPSTR(base->np))); + ND_PRINT(" [encrypted %s]", NPSTR(np)); goto done; } - CHECKLEN(p + 1, base->np) - - np = base->np; + CHECKLEN(p + 1, np) ext = (const struct isakmp_gen *)(p + 1); ikev2_sub_print(ndo, base, np, ext, ep, phase, 0, 0, 0); } done: if (ndo->ndo_vflag) { - if (ntohl(base->len) != length) { - ND_PRINT((ndo, " (len mismatch: isakmp %u/ip %u)", - (uint32_t)ntohl(base->len), length)); + if (GET_BE_U_4(base->len) != length) { + ND_PRINT(" (len mismatch: isakmp %u/ip %u)", + GET_BE_U_4(base->len), length); } } } @@ -3033,15 +3043,15 @@ isakmp_print(netdissect_options *ndo, const u_char *bp2) { const struct isakmp *p; - struct isakmp base; const u_char *ep; - int major, minor; + u_int major, minor; + ndo->ndo_protocol = "isakmp"; #ifdef HAVE_LIBCRYPTO /* initialize SAs */ if (ndo->ndo_sa_list_head == NULL) { if (ndo->ndo_espsecret) - esp_print_decodesecret(ndo); + esp_decodesecret_print(ndo); } #endif @@ -3049,42 +3059,40 @@ isakmp_print(netdissect_options *ndo, ep = ndo->ndo_snapend; if ((const struct isakmp *)ep < p + 1) { - ND_PRINT((ndo,"[|isakmp]")); + nd_print_trunc(ndo); return; } - UNALIGNED_MEMCPY(&base, p, sizeof(base)); - - ND_PRINT((ndo,"isakmp")); - major = (base.vers & ISAKMP_VERS_MAJOR) + ND_PRINT("isakmp"); + major = (GET_U_1(p->vers) & ISAKMP_VERS_MAJOR) >> ISAKMP_VERS_MAJOR_SHIFT; - minor = (base.vers & ISAKMP_VERS_MINOR) + minor = (GET_U_1(p->vers) & ISAKMP_VERS_MINOR) >> ISAKMP_VERS_MINOR_SHIFT; if (ndo->ndo_vflag) { - ND_PRINT((ndo," %d.%d", major, minor)); + ND_PRINT(" %u.%u", major, minor); } if (ndo->ndo_vflag) { - ND_PRINT((ndo," msgid ")); - hexprint(ndo, (const uint8_t *)&base.msgid, sizeof(base.msgid)); + ND_PRINT(" msgid "); + hexprint(ndo, p->msgid, sizeof(p->msgid)); } if (1 < ndo->ndo_vflag) { - ND_PRINT((ndo," cookie ")); - hexprint(ndo, (const uint8_t *)&base.i_ck, sizeof(base.i_ck)); - ND_PRINT((ndo,"->")); - hexprint(ndo, (const uint8_t *)&base.r_ck, sizeof(base.r_ck)); + ND_PRINT(" cookie "); + hexprint(ndo, p->i_ck, sizeof(p->i_ck)); + ND_PRINT("->"); + hexprint(ndo, p->r_ck, sizeof(p->r_ck)); } - ND_PRINT((ndo,":")); + ND_PRINT(":"); switch(major) { case IKEv1_MAJOR_VERSION: - ikev1_print(ndo, bp, length, bp2, &base); + ikev1_print(ndo, bp, length, bp2, p); break; case IKEv2_MAJOR_VERSION: - ikev2_print(ndo, bp, length, bp2, &base); + ikev2_print(ndo, bp, length, bp2, p); break; } } @@ -3092,55 +3100,42 @@ isakmp_print(netdissect_options *ndo, void isakmp_rfc3948_print(netdissect_options *ndo, const u_char *bp, u_int length, - const u_char *bp2) + const u_char *bp2, int ver, int fragmented, u_int ttl_hl) { - ND_TCHECK(bp[0]); - if(length == 1 && bp[0]==0xff) { - ND_PRINT((ndo, "isakmp-nat-keep-alive")); + ndo->ndo_protocol = "isakmp_rfc3948"; + if(length == 1 && GET_U_1(bp)==0xff) { + ND_PRINT("isakmp-nat-keep-alive"); return; } if(length < 4) { goto trunc; } - ND_TCHECK(bp[3]); /* * see if this is an IKE packet */ - if(bp[0]==0 && bp[1]==0 && bp[2]==0 && bp[3]==0) { - ND_PRINT((ndo, "NONESP-encap: ")); + if (GET_BE_U_4(bp) == 0) { + ND_PRINT("NONESP-encap: "); isakmp_print(ndo, bp+4, length-4, bp2); return; } /* must be an ESP packet */ { - int nh, enh, padlen; - int advance; - - ND_PRINT((ndo, "UDP-encap: ")); + ND_PRINT("UDP-encap: "); - advance = esp_print(ndo, bp, length, bp2, &enh, &padlen); - if(advance <= 0) - return; + esp_print(ndo, bp, length, bp2, ver, fragmented, ttl_hl); - bp += advance; - length -= advance + padlen; - nh = enh & 0xff; - - ip_print_inner(ndo, bp, length, nh, bp2); + /* + * Either this has decrypted the payload and + * printed it, in which case there's nothing more + * to do, or it hasn't, in which case there's + * nothing more to do. + */ return; } trunc: - ND_PRINT((ndo,"[|isakmp]")); - return; + nd_print_trunc(ndo); } - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/print-isoclns.c b/contrib/tcpdump/print-isoclns.c index 5e08c3c2a5..ddd559532a 100644 --- a/contrib/tcpdump/print-isoclns.c +++ b/contrib/tcpdump/print-isoclns.c @@ -26,32 +26,38 @@ /* \summary: ISO CLNS, ESIS, and ISIS printer */ +/* + * specification: + * + * CLNP: ISO 8473 (respective ITU version is at https://www.itu.int/rec/T-REC-X.233/en/) + * ES-IS: ISO 9542 + * IS-IS: ISO 10589 + */ + #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include #include "netdissect.h" #include "addrtoname.h" -#include "ether.h" #include "nlpid.h" #include "extract.h" #include "gmpls.h" #include "oui.h" #include "signature.h" -static const char tstr[] = " [|isis]"; /* * IS-IS is defined in ISO 10589. Look there for protocol definitions. */ -#define SYSTEM_ID_LEN ETHER_ADDR_LEN -#define NODE_ID_LEN SYSTEM_ID_LEN+1 -#define LSP_ID_LEN SYSTEM_ID_LEN+2 +#define SYSTEM_ID_LEN MAC_ADDR_LEN +#define NODE_ID_LEN (SYSTEM_ID_LEN+1) +#define LSP_ID_LEN (SYSTEM_ID_LEN+2) #define ISIS_VERSION 1 #define ESIS_VERSION 1 @@ -66,10 +72,10 @@ static const char tstr[] = " [|isis]"; #define ISIS_PDU_L1_LAN_IIH 15 #define ISIS_PDU_L2_LAN_IIH 16 #define ISIS_PDU_PTP_IIH 17 -#define ISIS_PDU_L1_LSP 18 -#define ISIS_PDU_L2_LSP 20 -#define ISIS_PDU_L1_CSNP 24 -#define ISIS_PDU_L2_CSNP 25 +#define ISIS_PDU_L1_LSP 18 +#define ISIS_PDU_L2_LSP 20 +#define ISIS_PDU_L1_CSNP 24 +#define ISIS_PDU_L2_CSNP 25 #define ISIS_PDU_L1_PSNP 26 #define ISIS_PDU_L2_PSNP 27 @@ -100,7 +106,7 @@ static const struct tok isis_pdu_values[] = { #define ISIS_TLV_PART_DIS 4 /* iso10589 */ #define ISIS_TLV_PREFIX_NEIGH 5 /* iso10589 */ #define ISIS_TLV_ISNEIGH 6 /* iso10589 */ -#define ISIS_TLV_ISNEIGH_VARLEN 7 /* iso10589 */ +#define ISIS_TLV_INSTANCE_ID 7 /* rfc8202 */ #define ISIS_TLV_PADDING 8 /* iso10589 */ #define ISIS_TLV_LSP 9 /* iso10589 */ #define ISIS_TLV_AUTH 10 /* iso10589, rfc3567 */ @@ -108,20 +114,18 @@ static const struct tok isis_pdu_values[] = { #define ISIS_TLV_CHECKSUM_MINLEN 2 #define ISIS_TLV_POI 13 /* rfc6232 */ #define ISIS_TLV_LSP_BUFFERSIZE 14 /* iso10589 rev2 */ -#define ISIS_TLV_LSP_BUFFERSIZE_MINLEN 2 -#define ISIS_TLV_EXT_IS_REACH 22 /* draft-ietf-isis-traffic-05 */ -#define ISIS_TLV_IS_ALIAS_ID 24 /* draft-ietf-isis-ext-lsp-frags-02 */ +#define ISIS_TLV_EXT_IS_REACH 22 /* rfc5305 */ +#define ISIS_TLV_IS_ALIAS_ID 24 /* rfc5311 */ #define ISIS_TLV_DECNET_PHASE4 42 #define ISIS_TLV_LUCENT_PRIVATE 66 #define ISIS_TLV_INT_IP_REACH 128 /* rfc1195, rfc2966 */ #define ISIS_TLV_PROTOCOLS 129 /* rfc1195 */ #define ISIS_TLV_EXT_IP_REACH 130 /* rfc1195, rfc2966 */ #define ISIS_TLV_IDRP_INFO 131 /* rfc1195 */ -#define ISIS_TLV_IDRP_INFO_MINLEN 1 #define ISIS_TLV_IPADDR 132 /* rfc1195 */ #define ISIS_TLV_IPAUTH 133 /* rfc1195 */ -#define ISIS_TLV_TE_ROUTER_ID 134 /* draft-ietf-isis-traffic-05 */ -#define ISIS_TLV_EXTD_IP_REACH 135 /* draft-ietf-isis-traffic-05 */ +#define ISIS_TLV_TE_ROUTER_ID 134 /* rfc5305 */ +#define ISIS_TLV_EXTD_IP_REACH 135 /* rfc5305 */ #define ISIS_TLV_HOSTNAME 137 /* rfc2763 */ #define ISIS_TLV_SHARED_RISK_GROUP 138 /* draft-ietf-isis-gmpls-extensions */ #define ISIS_TLV_MT_PORT_CAP 143 /* rfc6165 */ @@ -133,14 +137,13 @@ static const struct tok isis_pdu_values[] = { #define ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN 2 #define ISIS_TLV_MT_IS_REACH 222 /* draft-ietf-isis-wg-multi-topology-05 */ #define ISIS_TLV_MT_SUPPORTED 229 /* draft-ietf-isis-wg-multi-topology-05 */ -#define ISIS_TLV_MT_SUPPORTED_MINLEN 2 #define ISIS_TLV_IP6ADDR 232 /* draft-ietf-isis-ipv6-02 */ #define ISIS_TLV_MT_IP_REACH 235 /* draft-ietf-isis-wg-multi-topology-05 */ #define ISIS_TLV_IP6_REACH 236 /* draft-ietf-isis-ipv6-02 */ #define ISIS_TLV_MT_IP6_REACH 237 /* draft-ietf-isis-wg-multi-topology-05 */ #define ISIS_TLV_PTP_ADJ 240 /* rfc3373 */ #define ISIS_TLV_IIH_SEQNR 241 /* draft-shen-isis-iih-sequence-00 */ -#define ISIS_TLV_IIH_SEQNR_MINLEN 4 +#define ISIS_TLV_ROUTER_CAPABILITY 242 /* rfc7981 */ #define ISIS_TLV_VENDOR_PRIVATE 250 /* draft-ietf-isis-experimental-tlv-01 */ #define ISIS_TLV_VENDOR_PRIVATE_MINLEN 3 @@ -151,7 +154,7 @@ static const struct tok isis_tlv_values[] = { { ISIS_TLV_PART_DIS, "Partition DIS"}, { ISIS_TLV_PREFIX_NEIGH, "Prefix Neighbors"}, { ISIS_TLV_ISNEIGH, "IS Neighbor(s)"}, - { ISIS_TLV_ISNEIGH_VARLEN, "IS Neighbor(s) (variable length)"}, + { ISIS_TLV_INSTANCE_ID, "Instance Identifier"}, { ISIS_TLV_PADDING, "Padding"}, { ISIS_TLV_LSP, "LSP entries"}, { ISIS_TLV_AUTH, "Authentication"}, @@ -185,6 +188,7 @@ static const struct tok isis_tlv_values[] = { { ISIS_TLV_MT_IP6_REACH, "Multi-Topology IP6 Reachability"}, { ISIS_TLV_PTP_ADJ, "Point-to-point Adjacency State"}, { ISIS_TLV_IIH_SEQNR, "Hello PDU Sequence Number"}, + { ISIS_TLV_ROUTER_CAPABILITY, "IS-IS Router Capability"}, { ISIS_TLV_VENDOR_PRIVATE, "Vendor Private"}, { 0, NULL } }; @@ -338,20 +342,40 @@ static const struct tok clnp_option_qos_global_values[] = { { 0, NULL } }; -#define ISIS_SUBTLV_EXT_IS_REACH_ADMIN_GROUP 3 /* draft-ietf-isis-traffic-05 */ +static const struct tok isis_tlv_router_capability_flags[] = { + { 0x01, "S bit"}, + { 0x02, "D bit"}, + { 0, NULL } +}; + +#define ISIS_SUBTLV_ROUTER_CAP_SR 2 /* rfc 8667 */ + +static const struct tok isis_router_capability_subtlv_values[] = { + { ISIS_SUBTLV_ROUTER_CAP_SR, "SR-Capabilities"}, + { 0, NULL } +}; + +static const struct tok isis_router_capability_sr_flags[] = { + { 0x80, "ipv4"}, + { 0x40, "ipv6"}, + { 0, NULL } +}; + +#define ISIS_SUBTLV_EXT_IS_REACH_ADMIN_GROUP 3 /* rfc5305 */ #define ISIS_SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID 4 /* rfc4205 */ -#define ISIS_SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID 5 /* draft-ietf-isis-traffic-05 */ -#define ISIS_SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR 6 /* draft-ietf-isis-traffic-05 */ -#define ISIS_SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR 8 /* draft-ietf-isis-traffic-05 */ -#define ISIS_SUBTLV_EXT_IS_REACH_MAX_LINK_BW 9 /* draft-ietf-isis-traffic-05 */ -#define ISIS_SUBTLV_EXT_IS_REACH_RESERVABLE_BW 10 /* draft-ietf-isis-traffic-05 */ +#define ISIS_SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID 5 /* rfc5305 */ +#define ISIS_SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR 6 /* rfc5305 */ +#define ISIS_SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR 8 /* rfc5305 */ +#define ISIS_SUBTLV_EXT_IS_REACH_MAX_LINK_BW 9 /* rfc5305 */ +#define ISIS_SUBTLV_EXT_IS_REACH_RESERVABLE_BW 10 /* rfc5305 */ #define ISIS_SUBTLV_EXT_IS_REACH_UNRESERVED_BW 11 /* rfc4124 */ #define ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD 12 /* draft-ietf-tewg-diff-te-proto-06 */ -#define ISIS_SUBTLV_EXT_IS_REACH_TE_METRIC 18 /* draft-ietf-isis-traffic-05 */ +#define ISIS_SUBTLV_EXT_IS_REACH_TE_METRIC 18 /* rfc5305 */ #define ISIS_SUBTLV_EXT_IS_REACH_LINK_ATTRIBUTE 19 /* draft-ietf-isis-link-attr-01 */ #define ISIS_SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE 20 /* rfc4205 */ #define ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR 21 /* rfc4205 */ #define ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS 22 /* rfc4124 */ +#define ISIS_SUBTLV_EXT_IS_REACH_LAN_ADJ_SEGMENT_ID 32 /* rfc8667 */ #define ISIS_SUBTLV_SPB_METRIC 29 /* rfc6329 */ @@ -370,6 +394,7 @@ static const struct tok isis_ext_is_reach_subtlv_values[] = { { ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR, "Interface Switching Capability" }, { ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD, "Bandwidth Constraints (old)" }, { ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS, "Bandwidth Constraints" }, + { ISIS_SUBTLV_EXT_IS_REACH_LAN_ADJ_SEGMENT_ID, "LAN Adjacency Segment Identifier" }, { ISIS_SUBTLV_SPB_METRIC, "SPB Metric" }, { 250, "Reserved for cisco specific extensions" }, { 251, "Reserved for cisco specific extensions" }, @@ -382,15 +407,42 @@ static const struct tok isis_ext_is_reach_subtlv_values[] = { #define ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG32 1 /* draft-ietf-isis-admin-tags-01 */ #define ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG64 2 /* draft-ietf-isis-admin-tags-01 */ +#define ISIS_SUBTLV_EXTD_IP_REACH_PREFIX_SID 3 /* rfc8667 */ #define ISIS_SUBTLV_EXTD_IP_REACH_MGMT_PREFIX_COLOR 117 /* draft-ietf-isis-wg-multi-topology-05 */ static const struct tok isis_ext_ip_reach_subtlv_values[] = { { ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG32, "32-Bit Administrative tag" }, { ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG64, "64-Bit Administrative tag" }, + { ISIS_SUBTLV_EXTD_IP_REACH_PREFIX_SID, "Prefix SID" }, { ISIS_SUBTLV_EXTD_IP_REACH_MGMT_PREFIX_COLOR, "Management Prefix Color" }, { 0, NULL } }; +#define ISIS_PREFIX_SID_FLAG_R 0x80 /* rfc 8667 */ +#define ISIS_PREFIX_SID_FLAG_N 0x40 /* rfc 8667 */ +#define ISIS_PREFIX_SID_FLAG_P 0x20 /* rfc 8667 */ +#define ISIS_PREFIX_SID_FLAG_E 0x10 /* rfc 8667 */ +#define ISIS_PREFIX_SID_FLAG_V 0x08 /* rfc 8667 */ +#define ISIS_PREFIX_SID_FLAG_L 0x04 /* rfc 8667 */ + +static const struct tok prefix_sid_flag_values[] = { + { ISIS_PREFIX_SID_FLAG_R, "Readvertisement"}, + { ISIS_PREFIX_SID_FLAG_N, "Node"}, + { ISIS_PREFIX_SID_FLAG_P, "No-PHP"}, + { ISIS_PREFIX_SID_FLAG_E, "Explicit NULL"}, + { ISIS_PREFIX_SID_FLAG_V, "Value"}, + { ISIS_PREFIX_SID_FLAG_L, "Local"}, + { 0, NULL} +}; + + +/* rfc 8667 */ +static const struct tok prefix_sid_algo_values[] = { + { 0, "SPF"}, + { 1, "strict-SPF"}, + { 0, NULL} +}; + static const struct tok isis_subtlv_link_attribute_values[] = { { 0x01, "Local Protection Available" }, { 0x02, "Link excluded from local protection path" }, @@ -398,6 +450,16 @@ static const struct tok isis_subtlv_link_attribute_values[] = { { 0, NULL } }; +static const struct tok isis_lan_adj_sid_flag_values[] = { + { 0x80, "Address family IPv6" }, + { 0x40, "Backup" }, + { 0x20, "Value" }, + { 0x10, "Local significance" }, + { 0x08, "Set of adjacencies" }, + { 0x04, "Persistent" }, + { 0, NULL } +}; + #define ISIS_SUBTLV_AUTH_SIMPLE 1 #define ISIS_SUBTLV_AUTH_GENERIC 3 /* rfc 5310 */ #define ISIS_SUBTLV_AUTH_MD5 54 @@ -451,10 +513,10 @@ static const struct tok isis_mt_capability_subtlv_values[] = { }; struct isis_spb_mcid { - uint8_t format_id; - uint8_t name[32]; - uint8_t revision_lvl[2]; - uint8_t digest[16]; + nd_uint8_t format_id; + nd_byte name[32]; + nd_uint16_t revision_lvl; + nd_byte digest[16]; }; struct isis_subtlv_spb_mcid { @@ -463,11 +525,11 @@ struct isis_subtlv_spb_mcid { }; struct isis_subtlv_spb_instance { - uint8_t cist_root_id[8]; - uint8_t cist_external_root_path_cost[4]; - uint8_t bridge_priority[2]; - uint8_t spsourceid[4]; - uint8_t no_of_trees; + nd_byte cist_root_id[8]; + nd_uint32_t cist_external_root_path_cost; + nd_uint16_t bridge_priority; + nd_uint32_t spsourceid; + nd_uint8_t no_of_trees; }; #define CLNP_SEGMENT_PART 0x80 @@ -481,14 +543,14 @@ static const struct tok clnp_flag_values[] = { { 0, NULL} }; -#define ISIS_MASK_LSP_OL_BIT(x) ((x)&0x4) -#define ISIS_MASK_LSP_ISTYPE_BITS(x) ((x)&0x3) -#define ISIS_MASK_LSP_PARTITION_BIT(x) ((x)&0x80) -#define ISIS_MASK_LSP_ATT_BITS(x) ((x)&0x78) -#define ISIS_MASK_LSP_ATT_ERROR_BIT(x) ((x)&0x40) -#define ISIS_MASK_LSP_ATT_EXPENSE_BIT(x) ((x)&0x20) -#define ISIS_MASK_LSP_ATT_DELAY_BIT(x) ((x)&0x10) -#define ISIS_MASK_LSP_ATT_DEFAULT_BIT(x) ((x)&0x8) +#define ISIS_MASK_LSP_OL_BIT(x) (GET_U_1(x)&0x4) +#define ISIS_MASK_LSP_ISTYPE_BITS(x) (GET_U_1(x)&0x3) +#define ISIS_MASK_LSP_PARTITION_BIT(x) (GET_U_1(x)&0x80) +#define ISIS_MASK_LSP_ATT_BITS(x) (GET_U_1(x)&0x78) +#define ISIS_MASK_LSP_ATT_ERROR_BIT(x) (GET_U_1(x)&0x40) +#define ISIS_MASK_LSP_ATT_EXPENSE_BIT(x) (GET_U_1(x)&0x20) +#define ISIS_MASK_LSP_ATT_DELAY_BIT(x) (GET_U_1(x)&0x10) +#define ISIS_MASK_LSP_ATT_DEFAULT_BIT(x) (GET_U_1(x)&0x8) #define ISIS_MASK_MTID(x) ((x)&0x0fff) #define ISIS_MASK_MTFLAGS(x) ((x)&0xf000) @@ -505,10 +567,10 @@ static const struct tok isis_mt_flag_values[] = { #define ISIS_MASK_TLV_EXTD_IP6_IE(x) ((x)&0x40) #define ISIS_MASK_TLV_EXTD_IP6_SUBTLV(x) ((x)&0x20) -#define ISIS_LSP_TLV_METRIC_SUPPORTED(x) ((x)&0x80) -#define ISIS_LSP_TLV_METRIC_IE(x) ((x)&0x40) -#define ISIS_LSP_TLV_METRIC_UPDOWN(x) ((x)&0x80) -#define ISIS_LSP_TLV_METRIC_VALUE(x) ((x)&0x3f) +#define ISIS_LSP_TLV_METRIC_SUPPORTED(x) (GET_U_1(x)&0x80) +#define ISIS_LSP_TLV_METRIC_IE(x) (GET_U_1(x)&0x40) +#define ISIS_LSP_TLV_METRIC_UPDOWN(x) (GET_U_1(x)&0x80) +#define ISIS_LSP_TLV_METRIC_VALUE(x) (GET_U_1(x)&0x3f) #define ISIS_MASK_TLV_SHARED_RISK_GROUP(x) ((x)&0x1) @@ -558,10 +620,10 @@ static const struct tok isis_ptp_adjancey_values[] = { }; struct isis_tlv_ptp_adj { - uint8_t adjacency_state; - uint8_t extd_local_circuit_id[4]; - uint8_t neighbor_sysid[SYSTEM_ID_LEN]; - uint8_t neighbor_extd_local_circuit_id[4]; + nd_uint8_t adjacency_state; + nd_uint32_t extd_local_circuit_id; + nd_byte neighbor_sysid[SYSTEM_ID_LEN]; + nd_uint32_t neighbor_extd_local_circuit_id; }; static void osi_print_cksum(netdissect_options *, const uint8_t *pptr, @@ -571,26 +633,26 @@ static void esis_print(netdissect_options *, const uint8_t *, u_int); static int isis_print(netdissect_options *, const uint8_t *, u_int); struct isis_metric_block { - uint8_t metric_default; - uint8_t metric_delay; - uint8_t metric_expense; - uint8_t metric_error; + nd_uint8_t metric_default; + nd_uint8_t metric_delay; + nd_uint8_t metric_expense; + nd_uint8_t metric_error; }; struct isis_tlv_is_reach { struct isis_metric_block isis_metric_block; - uint8_t neighbor_nodeid[NODE_ID_LEN]; + nd_byte neighbor_nodeid[NODE_ID_LEN]; }; struct isis_tlv_es_reach { struct isis_metric_block isis_metric_block; - uint8_t neighbor_sysid[SYSTEM_ID_LEN]; + nd_byte neighbor_sysid[SYSTEM_ID_LEN]; }; struct isis_tlv_ip_reach { struct isis_metric_block isis_metric_block; - uint8_t prefix[4]; - uint8_t mask[4]; + nd_ipv4 prefix; + nd_ipv4 mask; }; static const struct tok isis_is_reach_virtual_values[] = { @@ -607,59 +669,59 @@ static const struct tok isis_restart_flag_values[] = { }; struct isis_common_header { - uint8_t nlpid; - uint8_t fixed_len; - uint8_t version; /* Protocol version */ - uint8_t id_length; - uint8_t pdu_type; /* 3 MSbits are reserved */ - uint8_t pdu_version; /* Packet format version */ - uint8_t reserved; - uint8_t max_area; + nd_uint8_t nlpid; + nd_uint8_t fixed_len; + nd_uint8_t version; /* Protocol version */ + nd_uint8_t id_length; + nd_uint8_t pdu_type; /* 3 MSbits are reserved */ + nd_uint8_t pdu_version; /* Packet format version */ + nd_byte reserved; + nd_uint8_t max_area; }; struct isis_iih_lan_header { - uint8_t circuit_type; - uint8_t source_id[SYSTEM_ID_LEN]; - uint8_t holding_time[2]; - uint8_t pdu_len[2]; - uint8_t priority; - uint8_t lan_id[NODE_ID_LEN]; + nd_uint8_t circuit_type; + nd_byte source_id[SYSTEM_ID_LEN]; + nd_uint16_t holding_time; + nd_uint16_t pdu_len; + nd_uint8_t priority; + nd_byte lan_id[NODE_ID_LEN]; }; struct isis_iih_ptp_header { - uint8_t circuit_type; - uint8_t source_id[SYSTEM_ID_LEN]; - uint8_t holding_time[2]; - uint8_t pdu_len[2]; - uint8_t circuit_id; + nd_uint8_t circuit_type; + nd_byte source_id[SYSTEM_ID_LEN]; + nd_uint16_t holding_time; + nd_uint16_t pdu_len; + nd_uint8_t circuit_id; }; struct isis_lsp_header { - uint8_t pdu_len[2]; - uint8_t remaining_lifetime[2]; - uint8_t lsp_id[LSP_ID_LEN]; - uint8_t sequence_number[4]; - uint8_t checksum[2]; - uint8_t typeblock; + nd_uint16_t pdu_len; + nd_uint16_t remaining_lifetime; + nd_byte lsp_id[LSP_ID_LEN]; + nd_uint32_t sequence_number; + nd_uint16_t checksum; + nd_uint8_t typeblock; }; struct isis_csnp_header { - uint8_t pdu_len[2]; - uint8_t source_id[NODE_ID_LEN]; - uint8_t start_lsp_id[LSP_ID_LEN]; - uint8_t end_lsp_id[LSP_ID_LEN]; + nd_uint16_t pdu_len; + nd_byte source_id[NODE_ID_LEN]; + nd_byte start_lsp_id[LSP_ID_LEN]; + nd_byte end_lsp_id[LSP_ID_LEN]; }; struct isis_psnp_header { - uint8_t pdu_len[2]; - uint8_t source_id[NODE_ID_LEN]; + nd_uint16_t pdu_len; + nd_byte source_id[NODE_ID_LEN]; }; struct isis_tlv_lsp { - uint8_t remaining_lifetime[2]; - uint8_t lsp_id[LSP_ID_LEN]; - uint8_t sequence_number[4]; - uint8_t checksum[2]; + nd_uint16_t remaining_lifetime; + nd_byte lsp_id[LSP_ID_LEN]; + nd_uint32_t sequence_number; + nd_uint16_t checksum; }; #define ISIS_COMMON_HEADER_SIZE (sizeof(struct isis_common_header)) @@ -670,17 +732,16 @@ struct isis_tlv_lsp { #define ISIS_PSNP_HEADER_SIZE (sizeof(struct isis_psnp_header)) void -isoclns_print(netdissect_options *ndo, const uint8_t *p, u_int length) +isoclns_print(netdissect_options *ndo, const u_char *p, u_int length) { - if (!ND_TTEST(*p)) { /* enough bytes on the wire ? */ - ND_PRINT((ndo, "|OSI")); - return; - } + ndo->ndo_protocol = "isoclns"; if (ndo->ndo_eflag) - ND_PRINT((ndo, "OSI NLPID %s (0x%02x): ", tok2str(nlpid_values, "Unknown", *p), *p)); + ND_PRINT("OSI NLPID %s (0x%02x): ", + tok2str(nlpid_values, "Unknown", GET_U_1(p)), + GET_U_1(p)); - switch (*p) { + switch (GET_U_1(p)) { case NLPID_CLNP: if (!clnp_print(ndo, p, length)) @@ -697,7 +758,7 @@ isoclns_print(netdissect_options *ndo, const uint8_t *p, u_int length) break; case NLPID_NULLNS: - ND_PRINT((ndo, "%slength: %u", ndo->ndo_eflag ? "" : ", ", length)); + ND_PRINT("%slength: %u", ndo->ndo_eflag ? "" : ", ", length); break; case NLPID_Q933: @@ -718,8 +779,8 @@ isoclns_print(netdissect_options *ndo, const uint8_t *p, u_int length) default: if (!ndo->ndo_eflag) - ND_PRINT((ndo, "OSI NLPID 0x%02x unknown", *p)); - ND_PRINT((ndo, "%slength: %u", ndo->ndo_eflag ? "" : ", ", length)); + ND_PRINT("OSI NLPID 0x%02x unknown", GET_U_1(p)); + ND_PRINT("%slength: %u", ndo->ndo_eflag ? "" : ", ", length); if (length > 1) print_unknown_data(ndo, p, "\n\t", length); break; @@ -742,19 +803,19 @@ static const struct tok clnp_pdu_values[] = { }; struct clnp_header_t { - uint8_t nlpid; - uint8_t length_indicator; - uint8_t version; - uint8_t lifetime; /* units of 500ms */ - uint8_t type; - uint8_t segment_length[2]; - uint8_t cksum[2]; + nd_uint8_t nlpid; + nd_uint8_t length_indicator; + nd_uint8_t version; + nd_uint8_t lifetime; /* units of 500ms */ + nd_uint8_t type; + nd_uint16_t segment_length; + nd_uint16_t cksum; }; struct clnp_segment_header_t { - uint8_t data_unit_id[2]; - uint8_t segment_offset[2]; - uint8_t total_length[2]; + nd_uint16_t data_unit_id; + nd_uint16_t segment_offset; + nd_uint16_t total_length; }; /* @@ -767,161 +828,164 @@ clnp_print(netdissect_options *ndo, const uint8_t *pptr, u_int length) { const uint8_t *optr,*source_address,*dest_address; - u_int li,tlen,nsap_offset,source_address_length,dest_address_length, clnp_pdu_type, clnp_flags; + u_int li,li_remaining,tlen,nsap_offset,source_address_length,dest_address_length, clnp_pdu_type, clnp_flags; const struct clnp_header_t *clnp_header; const struct clnp_segment_header_t *clnp_segment_header; - uint8_t rfd_error_major,rfd_error_minor; + uint8_t rfd_error,rfd_error_major,rfd_error_minor; + ndo->ndo_protocol = "clnp"; clnp_header = (const struct clnp_header_t *) pptr; - ND_TCHECK(*clnp_header); + ND_TCHECK_SIZE(clnp_header); - li = clnp_header->length_indicator; + li = GET_U_1(clnp_header->length_indicator); + li_remaining = li; optr = pptr; if (!ndo->ndo_eflag) - ND_PRINT((ndo, "CLNP")); + nd_print_protocol_caps(ndo); /* * Sanity checking of the header. */ - if (clnp_header->version != CLNP_VERSION) { - ND_PRINT((ndo, "version %d packet not supported", clnp_header->version)); + if (GET_U_1(clnp_header->version) != CLNP_VERSION) { + ND_PRINT("version %u packet not supported", + GET_U_1(clnp_header->version)); return (0); } if (li > length) { - ND_PRINT((ndo, " length indicator(%u) > PDU size (%u)!", li, length)); + ND_PRINT(" length indicator(%u) > PDU size (%u)!", li, length); return (0); } if (li < sizeof(struct clnp_header_t)) { - ND_PRINT((ndo, " length indicator %u < min PDU size:", li)); - while (pptr < ndo->ndo_snapend) - ND_PRINT((ndo, "%02X", *pptr++)); + ND_PRINT(" length indicator %u < min PDU size:", li); + while (pptr < ndo->ndo_snapend) { + ND_PRINT("%02X", GET_U_1(pptr)); + pptr++; + } return (0); } /* FIXME further header sanity checking */ - clnp_pdu_type = clnp_header->type & CLNP_PDU_TYPE_MASK; - clnp_flags = clnp_header->type & CLNP_FLAG_MASK; + clnp_pdu_type = GET_U_1(clnp_header->type) & CLNP_PDU_TYPE_MASK; + clnp_flags = GET_U_1(clnp_header->type) & CLNP_FLAG_MASK; pptr += sizeof(struct clnp_header_t); - li -= sizeof(struct clnp_header_t); + li_remaining -= sizeof(struct clnp_header_t); - if (li < 1) { - ND_PRINT((ndo, "li < size of fixed part of CLNP header and addresses")); + if (li_remaining < 1) { + ND_PRINT("li < size of fixed part of CLNP header and addresses"); return (0); } - ND_TCHECK(*pptr); - dest_address_length = *pptr; + dest_address_length = GET_U_1(pptr); pptr += 1; - li -= 1; - if (li < dest_address_length) { - ND_PRINT((ndo, "li < size of fixed part of CLNP header and addresses")); + li_remaining -= 1; + if (li_remaining < dest_address_length) { + ND_PRINT("li < size of fixed part of CLNP header and addresses"); return (0); } - ND_TCHECK2(*pptr, dest_address_length); + ND_TCHECK_LEN(pptr, dest_address_length); dest_address = pptr; pptr += dest_address_length; - li -= dest_address_length; + li_remaining -= dest_address_length; - if (li < 1) { - ND_PRINT((ndo, "li < size of fixed part of CLNP header and addresses")); + if (li_remaining < 1) { + ND_PRINT("li < size of fixed part of CLNP header and addresses"); return (0); } - ND_TCHECK(*pptr); - source_address_length = *pptr; + source_address_length = GET_U_1(pptr); pptr += 1; - li -= 1; - if (li < source_address_length) { - ND_PRINT((ndo, "li < size of fixed part of CLNP header and addresses")); + li_remaining -= 1; + if (li_remaining < source_address_length) { + ND_PRINT("li < size of fixed part of CLNP header and addresses"); return (0); } - ND_TCHECK2(*pptr, source_address_length); + ND_TCHECK_LEN(pptr, source_address_length); source_address = pptr; pptr += source_address_length; - li -= source_address_length; + li_remaining -= source_address_length; if (ndo->ndo_vflag < 1) { - ND_PRINT((ndo, "%s%s > %s, %s, length %u", + ND_PRINT("%s%s > %s, %s, length %u", ndo->ndo_eflag ? "" : ", ", - isonsap_string(ndo, source_address, source_address_length), - isonsap_string(ndo, dest_address, dest_address_length), + GET_ISONSAP_STRING(source_address, source_address_length), + GET_ISONSAP_STRING(dest_address, dest_address_length), tok2str(clnp_pdu_values,"unknown (%u)",clnp_pdu_type), - length)); + length); return (1); } - ND_PRINT((ndo, "%slength %u", ndo->ndo_eflag ? "" : ", ", length)); + ND_PRINT("%slength %u", ndo->ndo_eflag ? "" : ", ", length); - ND_PRINT((ndo, "\n\t%s PDU, hlen: %u, v: %u, lifetime: %u.%us, Segment PDU length: %u, checksum: 0x%04x", + ND_PRINT("\n\t%s PDU, hlen: %u, v: %u, lifetime: %u.%us, Segment PDU length: %u, checksum: 0x%04x", tok2str(clnp_pdu_values, "unknown (%u)",clnp_pdu_type), - clnp_header->length_indicator, - clnp_header->version, - clnp_header->lifetime/2, - (clnp_header->lifetime%2)*5, - EXTRACT_16BITS(clnp_header->segment_length), - EXTRACT_16BITS(clnp_header->cksum))); + GET_U_1(clnp_header->length_indicator), + GET_U_1(clnp_header->version), + GET_U_1(clnp_header->lifetime)/2, + (GET_U_1(clnp_header->lifetime)%2)*5, + GET_BE_U_2(clnp_header->segment_length), + GET_BE_U_2(clnp_header->cksum)); - osi_print_cksum(ndo, optr, EXTRACT_16BITS(clnp_header->cksum), 7, - clnp_header->length_indicator); + osi_print_cksum(ndo, optr, GET_BE_U_2(clnp_header->cksum), 7, + GET_U_1(clnp_header->length_indicator)); - ND_PRINT((ndo, "\n\tFlags [%s]", - bittok2str(clnp_flag_values, "none", clnp_flags))); + ND_PRINT("\n\tFlags [%s]", + bittok2str(clnp_flag_values, "none", clnp_flags)); - ND_PRINT((ndo, "\n\tsource address (length %u): %s\n\tdest address (length %u): %s", + ND_PRINT("\n\tsource address (length %u): %s\n\tdest address (length %u): %s", source_address_length, - isonsap_string(ndo, source_address, source_address_length), + GET_ISONSAP_STRING(source_address, source_address_length), dest_address_length, - isonsap_string(ndo, dest_address, dest_address_length))); + GET_ISONSAP_STRING(dest_address, dest_address_length)); if (clnp_flags & CLNP_SEGMENT_PART) { - if (li < sizeof(const struct clnp_segment_header_t)) { - ND_PRINT((ndo, "li < size of fixed part of CLNP header, addresses, and segment part")); + if (li_remaining < sizeof(struct clnp_segment_header_t)) { + ND_PRINT("li < size of fixed part of CLNP header, addresses, and segment part"); return (0); } - clnp_segment_header = (const struct clnp_segment_header_t *) pptr; - ND_TCHECK(*clnp_segment_header); - ND_PRINT((ndo, "\n\tData Unit ID: 0x%04x, Segment Offset: %u, Total PDU Length: %u", - EXTRACT_16BITS(clnp_segment_header->data_unit_id), - EXTRACT_16BITS(clnp_segment_header->segment_offset), - EXTRACT_16BITS(clnp_segment_header->total_length))); - pptr+=sizeof(const struct clnp_segment_header_t); - li-=sizeof(const struct clnp_segment_header_t); + clnp_segment_header = (const struct clnp_segment_header_t *) pptr; + ND_TCHECK_SIZE(clnp_segment_header); + ND_PRINT("\n\tData Unit ID: 0x%04x, Segment Offset: %u, Total PDU Length: %u", + GET_BE_U_2(clnp_segment_header->data_unit_id), + GET_BE_U_2(clnp_segment_header->segment_offset), + GET_BE_U_2(clnp_segment_header->total_length)); + pptr+=sizeof(struct clnp_segment_header_t); + li_remaining-=sizeof(struct clnp_segment_header_t); } /* now walk the options */ - while (li >= 2) { + while (li_remaining != 0) { u_int op, opli; const uint8_t *tptr; - if (li < 2) { - ND_PRINT((ndo, ", bad opts/li")); + if (li_remaining < 2) { + ND_PRINT(", bad opts/li"); return (0); } - ND_TCHECK2(*pptr, 2); - op = *pptr++; - opli = *pptr++; - li -= 2; - if (opli > li) { - ND_PRINT((ndo, ", opt (%d) too long", op)); + op = GET_U_1(pptr); + opli = GET_U_1(pptr + 1); + pptr += 2; + li_remaining -= 2; + if (opli > li_remaining) { + ND_PRINT(", opt (%u) too long", op); return (0); } - ND_TCHECK2(*pptr, opli); - li -= opli; + ND_TCHECK_LEN(pptr, opli); + li_remaining -= opli; tptr = pptr; tlen = opli; - ND_PRINT((ndo, "\n\t %s Option #%u, length %u, value: ", + ND_PRINT("\n\t %s Option #%u, length %u, value: ", tok2str(clnp_option_values,"Unknown",op), op, - opli)); + opli); /* * We've already checked that the entire option is present - * in the captured packet with the ND_TCHECK2() call. - * Therefore, we don't need to do ND_TCHECK()/ND_TCHECK2() + * in the captured packet with the ND_TCHECK_LEN() call. + * Therefore, we don't need to do ND_TCHECK()/ND_TCHECK_LEN() * checks. * We do, however, need to check tlen, to make sure we * don't run past the end of the option. @@ -932,36 +996,35 @@ clnp_print(netdissect_options *ndo, case CLNP_OPTION_ROUTE_RECORDING: /* those two options share the format */ case CLNP_OPTION_SOURCE_ROUTING: if (tlen < 2) { - ND_PRINT((ndo, ", bad opt len")); + ND_PRINT(", bad opt len"); return (0); } - ND_PRINT((ndo, "%s %s", - tok2str(clnp_option_sr_rr_values,"Unknown",*tptr), - tok2str(clnp_option_sr_rr_string_values, "Unknown Option %u", op))); - nsap_offset=*(tptr+1); + ND_PRINT("%s %s", + tok2str(clnp_option_sr_rr_values,"Unknown",GET_U_1(tptr)), + tok2str(clnp_option_sr_rr_string_values, "Unknown Option %u", op)); + nsap_offset=GET_U_1(tptr + 1); if (nsap_offset == 0) { - ND_PRINT((ndo, " Bad NSAP offset (0)")); + ND_PRINT(" Bad NSAP offset (0)"); break; } nsap_offset-=1; /* offset to nsap list */ if (nsap_offset > tlen) { - ND_PRINT((ndo, " Bad NSAP offset (past end of option)")); + ND_PRINT(" Bad NSAP offset (past end of option)"); break; } tptr+=nsap_offset; tlen-=nsap_offset; while (tlen > 0) { - source_address_length=*tptr; + source_address_length=GET_U_1(tptr); if (tlen < source_address_length+1) { - ND_PRINT((ndo, "\n\t NSAP address goes past end of option")); + ND_PRINT("\n\t NSAP address goes past end of option"); break; } if (source_address_length > 0) { source_address=(tptr+1); - ND_TCHECK2(*source_address, source_address_length); - ND_PRINT((ndo, "\n\t NSAP address (length %u): %s", + ND_PRINT("\n\t NSAP address (length %u): %s", source_address_length, - isonsap_string(ndo, source_address, source_address_length))); + GET_ISONSAP_STRING(source_address, source_address_length)); } tlen-=source_address_length+1; } @@ -969,53 +1032,54 @@ clnp_print(netdissect_options *ndo, case CLNP_OPTION_PRIORITY: if (tlen < 1) { - ND_PRINT((ndo, ", bad opt len")); + ND_PRINT(", bad opt len"); return (0); } - ND_PRINT((ndo, "0x%1x", *tptr&0x0f)); + ND_PRINT("0x%1x", GET_U_1(tptr)&0x0f); break; case CLNP_OPTION_QOS_MAINTENANCE: if (tlen < 1) { - ND_PRINT((ndo, ", bad opt len")); + ND_PRINT(", bad opt len"); return (0); } - ND_PRINT((ndo, "\n\t Format Code: %s", - tok2str(clnp_option_scope_values, "Reserved", *tptr&CLNP_OPTION_SCOPE_MASK))); + ND_PRINT("\n\t Format Code: %s", + tok2str(clnp_option_scope_values, "Reserved", GET_U_1(tptr) & CLNP_OPTION_SCOPE_MASK)); - if ((*tptr&CLNP_OPTION_SCOPE_MASK) == CLNP_OPTION_SCOPE_GLOBAL) - ND_PRINT((ndo, "\n\t QoS Flags [%s]", + if ((GET_U_1(tptr)&CLNP_OPTION_SCOPE_MASK) == CLNP_OPTION_SCOPE_GLOBAL) + ND_PRINT("\n\t QoS Flags [%s]", bittok2str(clnp_option_qos_global_values, "none", - *tptr&CLNP_OPTION_OPTION_QOS_MASK))); + GET_U_1(tptr)&CLNP_OPTION_OPTION_QOS_MASK)); break; case CLNP_OPTION_SECURITY: if (tlen < 2) { - ND_PRINT((ndo, ", bad opt len")); + ND_PRINT(", bad opt len"); return (0); } - ND_PRINT((ndo, "\n\t Format Code: %s, Security-Level %u", - tok2str(clnp_option_scope_values,"Reserved",*tptr&CLNP_OPTION_SCOPE_MASK), - *(tptr+1))); + ND_PRINT("\n\t Format Code: %s, Security-Level %u", + tok2str(clnp_option_scope_values,"Reserved",GET_U_1(tptr)&CLNP_OPTION_SCOPE_MASK), + GET_U_1(tptr + 1)); break; case CLNP_OPTION_DISCARD_REASON: if (tlen < 1) { - ND_PRINT((ndo, ", bad opt len")); + ND_PRINT(", bad opt len"); return (0); } - rfd_error_major = (*tptr&0xf0) >> 4; - rfd_error_minor = *tptr&0x0f; - ND_PRINT((ndo, "\n\t Class: %s Error (0x%01x), %s (0x%01x)", + rfd_error = GET_U_1(tptr); + rfd_error_major = (rfd_error&0xf0) >> 4; + rfd_error_minor = rfd_error&0x0f; + ND_PRINT("\n\t Class: %s Error (0x%01x), %s (0x%01x)", tok2str(clnp_option_rfd_class_values,"Unknown",rfd_error_major), rfd_error_major, tok2str(clnp_option_rfd_error_class[rfd_error_major],"Unknown",rfd_error_minor), - rfd_error_minor)); + rfd_error_minor); break; case CLNP_OPTION_PADDING: - ND_PRINT((ndo, "padding data")); + ND_PRINT("padding data"); break; /* @@ -1035,31 +1099,42 @@ clnp_print(netdissect_options *ndo, switch (clnp_pdu_type) { case CLNP_PDU_ER: /* fall through */ - case CLNP_PDU_ERP: - ND_TCHECK(*pptr); - if (*(pptr) == NLPID_CLNP) { - ND_PRINT((ndo, "\n\t-----original packet-----\n\t")); + case CLNP_PDU_ERP: + if (GET_U_1(pptr) == NLPID_CLNP) { + ND_PRINT("\n\t-----original packet-----\n\t"); /* FIXME recursion protection */ - clnp_print(ndo, pptr, length - clnp_header->length_indicator); + clnp_print(ndo, pptr, length - li); break; } - case CLNP_PDU_DT: - case CLNP_PDU_MD: - case CLNP_PDU_ERQ: + /* The cases above break from the switch block if they see and print + * a CLNP header in the Data part. For an Error Report PDU this is + * described in Section 7.9.6 of ITU X.233 (1997 E), also known as + * ISO/IEC 8473-1:1998(E). It is not clear why in this code the same + * applies to an Echo Response PDU, as the standard does not specify + * the contents -- could be a proprietary extension or a bug. In either + * case, if the Data part does not contain a CLNP header, its structure + * is considered unknown and the decoding falls through to print the + * contents as-is. + */ + ND_FALL_THROUGH; + + case CLNP_PDU_DT: + case CLNP_PDU_MD: + case CLNP_PDU_ERQ: default: /* dump the PDU specific data */ - if (length-(pptr-optr) > 0) { - ND_PRINT((ndo, "\n\t undecoded non-header data, length %u", length-clnp_header->length_indicator)); - print_unknown_data(ndo, pptr, "\n\t ", length - (pptr - optr)); + if (length > ND_BYTES_BETWEEN(pptr, optr)) { + ND_PRINT("\n\t undecoded non-header data, length %u", length-li); + print_unknown_data(ndo, pptr, "\n\t ", length - ND_BYTES_BETWEEN(pptr, optr)); } } return (1); trunc: - ND_PRINT((ndo, "[|clnp]")); + nd_print_trunc(ndo); return (1); } @@ -1077,13 +1152,13 @@ static const struct tok esis_pdu_values[] = { }; struct esis_header_t { - uint8_t nlpid; - uint8_t length_indicator; - uint8_t version; - uint8_t reserved; - uint8_t type; - uint8_t holdtime[2]; - uint8_t cksum[2]; + nd_uint8_t nlpid; + nd_uint8_t length_indicator; + nd_uint8_t version; + nd_byte reserved; + nd_uint8_t type; + nd_uint16_t holdtime; + nd_uint16_t cksum; }; static void @@ -1091,70 +1166,76 @@ esis_print(netdissect_options *ndo, const uint8_t *pptr, u_int length) { const uint8_t *optr; - u_int li,esis_pdu_type,source_address_length, source_address_number; + u_int li, version, esis_pdu_type, source_address_length, source_address_number; const struct esis_header_t *esis_header; + ndo->ndo_protocol = "esis"; if (!ndo->ndo_eflag) - ND_PRINT((ndo, "ES-IS")); + ND_PRINT("ES-IS"); if (length <= 2) { - ND_PRINT((ndo, ndo->ndo_qflag ? "bad pkt!" : "no header at all!")); + ND_PRINT(ndo->ndo_qflag ? "bad pkt!" : "no header at all!"); return; } esis_header = (const struct esis_header_t *) pptr; - ND_TCHECK(*esis_header); - li = esis_header->length_indicator; + ND_TCHECK_SIZE(esis_header); + li = GET_U_1(esis_header->length_indicator); optr = pptr; /* * Sanity checking of the header. */ - if (esis_header->nlpid != NLPID_ESIS) { - ND_PRINT((ndo, " nlpid 0x%02x packet not supported", esis_header->nlpid)); + if (GET_U_1(esis_header->nlpid) != NLPID_ESIS) { + ND_PRINT(" nlpid 0x%02x packet not supported", + GET_U_1(esis_header->nlpid)); return; } - if (esis_header->version != ESIS_VERSION) { - ND_PRINT((ndo, " version %d packet not supported", esis_header->version)); + version = GET_U_1(esis_header->version); + if (version != ESIS_VERSION) { + ND_PRINT(" version %u packet not supported", version); return; } if (li > length) { - ND_PRINT((ndo, " length indicator(%u) > PDU size (%u)!", li, length)); + ND_PRINT(" length indicator(%u) > PDU size (%u)!", li, length); return; } if (li < sizeof(struct esis_header_t) + 2) { - ND_PRINT((ndo, " length indicator %u < min PDU size:", li)); - while (pptr < ndo->ndo_snapend) - ND_PRINT((ndo, "%02X", *pptr++)); + ND_PRINT(" length indicator %u < min PDU size:", li); + while (pptr < ndo->ndo_snapend) { + ND_PRINT("%02X", GET_U_1(pptr)); + pptr++; + } return; } - esis_pdu_type = esis_header->type & ESIS_PDU_TYPE_MASK; + esis_pdu_type = GET_U_1(esis_header->type) & ESIS_PDU_TYPE_MASK; if (ndo->ndo_vflag < 1) { - ND_PRINT((ndo, "%s%s, length %u", + ND_PRINT("%s%s, length %u", ndo->ndo_eflag ? "" : ", ", tok2str(esis_pdu_values,"unknown type (%u)",esis_pdu_type), - length)); + length); return; } else - ND_PRINT((ndo, "%slength %u\n\t%s (%u)", + ND_PRINT("%slength %u\n\t%s (%u)", ndo->ndo_eflag ? "" : ", ", length, tok2str(esis_pdu_values,"unknown type: %u", esis_pdu_type), - esis_pdu_type)); + esis_pdu_type); - ND_PRINT((ndo, ", v: %u%s", esis_header->version, esis_header->version == ESIS_VERSION ? "" : "unsupported" )); - ND_PRINT((ndo, ", checksum: 0x%04x", EXTRACT_16BITS(esis_header->cksum))); + ND_PRINT(", v: %u%s", version, version == ESIS_VERSION ? "" : "unsupported" ); + ND_PRINT(", checksum: 0x%04x", GET_BE_U_2(esis_header->cksum)); - osi_print_cksum(ndo, pptr, EXTRACT_16BITS(esis_header->cksum), 7, li); + osi_print_cksum(ndo, pptr, GET_BE_U_2(esis_header->cksum), 7, + li); - ND_PRINT((ndo, ", holding time: %us, length indicator: %u", - EXTRACT_16BITS(esis_header->holdtime), li)); + ND_PRINT(", holding time: %us, length indicator: %u", + GET_BE_U_2(esis_header->holdtime), li); if (ndo->ndo_vflag > 1) print_unknown_data(ndo, optr, "\n\t", sizeof(struct esis_header_t)); @@ -1167,101 +1248,101 @@ esis_print(netdissect_options *ndo, const uint8_t *dst, *snpa, *neta; u_int dstl, snpal, netal; - ND_TCHECK(*pptr); + ND_TCHECK_1(pptr); if (li < 1) { - ND_PRINT((ndo, ", bad redirect/li")); + ND_PRINT(", bad redirect/li"); return; } - dstl = *pptr; + dstl = GET_U_1(pptr); pptr++; li--; - ND_TCHECK2(*pptr, dstl); + ND_TCHECK_LEN(pptr, dstl); if (li < dstl) { - ND_PRINT((ndo, ", bad redirect/li")); + ND_PRINT(", bad redirect/li"); return; } dst = pptr; pptr += dstl; li -= dstl; - ND_PRINT((ndo, "\n\t %s", isonsap_string(ndo, dst, dstl))); + ND_PRINT("\n\t %s", GET_ISONSAP_STRING(dst, dstl)); - ND_TCHECK(*pptr); + ND_TCHECK_1(pptr); if (li < 1) { - ND_PRINT((ndo, ", bad redirect/li")); + ND_PRINT(", bad redirect/li"); return; } - snpal = *pptr; + snpal = GET_U_1(pptr); pptr++; li--; - ND_TCHECK2(*pptr, snpal); + ND_TCHECK_LEN(pptr, snpal); if (li < snpal) { - ND_PRINT((ndo, ", bad redirect/li")); + ND_PRINT(", bad redirect/li"); return; } snpa = pptr; pptr += snpal; li -= snpal; - ND_TCHECK(*pptr); + ND_TCHECK_1(pptr); if (li < 1) { - ND_PRINT((ndo, ", bad redirect/li")); + ND_PRINT(", bad redirect/li"); return; } - netal = *pptr; + netal = GET_U_1(pptr); pptr++; - ND_TCHECK2(*pptr, netal); + ND_TCHECK_LEN(pptr, netal); if (li < netal) { - ND_PRINT((ndo, ", bad redirect/li")); + ND_PRINT(", bad redirect/li"); return; } neta = pptr; pptr += netal; li -= netal; - if (snpal == 6) - ND_PRINT((ndo, "\n\t SNPA (length: %u): %s", + if (snpal == MAC_ADDR_LEN) + ND_PRINT("\n\t SNPA (length: %u): %s", snpal, - etheraddr_string(ndo, snpa))); + GET_ETHERADDR_STRING(snpa)); else - ND_PRINT((ndo, "\n\t SNPA (length: %u): %s", + ND_PRINT("\n\t SNPA (length: %u): %s", snpal, - linkaddr_string(ndo, snpa, LINKADDR_OTHER, snpal))); + GET_LINKADDR_STRING(snpa, LINKADDR_OTHER, snpal)); if (netal != 0) - ND_PRINT((ndo, "\n\t NET (length: %u) %s", + ND_PRINT("\n\t NET (length: %u) %s", netal, - isonsap_string(ndo, neta, netal))); + GET_ISONSAP_STRING(neta, netal)); break; } case ESIS_PDU_ESH: - ND_TCHECK(*pptr); + ND_TCHECK_1(pptr); if (li < 1) { - ND_PRINT((ndo, ", bad esh/li")); + ND_PRINT(", bad esh/li"); return; } - source_address_number = *pptr; + source_address_number = GET_U_1(pptr); pptr++; li--; - ND_PRINT((ndo, "\n\t Number of Source Addresses: %u", source_address_number)); + ND_PRINT("\n\t Number of Source Addresses: %u", source_address_number); while (source_address_number > 0) { - ND_TCHECK(*pptr); - if (li < 1) { - ND_PRINT((ndo, ", bad esh/li")); - return; - } - source_address_length = *pptr; + ND_TCHECK_1(pptr); + if (li < 1) { + ND_PRINT(", bad esh/li"); + return; + } + source_address_length = GET_U_1(pptr); pptr++; - li--; - - ND_TCHECK2(*pptr, source_address_length); - if (li < source_address_length) { - ND_PRINT((ndo, ", bad esh/li")); - return; - } - ND_PRINT((ndo, "\n\t NET (length: %u): %s", + li--; + + ND_TCHECK_LEN(pptr, source_address_length); + if (li < source_address_length) { + ND_PRINT(", bad esh/li"); + return; + } + ND_PRINT("\n\t NET (length: %u): %s", source_address_length, - isonsap_string(ndo, pptr, source_address_length))); + GET_ISONSAP_STRING(pptr, source_address_length)); pptr += source_address_length; li -= source_address_length; source_address_number--; @@ -1270,20 +1351,20 @@ esis_print(netdissect_options *ndo, break; case ESIS_PDU_ISH: { - ND_TCHECK(*pptr); + ND_TCHECK_1(pptr); if (li < 1) { - ND_PRINT((ndo, ", bad ish/li")); + ND_PRINT(", bad ish/li"); return; } - source_address_length = *pptr; + source_address_length = GET_U_1(pptr); pptr++; li--; - ND_TCHECK2(*pptr, source_address_length); + ND_TCHECK_LEN(pptr, source_address_length); if (li < source_address_length) { - ND_PRINT((ndo, ", bad ish/li")); + ND_PRINT(", bad ish/li"); return; } - ND_PRINT((ndo, "\n\t NET (length: %u): %s", source_address_length, isonsap_string(ndo, pptr, source_address_length))); + ND_PRINT("\n\t NET (length: %u): %s", source_address_length, GET_ISONSAP_STRING(pptr, source_address_length)); pptr += source_address_length; li -= source_address_length; break; @@ -1291,8 +1372,12 @@ esis_print(netdissect_options *ndo, default: if (ndo->ndo_vflag <= 1) { - if (pptr < ndo->ndo_snapend) - print_unknown_data(ndo, pptr, "\n\t ", ndo->ndo_snapend - pptr); + /* + * If there's at least one byte to print, print + * it/them. + */ + if (ND_TTEST_LEN(pptr, 1)) + print_unknown_data(ndo, pptr, "\n\t ", ND_BYTES_AVAILABLE_AFTER(pptr)); } return; } @@ -1303,45 +1388,44 @@ esis_print(netdissect_options *ndo, const uint8_t *tptr; if (li < 2) { - ND_PRINT((ndo, ", bad opts/li")); + ND_PRINT(", bad opts/li"); return; } - ND_TCHECK2(*pptr, 2); - op = *pptr++; - opli = *pptr++; + op = GET_U_1(pptr); + opli = GET_U_1(pptr + 1); + pptr += 2; li -= 2; if (opli > li) { - ND_PRINT((ndo, ", opt (%d) too long", op)); + ND_PRINT(", opt (%u) too long", op); return; } li -= opli; tptr = pptr; - ND_PRINT((ndo, "\n\t %s Option #%u, length %u, value: ", + ND_PRINT("\n\t %s Option #%u, length %u, value: ", tok2str(esis_option_values,"Unknown",op), op, - opli)); + opli); switch (op) { case ESIS_OPTION_ES_CONF_TIME: if (opli == 2) { - ND_TCHECK2(*pptr, 2); - ND_PRINT((ndo, "%us", EXTRACT_16BITS(tptr))); + ND_TCHECK_2(pptr); + ND_PRINT("%us", GET_BE_U_2(tptr)); } else - ND_PRINT((ndo, "(bad length)")); + ND_PRINT("(bad length)"); break; case ESIS_OPTION_PROTOCOLS: while (opli>0) { - ND_TCHECK(*tptr); - ND_PRINT((ndo, "%s (0x%02x)", + ND_PRINT("%s (0x%02x)", tok2str(nlpid_values, "unknown", - *tptr), - *tptr)); + GET_U_1(tptr)), + GET_U_1(tptr)); if (opli>1) /* further NPLIDs ? - put comma */ - ND_PRINT((ndo, ", ")); + ND_PRINT(", "); tptr++; opli--; } @@ -1366,8 +1450,10 @@ esis_print(netdissect_options *ndo, print_unknown_data(ndo, pptr, "\n\t ", opli); pptr += opli; } + return; + trunc: - ND_PRINT((ndo, "[|esis]")); + nd_print_trunc(ndo); } static void @@ -1376,75 +1462,75 @@ isis_print_mcid(netdissect_options *ndo, { int i; - ND_TCHECK(*mcid); - ND_PRINT((ndo, "ID: %d, Name: ", mcid->format_id)); + ND_TCHECK_SIZE(mcid); + ND_PRINT("ID: %u, Name: ", GET_U_1(mcid->format_id)); - if (fn_printzp(ndo, mcid->name, 32, ndo->ndo_snapend)) - goto trunc; + nd_printjnp(ndo, mcid->name, sizeof(mcid->name)); - ND_PRINT((ndo, "\n\t Lvl: %d", EXTRACT_16BITS(mcid->revision_lvl))); + ND_PRINT("\n\t Lvl: %u", GET_BE_U_2(mcid->revision_lvl)); - ND_PRINT((ndo, ", Digest: ")); + ND_PRINT(", Digest: "); for(i=0;i<16;i++) - ND_PRINT((ndo, "%.2x ", mcid->digest[i])); + ND_PRINT("%.2x ", mcid->digest[i]); + return; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); } static int isis_print_mt_port_cap_subtlv(netdissect_options *ndo, - const uint8_t *tptr, int len) + const uint8_t *tptr, u_int len) { - int stlv_type, stlv_len; + u_int stlv_type, stlv_len; const struct isis_subtlv_spb_mcid *subtlv_spb_mcid; int i; while (len > 2) { - ND_TCHECK2(*tptr, 2); - stlv_type = *(tptr++); - stlv_len = *(tptr++); + stlv_type = GET_U_1(tptr); + stlv_len = GET_U_1(tptr + 1); /* first lets see if we know the subTLVs name*/ - ND_PRINT((ndo, "\n\t %s subTLV #%u, length: %u", + ND_PRINT("\n\t %s subTLV #%u, length: %u", tok2str(isis_mt_port_cap_subtlv_values, "unknown", stlv_type), stlv_type, - stlv_len)); + stlv_len); + tptr += 2; /*len -= TLV_TYPE_LEN_OFFSET;*/ - len = len -2; + len -= 2; /* Make sure the subTLV fits within the space left */ if (len < stlv_len) - goto trunc; + goto subtlv_too_long; /* Make sure the entire subTLV is in the captured data */ - ND_TCHECK2(*(tptr), stlv_len); + ND_TCHECK_LEN(tptr, stlv_len); switch (stlv_type) { case ISIS_SUBTLV_SPB_MCID: { - if (stlv_len < ISIS_SUBTLV_SPB_MCID_MIN_LEN) - goto trunc; + if (stlv_len < ISIS_SUBTLV_SPB_MCID_MIN_LEN) + goto subtlv_too_short; subtlv_spb_mcid = (const struct isis_subtlv_spb_mcid *)tptr; - ND_PRINT((ndo, "\n\t MCID: ")); + ND_PRINT("\n\t MCID: "); isis_print_mcid(ndo, &(subtlv_spb_mcid->mcid)); /*tptr += SPB_MCID_MIN_LEN; len -= SPB_MCID_MIN_LEN; */ - ND_PRINT((ndo, "\n\t AUX-MCID: ")); + ND_PRINT("\n\t AUX-MCID: "); isis_print_mcid(ndo, &(subtlv_spb_mcid->aux_mcid)); /*tptr += SPB_MCID_MIN_LEN; len -= SPB_MCID_MIN_LEN; */ - tptr = tptr + ISIS_SUBTLV_SPB_MCID_MIN_LEN; - len = len - ISIS_SUBTLV_SPB_MCID_MIN_LEN; - stlv_len = stlv_len - ISIS_SUBTLV_SPB_MCID_MIN_LEN; + tptr += ISIS_SUBTLV_SPB_MCID_MIN_LEN; + len -= ISIS_SUBTLV_SPB_MCID_MIN_LEN; + stlv_len -= ISIS_SUBTLV_SPB_MCID_MIN_LEN; break; } @@ -1452,47 +1538,55 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo, case ISIS_SUBTLV_SPB_DIGEST: { if (stlv_len < ISIS_SUBTLV_SPB_DIGEST_MIN_LEN) - goto trunc; + goto subtlv_too_short; - ND_PRINT((ndo, "\n\t RES: %d V: %d A: %d D: %d", - (*(tptr) >> 5), (((*tptr)>> 4) & 0x01), - ((*(tptr) >> 2) & 0x03), ((*tptr) & 0x03))); + ND_PRINT("\n\t RES: %u V: %u A: %u D: %u", + (GET_U_1(tptr) >> 5), + ((GET_U_1(tptr) >> 4) & 0x01), + ((GET_U_1(tptr) >> 2) & 0x03), + (GET_U_1(tptr) & 0x03)); tptr++; - ND_PRINT((ndo, "\n\t Digest: ")); + ND_PRINT("\n\t Digest: "); for(i=1;i<=8; i++) { - ND_PRINT((ndo, "%08x ", EXTRACT_32BITS(tptr))); + ND_PRINT("%08x ", GET_BE_U_4(tptr)); if (i%4 == 0 && i != 8) - ND_PRINT((ndo, "\n\t ")); - tptr = tptr + 4; + ND_PRINT("\n\t "); + tptr += 4; } - len = len - ISIS_SUBTLV_SPB_DIGEST_MIN_LEN; - stlv_len = stlv_len - ISIS_SUBTLV_SPB_DIGEST_MIN_LEN; + len -= ISIS_SUBTLV_SPB_DIGEST_MIN_LEN; + stlv_len -= ISIS_SUBTLV_SPB_DIGEST_MIN_LEN; break; } case ISIS_SUBTLV_SPB_BVID: { - while (stlv_len >= ISIS_SUBTLV_SPB_BVID_MIN_LEN) + while (stlv_len != 0) { - ND_PRINT((ndo, "\n\t ECT: %08x", - EXTRACT_32BITS(tptr))); - - tptr = tptr+4; - - ND_PRINT((ndo, " BVID: %d, U:%01x M:%01x ", - (EXTRACT_16BITS (tptr) >> 4) , - (EXTRACT_16BITS (tptr) >> 3) & 0x01, - (EXTRACT_16BITS (tptr) >> 2) & 0x01)); - - tptr = tptr + 2; - len = len - ISIS_SUBTLV_SPB_BVID_MIN_LEN; - stlv_len = stlv_len - ISIS_SUBTLV_SPB_BVID_MIN_LEN; + if (stlv_len < 4) + goto subtlv_too_short; + ND_PRINT("\n\t ECT: %08x", + GET_BE_U_4(tptr)); + + tptr += 4; + len -= 4; + stlv_len -= 4; + + if (stlv_len < 2) + goto subtlv_too_short; + ND_PRINT(" BVID: %u, U:%01x M:%01x ", + (GET_BE_U_2(tptr) >> 4) , + (GET_BE_U_2(tptr) >> 3) & 0x01, + (GET_BE_U_2(tptr) >> 2) & 0x01); + + tptr += 2; + len -= 2; + stlv_len -= 2; } break; @@ -1504,92 +1598,100 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo, tptr += stlv_len; len -= stlv_len; } + return (0); + +trunc: + nd_print_trunc(ndo); + return (1); - return 0; +subtlv_too_long: + ND_PRINT(" (> containing TLV length)"); + return (1); - trunc: - ND_PRINT((ndo, "\n\t\t")); - ND_PRINT((ndo, "%s", tstr)); - return(1); +subtlv_too_short: + ND_PRINT(" (too short)"); + return (1); } static int isis_print_mt_capability_subtlv(netdissect_options *ndo, - const uint8_t *tptr, int len) + const uint8_t *tptr, u_int len) { - int stlv_type, stlv_len, tmp; + u_int stlv_type, stlv_len, treecount; while (len > 2) { - ND_TCHECK2(*tptr, 2); - stlv_type = *(tptr++); - stlv_len = *(tptr++); + stlv_type = GET_U_1(tptr); + stlv_len = GET_U_1(tptr + 1); + tptr += 2; + len -= 2; /* first lets see if we know the subTLVs name*/ - ND_PRINT((ndo, "\n\t %s subTLV #%u, length: %u", + ND_PRINT("\n\t %s subTLV #%u, length: %u", tok2str(isis_mt_capability_subtlv_values, "unknown", stlv_type), stlv_type, - stlv_len)); - - len = len - 2; + stlv_len); /* Make sure the subTLV fits within the space left */ if (len < stlv_len) - goto trunc; + goto subtlv_too_long; /* Make sure the entire subTLV is in the captured data */ - ND_TCHECK2(*(tptr), stlv_len); + ND_TCHECK_LEN(tptr, stlv_len); switch (stlv_type) { case ISIS_SUBTLV_SPB_INSTANCE: if (stlv_len < ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN) - goto trunc; - - ND_PRINT((ndo, "\n\t CIST Root-ID: %08x", EXTRACT_32BITS(tptr))); - tptr = tptr+4; - ND_PRINT((ndo, " %08x", EXTRACT_32BITS(tptr))); - tptr = tptr+4; - ND_PRINT((ndo, ", Path Cost: %08x", EXTRACT_32BITS(tptr))); - tptr = tptr+4; - ND_PRINT((ndo, ", Prio: %d", EXTRACT_16BITS(tptr))); - tptr = tptr + 2; - ND_PRINT((ndo, "\n\t RES: %d", - EXTRACT_16BITS(tptr) >> 5)); - ND_PRINT((ndo, ", V: %d", - (EXTRACT_16BITS(tptr) >> 4) & 0x0001)); - ND_PRINT((ndo, ", SPSource-ID: %d", - (EXTRACT_32BITS(tptr) & 0x000fffff))); - tptr = tptr+4; - ND_PRINT((ndo, ", No of Trees: %x", *(tptr))); - - tmp = *(tptr++); - - len = len - ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN; - stlv_len = stlv_len - ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN; - - while (tmp) + goto subtlv_too_short; + + ND_PRINT("\n\t CIST Root-ID: %08x", GET_BE_U_4(tptr)); + tptr += 4; + ND_PRINT(" %08x", GET_BE_U_4(tptr)); + tptr += 4; + ND_PRINT(", Path Cost: %08x", GET_BE_U_4(tptr)); + tptr += 4; + ND_PRINT(", Prio: %u", GET_BE_U_2(tptr)); + tptr += 2; + ND_PRINT("\n\t RES: %u", + GET_BE_U_2(tptr) >> 5); + ND_PRINT(", V: %u", + (GET_BE_U_2(tptr) >> 4) & 0x0001); + ND_PRINT(", SPSource-ID: %u", + (GET_BE_U_4(tptr) & 0x000fffff)); + tptr += 4; + ND_PRINT(", No of Trees: %x", GET_U_1(tptr)); + + treecount = GET_U_1(tptr); + tptr++; + + len -= ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN; + stlv_len -= ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN; + + while (treecount) { if (stlv_len < ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN) goto trunc; - ND_PRINT((ndo, "\n\t U:%d, M:%d, A:%d, RES:%d", - *(tptr) >> 7, (*(tptr) >> 6) & 0x01, - (*(tptr) >> 5) & 0x01, (*(tptr) & 0x1f))); + ND_PRINT("\n\t U:%u, M:%u, A:%u, RES:%u", + GET_U_1(tptr) >> 7, + (GET_U_1(tptr) >> 6) & 0x01, + (GET_U_1(tptr) >> 5) & 0x01, + (GET_U_1(tptr) & 0x1f)); tptr++; - ND_PRINT((ndo, ", ECT: %08x", EXTRACT_32BITS(tptr))); + ND_PRINT(", ECT: %08x", GET_BE_U_4(tptr)); - tptr = tptr + 4; + tptr += 4; - ND_PRINT((ndo, ", BVID: %d, SPVID: %d", - (EXTRACT_24BITS(tptr) >> 12) & 0x000fff, - EXTRACT_24BITS(tptr) & 0x000fff)); + ND_PRINT(", BVID: %u, SPVID: %u", + (GET_BE_U_3(tptr) >> 12) & 0x000fff, + GET_BE_U_3(tptr) & 0x000fff); - tptr = tptr + 3; - len = len - ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN; - stlv_len = stlv_len - ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN; - tmp--; + tptr += 3; + len -= ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN; + stlv_len -= ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN; + treecount--; } break; @@ -1598,29 +1700,28 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo, if (stlv_len < 8) goto trunc; - ND_PRINT((ndo, "\n\t BMAC: %08x", EXTRACT_32BITS(tptr))); - tptr = tptr+4; - ND_PRINT((ndo, "%04x", EXTRACT_16BITS(tptr))); - tptr = tptr+2; + ND_PRINT("\n\t BMAC: %08x", GET_BE_U_4(tptr)); + tptr += 4; + ND_PRINT("%04x", GET_BE_U_2(tptr)); + tptr += 2; - ND_PRINT((ndo, ", RES: %d, VID: %d", EXTRACT_16BITS(tptr) >> 12, - (EXTRACT_16BITS(tptr)) & 0x0fff)); + ND_PRINT(", RES: %u, VID: %u", GET_BE_U_2(tptr) >> 12, + (GET_BE_U_2(tptr)) & 0x0fff); - tptr = tptr+2; - len = len - 8; - stlv_len = stlv_len - 8; + tptr += 2; + len -= 8; + stlv_len -= 8; while (stlv_len >= 4) { - ND_TCHECK2(*tptr, 4); - ND_PRINT((ndo, "\n\t T: %d, R: %d, RES: %d, ISID: %d", - (EXTRACT_32BITS(tptr) >> 31), - (EXTRACT_32BITS(tptr) >> 30) & 0x01, - (EXTRACT_32BITS(tptr) >> 24) & 0x03f, - (EXTRACT_32BITS(tptr)) & 0x0ffffff)); - - tptr = tptr + 4; - len = len - 4; - stlv_len = stlv_len - 4; + ND_PRINT("\n\t T: %u, R: %u, RES: %u, ISID: %u", + (GET_BE_U_4(tptr) >> 31), + (GET_BE_U_4(tptr) >> 30) & 0x01, + (GET_BE_U_4(tptr) >> 24) & 0x03f, + (GET_BE_U_4(tptr)) & 0x0ffffff); + + tptr += 4; + len -= 4; + stlv_len -= 4; } break; @@ -1631,38 +1732,47 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo, tptr += stlv_len; len -= stlv_len; } - return 0; + return (0); - trunc: - ND_PRINT((ndo, "\n\t\t")); - ND_PRINT((ndo, "%s", tstr)); - return(1); +trunc: + nd_print_trunc(ndo); + return (1); + +subtlv_too_long: + ND_PRINT(" (> containing TLV length)"); + return (1); + +subtlv_too_short: + ND_PRINT(" (too short)"); + return (1); } /* shared routine for printing system, node and lsp-ids */ static char * -isis_print_id(const uint8_t *cp, int id_len) +isis_print_id(netdissect_options *ndo, const uint8_t *cp, u_int id_len) { - int i; + u_int i; static char id[sizeof("xxxx.xxxx.xxxx.yy-zz")]; char *pos = id; - int sysid_len; + u_int sysid_len; sysid_len = SYSTEM_ID_LEN; if (sysid_len > id_len) sysid_len = id_len; for (i = 1; i <= sysid_len; i++) { - snprintf(pos, sizeof(id) - (pos - id), "%02x", *cp++); + snprintf(pos, sizeof(id) - (pos - id), "%02x", GET_U_1(cp)); + cp++; pos += strlen(pos); if (i == 2 || i == 4) *pos++ = '.'; } if (id_len >= NODE_ID_LEN) { - snprintf(pos, sizeof(id) - (pos - id), ".%02x", *cp++); + snprintf(pos, sizeof(id) - (pos - id), ".%02x", GET_U_1(cp)); + cp++; pos += strlen(pos); } if (id_len == LSP_ID_LEN) - snprintf(pos, sizeof(id) - (pos - id), "-%02x", *cp); + snprintf(pos, sizeof(id) - (pos - id), "-%02x", GET_U_1(cp)); return (id); } @@ -1671,28 +1781,28 @@ static int isis_print_metric_block(netdissect_options *ndo, const struct isis_metric_block *isis_metric_block) { - ND_PRINT((ndo, ", Default Metric: %d, %s", + ND_PRINT(", Default Metric: %u, %s", ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_default), - ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_default) ? "External" : "Internal")); + ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_default) ? "External" : "Internal"); if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_delay)) - ND_PRINT((ndo, "\n\t\t Delay Metric: %d, %s", + ND_PRINT("\n\t\t Delay Metric: %u, %s", ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_delay), - ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_delay) ? "External" : "Internal")); + ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_delay) ? "External" : "Internal"); if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_expense)) - ND_PRINT((ndo, "\n\t\t Expense Metric: %d, %s", + ND_PRINT("\n\t\t Expense Metric: %u, %s", ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_expense), - ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_expense) ? "External" : "Internal")); + ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_expense) ? "External" : "Internal"); if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_error)) - ND_PRINT((ndo, "\n\t\t Error Metric: %d, %s", + ND_PRINT("\n\t\t Error Metric: %u, %s", ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_error), - ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_error) ? "External" : "Internal")); + ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_error) ? "External" : "Internal"); return(1); /* everything is ok */ } static int isis_print_tlv_ip_reach(netdissect_options *ndo, - const uint8_t *cp, const char *ident, int length) + const uint8_t *cp, const char *ident, u_int length) { int prefix_len; const struct isis_tlv_ip_reach *tlv_ip_reach; @@ -1701,55 +1811,56 @@ isis_print_tlv_ip_reach(netdissect_options *ndo, while (length > 0) { if ((size_t)length < sizeof(*tlv_ip_reach)) { - ND_PRINT((ndo, "short IPv4 Reachability (%d vs %lu)", + ND_PRINT("short IPv4 Reachability (%u vs %zu)", length, - (unsigned long)sizeof(*tlv_ip_reach))); + sizeof(*tlv_ip_reach)); return (0); } - if (!ND_TTEST(*tlv_ip_reach)) - return (0); + ND_TCHECK_SIZE(tlv_ip_reach); - prefix_len = mask2plen(EXTRACT_32BITS(tlv_ip_reach->mask)); + prefix_len = mask2plen(GET_IPV4_TO_HOST_ORDER(tlv_ip_reach->mask)); if (prefix_len == -1) - ND_PRINT((ndo, "%sIPv4 prefix: %s mask %s", + ND_PRINT("%sIPv4 prefix: %s mask %s", ident, - ipaddr_string(ndo, (tlv_ip_reach->prefix)), - ipaddr_string(ndo, (tlv_ip_reach->mask)))); + GET_IPADDR_STRING(tlv_ip_reach->prefix), + GET_IPADDR_STRING(tlv_ip_reach->mask)); else - ND_PRINT((ndo, "%sIPv4 prefix: %15s/%u", + ND_PRINT("%sIPv4 prefix: %15s/%u", ident, - ipaddr_string(ndo, (tlv_ip_reach->prefix)), - prefix_len)); + GET_IPADDR_STRING(tlv_ip_reach->prefix), + prefix_len); - ND_PRINT((ndo, ", Distribution: %s, Metric: %u, %s", + ND_PRINT(", Distribution: %s, Metric: %u, %s", ISIS_LSP_TLV_METRIC_UPDOWN(tlv_ip_reach->isis_metric_block.metric_default) ? "down" : "up", ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_default), - ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_default) ? "External" : "Internal")); + ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_default) ? "External" : "Internal"); if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_delay)) - ND_PRINT((ndo, "%s Delay Metric: %u, %s", + ND_PRINT("%s Delay Metric: %u, %s", ident, ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_delay), - ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_delay) ? "External" : "Internal")); + ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_delay) ? "External" : "Internal"); if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_expense)) - ND_PRINT((ndo, "%s Expense Metric: %u, %s", + ND_PRINT("%s Expense Metric: %u, %s", ident, ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_expense), - ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_expense) ? "External" : "Internal")); + ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_expense) ? "External" : "Internal"); if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_error)) - ND_PRINT((ndo, "%s Error Metric: %u, %s", + ND_PRINT("%s Error Metric: %u, %s", ident, ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_error), - ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_error) ? "External" : "Internal")); + ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_error) ? "External" : "Internal"); length -= sizeof(struct isis_tlv_ip_reach); tlv_ip_reach++; } return (1); +trunc: + return 0; } /* @@ -1759,36 +1870,65 @@ isis_print_tlv_ip_reach(netdissect_options *ndo, static int isis_print_ip_reach_subtlv(netdissect_options *ndo, - const uint8_t *tptr, int subt, int subl, + const uint8_t *tptr, u_int subt, u_int subl, const char *ident) { /* first lets see if we know the subTLVs name*/ - ND_PRINT((ndo, "%s%s subTLV #%u, length: %u", + ND_PRINT("%s%s subTLV #%u, length: %u", ident, tok2str(isis_ext_ip_reach_subtlv_values, "unknown", subt), - subt, subl)); + subt, subl); - ND_TCHECK2(*tptr,subl); + ND_TCHECK_LEN(tptr, subl); switch(subt) { case ISIS_SUBTLV_EXTD_IP_REACH_MGMT_PREFIX_COLOR: /* fall through */ case ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG32: while (subl >= 4) { - ND_PRINT((ndo, ", 0x%08x (=%u)", - EXTRACT_32BITS(tptr), - EXTRACT_32BITS(tptr))); + ND_PRINT(", 0x%08x (=%u)", + GET_BE_U_4(tptr), + GET_BE_U_4(tptr)); tptr+=4; subl-=4; } break; case ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG64: while (subl >= 8) { - ND_PRINT((ndo, ", 0x%08x%08x", - EXTRACT_32BITS(tptr), - EXTRACT_32BITS(tptr+4))); + ND_PRINT(", 0x%08x%08x", + GET_BE_U_4(tptr), + GET_BE_U_4(tptr + 4)); tptr+=8; subl-=8; } break; + case ISIS_SUBTLV_EXTD_IP_REACH_PREFIX_SID: + { + uint8_t algo, flags; + uint32_t sid; + + flags = GET_U_1(tptr); + algo = GET_U_1(tptr+1); + + if (flags & ISIS_PREFIX_SID_FLAG_V) { + if (subl < 5) + goto trunc; + sid = GET_BE_U_3(tptr+2); + tptr+=5; + subl-=5; + } else { + if (subl < 6) + goto trunc; + sid = GET_BE_U_4(tptr+2); + tptr+=6; + subl-=6; + } + + ND_PRINT(", Flags [%s], Algo %s (%u), %s %u", + bittok2str(prefix_sid_flag_values, "None", flags), + tok2str(prefix_sid_algo_values, "Unknown", algo), algo, + flags & ISIS_PREFIX_SID_FLAG_V ? "label" : "index", + sid); + } + break; default: if (!print_unknown_data(ndo, tptr, "\n\t\t ", subl)) return(0); @@ -1797,172 +1937,7 @@ isis_print_ip_reach_subtlv(netdissect_options *ndo, return(1); trunc: - ND_PRINT((ndo, "%s", ident)); - ND_PRINT((ndo, "%s", tstr)); - return(0); -} - -/* - * this is the common IS-REACH subTLV decoder it is called - * from isis_print_ext_is_reach() - */ - -static int -isis_print_is_reach_subtlv(netdissect_options *ndo, - const uint8_t *tptr, u_int subt, u_int subl, - const char *ident) -{ - u_int te_class,priority_level,gmpls_switch_cap; - union { /* int to float conversion buffer for several subTLVs */ - float f; - uint32_t i; - } bw; - - /* first lets see if we know the subTLVs name*/ - ND_PRINT((ndo, "%s%s subTLV #%u, length: %u", - ident, tok2str(isis_ext_is_reach_subtlv_values, "unknown", subt), - subt, subl)); - - ND_TCHECK2(*tptr, subl); - - switch(subt) { - case ISIS_SUBTLV_EXT_IS_REACH_ADMIN_GROUP: - case ISIS_SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID: - case ISIS_SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID: - if (subl >= 4) { - ND_PRINT((ndo, ", 0x%08x", EXTRACT_32BITS(tptr))); - if (subl == 8) /* rfc4205 */ - ND_PRINT((ndo, ", 0x%08x", EXTRACT_32BITS(tptr+4))); - } - break; - case ISIS_SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR: - case ISIS_SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR: - if (subl >= sizeof(struct in_addr)) - ND_PRINT((ndo, ", %s", ipaddr_string(ndo, tptr))); - break; - case ISIS_SUBTLV_EXT_IS_REACH_MAX_LINK_BW : - case ISIS_SUBTLV_EXT_IS_REACH_RESERVABLE_BW: - if (subl >= 4) { - bw.i = EXTRACT_32BITS(tptr); - ND_PRINT((ndo, ", %.3f Mbps", bw.f * 8 / 1000000)); - } - break; - case ISIS_SUBTLV_EXT_IS_REACH_UNRESERVED_BW : - if (subl >= 32) { - for (te_class = 0; te_class < 8; te_class++) { - bw.i = EXTRACT_32BITS(tptr); - ND_PRINT((ndo, "%s TE-Class %u: %.3f Mbps", - ident, - te_class, - bw.f * 8 / 1000000)); - tptr+=4; - } - } - break; - case ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS: /* fall through */ - case ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD: - if (subl == 0) - break; - ND_PRINT((ndo, "%sBandwidth Constraints Model ID: %s (%u)", - ident, - tok2str(diffserv_te_bc_values, "unknown", *tptr), - *tptr)); - tptr++; - /* decode BCs until the subTLV ends */ - for (te_class = 0; te_class < (subl-1)/4; te_class++) { - bw.i = EXTRACT_32BITS(tptr); - ND_PRINT((ndo, "%s Bandwidth constraint CT%u: %.3f Mbps", - ident, - te_class, - bw.f * 8 / 1000000)); - tptr+=4; - } - break; - case ISIS_SUBTLV_EXT_IS_REACH_TE_METRIC: - if (subl >= 3) - ND_PRINT((ndo, ", %u", EXTRACT_24BITS(tptr))); - break; - case ISIS_SUBTLV_EXT_IS_REACH_LINK_ATTRIBUTE: - if (subl == 2) { - ND_PRINT((ndo, ", [ %s ] (0x%04x)", - bittok2str(isis_subtlv_link_attribute_values, - "Unknown", - EXTRACT_16BITS(tptr)), - EXTRACT_16BITS(tptr))); - } - break; - case ISIS_SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE: - if (subl >= 2) { - ND_PRINT((ndo, ", %s, Priority %u", - bittok2str(gmpls_link_prot_values, "none", *tptr), - *(tptr+1))); - } - break; - case ISIS_SUBTLV_SPB_METRIC: - if (subl >= 6) { - ND_PRINT((ndo, ", LM: %u", EXTRACT_24BITS(tptr))); - tptr=tptr+3; - ND_PRINT((ndo, ", P: %u", *(tptr))); - tptr++; - ND_PRINT((ndo, ", P-ID: %u", EXTRACT_16BITS(tptr))); - } - break; - case ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR: - if (subl >= 36) { - gmpls_switch_cap = *tptr; - ND_PRINT((ndo, "%s Interface Switching Capability:%s", - ident, - tok2str(gmpls_switch_cap_values, "Unknown", gmpls_switch_cap))); - ND_PRINT((ndo, ", LSP Encoding: %s", - tok2str(gmpls_encoding_values, "Unknown", *(tptr + 1)))); - tptr+=4; - ND_PRINT((ndo, "%s Max LSP Bandwidth:", ident)); - for (priority_level = 0; priority_level < 8; priority_level++) { - bw.i = EXTRACT_32BITS(tptr); - ND_PRINT((ndo, "%s priority level %d: %.3f Mbps", - ident, - priority_level, - bw.f * 8 / 1000000)); - tptr+=4; - } - subl-=36; - switch (gmpls_switch_cap) { - case GMPLS_PSC1: - case GMPLS_PSC2: - case GMPLS_PSC3: - case GMPLS_PSC4: - if (subl < 6) - break; - bw.i = EXTRACT_32BITS(tptr); - ND_PRINT((ndo, "%s Min LSP Bandwidth: %.3f Mbps", ident, bw.f * 8 / 1000000)); - ND_PRINT((ndo, "%s Interface MTU: %u", ident, EXTRACT_16BITS(tptr + 4))); - break; - case GMPLS_TSC: - if (subl < 8) - break; - bw.i = EXTRACT_32BITS(tptr); - ND_PRINT((ndo, "%s Min LSP Bandwidth: %.3f Mbps", ident, bw.f * 8 / 1000000)); - ND_PRINT((ndo, "%s Indication %s", ident, - tok2str(gmpls_switch_cap_tsc_indication_values, "Unknown (%u)", *(tptr + 4)))); - break; - default: - /* there is some optional stuff left to decode but this is as of yet - not specified so just lets hexdump what is left */ - if(subl>0){ - if (!print_unknown_data(ndo, tptr, "\n\t\t ", subl)) - return(0); - } - } - } - break; - default: - if (!print_unknown_data(ndo, tptr, "\n\t\t ", subl)) - return(0); - break; - } - return(1); - -trunc: + nd_print_trunc(ndo); return(0); } @@ -1973,47 +1948,290 @@ trunc: static int isis_print_ext_is_reach(netdissect_options *ndo, - const uint8_t *tptr, const char *ident, int tlv_type) + const uint8_t *tptr, const char *ident, u_int tlv_type, + u_int tlv_remaining) { char ident_buffer[20]; - int subtlv_type,subtlv_len,subtlv_sum_len; + u_int subtlv_type,subtlv_len,subtlv_sum_len; int proc_bytes = 0; /* how many bytes did we process ? */ - - if (!ND_TTEST2(*tptr, NODE_ID_LEN)) + u_int te_class,priority_level,gmpls_switch_cap; + union { /* int to float conversion buffer for several subTLVs */ + float f; + uint32_t i; + } bw; + + ND_TCHECK_LEN(tptr, NODE_ID_LEN); + if (tlv_remaining < NODE_ID_LEN) return(0); - ND_PRINT((ndo, "%sIS Neighbor: %s", ident, isis_print_id(tptr, NODE_ID_LEN))); - tptr+=(NODE_ID_LEN); + ND_PRINT("%sIS Neighbor: %s", ident, isis_print_id(ndo, tptr, NODE_ID_LEN)); + tptr+=NODE_ID_LEN; + tlv_remaining-=NODE_ID_LEN; + proc_bytes+=NODE_ID_LEN; if (tlv_type != ISIS_TLV_IS_ALIAS_ID) { /* the Alias TLV Metric field is implicit 0 */ - if (!ND_TTEST2(*tptr, 3)) /* and is therefore skipped */ + ND_TCHECK_3(tptr); + if (tlv_remaining < 3) return(0); - ND_PRINT((ndo, ", Metric: %d", EXTRACT_24BITS(tptr))); + ND_PRINT(", Metric: %u", GET_BE_U_3(tptr)); tptr+=3; + tlv_remaining-=3; + proc_bytes+=3; } - if (!ND_TTEST2(*tptr, 1)) + ND_TCHECK_1(tptr); + if (tlv_remaining < 1) return(0); - subtlv_sum_len=*(tptr++); /* read out subTLV length */ - proc_bytes=NODE_ID_LEN+3+1; - ND_PRINT((ndo, ", %ssub-TLVs present",subtlv_sum_len ? "" : "no ")); + subtlv_sum_len=GET_U_1(tptr); /* read out subTLV length */ + tptr++; + tlv_remaining--; + proc_bytes++; + ND_PRINT(", %ssub-TLVs present",subtlv_sum_len ? "" : "no "); if (subtlv_sum_len) { - ND_PRINT((ndo, " (%u)", subtlv_sum_len)); - while (subtlv_sum_len>0) { - if (!ND_TTEST2(*tptr,2)) - return(0); - subtlv_type=*(tptr++); - subtlv_len=*(tptr++); - /* prepend the indent string */ - snprintf(ident_buffer, sizeof(ident_buffer), "%s ",ident); - if (!isis_print_is_reach_subtlv(ndo, tptr, subtlv_type, subtlv_len, ident_buffer)) - return(0); - tptr+=subtlv_len; - subtlv_sum_len-=(subtlv_len+2); - proc_bytes+=(subtlv_len+2); + ND_PRINT(" (%u)", subtlv_sum_len); + /* prepend the indent string */ + snprintf(ident_buffer, sizeof(ident_buffer), "%s ",ident); + ident = ident_buffer; + while (subtlv_sum_len != 0) { + ND_TCHECK_2(tptr); + if (tlv_remaining < 2) { + ND_PRINT("%sRemaining data in TLV shorter than a subTLV header",ident); + proc_bytes += tlv_remaining; + break; + } + if (subtlv_sum_len < 2) { + ND_PRINT("%sRemaining data in subTLVs shorter than a subTLV header",ident); + proc_bytes += subtlv_sum_len; + break; + } + subtlv_type=GET_U_1(tptr); + subtlv_len=GET_U_1(tptr + 1); + tptr += 2; + tlv_remaining -= 2; + subtlv_sum_len -= 2; + proc_bytes += 2; + ND_PRINT("%s%s subTLV #%u, length: %u", + ident, tok2str(isis_ext_is_reach_subtlv_values, "unknown", subtlv_type), + subtlv_type, subtlv_len); + + if (subtlv_sum_len < subtlv_len) { + ND_PRINT(" (remaining data in subTLVs shorter than the current subTLV)"); + proc_bytes += subtlv_sum_len; + break; + } + + if (tlv_remaining < subtlv_len) { + ND_PRINT(" (> remaining tlv length)"); + proc_bytes += tlv_remaining; + break; + } + + ND_TCHECK_LEN(tptr, subtlv_len); + + switch(subtlv_type) { + case ISIS_SUBTLV_EXT_IS_REACH_ADMIN_GROUP: + case ISIS_SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID: + case ISIS_SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID: + if (subtlv_len >= 4) { + ND_PRINT(", 0x%08x", GET_BE_U_4(tptr)); + if (subtlv_len == 8) /* rfc4205 */ + ND_PRINT(", 0x%08x", GET_BE_U_4(tptr + 4)); + } + break; + case ISIS_SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR: + case ISIS_SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR: + if (subtlv_len >= sizeof(nd_ipv4)) + ND_PRINT(", %s", GET_IPADDR_STRING(tptr)); + break; + case ISIS_SUBTLV_EXT_IS_REACH_MAX_LINK_BW : + case ISIS_SUBTLV_EXT_IS_REACH_RESERVABLE_BW: + if (subtlv_len >= 4) { + bw.i = GET_BE_U_4(tptr); + ND_PRINT(", %.3f Mbps", bw.f * 8 / 1000000); + } + break; + case ISIS_SUBTLV_EXT_IS_REACH_UNRESERVED_BW : + if (subtlv_len >= 32) { + for (te_class = 0; te_class < 8; te_class++) { + bw.i = GET_BE_U_4(tptr); + ND_PRINT("%s TE-Class %u: %.3f Mbps", + ident, + te_class, + bw.f * 8 / 1000000); + tptr += 4; + subtlv_len -= 4; + subtlv_sum_len -= 4; + proc_bytes += 4; + } + } + break; + case ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS: /* fall through */ + case ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD: + if (subtlv_len == 0) + break; + ND_PRINT("%sBandwidth Constraints Model ID: %s (%u)", + ident, + tok2str(diffserv_te_bc_values, "unknown", GET_U_1(tptr)), + GET_U_1(tptr)); + tptr++; + subtlv_len--; + subtlv_sum_len--; + proc_bytes++; + /* decode BCs until the subTLV ends */ + for (te_class = 0; subtlv_len != 0; te_class++) { + if (subtlv_len < 4) + break; + bw.i = GET_BE_U_4(tptr); + ND_PRINT("%s Bandwidth constraint CT%u: %.3f Mbps", + ident, + te_class, + bw.f * 8 / 1000000); + tptr += 4; + subtlv_len -= 4; + subtlv_sum_len -= 4; + proc_bytes += 4; + } + break; + case ISIS_SUBTLV_EXT_IS_REACH_TE_METRIC: + if (subtlv_len >= 3) + ND_PRINT(", %u", GET_BE_U_3(tptr)); + break; + case ISIS_SUBTLV_EXT_IS_REACH_LINK_ATTRIBUTE: + if (subtlv_len == 2) { + ND_PRINT(", [ %s ] (0x%04x)", + bittok2str(isis_subtlv_link_attribute_values, + "Unknown", + GET_BE_U_2(tptr)), + GET_BE_U_2(tptr)); + } + break; + case ISIS_SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE: + if (subtlv_len >= 2) { + ND_PRINT(", %s, Priority %u", + bittok2str(gmpls_link_prot_values, "none", GET_U_1(tptr)), + GET_U_1(tptr + 1)); + } + break; + case ISIS_SUBTLV_SPB_METRIC: + if (subtlv_len >= 6) { + ND_PRINT(", LM: %u", GET_BE_U_3(tptr)); + tptr += 3; + subtlv_len -= 3; + subtlv_sum_len -= 3; + proc_bytes += 3; + ND_PRINT(", P: %u", GET_U_1(tptr)); + tptr++; + subtlv_len--; + subtlv_sum_len--; + proc_bytes++; + ND_PRINT(", P-ID: %u", GET_BE_U_2(tptr)); + } + break; + case ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR: + if (subtlv_len >= 36) { + gmpls_switch_cap = GET_U_1(tptr); + ND_PRINT("%s Interface Switching Capability:%s", + ident, + tok2str(gmpls_switch_cap_values, "Unknown", gmpls_switch_cap)); + ND_PRINT(", LSP Encoding: %s", + tok2str(gmpls_encoding_values, "Unknown", GET_U_1((tptr + 1)))); + tptr += 4; + subtlv_len -= 4; + subtlv_sum_len -= 4; + proc_bytes += 4; + ND_PRINT("%s Max LSP Bandwidth:", ident); + for (priority_level = 0; priority_level < 8; priority_level++) { + bw.i = GET_BE_U_4(tptr); + ND_PRINT("%s priority level %u: %.3f Mbps", + ident, + priority_level, + bw.f * 8 / 1000000); + tptr += 4; + subtlv_len -= 4; + subtlv_sum_len -= 4; + proc_bytes += 4; + } + switch (gmpls_switch_cap) { + case GMPLS_PSC1: + case GMPLS_PSC2: + case GMPLS_PSC3: + case GMPLS_PSC4: + if (subtlv_len < 6) + break; + bw.i = GET_BE_U_4(tptr); + ND_PRINT("%s Min LSP Bandwidth: %.3f Mbps", ident, bw.f * 8 / 1000000); + ND_PRINT("%s Interface MTU: %u", ident, + GET_BE_U_2(tptr + 4)); + break; + case GMPLS_TSC: + if (subtlv_len < 8) + break; + bw.i = GET_BE_U_4(tptr); + ND_PRINT("%s Min LSP Bandwidth: %.3f Mbps", ident, bw.f * 8 / 1000000); + ND_PRINT("%s Indication %s", ident, + tok2str(gmpls_switch_cap_tsc_indication_values, "Unknown (%u)", GET_U_1((tptr + 4)))); + break; + default: + /* there is some optional stuff left to decode but this is as of yet + not specified so just lets hexdump what is left */ + if (subtlv_len != 0) { + if (!print_unknown_data(ndo, tptr, "\n\t\t ", subtlv_len)) + return(0); + } + } + } + break; + case ISIS_SUBTLV_EXT_IS_REACH_LAN_ADJ_SEGMENT_ID: + if (subtlv_len >= 8) { + ND_PRINT("%s Flags: [%s]", ident, + bittok2str(isis_lan_adj_sid_flag_values, + "none", + GET_U_1(tptr))); + int vflag = (GET_U_1(tptr) & 0x20) ? 1:0; + int lflag = (GET_U_1(tptr) & 0x10) ? 1:0; + tptr++; + subtlv_len--; + subtlv_sum_len--; + proc_bytes++; + ND_PRINT("%s Weight: %u", ident, GET_U_1(tptr)); + tptr++; + subtlv_len--; + subtlv_sum_len--; + proc_bytes++; + if(subtlv_len>=SYSTEM_ID_LEN) { + ND_TCHECK_LEN(tptr, SYSTEM_ID_LEN); + ND_PRINT("%s Neighbor System-ID: %s", ident, + isis_print_id(ndo, tptr, SYSTEM_ID_LEN)); + } + /* RFC 8667 section 2.2.2 */ + /* if V-flag is set to 1 and L-flag is set to 1 ==> 3 octet label */ + /* if V-flag is set to 0 and L-flag is set to 0 ==> 4 octet index */ + if (vflag && lflag) { + ND_PRINT("%s Label: %u", + ident, GET_BE_U_3(tptr+SYSTEM_ID_LEN)); + } else if ((!vflag) && (!lflag)) { + ND_PRINT("%s Index: %u", + ident, GET_BE_U_4(tptr+SYSTEM_ID_LEN)); + } else + nd_print_invalid(ndo); + } + break; + default: + if (!print_unknown_data(ndo, tptr, "\n\t\t ", subtlv_len)) + return(0); + break; + } + + tptr += subtlv_len; + tlv_remaining -= subtlv_len; + subtlv_sum_len -= subtlv_len; + proc_bytes += subtlv_len; } } return(proc_bytes); + +trunc: + return(0); } /* @@ -2021,24 +2239,26 @@ isis_print_ext_is_reach(netdissect_options *ndo, * it is called from various MT-TLVs (222,229,235,237) */ -static int +static uint8_t isis_print_mtid(netdissect_options *ndo, - const uint8_t *tptr, const char *ident) + const uint8_t *tptr, const char *ident, u_int tlv_remaining) { - if (!ND_TTEST2(*tptr, 2)) - return(0); + if (tlv_remaining < 2) + goto trunc; - ND_PRINT((ndo, "%s%s", + ND_PRINT("%s%s", ident, tok2str(isis_mt_values, "Reserved for IETF Consensus", - ISIS_MASK_MTID(EXTRACT_16BITS(tptr))))); + ISIS_MASK_MTID(GET_BE_U_2(tptr)))); - ND_PRINT((ndo, " Topology (0x%03x), Flags: [%s]", - ISIS_MASK_MTID(EXTRACT_16BITS(tptr)), - bittok2str(isis_mt_flag_values, "none",ISIS_MASK_MTFLAGS(EXTRACT_16BITS(tptr))))); + ND_PRINT(" Topology (0x%03x), Flags: [%s]", + ISIS_MASK_MTID(GET_BE_U_2(tptr)), + bittok2str(isis_mt_flag_values, "none",ISIS_MASK_MTFLAGS(GET_BE_U_2(tptr)))); return(2); +trunc: + return 0; } /* @@ -2048,96 +2268,88 @@ isis_print_mtid(netdissect_options *ndo, * the amount of processed bytes */ -static int +static u_int isis_print_extd_ip_reach(netdissect_options *ndo, const uint8_t *tptr, const char *ident, uint16_t afi) { char ident_buffer[20]; - uint8_t prefix[sizeof(struct in6_addr)]; /* shared copy buffer for IPv4 and IPv6 prefixes */ + uint8_t prefix[sizeof(nd_ipv6)]; /* shared copy buffer for IPv4 and IPv6 prefixes */ u_int metric, status_byte, bit_length, byte_length, sublen, processed, subtlvtype, subtlvlen; - if (!ND_TTEST2(*tptr, 4)) - return (0); - metric = EXTRACT_32BITS(tptr); + metric = GET_BE_U_4(tptr); processed=4; tptr+=4; if (afi == AF_INET) { - if (!ND_TTEST2(*tptr, 1)) /* fetch status byte */ - return (0); - status_byte=*(tptr++); + status_byte=GET_U_1(tptr); + tptr++; bit_length = status_byte&0x3f; if (bit_length > 32) { - ND_PRINT((ndo, "%sIPv4 prefix: bad bit length %u", + ND_PRINT("%sIPv4 prefix: bad bit length %u", ident, - bit_length)); + bit_length); return (0); } processed++; } else if (afi == AF_INET6) { - if (!ND_TTEST2(*tptr, 2)) /* fetch status & prefix_len byte */ - return (0); - status_byte=*(tptr++); - bit_length=*(tptr++); + status_byte=GET_U_1(tptr); + bit_length=GET_U_1(tptr + 1); if (bit_length > 128) { - ND_PRINT((ndo, "%sIPv6 prefix: bad bit length %u", + ND_PRINT("%sIPv6 prefix: bad bit length %u", ident, - bit_length)); + bit_length); return (0); } + tptr+=2; processed+=2; } else return (0); /* somebody is fooling us */ byte_length = (bit_length + 7) / 8; /* prefix has variable length encoding */ - if (!ND_TTEST2(*tptr, byte_length)) - return (0); - memset(prefix, 0, sizeof prefix); /* clear the copy buffer */ - memcpy(prefix,tptr,byte_length); /* copy as much as is stored in the TLV */ + memset(prefix, 0, sizeof(prefix)); /* clear the copy buffer */ + GET_CPY_BYTES(prefix,tptr,byte_length); /* copy as much as is stored in the TLV */ tptr+=byte_length; processed+=byte_length; if (afi == AF_INET) - ND_PRINT((ndo, "%sIPv4 prefix: %15s/%u", + ND_PRINT("%sIPv4 prefix: %15s/%u", ident, - ipaddr_string(ndo, prefix), - bit_length)); + ipaddr_string(ndo, prefix), /* local buffer, not packet data; don't use GET_IPADDR_STRING() */ + bit_length); else if (afi == AF_INET6) - ND_PRINT((ndo, "%sIPv6 prefix: %s/%u", + ND_PRINT("%sIPv6 prefix: %s/%u", ident, - ip6addr_string(ndo, prefix), - bit_length)); + ip6addr_string(ndo, prefix), /* local buffer, not packet data; don't use GET_IP6ADDR_STRING() */ + bit_length); - ND_PRINT((ndo, ", Distribution: %s, Metric: %u", + ND_PRINT(", Distribution: %s, Metric: %u", ISIS_MASK_TLV_EXTD_IP_UPDOWN(status_byte) ? "down" : "up", - metric)); + metric); if (afi == AF_INET && ISIS_MASK_TLV_EXTD_IP_SUBTLV(status_byte)) - ND_PRINT((ndo, ", sub-TLVs present")); + ND_PRINT(", sub-TLVs present"); else if (afi == AF_INET6) - ND_PRINT((ndo, ", %s%s", + ND_PRINT(", %s%s", ISIS_MASK_TLV_EXTD_IP6_IE(status_byte) ? "External" : "Internal", - ISIS_MASK_TLV_EXTD_IP6_SUBTLV(status_byte) ? ", sub-TLVs present" : "")); + ISIS_MASK_TLV_EXTD_IP6_SUBTLV(status_byte) ? ", sub-TLVs present" : ""); if ((afi == AF_INET && ISIS_MASK_TLV_EXTD_IP_SUBTLV(status_byte)) || (afi == AF_INET6 && ISIS_MASK_TLV_EXTD_IP6_SUBTLV(status_byte)) - ) { + ) { /* assume that one prefix can hold more than one subTLV - therefore the first byte must reflect the aggregate bytecount of the subTLVs for this prefix */ - if (!ND_TTEST2(*tptr, 1)) - return (0); - sublen=*(tptr++); + sublen=GET_U_1(tptr); + tptr++; processed+=sublen+1; - ND_PRINT((ndo, " (%u)", sublen)); /* print out subTLV length */ + ND_PRINT(" (%u)", sublen); /* print out subTLV length */ while (sublen>0) { - if (!ND_TTEST2(*tptr,2)) - return (0); - subtlvtype=*(tptr++); - subtlvlen=*(tptr++); + subtlvtype=GET_U_1(tptr); + subtlvlen=GET_U_1(tptr + 1); + tptr+=2; /* prepend the indent string */ snprintf(ident_buffer, sizeof(ident_buffer), "%s ",ident); if (!isis_print_ip_reach_subtlv(ndo, tptr, subtlvtype, subtlvlen, ident_buffer)) @@ -2149,6 +2361,89 @@ isis_print_extd_ip_reach(netdissect_options *ndo, return (processed); } +static void +isis_print_router_cap_subtlv(netdissect_options *ndo, const uint8_t *tptr, uint8_t tlen) +{ + uint8_t subt, subl; + + while (tlen >= 2) { + subt = GET_U_1(tptr); + subl = GET_U_1(tptr+1); + tlen -= 2; + tptr += 2; + + /* first lets see if we know the subTLVs name*/ + ND_PRINT("\n\t\t%s subTLV #%u, length: %u", + tok2str(isis_router_capability_subtlv_values, "unknown", subt), + subt, subl); + + /* + * Boundary check. + */ + if (subl > tlen) { + break; + } + ND_TCHECK_LEN(tptr, subl); + + switch (subt) { + case ISIS_SUBTLV_ROUTER_CAP_SR: + { + uint8_t flags, sid_tlen, sid_type, sid_len; + uint32_t range; + const uint8_t *sid_ptr; + + flags = GET_U_1(tptr); + range = GET_BE_U_3(tptr+1); + ND_PRINT(", Flags [%s], Range %u", + bittok2str(isis_router_capability_sr_flags, "None", flags), + range); + sid_ptr = tptr + 4; + sid_tlen = subl - 4; + + while (sid_tlen >= 5) { + sid_type = GET_U_1(sid_ptr); + sid_len = GET_U_1(sid_ptr+1); + sid_tlen -= 2; + sid_ptr += 2; + + /* + * Boundary check. + */ + if (sid_len > sid_tlen) { + break; + } + + switch (sid_type) { + case 1: + if (sid_len == 3) { + ND_PRINT(", SID value %u", GET_BE_U_3(sid_ptr)); + } else if (sid_len == 4) { + ND_PRINT(", SID value %u", GET_BE_U_4(sid_ptr)); + } else { + ND_PRINT(", Unknown SID length%u", sid_len); + } + break; + default: + print_unknown_data(ndo, sid_ptr, "\n\t\t ", sid_len); + } + + sid_ptr += sid_len; + sid_tlen -= sid_len; + } + } + break; + default: + print_unknown_data(ndo, tptr, "\n\t\t", subl); + break; + } + + tlen -= subl; + tptr += subl; + } + trunc: + return; +} + /* * Clear checksum and lifetime prior to signature verification. */ @@ -2168,6 +2463,14 @@ isis_clear_checksum_lifetime(void *header) * Decode IS-IS packets. Return 0 on error. */ +#define INVALID_OR_DECREMENT(length,decr) \ + if ((length) < (decr)) { \ + ND_PRINT(" [packet length %u < %zu]", (length), (decr)); \ + nd_print_invalid(ndo); \ + return 1; \ + } \ + length -= (decr); + static int isis_print(netdissect_options *ndo, const uint8_t *p, u_int length) @@ -2185,19 +2488,26 @@ isis_print(netdissect_options *ndo, const struct isis_tlv_is_reach *tlv_is_reach; const struct isis_tlv_es_reach *tlv_es_reach; - uint8_t pdu_type, max_area, id_length, tlv_type, tlv_len, tmp, alen, lan_alen, prefix_len; - uint8_t ext_is_len, ext_ip_len, mt_len; + uint8_t version, pdu_version, fixed_len; + uint8_t pdu_type, pdu_max_area, max_area, pdu_id_length, id_length, tlv_type, tlv_len, tlen, alen, prefix_len; + u_int ext_is_len, ext_ip_len; + uint8_t mt_len; + uint8_t isis_subtlv_idrp; const uint8_t *optr, *pptr, *tptr; - u_short packet_len,pdu_len, key_id; - u_int i,vendor_id; + u_int packet_len; + u_short pdu_len, key_id; + u_int i,vendor_id, num_vals; + uint8_t auth_type; + uint8_t num_system_ids; int sigcheck; + ndo->ndo_protocol = "isis"; packet_len=length; optr = p; /* initialize the _o_riginal pointer to the packet start - need it for parsing the checksum TLV and authentication TLV verification */ isis_header = (const struct isis_common_header *)p; - ND_TCHECK(*isis_header); + ND_TCHECK_SIZE(isis_header); if (length < ISIS_COMMON_HEADER_SIZE) goto trunc; pptr = p+(ISIS_COMMON_HEADER_SIZE); @@ -2208,56 +2518,60 @@ isis_print(netdissect_options *ndo, header_psnp = (const struct isis_psnp_header *)pptr; if (!ndo->ndo_eflag) - ND_PRINT((ndo, "IS-IS")); + ND_PRINT("IS-IS"); /* * Sanity checking of the header. */ - if (isis_header->version != ISIS_VERSION) { - ND_PRINT((ndo, "version %d packet not supported", isis_header->version)); + version = GET_U_1(isis_header->version); + if (version != ISIS_VERSION) { + ND_PRINT("version %u packet not supported", version); return (0); } - if ((isis_header->id_length != SYSTEM_ID_LEN) && (isis_header->id_length != 0)) { - ND_PRINT((ndo, "system ID length of %d is not supported", - isis_header->id_length)); + pdu_id_length = GET_U_1(isis_header->id_length); + if ((pdu_id_length != SYSTEM_ID_LEN) && (pdu_id_length != 0)) { + ND_PRINT("system ID length of %u is not supported", + pdu_id_length); return (0); } - if (isis_header->pdu_version != ISIS_VERSION) { - ND_PRINT((ndo, "version %d packet not supported", isis_header->pdu_version)); + pdu_version = GET_U_1(isis_header->pdu_version); + if (pdu_version != ISIS_VERSION) { + ND_PRINT("version %u packet not supported", pdu_version); return (0); } - if (length < isis_header->fixed_len) { - ND_PRINT((ndo, "fixed header length %u > packet length %u", isis_header->fixed_len, length)); + fixed_len = GET_U_1(isis_header->fixed_len); + if (length < fixed_len) { + ND_PRINT("fixed header length %u > packet length %u", fixed_len, length); return (0); } - if (isis_header->fixed_len < ISIS_COMMON_HEADER_SIZE) { - ND_PRINT((ndo, "fixed header length %u < minimum header size %u", isis_header->fixed_len, (u_int)ISIS_COMMON_HEADER_SIZE)); + if (fixed_len < ISIS_COMMON_HEADER_SIZE) { + ND_PRINT("fixed header length %u < minimum header size %u", fixed_len, (u_int)ISIS_COMMON_HEADER_SIZE); return (0); } - max_area = isis_header->max_area; - switch(max_area) { + pdu_max_area = GET_U_1(isis_header->max_area); + switch(pdu_max_area) { case 0: max_area = 3; /* silly shit */ break; case 255: - ND_PRINT((ndo, "bad packet -- 255 areas")); + ND_PRINT("bad packet -- 255 areas"); return (0); default: + max_area = pdu_max_area; break; } - id_length = isis_header->id_length; - switch(id_length) { + switch(pdu_id_length) { case 0: id_length = 6; /* silly shit again */ break; - case 1: /* 1-8 are valid sys-ID lenghts */ + case 1: /* 1-8 are valid sys-ID lengths */ case 2: case 3: case 4: @@ -2265,42 +2579,44 @@ isis_print(netdissect_options *ndo, case 6: case 7: case 8: + id_length = pdu_id_length; break; case 255: id_length = 0; /* entirely useless */ break; default: + id_length = pdu_id_length; break; } /* toss any non 6-byte sys-ID len PDUs */ if (id_length != 6 ) { - ND_PRINT((ndo, "bad packet -- illegal sys-ID length (%u)", id_length)); + ND_PRINT("bad packet -- illegal sys-ID length (%u)", id_length); return (0); } - pdu_type=isis_header->pdu_type; + pdu_type = GET_U_1(isis_header->pdu_type); /* in non-verbose mode print the basic PDU Type plus PDU specific brief information*/ if (ndo->ndo_vflag == 0) { - ND_PRINT((ndo, "%s%s", + ND_PRINT("%s%s", ndo->ndo_eflag ? "" : ", ", - tok2str(isis_pdu_values, "unknown PDU-Type %u", pdu_type))); + tok2str(isis_pdu_values, "unknown PDU-Type %u", pdu_type)); } else { /* ok they seem to want to know everything - lets fully decode it */ - ND_PRINT((ndo, "%slength %u", ndo->ndo_eflag ? "" : ", ", length)); + ND_PRINT("%slength %u", ndo->ndo_eflag ? "" : ", ", length); - ND_PRINT((ndo, "\n\t%s, hlen: %u, v: %u, pdu-v: %u, sys-id-len: %u (%u), max-area: %u (%u)", + ND_PRINT("\n\t%s, hlen: %u, v: %u, pdu-v: %u, sys-id-len: %u (%u), max-area: %u (%u)", tok2str(isis_pdu_values, "unknown, type %u", pdu_type), - isis_header->fixed_len, - isis_header->version, - isis_header->pdu_version, + fixed_len, + version, + pdu_version, id_length, - isis_header->id_length, + pdu_id_length, max_area, - isis_header->max_area)); + pdu_max_area); if (ndo->ndo_vflag > 1) { if (!print_unknown_data(ndo, optr, "\n\t", 8)) /* provide the _o_riginal pointer */ @@ -2312,223 +2628,222 @@ isis_print(netdissect_options *ndo, case ISIS_PDU_L1_LAN_IIH: case ISIS_PDU_L2_LAN_IIH: - if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)) { - ND_PRINT((ndo, ", bogus fixed header length %u should be %lu", - isis_header->fixed_len, (unsigned long)(ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE))); + if (fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)) { + ND_PRINT(", bogus fixed header length %u should be %zu", + fixed_len, ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE); return (0); } - ND_TCHECK(*header_iih_lan); + ND_TCHECK_SIZE(header_iih_lan); if (length < ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE) goto trunc; if (ndo->ndo_vflag == 0) { - ND_PRINT((ndo, ", src-id %s", - isis_print_id(header_iih_lan->source_id, SYSTEM_ID_LEN))); - ND_PRINT((ndo, ", lan-id %s, prio %u", - isis_print_id(header_iih_lan->lan_id,NODE_ID_LEN), - header_iih_lan->priority)); - ND_PRINT((ndo, ", length %u", length)); + ND_PRINT(", src-id %s", + isis_print_id(ndo, header_iih_lan->source_id, SYSTEM_ID_LEN)); + ND_PRINT(", lan-id %s, prio %u", + isis_print_id(ndo, header_iih_lan->lan_id,NODE_ID_LEN), + GET_U_1(header_iih_lan->priority)); + ND_PRINT(", length %u", length); return (1); } - pdu_len=EXTRACT_16BITS(header_iih_lan->pdu_len); + pdu_len=GET_BE_U_2(header_iih_lan->pdu_len); if (packet_len>pdu_len) { packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ length=pdu_len; } - ND_PRINT((ndo, "\n\t source-id: %s, holding time: %us, Flags: [%s]", - isis_print_id(header_iih_lan->source_id,SYSTEM_ID_LEN), - EXTRACT_16BITS(header_iih_lan->holding_time), + ND_PRINT("\n\t source-id: %s, holding time: %us, Flags: [%s]", + isis_print_id(ndo, header_iih_lan->source_id,SYSTEM_ID_LEN), + GET_BE_U_2(header_iih_lan->holding_time), tok2str(isis_iih_circuit_type_values, "unknown circuit type 0x%02x", - header_iih_lan->circuit_type))); + GET_U_1(header_iih_lan->circuit_type))); - ND_PRINT((ndo, "\n\t lan-id: %s, Priority: %u, PDU length: %u", - isis_print_id(header_iih_lan->lan_id, NODE_ID_LEN), - (header_iih_lan->priority) & ISIS_LAN_PRIORITY_MASK, - pdu_len)); + ND_PRINT("\n\t lan-id: %s, Priority: %u, PDU length: %u", + isis_print_id(ndo, header_iih_lan->lan_id, NODE_ID_LEN), + GET_U_1(header_iih_lan->priority) & ISIS_LAN_PRIORITY_MASK, + pdu_len); if (ndo->ndo_vflag > 1) { if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_IIH_LAN_HEADER_SIZE)) return (0); } - packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE); + INVALID_OR_DECREMENT(packet_len,ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE); pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE); break; case ISIS_PDU_PTP_IIH: - if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)) { - ND_PRINT((ndo, ", bogus fixed header length %u should be %lu", - isis_header->fixed_len, (unsigned long)(ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE))); + if (fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)) { + ND_PRINT(", bogus fixed header length %u should be %zu", + fixed_len, ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE); return (0); } - ND_TCHECK(*header_iih_ptp); + ND_TCHECK_SIZE(header_iih_ptp); if (length < ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE) goto trunc; if (ndo->ndo_vflag == 0) { - ND_PRINT((ndo, ", src-id %s", isis_print_id(header_iih_ptp->source_id, SYSTEM_ID_LEN))); - ND_PRINT((ndo, ", length %u", length)); + ND_PRINT(", src-id %s", isis_print_id(ndo, header_iih_ptp->source_id, SYSTEM_ID_LEN)); + ND_PRINT(", length %u", length); return (1); } - pdu_len=EXTRACT_16BITS(header_iih_ptp->pdu_len); + pdu_len=GET_BE_U_2(header_iih_ptp->pdu_len); if (packet_len>pdu_len) { packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ length=pdu_len; } - ND_PRINT((ndo, "\n\t source-id: %s, holding time: %us, Flags: [%s]", - isis_print_id(header_iih_ptp->source_id,SYSTEM_ID_LEN), - EXTRACT_16BITS(header_iih_ptp->holding_time), + ND_PRINT("\n\t source-id: %s, holding time: %us, Flags: [%s]", + isis_print_id(ndo, header_iih_ptp->source_id,SYSTEM_ID_LEN), + GET_BE_U_2(header_iih_ptp->holding_time), tok2str(isis_iih_circuit_type_values, "unknown circuit type 0x%02x", - header_iih_ptp->circuit_type))); + GET_U_1(header_iih_ptp->circuit_type))); - ND_PRINT((ndo, "\n\t circuit-id: 0x%02x, PDU length: %u", - header_iih_ptp->circuit_id, - pdu_len)); + ND_PRINT("\n\t circuit-id: 0x%02x, PDU length: %u", + GET_U_1(header_iih_ptp->circuit_id), + pdu_len); if (ndo->ndo_vflag > 1) { if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_IIH_PTP_HEADER_SIZE)) return (0); } - - packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE); + INVALID_OR_DECREMENT(packet_len,ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE); pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE); break; case ISIS_PDU_L1_LSP: case ISIS_PDU_L2_LSP: - if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)) { - ND_PRINT((ndo, ", bogus fixed header length %u should be %lu", - isis_header->fixed_len, (unsigned long)ISIS_LSP_HEADER_SIZE)); + if (fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)) { + ND_PRINT(", bogus fixed header length %u should be %zu", + fixed_len, ISIS_LSP_HEADER_SIZE); return (0); } - ND_TCHECK(*header_lsp); + ND_TCHECK_SIZE(header_lsp); if (length < ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE) goto trunc; if (ndo->ndo_vflag == 0) { - ND_PRINT((ndo, ", lsp-id %s, seq 0x%08x, lifetime %5us", - isis_print_id(header_lsp->lsp_id, LSP_ID_LEN), - EXTRACT_32BITS(header_lsp->sequence_number), - EXTRACT_16BITS(header_lsp->remaining_lifetime))); - ND_PRINT((ndo, ", length %u", length)); + ND_PRINT(", lsp-id %s, seq 0x%08x, lifetime %5us", + isis_print_id(ndo, header_lsp->lsp_id, LSP_ID_LEN), + GET_BE_U_4(header_lsp->sequence_number), + GET_BE_U_2(header_lsp->remaining_lifetime)); + ND_PRINT(", length %u", length); return (1); } - pdu_len=EXTRACT_16BITS(header_lsp->pdu_len); + pdu_len=GET_BE_U_2(header_lsp->pdu_len); if (packet_len>pdu_len) { packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ length=pdu_len; } - ND_PRINT((ndo, "\n\t lsp-id: %s, seq: 0x%08x, lifetime: %5us\n\t chksum: 0x%04x", - isis_print_id(header_lsp->lsp_id, LSP_ID_LEN), - EXTRACT_32BITS(header_lsp->sequence_number), - EXTRACT_16BITS(header_lsp->remaining_lifetime), - EXTRACT_16BITS(header_lsp->checksum))); + ND_PRINT("\n\t lsp-id: %s, seq: 0x%08x, lifetime: %5us\n\t chksum: 0x%04x", + isis_print_id(ndo, header_lsp->lsp_id, LSP_ID_LEN), + GET_BE_U_4(header_lsp->sequence_number), + GET_BE_U_2(header_lsp->remaining_lifetime), + GET_BE_U_2(header_lsp->checksum)); osi_print_cksum(ndo, (const uint8_t *)header_lsp->lsp_id, - EXTRACT_16BITS(header_lsp->checksum), + GET_BE_U_2(header_lsp->checksum), 12, length-12); - ND_PRINT((ndo, ", PDU length: %u, Flags: [ %s", + ND_PRINT(", PDU length: %u, Flags: [ %s", pdu_len, - ISIS_MASK_LSP_OL_BIT(header_lsp->typeblock) ? "Overload bit set, " : "")); + ISIS_MASK_LSP_OL_BIT(header_lsp->typeblock) ? "Overload bit set, " : ""); if (ISIS_MASK_LSP_ATT_BITS(header_lsp->typeblock)) { - ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp->typeblock) ? "default " : "")); - ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp->typeblock) ? "delay " : "")); - ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp->typeblock) ? "expense " : "")); - ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp->typeblock) ? "error " : "")); - ND_PRINT((ndo, "ATT bit set, ")); + ND_PRINT("%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp->typeblock) ? "default " : ""); + ND_PRINT("%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp->typeblock) ? "delay " : ""); + ND_PRINT("%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp->typeblock) ? "expense " : ""); + ND_PRINT("%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp->typeblock) ? "error " : ""); + ND_PRINT("ATT bit set, "); } - ND_PRINT((ndo, "%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp->typeblock) ? "P bit set, " : "")); - ND_PRINT((ndo, "%s ]", tok2str(isis_lsp_istype_values, "Unknown(0x%x)", - ISIS_MASK_LSP_ISTYPE_BITS(header_lsp->typeblock)))); + ND_PRINT("%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp->typeblock) ? "P bit set, " : ""); + ND_PRINT("%s ]", tok2str(isis_lsp_istype_values, "Unknown(0x%x)", + ISIS_MASK_LSP_ISTYPE_BITS(header_lsp->typeblock))); if (ndo->ndo_vflag > 1) { if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_LSP_HEADER_SIZE)) return (0); } - packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE); + INVALID_OR_DECREMENT(packet_len,ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE); pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE); break; case ISIS_PDU_L1_CSNP: case ISIS_PDU_L2_CSNP: - if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)) { - ND_PRINT((ndo, ", bogus fixed header length %u should be %lu", - isis_header->fixed_len, (unsigned long)(ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE))); + if (fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)) { + ND_PRINT(", bogus fixed header length %u should be %zu", + fixed_len, ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE); return (0); } - ND_TCHECK(*header_csnp); + ND_TCHECK_SIZE(header_csnp); if (length < ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE) goto trunc; if (ndo->ndo_vflag == 0) { - ND_PRINT((ndo, ", src-id %s", isis_print_id(header_csnp->source_id, NODE_ID_LEN))); - ND_PRINT((ndo, ", length %u", length)); + ND_PRINT(", src-id %s", isis_print_id(ndo, header_csnp->source_id, NODE_ID_LEN)); + ND_PRINT(", length %u", length); return (1); } - pdu_len=EXTRACT_16BITS(header_csnp->pdu_len); + pdu_len=GET_BE_U_2(header_csnp->pdu_len); if (packet_len>pdu_len) { packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ length=pdu_len; } - ND_PRINT((ndo, "\n\t source-id: %s, PDU length: %u", - isis_print_id(header_csnp->source_id, NODE_ID_LEN), - pdu_len)); - ND_PRINT((ndo, "\n\t start lsp-id: %s", - isis_print_id(header_csnp->start_lsp_id, LSP_ID_LEN))); - ND_PRINT((ndo, "\n\t end lsp-id: %s", - isis_print_id(header_csnp->end_lsp_id, LSP_ID_LEN))); + ND_PRINT("\n\t source-id: %s, PDU length: %u", + isis_print_id(ndo, header_csnp->source_id, NODE_ID_LEN), + pdu_len); + ND_PRINT("\n\t start lsp-id: %s", + isis_print_id(ndo, header_csnp->start_lsp_id, LSP_ID_LEN)); + ND_PRINT("\n\t end lsp-id: %s", + isis_print_id(ndo, header_csnp->end_lsp_id, LSP_ID_LEN)); if (ndo->ndo_vflag > 1) { if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_CSNP_HEADER_SIZE)) return (0); } - packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE); + INVALID_OR_DECREMENT(packet_len,ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE); pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE); break; case ISIS_PDU_L1_PSNP: case ISIS_PDU_L2_PSNP: - if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)) { - ND_PRINT((ndo, "- bogus fixed header length %u should be %lu", - isis_header->fixed_len, (unsigned long)(ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE))); + if (fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)) { + ND_PRINT("- bogus fixed header length %u should be %zu", + fixed_len, ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE); return (0); } - ND_TCHECK(*header_psnp); + ND_TCHECK_SIZE(header_psnp); if (length < ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE) goto trunc; if (ndo->ndo_vflag == 0) { - ND_PRINT((ndo, ", src-id %s", isis_print_id(header_psnp->source_id, NODE_ID_LEN))); - ND_PRINT((ndo, ", length %u", length)); + ND_PRINT(", src-id %s", isis_print_id(ndo, header_psnp->source_id, NODE_ID_LEN)); + ND_PRINT(", length %u", length); return (1); } - pdu_len=EXTRACT_16BITS(header_psnp->pdu_len); + pdu_len=GET_BE_U_2(header_psnp->pdu_len); if (packet_len>pdu_len) { packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ length=pdu_len; } - ND_PRINT((ndo, "\n\t source-id: %s, PDU length: %u", - isis_print_id(header_psnp->source_id, NODE_ID_LEN), - pdu_len)); + ND_PRINT("\n\t source-id: %s, PDU length: %u", + isis_print_id(ndo, header_psnp->source_id, NODE_ID_LEN), + pdu_len); if (ndo->ndo_vflag > 1) { if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_PSNP_HEADER_SIZE)) return (0); } - packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE); + INVALID_OR_DECREMENT(packet_len,ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE); pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE); break; default: if (ndo->ndo_vflag == 0) { - ND_PRINT((ndo, ", length %u", length)); + ND_PRINT(", length %u", length); return (1); } (void)print_unknown_data(ndo, pptr, "\n\t ", length); @@ -2540,25 +2855,23 @@ isis_print(netdissect_options *ndo, */ while (packet_len > 0) { - ND_TCHECK2(*pptr, 2); + ND_TCHECK_2(pptr); if (packet_len < 2) goto trunc; - tlv_type = *pptr++; - tlv_len = *pptr++; - tmp =tlv_len; /* copy temporary len & pointer to packet data */ - tptr = pptr; + tlv_type = GET_U_1(pptr); + tlv_len = GET_U_1(pptr + 1); + pptr += 2; packet_len -= 2; + tlen = tlv_len; /* copy temporary len & pointer to packet data */ + tptr = pptr; /* first lets see if we know the TLVs name*/ - ND_PRINT((ndo, "\n\t %s TLV #%u, length: %u", + ND_PRINT("\n\t %s TLV #%u, length: %u", tok2str(isis_tlv_values, "unknown", tlv_type), tlv_type, - tlv_len)); - - if (tlv_len == 0) /* something is invalid */ - continue; + tlv_len); if (packet_len < tlv_len) goto trunc; @@ -2566,45 +2879,46 @@ isis_print(netdissect_options *ndo, /* now check if we have a decoder otherwise do a hexdump at the end*/ switch (tlv_type) { case ISIS_TLV_AREA_ADDR: - ND_TCHECK2(*tptr, 1); - alen = *tptr++; - while (tmp && alen < tmp) { - ND_TCHECK2(*tptr, alen); - ND_PRINT((ndo, "\n\t Area address (length: %u): %s", + while (tlen != 0) { + alen = GET_U_1(tptr); + tptr++; + tlen--; + if (tlen < alen) + goto tlv_trunc; + ND_PRINT("\n\t Area address (length: %u): %s", alen, - isonsap_string(ndo, tptr, alen))); + GET_ISONSAP_STRING(tptr, alen)); tptr += alen; - tmp -= alen + 1; - if (tmp==0) /* if this is the last area address do not attemt a boundary check */ - break; - ND_TCHECK2(*tptr, 1); - alen = *tptr++; + tlen -= alen; } break; case ISIS_TLV_ISNEIGH: - while (tmp >= ETHER_ADDR_LEN) { - ND_TCHECK2(*tptr, ETHER_ADDR_LEN); - ND_PRINT((ndo, "\n\t SNPA: %s", isis_print_id(tptr, ETHER_ADDR_LEN))); - tmp -= ETHER_ADDR_LEN; - tptr += ETHER_ADDR_LEN; + while (tlen != 0) { + if (tlen < MAC_ADDR_LEN) + goto tlv_trunc; + ND_TCHECK_LEN(tptr, MAC_ADDR_LEN); + ND_PRINT("\n\t SNPA: %s", isis_print_id(ndo, tptr, MAC_ADDR_LEN)); + tlen -= MAC_ADDR_LEN; + tptr += MAC_ADDR_LEN; } break; - case ISIS_TLV_ISNEIGH_VARLEN: - if (!ND_TTEST2(*tptr, 1) || tmp < 3) /* min. TLV length */ - goto trunctlv; - lan_alen = *tptr++; /* LAN address length */ - if (lan_alen == 0) { - ND_PRINT((ndo, "\n\t LAN address length 0 bytes (invalid)")); - break; - } - tmp --; - ND_PRINT((ndo, "\n\t LAN address length %u bytes ", lan_alen)); - while (tmp >= lan_alen) { - ND_TCHECK2(*tptr, lan_alen); - ND_PRINT((ndo, "\n\t\tIS Neighbor: %s", isis_print_id(tptr, lan_alen))); - tmp -= lan_alen; - tptr +=lan_alen; + case ISIS_TLV_INSTANCE_ID: + if (tlen < 4) + goto tlv_trunc; + num_vals = (tlen-2)/2; + ND_PRINT("\n\t Instance ID: %u, ITIDs(%u)%s ", + GET_BE_U_2(tptr), num_vals, + num_vals ? ":" : ""); + tptr += 2; + tlen -= 2; + for (i=0; i < num_vals; i++) { + ND_PRINT("%u", GET_BE_U_2(tptr)); + if (i < (num_vals - 1)) { + ND_PRINT(", "); + } + tptr += 2; + tlen -= 2; } break; @@ -2612,65 +2926,86 @@ isis_print(netdissect_options *ndo, break; case ISIS_TLV_MT_IS_REACH: - mt_len = isis_print_mtid(ndo, tptr, "\n\t "); + mt_len = isis_print_mtid(ndo, tptr, "\n\t ", tlen); if (mt_len == 0) /* did something go wrong ? */ - goto trunctlv; + goto trunc; tptr+=mt_len; - tmp-=mt_len; - while (tmp >= 2+NODE_ID_LEN+3+1) { - ext_is_len = isis_print_ext_is_reach(ndo, tptr, "\n\t ", tlv_type); + tlen-=mt_len; + while (tlen != 0) { + ext_is_len = isis_print_ext_is_reach(ndo, tptr, "\n\t ", tlv_type, tlen); if (ext_is_len == 0) /* did something go wrong ? */ - goto trunctlv; - - tmp-=ext_is_len; - tptr+=ext_is_len; + goto trunc; + if (tlen < ext_is_len) { + ND_PRINT(" [remaining tlv length %u < %u]", tlen, ext_is_len); + nd_print_invalid(ndo); + break; + } + tlen-=(uint8_t)ext_is_len; + tptr+=(uint8_t)ext_is_len; } break; case ISIS_TLV_IS_ALIAS_ID: - while (tmp >= NODE_ID_LEN+1) { /* is it worth attempting a decode ? */ - ext_is_len = isis_print_ext_is_reach(ndo, tptr, "\n\t ", tlv_type); + while (tlen != 0) { + ext_is_len = isis_print_ext_is_reach(ndo, tptr, "\n\t ", tlv_type, tlen); if (ext_is_len == 0) /* did something go wrong ? */ - goto trunctlv; - tmp-=ext_is_len; - tptr+=ext_is_len; + goto trunc; + if (tlen < ext_is_len) { + ND_PRINT(" [remaining tlv length %u < %u]", tlen, ext_is_len); + nd_print_invalid(ndo); + break; + } + tlen-=(uint8_t)ext_is_len; + tptr+=(uint8_t)ext_is_len; } break; case ISIS_TLV_EXT_IS_REACH: - while (tmp >= NODE_ID_LEN+3+1) { /* is it worth attempting a decode ? */ - ext_is_len = isis_print_ext_is_reach(ndo, tptr, "\n\t ", tlv_type); + while (tlen != 0) { + ext_is_len = isis_print_ext_is_reach(ndo, tptr, "\n\t ", tlv_type, tlen); if (ext_is_len == 0) /* did something go wrong ? */ - goto trunctlv; - tmp-=ext_is_len; - tptr+=ext_is_len; + goto trunc; + if (tlen < ext_is_len) { + ND_PRINT(" [remaining tlv length %u < %u]", tlen, ext_is_len); + nd_print_invalid(ndo); + break; + } + tlen-=(uint8_t)ext_is_len; + tptr+=(uint8_t)ext_is_len; } break; case ISIS_TLV_IS_REACH: - ND_TCHECK2(*tptr,1); /* check if there is one byte left to read out the virtual flag */ - ND_PRINT((ndo, "\n\t %s", + if (tlen < 1) + goto tlv_trunc; + ND_PRINT("\n\t %s", tok2str(isis_is_reach_virtual_values, "bogus virtual flag 0x%02x", - *tptr++))); + GET_U_1(tptr))); + tptr++; + tlen--; tlv_is_reach = (const struct isis_tlv_is_reach *)tptr; - while (tmp >= sizeof(struct isis_tlv_is_reach)) { - ND_TCHECK(*tlv_is_reach); - ND_PRINT((ndo, "\n\t IS Neighbor: %s", - isis_print_id(tlv_is_reach->neighbor_nodeid, NODE_ID_LEN))); + while (tlen != 0) { + if (tlen < sizeof(struct isis_tlv_is_reach)) + goto tlv_trunc; + ND_TCHECK_SIZE(tlv_is_reach); + ND_PRINT("\n\t IS Neighbor: %s", + isis_print_id(ndo, tlv_is_reach->neighbor_nodeid, NODE_ID_LEN)); isis_print_metric_block(ndo, &tlv_is_reach->isis_metric_block); - tmp -= sizeof(struct isis_tlv_is_reach); + tlen -= sizeof(struct isis_tlv_is_reach); tlv_is_reach++; } break; case ISIS_TLV_ESNEIGH: tlv_es_reach = (const struct isis_tlv_es_reach *)tptr; - while (tmp >= sizeof(struct isis_tlv_es_reach)) { - ND_TCHECK(*tlv_es_reach); - ND_PRINT((ndo, "\n\t ES Neighbor: %s", - isis_print_id(tlv_es_reach->neighbor_sysid, SYSTEM_ID_LEN))); + while (tlen != 0) { + if (tlen < sizeof(struct isis_tlv_es_reach)) + goto tlv_trunc; + ND_TCHECK_SIZE(tlv_es_reach); + ND_PRINT("\n\t ES Neighbor: %s", + isis_print_id(ndo, tlv_es_reach->neighbor_sysid, SYSTEM_ID_LEN)); isis_print_metric_block(ndo, &tlv_es_reach->isis_metric_block); - tmp -= sizeof(struct isis_tlv_es_reach); + tlen -= sizeof(struct isis_tlv_es_reach); tlv_es_reach++; } break; @@ -2683,109 +3018,133 @@ isis_print(netdissect_options *ndo, break; case ISIS_TLV_EXTD_IP_REACH: - while (tmp>0) { + while (tlen != 0) { ext_ip_len = isis_print_extd_ip_reach(ndo, tptr, "\n\t ", AF_INET); if (ext_ip_len == 0) /* did something go wrong ? */ - goto trunctlv; - tptr+=ext_ip_len; - tmp-=ext_ip_len; - } - break; + goto trunc; + if (tlen < ext_ip_len) { + ND_PRINT(" [remaining tlv length %u < %u]", tlen, ext_ip_len); + nd_print_invalid(ndo); + break; + } + tlen-=(uint8_t)ext_ip_len; + tptr+=(uint8_t)ext_ip_len; + } + break; case ISIS_TLV_MT_IP_REACH: - mt_len = isis_print_mtid(ndo, tptr, "\n\t "); + mt_len = isis_print_mtid(ndo, tptr, "\n\t ", tlen); if (mt_len == 0) { /* did something go wrong ? */ - goto trunctlv; + goto trunc; } tptr+=mt_len; - tmp-=mt_len; + tlen-=mt_len; - while (tmp>0) { + while (tlen != 0) { ext_ip_len = isis_print_extd_ip_reach(ndo, tptr, "\n\t ", AF_INET); if (ext_ip_len == 0) /* did something go wrong ? */ - goto trunctlv; - tptr+=ext_ip_len; - tmp-=ext_ip_len; - } - break; + goto trunc; + if (tlen < ext_ip_len) { + ND_PRINT(" [remaining tlv length %u < %u]", tlen, ext_ip_len); + nd_print_invalid(ndo); + break; + } + tlen-=(uint8_t)ext_ip_len; + tptr+=(uint8_t)ext_ip_len; + } + break; case ISIS_TLV_IP6_REACH: - while (tmp>0) { + while (tlen != 0) { ext_ip_len = isis_print_extd_ip_reach(ndo, tptr, "\n\t ", AF_INET6); if (ext_ip_len == 0) /* did something go wrong ? */ - goto trunctlv; - tptr+=ext_ip_len; - tmp-=ext_ip_len; - } - break; + goto trunc; + if (tlen < ext_ip_len) { + ND_PRINT(" [remaining tlv length %u < %u]", tlen, ext_ip_len); + nd_print_invalid(ndo); + break; + } + tlen-=(uint8_t)ext_ip_len; + tptr+=(uint8_t)ext_ip_len; + } + break; case ISIS_TLV_MT_IP6_REACH: - mt_len = isis_print_mtid(ndo, tptr, "\n\t "); + mt_len = isis_print_mtid(ndo, tptr, "\n\t ", tlen); if (mt_len == 0) { /* did something go wrong ? */ - goto trunctlv; + goto trunc; } tptr+=mt_len; - tmp-=mt_len; + tlen-=mt_len; - while (tmp>0) { + while (tlen != 0) { ext_ip_len = isis_print_extd_ip_reach(ndo, tptr, "\n\t ", AF_INET6); if (ext_ip_len == 0) /* did something go wrong ? */ - goto trunctlv; - tptr+=ext_ip_len; - tmp-=ext_ip_len; - } - break; + goto trunc; + if (tlen < ext_ip_len) { + ND_PRINT(" [remaining tlv length %u < %u]", tlen, ext_ip_len); + nd_print_invalid(ndo); + break; + } + tlen-=(uint8_t)ext_ip_len; + tptr+=(uint8_t)ext_ip_len; + } + break; case ISIS_TLV_IP6ADDR: - while (tmp>=sizeof(struct in6_addr)) { - ND_TCHECK2(*tptr, sizeof(struct in6_addr)); - - ND_PRINT((ndo, "\n\t IPv6 interface address: %s", - ip6addr_string(ndo, tptr))); - - tptr += sizeof(struct in6_addr); - tmp -= sizeof(struct in6_addr); + while (tlen != 0) { + if (tlen < sizeof(nd_ipv6)) + goto tlv_trunc; + ND_PRINT("\n\t IPv6 interface address: %s", + GET_IP6ADDR_STRING(tptr)); + + tptr += sizeof(nd_ipv6); + tlen -= sizeof(nd_ipv6); } break; case ISIS_TLV_AUTH: - ND_TCHECK2(*tptr, 1); + if (tlen < 1) + goto tlv_trunc; + auth_type = GET_U_1(tptr); + tptr++; + tlen--; - ND_PRINT((ndo, "\n\t %s: ", + ND_PRINT("\n\t %s: ", tok2str(isis_subtlv_auth_values, "unknown Authentication type 0x%02x", - *tptr))); + auth_type)); - switch (*tptr) { + switch (auth_type) { case ISIS_SUBTLV_AUTH_SIMPLE: - if (fn_printzp(ndo, tptr + 1, tlv_len - 1, ndo->ndo_snapend)) - goto trunctlv; + nd_printjnp(ndo, tptr, tlen); break; case ISIS_SUBTLV_AUTH_MD5: - for(i=1;i=1) { - ND_TCHECK2(*tptr, 1); - ND_PRINT((ndo, "\n\t Adjacency State: %s (%u)", - tok2str(isis_ptp_adjancey_values, "unknown", *tptr), - *tptr)); - tmp--; + if(tlen>=1) { + ND_PRINT("\n\t Adjacency State: %s (%u)", + tok2str(isis_ptp_adjancey_values, "unknown", GET_U_1(tptr)), + GET_U_1(tptr)); + tlen--; } - if(tmp>sizeof(tlv_ptp_adj->extd_local_circuit_id)) { - ND_TCHECK(tlv_ptp_adj->extd_local_circuit_id); - ND_PRINT((ndo, "\n\t Extended Local circuit-ID: 0x%08x", - EXTRACT_32BITS(tlv_ptp_adj->extd_local_circuit_id))); - tmp-=sizeof(tlv_ptp_adj->extd_local_circuit_id); + if(tlen>sizeof(tlv_ptp_adj->extd_local_circuit_id)) { + ND_PRINT("\n\t Extended Local circuit-ID: 0x%08x", + GET_BE_U_4(tlv_ptp_adj->extd_local_circuit_id)); + tlen-=sizeof(tlv_ptp_adj->extd_local_circuit_id); } - if(tmp>=SYSTEM_ID_LEN) { - ND_TCHECK2(tlv_ptp_adj->neighbor_sysid, SYSTEM_ID_LEN); - ND_PRINT((ndo, "\n\t Neighbor System-ID: %s", - isis_print_id(tlv_ptp_adj->neighbor_sysid, SYSTEM_ID_LEN))); - tmp-=SYSTEM_ID_LEN; + if(tlen>=SYSTEM_ID_LEN) { + ND_TCHECK_LEN(tlv_ptp_adj->neighbor_sysid, SYSTEM_ID_LEN); + ND_PRINT("\n\t Neighbor System-ID: %s", + isis_print_id(ndo, tlv_ptp_adj->neighbor_sysid, SYSTEM_ID_LEN)); + tlen-=SYSTEM_ID_LEN; } - if(tmp>=sizeof(tlv_ptp_adj->neighbor_extd_local_circuit_id)) { - ND_TCHECK(tlv_ptp_adj->neighbor_extd_local_circuit_id); - ND_PRINT((ndo, "\n\t Neighbor Extended Local circuit-ID: 0x%08x", - EXTRACT_32BITS(tlv_ptp_adj->neighbor_extd_local_circuit_id))); + if(tlen>=sizeof(tlv_ptp_adj->neighbor_extd_local_circuit_id)) { + ND_PRINT("\n\t Neighbor Extended Local circuit-ID: 0x%08x", + GET_BE_U_4(tlv_ptp_adj->neighbor_extd_local_circuit_id)); } break; case ISIS_TLV_PROTOCOLS: - ND_PRINT((ndo, "\n\t NLPID(s): ")); - while (tmp>0) { - ND_TCHECK2(*(tptr), 1); - ND_PRINT((ndo, "%s (0x%02x)", + ND_PRINT("\n\t NLPID(s): "); + while (tlen != 0) { + ND_PRINT("%s (0x%02x)", tok2str(nlpid_values, "unknown", - *tptr), - *tptr)); - if (tmp>1) /* further NPLIDs ? - put comma */ - ND_PRINT((ndo, ", ")); + GET_U_1(tptr)), + GET_U_1(tptr)); + if (tlen>1) /* further NPLIDs ? - put comma */ + ND_PRINT(", "); tptr++; - tmp--; + tlen--; } break; - case ISIS_TLV_MT_PORT_CAP: - { - ND_TCHECK2(*(tptr), 2); - - ND_PRINT((ndo, "\n\t RES: %d, MTID(s): %d", - (EXTRACT_16BITS (tptr) >> 12), - (EXTRACT_16BITS (tptr) & 0x0fff))); + case ISIS_TLV_MT_PORT_CAP: + { + if (tlen < 2) + goto tlv_trunc; - tmp = tmp-2; - tptr = tptr+2; + ND_PRINT("\n\t RES: %u, MTID(s): %u", + (GET_BE_U_2(tptr) >> 12), + (GET_BE_U_2(tptr) & 0x0fff)); - if (tmp) - isis_print_mt_port_cap_subtlv(ndo, tptr, tmp); + tptr += 2; + tlen -= 2; - break; - } + if (tlen) + isis_print_mt_port_cap_subtlv(ndo, tptr, tlen); - case ISIS_TLV_MT_CAPABILITY: + break; + } - ND_TCHECK2(*(tptr), 2); + case ISIS_TLV_MT_CAPABILITY: + if (tlen < 2) + goto tlv_trunc; - ND_PRINT((ndo, "\n\t O: %d, RES: %d, MTID(s): %d", - (EXTRACT_16BITS(tptr) >> 15) & 0x01, - (EXTRACT_16BITS(tptr) >> 12) & 0x07, - EXTRACT_16BITS(tptr) & 0x0fff)); + ND_PRINT("\n\t O: %u, RES: %u, MTID(s): %u", + (GET_BE_U_2(tptr) >> 15) & 0x01, + (GET_BE_U_2(tptr) >> 12) & 0x07, + GET_BE_U_2(tptr) & 0x0fff); - tmp = tmp-2; - tptr = tptr+2; + tptr += 2; + tlen -= 2; - if (tmp) - isis_print_mt_capability_subtlv(ndo, tptr, tmp); + if (tlen) + isis_print_mt_capability_subtlv(ndo, tptr, tlen); - break; + break; case ISIS_TLV_TE_ROUTER_ID: - ND_TCHECK2(*pptr, sizeof(struct in_addr)); - ND_PRINT((ndo, "\n\t Traffic Engineering Router ID: %s", ipaddr_string(ndo, pptr))); + if (tlen < sizeof(nd_ipv4)) + goto tlv_trunc; + ND_PRINT("\n\t Traffic Engineering Router ID: %s", GET_IPADDR_STRING(pptr)); break; case ISIS_TLV_IPADDR: - while (tmp>=sizeof(struct in_addr)) { - ND_TCHECK2(*tptr, sizeof(struct in_addr)); - ND_PRINT((ndo, "\n\t IPv4 interface address: %s", ipaddr_string(ndo, tptr))); - tptr += sizeof(struct in_addr); - tmp -= sizeof(struct in_addr); + while (tlen != 0) { + if (tlen < sizeof(nd_ipv4)) + goto tlv_trunc; + ND_PRINT("\n\t IPv4 interface address: %s", GET_IPADDR_STRING(tptr)); + tptr += sizeof(nd_ipv4); + tlen -= sizeof(nd_ipv4); } break; case ISIS_TLV_HOSTNAME: - ND_PRINT((ndo, "\n\t Hostname: ")); - if (fn_printzp(ndo, tptr, tmp, ndo->ndo_snapend)) - goto trunctlv; + ND_PRINT("\n\t Hostname: "); + nd_printjnp(ndo, tptr, tlen); break; case ISIS_TLV_SHARED_RISK_GROUP: - if (tmp < NODE_ID_LEN) + if (tlen < NODE_ID_LEN) break; - ND_TCHECK2(*tptr, NODE_ID_LEN); - ND_PRINT((ndo, "\n\t IS Neighbor: %s", isis_print_id(tptr, NODE_ID_LEN))); - tptr+=(NODE_ID_LEN); - tmp-=(NODE_ID_LEN); + ND_TCHECK_LEN(tptr, NODE_ID_LEN); + ND_PRINT("\n\t IS Neighbor: %s", isis_print_id(ndo, tptr, NODE_ID_LEN)); + tptr+=NODE_ID_LEN; + tlen-=NODE_ID_LEN; - if (tmp < 1) + if (tlen < 1) break; - ND_TCHECK2(*tptr, 1); - ND_PRINT((ndo, ", Flags: [%s]", ISIS_MASK_TLV_SHARED_RISK_GROUP(*tptr++) ? "numbered" : "unnumbered")); - tmp--; + ND_PRINT(", Flags: [%s]", + ISIS_MASK_TLV_SHARED_RISK_GROUP(GET_U_1(tptr)) ? "numbered" : "unnumbered"); + tptr++; + tlen--; - if (tmp < sizeof(struct in_addr)) + if (tlen < sizeof(nd_ipv4)) break; - ND_TCHECK2(*tptr, sizeof(struct in_addr)); - ND_PRINT((ndo, "\n\t IPv4 interface address: %s", ipaddr_string(ndo, tptr))); - tptr+=sizeof(struct in_addr); - tmp-=sizeof(struct in_addr); + ND_PRINT("\n\t IPv4 interface address: %s", GET_IPADDR_STRING(tptr)); + tptr+=sizeof(nd_ipv4); + tlen-=sizeof(nd_ipv4); - if (tmp < sizeof(struct in_addr)) + if (tlen < sizeof(nd_ipv4)) break; - ND_TCHECK2(*tptr, sizeof(struct in_addr)); - ND_PRINT((ndo, "\n\t IPv4 neighbor address: %s", ipaddr_string(ndo, tptr))); - tptr+=sizeof(struct in_addr); - tmp-=sizeof(struct in_addr); - - while (tmp>=4) { - ND_TCHECK2(*tptr, 4); - ND_PRINT((ndo, "\n\t Link-ID: 0x%08x", EXTRACT_32BITS(tptr))); + ND_PRINT("\n\t IPv4 neighbor address: %s", GET_IPADDR_STRING(tptr)); + tptr+=sizeof(nd_ipv4); + tlen-=sizeof(nd_ipv4); + + while (tlen != 0) { + if (tlen < 4) + goto tlv_trunc; + ND_PRINT("\n\t Link-ID: 0x%08x", GET_BE_U_4(tptr)); tptr+=4; - tmp-=4; + tlen-=4; } break; case ISIS_TLV_LSP: tlv_lsp = (const struct isis_tlv_lsp *)tptr; - while(tmp>=sizeof(struct isis_tlv_lsp)) { - ND_TCHECK((tlv_lsp->lsp_id)[LSP_ID_LEN-1]); - ND_PRINT((ndo, "\n\t lsp-id: %s", - isis_print_id(tlv_lsp->lsp_id, LSP_ID_LEN))); - ND_TCHECK2(tlv_lsp->sequence_number, 4); - ND_PRINT((ndo, ", seq: 0x%08x", EXTRACT_32BITS(tlv_lsp->sequence_number))); - ND_TCHECK2(tlv_lsp->remaining_lifetime, 2); - ND_PRINT((ndo, ", lifetime: %5ds", EXTRACT_16BITS(tlv_lsp->remaining_lifetime))); - ND_TCHECK2(tlv_lsp->checksum, 2); - ND_PRINT((ndo, ", chksum: 0x%04x", EXTRACT_16BITS(tlv_lsp->checksum))); - tmp-=sizeof(struct isis_tlv_lsp); + while (tlen != 0) { + if (tlen < sizeof(struct isis_tlv_lsp)) + goto tlv_trunc; + ND_TCHECK_1(tlv_lsp->lsp_id + LSP_ID_LEN - 1); + ND_PRINT("\n\t lsp-id: %s", + isis_print_id(ndo, tlv_lsp->lsp_id, LSP_ID_LEN)); + ND_PRINT(", seq: 0x%08x", + GET_BE_U_4(tlv_lsp->sequence_number)); + ND_PRINT(", lifetime: %5ds", + GET_BE_U_2(tlv_lsp->remaining_lifetime)); + ND_PRINT(", chksum: 0x%04x", GET_BE_U_2(tlv_lsp->checksum)); + tlen-=sizeof(struct isis_tlv_lsp); tlv_lsp++; } break; case ISIS_TLV_CHECKSUM: - if (tmp < ISIS_TLV_CHECKSUM_MINLEN) + if (tlen < ISIS_TLV_CHECKSUM_MINLEN) break; - ND_TCHECK2(*tptr, ISIS_TLV_CHECKSUM_MINLEN); - ND_PRINT((ndo, "\n\t checksum: 0x%04x ", EXTRACT_16BITS(tptr))); + ND_TCHECK_LEN(tptr, ISIS_TLV_CHECKSUM_MINLEN); + ND_PRINT("\n\t checksum: 0x%04x ", GET_BE_U_2(tptr)); /* do not attempt to verify the checksum if it is zero * most likely a HMAC-MD5 TLV is also present and * to avoid conflicts the checksum TLV is zeroed. * see rfc3358 for details */ - osi_print_cksum(ndo, optr, EXTRACT_16BITS(tptr), tptr-optr, - length); + osi_print_cksum(ndo, optr, GET_BE_U_2(tptr), (int)(tptr-optr), + length); break; case ISIS_TLV_POI: - if (tlv_len >= SYSTEM_ID_LEN + 1) { - ND_TCHECK2(*tptr, SYSTEM_ID_LEN + 1); - ND_PRINT((ndo, "\n\t Purge Originator System-ID: %s", - isis_print_id(tptr + 1, SYSTEM_ID_LEN))); - } - - if (tlv_len == 2 * SYSTEM_ID_LEN + 1) { - ND_TCHECK2(*tptr, 2 * SYSTEM_ID_LEN + 1); - ND_PRINT((ndo, "\n\t Received from System-ID: %s", - isis_print_id(tptr + SYSTEM_ID_LEN + 1, SYSTEM_ID_LEN))); + if (tlen < 1) + goto tlv_trunc; + num_system_ids = GET_U_1(tptr); + tptr++; + tlen--; + if (num_system_ids == 0) { + /* Not valid */ + ND_PRINT(" No system IDs supplied"); + } else { + if (tlen < SYSTEM_ID_LEN) + goto tlv_trunc; + ND_TCHECK_LEN(tptr, SYSTEM_ID_LEN); + ND_PRINT("\n\t Purge Originator System-ID: %s", + isis_print_id(ndo, tptr, SYSTEM_ID_LEN)); + tptr += SYSTEM_ID_LEN; + tlen -= SYSTEM_ID_LEN; + + if (num_system_ids > 1) { + if (tlen < SYSTEM_ID_LEN) + goto tlv_trunc; + ND_TCHECK_LEN(tptr, SYSTEM_ID_LEN); + ND_TCHECK_LEN(tptr, 2 * SYSTEM_ID_LEN + 1); + ND_PRINT("\n\t Received from System-ID: %s", + isis_print_id(ndo, tptr, SYSTEM_ID_LEN)); + } } break; case ISIS_TLV_MT_SUPPORTED: - if (tmp < ISIS_TLV_MT_SUPPORTED_MINLEN) - break; - while (tmp>1) { + while (tlen != 0) { /* length can only be a multiple of 2, otherwise there is something broken -> so decode down until length is 1 */ - if (tmp!=1) { - mt_len = isis_print_mtid(ndo, tptr, "\n\t "); + if (tlen!=1) { + mt_len = isis_print_mtid(ndo, tptr, "\n\t ", tlen); if (mt_len == 0) /* did something go wrong ? */ - goto trunctlv; + goto trunc; tptr+=mt_len; - tmp-=mt_len; + tlen-=mt_len; } else { - ND_PRINT((ndo, "\n\t invalid MT-ID")); + ND_PRINT("\n\t invalid MT-ID"); break; } } @@ -2991,117 +3362,134 @@ isis_print(netdissect_options *ndo, case ISIS_TLV_RESTART_SIGNALING: /* first attempt to decode the flags */ - if (tmp < ISIS_TLV_RESTART_SIGNALING_FLAGLEN) + if (tlen < ISIS_TLV_RESTART_SIGNALING_FLAGLEN) break; - ND_TCHECK2(*tptr, ISIS_TLV_RESTART_SIGNALING_FLAGLEN); - ND_PRINT((ndo, "\n\t Flags [%s]", - bittok2str(isis_restart_flag_values, "none", *tptr))); + ND_TCHECK_LEN(tptr, ISIS_TLV_RESTART_SIGNALING_FLAGLEN); + ND_PRINT("\n\t Flags [%s]", + bittok2str(isis_restart_flag_values, "none", GET_U_1(tptr))); tptr+=ISIS_TLV_RESTART_SIGNALING_FLAGLEN; - tmp-=ISIS_TLV_RESTART_SIGNALING_FLAGLEN; + tlen-=ISIS_TLV_RESTART_SIGNALING_FLAGLEN; /* is there anything other than the flags field? */ - if (tmp == 0) + if (tlen == 0) break; - if (tmp < ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN) + if (tlen < ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN) break; - ND_TCHECK2(*tptr, ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN); + ND_TCHECK_LEN(tptr, ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN); - ND_PRINT((ndo, ", Remaining holding time %us", EXTRACT_16BITS(tptr))); + ND_PRINT(", Remaining holding time %us", GET_BE_U_2(tptr)); tptr+=ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN; - tmp-=ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN; + tlen-=ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN; /* is there an additional sysid field present ?*/ - if (tmp == SYSTEM_ID_LEN) { - ND_TCHECK2(*tptr, SYSTEM_ID_LEN); - ND_PRINT((ndo, ", for %s", isis_print_id(tptr,SYSTEM_ID_LEN))); + if (tlen == SYSTEM_ID_LEN) { + ND_TCHECK_LEN(tptr, SYSTEM_ID_LEN); + ND_PRINT(", for %s", isis_print_id(ndo, tptr,SYSTEM_ID_LEN)); } break; case ISIS_TLV_IDRP_INFO: - if (tmp < ISIS_TLV_IDRP_INFO_MINLEN) + if (tlen < 1) break; - ND_TCHECK2(*tptr, ISIS_TLV_IDRP_INFO_MINLEN); - ND_PRINT((ndo, "\n\t Inter-Domain Information Type: %s", + isis_subtlv_idrp = GET_U_1(tptr); + ND_PRINT("\n\t Inter-Domain Information Type: %s", tok2str(isis_subtlv_idrp_values, "Unknown (0x%02x)", - *tptr))); - switch (*tptr++) { + isis_subtlv_idrp)); + tptr++; + tlen--; + switch (isis_subtlv_idrp) { case ISIS_SUBTLV_IDRP_ASN: - ND_TCHECK2(*tptr, 2); /* fetch AS number */ - ND_PRINT((ndo, "AS Number: %u", EXTRACT_16BITS(tptr))); + if (tlen < 2) + goto tlv_trunc; + ND_PRINT("AS Number: %u", GET_BE_U_2(tptr)); break; case ISIS_SUBTLV_IDRP_LOCAL: case ISIS_SUBTLV_IDRP_RES: default: - if (!print_unknown_data(ndo, tptr, "\n\t ", tlv_len - 1)) + if (!print_unknown_data(ndo, tptr, "\n\t ", tlen)) return(0); break; } break; case ISIS_TLV_LSP_BUFFERSIZE: - if (tmp < ISIS_TLV_LSP_BUFFERSIZE_MINLEN) + if (tlen < 2) break; - ND_TCHECK2(*tptr, ISIS_TLV_LSP_BUFFERSIZE_MINLEN); - ND_PRINT((ndo, "\n\t LSP Buffersize: %u", EXTRACT_16BITS(tptr))); + ND_PRINT("\n\t LSP Buffersize: %u", GET_BE_U_2(tptr)); break; case ISIS_TLV_PART_DIS: - while (tmp >= SYSTEM_ID_LEN) { - ND_TCHECK2(*tptr, SYSTEM_ID_LEN); - ND_PRINT((ndo, "\n\t %s", isis_print_id(tptr, SYSTEM_ID_LEN))); + while (tlen != 0) { + if (tlen < SYSTEM_ID_LEN) + goto tlv_trunc; + ND_TCHECK_LEN(tptr, SYSTEM_ID_LEN); + ND_PRINT("\n\t %s", isis_print_id(ndo, tptr, SYSTEM_ID_LEN)); tptr+=SYSTEM_ID_LEN; - tmp-=SYSTEM_ID_LEN; + tlen-=SYSTEM_ID_LEN; } break; case ISIS_TLV_PREFIX_NEIGH: - if (tmp < sizeof(struct isis_metric_block)) + if (tlen < sizeof(struct isis_metric_block)) break; - ND_TCHECK2(*tptr, sizeof(struct isis_metric_block)); - ND_PRINT((ndo, "\n\t Metric Block")); + ND_TCHECK_LEN(tptr, sizeof(struct isis_metric_block)); + ND_PRINT("\n\t Metric Block"); isis_print_metric_block(ndo, (const struct isis_metric_block *)tptr); tptr+=sizeof(struct isis_metric_block); - tmp-=sizeof(struct isis_metric_block); + tlen-=sizeof(struct isis_metric_block); - while(tmp>0) { - ND_TCHECK2(*tptr, 1); - prefix_len=*tptr++; /* read out prefix length in semioctets*/ + while (tlen != 0) { + prefix_len=GET_U_1(tptr); /* read out prefix length in semioctets*/ + tptr++; + tlen--; if (prefix_len < 2) { - ND_PRINT((ndo, "\n\t\tAddress: prefix length %u < 2", prefix_len)); + ND_PRINT("\n\t\tAddress: prefix length %u < 2", prefix_len); break; } - tmp--; - if (tmp < prefix_len/2) + if (tlen < prefix_len/2) break; - ND_TCHECK2(*tptr, prefix_len / 2); - ND_PRINT((ndo, "\n\t\tAddress: %s/%u", - isonsap_string(ndo, tptr, prefix_len / 2), prefix_len * 4)); + ND_PRINT("\n\t\tAddress: %s/%u", + GET_ISONSAP_STRING(tptr, prefix_len / 2), prefix_len * 4); tptr+=prefix_len/2; - tmp-=prefix_len/2; + tlen-=prefix_len/2; } break; case ISIS_TLV_IIH_SEQNR: - if (tmp < ISIS_TLV_IIH_SEQNR_MINLEN) + if (tlen < 4) break; - ND_TCHECK2(*tptr, ISIS_TLV_IIH_SEQNR_MINLEN); /* check if four bytes are on the wire */ - ND_PRINT((ndo, "\n\t Sequence number: %u", EXTRACT_32BITS(tptr))); + ND_PRINT("\n\t Sequence number: %u", GET_BE_U_4(tptr)); + break; + + case ISIS_TLV_ROUTER_CAPABILITY: + if (tlen < 5) { + ND_PRINT(" [object length %u < 5]", tlen); + nd_print_invalid(ndo); + break; + } + ND_PRINT("\n\t Router-ID %s", GET_IPADDR_STRING(tptr)); + ND_PRINT(", Flags [%s]", + bittok2str(isis_tlv_router_capability_flags, "none", GET_U_1(tptr+4))); + + /* Optional set of sub-TLV */ + if (tlen > 5) { + isis_print_router_cap_subtlv(ndo, tptr+5, tlen-5); + } break; case ISIS_TLV_VENDOR_PRIVATE: - if (tmp < ISIS_TLV_VENDOR_PRIVATE_MINLEN) + if (tlen < 3) break; - ND_TCHECK2(*tptr, ISIS_TLV_VENDOR_PRIVATE_MINLEN); /* check if enough byte for a full oui */ - vendor_id = EXTRACT_24BITS(tptr); - ND_PRINT((ndo, "\n\t Vendor: %s (%u)", + vendor_id = GET_BE_U_3(tptr); + ND_PRINT("\n\t Vendor: %s (%u)", tok2str(oui_values, "Unknown", vendor_id), - vendor_id)); + vendor_id); tptr+=3; - tmp-=3; - if (tmp > 0) /* hexdump the rest */ - if (!print_unknown_data(ndo, tptr, "\n\t\t", tmp)) + tlen-=3; + if (tlen != 0) /* hexdump the rest */ + if (!print_unknown_data(ndo, tptr, "\n\t\t", tlen)) return(0); break; /* @@ -3122,6 +3510,7 @@ isis_print(netdissect_options *ndo, } break; } +tlv_trunc: /* do we want to see an additionally hexdump ? */ if (ndo->ndo_vflag> 1) { if (!print_unknown_data(ndo, pptr, "\n\t ", tlv_len)) @@ -3133,18 +3522,13 @@ isis_print(netdissect_options *ndo, } if (packet_len != 0) { - ND_PRINT((ndo, "\n\t %u straggler bytes", packet_len)); + ND_PRINT("\n\t %u straggler bytes", packet_len); } return (1); - trunc: - ND_PRINT((ndo, "%s", tstr)); +trunc: + nd_print_trunc(ndo); return (1); - - trunctlv: - ND_PRINT((ndo, "\n\t\t")); - ND_PRINT((ndo, "%s", tstr)); - return(1); } static void @@ -3159,26 +3543,19 @@ osi_print_cksum(netdissect_options *ndo, const uint8_t *pptr, */ if (!checksum || checksum_offset < 0 - || !ND_TTEST2(*(pptr + checksum_offset), 2) + || !ND_TTEST_2(pptr + checksum_offset) || (u_int)checksum_offset > length - || !ND_TTEST2(*pptr, length)) { - ND_PRINT((ndo, " (unverified)")); + || !ND_TTEST_LEN(pptr, length)) { + ND_PRINT(" (unverified)"); } else { #if 0 - printf("\nosi_print_cksum: %p %u %u\n", pptr, checksum_offset, length); + ND_PRINT("\nosi_print_cksum: %p %d %u\n", pptr, checksum_offset, length); #endif calculated_checksum = create_osi_cksum(pptr, checksum_offset, length); if (checksum == calculated_checksum) { - ND_PRINT((ndo, " (correct)")); + ND_PRINT(" (correct)"); } else { - ND_PRINT((ndo, " (incorrect should be 0x%04x)", calculated_checksum)); + ND_PRINT(" (incorrect should be 0x%04x)", calculated_checksum); } } } - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/print-juniper.c b/contrib/tcpdump/print-juniper.c index a969895286..7c3df49ff2 100644 --- a/contrib/tcpdump/print-juniper.c +++ b/contrib/tcpdump/print-juniper.c @@ -23,10 +23,10 @@ __RCSID("NetBSD: print-juniper.c,v 1.3 2007/07/25 06:31:32 dogcow Exp "); #endif #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include @@ -39,6 +39,17 @@ __RCSID("NetBSD: print-juniper.c,v 1.3 2007/07/25 06:31:32 dogcow Exp "); #include "ethertype.h" #include "atm.h" +/* + * If none of the Juniper DLT_s are defined, there's nothing to do. + */ +#if defined(DLT_JUNIPER_GGSN) || defined(DLT_JUNIPER_ES) || \ + defined(DLT_JUNIPER_MONITOR) || defined(DLT_JUNIPER_SERVICES) || \ + defined(DLT_JUNIPER_PPPOE) || defined(DLT_JUNIPER_ETHER) || \ + defined(DLT_JUNIPER_PPP) || defined(DLT_JUNIPER_FRELAY) || \ + defined(DLT_JUNIPER_CHDLC) || defined(DLT_JUNIPER_PPPOE_ATM) || \ + defined(DLT_JUNIPER_MLPPP) || defined(DLT_JUNIPER_MFR) || \ + defined(DLT_JUNIPER_MLFR) || defined(DLT_JUNIPER_ATM1) || \ + defined(DLT_JUNIPER_ATM2) #define JUNIPER_BPF_OUT 0 /* Outgoing packet */ #define JUNIPER_BPF_IN 1 /* Incoming packet */ #define JUNIPER_BPF_PKT_IN 0x1 /* Incoming packet */ @@ -64,6 +75,7 @@ __RCSID("NetBSD: print-juniper.c,v 1.3 2007/07/25 06:31:32 dogcow Exp "); #define JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE 4 #define JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE 5 +#ifdef DLT_JUNIPER_ES static const struct tok juniper_ipsec_type_values[] = { { JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE, "ESP ENCR-AUTH" }, { JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE, "ESP ENCR-AH AUTH" }, @@ -72,6 +84,7 @@ static const struct tok juniper_ipsec_type_values[] = { { JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE, "ESP ENCR" }, { 0, NULL} }; +#endif static const struct tok juniper_direction_values[] = { { JUNIPER_BPF_IN, "In"}, @@ -366,7 +379,7 @@ static const struct tok juniper_ifle_values[] = { struct juniper_cookie_table_t { uint32_t pictype; /* pic type */ - uint8_t cookie_len; /* cookie len */ + uint8_t cookie_len; /* cookie len */ const char *s; /* pic name */ }; @@ -412,11 +425,11 @@ struct juniper_l2info_t { uint32_t caplen; uint32_t pictype; uint8_t direction; - uint8_t header_len; + u_int header_len; uint8_t cookie_len; uint8_t cookie_type; uint8_t cookie[8]; - uint8_t bundle; + u_int bundle; uint16_t proto; uint8_t flags; }; @@ -438,49 +451,59 @@ struct juniper_l2info_t { #define MFR_BE_MASK 0xc0 +#ifdef DLT_JUNIPER_GGSN static const struct tok juniper_protocol_values[] = { { JUNIPER_PROTO_NULL, "Null" }, { JUNIPER_PROTO_IPV4, "IPv4" }, { JUNIPER_PROTO_IPV6, "IPv6" }, { 0, NULL} }; +#endif -static int ip_heuristic_guess(netdissect_options *, register const u_char *, u_int); -static int juniper_ppp_heuristic_guess(netdissect_options *, register const u_char *, u_int); +static int ip_heuristic_guess(netdissect_options *, const u_char *, u_int); +#ifdef DLT_JUNIPER_ATM2 +static int juniper_ppp_heuristic_guess(netdissect_options *, const u_char *, u_int); +#endif static int juniper_parse_header(netdissect_options *, const u_char *, const struct pcap_pkthdr *, struct juniper_l2info_t *); #ifdef DLT_JUNIPER_GGSN -u_int -juniper_ggsn_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, register const u_char *p) +void +juniper_ggsn_if_print(netdissect_options *ndo, + const struct pcap_pkthdr *h, const u_char *p) { struct juniper_l2info_t l2info; struct juniper_ggsn_header { - uint8_t svc_id; - uint8_t flags_len; - uint8_t proto; - uint8_t flags; - uint8_t vlan_id[2]; - uint8_t res[2]; + nd_uint8_t svc_id; + nd_uint8_t flags_len; + nd_uint8_t proto; + nd_uint8_t flags; + nd_uint16_t vlan_id; + nd_byte res[2]; }; const struct juniper_ggsn_header *gh; + uint8_t proto; + ndo->ndo_protocol = "juniper_ggsn"; + memset(&l2info, 0, sizeof(l2info)); l2info.pictype = DLT_JUNIPER_GGSN; - if (juniper_parse_header(ndo, p, h, &l2info) == 0) - return l2info.header_len; + if (juniper_parse_header(ndo, p, h, &l2info) == 0) { + ndo->ndo_ll_hdr_len += l2info.header_len; + return; + } p+=l2info.header_len; gh = (struct juniper_ggsn_header *)&l2info.cookie; - ND_TCHECK(*gh); + ND_TCHECK_SIZE(gh); + proto = GET_U_1(gh->proto); if (ndo->ndo_eflag) { - ND_PRINT((ndo, "proto %s (%u), vlan %u: ", - tok2str(juniper_protocol_values,"Unknown",gh->proto), - gh->proto, - EXTRACT_16BITS(&gh->vlan_id[0]))); + ND_PRINT("proto %s (%u), vlan %u: ", + tok2str(juniper_protocol_values,"Unknown",proto), + proto, + GET_BE_U_2(gh->vlan_id)); } - switch (gh->proto) { + switch (proto) { case JUNIPER_PROTO_IPV4: ip_print(ndo, p, l2info.length); break; @@ -489,43 +512,48 @@ juniper_ggsn_print(netdissect_options *ndo, break; default: if (!ndo->ndo_eflag) - ND_PRINT((ndo, "unknown GGSN proto (%u)", gh->proto)); + ND_PRINT("unknown GGSN proto (%u)", proto); } - return l2info.header_len; + ndo->ndo_ll_hdr_len += l2info.header_len; + return; trunc: - ND_PRINT((ndo, "[|juniper_services]")); - return l2info.header_len; + nd_print_trunc(ndo); + ndo->ndo_ll_hdr_len += l2info.header_len; } #endif #ifdef DLT_JUNIPER_ES -u_int -juniper_es_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, register const u_char *p) +void +juniper_es_if_print(netdissect_options *ndo, + const struct pcap_pkthdr *h, const u_char *p) { struct juniper_l2info_t l2info; struct juniper_ipsec_header { - uint8_t sa_index[2]; - uint8_t ttl; - uint8_t type; - uint8_t spi[4]; - uint8_t src_ip[4]; - uint8_t dst_ip[4]; + nd_uint16_t sa_index; + nd_uint8_t ttl; + nd_uint8_t type; + nd_uint32_t spi; + nd_ipv4 src_ip; + nd_ipv4 dst_ip; }; u_int rewrite_len,es_type_bundle; const struct juniper_ipsec_header *ih; + ndo->ndo_protocol = "juniper_es"; + memset(&l2info, 0, sizeof(l2info)); l2info.pictype = DLT_JUNIPER_ES; - if (juniper_parse_header(ndo, p, h, &l2info) == 0) - return l2info.header_len; + if (juniper_parse_header(ndo, p, h, &l2info) == 0) { + ndo->ndo_ll_hdr_len += l2info.header_len; + return; + } p+=l2info.header_len; ih = (const struct juniper_ipsec_header *)p; - ND_TCHECK(*ih); - switch (ih->type) { + ND_TCHECK_SIZE(ih); + switch (GET_U_1(ih->type)) { case JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE: case JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE: rewrite_len = 0; @@ -538,10 +566,11 @@ juniper_es_print(netdissect_options *ndo, es_type_bundle = 0; break; default: - ND_PRINT((ndo, "ES Invalid type %u, length %u", - ih->type, - l2info.length)); - return l2info.header_len; + ND_PRINT("ES Invalid type %u, length %u", + GET_U_1(ih->type), + l2info.length); + ndo->ndo_ll_hdr_len += l2info.header_len; + return; } l2info.length-=rewrite_len; @@ -549,219 +578,255 @@ juniper_es_print(netdissect_options *ndo, if (ndo->ndo_eflag) { if (!es_type_bundle) { - ND_PRINT((ndo, "ES SA, index %u, ttl %u type %s (%u), spi %u, Tunnel %s > %s, length %u\n", - EXTRACT_16BITS(&ih->sa_index), - ih->ttl, - tok2str(juniper_ipsec_type_values,"Unknown",ih->type), - ih->type, - EXTRACT_32BITS(&ih->spi), - ipaddr_string(ndo, &ih->src_ip), - ipaddr_string(ndo, &ih->dst_ip), - l2info.length)); + ND_PRINT("ES SA, index %u, ttl %u type %s (%u), spi %u, Tunnel %s > %s, length %u\n", + GET_BE_U_2(ih->sa_index), + GET_U_1(ih->ttl), + tok2str(juniper_ipsec_type_values,"Unknown",GET_U_1(ih->type)), + GET_U_1(ih->type), + GET_BE_U_4(ih->spi), + GET_IPADDR_STRING(ih->src_ip), + GET_IPADDR_STRING(ih->dst_ip), + l2info.length); } else { - ND_PRINT((ndo, "ES SA, index %u, ttl %u type %s (%u), length %u\n", - EXTRACT_16BITS(&ih->sa_index), - ih->ttl, - tok2str(juniper_ipsec_type_values,"Unknown",ih->type), - ih->type, - l2info.length)); + ND_PRINT("ES SA, index %u, ttl %u type %s (%u), length %u\n", + GET_BE_U_2(ih->sa_index), + GET_U_1(ih->ttl), + tok2str(juniper_ipsec_type_values,"Unknown",GET_U_1(ih->type)), + GET_U_1(ih->type), + l2info.length); } } ip_print(ndo, p, l2info.length); - return l2info.header_len; + ndo->ndo_ll_hdr_len += l2info.header_len; + return; trunc: - ND_PRINT((ndo, "[|juniper_services]")); - return l2info.header_len; + nd_print_trunc(ndo); + ndo->ndo_ll_hdr_len += l2info.header_len; } #endif #ifdef DLT_JUNIPER_MONITOR -u_int -juniper_monitor_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, register const u_char *p) +void +juniper_monitor_if_print(netdissect_options *ndo, + const struct pcap_pkthdr *h, const u_char *p) { struct juniper_l2info_t l2info; struct juniper_monitor_header { - uint8_t pkt_type; - uint8_t padding; - uint8_t iif[2]; - uint8_t service_id[4]; + nd_uint8_t pkt_type; + nd_byte padding; + nd_uint16_t iif; + nd_uint32_t service_id; }; const struct juniper_monitor_header *mh; + ndo->ndo_protocol = "juniper_monitor"; + memset(&l2info, 0, sizeof(l2info)); l2info.pictype = DLT_JUNIPER_MONITOR; - if (juniper_parse_header(ndo, p, h, &l2info) == 0) - return l2info.header_len; + if (juniper_parse_header(ndo, p, h, &l2info) == 0) { + ndo->ndo_ll_hdr_len += l2info.header_len; + return; + } p+=l2info.header_len; mh = (const struct juniper_monitor_header *)p; - ND_TCHECK(*mh); + ND_TCHECK_SIZE(mh); if (ndo->ndo_eflag) - ND_PRINT((ndo, "service-id %u, iif %u, pkt-type %u: ", - EXTRACT_32BITS(&mh->service_id), - EXTRACT_16BITS(&mh->iif), - mh->pkt_type)); + ND_PRINT("service-id %u, iif %u, pkt-type %u: ", + GET_BE_U_4(mh->service_id), + GET_BE_U_2(mh->iif), + GET_U_1(mh->pkt_type)); /* no proto field - lets guess by first byte of IP header*/ ip_heuristic_guess (ndo, p, l2info.length); - return l2info.header_len; + ndo->ndo_ll_hdr_len += l2info.header_len; + return; trunc: - ND_PRINT((ndo, "[|juniper_services]")); - return l2info.header_len; + nd_print_trunc(ndo); + ndo->ndo_ll_hdr_len += l2info.header_len; } #endif #ifdef DLT_JUNIPER_SERVICES -u_int -juniper_services_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, register const u_char *p) +void +juniper_services_if_print(netdissect_options *ndo, + const struct pcap_pkthdr *h, const u_char *p) { struct juniper_l2info_t l2info; struct juniper_services_header { - uint8_t svc_id; - uint8_t flags_len; - uint8_t svc_set_id[2]; - uint8_t dir_iif[4]; + nd_uint8_t svc_id; + nd_uint8_t flags_len; + nd_uint16_t svc_set_id; + nd_byte pad; + nd_uint24_t dir_iif; }; const struct juniper_services_header *sh; + ndo->ndo_protocol = "juniper_services"; + memset(&l2info, 0, sizeof(l2info)); l2info.pictype = DLT_JUNIPER_SERVICES; - if (juniper_parse_header(ndo, p, h, &l2info) == 0) - return l2info.header_len; + if (juniper_parse_header(ndo, p, h, &l2info) == 0) { + ndo->ndo_ll_hdr_len += l2info.header_len; + return; + } p+=l2info.header_len; sh = (const struct juniper_services_header *)p; - ND_TCHECK(*sh); + ND_TCHECK_SIZE(sh); if (ndo->ndo_eflag) - ND_PRINT((ndo, "service-id %u flags 0x%02x service-set-id 0x%04x iif %u: ", - sh->svc_id, - sh->flags_len, - EXTRACT_16BITS(&sh->svc_set_id), - EXTRACT_24BITS(&sh->dir_iif[1]))); + ND_PRINT("service-id %u flags 0x%02x service-set-id 0x%04x iif %u: ", + GET_U_1(sh->svc_id), + GET_U_1(sh->flags_len), + GET_BE_U_2(sh->svc_set_id), + GET_BE_U_3(sh->dir_iif)); /* no proto field - lets guess by first byte of IP header*/ ip_heuristic_guess (ndo, p, l2info.length); - return l2info.header_len; + ndo->ndo_ll_hdr_len += l2info.header_len; + return; trunc: - ND_PRINT((ndo, "[|juniper_services]")); - return l2info.header_len; + nd_print_trunc(ndo); + ndo->ndo_ll_hdr_len += l2info.header_len; } #endif #ifdef DLT_JUNIPER_PPPOE -u_int -juniper_pppoe_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, register const u_char *p) +void +juniper_pppoe_if_print(netdissect_options *ndo, + const struct pcap_pkthdr *h, const u_char *p) { struct juniper_l2info_t l2info; + ndo->ndo_protocol = "juniper_pppoe"; + memset(&l2info, 0, sizeof(l2info)); l2info.pictype = DLT_JUNIPER_PPPOE; - if (juniper_parse_header(ndo, p, h, &l2info) == 0) - return l2info.header_len; + if (juniper_parse_header(ndo, p, h, &l2info) == 0) { + ndo->ndo_ll_hdr_len += l2info.header_len; + return; + } p+=l2info.header_len; /* this DLT contains nothing but raw ethernet frames */ ether_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL); - return l2info.header_len; + ndo->ndo_ll_hdr_len += l2info.header_len; } #endif #ifdef DLT_JUNIPER_ETHER -u_int -juniper_ether_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, register const u_char *p) +void +juniper_ether_if_print(netdissect_options *ndo, + const struct pcap_pkthdr *h, const u_char *p) { struct juniper_l2info_t l2info; + ndo->ndo_protocol = "juniper_ether"; + memset(&l2info, 0, sizeof(l2info)); l2info.pictype = DLT_JUNIPER_ETHER; - if (juniper_parse_header(ndo, p, h, &l2info) == 0) - return l2info.header_len; + if (juniper_parse_header(ndo, p, h, &l2info) == 0) { + ndo->ndo_ll_hdr_len += l2info.header_len; + return; + } p+=l2info.header_len; /* this DLT contains nothing but raw Ethernet frames */ - ether_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL); - return l2info.header_len; + ndo->ndo_ll_hdr_len += + l2info.header_len + + ether_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL); } #endif #ifdef DLT_JUNIPER_PPP -u_int -juniper_ppp_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, register const u_char *p) +void +juniper_ppp_if_print(netdissect_options *ndo, + const struct pcap_pkthdr *h, const u_char *p) { struct juniper_l2info_t l2info; + ndo->ndo_protocol = "juniper_ppp"; + memset(&l2info, 0, sizeof(l2info)); l2info.pictype = DLT_JUNIPER_PPP; - if (juniper_parse_header(ndo, p, h, &l2info) == 0) - return l2info.header_len; + if (juniper_parse_header(ndo, p, h, &l2info) == 0) { + ndo->ndo_ll_hdr_len += l2info.header_len; + return; + } p+=l2info.header_len; /* this DLT contains nothing but raw ppp frames */ ppp_print(ndo, p, l2info.length); - return l2info.header_len; + ndo->ndo_ll_hdr_len += l2info.header_len; } #endif #ifdef DLT_JUNIPER_FRELAY -u_int -juniper_frelay_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, register const u_char *p) +void +juniper_frelay_if_print(netdissect_options *ndo, + const struct pcap_pkthdr *h, const u_char *p) { struct juniper_l2info_t l2info; + ndo->ndo_protocol = "juniper_frelay"; + memset(&l2info, 0, sizeof(l2info)); l2info.pictype = DLT_JUNIPER_FRELAY; - if (juniper_parse_header(ndo, p, h, &l2info) == 0) - return l2info.header_len; + if (juniper_parse_header(ndo, p, h, &l2info) == 0) { + ndo->ndo_ll_hdr_len += l2info.header_len; + return; + } p+=l2info.header_len; /* this DLT contains nothing but raw frame-relay frames */ fr_print(ndo, p, l2info.length); - return l2info.header_len; + ndo->ndo_ll_hdr_len += l2info.header_len; } #endif #ifdef DLT_JUNIPER_CHDLC -u_int -juniper_chdlc_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, register const u_char *p) +void +juniper_chdlc_if_print(netdissect_options *ndo, + const struct pcap_pkthdr *h, const u_char *p) { struct juniper_l2info_t l2info; + ndo->ndo_protocol = "juniper_chdlc"; + memset(&l2info, 0, sizeof(l2info)); l2info.pictype = DLT_JUNIPER_CHDLC; - if (juniper_parse_header(ndo, p, h, &l2info) == 0) - return l2info.header_len; + if (juniper_parse_header(ndo, p, h, &l2info) == 0) { + ndo->ndo_ll_hdr_len += l2info.header_len; + return; + } p+=l2info.header_len; /* this DLT contains nothing but raw c-hdlc frames */ chdlc_print(ndo, p, l2info.length); - return l2info.header_len; + ndo->ndo_ll_hdr_len += l2info.header_len; } #endif #ifdef DLT_JUNIPER_PPPOE_ATM -u_int -juniper_pppoe_atm_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, register const u_char *p) +void +juniper_pppoe_atm_if_print(netdissect_options *ndo, + const struct pcap_pkthdr *h, const u_char *p) { struct juniper_l2info_t l2info; - uint16_t extracted_ethertype; + uint16_t extracted_ethertype; + ndo->ndo_protocol = "juniper_pppoe_atm"; + memset(&l2info, 0, sizeof(l2info)); l2info.pictype = DLT_JUNIPER_PPPOE_ATM; - if (juniper_parse_header(ndo, p, h, &l2info) == 0) - return l2info.header_len; + if (juniper_parse_header(ndo, p, h, &l2info) == 0) { + ndo->ndo_ll_hdr_len += l2info.header_len; + return; + } p+=l2info.header_len; - ND_TCHECK2(p[0], 2); - extracted_ethertype = EXTRACT_16BITS(p); + extracted_ethertype = GET_BE_U_2(p); /* this DLT contains nothing but raw PPPoE frames, * prepended with a type field*/ if (ethertype_print(ndo, extracted_ethertype, @@ -770,33 +835,35 @@ juniper_pppoe_atm_print(netdissect_options *ndo, l2info.caplen-ETHERTYPE_LEN, NULL, NULL) == 0) /* ether_type not known, probably it wasn't one */ - ND_PRINT((ndo, "unknown ethertype 0x%04x", extracted_ethertype)); - - return l2info.header_len; + ND_PRINT("unknown ethertype 0x%04x", extracted_ethertype); -trunc: - ND_PRINT((ndo, "[|juniper_pppoe_atm]")); - return l2info.header_len; + ndo->ndo_ll_hdr_len += l2info.header_len; } #endif #ifdef DLT_JUNIPER_MLPPP -u_int -juniper_mlppp_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, register const u_char *p) +void +juniper_mlppp_if_print(netdissect_options *ndo, + const struct pcap_pkthdr *h, const u_char *p) { struct juniper_l2info_t l2info; + ndo->ndo_protocol = "juniper_mlppp"; + memset(&l2info, 0, sizeof(l2info)); l2info.pictype = DLT_JUNIPER_MLPPP; - if (juniper_parse_header(ndo, p, h, &l2info) == 0) - return l2info.header_len; + if (juniper_parse_header(ndo, p, h, &l2info) == 0) { + ndo->ndo_ll_hdr_len += l2info.header_len; + return; + } /* suppress Bundle-ID if frame was captured on a child-link * best indicator if the cookie looks like a proto */ if (ndo->ndo_eflag && - EXTRACT_16BITS(&l2info.cookie) != PPP_OSI && - EXTRACT_16BITS(&l2info.cookie) != (PPP_ADDRESS << 8 | PPP_CONTROL)) - ND_PRINT((ndo, "Bundle-ID %u: ", l2info.bundle)); + /* use EXTRACT_, not GET_ (not packet buffer pointer) */ + EXTRACT_BE_U_2(&l2info.cookie) != PPP_OSI && + /* use EXTRACT_, not GET_ (not packet buffer pointer) */ + EXTRACT_BE_U_2(&l2info.cookie) != (PPP_ADDRESS << 8 | PPP_CONTROL)) + ND_PRINT("Bundle-ID %u: ", l2info.bundle); p+=l2info.header_len; @@ -810,22 +877,27 @@ juniper_mlppp_print(netdissect_options *ndo, ppp_print(ndo, p, l2info.length); else ip_print(ndo, p, l2info.length); - return l2info.header_len; + ndo->ndo_ll_hdr_len += l2info.header_len; + return; case JUNIPER_LSQ_L3_PROTO_IPV6: ip6_print(ndo, p,l2info.length); - return l2info.header_len; + ndo->ndo_ll_hdr_len += l2info.header_len; + return; case JUNIPER_LSQ_L3_PROTO_MPLS: mpls_print(ndo, p, l2info.length); - return l2info.header_len; + ndo->ndo_ll_hdr_len += l2info.header_len; + return; case JUNIPER_LSQ_L3_PROTO_ISO: isoclns_print(ndo, p, l2info.length); - return l2info.header_len; + ndo->ndo_ll_hdr_len += l2info.header_len; + return; default: break; } /* zero length cookie ? */ - switch (EXTRACT_16BITS(&l2info.cookie)) { + /* use EXTRACT_, not GET_ (not packet buffer pointer) */ + switch (EXTRACT_BE_U_2(&l2info.cookie)) { case PPP_OSI: ppp_print(ndo, p - 2, l2info.length + 2); break; @@ -835,29 +907,33 @@ juniper_mlppp_print(netdissect_options *ndo, break; } - return l2info.header_len; + ndo->ndo_ll_hdr_len += l2info.header_len; } #endif #ifdef DLT_JUNIPER_MFR -u_int -juniper_mfr_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, register const u_char *p) +void +juniper_mfr_if_print(netdissect_options *ndo, + const struct pcap_pkthdr *h, const u_char *p) { struct juniper_l2info_t l2info; + ndo->ndo_protocol = "juniper_mfr"; memset(&l2info, 0, sizeof(l2info)); l2info.pictype = DLT_JUNIPER_MFR; - if (juniper_parse_header(ndo, p, h, &l2info) == 0) - return l2info.header_len; + if (juniper_parse_header(ndo, p, h, &l2info) == 0) { + ndo->ndo_ll_hdr_len += l2info.header_len; + return; + } p+=l2info.header_len; /* child-link ? */ if (l2info.cookie_len == 0) { mfr_print(ndo, p, l2info.length); - return l2info.header_len; + ndo->ndo_ll_hdr_len += l2info.header_len; + return; } /* first try the LSQ protos */ @@ -865,25 +941,31 @@ juniper_mfr_print(netdissect_options *ndo, switch(l2info.proto) { case JUNIPER_LSQ_L3_PROTO_IPV4: ip_print(ndo, p, l2info.length); - return l2info.header_len; + ndo->ndo_ll_hdr_len += l2info.header_len; + return; case JUNIPER_LSQ_L3_PROTO_IPV6: ip6_print(ndo, p,l2info.length); - return l2info.header_len; + ndo->ndo_ll_hdr_len += l2info.header_len; + return; case JUNIPER_LSQ_L3_PROTO_MPLS: mpls_print(ndo, p, l2info.length); - return l2info.header_len; + ndo->ndo_ll_hdr_len += l2info.header_len; + return; case JUNIPER_LSQ_L3_PROTO_ISO: isoclns_print(ndo, p, l2info.length); - return l2info.header_len; + ndo->ndo_ll_hdr_len += l2info.header_len; + return; default: break; } - return l2info.header_len; + ndo->ndo_ll_hdr_len += l2info.header_len; + return; } /* suppress Bundle-ID if frame was captured on a child-link */ - if (ndo->ndo_eflag && EXTRACT_32BITS(l2info.cookie) != 1) - ND_PRINT((ndo, "Bundle-ID %u, ", l2info.bundle)); + /* use EXTRACT_, not GET_ (not packet buffer pointer) */ + if (ndo->ndo_eflag && EXTRACT_BE_U_4(l2info.cookie) != 1) + ND_PRINT("Bundle-ID %u, ", l2info.bundle); switch (l2info.proto) { case (LLCSAP_ISONS<<8 | LLCSAP_ISONS): isoclns_print(ndo, p + 1, l2info.length - 1); @@ -895,29 +977,34 @@ juniper_mfr_print(netdissect_options *ndo, isoclns_print(ndo, p - 1, l2info.length + 1); break; default: - ND_PRINT((ndo, "unknown protocol 0x%04x, length %u", l2info.proto, l2info.length)); + ND_PRINT("unknown protocol 0x%04x, length %u", l2info.proto, l2info.length); } - return l2info.header_len; + ndo->ndo_ll_hdr_len += l2info.header_len; } #endif #ifdef DLT_JUNIPER_MLFR -u_int -juniper_mlfr_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, register const u_char *p) +void +juniper_mlfr_if_print(netdissect_options *ndo, + const struct pcap_pkthdr *h, const u_char *p) { struct juniper_l2info_t l2info; + ndo->ndo_protocol = "juniper_mlfr"; + memset(&l2info, 0, sizeof(l2info)); l2info.pictype = DLT_JUNIPER_MLFR; - if (juniper_parse_header(ndo, p, h, &l2info) == 0) - return l2info.header_len; + if (juniper_parse_header(ndo, p, h, &l2info) == 0) { + ndo->ndo_ll_hdr_len += l2info.header_len; + return; + } p+=l2info.header_len; /* suppress Bundle-ID if frame was captured on a child-link */ - if (ndo->ndo_eflag && EXTRACT_32BITS(l2info.cookie) != 1) - ND_PRINT((ndo, "Bundle-ID %u, ", l2info.bundle)); + /* use EXTRACT_, not GET_ (not packet buffer pointer) */ + if (ndo->ndo_eflag && EXTRACT_BE_U_4(l2info.cookie) != 1) + ND_PRINT("Bundle-ID %u, ", l2info.bundle); switch (l2info.proto) { case (LLC_UI): case (LLC_UI<<8): @@ -930,10 +1017,10 @@ juniper_mlfr_print(netdissect_options *ndo, isoclns_print(ndo, p - 1, l2info.length + 1); break; default: - ND_PRINT((ndo, "unknown protocol 0x%04x, length %u", l2info.proto, l2info.length)); + ND_PRINT("unknown protocol 0x%04x, length %u", l2info.proto, l2info.length); } - return l2info.header_len; + ndo->ndo_ll_hdr_len += l2info.header_len; } #endif @@ -946,48 +1033,53 @@ juniper_mlfr_print(netdissect_options *ndo, */ #ifdef DLT_JUNIPER_ATM1 -u_int -juniper_atm1_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, register const u_char *p) +void +juniper_atm1_if_print(netdissect_options *ndo, + const struct pcap_pkthdr *h, const u_char *p) { int llc_hdrlen; struct juniper_l2info_t l2info; + ndo->ndo_protocol = "juniper_atm1"; + memset(&l2info, 0, sizeof(l2info)); l2info.pictype = DLT_JUNIPER_ATM1; - if (juniper_parse_header(ndo, p, h, &l2info) == 0) - return l2info.header_len; + if (juniper_parse_header(ndo, p, h, &l2info) == 0) { + ndo->ndo_ll_hdr_len += l2info.header_len; + return; + } p+=l2info.header_len; if (l2info.cookie[0] == 0x80) { /* OAM cell ? */ oam_print(ndo, p, l2info.length, ATM_OAM_NOHEC); - return l2info.header_len; + ndo->ndo_ll_hdr_len += l2info.header_len; + return; } - ND_TCHECK2(p[0], 3); - if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */ - EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */ + if (GET_BE_U_3(p) == 0xfefe03 || /* NLPID encaps ? */ + GET_BE_U_3(p) == 0xaaaa03) { /* SNAP encaps ? */ llc_hdrlen = llc_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL); - if (llc_hdrlen > 0) - return l2info.header_len; + if (llc_hdrlen > 0) { + ndo->ndo_ll_hdr_len += l2info.header_len; + return; + } } - if (p[0] == 0x03) { /* Cisco style NLPID encaps ? */ + if (GET_U_1(p) == 0x03) { /* Cisco style NLPID encaps ? */ isoclns_print(ndo, p + 1, l2info.length - 1); /* FIXME check if frame was recognized */ - return l2info.header_len; + ndo->ndo_ll_hdr_len += l2info.header_len; + return; } - if (ip_heuristic_guess(ndo, p, l2info.length) != 0) /* last try - vcmux encaps ? */ - return l2info.header_len; - - return l2info.header_len; + if (ip_heuristic_guess(ndo, p, l2info.length) != 0) { /* last try - vcmux encaps ? */ + ndo->ndo_ll_hdr_len += l2info.header_len; + return; + } -trunc: - ND_PRINT((ndo, "[|juniper_atm1]")); - return l2info.header_len; + ndo->ndo_ll_hdr_len += l2info.header_len; } #endif @@ -1000,68 +1092,75 @@ trunc: */ #ifdef DLT_JUNIPER_ATM2 -u_int -juniper_atm2_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, register const u_char *p) +void +juniper_atm2_if_print(netdissect_options *ndo, + const struct pcap_pkthdr *h, const u_char *p) { int llc_hdrlen; struct juniper_l2info_t l2info; + ndo->ndo_protocol = "juniper_atm2"; + memset(&l2info, 0, sizeof(l2info)); l2info.pictype = DLT_JUNIPER_ATM2; - if (juniper_parse_header(ndo, p, h, &l2info) == 0) - return l2info.header_len; + if (juniper_parse_header(ndo, p, h, &l2info) == 0) { + ndo->ndo_ll_hdr_len += l2info.header_len; + return; + } p+=l2info.header_len; if (l2info.cookie[7] & ATM2_PKT_TYPE_MASK) { /* OAM cell ? */ oam_print(ndo, p, l2info.length, ATM_OAM_NOHEC); - return l2info.header_len; + ndo->ndo_ll_hdr_len += l2info.header_len; + return; } - ND_TCHECK2(p[0], 3); - if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */ - EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */ + if (GET_BE_U_3(p) == 0xfefe03 || /* NLPID encaps ? */ + GET_BE_U_3(p) == 0xaaaa03) { /* SNAP encaps ? */ llc_hdrlen = llc_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL); - if (llc_hdrlen > 0) - return l2info.header_len; + if (llc_hdrlen > 0) { + ndo->ndo_ll_hdr_len += l2info.header_len; + return; + } } if (l2info.direction != JUNIPER_BPF_PKT_IN && /* ether-over-1483 encaps ? */ - (EXTRACT_32BITS(l2info.cookie) & ATM2_GAP_COUNT_MASK)) { + /* use EXTRACT_, not GET_ (not packet buffer pointer) */ + (EXTRACT_BE_U_4(l2info.cookie) & ATM2_GAP_COUNT_MASK)) { ether_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL); - return l2info.header_len; + ndo->ndo_ll_hdr_len += l2info.header_len; + return; } - if (p[0] == 0x03) { /* Cisco style NLPID encaps ? */ + if (GET_U_1(p) == 0x03) { /* Cisco style NLPID encaps ? */ isoclns_print(ndo, p + 1, l2info.length - 1); /* FIXME check if frame was recognized */ - return l2info.header_len; + ndo->ndo_ll_hdr_len += l2info.header_len; + return; } - if(juniper_ppp_heuristic_guess(ndo, p, l2info.length) != 0) /* PPPoA vcmux encaps ? */ - return l2info.header_len; - - if (ip_heuristic_guess(ndo, p, l2info.length) != 0) /* last try - vcmux encaps ? */ - return l2info.header_len; + if(juniper_ppp_heuristic_guess(ndo, p, l2info.length) != 0) { /* PPPoA vcmux encaps ? */ + ndo->ndo_ll_hdr_len += l2info.header_len; + return; + } - return l2info.header_len; + if (ip_heuristic_guess(ndo, p, l2info.length) != 0) { /* last try - vcmux encaps ? */ + ndo->ndo_ll_hdr_len += l2info.header_len; + return; + } -trunc: - ND_PRINT((ndo, "[|juniper_atm2]")); - return l2info.header_len; + ndo->ndo_ll_hdr_len += l2info.header_len; } -#endif - /* try to guess, based on all PPP protos that are supported in * a juniper router if the payload data is encapsulated using PPP */ static int juniper_ppp_heuristic_guess(netdissect_options *ndo, - register const u_char *p, u_int length) + const u_char *p, u_int length) { - switch(EXTRACT_16BITS(p)) { + switch(GET_BE_U_2(p)) { case PPP_IP : case PPP_OSI : case PPP_MPLS_UCAST : @@ -1084,12 +1183,13 @@ juniper_ppp_heuristic_guess(netdissect_options *ndo, } return 1; /* we printed a ppp packet */ } +#endif static int ip_heuristic_guess(netdissect_options *ndo, - register const u_char *p, u_int length) + const u_char *p, u_int length) { - switch(p[0]) { + switch(GET_U_1(p)) { case 0x45: case 0x46: case 0x47: @@ -1101,8 +1201,8 @@ ip_heuristic_guess(netdissect_options *ndo, case 0x4d: case 0x4e: case 0x4f: - ip_print(ndo, p, length); - break; + ip_print(ndo, p, length); + break; case 0x60: case 0x61: case 0x62: @@ -1129,7 +1229,8 @@ ip_heuristic_guess(netdissect_options *ndo, } static int -juniper_read_tlv_value(const u_char *p, u_int tlv_type, u_int tlv_len) +juniper_read_tlv_value(netdissect_options *ndo, + const u_char *p, u_int tlv_type, u_int tlv_len) { int tlv_value; @@ -1137,16 +1238,16 @@ juniper_read_tlv_value(const u_char *p, u_int tlv_type, u_int tlv_len) if (tlv_type < 128) { switch (tlv_len) { case 1: - tlv_value = *p; + tlv_value = GET_U_1(p); break; case 2: - tlv_value = EXTRACT_LE_16BITS(p); + tlv_value = GET_LE_U_2(p); break; case 3: - tlv_value = EXTRACT_LE_24BITS(p); + tlv_value = GET_LE_U_3(p); break; case 4: - tlv_value = EXTRACT_LE_32BITS(p); + tlv_value = GET_LE_U_4(p); break; default: tlv_value = -1; @@ -1156,16 +1257,16 @@ juniper_read_tlv_value(const u_char *p, u_int tlv_type, u_int tlv_len) /* TLVs >= 128 are big endian encoded */ switch (tlv_len) { case 1: - tlv_value = *p; + tlv_value = GET_U_1(p); break; case 2: - tlv_value = EXTRACT_16BITS(p); + tlv_value = GET_BE_U_2(p); break; case 3: - tlv_value = EXTRACT_24BITS(p); + tlv_value = GET_BE_U_3(p); break; case 4: - tlv_value = EXTRACT_32BITS(p); + tlv_value = GET_BE_U_4(p); break; default: tlv_value = -1; @@ -1182,7 +1283,9 @@ juniper_parse_header(netdissect_options *ndo, const struct juniper_cookie_table_t *lp = juniper_cookie_table; u_int idx, jnx_ext_len, jnx_header_len = 0; uint8_t tlv_type,tlv_len; +#ifdef DLT_JUNIPER_ATM2 uint32_t control_word; +#endif int tlv_value; const u_char *tptr; @@ -1194,24 +1297,23 @@ juniper_parse_header(netdissect_options *ndo, l2info->length = h->len; l2info->caplen = h->caplen; - ND_TCHECK2(p[0], 4); - l2info->flags = p[3]; - l2info->direction = p[3]&JUNIPER_BPF_PKT_IN; + l2info->flags = GET_U_1(p + 3); + l2info->direction = GET_U_1(p + 3) & JUNIPER_BPF_PKT_IN; - if (EXTRACT_24BITS(p) != JUNIPER_MGC_NUMBER) { /* magic number found ? */ - ND_PRINT((ndo, "no magic-number found!")); + if (GET_BE_U_3(p) != JUNIPER_MGC_NUMBER) { /* magic number found ? */ + ND_PRINT("no magic-number found!"); return 0; } if (ndo->ndo_eflag) /* print direction */ - ND_PRINT((ndo, "%3s ", tok2str(juniper_direction_values, "---", l2info->direction))); + ND_PRINT("%3s ", tok2str(juniper_direction_values, "---", l2info->direction)); /* magic number + flags */ jnx_header_len = 4; if (ndo->ndo_vflag > 1) - ND_PRINT((ndo, "\n\tJuniper PCAP Flags [%s]", - bittok2str(jnx_flag_values, "none", l2info->flags))); + ND_PRINT("\n\tJuniper PCAP Flags [%s]", + bittok2str(jnx_flag_values, "none", l2info->flags)); /* extensions present ? - calculate how much bytes to skip */ if ((l2info->flags & JUNIPER_BPF_EXT ) == JUNIPER_BPF_EXT ) { @@ -1219,8 +1321,7 @@ juniper_parse_header(netdissect_options *ndo, tptr = p+jnx_header_len; /* ok to read extension length ? */ - ND_TCHECK2(tptr[0], 2); - jnx_ext_len = EXTRACT_16BITS(tptr); + jnx_ext_len = GET_BE_U_2(tptr); jnx_header_len += 2; tptr +=2; @@ -1230,12 +1331,14 @@ juniper_parse_header(netdissect_options *ndo, jnx_header_len += jnx_ext_len; if (ndo->ndo_vflag > 1) - ND_PRINT((ndo, ", PCAP Extension(s) total length %u", jnx_ext_len)); + ND_PRINT(", PCAP Extension(s) total length %u", jnx_ext_len); - ND_TCHECK2(tptr[0], jnx_ext_len); + ND_TCHECK_LEN(tptr, jnx_ext_len); while (jnx_ext_len > JUNIPER_EXT_TLV_OVERHEAD) { - tlv_type = *(tptr++); - tlv_len = *(tptr++); + tlv_type = GET_U_1(tptr); + tptr++; + tlv_len = GET_U_1(tptr); + tptr++; tlv_value = 0; /* sanity checks */ @@ -1245,12 +1348,12 @@ juniper_parse_header(netdissect_options *ndo, goto trunc; if (ndo->ndo_vflag > 1) - ND_PRINT((ndo, "\n\t %s Extension TLV #%u, length %u, value ", + ND_PRINT("\n\t %s Extension TLV #%u, length %u, value ", tok2str(jnx_ext_tlv_values,"Unknown",tlv_type), tlv_type, - tlv_len)); + tlv_len); - tlv_value = juniper_read_tlv_value(tptr, tlv_type, tlv_len); + tlv_value = juniper_read_tlv_value(ndo, tptr, tlv_type, tlv_len); switch (tlv_type) { case JUNIPER_EXT_TLV_IFD_NAME: /* FIXME */ @@ -1259,18 +1362,18 @@ juniper_parse_header(netdissect_options *ndo, case JUNIPER_EXT_TLV_TTP_IFD_MEDIATYPE: if (tlv_value != -1) { if (ndo->ndo_vflag > 1) - ND_PRINT((ndo, "%s (%u)", + ND_PRINT("%s (%u)", tok2str(juniper_ifmt_values, "Unknown", tlv_value), - tlv_value)); + tlv_value); } break; case JUNIPER_EXT_TLV_IFL_ENCAPS: case JUNIPER_EXT_TLV_TTP_IFL_ENCAPS: if (tlv_value != -1) { if (ndo->ndo_vflag > 1) - ND_PRINT((ndo, "%s (%u)", + ND_PRINT("%s (%u)", tok2str(juniper_ifle_values, "Unknown", tlv_value), - tlv_value)); + tlv_value); } break; case JUNIPER_EXT_TLV_IFL_IDX: /* fall through */ @@ -1279,7 +1382,7 @@ juniper_parse_header(netdissect_options *ndo, default: if (tlv_value != -1) { if (ndo->ndo_vflag > 1) - ND_PRINT((ndo, "%u", tlv_value)); + ND_PRINT("%u", tlv_value); } break; } @@ -1289,21 +1392,21 @@ juniper_parse_header(netdissect_options *ndo, } if (ndo->ndo_vflag > 1) - ND_PRINT((ndo, "\n\t-----original packet-----\n\t")); + ND_PRINT("\n\t-----original packet-----\n\t"); } if ((l2info->flags & JUNIPER_BPF_NO_L2 ) == JUNIPER_BPF_NO_L2 ) { if (ndo->ndo_eflag) - ND_PRINT((ndo, "no-L2-hdr, ")); + ND_PRINT("no-L2-hdr, "); /* there is no link-layer present - * perform the v4/v6 heuristics * to figure out what it is */ - ND_TCHECK2(p[jnx_header_len + 4], 1); + ND_TCHECK_1(p + (jnx_header_len + 4)); if (ip_heuristic_guess(ndo, p + jnx_header_len + 4, l2info->length - (jnx_header_len + 4)) == 0) - ND_PRINT((ndo, "no IP-hdr found!")); + ND_PRINT("no IP-hdr found!"); l2info->header_len=jnx_header_len+4; return 0; /* stop parsing the output further */ @@ -1315,13 +1418,13 @@ juniper_parse_header(netdissect_options *ndo, l2info->caplen -= l2info->header_len; /* search through the cookie table and copy values matching for our PIC type */ - ND_TCHECK(p[0]); + ND_TCHECK_1(p); while (lp->s != NULL) { if (lp->pictype == l2info->pictype) { l2info->cookie_len += lp->cookie_len; - switch (p[0]) { + switch (GET_U_1(p)) { case LS_COOKIE_ID: l2info->cookie_type = LS_COOKIE_ID; l2info->cookie_len += 2; @@ -1340,7 +1443,7 @@ juniper_parse_header(netdissect_options *ndo, #ifdef DLT_JUNIPER_MFR /* MFR child links don't carry cookies */ if (l2info->pictype == DLT_JUNIPER_MFR && - (p[0] & MFR_BE_MASK) == MFR_BE_MASK) { + (GET_U_1(p) & MFR_BE_MASK) == MFR_BE_MASK) { l2info->cookie_len = 0; } #endif @@ -1350,30 +1453,29 @@ juniper_parse_header(netdissect_options *ndo, l2info->caplen -= l2info->cookie_len; if (ndo->ndo_eflag) - ND_PRINT((ndo, "%s-PIC, cookie-len %u", + ND_PRINT("%s-PIC, cookie-len %u", lp->s, - l2info->cookie_len)); + l2info->cookie_len); if (l2info->cookie_len > 8) { - ND_PRINT((ndo, " (invalid)")); + nd_print_invalid(ndo); return 0; } if (l2info->cookie_len > 0) { - ND_TCHECK2(p[0], l2info->cookie_len); + ND_TCHECK_LEN(p, l2info->cookie_len); if (ndo->ndo_eflag) - ND_PRINT((ndo, ", cookie 0x")); + ND_PRINT(", cookie 0x"); for (idx = 0; idx < l2info->cookie_len; idx++) { - l2info->cookie[idx] = p[idx]; /* copy cookie data */ - if (ndo->ndo_eflag) ND_PRINT((ndo, "%02x", p[idx])); + l2info->cookie[idx] = GET_U_1(p + idx); /* copy cookie data */ + if (ndo->ndo_eflag) ND_PRINT("%02x", GET_U_1(p + idx)); } } - if (ndo->ndo_eflag) ND_PRINT((ndo, ": ")); /* print demarc b/w L2/L3*/ + if (ndo->ndo_eflag) ND_PRINT(": "); /* print demarc b/w L2/L3*/ - ND_TCHECK_16BITS(p+l2info->cookie_len); - l2info->proto = EXTRACT_16BITS(p+l2info->cookie_len); + l2info->proto = GET_BE_U_2(p + l2info->cookie_len); break; } ++lp; @@ -1389,7 +1491,8 @@ juniper_parse_header(netdissect_options *ndo, l2info->bundle = l2info->cookie[1]; break; case AS_COOKIE_ID: - l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff; + /* use EXTRACT_, not GET_ (not packet buffer pointer) */ + l2info->bundle = (EXTRACT_BE_U_2(&l2info->cookie[6])>>3)&0xfff; l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK; break; default: @@ -1402,15 +1505,15 @@ juniper_parse_header(netdissect_options *ndo, case DLT_JUNIPER_MLFR: switch (l2info->cookie_type) { case LS_COOKIE_ID: - ND_TCHECK2(p[0], 2); l2info->bundle = l2info->cookie[1]; - l2info->proto = EXTRACT_16BITS(p); + l2info->proto = GET_BE_U_2(p); l2info->header_len += 2; l2info->length -= 2; l2info->caplen -= 2; break; case AS_COOKIE_ID: - l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff; + /* use EXTRACT_, not GET_ (not packet buffer pointer) */ + l2info->bundle = (EXTRACT_BE_U_2(&l2info->cookie[6])>>3)&0xfff; l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK; break; default: @@ -1426,15 +1529,15 @@ juniper_parse_header(netdissect_options *ndo, case DLT_JUNIPER_MFR: switch (l2info->cookie_type) { case LS_COOKIE_ID: - ND_TCHECK2(p[0], 2); l2info->bundle = l2info->cookie[1]; - l2info->proto = EXTRACT_16BITS(p); + l2info->proto = GET_BE_U_2(p); l2info->header_len += 2; l2info->length -= 2; l2info->caplen -= 2; break; case AS_COOKIE_ID: - l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff; + /* use EXTRACT_, not GET_ (not packet buffer pointer) */ + l2info->bundle = (EXTRACT_BE_U_2(&l2info->cookie[6])>>3)&0xfff; l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK; break; default: @@ -1445,10 +1548,10 @@ juniper_parse_header(netdissect_options *ndo, #endif #ifdef DLT_JUNIPER_ATM2 case DLT_JUNIPER_ATM2: - ND_TCHECK2(p[0], 4); + ND_TCHECK_4(p); /* ATM cell relay control word present ? */ if (l2info->cookie[7] & ATM2_PKT_TYPE_MASK) { - control_word = EXTRACT_32BITS(p); + control_word = GET_BE_U_4(p); /* some control word heuristics */ switch(control_word) { case 0: /* zero control word */ @@ -1461,7 +1564,7 @@ juniper_parse_header(netdissect_options *ndo, } if (ndo->ndo_eflag) - ND_PRINT((ndo, "control-word 0x%08x ", control_word)); + ND_PRINT("control-word 0x%08x ", control_word); } break; #endif @@ -1491,23 +1594,23 @@ juniper_parse_header(netdissect_options *ndo, #endif default: - ND_PRINT((ndo, "Unknown Juniper DLT_ type %u: ", l2info->pictype)); + ND_PRINT("Unknown Juniper DLT_ type %u: ", l2info->pictype); break; } - if (ndo->ndo_eflag > 1) - ND_PRINT((ndo, "hlen %u, proto 0x%04x, ", l2info->header_len, l2info->proto)); + if (ndo->ndo_eflag) + ND_PRINT("hlen %u, proto 0x%04x, ", l2info->header_len, l2info->proto); return 1; /* everything went ok so far. continue parsing */ - trunc: - ND_PRINT((ndo, "[|juniper_hdr], length %u", h->len)); +trunc: + nd_print_trunc(ndo); return 0; } - - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 4 - * End: - */ +#endif /* defined(DLT_JUNIPER_GGSN) || defined(DLT_JUNIPER_ES) || \ + defined(DLT_JUNIPER_MONITOR) || defined(DLT_JUNIPER_SERVICES) || \ + defined(DLT_JUNIPER_PPPOE) || defined(DLT_JUNIPER_ETHER) || \ + defined(DLT_JUNIPER_PPP) || defined(DLT_JUNIPER_FRELAY) || \ + defined(DLT_JUNIPER_CHDLC) || defined(DLT_JUNIPER_PPPOE_ATM) || \ + defined(DLT_JUNIPER_MLPPP) || defined(DLT_JUNIPER_MFR) || \ + defined(DLT_JUNIPER_MLFR) || defined(DLT_JUNIPER_ATM1) || \ + defined(DLT_JUNIPER_ATM2) */ diff --git a/contrib/tcpdump/print-krb.c b/contrib/tcpdump/print-krb.c index de69054c39..b4c0fadf7c 100644 --- a/contrib/tcpdump/print-krb.c +++ b/contrib/tcpdump/print-krb.c @@ -24,17 +24,33 @@ /* \summary: Kerberos printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "extract.h" -static const char tstr[] = " [|kerberos]"; +/* + * Kerberos 4: + * + * Athena Technical Plan + * Section E.2.1 + * Kerberos Authentication and Authorization System + * by S. P. Miller, B. C. Neuman, J. I. Schiller, and J. H. Saltzer + * + * https://web.mit.edu/Saltzer/www/publications/athenaplan/e.2.1.pdf + * + * 7. Appendix I Design Specifications + * + * Kerberos 5: + * + * RFC 1510, RFC 2630, etc. + */ -static const u_char *c_print(netdissect_options *, register const u_char *, register const u_char *); + +static const u_char *c_print(netdissect_options *, const u_char *, const u_char *); static const u_char *krb4_print_hdr(netdissect_options *, const u_char *); static void krb4_print(netdissect_options *, const u_char *); @@ -61,8 +77,8 @@ static void krb4_print(netdissect_options *, const u_char *); #define KERB_ERR_NULL_KEY 10 struct krb { - uint8_t pvno; /* Protocol Version */ - uint8_t type; /* Type+B */ + nd_uint8_t pvno; /* Protocol Version */ + nd_uint8_t type; /* Type+B */ }; static const struct tok type2str[] = { @@ -95,27 +111,20 @@ static const struct tok kerr2str[] = { static const u_char * c_print(netdissect_options *ndo, - register const u_char *s, register const u_char *ep) + const u_char *s, const u_char *ep) { - register u_char c; - register int flag; + u_char c; + int flag; flag = 1; while (s < ep) { - c = *s++; + c = GET_U_1(s); + s++; if (c == '\0') { flag = 0; break; } - if (!ND_ISASCII(c)) { - c = ND_TOASCII(c); - ND_PRINT((ndo, "M-")); - } - if (!ND_ISPRINT(c)) { - c ^= 0x40; /* DEL to ?, others to alpha */ - ND_PRINT((ndo, "^")); - } - ND_PRINT((ndo, "%c", c)); + fn_print_char(ndo, c); } if (flag) return NULL; @@ -131,14 +140,14 @@ krb4_print_hdr(netdissect_options *ndo, #define PRINT if ((cp = c_print(ndo, cp, ndo->ndo_snapend)) == NULL) goto trunc PRINT; - ND_PRINT((ndo, ".")); + ND_PRINT("."); PRINT; - ND_PRINT((ndo, "@")); + ND_PRINT("@"); PRINT; return (cp); trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return (NULL); #undef PRINT @@ -148,26 +157,21 @@ static void krb4_print(netdissect_options *ndo, const u_char *cp) { - register const struct krb *kp; + const struct krb *kp; u_char type; u_short len; #define PRINT if ((cp = c_print(ndo, cp, ndo->ndo_snapend)) == NULL) goto trunc /* True if struct krb is little endian */ -#define IS_LENDIAN(kp) (((kp)->type & 0x01) != 0) -#define KTOHSP(kp, cp) (IS_LENDIAN(kp) ? EXTRACT_LE_16BITS(cp) : EXTRACT_16BITS(cp)) +#define IS_LENDIAN(kp) ((GET_U_1((kp)->type) & 0x01) != 0) +#define KTOHSP(kp, cp) (IS_LENDIAN(kp) ? GET_LE_U_2(cp) : GET_BE_U_2(cp)) kp = (const struct krb *)cp; - if ((&kp->type) >= ndo->ndo_snapend) { - ND_PRINT((ndo, "%s", tstr)); - return; - } - - type = kp->type & (0xFF << 1); + type = GET_U_1(kp->type) & (0xFF << 1); - ND_PRINT((ndo, " %s %s: ", - IS_LENDIAN(kp) ? "le" : "be", tok2str(type2str, NULL, type))); + ND_PRINT(" %s %s: ", + IS_LENDIAN(kp) ? "le" : "be", tok2str(type2str, NULL, type)); switch (type) { @@ -175,84 +179,81 @@ krb4_print(netdissect_options *ndo, if ((cp = krb4_print_hdr(ndo, cp)) == NULL) return; cp += 4; /* ctime */ - ND_TCHECK(*cp); - ND_PRINT((ndo, " %dmin ", *cp++ * 5)); + ND_PRINT(" %umin ", GET_U_1(cp) * 5); + cp++; PRINT; - ND_PRINT((ndo, ".")); + ND_PRINT("."); PRINT; break; case AUTH_MSG_APPL_REQUEST: cp += 2; - ND_TCHECK(*cp); - ND_PRINT((ndo, "v%d ", *cp++)); + ND_PRINT("v%u ", GET_U_1(cp)); + cp++; PRINT; - ND_TCHECK(*cp); - ND_PRINT((ndo, " (%d)", *cp++)); - ND_TCHECK(*cp); - ND_PRINT((ndo, " (%d)", *cp)); + ND_PRINT(" (%u)", GET_U_1(cp)); + cp++; + ND_PRINT(" (%u)", GET_U_1(cp)); break; case AUTH_MSG_KDC_REPLY: if ((cp = krb4_print_hdr(ndo, cp)) == NULL) return; cp += 10; /* timestamp + n + exp + kvno */ - ND_TCHECK2(*cp, sizeof(short)); len = KTOHSP(kp, cp); - ND_PRINT((ndo, " (%d)", len)); + ND_PRINT(" (%u)", len); break; case AUTH_MSG_ERR_REPLY: if ((cp = krb4_print_hdr(ndo, cp)) == NULL) return; cp += 4; /* timestamp */ - ND_TCHECK2(*cp, sizeof(short)); - ND_PRINT((ndo, " %s ", tok2str(kerr2str, NULL, KTOHSP(kp, cp)))); + ND_PRINT(" %s ", tok2str(kerr2str, NULL, KTOHSP(kp, cp))); cp += 4; PRINT; break; default: - ND_PRINT((ndo, "(unknown)")); + ND_PRINT("(unknown)"); break; } return; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); } void krb_print(netdissect_options *ndo, const u_char *dat) { - register const struct krb *kp; + const struct krb *kp; + ndo->ndo_protocol = "krb"; kp = (const struct krb *)dat; if (dat >= ndo->ndo_snapend) { - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return; } - switch (kp->pvno) { + switch (GET_U_1(kp->pvno)) { case 1: case 2: case 3: - ND_PRINT((ndo, " v%d", kp->pvno)); + ND_PRINT(" v%u", GET_U_1(kp->pvno)); break; case 4: - ND_PRINT((ndo, " v%d", kp->pvno)); + ND_PRINT(" v%u", GET_U_1(kp->pvno)); krb4_print(ndo, (const u_char *)kp); break; case 106: case 107: - ND_PRINT((ndo, " v5")); + ND_PRINT(" v5"); /* Decode ASN.1 here "someday" */ break; } - return; } diff --git a/contrib/tcpdump/print-l2tp.c b/contrib/tcpdump/print-l2tp.c index 7622bf3e67..940aa2b662 100644 --- a/contrib/tcpdump/print-l2tp.c +++ b/contrib/tcpdump/print-l2tp.c @@ -26,10 +26,10 @@ /* specification: RFC 2661 */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "extract.h" @@ -70,7 +70,6 @@ #define L2TP_PROXY_AUTH_ID_MASK 0x00ff -static const char tstr[] = " [|l2tp]"; #define L2TP_MSGTYPE_SCCRQ 1 /* Start-Control-Connection-Request */ #define L2TP_MSGTYPE_SCCRP 2 /* Start-Control-Connection-Reply */ @@ -233,9 +232,9 @@ static char *l2tp_result_code_CDN[] = { "Call disconnected due to loss of carrier", "Call disconnected for the reason indicated in error code", "Call disconnected for administrative reasons", - "Call failed due to lack of appropriate facilities being " \ + "Call failed due to lack of appropriate facilities being " "available (temporary condition)", - "Call failed due to lack of appropriate facilities being " \ + "Call failed due to lack of appropriate facilities being " "available (permanent condition)", "Invalid destination", "Call failed due to no carrier detected", @@ -252,7 +251,7 @@ static char *l2tp_error_code_general[] = { "No general error", "No control connection exists yet for this LAC-LNS pair", "Length is wrong", - "One of the field values was out of range or " \ + "One of the field values was out of range or " "reserved field was non-zero" "Insufficient resources to handle this operation now", "The Session ID is invalid in this context", @@ -270,7 +269,8 @@ print_string(netdissect_options *ndo, const u_char *dat, u_int length) { u_int i; for (i=0; i> 8), - (EXTRACT_16BITS(dat) & 0xff))); + ND_PRINT("%u.%u", (GET_BE_U_2(dat) >> 8), + (GET_BE_U_2(dat) & 0xff)); } static void l2tp_framing_cap_print(netdissect_options *ndo, const u_char *dat, u_int length) { if (length < 4) { - ND_PRINT((ndo, "AVP too short")); + ND_PRINT("AVP too short"); return; } - if (EXTRACT_32BITS(dat) & L2TP_FRAMING_CAP_ASYNC_MASK) { - ND_PRINT((ndo, "A")); + if (GET_BE_U_4(dat) & L2TP_FRAMING_CAP_ASYNC_MASK) { + ND_PRINT("A"); } - if (EXTRACT_32BITS(dat) & L2TP_FRAMING_CAP_SYNC_MASK) { - ND_PRINT((ndo, "S")); + if (GET_BE_U_4(dat) & L2TP_FRAMING_CAP_SYNC_MASK) { + ND_PRINT("S"); } } @@ -369,14 +370,14 @@ static void l2tp_bearer_cap_print(netdissect_options *ndo, const u_char *dat, u_int length) { if (length < 4) { - ND_PRINT((ndo, "AVP too short")); + ND_PRINT("AVP too short"); return; } - if (EXTRACT_32BITS(dat) & L2TP_BEARER_CAP_ANALOG_MASK) { - ND_PRINT((ndo, "A")); + if (GET_BE_U_4(dat) & L2TP_BEARER_CAP_ANALOG_MASK) { + ND_PRINT("A"); } - if (EXTRACT_32BITS(dat) & L2TP_BEARER_CAP_DIGITAL_MASK) { - ND_PRINT((ndo, "D")); + if (GET_BE_U_4(dat) & L2TP_BEARER_CAP_DIGITAL_MASK) { + ND_PRINT("D"); } } @@ -384,15 +385,15 @@ static void l2tp_q931_cc_print(netdissect_options *ndo, const u_char *dat, u_int length) { if (length < 3) { - ND_PRINT((ndo, "AVP too short")); + ND_PRINT("AVP too short"); return; } print_16bits_val(ndo, dat); - ND_PRINT((ndo, ", %02x", EXTRACT_8BITS(dat + 2))); + ND_PRINT(", %02x", GET_U_1(dat + 2)); dat += 3; length -= 3; if (length != 0) { - ND_PRINT((ndo, " ")); + ND_PRINT(" "); print_string(ndo, dat, length); } } @@ -401,14 +402,14 @@ static void l2tp_bearer_type_print(netdissect_options *ndo, const u_char *dat, u_int length) { if (length < 4) { - ND_PRINT((ndo, "AVP too short")); + ND_PRINT("AVP too short"); return; } - if (EXTRACT_32BITS(dat) & L2TP_BEARER_TYPE_ANALOG_MASK) { - ND_PRINT((ndo, "A")); + if (GET_BE_U_4(dat) & L2TP_BEARER_TYPE_ANALOG_MASK) { + ND_PRINT("A"); } - if (EXTRACT_32BITS(dat) & L2TP_BEARER_TYPE_DIGITAL_MASK) { - ND_PRINT((ndo, "D")); + if (GET_BE_U_4(dat) & L2TP_BEARER_TYPE_DIGITAL_MASK) { + ND_PRINT("D"); } } @@ -416,42 +417,42 @@ static void l2tp_framing_type_print(netdissect_options *ndo, const u_char *dat, u_int length) { if (length < 4) { - ND_PRINT((ndo, "AVP too short")); + ND_PRINT("AVP too short"); return; } - if (EXTRACT_32BITS(dat) & L2TP_FRAMING_TYPE_ASYNC_MASK) { - ND_PRINT((ndo, "A")); + if (GET_BE_U_4(dat) & L2TP_FRAMING_TYPE_ASYNC_MASK) { + ND_PRINT("A"); } - if (EXTRACT_32BITS(dat) & L2TP_FRAMING_TYPE_SYNC_MASK) { - ND_PRINT((ndo, "S")); + if (GET_BE_U_4(dat) & L2TP_FRAMING_TYPE_SYNC_MASK) { + ND_PRINT("S"); } } static void l2tp_packet_proc_delay_print(netdissect_options *ndo) { - ND_PRINT((ndo, "obsolete")); + ND_PRINT("obsolete"); } static void l2tp_proxy_auth_type_print(netdissect_options *ndo, const u_char *dat, u_int length) { if (length < 2) { - ND_PRINT((ndo, "AVP too short")); + ND_PRINT("AVP too short"); return; } - ND_PRINT((ndo, "%s", tok2str(l2tp_authentype2str, - "AuthType-#%u", EXTRACT_16BITS(dat)))); + ND_PRINT("%s", tok2str(l2tp_authentype2str, + "AuthType-#%u", GET_BE_U_2(dat))); } static void l2tp_proxy_auth_id_print(netdissect_options *ndo, const u_char *dat, u_int length) { if (length < 2) { - ND_PRINT((ndo, "AVP too short")); + ND_PRINT("AVP too short"); return; } - ND_PRINT((ndo, "%u", EXTRACT_16BITS(dat) & L2TP_PROXY_AUTH_ID_MASK)); + ND_PRINT("%u", GET_BE_U_2(dat) & L2TP_PROXY_AUTH_ID_MASK); } static void @@ -460,53 +461,53 @@ l2tp_call_errors_print(netdissect_options *ndo, const u_char *dat, u_int length) uint32_t val; if (length < 2) { - ND_PRINT((ndo, "AVP too short")); + ND_PRINT("AVP too short"); return; } dat += 2; /* skip "Reserved" */ length -= 2; if (length < 4) { - ND_PRINT((ndo, "AVP too short")); + ND_PRINT("AVP too short"); return; } - val = EXTRACT_32BITS(dat); dat += 4; length -= 4; - ND_PRINT((ndo, "CRCErr=%u ", val)); + val = GET_BE_U_4(dat); dat += 4; length -= 4; + ND_PRINT("CRCErr=%u ", val); if (length < 4) { - ND_PRINT((ndo, "AVP too short")); + ND_PRINT("AVP too short"); return; } - val = EXTRACT_32BITS(dat); dat += 4; length -= 4; - ND_PRINT((ndo, "FrameErr=%u ", val)); + val = GET_BE_U_4(dat); dat += 4; length -= 4; + ND_PRINT("FrameErr=%u ", val); if (length < 4) { - ND_PRINT((ndo, "AVP too short")); + ND_PRINT("AVP too short"); return; } - val = EXTRACT_32BITS(dat); dat += 4; length -= 4; - ND_PRINT((ndo, "HardOver=%u ", val)); + val = GET_BE_U_4(dat); dat += 4; length -= 4; + ND_PRINT("HardOver=%u ", val); if (length < 4) { - ND_PRINT((ndo, "AVP too short")); + ND_PRINT("AVP too short"); return; } - val = EXTRACT_32BITS(dat); dat += 4; length -= 4; - ND_PRINT((ndo, "BufOver=%u ", val)); + val = GET_BE_U_4(dat); dat += 4; length -= 4; + ND_PRINT("BufOver=%u ", val); if (length < 4) { - ND_PRINT((ndo, "AVP too short")); + ND_PRINT("AVP too short"); return; } - val = EXTRACT_32BITS(dat); dat += 4; length -= 4; - ND_PRINT((ndo, "Timeout=%u ", val)); + val = GET_BE_U_4(dat); dat += 4; length -= 4; + ND_PRINT("Timeout=%u ", val); if (length < 4) { - ND_PRINT((ndo, "AVP too short")); + ND_PRINT("AVP too short"); return; } - val = EXTRACT_32BITS(dat); dat += 4; length -= 4; - ND_PRINT((ndo, "AlignErr=%u ", val)); + val = GET_BE_U_4(dat); dat += 4; length -= 4; + ND_PRINT("AlignErr=%u ", val); } static void @@ -515,50 +516,50 @@ l2tp_accm_print(netdissect_options *ndo, const u_char *dat, u_int length) uint32_t val; if (length < 2) { - ND_PRINT((ndo, "AVP too short")); + ND_PRINT("AVP too short"); return; } dat += 2; /* skip "Reserved" */ length -= 2; if (length < 4) { - ND_PRINT((ndo, "AVP too short")); + ND_PRINT("AVP too short"); return; } - val = EXTRACT_32BITS(dat); dat += 4; length -= 4; - ND_PRINT((ndo, "send=%08x ", val)); + val = GET_BE_U_4(dat); dat += 4; length -= 4; + ND_PRINT("send=%08x ", val); if (length < 4) { - ND_PRINT((ndo, "AVP too short")); + ND_PRINT("AVP too short"); return; } - val = EXTRACT_32BITS(dat); dat += 4; length -= 4; - ND_PRINT((ndo, "recv=%08x ", val)); + val = GET_BE_U_4(dat); dat += 4; length -= 4; + ND_PRINT("recv=%08x ", val); } static void l2tp_ppp_discon_cc_print(netdissect_options *ndo, const u_char *dat, u_int length) { if (length < 5) { - ND_PRINT((ndo, "AVP too short")); + ND_PRINT("AVP too short"); return; } /* Disconnect Code */ - ND_PRINT((ndo, "%04x, ", EXTRACT_16BITS(dat))); + ND_PRINT("%04x, ", GET_BE_U_2(dat)); dat += 2; length -= 2; /* Control Protocol Number */ - ND_PRINT((ndo, "%04x ", EXTRACT_16BITS(dat))); + ND_PRINT("%04x ", GET_BE_U_2(dat)); dat += 2; length -= 2; /* Direction */ - ND_PRINT((ndo, "%s", tok2str(l2tp_cc_direction2str, - "Direction-#%u", EXTRACT_8BITS(dat)))); + ND_PRINT("%s", tok2str(l2tp_cc_direction2str, + "Direction-#%u", GET_U_1(dat))); dat++; length--; if (length != 0) { - ND_PRINT((ndo, " ")); + ND_PRINT(" "); print_string(ndo, (const u_char *)dat, length); } } @@ -570,10 +571,9 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, u_int length) uint16_t attr_type; int hidden = FALSE; - ND_PRINT((ndo, " ")); - - ND_TCHECK_16BITS(dat); /* Flags & Length */ - len = EXTRACT_16BITS(dat) & L2TP_AVP_HDR_LEN_MASK; + ND_PRINT(" "); + /* Flags & Length */ + len = GET_BE_U_2(dat) & L2TP_AVP_HDR_LEN_MASK; /* If it is not long enough to contain the header, we'll give up. */ if (len < 6) @@ -586,7 +586,7 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, u_int length) /* If it goes past the end of the remaining length of the captured data, we'll give up. */ - ND_TCHECK2(*dat, len); + ND_TCHECK_LEN(dat, len); /* * After this point, we don't need to check whether we go past @@ -594,30 +594,30 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, u_int length) * check whether we go past the end of the AVP. */ - if (EXTRACT_16BITS(dat) & L2TP_AVP_HDR_FLAG_MANDATORY) { - ND_PRINT((ndo, "*")); + if (GET_BE_U_2(dat) & L2TP_AVP_HDR_FLAG_MANDATORY) { + ND_PRINT("*"); } - if (EXTRACT_16BITS(dat) & L2TP_AVP_HDR_FLAG_HIDDEN) { + if (GET_BE_U_2(dat) & L2TP_AVP_HDR_FLAG_HIDDEN) { hidden = TRUE; - ND_PRINT((ndo, "?")); + ND_PRINT("?"); } dat += 2; - if (EXTRACT_16BITS(dat)) { + if (GET_BE_U_2(dat)) { /* Vendor Specific Attribute */ - ND_PRINT((ndo, "VENDOR%04x:", EXTRACT_16BITS(dat))); dat += 2; - ND_PRINT((ndo, "ATTR%04x", EXTRACT_16BITS(dat))); dat += 2; - ND_PRINT((ndo, "(")); + ND_PRINT("VENDOR%04x:", GET_BE_U_2(dat)); dat += 2; + ND_PRINT("ATTR%04x", GET_BE_U_2(dat)); dat += 2; + ND_PRINT("("); print_octets(ndo, dat, len-6); - ND_PRINT((ndo, ")")); + ND_PRINT(")"); } else { /* IETF-defined Attributes */ dat += 2; - attr_type = EXTRACT_16BITS(dat); dat += 2; - ND_PRINT((ndo, "%s", tok2str(l2tp_avp2str, "AVP-#%u", attr_type))); - ND_PRINT((ndo, "(")); + attr_type = GET_BE_U_2(dat); dat += 2; + ND_PRINT("%s", tok2str(l2tp_avp2str, "AVP-#%u", attr_type)); + ND_PRINT("("); if (hidden) { - ND_PRINT((ndo, "???")); + ND_PRINT("???"); } else { switch (attr_type) { case L2TP_AVP_MSGTYPE: @@ -637,7 +637,7 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, u_int length) break; case L2TP_AVP_TIE_BREAKER: if (len-6 < 8) { - ND_PRINT((ndo, "AVP too short")); + ND_PRINT("AVP too short"); break; } print_octets(ndo, dat, 8); @@ -647,7 +647,7 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, u_int length) case L2TP_AVP_RECV_WIN_SIZE: case L2TP_AVP_ASSND_SESS_ID: if (len-6 < 2) { - ND_PRINT((ndo, "AVP too short")); + ND_PRINT("AVP too short"); break; } print_16bits_val(ndo, dat); @@ -675,7 +675,7 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, u_int length) break; case L2TP_AVP_CHALLENGE_RESP: if (len-6 < 16) { - ND_PRINT((ndo, "AVP too short")); + ND_PRINT("AVP too short"); break; } print_octets(ndo, dat, 16); @@ -687,7 +687,7 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, u_int length) case L2TP_AVP_PHY_CHANNEL_ID: case L2TP_AVP_RX_CONN_SPEED: if (len-6 < 4) { - ND_PRINT((ndo, "AVP too short")); + ND_PRINT("AVP too short"); break; } print_32bits_val(ndo, dat); @@ -722,13 +722,13 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, u_int length) break; } } - ND_PRINT((ndo, ")")); + ND_PRINT(")"); } return (len); trunc: - ND_PRINT((ndo, "|...")); + nd_print_trunc(ndo); return (0); } @@ -742,97 +742,94 @@ l2tp_print(netdissect_options *ndo, const u_char *dat, u_int length) int flag_t, flag_l, flag_s, flag_o; uint16_t l2tp_len; + ndo->ndo_protocol = "l2tp"; flag_t = flag_l = flag_s = flag_o = FALSE; - ND_TCHECK2(*ptr, 2); /* Flags & Version */ - if ((EXTRACT_16BITS(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2TP) { - ND_PRINT((ndo, " l2tp:")); - } else if ((EXTRACT_16BITS(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2F) { - ND_PRINT((ndo, " l2f:")); + if ((GET_BE_U_2(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2TP) { + ND_PRINT(" l2tp:"); + } else if ((GET_BE_U_2(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2F) { + ND_PRINT(" l2f:"); return; /* nothing to do */ } else { - ND_PRINT((ndo, " Unknown Version, neither L2F(1) nor L2TP(2)")); + ND_PRINT(" Unknown Version, neither L2F(1) nor L2TP(2)"); return; /* nothing we can do */ } - ND_PRINT((ndo, "[")); - if (EXTRACT_16BITS(ptr) & L2TP_FLAG_TYPE) { + ND_PRINT("["); + if (GET_BE_U_2(ptr) & L2TP_FLAG_TYPE) { flag_t = TRUE; - ND_PRINT((ndo, "T")); + ND_PRINT("T"); } - if (EXTRACT_16BITS(ptr) & L2TP_FLAG_LENGTH) { + if (GET_BE_U_2(ptr) & L2TP_FLAG_LENGTH) { flag_l = TRUE; - ND_PRINT((ndo, "L")); + ND_PRINT("L"); } - if (EXTRACT_16BITS(ptr) & L2TP_FLAG_SEQUENCE) { + if (GET_BE_U_2(ptr) & L2TP_FLAG_SEQUENCE) { flag_s = TRUE; - ND_PRINT((ndo, "S")); + ND_PRINT("S"); } - if (EXTRACT_16BITS(ptr) & L2TP_FLAG_OFFSET) { + if (GET_BE_U_2(ptr) & L2TP_FLAG_OFFSET) { flag_o = TRUE; - ND_PRINT((ndo, "O")); + ND_PRINT("O"); } - if (EXTRACT_16BITS(ptr) & L2TP_FLAG_PRIORITY) - ND_PRINT((ndo, "P")); - ND_PRINT((ndo, "]")); + if (GET_BE_U_2(ptr) & L2TP_FLAG_PRIORITY) + ND_PRINT("P"); + ND_PRINT("]"); ptr += 2; cnt += 2; if (flag_l) { - ND_TCHECK2(*ptr, 2); /* Length */ - l2tp_len = EXTRACT_16BITS(ptr); + l2tp_len = GET_BE_U_2(ptr); ptr += 2; cnt += 2; } else { l2tp_len = 0; } - - ND_TCHECK2(*ptr, 2); /* Tunnel ID */ - ND_PRINT((ndo, "(%u/", EXTRACT_16BITS(ptr))); + /* Tunnel ID */ + ND_PRINT("(%u/", GET_BE_U_2(ptr)); ptr += 2; cnt += 2; - ND_TCHECK2(*ptr, 2); /* Session ID */ - ND_PRINT((ndo, "%u)", EXTRACT_16BITS(ptr))); + /* Session ID */ + ND_PRINT("%u)", GET_BE_U_2(ptr)); ptr += 2; cnt += 2; if (flag_s) { - ND_TCHECK2(*ptr, 2); /* Ns */ - ND_PRINT((ndo, "Ns=%u,", EXTRACT_16BITS(ptr))); + ND_PRINT("Ns=%u,", GET_BE_U_2(ptr)); ptr += 2; cnt += 2; - ND_TCHECK2(*ptr, 2); /* Nr */ - ND_PRINT((ndo, "Nr=%u", EXTRACT_16BITS(ptr))); + ND_PRINT("Nr=%u", GET_BE_U_2(ptr)); ptr += 2; cnt += 2; } - if (flag_o) { - ND_TCHECK2(*ptr, 2); /* Offset Size */ - pad = EXTRACT_16BITS(ptr); + if (flag_o) { /* Offset Size */ + pad = GET_BE_U_2(ptr); + /* Offset padding octets in packet buffer? */ + ND_TCHECK_LEN(ptr + 2, pad); ptr += (2 + pad); cnt += (2 + pad); } if (flag_l) { if (length < l2tp_len) { - ND_PRINT((ndo, " Length %u larger than packet", l2tp_len)); + ND_PRINT(" Length %u larger than packet", l2tp_len); return; } length = l2tp_len; } if (length < cnt) { - ND_PRINT((ndo, " Length %u smaller than header length", length)); + ND_PRINT(" Length %u smaller than header length", length); return; } if (flag_t) { if (!flag_l) { - ND_PRINT((ndo, " No length")); + ND_PRINT(" No length"); return; } if (length - cnt == 0) { - ND_PRINT((ndo, " ZLB")); + ND_PRINT(" ZLB"); } else { /* * Print AVPs. @@ -852,13 +849,11 @@ l2tp_print(netdissect_options *ndo, const u_char *dat, u_int length) } } } else { - ND_PRINT((ndo, " {")); + ND_PRINT(" {"); ppp_print(ndo, ptr, length - cnt); - ND_PRINT((ndo, "}")); + ND_PRINT("}"); } - return; - - trunc: - ND_PRINT((ndo, "%s", tstr)); +trunc: + nd_print_trunc(ndo); } diff --git a/contrib/tcpdump/print-lane.c b/contrib/tcpdump/print-lane.c index ba5208425b..c5fa33beb4 100644 --- a/contrib/tcpdump/print-lane.c +++ b/contrib/tcpdump/print-lane.c @@ -23,27 +23,27 @@ /* \summary: ATM LANE printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" -#include "ether.h" struct lecdatahdr_8023 { - uint16_t le_header; - uint8_t h_dest[ETHER_ADDR_LEN]; - uint8_t h_source[ETHER_ADDR_LEN]; - uint16_t h_type; + nd_uint16_t le_header; + nd_mac_addr h_dest; + nd_mac_addr h_source; + nd_uint16_t h_type; }; struct lane_controlhdr { - uint16_t lec_header; - uint8_t lec_proto; - uint8_t lec_vers; - uint16_t lec_opcode; + nd_uint16_t lec_header; + nd_uint8_t lec_proto; + nd_uint8_t lec_vers; + nd_uint16_t lec_opcode; }; static const struct tok lecop2str[] = { @@ -69,15 +69,10 @@ static const struct tok lecop2str[] = { static void lane_hdr_print(netdissect_options *ndo, const u_char *bp) { - ND_PRINT((ndo, "lecid:%x ", EXTRACT_16BITS(bp))); + ND_PRINT("lecid:%x ", GET_BE_U_2(bp)); } /* - * This is the top level routine of the printer. 'p' points - * to the LANE 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 assumes 802.3, not 802.5, LAN emulation. */ void @@ -85,25 +80,24 @@ lane_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen) { const struct lane_controlhdr *lec; - if (caplen < sizeof(struct lane_controlhdr)) { - ND_PRINT((ndo, "[|lane]")); - return; - } + ndo->ndo_protocol = "lane"; lec = (const struct lane_controlhdr *)p; - if (EXTRACT_16BITS(&lec->lec_header) == 0xff00) { + if (GET_BE_U_2(lec->lec_header) == 0xff00) { /* * LE Control. */ - ND_PRINT((ndo, "lec: proto %x vers %x %s", - lec->lec_proto, lec->lec_vers, - tok2str(lecop2str, "opcode-#%u", EXTRACT_16BITS(&lec->lec_opcode)))); + ND_PRINT("lec: proto %x vers %x %s", + GET_U_1(lec->lec_proto), + GET_U_1(lec->lec_vers), + tok2str(lecop2str, "opcode-#%u", GET_BE_U_2(lec->lec_opcode))); return; } /* * Go past the LE header. */ + ND_TCHECK_2(p); /* Needed */ length -= 2; caplen -= 2; p += 2; @@ -114,11 +108,3 @@ lane_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen) */ ether_print(ndo, p, length, caplen, lane_hdr_print, p - 2); } - -u_int -lane_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) -{ - lane_print(ndo, p, h->len, h->caplen); - - return (sizeof(struct lecdatahdr_8023)); -} diff --git a/contrib/tcpdump/print-ldp.c b/contrib/tcpdump/print-ldp.c index e7f00c3524..896bc40395 100644 --- a/contrib/tcpdump/print-ldp.c +++ b/contrib/tcpdump/print-ldp.c @@ -17,10 +17,10 @@ /* \summary: Label Distribution Protocol (LDP) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "extract.h" @@ -29,7 +29,6 @@ #include "l2vpn.h" #include "af.h" -static const char tstr[] = " [|LDP]"; /* * ldp common header @@ -47,10 +46,10 @@ static const char tstr[] = " [|LDP]"; */ struct ldp_common_header { - uint8_t version[2]; - uint8_t pdu_length[2]; - uint8_t lsr_id[4]; - uint8_t label_space[2]; + nd_uint16_t version; + nd_uint16_t pdu_length; + nd_ipv4 lsr_id; + nd_uint16_t label_space; }; #define LDP_VERSION 1 @@ -80,9 +79,9 @@ struct ldp_common_header { */ struct ldp_msg_header { - uint8_t type[2]; - uint8_t length[2]; - uint8_t id[4]; + nd_uint16_t type; + nd_uint16_t length; + nd_uint32_t id; }; #define LDP_MASK_MSG_TYPE(x) ((x)&0x7fff) @@ -212,7 +211,7 @@ static const struct tok ldp_fec_martini_ifparm_vccv_cv_values[] = { { 0, NULL} }; -static u_int ldp_pdu_print(netdissect_options *, register const u_char *); +static u_int ldp_pdu_print(netdissect_options *, const u_char *); /* * ldp tlv header @@ -232,16 +231,20 @@ static u_int ldp_pdu_print(netdissect_options *, register const u_char *); */ #define TLV_TCHECK(minlen) \ - ND_TCHECK2(*tptr, minlen); if (tlv_tlen < minlen) goto badtlv; + if (tlv_tlen < minlen) { \ + ND_PRINT(" [tlv length %u < %u]", tlv_tlen, minlen); \ + nd_print_invalid(ndo); \ + goto invalid; \ + } -static int +static u_int ldp_tlv_print(netdissect_options *ndo, - register const u_char *tptr, - u_short msg_tlen) + const u_char *tptr, + u_int msg_tlen) { struct ldp_tlv_header { - uint8_t type[2]; - uint8_t length[2]; + nd_uint16_t type; + nd_uint16_t length; }; const struct ldp_tlv_header *ldp_tlv_header; @@ -252,24 +255,24 @@ ldp_tlv_print(netdissect_options *ndo, int i; ldp_tlv_header = (const struct ldp_tlv_header *)tptr; - ND_TCHECK(*ldp_tlv_header); - tlv_len=EXTRACT_16BITS(ldp_tlv_header->length); - if (tlv_len + 4 > msg_tlen) { - ND_PRINT((ndo, "\n\t\t TLV contents go past end of message")); + ND_TCHECK_SIZE(ldp_tlv_header); + tlv_len=GET_BE_U_2(ldp_tlv_header->length); + if (tlv_len + 4U > msg_tlen) { + ND_PRINT("\n\t\t TLV contents go past end of message"); return 0; } tlv_tlen=tlv_len; - tlv_type=LDP_MASK_TLV_TYPE(EXTRACT_16BITS(ldp_tlv_header->type)); + tlv_type=LDP_MASK_TLV_TYPE(GET_BE_U_2(ldp_tlv_header->type)); /* FIXME vendor private / experimental check */ - ND_PRINT((ndo, "\n\t %s TLV (0x%04x), length: %u, Flags: [%s and %s forward if unknown]", + ND_PRINT("\n\t %s TLV (0x%04x), length: %u, Flags: [%s and %s forward if unknown]", tok2str(ldp_tlv_values, "Unknown", tlv_type), tlv_type, tlv_len, - LDP_MASK_U_BIT(EXTRACT_16BITS(&ldp_tlv_header->type)) ? "continue processing" : "ignore", - LDP_MASK_F_BIT(EXTRACT_16BITS(&ldp_tlv_header->type)) ? "do" : "don't")); + LDP_MASK_U_BIT(GET_BE_U_2(ldp_tlv_header->type)) ? "continue processing" : "ignore", + LDP_MASK_F_BIT(GET_BE_U_2(ldp_tlv_header->type)) ? "do" : "don't"); tptr+=sizeof(struct ldp_tlv_header); @@ -277,47 +280,45 @@ ldp_tlv_print(netdissect_options *ndo, case LDP_TLV_COMMON_HELLO: TLV_TCHECK(4); - ND_PRINT((ndo, "\n\t Hold Time: %us, Flags: [%s Hello%s]", - EXTRACT_16BITS(tptr), - (EXTRACT_16BITS(tptr+2)&0x8000) ? "Targeted" : "Link", - (EXTRACT_16BITS(tptr+2)&0x4000) ? ", Request for targeted Hellos" : "")); + ND_PRINT("\n\t Hold Time: %us, Flags: [%s Hello%s]", + GET_BE_U_2(tptr), + (GET_BE_U_2(tptr + 2)&0x8000) ? "Targeted" : "Link", + (GET_BE_U_2(tptr + 2)&0x4000) ? ", Request for targeted Hellos" : ""); break; case LDP_TLV_IPV4_TRANSPORT_ADDR: TLV_TCHECK(4); - ND_PRINT((ndo, "\n\t IPv4 Transport Address: %s", ipaddr_string(ndo, tptr))); + ND_PRINT("\n\t IPv4 Transport Address: %s", GET_IPADDR_STRING(tptr)); break; case LDP_TLV_IPV6_TRANSPORT_ADDR: TLV_TCHECK(16); - ND_PRINT((ndo, "\n\t IPv6 Transport Address: %s", ip6addr_string(ndo, tptr))); + ND_PRINT("\n\t IPv6 Transport Address: %s", GET_IP6ADDR_STRING(tptr)); break; case LDP_TLV_CONFIG_SEQ_NUMBER: TLV_TCHECK(4); - ND_PRINT((ndo, "\n\t Sequence Number: %u", EXTRACT_32BITS(tptr))); + ND_PRINT("\n\t Sequence Number: %u", GET_BE_U_4(tptr)); break; case LDP_TLV_ADDRESS_LIST: TLV_TCHECK(LDP_TLV_ADDRESS_LIST_AFNUM_LEN); - af = EXTRACT_16BITS(tptr); + af = GET_BE_U_2(tptr); tptr+=LDP_TLV_ADDRESS_LIST_AFNUM_LEN; tlv_tlen -= LDP_TLV_ADDRESS_LIST_AFNUM_LEN; - ND_PRINT((ndo, "\n\t Address Family: %s, addresses", - tok2str(af_values, "Unknown (%u)", af))); + ND_PRINT("\n\t Address Family: %s, addresses", + tok2str(af_values, "Unknown (%u)", af)); switch (af) { case AFNUM_INET: - while(tlv_tlen >= sizeof(struct in_addr)) { - ND_TCHECK2(*tptr, sizeof(struct in_addr)); - ND_PRINT((ndo, " %s", ipaddr_string(ndo, tptr))); - tlv_tlen-=sizeof(struct in_addr); - tptr+=sizeof(struct in_addr); + while(tlv_tlen >= sizeof(nd_ipv4)) { + ND_PRINT(" %s", GET_IPADDR_STRING(tptr)); + tlv_tlen-=sizeof(nd_ipv4); + tptr+=sizeof(nd_ipv4); } break; case AFNUM_INET6: - while(tlv_tlen >= sizeof(struct in6_addr)) { - ND_TCHECK2(*tptr, sizeof(struct in6_addr)); - ND_PRINT((ndo, " %s", ip6addr_string(ndo, tptr))); - tlv_tlen-=sizeof(struct in6_addr); - tptr+=sizeof(struct in6_addr); + while(tlv_tlen >= sizeof(nd_ipv6)) { + ND_PRINT(" %s", GET_IP6ADDR_STRING(tptr)); + tlv_tlen-=sizeof(nd_ipv6); + tptr+=sizeof(nd_ipv6); } break; default: @@ -328,19 +329,19 @@ ldp_tlv_print(netdissect_options *ndo, case LDP_TLV_COMMON_SESSION: TLV_TCHECK(8); - ND_PRINT((ndo, "\n\t Version: %u, Keepalive: %us, Flags: [Downstream %s, Loop Detection %s]", - EXTRACT_16BITS(tptr), EXTRACT_16BITS(tptr+2), - (EXTRACT_16BITS(tptr+6)&0x8000) ? "On Demand" : "Unsolicited", - (EXTRACT_16BITS(tptr+6)&0x4000) ? "Enabled" : "Disabled" - )); + ND_PRINT("\n\t Version: %u, Keepalive: %us, Flags: [Downstream %s, Loop Detection %s]", + GET_BE_U_2(tptr), GET_BE_U_2(tptr + 2), + (GET_BE_U_2(tptr + 6)&0x8000) ? "On Demand" : "Unsolicited", + (GET_BE_U_2(tptr + 6)&0x4000) ? "Enabled" : "Disabled" + ); break; case LDP_TLV_FEC: TLV_TCHECK(1); - fec_type = *tptr; - ND_PRINT((ndo, "\n\t %s FEC (0x%02x)", + fec_type = GET_U_1(tptr); + ND_PRINT("\n\t %s FEC (0x%02x)", tok2str(ldp_fec_values, "Unknown", fec_type), - fec_type)); + fec_type); tptr+=1; tlv_tlen-=1; @@ -350,33 +351,33 @@ ldp_tlv_print(netdissect_options *ndo, break; case LDP_FEC_PREFIX: TLV_TCHECK(2); - af = EXTRACT_16BITS(tptr); - tptr+=LDP_TLV_ADDRESS_LIST_AFNUM_LEN; - tlv_tlen-=LDP_TLV_ADDRESS_LIST_AFNUM_LEN; + af = GET_BE_U_2(tptr); + tptr+=2; + tlv_tlen-=2; if (af == AFNUM_INET) { i=decode_prefix4(ndo, tptr, tlv_tlen, buf, sizeof(buf)); if (i == -2) goto trunc; if (i == -3) - ND_PRINT((ndo, ": IPv4 prefix (goes past end of TLV)")); + ND_PRINT(": IPv4 prefix (goes past end of TLV)"); else if (i == -1) - ND_PRINT((ndo, ": IPv4 prefix (invalid length)")); + ND_PRINT(": IPv4 prefix (invalid length)"); else - ND_PRINT((ndo, ": IPv4 prefix %s", buf)); + ND_PRINT(": IPv4 prefix %s", buf); } else if (af == AFNUM_INET6) { i=decode_prefix6(ndo, tptr, tlv_tlen, buf, sizeof(buf)); if (i == -2) goto trunc; if (i == -3) - ND_PRINT((ndo, ": IPv4 prefix (goes past end of TLV)")); + ND_PRINT(": IPv4 prefix (goes past end of TLV)"); else if (i == -1) - ND_PRINT((ndo, ": IPv6 prefix (invalid length)")); + ND_PRINT(": IPv6 prefix (invalid length)"); else - ND_PRINT((ndo, ": IPv6 prefix %s", buf)); + ND_PRINT(": IPv6 prefix %s", buf); } else - ND_PRINT((ndo, ": Address family %u prefix", af)); + ND_PRINT(": Address family %u prefix", af); break; case LDP_FEC_HOSTADDRESS: break; @@ -386,7 +387,7 @@ ldp_tlv_print(netdissect_options *ndo, * Pseudowire Types. */ TLV_TCHECK(7); - vc_info_len = *(tptr+2); + vc_info_len = GET_U_1(tptr + 2); /* * According to RFC 4908, the VC info Length field can be zero, @@ -394,25 +395,25 @@ ldp_tlv_print(netdissect_options *ndo, * there's no VC ID. */ if (vc_info_len == 0) { - ND_PRINT((ndo, ": %s, %scontrol word, group-ID %u, VC-info-length: %u", - tok2str(mpls_pw_types_values, "Unknown", EXTRACT_16BITS(tptr)&0x7fff), - EXTRACT_16BITS(tptr)&0x8000 ? "" : "no ", - EXTRACT_32BITS(tptr+3), - vc_info_len)); + ND_PRINT(": %s, %scontrol word, group-ID %u, VC-info-length: %u", + tok2str(mpls_pw_types_values, "Unknown", GET_BE_U_2(tptr)&0x7fff), + GET_BE_U_2(tptr)&0x8000 ? "" : "no ", + GET_BE_U_4(tptr + 3), + vc_info_len); break; } /* Make sure we have the VC ID as well */ TLV_TCHECK(11); - ND_PRINT((ndo, ": %s, %scontrol word, group-ID %u, VC-ID %u, VC-info-length: %u", - tok2str(mpls_pw_types_values, "Unknown", EXTRACT_16BITS(tptr)&0x7fff), - EXTRACT_16BITS(tptr)&0x8000 ? "" : "no ", - EXTRACT_32BITS(tptr+3), - EXTRACT_32BITS(tptr+7), - vc_info_len)); + ND_PRINT(": %s, %scontrol word, group-ID %u, VC-ID %u, VC-info-length: %u", + tok2str(mpls_pw_types_values, "Unknown", GET_BE_U_2(tptr)&0x7fff), + GET_BE_U_2(tptr)&0x8000 ? "" : "no ", + GET_BE_U_4(tptr + 3), + GET_BE_U_4(tptr + 7), + vc_info_len); if (vc_info_len < 4) { /* minimum 4, for the VC ID */ - ND_PRINT((ndo, " (invalid, < 4")); + ND_PRINT(" (invalid, < 4"); return(tlv_len+4); /* Type & Length fields not included */ } vc_info_len -= 4; /* subtract out the VC ID, giving the length of the interface parameters */ @@ -423,41 +424,36 @@ ldp_tlv_print(netdissect_options *ndo, TLV_TCHECK(vc_info_len); while (vc_info_len > 2) { - vc_info_tlv_type = *tptr; - vc_info_tlv_len = *(tptr+1); + vc_info_tlv_type = GET_U_1(tptr); + vc_info_tlv_len = GET_U_1(tptr + 1); if (vc_info_tlv_len < 2) break; if (vc_info_len < vc_info_tlv_len) break; - ND_PRINT((ndo, "\n\t\tInterface Parameter: %s (0x%02x), len %u", + ND_PRINT("\n\t\tInterface Parameter: %s (0x%02x), len %u", tok2str(ldp_fec_martini_ifparm_values,"Unknown",vc_info_tlv_type), vc_info_tlv_type, - vc_info_tlv_len)); + vc_info_tlv_len); switch(vc_info_tlv_type) { case LDP_FEC_MARTINI_IFPARM_MTU: - ND_TCHECK_16BITS(tptr + 2); - ND_PRINT((ndo, ": %u", EXTRACT_16BITS(tptr+2))); + ND_PRINT(": %u", GET_BE_U_2(tptr + 2)); break; case LDP_FEC_MARTINI_IFPARM_DESC: - ND_PRINT((ndo, ": ")); - for (idx = 2; idx < vc_info_tlv_len; idx++) { - ND_TCHECK_8BITS(tptr + idx); - safeputchar(ndo, *(tptr + idx)); - } + ND_PRINT(": "); + for (idx = 2; idx < vc_info_tlv_len; idx++) + fn_print_char(ndo, GET_U_1(tptr + idx)); break; case LDP_FEC_MARTINI_IFPARM_VCCV: - ND_TCHECK_8BITS(tptr + 2); - ND_PRINT((ndo, "\n\t\t Control Channels (0x%02x) = [%s]", - *(tptr+2), - bittok2str(ldp_fec_martini_ifparm_vccv_cc_values, "none", *(tptr+2)))); - ND_TCHECK_8BITS(tptr + 3); - ND_PRINT((ndo, "\n\t\t CV Types (0x%02x) = [%s]", - *(tptr+3), - bittok2str(ldp_fec_martini_ifparm_vccv_cv_values, "none", *(tptr+3)))); + ND_PRINT("\n\t\t Control Channels (0x%02x) = [%s]", + GET_U_1((tptr + 2)), + bittok2str(ldp_fec_martini_ifparm_vccv_cc_values, "none", GET_U_1((tptr + 2)))); + ND_PRINT("\n\t\t CV Types (0x%02x) = [%s]", + GET_U_1((tptr + 3)), + bittok2str(ldp_fec_martini_ifparm_vccv_cv_values, "none", GET_U_1((tptr + 3)))); break; default: @@ -475,46 +471,46 @@ ldp_tlv_print(netdissect_options *ndo, case LDP_TLV_GENERIC_LABEL: TLV_TCHECK(4); - ND_PRINT((ndo, "\n\t Label: %u", EXTRACT_32BITS(tptr) & 0xfffff)); + ND_PRINT("\n\t Label: %u", GET_BE_U_4(tptr) & 0xfffff); break; case LDP_TLV_STATUS: TLV_TCHECK(8); - ui = EXTRACT_32BITS(tptr); + ui = GET_BE_U_4(tptr); tptr+=4; - ND_PRINT((ndo, "\n\t Status: 0x%02x, Flags: [%s and %s forward]", + ND_PRINT("\n\t Status: 0x%02x, Flags: [%s and %s forward]", ui&0x3fffffff, ui&0x80000000 ? "Fatal error" : "Advisory Notification", - ui&0x40000000 ? "do" : "don't")); - ui = EXTRACT_32BITS(tptr); + ui&0x40000000 ? "do" : "don't"); + ui = GET_BE_U_4(tptr); tptr+=4; if (ui) - ND_PRINT((ndo, ", causing Message ID: 0x%08x", ui)); + ND_PRINT(", causing Message ID: 0x%08x", ui); break; case LDP_TLV_FT_SESSION: TLV_TCHECK(12); - ft_flags = EXTRACT_16BITS(tptr); - ND_PRINT((ndo, "\n\t Flags: [%sReconnect, %sSave State, %sAll-Label Protection, %s Checkpoint, %sRe-Learn State]", + ft_flags = GET_BE_U_2(tptr); + ND_PRINT("\n\t Flags: [%sReconnect, %sSave State, %sAll-Label Protection, %s Checkpoint, %sRe-Learn State]", ft_flags&0x8000 ? "" : "No ", ft_flags&0x8 ? "" : "Don't ", ft_flags&0x4 ? "" : "No ", ft_flags&0x2 ? "Sequence Numbered Label" : "All Labels", - ft_flags&0x1 ? "" : "Don't ")); + ft_flags&0x1 ? "" : "Don't "); /* 16 bits (FT Flags) + 16 bits (Reserved) */ tptr+=4; - ui = EXTRACT_32BITS(tptr); + ui = GET_BE_U_4(tptr); if (ui) - ND_PRINT((ndo, ", Reconnect Timeout: %ums", ui)); + ND_PRINT(", Reconnect Timeout: %ums", ui); tptr+=4; - ui = EXTRACT_32BITS(tptr); + ui = GET_BE_U_4(tptr); if (ui) - ND_PRINT((ndo, ", Recovery Time: %ums", ui)); + ND_PRINT(", Recovery Time: %ums", ui); break; case LDP_TLV_MTU: TLV_TCHECK(2); - ND_PRINT((ndo, "\n\t MTU: %u", EXTRACT_16BITS(tptr))); + ND_PRINT("\n\t MTU: %u", GET_BE_U_2(tptr)); break; @@ -542,28 +538,27 @@ ldp_tlv_print(netdissect_options *ndo, return(tlv_len+4); /* Type & Length fields not included */ trunc: - ND_PRINT((ndo, "%s", tstr)); - return 0; + nd_trunc_longjmp(ndo); -badtlv: - ND_PRINT((ndo, "\n\t\t TLV contents go past end of TLV")); +invalid: return(tlv_len+4); /* Type & Length fields not included */ } void ldp_print(netdissect_options *ndo, - register const u_char *pptr, register u_int len) + const u_char *pptr, u_int len) { u_int processed; + + ndo->ndo_protocol = "ldp"; while (len > (sizeof(struct ldp_common_header) + sizeof(struct ldp_msg_header))) { processed = ldp_pdu_print(ndo, pptr); if (processed == 0) return; if (len < processed) { - ND_PRINT((ndo, " [remaining length %u < %u]", len, processed)); - ND_PRINT((ndo, "%s", istr)); + ND_PRINT(" [remaining length %u < %u]", len, processed); + nd_print_invalid(ndo); break; - } len -= processed; pptr += processed; @@ -572,89 +567,90 @@ ldp_print(netdissect_options *ndo, static u_int ldp_pdu_print(netdissect_options *ndo, - register const u_char *pptr) + const u_char *pptr) { const struct ldp_common_header *ldp_com_header; const struct ldp_msg_header *ldp_msg_header; const u_char *tptr,*msg_tptr; u_short tlen; - u_short pdu_len,msg_len,msg_type,msg_tlen; + u_short pdu_len,msg_len,msg_type; + u_int msg_tlen; int hexdump,processed; ldp_com_header = (const struct ldp_common_header *)pptr; - ND_TCHECK(*ldp_com_header); + ND_TCHECK_SIZE(ldp_com_header); /* * Sanity checking of the header. */ - if (EXTRACT_16BITS(&ldp_com_header->version) != LDP_VERSION) { - ND_PRINT((ndo, "%sLDP version %u packet not supported", + if (GET_BE_U_2(ldp_com_header->version) != LDP_VERSION) { + ND_PRINT("%sLDP version %u packet not supported", (ndo->ndo_vflag < 1) ? "" : "\n\t", - EXTRACT_16BITS(&ldp_com_header->version))); + GET_BE_U_2(ldp_com_header->version)); return 0; } - pdu_len = EXTRACT_16BITS(&ldp_com_header->pdu_length); - if (pdu_len < sizeof(const struct ldp_common_header)-4) { + pdu_len = GET_BE_U_2(ldp_com_header->pdu_length); + if (pdu_len < sizeof(struct ldp_common_header)-4) { /* length too short */ - ND_PRINT((ndo, "%sLDP, pdu-length: %u (too short, < %u)", - (ndo->ndo_vflag < 1) ? "" : "\n\t", - pdu_len, - (u_int)(sizeof(const struct ldp_common_header)-4))); + ND_PRINT("%sLDP, pdu-length: %u (too short, < %zu)", + (ndo->ndo_vflag < 1) ? "" : "\n\t", + pdu_len, + sizeof(struct ldp_common_header)-4); return 0; } /* print the LSR-ID, label-space & length */ - ND_PRINT((ndo, "%sLDP, Label-Space-ID: %s:%u, pdu-length: %u", + ND_PRINT("%sLDP, Label-Space-ID: %s:%u, pdu-length: %u", (ndo->ndo_vflag < 1) ? "" : "\n\t", - ipaddr_string(ndo, &ldp_com_header->lsr_id), - EXTRACT_16BITS(&ldp_com_header->label_space), - pdu_len)); + GET_IPADDR_STRING(ldp_com_header->lsr_id), + GET_BE_U_2(ldp_com_header->label_space), + pdu_len); /* bail out if non-verbose */ if (ndo->ndo_vflag < 1) return 0; /* ok they seem to want to know everything - lets fully decode it */ - tptr = pptr + sizeof(const struct ldp_common_header); - tlen = pdu_len - (sizeof(const struct ldp_common_header)-4); /* Type & Length fields not included */ + tptr = pptr + sizeof(struct ldp_common_header); + tlen = pdu_len - (sizeof(struct ldp_common_header)-4); /* Type & Length fields not included */ while(tlen>0) { /* did we capture enough for fully decoding the msg header ? */ - ND_TCHECK2(*tptr, sizeof(struct ldp_msg_header)); + ND_TCHECK_LEN(tptr, sizeof(struct ldp_msg_header)); ldp_msg_header = (const struct ldp_msg_header *)tptr; - msg_len=EXTRACT_16BITS(ldp_msg_header->length); - msg_type=LDP_MASK_MSG_TYPE(EXTRACT_16BITS(ldp_msg_header->type)); + msg_len=GET_BE_U_2(ldp_msg_header->length); + msg_type=LDP_MASK_MSG_TYPE(GET_BE_U_2(ldp_msg_header->type)); if (msg_len < sizeof(struct ldp_msg_header)-4) { /* length too short */ /* FIXME vendor private / experimental check */ - ND_PRINT((ndo, "\n\t %s Message (0x%04x), length: %u (too short, < %u)", - tok2str(ldp_msg_values, - "Unknown", - msg_type), - msg_type, - msg_len, - (u_int)(sizeof(struct ldp_msg_header)-4))); + ND_PRINT("\n\t %s Message (0x%04x), length: %u (too short, < %zu)", + tok2str(ldp_msg_values, + "Unknown", + msg_type), + msg_type, + msg_len, + sizeof(struct ldp_msg_header)-4); return 0; } /* FIXME vendor private / experimental check */ - ND_PRINT((ndo, "\n\t %s Message (0x%04x), length: %u, Message ID: 0x%08x, Flags: [%s if unknown]", + ND_PRINT("\n\t %s Message (0x%04x), length: %u, Message ID: 0x%08x, Flags: [%s if unknown]", tok2str(ldp_msg_values, "Unknown", msg_type), msg_type, msg_len, - EXTRACT_32BITS(&ldp_msg_header->id), - LDP_MASK_U_BIT(EXTRACT_16BITS(&ldp_msg_header->type)) ? "continue processing" : "ignore")); + GET_BE_U_4(ldp_msg_header->id), + LDP_MASK_U_BIT(GET_BE_U_2(ldp_msg_header->type)) ? "continue processing" : "ignore"); msg_tptr=tptr+sizeof(struct ldp_msg_header); msg_tlen=msg_len-(sizeof(struct ldp_msg_header)-4); /* Type & Length fields not included */ /* did we capture enough for fully decoding the message ? */ - ND_TCHECK2(*tptr, msg_len); + ND_TCHECK_LEN(tptr, msg_len); hexdump=FALSE; switch(msg_type) { @@ -700,13 +696,5 @@ ldp_pdu_print(netdissect_options *ndo, } return pdu_len+4; trunc: - ND_PRINT((ndo, "%s", tstr)); - return 0; + nd_trunc_longjmp(ndo); } - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/print-lisp.c b/contrib/tcpdump/print-lisp.c index 47afe50359..0012e06eea 100644 --- a/contrib/tcpdump/print-lisp.c +++ b/contrib/tcpdump/print-lisp.c @@ -95,13 +95,11 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include -#include -#include -#include +#include "netdissect-stdinc.h" +#include "netdissect.h" #include "ip.h" #include "ip6.h" @@ -109,7 +107,6 @@ #include "extract.h" #include "addrtoname.h" -static const char tstr[] = " [|LISP]"; #define IPv4_AFI 1 #define IPv6_AFI 2 @@ -205,8 +202,7 @@ typedef struct map_register_eid { nd_uint8_t eid_prefix_mask_length; nd_uint8_t act_auth_inc_res; nd_uint8_t reserved; - nd_uint8_t reserved_version_hi; - nd_uint8_t version_low; + nd_uint16_t reserved_and_version; nd_uint16_t eid_prefix_afi; } lisp_map_register_eid; @@ -223,14 +219,16 @@ typedef struct map_register_loc { #define MAP_REGISTER_LOC_LEN sizeof(lisp_map_register_loc) -static inline uint8_t extract_lisp_type(uint8_t); -static inline uint8_t is_xtr_data_present(uint8_t , uint8_t); +static uint8_t extract_lisp_type(uint8_t); +static uint8_t is_xtr_data_present(uint8_t, uint8_t); static void lisp_hdr_flag(netdissect_options *, const lisp_map_register_hdr *); static void action_flag(netdissect_options *, uint8_t); static void loc_hdr_flag(netdissect_options *, uint16_t); -void lisp_print(netdissect_options *ndo, const u_char *bp, u_int length) +void +lisp_print(netdissect_options *ndo, const u_char *bp, u_int length) { + uint8_t type_and_flag; uint8_t type; uint8_t mask_len; uint8_t loc_count; @@ -249,33 +247,35 @@ void lisp_print(netdissect_options *ndo, const u_char *bp, u_int length) const lisp_map_register_eid *lisp_eid; const lisp_map_register_loc *lisp_loc; + ndo->ndo_protocol = "lisp"; /* Check if enough bytes for header are available */ - ND_TCHECK2(*bp, MAP_REGISTER_HDR_LEN); + ND_TCHECK_LEN(bp, MAP_REGISTER_HDR_LEN); lisp_hdr = (const lisp_map_register_hdr *) bp; lisp_hdr_flag(ndo, lisp_hdr); /* Supporting only MAP NOTIFY and MAP REGISTER LISP packets */ - type = extract_lisp_type(lisp_hdr->type_and_flag); + type_and_flag = GET_U_1(lisp_hdr->type_and_flag); + type = extract_lisp_type(type_and_flag); if ((type != LISP_MAP_REGISTER) && (type != LISP_MAP_NOTIFY)) return; /* Find if the packet contains xTR and Site-ID data */ - xtr_present = is_xtr_data_present(type, lisp_hdr->type_and_flag); + xtr_present = is_xtr_data_present(type, type_and_flag); /* Extract the number of EID records present */ - auth_data_len = EXTRACT_16BITS(&lisp_hdr->auth_data_len); + auth_data_len = GET_BE_U_2(lisp_hdr->auth_data_len); packet_iterator = (const u_char *)(lisp_hdr); packet_offset = MAP_REGISTER_HDR_LEN; - record_count = lisp_hdr->record_count; + record_count = GET_U_1(lisp_hdr->record_count); if (ndo->ndo_vflag) { - key_id = EXTRACT_16BITS(&lisp_hdr->key_id); - ND_PRINT((ndo, "\n %u record(s), ", record_count)); - ND_PRINT((ndo, "Authentication %s,", - tok2str(auth_type, "unknown-type", key_id))); + key_id = GET_BE_U_2(lisp_hdr->key_id); + ND_PRINT("\n %u record(s), ", record_count); + ND_PRINT("Authentication %s,", + tok2str(auth_type, "unknown-type", key_id)); hex_print(ndo, "\n Authentication-Data: ", packet_iterator + packet_offset, auth_data_len); } else { - ND_PRINT((ndo, " %u record(s),", record_count)); + ND_PRINT(" %u record(s),", record_count); } packet_offset += auth_data_len; @@ -285,35 +285,35 @@ void lisp_print(netdissect_options *ndo, const u_char *bp, u_int length) /* Print all the EID records */ while ((length > packet_offset) && (record_count--)) { - ND_TCHECK2(*(packet_iterator + packet_offset), MAP_REGISTER_EID_LEN); - ND_PRINT((ndo, "\n")); + ND_TCHECK_LEN(packet_iterator + packet_offset, + MAP_REGISTER_EID_LEN); + ND_PRINT("\n"); lisp_eid = (const lisp_map_register_eid *) ((const u_char *)lisp_hdr + packet_offset); packet_offset += MAP_REGISTER_EID_LEN; - mask_len = lisp_eid->eid_prefix_mask_length; - eid_afi = EXTRACT_16BITS(&lisp_eid->eid_prefix_afi); - loc_count = lisp_eid->locator_count; + mask_len = GET_U_1(lisp_eid->eid_prefix_mask_length); + eid_afi = GET_BE_U_2(lisp_eid->eid_prefix_afi); + loc_count = GET_U_1(lisp_eid->locator_count); if (ndo->ndo_vflag) { - ttl = EXTRACT_32BITS(&lisp_eid->ttl); - ND_PRINT((ndo, " Record TTL %u,", ttl)); - action_flag(ndo, lisp_eid->act_auth_inc_res); - map_version = (((lisp_eid->reserved_version_hi) & 15 ) * 255) + - lisp_eid->version_low; - ND_PRINT((ndo, " Map Version: %u,", map_version)); + ttl = GET_BE_U_4(lisp_eid->ttl); + ND_PRINT(" Record TTL %u,", ttl); + action_flag(ndo, GET_U_1(lisp_eid->act_auth_inc_res)); + map_version = GET_BE_U_2(lisp_eid->reserved_and_version) & 0x0FFF; + ND_PRINT(" Map Version: %u,", map_version); } switch (eid_afi) { case IPv4_AFI: - ND_TCHECK2(*(packet_iterator + packet_offset), 4); - ND_PRINT((ndo, " EID %s/%u,", ipaddr_string(ndo, - packet_iterator + packet_offset), mask_len)); + ND_PRINT(" EID %s/%u,", + GET_IPADDR_STRING(packet_iterator + packet_offset), + mask_len); packet_offset += 4; break; case IPv6_AFI: - ND_TCHECK2(*(packet_iterator + packet_offset), 16); - ND_PRINT((ndo, " EID %s/%u,", ip6addr_string(ndo, - packet_iterator + packet_offset), mask_len)); + ND_PRINT(" EID %s/%u,", + GET_IP6ADDR_STRING(packet_iterator + packet_offset), + mask_len); packet_offset += 16; break; default: @@ -324,38 +324,42 @@ void lisp_print(netdissect_options *ndo, const u_char *bp, u_int length) break; } - ND_PRINT((ndo, " %u locator(s)", loc_count)); + ND_PRINT(" %u locator(s)", loc_count); while (loc_count--) { - ND_TCHECK2(*(packet_iterator + packet_offset), MAP_REGISTER_LOC_LEN); + ND_TCHECK_LEN(packet_iterator + packet_offset, + MAP_REGISTER_LOC_LEN); lisp_loc = (const lisp_map_register_loc *) (packet_iterator + packet_offset); loc_ip_pointer = (const u_char *) (lisp_loc + 1); packet_offset += MAP_REGISTER_LOC_LEN; - loc_afi = EXTRACT_16BITS(&lisp_loc->locator_afi); + loc_afi = GET_BE_U_2(lisp_loc->locator_afi); if (ndo->ndo_vflag) - ND_PRINT((ndo, "\n ")); + ND_PRINT("\n "); switch (loc_afi) { case IPv4_AFI: - ND_TCHECK2(*(packet_iterator + packet_offset), 4); - ND_PRINT((ndo, " LOC %s", ipaddr_string(ndo, loc_ip_pointer))); + ND_TCHECK_4(packet_iterator + packet_offset); + ND_PRINT(" LOC %s", GET_IPADDR_STRING(loc_ip_pointer)); packet_offset += 4; break; case IPv6_AFI: - ND_TCHECK2(*(packet_iterator + packet_offset), 16); - ND_PRINT((ndo, " LOC %s", ip6addr_string(ndo, loc_ip_pointer))); + ND_TCHECK_16(packet_iterator + packet_offset); + ND_PRINT(" LOC %s", GET_IP6ADDR_STRING(loc_ip_pointer)); packet_offset += 16; break; default: break; } if (ndo->ndo_vflag) { - ND_PRINT((ndo, "\n Priority/Weight %u/%u," + ND_PRINT("\n Priority/Weight %u/%u," " Multicast Priority/Weight %u/%u,", - lisp_loc->priority, lisp_loc->weight, - lisp_loc->m_priority, lisp_loc->m_weight)); - loc_hdr_flag(ndo, EXTRACT_16BITS(&lisp_loc->unused_and_flag)); + GET_U_1(lisp_loc->priority), + GET_U_1(lisp_loc->weight), + GET_U_1(lisp_loc->m_priority), + GET_U_1(lisp_loc->m_weight)); + loc_hdr_flag(ndo, + GET_BE_U_2(lisp_loc->unused_and_flag)); } } } @@ -366,33 +370,34 @@ void lisp_print(netdissect_options *ndo, const u_char *bp, u_int length) * show it as hex data. */ if (xtr_present) { - if (!ND_TTEST2(*(packet_iterator + packet_offset), 24)) + if (!ND_TTEST_LEN(packet_iterator + packet_offset, 24)) goto invalid; - hex_print_with_offset(ndo, "\n xTR-ID: ", packet_iterator + packet_offset, 16, 0); - ND_PRINT((ndo, "\n SITE-ID: %" PRIu64, - EXTRACT_64BITS(packet_iterator + packet_offset + 16))); + hex_print(ndo, "\n xTR-ID: ", packet_iterator + packet_offset, 16); + ND_PRINT("\n SITE-ID: %" PRIu64, + GET_BE_U_8(packet_iterator + packet_offset + 16)); } else { /* Check if packet isn't over yet */ if (packet_iterator + packet_offset < ndo->ndo_snapend) { - hex_print_with_offset(ndo, "\n Data: ", packet_iterator + packet_offset, - (ndo->ndo_snapend - (packet_iterator + packet_offset)), 0); + hex_print(ndo, "\n Data: ", packet_iterator + packet_offset, + ND_BYTES_AVAILABLE_AFTER(packet_iterator + packet_offset)); } } return; trunc: - ND_PRINT((ndo, "\n %s", tstr)); + nd_print_trunc(ndo); return; invalid: - ND_PRINT((ndo, "\n %s", istr)); - return; + nd_print_invalid(ndo); } -static inline uint8_t extract_lisp_type(uint8_t lisp_hdr_flags) +static uint8_t +extract_lisp_type(uint8_t lisp_hdr_flags) { return (lisp_hdr_flags) >> TYPE_INDEX; } -static inline uint8_t is_xtr_data_present(uint8_t type, uint8_t lisp_hdr_flags) +static uint8_t +is_xtr_data_present(uint8_t type, uint8_t lisp_hdr_flags) { uint8_t xtr_present = 0; @@ -406,24 +411,22 @@ static inline uint8_t is_xtr_data_present(uint8_t type, uint8_t lisp_hdr_flags) static void lisp_hdr_flag(netdissect_options *ndo, const lisp_map_register_hdr *lisp_hdr) { - uint8_t type = extract_lisp_type(lisp_hdr->type_and_flag); + uint8_t type = extract_lisp_type(GET_U_1(lisp_hdr->type_and_flag)); if (!ndo->ndo_vflag) { - ND_PRINT((ndo, "%s,", tok2str(lisp_type, "unknown-type-%u", type))); + ND_PRINT("%s,", tok2str(lisp_type, "unknown-type-%u", type)); return; } else { - ND_PRINT((ndo, "%s,", tok2str(lisp_type, "unknown-type-%u", type))); + ND_PRINT("%s,", tok2str(lisp_type, "unknown-type-%u", type)); } if (type == LISP_MAP_REGISTER) { - ND_PRINT((ndo, " flags [%s],", bittok2str(map_register_hdr_flag, - "none", EXTRACT_32BITS(lisp_hdr)))); + ND_PRINT(" flags [%s],", bittok2str(map_register_hdr_flag, + "none", GET_BE_U_4(lisp_hdr))); } else if (type == LISP_MAP_NOTIFY) { - ND_PRINT((ndo, " flags [%s],", bittok2str(map_notify_hdr_flag, - "none", EXTRACT_32BITS(lisp_hdr)))); + ND_PRINT(" flags [%s],", bittok2str(map_notify_hdr_flag, + "none", GET_BE_U_4(lisp_hdr))); } - - return; } static void action_flag(netdissect_options *ndo, uint8_t act_auth_inc_res) @@ -434,16 +437,16 @@ static void action_flag(netdissect_options *ndo, uint8_t act_auth_inc_res) authoritative = ((act_auth_inc_res >> 4) & 1); if (authoritative) - ND_PRINT((ndo, " Authoritative,")); + ND_PRINT(" Authoritative,"); else - ND_PRINT((ndo, " Non-Authoritative,")); + ND_PRINT(" Non-Authoritative,"); action = act_auth_inc_res >> 5; - ND_PRINT((ndo, " %s,", tok2str(lisp_eid_action, "unknown", action))); + ND_PRINT(" %s,", tok2str(lisp_eid_action, "unknown", action)); } static void loc_hdr_flag(netdissect_options *ndo, uint16_t flag) { - ND_PRINT((ndo, " flags [%s],", bittok2str(lisp_loc_flag, "none", flag))); + ND_PRINT(" flags [%s],", bittok2str(lisp_loc_flag, "none", flag)); } diff --git a/contrib/tcpdump/print-llc.c b/contrib/tcpdump/print-llc.c index be8886abdd..ae3ae4cf5c 100644 --- a/contrib/tcpdump/print-llc.c +++ b/contrib/tcpdump/print-llc.c @@ -25,10 +25,10 @@ /* \summary: IEEE 802.2 LLC printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "addrtoname.h" @@ -155,19 +155,20 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, int hdrlen; int is_u; + ndo->ndo_protocol = "llc"; if (caplen < 3) { - ND_PRINT((ndo, "[|llc]")); + nd_print_trunc(ndo); ND_DEFAULTPRINT((const u_char *)p, caplen); return (caplen); } if (length < 3) { - ND_PRINT((ndo, "[|llc]")); + nd_print_trunc(ndo); ND_DEFAULTPRINT((const u_char *)p, caplen); return (length); } - dsap_field = *p; - ssap_field = *(p + 1); + dsap_field = GET_U_1(p); + ssap_field = GET_U_1(p + 1); /* * OK, what type of LLC frame is this? The length @@ -175,7 +176,7 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, * have a two-byte control field, and U frames have * a one-byte control field. */ - control = *(p + 2); + control = GET_U_1(p + 2); if ((control & LLC_U_FMT) == LLC_U_FMT) { /* * U frame. @@ -188,12 +189,12 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, * 2 bytes... */ if (caplen < 4) { - ND_PRINT((ndo, "[|llc]")); + nd_print_trunc(ndo); ND_DEFAULTPRINT((const u_char *)p, caplen); return (caplen); } if (length < 4) { - ND_PRINT((ndo, "[|llc]")); + nd_print_trunc(ndo); ND_DEFAULTPRINT((const u_char *)p, caplen); return (length); } @@ -201,7 +202,7 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, /* * ...and is little-endian. */ - control = EXTRACT_LE_16BITS(p + 2); + control = GET_LE_U_2(p + 2); is_u = 0; hdrlen = 4; /* DSAP, SSAP, 2-byte control field */ } @@ -210,11 +211,11 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, /* * This is an Ethernet_802.3 IPX frame; it has an * 802.3 header (i.e., an Ethernet header where the - * type/length field is <= ETHERMTU, i.e. it's a length - * field, not a type field), but has no 802.2 header - - * the IPX packet starts right after the Ethernet header, - * with a signature of two bytes of 0xFF (which is - * LLCSAP_GLOBAL). + * type/length field is <= MAX_ETHERNET_LENGTH_VAL, + * i.e. it's a length field, not a type field), but + * has no 802.2 header - the IPX packet starts right + * after the Ethernet header, with a signature of two + * bytes of 0xFF (which is LLCSAP_GLOBAL). * * (It might also have been an Ethernet_802.3 IPX at * one time, but got bridged onto another network, @@ -223,7 +224,7 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, */ if (ndo->ndo_eflag) - ND_PRINT((ndo, "IPX 802.3: ")); + ND_PRINT("IPX 802.3: "); ipx_print(ndo, p, length); return (0); /* no LLC header */ @@ -233,18 +234,18 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, ssap = ssap_field & ~LLC_GSAP; if (ndo->ndo_eflag) { - ND_PRINT((ndo, "LLC, dsap %s (0x%02x) %s, ssap %s (0x%02x) %s", + ND_PRINT("LLC, dsap %s (0x%02x) %s, ssap %s (0x%02x) %s", tok2str(llc_values, "Unknown", dsap), dsap, tok2str(llc_ig_flag_values, "Unknown", dsap_field & LLC_IG), tok2str(llc_values, "Unknown", ssap), ssap, - tok2str(llc_flag_values, "Unknown", ssap_field & LLC_GSAP))); + tok2str(llc_flag_values, "Unknown", ssap_field & LLC_GSAP)); if (is_u) { - ND_PRINT((ndo, ", ctrl 0x%02x: ", control)); + ND_PRINT(", ctrl 0x%02x: ", control); } else { - ND_PRINT((ndo, ", ctrl 0x%04x: ", control)); + ND_PRINT(", ctrl 0x%04x: ", control); } } @@ -299,7 +300,7 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, * destination SAPs being the IPX SAP. */ if (ndo->ndo_eflag) - ND_PRINT((ndo, "IPX 802.2: ")); + ND_PRINT("IPX 802.2: "); ipx_print(ndo, p, length); return (hdrlen); @@ -331,31 +332,31 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, if (!ndo->ndo_eflag) { if (ssap == dsap) { if (src == NULL || dst == NULL) - ND_PRINT((ndo, "%s ", tok2str(llc_values, "Unknown DSAP 0x%02x", dsap))); + ND_PRINT("%s ", tok2str(llc_values, "Unknown DSAP 0x%02x", dsap)); else - ND_PRINT((ndo, "%s > %s %s ", + ND_PRINT("%s > %s %s ", (src->addr_string)(ndo, src->addr), (dst->addr_string)(ndo, dst->addr), - tok2str(llc_values, "Unknown DSAP 0x%02x", dsap))); + tok2str(llc_values, "Unknown DSAP 0x%02x", dsap)); } else { if (src == NULL || dst == NULL) - ND_PRINT((ndo, "%s > %s ", + ND_PRINT("%s > %s ", tok2str(llc_values, "Unknown SSAP 0x%02x", ssap), - tok2str(llc_values, "Unknown DSAP 0x%02x", dsap))); + tok2str(llc_values, "Unknown DSAP 0x%02x", dsap)); else - ND_PRINT((ndo, "%s %s > %s %s ", + ND_PRINT("%s %s > %s %s ", (src->addr_string)(ndo, src->addr), tok2str(llc_values, "Unknown SSAP 0x%02x", ssap), (dst->addr_string)(ndo, dst->addr), - tok2str(llc_values, "Unknown DSAP 0x%02x", dsap))); + tok2str(llc_values, "Unknown DSAP 0x%02x", dsap)); } } if (is_u) { - ND_PRINT((ndo, "Unnumbered, %s, Flags [%s], length %u", + ND_PRINT("Unnumbered, %s, Flags [%s], length %u", tok2str(llc_cmd_values, "%02x", LLC_U_CMD(control)), tok2str(llc_flag_values,"?",(ssap_field & LLC_GSAP) | (control & LLC_U_POLL)), - length + hdrlen)); + length + hdrlen); if ((control & ~LLC_U_POLL) == LLC_XID) { if (length == 0) { @@ -367,35 +368,37 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, return (hdrlen); } if (caplen < 1) { - ND_PRINT((ndo, "[|llc]")); + nd_print_trunc(ndo); if (caplen > 0) ND_DEFAULTPRINT((const u_char *)p, caplen); return (hdrlen); } - if (*p == LLC_XID_FI) { + if (GET_U_1(p) == LLC_XID_FI) { if (caplen < 3 || length < 3) { - ND_PRINT((ndo, "[|llc]")); + nd_print_trunc(ndo); if (caplen > 0) ND_DEFAULTPRINT((const u_char *)p, caplen); } else - ND_PRINT((ndo, ": %02x %02x", p[1], p[2])); + ND_PRINT(": %02x %02x", + GET_U_1(p + 1), + GET_U_1(p + 2)); return (hdrlen); } } } else { if ((control & LLC_S_FMT) == LLC_S_FMT) { - ND_PRINT((ndo, "Supervisory, %s, rcv seq %u, Flags [%s], length %u", + ND_PRINT("Supervisory, %s, rcv seq %u, Flags [%s], length %u", tok2str(llc_supervisory_values,"?",LLC_S_CMD(control)), LLC_IS_NR(control), tok2str(llc_flag_values,"?",(ssap_field & LLC_GSAP) | (control & LLC_IS_POLL)), - length + hdrlen)); + length + hdrlen); return (hdrlen); /* no payload to print */ } else { - ND_PRINT((ndo, "Information, send seq %u, rcv seq %u, Flags [%s], length %u", + ND_PRINT("Information, send seq %u, rcv seq %u, Flags [%s], length %u", LLC_I_NS(control), LLC_IS_NR(control), tok2str(llc_flag_values,"?",(ssap_field & LLC_GSAP) | (control & LLC_IS_POLL)), - length + hdrlen)); + length + hdrlen); } } return (-hdrlen); @@ -422,14 +425,15 @@ snap_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, u_int bridge_pad) { uint32_t orgcode; - register u_short et; - register int ret; + u_short et; + int ret; - ND_TCHECK2(*p, 5); + ndo->ndo_protocol = "snap"; + ND_TCHECK_5(p); if (caplen < 5 || length < 5) goto trunc; - orgcode = EXTRACT_24BITS(p); - et = EXTRACT_16BITS(p + 3); + orgcode = GET_BE_U_3(p); + et = GET_BE_U_2(p + 3); if (ndo->ndo_eflag) { /* @@ -437,12 +441,12 @@ snap_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, * are any, so just print the SNAP header, not the MAC * addresses. */ - ND_PRINT((ndo, "oui %s (0x%06x), %s %s (0x%04x), length %u: ", + ND_PRINT("oui %s (0x%06x), %s %s (0x%04x), length %u: ", tok2str(oui_values, "Unknown", orgcode), orgcode, (orgcode == 0x000000 ? "ethertype" : "pid"), tok2str(oui_to_struct_tok(orgcode), "Unknown", et), - et, length - 5)); + et, length - 5); } p += 5; length -= 5; @@ -481,7 +485,7 @@ snap_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, case OUI_CISCO: switch (et) { case PID_CISCO_CDP: - cdp_print(ndo, p, length, caplen); + cdp_print(ndo, p, length); return (1); case PID_CISCO_DTP: dtp_print(ndo, p, length); @@ -513,7 +517,7 @@ snap_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, /* * Skip the padding. */ - ND_TCHECK2(*p, bridge_pad); + ND_TCHECK_LEN(p, bridge_pad); caplen -= bridge_pad; length -= bridge_pad; p += bridge_pad; @@ -534,7 +538,7 @@ snap_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, * Skip the padding, but not the Access * Control field. */ - ND_TCHECK2(*p, bridge_pad); + ND_TCHECK_LEN(p, bridge_pad); caplen -= bridge_pad; length -= bridge_pad; p += bridge_pad; @@ -555,7 +559,7 @@ snap_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, /* * Skip the padding. */ - ND_TCHECK2(*p, bridge_pad + 1); + ND_TCHECK_LEN(p, bridge_pad + 1); caplen -= bridge_pad + 1; length -= bridge_pad + 1; p += bridge_pad + 1; @@ -577,9 +581,9 @@ snap_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, * we have any. */ if (src != NULL && dst != NULL) { - ND_PRINT((ndo, "%s > %s ", + ND_PRINT("%s > %s ", (src->addr_string)(ndo, src->addr), - (dst->addr_string)(ndo, dst->addr))); + (dst->addr_string)(ndo, dst->addr)); } /* * Print the SNAP header, but if the OUI is 000000, don't @@ -587,28 +591,20 @@ snap_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, * ethertype. */ if (orgcode == 0x000000) { - ND_PRINT((ndo, "SNAP, ethertype %s (0x%04x), length %u: ", + ND_PRINT("SNAP, ethertype %s (0x%04x), length %u: ", tok2str(ethertype_values, "Unknown", et), - et, length)); + et, length); } else { - ND_PRINT((ndo, "SNAP, oui %s (0x%06x), pid %s (0x%04x), length %u: ", + ND_PRINT("SNAP, oui %s (0x%06x), pid %s (0x%04x), length %u: ", tok2str(oui_values, "Unknown", orgcode), orgcode, tok2str(oui_to_struct_tok(orgcode), "Unknown", et), - et, length)); + et, length); } } return (0); trunc: - ND_PRINT((ndo, "[|snap]")); + nd_print_trunc(ndo); return (1); } - - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/print-lldp.c b/contrib/tcpdump/print-lldp.c index e87b16bd0f..a0cd9ba480 100644 --- a/contrib/tcpdump/print-lldp.c +++ b/contrib/tcpdump/print-lldp.c @@ -20,10 +20,10 @@ /* \summary: IEEE 802.1ab Link Layer Discovery Protocol (LLDP) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include @@ -136,6 +136,7 @@ static const struct tok lldp_cap_values[] = { #define LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_VLAN_ID 2 #define LLDP_PRIVATE_8021_SUBTYPE_VLAN_NAME 3 #define LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_IDENTITY 4 +#define LLDP_PRIVATE_8021_SUBTYPE_LINKAGGR 7 #define LLDP_PRIVATE_8021_SUBTYPE_CONGESTION_NOTIFICATION 8 #define LLDP_PRIVATE_8021_SUBTYPE_ETS_CONFIGURATION 9 #define LLDP_PRIVATE_8021_SUBTYPE_ETS_RECOMMENDATION 10 @@ -149,6 +150,7 @@ static const struct tok lldp_8021_subtype_values[] = { { LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_VLAN_ID, "Port and Protocol VLAN ID"}, { LLDP_PRIVATE_8021_SUBTYPE_VLAN_NAME, "VLAN name"}, { LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_IDENTITY, "Protocol Identity"}, + { LLDP_PRIVATE_8021_SUBTYPE_LINKAGGR, "Link aggregation"}, { LLDP_PRIVATE_8021_SUBTYPE_CONGESTION_NOTIFICATION, "Congestion Notification"}, { LLDP_PRIVATE_8021_SUBTYPE_ETS_CONFIGURATION, "ETS Configuration"}, { LLDP_PRIVATE_8021_SUBTYPE_ETS_RECOMMENDATION, "ETS Recommendation"}, @@ -540,11 +542,11 @@ static const struct tok lldp_mdi_power_class_values[] = { { 0, NULL} }; -#define LLDP_AGGREGATION_CAPABILTIY (1 << 0) +#define LLDP_AGGREGATION_CAPABILITY (1 << 0) #define LLDP_AGGREGATION_STATUS (1 << 1) static const struct tok lldp_aggregation_values[] = { - { LLDP_AGGREGATION_CAPABILTIY, "supported"}, + { LLDP_AGGREGATION_CAPABILITY, "supported"}, { LLDP_AGGREGATION_STATUS, "enabled"}, { 0, NULL} }; @@ -588,7 +590,7 @@ static const struct tok lldp_intf_numb_subtype_values[] = { static const struct tok lldp_evb_mode_values[]={ { LLDP_EVB_MODE_NOT_SUPPORTED, "Not Supported"}, { LLDP_EVB_MODE_EVB_BRIDGE, "EVB Bridge"}, - { LLDP_EVB_MODE_EVB_STATION, "EVB Staion"}, + { LLDP_EVB_MODE_EVB_STATION, "EVB Station"}, { LLDP_EVB_MODE_RESERVED, "Reserved for future Standardization"}, { 0, NULL}, }; @@ -614,31 +616,37 @@ static void print_ets_priority_assignment_table(netdissect_options *ndo, const u_char *ptr) { - ND_PRINT((ndo, "\n\t Priority Assignment Table")); - ND_PRINT((ndo, "\n\t Priority : 0 1 2 3 4 5 6 7")); - ND_PRINT((ndo, "\n\t Value : %-3d %-3d %-3d %-3d %-3d %-3d %-3d %-3d", - ptr[0]>>4,ptr[0]&0x0f,ptr[1]>>4,ptr[1]&0x0f,ptr[2]>>4, - ptr[2] & 0x0f, ptr[3] >> 4, ptr[3] & 0x0f)); + ND_PRINT("\n\t Priority Assignment Table"); + ND_PRINT("\n\t Priority : 0 1 2 3 4 5 6 7"); + ND_PRINT("\n\t Value : %-3d %-3d %-3d %-3d %-3d %-3d %-3d %-3d", + GET_U_1(ptr) >> 4, GET_U_1(ptr) & 0x0f, + GET_U_1(ptr + 1) >> 4, GET_U_1(ptr + 1) & 0x0f, + GET_U_1(ptr + 2) >> 4, GET_U_1(ptr + 2) & 0x0f, + GET_U_1(ptr + 3) >> 4, GET_U_1(ptr + 3) & 0x0f); } static void print_tc_bandwidth_table(netdissect_options *ndo, const u_char *ptr) { - ND_PRINT((ndo, "\n\t TC Bandwidth Table")); - ND_PRINT((ndo, "\n\t TC%% : 0 1 2 3 4 5 6 7")); - ND_PRINT((ndo, "\n\t Value : %-3d %-3d %-3d %-3d %-3d %-3d %-3d %-3d", - ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7])); + ND_PRINT("\n\t TC Bandwidth Table"); + ND_PRINT("\n\t TC%% : 0 1 2 3 4 5 6 7"); + ND_PRINT("\n\t Value : %-3d %-3d %-3d %-3d %-3d %-3d %-3d %-3d", + GET_U_1(ptr), GET_U_1(ptr + 1), GET_U_1(ptr + 2), + GET_U_1(ptr + 3), GET_U_1(ptr + 4), GET_U_1(ptr + 5), + GET_U_1(ptr + 6), GET_U_1(ptr + 7)); } static void print_tsa_assignment_table(netdissect_options *ndo, const u_char *ptr) { - ND_PRINT((ndo, "\n\t TSA Assignment Table")); - ND_PRINT((ndo, "\n\t Traffic Class: 0 1 2 3 4 5 6 7")); - ND_PRINT((ndo, "\n\t Value : %-3d %-3d %-3d %-3d %-3d %-3d %-3d %-3d", - ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7])); + ND_PRINT("\n\t TSA Assignment Table"); + ND_PRINT("\n\t Traffic Class: 0 1 2 3 4 5 6 7"); + ND_PRINT("\n\t Value : %-3d %-3d %-3d %-3d %-3d %-3d %-3d %-3d", + GET_U_1(ptr), GET_U_1(ptr + 1), GET_U_1(ptr + 2), + GET_U_1(ptr + 3), GET_U_1(ptr + 4), GET_U_1(ptr + 5), + GET_U_1(ptr + 6), GET_U_1(ptr + 7)); } /* @@ -648,7 +656,8 @@ static int lldp_private_8021_print(netdissect_options *ndo, const u_char *tptr, u_int tlv_len) { - int subtype, hexdump = FALSE; + int hexdump = FALSE; + u_int subtype; u_int sublen; u_int tval; u_int i; @@ -656,80 +665,90 @@ lldp_private_8021_print(netdissect_options *ndo, if (tlv_len < 4) { return hexdump; } - subtype = *(tptr+3); + subtype = GET_U_1(tptr + 3); - ND_PRINT((ndo, "\n\t %s Subtype (%u)", + ND_PRINT("\n\t %s Subtype (%u)", tok2str(lldp_8021_subtype_values, "unknown", subtype), - subtype)); + subtype); switch (subtype) { case LLDP_PRIVATE_8021_SUBTYPE_PORT_VLAN_ID: if (tlv_len < 6) { return hexdump; } - ND_PRINT((ndo, "\n\t port vlan id (PVID): %u", - EXTRACT_16BITS(tptr + 4))); + ND_PRINT("\n\t port vlan id (PVID): %u", + GET_BE_U_2(tptr + 4)); break; case LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_VLAN_ID: if (tlv_len < 7) { return hexdump; } - ND_PRINT((ndo, "\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))); + ND_PRINT("\n\t port and protocol vlan id (PPVID): %u, flags [%s] (0x%02x)", + GET_BE_U_2(tptr + 5), + bittok2str(lldp_8021_port_protocol_id_values, "none", GET_U_1(tptr + 4)), + GET_U_1(tptr + 4)); break; case LLDP_PRIVATE_8021_SUBTYPE_VLAN_NAME: if (tlv_len < 6) { return hexdump; } - ND_PRINT((ndo, "\n\t vlan id (VID): %u", EXTRACT_16BITS(tptr + 4))); + ND_PRINT("\n\t vlan id (VID): %u", GET_BE_U_2(tptr + 4)); if (tlv_len < 7) { return hexdump; } - sublen = *(tptr+6); + sublen = GET_U_1(tptr + 6); if (tlv_len < 7+sublen) { return hexdump; } - ND_PRINT((ndo, "\n\t vlan name: ")); - safeputs(ndo, tptr + 7, sublen); + ND_PRINT("\n\t vlan name: "); + nd_printjnp(ndo, tptr + 7, sublen); break; case LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_IDENTITY: if (tlv_len < 5) { return hexdump; } - sublen = *(tptr+4); + sublen = GET_U_1(tptr + 4); if (tlv_len < 5+sublen) { return hexdump; } - ND_PRINT((ndo, "\n\t protocol identity: ")); - safeputs(ndo, tptr + 5, sublen); + ND_PRINT("\n\t protocol identity: "); + nd_printjnp(ndo, tptr + 5, sublen); break; + + case LLDP_PRIVATE_8021_SUBTYPE_LINKAGGR: + if (tlv_len < 9) { + return hexdump; + } + ND_PRINT("\n\t aggregation status [%s], aggregation port ID %u", + bittok2str(lldp_aggregation_values, "none", GET_U_1((tptr + 4))), + GET_BE_U_4(tptr + 5)); + break; + case LLDP_PRIVATE_8021_SUBTYPE_CONGESTION_NOTIFICATION: if(tlv_len> i) & 0x01)); - tval=*(tptr+5); - ND_PRINT((ndo, "\n\t Pre-Priority Ready Indicator")); - ND_PRINT((ndo, "\n\t Priority : 0 1 2 3 4 5 6 7")); - ND_PRINT((ndo, "\n\t Value : ")); + ND_PRINT("%-2d ", (tval >> i) & 0x01); + tval=GET_U_1(tptr + 5); + ND_PRINT("\n\t Pre-Priority Ready Indicator"); + ND_PRINT("\n\t Priority : 0 1 2 3 4 5 6 7"); + ND_PRINT("\n\t Value : "); for(i=0;i> i) & 0x01)); + ND_PRINT("%-2d ", (tval >> i) & 0x01); break; case LLDP_PRIVATE_8021_SUBTYPE_ETS_CONFIGURATION: if(tlv_len> 7, (tval >> 6) & 0x02, (tval >> 3) & 0x07, tval & 0x07)); + tval=GET_U_1(tptr + 4); + ND_PRINT("\n\t Willing:%u, CBS:%u, RES:%u, Max TCs:%u", + tval >> 7, (tval >> 6) & 0x02, (tval >> 3) & 0x07, tval & 0x07); /*Print Priority Assignment Table*/ print_ets_priority_assignment_table(ndo, tptr + 5); @@ -744,9 +763,9 @@ lldp_private_8021_print(netdissect_options *ndo, case LLDP_PRIVATE_8021_SUBTYPE_ETS_RECOMMENDATION: if(tlv_len> 7, (tval >> 6) & 0x01, (tval >> 4) & 0x03, (tval & 0x0f))); - ND_PRINT((ndo, "\n\t PFC Enable")); - tval=*(tptr+5); - ND_PRINT((ndo, "\n\t Priority : 0 1 2 3 4 5 6 7")); - ND_PRINT((ndo, "\n\t Value : ")); + tval=GET_U_1(tptr + 4); + ND_PRINT("\n\t Willing: %u, MBC: %u, RES: %u, PFC cap:%u ", + tval >> 7, (tval >> 6) & 0x01, (tval >> 4) & 0x03, (tval & 0x0f)); + ND_PRINT("\n\t PFC Enable"); + tval=GET_U_1(tptr + 5); + ND_PRINT("\n\t Priority : 0 1 2 3 4 5 6 7"); + ND_PRINT("\n\t Value : "); for(i=0;i> i) & 0x01)); + ND_PRINT("%-2d ", (tval >> i) & 0x01); break; case LLDP_PRIVATE_8021_SUBTYPE_APPLICATION_PRIORITY: if(tlv_len> 5, (tval >> 3) & 0x03, (tval & 0x07), - EXTRACT_16BITS(tptr + i + 5))); - i=i+3; + tval=GET_U_1(tptr + i + 5); + ND_PRINT("\n\t Priority: %u, RES: %u, Sel: %u, Protocol ID: %u", + tval >> 5, (tval >> 3) & 0x03, (tval & 0x07), + GET_BE_U_2(tptr + i + 6)); + i=i+3; } break; case LLDP_PRIVATE_8021_SUBTYPE_EVB: if(tlv_len> 3, (tval >> 2) & 0x01, (tval >> 1) & 0x01, tval & 0x01)); - ND_PRINT((ndo, "\n\t EVB Station Status")); - tval=*(tptr+5); - ND_PRINT((ndo, "\n\t RES: %d, SGID: %d, RRREQ: %d,RRSTAT: %d", - tval >> 4, (tval >> 3) & 0x01, (tval >> 2) & 0x01, tval & 0x03)); - tval=*(tptr+6); - ND_PRINT((ndo, "\n\t R: %d, RTE: %d, ",tval >> 5, tval & 0x1f)); - tval=*(tptr+7); - ND_PRINT((ndo, "EVB Mode: %s [%d]", - tok2str(lldp_evb_mode_values, "unknown", tval >> 6), tval >> 6)); - ND_PRINT((ndo, "\n\t ROL: %d, RWD: %d, ", (tval >> 5) & 0x01, tval & 0x1f)); - tval=*(tptr+8); - ND_PRINT((ndo, "RES: %d, ROL: %d, RKA: %d", tval >> 6, (tval >> 5) & 0x01, tval & 0x1f)); + ND_PRINT("\n\t EVB Bridge Status"); + tval=GET_U_1(tptr + 4); + ND_PRINT("\n\t RES: %u, BGID: %u, RRCAP: %u, RRCTR: %u", + tval >> 3, (tval >> 2) & 0x01, (tval >> 1) & 0x01, tval & 0x01); + ND_PRINT("\n\t EVB Station Status"); + tval=GET_U_1(tptr + 5); + ND_PRINT("\n\t RES: %u, SGID: %u, RRREQ: %u,RRSTAT: %u", + tval >> 4, (tval >> 3) & 0x01, (tval >> 2) & 0x01, tval & 0x03); + tval=GET_U_1(tptr + 6); + ND_PRINT("\n\t R: %u, RTE: %u, ",tval >> 5, tval & 0x1f); + tval=GET_U_1(tptr + 7); + ND_PRINT("EVB Mode: %s [%u]", + tok2str(lldp_evb_mode_values, "unknown", tval >> 6), tval >> 6); + ND_PRINT("\n\t ROL: %u, RWD: %u, ", (tval >> 5) & 0x01, tval & 0x1f); + tval=GET_U_1(tptr + 8); + ND_PRINT("RES: %u, ROL: %u, RKA: %u", tval >> 6, (tval >> 5) & 0x01, tval & 0x1f); break; case LLDP_PRIVATE_8021_SUBTYPE_CDCP: if(tlv_len> 7, (tval >> 4) & 0x07, (tval >> 3) & 0x01)); - ND_PRINT((ndo, "ChnCap: %d", EXTRACT_16BITS(tptr + 6) & 0x0fff)); + tval=GET_U_1(tptr + 4); + ND_PRINT("\n\t Role: %u, RES: %u, Scomp: %u ", + tval >> 7, (tval >> 4) & 0x07, (tval >> 3) & 0x01); + ND_PRINT("ChnCap: %u", GET_BE_U_2(tptr + 6) & 0x0fff); sublen=tlv_len-8; if(sublen%3!=0) { - return hexdump; + return hexdump; } i=0; while(i> 12, tval & 0x000fff)); - i=i+3; + tval=GET_BE_U_3(tptr + i + 8); + ND_PRINT("\n\t SCID: %u, SVID: %u", + tval >> 12, tval & 0x000fff); + i=i+3; } break; @@ -851,57 +870,58 @@ static int lldp_private_8023_print(netdissect_options *ndo, const u_char *tptr, u_int tlv_len) { - int subtype, hexdump = FALSE; + int hexdump = FALSE; + u_int subtype; if (tlv_len < 4) { return hexdump; } - subtype = *(tptr+3); + subtype = GET_U_1(tptr + 3); - ND_PRINT((ndo, "\n\t %s Subtype (%u)", + ND_PRINT("\n\t %s Subtype (%u)", tok2str(lldp_8023_subtype_values, "unknown", subtype), - subtype)); + subtype); switch (subtype) { case LLDP_PRIVATE_8023_SUBTYPE_MACPHY: if (tlv_len < 9) { return hexdump; } - ND_PRINT((ndo, "\n\t autonegotiation [%s] (0x%02x)", - bittok2str(lldp_8023_autonegotiation_values, "none", *(tptr+4)), - *(tptr + 4))); - ND_PRINT((ndo, "\n\t PMD autoneg capability [%s] (0x%04x)", - bittok2str(lldp_pmd_capability_values,"unknown", EXTRACT_16BITS(tptr+5)), - EXTRACT_16BITS(tptr + 5))); - ND_PRINT((ndo, "\n\t MAU type %s (0x%04x)", - tok2str(lldp_mau_types_values, "unknown", EXTRACT_16BITS(tptr+7)), - EXTRACT_16BITS(tptr + 7))); + ND_PRINT("\n\t autonegotiation [%s] (0x%02x)", + bittok2str(lldp_8023_autonegotiation_values, "none", GET_U_1(tptr + 4)), + GET_U_1(tptr + 4)); + ND_PRINT("\n\t PMD autoneg capability [%s] (0x%04x)", + bittok2str(lldp_pmd_capability_values,"unknown", GET_BE_U_2(tptr + 5)), + GET_BE_U_2(tptr + 5)); + ND_PRINT("\n\t MAU type %s (0x%04x)", + tok2str(lldp_mau_types_values, "unknown", GET_BE_U_2(tptr + 7)), + GET_BE_U_2(tptr + 7)); break; case LLDP_PRIVATE_8023_SUBTYPE_MDIPOWER: if (tlv_len < 7) { return hexdump; } - ND_PRINT((ndo, "\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)), - tok2str(lldp_mdi_power_class_values, "unknown", *(tptr + 6)))); + ND_PRINT("\n\t MDI power support [%s], power pair %s, power class %s", + bittok2str(lldp_mdi_values, "none", GET_U_1((tptr + 4))), + tok2str(lldp_mdi_power_pairs_values, "unknown", GET_U_1((tptr + 5))), + tok2str(lldp_mdi_power_class_values, "unknown", GET_U_1((tptr + 6)))); break; case LLDP_PRIVATE_8023_SUBTYPE_LINKAGGR: if (tlv_len < 9) { return hexdump; } - ND_PRINT((ndo, "\n\t aggregation status [%s], aggregation port ID %u", - bittok2str(lldp_aggregation_values, "none", *(tptr+4)), - EXTRACT_32BITS(tptr + 5))); + ND_PRINT("\n\t aggregation status [%s], aggregation port ID %u", + bittok2str(lldp_aggregation_values, "none", GET_U_1((tptr + 4))), + GET_BE_U_4(tptr + 5)); break; case LLDP_PRIVATE_8023_SUBTYPE_MTU: if (tlv_len < 6) { return hexdump; } - ND_PRINT((ndo, "\n\t MTU size %u", EXTRACT_16BITS(tptr + 4))); + ND_PRINT("\n\t MTU size %u", GET_BE_U_2(tptr + 4)); break; default: @@ -916,12 +936,12 @@ lldp_private_8023_print(netdissect_options *ndo, * Extract 34bits of latitude/longitude coordinates. */ static uint64_t -lldp_extract_latlon(const u_char *tptr) +lldp_extract_latlon(netdissect_options *ndo, const u_char *tptr) { uint64_t latlon; - latlon = *tptr & 0x3; - latlon = (latlon << 32) | EXTRACT_32BITS(tptr+1); + latlon = GET_U_1(tptr) & 0x3; + latlon = (latlon << 32) | GET_BE_U_4(tptr + 1); return latlon; } @@ -935,21 +955,22 @@ static int lldp_private_iana_print(netdissect_options *ndo, const u_char *tptr, u_int tlv_len) { - int subtype, hexdump = FALSE; + int hexdump = FALSE; + u_int subtype; if (tlv_len < 8) { return hexdump; } - subtype = *(tptr+3); + subtype = GET_U_1(tptr + 3); - ND_PRINT((ndo, "\n\t %s Subtype (%u)", + ND_PRINT("\n\t %s Subtype (%u)", tok2str(lldp_iana_subtype_values, "unknown", subtype), - subtype)); + subtype); switch (subtype) { case LLDP_IANA_SUBTYPE_MUDURL: - ND_PRINT((ndo, "\n\t MUD-URL=")); - (void)fn_printn(ndo, tptr+4, tlv_len-4, NULL); + ND_PRINT("\n\t MUD-URL="); + (void)nd_printn(ndo, tptr+4, tlv_len-4, NULL); break; default: hexdump=TRUE; @@ -967,7 +988,8 @@ static int lldp_private_tia_print(netdissect_options *ndo, const u_char *tptr, u_int tlv_len) { - int subtype, hexdump = FALSE; + int hexdump = FALSE; + u_int subtype; uint8_t location_format; uint16_t power_val; u_int lci_len; @@ -976,89 +998,91 @@ lldp_private_tia_print(netdissect_options *ndo, if (tlv_len < 4) { return hexdump; } - subtype = *(tptr+3); + subtype = GET_U_1(tptr + 3); - ND_PRINT((ndo, "\n\t %s Subtype (%u)", + ND_PRINT("\n\t %s Subtype (%u)", tok2str(lldp_tia_subtype_values, "unknown", subtype), - subtype)); + subtype); switch (subtype) { case LLDP_PRIVATE_TIA_SUBTYPE_CAPABILITIES: if (tlv_len < 7) { return hexdump; } - ND_PRINT((ndo, "\n\t Media capabilities [%s] (0x%04x)", + ND_PRINT("\n\t Media capabilities [%s] (0x%04x)", bittok2str(lldp_tia_capabilities_values, "none", - EXTRACT_16BITS(tptr + 4)), EXTRACT_16BITS(tptr + 4))); - ND_PRINT((ndo, "\n\t Device type [%s] (0x%02x)", - tok2str(lldp_tia_device_type_values, "unknown", *(tptr+6)), - *(tptr + 6))); + GET_BE_U_2(tptr + 4)), GET_BE_U_2(tptr + 4)); + ND_PRINT("\n\t Device type [%s] (0x%02x)", + tok2str(lldp_tia_device_type_values, "unknown", GET_U_1(tptr + 6)), + GET_U_1(tptr + 6)); break; case LLDP_PRIVATE_TIA_SUBTYPE_NETWORK_POLICY: if (tlv_len < 8) { return hexdump; } - ND_PRINT((ndo, "\n\t Application type [%s] (0x%02x)", - tok2str(lldp_tia_application_type_values, "none", *(tptr+4)), - *(tptr + 4))); - ND_PRINT((ndo, ", Flags [%s]", bittok2str( - lldp_tia_network_policy_bits_values, "none", *(tptr + 5)))); - ND_PRINT((ndo, "\n\t Vlan id %u", - LLDP_EXTRACT_NETWORK_POLICY_VLAN(EXTRACT_16BITS(tptr + 5)))); - ND_PRINT((ndo, ", L2 priority %u", - LLDP_EXTRACT_NETWORK_POLICY_L2_PRIORITY(EXTRACT_16BITS(tptr + 6)))); - ND_PRINT((ndo, ", DSCP value %u", - LLDP_EXTRACT_NETWORK_POLICY_DSCP(EXTRACT_16BITS(tptr + 6)))); + ND_PRINT("\n\t Application type [%s] (0x%02x)", + tok2str(lldp_tia_application_type_values, "none", GET_U_1(tptr + 4)), + GET_U_1(tptr + 4)); + ND_PRINT(", Flags [%s]", bittok2str( + lldp_tia_network_policy_bits_values, "none", GET_U_1((tptr + 5)))); + ND_PRINT("\n\t Vlan id %u", + LLDP_EXTRACT_NETWORK_POLICY_VLAN(GET_BE_U_2(tptr + 5))); + ND_PRINT(", L2 priority %u", + LLDP_EXTRACT_NETWORK_POLICY_L2_PRIORITY(GET_BE_U_2(tptr + 6))); + ND_PRINT(", DSCP value %u", + LLDP_EXTRACT_NETWORK_POLICY_DSCP(GET_BE_U_2(tptr + 6))); break; case LLDP_PRIVATE_TIA_SUBTYPE_LOCAL_ID: if (tlv_len < 5) { return hexdump; } - location_format = *(tptr+4); - ND_PRINT((ndo, "\n\t Location data format %s (0x%02x)", + location_format = GET_U_1(tptr + 4); + ND_PRINT("\n\t Location data format %s (0x%02x)", tok2str(lldp_tia_location_data_format_values, "unknown", location_format), - location_format)); + location_format); switch (location_format) { case LLDP_TIA_LOCATION_DATA_FORMAT_COORDINATE_BASED: if (tlv_len < 21) { return hexdump; } - ND_PRINT((ndo, "\n\t Latitude resolution %u, latitude value %" PRIu64, - (*(tptr + 5) >> 2), lldp_extract_latlon(tptr + 5))); - ND_PRINT((ndo, "\n\t Longitude resolution %u, longitude value %" PRIu64, - (*(tptr + 10) >> 2), lldp_extract_latlon(tptr + 10))); - ND_PRINT((ndo, "\n\t Altitude type %s (%u)", - tok2str(lldp_tia_location_altitude_type_values, "unknown",(*(tptr+15)>>4)), - (*(tptr + 15) >> 4))); - ND_PRINT((ndo, "\n\t Altitude resolution %u, altitude value 0x%x", - (EXTRACT_16BITS(tptr+15)>>6)&0x3f, - ((EXTRACT_32BITS(tptr + 16) & 0x3fffffff)))); - ND_PRINT((ndo, "\n\t Datum %s (0x%02x)", - tok2str(lldp_tia_location_datum_type_values, "unknown", *(tptr+20)), - *(tptr + 20))); + ND_PRINT("\n\t Latitude resolution %u, latitude value %" PRIu64, + (GET_U_1(tptr + 5) >> 2), + lldp_extract_latlon(ndo, tptr + 5)); + ND_PRINT("\n\t Longitude resolution %u, longitude value %" PRIu64, + (GET_U_1(tptr + 10) >> 2), + lldp_extract_latlon(ndo, tptr + 10)); + ND_PRINT("\n\t Altitude type %s (%u)", + tok2str(lldp_tia_location_altitude_type_values, "unknown",GET_U_1(tptr + 15) >> 4), + (GET_U_1(tptr + 15) >> 4)); + ND_PRINT("\n\t Altitude resolution %u, altitude value 0x%x", + (GET_BE_U_2(tptr + 15)>>6)&0x3f, + (GET_BE_U_4(tptr + 16) & 0x3fffffff)); + ND_PRINT("\n\t Datum %s (0x%02x)", + tok2str(lldp_tia_location_datum_type_values, "unknown", GET_U_1(tptr + 20)), + GET_U_1(tptr + 20)); break; case LLDP_TIA_LOCATION_DATA_FORMAT_CIVIC_ADDRESS: if (tlv_len < 6) { return hexdump; } - lci_len = *(tptr+5); + lci_len = GET_U_1(tptr + 5); if (lci_len < 3) { return hexdump; } if (tlv_len < 7+lci_len) { return hexdump; } - ND_PRINT((ndo, "\n\t LCI length %u, LCI what %s (0x%02x), Country-code ", + ND_PRINT("\n\t LCI length %u, LCI what %s (0x%02x), Country-code ", lci_len, - tok2str(lldp_tia_location_lci_what_values, "unknown", *(tptr+6)), - *(tptr + 6))); + tok2str(lldp_tia_location_lci_what_values, "unknown", GET_U_1(tptr + 6)), + GET_U_1(tptr + 6)); /* Country code */ - safeputs(ndo, tptr + 7, 2); + nd_printjnp(ndo, tptr + 7, 2); lci_len = lci_len-3; tptr = tptr + 9; @@ -1068,15 +1092,15 @@ lldp_private_tia_print(netdissect_options *ndo, if (lci_len < 2) { return hexdump; } - ca_type = *(tptr); - ca_len = *(tptr+1); + ca_type = GET_U_1(tptr); + ca_len = GET_U_1(tptr + 1); tptr += 2; lci_len -= 2; - ND_PRINT((ndo, "\n\t CA type \'%s\' (%u), length %u: ", + ND_PRINT("\n\t CA type \'%s\' (%u), length %u: ", tok2str(lldp_tia_location_lci_catype_values, "unknown", ca_type), - ca_type, ca_len)); + ca_type, ca_len); /* basic sanity check */ if ( ca_type == 0 || ca_len == 0) { @@ -1086,19 +1110,19 @@ lldp_private_tia_print(netdissect_options *ndo, return hexdump; } - safeputs(ndo, tptr, ca_len); + nd_printjnp(ndo, tptr, ca_len); tptr += ca_len; lci_len -= ca_len; } break; case LLDP_TIA_LOCATION_DATA_FORMAT_ECS_ELIN: - ND_PRINT((ndo, "\n\t ECS ELIN id ")); - safeputs(ndo, tptr + 5, tlv_len - 5); + ND_PRINT("\n\t ECS ELIN id "); + nd_printjnp(ndo, tptr + 5, tlv_len - 5); break; default: - ND_PRINT((ndo, "\n\t Location ID ")); + ND_PRINT("\n\t Location ID "); print_unknown_data(ndo, tptr + 5, "\n\t ", tlv_len - 5); } break; @@ -1107,18 +1131,18 @@ lldp_private_tia_print(netdissect_options *ndo, if (tlv_len < 7) { return hexdump; } - ND_PRINT((ndo, "\n\t Power type [%s]", - (*(tptr + 4) & 0xC0 >> 6) ? "PD device" : "PSE device")); - ND_PRINT((ndo, ", Power source [%s]", - tok2str(lldp_tia_power_source_values, "none", (*(tptr + 4) & 0x30) >> 4))); - ND_PRINT((ndo, "\n\t Power priority [%s] (0x%02x)", - tok2str(lldp_tia_power_priority_values, "none", *(tptr+4)&0x0f), - *(tptr + 4) & 0x0f)); - power_val = EXTRACT_16BITS(tptr+5); + ND_PRINT("\n\t Power type [%s]", + (GET_U_1(tptr + 4) & 0xC0 >> 6) ? "PD device" : "PSE device"); + ND_PRINT(", Power source [%s]", + tok2str(lldp_tia_power_source_values, "none", (GET_U_1((tptr + 4)) & 0x30) >> 4)); + ND_PRINT("\n\t Power priority [%s] (0x%02x)", + tok2str(lldp_tia_power_priority_values, "none", GET_U_1(tptr + 4) & 0x0f), + GET_U_1(tptr + 4) & 0x0f); + power_val = GET_BE_U_2(tptr + 5); if (power_val < LLDP_TIA_POWER_VAL_MAX) { - ND_PRINT((ndo, ", Power %.1f Watts", ((float)power_val) / 10)); + ND_PRINT(", Power %.1f Watts", ((float)power_val) / 10); } else { - ND_PRINT((ndo, ", Power %u (Reserved)", power_val)); + ND_PRINT(", Power %u (Reserved)", power_val); } break; @@ -1129,9 +1153,9 @@ lldp_private_tia_print(netdissect_options *ndo, case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME: case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME: case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID: - ND_PRINT((ndo, "\n\t %s ", - tok2str(lldp_tia_inventory_values, "unknown", subtype))); - safeputs(ndo, tptr + 4, tlv_len - 4); + ND_PRINT("\n\t %s ", + tok2str(lldp_tia_inventory_values, "unknown", subtype)); + nd_printjnp(ndo, tptr + 4, tlv_len - 4); break; default: @@ -1149,21 +1173,23 @@ static int lldp_private_dcbx_print(netdissect_options *ndo, const u_char *pptr, u_int len) { - int subtype, hexdump = FALSE; - uint8_t tval; + int hexdump = FALSE; + u_int subtype; + uint16_t tval; uint16_t tlv; uint32_t i, pgval, uval; - u_int tlen, tlv_type, tlv_len; + u_int tlen, tlv_type; + uint16_t tlv_len; const u_char *tptr, *mptr; if (len < 4) { return hexdump; } - subtype = *(pptr+3); + subtype = GET_U_1(pptr + 3); - ND_PRINT((ndo, "\n\t %s Subtype (%u)", + ND_PRINT("\n\t %s Subtype (%u)", tok2str(lldp_dcbx_subtype_values, "unknown", subtype), - subtype)); + subtype); /* by passing old version */ if (subtype == LLDP_DCBX_SUBTYPE_1) @@ -1174,9 +1200,9 @@ lldp_private_dcbx_print(netdissect_options *ndo, while (tlen >= sizeof(tlv)) { - ND_TCHECK2(*tptr, sizeof(tlv)); + ND_TCHECK_LEN(tptr, sizeof(tlv)); - tlv = EXTRACT_16BITS(tptr); + tlv = GET_BE_U_2(tptr); tlv_type = LLDP_EXTRACT_TYPE(tlv); tlv_len = LLDP_EXTRACT_LEN(tlv); @@ -1190,7 +1216,7 @@ lldp_private_dcbx_print(netdissect_options *ndo, break; } - ND_TCHECK2(*tptr, tlv_len); + ND_TCHECK_LEN(tptr, tlv_len); if (tlen < tlv_len) { goto trunc; } @@ -1201,92 +1227,94 @@ lldp_private_dcbx_print(netdissect_options *ndo, if (tlv_len < 10) { goto trunc; } - ND_PRINT((ndo, "\n\t Control - Protocol Control (type 0x%x, length %d)", - LLDP_DCBX_CONTROL_TLV, tlv_len)); - ND_PRINT((ndo, "\n\t Oper_Version: %d", *tptr)); - ND_PRINT((ndo, "\n\t Max_Version: %d", *(tptr + 1))); - ND_PRINT((ndo, "\n\t Sequence Number: %d", EXTRACT_32BITS(tptr + 2))); - ND_PRINT((ndo, "\n\t Acknowledgement Number: %d", - EXTRACT_32BITS(tptr + 6))); + ND_PRINT("\n\t Control - Protocol Control (type 0x%x, length %u)", + LLDP_DCBX_CONTROL_TLV, tlv_len); + ND_PRINT("\n\t Oper_Version: %u", GET_U_1(tptr)); + ND_PRINT("\n\t Max_Version: %u", GET_U_1(tptr + 1)); + ND_PRINT("\n\t Sequence Number: %u", GET_BE_U_4(tptr + 2)); + ND_PRINT("\n\t Acknowledgement Number: %u", + GET_BE_U_4(tptr + 6)); break; case LLDP_DCBX_PRIORITY_GROUPS_TLV: if (tlv_len < 17) { goto trunc; } - ND_PRINT((ndo, "\n\t Feature - Priority Group (type 0x%x, length %d)", - LLDP_DCBX_PRIORITY_GROUPS_TLV, tlv_len)); - ND_PRINT((ndo, "\n\t Oper_Version: %d", *tptr)); - ND_PRINT((ndo, "\n\t Max_Version: %d", *(tptr + 1))); - ND_PRINT((ndo, "\n\t Info block(0x%02X): ", *(tptr + 2))); - tval = *(tptr+2); - ND_PRINT((ndo, "Enable bit: %d, Willing bit: %d, Error Bit: %d", + ND_PRINT("\n\t Feature - Priority Group (type 0x%x, length %u)", + LLDP_DCBX_PRIORITY_GROUPS_TLV, tlv_len); + ND_PRINT("\n\t Oper_Version: %u", GET_U_1(tptr)); + ND_PRINT("\n\t Max_Version: %u", GET_U_1(tptr + 1)); + ND_PRINT("\n\t Info block(0x%02X): ", GET_U_1(tptr + 2)); + tval = GET_U_1(tptr + 2); + ND_PRINT("Enable bit: %u, Willing bit: %u, Error Bit: %u", (tval & 0x80) ? 1 : 0, (tval & 0x40) ? 1 : 0, - (tval & 0x20) ? 1 : 0)); - ND_PRINT((ndo, "\n\t SubType: %d", *(tptr + 3))); - ND_PRINT((ndo, "\n\t Priority Allocation")); + (tval & 0x20) ? 1 : 0); + ND_PRINT("\n\t SubType: %u", GET_U_1(tptr + 3)); + ND_PRINT("\n\t Priority Allocation"); /* * Array of 8 4-bit priority group ID values; we fetch all * 32 bits and extract each nibble. */ - pgval = EXTRACT_32BITS(tptr+4); + pgval = GET_BE_U_4(tptr + 4); for (i = 0; i <= 7; i++) { - ND_PRINT((ndo, "\n\t PgId_%d: %d", - i, (pgval >> (28 - 4 * i)) & 0xF)); + ND_PRINT("\n\t PgId_%u: %u", + i, (pgval >> (28 - 4 * i)) & 0xF); } - ND_PRINT((ndo, "\n\t Priority Group Allocation")); + ND_PRINT("\n\t Priority Group Allocation"); for (i = 0; i <= 7; i++) - ND_PRINT((ndo, "\n\t Pg percentage[%d]: %d", i, *(tptr + 8 + i))); - ND_PRINT((ndo, "\n\t NumTCsSupported: %d", *(tptr + 8 + 8))); + ND_PRINT("\n\t Pg percentage[%u]: %u", i, + GET_U_1(tptr + 8 + i)); + ND_PRINT("\n\t NumTCsSupported: %u", GET_U_1(tptr + 8 + 8)); break; case LLDP_DCBX_PRIORITY_FLOW_CONTROL_TLV: if (tlv_len < 6) { goto trunc; } - ND_PRINT((ndo, "\n\t Feature - Priority Flow Control")); - ND_PRINT((ndo, " (type 0x%x, length %d)", - LLDP_DCBX_PRIORITY_FLOW_CONTROL_TLV, tlv_len)); - ND_PRINT((ndo, "\n\t Oper_Version: %d", *tptr)); - ND_PRINT((ndo, "\n\t Max_Version: %d", *(tptr + 1))); - ND_PRINT((ndo, "\n\t Info block(0x%02X): ", *(tptr + 2))); - tval = *(tptr+2); - ND_PRINT((ndo, "Enable bit: %d, Willing bit: %d, Error Bit: %d", + ND_PRINT("\n\t Feature - Priority Flow Control"); + ND_PRINT(" (type 0x%x, length %u)", + LLDP_DCBX_PRIORITY_FLOW_CONTROL_TLV, tlv_len); + ND_PRINT("\n\t Oper_Version: %u", GET_U_1(tptr)); + ND_PRINT("\n\t Max_Version: %u", GET_U_1(tptr + 1)); + ND_PRINT("\n\t Info block(0x%02X): ", GET_U_1(tptr + 2)); + tval = GET_U_1(tptr + 2); + ND_PRINT("Enable bit: %u, Willing bit: %u, Error Bit: %u", (tval & 0x80) ? 1 : 0, (tval & 0x40) ? 1 : 0, - (tval & 0x20) ? 1 : 0)); - ND_PRINT((ndo, "\n\t SubType: %d", *(tptr + 3))); - tval = *(tptr+4); - ND_PRINT((ndo, "\n\t PFC Config (0x%02X)", *(tptr + 4))); + (tval & 0x20) ? 1 : 0); + ND_PRINT("\n\t SubType: %u", GET_U_1(tptr + 3)); + tval = GET_U_1(tptr + 4); + ND_PRINT("\n\t PFC Config (0x%02X)", GET_U_1(tptr + 4)); for (i = 0; i <= 7; i++) - ND_PRINT((ndo, "\n\t Priority Bit %d: %s", - i, (tval & (1 << i)) ? "Enabled" : "Disabled")); - ND_PRINT((ndo, "\n\t NumTCPFCSupported: %d", *(tptr + 5))); + ND_PRINT("\n\t Priority Bit %u: %s", + i, (tval & (1 << i)) ? "Enabled" : "Disabled"); + ND_PRINT("\n\t NumTCPFCSupported: %u", GET_U_1(tptr + 5)); break; case LLDP_DCBX_APPLICATION_TLV: if (tlv_len < 4) { goto trunc; } - ND_PRINT((ndo, "\n\t Feature - Application (type 0x%x, length %d)", - LLDP_DCBX_APPLICATION_TLV, tlv_len)); - ND_PRINT((ndo, "\n\t Oper_Version: %d", *tptr)); - ND_PRINT((ndo, "\n\t Max_Version: %d", *(tptr + 1))); - ND_PRINT((ndo, "\n\t Info block(0x%02X): ", *(tptr + 2))); - tval = *(tptr+2); - ND_PRINT((ndo, "Enable bit: %d, Willing bit: %d, Error Bit: %d", + ND_PRINT("\n\t Feature - Application (type 0x%x, length %u)", + LLDP_DCBX_APPLICATION_TLV, tlv_len); + ND_PRINT("\n\t Oper_Version: %u", GET_U_1(tptr)); + ND_PRINT("\n\t Max_Version: %u", GET_U_1(tptr + 1)); + ND_PRINT("\n\t Info block(0x%02X): ", GET_U_1(tptr + 2)); + tval = GET_U_1(tptr + 2); + ND_PRINT("Enable bit: %u, Willing bit: %u, Error Bit: %u", (tval & 0x80) ? 1 : 0, (tval & 0x40) ? 1 : 0, - (tval & 0x20) ? 1 : 0)); - ND_PRINT((ndo, "\n\t SubType: %d", *(tptr + 3))); + (tval & 0x20) ? 1 : 0); + ND_PRINT("\n\t SubType: %u", GET_U_1(tptr + 3)); tval = tlv_len - 4; mptr = tptr + 4; while (tval >= 6) { - ND_PRINT((ndo, "\n\t Application Value")); - ND_PRINT((ndo, "\n\t Application Protocol ID: 0x%04x", - EXTRACT_16BITS(mptr))); - uval = EXTRACT_24BITS(mptr+2); - ND_PRINT((ndo, "\n\t SF (0x%x) Application Protocol ID is %s", + ND_PRINT("\n\t Application Value"); + ND_PRINT("\n\t Application Protocol ID: 0x%04x", + GET_BE_U_2(mptr)); + uval = GET_BE_U_3(mptr + 2); + ND_PRINT("\n\t SF (0x%x) Application Protocol ID is %s", (uval >> 22), - (uval >> 22) ? "Socket Number" : "L2 EtherType")); - ND_PRINT((ndo, "\n\t OUI: 0x%06x", uval & 0x3fffff)); - ND_PRINT((ndo, "\n\t User Priority Map: 0x%02x", *(mptr + 5))); + (uval >> 22) ? "Socket Number" : "L2 EtherType"); + ND_PRINT("\n\t OUI: 0x%06x", uval & 0x3fffff); + ND_PRINT("\n\t User Priority Map: 0x%02x", + GET_U_1(mptr + 5)); tval = tval - 6; mptr = mptr + 6; } @@ -1319,22 +1347,20 @@ lldp_network_addr_print(netdissect_options *ndo, const u_char *tptr, u_int len) if (len < 1) return NULL; len--; - af = *tptr; + af = GET_U_1(tptr); switch (af) { case AFNUM_INET: - if (len < 4) + if (len < sizeof(nd_ipv4)) return NULL; - /* This cannot be assigned to ipaddr_string(), which is a macro. */ - pfunc = getname; + pfunc = ipaddr_string; break; case AFNUM_INET6: - if (len < 16) + if (len < sizeof(nd_ipv6)) return NULL; - /* This cannot be assigned to ip6addr_string(), which is a macro. */ - pfunc = getname6; + pfunc = ip6addr_string; break; case AFNUM_802: - if (len < 6) + if (len < MAC_ADDR_LEN) return NULL; pfunc = etheraddr_string; break; @@ -1369,7 +1395,8 @@ lldp_mgmt_addr_tlv_print(netdissect_options *ndo, if (tlen < 1) { return 0; } - mgmt_addr_len = *tptr++; + mgmt_addr_len = GET_U_1(tptr); + tptr++; tlen--; if (tlen < mgmt_addr_len) { @@ -1380,8 +1407,8 @@ lldp_mgmt_addr_tlv_print(netdissect_options *ndo, if (mgmt_addr == NULL) { return 0; } - ND_PRINT((ndo, "\n\t Management Address length %u, %s", - mgmt_addr_len, mgmt_addr)); + ND_PRINT("\n\t Management Address length %u, %s", + mgmt_addr_len, mgmt_addr); tptr += mgmt_addr_len; tlen -= mgmt_addr_len; @@ -1389,11 +1416,11 @@ lldp_mgmt_addr_tlv_print(netdissect_options *ndo, return 0; } - intf_num_subtype = *tptr; - ND_PRINT((ndo, "\n\t %s Interface Numbering (%u): %u", + intf_num_subtype = GET_U_1(tptr); + ND_PRINT("\n\t %s Interface Numbering (%u): %u", tok2str(lldp_intf_numb_subtype_values, "Unknown", intf_num_subtype), intf_num_subtype, - EXTRACT_32BITS(tptr + 1))); + GET_BE_U_4(tptr + 1)); tptr += LLDP_INTF_NUM_LEN; tlen -= LLDP_INTF_NUM_LEN; @@ -1402,14 +1429,14 @@ lldp_mgmt_addr_tlv_print(netdissect_options *ndo, * The OID is optional. */ if (tlen) { - oid_len = *tptr; + oid_len = GET_U_1(tptr); if (tlen < 1U + oid_len) { return 0; } if (oid_len) { - ND_PRINT((ndo, "\n\t OID length %u", oid_len)); - safeputs(ndo, tptr + 1, oid_len); + ND_PRINT("\n\t OID length %u", oid_len); + nd_printjnp(ndo, tptr + 1, oid_len); } } @@ -1418,7 +1445,7 @@ lldp_mgmt_addr_tlv_print(netdissect_options *ndo, void lldp_print(netdissect_options *ndo, - register const u_char *pptr, register u_int len) + const u_char *pptr, u_int len) { uint8_t subtype; uint16_t tlv, cap, ena_cap; @@ -1426,16 +1453,17 @@ lldp_print(netdissect_options *ndo, const u_char *tptr; char *network_addr; + ndo->ndo_protocol = "lldp"; tptr = pptr; tlen = len; - ND_PRINT((ndo, "LLDP, length %u", len)); + ND_PRINT("LLDP, length %u", len); while (tlen >= sizeof(tlv)) { - ND_TCHECK2(*tptr, sizeof(tlv)); + ND_TCHECK_LEN(tptr, sizeof(tlv)); - tlv = EXTRACT_16BITS(tptr); + tlv = GET_BE_U_2(tptr); tlv_type = LLDP_EXTRACT_TYPE(tlv); tlv_len = LLDP_EXTRACT_LEN(tlv); @@ -1445,9 +1473,9 @@ lldp_print(netdissect_options *ndo, tptr += sizeof(tlv); if (ndo->ndo_vflag) { - ND_PRINT((ndo, "\n\t%s TLV (%u), length %u", + ND_PRINT("\n\t%s TLV (%u), length %u", tok2str(lldp_tlv_values, "Unknown", tlv_type), - tlv_type, tlv_len)); + tlv_type, tlv_len); } /* infinite loop check */ @@ -1455,7 +1483,7 @@ lldp_print(netdissect_options *ndo, break; } - ND_TCHECK2(*tptr, tlv_len); + ND_TCHECK_LEN(tptr, tlv_len); if (tlen < tlv_len) { goto trunc; } @@ -1467,17 +1495,17 @@ lldp_print(netdissect_options *ndo, if (tlv_len < 2) { goto trunc; } - subtype = *tptr; - ND_PRINT((ndo, "\n\t Subtype %s (%u): ", + subtype = GET_U_1(tptr); + ND_PRINT("\n\t Subtype %s (%u): ", tok2str(lldp_chassis_subtype_values, "Unknown", subtype), - subtype)); + subtype); switch (subtype) { case LLDP_CHASSIS_MAC_ADDR_SUBTYPE: if (tlv_len < 1+6) { goto trunc; } - ND_PRINT((ndo, "%s", etheraddr_string(ndo, tptr + 1))); + ND_PRINT("%s", GET_ETHERADDR_STRING(tptr + 1)); break; case LLDP_CHASSIS_INTF_NAME_SUBTYPE: /* fall through */ @@ -1485,7 +1513,7 @@ lldp_print(netdissect_options *ndo, case LLDP_CHASSIS_CHASSIS_COMP_SUBTYPE: case LLDP_CHASSIS_INTF_ALIAS_SUBTYPE: case LLDP_CHASSIS_PORT_COMP_SUBTYPE: - safeputs(ndo, tptr + 1, tlv_len - 1); + nd_printjnp(ndo, tptr + 1, tlv_len - 1); break; case LLDP_CHASSIS_NETWORK_ADDR_SUBTYPE: @@ -1493,7 +1521,7 @@ lldp_print(netdissect_options *ndo, if (network_addr == NULL) { goto trunc; } - ND_PRINT((ndo, "%s", network_addr)); + ND_PRINT("%s", network_addr); break; default: @@ -1508,17 +1536,17 @@ lldp_print(netdissect_options *ndo, if (tlv_len < 2) { goto trunc; } - subtype = *tptr; - ND_PRINT((ndo, "\n\t Subtype %s (%u): ", + subtype = GET_U_1(tptr); + ND_PRINT("\n\t Subtype %s (%u): ", tok2str(lldp_port_subtype_values, "Unknown", subtype), - subtype)); + subtype); switch (subtype) { case LLDP_PORT_MAC_ADDR_SUBTYPE: if (tlv_len < 1+6) { goto trunc; } - ND_PRINT((ndo, "%s", etheraddr_string(ndo, tptr + 1))); + ND_PRINT("%s", GET_ETHERADDR_STRING(tptr + 1)); break; case LLDP_PORT_INTF_NAME_SUBTYPE: /* fall through */ @@ -1526,7 +1554,7 @@ lldp_print(netdissect_options *ndo, case LLDP_PORT_AGENT_CIRC_ID_SUBTYPE: case LLDP_PORT_INTF_ALIAS_SUBTYPE: case LLDP_PORT_PORT_COMP_SUBTYPE: - safeputs(ndo, tptr + 1, tlv_len - 1); + nd_printjnp(ndo, tptr + 1, tlv_len - 1); break; case LLDP_PORT_NETWORK_ADDR_SUBTYPE: @@ -1534,7 +1562,7 @@ lldp_print(netdissect_options *ndo, if (network_addr == NULL) { goto trunc; } - ND_PRINT((ndo, "%s", network_addr)); + ND_PRINT("%s", network_addr); break; default: @@ -1549,14 +1577,14 @@ lldp_print(netdissect_options *ndo, if (tlv_len < 2) { goto trunc; } - ND_PRINT((ndo, ": TTL %us", EXTRACT_16BITS(tptr))); + ND_PRINT(": TTL %us", GET_BE_U_2(tptr)); } break; case LLDP_PORT_DESCR_TLV: if (ndo->ndo_vflag) { - ND_PRINT((ndo, ": ")); - safeputs(ndo, tptr, tlv_len); + ND_PRINT(": "); + nd_printjnp(ndo, tptr, tlv_len); } break; @@ -1565,14 +1593,14 @@ lldp_print(netdissect_options *ndo, * The system name is also print in non-verbose mode * similar to the CDP printer. */ - ND_PRINT((ndo, ": ")); - safeputs(ndo, tptr, tlv_len); + ND_PRINT(": "); + nd_printjnp(ndo, tptr, tlv_len); break; case LLDP_SYSTEM_DESCR_TLV: if (ndo->ndo_vflag) { - ND_PRINT((ndo, "\n\t ")); - safeputs(ndo, tptr, tlv_len); + ND_PRINT("\n\t "); + nd_printjnp(ndo, tptr, tlv_len); } break; @@ -1587,12 +1615,12 @@ lldp_print(netdissect_options *ndo, if (tlv_len < 4) { goto trunc; } - cap = EXTRACT_16BITS(tptr); - ena_cap = EXTRACT_16BITS(tptr+2); - ND_PRINT((ndo, "\n\t System Capabilities [%s] (0x%04x)", - bittok2str(lldp_cap_values, "none", cap), cap)); - ND_PRINT((ndo, "\n\t Enabled Capabilities [%s] (0x%04x)", - bittok2str(lldp_cap_values, "none", ena_cap), ena_cap)); + cap = GET_BE_U_2(tptr); + ena_cap = GET_BE_U_2(tptr + 2); + ND_PRINT("\n\t System Capabilities [%s] (0x%04x)", + bittok2str(lldp_cap_values, "none", cap), cap); + ND_PRINT("\n\t Enabled Capabilities [%s] (0x%04x)", + bittok2str(lldp_cap_values, "none", ena_cap), ena_cap); } break; @@ -1609,8 +1637,8 @@ lldp_print(netdissect_options *ndo, if (tlv_len < 3) { goto trunc; } - oui = EXTRACT_24BITS(tptr); - ND_PRINT((ndo, ": OUI %s (0x%06x)", tok2str(oui_values, "Unknown", oui), oui)); + oui = GET_BE_U_3(tptr); + ND_PRINT(": OUI %s (0x%06x)", tok2str(oui_values, "Unknown", oui), oui); switch (oui) { case OUI_IEEE_8021_PRIVATE: @@ -1650,12 +1678,5 @@ lldp_print(netdissect_options *ndo, } return; trunc: - ND_PRINT((ndo, "\n\t[|LLDP]")); + nd_print_trunc(ndo); } - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 4 - * End: - */ diff --git a/contrib/tcpdump/print-lmp.c b/contrib/tcpdump/print-lmp.c index e836101178..925f3b07f3 100644 --- a/contrib/tcpdump/print-lmp.c +++ b/contrib/tcpdump/print-lmp.c @@ -18,20 +18,20 @@ /* \summary: Link Management Protocol (LMP) printer */ /* specification: RFC 4204 */ -/* OIF UNI 1.0: http://www.oiforum.com/public/documents/OIF-UNI-01.0.pdf */ +/* OIF UNI 1.0: https://web.archive.org/web/20160401194747/http://www.oiforum.com/public/documents/OIF-UNI-01.0.pdf */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" #include "addrtoname.h" #include "gmpls.h" -static const char tstr[] = " [|LMP]"; /* * LMP common header @@ -46,15 +46,15 @@ static const char tstr[] = " [|LMP]"; */ struct lmp_common_header { - uint8_t version_res[2]; - uint8_t flags; - uint8_t msg_type; - uint8_t length[2]; - uint8_t reserved[2]; + nd_uint16_t version_res; + nd_uint8_t flags; + nd_uint8_t msg_type; + nd_uint16_t length; + nd_byte reserved[2]; }; #define LMP_VERSION 1 -#define LMP_EXTRACT_VERSION(x) (((x)&0xf0)>>4) +#define LMP_EXTRACT_VERSION(x) (((x)&0xf000)>>12) static const struct tok lmp_header_flag_values[] = { { 0x01, "Control Channel Down"}, @@ -216,9 +216,9 @@ static const struct tok lmp_msg_type_values[] = { */ struct lmp_object_header { - uint8_t ctype; - uint8_t class_num; - uint8_t length[2]; + nd_uint8_t ctype; + nd_uint8_t class_num; + nd_uint16_t length; }; #define LMP_OBJ_CC_ID 1 @@ -369,54 +369,48 @@ lmp_print_data_link_subobjs(netdissect_options *ndo, const u_char *obj_tptr, } bw; while (total_subobj_len > 0 && hexdump == FALSE ) { - ND_TCHECK_16BITS(obj_tptr + offset); - subobj_type = EXTRACT_8BITS(obj_tptr + offset); - subobj_len = EXTRACT_8BITS(obj_tptr + offset + 1); - ND_PRINT((ndo, "\n\t Subobject, Type: %s (%u), Length: %u", + subobj_type = GET_U_1(obj_tptr + offset); + subobj_len = GET_U_1(obj_tptr + offset + 1); + ND_PRINT("\n\t Subobject, Type: %s (%u), Length: %u", tok2str(lmp_data_link_subobj, "Unknown", subobj_type), subobj_type, - subobj_len)); + subobj_len); if (subobj_len < 4) { - ND_PRINT((ndo, " (too short)")); + ND_PRINT(" (too short)"); break; } if ((subobj_len % 4) != 0) { - ND_PRINT((ndo, " (not a multiple of 4)")); + ND_PRINT(" (not a multiple of 4)"); break; } if (total_subobj_len < subobj_len) { - ND_PRINT((ndo, " (goes past the end of the object)")); + ND_PRINT(" (goes past the end of the object)"); break; } switch(subobj_type) { case INT_SWITCHING_TYPE_SUBOBJ: - ND_TCHECK_8BITS(obj_tptr + offset + 2); - ND_PRINT((ndo, "\n\t Switching Type: %s (%u)", + ND_PRINT("\n\t Switching Type: %s (%u)", tok2str(gmpls_switch_cap_values, "Unknown", - EXTRACT_8BITS(obj_tptr + offset + 2)), - EXTRACT_8BITS(obj_tptr + offset + 2))); - ND_TCHECK_8BITS(obj_tptr + offset + 3); - ND_PRINT((ndo, "\n\t Encoding Type: %s (%u)", + GET_U_1(obj_tptr + offset + 2)), + GET_U_1(obj_tptr + offset + 2)); + ND_PRINT("\n\t Encoding Type: %s (%u)", tok2str(gmpls_encoding_values, "Unknown", - EXTRACT_8BITS(obj_tptr + offset + 3)), - EXTRACT_8BITS(obj_tptr + offset + 3))); - ND_TCHECK_32BITS(obj_tptr + offset + 4); - bw.i = EXTRACT_32BITS(obj_tptr+offset+4); - ND_PRINT((ndo, "\n\t Min Reservable Bandwidth: %.3f Mbps", - bw.f*8/1000000)); - ND_TCHECK_32BITS(obj_tptr + offset + 8); - bw.i = EXTRACT_32BITS(obj_tptr+offset+8); - ND_PRINT((ndo, "\n\t Max Reservable Bandwidth: %.3f Mbps", - bw.f*8/1000000)); + GET_U_1(obj_tptr + offset + 3)), + GET_U_1(obj_tptr + offset + 3)); + bw.i = GET_BE_U_4(obj_tptr + offset + 4); + ND_PRINT("\n\t Min Reservable Bandwidth: %.3f Mbps", + bw.f*8/1000000); + bw.i = GET_BE_U_4(obj_tptr + offset + 8); + ND_PRINT("\n\t Max Reservable Bandwidth: %.3f Mbps", + bw.f*8/1000000); break; case WAVELENGTH_SUBOBJ: - ND_TCHECK_32BITS(obj_tptr + offset + 4); - ND_PRINT((ndo, "\n\t Wavelength: %u", - EXTRACT_32BITS(obj_tptr+offset+4))); + ND_PRINT("\n\t Wavelength: %u", + GET_BE_U_4(obj_tptr + offset + 4)); break; default: /* Any Unknown Subobject ==> Exit loop */ @@ -427,19 +421,16 @@ lmp_print_data_link_subobjs(netdissect_options *ndo, const u_char *obj_tptr, offset+=subobj_len; } return (hexdump); -trunc: - return -1; } void lmp_print(netdissect_options *ndo, - register const u_char *pptr, register u_int len) + const u_char *pptr, u_int length) { const struct lmp_common_header *lmp_com_header; - const struct lmp_object_header *lmp_obj_header; const u_char *tptr,*obj_tptr; - u_int tlen,lmp_obj_len,lmp_obj_ctype,obj_tlen; - int hexdump, ret; + u_int version_res, tlen, lmp_obj_len, lmp_obj_ctype, obj_tlen; + int hexdump; u_int offset; u_int link_type; @@ -448,75 +439,76 @@ lmp_print(netdissect_options *ndo, uint32_t i; } bw; + ndo->ndo_protocol = "lmp"; tptr=pptr; lmp_com_header = (const struct lmp_common_header *)pptr; - ND_TCHECK(*lmp_com_header); + ND_TCHECK_SIZE(lmp_com_header); + + version_res = GET_BE_U_2(lmp_com_header->version_res); /* * Sanity checking of the header. */ - if (LMP_EXTRACT_VERSION(lmp_com_header->version_res[0]) != LMP_VERSION) { - ND_PRINT((ndo, "LMP version %u packet not supported", - LMP_EXTRACT_VERSION(lmp_com_header->version_res[0]))); + if (LMP_EXTRACT_VERSION(version_res) != LMP_VERSION) { + ND_PRINT("LMP version %u packet not supported", + LMP_EXTRACT_VERSION(version_res)); return; } /* in non-verbose mode just lets print the basic Message Type*/ if (ndo->ndo_vflag < 1) { - ND_PRINT((ndo, "LMPv%u %s Message, length: %u", - LMP_EXTRACT_VERSION(lmp_com_header->version_res[0]), - tok2str(lmp_msg_type_values, "unknown (%u)",lmp_com_header->msg_type), - len)); + ND_PRINT("LMPv%u %s Message, length: %u", + LMP_EXTRACT_VERSION(version_res), + tok2str(lmp_msg_type_values, "unknown (%u)",GET_U_1(lmp_com_header->msg_type)), + length); return; } /* ok they seem to want to know everything - lets fully decode it */ - tlen=EXTRACT_16BITS(lmp_com_header->length); + tlen=GET_BE_U_2(lmp_com_header->length); - ND_PRINT((ndo, "\n\tLMPv%u, msg-type: %s, Flags: [%s], length: %u", - LMP_EXTRACT_VERSION(lmp_com_header->version_res[0]), - tok2str(lmp_msg_type_values, "unknown, type: %u",lmp_com_header->msg_type), - bittok2str(lmp_header_flag_values,"none",lmp_com_header->flags), - tlen)); - if (tlen < sizeof(const struct lmp_common_header)) { - ND_PRINT((ndo, " (too short)")); + ND_PRINT("\n\tLMPv%u, msg-type: %s, Flags: [%s], length: %u", + LMP_EXTRACT_VERSION(version_res), + tok2str(lmp_msg_type_values, "unknown, type: %u",GET_U_1(lmp_com_header->msg_type)), + bittok2str(lmp_header_flag_values,"none",GET_U_1(lmp_com_header->flags)), + tlen); + if (tlen < sizeof(struct lmp_common_header)) { + ND_PRINT(" (too short)"); return; } - if (tlen > len) { - ND_PRINT((ndo, " (too long)")); - tlen = len; + if (tlen > length) { + ND_PRINT(" (too long)"); + tlen = length; } - tptr+=sizeof(const struct lmp_common_header); - tlen-=sizeof(const struct lmp_common_header); + tptr+=sizeof(struct lmp_common_header); + tlen-=sizeof(struct lmp_common_header); while(tlen>0) { - /* did we capture enough for fully decoding the object header ? */ - ND_TCHECK2(*tptr, sizeof(struct lmp_object_header)); - - lmp_obj_header = (const struct lmp_object_header *)tptr; - lmp_obj_len=EXTRACT_16BITS(lmp_obj_header->length); - lmp_obj_ctype=(lmp_obj_header->ctype)&0x7f; + const struct lmp_object_header *lmp_obj_header = + (const struct lmp_object_header *)tptr; + lmp_obj_len=GET_BE_U_2(lmp_obj_header->length); + lmp_obj_ctype=GET_U_1(lmp_obj_header->ctype)&0x7f; - ND_PRINT((ndo, "\n\t %s Object (%u), Class-Type: %s (%u) Flags: [%snegotiable], length: %u", + ND_PRINT("\n\t %s Object (%u), Class-Type: %s (%u) Flags: [%snegotiable], length: %u", tok2str(lmp_obj_values, "Unknown", - lmp_obj_header->class_num), - lmp_obj_header->class_num, + GET_U_1(lmp_obj_header->class_num)), + GET_U_1(lmp_obj_header->class_num), tok2str(lmp_ctype_values, "Unknown", - ((lmp_obj_header->class_num)<<8)+lmp_obj_ctype), + (GET_U_1(lmp_obj_header->class_num)<<8)+lmp_obj_ctype), lmp_obj_ctype, - (lmp_obj_header->ctype)&0x80 ? "" : "non-", - lmp_obj_len)); + GET_U_1(lmp_obj_header->ctype)&0x80 ? "" : "non-", + lmp_obj_len); if (lmp_obj_len < 4) { - ND_PRINT((ndo, " (too short)")); + ND_PRINT(" (too short)"); return; } if ((lmp_obj_len % 4) != 0) { - ND_PRINT((ndo, " (not a multiple of 4)")); + ND_PRINT(" (not a multiple of 4)"); return; } @@ -524,22 +516,22 @@ lmp_print(netdissect_options *ndo, obj_tlen=lmp_obj_len-sizeof(struct lmp_object_header); /* did we capture enough for fully decoding the object ? */ - ND_TCHECK2(*tptr, lmp_obj_len); + ND_TCHECK_LEN(tptr, lmp_obj_len); hexdump=FALSE; - switch(lmp_obj_header->class_num) { + switch(GET_U_1(lmp_obj_header->class_num)) { case LMP_OBJ_CC_ID: switch(lmp_obj_ctype) { case LMP_CTYPE_LOC: case LMP_CTYPE_RMT: if (obj_tlen != 4) { - ND_PRINT((ndo, " (not correct for object)")); + ND_PRINT(" (not correct for object)"); break; } - ND_PRINT((ndo, "\n\t Control Channel ID: %u (0x%08x)", - EXTRACT_32BITS(obj_tptr), - EXTRACT_32BITS(obj_tptr))); + ND_PRINT("\n\t Control Channel ID: %u (0x%08x)", + GET_BE_U_4(obj_tptr), + GET_BE_U_4(obj_tptr)); break; default: @@ -553,32 +545,32 @@ lmp_print(netdissect_options *ndo, case LMP_CTYPE_IPV4_LOC: case LMP_CTYPE_IPV4_RMT: if (obj_tlen != 4) { - ND_PRINT((ndo, " (not correct for object)")); + ND_PRINT(" (not correct for object)"); break; } - ND_PRINT((ndo, "\n\t IPv4 Link ID: %s (0x%08x)", - ipaddr_string(ndo, obj_tptr), - EXTRACT_32BITS(obj_tptr))); + ND_PRINT("\n\t IPv4 Link ID: %s (0x%08x)", + GET_IPADDR_STRING(obj_tptr), + GET_BE_U_4(obj_tptr)); break; case LMP_CTYPE_IPV6_LOC: case LMP_CTYPE_IPV6_RMT: if (obj_tlen != 16) { - ND_PRINT((ndo, " (not correct for object)")); + ND_PRINT(" (not correct for object)"); break; } - ND_PRINT((ndo, "\n\t IPv6 Link ID: %s (0x%08x)", - ip6addr_string(ndo, obj_tptr), - EXTRACT_32BITS(obj_tptr))); + ND_PRINT("\n\t IPv6 Link ID: %s (0x%08x)", + GET_IP6ADDR_STRING(obj_tptr), + GET_BE_U_4(obj_tptr)); break; case LMP_CTYPE_UNMD_LOC: case LMP_CTYPE_UNMD_RMT: if (obj_tlen != 4) { - ND_PRINT((ndo, " (not correct for object)")); + ND_PRINT(" (not correct for object)"); break; } - ND_PRINT((ndo, "\n\t Link ID: %u (0x%08x)", - EXTRACT_32BITS(obj_tptr), - EXTRACT_32BITS(obj_tptr))); + ND_PRINT("\n\t Link ID: %u (0x%08x)", + GET_BE_U_4(obj_tptr), + GET_BE_U_4(obj_tptr)); break; default: hexdump=TRUE; @@ -589,21 +581,21 @@ lmp_print(netdissect_options *ndo, switch(lmp_obj_ctype) { case LMP_CTYPE_1: if (obj_tlen != 4) { - ND_PRINT((ndo, " (not correct for object)")); + ND_PRINT(" (not correct for object)"); break; } - ND_PRINT((ndo, "\n\t Message ID: %u (0x%08x)", - EXTRACT_32BITS(obj_tptr), - EXTRACT_32BITS(obj_tptr))); + ND_PRINT("\n\t Message ID: %u (0x%08x)", + GET_BE_U_4(obj_tptr), + GET_BE_U_4(obj_tptr)); break; case LMP_CTYPE_2: if (obj_tlen != 4) { - ND_PRINT((ndo, " (not correct for object)")); + ND_PRINT(" (not correct for object)"); break; } - ND_PRINT((ndo, "\n\t Message ID Ack: %u (0x%08x)", - EXTRACT_32BITS(obj_tptr), - EXTRACT_32BITS(obj_tptr))); + ND_PRINT("\n\t Message ID Ack: %u (0x%08x)", + GET_BE_U_4(obj_tptr), + GET_BE_U_4(obj_tptr)); break; default: hexdump=TRUE; @@ -615,12 +607,12 @@ lmp_print(netdissect_options *ndo, case LMP_CTYPE_LOC: case LMP_CTYPE_RMT: if (obj_tlen != 4) { - ND_PRINT((ndo, " (not correct for object)")); + ND_PRINT(" (not correct for object)"); break; } - ND_PRINT((ndo, "\n\t Node ID: %s (0x%08x)", - ipaddr_string(ndo, obj_tptr), - EXTRACT_32BITS(obj_tptr))); + ND_PRINT("\n\t Node ID: %s (0x%08x)", + GET_IPADDR_STRING(obj_tptr), + GET_BE_U_4(obj_tptr)); break; default: @@ -632,12 +624,12 @@ lmp_print(netdissect_options *ndo, switch(lmp_obj_ctype) { case LMP_CTYPE_HELLO_CONFIG: if (obj_tlen != 4) { - ND_PRINT((ndo, " (not correct for object)")); + ND_PRINT(" (not correct for object)"); break; } - ND_PRINT((ndo, "\n\t Hello Interval: %u\n\t Hello Dead Interval: %u", - EXTRACT_16BITS(obj_tptr), - EXTRACT_16BITS(obj_tptr+2))); + ND_PRINT("\n\t Hello Interval: %u\n\t Hello Dead Interval: %u", + GET_BE_U_2(obj_tptr), + GET_BE_U_2(obj_tptr + 2)); break; default: @@ -649,12 +641,12 @@ lmp_print(netdissect_options *ndo, switch(lmp_obj_ctype) { case LMP_CTYPE_HELLO: if (obj_tlen != 8) { - ND_PRINT((ndo, " (not correct for object)")); + ND_PRINT(" (not correct for object)"); break; } - ND_PRINT((ndo, "\n\t Tx Seq: %u, Rx Seq: %u", - EXTRACT_32BITS(obj_tptr), - EXTRACT_32BITS(obj_tptr+4))); + ND_PRINT("\n\t Tx Seq: %u, Rx Seq: %u", + GET_BE_U_4(obj_tptr), + GET_BE_U_4(obj_tptr + 4)); break; default: @@ -666,56 +658,56 @@ lmp_print(netdissect_options *ndo, switch(lmp_obj_ctype) { case LMP_CTYPE_IPV4: if (obj_tlen != 12) { - ND_PRINT((ndo, " (not correct for object)")); + ND_PRINT(" (not correct for object)"); break; } - ND_PRINT((ndo, "\n\t Flags: [%s]", + ND_PRINT("\n\t Flags: [%s]", bittok2str(lmp_obj_te_link_flag_values, "none", - EXTRACT_8BITS(obj_tptr)))); + GET_U_1(obj_tptr))); - ND_PRINT((ndo, "\n\t Local Link-ID: %s (0x%08x)" + ND_PRINT("\n\t Local Link-ID: %s (0x%08x)" "\n\t Remote Link-ID: %s (0x%08x)", - ipaddr_string(ndo, obj_tptr+4), - EXTRACT_32BITS(obj_tptr+4), - ipaddr_string(ndo, obj_tptr+8), - EXTRACT_32BITS(obj_tptr+8))); + GET_IPADDR_STRING(obj_tptr+4), + GET_BE_U_4(obj_tptr + 4), + GET_IPADDR_STRING(obj_tptr+8), + GET_BE_U_4(obj_tptr + 8)); break; case LMP_CTYPE_IPV6: if (obj_tlen != 36) { - ND_PRINT((ndo, " (not correct for object)")); + ND_PRINT(" (not correct for object)"); break; } - ND_PRINT((ndo, "\n\t Flags: [%s]", + ND_PRINT("\n\t Flags: [%s]", bittok2str(lmp_obj_te_link_flag_values, "none", - EXTRACT_8BITS(obj_tptr)))); + GET_U_1(obj_tptr))); - ND_PRINT((ndo, "\n\t Local Link-ID: %s (0x%08x)" + ND_PRINT("\n\t Local Link-ID: %s (0x%08x)" "\n\t Remote Link-ID: %s (0x%08x)", - ip6addr_string(ndo, obj_tptr+4), - EXTRACT_32BITS(obj_tptr+4), - ip6addr_string(ndo, obj_tptr+20), - EXTRACT_32BITS(obj_tptr+20))); + GET_IP6ADDR_STRING(obj_tptr+4), + GET_BE_U_4(obj_tptr + 4), + GET_IP6ADDR_STRING(obj_tptr+20), + GET_BE_U_4(obj_tptr + 20)); break; case LMP_CTYPE_UNMD: if (obj_tlen != 12) { - ND_PRINT((ndo, " (not correct for object)")); + ND_PRINT(" (not correct for object)"); break; } - ND_PRINT((ndo, "\n\t Flags: [%s]", + ND_PRINT("\n\t Flags: [%s]", bittok2str(lmp_obj_te_link_flag_values, "none", - EXTRACT_8BITS(obj_tptr)))); + GET_U_1(obj_tptr))); - ND_PRINT((ndo, "\n\t Local Link-ID: %u (0x%08x)" + ND_PRINT("\n\t Local Link-ID: %u (0x%08x)" "\n\t Remote Link-ID: %u (0x%08x)", - EXTRACT_32BITS(obj_tptr+4), - EXTRACT_32BITS(obj_tptr+4), - EXTRACT_32BITS(obj_tptr+8), - EXTRACT_32BITS(obj_tptr+8))); + GET_BE_U_4(obj_tptr + 4), + GET_BE_U_4(obj_tptr + 4), + GET_BE_U_4(obj_tptr + 8), + GET_BE_U_4(obj_tptr + 8)); break; default: @@ -727,70 +719,61 @@ lmp_print(netdissect_options *ndo, switch(lmp_obj_ctype) { case LMP_CTYPE_IPV4: if (obj_tlen < 12) { - ND_PRINT((ndo, " (not correct for object)")); + ND_PRINT(" (not correct for object)"); break; } - ND_PRINT((ndo, "\n\t Flags: [%s]", + ND_PRINT("\n\t Flags: [%s]", bittok2str(lmp_obj_data_link_flag_values, "none", - EXTRACT_8BITS(obj_tptr)))); - ND_PRINT((ndo, "\n\t Local Interface ID: %s (0x%08x)" + GET_U_1(obj_tptr))); + ND_PRINT("\n\t Local Interface ID: %s (0x%08x)" "\n\t Remote Interface ID: %s (0x%08x)", - ipaddr_string(ndo, obj_tptr+4), - EXTRACT_32BITS(obj_tptr+4), - ipaddr_string(ndo, obj_tptr+8), - EXTRACT_32BITS(obj_tptr+8))); - - ret = lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 12, 12); - if (ret == -1) - goto trunc; - if (ret == TRUE) + GET_IPADDR_STRING(obj_tptr+4), + GET_BE_U_4(obj_tptr + 4), + GET_IPADDR_STRING(obj_tptr+8), + GET_BE_U_4(obj_tptr + 8)); + + if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 12, 12)) hexdump=TRUE; break; case LMP_CTYPE_IPV6: if (obj_tlen < 36) { - ND_PRINT((ndo, " (not correct for object)")); + ND_PRINT(" (not correct for object)"); break; } - ND_PRINT((ndo, "\n\t Flags: [%s]", + ND_PRINT("\n\t Flags: [%s]", bittok2str(lmp_obj_data_link_flag_values, "none", - EXTRACT_8BITS(obj_tptr)))); - ND_PRINT((ndo, "\n\t Local Interface ID: %s (0x%08x)" + GET_U_1(obj_tptr))); + ND_PRINT("\n\t Local Interface ID: %s (0x%08x)" "\n\t Remote Interface ID: %s (0x%08x)", - ip6addr_string(ndo, obj_tptr+4), - EXTRACT_32BITS(obj_tptr+4), - ip6addr_string(ndo, obj_tptr+20), - EXTRACT_32BITS(obj_tptr+20))); - - ret = lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 36, 36); - if (ret == -1) - goto trunc; - if (ret == TRUE) + GET_IP6ADDR_STRING(obj_tptr+4), + GET_BE_U_4(obj_tptr + 4), + GET_IP6ADDR_STRING(obj_tptr+20), + GET_BE_U_4(obj_tptr + 20)); + + if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 36, 36)) hexdump=TRUE; break; case LMP_CTYPE_UNMD: if (obj_tlen < 12) { - ND_PRINT((ndo, " (not correct for object)")); + ND_PRINT(" (not correct for object)"); break; } - ND_PRINT((ndo, "\n\t Flags: [%s]", + ND_PRINT("\n\t Flags: [%s]", bittok2str(lmp_obj_data_link_flag_values, "none", - EXTRACT_8BITS(obj_tptr)))); - ND_PRINT((ndo, "\n\t Local Interface ID: %u (0x%08x)" + GET_U_1(obj_tptr))); + ND_PRINT("\n\t Local Interface ID: %u (0x%08x)" "\n\t Remote Interface ID: %u (0x%08x)", - EXTRACT_32BITS(obj_tptr+4), - EXTRACT_32BITS(obj_tptr+4), - EXTRACT_32BITS(obj_tptr+8), - EXTRACT_32BITS(obj_tptr+8))); - - ret = lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 12, 12); - if (ret == -1) - goto trunc; - if (ret == TRUE) + GET_BE_U_4(obj_tptr + 4), + GET_BE_U_4(obj_tptr + 4), + GET_BE_U_4(obj_tptr + 8), + GET_BE_U_4(obj_tptr + 8)); + + if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 12, 12)) hexdump=TRUE; break; @@ -803,27 +786,27 @@ lmp_print(netdissect_options *ndo, switch(lmp_obj_ctype) { case LMP_CTYPE_1: if (obj_tlen != 20) { - ND_PRINT((ndo, " (not correct for object)")); + ND_PRINT(" (not correct for object)"); break; } - ND_PRINT((ndo, "\n\t Flags: %s", + ND_PRINT("\n\t Flags: %s", bittok2str(lmp_obj_begin_verify_flag_values, "none", - EXTRACT_16BITS(obj_tptr)))); - ND_PRINT((ndo, "\n\t Verify Interval: %u", - EXTRACT_16BITS(obj_tptr+2))); - ND_PRINT((ndo, "\n\t Data links: %u", - EXTRACT_32BITS(obj_tptr+4))); - ND_PRINT((ndo, "\n\t Encoding type: %s", - tok2str(gmpls_encoding_values, "Unknown", *(obj_tptr+8)))); - ND_PRINT((ndo, "\n\t Verify Transport Mechanism: %u (0x%x)%s", - EXTRACT_16BITS(obj_tptr+10), - EXTRACT_16BITS(obj_tptr+10), - EXTRACT_16BITS(obj_tptr+10)&8000 ? " (Payload test messages capable)" : "")); - bw.i = EXTRACT_32BITS(obj_tptr+12); - ND_PRINT((ndo, "\n\t Transmission Rate: %.3f Mbps",bw.f*8/1000000)); - ND_PRINT((ndo, "\n\t Wavelength: %u", - EXTRACT_32BITS(obj_tptr+16))); + GET_BE_U_2(obj_tptr))); + ND_PRINT("\n\t Verify Interval: %u", + GET_BE_U_2(obj_tptr + 2)); + ND_PRINT("\n\t Data links: %u", + GET_BE_U_4(obj_tptr + 4)); + ND_PRINT("\n\t Encoding type: %s", + tok2str(gmpls_encoding_values, "Unknown", GET_U_1((obj_tptr + 8)))); + ND_PRINT("\n\t Verify Transport Mechanism: %u (0x%x)%s", + GET_BE_U_2(obj_tptr + 10), + GET_BE_U_2(obj_tptr + 10), + GET_BE_U_2(obj_tptr + 10)&8000 ? " (Payload test messages capable)" : ""); + bw.i = GET_BE_U_4(obj_tptr + 12); + ND_PRINT("\n\t Transmission Rate: %.3f Mbps",bw.f*8/1000000); + ND_PRINT("\n\t Wavelength: %u", + GET_BE_U_4(obj_tptr + 16)); break; default: @@ -835,13 +818,13 @@ lmp_print(netdissect_options *ndo, switch(lmp_obj_ctype) { case LMP_CTYPE_1: if (obj_tlen != 4) { - ND_PRINT((ndo, " (not correct for object)")); + ND_PRINT(" (not correct for object)"); break; } - ND_PRINT((ndo, "\n\t Verify Dead Interval: %u" + ND_PRINT("\n\t Verify Dead Interval: %u" "\n\t Verify Transport Response: %u", - EXTRACT_16BITS(obj_tptr), - EXTRACT_16BITS(obj_tptr+2))); + GET_BE_U_2(obj_tptr), + GET_BE_U_2(obj_tptr + 2)); break; default: @@ -853,11 +836,11 @@ lmp_print(netdissect_options *ndo, switch(lmp_obj_ctype) { case LMP_CTYPE_1: if (obj_tlen != 4) { - ND_PRINT((ndo, " (not correct for object)")); + ND_PRINT(" (not correct for object)"); break; } - ND_PRINT((ndo, "\n\t Verify ID: %u", - EXTRACT_32BITS(obj_tptr))); + ND_PRINT("\n\t Verify ID: %u", + GET_BE_U_4(obj_tptr)); break; default: @@ -871,25 +854,25 @@ lmp_print(netdissect_options *ndo, offset = 0; /* Decode pairs: */ while (offset+8 <= obj_tlen) { - ND_PRINT((ndo, "\n\t Interface ID: %s (0x%08x)", - ipaddr_string(ndo, obj_tptr+offset), - EXTRACT_32BITS(obj_tptr+offset))); + ND_PRINT("\n\t Interface ID: %s (0x%08x)", + GET_IPADDR_STRING(obj_tptr+offset), + GET_BE_U_4(obj_tptr + offset)); - ND_PRINT((ndo, "\n\t\t Active: %s (%u)", - (EXTRACT_32BITS(obj_tptr+offset+4)>>31) ? - "Allocated" : "Non-allocated", - (EXTRACT_32BITS(obj_tptr+offset+4)>>31))); + ND_PRINT("\n\t\t Active: %s (%u)", + (GET_BE_U_4(obj_tptr + offset + 4)>>31) ? + "Allocated" : "Non-allocated", + (GET_BE_U_4(obj_tptr + offset + 4)>>31)); - ND_PRINT((ndo, "\n\t\t Direction: %s (%u)", - (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1 ? - "Transmit" : "Receive", - (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1)); + ND_PRINT("\n\t\t Direction: %s (%u)", + (GET_BE_U_4(obj_tptr + offset + 4)>>30)&0x1 ? + "Transmit" : "Receive", + (GET_BE_U_4(obj_tptr + offset + 4)>>30)&0x1); - ND_PRINT((ndo, "\n\t\t Channel Status: %s (%u)", + ND_PRINT("\n\t\t Channel Status: %s (%u)", tok2str(lmp_obj_channel_status_values, - "Unknown", - EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF), - EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF)); + "Unknown", + GET_BE_U_4(obj_tptr + offset + 4)&0x3FFFFFF), + GET_BE_U_4(obj_tptr + offset + 4)&0x3FFFFFF); offset+=8; } break; @@ -898,25 +881,25 @@ lmp_print(netdissect_options *ndo, offset = 0; /* Decode pairs: */ while (offset+20 <= obj_tlen) { - ND_PRINT((ndo, "\n\t Interface ID: %s (0x%08x)", - ip6addr_string(ndo, obj_tptr+offset), - EXTRACT_32BITS(obj_tptr+offset))); + ND_PRINT("\n\t Interface ID: %s (0x%08x)", + GET_IP6ADDR_STRING(obj_tptr+offset), + GET_BE_U_4(obj_tptr + offset)); - ND_PRINT((ndo, "\n\t\t Active: %s (%u)", - (EXTRACT_32BITS(obj_tptr+offset+16)>>31) ? - "Allocated" : "Non-allocated", - (EXTRACT_32BITS(obj_tptr+offset+16)>>31))); + ND_PRINT("\n\t\t Active: %s (%u)", + (GET_BE_U_4(obj_tptr + offset + 16)>>31) ? + "Allocated" : "Non-allocated", + (GET_BE_U_4(obj_tptr + offset + 16)>>31)); - ND_PRINT((ndo, "\n\t\t Direction: %s (%u)", - (EXTRACT_32BITS(obj_tptr+offset+16)>>30)&0x1 ? - "Transmit" : "Receive", - (EXTRACT_32BITS(obj_tptr+offset+16)>>30)&0x1)); + ND_PRINT("\n\t\t Direction: %s (%u)", + (GET_BE_U_4(obj_tptr + offset + 16)>>30)&0x1 ? + "Transmit" : "Receive", + (GET_BE_U_4(obj_tptr + offset + 16)>>30)&0x1); - ND_PRINT((ndo, "\n\t\t Channel Status: %s (%u)", + ND_PRINT("\n\t\t Channel Status: %s (%u)", tok2str(lmp_obj_channel_status_values, "Unknown", - EXTRACT_32BITS(obj_tptr+offset+16)&0x3FFFFFF), - EXTRACT_32BITS(obj_tptr+offset+16)&0x3FFFFFF)); + GET_BE_U_4(obj_tptr + offset + 16)&0x3FFFFFF), + GET_BE_U_4(obj_tptr + offset + 16)&0x3FFFFFF); offset+=20; } break; @@ -925,25 +908,25 @@ lmp_print(netdissect_options *ndo, offset = 0; /* Decode pairs: */ while (offset+8 <= obj_tlen) { - ND_PRINT((ndo, "\n\t Interface ID: %u (0x%08x)", - EXTRACT_32BITS(obj_tptr+offset), - EXTRACT_32BITS(obj_tptr+offset))); + ND_PRINT("\n\t Interface ID: %u (0x%08x)", + GET_BE_U_4(obj_tptr + offset), + GET_BE_U_4(obj_tptr + offset)); - ND_PRINT((ndo, "\n\t\t Active: %s (%u)", - (EXTRACT_32BITS(obj_tptr+offset+4)>>31) ? - "Allocated" : "Non-allocated", - (EXTRACT_32BITS(obj_tptr+offset+4)>>31))); + ND_PRINT("\n\t\t Active: %s (%u)", + (GET_BE_U_4(obj_tptr + offset + 4)>>31) ? + "Allocated" : "Non-allocated", + (GET_BE_U_4(obj_tptr + offset + 4)>>31)); - ND_PRINT((ndo, "\n\t\t Direction: %s (%u)", - (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1 ? - "Transmit" : "Receive", - (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1)); + ND_PRINT("\n\t\t Direction: %s (%u)", + (GET_BE_U_4(obj_tptr + offset + 4)>>30)&0x1 ? + "Transmit" : "Receive", + (GET_BE_U_4(obj_tptr + offset + 4)>>30)&0x1); - ND_PRINT((ndo, "\n\t\t Channel Status: %s (%u)", + ND_PRINT("\n\t\t Channel Status: %s (%u)", tok2str(lmp_obj_channel_status_values, "Unknown", - EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF), - EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF)); + GET_BE_U_4(obj_tptr + offset + 4)&0x3FFFFFF), + GET_BE_U_4(obj_tptr + offset + 4)&0x3FFFFFF); offset+=8; } break; @@ -958,9 +941,9 @@ lmp_print(netdissect_options *ndo, case LMP_CTYPE_IPV4: offset = 0; while (offset+4 <= obj_tlen) { - ND_PRINT((ndo, "\n\t Interface ID: %s (0x%08x)", - ipaddr_string(ndo, obj_tptr+offset), - EXTRACT_32BITS(obj_tptr+offset))); + ND_PRINT("\n\t Interface ID: %s (0x%08x)", + GET_IPADDR_STRING(obj_tptr+offset), + GET_BE_U_4(obj_tptr + offset)); offset+=4; } break; @@ -968,9 +951,9 @@ lmp_print(netdissect_options *ndo, case LMP_CTYPE_IPV6: offset = 0; while (offset+16 <= obj_tlen) { - ND_PRINT((ndo, "\n\t Interface ID: %s (0x%08x)", - ip6addr_string(ndo, obj_tptr+offset), - EXTRACT_32BITS(obj_tptr+offset))); + ND_PRINT("\n\t Interface ID: %s (0x%08x)", + GET_IP6ADDR_STRING(obj_tptr+offset), + GET_BE_U_4(obj_tptr + offset)); offset+=16; } break; @@ -978,9 +961,9 @@ lmp_print(netdissect_options *ndo, case LMP_CTYPE_UNMD: offset = 0; while (offset+4 <= obj_tlen) { - ND_PRINT((ndo, "\n\t Interface ID: %u (0x%08x)", - EXTRACT_32BITS(obj_tptr+offset), - EXTRACT_32BITS(obj_tptr+offset))); + ND_PRINT("\n\t Interface ID: %u (0x%08x)", + GET_BE_U_4(obj_tptr + offset), + GET_BE_U_4(obj_tptr + offset)); offset+=4; } break; @@ -994,24 +977,24 @@ lmp_print(netdissect_options *ndo, switch(lmp_obj_ctype) { case LMP_CTYPE_BEGIN_VERIFY_ERROR: if (obj_tlen != 4) { - ND_PRINT((ndo, " (not correct for object)")); + ND_PRINT(" (not correct for object)"); break; } - ND_PRINT((ndo, "\n\t Error Code: %s", + ND_PRINT("\n\t Error Code: %s", bittok2str(lmp_obj_begin_verify_error_values, "none", - EXTRACT_32BITS(obj_tptr)))); + GET_BE_U_4(obj_tptr))); break; case LMP_CTYPE_LINK_SUMMARY_ERROR: if (obj_tlen != 4) { - ND_PRINT((ndo, " (not correct for object)")); + ND_PRINT(" (not correct for object)"); break; } - ND_PRINT((ndo, "\n\t Error Code: %s", + ND_PRINT("\n\t Error Code: %s", bittok2str(lmp_obj_link_summary_error_values, "none", - EXTRACT_32BITS(obj_tptr)))); + GET_BE_U_4(obj_tptr))); break; default: hexdump=TRUE; @@ -1022,109 +1005,109 @@ lmp_print(netdissect_options *ndo, switch (lmp_obj_ctype) { case LMP_CTYPE_SERVICE_CONFIG_SP: if (obj_tlen != 4) { - ND_PRINT((ndo, " (not correct for object)")); + ND_PRINT(" (not correct for object)"); break; } - ND_PRINT((ndo, "\n\t Flags: %s", + ND_PRINT("\n\t Flags: %s", bittok2str(lmp_obj_service_config_sp_flag_values, "none", - EXTRACT_8BITS(obj_tptr)))); + GET_U_1(obj_tptr))); - ND_PRINT((ndo, "\n\t UNI Version: %u", - EXTRACT_8BITS(obj_tptr + 1))); + ND_PRINT("\n\t UNI Version: %u", + GET_U_1(obj_tptr + 1)); break; case LMP_CTYPE_SERVICE_CONFIG_CPSA: if (obj_tlen != 16) { - ND_PRINT((ndo, " (not correct for object)")); + ND_PRINT(" (not correct for object)"); break; } - link_type = EXTRACT_8BITS(obj_tptr); + link_type = GET_U_1(obj_tptr); - ND_PRINT((ndo, "\n\t Link Type: %s (%u)", + ND_PRINT("\n\t Link Type: %s (%u)", tok2str(lmp_sd_service_config_cpsa_link_type_values, "Unknown", link_type), - link_type)); + link_type); switch (link_type) { case LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SDH: - ND_PRINT((ndo, "\n\t Signal Type: %s (%u)", + ND_PRINT("\n\t Signal Type: %s (%u)", tok2str(lmp_sd_service_config_cpsa_signal_type_sdh_values, "Unknown", - EXTRACT_8BITS(obj_tptr + 1)), - EXTRACT_8BITS(obj_tptr + 1))); + GET_U_1(obj_tptr + 1)), + GET_U_1(obj_tptr + 1)); break; case LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SONET: - ND_PRINT((ndo, "\n\t Signal Type: %s (%u)", + ND_PRINT("\n\t Signal Type: %s (%u)", tok2str(lmp_sd_service_config_cpsa_signal_type_sonet_values, "Unknown", - EXTRACT_8BITS(obj_tptr + 1)), - EXTRACT_8BITS(obj_tptr + 1))); + GET_U_1(obj_tptr + 1)), + GET_U_1(obj_tptr + 1)); break; } - ND_PRINT((ndo, "\n\t Transparency: %s", + ND_PRINT("\n\t Transparency: %s", bittok2str(lmp_obj_service_config_cpsa_tp_flag_values, "none", - EXTRACT_8BITS(obj_tptr + 2)))); + GET_U_1(obj_tptr + 2))); - ND_PRINT((ndo, "\n\t Contiguous Concatenation Types: %s", + ND_PRINT("\n\t Contiguous Concatenation Types: %s", bittok2str(lmp_obj_service_config_cpsa_cct_flag_values, "none", - EXTRACT_8BITS(obj_tptr + 3)))); + GET_U_1(obj_tptr + 3))); - ND_PRINT((ndo, "\n\t Minimum NCC: %u", - EXTRACT_16BITS(obj_tptr+4))); + ND_PRINT("\n\t Minimum NCC: %u", + GET_BE_U_2(obj_tptr + 4)); - ND_PRINT((ndo, "\n\t Maximum NCC: %u", - EXTRACT_16BITS(obj_tptr+6))); + ND_PRINT("\n\t Maximum NCC: %u", + GET_BE_U_2(obj_tptr + 6)); - ND_PRINT((ndo, "\n\t Minimum NVC:%u", - EXTRACT_16BITS(obj_tptr+8))); + ND_PRINT("\n\t Minimum NVC:%u", + GET_BE_U_2(obj_tptr + 8)); - ND_PRINT((ndo, "\n\t Maximum NVC:%u", - EXTRACT_16BITS(obj_tptr+10))); + ND_PRINT("\n\t Maximum NVC:%u", + GET_BE_U_2(obj_tptr + 10)); - ND_PRINT((ndo, "\n\t Local Interface ID: %s (0x%08x)", - ipaddr_string(ndo, obj_tptr+12), - EXTRACT_32BITS(obj_tptr+12))); + ND_PRINT("\n\t Local Interface ID: %s (0x%08x)", + GET_IPADDR_STRING(obj_tptr+12), + GET_BE_U_4(obj_tptr + 12)); break; case LMP_CTYPE_SERVICE_CONFIG_TRANSPARENCY_TCM: if (obj_tlen != 8) { - ND_PRINT((ndo, " (not correct for object)")); + ND_PRINT(" (not correct for object)"); break; } - ND_PRINT((ndo, "\n\t Transparency Flags: %s", + ND_PRINT("\n\t Transparency Flags: %s", bittok2str( lmp_obj_service_config_nsa_transparency_flag_values, "none", - EXTRACT_32BITS(obj_tptr)))); + GET_BE_U_4(obj_tptr))); - ND_PRINT((ndo, "\n\t TCM Monitoring Flags: %s", + ND_PRINT("\n\t TCM Monitoring Flags: %s", bittok2str( lmp_obj_service_config_nsa_tcm_flag_values, "none", - EXTRACT_8BITS(obj_tptr + 7)))); + GET_U_1(obj_tptr + 7))); break; case LMP_CTYPE_SERVICE_CONFIG_NETWORK_DIVERSITY: if (obj_tlen != 4) { - ND_PRINT((ndo, " (not correct for object)")); + ND_PRINT(" (not correct for object)"); break; } - ND_PRINT((ndo, "\n\t Diversity: Flags: %s", + ND_PRINT("\n\t Diversity: Flags: %s", bittok2str( lmp_obj_service_config_nsa_network_diversity_flag_values, "none", - EXTRACT_8BITS(obj_tptr + 3)))); + GET_U_1(obj_tptr + 3))); break; default: @@ -1143,16 +1126,12 @@ lmp_print(netdissect_options *ndo, print_unknown_data(ndo,tptr+sizeof(struct lmp_object_header),"\n\t ", lmp_obj_len-sizeof(struct lmp_object_header)); + if (tlen < lmp_obj_len) { + ND_PRINT(" [remaining objects length %u < %u]", tlen, lmp_obj_len); + nd_print_invalid(ndo); + break; + } tptr+=lmp_obj_len; tlen-=lmp_obj_len; } - return; -trunc: - ND_PRINT((ndo, "%s", tstr)); } -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/print-loopback.c b/contrib/tcpdump/print-loopback.c index 10f69310c5..ee0caf3cfe 100644 --- a/contrib/tcpdump/print-loopback.c +++ b/contrib/tcpdump/print-loopback.c @@ -29,21 +29,20 @@ /* * originally defined as the Ethernet Configuration Testing Protocol. - * specification: http://www.mit.edu/people/jhawk/ctp.pdf + * specification: https://www.mit.edu/people/jhawk/ctp.pdf */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" -#include "ether.h" #include "addrtoname.h" -static const char tstr[] = " [|loopback]"; #define LOOPBACK_REPLY 1 #define LOOPBACK_FWDDATA 2 @@ -55,82 +54,82 @@ static const struct tok fcode_str[] = { }; static void -loopback_message_print(netdissect_options *ndo, const u_char *cp, const u_int len) +loopback_message_print(netdissect_options *ndo, + const u_char *cp, u_int len) { - const u_char *ep = cp + len; uint16_t function; if (len < 2) goto invalid; /* function */ - ND_TCHECK2(*cp, 2); - function = EXTRACT_LE_16BITS(cp); + function = GET_LE_U_2(cp); cp += 2; - ND_PRINT((ndo, ", %s", tok2str(fcode_str, " invalid (%u)", function))); + len -= 2; + ND_PRINT(", %s", tok2str(fcode_str, " invalid (%u)", function)); switch (function) { case LOOPBACK_REPLY: - if (len < 4) + if (len < 2) goto invalid; /* receipt number */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, ", receipt number %u", EXTRACT_LE_16BITS(cp))); + ND_PRINT(", receipt number %u", GET_LE_U_2(cp)); cp += 2; + len -= 2; /* data */ - ND_PRINT((ndo, ", data (%u octets)", len - 4)); - ND_TCHECK2(*cp, len - 4); + ND_PRINT(", data (%u octets)", len); + ND_TCHECK_LEN(cp, len); break; case LOOPBACK_FWDDATA: - if (len < 8) + if (len < MAC_ADDR_LEN) goto invalid; /* forwarding address */ - ND_TCHECK2(*cp, ETHER_ADDR_LEN); - ND_PRINT((ndo, ", forwarding address %s", etheraddr_string(ndo, cp))); - cp += ETHER_ADDR_LEN; + ND_PRINT(", forwarding address %s", GET_ETHERADDR_STRING(cp)); + cp += MAC_ADDR_LEN; + len -= MAC_ADDR_LEN; /* data */ - ND_PRINT((ndo, ", data (%u octets)", len - 8)); - ND_TCHECK2(*cp, len - 8); + ND_PRINT(", data (%u octets)", len); + ND_TCHECK_LEN(cp, len); break; default: - ND_TCHECK2(*cp, len - 2); + ND_TCHECK_LEN(cp, len); break; } return; invalid: - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp, ep - cp); - return; -trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } void -loopback_print(netdissect_options *ndo, const u_char *cp, const u_int len) +loopback_print(netdissect_options *ndo, + const u_char *cp, u_int len) { - const u_char *ep = cp + len; uint16_t skipCount; - ND_PRINT((ndo, "Loopback")); + ndo->ndo_protocol = "loopback"; + ND_PRINT("Loopback"); if (len < 2) goto invalid; /* skipCount */ - ND_TCHECK2(*cp, 2); - skipCount = EXTRACT_LE_16BITS(cp); + skipCount = GET_LE_U_2(cp); cp += 2; - ND_PRINT((ndo, ", skipCount %u", skipCount)); + len -= 2; + ND_PRINT(", skipCount %u", skipCount); if (skipCount % 8) - ND_PRINT((ndo, " (bogus)")); - if (skipCount > len - 2) + ND_PRINT(" (bogus)"); + if (skipCount > len) goto invalid; - loopback_message_print(ndo, cp + skipCount, len - 2 - skipCount); + /* the octets to skip */ + ND_TCHECK_LEN(cp, skipCount); + cp += skipCount; + len -= skipCount; + /* the first message to decode */ + loopback_message_print(ndo, cp, len); return; invalid: - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp, ep - cp); - return; -trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } diff --git a/contrib/tcpdump/print-lspping.c b/contrib/tcpdump/print-lspping.c index 274cc68b76..4c5fc4e8cc 100644 --- a/contrib/tcpdump/print-lspping.c +++ b/contrib/tcpdump/print-lspping.c @@ -15,20 +15,23 @@ /* \summary: MPLS LSP PING printer */ +/* specification: RFC 4379 */ + #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" #include "addrtoname.h" +#include "ntp.h" #include "l2vpn.h" #include "oui.h" -/* RFC 4349 */ /* * LSPPING common header @@ -59,18 +62,16 @@ */ struct lspping_common_header { - uint8_t version[2]; - uint8_t global_flags[2]; - uint8_t msg_type; - uint8_t reply_mode; - uint8_t return_code; - uint8_t return_subcode; - uint8_t sender_handle[4]; - uint8_t seq_number[4]; - uint8_t ts_sent_sec[4]; - uint8_t ts_sent_usec[4]; - uint8_t ts_rcvd_sec[4]; - uint8_t ts_rcvd_usec[4]; + nd_uint16_t version; + nd_uint16_t global_flags; + nd_uint8_t msg_type; + nd_uint8_t reply_mode; + nd_uint8_t return_code; + nd_uint8_t return_subcode; + nd_uint32_t sender_handle; + nd_uint32_t seq_number; + struct l_fixedpt ts_sent; + struct l_fixedpt ts_rcvd; }; #define LSPPING_VERSION 1 @@ -124,8 +125,8 @@ static const struct tok lspping_return_code_values[] = { */ struct lspping_tlv_header { - uint8_t type[2]; - uint8_t length[2]; + nd_uint16_t type; + nd_uint16_t length; }; #define LSPPING_TLV_TARGET_FEC_STACK 1 @@ -199,8 +200,8 @@ static const struct tok lspping_tlvtargetfec_subtlv_values[] = { * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t { - uint8_t prefix [4]; - uint8_t prefix_len; + nd_ipv4 prefix; + nd_uint8_t prefix_len; }; /* @@ -216,8 +217,8 @@ struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t { * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t { - uint8_t prefix [16]; - uint8_t prefix_len; + nd_ipv6 prefix; + nd_uint8_t prefix_len; }; /* @@ -236,13 +237,13 @@ struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t { * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t { - uint8_t tunnel_endpoint [4]; - uint8_t res[2]; - uint8_t tunnel_id[2]; - uint8_t extended_tunnel_id[4]; - uint8_t tunnel_sender [4]; - uint8_t res2[2]; - uint8_t lsp_id [2]; + nd_ipv4 tunnel_endpoint; + nd_byte res[2]; + nd_uint16_t tunnel_id; + nd_ipv4 extended_tunnel_id; + nd_ipv4 tunnel_sender; + nd_byte res2[2]; + nd_uint16_t lsp_id; }; /* @@ -270,13 +271,13 @@ struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t { * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t { - uint8_t tunnel_endpoint [16]; - uint8_t res[2]; - uint8_t tunnel_id[2]; - uint8_t extended_tunnel_id[16]; - uint8_t tunnel_sender [16]; - uint8_t res2[2]; - uint8_t lsp_id [2]; + nd_ipv6 tunnel_endpoint; + nd_byte res[2]; + nd_uint16_t tunnel_id; + nd_ipv6 extended_tunnel_id; + nd_ipv6 tunnel_sender; + nd_byte res2[2]; + nd_uint16_t lsp_id; }; /* @@ -292,9 +293,9 @@ struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t { * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t { - uint8_t rd [8]; - uint8_t prefix [4]; - uint8_t prefix_len; + nd_byte rd[8]; + nd_ipv4 prefix; + nd_uint8_t prefix_len; }; /* @@ -313,9 +314,9 @@ struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t { * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t { - uint8_t rd [8]; - uint8_t prefix [16]; - uint8_t prefix_len; + nd_byte rd[8]; + nd_ipv6 prefix; + nd_uint8_t prefix_len; }; /* @@ -332,10 +333,10 @@ struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t { * 0 1 2 3 */ struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t { - uint8_t rd [8]; - uint8_t sender_ve_id [2]; - uint8_t receiver_ve_id [2]; - uint8_t encapsulation[2]; + nd_byte rd[8]; + nd_uint16_t sender_ve_id; + nd_uint16_t receiver_ve_id; + nd_uint16_t encapsulation; }; /* @@ -349,9 +350,9 @@ struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t { * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct lspping_tlv_targetfec_subtlv_fec_128_pw_old { - uint8_t remote_pe_address [4]; - uint8_t pw_id [4]; - uint8_t pw_type[2]; + nd_ipv4 remote_pe_address; + nd_uint32_t pw_id; + nd_uint16_t pw_type; }; /* @@ -367,10 +368,10 @@ struct lspping_tlv_targetfec_subtlv_fec_128_pw_old { * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct lspping_tlv_targetfec_subtlv_fec_128_pw { - uint8_t sender_pe_address [4]; - uint8_t remote_pe_address [4]; - uint8_t pw_id [4]; - uint8_t pw_type[2]; + nd_ipv4 sender_pe_address; + nd_ipv4 remote_pe_address; + nd_uint32_t pw_id; + nd_uint16_t pw_type; }; /* @@ -382,8 +383,8 @@ struct lspping_tlv_targetfec_subtlv_fec_128_pw { * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t { - uint8_t prefix [4]; - uint8_t prefix_len; + nd_ipv4 prefix; + nd_uint8_t prefix_len; }; /* @@ -398,8 +399,8 @@ struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t { * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t { - uint8_t prefix [16]; - uint8_t prefix_len; + nd_ipv6 prefix; + nd_uint8_t prefix_len; }; /* @@ -429,47 +430,47 @@ struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t { */ /* Enough to get the address type */ struct lspping_tlv_downstream_map_t { - uint8_t mtu [2]; - uint8_t address_type; - uint8_t ds_flags; + nd_uint16_t mtu; + nd_uint8_t address_type; + nd_uint8_t ds_flags; }; struct lspping_tlv_downstream_map_ipv4_t { - uint8_t mtu [2]; - uint8_t address_type; - uint8_t ds_flags; - uint8_t downstream_ip[4]; - uint8_t downstream_interface[4]; + nd_uint16_t mtu; + nd_uint8_t address_type; + nd_uint8_t ds_flags; + nd_ipv4 downstream_ip; + nd_ipv4 downstream_interface; }; struct lspping_tlv_downstream_map_ipv4_unmb_t { - uint8_t mtu [2]; - uint8_t address_type; - uint8_t ds_flags; - uint8_t downstream_ip[4]; - uint8_t downstream_interface[4]; + nd_uint16_t mtu; + nd_uint8_t address_type; + nd_uint8_t ds_flags; + nd_ipv4 downstream_ip; + nd_uint32_t downstream_interface; }; struct lspping_tlv_downstream_map_ipv6_t { - uint8_t mtu [2]; - uint8_t address_type; - uint8_t ds_flags; - uint8_t downstream_ip[16]; - uint8_t downstream_interface[16]; + nd_uint16_t mtu; + nd_uint8_t address_type; + nd_uint8_t ds_flags; + nd_ipv6 downstream_ip; + nd_ipv6 downstream_interface; }; struct lspping_tlv_downstream_map_ipv6_unmb_t { - uint8_t mtu [2]; - uint8_t address_type; - uint8_t ds_flags; - uint8_t downstream_ip[16]; - uint8_t downstream_interface[4]; + nd_uint16_t mtu; + nd_uint8_t address_type; + nd_uint8_t ds_flags; + nd_ipv6 downstream_ip; + nd_uint32_t downstream_interface; }; struct lspping_tlv_downstream_map_info_t { - uint8_t multipath_type; - uint8_t depth_limit; - uint8_t multipath_length [2]; + nd_uint8_t multipath_type; + nd_uint8_t depth_limit; + nd_uint16_t multipath_length; }; #define LSPPING_AFI_IPV4 1 @@ -487,16 +488,18 @@ static const struct tok lspping_tlv_downstream_addr_values[] = { void lspping_print(netdissect_options *ndo, - register const u_char *pptr, register u_int len) + const u_char *pptr, u_int len) { const struct lspping_common_header *lspping_com_header; const struct lspping_tlv_header *lspping_tlv_header; const struct lspping_tlv_header *lspping_subtlv_header; const u_char *tptr,*tlv_tptr,*subtlv_tptr; + u_int return_code, return_subcode; u_int tlen,lspping_tlv_len,lspping_tlv_type,tlv_tlen; int tlv_hexdump,subtlv_hexdump; u_int lspping_subtlv_len,lspping_subtlv_type; - struct timeval timestamp; + uint32_t int_part, fraction; + u_int address_type; union { const struct lspping_tlv_downstream_map_t *lspping_tlv_downstream_map; @@ -521,28 +524,29 @@ lspping_print(netdissect_options *ndo, const struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t *lspping_tlv_targetfec_subtlv_bgp_ipv6; } subtlv_ptr; + ndo->ndo_protocol = "lspping"; tptr=pptr; lspping_com_header = (const struct lspping_common_header *)pptr; - if (len < sizeof(const struct lspping_common_header)) + if (len < sizeof(struct lspping_common_header)) goto tooshort; - ND_TCHECK(*lspping_com_header); + ND_TCHECK_SIZE(lspping_com_header); /* * Sanity checking of the header. */ - if (EXTRACT_16BITS(&lspping_com_header->version[0]) != LSPPING_VERSION) { - ND_PRINT((ndo, "LSP-PING version %u packet not supported", - EXTRACT_16BITS(&lspping_com_header->version[0]))); + if (GET_BE_U_2(lspping_com_header->version) != LSPPING_VERSION) { + ND_PRINT("LSP-PING version %u packet not supported", + GET_BE_U_2(lspping_com_header->version)); return; } /* in non-verbose mode just lets print the basic Message Type*/ if (ndo->ndo_vflag < 1) { - ND_PRINT((ndo, "LSP-PINGv%u, %s, seq %u, length: %u", - EXTRACT_16BITS(&lspping_com_header->version[0]), - tok2str(lspping_msg_type_values, "unknown (%u)",lspping_com_header->msg_type), - EXTRACT_32BITS(lspping_com_header->seq_number), - len)); + ND_PRINT("LSP-PINGv%u, %s, seq %u, length: %u", + GET_BE_U_2(lspping_com_header->version), + tok2str(lspping_msg_type_values, "unknown (%u)",GET_U_1(lspping_com_header->msg_type)), + GET_BE_U_4(lspping_com_header->seq_number), + len); return; } @@ -550,73 +554,71 @@ lspping_print(netdissect_options *ndo, tlen=len; - ND_PRINT((ndo, "\n\tLSP-PINGv%u, msg-type: %s (%u), length: %u\n\t reply-mode: %s (%u)", - EXTRACT_16BITS(&lspping_com_header->version[0]), - tok2str(lspping_msg_type_values, "unknown",lspping_com_header->msg_type), - lspping_com_header->msg_type, + ND_PRINT("\n\tLSP-PINGv%u, msg-type: %s (%u), length: %u\n\t reply-mode: %s (%u)", + GET_BE_U_2(lspping_com_header->version), + tok2str(lspping_msg_type_values, "unknown",GET_U_1(lspping_com_header->msg_type)), + GET_U_1(lspping_com_header->msg_type), len, - tok2str(lspping_reply_mode_values, "unknown",lspping_com_header->reply_mode), - lspping_com_header->reply_mode)); + tok2str(lspping_reply_mode_values, "unknown",GET_U_1(lspping_com_header->reply_mode)), + GET_U_1(lspping_com_header->reply_mode)); /* * the following return codes require that the subcode is attached * at the end of the translated token output */ - if (lspping_com_header->return_code == 3 || - lspping_com_header->return_code == 4 || - lspping_com_header->return_code == 8 || - lspping_com_header->return_code == 10 || - lspping_com_header->return_code == 11 || - lspping_com_header->return_code == 12 ) - ND_PRINT((ndo, "\n\t Return Code: %s %u (%u)\n\t Return Subcode: (%u)", - tok2str(lspping_return_code_values, "unknown",lspping_com_header->return_code), - lspping_com_header->return_subcode, - lspping_com_header->return_code, - lspping_com_header->return_subcode)); + return_code = GET_U_1(lspping_com_header->return_code); + return_subcode = GET_U_1(lspping_com_header->return_subcode); + if (return_code == 3 || + return_code == 4 || + return_code == 8 || + return_code == 10 || + return_code == 11 || + return_code == 12 ) + ND_PRINT("\n\t Return Code: %s %u (%u)\n\t Return Subcode: (%u)", + tok2str(lspping_return_code_values, "unknown",return_code), + return_subcode, + return_code, + return_subcode); else - ND_PRINT((ndo, "\n\t Return Code: %s (%u)\n\t Return Subcode: (%u)", - tok2str(lspping_return_code_values, "unknown",lspping_com_header->return_code), - lspping_com_header->return_code, - lspping_com_header->return_subcode)); - - ND_PRINT((ndo, "\n\t Sender Handle: 0x%08x, Sequence: %u", - EXTRACT_32BITS(lspping_com_header->sender_handle), - EXTRACT_32BITS(lspping_com_header->seq_number))); - - timestamp.tv_sec=EXTRACT_32BITS(lspping_com_header->ts_sent_sec); - timestamp.tv_usec=EXTRACT_32BITS(lspping_com_header->ts_sent_usec); - ND_PRINT((ndo, "\n\t Sender Timestamp: ")); - ts_print(ndo, ×tamp); - - timestamp.tv_sec=EXTRACT_32BITS(lspping_com_header->ts_rcvd_sec); - timestamp.tv_usec=EXTRACT_32BITS(lspping_com_header->ts_rcvd_usec); - ND_PRINT((ndo, "Receiver Timestamp: ")); - if ((timestamp.tv_sec != 0) && (timestamp.tv_usec != 0)) - ts_print(ndo, ×tamp); + ND_PRINT("\n\t Return Code: %s (%u)\n\t Return Subcode: (%u)", + tok2str(lspping_return_code_values, "unknown",return_code), + return_code, + return_subcode); + + ND_PRINT("\n\t Sender Handle: 0x%08x, Sequence: %u", + GET_BE_U_4(lspping_com_header->sender_handle), + GET_BE_U_4(lspping_com_header->seq_number)); + + ND_PRINT("\n\t Sender Timestamp: "); + p_ntp_time(ndo, &lspping_com_header->ts_sent); + ND_PRINT(" "); + + int_part=GET_BE_U_4(lspping_com_header->ts_rcvd.int_part); + fraction=GET_BE_U_4(lspping_com_header->ts_rcvd.fraction); + ND_PRINT("Receiver Timestamp: "); + if (! (int_part == 0 && fraction == 0)) + p_ntp_time(ndo, &lspping_com_header->ts_rcvd); else - ND_PRINT((ndo, "no timestamp")); + ND_PRINT("no timestamp"); - tptr+=sizeof(const struct lspping_common_header); - tlen-=sizeof(const struct lspping_common_header); + tptr+=sizeof(struct lspping_common_header); + tlen-=sizeof(struct lspping_common_header); while (tlen != 0) { /* Does the TLV go past the end of the packet? */ if (tlen < sizeof(struct lspping_tlv_header)) goto tooshort; - /* did we capture enough for fully decoding the tlv header ? */ - ND_TCHECK2(*tptr, sizeof(struct lspping_tlv_header)); - lspping_tlv_header = (const struct lspping_tlv_header *)tptr; - lspping_tlv_type=EXTRACT_16BITS(lspping_tlv_header->type); - lspping_tlv_len=EXTRACT_16BITS(lspping_tlv_header->length); + lspping_tlv_type=GET_BE_U_2(lspping_tlv_header->type); + lspping_tlv_len=GET_BE_U_2(lspping_tlv_header->length); - ND_PRINT((ndo, "\n\t %s TLV (%u), length: %u", + ND_PRINT("\n\t %s TLV (%u), length: %u", tok2str(lspping_tlv_values, "Unknown", lspping_tlv_type), lspping_tlv_type, - lspping_tlv_len)); + lspping_tlv_len); /* some little sanity checking */ if (lspping_tlv_len == 0) { @@ -632,7 +634,7 @@ lspping_print(netdissect_options *ndo, if (tlen < lspping_tlv_len+sizeof(struct lspping_tlv_header)) goto tooshort; /* did we capture enough for fully decoding the tlv ? */ - ND_TCHECK2(*tlv_tptr, lspping_tlv_len); + ND_TCHECK_LEN(tlv_tptr, lspping_tlv_len); tlv_hexdump=FALSE; switch(lspping_tlv_type) { @@ -640,177 +642,175 @@ lspping_print(netdissect_options *ndo, while (tlv_tlen != 0) { /* Does the subTLV header go past the end of the TLV? */ if (tlv_tlen < sizeof(struct lspping_tlv_header)) { - ND_PRINT((ndo, "\n\t TLV is too short")); + ND_PRINT("\n\t TLV is too short"); tlv_hexdump = TRUE; goto tlv_tooshort; } - /* did we capture enough for fully decoding the subtlv header ? */ - ND_TCHECK2(*tlv_tptr, sizeof(struct lspping_tlv_header)); subtlv_hexdump=FALSE; lspping_subtlv_header = (const struct lspping_tlv_header *)tlv_tptr; - lspping_subtlv_type=EXTRACT_16BITS(lspping_subtlv_header->type); - lspping_subtlv_len=EXTRACT_16BITS(lspping_subtlv_header->length); + lspping_subtlv_type=GET_BE_U_2(lspping_subtlv_header->type); + lspping_subtlv_len=GET_BE_U_2(lspping_subtlv_header->length); subtlv_tptr=tlv_tptr+sizeof(struct lspping_tlv_header); /* Does the subTLV go past the end of the TLV? */ if (tlv_tlen < lspping_subtlv_len+sizeof(struct lspping_tlv_header)) { - ND_PRINT((ndo, "\n\t TLV is too short")); + ND_PRINT("\n\t TLV is too short"); tlv_hexdump = TRUE; goto tlv_tooshort; } /* Did we capture enough for fully decoding the subTLV? */ - ND_TCHECK2(*subtlv_tptr, lspping_subtlv_len); + ND_TCHECK_LEN(subtlv_tptr, lspping_subtlv_len); - ND_PRINT((ndo, "\n\t %s subTLV (%u), length: %u", + ND_PRINT("\n\t %s subTLV (%u), length: %u", tok2str(lspping_tlvtargetfec_subtlv_values, "Unknown", lspping_subtlv_type), lspping_subtlv_type, - lspping_subtlv_len)); + lspping_subtlv_len); switch(lspping_subtlv_type) { case LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4: /* Is the subTLV length correct? */ if (lspping_subtlv_len != 5) { - ND_PRINT((ndo, "\n\t invalid subTLV length, should be 5")); + ND_PRINT("\n\t invalid subTLV length, should be 5"); subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ } else { - subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4 = \ + subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4 = (const struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t *)subtlv_tptr; - ND_PRINT((ndo, "\n\t %s/%u", - ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4->prefix), - subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4->prefix_len)); + ND_PRINT("\n\t %s/%u", + GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4->prefix), + GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4->prefix_len)); } break; case LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6: /* Is the subTLV length correct? */ if (lspping_subtlv_len != 17) { - ND_PRINT((ndo, "\n\t invalid subTLV length, should be 17")); + ND_PRINT("\n\t invalid subTLV length, should be 17"); subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ } else { - subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6 = \ + subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6 = (const struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t *)subtlv_tptr; - ND_PRINT((ndo, "\n\t %s/%u", - ip6addr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6->prefix), - subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6->prefix_len)); + ND_PRINT("\n\t %s/%u", + GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6->prefix), + GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6->prefix_len)); } break; case LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4: /* Is the subTLV length correct? */ if (lspping_subtlv_len != 5) { - ND_PRINT((ndo, "\n\t invalid subTLV length, should be 5")); + ND_PRINT("\n\t invalid subTLV length, should be 5"); subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ } else { - subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4 = \ + subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4 = (const struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t *)subtlv_tptr; - ND_PRINT((ndo, "\n\t %s/%u", - ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix), - subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix_len)); + ND_PRINT("\n\t %s/%u", + GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix), + GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix_len)); } break; case LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6: /* Is the subTLV length correct? */ if (lspping_subtlv_len != 17) { - ND_PRINT((ndo, "\n\t invalid subTLV length, should be 17")); + ND_PRINT("\n\t invalid subTLV length, should be 17"); subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ } else { - subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6 = \ + subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6 = (const struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t *)subtlv_tptr; - ND_PRINT((ndo, "\n\t %s/%u", - ip6addr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix), - subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix_len)); + ND_PRINT("\n\t %s/%u", + GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix), + GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix_len)); } break; case LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4: /* Is the subTLV length correct? */ if (lspping_subtlv_len != 20) { - ND_PRINT((ndo, "\n\t invalid subTLV length, should be 20")); + ND_PRINT("\n\t invalid subTLV length, should be 20"); subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ } else { - subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4 = \ + subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4 = (const struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t *)subtlv_tptr; - ND_PRINT((ndo, "\n\t tunnel end-point %s, tunnel sender %s, lsp-id 0x%04x" \ + ND_PRINT("\n\t tunnel end-point %s, tunnel sender %s, lsp-id 0x%04x" "\n\t tunnel-id 0x%04x, extended tunnel-id %s", - ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_endpoint), - ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_sender), - EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->lsp_id), - EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_id), - ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->extended_tunnel_id))); + GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_endpoint), + GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_sender), + GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->lsp_id), + GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_id), + GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->extended_tunnel_id)); } break; case LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6: /* Is the subTLV length correct? */ if (lspping_subtlv_len != 56) { - ND_PRINT((ndo, "\n\t invalid subTLV length, should be 56")); + ND_PRINT("\n\t invalid subTLV length, should be 56"); subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ } else { - subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6 = \ + subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6 = (const struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t *)subtlv_tptr; - ND_PRINT((ndo, "\n\t tunnel end-point %s, tunnel sender %s, lsp-id 0x%04x" \ + ND_PRINT("\n\t tunnel end-point %s, tunnel sender %s, lsp-id 0x%04x" "\n\t tunnel-id 0x%04x, extended tunnel-id %s", - ip6addr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_endpoint), - ip6addr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_sender), - EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->lsp_id), - EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_id), - ip6addr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->extended_tunnel_id))); + GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_endpoint), + GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_sender), + GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->lsp_id), + GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_id), + GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->extended_tunnel_id)); } break; case LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4: /* Is the subTLV length correct? */ if (lspping_subtlv_len != 13) { - ND_PRINT((ndo, "\n\t invalid subTLV length, should be 13")); + ND_PRINT("\n\t invalid subTLV length, should be 13"); subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ } else { - subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4 = \ + subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4 = (const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t *)subtlv_tptr; - ND_PRINT((ndo, "\n\t RD: %s, %s/%u", + ND_PRINT("\n\t RD: %s, %s/%u", bgp_vpn_rd_print(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->rd), - ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->prefix), - subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->prefix_len)); + GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->prefix), + GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->prefix_len)); } break; case LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6: /* Is the subTLV length correct? */ if (lspping_subtlv_len != 25) { - ND_PRINT((ndo, "\n\t invalid subTLV length, should be 25")); + ND_PRINT("\n\t invalid subTLV length, should be 25"); subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ } else { - subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6 = \ + subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6 = (const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t *)subtlv_tptr; - ND_PRINT((ndo, "\n\t RD: %s, %s/%u", + ND_PRINT("\n\t RD: %s, %s/%u", bgp_vpn_rd_print(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->rd), - ip6addr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->prefix), - subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->prefix_len)); + GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->prefix), + GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->prefix_len)); } break; case LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT: /* Is the subTLV length correct? */ if (lspping_subtlv_len != 14) { - ND_PRINT((ndo, "\n\t invalid subTLV length, should be 14")); + ND_PRINT("\n\t invalid subTLV length, should be 14"); subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ } else { - subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt = \ + subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt = (const struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t *)subtlv_tptr; - ND_PRINT((ndo, "\n\t RD: %s, Sender VE ID: %u, Receiver VE ID: %u" \ + ND_PRINT("\n\t RD: %s, Sender VE ID: %u, Receiver VE ID: %u" "\n\t Encapsulation Type: %s (%u)", bgp_vpn_rd_print(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->rd), - EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->sender_ve_id), - EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->receiver_ve_id), + GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->sender_ve_id), + GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->receiver_ve_id), tok2str(mpls_pw_types_values, "unknown", - EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation)), - EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation))); + GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation)), + GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation)); } break; @@ -818,39 +818,39 @@ lspping_print(netdissect_options *ndo, case LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW_OLD: /* Is the subTLV length correct? */ if (lspping_subtlv_len != 10) { - ND_PRINT((ndo, "\n\t invalid subTLV length, should be 10")); + ND_PRINT("\n\t invalid subTLV length, should be 10"); subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ } else { - subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old = \ + subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old = (const struct lspping_tlv_targetfec_subtlv_fec_128_pw_old *)subtlv_tptr; - ND_PRINT((ndo, "\n\t Remote PE: %s" \ + ND_PRINT("\n\t Remote PE: %s" "\n\t PW ID: 0x%08x, PW Type: %s (%u)", - ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->remote_pe_address), - EXTRACT_32BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->pw_id), + GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->remote_pe_address), + GET_BE_U_4(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->pw_id), tok2str(mpls_pw_types_values, "unknown", - EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->pw_type)), - EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->pw_type))); + GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->pw_type)), + GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->pw_type)); } break; case LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW: /* Is the subTLV length correct? */ if (lspping_subtlv_len != 14) { - ND_PRINT((ndo, "\n\t invalid subTLV length, should be 14")); + ND_PRINT("\n\t invalid subTLV length, should be 14"); subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ } else { - subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid = \ + subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid = (const struct lspping_tlv_targetfec_subtlv_fec_128_pw *)subtlv_tptr; - ND_PRINT((ndo, "\n\t Sender PE: %s, Remote PE: %s" \ + ND_PRINT("\n\t Sender PE: %s, Remote PE: %s" "\n\t PW ID: 0x%08x, PW Type: %s (%u)", - ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->sender_pe_address), - ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->remote_pe_address), - EXTRACT_32BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->pw_id), + GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->sender_pe_address), + GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->remote_pe_address), + GET_BE_U_4(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->pw_id), tok2str(mpls_pw_types_values, "unknown", - EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->pw_type)), - EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->pw_type))); + GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->pw_type)), + GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->pw_type)); } break; @@ -860,7 +860,7 @@ lspping_print(netdissect_options *ndo, } /* do we want to see an additionally subtlv hexdump ? */ if (ndo->ndo_vflag > 1 || subtlv_hexdump==TRUE) - print_unknown_data(ndo, tlv_tptr+sizeof(struct lspping_tlv_header), \ + print_unknown_data(ndo, tlv_tptr+sizeof(struct lspping_tlv_header), "\n\t ", lspping_subtlv_len); @@ -869,7 +869,7 @@ lspping_print(netdissect_options *ndo, lspping_subtlv_len += 4 - (lspping_subtlv_len % 4); /* Does the subTLV, including padding, go past the end of the TLV? */ if (tlv_tlen < lspping_subtlv_len+sizeof(struct lspping_tlv_header)) { - ND_PRINT((ndo, "\n\t\t TLV is too short")); + ND_PRINT("\n\t\t TLV is too short"); return; } } @@ -881,102 +881,108 @@ lspping_print(netdissect_options *ndo, case LSPPING_TLV_DOWNSTREAM_MAPPING: /* Does the header go past the end of the TLV? */ if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_t)) { - ND_PRINT((ndo, "\n\t TLV is too short")); + ND_PRINT("\n\t TLV is too short"); tlv_hexdump = TRUE; goto tlv_tooshort; } /* Did we capture enough to get the address family? */ - ND_TCHECK2(*tlv_tptr, sizeof(struct lspping_tlv_downstream_map_t)); + ND_TCHECK_LEN(tlv_tptr, + sizeof(struct lspping_tlv_downstream_map_t)); - tlv_ptr.lspping_tlv_downstream_map= \ + tlv_ptr.lspping_tlv_downstream_map= (const struct lspping_tlv_downstream_map_t *)tlv_tptr; /* that strange thing with the downstream map TLV is that until now * we do not know if its IPv4 or IPv6 or is unnumbered; after * we find the address-type, we recast the tlv_tptr and move on. */ - ND_PRINT((ndo, "\n\t MTU: %u, Address-Type: %s (%u)", - EXTRACT_16BITS(tlv_ptr.lspping_tlv_downstream_map->mtu), + address_type = GET_U_1(tlv_ptr.lspping_tlv_downstream_map->address_type); + ND_PRINT("\n\t MTU: %u, Address-Type: %s (%u)", + GET_BE_U_2(tlv_ptr.lspping_tlv_downstream_map->mtu), tok2str(lspping_tlv_downstream_addr_values, "unknown", - tlv_ptr.lspping_tlv_downstream_map->address_type), - tlv_ptr.lspping_tlv_downstream_map->address_type)); + address_type), + address_type); - switch(tlv_ptr.lspping_tlv_downstream_map->address_type) { + switch(address_type) { case LSPPING_AFI_IPV4: /* Does the data go past the end of the TLV? */ if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv4_t)) { - ND_PRINT((ndo, "\n\t TLV is too short")); + ND_PRINT("\n\t TLV is too short"); tlv_hexdump = TRUE; goto tlv_tooshort; } /* Did we capture enough for this part of the TLV? */ - ND_TCHECK2(*tlv_tptr, sizeof(struct lspping_tlv_downstream_map_ipv4_t)); + ND_TCHECK_LEN(tlv_tptr, + sizeof(struct lspping_tlv_downstream_map_ipv4_t)); - tlv_ptr.lspping_tlv_downstream_map_ipv4= \ + tlv_ptr.lspping_tlv_downstream_map_ipv4= (const struct lspping_tlv_downstream_map_ipv4_t *)tlv_tptr; - ND_PRINT((ndo, "\n\t Downstream IP: %s" \ + ND_PRINT("\n\t Downstream IP: %s" "\n\t Downstream Interface IP: %s", - ipaddr_string(ndo, tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_ip), - ipaddr_string(ndo, tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_interface))); + GET_IPADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_ip), + GET_IPADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_interface)); tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_t); tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_t); break; case LSPPING_AFI_IPV4_UNMB: /* Does the data go past the end of the TLV? */ if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t)) { - ND_PRINT((ndo, "\n\t TLV is too short")); + ND_PRINT("\n\t TLV is too short"); tlv_hexdump = TRUE; goto tlv_tooshort; } /* Did we capture enough for this part of the TLV? */ - ND_TCHECK2(*tlv_tptr, sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t)); + ND_TCHECK_LEN(tlv_tptr, + sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t)); - tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb= \ + tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb= (const struct lspping_tlv_downstream_map_ipv4_unmb_t *)tlv_tptr; - ND_PRINT((ndo, "\n\t Downstream IP: %s" \ + ND_PRINT("\n\t Downstream IP: %s" "\n\t Downstream Interface Index: 0x%08x", - ipaddr_string(ndo, tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb->downstream_ip), - EXTRACT_32BITS(tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb->downstream_interface))); + GET_IPADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb->downstream_ip), + GET_BE_U_4(tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb->downstream_interface)); tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t); tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t); break; case LSPPING_AFI_IPV6: /* Does the data go past the end of the TLV? */ if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv6_t)) { - ND_PRINT((ndo, "\n\t TLV is too short")); + ND_PRINT("\n\t TLV is too short"); tlv_hexdump = TRUE; goto tlv_tooshort; } /* Did we capture enough for this part of the TLV? */ - ND_TCHECK2(*tlv_tptr, sizeof(struct lspping_tlv_downstream_map_ipv6_t)); + ND_TCHECK_LEN(tlv_tptr, + sizeof(struct lspping_tlv_downstream_map_ipv6_t)); - tlv_ptr.lspping_tlv_downstream_map_ipv6= \ + tlv_ptr.lspping_tlv_downstream_map_ipv6= (const struct lspping_tlv_downstream_map_ipv6_t *)tlv_tptr; - ND_PRINT((ndo, "\n\t Downstream IP: %s" \ + ND_PRINT("\n\t Downstream IP: %s" "\n\t Downstream Interface IP: %s", - ip6addr_string(ndo, tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_ip), - ip6addr_string(ndo, tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_interface))); + GET_IP6ADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_ip), + GET_IP6ADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_interface)); tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv6_t); tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv6_t); break; case LSPPING_AFI_IPV6_UNMB: /* Does the data go past the end of the TLV? */ if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t)) { - ND_PRINT((ndo, "\n\t TLV is too short")); + ND_PRINT("\n\t TLV is too short"); tlv_hexdump = TRUE; goto tlv_tooshort; } /* Did we capture enough for this part of the TLV? */ - ND_TCHECK2(*tlv_tptr, sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t)); + ND_TCHECK_LEN(tlv_tptr, + sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t)); - tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb= \ + tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb= (const struct lspping_tlv_downstream_map_ipv6_unmb_t *)tlv_tptr; - ND_PRINT((ndo, "\n\t Downstream IP: %s" \ + ND_PRINT("\n\t Downstream IP: %s" "\n\t Downstream Interface Index: 0x%08x", - ip6addr_string(ndo, tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb->downstream_ip), - EXTRACT_32BITS(tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb->downstream_interface))); + GET_IP6ADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb->downstream_ip), + GET_BE_U_4(tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb->downstream_interface)); tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t); tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t); break; @@ -988,14 +994,15 @@ lspping_print(netdissect_options *ndo, /* Does the data go past the end of the TLV? */ if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_info_t)) { - ND_PRINT((ndo, "\n\t TLV is too short")); + ND_PRINT("\n\t TLV is too short"); tlv_hexdump = TRUE; goto tlv_tooshort; } /* Did we capture enough for this part of the TLV? */ - ND_TCHECK2(*tlv_tptr, sizeof(struct lspping_tlv_downstream_map_info_t)); + ND_TCHECK_LEN(tlv_tptr, + sizeof(struct lspping_tlv_downstream_map_info_t)); - tlv_ptr.lspping_tlv_downstream_map_info= \ + tlv_ptr.lspping_tlv_downstream_map_info= (const struct lspping_tlv_downstream_map_info_t *)tlv_tptr; /* FIXME add hash-key type, depth limit, multipath processing */ @@ -1011,12 +1018,11 @@ lspping_print(netdissect_options *ndo, case LSPPING_TLV_BFD_DISCRIMINATOR: if (tlv_tlen < LSPPING_TLV_BFD_DISCRIMINATOR_LEN) { - ND_PRINT((ndo, "\n\t TLV is too short")); + ND_PRINT("\n\t TLV is too short"); tlv_hexdump = TRUE; goto tlv_tooshort; } else { - ND_TCHECK2(*tptr, LSPPING_TLV_BFD_DISCRIMINATOR_LEN); - ND_PRINT((ndo, "\n\t BFD Discriminator 0x%08x", EXTRACT_32BITS(tptr))); + ND_PRINT("\n\t BFD Discriminator 0x%08x", GET_BE_U_4(tlv_tptr)); } break; @@ -1025,15 +1031,14 @@ lspping_print(netdissect_options *ndo, uint32_t vendor_id; if (tlv_tlen < LSPPING_TLV_VENDOR_ENTERPRISE_LEN) { - ND_PRINT((ndo, "\n\t TLV is too short")); + ND_PRINT("\n\t TLV is too short"); tlv_hexdump = TRUE; goto tlv_tooshort; } else { - ND_TCHECK2(*tptr, LSPPING_TLV_VENDOR_ENTERPRISE_LEN); - vendor_id = EXTRACT_32BITS(tlv_tptr); - ND_PRINT((ndo, "\n\t Vendor: %s (0x%04x)", + vendor_id = GET_BE_U_4(tlv_tptr); + ND_PRINT("\n\t Vendor: %s (0x%04x)", tok2str(smi_values, "Unknown", vendor_id), - vendor_id)); + vendor_id); } } break; @@ -1071,15 +1076,5 @@ lspping_print(netdissect_options *ndo, } return; tooshort: - ND_PRINT((ndo, "\n\t\t packet is too short")); - return; -trunc: - ND_PRINT((ndo, "\n\t\t packet exceeded snapshot")); - return; + ND_PRINT("\n\t\t packet is too short"); } -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/print-lwapp.c b/contrib/tcpdump/print-lwapp.c index bab3219f10..10a2e0bed0 100644 --- a/contrib/tcpdump/print-lwapp.c +++ b/contrib/tcpdump/print-lwapp.c @@ -20,15 +20,16 @@ /* specification: RFC 5412 */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "extract.h" #include "addrtoname.h" + /* * LWAPP transport (common) header * 0 1 2 3 @@ -42,10 +43,10 @@ */ struct lwapp_transport_header { - uint8_t version; - uint8_t frag_id; - uint8_t length[2]; - uint16_t status; + nd_uint8_t version; + nd_uint8_t frag_id; + nd_uint16_t length; + nd_uint16_t status; }; /* @@ -62,10 +63,10 @@ struct lwapp_transport_header { */ struct lwapp_control_header { - uint8_t msg_type; - uint8_t seq_num; - uint8_t len[2]; - uint8_t session_id[4]; + nd_uint8_t msg_type; + nd_uint8_t seq_num; + nd_uint16_t len; + nd_uint32_t session_id; }; #define LWAPP_VERSION 0 @@ -157,8 +158,8 @@ static const struct tok lwapp_msg_type_values[] = { * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct lwapp_message_header { - uint8_t type; - uint8_t length[2]; + nd_uint8_t type; + nd_uint16_t length; }; void @@ -168,78 +169,90 @@ lwapp_control_print(netdissect_options *ndo, const struct lwapp_transport_header *lwapp_trans_header; const struct lwapp_control_header *lwapp_control_header; const u_char *tptr; - int tlen; - int msg_tlen; + uint8_t version; + u_int tlen; + u_int msg_type, msg_tlen; + ndo->ndo_protocol = "lwapp_control"; tptr=pptr; if (has_ap_ident) { /* check if enough bytes for AP identity */ - ND_TCHECK2(*tptr, 6); + ND_TCHECK_6(tptr); lwapp_trans_header = (const struct lwapp_transport_header *)(pptr+6); } else { lwapp_trans_header = (const struct lwapp_transport_header *)pptr; } - ND_TCHECK(*lwapp_trans_header); + ND_TCHECK_SIZE(lwapp_trans_header); + version = GET_U_1(lwapp_trans_header->version); /* * Sanity checking of the header. */ - if (LWAPP_EXTRACT_VERSION(lwapp_trans_header->version) != LWAPP_VERSION) { - ND_PRINT((ndo, "LWAPP version %u packet not supported", - LWAPP_EXTRACT_VERSION(lwapp_trans_header->version))); + if (LWAPP_EXTRACT_VERSION(version) != LWAPP_VERSION) { + ND_PRINT("LWAPP version %u packet not supported", + LWAPP_EXTRACT_VERSION(version)); return; } /* non-verbose */ if (ndo->ndo_vflag < 1) { - ND_PRINT((ndo, "LWAPPv%u, %s frame, Flags [%s], length %u", - LWAPP_EXTRACT_VERSION(lwapp_trans_header->version), - LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data", - bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07), - len)); + ND_PRINT("LWAPPv%u, %s frame, Flags [%s], length %u", + LWAPP_EXTRACT_VERSION(version), + LWAPP_EXTRACT_CONTROL_BIT(version) ? "Control" : "Data", + bittok2str(lwapp_header_bits_values,"none",version&0x07), + len); return; } /* ok they seem to want to know everything - lets fully decode it */ - tlen=EXTRACT_16BITS(lwapp_trans_header->length); + tlen=GET_BE_U_2(lwapp_trans_header->length); - ND_PRINT((ndo, "LWAPPv%u, %s frame, Radio-id %u, Flags [%s], Frag-id %u, length %u", - LWAPP_EXTRACT_VERSION(lwapp_trans_header->version), - LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data", - LWAPP_EXTRACT_RID(lwapp_trans_header->version), - bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07), - lwapp_trans_header->frag_id, - tlen)); + ND_PRINT("LWAPPv%u, %s frame, Radio-id %u, Flags [%s], Frag-id %u, length %u", + LWAPP_EXTRACT_VERSION(version), + LWAPP_EXTRACT_CONTROL_BIT(version) ? "Control" : "Data", + LWAPP_EXTRACT_RID(version), + bittok2str(lwapp_header_bits_values,"none",version&0x07), + GET_U_1(lwapp_trans_header->frag_id), + tlen); if (has_ap_ident) { - ND_PRINT((ndo, "\n\tAP identity: %s", etheraddr_string(ndo, tptr))); - tptr+=sizeof(const struct lwapp_transport_header)+6; + ND_PRINT("\n\tAP identity: %s", GET_ETHERADDR_STRING(tptr)); + tptr+=sizeof(struct lwapp_transport_header)+6; } else { - tptr+=sizeof(const struct lwapp_transport_header); + tptr+=sizeof(struct lwapp_transport_header); } - while(tlen>0) { + while(tlen!=0) { /* did we capture enough for fully decoding the object header ? */ - ND_TCHECK2(*tptr, sizeof(struct lwapp_control_header)); + ND_TCHECK_LEN(tptr, sizeof(struct lwapp_control_header)); + if (tlen < sizeof(struct lwapp_control_header)) { + ND_PRINT("\n\t Msg goes past end of PDU"); + break; + } lwapp_control_header = (const struct lwapp_control_header *)tptr; - msg_tlen = EXTRACT_16BITS(lwapp_control_header->len); + msg_tlen = GET_BE_U_2(lwapp_control_header->len); + if (tlen < sizeof(struct lwapp_control_header) + msg_tlen) { + ND_PRINT("\n\t Msg goes past end of PDU"); + break; + } /* print message header */ - ND_PRINT((ndo, "\n\t Msg type: %s (%u), Seqnum: %u, Msg len: %d, Session: 0x%08x", - tok2str(lwapp_msg_type_values,"Unknown",lwapp_control_header->msg_type), - lwapp_control_header->msg_type, - lwapp_control_header->seq_num, + msg_type = GET_U_1(lwapp_control_header->msg_type); + ND_PRINT("\n\t Msg type: %s (%u), Seqnum: %u, Msg len: %u, Session: 0x%08x", + tok2str(lwapp_msg_type_values,"Unknown",msg_type), + msg_type, + GET_U_1(lwapp_control_header->seq_num), msg_tlen, - EXTRACT_32BITS(lwapp_control_header->session_id))); + GET_BE_U_4(lwapp_control_header->session_id)); /* did we capture enough for fully decoding the message */ - ND_TCHECK2(*tptr, msg_tlen); + ND_TCHECK_LEN(tptr, msg_tlen); /* XXX - Decode sub messages for each message */ - switch(lwapp_control_header->msg_type) { + switch(msg_type) { case LWAPP_MSGTYPE_DISCOVERY_REQUEST: case LWAPP_MSGTYPE_DISCOVERY_RESPONSE: case LWAPP_MSGTYPE_JOIN_REQUEST: @@ -280,8 +293,8 @@ lwapp_control_print(netdissect_options *ndo, } return; - trunc: - ND_PRINT((ndo, "\n\t\t packet exceeded snapshot")); +trunc: + nd_print_trunc(ndo); } void @@ -290,60 +303,65 @@ lwapp_data_print(netdissect_options *ndo, { const struct lwapp_transport_header *lwapp_trans_header; const u_char *tptr; - int tlen; + u_int tlen; + u_int version; + ndo->ndo_protocol = "lwapp_data"; tptr=pptr; /* check if enough bytes for AP identity */ - ND_TCHECK2(*tptr, 6); + ND_TCHECK_6(tptr); lwapp_trans_header = (const struct lwapp_transport_header *)pptr; - ND_TCHECK(*lwapp_trans_header); + ND_TCHECK_SIZE(lwapp_trans_header); + version = GET_U_1(lwapp_trans_header->version); /* * Sanity checking of the header. */ - if (LWAPP_EXTRACT_VERSION(lwapp_trans_header->version) != LWAPP_VERSION) { - ND_PRINT((ndo, "LWAPP version %u packet not supported", - LWAPP_EXTRACT_VERSION(lwapp_trans_header->version))); + if (LWAPP_EXTRACT_VERSION(version) != LWAPP_VERSION) { + ND_PRINT("LWAPP version %u packet not supported", + LWAPP_EXTRACT_VERSION(version)); return; } /* non-verbose */ if (ndo->ndo_vflag < 1) { - ND_PRINT((ndo, "LWAPPv%u, %s frame, Flags [%s], length %u", - LWAPP_EXTRACT_VERSION(lwapp_trans_header->version), - LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data", - bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07), - len)); + ND_PRINT("LWAPPv%u, %s frame, Flags [%s], length %u", + LWAPP_EXTRACT_VERSION(version), + LWAPP_EXTRACT_CONTROL_BIT(version) ? "Control" : "Data", + bittok2str(lwapp_header_bits_values,"none",version&0x07), + len); return; } /* ok they seem to want to know everything - lets fully decode it */ - tlen=EXTRACT_16BITS(lwapp_trans_header->length); + tlen=GET_BE_U_2(lwapp_trans_header->length); + if (tlen < sizeof(struct lwapp_transport_header)) { + ND_PRINT("LWAPPv%u, %s frame, Radio-id %u, Flags [%s], length %u < transport header length", + LWAPP_EXTRACT_VERSION(version), + LWAPP_EXTRACT_CONTROL_BIT(version) ? "Control" : "Data", + LWAPP_EXTRACT_RID(version), + bittok2str(lwapp_header_bits_values,"none",version&0x07), + tlen); + return; + } - ND_PRINT((ndo, "LWAPPv%u, %s frame, Radio-id %u, Flags [%s], Frag-id %u, length %u", - LWAPP_EXTRACT_VERSION(lwapp_trans_header->version), - LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data", - LWAPP_EXTRACT_RID(lwapp_trans_header->version), - bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07), - lwapp_trans_header->frag_id, - tlen)); + ND_PRINT("LWAPPv%u, %s frame, Radio-id %u, Flags [%s], Frag-id %u, length %u", + LWAPP_EXTRACT_VERSION(version), + LWAPP_EXTRACT_CONTROL_BIT(version) ? "Control" : "Data", + LWAPP_EXTRACT_RID(version), + bittok2str(lwapp_header_bits_values,"none",version&0x07), + GET_U_1(lwapp_trans_header->frag_id), + tlen); - tptr+=sizeof(const struct lwapp_transport_header); - tlen-=sizeof(const struct lwapp_transport_header); + tptr+=sizeof(struct lwapp_transport_header); + tlen-=sizeof(struct lwapp_transport_header); /* FIX - An IEEE 802.11 frame follows - hexdump for now */ print_unknown_data(ndo, tptr, "\n\t", tlen); return; - trunc: - ND_PRINT((ndo, "\n\t\t packet exceeded snapshot")); +trunc: + nd_print_trunc(ndo); } - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/print-lwres.c b/contrib/tcpdump/print-lwres.c index ae352807d0..c237e482a0 100644 --- a/contrib/tcpdump/print-lwres.c +++ b/contrib/tcpdump/print-lwres.c @@ -30,35 +30,34 @@ /* \summary: BIND9 Lightweight Resolver protocol printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include - -#include "nameser.h" - -#include -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "addrtoname.h" #include "extract.h" +#include "nameser.h" + /* BIND9 lib/lwres/include/lwres */ -typedef uint32_t lwres_uint32_t; -typedef uint16_t lwres_uint16_t; -typedef uint8_t lwres_uint8_t; +/* + * Use nd_uint16_t for lwres_uint16_t + * Use nd_uint32_t for lwres_uint32_t +*/ struct lwres_lwpacket { - lwres_uint32_t length; - lwres_uint16_t version; - lwres_uint16_t pktflags; - lwres_uint32_t serial; - lwres_uint32_t opcode; - lwres_uint32_t result; - lwres_uint32_t recvlength; - lwres_uint16_t authtype; - lwres_uint16_t authlength; + nd_uint32_t length; + nd_uint16_t version; + nd_uint16_t pktflags; + nd_uint32_t serial; + nd_uint32_t opcode; + nd_uint32_t result; + nd_uint32_t recvlength; + nd_uint16_t authtype; + nd_uint16_t authlength; }; #define LWRES_LWPACKETFLAG_RESPONSE 0x0001U /* if set, pkt is a response */ @@ -75,13 +74,13 @@ struct lwres_lwpacket { typedef struct { /* public */ - lwres_uint16_t datalength; + nd_uint16_t datalength; /* data follows */ } lwres_nooprequest_t; typedef struct { /* public */ - lwres_uint16_t datalength; + nd_uint16_t datalength; /* data follows */ } lwres_noopresponse_t; @@ -93,29 +92,32 @@ typedef struct { typedef struct lwres_addr lwres_addr_t; struct lwres_addr { - lwres_uint32_t family; - lwres_uint16_t length; - /* address folows */ + nd_uint32_t family; + nd_uint16_t length; + /* address follows */ }; +#define LWRES_ADDR_LEN 6 typedef struct { /* public */ - lwres_uint32_t flags; - lwres_uint32_t addrtypes; - lwres_uint16_t namelen; + nd_uint32_t flags; + nd_uint32_t addrtypes; + nd_uint16_t namelen; /* name follows */ } lwres_gabnrequest_t; +#define LWRES_GABNREQUEST_LEN 10 typedef struct { /* public */ - lwres_uint32_t flags; - lwres_uint16_t naliases; - lwres_uint16_t naddrs; - lwres_uint16_t realnamelen; + nd_uint32_t flags; + nd_uint16_t naliases; + nd_uint16_t naddrs; + nd_uint16_t realnamelen; /* aliases follows */ /* addrs follows */ /* realname follows */ } lwres_gabnresponse_t; +#define LWRES_GABNRESPONSE_LEN 10 /* * get name by address @@ -123,19 +125,20 @@ typedef struct { #define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U typedef struct { /* public */ - lwres_uint32_t flags; - lwres_addr_t addr; - /* addr body follows */ + nd_uint32_t flags; + /* addr follows */ } lwres_gnbarequest_t; +#define LWRES_GNBAREQUEST_LEN 4 typedef struct { /* public */ - lwres_uint32_t flags; - lwres_uint16_t naliases; - lwres_uint16_t realnamelen; + nd_uint32_t flags; + nd_uint16_t naliases; + nd_uint16_t realnamelen; /* aliases follows */ /* realname follows */ } lwres_gnbaresponse_t; +#define LWRES_GNBARESPONSE_LEN 8 /* * get rdata by name @@ -144,25 +147,27 @@ typedef struct { typedef struct { /* public */ - lwres_uint32_t flags; - lwres_uint16_t rdclass; - lwres_uint16_t rdtype; - lwres_uint16_t namelen; + nd_uint32_t flags; + nd_uint16_t rdclass; + nd_uint16_t rdtype; + nd_uint16_t namelen; /* name follows */ } lwres_grbnrequest_t; +#define LWRES_GRBNREQUEST_LEN 10 typedef struct { /* public */ - lwres_uint32_t flags; - lwres_uint16_t rdclass; - lwres_uint16_t rdtype; - lwres_uint32_t ttl; - lwres_uint16_t nrdatas; - lwres_uint16_t nsigs; + nd_uint32_t flags; + nd_uint16_t rdclass; + nd_uint16_t rdtype; + nd_uint32_t ttl; + nd_uint16_t nrdatas; + nd_uint16_t nsigs; /* realname here (len + name) */ /* rdata here (len + name) */ /* signatures here (len + name) */ } lwres_grbnresponse_t; +#define LWRES_GRBNRESPONSE_LEN 16 #define LWRDATA_VALIDATED 0x00000001 @@ -184,157 +189,135 @@ static const struct tok opcode[] = { extern const struct tok ns_type2str[]; extern const struct tok ns_class2str[]; -static int +static unsigned lwres_printname(netdissect_options *ndo, - size_t l, const char *p0) + size_t l, const u_char *p0) { - const char *p; - size_t i; - - p = p0; - /* + 1 for terminating \0 */ - if (p + l + 1 > (const char *)ndo->ndo_snapend) - goto trunc; - - ND_PRINT((ndo, " ")); - for (i = 0; i < l; i++) - safeputchar(ndo, *p++); - p++; /* skip terminating \0 */ - - return p - p0; - - trunc: - return -1; + ND_PRINT(" "); + (void)nd_printn(ndo, p0, l, NULL); + p0 += l; + if (GET_U_1(p0)) + ND_PRINT(" (not NUL-terminated!)"); + return l + 1; } -static int +static unsigned lwres_printnamelen(netdissect_options *ndo, - const char *p) + const u_char *p) { uint16_t l; int advance; - if (p + 2 > (const char *)ndo->ndo_snapend) - goto trunc; - l = EXTRACT_16BITS(p); + l = GET_BE_U_2(p); advance = lwres_printname(ndo, l, p + 2); - if (advance < 0) - goto trunc; return 2 + advance; - - trunc: - return -1; } -static int +static unsigned lwres_printbinlen(netdissect_options *ndo, - const char *p0) + const u_char *p0) { - const char *p; + const u_char *p; uint16_t l; int i; p = p0; - if (p + 2 > (const char *)ndo->ndo_snapend) - goto trunc; - l = EXTRACT_16BITS(p); - if (p + 2 + l > (const char *)ndo->ndo_snapend) - goto trunc; + l = GET_BE_U_2(p); p += 2; - for (i = 0; i < l; i++) - ND_PRINT((ndo, "%02x", *p++)); - return p - p0; - - trunc: - return -1; + for (i = 0; i < l; i++) { + ND_PRINT("%02x", GET_U_1(p)); + p++; + } + return 2 + l; } static int lwres_printaddr(netdissect_options *ndo, - const lwres_addr_t *ap) + const u_char *p0) { + const u_char *p; + const lwres_addr_t *ap; uint16_t l; - const char *p; int i; - ND_TCHECK(ap->length); - l = EXTRACT_16BITS(&ap->length); - /* XXX ap points to packed struct */ - p = (const char *)&ap->length + sizeof(ap->length); - ND_TCHECK2(*p, l); + p = p0; + ap = (const lwres_addr_t *)p; + l = GET_BE_U_2(ap->length); + p += LWRES_ADDR_LEN; + ND_TCHECK_LEN(p, l); - switch (EXTRACT_32BITS(&ap->family)) { + switch (GET_BE_U_4(ap->family)) { case 1: /* IPv4 */ if (l < 4) return -1; - ND_PRINT((ndo, " %s", ipaddr_string(ndo, p))); - p += sizeof(struct in_addr); + ND_PRINT(" %s", GET_IPADDR_STRING(p)); + p += sizeof(nd_ipv4); break; case 2: /* IPv6 */ if (l < 16) return -1; - ND_PRINT((ndo, " %s", ip6addr_string(ndo, p))); - p += sizeof(struct in6_addr); + ND_PRINT(" %s", GET_IP6ADDR_STRING(p)); + p += sizeof(nd_ipv6); break; default: - ND_PRINT((ndo, " %u/", EXTRACT_32BITS(&ap->family))); - for (i = 0; i < l; i++) - ND_PRINT((ndo, "%02x", *p++)); + ND_PRINT(" %u/", GET_BE_U_4(ap->family)); + for (i = 0; i < l; i++) { + ND_PRINT("%02x", GET_U_1(p)); + p++; + } } - return p - (const char *)ap; - - trunc: - return -1; + return ND_BYTES_BETWEEN(p, p0); } void lwres_print(netdissect_options *ndo, - register const u_char *bp, u_int length) + const u_char *bp, u_int length) { + const u_char *p; const struct lwres_lwpacket *np; uint32_t v; - const char *s; + const u_char *s; int response; int advance; int unsupported = 0; + ndo->ndo_protocol = "lwres"; np = (const struct lwres_lwpacket *)bp; - ND_TCHECK(np->authlength); + ND_TCHECK_2(np->authlength); - ND_PRINT((ndo, " lwres")); - v = EXTRACT_16BITS(&np->version); + ND_PRINT(" lwres"); + v = GET_BE_U_2(np->version); if (ndo->ndo_vflag || v != LWRES_LWPACKETVERSION_0) - ND_PRINT((ndo, " v%u", v)); + ND_PRINT(" v%u", v); if (v != LWRES_LWPACKETVERSION_0) { - s = (const char *)np + EXTRACT_32BITS(&np->length); + s = bp + GET_BE_U_4(np->length); goto tail; } - response = EXTRACT_16BITS(&np->pktflags) & LWRES_LWPACKETFLAG_RESPONSE; + response = GET_BE_U_2(np->pktflags) & LWRES_LWPACKETFLAG_RESPONSE; /* opcode and pktflags */ - v = EXTRACT_32BITS(&np->opcode); - s = tok2str(opcode, "#0x%x", v); - ND_PRINT((ndo, " %s%s", s, response ? "" : "?")); + v = GET_BE_U_4(np->opcode); + ND_PRINT(" %s%s", tok2str(opcode, "#0x%x", v), response ? "" : "?"); /* pktflags */ - v = EXTRACT_16BITS(&np->pktflags); + v = GET_BE_U_2(np->pktflags); if (v & ~LWRES_LWPACKETFLAG_RESPONSE) - ND_PRINT((ndo, "[0x%x]", v)); + ND_PRINT("[0x%x]", v); if (ndo->ndo_vflag > 1) { - ND_PRINT((ndo, " (")); /*)*/ - ND_PRINT((ndo, "serial:0x%x", EXTRACT_32BITS(&np->serial))); - ND_PRINT((ndo, " result:0x%x", EXTRACT_32BITS(&np->result))); - ND_PRINT((ndo, " recvlen:%u", EXTRACT_32BITS(&np->recvlength))); + ND_PRINT(" ("); /*)*/ + ND_PRINT("serial:0x%x", GET_BE_U_4(np->serial)); + ND_PRINT(" result:0x%x", GET_BE_U_4(np->result)); + ND_PRINT(" recvlen:%u", GET_BE_U_4(np->recvlength)); /* BIND910: not used */ if (ndo->ndo_vflag > 2) { - ND_PRINT((ndo, " authtype:0x%x", EXTRACT_16BITS(&np->authtype))); - ND_PRINT((ndo, " authlen:%u", EXTRACT_16BITS(&np->authlength))); + ND_PRINT(" authtype:0x%x", GET_BE_U_2(np->authtype)); + ND_PRINT(" authlen:%u", GET_BE_U_2(np->authlength)); } /*(*/ - ND_PRINT((ndo, ")")); + ND_PRINT(")"); } /* per-opcode content */ @@ -351,89 +334,82 @@ lwres_print(netdissect_options *ndo, gnba = NULL; grbn = NULL; - switch (EXTRACT_32BITS(&np->opcode)) { + p = (const u_char *)(np + 1); + switch (GET_BE_U_4(np->opcode)) { case LWRES_OPCODE_NOOP: + s = p; break; case LWRES_OPCODE_GETADDRSBYNAME: - gabn = (const lwres_gabnrequest_t *)(np + 1); - ND_TCHECK(gabn->namelen); - /* XXX gabn points to packed struct */ - s = (const char *)&gabn->namelen + - sizeof(gabn->namelen); - l = EXTRACT_16BITS(&gabn->namelen); + gabn = (const lwres_gabnrequest_t *)p; + ND_TCHECK_2(gabn->namelen); /* BIND910: not used */ if (ndo->ndo_vflag > 2) { - ND_PRINT((ndo, " flags:0x%x", - EXTRACT_32BITS(&gabn->flags))); + ND_PRINT(" flags:0x%x", + GET_BE_U_4(gabn->flags)); } - v = EXTRACT_32BITS(&gabn->addrtypes); + v = GET_BE_U_4(gabn->addrtypes); switch (v & (LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6)) { case LWRES_ADDRTYPE_V4: - ND_PRINT((ndo, " IPv4")); + ND_PRINT(" IPv4"); break; case LWRES_ADDRTYPE_V6: - ND_PRINT((ndo, " IPv6")); + ND_PRINT(" IPv6"); break; case LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6: - ND_PRINT((ndo, " IPv4/6")); + ND_PRINT(" IPv4/6"); break; } if (v & ~(LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6)) - ND_PRINT((ndo, "[0x%x]", v)); + ND_PRINT("[0x%x]", v); + s = p + LWRES_GABNREQUEST_LEN; + l = GET_BE_U_2(gabn->namelen); advance = lwres_printname(ndo, l, s); - if (advance < 0) - goto trunc; s += advance; break; case LWRES_OPCODE_GETNAMEBYADDR: - gnba = (const lwres_gnbarequest_t *)(np + 1); - ND_TCHECK(gnba->addr); + gnba = (const lwres_gnbarequest_t *)p; + ND_TCHECK_4(gnba->flags); /* BIND910: not used */ if (ndo->ndo_vflag > 2) { - ND_PRINT((ndo, " flags:0x%x", - EXTRACT_32BITS(&gnba->flags))); + ND_PRINT(" flags:0x%x", + GET_BE_U_4(gnba->flags)); } - s = (const char *)&gnba->addr; - - advance = lwres_printaddr(ndo, &gnba->addr); + s = p + LWRES_GNBAREQUEST_LEN; + advance = lwres_printaddr(ndo, s); if (advance < 0) - goto trunc; + goto invalid; s += advance; break; case LWRES_OPCODE_GETRDATABYNAME: /* XXX no trace, not tested */ - grbn = (const lwres_grbnrequest_t *)(np + 1); - ND_TCHECK(grbn->namelen); + grbn = (const lwres_grbnrequest_t *)p; + ND_TCHECK_2(grbn->namelen); /* BIND910: not used */ if (ndo->ndo_vflag > 2) { - ND_PRINT((ndo, " flags:0x%x", - EXTRACT_32BITS(&grbn->flags))); + ND_PRINT(" flags:0x%x", + GET_BE_U_4(grbn->flags)); } - ND_PRINT((ndo, " %s", tok2str(ns_type2str, "Type%d", - EXTRACT_16BITS(&grbn->rdtype)))); - if (EXTRACT_16BITS(&grbn->rdclass) != C_IN) { - ND_PRINT((ndo, " %s", tok2str(ns_class2str, "Class%d", - EXTRACT_16BITS(&grbn->rdclass)))); + ND_PRINT(" %s", tok2str(ns_type2str, "Type%u", + GET_BE_U_2(grbn->rdtype))); + if (GET_BE_U_2(grbn->rdclass) != C_IN) { + ND_PRINT(" %s", tok2str(ns_class2str, "Class%u", + GET_BE_U_2(grbn->rdclass))); } - /* XXX grbn points to packed struct */ - s = (const char *)&grbn->namelen + - sizeof(grbn->namelen); - l = EXTRACT_16BITS(&grbn->namelen); - + s = p + LWRES_GRBNREQUEST_LEN; + l = GET_BE_U_2(grbn->namelen); advance = lwres_printname(ndo, l, s); - if (advance < 0) - goto trunc; s += advance; break; default: + s = p; unsupported++; break; } @@ -451,130 +427,114 @@ lwres_print(netdissect_options *ndo, gnba = NULL; grbn = NULL; - switch (EXTRACT_32BITS(&np->opcode)) { + p = (const u_char *)(np + 1); + switch (GET_BE_U_4(np->opcode)) { case LWRES_OPCODE_NOOP: + s = p; break; case LWRES_OPCODE_GETADDRSBYNAME: - gabn = (const lwres_gabnresponse_t *)(np + 1); - ND_TCHECK(gabn->realnamelen); - /* XXX gabn points to packed struct */ - s = (const char *)&gabn->realnamelen + - sizeof(gabn->realnamelen); - l = EXTRACT_16BITS(&gabn->realnamelen); + gabn = (const lwres_gabnresponse_t *)p; + ND_TCHECK_2(gabn->realnamelen); /* BIND910: not used */ if (ndo->ndo_vflag > 2) { - ND_PRINT((ndo, " flags:0x%x", - EXTRACT_32BITS(&gabn->flags))); + ND_PRINT(" flags:0x%x", + GET_BE_U_4(gabn->flags)); } - ND_PRINT((ndo, " %u/%u", EXTRACT_16BITS(&gabn->naliases), - EXTRACT_16BITS(&gabn->naddrs))); + ND_PRINT(" %u/%u", GET_BE_U_2(gabn->naliases), + GET_BE_U_2(gabn->naddrs)); + s = p + LWRES_GABNRESPONSE_LEN; + l = GET_BE_U_2(gabn->realnamelen); advance = lwres_printname(ndo, l, s); - if (advance < 0) - goto trunc; s += advance; /* aliases */ - na = EXTRACT_16BITS(&gabn->naliases); + na = GET_BE_U_2(gabn->naliases); for (i = 0; i < na; i++) { advance = lwres_printnamelen(ndo, s); - if (advance < 0) - goto trunc; s += advance; } /* addrs */ - na = EXTRACT_16BITS(&gabn->naddrs); + na = GET_BE_U_2(gabn->naddrs); for (i = 0; i < na; i++) { - advance = lwres_printaddr(ndo, (const lwres_addr_t *)s); + advance = lwres_printaddr(ndo, s); if (advance < 0) - goto trunc; + goto invalid; s += advance; } break; case LWRES_OPCODE_GETNAMEBYADDR: - gnba = (const lwres_gnbaresponse_t *)(np + 1); - ND_TCHECK(gnba->realnamelen); - /* XXX gnba points to packed struct */ - s = (const char *)&gnba->realnamelen + - sizeof(gnba->realnamelen); - l = EXTRACT_16BITS(&gnba->realnamelen); + gnba = (const lwres_gnbaresponse_t *)p; + ND_TCHECK_2(gnba->realnamelen); /* BIND910: not used */ if (ndo->ndo_vflag > 2) { - ND_PRINT((ndo, " flags:0x%x", - EXTRACT_32BITS(&gnba->flags))); + ND_PRINT(" flags:0x%x", + GET_BE_U_4(gnba->flags)); } - ND_PRINT((ndo, " %u", EXTRACT_16BITS(&gnba->naliases))); + ND_PRINT(" %u", GET_BE_U_2(gnba->naliases)); + s = p + LWRES_GNBARESPONSE_LEN; + l = GET_BE_U_2(gnba->realnamelen); advance = lwres_printname(ndo, l, s); - if (advance < 0) - goto trunc; s += advance; /* aliases */ - na = EXTRACT_16BITS(&gnba->naliases); + na = GET_BE_U_2(gnba->naliases); for (i = 0; i < na; i++) { advance = lwres_printnamelen(ndo, s); - if (advance < 0) - goto trunc; s += advance; } break; case LWRES_OPCODE_GETRDATABYNAME: /* XXX no trace, not tested */ - grbn = (const lwres_grbnresponse_t *)(np + 1); - ND_TCHECK(grbn->nsigs); + grbn = (const lwres_grbnresponse_t *)p; + ND_TCHECK_2(grbn->nsigs); /* BIND910: not used */ if (ndo->ndo_vflag > 2) { - ND_PRINT((ndo, " flags:0x%x", - EXTRACT_32BITS(&grbn->flags))); + ND_PRINT(" flags:0x%x", + GET_BE_U_4(grbn->flags)); } - ND_PRINT((ndo, " %s", tok2str(ns_type2str, "Type%d", - EXTRACT_16BITS(&grbn->rdtype)))); - if (EXTRACT_16BITS(&grbn->rdclass) != C_IN) { - ND_PRINT((ndo, " %s", tok2str(ns_class2str, "Class%d", - EXTRACT_16BITS(&grbn->rdclass)))); + ND_PRINT(" %s", tok2str(ns_type2str, "Type%u", + GET_BE_U_2(grbn->rdtype))); + if (GET_BE_U_2(grbn->rdclass) != C_IN) { + ND_PRINT(" %s", tok2str(ns_class2str, "Class%u", + GET_BE_U_2(grbn->rdclass))); } - ND_PRINT((ndo, " TTL ")); - unsigned_relts_print(ndo, EXTRACT_32BITS(&grbn->ttl)); - ND_PRINT((ndo, " %u/%u", EXTRACT_16BITS(&grbn->nrdatas), - EXTRACT_16BITS(&grbn->nsigs))); - - /* XXX grbn points to packed struct */ - s = (const char *)&grbn->nsigs+ sizeof(grbn->nsigs); + ND_PRINT(" TTL "); + unsigned_relts_print(ndo, + GET_BE_U_4(grbn->ttl)); + ND_PRINT(" %u/%u", GET_BE_U_2(grbn->nrdatas), + GET_BE_U_2(grbn->nsigs)); + s = p + LWRES_GRBNRESPONSE_LEN; advance = lwres_printnamelen(ndo, s); - if (advance < 0) - goto trunc; s += advance; /* rdatas */ - na = EXTRACT_16BITS(&grbn->nrdatas); + na = GET_BE_U_2(grbn->nrdatas); for (i = 0; i < na; i++) { /* XXX should decode resource data */ advance = lwres_printbinlen(ndo, s); - if (advance < 0) - goto trunc; s += advance; } /* sigs */ - na = EXTRACT_16BITS(&grbn->nsigs); + na = GET_BE_U_2(grbn->nsigs); for (i = 0; i < na; i++) { /* XXX how should we print it? */ advance = lwres_printbinlen(ndo, s); - if (advance < 0) - goto trunc; s += advance; } break; default: + s = p; unsupported++; break; } @@ -582,14 +542,14 @@ lwres_print(netdissect_options *ndo, tail: /* length mismatch */ - if (EXTRACT_32BITS(&np->length) != length) { - ND_PRINT((ndo, " [len: %u != %u]", EXTRACT_32BITS(&np->length), - length)); + if (GET_BE_U_4(np->length) != length) { + ND_PRINT(" [len: %u != %u]", GET_BE_U_4(np->length), + length); } - if (!unsupported && s < (const char *)np + EXTRACT_32BITS(&np->length)) - ND_PRINT((ndo, "[extra]")); + if (!unsupported && s < bp + GET_BE_U_4(np->length)) + ND_PRINT("[extra]"); return; - trunc: - ND_PRINT((ndo, "[|lwres]")); + invalid: + nd_print_invalid(ndo); } diff --git a/contrib/tcpdump/print-m3ua.c b/contrib/tcpdump/print-m3ua.c index 71a585ffed..ecf7db8343 100644 --- a/contrib/tcpdump/print-m3ua.c +++ b/contrib/tcpdump/print-m3ua.c @@ -27,29 +27,29 @@ /* RFC 4666 */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" -static const char tstr[] = " [|m3ua]"; #define M3UA_REL_1_0 1 struct m3ua_common_header { - uint8_t v; - uint8_t reserved; - uint8_t msg_class; - uint8_t msg_type; - uint32_t len; + nd_uint8_t v; + nd_uint8_t reserved; + nd_uint8_t msg_class; + nd_uint8_t msg_type; + nd_uint32_t len; }; struct m3ua_param_header { - uint16_t tag; - uint16_t len; + nd_uint16_t tag; + nd_uint16_t len; }; /* message classes */ @@ -153,6 +153,16 @@ static const struct tok RoutingKeyMgmtMessages[] = { { 0, NULL } }; +static const struct uint_tokary m3ua_msgc2tokary[] = { + { M3UA_MSGC_MGMT, MgmtMessages }, + { M3UA_MSGC_TRANSFER, TransferMessages }, + { M3UA_MSGC_SSNM, SS7Messages }, + { M3UA_MSGC_ASPSM, ASPStateMessages }, + { M3UA_MSGC_ASPTM, ASPTrafficMessages }, + { M3UA_MSGC_RKM, RoutingKeyMgmtMessages }, + /* uint2tokary() does not use array termination. */ +}; + /* M3UA Parameters */ #define M3UA_PARAM_INFO 0x0004 #define M3UA_PARAM_ROUTING_CTX 0x0006 @@ -219,22 +229,18 @@ tag_value_print(netdissect_options *ndo, /* buf and size don't include the header */ if (size < 4) goto invalid; - ND_TCHECK2(*buf, size); - ND_PRINT((ndo, "0x%08x", EXTRACT_32BITS(buf))); + ND_PRINT("0x%08x", GET_BE_U_4(buf)); break; /* ... */ default: - ND_PRINT((ndo, "(length %u)", size + (u_int)sizeof(struct m3ua_param_header))); - ND_TCHECK2(*buf, size); + ND_PRINT("(length %zu)", size + sizeof(struct m3ua_param_header)); } + ND_TCHECK_LEN(buf, size); return; invalid: - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*buf, size); - return; -trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_invalid(ndo); + ND_TCHECK_LEN(buf, size); } /* @@ -260,29 +266,25 @@ m3ua_tags_print(netdissect_options *ndo, while (p < buf + size) { if (p + sizeof(struct m3ua_param_header) > buf + size) goto invalid; - ND_TCHECK2(*p, sizeof(struct m3ua_param_header)); /* Parameter Tag */ - hdr_tag = EXTRACT_16BITS(p); - ND_PRINT((ndo, "\n\t\t\t%s: ", tok2str(ParamName, "Unknown Parameter (0x%04x)", hdr_tag))); + hdr_tag = GET_BE_U_2(p); + ND_PRINT("\n\t\t\t%s: ", tok2str(ParamName, "Unknown Parameter (0x%04x)", hdr_tag)); /* Parameter Length */ - hdr_len = EXTRACT_16BITS(p + 2); + hdr_len = GET_BE_U_2(p + 2); if (hdr_len < sizeof(struct m3ua_param_header)) goto invalid; /* Parameter Value */ align = (p + hdr_len - buf) % 4; align = align ? 4 - align : 0; - ND_TCHECK2(*p, hdr_len + align); + ND_TCHECK_LEN(p, hdr_len + align); tag_value_print(ndo, p, hdr_tag, hdr_len - sizeof(struct m3ua_param_header)); p += hdr_len + align; } return; invalid: - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*buf, size); - return; -trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_invalid(ndo); + ND_TCHECK_LEN(buf, size); } /* @@ -302,38 +304,34 @@ m3ua_print(netdissect_options *ndo, { const struct m3ua_common_header *hdr = (const struct m3ua_common_header *) buf; const struct tok *dict; + uint8_t msg_class; + ndo->ndo_protocol = "m3ua"; /* size includes the header */ if (size < sizeof(struct m3ua_common_header)) goto invalid; - ND_TCHECK(*hdr); - if (hdr->v != M3UA_REL_1_0) + ND_TCHECK_SIZE(hdr); + if (GET_U_1(hdr->v) != M3UA_REL_1_0) return; - dict = - hdr->msg_class == M3UA_MSGC_MGMT ? MgmtMessages : - hdr->msg_class == M3UA_MSGC_TRANSFER ? TransferMessages : - hdr->msg_class == M3UA_MSGC_SSNM ? SS7Messages : - hdr->msg_class == M3UA_MSGC_ASPSM ? ASPStateMessages : - hdr->msg_class == M3UA_MSGC_ASPTM ? ASPTrafficMessages : - hdr->msg_class == M3UA_MSGC_RKM ? RoutingKeyMgmtMessages : - NULL; + msg_class = GET_U_1(hdr->msg_class); + dict = uint2tokary(m3ua_msgc2tokary, msg_class); - ND_PRINT((ndo, "\n\t\t%s", tok2str(MessageClasses, "Unknown message class %i", hdr->msg_class))); + ND_PRINT("\n\t\t%s", tok2str(MessageClasses, "Unknown message class %i", msg_class)); if (dict != NULL) - ND_PRINT((ndo, " %s Message", tok2str(dict, "Unknown (0x%02x)", hdr->msg_type))); + ND_PRINT(" %s Message", + tok2str(dict, "Unknown (0x%02x)", GET_U_1(hdr->msg_type))); - if (size != EXTRACT_32BITS(&hdr->len)) - ND_PRINT((ndo, "\n\t\t\t@@@@@@ Corrupted length %u of message @@@@@@", EXTRACT_32BITS(&hdr->len))); + if (size != GET_BE_U_4(hdr->len)) + ND_PRINT("\n\t\t\t@@@@@@ Corrupted length %u of message @@@@@@", + GET_BE_U_4(hdr->len)); else - m3ua_tags_print(ndo, buf + sizeof(struct m3ua_common_header), EXTRACT_32BITS(&hdr->len) - sizeof(struct m3ua_common_header)); + m3ua_tags_print(ndo, buf + sizeof(struct m3ua_common_header), + GET_BE_U_4(hdr->len) - sizeof(struct m3ua_common_header)); return; invalid: - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*buf, size); - return; -trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_invalid(ndo); + ND_TCHECK_LEN(buf, size); } diff --git a/contrib/tcpdump/print-macsec.c b/contrib/tcpdump/print-macsec.c new file mode 100644 index 0000000000..607f696ef2 --- /dev/null +++ b/contrib/tcpdump/print-macsec.c @@ -0,0 +1,256 @@ +/* Copyright (c) 2017, Sabrina Dubroca + * + * 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. The names of the authors 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. + */ + +/* \summary: MACsec printer */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "netdissect-stdinc.h" + +#include "netdissect.h" +#include "addrtoname.h" +#include "ethertype.h" +#include "extract.h" + +#define MACSEC_DEFAULT_ICV_LEN 16 + +/* Header format (SecTAG), following an Ethernet header + * IEEE 802.1AE-2006 9.3 + * + * +---------------------------------+----------------+----------------+ + * | (MACsec ethertype) | TCI_AN | SL | + * +---------------------------------+----------------+----------------+ + * | Packet Number | + * +-------------------------------------------------------------------+ + * | Secure Channel Identifier | + * | (optional) | + * +-------------------------------------------------------------------+ + * + * MACsec ethertype = 0x88e5 + * TCI: Tag Control Information, set of flags + * AN: association number, 2 bits + * SL (short length): 6-bit length of the protected payload, if < 48 + * Packet Number: 32-bits packet identifier + * Secure Channel Identifier: 64-bit unique identifier, usually + * composed of a MAC address + 16-bit port number + */ +struct macsec_sectag { + nd_uint8_t tci_an; + nd_uint8_t short_length; + nd_uint32_t packet_number; + nd_uint8_t secure_channel_id[8]; /* optional */ +}; + +/* IEEE 802.1AE-2006 9.5 */ +#define MACSEC_TCI_VERSION 0x80 +#define MACSEC_TCI_ES 0x40 /* end station */ +#define MACSEC_TCI_SC 0x20 /* SCI present */ +#define MACSEC_TCI_SCB 0x10 /* epon */ +#define MACSEC_TCI_E 0x08 /* encryption */ +#define MACSEC_TCI_C 0x04 /* changed text */ +#define MACSEC_AN_MASK 0x03 /* association number */ +#define MACSEC_TCI_FLAGS (MACSEC_TCI_ES | MACSEC_TCI_SC | MACSEC_TCI_SCB | MACSEC_TCI_E | MACSEC_TCI_C) +#define MACSEC_TCI_CONFID (MACSEC_TCI_E | MACSEC_TCI_C) +#define MACSEC_SL_MASK 0x3F /* short length */ + +#define MACSEC_SECTAG_LEN_NOSCI 6 /* length of MACsec header without SCI */ +#define MACSEC_SECTAG_LEN_SCI 14 /* length of MACsec header with SCI */ + +#define SCI_FMT "%016" PRIx64 + +static const struct tok macsec_flag_values[] = { + { MACSEC_TCI_E, "E" }, + { MACSEC_TCI_C, "C" }, + { MACSEC_TCI_ES, "S" }, + { MACSEC_TCI_SCB, "B" }, + { MACSEC_TCI_SC, "I" }, + { 0, NULL } +}; + +static void macsec_print_header(netdissect_options *ndo, + const struct macsec_sectag *sectag, + u_int short_length) +{ + ND_PRINT("an %u, pn %u, flags %s", + GET_U_1(sectag->tci_an) & MACSEC_AN_MASK, + GET_BE_U_4(sectag->packet_number), + bittok2str_nosep(macsec_flag_values, "none", + GET_U_1(sectag->tci_an) & MACSEC_TCI_FLAGS)); + + if (short_length != 0) + ND_PRINT(", sl %u", short_length); + + if (GET_U_1(sectag->tci_an) & MACSEC_TCI_SC) + ND_PRINT(", sci " SCI_FMT, GET_BE_U_8(sectag->secure_channel_id)); + + ND_PRINT(", "); +} + +/* returns < 0 iff the packet can be decoded completely */ +int macsec_print(netdissect_options *ndo, const u_char **bp, + u_int *lengthp, u_int *caplenp, u_int *hdrlenp, + const struct lladdr_info *src, const struct lladdr_info *dst) +{ + const char *save_protocol; + const u_char *p = *bp; + u_int length = *lengthp; + u_int caplen = *caplenp; + u_int hdrlen = *hdrlenp; + const struct macsec_sectag *sectag = (const struct macsec_sectag *)p; + u_int sectag_len; + u_int short_length; + + save_protocol = ndo->ndo_protocol; + ndo->ndo_protocol = "macsec"; + + /* we need the full MACsec header in the capture */ + if (caplen < MACSEC_SECTAG_LEN_NOSCI) { + nd_print_trunc(ndo); + ndo->ndo_protocol = save_protocol; + return hdrlen + caplen; + } + if (length < MACSEC_SECTAG_LEN_NOSCI) { + nd_print_trunc(ndo); + ndo->ndo_protocol = save_protocol; + return hdrlen + caplen; + } + + if (GET_U_1(sectag->tci_an) & MACSEC_TCI_SC) { + sectag_len = MACSEC_SECTAG_LEN_SCI; + if (caplen < MACSEC_SECTAG_LEN_SCI) { + nd_print_trunc(ndo); + ndo->ndo_protocol = save_protocol; + return hdrlen + caplen; + } + if (length < MACSEC_SECTAG_LEN_SCI) { + nd_print_trunc(ndo); + ndo->ndo_protocol = save_protocol; + return hdrlen + caplen; + } + } else + sectag_len = MACSEC_SECTAG_LEN_NOSCI; + + if ((GET_U_1(sectag->short_length) & ~MACSEC_SL_MASK) != 0 || + GET_U_1(sectag->tci_an) & MACSEC_TCI_VERSION) { + nd_print_invalid(ndo); + ndo->ndo_protocol = save_protocol; + return hdrlen + caplen; + } + + short_length = GET_U_1(sectag->short_length) & MACSEC_SL_MASK; + if (ndo->ndo_eflag) + macsec_print_header(ndo, sectag, short_length); + + /* Skip the MACsec header. */ + *bp += sectag_len; + *hdrlenp += sectag_len; + + /* Remove it from the lengths, as it's been processed. */ + *lengthp -= sectag_len; + *caplenp -= sectag_len; + + if ((GET_U_1(sectag->tci_an) & MACSEC_TCI_CONFID)) { + /* + * The payload is encrypted. Print link-layer + * information, if it hasn't already been printed. + */ + if (!ndo->ndo_eflag) { + /* + * Nobody printed the link-layer addresses, + * so print them, if we have any. + */ + if (src != NULL && dst != NULL) { + ND_PRINT("%s > %s ", + (src->addr_string)(ndo, src->addr), + (dst->addr_string)(ndo, dst->addr)); + } + + ND_PRINT("802.1AE MACsec, "); + + /* + * Print the MACsec header. + */ + macsec_print_header(ndo, sectag, short_length); + } + + /* + * Tell our caller it can't be dissected. + */ + ndo->ndo_protocol = save_protocol; + return 0; + } + + /* + * The payload isn't encrypted; remove the + * ICV length from the lengths, so our caller + * doesn't treat it as payload. + */ + if (*lengthp < MACSEC_DEFAULT_ICV_LEN) { + nd_print_trunc(ndo); + ndo->ndo_protocol = save_protocol; + return hdrlen + caplen; + } + if (*caplenp < MACSEC_DEFAULT_ICV_LEN) { + nd_print_trunc(ndo); + ndo->ndo_protocol = save_protocol; + return hdrlen + caplen; + } + *lengthp -= MACSEC_DEFAULT_ICV_LEN; + *caplenp -= MACSEC_DEFAULT_ICV_LEN; + /* + * Update the snapend thus the ICV field is not in the payload for + * the caller. + * The ICV (Integrity Check Value) is at the end of the frame, after + * the secure data. + */ + ndo->ndo_snapend -= MACSEC_DEFAULT_ICV_LEN; + + /* + * If the SL field is non-zero, then it's the length of the + * Secure Data; otherwise, the Secure Data is what's left + * ver after the MACsec header and ICV are removed. + */ + if (short_length != 0) { + /* + * If the short length is more than we *have*, + * that's an error. + */ + if (short_length > *lengthp) { + nd_print_trunc(ndo); + ndo->ndo_protocol = save_protocol; + return hdrlen + caplen; + } + if (short_length > *caplenp) { + nd_print_trunc(ndo); + ndo->ndo_protocol = save_protocol; + return hdrlen + caplen; + } + if (*lengthp > short_length) + *lengthp = short_length; + if (*caplenp > short_length) + *caplenp = short_length; + } + + ndo->ndo_protocol = save_protocol; + return -1; +} diff --git a/contrib/tcpdump/print-medsa.c b/contrib/tcpdump/print-medsa.c deleted file mode 100644 index 4895fd94a4..0000000000 --- a/contrib/tcpdump/print-medsa.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (c) 1988, 1989, 1990, 1991, 1992, 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. - */ - -/* \summary: Marvell Extended Distributed Switch Architecture (MEDSA) printer */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "netdissect.h" -#include "ether.h" -#include "ethertype.h" -#include "addrtoname.h" -#include "extract.h" - -static const char tstr[] = "[|MEDSA]"; - -/* - * Marvell Extended Distributed Switch Archiecture. - * - * A Marvell propriatary header used for passing packets to/from - * specific ports of a switch. There is no open specification of this - * header, but is documented in the Marvell Switch data sheets. For - * background, see: - * - * https://lwn.net/Articles/302333/ - */ -struct medsa_pkthdr { - u_char bytes[6]; - u_short ether_type; -}; - -/* Bytes 0 and 1 are reserved and should contain 0 */ -#define TAG(medsa) (medsa->bytes[2] >> 6) -#define TAG_TO_CPU 0 -#define TAG_FROM_CPU 1 -#define TAG_FORWARD 3 -#define SRC_TAG(medsa) ((medsa->bytes[2] >> 5) & 0x01) -#define SRC_DEV(medsa) (medsa->bytes[2] & 0x1f) -#define SRC_PORT(medsa) ((medsa->bytes[3] >> 3) & 0x01f) -#define TRUNK(medsa) ((medsa->bytes[3] >> 2) & 0x01) -#define CODE(medsa) ((medsa->bytes[3] & 0x06) | \ - ((medsa->bytes[4] >> 4) & 0x01)) -#define CODE_BDPU 0 -#define CODE_IGMP_MLD 2 -#define CODE_ARP_MIRROR 4 -#define CFI(medsa) (medsa->bytes[3] & 0x01) -#define PRI(medsa) (medsa->bytes[4] >> 5) -#define VID(medsa) (((u_short)(medsa->bytes[4] & 0xf) << 8 | \ - medsa->bytes[5])) - -static const struct tok tag_values[] = { - { TAG_TO_CPU, "To_CPU" }, - { TAG_FROM_CPU, "From_CPU" }, - { TAG_FORWARD, "Forward" }, - { 0, NULL }, -}; - -static const struct tok code_values[] = { - { CODE_BDPU, "BDPU" }, - { CODE_IGMP_MLD, "IGMP/MLD" }, - { CODE_ARP_MIRROR, "APR_Mirror" }, - { 0, NULL }, -}; - -static void -medsa_print_full(netdissect_options *ndo, - const struct medsa_pkthdr *medsa, - u_int caplen) -{ - u_char tag = TAG(medsa); - - ND_PRINT((ndo, "%s", - tok2str(tag_values, "Unknown (%u)", tag))); - - switch (tag) { - case TAG_TO_CPU: - ND_PRINT((ndo, ", %stagged", SRC_TAG(medsa) ? "" : "un")); - ND_PRINT((ndo, ", dev.port:vlan %d.%d:%d", - SRC_DEV(medsa), SRC_PORT(medsa), VID(medsa))); - - ND_PRINT((ndo, ", %s", - tok2str(code_values, "Unknown (%u)", CODE(medsa)))); - if (CFI(medsa)) - ND_PRINT((ndo, ", CFI")); - - ND_PRINT((ndo, ", pri %d: ", PRI(medsa))); - break; - case TAG_FROM_CPU: - ND_PRINT((ndo, ", %stagged", SRC_TAG(medsa) ? "" : "un")); - ND_PRINT((ndo, ", dev.port:vlan %d.%d:%d", - SRC_DEV(medsa), SRC_PORT(medsa), VID(medsa))); - - if (CFI(medsa)) - ND_PRINT((ndo, ", CFI")); - - ND_PRINT((ndo, ", pri %d: ", PRI(medsa))); - break; - case TAG_FORWARD: - ND_PRINT((ndo, ", %stagged", SRC_TAG(medsa) ? "" : "un")); - if (TRUNK(medsa)) - ND_PRINT((ndo, ", dev.trunk:vlan %d.%d:%d", - SRC_DEV(medsa), SRC_PORT(medsa), VID(medsa))); - else - ND_PRINT((ndo, ", dev.port:vlan %d.%d:%d", - SRC_DEV(medsa), SRC_PORT(medsa), VID(medsa))); - - if (CFI(medsa)) - ND_PRINT((ndo, ", CFI")); - - ND_PRINT((ndo, ", pri %d: ", PRI(medsa))); - break; - default: - ND_DEFAULTPRINT((const u_char *)medsa, caplen); - return; - } -} - -void -medsa_print(netdissect_options *ndo, - const u_char *bp, u_int length, u_int caplen, - const struct lladdr_info *src, const struct lladdr_info *dst) -{ - const struct medsa_pkthdr *medsa; - u_short ether_type; - - medsa = (const struct medsa_pkthdr *)bp; - ND_TCHECK(*medsa); - - if (!ndo->ndo_eflag) - ND_PRINT((ndo, "MEDSA %d.%d:%d: ", - SRC_DEV(medsa), SRC_PORT(medsa), VID(medsa))); - else - medsa_print_full(ndo, medsa, caplen); - - bp += 8; - length -= 8; - caplen -= 8; - - ether_type = EXTRACT_16BITS(&medsa->ether_type); - if (ether_type <= ETHERMTU) { - /* Try to print the LLC-layer header & higher layers */ - if (llc_print(ndo, bp, length, caplen, src, dst) < 0) { - /* packet type not known, print raw packet */ - if (!ndo->ndo_suppress_default_print) - ND_DEFAULTPRINT(bp, caplen); - } - } else { - if (ndo->ndo_eflag) - ND_PRINT((ndo, "ethertype %s (0x%04x) ", - tok2str(ethertype_values, "Unknown", - ether_type), - ether_type)); - if (ethertype_print(ndo, ether_type, bp, length, caplen, src, dst) == 0) { - /* ether_type not known, print raw packet */ - if (!ndo->ndo_eflag) - ND_PRINT((ndo, "ethertype %s (0x%04x) ", - tok2str(ethertype_values, "Unknown", - ether_type), - ether_type)); - - if (!ndo->ndo_suppress_default_print) - ND_DEFAULTPRINT(bp, caplen); - } - } - return; -trunc: - ND_PRINT((ndo, "%s", tstr)); -} - -/* - * Local Variables: - * c-style: bsd - * End: - */ - diff --git a/contrib/tcpdump/print-mobile.c b/contrib/tcpdump/print-mobile.c index 6d31648cb4..528da79c9f 100644 --- a/contrib/tcpdump/print-mobile.c +++ b/contrib/tcpdump/print-mobile.c @@ -39,10 +39,10 @@ /* \summary: IPv4 mobility printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "addrtoname.h" @@ -51,10 +51,10 @@ #define MOBILE_SIZE (8) struct mobile_ip { - uint16_t proto; - uint16_t hcheck; - uint32_t odst; - uint32_t osrc; + nd_uint16_t proto; + nd_uint16_t hcheck; + nd_uint32_t odst; + nd_uint32_t osrc; }; #define OSRC_PRES 0x0080 /* old source is present */ @@ -70,34 +70,35 @@ mobile_print(netdissect_options *ndo, const u_char *bp, u_int length) u_short proto,crc; u_char osp =0; /* old source address present */ + ndo->ndo_protocol = "mobile"; mob = (const struct mobile_ip *)bp; - if (length < MOBILE_SIZE || !ND_TTEST(*mob)) { - ND_PRINT((ndo, "[|mobile]")); + if (length < MOBILE_SIZE || !ND_TTEST_SIZE(mob)) { + nd_print_trunc(ndo); return; } - ND_PRINT((ndo, "mobile: ")); + ND_PRINT("mobile: "); - proto = EXTRACT_16BITS(&mob->proto); - crc = EXTRACT_16BITS(&mob->hcheck); + proto = GET_BE_U_2(mob->proto); + crc = GET_BE_U_2(mob->hcheck); if (proto & OSRC_PRES) { osp=1; } if (osp) { - ND_PRINT((ndo, "[S] ")); + ND_PRINT("[S] "); if (ndo->ndo_vflag) - ND_PRINT((ndo, "%s ", ipaddr_string(ndo, &mob->osrc))); + ND_PRINT("%s ", GET_IPADDR_STRING(mob->osrc)); } else { - ND_PRINT((ndo, "[] ")); + ND_PRINT("[] "); } if (ndo->ndo_vflag) { - ND_PRINT((ndo, "> %s ", ipaddr_string(ndo, &mob->odst))); - ND_PRINT((ndo, "(oproto=%d)", proto>>8)); + ND_PRINT("> %s ", GET_IPADDR_STRING(mob->odst)); + ND_PRINT("(oproto=%u)", proto>>8); } vec[0].ptr = (const uint8_t *)(const void *)mob; vec[0].len = osp ? 12 : 8; if (in_cksum(vec, 1)!=0) { - ND_PRINT((ndo, " (bad checksum %d)", crc)); + ND_PRINT(" (bad checksum %u)", crc); } } diff --git a/contrib/tcpdump/print-mobility.c b/contrib/tcpdump/print-mobility.c index feb4c98fea..55340ca56d 100644 --- a/contrib/tcpdump/print-mobility.c +++ b/contrib/tcpdump/print-mobility.c @@ -31,10 +31,10 @@ /* RFC 3775 */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "addrtoname.h" @@ -42,18 +42,17 @@ #include "ip6.h" -static const char tstr[] = "[|MOBILITY]"; /* Mobility header */ struct ip6_mobility { - uint8_t ip6m_pproto; /* following payload protocol (for PG) */ - uint8_t ip6m_len; /* length in units of 8 octets */ - uint8_t ip6m_type; /* message type */ - uint8_t reserved; /* reserved */ - uint16_t ip6m_cksum; /* sum of IPv6 pseudo-header and MH */ + nd_uint8_t ip6m_pproto; /* following payload protocol (for PG) */ + nd_uint8_t ip6m_len; /* length in units of 8 octets */ + nd_uint8_t ip6m_type; /* message type */ + nd_uint8_t reserved; /* reserved */ + nd_uint16_t ip6m_cksum; /* sum of IPv6 pseudo-header and MH */ union { - uint16_t ip6m_un_data16[1]; /* type-specific field */ - uint8_t ip6m_un_data8[2]; /* type-specific field */ + nd_uint16_t ip6m_un_data16[1]; /* type-specific field */ + nd_uint8_t ip6m_un_data8[2]; /* type-specific field */ } ip6m_dataun; }; @@ -62,7 +61,7 @@ struct ip6_mobility { #define IP6M_MINLEN 8 -/* http://www.iana.org/assignments/mobility-parameters/mobility-parameters.xhtml */ +/* https://www.iana.org/assignments/mobility-parameters/mobility-parameters.xhtml */ /* message type */ #define IP6M_BINDING_REQUEST 0 /* Binding Refresh Request */ @@ -111,6 +110,14 @@ static const unsigned ip6m_hdrlen[IP6M_MAX + 1] = { #define IP6MOPT_AUTH 0x5 /* Binding Authorization Data */ #define IP6MOPT_AUTH_MINLEN 12 +static const struct tok ip6m_binding_update_bits [] = { + { 0x08, "A" }, + { 0x04, "H" }, + { 0x02, "L" }, + { 0x01, "K" }, + { 0, NULL } +}; + static int mobility_opt_print(netdissect_options *ndo, const u_char *bp, const unsigned len) @@ -118,74 +125,70 @@ mobility_opt_print(netdissect_options *ndo, unsigned i, optlen; for (i = 0; i < len; i += optlen) { - ND_TCHECK(bp[i]); - if (bp[i] == IP6MOPT_PAD1) + if (GET_U_1(bp + i) == IP6MOPT_PAD1) optlen = 1; else { if (i + 1 < len) { - ND_TCHECK(bp[i + 1]); - optlen = bp[i + 1] + 2; + optlen = GET_U_1(bp + i + 1) + 2; } else goto trunc; } if (i + optlen > len) goto trunc; - ND_TCHECK(bp[i + optlen]); + ND_TCHECK_1(bp + i + optlen); - switch (bp[i]) { + switch (GET_U_1(bp + i)) { case IP6MOPT_PAD1: - ND_PRINT((ndo, "(pad1)")); + ND_PRINT("(pad1)"); break; case IP6MOPT_PADN: if (len - i < IP6MOPT_MINLEN) { - ND_PRINT((ndo, "(padn: trunc)")); + ND_PRINT("(padn: trunc)"); goto trunc; } - ND_PRINT((ndo, "(padn)")); + ND_PRINT("(padn)"); break; case IP6MOPT_REFRESH: if (len - i < IP6MOPT_REFRESH_MINLEN) { - ND_PRINT((ndo, "(refresh: trunc)")); + ND_PRINT("(refresh: trunc)"); goto trunc; } /* units of 4 secs */ - ND_TCHECK_16BITS(&bp[i+2]); - ND_PRINT((ndo, "(refresh: %u)", - EXTRACT_16BITS(&bp[i+2]) << 2)); + ND_PRINT("(refresh: %u)", + GET_BE_U_2(bp + i + 2) << 2); break; case IP6MOPT_ALTCOA: if (len - i < IP6MOPT_ALTCOA_MINLEN) { - ND_PRINT((ndo, "(altcoa: trunc)")); + ND_PRINT("(altcoa: trunc)"); goto trunc; } - ND_TCHECK_128BITS(&bp[i+2]); - ND_PRINT((ndo, "(alt-CoA: %s)", ip6addr_string(ndo, &bp[i+2]))); + ND_PRINT("(alt-CoA: %s)", GET_IP6ADDR_STRING(bp + i + 2)); break; case IP6MOPT_NONCEID: if (len - i < IP6MOPT_NONCEID_MINLEN) { - ND_PRINT((ndo, "(ni: trunc)")); + ND_PRINT("(ni: trunc)"); goto trunc; } - ND_TCHECK_16BITS(&bp[i+2]); - ND_TCHECK_16BITS(&bp[i+4]); - ND_PRINT((ndo, "(ni: ho=0x%04x co=0x%04x)", - EXTRACT_16BITS(&bp[i+2]), - EXTRACT_16BITS(&bp[i+4]))); + ND_PRINT("(ni: ho=0x%04x co=0x%04x)", + GET_BE_U_2(bp + i + 2), + GET_BE_U_2(bp + i + 4)); break; case IP6MOPT_AUTH: if (len - i < IP6MOPT_AUTH_MINLEN) { - ND_PRINT((ndo, "(auth: trunc)")); + ND_PRINT("(auth: trunc)"); goto trunc; } - ND_PRINT((ndo, "(auth)")); + ND_PRINT("(auth)"); break; default: if (len - i < IP6MOPT_MINLEN) { - ND_PRINT((ndo, "(sopt_type %u: trunc)", bp[i])); + ND_PRINT("(sopt_type %u: trunc)", + GET_U_1(bp + i)); goto trunc; } - ND_PRINT((ndo, "(type-0x%02x: len=%u)", bp[i], bp[i + 1])); + ND_PRINT("(type-0x%02x: len=%u)", GET_U_1(bp + i), + GET_U_1(bp + i + 1)); break; } } @@ -207,12 +210,13 @@ mobility_print(netdissect_options *ndo, unsigned mhlen, hlen; uint8_t type; + ndo->ndo_protocol = "mobility"; mh = (const struct ip6_mobility *)bp; /* 'ep' points to the end of available data. */ ep = ndo->ndo_snapend; - if (!ND_TTEST(mh->ip6m_len)) { + if (!ND_TTEST_1(mh->ip6m_len)) { /* * There's not enough captured data to include the * mobility header length. @@ -225,20 +229,19 @@ mobility_print(netdissect_options *ndo, * returned length, however, as it breaks out of the * header-processing loop. */ - mhlen = ep - bp; + mhlen = (unsigned)(ep - bp); goto trunc; } - mhlen = (mh->ip6m_len + 1) << 3; + mhlen = (GET_U_1(mh->ip6m_len) + 1) << 3; /* XXX ip6m_cksum */ - ND_TCHECK(mh->ip6m_type); - type = mh->ip6m_type; + type = GET_U_1(mh->ip6m_type); if (type <= IP6M_MAX && mhlen < ip6m_hdrlen[type]) { - ND_PRINT((ndo, "(header length %u is too small for type %u)", mhlen, type)); + ND_PRINT("(header length %u is too small for type %u)", mhlen, type); goto trunc; } - ND_PRINT((ndo, "mobility: %s", tok2str(ip6m_str, "type-#%u", type))); + ND_PRINT("mobility: %s", tok2str(ip6m_str, "type-#%u", type)); switch (type) { case IP6M_BINDING_REQUEST: hlen = IP6M_MINLEN; @@ -247,98 +250,85 @@ mobility_print(netdissect_options *ndo, case IP6M_CAREOF_TEST_INIT: hlen = IP6M_MINLEN; if (ndo->ndo_vflag) { - ND_TCHECK_32BITS(&bp[hlen + 4]); - ND_PRINT((ndo, " %s Init Cookie=%08x:%08x", + ND_PRINT(" %s Init Cookie=%08x:%08x", type == IP6M_HOME_TEST_INIT ? "Home" : "Care-of", - EXTRACT_32BITS(&bp[hlen]), - EXTRACT_32BITS(&bp[hlen + 4]))); + GET_BE_U_4(bp + hlen), + GET_BE_U_4(bp + hlen + 4)); } hlen += 8; break; case IP6M_HOME_TEST: case IP6M_CAREOF_TEST: - ND_TCHECK(mh->ip6m_data16[0]); - ND_PRINT((ndo, " nonce id=0x%x", EXTRACT_16BITS(&mh->ip6m_data16[0]))); + ND_PRINT(" nonce id=0x%x", GET_BE_U_2(mh->ip6m_data16[0])); hlen = IP6M_MINLEN; if (ndo->ndo_vflag) { - ND_TCHECK_32BITS(&bp[hlen + 4]); - ND_PRINT((ndo, " %s Init Cookie=%08x:%08x", + ND_PRINT(" %s Init Cookie=%08x:%08x", type == IP6M_HOME_TEST ? "Home" : "Care-of", - EXTRACT_32BITS(&bp[hlen]), - EXTRACT_32BITS(&bp[hlen + 4]))); + GET_BE_U_4(bp + hlen), + GET_BE_U_4(bp + hlen + 4)); } hlen += 8; if (ndo->ndo_vflag) { - ND_TCHECK_32BITS(&bp[hlen + 4]); - ND_PRINT((ndo, " %s Keygen Token=%08x:%08x", + ND_PRINT(" %s Keygen Token=%08x:%08x", type == IP6M_HOME_TEST ? "Home" : "Care-of", - EXTRACT_32BITS(&bp[hlen]), - EXTRACT_32BITS(&bp[hlen + 4]))); + GET_BE_U_4(bp + hlen), + GET_BE_U_4(bp + hlen + 4)); } hlen += 8; break; case IP6M_BINDING_UPDATE: - ND_TCHECK(mh->ip6m_data16[0]); - ND_PRINT((ndo, " seq#=%u", EXTRACT_16BITS(&mh->ip6m_data16[0]))); + { + int bits; + ND_PRINT(" seq#=%u", GET_BE_U_2(mh->ip6m_data16[0])); hlen = IP6M_MINLEN; - ND_TCHECK_16BITS(&bp[hlen]); - if (bp[hlen] & 0xf0) { - ND_PRINT((ndo, " ")); - if (bp[hlen] & 0x80) - ND_PRINT((ndo, "A")); - if (bp[hlen] & 0x40) - ND_PRINT((ndo, "H")); - if (bp[hlen] & 0x20) - ND_PRINT((ndo, "L")); - if (bp[hlen] & 0x10) - ND_PRINT((ndo, "K")); + ND_TCHECK_2(bp + hlen); + bits = (GET_U_1(bp + hlen) & 0xf0) >> 4; + if (bits) { + ND_PRINT(" "); + ND_PRINT("%s", + bittok2str_nosep(ip6m_binding_update_bits, + "bits-#0x%x", bits)); } /* Reserved (4bits) */ hlen += 1; /* Reserved (8bits) */ hlen += 1; - ND_TCHECK_16BITS(&bp[hlen]); /* units of 4 secs */ - ND_PRINT((ndo, " lifetime=%u", EXTRACT_16BITS(&bp[hlen]) << 2)); + ND_PRINT(" lifetime=%u", GET_BE_U_2(bp + hlen) << 2); hlen += 2; break; + } case IP6M_BINDING_ACK: - ND_TCHECK(mh->ip6m_data8[0]); - ND_PRINT((ndo, " status=%u", mh->ip6m_data8[0])); - ND_TCHECK(mh->ip6m_data8[1]); - if (mh->ip6m_data8[1] & 0x80) - ND_PRINT((ndo, " K")); + ND_PRINT(" status=%u", GET_U_1(mh->ip6m_data8[0])); + if (GET_U_1(mh->ip6m_data8[1]) & 0x80) + ND_PRINT(" K"); /* Reserved (7bits) */ hlen = IP6M_MINLEN; - ND_TCHECK_16BITS(&bp[hlen]); - ND_PRINT((ndo, " seq#=%u", EXTRACT_16BITS(&bp[hlen]))); + ND_PRINT(" seq#=%u", GET_BE_U_2(bp + hlen)); hlen += 2; - ND_TCHECK_16BITS(&bp[hlen]); /* units of 4 secs */ - ND_PRINT((ndo, " lifetime=%u", EXTRACT_16BITS(&bp[hlen]) << 2)); + ND_PRINT(" lifetime=%u", GET_BE_U_2(bp + hlen) << 2); hlen += 2; break; case IP6M_BINDING_ERROR: - ND_TCHECK(mh->ip6m_data8[0]); - ND_PRINT((ndo, " status=%u", mh->ip6m_data8[0])); + ND_PRINT(" status=%u", GET_U_1(mh->ip6m_data8[0])); /* Reserved */ hlen = IP6M_MINLEN; - ND_TCHECK2(bp[hlen], 16); - ND_PRINT((ndo, " homeaddr %s", ip6addr_string(ndo, &bp[hlen]))); + ND_PRINT(" homeaddr %s", GET_IP6ADDR_STRING(bp + hlen)); hlen += 16; break; default: - ND_PRINT((ndo, " len=%u", mh->ip6m_len)); + ND_PRINT(" len=%u", GET_U_1(mh->ip6m_len)); return(mhlen); break; } if (ndo->ndo_vflag) - if (mobility_opt_print(ndo, &bp[hlen], mhlen - hlen)) - goto trunc;; + if (mobility_opt_print(ndo, bp + hlen, mhlen - hlen)) + goto trunc; return(mhlen); trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return(-1); } diff --git a/contrib/tcpdump/print-mpcp.c b/contrib/tcpdump/print-mpcp.c index 3e022ad4a9..4ba873bf3f 100644 --- a/contrib/tcpdump/print-mpcp.c +++ b/contrib/tcpdump/print-mpcp.c @@ -18,20 +18,17 @@ /* \summary: IEEE 802.3ah Multi-Point Control Protocol (MPCP) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "extract.h" -#define MPCP_TIMESTAMP_LEN 4 -#define MPCP_TIMESTAMP_DURATION_LEN 2 - struct mpcp_common_header_t { - uint8_t opcode[2]; - uint8_t timestamp[MPCP_TIMESTAMP_LEN]; + nd_uint16_t opcode; + nd_uint32_t timestamp; }; #define MPCP_OPCODE_PAUSE 0x0001 @@ -63,13 +60,13 @@ static const struct tok mpcp_grant_flag_values[] = { }; struct mpcp_grant_t { - uint8_t starttime[MPCP_TIMESTAMP_LEN]; - uint8_t duration[MPCP_TIMESTAMP_DURATION_LEN]; + nd_uint32_t starttime; + nd_uint16_t duration; }; struct mpcp_reg_req_t { - uint8_t flags; - uint8_t pending_grants; + nd_uint8_t flags; + nd_uint8_t pending_grants; }; @@ -80,10 +77,10 @@ static const struct tok mpcp_reg_req_flag_values[] = { }; struct mpcp_reg_t { - uint8_t assigned_port[2]; - uint8_t flags; - uint8_t sync_time[MPCP_TIMESTAMP_DURATION_LEN]; - uint8_t echoed_pending_grants; + nd_uint16_t assigned_port; + nd_uint8_t flags; + nd_uint16_t sync_time; + nd_uint8_t echoed_pending_grants; }; static const struct tok mpcp_reg_flag_values[] = { @@ -109,9 +106,9 @@ static const struct tok mpcp_report_bitmap_values[] = { }; struct mpcp_reg_ack_t { - uint8_t flags; - uint8_t echoed_assigned_port[2]; - uint8_t echoed_sync_time[MPCP_TIMESTAMP_DURATION_LEN]; + nd_uint8_t flags; + nd_uint16_t echoed_assigned_port; + nd_uint16_t echoed_sync_time; }; static const struct tok mpcp_reg_ack_flag_values[] = { @@ -121,89 +118,82 @@ static const struct tok mpcp_reg_ack_flag_values[] = { }; void -mpcp_print(netdissect_options *ndo, register const u_char *pptr, register u_int length) +mpcp_print(netdissect_options *ndo, const u_char *pptr, u_int length) { - union { - const struct mpcp_common_header_t *common_header; - const struct mpcp_grant_t *grant; - const struct mpcp_reg_req_t *reg_req; - const struct mpcp_reg_t *reg; - const struct mpcp_reg_ack_t *reg_ack; - } mpcp; + const struct mpcp_common_header_t *mpcp_common_header; + const struct mpcp_reg_req_t *mpcp_reg_req; + const struct mpcp_reg_t *mpcp_reg; + const struct mpcp_reg_ack_t *mpcp_reg_ack; const u_char *tptr; uint16_t opcode; + uint32_t timestamp; uint8_t grant_numbers, grant; uint8_t queue_sets, queue_set, report_bitmap, report; + ndo->ndo_protocol = "mpcp"; tptr=pptr; - mpcp.common_header = (const struct mpcp_common_header_t *)pptr; + mpcp_common_header = (const struct mpcp_common_header_t *)pptr; - ND_TCHECK2(*tptr, sizeof(const struct mpcp_common_header_t)); - opcode = EXTRACT_16BITS(mpcp.common_header->opcode); - ND_PRINT((ndo, "MPCP, Opcode %s", tok2str(mpcp_opcode_values, "Unknown (%u)", opcode))); + opcode = GET_BE_U_2(mpcp_common_header->opcode); + timestamp = GET_BE_U_4(mpcp_common_header->timestamp); + ND_PRINT("MPCP, Opcode %s", tok2str(mpcp_opcode_values, "Unknown (%u)", opcode)); if (opcode != MPCP_OPCODE_PAUSE) { - ND_PRINT((ndo, ", Timestamp %u ticks", EXTRACT_32BITS(mpcp.common_header->timestamp))); + ND_PRINT(", Timestamp %u ticks", timestamp); } - ND_PRINT((ndo, ", length %u", length)); + ND_PRINT(", length %u", length); if (!ndo->ndo_vflag) return; - tptr += sizeof(const struct mpcp_common_header_t); + tptr += sizeof(struct mpcp_common_header_t); switch (opcode) { case MPCP_OPCODE_PAUSE: break; case MPCP_OPCODE_GATE: - ND_TCHECK2(*tptr, MPCP_GRANT_NUMBER_LEN); - grant_numbers = *tptr & MPCP_GRANT_NUMBER_MASK; - ND_PRINT((ndo, "\n\tGrant Numbers %u, Flags [ %s ]", + grant_numbers = GET_U_1(tptr) & MPCP_GRANT_NUMBER_MASK; + ND_PRINT("\n\tGrant Numbers %u, Flags [ %s ]", grant_numbers, bittok2str(mpcp_grant_flag_values, "?", - *tptr &~ MPCP_GRANT_NUMBER_MASK))); + GET_U_1(tptr) & ~MPCP_GRANT_NUMBER_MASK)); tptr++; for (grant = 1; grant <= grant_numbers; grant++) { - ND_TCHECK2(*tptr, sizeof(const struct mpcp_grant_t)); - mpcp.grant = (const struct mpcp_grant_t *)tptr; - ND_PRINT((ndo, "\n\tGrant #%u, Start-Time %u ticks, duration %u ticks", + const struct mpcp_grant_t *mpcp_grant = (const struct mpcp_grant_t *)tptr; + ND_PRINT("\n\tGrant #%u, Start-Time %u ticks, duration %u ticks", grant, - EXTRACT_32BITS(mpcp.grant->starttime), - EXTRACT_16BITS(mpcp.grant->duration))); - tptr += sizeof(const struct mpcp_grant_t); + GET_BE_U_4(mpcp_grant->starttime), + GET_BE_U_2(mpcp_grant->duration)); + tptr += sizeof(struct mpcp_grant_t); } - ND_TCHECK2(*tptr, MPCP_TIMESTAMP_DURATION_LEN); - ND_PRINT((ndo, "\n\tSync-Time %u ticks", EXTRACT_16BITS(tptr))); + ND_PRINT("\n\tSync-Time %u ticks", GET_BE_U_2(tptr)); break; case MPCP_OPCODE_REPORT: - ND_TCHECK2(*tptr, MPCP_REPORT_QUEUESETS_LEN); - queue_sets = *tptr; + queue_sets = GET_U_1(tptr); tptr+=MPCP_REPORT_QUEUESETS_LEN; - ND_PRINT((ndo, "\n\tTotal Queue-Sets %u", queue_sets)); + ND_PRINT("\n\tTotal Queue-Sets %u", queue_sets); for (queue_set = 1; queue_set < queue_sets; queue_set++) { - ND_TCHECK2(*tptr, MPCP_REPORT_REPORTBITMAP_LEN); - report_bitmap = *(tptr); - ND_PRINT((ndo, "\n\t Queue-Set #%u, Report-Bitmap [ %s ]", + report_bitmap = GET_U_1(tptr); + ND_PRINT("\n\t Queue-Set #%u, Report-Bitmap [ %s ]", queue_sets, - bittok2str(mpcp_report_bitmap_values, "Unknown", report_bitmap))); + bittok2str(mpcp_report_bitmap_values, "Unknown", report_bitmap)); tptr++; report=1; while (report_bitmap != 0) { if (report_bitmap & 1) { - ND_TCHECK2(*tptr, MPCP_TIMESTAMP_DURATION_LEN); - ND_PRINT((ndo, "\n\t Q%u Report, Duration %u ticks", + ND_PRINT("\n\t Q%u Report, Duration %u ticks", report, - EXTRACT_16BITS(tptr))); - tptr+=MPCP_TIMESTAMP_DURATION_LEN; + GET_BE_U_2(tptr)); + tptr += 2; } report++; report_bitmap = report_bitmap >> 1; @@ -212,32 +202,29 @@ mpcp_print(netdissect_options *ndo, register const u_char *pptr, register u_int break; case MPCP_OPCODE_REG_REQ: - ND_TCHECK2(*tptr, sizeof(const struct mpcp_reg_req_t)); - mpcp.reg_req = (const struct mpcp_reg_req_t *)tptr; - ND_PRINT((ndo, "\n\tFlags [ %s ], Pending-Grants %u", - bittok2str(mpcp_reg_req_flag_values, "Reserved", mpcp.reg_req->flags), - mpcp.reg_req->pending_grants)); + mpcp_reg_req = (const struct mpcp_reg_req_t *)tptr; + ND_PRINT("\n\tFlags [ %s ], Pending-Grants %u", + bittok2str(mpcp_reg_req_flag_values, "Reserved", GET_U_1(mpcp_reg_req->flags)), + GET_U_1(mpcp_reg_req->pending_grants)); break; case MPCP_OPCODE_REG: - ND_TCHECK2(*tptr, sizeof(const struct mpcp_reg_t)); - mpcp.reg = (const struct mpcp_reg_t *)tptr; - ND_PRINT((ndo, "\n\tAssigned-Port %u, Flags [ %s ]" \ + mpcp_reg = (const struct mpcp_reg_t *)tptr; + ND_PRINT("\n\tAssigned-Port %u, Flags [ %s ]" "\n\tSync-Time %u ticks, Echoed-Pending-Grants %u", - EXTRACT_16BITS(mpcp.reg->assigned_port), - bittok2str(mpcp_reg_flag_values, "Reserved", mpcp.reg->flags), - EXTRACT_16BITS(mpcp.reg->sync_time), - mpcp.reg->echoed_pending_grants)); + GET_BE_U_2(mpcp_reg->assigned_port), + bittok2str(mpcp_reg_flag_values, "Reserved", GET_U_1(mpcp_reg->flags)), + GET_BE_U_2(mpcp_reg->sync_time), + GET_U_1(mpcp_reg->echoed_pending_grants)); break; case MPCP_OPCODE_REG_ACK: - ND_TCHECK2(*tptr, sizeof(const struct mpcp_reg_ack_t)); - mpcp.reg_ack = (const struct mpcp_reg_ack_t *)tptr; - ND_PRINT((ndo, "\n\tEchoed-Assigned-Port %u, Flags [ %s ]" \ + mpcp_reg_ack = (const struct mpcp_reg_ack_t *)tptr; + ND_PRINT("\n\tEchoed-Assigned-Port %u, Flags [ %s ]" "\n\tEchoed-Sync-Time %u ticks", - EXTRACT_16BITS(mpcp.reg_ack->echoed_assigned_port), - bittok2str(mpcp_reg_ack_flag_values, "Reserved", mpcp.reg_ack->flags), - EXTRACT_16BITS(mpcp.reg_ack->echoed_sync_time))); + GET_BE_U_2(mpcp_reg_ack->echoed_assigned_port), + bittok2str(mpcp_reg_ack_flag_values, "Reserved", GET_U_1(mpcp_reg_ack->flags)), + GET_BE_U_2(mpcp_reg_ack->echoed_sync_time)); break; default: @@ -245,15 +232,4 @@ mpcp_print(netdissect_options *ndo, register const u_char *pptr, register u_int print_unknown_data(ndo,pptr, "\n\t", length); break; } - - return; - -trunc: - ND_PRINT((ndo, "\n\t[|MPCP]")); } -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/print-mpls.c b/contrib/tcpdump/print-mpls.c index 5c26e4f9b2..b8820aa9c6 100644 --- a/contrib/tcpdump/print-mpls.c +++ b/contrib/tcpdump/print-mpls.c @@ -29,11 +29,12 @@ /* \summary: Multi-Protocol Label Switching (MPLS) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" #include "mpls.h" @@ -62,28 +63,27 @@ mpls_print(netdissect_options *ndo, const u_char *bp, u_int length) const u_char *p; uint32_t label_entry; uint16_t label_stack_depth = 0; + uint8_t first; enum mpls_packet_type pt = PT_UNKNOWN; + ndo->ndo_protocol = "mpls"; p = bp; - ND_PRINT((ndo, "MPLS")); + nd_print_protocol_caps(ndo); do { - ND_TCHECK2(*p, sizeof(label_entry)); - if (length < sizeof(label_entry)) { - ND_PRINT((ndo, "[|MPLS], length %u", length)); - return; - } - label_entry = EXTRACT_32BITS(p); - ND_PRINT((ndo, "%s(label %u", + if (length < sizeof(label_entry)) + goto invalid; + label_entry = GET_BE_U_4(p); + ND_PRINT("%s(label %u", (label_stack_depth && ndo->ndo_vflag) ? "\n\t" : " ", - MPLS_LABEL(label_entry))); + MPLS_LABEL(label_entry)); label_stack_depth++; if (ndo->ndo_vflag && MPLS_LABEL(label_entry) < sizeof(mpls_labelname) / sizeof(mpls_labelname[0])) - ND_PRINT((ndo, " (%s)", mpls_labelname[MPLS_LABEL(label_entry)])); - ND_PRINT((ndo, ", exp %u", MPLS_EXP(label_entry))); + ND_PRINT(" (%s)", mpls_labelname[MPLS_LABEL(label_entry)]); + ND_PRINT(", exp %u", MPLS_EXP(label_entry)); if (MPLS_STACK(label_entry)) - ND_PRINT((ndo, ", [S]")); - ND_PRINT((ndo, ", ttl %u)", MPLS_TTL(label_entry))); + ND_PRINT(", [S]"); + ND_PRINT(", ttl %u)", MPLS_TTL(label_entry)); p += sizeof(label_entry); length -= sizeof(label_entry); @@ -129,94 +129,46 @@ mpls_print(netdissect_options *ndo, const u_char *bp, u_int length) * Cisco sends control-plane traffic MPLS-encapsulated in * this fashion. */ - ND_TCHECK(*p); if (length < 1) { /* nothing to print */ return; } - 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: + first = GET_U_1(p); + pt = + (first >= 0x45 && first <= 0x4f) ? PT_IPV4 : + (first >= 0x60 && first <= 0x6f) ? PT_IPV6 : + (first >= 0x81 && first <= 0x83) ? PT_OSI : /* ok bail out - we did not figure out what it is*/ - break; - } + PT_UNKNOWN; } /* * Print the payload. */ - if (pt == PT_UNKNOWN) { + switch (pt) { + case PT_UNKNOWN: if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, length); - return; - } - ND_PRINT((ndo, ndo->ndo_vflag ? "\n\t" : " ")); - switch (pt) { + break; case PT_IPV4: + ND_PRINT(ndo->ndo_vflag ? "\n\t" : " "); ip_print(ndo, p, length); break; case PT_IPV6: + ND_PRINT(ndo->ndo_vflag ? "\n\t" : " "); ip6_print(ndo, p, length); break; case PT_OSI: + ND_PRINT(ndo->ndo_vflag ? "\n\t" : " "); isoclns_print(ndo, p, length); break; - - default: - break; } return; -trunc: - ND_PRINT((ndo, "[|MPLS]")); +invalid: + nd_print_invalid(ndo); + ND_TCHECK_LEN(p, length); } - - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/print-mptcp.c b/contrib/tcpdump/print-mptcp.c index 392791e66e..aae78df2b0 100644 --- a/contrib/tcpdump/print-mptcp.c +++ b/contrib/tcpdump/print-mptcp.c @@ -37,10 +37,10 @@ /* specification: RFC 6824 */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "extract.h" @@ -58,42 +58,42 @@ #define MPTCP_SUB_FCLOSE 0x7 struct mptcp_option { - uint8_t kind; - uint8_t len; - uint8_t sub_etc; /* subtype upper 4 bits, other stuff lower 4 bits */ + nd_uint8_t kind; + nd_uint8_t len; + nd_uint8_t sub_etc; /* subtype upper 4 bits, other stuff lower 4 bits */ }; -#define MPTCP_OPT_SUBTYPE(sub_etc) (((sub_etc) >> 4) & 0xF) +#define MPTCP_OPT_SUBTYPE(sub_etc) ((GET_U_1(sub_etc) >> 4) & 0xF) struct mp_capable { - uint8_t kind; - uint8_t len; - uint8_t sub_ver; - uint8_t flags; - uint8_t sender_key[8]; - uint8_t receiver_key[8]; + nd_uint8_t kind; + nd_uint8_t len; + nd_uint8_t sub_ver; + nd_uint8_t flags; + nd_uint64_t sender_key; + nd_uint64_t receiver_key; }; -#define MP_CAPABLE_OPT_VERSION(sub_ver) (((sub_ver) >> 0) & 0xF) +#define MP_CAPABLE_OPT_VERSION(sub_ver) ((GET_U_1(sub_ver) >> 0) & 0xF) #define MP_CAPABLE_C 0x80 #define MP_CAPABLE_S 0x01 struct mp_join { - uint8_t kind; - uint8_t len; - uint8_t sub_b; - uint8_t addr_id; + nd_uint8_t kind; + nd_uint8_t len; + nd_uint8_t sub_b; + nd_uint8_t addr_id; union { struct { - uint8_t token[4]; - uint8_t nonce[4]; + nd_uint32_t token; + nd_uint32_t nonce; } syn; struct { - uint8_t mac[8]; - uint8_t nonce[4]; + nd_uint64_t mac; + nd_uint32_t nonce; } synack; struct { - uint8_t mac[20]; + nd_byte mac[20]; } ack; } u; }; @@ -101,10 +101,10 @@ struct mp_join { #define MP_JOIN_B 0x01 struct mp_dss { - uint8_t kind; - uint8_t len; - uint8_t sub; - uint8_t flags; + nd_uint8_t kind; + nd_uint8_t len; + nd_uint8_t sub; + nd_uint8_t flags; }; #define MP_DSS_F 0x10 @@ -113,54 +113,70 @@ struct mp_dss { #define MP_DSS_a 0x02 #define MP_DSS_A 0x01 +static const struct tok mptcp_addr_subecho_bits[] = { + { 0x6, "v0-ip6" }, + { 0x4, "v0-ip4" }, + { 0x1, "v1-echo" }, + { 0x0, "v1" }, + { 0, NULL } +}; + struct mp_add_addr { - uint8_t kind; - uint8_t len; - uint8_t sub_ipver; - uint8_t addr_id; + nd_uint8_t kind; + nd_uint8_t len; + nd_uint8_t sub_echo; + nd_uint8_t addr_id; union { struct { - uint8_t addr[4]; - uint8_t port[2]; + nd_ipv4 addr; + nd_uint16_t port; + nd_uint64_t mac; } v4; struct { - uint8_t addr[16]; - uint8_t port[2]; + nd_ipv4 addr; + nd_uint64_t mac; + } v4np; + struct { + nd_ipv6 addr; + nd_uint16_t port; + nd_uint64_t mac; } v6; + struct { + nd_ipv6 addr; + nd_uint64_t mac; + } v6np; } u; }; -#define MP_ADD_ADDR_IPVER(sub_ipver) (((sub_ipver) >> 0) & 0xF) - struct mp_remove_addr { - uint8_t kind; - uint8_t len; - uint8_t sub; + nd_uint8_t kind; + nd_uint8_t len; + nd_uint8_t sub; /* list of addr_id */ - uint8_t addrs_id; + nd_uint8_t addrs_id[1]; }; struct mp_fail { - uint8_t kind; - uint8_t len; - uint8_t sub; - uint8_t resv; - uint8_t data_seq[8]; + nd_uint8_t kind; + nd_uint8_t len; + nd_uint8_t sub; + nd_uint8_t resv; + nd_uint64_t data_seq; }; struct mp_close { - uint8_t kind; - uint8_t len; - uint8_t sub; - uint8_t rsv; - uint8_t key[8]; + nd_uint8_t kind; + nd_uint8_t len; + nd_uint8_t sub; + nd_uint8_t rsv; + nd_byte key[8]; }; struct mp_prio { - uint8_t kind; - uint8_t len; - uint8_t sub_b; - uint8_t addr_id; + nd_uint8_t kind; + nd_uint8_t len; + nd_uint8_t sub_b; + nd_uint8_t addr_id; }; #define MP_PRIO_B 0x01 @@ -177,22 +193,32 @@ mp_capable_print(netdissect_options *ndo, const u_char *opt, u_int opt_len, u_char flags) { const struct mp_capable *mpc = (const struct mp_capable *) opt; + uint8_t version; - if (!(opt_len == 12 && (flags & TH_SYN)) && - !(opt_len == 20 && (flags & (TH_SYN | TH_ACK)) == TH_ACK)) + if (!((opt_len == 12 || opt_len == 4) && flags & TH_SYN) && + !((opt_len == 20 || opt_len == 22) && (flags & (TH_SYN | TH_ACK)) == + TH_ACK)) return 0; - if (MP_CAPABLE_OPT_VERSION(mpc->sub_ver) != 0) { - ND_PRINT((ndo, " Unknown Version (%d)", MP_CAPABLE_OPT_VERSION(mpc->sub_ver))); - return 1; + version = MP_CAPABLE_OPT_VERSION(mpc->sub_ver); /* uses GET_U_1() */ + switch (version) { + case 0: /* fall through */ + case 1: + ND_PRINT(" v%u", version); + break; + default: + ND_PRINT(" Unknown Version (%u)", version); + return 1; } - if (mpc->flags & MP_CAPABLE_C) - ND_PRINT((ndo, " csum")); - ND_PRINT((ndo, " {0x%" PRIx64, EXTRACT_64BITS(mpc->sender_key))); - if (opt_len == 20) /* ACK */ - ND_PRINT((ndo, ",0x%" PRIx64, EXTRACT_64BITS(mpc->receiver_key))); - ND_PRINT((ndo, "}")); + if (GET_U_1(mpc->flags) & MP_CAPABLE_C) + ND_PRINT(" csum"); + if (opt_len == 12 || opt_len >= 20) { + ND_PRINT(" {0x%" PRIx64, GET_BE_U_8(mpc->sender_key)); + if (opt_len >= 20) + ND_PRINT(",0x%" PRIx64, GET_BE_U_8(mpc->receiver_key)); + ND_PRINT("}"); + } return 1; } @@ -208,27 +234,27 @@ mp_join_print(netdissect_options *ndo, return 0; if (opt_len != 24) { - if (mpj->sub_b & MP_JOIN_B) - ND_PRINT((ndo, " backup")); - ND_PRINT((ndo, " id %u", mpj->addr_id)); + if (GET_U_1(mpj->sub_b) & MP_JOIN_B) + ND_PRINT(" backup"); + ND_PRINT(" id %u", GET_U_1(mpj->addr_id)); } switch (opt_len) { case 12: /* SYN */ - ND_PRINT((ndo, " token 0x%x" " nonce 0x%x", - EXTRACT_32BITS(mpj->u.syn.token), - EXTRACT_32BITS(mpj->u.syn.nonce))); + ND_PRINT(" token 0x%x" " nonce 0x%x", + GET_BE_U_4(mpj->u.syn.token), + GET_BE_U_4(mpj->u.syn.nonce)); break; case 16: /* SYN/ACK */ - ND_PRINT((ndo, " hmac 0x%" PRIx64 " nonce 0x%x", - EXTRACT_64BITS(mpj->u.synack.mac), - EXTRACT_32BITS(mpj->u.synack.nonce))); + ND_PRINT(" hmac 0x%" PRIx64 " nonce 0x%x", + GET_BE_U_8(mpj->u.synack.mac), + GET_BE_U_4(mpj->u.synack.nonce)); break; case 24: {/* ACK */ size_t i; - ND_PRINT((ndo, " hmac 0x")); + ND_PRINT(" hmac 0x"); for (i = 0; i < sizeof(mpj->u.ack.mac); ++i) - ND_PRINT((ndo, "%02x", mpj->u.ack.mac[i])); + ND_PRINT("%02x", mpj->u.ack.mac[i]); } default: break; @@ -241,6 +267,7 @@ mp_dss_print(netdissect_options *ndo, const u_char *opt, u_int opt_len, u_char flags) { const struct mp_dss *mdss = (const struct mp_dss *) opt; + uint8_t mdss_flags; /* We need the flags, at a minimum. */ if (opt_len < 4) @@ -249,64 +276,65 @@ mp_dss_print(netdissect_options *ndo, if (flags & TH_SYN) return 0; - if (mdss->flags & MP_DSS_F) - ND_PRINT((ndo, " fin")); + mdss_flags = GET_U_1(mdss->flags); + if (mdss_flags & MP_DSS_F) + ND_PRINT(" fin"); opt += 4; opt_len -= 4; - if (mdss->flags & MP_DSS_A) { + if (mdss_flags & MP_DSS_A) { /* Ack present */ - ND_PRINT((ndo, " ack ")); + ND_PRINT(" ack "); /* * If the a flag is set, we have an 8-byte ack; if it's * clear, we have a 4-byte ack. */ - if (mdss->flags & MP_DSS_a) { + if (mdss_flags & MP_DSS_a) { if (opt_len < 8) return 0; - ND_PRINT((ndo, "%" PRIu64, EXTRACT_64BITS(opt))); + ND_PRINT("%" PRIu64, GET_BE_U_8(opt)); opt += 8; opt_len -= 8; } else { if (opt_len < 4) return 0; - ND_PRINT((ndo, "%u", EXTRACT_32BITS(opt))); + ND_PRINT("%u", GET_BE_U_4(opt)); opt += 4; opt_len -= 4; } } - if (mdss->flags & MP_DSS_M) { + if (mdss_flags & MP_DSS_M) { /* * Data Sequence Number (DSN), Subflow Sequence Number (SSN), * Data-Level Length present, and Checksum possibly present. */ - ND_PRINT((ndo, " seq ")); + ND_PRINT(" seq "); /* * If the m flag is set, we have an 8-byte NDS; if it's clear, * we have a 4-byte DSN. */ - if (mdss->flags & MP_DSS_m) { + if (mdss_flags & MP_DSS_m) { if (opt_len < 8) return 0; - ND_PRINT((ndo, "%" PRIu64, EXTRACT_64BITS(opt))); + ND_PRINT("%" PRIu64, GET_BE_U_8(opt)); opt += 8; opt_len -= 8; } else { if (opt_len < 4) return 0; - ND_PRINT((ndo, "%u", EXTRACT_32BITS(opt))); + ND_PRINT("%u", GET_BE_U_4(opt)); opt += 4; opt_len -= 4; } if (opt_len < 4) return 0; - ND_PRINT((ndo, " subseq %u", EXTRACT_32BITS(opt))); + ND_PRINT(" subseq %u", GET_BE_U_4(opt)); opt += 4; opt_len -= 4; if (opt_len < 2) return 0; - ND_PRINT((ndo, " len %u", EXTRACT_16BITS(opt))); + ND_PRINT(" len %u", GET_BE_U_2(opt)); opt += 2; opt_len -= 2; @@ -316,7 +344,7 @@ mp_dss_print(netdissect_options *ndo, * bytes as the Checksum. */ if (opt_len >= 2) { - ND_PRINT((ndo, " csum 0x%x", EXTRACT_16BITS(opt))); + ND_PRINT(" csum 0x%x", GET_BE_U_2(opt)); opt_len -= 2; } } @@ -330,26 +358,33 @@ add_addr_print(netdissect_options *ndo, const u_char *opt, u_int opt_len, u_char flags _U_) { const struct mp_add_addr *add_addr = (const struct mp_add_addr *) opt; - u_int ipver = MP_ADD_ADDR_IPVER(add_addr->sub_ipver); - if (!((opt_len == 8 || opt_len == 10) && ipver == 4) && - !((opt_len == 20 || opt_len == 22) && ipver == 6)) + if (!(opt_len == 8 || opt_len == 10 || opt_len == 16 || opt_len == 18 || + opt_len == 20 || opt_len == 22 || opt_len == 28 || opt_len == 30)) return 0; - ND_PRINT((ndo, " id %u", add_addr->addr_id)); - switch (ipver) { - case 4: - ND_PRINT((ndo, " %s", ipaddr_string(ndo, add_addr->u.v4.addr))); - if (opt_len == 10) - ND_PRINT((ndo, ":%u", EXTRACT_16BITS(add_addr->u.v4.port))); - break; - case 6: - ND_PRINT((ndo, " %s", ip6addr_string(ndo, add_addr->u.v6.addr))); - if (opt_len == 22) - ND_PRINT((ndo, ":%u", EXTRACT_16BITS(add_addr->u.v6.port))); - break; - default: - return 0; + ND_PRINT(" %s", + tok2str(mptcp_addr_subecho_bits, "[bad version/echo]", + GET_U_1(add_addr->sub_echo) & 0xF)); + ND_PRINT(" id %u", GET_U_1(add_addr->addr_id)); + if (opt_len == 8 || opt_len == 10 || opt_len == 16 || opt_len == 18) { + ND_PRINT(" %s", GET_IPADDR_STRING(add_addr->u.v4.addr)); + if (opt_len == 10 || opt_len == 18) + ND_PRINT(":%u", GET_BE_U_2(add_addr->u.v4.port)); + if (opt_len == 16) + ND_PRINT(" hmac 0x%" PRIx64, GET_BE_U_8(add_addr->u.v4np.mac)); + if (opt_len == 18) + ND_PRINT(" hmac 0x%" PRIx64, GET_BE_U_8(add_addr->u.v4.mac)); + } + + if (opt_len == 20 || opt_len == 22 || opt_len == 28 || opt_len == 30) { + ND_PRINT(" %s", GET_IP6ADDR_STRING(add_addr->u.v6.addr)); + if (opt_len == 22 || opt_len == 30) + ND_PRINT(":%u", GET_BE_U_2(add_addr->u.v6.port)); + if (opt_len == 28) + ND_PRINT(" hmac 0x%" PRIx64, GET_BE_U_8(add_addr->u.v6np.mac)); + if (opt_len == 30) + ND_PRINT(" hmac 0x%" PRIx64, GET_BE_U_8(add_addr->u.v6.mac)); } return 1; @@ -360,15 +395,15 @@ remove_addr_print(netdissect_options *ndo, const u_char *opt, u_int opt_len, u_char flags _U_) { const struct mp_remove_addr *remove_addr = (const struct mp_remove_addr *) opt; - const uint8_t *addr_id = &remove_addr->addrs_id; + u_int i; if (opt_len < 4) return 0; opt_len -= 3; - ND_PRINT((ndo, " id")); - while (opt_len--) - ND_PRINT((ndo, " %u", *addr_id++)); + ND_PRINT(" id"); + for (i = 0; i < opt_len; i++) + ND_PRINT(" %u", GET_U_1(remove_addr->addrs_id[i])); return 1; } @@ -381,12 +416,12 @@ mp_prio_print(netdissect_options *ndo, if (opt_len != 3 && opt_len != 4) return 0; - if (mpp->sub_b & MP_PRIO_B) - ND_PRINT((ndo, " backup")); + if (GET_U_1(mpp->sub_b) & MP_PRIO_B) + ND_PRINT(" backup"); else - ND_PRINT((ndo, " non-backup")); + ND_PRINT(" non-backup"); if (opt_len == 4) - ND_PRINT((ndo, " id %u", mpp->addr_id)); + ND_PRINT(" id %u", GET_U_1(mpp->addr_id)); return 1; } @@ -398,7 +433,7 @@ mp_fail_print(netdissect_options *ndo, if (opt_len != 12) return 0; - ND_PRINT((ndo, " seq %" PRIu64, EXTRACT_64BITS(opt + 4))); + ND_PRINT(" seq %" PRIu64, GET_BE_U_8(opt + 4)); return 1; } @@ -409,7 +444,7 @@ mp_fast_close_print(netdissect_options *ndo, if (opt_len != 12) return 0; - ND_PRINT((ndo, " key 0x%" PRIx64, EXTRACT_64BITS(opt + 4))); + ND_PRINT(" key 0x%" PRIx64, GET_BE_U_8(opt + 4)); return 1; } @@ -435,12 +470,14 @@ mptcp_print(netdissect_options *ndo, const struct mptcp_option *opt; u_int subtype; + ndo->ndo_protocol = "mptcp"; if (len < 3) return 0; opt = (const struct mptcp_option *) cp; - subtype = min(MPTCP_OPT_SUBTYPE(opt->sub_etc), MPTCP_SUB_FCLOSE + 1); + subtype = MPTCP_OPT_SUBTYPE(opt->sub_etc); /* uses GET_U_1() */ + subtype = ND_MIN(subtype, MPTCP_SUB_FCLOSE + 1); - ND_PRINT((ndo, " %s", mptcp_options[subtype].name)); + ND_PRINT(" %s", mptcp_options[subtype].name); return mptcp_options[subtype].print(ndo, cp, len, flags); } diff --git a/contrib/tcpdump/print-msdp.c b/contrib/tcpdump/print-msdp.c index 50bafb0ae0..7845116bdc 100644 --- a/contrib/tcpdump/print-msdp.c +++ b/contrib/tcpdump/print-msdp.c @@ -19,10 +19,10 @@ /* \summary: Multicast Source Discovery Protocol (MSDP) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "addrtoname.h" @@ -35,56 +35,57 @@ msdp_print(netdissect_options *ndo, const u_char *sp, u_int length) { unsigned int type, len; - ND_TCHECK2(*sp, 3); + ndo->ndo_protocol = "msdp"; + ND_PRINT(": "); + nd_print_protocol(ndo); /* See if we think we're at the beginning of a compound packet */ - type = *sp; - len = EXTRACT_16BITS(sp + 1); + type = GET_U_1(sp); + len = GET_BE_U_2(sp + 1); if (len > 1500 || len < 3 || type == 0 || type > MSDP_TYPE_MAX) goto trunc; /* not really truncated, but still not decodable */ - ND_PRINT((ndo, " msdp:")); - while (length > 0) { - ND_TCHECK2(*sp, 3); - type = *sp; - len = EXTRACT_16BITS(sp + 1); + while (length != 0) { + type = GET_U_1(sp); + len = GET_BE_U_2(sp + 1); if (len > 1400 || ndo->ndo_vflag) - ND_PRINT((ndo, " [len %u]", len)); + ND_PRINT(" [len %u]", len); if (len < 3) goto trunc; + if (length < len) + goto trunc; sp += 3; length -= 3; switch (type) { case 1: /* IPv4 Source-Active */ case 3: /* IPv4 Source-Active Response */ if (type == 1) - ND_PRINT((ndo, " SA")); + ND_PRINT(" SA"); else - ND_PRINT((ndo, " SA-Response")); - ND_TCHECK(*sp); - ND_PRINT((ndo, " %u entries", *sp)); - if ((u_int)((*sp * 12) + 8) < len) { - ND_PRINT((ndo, " [w/data]")); + ND_PRINT(" SA-Response"); + ND_PRINT(" %u entries", GET_U_1(sp)); + if ((u_int)((GET_U_1(sp) * 12) + 8) < len) { + ND_PRINT(" [w/data]"); if (ndo->ndo_vflag > 1) { - ND_PRINT((ndo, " ")); - ip_print(ndo, sp + *sp * 12 + 8 - 3, - len - (*sp * 12 + 8)); + ND_PRINT(" "); + ip_print(ndo, sp + + GET_U_1(sp) * 12 + 8 - 3, + len - (GET_U_1(sp) * 12 + 8)); } } break; case 2: - ND_PRINT((ndo, " SA-Request")); - ND_TCHECK2(*sp, 5); - ND_PRINT((ndo, " for %s", ipaddr_string(ndo, sp + 1))); + ND_PRINT(" SA-Request"); + ND_PRINT(" for %s", GET_IPADDR_STRING(sp + 1)); break; case 4: - ND_PRINT((ndo, " Keepalive")); + ND_PRINT(" Keepalive"); if (len != 3) - ND_PRINT((ndo, "[len=%d] ", len)); + ND_PRINT("[len=%u] ", len); break; case 5: - ND_PRINT((ndo, " Notification")); + ND_PRINT(" Notification"); break; default: - ND_PRINT((ndo, " [type=%d len=%d]", type, len)); + ND_PRINT(" [type=%u len=%u]", type, len); break; } sp += (len - 3); @@ -92,12 +93,5 @@ msdp_print(netdissect_options *ndo, const u_char *sp, u_int length) } return; trunc: - ND_PRINT((ndo, " [|msdp]")); + nd_print_trunc(ndo); } - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/print-msnlb.c b/contrib/tcpdump/print-msnlb.c index 5264da496c..8afaa7fe71 100644 --- a/contrib/tcpdump/print-msnlb.c +++ b/contrib/tcpdump/print-msnlb.c @@ -29,21 +29,21 @@ /* \summary: MS Network Load Balancing's (NLB) heartbeat printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "addrtoname.h" #include "extract.h" struct msnlb_heartbeat_pkt { - uint32_t unknown1; - uint32_t unknown2; - uint32_t host_prio; /* little-endian */ - uint32_t virtual_ip; - uint32_t host_ip; + nd_byte unknown1[4]; + nd_byte unknown2[4]; + nd_uint32_t host_prio; /* little-endian */ + nd_ipv4 virtual_ip; + nd_ipv4 host_ip; /* the protocol is undocumented so we ignore the rest */ }; @@ -52,14 +52,11 @@ msnlb_print(netdissect_options *ndo, const u_char *bp) { const struct msnlb_heartbeat_pkt *hb; + ndo->ndo_protocol = "msnlb"; hb = (const struct msnlb_heartbeat_pkt *)bp; - ND_TCHECK(*hb); - ND_PRINT((ndo, "MS NLB heartbeat, host priority: %u,", - EXTRACT_LE_32BITS(&(hb->host_prio)))); - ND_PRINT((ndo, " cluster IP: %s,", ipaddr_string(ndo, &(hb->virtual_ip)))); - ND_PRINT((ndo, " host IP: %s", ipaddr_string(ndo, &(hb->host_ip)))); - return; -trunc: - ND_PRINT((ndo, "[|MS NLB]")); + ND_PRINT("MS NLB heartbeat"); + ND_PRINT(", host priority: %u", GET_LE_U_4((hb->host_prio))); + ND_PRINT(", cluster IP: %s", GET_IPADDR_STRING(hb->virtual_ip)); + ND_PRINT(", host IP: %s", GET_IPADDR_STRING(hb->host_ip)); } diff --git a/contrib/tcpdump/print-nflog.c b/contrib/tcpdump/print-nflog.c index 41cbf788fd..1e75561b96 100644 --- a/contrib/tcpdump/print-nflog.c +++ b/contrib/tcpdump/print-nflog.c @@ -28,109 +28,170 @@ /* \summary: DLT_NFLOG printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" +#include "extract.h" -#if defined(DLT_NFLOG) && defined(HAVE_PCAP_NFLOG_H) -#include +#ifdef DLT_NFLOG + +/* + * Structure of an NFLOG header and TLV parts, as described at + * https://www.tcpdump.org/linktypes/LINKTYPE_NFLOG.html + * + * The NFLOG header is big-endian. + * + * The TLV length and type are in host byte order. The value is either + * big-endian or is an array of bytes in some externally-specified byte + * order (text string, link-layer address, link-layer header, packet + * data, etc.). + */ +typedef struct nflog_hdr { + nd_uint8_t nflog_family; /* address family */ + nd_uint8_t nflog_version; /* version */ + nd_uint16_t nflog_rid; /* resource ID */ +} nflog_hdr_t; + +#define NFLOG_HDR_LEN sizeof(nflog_hdr_t) + +typedef struct nflog_tlv { + nd_uint16_t tlv_length; /* tlv length */ + nd_uint16_t tlv_type; /* tlv type */ + /* value follows this */ +} nflog_tlv_t; + +#define NFLOG_TLV_LEN sizeof(nflog_tlv_t) + +typedef struct nflog_packet_hdr { + nd_uint16_t hw_protocol; /* hw protocol */ + nd_uint8_t hook; /* netfilter hook */ + nd_byte pad[1]; /* padding to 32 bits */ +} nflog_packet_hdr_t; + +typedef struct nflog_hwaddr { + nd_uint16_t hw_addrlen; /* address length */ + nd_byte pad[2]; /* padding to 32-bit boundary */ + nd_byte hw_addr[8]; /* address, up to 8 bytes */ +} nflog_hwaddr_t; + +typedef struct nflog_timestamp { + nd_uint64_t sec; + nd_uint64_t usec; +} nflog_timestamp_t; + +/* + * TLV types. + */ +#define NFULA_PACKET_HDR 1 /* nflog_packet_hdr_t */ +#define NFULA_MARK 2 /* packet mark from skbuff */ +#define NFULA_TIMESTAMP 3 /* nflog_timestamp_t for skbuff's time stamp */ +#define NFULA_IFINDEX_INDEV 4 /* ifindex of device on which packet received (possibly bridge group) */ +#define NFULA_IFINDEX_OUTDEV 5 /* ifindex of device on which packet transmitted (possibly bridge group) */ +#define NFULA_IFINDEX_PHYSINDEV 6 /* ifindex of physical device on which packet received (not bridge group) */ +#define NFULA_IFINDEX_PHYSOUTDEV 7 /* ifindex of physical device on which packet transmitted (not bridge group) */ +#define NFULA_HWADDR 8 /* nflog_hwaddr_t for hardware address */ +#define NFULA_PAYLOAD 9 /* packet payload */ +#define NFULA_PREFIX 10 /* text string - null-terminated, count includes NUL */ +#define NFULA_UID 11 /* UID owning socket on which packet was sent/received */ +#define NFULA_SEQ 12 /* sequence number of packets on this NFLOG socket */ +#define NFULA_SEQ_GLOBAL 13 /* sequence number of pakets on all NFLOG sockets */ +#define NFULA_GID 14 /* GID owning socket on which packet was sent/received */ +#define NFULA_HWTYPE 15 /* ARPHRD_ type of skbuff's device */ +#define NFULA_HWHEADER 16 /* skbuff's MAC-layer header */ +#define NFULA_HWLEN 17 /* length of skbuff's MAC-layer header */ static const struct tok nflog_values[] = { { AF_INET, "IPv4" }, -#ifdef AF_INET6 { AF_INET6, "IPv6" }, -#endif /*AF_INET6*/ { 0, NULL } }; -static inline void +static void nflog_hdr_print(netdissect_options *ndo, const nflog_hdr_t *hdr, u_int length) { - ND_PRINT((ndo, "version %d, resource ID %d", hdr->nflog_version, ntohs(hdr->nflog_rid))); + ND_PRINT("version %u, resource ID %u", + GET_U_1(hdr->nflog_version), GET_BE_U_2(hdr->nflog_rid)); if (!ndo->ndo_qflag) { - ND_PRINT((ndo,", family %s (%d)", - tok2str(nflog_values, "Unknown", - hdr->nflog_family), - hdr->nflog_family)); + ND_PRINT(", family %s (%u)", + tok2str(nflog_values, "Unknown", + GET_U_1(hdr->nflog_family)), + GET_U_1(hdr->nflog_family)); } else { - ND_PRINT((ndo,", %s", - tok2str(nflog_values, - "Unknown NFLOG (0x%02x)", - hdr->nflog_family))); + ND_PRINT(", %s", + tok2str(nflog_values, + "Unknown NFLOG (0x%02x)", + GET_U_1(hdr->nflog_family))); } - ND_PRINT((ndo, ", length %u: ", length)); + ND_PRINT(", length %u: ", length); } -u_int +void nflog_if_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, const u_char *p) + const struct pcap_pkthdr *h, const u_char *p) { const nflog_hdr_t *hdr = (const nflog_hdr_t *)p; - const nflog_tlv_t *tlv; uint16_t size; - uint16_t h_size = sizeof(nflog_hdr_t); + uint16_t h_size = NFLOG_HDR_LEN; u_int caplen = h->caplen; u_int length = h->len; - if (caplen < (int) sizeof(nflog_hdr_t) || length < (int) sizeof(nflog_hdr_t)) { - ND_PRINT((ndo, "[|nflog]")); - return h_size; + ndo->ndo_protocol = "nflog"; + if (caplen < NFLOG_HDR_LEN) { + nd_print_trunc(ndo); + ndo->ndo_ll_hdr_len += caplen; + return; } + ndo->ndo_ll_hdr_len += NFLOG_HDR_LEN; - if (hdr->nflog_version != 0) { - ND_PRINT((ndo, "version %u (unknown)", hdr->nflog_version)); - return h_size; + ND_TCHECK_SIZE(hdr); + if (GET_U_1(hdr->nflog_version) != 0) { + ND_PRINT("version %u (unknown)", GET_U_1(hdr->nflog_version)); + return; } if (ndo->ndo_eflag) nflog_hdr_print(ndo, hdr, length); - p += sizeof(nflog_hdr_t); - length -= sizeof(nflog_hdr_t); - caplen -= sizeof(nflog_hdr_t); + p += NFLOG_HDR_LEN; + length -= NFLOG_HDR_LEN; + caplen -= NFLOG_HDR_LEN; while (length > 0) { + const nflog_tlv_t *tlv; + /* We have some data. Do we have enough for the TLV header? */ - if (caplen < sizeof(nflog_tlv_t) || length < sizeof(nflog_tlv_t)) { - /* No. */ - ND_PRINT((ndo, "[|nflog]")); - return h_size; - } + if (caplen < NFLOG_TLV_LEN) + goto trunc; /* No. */ tlv = (const nflog_tlv_t *) p; - size = tlv->tlv_length; + ND_TCHECK_SIZE(tlv); + size = GET_HE_U_2(tlv->tlv_length); if (size % 4 != 0) size += 4 - size % 4; /* Is the TLV's length less than the minimum? */ - if (size < sizeof(nflog_tlv_t)) { - /* Yes. Give up now. */ - ND_PRINT((ndo, "[|nflog]")); - return h_size; - } + if (size < NFLOG_TLV_LEN) + goto trunc; /* Yes. Give up now. */ /* Do we have enough data for the full TLV? */ - if (caplen < size || length < size) { - /* No. */ - ND_PRINT((ndo, "[|nflog]")); - return h_size; - } + if (caplen < size) + goto trunc; /* No. */ - if (tlv->tlv_type == NFULA_PAYLOAD) { + if (GET_HE_U_2(tlv->tlv_type) == NFULA_PAYLOAD) { /* * This TLV's data is the packet payload. * Skip past the TLV header, and break out * of the loop so we print the packet data. */ - p += sizeof(nflog_tlv_t); - h_size += sizeof(nflog_tlv_t); - length -= sizeof(nflog_tlv_t); - caplen -= sizeof(nflog_tlv_t); + p += NFLOG_TLV_LEN; + h_size += NFLOG_TLV_LEN; + length -= NFLOG_TLV_LEN; + caplen -= NFLOG_TLV_LEN; break; } @@ -140,29 +201,31 @@ nflog_if_print(netdissect_options *ndo, caplen -= size; } - switch (hdr->nflog_family) { + switch (GET_U_1(hdr->nflog_family)) { case AF_INET: ip_print(ndo, p, length); break; -#ifdef AF_INET6 case AF_INET6: ip6_print(ndo, p, length); break; -#endif /* AF_INET6 */ default: if (!ndo->ndo_eflag) nflog_hdr_print(ndo, hdr, - length + sizeof(nflog_hdr_t)); + length + NFLOG_HDR_LEN); if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); break; } - return h_size; + ndo->ndo_ll_hdr_len += h_size - NFLOG_HDR_LEN; + return; +trunc: + nd_print_trunc(ndo); + ndo->ndo_ll_hdr_len += h_size - NFLOG_HDR_LEN; } -#endif /* defined(DLT_NFLOG) && defined(HAVE_PCAP_NFLOG_H) */ +#endif /* DLT_NFLOG */ diff --git a/contrib/tcpdump/print-nfs.c b/contrib/tcpdump/print-nfs.c index 2118a963fb..20b0cfcef4 100644 --- a/contrib/tcpdump/print-nfs.c +++ b/contrib/tcpdump/print-nfs.c @@ -22,13 +22,14 @@ /* \summary: Network File System (NFS) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include #include +#include #include "netdissect.h" #include "addrtoname.h" @@ -42,12 +43,10 @@ #include "rpc_auth.h" #include "rpc_msg.h" -static const char tstr[] = " [|nfs]"; static void nfs_printfh(netdissect_options *, const uint32_t *, const u_int); static int xid_map_enter(netdissect_options *, const struct sunrpc_msg *, const u_char *); -static int xid_map_find(const struct sunrpc_msg *, const u_char *, - uint32_t *, uint32_t *); +static int xid_map_find(netdissect_options *, const struct sunrpc_msg *, const u_char *, uint32_t *, uint32_t *); static void interp_reply(netdissect_options *, const struct sunrpc_msg *, uint32_t, uint32_t, int); static const uint32_t *parse_post_op_attr(netdissect_options *, const uint32_t *, int); @@ -210,14 +209,14 @@ print_nfsaddr(netdissect_options *ndo, switch (IP_V((const struct ip *)bp)) { case 4: ip = (const struct ip *)bp; - strlcpy(srcaddr, ipaddr_string(ndo, &ip->ip_src), sizeof(srcaddr)); - strlcpy(dstaddr, ipaddr_string(ndo, &ip->ip_dst), sizeof(dstaddr)); + strlcpy(srcaddr, GET_IPADDR_STRING(ip->ip_src), sizeof(srcaddr)); + strlcpy(dstaddr, GET_IPADDR_STRING(ip->ip_dst), sizeof(dstaddr)); break; case 6: ip6 = (const struct ip6_hdr *)bp; - strlcpy(srcaddr, ip6addr_string(ndo, &ip6->ip6_src), + strlcpy(srcaddr, GET_IP6ADDR_STRING(ip6->ip6_src), sizeof(srcaddr)); - strlcpy(dstaddr, ip6addr_string(ndo, &ip6->ip6_dst), + strlcpy(dstaddr, GET_IP6ADDR_STRING(ip6->ip6_dst), sizeof(dstaddr)); break; default: @@ -226,188 +225,193 @@ print_nfsaddr(netdissect_options *ndo, break; } - ND_PRINT((ndo, "%s.%s > %s.%s: ", srcaddr, s, dstaddr, d)); + ND_PRINT("%s.%s > %s.%s: ", srcaddr, s, dstaddr, d); } +/* + * NFS Version 3 sattr3 structure for the new node creation case. + * This does not have a fixed layout on the network, so this + * structure does not correspond to the layout of the data on + * the network; it's used to store the data when the sattr3 + * is parsed for use when it's later printed. + */ +struct nfsv3_sattr { + uint32_t sa_modeset; + uint32_t sa_mode; + uint32_t sa_uidset; + uint32_t sa_uid; + uint32_t sa_gidset; + uint32_t sa_gid; + uint32_t sa_sizeset; + uint32_t sa_size; + uint32_t sa_atimetype; + struct { + uint32_t nfsv3_sec; + uint32_t nfsv3_nsec; + } sa_atime; + uint32_t sa_mtimetype; + struct { + uint32_t nfsv3_sec; + uint32_t nfsv3_nsec; + } sa_mtime; +}; + static const uint32_t * parse_sattr3(netdissect_options *ndo, const uint32_t *dp, struct nfsv3_sattr *sa3) { - ND_TCHECK(dp[0]); - sa3->sa_modeset = EXTRACT_32BITS(dp); + sa3->sa_modeset = GET_BE_U_4(dp); dp++; if (sa3->sa_modeset) { - ND_TCHECK(dp[0]); - sa3->sa_mode = EXTRACT_32BITS(dp); + sa3->sa_mode = GET_BE_U_4(dp); dp++; } - ND_TCHECK(dp[0]); - sa3->sa_uidset = EXTRACT_32BITS(dp); + sa3->sa_uidset = GET_BE_U_4(dp); dp++; if (sa3->sa_uidset) { - ND_TCHECK(dp[0]); - sa3->sa_uid = EXTRACT_32BITS(dp); + sa3->sa_uid = GET_BE_U_4(dp); dp++; } - ND_TCHECK(dp[0]); - sa3->sa_gidset = EXTRACT_32BITS(dp); + sa3->sa_gidset = GET_BE_U_4(dp); dp++; if (sa3->sa_gidset) { - ND_TCHECK(dp[0]); - sa3->sa_gid = EXTRACT_32BITS(dp); + sa3->sa_gid = GET_BE_U_4(dp); dp++; } - ND_TCHECK(dp[0]); - sa3->sa_sizeset = EXTRACT_32BITS(dp); + sa3->sa_sizeset = GET_BE_U_4(dp); dp++; if (sa3->sa_sizeset) { - ND_TCHECK(dp[0]); - sa3->sa_size = EXTRACT_32BITS(dp); + sa3->sa_size = GET_BE_U_4(dp); dp++; } - ND_TCHECK(dp[0]); - sa3->sa_atimetype = EXTRACT_32BITS(dp); + sa3->sa_atimetype = GET_BE_U_4(dp); dp++; if (sa3->sa_atimetype == NFSV3SATTRTIME_TOCLIENT) { - ND_TCHECK(dp[1]); - sa3->sa_atime.nfsv3_sec = EXTRACT_32BITS(dp); + sa3->sa_atime.nfsv3_sec = GET_BE_U_4(dp); dp++; - sa3->sa_atime.nfsv3_nsec = EXTRACT_32BITS(dp); + sa3->sa_atime.nfsv3_nsec = GET_BE_U_4(dp); dp++; } - ND_TCHECK(dp[0]); - sa3->sa_mtimetype = EXTRACT_32BITS(dp); + sa3->sa_mtimetype = GET_BE_U_4(dp); dp++; if (sa3->sa_mtimetype == NFSV3SATTRTIME_TOCLIENT) { - ND_TCHECK(dp[1]); - sa3->sa_mtime.nfsv3_sec = EXTRACT_32BITS(dp); + sa3->sa_mtime.nfsv3_sec = GET_BE_U_4(dp); dp++; - sa3->sa_mtime.nfsv3_nsec = EXTRACT_32BITS(dp); + sa3->sa_mtime.nfsv3_nsec = GET_BE_U_4(dp); dp++; } return dp; -trunc: - return NULL; } -static int nfserr; /* true if we error rather than trunc */ - static void print_sattr3(netdissect_options *ndo, const struct nfsv3_sattr *sa3, int verbose) { if (sa3->sa_modeset) - ND_PRINT((ndo, " mode %o", sa3->sa_mode)); + ND_PRINT(" mode %o", sa3->sa_mode); if (sa3->sa_uidset) - ND_PRINT((ndo, " uid %u", sa3->sa_uid)); + ND_PRINT(" uid %u", sa3->sa_uid); if (sa3->sa_gidset) - ND_PRINT((ndo, " gid %u", sa3->sa_gid)); + ND_PRINT(" gid %u", sa3->sa_gid); if (verbose > 1) { if (sa3->sa_atimetype == NFSV3SATTRTIME_TOCLIENT) - ND_PRINT((ndo, " atime %u.%06u", sa3->sa_atime.nfsv3_sec, - sa3->sa_atime.nfsv3_nsec)); + ND_PRINT(" atime %u.%06u", sa3->sa_atime.nfsv3_sec, + sa3->sa_atime.nfsv3_nsec); if (sa3->sa_mtimetype == NFSV3SATTRTIME_TOCLIENT) - ND_PRINT((ndo, " mtime %u.%06u", sa3->sa_mtime.nfsv3_sec, - sa3->sa_mtime.nfsv3_nsec)); + ND_PRINT(" mtime %u.%06u", sa3->sa_mtime.nfsv3_sec, + sa3->sa_mtime.nfsv3_nsec); } } void nfsreply_print(netdissect_options *ndo, - register const u_char *bp, u_int length, - register const u_char *bp2) + const u_char *bp, u_int length, + const u_char *bp2) { - register const struct sunrpc_msg *rp; + const struct sunrpc_msg *rp; char srcid[20], dstid[20]; /*fits 32bit*/ - nfserr = 0; /* assume no error */ + ndo->ndo_protocol = "nfs"; rp = (const struct sunrpc_msg *)bp; - ND_TCHECK(rp->rm_xid); if (!ndo->ndo_nflag) { strlcpy(srcid, "nfs", sizeof(srcid)); snprintf(dstid, sizeof(dstid), "%u", - EXTRACT_32BITS(&rp->rm_xid)); + GET_BE_U_4(rp->rm_xid)); } else { snprintf(srcid, sizeof(srcid), "%u", NFS_PORT); snprintf(dstid, sizeof(dstid), "%u", - EXTRACT_32BITS(&rp->rm_xid)); + GET_BE_U_4(rp->rm_xid)); } print_nfsaddr(ndo, bp2, srcid, dstid); - nfsreply_print_noaddr(ndo, bp, length, bp2); - return; - -trunc: - if (!nfserr) - ND_PRINT((ndo, "%s", tstr)); + nfsreply_noaddr_print(ndo, bp, length, bp2); } void -nfsreply_print_noaddr(netdissect_options *ndo, - register const u_char *bp, u_int length, - register const u_char *bp2) +nfsreply_noaddr_print(netdissect_options *ndo, + const u_char *bp, u_int length, + const u_char *bp2) { - register const struct sunrpc_msg *rp; + const struct sunrpc_msg *rp; uint32_t proc, vers, reply_stat; enum sunrpc_reject_stat rstat; uint32_t rlow; uint32_t rhigh; enum sunrpc_auth_stat rwhy; - nfserr = 0; /* assume no error */ + ndo->ndo_protocol = "nfs"; rp = (const struct sunrpc_msg *)bp; - ND_TCHECK(rp->rm_reply.rp_stat); - reply_stat = EXTRACT_32BITS(&rp->rm_reply.rp_stat); + ND_TCHECK_4(rp->rm_reply.rp_stat); + reply_stat = GET_BE_U_4(&rp->rm_reply.rp_stat); switch (reply_stat) { case SUNRPC_MSG_ACCEPTED: - ND_PRINT((ndo, "reply ok %u", length)); - if (xid_map_find(rp, bp2, &proc, &vers) >= 0) + ND_PRINT("reply ok %u", length); + if (xid_map_find(ndo, rp, bp2, &proc, &vers) >= 0) interp_reply(ndo, rp, proc, vers, length); break; case SUNRPC_MSG_DENIED: - ND_PRINT((ndo, "reply ERR %u: ", length)); - ND_TCHECK(rp->rm_reply.rp_reject.rj_stat); - rstat = EXTRACT_32BITS(&rp->rm_reply.rp_reject.rj_stat); + ND_PRINT("reply ERR %u: ", length); + ND_TCHECK_4(rp->rm_reply.rp_reject.rj_stat); + rstat = GET_BE_U_4(&rp->rm_reply.rp_reject.rj_stat); switch (rstat) { case SUNRPC_RPC_MISMATCH: - ND_TCHECK(rp->rm_reply.rp_reject.rj_vers.high); - rlow = EXTRACT_32BITS(&rp->rm_reply.rp_reject.rj_vers.low); - rhigh = EXTRACT_32BITS(&rp->rm_reply.rp_reject.rj_vers.high); - ND_PRINT((ndo, "RPC Version mismatch (%u-%u)", rlow, rhigh)); + ND_TCHECK_4(rp->rm_reply.rp_reject.rj_vers.high); + rlow = GET_BE_U_4(&rp->rm_reply.rp_reject.rj_vers.low); + rhigh = GET_BE_U_4(&rp->rm_reply.rp_reject.rj_vers.high); + ND_PRINT("RPC Version mismatch (%u-%u)", rlow, rhigh); break; case SUNRPC_AUTH_ERROR: - ND_TCHECK(rp->rm_reply.rp_reject.rj_why); - rwhy = EXTRACT_32BITS(&rp->rm_reply.rp_reject.rj_why); - ND_PRINT((ndo, "Auth %s", tok2str(sunrpc_auth_str, "Invalid failure code %u", rwhy))); + ND_TCHECK_4(rp->rm_reply.rp_reject.rj_why); + rwhy = GET_BE_U_4(&rp->rm_reply.rp_reject.rj_why); + ND_PRINT("Auth %s", tok2str(sunrpc_auth_str, "Invalid failure code %u", rwhy)); break; default: - ND_PRINT((ndo, "Unknown reason for rejecting rpc message %u", (unsigned int)rstat)); + ND_PRINT("Unknown reason for rejecting rpc message %u", (unsigned int)rstat); break; } break; default: - ND_PRINT((ndo, "reply Unknown rpc response code=%u %u", reply_stat, length)); + ND_PRINT("reply Unknown rpc response code=%u %u", reply_stat, length); break; } return; trunc: - if (!nfserr) - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); } /* @@ -416,24 +420,49 @@ trunc: */ static const uint32_t * parsereq(netdissect_options *ndo, - register const struct sunrpc_msg *rp, register u_int length) + const struct sunrpc_msg *rp, u_int length) { - register const uint32_t *dp; - register u_int len; + const uint32_t *dp; + u_int len, rounded_len; /* - * find the start of the req data (if we captured it) + * Find the start of the req data (if we captured it). + * First, get the length of the credentials, and make sure + * we have all of the opaque part of the credentials. */ dp = (const uint32_t *)&rp->rm_call.cb_cred; - ND_TCHECK(dp[1]); - len = EXTRACT_32BITS(&dp[1]); - if (len < length) { + if (length < 2 * sizeof(*dp)) + goto trunc; + len = GET_BE_U_4(dp + 1); + rounded_len = roundup2(len, 4); + ND_TCHECK_LEN(dp + 2, rounded_len); + if (2 * sizeof(*dp) + rounded_len <= length) { + /* + * We have all of the credentials. Skip past them; they + * consist of 4 bytes of flavor, 4 bytes of length, + * and len-rounded-up-to-a-multiple-of-4 bytes of + * data. + */ dp += (len + (2 * sizeof(*dp) + 3)) / sizeof(*dp); - ND_TCHECK(dp[1]); - len = EXTRACT_32BITS(&dp[1]); - if (len < length) { + length -= 2 * sizeof(*dp) + rounded_len; + + /* + * Now get the length of the verifier, and make sure + * we have all of the opaque part of the verifier. + */ + if (length < 2 * sizeof(*dp)) + goto trunc; + len = GET_BE_U_4(dp + 1); + rounded_len = roundup2(len, 4); + ND_TCHECK_LEN(dp + 2, rounded_len); + if (2 * sizeof(*dp) + rounded_len < length) { + /* + * We have all of the verifier. Skip past it; + * it consists of 4 bytes of flavor, 4 bytes of + * length, and len-rounded-up-to-a-multiple-of-4 + * bytes of data. + */ dp += (len + (2 * sizeof(*dp) + 3)) / sizeof(*dp); - ND_TCHECK2(dp[0], 0); return (dp); } } @@ -447,23 +476,21 @@ trunc: */ static const uint32_t * parsefh(netdissect_options *ndo, - register const uint32_t *dp, int v3) + const uint32_t *dp, int v3) { u_int len; if (v3) { - ND_TCHECK(dp[0]); - len = EXTRACT_32BITS(dp) / 4; + len = GET_BE_U_4(dp) / 4; dp++; } else len = NFSX_V2FH / 4; - if (ND_TTEST2(*dp, len * sizeof(*dp))) { + if (ND_TTEST_LEN(dp, len * sizeof(*dp))) { nfs_printfh(ndo, dp, len); return (dp + len); - } -trunc: - return (NULL); + } else + return NULL; } /* @@ -472,29 +499,33 @@ trunc: */ static const uint32_t * parsefn(netdissect_options *ndo, - register const uint32_t *dp) + const uint32_t *dp) { - register uint32_t len; - register const u_char *cp; + uint32_t len, rounded_len; + const u_char *cp; - /* Bail if we don't have the string length */ - ND_TCHECK(*dp); + /* Fetch big-endian string length */ + len = GET_BE_U_4(dp); + dp++; - /* Fetch string length; convert to host order */ - len = *dp++; - NTOHL(len); + if (UINT_MAX - len < 3) { + ND_PRINT("[cannot pad to 32-bit boundaries]"); + nd_print_invalid(ndo); + return NULL; + } - ND_TCHECK2(*dp, ((len + 3) & ~3)); + rounded_len = roundup2(len, 4); + ND_TCHECK_LEN(dp, rounded_len); cp = (const u_char *)dp; /* Update 32-bit pointer (NFS filenames padded to 32-bit boundaries) */ - dp += ((len + 3) & ~3) / sizeof(*dp); - ND_PRINT((ndo, "\"")); - if (fn_printn(ndo, cp, len, ndo->ndo_snapend)) { - ND_PRINT((ndo, "\"")); + dp += rounded_len / sizeof(*dp); + ND_PRINT("\""); + if (nd_printn(ndo, cp, len, ndo->ndo_snapend)) { + ND_PRINT("\""); goto trunc; } - ND_PRINT((ndo, "\"")); + ND_PRINT("\""); return (dp); trunc: @@ -508,42 +539,42 @@ trunc: */ static const uint32_t * parsefhn(netdissect_options *ndo, - register const uint32_t *dp, int v3) + const uint32_t *dp, int v3) { dp = parsefh(ndo, dp, v3); if (dp == NULL) return (NULL); - ND_PRINT((ndo, " ")); + ND_PRINT(" "); return (parsefn(ndo, dp)); } void -nfsreq_print_noaddr(netdissect_options *ndo, - register const u_char *bp, u_int length, - register const u_char *bp2) +nfsreq_noaddr_print(netdissect_options *ndo, + const u_char *bp, u_int length, + const u_char *bp2) { - register const struct sunrpc_msg *rp; - register const uint32_t *dp; + const struct sunrpc_msg *rp; + const uint32_t *dp; nfs_type type; int v3; uint32_t proc; uint32_t access_flags; struct nfsv3_sattr sa3; - ND_PRINT((ndo, "%d", length)); - nfserr = 0; /* assume no error */ + ndo->ndo_protocol = "nfs"; + ND_PRINT("%u", length); rp = (const struct sunrpc_msg *)bp; if (!xid_map_enter(ndo, rp, bp2)) /* record proc number for later on */ goto trunc; - v3 = (EXTRACT_32BITS(&rp->rm_call.cb_vers) == NFS_VER3); - proc = EXTRACT_32BITS(&rp->rm_call.cb_proc); + v3 = (GET_BE_U_4(&rp->rm_call.cb_vers) == NFS_VER3); + proc = GET_BE_U_4(&rp->rm_call.cb_proc); if (!v3 && proc < NFS_NPROCS) proc = nfsv3_procid[proc]; - ND_PRINT((ndo, " %s", tok2str(nfsproc_str, "proc-%u", proc))); + ND_PRINT(" %s", tok2str(nfsproc_str, "proc-%u", proc)); switch (proc) { case NFSPROC_GETATTR: @@ -552,9 +583,11 @@ nfsreq_print_noaddr(netdissect_options *ndo, case NFSPROC_FSSTAT: case NFSPROC_FSINFO: case NFSPROC_PATHCONF: - if ((dp = parsereq(ndo, rp, length)) != NULL && - parsefh(ndo, dp, v3) != NULL) - return; + dp = parsereq(ndo, rp, length); + if (dp == NULL) + goto trunc; + if (parsefh(ndo, dp, v3) == NULL) + goto trunc; break; case NFSPROC_LOOKUP: @@ -562,214 +595,244 @@ nfsreq_print_noaddr(netdissect_options *ndo, case NFSPROC_MKDIR: case NFSPROC_REMOVE: case NFSPROC_RMDIR: - if ((dp = parsereq(ndo, rp, length)) != NULL && - parsefhn(ndo, dp, v3) != NULL) - return; + dp = parsereq(ndo, rp, length); + if (dp == NULL) + goto trunc; + if (parsefhn(ndo, dp, v3) == NULL) + goto trunc; break; case NFSPROC_ACCESS: - if ((dp = parsereq(ndo, rp, length)) != NULL && - (dp = parsefh(ndo, dp, v3)) != NULL) { - ND_TCHECK(dp[0]); - access_flags = EXTRACT_32BITS(&dp[0]); - if (access_flags & ~NFSV3ACCESS_FULL) { - /* NFSV3ACCESS definitions aren't up to date */ - ND_PRINT((ndo, " %04x", access_flags)); - } else if ((access_flags & NFSV3ACCESS_FULL) == NFSV3ACCESS_FULL) { - ND_PRINT((ndo, " NFS_ACCESS_FULL")); - } else { - char separator = ' '; - if (access_flags & NFSV3ACCESS_READ) { - ND_PRINT((ndo, " NFS_ACCESS_READ")); - separator = '|'; - } - if (access_flags & NFSV3ACCESS_LOOKUP) { - ND_PRINT((ndo, "%cNFS_ACCESS_LOOKUP", separator)); - separator = '|'; - } - if (access_flags & NFSV3ACCESS_MODIFY) { - ND_PRINT((ndo, "%cNFS_ACCESS_MODIFY", separator)); - separator = '|'; - } - if (access_flags & NFSV3ACCESS_EXTEND) { - ND_PRINT((ndo, "%cNFS_ACCESS_EXTEND", separator)); - separator = '|'; - } - if (access_flags & NFSV3ACCESS_DELETE) { - ND_PRINT((ndo, "%cNFS_ACCESS_DELETE", separator)); - separator = '|'; - } - if (access_flags & NFSV3ACCESS_EXECUTE) - ND_PRINT((ndo, "%cNFS_ACCESS_EXECUTE", separator)); + dp = parsereq(ndo, rp, length); + if (dp == NULL) + goto trunc; + dp = parsefh(ndo, dp, v3); + if (dp == NULL) + goto trunc; + access_flags = GET_BE_U_4(dp); + if (access_flags & ~NFSV3ACCESS_FULL) { + /* NFSV3ACCESS definitions aren't up to date */ + ND_PRINT(" %04x", access_flags); + } else if ((access_flags & NFSV3ACCESS_FULL) == NFSV3ACCESS_FULL) { + ND_PRINT(" NFS_ACCESS_FULL"); + } else { + char separator = ' '; + if (access_flags & NFSV3ACCESS_READ) { + ND_PRINT(" NFS_ACCESS_READ"); + separator = '|'; } - return; + if (access_flags & NFSV3ACCESS_LOOKUP) { + ND_PRINT("%cNFS_ACCESS_LOOKUP", separator); + separator = '|'; + } + if (access_flags & NFSV3ACCESS_MODIFY) { + ND_PRINT("%cNFS_ACCESS_MODIFY", separator); + separator = '|'; + } + if (access_flags & NFSV3ACCESS_EXTEND) { + ND_PRINT("%cNFS_ACCESS_EXTEND", separator); + separator = '|'; + } + if (access_flags & NFSV3ACCESS_DELETE) { + ND_PRINT("%cNFS_ACCESS_DELETE", separator); + separator = '|'; + } + if (access_flags & NFSV3ACCESS_EXECUTE) + ND_PRINT("%cNFS_ACCESS_EXECUTE", separator); } break; case NFSPROC_READ: - if ((dp = parsereq(ndo, rp, length)) != NULL && - (dp = parsefh(ndo, dp, v3)) != NULL) { - if (v3) { - ND_TCHECK(dp[2]); - ND_PRINT((ndo, " %u bytes @ %" PRIu64, - EXTRACT_32BITS(&dp[2]), - EXTRACT_64BITS(&dp[0]))); - } else { - ND_TCHECK(dp[1]); - ND_PRINT((ndo, " %u bytes @ %u", - EXTRACT_32BITS(&dp[1]), - EXTRACT_32BITS(&dp[0]))); - } - return; + dp = parsereq(ndo, rp, length); + if (dp == NULL) + goto trunc; + dp = parsefh(ndo, dp, v3); + if (dp == NULL) + goto trunc; + if (v3) { + ND_PRINT(" %u bytes @ %" PRIu64, + GET_BE_U_4(dp + 2), + GET_BE_U_8(dp)); + } else { + ND_PRINT(" %u bytes @ %u", + GET_BE_U_4(dp + 1), + GET_BE_U_4(dp)); } break; case NFSPROC_WRITE: - if ((dp = parsereq(ndo, rp, length)) != NULL && - (dp = parsefh(ndo, dp, v3)) != NULL) { - if (v3) { - ND_TCHECK(dp[4]); - ND_PRINT((ndo, " %u (%u) bytes @ %" PRIu64, - EXTRACT_32BITS(&dp[4]), - EXTRACT_32BITS(&dp[2]), - EXTRACT_64BITS(&dp[0]))); - if (ndo->ndo_vflag) { - ND_PRINT((ndo, " <%s>", - tok2str(nfsv3_writemodes, - NULL, EXTRACT_32BITS(&dp[3])))); - } - } else { - ND_TCHECK(dp[3]); - ND_PRINT((ndo, " %u (%u) bytes @ %u (%u)", - EXTRACT_32BITS(&dp[3]), - EXTRACT_32BITS(&dp[2]), - EXTRACT_32BITS(&dp[1]), - EXTRACT_32BITS(&dp[0]))); + dp = parsereq(ndo, rp, length); + if (dp == NULL) + goto trunc; + dp = parsefh(ndo, dp, v3); + if (dp == NULL) + goto trunc; + if (v3) { + ND_PRINT(" %u (%u) bytes @ %" PRIu64, + GET_BE_U_4(dp + 4), + GET_BE_U_4(dp + 2), + GET_BE_U_8(dp)); + if (ndo->ndo_vflag) { + ND_PRINT(" <%s>", + tok2str(nfsv3_writemodes, + NULL, GET_BE_U_4(dp + 3))); } - return; + } else { + ND_PRINT(" %u (%u) bytes @ %u (%u)", + GET_BE_U_4(dp + 3), + GET_BE_U_4(dp + 2), + GET_BE_U_4(dp + 1), + GET_BE_U_4(dp)); } break; case NFSPROC_SYMLINK: - if ((dp = parsereq(ndo, rp, length)) != NULL && - (dp = parsefhn(ndo, dp, v3)) != NULL) { - ND_PRINT((ndo, " ->")); - if (v3 && (dp = parse_sattr3(ndo, dp, &sa3)) == NULL) - break; - if (parsefn(ndo, dp) == NULL) - break; - if (v3 && ndo->ndo_vflag) - print_sattr3(ndo, &sa3, ndo->ndo_vflag); - return; - } + dp = parsereq(ndo, rp, length); + if (dp == NULL) + goto trunc; + dp = parsefhn(ndo, dp, v3); + if (dp == NULL) + goto trunc; + ND_PRINT(" ->"); + if (v3 && (dp = parse_sattr3(ndo, dp, &sa3)) == NULL) + goto trunc; + if (parsefn(ndo, dp) == NULL) + goto trunc; + if (v3 && ndo->ndo_vflag) + print_sattr3(ndo, &sa3, ndo->ndo_vflag); break; case NFSPROC_MKNOD: - if ((dp = parsereq(ndo, rp, length)) != NULL && - (dp = parsefhn(ndo, dp, v3)) != NULL) { - ND_TCHECK(*dp); - type = (nfs_type)EXTRACT_32BITS(dp); - dp++; - if ((dp = parse_sattr3(ndo, dp, &sa3)) == NULL) - break; - ND_PRINT((ndo, " %s", tok2str(type2str, "unk-ft %d", type))); - if (ndo->ndo_vflag && (type == NFCHR || type == NFBLK)) { - ND_TCHECK(dp[1]); - ND_PRINT((ndo, " %u/%u", - EXTRACT_32BITS(&dp[0]), - EXTRACT_32BITS(&dp[1]))); - dp += 2; - } - if (ndo->ndo_vflag) - print_sattr3(ndo, &sa3, ndo->ndo_vflag); - return; + dp = parsereq(ndo, rp, length); + if (dp == NULL) + goto trunc; + dp = parsefhn(ndo, dp, v3); + if (dp == NULL) + goto trunc; + type = (nfs_type) GET_BE_U_4(dp); + dp++; + dp = parse_sattr3(ndo, dp, &sa3); + if (dp == NULL) + goto trunc; + ND_PRINT(" %s", tok2str(type2str, "unk-ft %u", type)); + if (ndo->ndo_vflag && (type == NFCHR || type == NFBLK)) { + ND_PRINT(" %u/%u", + GET_BE_U_4(dp), + GET_BE_U_4(dp + 1)); + dp += 2; } + if (ndo->ndo_vflag) + print_sattr3(ndo, &sa3, ndo->ndo_vflag); break; case NFSPROC_RENAME: - if ((dp = parsereq(ndo, rp, length)) != NULL && - (dp = parsefhn(ndo, dp, v3)) != NULL) { - ND_PRINT((ndo, " ->")); - if (parsefhn(ndo, dp, v3) != NULL) - return; - } + dp = parsereq(ndo, rp, length); + if (dp == NULL) + goto trunc; + dp = parsefhn(ndo, dp, v3); + if (dp == NULL) + goto trunc; + ND_PRINT(" ->"); + if (parsefhn(ndo, dp, v3) == NULL) + goto trunc; break; case NFSPROC_LINK: - if ((dp = parsereq(ndo, rp, length)) != NULL && - (dp = parsefh(ndo, dp, v3)) != NULL) { - ND_PRINT((ndo, " ->")); - if (parsefhn(ndo, dp, v3) != NULL) - return; - } + dp = parsereq(ndo, rp, length); + if (dp == NULL) + goto trunc; + dp = parsefh(ndo, dp, v3); + if (dp == NULL) + goto trunc; + ND_PRINT(" ->"); + if (parsefhn(ndo, dp, v3) == NULL) + goto trunc; break; case NFSPROC_READDIR: - if ((dp = parsereq(ndo, rp, length)) != NULL && - (dp = parsefh(ndo, dp, v3)) != NULL) { - if (v3) { - ND_TCHECK(dp[4]); - /* - * We shouldn't really try to interpret the - * offset cookie here. - */ - ND_PRINT((ndo, " %u bytes @ %" PRId64, - EXTRACT_32BITS(&dp[4]), - EXTRACT_64BITS(&dp[0]))); - if (ndo->ndo_vflag) - ND_PRINT((ndo, " verf %08x%08x", dp[2], dp[3])); - } else { - ND_TCHECK(dp[1]); + dp = parsereq(ndo, rp, length); + if (dp == NULL) + goto trunc; + dp = parsefh(ndo, dp, v3); + if (dp == NULL) + goto trunc; + if (v3) { + /* + * We shouldn't really try to interpret the + * offset cookie here. + */ + ND_PRINT(" %u bytes @ %" PRId64, + GET_BE_U_4(dp + 4), + GET_BE_U_8(dp)); + if (ndo->ndo_vflag) { /* - * Print the offset as signed, since -1 is - * common, but offsets > 2^31 aren't. + * This displays the 8 bytes + * of the verifier in order, + * from the low-order byte + * to the high-order byte. */ - ND_PRINT((ndo, " %u bytes @ %d", - EXTRACT_32BITS(&dp[1]), - EXTRACT_32BITS(&dp[0]))); + ND_PRINT(" verf %08x%08x", + GET_BE_U_4(dp + 2), + GET_BE_U_4(dp + 3)); } - return; + } else { + /* + * Print the offset as signed, since -1 is + * common, but offsets > 2^31 aren't. + */ + ND_PRINT(" %u bytes @ %u", + GET_BE_U_4(dp + 1), + GET_BE_U_4(dp)); } break; case NFSPROC_READDIRPLUS: - if ((dp = parsereq(ndo, rp, length)) != NULL && - (dp = parsefh(ndo, dp, v3)) != NULL) { - ND_TCHECK(dp[4]); + dp = parsereq(ndo, rp, length); + if (dp == NULL) + goto trunc; + dp = parsefh(ndo, dp, v3); + if (dp == NULL) + goto trunc; + /* + * We don't try to interpret the offset + * cookie here. + */ + ND_PRINT(" %u bytes @ %" PRId64, + GET_BE_U_4(dp + 4), + GET_BE_U_8(dp)); + if (ndo->ndo_vflag) { /* - * We don't try to interpret the offset - * cookie here. + * This displays the 8 bytes + * of the verifier in order, + * from the low-order byte + * to the high-order byte. */ - ND_PRINT((ndo, " %u bytes @ %" PRId64, - EXTRACT_32BITS(&dp[4]), - EXTRACT_64BITS(&dp[0]))); - if (ndo->ndo_vflag) { - ND_TCHECK(dp[5]); - ND_PRINT((ndo, " max %u verf %08x%08x", - EXTRACT_32BITS(&dp[5]), dp[2], dp[3])); - } - return; + ND_PRINT(" max %u verf %08x%08x", + GET_BE_U_4(dp + 5), + GET_BE_U_4(dp + 2), + GET_BE_U_4(dp + 3)); } break; case NFSPROC_COMMIT: - if ((dp = parsereq(ndo, rp, length)) != NULL && - (dp = parsefh(ndo, dp, v3)) != NULL) { - ND_TCHECK(dp[2]); - ND_PRINT((ndo, " %u bytes @ %" PRIu64, - EXTRACT_32BITS(&dp[2]), - EXTRACT_64BITS(&dp[0]))); - return; - } + dp = parsereq(ndo, rp, length); + if (dp == NULL) + goto trunc; + dp = parsefh(ndo, dp, v3); + if (dp == NULL) + goto trunc; + ND_PRINT(" %u bytes @ %" PRIu64, + GET_BE_U_4(dp + 2), + GET_BE_U_8(dp)); break; default: - return; + break; } + return; trunc: - if (!nfserr) - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); } /* @@ -783,7 +846,7 @@ trunc: */ static void nfs_printfh(netdissect_options *ndo, - register const uint32_t *dp, const u_int len) + const uint32_t *dp, const u_int len) { my_fsid fsid; uint32_t ino; @@ -794,16 +857,28 @@ nfs_printfh(netdissect_options *ndo, u_int i; char const *sep = ""; - ND_PRINT((ndo, " fh[")); + ND_PRINT(" fh["); for (i=0; irm_call.cb_proc)) + if (!ND_TTEST_4(rp->rm_call.cb_proc)) return (0); switch (IP_V((const struct ip *)bp)) { case 4: @@ -891,16 +966,20 @@ xid_map_enter(netdissect_options *ndo, UNALIGNED_MEMCPY(&xmep->xid, &rp->rm_xid, sizeof(xmep->xid)); if (ip) { xmep->ipver = 4; - UNALIGNED_MEMCPY(&xmep->client, &ip->ip_src, sizeof(ip->ip_src)); - UNALIGNED_MEMCPY(&xmep->server, &ip->ip_dst, sizeof(ip->ip_dst)); + UNALIGNED_MEMCPY(&xmep->client, ip->ip_src, + sizeof(ip->ip_src)); + UNALIGNED_MEMCPY(&xmep->server, ip->ip_dst, + sizeof(ip->ip_dst)); } else if (ip6) { xmep->ipver = 6; - UNALIGNED_MEMCPY(&xmep->client, &ip6->ip6_src, sizeof(ip6->ip6_src)); - UNALIGNED_MEMCPY(&xmep->server, &ip6->ip6_dst, sizeof(ip6->ip6_dst)); + UNALIGNED_MEMCPY(&xmep->client, ip6->ip6_src, + sizeof(ip6->ip6_src)); + UNALIGNED_MEMCPY(&xmep->server, ip6->ip6_dst, + sizeof(ip6->ip6_dst)); } - xmep->proc = EXTRACT_32BITS(&rp->rm_call.cb_proc); - xmep->vers = EXTRACT_32BITS(&rp->rm_call.cb_vers); + xmep->proc = GET_BE_U_4(&rp->rm_call.cb_proc); + xmep->vers = GET_BE_U_4(&rp->rm_call.cb_vers); return (1); } @@ -909,8 +988,8 @@ xid_map_enter(netdissect_options *ndo, * version in vers return, or returns -1 on failure */ static int -xid_map_find(const struct sunrpc_msg *rp, const u_char *bp, uint32_t *proc, - uint32_t *vers) +xid_map_find(netdissect_options *ndo, const struct sunrpc_msg *rp, + const u_char *bp, uint32_t *proc, uint32_t *vers) { int i; struct xid_map_entry *xmep; @@ -929,18 +1008,18 @@ xid_map_find(const struct sunrpc_msg *rp, const u_char *bp, uint32_t *proc, goto nextitem; switch (xmep->ipver) { case 4: - if (UNALIGNED_MEMCMP(&ip->ip_src, &xmep->server, - sizeof(ip->ip_src)) != 0 || - UNALIGNED_MEMCMP(&ip->ip_dst, &xmep->client, - sizeof(ip->ip_dst)) != 0) { + if (UNALIGNED_MEMCMP(ip->ip_src, &xmep->server, + sizeof(ip->ip_src)) != 0 || + UNALIGNED_MEMCMP(ip->ip_dst, &xmep->client, + sizeof(ip->ip_dst)) != 0) { cmp = 0; } break; case 6: - if (UNALIGNED_MEMCMP(&ip6->ip6_src, &xmep->server, - sizeof(ip6->ip6_src)) != 0 || - UNALIGNED_MEMCMP(&ip6->ip6_dst, &xmep->client, - sizeof(ip6->ip6_dst)) != 0) { + if (UNALIGNED_MEMCMP(ip6->ip6_src, &xmep->server, + sizeof(ip6->ip6_src)) != 0 || + UNALIGNED_MEMCMP(ip6->ip6_dst, &xmep->client, + sizeof(ip6->ip6_dst)) != 0) { cmp = 0; } break; @@ -974,9 +1053,9 @@ xid_map_find(const struct sunrpc_msg *rp, const u_char *bp, uint32_t *proc, */ static const uint32_t * parserep(netdissect_options *ndo, - register const struct sunrpc_msg *rp, register u_int length) + const struct sunrpc_msg *rp, u_int length, int *nfserrp) { - register const uint32_t *dp; + const uint32_t *dp; u_int len; enum sunrpc_accept_stat astat; @@ -996,8 +1075,7 @@ parserep(netdissect_options *ndo, * which is an "enum" and so occupies one 32-bit word. */ dp = ((const uint32_t *)&rp->rm_reply) + 1; - ND_TCHECK(dp[1]); - len = EXTRACT_32BITS(&dp[1]); + len = GET_BE_U_4(dp + 1); if (len >= length) return (NULL); /* @@ -1008,15 +1086,14 @@ parserep(netdissect_options *ndo, /* * now we can check the ar_stat field */ - ND_TCHECK(dp[0]); - astat = (enum sunrpc_accept_stat) EXTRACT_32BITS(dp); + astat = (enum sunrpc_accept_stat) GET_BE_U_4(dp); if (astat != SUNRPC_SUCCESS) { - ND_PRINT((ndo, " %s", tok2str(sunrpc_str, "ar_stat %d", astat))); - nfserr = 1; /* suppress trunc string */ + ND_PRINT(" %s", tok2str(sunrpc_str, "ar_stat %u", astat)); + *nfserrp = 1; /* suppress trunc string */ return (NULL); } /* successful return */ - ND_TCHECK2(*dp, sizeof(astat)); + ND_TCHECK_LEN(dp, sizeof(astat)); return ((const uint32_t *) (sizeof(astat) + ((const char *)dp))); trunc: return (0); @@ -1024,24 +1101,20 @@ trunc: static const uint32_t * parsestatus(netdissect_options *ndo, - const uint32_t *dp, int *er) + const uint32_t *dp, u_int *er, int *nfserrp) { - int errnum; + u_int errnum; - ND_TCHECK(dp[0]); - - errnum = EXTRACT_32BITS(&dp[0]); + errnum = GET_BE_U_4(dp); if (er) *er = errnum; if (errnum != 0) { if (!ndo->ndo_qflag) - ND_PRINT((ndo, " ERROR: %s", - tok2str(status2str, "unk %d", errnum))); - nfserr = 1; + ND_PRINT(" ERROR: %s", + tok2str(status2str, "unk %u", errnum)); + *nfserrp = 1; } return (dp + 1); -trunc: - return NULL; } static const uint32_t * @@ -1051,60 +1124,64 @@ parsefattr(netdissect_options *ndo, const struct nfs_fattr *fap; fap = (const struct nfs_fattr *)dp; - ND_TCHECK(fap->fa_gid); + ND_TCHECK_4(fap->fa_gid); if (verbose) { - ND_PRINT((ndo, " %s %o ids %d/%d", - tok2str(type2str, "unk-ft %d ", - EXTRACT_32BITS(&fap->fa_type)), - EXTRACT_32BITS(&fap->fa_mode), - EXTRACT_32BITS(&fap->fa_uid), - EXTRACT_32BITS(&fap->fa_gid))); + /* + * XXX - UIDs and GIDs are unsigned in NFS and in + * at least some UN*Xes, but we'll show them as + * signed because -2 has traditionally been the + * UID for "nobody", rather than 4294967294. + */ + ND_PRINT(" %s %o ids %d/%d", + tok2str(type2str, "unk-ft %u ", + GET_BE_U_4(fap->fa_type)), + GET_BE_U_4(fap->fa_mode), + GET_BE_S_4(fap->fa_uid), + GET_BE_S_4(fap->fa_gid)); if (v3) { - ND_TCHECK(fap->fa3_size); - ND_PRINT((ndo, " sz %" PRIu64, - EXTRACT_64BITS((const uint32_t *)&fap->fa3_size))); + ND_PRINT(" sz %" PRIu64, + GET_BE_U_8(fap->fa3_size)); } else { - ND_TCHECK(fap->fa2_size); - ND_PRINT((ndo, " sz %d", EXTRACT_32BITS(&fap->fa2_size))); + ND_PRINT(" sz %u", GET_BE_U_4(fap->fa2_size)); } } /* print lots more stuff */ if (verbose > 1) { if (v3) { - ND_TCHECK(fap->fa3_ctime); - ND_PRINT((ndo, " nlink %d rdev %d/%d", - EXTRACT_32BITS(&fap->fa_nlink), - EXTRACT_32BITS(&fap->fa3_rdev.specdata1), - EXTRACT_32BITS(&fap->fa3_rdev.specdata2))); - ND_PRINT((ndo, " fsid %" PRIx64, - EXTRACT_64BITS((const uint32_t *)&fap->fa3_fsid))); - ND_PRINT((ndo, " fileid %" PRIx64, - EXTRACT_64BITS((const uint32_t *)&fap->fa3_fileid))); - ND_PRINT((ndo, " a/m/ctime %u.%06u", - EXTRACT_32BITS(&fap->fa3_atime.nfsv3_sec), - EXTRACT_32BITS(&fap->fa3_atime.nfsv3_nsec))); - ND_PRINT((ndo, " %u.%06u", - EXTRACT_32BITS(&fap->fa3_mtime.nfsv3_sec), - EXTRACT_32BITS(&fap->fa3_mtime.nfsv3_nsec))); - ND_PRINT((ndo, " %u.%06u", - EXTRACT_32BITS(&fap->fa3_ctime.nfsv3_sec), - EXTRACT_32BITS(&fap->fa3_ctime.nfsv3_nsec))); + ND_TCHECK_8(&fap->fa3_ctime); + ND_PRINT(" nlink %u rdev %u/%u", + GET_BE_U_4(fap->fa_nlink), + GET_BE_U_4(fap->fa3_rdev.specdata1), + GET_BE_U_4(fap->fa3_rdev.specdata2)); + ND_PRINT(" fsid %" PRIx64, + GET_BE_U_8(fap->fa3_fsid)); + ND_PRINT(" fileid %" PRIx64, + GET_BE_U_8(fap->fa3_fileid)); + ND_PRINT(" a/m/ctime %u.%06u", + GET_BE_U_4(fap->fa3_atime.nfsv3_sec), + GET_BE_U_4(fap->fa3_atime.nfsv3_nsec)); + ND_PRINT(" %u.%06u", + GET_BE_U_4(fap->fa3_mtime.nfsv3_sec), + GET_BE_U_4(fap->fa3_mtime.nfsv3_nsec)); + ND_PRINT(" %u.%06u", + GET_BE_U_4(fap->fa3_ctime.nfsv3_sec), + GET_BE_U_4(fap->fa3_ctime.nfsv3_nsec)); } else { - ND_TCHECK(fap->fa2_ctime); - ND_PRINT((ndo, " nlink %d rdev 0x%x fsid 0x%x nodeid 0x%x a/m/ctime", - EXTRACT_32BITS(&fap->fa_nlink), - EXTRACT_32BITS(&fap->fa2_rdev), - EXTRACT_32BITS(&fap->fa2_fsid), - EXTRACT_32BITS(&fap->fa2_fileid))); - ND_PRINT((ndo, " %u.%06u", - EXTRACT_32BITS(&fap->fa2_atime.nfsv2_sec), - EXTRACT_32BITS(&fap->fa2_atime.nfsv2_usec))); - ND_PRINT((ndo, " %u.%06u", - EXTRACT_32BITS(&fap->fa2_mtime.nfsv2_sec), - EXTRACT_32BITS(&fap->fa2_mtime.nfsv2_usec))); - ND_PRINT((ndo, " %u.%06u", - EXTRACT_32BITS(&fap->fa2_ctime.nfsv2_sec), - EXTRACT_32BITS(&fap->fa2_ctime.nfsv2_usec))); + ND_TCHECK_8(&fap->fa2_ctime); + ND_PRINT(" nlink %u rdev 0x%x fsid 0x%x nodeid 0x%x a/m/ctime", + GET_BE_U_4(fap->fa_nlink), + GET_BE_U_4(fap->fa2_rdev), + GET_BE_U_4(fap->fa2_fsid), + GET_BE_U_4(fap->fa2_fileid)); + ND_PRINT(" %u.%06u", + GET_BE_U_4(fap->fa2_atime.nfsv2_sec), + GET_BE_U_4(fap->fa2_atime.nfsv2_usec)); + ND_PRINT(" %u.%06u", + GET_BE_U_4(fap->fa2_mtime.nfsv2_sec), + GET_BE_U_4(fap->fa2_mtime.nfsv2_usec)); + ND_PRINT(" %u.%06u", + GET_BE_U_4(fap->fa2_ctime.nfsv2_sec), + GET_BE_U_4(fap->fa2_ctime.nfsv2_usec)); } } return ((const uint32_t *)((const unsigned char *)dp + @@ -1115,11 +1192,11 @@ trunc: static int parseattrstat(netdissect_options *ndo, - const uint32_t *dp, int verbose, int v3) + const uint32_t *dp, int verbose, int v3, int *nfserrp) { - int er; + u_int er; - dp = parsestatus(ndo, dp, &er); + dp = parsestatus(ndo, dp, &er, nfserrp); if (dp == NULL) return (0); if (er) @@ -1130,11 +1207,12 @@ parseattrstat(netdissect_options *ndo, static int parsediropres(netdissect_options *ndo, - const uint32_t *dp) + const uint32_t *dp, int *nfserrp) { - int er; + u_int er; - if (!(dp = parsestatus(ndo, dp, &er))) + dp = parsestatus(ndo, dp, &er, nfserrp); + if (dp == NULL) return (0); if (er) return (1); @@ -1148,29 +1226,32 @@ parsediropres(netdissect_options *ndo, static int parselinkres(netdissect_options *ndo, - const uint32_t *dp, int v3) + const uint32_t *dp, int v3, int *nfserrp) { - int er; + u_int er; - dp = parsestatus(ndo, dp, &er); + dp = parsestatus(ndo, dp, &er, nfserrp); if (dp == NULL) return(0); if (er) return(1); - if (v3 && !(dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag))) - return (0); - ND_PRINT((ndo, " ")); + if (v3) { + dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag); + if (dp == NULL) + return (0); + } + ND_PRINT(" "); return (parsefn(ndo, dp) != NULL); } static int parsestatfs(netdissect_options *ndo, - const uint32_t *dp, int v3) + const uint32_t *dp, int v3, int *nfserrp) { const struct nfs_statfs *sfsp; - int er; + u_int er; - dp = parsestatus(ndo, dp, &er); + dp = parsestatus(ndo, dp, &er, nfserrp); if (dp == NULL) return (0); if (!v3 && er) @@ -1181,34 +1262,35 @@ parsestatfs(netdissect_options *ndo, if (v3) { if (ndo->ndo_vflag) - ND_PRINT((ndo, " POST:")); - if (!(dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag))) + ND_PRINT(" POST:"); + dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag); + if (dp == NULL) return (0); } - ND_TCHECK2(*dp, (v3 ? NFSX_V3STATFS : NFSX_V2STATFS)); + ND_TCHECK_LEN(dp, (v3 ? NFSX_V3STATFS : NFSX_V2STATFS)); sfsp = (const struct nfs_statfs *)dp; if (v3) { - ND_PRINT((ndo, " tbytes %" PRIu64 " fbytes %" PRIu64 " abytes %" PRIu64, - EXTRACT_64BITS((const uint32_t *)&sfsp->sf_tbytes), - EXTRACT_64BITS((const uint32_t *)&sfsp->sf_fbytes), - EXTRACT_64BITS((const uint32_t *)&sfsp->sf_abytes))); + ND_PRINT(" tbytes %" PRIu64 " fbytes %" PRIu64 " abytes %" PRIu64, + GET_BE_U_8(sfsp->sf_tbytes), + GET_BE_U_8(sfsp->sf_fbytes), + GET_BE_U_8(sfsp->sf_abytes)); if (ndo->ndo_vflag) { - ND_PRINT((ndo, " tfiles %" PRIu64 " ffiles %" PRIu64 " afiles %" PRIu64 " invar %u", - EXTRACT_64BITS((const uint32_t *)&sfsp->sf_tfiles), - EXTRACT_64BITS((const uint32_t *)&sfsp->sf_ffiles), - EXTRACT_64BITS((const uint32_t *)&sfsp->sf_afiles), - EXTRACT_32BITS(&sfsp->sf_invarsec))); + ND_PRINT(" tfiles %" PRIu64 " ffiles %" PRIu64 " afiles %" PRIu64 " invar %u", + GET_BE_U_8(sfsp->sf_tfiles), + GET_BE_U_8(sfsp->sf_ffiles), + GET_BE_U_8(sfsp->sf_afiles), + GET_BE_U_4(sfsp->sf_invarsec)); } } else { - ND_PRINT((ndo, " tsize %d bsize %d blocks %d bfree %d bavail %d", - EXTRACT_32BITS(&sfsp->sf_tsize), - EXTRACT_32BITS(&sfsp->sf_bsize), - EXTRACT_32BITS(&sfsp->sf_blocks), - EXTRACT_32BITS(&sfsp->sf_bfree), - EXTRACT_32BITS(&sfsp->sf_bavail))); + ND_PRINT(" tsize %u bsize %u blocks %u bfree %u bavail %u", + GET_BE_U_4(sfsp->sf_tsize), + GET_BE_U_4(sfsp->sf_bsize), + GET_BE_U_4(sfsp->sf_blocks), + GET_BE_U_4(sfsp->sf_bfree), + GET_BE_U_4(sfsp->sf_bavail)); } return (1); @@ -1218,11 +1300,11 @@ trunc: static int parserddires(netdissect_options *ndo, - const uint32_t *dp) + const uint32_t *dp, int *nfserrp) { - int er; + u_int er; - dp = parsestatus(ndo, dp, &er); + dp = parsestatus(ndo, dp, &er, nfserrp); if (dp == NULL) return (0); if (er) @@ -1230,15 +1312,12 @@ parserddires(netdissect_options *ndo, if (ndo->ndo_qflag) return (1); - ND_TCHECK(dp[2]); - ND_PRINT((ndo, " offset 0x%x size %d ", - EXTRACT_32BITS(&dp[0]), EXTRACT_32BITS(&dp[1]))); - if (dp[2] != 0) - ND_PRINT((ndo, " eof")); + ND_PRINT(" offset 0x%x size %u ", + GET_BE_U_4(dp), GET_BE_U_4(dp + 1)); + if (GET_BE_U_4(dp + 2) != 0) + ND_PRINT(" eof"); return (1); -trunc: - return (0); } static const uint32_t * @@ -1246,10 +1325,10 @@ parse_wcc_attr(netdissect_options *ndo, const uint32_t *dp) { /* Our caller has already checked this */ - ND_PRINT((ndo, " sz %" PRIu64, EXTRACT_64BITS(&dp[0]))); - ND_PRINT((ndo, " mtime %u.%06u ctime %u.%06u", - EXTRACT_32BITS(&dp[2]), EXTRACT_32BITS(&dp[3]), - EXTRACT_32BITS(&dp[4]), EXTRACT_32BITS(&dp[5]))); + ND_PRINT(" sz %" PRIu64, GET_BE_U_8(dp)); + ND_PRINT(" mtime %u.%06u ctime %u.%06u", + GET_BE_U_4(dp + 2), GET_BE_U_4(dp + 3), + GET_BE_U_4(dp + 4), GET_BE_U_4(dp + 5)); return (dp + 6); } @@ -1260,11 +1339,10 @@ static const uint32_t * parse_pre_op_attr(netdissect_options *ndo, const uint32_t *dp, int verbose) { - ND_TCHECK(dp[0]); - if (!EXTRACT_32BITS(&dp[0])) + if (!GET_BE_U_4(dp)) return (dp + 1); dp++; - ND_TCHECK2(*dp, 24); + ND_TCHECK_LEN(dp, 24); if (verbose > 1) { return parse_wcc_attr(ndo, dp); } else { @@ -1282,16 +1360,13 @@ static const uint32_t * parse_post_op_attr(netdissect_options *ndo, const uint32_t *dp, int verbose) { - ND_TCHECK(dp[0]); - if (!EXTRACT_32BITS(&dp[0])) + if (!GET_BE_U_4(dp)) return (dp + 1); dp++; if (verbose) { return parsefattr(ndo, dp, verbose, 1); } else return (dp + (NFSX_V3FATTR / sizeof (uint32_t))); -trunc: - return (NULL); } static const uint32_t * @@ -1299,113 +1374,121 @@ parse_wcc_data(netdissect_options *ndo, const uint32_t *dp, int verbose) { if (verbose > 1) - ND_PRINT((ndo, " PRE:")); - if (!(dp = parse_pre_op_attr(ndo, dp, verbose))) + ND_PRINT(" PRE:"); + dp = parse_pre_op_attr(ndo, dp, verbose); + if (dp == NULL) return (0); if (verbose) - ND_PRINT((ndo, " POST:")); + ND_PRINT(" POST:"); return parse_post_op_attr(ndo, dp, verbose); } static const uint32_t * parsecreateopres(netdissect_options *ndo, - const uint32_t *dp, int verbose) + const uint32_t *dp, int verbose, int *nfserrp) { - int er; + u_int er; - if (!(dp = parsestatus(ndo, dp, &er))) + dp = parsestatus(ndo, dp, &er, nfserrp); + if (dp == NULL) return (0); if (er) dp = parse_wcc_data(ndo, dp, verbose); else { - ND_TCHECK(dp[0]); - if (!EXTRACT_32BITS(&dp[0])) + if (!GET_BE_U_4(dp)) return (dp + 1); dp++; - if (!(dp = parsefh(ndo, dp, 1))) + dp = parsefh(ndo, dp, 1); + if (dp == NULL) return (0); if (verbose) { - if (!(dp = parse_post_op_attr(ndo, dp, verbose))) + dp = parse_post_op_attr(ndo, dp, verbose); + if (dp == NULL) return (0); if (ndo->ndo_vflag > 1) { - ND_PRINT((ndo, " dir attr:")); + ND_PRINT(" dir attr:"); dp = parse_wcc_data(ndo, dp, verbose); } } } return (dp); -trunc: - return (NULL); } -static int +static const uint32_t * parsewccres(netdissect_options *ndo, - const uint32_t *dp, int verbose) + const uint32_t *dp, int verbose, int *nfserrp) { - int er; + u_int er; - if (!(dp = parsestatus(ndo, dp, &er))) + dp = parsestatus(ndo, dp, &er, nfserrp); + if (dp == NULL) return (0); - return parse_wcc_data(ndo, dp, verbose) != NULL; + return parse_wcc_data(ndo, dp, verbose); } static const uint32_t * parsev3rddirres(netdissect_options *ndo, - const uint32_t *dp, int verbose) + const uint32_t *dp, int verbose, int *nfserrp) { - int er; + u_int er; - if (!(dp = parsestatus(ndo, dp, &er))) + dp = parsestatus(ndo, dp, &er, nfserrp); + if (dp == NULL) return (0); if (ndo->ndo_vflag) - ND_PRINT((ndo, " POST:")); - if (!(dp = parse_post_op_attr(ndo, dp, verbose))) + ND_PRINT(" POST:"); + dp = parse_post_op_attr(ndo, dp, verbose); + if (dp == NULL) return (0); if (er) return dp; if (ndo->ndo_vflag) { - ND_TCHECK(dp[1]); - ND_PRINT((ndo, " verf %08x%08x", dp[0], dp[1])); + /* + * This displays the 8 bytes of the verifier in order, + * from the low-order byte to the high-order byte. + */ + ND_PRINT(" verf %08x%08x", + GET_BE_U_4(dp), GET_BE_U_4(dp + 1)); dp += 2; } return dp; -trunc: - return (NULL); } static int parsefsinfo(netdissect_options *ndo, - const uint32_t *dp) + const uint32_t *dp, int *nfserrp) { const struct nfsv3_fsinfo *sfp; - int er; + u_int er; - if (!(dp = parsestatus(ndo, dp, &er))) + dp = parsestatus(ndo, dp, &er, nfserrp); + if (dp == NULL) return (0); if (ndo->ndo_vflag) - ND_PRINT((ndo, " POST:")); - if (!(dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag))) + ND_PRINT(" POST:"); + dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag); + if (dp == NULL) return (0); if (er) return (1); sfp = (const struct nfsv3_fsinfo *)dp; - ND_TCHECK(*sfp); - ND_PRINT((ndo, " rtmax %u rtpref %u wtmax %u wtpref %u dtpref %u", - EXTRACT_32BITS(&sfp->fs_rtmax), - EXTRACT_32BITS(&sfp->fs_rtpref), - EXTRACT_32BITS(&sfp->fs_wtmax), - EXTRACT_32BITS(&sfp->fs_wtpref), - EXTRACT_32BITS(&sfp->fs_dtpref))); + ND_TCHECK_SIZE(sfp); + ND_PRINT(" rtmax %u rtpref %u wtmax %u wtpref %u dtpref %u", + GET_BE_U_4(sfp->fs_rtmax), + GET_BE_U_4(sfp->fs_rtpref), + GET_BE_U_4(sfp->fs_wtmax), + GET_BE_U_4(sfp->fs_wtpref), + GET_BE_U_4(sfp->fs_dtpref)); if (ndo->ndo_vflag) { - ND_PRINT((ndo, " rtmult %u wtmult %u maxfsz %" PRIu64, - EXTRACT_32BITS(&sfp->fs_rtmult), - EXTRACT_32BITS(&sfp->fs_wtmult), - EXTRACT_64BITS((const uint32_t *)&sfp->fs_maxfilesize))); - ND_PRINT((ndo, " delta %u.%06u ", - EXTRACT_32BITS(&sfp->fs_timedelta.nfsv3_sec), - EXTRACT_32BITS(&sfp->fs_timedelta.nfsv3_nsec))); + ND_PRINT(" rtmult %u wtmult %u maxfsz %" PRIu64, + GET_BE_U_4(sfp->fs_rtmult), + GET_BE_U_4(sfp->fs_wtmult), + GET_BE_U_8(sfp->fs_maxfilesize)); + ND_PRINT(" delta %u.%06u ", + GET_BE_U_4(sfp->fs_timedelta.nfsv3_sec), + GET_BE_U_4(sfp->fs_timedelta.nfsv3_nsec)); } return (1); trunc: @@ -1414,30 +1497,32 @@ trunc: static int parsepathconf(netdissect_options *ndo, - const uint32_t *dp) + const uint32_t *dp, int *nfserrp) { - int er; + u_int er; const struct nfsv3_pathconf *spp; - if (!(dp = parsestatus(ndo, dp, &er))) + dp = parsestatus(ndo, dp, &er, nfserrp); + if (dp == NULL) return (0); if (ndo->ndo_vflag) - ND_PRINT((ndo, " POST:")); - if (!(dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag))) + ND_PRINT(" POST:"); + dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag); + if (dp == NULL) return (0); if (er) return (1); spp = (const struct nfsv3_pathconf *)dp; - ND_TCHECK(*spp); - - ND_PRINT((ndo, " linkmax %u namemax %u %s %s %s %s", - EXTRACT_32BITS(&spp->pc_linkmax), - EXTRACT_32BITS(&spp->pc_namemax), - EXTRACT_32BITS(&spp->pc_notrunc) ? "notrunc" : "", - EXTRACT_32BITS(&spp->pc_chownrestricted) ? "chownres" : "", - EXTRACT_32BITS(&spp->pc_caseinsensitive) ? "igncase" : "", - EXTRACT_32BITS(&spp->pc_casepreserving) ? "keepcase" : "")); + ND_TCHECK_SIZE(spp); + + ND_PRINT(" linkmax %u namemax %u %s %s %s %s", + GET_BE_U_4(spp->pc_linkmax), + GET_BE_U_4(spp->pc_namemax), + GET_BE_U_4(spp->pc_notrunc) ? "notrunc" : "", + GET_BE_U_4(spp->pc_chownrestricted) ? "chownres" : "", + GET_BE_U_4(spp->pc_caseinsensitive) ? "igncase" : "", + GET_BE_U_4(spp->pc_casepreserving) ? "keepcase" : ""); return (1); trunc: return (0); @@ -1445,271 +1530,321 @@ trunc: static void interp_reply(netdissect_options *ndo, - const struct sunrpc_msg *rp, uint32_t proc, uint32_t vers, int length) + const struct sunrpc_msg *rp, uint32_t proc, uint32_t vers, + int length) { - register const uint32_t *dp; - register int v3; - int er; + const uint32_t *dp; + int v3; + u_int er; + int nfserr = 0; v3 = (vers == NFS_VER3); if (!v3 && proc < NFS_NPROCS) proc = nfsv3_procid[proc]; - ND_PRINT((ndo, " %s", tok2str(nfsproc_str, "proc-%u", proc))); + ND_PRINT(" %s", tok2str(nfsproc_str, "proc-%u", proc)); switch (proc) { case NFSPROC_GETATTR: - dp = parserep(ndo, rp, length); - if (dp != NULL && parseattrstat(ndo, dp, !ndo->ndo_qflag, v3) != 0) - return; + dp = parserep(ndo, rp, length, &nfserr); + if (dp == NULL) + goto trunc; + if (parseattrstat(ndo, dp, !ndo->ndo_qflag, v3, &nfserr) == 0) + goto trunc; break; case NFSPROC_SETATTR: - if (!(dp = parserep(ndo, rp, length))) - return; + dp = parserep(ndo, rp, length, &nfserr); + if (dp == NULL) + goto trunc; if (v3) { - if (parsewccres(ndo, dp, ndo->ndo_vflag)) - return; + if (parsewccres(ndo, dp, ndo->ndo_vflag, &nfserr) == 0) + goto trunc; } else { - if (parseattrstat(ndo, dp, !ndo->ndo_qflag, 0) != 0) - return; + if (parseattrstat(ndo, dp, !ndo->ndo_qflag, 0, &nfserr) == 0) + goto trunc; } break; case NFSPROC_LOOKUP: - if (!(dp = parserep(ndo, rp, length))) - break; + dp = parserep(ndo, rp, length, &nfserr); + if (dp == NULL) + goto trunc; if (v3) { - if (!(dp = parsestatus(ndo, dp, &er))) - break; + dp = parsestatus(ndo, dp, &er, &nfserr); + if (dp == NULL) + goto trunc; if (er) { if (ndo->ndo_vflag > 1) { - ND_PRINT((ndo, " post dattr:")); + ND_PRINT(" post dattr:"); dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag); + if (dp == NULL) + goto trunc; } } else { - if (!(dp = parsefh(ndo, dp, v3))) - break; - if ((dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag)) && - ndo->ndo_vflag > 1) { - ND_PRINT((ndo, " post dattr:")); + dp = parsefh(ndo, dp, v3); + if (dp == NULL) + goto trunc; + dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag); + if (dp == NULL) + goto trunc; + if (ndo->ndo_vflag > 1) { + ND_PRINT(" post dattr:"); dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag); + if (dp == NULL) + goto trunc; } } - if (dp) - return; } else { - if (parsediropres(ndo, dp) != 0) - return; + if (parsediropres(ndo, dp, &nfserr) == 0) + goto trunc; } break; case NFSPROC_ACCESS: - if (!(dp = parserep(ndo, rp, length))) - break; - if (!(dp = parsestatus(ndo, dp, &er))) - break; + dp = parserep(ndo, rp, length, &nfserr); + if (dp == NULL) + goto trunc; + dp = parsestatus(ndo, dp, &er, &nfserr); + if (dp == NULL) + goto trunc; if (ndo->ndo_vflag) - ND_PRINT((ndo, " attr:")); - if (!(dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag))) - break; + ND_PRINT(" attr:"); + dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag); + if (dp == NULL) + goto trunc; if (!er) { - ND_TCHECK(dp[0]); - ND_PRINT((ndo, " c %04x", EXTRACT_32BITS(&dp[0]))); + ND_PRINT(" c %04x", GET_BE_U_4(dp)); } - return; + break; case NFSPROC_READLINK: - dp = parserep(ndo, rp, length); - if (dp != NULL && parselinkres(ndo, dp, v3) != 0) - return; + dp = parserep(ndo, rp, length, &nfserr); + if (dp == NULL) + goto trunc; + if (parselinkres(ndo, dp, v3, &nfserr) == 0) + goto trunc; break; case NFSPROC_READ: - if (!(dp = parserep(ndo, rp, length))) - break; + dp = parserep(ndo, rp, length, &nfserr); + if (dp == NULL) + goto trunc; if (v3) { - if (!(dp = parsestatus(ndo, dp, &er))) - break; - if (!(dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag))) - break; - if (er) - return; - if (ndo->ndo_vflag) { - ND_TCHECK(dp[1]); - ND_PRINT((ndo, " %u bytes", EXTRACT_32BITS(&dp[0]))); - if (EXTRACT_32BITS(&dp[1])) - ND_PRINT((ndo, " EOF")); + dp = parsestatus(ndo, dp, &er, &nfserr); + if (dp == NULL) + goto trunc; + dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag); + if (dp == NULL) + goto trunc; + if (!er) { + if (ndo->ndo_vflag) { + ND_PRINT(" %u bytes", GET_BE_U_4(dp)); + if (GET_BE_U_4(dp + 1)) + ND_PRINT(" EOF"); + } } - return; } else { - if (parseattrstat(ndo, dp, ndo->ndo_vflag, 0) != 0) - return; + if (parseattrstat(ndo, dp, ndo->ndo_vflag, 0, &nfserr) == 0) + goto trunc; } break; case NFSPROC_WRITE: - if (!(dp = parserep(ndo, rp, length))) - break; + dp = parserep(ndo, rp, length, &nfserr); + if (dp == NULL) + goto trunc; if (v3) { - if (!(dp = parsestatus(ndo, dp, &er))) - break; - if (!(dp = parse_wcc_data(ndo, dp, ndo->ndo_vflag))) - break; - if (er) - return; - if (ndo->ndo_vflag) { - ND_TCHECK(dp[0]); - ND_PRINT((ndo, " %u bytes", EXTRACT_32BITS(&dp[0]))); - if (ndo->ndo_vflag > 1) { - ND_TCHECK(dp[1]); - ND_PRINT((ndo, " <%s>", - tok2str(nfsv3_writemodes, - NULL, EXTRACT_32BITS(&dp[1])))); + dp = parsestatus(ndo, dp, &er, &nfserr); + if (dp == NULL) + goto trunc; + dp = parse_wcc_data(ndo, dp, ndo->ndo_vflag); + if (dp == NULL) + goto trunc; + if (!er) { + if (ndo->ndo_vflag) { + ND_PRINT(" %u bytes", GET_BE_U_4(dp)); + if (ndo->ndo_vflag > 1) { + ND_PRINT(" <%s>", + tok2str(nfsv3_writemodes, + NULL, GET_BE_U_4(dp + 1))); + + /* write-verf-cookie */ + ND_PRINT(" verf %" PRIx64, + GET_BE_U_8(dp + 2)); + } } } return; } else { - if (parseattrstat(ndo, dp, ndo->ndo_vflag, v3) != 0) - return; + if (parseattrstat(ndo, dp, ndo->ndo_vflag, v3, &nfserr) == 0) + goto trunc; } break; case NFSPROC_CREATE: case NFSPROC_MKDIR: - if (!(dp = parserep(ndo, rp, length))) - break; + dp = parserep(ndo, rp, length, &nfserr); + if (dp == NULL) + goto trunc; if (v3) { - if (parsecreateopres(ndo, dp, ndo->ndo_vflag) != NULL) - return; + if (parsecreateopres(ndo, dp, ndo->ndo_vflag, &nfserr) == NULL) + goto trunc; } else { - if (parsediropres(ndo, dp) != 0) - return; + if (parsediropres(ndo, dp, &nfserr) == 0) + goto trunc; } break; case NFSPROC_SYMLINK: - if (!(dp = parserep(ndo, rp, length))) - break; + dp = parserep(ndo, rp, length, &nfserr); + if (dp == NULL) + goto trunc; if (v3) { - if (parsecreateopres(ndo, dp, ndo->ndo_vflag) != NULL) - return; + if (parsecreateopres(ndo, dp, ndo->ndo_vflag, &nfserr) == NULL) + goto trunc; } else { - if (parsestatus(ndo, dp, &er) != NULL) - return; + if (parsestatus(ndo, dp, &er, &nfserr) == NULL) + goto trunc; } break; case NFSPROC_MKNOD: - if (!(dp = parserep(ndo, rp, length))) - break; - if (parsecreateopres(ndo, dp, ndo->ndo_vflag) != NULL) - return; + dp = parserep(ndo, rp, length, &nfserr); + if (dp == NULL) + goto trunc; + if (parsecreateopres(ndo, dp, ndo->ndo_vflag, &nfserr) == NULL) + goto trunc; break; case NFSPROC_REMOVE: case NFSPROC_RMDIR: - if (!(dp = parserep(ndo, rp, length))) - break; + dp = parserep(ndo, rp, length, &nfserr); + if (dp == NULL) + goto trunc; if (v3) { - if (parsewccres(ndo, dp, ndo->ndo_vflag)) - return; + if (parsewccres(ndo, dp, ndo->ndo_vflag, &nfserr) == NULL) + goto trunc; } else { - if (parsestatus(ndo, dp, &er) != NULL) - return; + if (parsestatus(ndo, dp, &er, &nfserr) == NULL) + goto trunc; } break; case NFSPROC_RENAME: - if (!(dp = parserep(ndo, rp, length))) - break; + dp = parserep(ndo, rp, length, &nfserr); + if (dp == NULL) + goto trunc; if (v3) { - if (!(dp = parsestatus(ndo, dp, &er))) - break; + dp = parsestatus(ndo, dp, &er, &nfserr); + if (dp == NULL) + goto trunc; if (ndo->ndo_vflag) { - ND_PRINT((ndo, " from:")); - if (!(dp = parse_wcc_data(ndo, dp, ndo->ndo_vflag))) - break; - ND_PRINT((ndo, " to:")); - if (!(dp = parse_wcc_data(ndo, dp, ndo->ndo_vflag))) - break; + ND_PRINT(" from:"); + dp = parse_wcc_data(ndo, dp, ndo->ndo_vflag); + if (dp == NULL) + goto trunc; + ND_PRINT(" to:"); + dp = parse_wcc_data(ndo, dp, ndo->ndo_vflag); + if (dp == NULL) + goto trunc; } - return; } else { - if (parsestatus(ndo, dp, &er) != NULL) - return; + if (parsestatus(ndo, dp, &er, &nfserr) == NULL) + goto trunc; } break; case NFSPROC_LINK: - if (!(dp = parserep(ndo, rp, length))) - break; + dp = parserep(ndo, rp, length, &nfserr); + if (dp == NULL) + goto trunc; if (v3) { - if (!(dp = parsestatus(ndo, dp, &er))) - break; + dp = parsestatus(ndo, dp, &er, &nfserr); + if (dp == NULL) + goto trunc; if (ndo->ndo_vflag) { - ND_PRINT((ndo, " file POST:")); - if (!(dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag))) - break; - ND_PRINT((ndo, " dir:")); - if (!(dp = parse_wcc_data(ndo, dp, ndo->ndo_vflag))) - break; + ND_PRINT(" file POST:"); + dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag); + if (dp == NULL) + goto trunc; + ND_PRINT(" dir:"); + dp = parse_wcc_data(ndo, dp, ndo->ndo_vflag); + if (dp == NULL) + goto trunc; } return; } else { - if (parsestatus(ndo, dp, &er) != NULL) - return; + if (parsestatus(ndo, dp, &er, &nfserr) == NULL) + goto trunc; } break; case NFSPROC_READDIR: - if (!(dp = parserep(ndo, rp, length))) - break; + dp = parserep(ndo, rp, length, &nfserr); + if (dp == NULL) + goto trunc; if (v3) { - if (parsev3rddirres(ndo, dp, ndo->ndo_vflag)) - return; + if (parsev3rddirres(ndo, dp, ndo->ndo_vflag, &nfserr) == NULL) + goto trunc; } else { - if (parserddires(ndo, dp) != 0) - return; + if (parserddires(ndo, dp, &nfserr) == 0) + goto trunc; } break; case NFSPROC_READDIRPLUS: - if (!(dp = parserep(ndo, rp, length))) - break; - if (parsev3rddirres(ndo, dp, ndo->ndo_vflag)) - return; + dp = parserep(ndo, rp, length, &nfserr); + if (dp == NULL) + goto trunc; + if (parsev3rddirres(ndo, dp, ndo->ndo_vflag, &nfserr) == NULL) + goto trunc; break; case NFSPROC_FSSTAT: - dp = parserep(ndo, rp, length); - if (dp != NULL && parsestatfs(ndo, dp, v3) != 0) - return; + dp = parserep(ndo, rp, length, &nfserr); + if (dp == NULL) + goto trunc; + if (parsestatfs(ndo, dp, v3, &nfserr) == 0) + goto trunc; break; case NFSPROC_FSINFO: - dp = parserep(ndo, rp, length); - if (dp != NULL && parsefsinfo(ndo, dp) != 0) - return; + dp = parserep(ndo, rp, length, &nfserr); + if (dp == NULL) + goto trunc; + if (parsefsinfo(ndo, dp, &nfserr) == 0) + goto trunc; break; case NFSPROC_PATHCONF: - dp = parserep(ndo, rp, length); - if (dp != NULL && parsepathconf(ndo, dp) != 0) - return; + dp = parserep(ndo, rp, length, &nfserr); + if (dp == NULL) + goto trunc; + if (parsepathconf(ndo, dp, &nfserr) == 0) + goto trunc; break; case NFSPROC_COMMIT: - dp = parserep(ndo, rp, length); - if (dp != NULL && parsewccres(ndo, dp, ndo->ndo_vflag) != 0) - return; + dp = parserep(ndo, rp, length, &nfserr); + if (dp == NULL) + goto trunc; + dp = parsewccres(ndo, dp, ndo->ndo_vflag, &nfserr); + if (dp == NULL) + goto trunc; + if (ndo->ndo_vflag > 1) { + /* write-verf-cookie */ + ND_PRINT(" verf %" PRIx64, GET_BE_U_8(dp)); + } break; default: - return; + break; } + return; + trunc: if (!nfserr) - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); } diff --git a/contrib/tcpdump/print-nsh.c b/contrib/tcpdump/print-nsh.c index abd722d404..12a63cd637 100644 --- a/contrib/tcpdump/print-nsh.c +++ b/contrib/tcpdump/print-nsh.c @@ -23,163 +23,242 @@ /* \summary: Network Service Header (NSH) printer */ -/* specification: draft-ietf-sfc-nsh-01 */ +/* specification: RFC 8300 */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" -static const char tstr[] = " [|NSH]"; static const struct tok nsh_flags [] = { - { 0x20, "O" }, - { 0x10, "C" }, + { 0x2, "O" }, { 0, NULL } }; +/* + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |Ver|O|U| TTL | Length |U|U|U|U|MD Type| Next Protocol | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ #define NSH_BASE_HDR_LEN 4 +#define NSH_VER(x) (((x) & 0xc0000000) >> 30) +#define NSH_FLAGS(x) (((x) & 0x30000000) >> 28) +#define NSH_TTL(x) (((x) & 0x0fc00000) >> 22) +#define NSH_LENGTH(x) (((x) & 0x003f0000) >> 16) +#define NSH_MD_TYPE(x) (((x) & 0x00000f00) >> 8) +#define NSH_NEXT_PROT(x) (((x) & 0x000000ff) >> 0) + #define NSH_SERVICE_PATH_HDR_LEN 4 #define NSH_HDR_WORD_SIZE 4U +#define MD_RSV 0x00 +#define MD_TYPE1 0x01 +#define MD_TYPE2 0x02 +#define MD_EXP 0x0F +static const struct tok md_str[] = { + { MD_RSV, "reserved" }, + { MD_TYPE1, "1" }, + { MD_TYPE2, "2" }, + { MD_EXP, "experimental" }, + { 0, NULL } +}; + +#define NP_IPV4 0x01 +#define NP_IPV6 0x02 +#define NP_ETH 0x03 +#define NP_NSH 0x04 +#define NP_MPLS 0x05 +#define NP_EXP1 0xFE +#define NP_EXP2 0xFF +static const struct tok np_str[] = { + { NP_IPV4, "IPv4" }, + { NP_IPV6, "IPv6" }, + { NP_ETH, "Ethernet" }, + { NP_NSH, "NSH" }, + { NP_MPLS, "MPLS" }, + { NP_EXP1, "Experiment 1" }, + { NP_EXP2, "Experiment 2" }, + { 0, NULL } +}; + void nsh_print(netdissect_options *ndo, const u_char *bp, u_int len) { - int n, vn; - uint8_t ver; - uint8_t flags; - uint8_t length; - uint8_t md_type; + uint32_t basehdr; + u_int ver, length, md_type; uint8_t next_protocol; - uint32_t service_path_id; - uint8_t service_index; - uint32_t ctx; - uint16_t tlv_class; - uint8_t tlv_type; - uint8_t tlv_len; + u_char past_headers = 0; u_int next_len; + ndo->ndo_protocol = "nsh"; + /* + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Base Header | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Service Path Header | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * ~ Context Header(s) ~ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + /* print Base Header and Service Path Header */ - if (len < NSH_BASE_HDR_LEN + NSH_SERVICE_PATH_HDR_LEN) - goto trunc; + if (len < NSH_BASE_HDR_LEN + NSH_SERVICE_PATH_HDR_LEN) { + ND_PRINT(" (packet length %u < %u)", + len, NSH_BASE_HDR_LEN + NSH_SERVICE_PATH_HDR_LEN); + goto invalid; + } - ND_TCHECK2(*bp, NSH_BASE_HDR_LEN + NSH_SERVICE_PATH_HDR_LEN); + basehdr = GET_BE_U_4(bp); + bp += 4; + ver = NSH_VER(basehdr); + length = NSH_LENGTH(basehdr); + md_type = NSH_MD_TYPE(basehdr); + next_protocol = NSH_NEXT_PROT(basehdr); - ver = (uint8_t)(*bp >> 6); - flags = *bp; - bp += 1; - length = *bp; - bp += 1; - md_type = *bp; - bp += 1; - next_protocol = *bp; - bp += 1; - service_path_id = EXTRACT_24BITS(bp); - bp += 3; - service_index = *bp; - bp += 1; - - ND_PRINT((ndo, "NSH, ")); + ND_PRINT("NSH, "); if (ndo->ndo_vflag > 1) { - ND_PRINT((ndo, "ver %d, ", ver)); + ND_PRINT("ver %u, ", ver); } - ND_PRINT((ndo, "flags [%s], ", bittok2str_nosep(nsh_flags, "none", flags))); + if (ver != 0) + return; + ND_PRINT("flags [%s], ", + bittok2str_nosep(nsh_flags, "none", NSH_FLAGS(basehdr))); if (ndo->ndo_vflag > 2) { - ND_PRINT((ndo, "length %d, ", length)); - ND_PRINT((ndo, "md type 0x%x, ", md_type)); + ND_PRINT("TTL %u, ", NSH_TTL(basehdr)); + ND_PRINT("length %u, ", length); + ND_PRINT("md type %s, ", tok2str(md_str, "unknown (0x%02x)", md_type)); } if (ndo->ndo_vflag > 1) { - ND_PRINT((ndo, "next-protocol 0x%x, ", next_protocol)); + ND_PRINT("next-protocol %s, ", + tok2str(np_str, "unknown (0x%02x)", next_protocol)); } - ND_PRINT((ndo, "service-path-id 0x%06x, ", service_path_id)); - ND_PRINT((ndo, "service-index 0x%x", service_index)); /* Make sure we have all the headers */ - if (len < length * NSH_HDR_WORD_SIZE) - goto trunc; + if (len < length * NSH_HDR_WORD_SIZE) { + ND_PRINT(" (too many headers for packet length %u)", len); + goto invalid; + } - ND_TCHECK2(*bp, length * NSH_HDR_WORD_SIZE); + /* + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Service Path Identifier (SPI) | Service Index | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + */ + ND_PRINT("service-path-id 0x%06x, ", GET_BE_U_3(bp)); + bp += 3; + ND_PRINT("service-index 0x%x", GET_U_1(bp)); + bp += 1; /* * length includes the lengths of the Base and Service Path headers. * That means it must be at least 2. */ - if (length < 2) - goto trunc; + if (length < 2) { + ND_PRINT(" (less than two headers)"); + goto invalid; + } /* * Print, or skip, the Context Headers. * (length - 2) is the length of those headers. */ if (ndo->ndo_vflag > 2) { - if (md_type == 0x01) { + u_int n; + + if (md_type == MD_TYPE1) { + if (length != 6) { + ND_PRINT(" (invalid length for the MD type)"); + goto invalid; + } for (n = 0; n < length - 2; n++) { - ctx = EXTRACT_32BITS(bp); + ND_PRINT("\n Context[%02u]: 0x%08x", n, GET_BE_U_4(bp)); bp += NSH_HDR_WORD_SIZE; - ND_PRINT((ndo, "\n Context[%02d]: 0x%08x", n, ctx)); } + past_headers = 1; } - else if (md_type == 0x02) { + else if (md_type == MD_TYPE2) { n = 0; while (n < length - 2) { - tlv_class = EXTRACT_16BITS(bp); + uint16_t tlv_class; + uint8_t tlv_type, tlv_len, tlv_len_padded; + + tlv_class = GET_BE_U_2(bp); bp += 2; - tlv_type = *bp; + tlv_type = GET_U_1(bp); bp += 1; - tlv_len = *bp; + tlv_len = GET_U_1(bp) & 0x7f; bp += 1; + tlv_len_padded = roundup2(tlv_len, NSH_HDR_WORD_SIZE); - ND_PRINT((ndo, "\n TLV Class %d, Type %d, Len %d", - tlv_class, tlv_type, tlv_len)); + ND_PRINT("\n TLV Class %u, Type %u, Len %u", + tlv_class, tlv_type, tlv_len); n += 1; - if (length - 2 < n + tlv_len) { - ND_PRINT((ndo, " ERROR: invalid-tlv-length")); - return; + if (length - 2 < n + tlv_len_padded / NSH_HDR_WORD_SIZE) { + ND_PRINT(" (length too big)"); + goto invalid; } - for (vn = 0; vn < tlv_len; vn++) { - ctx = EXTRACT_32BITS(bp); - bp += NSH_HDR_WORD_SIZE; - ND_PRINT((ndo, "\n Value[%02d]: 0x%08x", vn, ctx)); + if (tlv_len) { + const char *sep = "0x"; + u_int vn; + + ND_PRINT("\n Value: "); + for (vn = 0; vn < tlv_len; vn++) { + ND_PRINT("%s%02x", sep, GET_U_1(bp)); + bp += 1; + sep = ":"; + } + /* Cover any TLV padding. */ + ND_TCHECK_LEN(bp, tlv_len_padded - tlv_len); + bp += tlv_len_padded - tlv_len; + n += tlv_len_padded / NSH_HDR_WORD_SIZE; } - n += tlv_len; } - } - else { - ND_PRINT((ndo, "ERROR: unknown-next-protocol")); - return; + past_headers = 1; } } - else { + if (! past_headers) { + ND_TCHECK_LEN(bp, (length - 2) * NSH_HDR_WORD_SIZE); bp += (length - 2) * NSH_HDR_WORD_SIZE; } - ND_PRINT((ndo, ndo->ndo_vflag ? "\n " : ": ")); + ND_PRINT(ndo->ndo_vflag ? "\n " : ": "); /* print Next Protocol */ next_len = len - length * NSH_HDR_WORD_SIZE; switch (next_protocol) { - case 0x1: + case NP_IPV4: ip_print(ndo, bp, next_len); break; - case 0x2: + case NP_IPV6: ip6_print(ndo, bp, next_len); break; - case 0x3: - ether_print(ndo, bp, next_len, ndo->ndo_snapend - bp, NULL, NULL); + case NP_ETH: + ether_print(ndo, bp, next_len, ND_BYTES_AVAILABLE_AFTER(bp), NULL, NULL); break; default: - ND_PRINT((ndo, "ERROR: unknown-next-protocol")); + ND_PRINT("ERROR: unknown-next-protocol"); return; } return; -trunc: - ND_PRINT((ndo, "%s", tstr)); +invalid: + nd_print_invalid(ndo); } diff --git a/contrib/tcpdump/print-ntp.c b/contrib/tcpdump/print-ntp.c index 0689264ff7..99c0896343 100644 --- a/contrib/tcpdump/print-ntp.c +++ b/contrib/tcpdump/print-ntp.c @@ -24,11 +24,19 @@ /* \summary: Network Time Protocol (NTP) printer */ +/* + * specification: + * + * RFC 1119 - NTPv2 + * RFC 1305 - NTPv3 + * RFC 5905 - NTPv4 + */ + #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #ifdef HAVE_STRFTIME #include @@ -38,43 +46,13 @@ #include "addrtoname.h" #include "extract.h" +#include "ntp.h" + /* * Based on ntp.h from the U of MD implementation * This file is based on Version 2 of the NTP spec (RFC1119). */ -/* - * Definitions for the masses - */ -#define JAN_1970 2208988800U /* 1970 - 1900 in seconds */ - -/* - * Structure definitions for NTP fixed point values - * - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Integer Part | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Fraction Part | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Integer Part | Fraction Part | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -*/ -struct l_fixedpt { - uint32_t int_part; - uint32_t fraction; -}; - -struct s_fixedpt { - uint16_t int_part; - uint16_t fraction; -}; - /* rfc2030 * 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 @@ -113,20 +91,26 @@ struct s_fixedpt { * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -struct ntpdata { - u_char status; /* status of local clock and leap info */ - u_char stratum; /* Stratum level */ - u_char ppoll; /* poll value */ - int precision:8; +/* Length of the NTP data message with the mandatory fields ("the header") + * and without any optional fields (extension, Key Identifier, + * Message Digest). + */ +#define NTP_TIMEMSG_MINLEN 48U + +struct ntp_time_data { + nd_uint8_t status; /* status of local clock and leap info */ + nd_uint8_t stratum; /* Stratum level */ + nd_int8_t ppoll; /* poll value */ + nd_int8_t precision; struct s_fixedpt root_delay; struct s_fixedpt root_dispersion; - uint32_t refid; + nd_uint32_t refid; struct l_fixedpt ref_timestamp; struct l_fixedpt org_timestamp; struct l_fixedpt rec_timestamp; struct l_fixedpt xmt_timestamp; - uint32_t key_id; - uint8_t message_digest[16]; + nd_uint32_t key_id; + nd_uint8_t message_digest[20]; }; /* * Leap Second Codes (high order two bits) @@ -141,11 +125,14 @@ struct ntpdata { */ #define NTPVERSION_1 0x08 #define VERSIONMASK 0x38 +#define VERSIONSHIFT 3 #define LEAPMASK 0xc0 +#define LEAPSHIFT 6 #ifdef MODEMASK #undef MODEMASK /* Solaris sucks */ #endif #define MODEMASK 0x07 +#define MODESHIFT 0 /* * Code values @@ -156,7 +143,7 @@ struct ntpdata { #define MODE_CLIENT 3 /* client */ #define MODE_SERVER 4 /* server */ #define MODE_BROADCAST 5 /* broadcast */ -#define MODE_RES1 6 /* reserved */ +#define MODE_CONTROL 6 /* control message */ #define MODE_RES2 7 /* reserved */ /* @@ -168,8 +155,8 @@ struct ntpdata { #define INFO_REPLY 63 /* **** THIS implementation dependent **** */ static void p_sfix(netdissect_options *ndo, const struct s_fixedpt *); -static void p_ntp_time(netdissect_options *, const struct l_fixedpt *); static void p_ntp_delta(netdissect_options *, const struct l_fixedpt *, const struct l_fixedpt *); +static void p_poll(netdissect_options *, const int); static const struct tok ntp_mode_values[] = { { MODE_UNSPEC, "unspecified" }, @@ -178,7 +165,7 @@ static const struct tok ntp_mode_values[] = { { MODE_CLIENT, "Client" }, { MODE_SERVER, "Server" }, { MODE_BROADCAST, "Broadcast" }, - { MODE_RES1, "Reserved" }, + { MODE_CONTROL, "Control Message" }, { MODE_RES2, "Reserved" }, { 0, NULL } }; @@ -197,217 +184,327 @@ static const struct tok ntp_stratum_values[] = { { 0, NULL } }; -/* - * Print ntp requests +/* draft-ietf-ntp-mode-6-cmds-02 + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |LI | VN |Mode |R|E|M| OpCode | Sequence Number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Status | Association ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Offset | Count | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * / Data (up to 468 bytes) / + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Padding (optional) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * / Authenticator (optional, 96 bytes) / + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Figure 1: NTP Control Message Header */ -void -ntp_print(netdissect_options *ndo, - register const u_char *cp, u_int length) -{ - register const struct ntpdata *bp; - int mode, version, leapind; - - bp = (const struct ntpdata *)cp; - ND_TCHECK(bp->status); - - version = (int)(bp->status & VERSIONMASK) >> 3; - ND_PRINT((ndo, "NTPv%d", version)); - - mode = bp->status & MODEMASK; - if (!ndo->ndo_vflag) { - ND_PRINT((ndo, ", %s, length %u", - tok2str(ntp_mode_values, "Unknown mode", mode), - length)); - return; - } +/* Length of the NTP control message with the mandatory fields ("the header") + * and without any optional fields (Data, Padding, Authenticator). + */ +#define NTP_CTRLMSG_MINLEN 12U + +struct ntp_control_data { + nd_uint8_t magic; /* LI, VN, Mode */ + nd_uint8_t control; /* R, E, M, OpCode */ + nd_uint16_t sequence; /* Sequence Number */ + nd_uint16_t status; /* Status */ + nd_uint16_t assoc; /* Association ID */ + nd_uint16_t offset; /* Offset */ + nd_uint16_t count; /* Count */ + nd_uint8_t data[564]; /* Data, [Padding, [Authenticator]] */ +}; - ND_PRINT((ndo, ", length %u\n\t%s", - length, - tok2str(ntp_mode_values, "Unknown mode", mode))); +/* + * Print NTP time requests and responses + */ +static void +ntp_time_print(netdissect_options *ndo, + const struct ntp_time_data *bp, u_int length) +{ + uint8_t stratum; - leapind = bp->status & LEAPMASK; - ND_PRINT((ndo, ", Leap indicator: %s (%u)", - tok2str(ntp_leapind_values, "Unknown", leapind), - leapind)); + if (length < NTP_TIMEMSG_MINLEN) + goto invalid; - ND_TCHECK(bp->stratum); - ND_PRINT((ndo, ", Stratum %u (%s)", - bp->stratum, - tok2str(ntp_stratum_values, (bp->stratum >=2 && bp->stratum<=15) ? "secondary reference" : "reserved", bp->stratum))); + stratum = GET_U_1(bp->stratum); + ND_PRINT(", Stratum %u (%s)", + stratum, + tok2str(ntp_stratum_values, (stratum >=2 && stratum<=15) ? "secondary reference" : "reserved", stratum)); - ND_TCHECK(bp->ppoll); - ND_PRINT((ndo, ", poll %u (%us)", bp->ppoll, 1 << bp->ppoll)); + ND_PRINT(", poll %d", GET_S_1(bp->ppoll)); + p_poll(ndo, GET_S_1(bp->ppoll)); - /* Can't ND_TCHECK bp->precision bitfield so bp->distance + 0 instead */ - ND_TCHECK2(bp->root_delay, 0); - ND_PRINT((ndo, ", precision %d", bp->precision)); + ND_PRINT(", precision %d", GET_S_1(bp->precision)); - ND_TCHECK(bp->root_delay); - ND_PRINT((ndo, "\n\tRoot Delay: ")); + ND_TCHECK_SIZE(&bp->root_delay); + ND_PRINT("\n\tRoot Delay: "); p_sfix(ndo, &bp->root_delay); - ND_TCHECK(bp->root_dispersion); - ND_PRINT((ndo, ", Root dispersion: ")); + ND_TCHECK_SIZE(&bp->root_dispersion); + ND_PRINT(", Root dispersion: "); p_sfix(ndo, &bp->root_dispersion); - ND_TCHECK(bp->refid); - ND_PRINT((ndo, ", Reference-ID: ")); + ND_TCHECK_4(bp->refid); + ND_PRINT(", Reference-ID: "); /* Interpretation depends on stratum */ - switch (bp->stratum) { + switch (stratum) { case UNSPECIFIED: - ND_PRINT((ndo, "(unspec)")); + ND_PRINT("(unspec)"); break; case PRIM_REF: - if (fn_printn(ndo, (const u_char *)&(bp->refid), 4, ndo->ndo_snapend)) + if (nd_printn(ndo, (const u_char *)&(bp->refid), 4, ndo->ndo_snapend)) goto trunc; break; case INFO_QUERY: - ND_PRINT((ndo, "%s INFO_QUERY", ipaddr_string(ndo, &(bp->refid)))); + ND_PRINT("%s INFO_QUERY", GET_IPADDR_STRING(bp->refid)); /* this doesn't have more content */ return; case INFO_REPLY: - ND_PRINT((ndo, "%s INFO_REPLY", ipaddr_string(ndo, &(bp->refid)))); + ND_PRINT("%s INFO_REPLY", GET_IPADDR_STRING(bp->refid)); /* this is too complex to be worth printing */ return; default: - ND_PRINT((ndo, "%s", ipaddr_string(ndo, &(bp->refid)))); + /* In NTPv4 (RFC 5905) refid is an IPv4 address or first 32 bits of + MD5 sum of IPv6 address */ + ND_PRINT("0x%08x", GET_BE_U_4(bp->refid)); break; } - ND_TCHECK(bp->ref_timestamp); - ND_PRINT((ndo, "\n\t Reference Timestamp: ")); + ND_TCHECK_SIZE(&bp->ref_timestamp); + ND_PRINT("\n\t Reference Timestamp: "); p_ntp_time(ndo, &(bp->ref_timestamp)); - ND_TCHECK(bp->org_timestamp); - ND_PRINT((ndo, "\n\t Originator Timestamp: ")); + ND_TCHECK_SIZE(&bp->org_timestamp); + ND_PRINT("\n\t Originator Timestamp: "); p_ntp_time(ndo, &(bp->org_timestamp)); - ND_TCHECK(bp->rec_timestamp); - ND_PRINT((ndo, "\n\t Receive Timestamp: ")); + ND_TCHECK_SIZE(&bp->rec_timestamp); + ND_PRINT("\n\t Receive Timestamp: "); p_ntp_time(ndo, &(bp->rec_timestamp)); - ND_TCHECK(bp->xmt_timestamp); - ND_PRINT((ndo, "\n\t Transmit Timestamp: ")); + ND_TCHECK_SIZE(&bp->xmt_timestamp); + ND_PRINT("\n\t Transmit Timestamp: "); p_ntp_time(ndo, &(bp->xmt_timestamp)); - ND_PRINT((ndo, "\n\t Originator - Receive Timestamp: ")); + ND_PRINT("\n\t Originator - Receive Timestamp: "); p_ntp_delta(ndo, &(bp->org_timestamp), &(bp->rec_timestamp)); - ND_PRINT((ndo, "\n\t Originator - Transmit Timestamp: ")); + ND_PRINT("\n\t Originator - Transmit Timestamp: "); p_ntp_delta(ndo, &(bp->org_timestamp), &(bp->xmt_timestamp)); - if ( (sizeof(struct ntpdata) - length) == 16) { /* Optional: key-id */ - ND_TCHECK(bp->key_id); - ND_PRINT((ndo, "\n\tKey id: %u", bp->key_id)); - } else if ( (sizeof(struct ntpdata) - length) == 0) { /* Optional: key-id + authentication */ - ND_TCHECK(bp->key_id); - ND_PRINT((ndo, "\n\tKey id: %u", bp->key_id)); - ND_TCHECK2(bp->message_digest, sizeof (bp->message_digest)); - ND_PRINT((ndo, "\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))); - } + /* FIXME: this code is not aware of any extension fields */ + if (length == NTP_TIMEMSG_MINLEN + 4) { /* Optional: key-id (crypto-NAK) */ + ND_PRINT("\n\tKey id: %u", GET_BE_U_4(bp->key_id)); + } else if (length == NTP_TIMEMSG_MINLEN + 4 + 16) { /* Optional: key-id + 128-bit digest */ + ND_PRINT("\n\tKey id: %u", GET_BE_U_4(bp->key_id)); + ND_TCHECK_LEN(bp->message_digest, 16); + ND_PRINT("\n\tAuthentication: %08x%08x%08x%08x", + GET_BE_U_4(bp->message_digest), + GET_BE_U_4(bp->message_digest + 4), + GET_BE_U_4(bp->message_digest + 8), + GET_BE_U_4(bp->message_digest + 12)); + } else if (length == NTP_TIMEMSG_MINLEN + 4 + 20) { /* Optional: key-id + 160-bit digest */ + ND_PRINT("\n\tKey id: %u", GET_BE_U_4(bp->key_id)); + ND_TCHECK_LEN(bp->message_digest, 20); + ND_PRINT("\n\tAuthentication: %08x%08x%08x%08x%08x", + GET_BE_U_4(bp->message_digest), + GET_BE_U_4(bp->message_digest + 4), + GET_BE_U_4(bp->message_digest + 8), + GET_BE_U_4(bp->message_digest + 12), + GET_BE_U_4(bp->message_digest + 16)); + } else if (length > NTP_TIMEMSG_MINLEN) { + ND_PRINT("\n\t(%u more bytes after the header)", length - NTP_TIMEMSG_MINLEN); + } + return; + +invalid: + nd_print_invalid(ndo); + ND_TCHECK_LEN(bp, length); return; trunc: - ND_PRINT((ndo, " [|ntp]")); + nd_print_trunc(ndo); } +/* + * Print NTP control message requests and responses + */ static void -p_sfix(netdissect_options *ndo, - register const struct s_fixedpt *sfp) +ntp_control_print(netdissect_options *ndo, + const struct ntp_control_data *cd, u_int length) { - register int i; - register int f; - register double ff; + uint8_t control, R, E, M, opcode; + uint16_t sequence, status, assoc, offset, count; - i = EXTRACT_16BITS(&sfp->int_part); - f = EXTRACT_16BITS(&sfp->fraction); - ff = f / 65536.0; /* shift radix point by 16 bits */ - f = (int)(ff * 1000000.0); /* Treat fraction as parts per million */ - ND_PRINT((ndo, "%d.%06d", i, f)); + if (length < NTP_CTRLMSG_MINLEN) + goto invalid; + + control = GET_U_1(cd->control); + R = (control & 0x80) != 0; + E = (control & 0x40) != 0; + M = (control & 0x20) != 0; + opcode = control & 0x1f; + ND_PRINT(", %s, %s, %s, OpCode=%u\n", + R ? "Response" : "Request", E ? "Error" : "OK", + M ? "More" : "Last", opcode); + + sequence = GET_BE_U_2(cd->sequence); + ND_PRINT("\tSequence=%hu", sequence); + + status = GET_BE_U_2(cd->status); + ND_PRINT(", Status=%#hx", status); + + assoc = GET_BE_U_2(cd->assoc); + ND_PRINT(", Assoc.=%hu", assoc); + + offset = GET_BE_U_2(cd->offset); + ND_PRINT(", Offset=%hu", offset); + + count = GET_BE_U_2(cd->count); + ND_PRINT(", Count=%hu", count); + + if (NTP_CTRLMSG_MINLEN + count > length) + goto invalid; + if (count != 0) { + ND_TCHECK_LEN(cd->data, count); + ND_PRINT("\n\tTO-BE-DONE: data not interpreted"); + } + return; + +invalid: + nd_print_invalid(ndo); + ND_TCHECK_LEN(cd, length); + return; + +trunc: + nd_print_trunc(ndo); } -#define FMAXINT (4294967296.0) /* floating point rep. of MAXINT */ +union ntpdata { + struct ntp_time_data td; + struct ntp_control_data cd; +}; -static void -p_ntp_time(netdissect_options *ndo, - register const struct l_fixedpt *lfp) +/* + * Print NTP requests, handling the common VN, LI, and Mode + */ +void +ntp_print(netdissect_options *ndo, + const u_char *cp, u_int length) { - register int32_t i; - register uint32_t uf; - register uint32_t f; - register double ff; - - i = EXTRACT_32BITS(&lfp->int_part); - uf = EXTRACT_32BITS(&lfp->fraction); - ff = uf; - if (ff < 0.0) /* some compilers are buggy */ - ff += FMAXINT; - ff = ff / FMAXINT; /* shift radix point by 32 bits */ - f = (uint32_t)(ff * 1000000000.0); /* treat fraction as parts per billion */ - ND_PRINT((ndo, "%u.%09d", i, f)); + const union ntpdata *bp = (const union ntpdata *)cp; + u_int mode, version, leapind; + uint8_t status; -#ifdef HAVE_STRFTIME - /* - * print the time in human-readable format. - */ - if (i) { - time_t seconds = i - JAN_1970; - struct tm *tm; - char time_buf[128]; - - tm = localtime(&seconds); - strftime(time_buf, sizeof (time_buf), "%Y/%m/%d %H:%M:%S", tm); - ND_PRINT((ndo, " (%s)", time_buf)); + ndo->ndo_protocol = "ntp"; + status = GET_U_1(bp->td.status); + + version = (status & VERSIONMASK) >> VERSIONSHIFT; + ND_PRINT("NTPv%u", version); + + mode = (status & MODEMASK) >> MODESHIFT; + if (!ndo->ndo_vflag) { + ND_PRINT(", %s, length %u", + tok2str(ntp_mode_values, "Unknown mode", mode), + length); + return; + } + + ND_PRINT(", %s, length %u\n", + tok2str(ntp_mode_values, "Unknown mode", mode), length); + + /* leapind = (status & LEAPMASK) >> LEAPSHIFT; */ + leapind = (status & LEAPMASK); + ND_PRINT("\tLeap indicator: %s (%u)", + tok2str(ntp_leapind_values, "Unknown", leapind), + leapind); + + switch (mode) { + + case MODE_UNSPEC: + case MODE_SYM_ACT: + case MODE_SYM_PAS: + case MODE_CLIENT: + case MODE_SERVER: + case MODE_BROADCAST: + ntp_time_print(ndo, &bp->td, length); + break; + + case MODE_CONTROL: + ntp_control_print(ndo, &bp->cd, length); + break; + + default: + break; /* XXX: not implemented! */ } -#endif +} + +static void +p_sfix(netdissect_options *ndo, + const struct s_fixedpt *sfp) +{ + int i; + int f; + double ff; + + i = GET_BE_U_2(sfp->int_part); + f = GET_BE_U_2(sfp->fraction); + ff = f / 65536.0; /* shift radix point by 16 bits */ + f = (int)(ff * 1000000.0); /* Treat fraction as parts per million */ + ND_PRINT("%d.%06d", i, f); } /* Prints time difference between *lfp and *olfp */ static void p_ntp_delta(netdissect_options *ndo, - register const struct l_fixedpt *olfp, - register const struct l_fixedpt *lfp) + const struct l_fixedpt *olfp, + const struct l_fixedpt *lfp) { - register int32_t i; - register uint32_t u, uf; - register uint32_t ou, ouf; - register uint32_t f; - register double ff; + uint32_t u, uf; + uint32_t ou, ouf; + uint32_t i; + uint32_t f; + double ff; int signbit; - u = EXTRACT_32BITS(&lfp->int_part); - ou = EXTRACT_32BITS(&olfp->int_part); - uf = EXTRACT_32BITS(&lfp->fraction); - ouf = EXTRACT_32BITS(&olfp->fraction); + u = GET_BE_U_4(lfp->int_part); + ou = GET_BE_U_4(olfp->int_part); + uf = GET_BE_U_4(lfp->fraction); + ouf = GET_BE_U_4(olfp->fraction); if (ou == 0 && ouf == 0) { p_ntp_time(ndo, lfp); return; } - i = u - ou; - - if (i > 0) { /* new is definitely greater than old */ + if (u > ou) { /* new is definitely greater than old */ signbit = 0; + i = u - ou; f = uf - ouf; if (ouf > uf) /* must borrow from high-order bits */ i -= 1; - } else if (i < 0) { /* new is definitely less than old */ + } else if (u < ou) { /* new is definitely less than old */ signbit = 1; + i = ou - u; f = ouf - uf; - if (uf > ouf) /* must carry into the high-order bits */ - i += 1; - i = -i; + if (uf > ouf) /* must borrow from the high-order bits */ + i -= 1; } else { /* int_part is zero */ + i = 0; if (uf > ouf) { signbit = 0; f = uf - ouf; @@ -422,6 +519,20 @@ p_ntp_delta(netdissect_options *ndo, ff += FMAXINT; ff = ff / FMAXINT; /* shift radix point by 32 bits */ f = (uint32_t)(ff * 1000000000.0); /* treat fraction as parts per billion */ - ND_PRINT((ndo, "%s%d.%09d", signbit ? "-" : "+", i, f)); + ND_PRINT("%s%u.%09u", signbit ? "-" : "+", i, f); +} + +/* Prints polling interval in log2 as seconds or fraction of second */ +static void +p_poll(netdissect_options *ndo, + const int poll_interval) +{ + if (poll_interval <= -32 || poll_interval >= 32) + return; + + if (poll_interval >= 0) + ND_PRINT(" (%us)", 1U << poll_interval); + else + ND_PRINT(" (1/%us)", 1U << -poll_interval); } diff --git a/contrib/tcpdump/print-null.c b/contrib/tcpdump/print-null.c index 59b691cc63..a1b03f86aa 100644 --- a/contrib/tcpdump/print-null.c +++ b/contrib/tcpdump/print-null.c @@ -22,16 +22,17 @@ /* \summary: BSD loopback device printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include - -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" +#include "extract.h" #include "af.h" + /* * The DLT_NULL packet header is 4 bytes long. It contains a host-byte-order * 32-bit integer that specifies the family, e.g. AF_INET. @@ -52,18 +53,18 @@ #define SWAPLONG(y) \ ((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff)) -static inline void -null_hdr_print(netdissect_options *ndo, u_int family, u_int length) +static void +null_hdr_print(netdissect_options *ndo, uint32_t family, u_int length) { if (!ndo->ndo_qflag) { - ND_PRINT((ndo, "AF %s (%u)", - tok2str(bsd_af_values,"Unknown",family),family)); + ND_PRINT("AF %s (%u)", + tok2str(bsd_af_values,"Unknown",family),family); } else { - ND_PRINT((ndo, "%s", - tok2str(bsd_af_values,"Unknown AF %u",family))); + ND_PRINT("%s", + tok2str(bsd_af_values,"Unknown AF %u",family)); } - ND_PRINT((ndo, ", length %u: ", length)); + ND_PRINT(", length %u: ", length); } /* @@ -72,19 +73,18 @@ null_hdr_print(netdissect_options *ndo, u_int family, u_int length) * 'h->len' is the length of the packet off the wire, and 'h->caplen' * is the number of bytes actually captured. */ -u_int +void null_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { u_int length = h->len; u_int caplen = h->caplen; - u_int family; + uint32_t family; - if (caplen < NULL_HDRLEN) { - ND_PRINT((ndo, "[|null]")); - return (NULL_HDRLEN); - } + ndo->ndo_protocol = "null"; + ND_TCHECK_LEN(p, NULL_HDRLEN); + ndo->ndo_ll_hdr_len += NULL_HDRLEN; - memcpy((char *)&family, (const char *)p, sizeof(family)); + family = GET_HE_U_4(p); /* * This isn't necessarily in our host byte order; if this is @@ -135,13 +135,4 @@ null_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); } - - return (NULL_HDRLEN); } - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/print-olsr.c b/contrib/tcpdump/print-olsr.c index e67988dfd8..8f04923716 100644 --- a/contrib/tcpdump/print-olsr.c +++ b/contrib/tcpdump/print-olsr.c @@ -22,10 +22,10 @@ /* specification: RFC 3626 */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "addrtoname.h" @@ -63,8 +63,8 @@ */ struct olsr_common { - uint8_t packet_len[2]; - uint8_t packet_seq[2]; + nd_uint16_t packet_len; + nd_uint16_t packet_seq; }; #define OLSR_HELLO_MSG 1 /* rfc3626 */ @@ -89,50 +89,50 @@ static const struct tok olsr_msg_values[] = { }; struct olsr_msg4 { - uint8_t msg_type; - uint8_t vtime; - uint8_t msg_len[2]; - uint8_t originator[4]; - uint8_t ttl; - uint8_t hopcount; - uint8_t msg_seq[2]; + nd_uint8_t msg_type; + nd_uint8_t vtime; + nd_uint16_t msg_len; + nd_ipv4 originator; + nd_uint8_t ttl; + nd_uint8_t hopcount; + nd_uint16_t msg_seq; }; struct olsr_msg6 { - uint8_t msg_type; - uint8_t vtime; - uint8_t msg_len[2]; - uint8_t originator[16]; - uint8_t ttl; - uint8_t hopcount; - uint8_t msg_seq[2]; + nd_uint8_t msg_type; + nd_uint8_t vtime; + nd_uint16_t msg_len; + nd_ipv6 originator; + nd_uint8_t ttl; + nd_uint8_t hopcount; + nd_uint16_t msg_seq; }; struct olsr_hello { - uint8_t res[2]; - uint8_t htime; - uint8_t will; + nd_byte res[2]; + nd_uint8_t htime; + nd_uint8_t will; }; struct olsr_hello_link { - uint8_t link_code; - uint8_t res; - uint8_t len[2]; + nd_uint8_t link_code; + nd_byte res; + nd_uint16_t len; }; struct olsr_tc { - uint8_t ans_seq[2]; - uint8_t res[2]; + nd_uint16_t ans_seq; + nd_byte res[2]; }; struct olsr_hna4 { - uint8_t network[4]; - uint8_t mask[4]; + nd_ipv4 network; + nd_ipv4 mask; }; struct olsr_hna6 { - uint8_t network[16]; - uint8_t mask[16]; + nd_ipv6 network; + nd_ipv6 mask; }; @@ -175,17 +175,17 @@ static const struct tok olsr_neighbor_type_values[] = { }; struct olsr_lq_neighbor4 { - uint8_t neighbor[4]; - uint8_t link_quality; - uint8_t neighbor_link_quality; - uint8_t res[2]; + nd_ipv4 neighbor; + nd_uint8_t link_quality; + nd_uint8_t neighbor_link_quality; + nd_byte res[2]; }; struct olsr_lq_neighbor6 { - uint8_t neighbor[16]; - uint8_t link_quality; - uint8_t neighbor_link_quality; - uint8_t res[2]; + nd_ipv6 neighbor; + nd_uint8_t link_quality; + nd_uint8_t neighbor_link_quality; + nd_byte res[2]; }; #define MAX_SMARTGW_SPEED 320000000 @@ -213,8 +213,9 @@ static uint32_t deserialize_gw_speed(uint8_t value) { speed = (value >> 3) + 1; exp = value & 7; - while (exp-- > 0) { + while (exp != 0) { speed *= 10; + exp--; } return speed; } @@ -239,19 +240,20 @@ olsr_print_lq_neighbor4(netdissect_options *ndo, while (hello_len >= sizeof(struct olsr_lq_neighbor4)) { lq_neighbor = (const struct olsr_lq_neighbor4 *)msg_data; - if (!ND_TTEST(*lq_neighbor)) - return (-1); + ND_TCHECK_SIZE(lq_neighbor); - ND_PRINT((ndo, "\n\t neighbor %s, link-quality %.2f%%" + ND_PRINT("\n\t neighbor %s, link-quality %.2f%%" ", neighbor-link-quality %.2f%%", - ipaddr_string(ndo, lq_neighbor->neighbor), - ((double)lq_neighbor->link_quality/2.55), - ((double)lq_neighbor->neighbor_link_quality/2.55))); + GET_IPADDR_STRING(lq_neighbor->neighbor), + ((double) GET_U_1(lq_neighbor->link_quality)/2.55), + ((double) GET_U_1(lq_neighbor->neighbor_link_quality)/2.55)); msg_data += sizeof(struct olsr_lq_neighbor4); hello_len -= sizeof(struct olsr_lq_neighbor4); } return (0); +trunc: + return -1; } static int @@ -263,19 +265,20 @@ olsr_print_lq_neighbor6(netdissect_options *ndo, while (hello_len >= sizeof(struct olsr_lq_neighbor6)) { lq_neighbor = (const struct olsr_lq_neighbor6 *)msg_data; - if (!ND_TTEST(*lq_neighbor)) - return (-1); + ND_TCHECK_SIZE(lq_neighbor); - ND_PRINT((ndo, "\n\t neighbor %s, link-quality %.2f%%" + ND_PRINT("\n\t neighbor %s, link-quality %.2f%%" ", neighbor-link-quality %.2f%%", - ip6addr_string(ndo, lq_neighbor->neighbor), - ((double)lq_neighbor->link_quality/2.55), - ((double)lq_neighbor->neighbor_link_quality/2.55))); + GET_IP6ADDR_STRING(lq_neighbor->neighbor), + ((double) GET_U_1(lq_neighbor->link_quality)/2.55), + ((double) GET_U_1(lq_neighbor->neighbor_link_quality)/2.55)); msg_data += sizeof(struct olsr_lq_neighbor6); hello_len -= sizeof(struct olsr_lq_neighbor6); } return (0); +trunc: + return -1; } /* @@ -287,20 +290,16 @@ olsr_print_neighbor(netdissect_options *ndo, { int neighbor; - ND_PRINT((ndo, "\n\t neighbor\n\t\t")); + ND_PRINT("\n\t neighbor\n\t\t"); neighbor = 1; - while (hello_len >= sizeof(struct in_addr)) { - - if (!ND_TTEST2(*msg_data, sizeof(struct in_addr))) - return (-1); + while (hello_len >= sizeof(nd_ipv4)) { /* print 4 neighbors per line */ + ND_PRINT("%s%s", GET_IPADDR_STRING(msg_data), + neighbor % 4 == 0 ? "\n\t\t" : " "); - ND_PRINT((ndo, "%s%s", ipaddr_string(ndo, msg_data), - neighbor % 4 == 0 ? "\n\t\t" : " ")); - - msg_data += sizeof(struct in_addr); - hello_len -= sizeof(struct in_addr); + msg_data += sizeof(nd_ipv4); + hello_len -= sizeof(nd_ipv4); } return (0); } @@ -326,21 +325,24 @@ olsr_print(netdissect_options *ndo, uint8_t link_type, neighbor_type; const u_char *tptr, *msg_data; + ndo->ndo_protocol = "olsr"; tptr = pptr; + nd_print_protocol_caps(ndo); + ND_PRINT("v%u", (is_ipv6) ? 6 : 4); + if (length < sizeof(struct olsr_common)) { goto trunc; } - ND_TCHECK2(*tptr, sizeof(struct olsr_common)); + ND_TCHECK_LEN(tptr, sizeof(struct olsr_common)); ptr.common = (const struct olsr_common *)tptr; - length = min(length, EXTRACT_16BITS(ptr.common->packet_len)); + length = ND_MIN(length, GET_BE_U_2(ptr.common->packet_len)); - ND_PRINT((ndo, "OLSRv%i, seq 0x%04x, length %u", - (is_ipv6 == 0) ? 4 : 6, - EXTRACT_16BITS(ptr.common->packet_seq), - length)); + ND_PRINT(", seq 0x%04x, length %u", + GET_BE_U_2(ptr.common->packet_seq), + length); tptr += sizeof(struct olsr_common); @@ -361,10 +363,10 @@ olsr_print(netdissect_options *ndo, if (is_ipv6) { - ND_TCHECK2(*tptr, sizeof(struct olsr_msg6)); + ND_TCHECK_LEN(tptr, sizeof(struct olsr_msg6)); msgptr.v6 = (const struct olsr_msg6 *) tptr; - msg_type = msgptr.v6->msg_type; - msg_len = EXTRACT_16BITS(msgptr.v6->msg_len); + msg_type = GET_U_1(msgptr.v6->msg_type); + msg_len = GET_BE_U_2(msgptr.v6->msg_len); if ((msg_len >= sizeof (struct olsr_msg6)) && (msg_len <= length)) msg_len_valid = 1; @@ -374,15 +376,15 @@ olsr_print(netdissect_options *ndo, return; } - ND_PRINT((ndo, "\n\t%s Message (%#04x), originator %s, ttl %u, hop %u" + ND_PRINT("\n\t%s Message (%#04x), originator %s, ttl %u, hop %u" "\n\t vtime %.3fs, msg-seq 0x%04x, length %u%s", tok2str(olsr_msg_values, "Unknown", msg_type), - msg_type, ip6addr_string(ndo, 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_type, GET_IP6ADDR_STRING(msgptr.v6->originator), + GET_U_1(msgptr.v6->ttl), + GET_U_1(msgptr.v6->hopcount), + ME_TO_DOUBLE(GET_U_1(msgptr.v6->vtime)), + GET_BE_U_2(msgptr.v6->msg_seq), + msg_len, (msg_len_valid == 0) ? " (invalid)" : ""); if (!msg_len_valid) { return; } @@ -392,10 +394,10 @@ olsr_print(netdissect_options *ndo, } else /* (!is_ipv6) */ { - ND_TCHECK2(*tptr, sizeof(struct olsr_msg4)); + ND_TCHECK_LEN(tptr, sizeof(struct olsr_msg4)); msgptr.v4 = (const struct olsr_msg4 *) tptr; - msg_type = msgptr.v4->msg_type; - msg_len = EXTRACT_16BITS(msgptr.v4->msg_len); + msg_type = GET_U_1(msgptr.v4->msg_type); + msg_len = GET_BE_U_2(msgptr.v4->msg_len); if ((msg_len >= sizeof (struct olsr_msg4)) && (msg_len <= length)) msg_len_valid = 1; @@ -405,15 +407,15 @@ olsr_print(netdissect_options *ndo, return; } - ND_PRINT((ndo, "\n\t%s Message (%#04x), originator %s, ttl %u, hop %u" + ND_PRINT("\n\t%s Message (%#04x), originator %s, ttl %u, hop %u" "\n\t vtime %.3fs, msg-seq 0x%04x, length %u%s", tok2str(olsr_msg_values, "Unknown", msg_type), - msg_type, ipaddr_string(ndo, 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_type, GET_IPADDR_STRING(msgptr.v4->originator), + GET_U_1(msgptr.v4->ttl), + GET_U_1(msgptr.v4->hopcount), + ME_TO_DOUBLE(GET_U_1(msgptr.v4->vtime)), + GET_BE_U_2(msgptr.v4->msg_seq), + msg_len, (msg_len_valid == 0) ? " (invalid)" : ""); if (!msg_len_valid) { return; } @@ -427,11 +429,12 @@ olsr_print(netdissect_options *ndo, case OLSR_HELLO_LQ_MSG: if (msg_tlen < sizeof(struct olsr_hello)) goto trunc; - ND_TCHECK2(*msg_data, sizeof(struct olsr_hello)); + ND_TCHECK_LEN(msg_data, sizeof(struct olsr_hello)); ptr.hello = (const struct olsr_hello *)msg_data; - ND_PRINT((ndo, "\n\t hello-time %.3fs, MPR willingness %u", - ME_TO_DOUBLE(ptr.hello->htime), ptr.hello->will)); + ND_PRINT("\n\t hello-time %.3fs, MPR willingness %u", + ME_TO_DOUBLE(GET_U_1(ptr.hello->htime)), + GET_U_1(ptr.hello->will)); msg_data += sizeof(struct olsr_hello); msg_tlen -= sizeof(struct olsr_hello); @@ -441,23 +444,23 @@ olsr_print(netdissect_options *ndo, /* * link-type. */ - ND_TCHECK2(*msg_data, sizeof(struct olsr_hello_link)); + ND_TCHECK_LEN(msg_data, sizeof(struct olsr_hello_link)); ptr.hello_link = (const struct olsr_hello_link *)msg_data; - hello_len = EXTRACT_16BITS(ptr.hello_link->len); - link_type = OLSR_EXTRACT_LINK_TYPE(ptr.hello_link->link_code); - neighbor_type = OLSR_EXTRACT_NEIGHBOR_TYPE(ptr.hello_link->link_code); + hello_len = GET_BE_U_2(ptr.hello_link->len); + link_type = OLSR_EXTRACT_LINK_TYPE(GET_U_1(ptr.hello_link->link_code)); + neighbor_type = OLSR_EXTRACT_NEIGHBOR_TYPE(GET_U_1(ptr.hello_link->link_code)); if ((hello_len <= msg_tlen) && (hello_len >= sizeof(struct olsr_hello_link))) hello_len_valid = 1; - ND_PRINT((ndo, "\n\t link-type %s, neighbor-type %s, len %u%s", + ND_PRINT("\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_valid == 0) ? " (invalid)" : "")); + (hello_len_valid == 0) ? " (invalid)" : ""); if (hello_len_valid == 0) break; @@ -466,7 +469,7 @@ olsr_print(netdissect_options *ndo, msg_tlen -= sizeof(struct olsr_hello_link); hello_len -= sizeof(struct olsr_hello_link); - ND_TCHECK2(*msg_data, hello_len); + ND_TCHECK_LEN(msg_data, hello_len); if (msg_type == OLSR_HELLO_MSG) { if (olsr_print_neighbor(ndo, msg_data, hello_len) == -1) goto trunc; @@ -489,11 +492,11 @@ olsr_print(netdissect_options *ndo, case OLSR_TC_LQ_MSG: if (msg_tlen < sizeof(struct olsr_tc)) goto trunc; - ND_TCHECK2(*msg_data, sizeof(struct olsr_tc)); + ND_TCHECK_LEN(msg_data, sizeof(struct olsr_tc)); ptr.tc = (const struct olsr_tc *)msg_data; - ND_PRINT((ndo, "\n\t advertised neighbor seq 0x%04x", - EXTRACT_16BITS(ptr.tc->ans_seq))); + ND_PRINT("\n\t advertised neighbor seq 0x%04x", + GET_BE_U_2(ptr.tc->ans_seq)); msg_data += sizeof(struct olsr_tc); msg_tlen -= sizeof(struct olsr_tc); @@ -513,16 +516,16 @@ olsr_print(netdissect_options *ndo, case OLSR_MID_MSG: { - size_t addr_size = sizeof(struct in_addr); + u_int addr_size = (u_int)sizeof(nd_ipv4); if (is_ipv6) - addr_size = sizeof(struct in6_addr); + addr_size = (u_int)sizeof(nd_ipv6); while (msg_tlen >= addr_size) { - ND_TCHECK2(*msg_data, addr_size); - ND_PRINT((ndo, "\n\t interface address %s", - is_ipv6 ? ip6addr_string(ndo, msg_data) : - ipaddr_string(ndo, msg_data))); + ND_TCHECK_LEN(msg_data, addr_size); + ND_PRINT("\n\t interface address %s", + is_ipv6 ? GET_IP6ADDR_STRING(msg_data) : + GET_IPADDR_STRING(msg_data)); msg_data += addr_size; msg_tlen -= addr_size; @@ -535,19 +538,19 @@ olsr_print(netdissect_options *ndo, { int i = 0; - ND_PRINT((ndo, "\n\t Advertised networks (total %u)", - (unsigned int) (msg_tlen / sizeof(struct olsr_hna6)))); + ND_PRINT("\n\t Advertised networks (total %u)", + (unsigned int) (msg_tlen / sizeof(struct olsr_hna6))); while (msg_tlen >= sizeof(struct olsr_hna6)) { const struct olsr_hna6 *hna6; - ND_TCHECK2(*msg_data, sizeof(struct olsr_hna6)); + ND_TCHECK_LEN(msg_data, sizeof(struct olsr_hna6)); hna6 = (const struct olsr_hna6 *)msg_data; - ND_PRINT((ndo, "\n\t #%i: %s/%u", - i, ip6addr_string(ndo, hna6->network), - mask62plen (hna6->mask))); + ND_PRINT("\n\t #%i: %s/%u", + i, GET_IP6ADDR_STRING(hna6->network), + mask62plen (hna6->mask)); msg_data += sizeof(struct olsr_hna6); msg_tlen -= sizeof(struct olsr_hna6); @@ -557,11 +560,11 @@ olsr_print(netdissect_options *ndo, { int col = 0; - ND_PRINT((ndo, "\n\t Advertised networks (total %u)", - (unsigned int) (msg_tlen / sizeof(struct olsr_hna4)))); + ND_PRINT("\n\t Advertised networks (total %u)", + (unsigned int) (msg_tlen / sizeof(struct olsr_hna4))); while (msg_tlen >= sizeof(struct olsr_hna4)) { - ND_TCHECK2(*msg_data, sizeof(struct olsr_hna4)); + ND_TCHECK_LEN(msg_data, sizeof(struct olsr_hna4)); ptr.hna = (const struct olsr_hna4 *)msg_data; @@ -571,7 +574,7 @@ olsr_print(netdissect_options *ndo, !ptr.hna->mask[GW_HNA_PAD] && ptr.hna->mask[GW_HNA_FLAGS]) { /* smart gateway */ - ND_PRINT((ndo, "%sSmart-Gateway:%s%s%s%s%s %u/%u", + ND_PRINT("%sSmart-Gateway:%s%s%s%s%s %u/%u", col == 0 ? "\n\t " : ", ", /* indent */ /* sgw */ /* LINKSPEED */ @@ -597,13 +600,13 @@ olsr_print(netdissect_options *ndo, (ptr.hna->mask[GW_HNA_FLAGS] & GW_HNA_FLAG_LINKSPEED) ? deserialize_gw_speed(ptr.hna->mask[GW_HNA_DOWNLINK]) : 0 - )); + ); } else { /* normal route */ - ND_PRINT((ndo, "%s%s/%u", + ND_PRINT("%s%s/%u", col == 0 ? "\n\t " : ", ", - ipaddr_string(ndo, ptr.hna->network), - mask2plen(EXTRACT_32BITS(ptr.hna->mask)))); + GET_IPADDR_STRING(ptr.hna->network), + mask2plen(GET_BE_U_4(ptr.hna->mask))); } msg_data += sizeof(struct olsr_hna4); @@ -623,9 +626,8 @@ olsr_print(netdissect_options *ndo, if (msg_tlen < 4) goto trunc; - ND_TCHECK2(*msg_data, 4); - name_entries = EXTRACT_16BITS(msg_data+2); + name_entries = GET_BE_U_2(msg_data + 2); addr_size = 4; if (is_ipv6) addr_size = 16; @@ -635,9 +637,9 @@ olsr_print(netdissect_options *ndo, && ((name_entries * (4 + addr_size)) <= msg_tlen)) name_entries_valid = 1; - ND_PRINT((ndo, "\n\t Version %u, Entries %u%s", - EXTRACT_16BITS(msg_data), - name_entries, (name_entries_valid == 0) ? " (invalid)" : "")); + ND_PRINT("\n\t Version %u, Entries %u%s", + GET_BE_U_2(msg_data), + name_entries, (name_entries_valid == 0) ? " (invalid)" : ""); if (name_entries_valid == 0) break; @@ -650,10 +652,9 @@ olsr_print(netdissect_options *ndo, if (msg_tlen < 4) break; - ND_TCHECK2(*msg_data, 4); - name_entry_type = EXTRACT_16BITS(msg_data); - name_entry_len = EXTRACT_16BITS(msg_data+2); + name_entry_type = GET_BE_U_2(msg_data); + name_entry_len = GET_BE_U_2(msg_data + 2); msg_data += 4; msg_tlen -= 4; @@ -661,9 +662,9 @@ olsr_print(netdissect_options *ndo, if ((name_entry_len > 0) && ((addr_size + name_entry_len) <= msg_tlen)) name_entry_len_valid = 1; - ND_PRINT((ndo, "\n\t #%u: type %#06x, length %u%s", + ND_PRINT("\n\t #%u: type %#06x, length %u%s", (unsigned int) i, name_entry_type, - name_entry_len, (name_entry_len_valid == 0) ? " (invalid)" : "")); + name_entry_len, (name_entry_len_valid == 0) ? " (invalid)" : ""); if (name_entry_len_valid == 0) break; @@ -676,16 +677,17 @@ olsr_print(netdissect_options *ndo, if (msg_tlen < addr_size + name_entry_len + name_entry_padding) goto trunc; - ND_TCHECK2(*msg_data, addr_size + name_entry_len + name_entry_padding); + ND_TCHECK_LEN(msg_data, + addr_size + name_entry_len + name_entry_padding); if (is_ipv6) - ND_PRINT((ndo, ", address %s, name \"", - ip6addr_string(ndo, msg_data))); + ND_PRINT(", address %s, name \"", + GET_IP6ADDR_STRING(msg_data)); else - ND_PRINT((ndo, ", address %s, name \"", - ipaddr_string(ndo, msg_data))); - (void)fn_printn(ndo, msg_data + addr_size, name_entry_len, NULL); - ND_PRINT((ndo, "\"")); + ND_PRINT(", address %s, name \"", + GET_IPADDR_STRING(msg_data)); + (void)nd_printn(ndo, msg_data + addr_size, name_entry_len, NULL); + ND_PRINT("\""); msg_data += addr_size + name_entry_len + name_entry_padding; msg_tlen -= addr_size + name_entry_len + name_entry_padding; @@ -708,12 +710,5 @@ olsr_print(netdissect_options *ndo, return; trunc: - ND_PRINT((ndo, "[|olsr]")); + nd_print_trunc(ndo); } - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 4 - * End: - */ diff --git a/contrib/tcpdump/print-openflow-1.0.c b/contrib/tcpdump/print-openflow-1.0.c index ce9584305f..1d7f247487 100644 --- a/contrib/tcpdump/print-openflow-1.0.c +++ b/contrib/tcpdump/print-openflow-1.0.c @@ -6,17 +6,18 @@ * up bogus values of selected message fields and decodes partially captured * messages up to the snapshot end. It is based on the specification below: * - * [OF10] http://www.openflow.org/documents/openflow-spec-v1.0.0.pdf + * [OF10] https://www.opennetworking.org/wp-content/uploads/2013/04/openflow-spec-v1.0.0.pdf * - * Most functions in this file take 3 arguments into account: + * Most functions in this file take the following arguments: * * cp -- the pointer to the first octet to decode - * * len -- the length of the current structure as declared on the wire - * * ep -- the pointer to the end of the captured frame - * They return either the pointer to the next not-yet-decoded part of the frame - * or the value of ep, which means the current frame processing is over as it - * has been fully decoded or is invalid or truncated. This way it is possible - * to chain and nest such functions uniformly to decode an OF1.0 message, which - * consists of several layers of nested structures. + * * len -- the declared length of the structure to decode + * The convention is that a printer function returns iff the given structure is + * completely within the packet buffer; otherwise it processes the part that is + * within the buffer, sooner of later takes the "truncated packet" shortcut via + * longjmp() and never returns. With that in mind, the function may return + * without printing the structure completely if it is invalid or the ndo_vflag + * value is not high enough. This way the calling function can try to decode + * the next data item. * * Decoding of Ethernet frames nested in OFPT_PACKET_IN and OFPT_PACKET_OUT * messages is done only when the verbosity level set by command-line argument @@ -59,21 +60,20 @@ /* \summary: OpenFlow protocol version 1.0 printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" #include "addrtoname.h" -#include "ether.h" #include "ethertype.h" #include "ipproto.h" #include "oui.h" #include "openflow.h" -static const char tstr[] = " [|openflow]"; #define OFPT_HELLO 0x00 #define OFPT_ERROR 0x01 @@ -97,39 +97,15 @@ static const char tstr[] = " [|openflow]"; #define OFPT_BARRIER_REPLY 0x13 #define OFPT_QUEUE_GET_CONFIG_REQUEST 0x14 #define OFPT_QUEUE_GET_CONFIG_REPLY 0x15 -static const struct tok ofpt_str[] = { - { OFPT_HELLO, "HELLO" }, - { OFPT_ERROR, "ERROR" }, - { OFPT_ECHO_REQUEST, "ECHO_REQUEST" }, - { OFPT_ECHO_REPLY, "ECHO_REPLY" }, - { OFPT_VENDOR, "VENDOR" }, - { OFPT_FEATURES_REQUEST, "FEATURES_REQUEST" }, - { OFPT_FEATURES_REPLY, "FEATURES_REPLY" }, - { OFPT_GET_CONFIG_REQUEST, "GET_CONFIG_REQUEST" }, - { OFPT_GET_CONFIG_REPLY, "GET_CONFIG_REPLY" }, - { OFPT_SET_CONFIG, "SET_CONFIG" }, - { OFPT_PACKET_IN, "PACKET_IN" }, - { OFPT_FLOW_REMOVED, "FLOW_REMOVED" }, - { OFPT_PORT_STATUS, "PORT_STATUS" }, - { OFPT_PACKET_OUT, "PACKET_OUT" }, - { OFPT_FLOW_MOD, "FLOW_MOD" }, - { OFPT_PORT_MOD, "PORT_MOD" }, - { OFPT_STATS_REQUEST, "STATS_REQUEST" }, - { OFPT_STATS_REPLY, "STATS_REPLY" }, - { OFPT_BARRIER_REQUEST, "BARRIER_REQUEST" }, - { OFPT_BARRIER_REPLY, "BARRIER_REPLY" }, - { OFPT_QUEUE_GET_CONFIG_REQUEST, "QUEUE_GET_CONFIG_REQUEST" }, - { OFPT_QUEUE_GET_CONFIG_REPLY, "QUEUE_GET_CONFIG_REPLY" }, - { 0, NULL } -}; - -#define OFPPC_PORT_DOWN (1 << 0) -#define OFPPC_NO_STP (1 << 1) -#define OFPPC_NO_RECV (1 << 2) -#define OFPPC_NO_RECV_STP (1 << 3) -#define OFPPC_NO_FLOOD (1 << 4) -#define OFPPC_NO_FWD (1 << 5) -#define OFPPC_NO_PACKET_IN (1 << 6) +#define OFPT_MAX OFPT_QUEUE_GET_CONFIG_REPLY + +#define OFPPC_PORT_DOWN (1U <<0) +#define OFPPC_NO_STP (1U <<1) +#define OFPPC_NO_RECV (1U <<2) +#define OFPPC_NO_RECV_STP (1U <<3) +#define OFPPC_NO_FLOOD (1U <<4) +#define OFPPC_NO_FWD (1U <<5) +#define OFPPC_NO_PACKET_IN (1U <<6) static const struct tok ofppc_bm[] = { { OFPPC_PORT_DOWN, "PORT_DOWN" }, { OFPPC_NO_STP, "NO_STP" }, @@ -144,14 +120,18 @@ static const struct tok ofppc_bm[] = { OFPPC_NO_RECV_STP | OFPPC_NO_FLOOD | OFPPC_NO_FWD | \ OFPPC_NO_PACKET_IN)) -#define OFPPS_LINK_DOWN (1 << 0) -#define OFPPS_STP_LISTEN (0 << 8) -#define OFPPS_STP_LEARN (1 << 8) -#define OFPPS_STP_FORWARD (2 << 8) -#define OFPPS_STP_BLOCK (3 << 8) -#define OFPPS_STP_MASK (3 << 8) -static const struct tok ofpps_bm[] = { - { OFPPS_LINK_DOWN, "LINK_DOWN" }, +/* + * [OF10] lists all FPPS_ constants in one enum, but they mean a 1-bit bitmap + * in the least significant octet and a 2-bit code point in the next octet. + * Remember to mix or to separate these two parts as the context requires. + */ +#define OFPPS_LINK_DOWN (1U << 0) /* bitmap */ +#define OFPPS_STP_LISTEN (0U << 8) /* code point */ +#define OFPPS_STP_LEARN (1U << 8) /* code point */ +#define OFPPS_STP_FORWARD (2U << 8) /* code point */ +#define OFPPS_STP_BLOCK (3U << 8) /* code point */ +#define OFPPS_STP_MASK (3U << 8) /* code point bitmask */ +static const struct tok ofpps_stp_str[] = { { OFPPS_STP_LISTEN, "STP_LISTEN" }, { OFPPS_STP_LEARN, "STP_LEARN" }, { OFPPS_STP_FORWARD, "STP_FORWARD" }, @@ -161,15 +141,15 @@ static const struct tok ofpps_bm[] = { #define OFPPS_U (~(OFPPS_LINK_DOWN | OFPPS_STP_LISTEN | OFPPS_STP_LEARN | \ OFPPS_STP_FORWARD | OFPPS_STP_BLOCK)) -#define OFPP_MAX 0xff00 -#define OFPP_IN_PORT 0xfff8 -#define OFPP_TABLE 0xfff9 -#define OFPP_NORMAL 0xfffa -#define OFPP_FLOOD 0xfffb -#define OFPP_ALL 0xfffc -#define OFPP_CONTROLLER 0xfffd -#define OFPP_LOCAL 0xfffe -#define OFPP_NONE 0xffff +#define OFPP_MAX 0xff00U +#define OFPP_IN_PORT 0xfff8U +#define OFPP_TABLE 0xfff9U +#define OFPP_NORMAL 0xfffaU +#define OFPP_FLOOD 0xfffbU +#define OFPP_ALL 0xfffcU +#define OFPP_CONTROLLER 0xfffdU +#define OFPP_LOCAL 0xfffeU +#define OFPP_NONE 0xffffU static const struct tok ofpp_str[] = { { OFPP_MAX, "MAX" }, { OFPP_IN_PORT, "IN_PORT" }, @@ -183,18 +163,18 @@ static const struct tok ofpp_str[] = { { 0, NULL } }; -#define OFPPF_10MB_HD (1 << 0) -#define OFPPF_10MB_FD (1 << 1) -#define OFPPF_100MB_HD (1 << 2) -#define OFPPF_100MB_FD (1 << 3) -#define OFPPF_1GB_HD (1 << 4) -#define OFPPF_1GB_FD (1 << 5) -#define OFPPF_10GB_FD (1 << 6) -#define OFPPF_COPPER (1 << 7) -#define OFPPF_FIBER (1 << 8) -#define OFPPF_AUTONEG (1 << 9) -#define OFPPF_PAUSE (1 << 10) -#define OFPPF_PAUSE_ASYM (1 << 11) +#define OFPPF_10MB_HD (1U << 0) +#define OFPPF_10MB_FD (1U << 1) +#define OFPPF_100MB_HD (1U << 2) +#define OFPPF_100MB_FD (1U << 3) +#define OFPPF_1GB_HD (1U << 4) +#define OFPPF_1GB_FD (1U << 5) +#define OFPPF_10GB_FD (1U << 6) +#define OFPPF_COPPER (1U << 7) +#define OFPPF_FIBER (1U << 8) +#define OFPPF_AUTONEG (1U << 9) +#define OFPPF_PAUSE (1U <<10) +#define OFPPF_PAUSE_ASYM (1U <<11) static const struct tok ofppf_bm[] = { { OFPPF_10MB_HD, "10MB_HD" }, { OFPPF_10MB_FD, "10MB_FD" }, @@ -223,23 +203,23 @@ static const struct tok ofpqt_str[] = { { 0, NULL } }; -#define OFPFW_IN_PORT (1 << 0) -#define OFPFW_DL_VLAN (1 << 1) -#define OFPFW_DL_SRC (1 << 2) -#define OFPFW_DL_DST (1 << 3) -#define OFPFW_DL_TYPE (1 << 4) -#define OFPFW_NW_PROTO (1 << 5) -#define OFPFW_TP_SRC (1 << 6) -#define OFPFW_TP_DST (1 << 7) +#define OFPFW_IN_PORT (1U <<0) +#define OFPFW_DL_VLAN (1U <<1) +#define OFPFW_DL_SRC (1U <<2) +#define OFPFW_DL_DST (1U <<3) +#define OFPFW_DL_TYPE (1U <<4) +#define OFPFW_NW_PROTO (1U <<5) +#define OFPFW_TP_SRC (1U <<6) +#define OFPFW_TP_DST (1U <<7) #define OFPFW_NW_SRC_SHIFT 8 #define OFPFW_NW_SRC_BITS 6 -#define OFPFW_NW_SRC_MASK (((1 << OFPFW_NW_SRC_BITS) - 1) << OFPFW_NW_SRC_SHIFT) +#define OFPFW_NW_SRC_MASK (((1U < 0 && vid < 0x0fff) ? "%u" : "%u (bogus)"; - snprintf(buf, sizeof(buf), fmt, vid); + snprintf(buf, sizeof(buf), "%u%s", vid, + (vid > 0 && vid < 0x0fff) ? "" : " (bogus)"); return buf; } @@ -712,60 +689,23 @@ static const char * pcp_str(const uint8_t pcp) { static char buf[sizeof("255 (bogus)")]; - snprintf(buf, sizeof(buf), pcp <= 7 ? "%u" : "%u (bogus)", pcp); + snprintf(buf, sizeof(buf), "%u%s", pcp, + pcp <= 7 ? "" : " (bogus)"); return buf; } static void -of10_bitmap_print(netdissect_options *ndo, - const struct tok *t, const uint32_t v, const uint32_t u) -{ - const char *sep = " ("; - - if (v == 0) - return; - /* assigned bits */ - for (; t->s != NULL; t++) - if (v & t->v) { - ND_PRINT((ndo, "%s%s", sep, t->s)); - sep = ", "; - } - /* unassigned bits? */ - ND_PRINT((ndo, v & u ? ") (bogus)" : ")")); -} - -static const u_char * -of10_data_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, const u_int len) -{ - if (len == 0) - return cp; - /* data */ - ND_PRINT((ndo, "\n\t data (%u octets)", len)); - ND_TCHECK2(*cp, len); - if (ndo->ndo_vflag >= 2) - hex_and_ascii_print(ndo, "\n\t ", cp, len); - return cp + len; - -trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; -} - -static const u_char * of10_bsn_message_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, const u_int len) + const u_char *cp, u_int len) { - const u_char *cp0 = cp; uint32_t subtype; if (len < 4) goto invalid; /* subtype */ - ND_TCHECK2(*cp, 4); - subtype = EXTRACT_32BITS(cp); - cp += 4; - ND_PRINT((ndo, "\n\t subtype %s", tok2str(bsn_subtype_str, "unknown (0x%08x)", subtype))); + subtype = GET_BE_U_4(cp); + OF_FWD(4); + ND_PRINT("\n\t subtype %s", tok2str(bsn_subtype_str, "unknown (0x%08x)", subtype)); switch (subtype) { case BSN_GET_IP_MASK_REQUEST: /* @@ -780,15 +720,14 @@ of10_bsn_message_print(netdissect_options *ndo, * +---------------+---------------+---------------+---------------+ * */ - if (len != 12) + if (len != 8) goto invalid; /* index */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, ", index %u", *cp)); - cp += 1; + ND_PRINT(", index %u", GET_U_1(cp)); + OF_FWD(1); /* pad */ - ND_TCHECK2(*cp, 7); - cp += 7; + /* Always the last field, check bounds. */ + ND_TCHECK_7(cp); break; case BSN_SET_IP_MASK: case BSN_GET_IP_MASK_REPLY: @@ -804,19 +743,15 @@ of10_bsn_message_print(netdissect_options *ndo, * +---------------+---------------+---------------+---------------+ * */ - if (len != 12) + if (len != 8) goto invalid; /* index */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, ", index %u", *cp)); - cp += 1; + ND_PRINT(", index %u", GET_U_1(cp)); + OF_FWD(1); /* pad */ - ND_TCHECK2(*cp, 3); - cp += 3; + OF_FWD(3); /* mask */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, ", mask %s", ipaddr_string(ndo, cp))); - cp += 4; + ND_PRINT(", mask %s", GET_IPADDR_STRING(cp)); break; case BSN_SET_MIRRORING: case BSN_GET_MIRRORING_REQUEST: @@ -831,15 +766,15 @@ of10_bsn_message_print(netdissect_options *ndo, * +---------------+---------------+---------------+---------------+ * */ - if (len != 8) + if (len != 4) goto invalid; /* report_mirror_ports */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, ", report_mirror_ports %s", tok2str(bsn_onoff_str, "bogus (%u)", *cp))); - cp += 1; + ND_PRINT(", report_mirror_ports %s", + tok2str(bsn_onoff_str, "bogus (%u)", GET_U_1(cp))); + OF_FWD(1); /* pad */ - ND_TCHECK2(*cp, 3); - cp += 3; + /* Always the last field, check bounds. */ + ND_TCHECK_3(cp); break; case BSN_GET_INTERFACES_REQUEST: case BSN_GET_L2_TABLE_REQUEST: @@ -854,7 +789,7 @@ of10_bsn_message_print(netdissect_options *ndo, * +---------------+---------------+---------------+---------------+ * */ - if (len != 4) + if (len) goto invalid; break; case BSN_VIRTUAL_PORT_REMOVE_REQUEST: @@ -868,12 +803,10 @@ of10_bsn_message_print(netdissect_options *ndo, * +---------------+---------------+---------------+---------------+ * */ - if (len != 8) + if (len != 4) goto invalid; /* vport_no */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, ", vport_no %u", EXTRACT_32BITS(cp))); - cp += 4; + ND_PRINT(", vport_no %u", GET_BE_U_4(cp)); break; case BSN_SHELL_COMMAND: /* @@ -888,20 +821,15 @@ of10_bsn_message_print(netdissect_options *ndo, * +---------------+---------------+-------- * */ - if (len < 8) + if (len < 4) goto invalid; /* service */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, ", service %u", EXTRACT_32BITS(cp))); - cp += 4; + ND_PRINT(", service %u", GET_BE_U_4(cp)); + OF_FWD(4); /* data */ - ND_PRINT((ndo, ", data '")); - if (fn_printn(ndo, cp, len - 8, ep)) { - ND_PRINT((ndo, "'")); - goto trunc; - } - ND_PRINT((ndo, "'")); - cp += len - 8; + ND_PRINT(", data '"); + (void)nd_printn(ndo, cp, len, NULL); + ND_PRINT("'"); break; case BSN_SHELL_OUTPUT: /* @@ -916,13 +844,9 @@ of10_bsn_message_print(netdissect_options *ndo, */ /* already checked that len >= 4 */ /* data */ - ND_PRINT((ndo, ", data '")); - if (fn_printn(ndo, cp, len - 4, ep)) { - ND_PRINT((ndo, "'")); - goto trunc; - } - ND_PRINT((ndo, "'")); - cp += len - 4; + ND_PRINT(", data '"); + (void)nd_printn(ndo, cp, len, NULL); + ND_PRINT("'"); break; case BSN_SHELL_STATUS: /* @@ -935,42 +859,33 @@ of10_bsn_message_print(netdissect_options *ndo, * +---------------+---------------+---------------+---------------+ * */ - if (len != 8) + if (len != 4) goto invalid; /* status */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, ", status 0x%08x", EXTRACT_32BITS(cp))); - cp += 4; + ND_PRINT(", status 0x%08x", GET_BE_U_4(cp)); break; default: - ND_TCHECK2(*cp, len - 4); - cp += len - 4; + ND_TCHECK_LEN(cp, len); } - return cp; + return; invalid: /* skip the undersized data */ - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp0, len); - return cp0 + len; -trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } -static const u_char * +static void of10_bsn_actions_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, const u_int len) + const u_char *cp, u_int len) { - const u_char *cp0 = cp; uint32_t subtype, vlan_tag; if (len < 4) goto invalid; /* subtype */ - ND_TCHECK2(*cp, 4); - subtype = EXTRACT_32BITS(cp); - cp += 4; - ND_PRINT((ndo, "\n\t subtype %s", tok2str(bsn_action_subtype_str, "unknown (0x%08x)", subtype))); + subtype = GET_BE_U_4(cp); + OF_FWD(4); + ND_PRINT("\n\t subtype %s", tok2str(bsn_action_subtype_str, "unknown (0x%08x)", subtype)); switch (subtype) { case BSN_ACTION_MIRROR: /* @@ -987,489 +902,419 @@ of10_bsn_actions_print(netdissect_options *ndo, * +---------------+---------------+---------------+---------------+ * */ - if (len != 16) + if (len != 12) goto invalid; /* dest_port */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, ", dest_port %u", EXTRACT_32BITS(cp))); - cp += 4; + ND_PRINT(", dest_port %u", GET_BE_U_4(cp)); + OF_FWD(4); /* vlan_tag */ - ND_TCHECK2(*cp, 4); - vlan_tag = EXTRACT_32BITS(cp); - cp += 4; + vlan_tag = GET_BE_U_4(cp); + OF_FWD(4); switch (vlan_tag >> 16) { case 0: - ND_PRINT((ndo, ", vlan_tag none")); + ND_PRINT(", vlan_tag none"); break; case ETHERTYPE_8021Q: - ND_PRINT((ndo, ", vlan_tag 802.1Q (%s)", ieee8021q_tci_string(vlan_tag & 0xffff))); + ND_PRINT(", vlan_tag 802.1Q (%s)", ieee8021q_tci_string(vlan_tag & 0xffff)); break; default: - ND_PRINT((ndo, ", vlan_tag unknown (0x%04x)", vlan_tag >> 16)); + ND_PRINT(", vlan_tag unknown (0x%04x)", vlan_tag >> 16); } /* copy_stage */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, ", copy_stage %s", tok2str(bsn_mirror_copy_stage_str, "unknown (%u)", *cp))); - cp += 1; + ND_PRINT(", copy_stage %s", + tok2str(bsn_mirror_copy_stage_str, "unknown (%u)", GET_U_1(cp))); + OF_FWD(1); /* pad */ - ND_TCHECK2(*cp, 3); - cp += 3; + /* Always the last field, check bounds. */ + ND_TCHECK_3(cp); break; default: - ND_TCHECK2(*cp, len - 4); - cp += len - 4; + ND_TCHECK_LEN(cp, len); } - - return cp; + return; invalid: - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp0, len); - return cp0 + len; -trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } -static const u_char * +static void of10_vendor_action_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, const u_int len) + const u_char *cp, u_int len) { uint32_t vendor; - const u_char *(*decoder)(netdissect_options *, const u_char *, const u_char *, const u_int); + void (*decoder)(netdissect_options *, const u_char *, u_int); if (len < 4) goto invalid; /* vendor */ - ND_TCHECK2(*cp, 4); - vendor = EXTRACT_32BITS(cp); - cp += 4; - ND_PRINT((ndo, ", vendor 0x%08x (%s)", vendor, of_vendor_name(vendor))); + vendor = GET_BE_U_4(cp); + OF_FWD(4); + ND_PRINT(", vendor 0x%08x (%s)", vendor, of_vendor_name(vendor)); /* data */ decoder = vendor == OUI_BSN ? of10_bsn_actions_print : - of10_data_print; - return decoder(ndo, cp, ep, len - 4); + of_data_print; + decoder(ndo, cp, len); + return; invalid: /* skip the undersized data */ - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp, len); - return cp + len; -trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } -static const u_char * +/* [OF10] Section 5.5.4 */ +static void of10_vendor_message_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, const u_int len) + const u_char *cp, u_int len) { uint32_t vendor; - const u_char *(*decoder)(netdissect_options *, const u_char *, const u_char *, u_int); + void (*decoder)(netdissect_options *, const u_char *, u_int); - if (len < 4) - goto invalid; /* vendor */ - ND_TCHECK2(*cp, 4); - vendor = EXTRACT_32BITS(cp); - cp += 4; - ND_PRINT((ndo, ", vendor 0x%08x (%s)", vendor, of_vendor_name(vendor))); + vendor = GET_BE_U_4(cp); + OF_FWD(4); + ND_PRINT(", vendor 0x%08x (%s)", vendor, of_vendor_name(vendor)); /* data */ decoder = vendor == OUI_BSN ? of10_bsn_message_print : - of10_data_print; - return decoder(ndo, cp, ep, len - 4); - -invalid: /* skip the undersized data */ - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp, len); - return cp + len; -trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; + of_data_print; + decoder(ndo, cp, len); } /* Vendor ID is mandatory, data is optional. */ -static const u_char * +static void of10_vendor_data_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, const u_int len) + const u_char *cp, u_int len) { uint32_t vendor; if (len < 4) goto invalid; /* vendor */ - ND_TCHECK2(*cp, 4); - vendor = EXTRACT_32BITS(cp); - cp += 4; - ND_PRINT((ndo, ", vendor 0x%08x (%s)", vendor, of_vendor_name(vendor))); + vendor = GET_BE_U_4(cp); + OF_FWD(4); + ND_PRINT(", vendor 0x%08x (%s)", vendor, of_vendor_name(vendor)); /* data */ - return of10_data_print(ndo, cp, ep, len - 4); + of_data_print(ndo, cp, len); + return; invalid: /* skip the undersized data */ - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp, len); - return cp + len; -trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } -static const u_char * +static void of10_packet_data_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, const u_int len) + const u_char *cp, const u_int len) { if (len == 0) - return cp; + return; /* data */ - ND_PRINT((ndo, "\n\t data (%u octets)", len)); - if (ndo->ndo_vflag < 3) - return cp + len; - ND_TCHECK2(*cp, len); + ND_PRINT("\n\t data (%u octets)", len); + if (ndo->ndo_vflag < 3) { + ND_TCHECK_LEN(cp, len); + return; + } ndo->ndo_vflag -= 3; - ND_PRINT((ndo, ", frame decoding below\n")); - ether_print(ndo, cp, len, ndo->ndo_snapend - cp, NULL, NULL); + ND_PRINT(", frame decoding below\n"); + /* + * The encapsulated Ethernet frame is not necessarily the last + * data of this packet (i.e. there may be more OpenFlow messages + * after the current OFPT_PACKET_IN/OFPT_PACKET_OUT message, in + * which case the current (outer) packet's snapshot end is not + * what ether_print() needs to decode an Ethernet frame nested in + * the middle of a TCP payload. + */ + const u_char *snapend_save = ndo->ndo_snapend; + ndo->ndo_snapend = ND_MIN(cp + len, ndo->ndo_snapend); + ether_print(ndo, cp, len, ND_BYTES_AVAILABLE_AFTER(cp), NULL, NULL); + ndo->ndo_snapend = snapend_save; ndo->ndo_vflag += 3; - return cp + len; - -trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; } /* [OF10] Section 5.2.1 */ -static const u_char * -of10_phy_ports_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, u_int len) +static void +of10_phy_port_print(netdissect_options *ndo, + const u_char *cp) { - const u_char *cp0 = cp; - const u_int len0 = len; + uint32_t state; - while (len) { - if (len < OF_PHY_PORT_LEN) - goto invalid; - /* port_no */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, "\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); - cp += 2; - /* hw_addr */ - ND_TCHECK2(*cp, ETHER_ADDR_LEN); - ND_PRINT((ndo, ", hw_addr %s", etheraddr_string(ndo, cp))); - cp += ETHER_ADDR_LEN; - /* name */ - ND_TCHECK2(*cp, OFP_MAX_PORT_NAME_LEN); - ND_PRINT((ndo, ", name '")); - fn_print(ndo, cp, cp + OFP_MAX_PORT_NAME_LEN); - ND_PRINT((ndo, "'")); - cp += OFP_MAX_PORT_NAME_LEN; - - if (ndo->ndo_vflag < 2) { - ND_TCHECK2(*cp, 24); - cp += 24; - goto next_port; - } - /* config */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, "\n\t config 0x%08x", EXTRACT_32BITS(cp))); - of10_bitmap_print(ndo, ofppc_bm, EXTRACT_32BITS(cp), OFPPC_U); - cp += 4; - /* state */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, "\n\t state 0x%08x", EXTRACT_32BITS(cp))); - of10_bitmap_print(ndo, ofpps_bm, EXTRACT_32BITS(cp), OFPPS_U); - cp += 4; - /* curr */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, "\n\t curr 0x%08x", EXTRACT_32BITS(cp))); - of10_bitmap_print(ndo, ofppf_bm, EXTRACT_32BITS(cp), OFPPF_U); - cp += 4; - /* advertised */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, "\n\t advertised 0x%08x", EXTRACT_32BITS(cp))); - of10_bitmap_print(ndo, ofppf_bm, EXTRACT_32BITS(cp), OFPPF_U); - cp += 4; - /* supported */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, "\n\t supported 0x%08x", EXTRACT_32BITS(cp))); - of10_bitmap_print(ndo, ofppf_bm, EXTRACT_32BITS(cp), OFPPF_U); - cp += 4; - /* peer */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, "\n\t peer 0x%08x", EXTRACT_32BITS(cp))); - of10_bitmap_print(ndo, ofppf_bm, EXTRACT_32BITS(cp), OFPPF_U); - cp += 4; -next_port: - len -= OF_PHY_PORT_LEN; - } /* while */ - return cp; - -invalid: /* skip the undersized trailing data */ - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp0, len0); - return cp0 + len0; -trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; + /* port_no */ + ND_PRINT("\n\t port_no %s", + tok2str(ofpp_str, "%u", GET_BE_U_2(cp))); + cp += 2; + /* hw_addr */ + ND_PRINT(", hw_addr %s", GET_ETHERADDR_STRING(cp)); + cp += MAC_ADDR_LEN; + /* name */ + ND_PRINT(", name '"); + nd_printjnp(ndo, cp, OFP_MAX_PORT_NAME_LEN); + ND_PRINT("'"); + cp += OFP_MAX_PORT_NAME_LEN; + + if (ndo->ndo_vflag < 2) { + ND_TCHECK_LEN(cp, 24); + return; + } + /* config */ + ND_PRINT("\n\t config 0x%08x", GET_BE_U_4(cp)); + of_bitmap_print(ndo, ofppc_bm, GET_BE_U_4(cp), OFPPC_U); + cp += 4; + /* state */ + state = GET_BE_U_4(cp); + /* + * Decode the code point and the single bit separately, but + * format the result as a single sequence of comma-separated + * strings (see the comments at the OFPPS_ props). + */ + ND_PRINT("\n\t state 0x%08x (%s%s)%s", state, + tok2str(ofpps_stp_str, "", state & OFPPS_STP_MASK), + state & OFPPS_LINK_DOWN ? ", LINK_DOWN" : "", + state & OFPPS_U ? " (bogus)" : ""); + cp += 4; + /* curr */ + ND_PRINT("\n\t curr 0x%08x", GET_BE_U_4(cp)); + of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U); + cp += 4; + /* advertised */ + ND_PRINT("\n\t advertised 0x%08x", GET_BE_U_4(cp)); + of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U); + cp += 4; + /* supported */ + ND_PRINT("\n\t supported 0x%08x", GET_BE_U_4(cp)); + of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U); + cp += 4; + /* peer */ + ND_PRINT("\n\t peer 0x%08x", GET_BE_U_4(cp)); + of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U); } /* [OF10] Section 5.2.2 */ -static const u_char * +static void of10_queue_props_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, u_int len) + const u_char *cp, u_int len) { - const u_char *cp0 = cp; - const u_int len0 = len; - uint16_t property, plen, rate; - while (len) { + uint16_t property, plen; u_char plen_bogus = 0, skip = 0; - if (len < OF_QUEUE_PROP_HEADER_LEN) + if (len < OF_QUEUE_PROP_MINLEN) goto invalid; /* property */ - ND_TCHECK2(*cp, 2); - property = EXTRACT_16BITS(cp); - cp += 2; - ND_PRINT((ndo, "\n\t property %s", tok2str(ofpqt_str, "invalid (0x%04x)", property))); + property = GET_BE_U_2(cp); + OF_FWD(2); + ND_PRINT("\n\t property %s", tok2str(ofpqt_str, "invalid (0x%04x)", property)); /* len */ - ND_TCHECK2(*cp, 2); - plen = EXTRACT_16BITS(cp); - cp += 2; - ND_PRINT((ndo, ", len %u", plen)); - if (plen < OF_QUEUE_PROP_HEADER_LEN || plen > len) + plen = GET_BE_U_2(cp); + OF_FWD(2); + ND_PRINT(", len %u", plen); + if (plen < OF_QUEUE_PROP_MINLEN || plen > len + 4) goto invalid; /* pad */ - ND_TCHECK2(*cp, 4); - cp += 4; + /* Sometimes the last field, check bounds. */ + OF_CHK_FWD(4); /* property-specific constraints and decoding */ switch (property) { case OFPQT_NONE: - plen_bogus = plen != OF_QUEUE_PROP_HEADER_LEN; + plen_bogus = plen != OF_QUEUE_PROP_MINLEN; break; case OFPQT_MIN_RATE: - plen_bogus = plen != OF_QUEUE_PROP_MIN_RATE_LEN; + plen_bogus = plen != OF_QUEUE_PROP_MIN_RATE_FIXLEN; break; default: skip = 1; } if (plen_bogus) { - ND_PRINT((ndo, " (bogus)")); + ND_PRINT(" (bogus)"); skip = 1; } if (skip) { - ND_TCHECK2(*cp, plen - 4); - cp += plen - 4; - goto next_property; + /* + * plen >= OF_QUEUE_PROP_MINLEN + * cp is OF_QUEUE_PROP_MINLEN bytes in + */ + OF_CHK_FWD(plen - OF_QUEUE_PROP_MINLEN); + continue; } if (property == OFPQT_MIN_RATE) { /* the only case of property decoding */ /* rate */ - ND_TCHECK2(*cp, 2); - rate = EXTRACT_16BITS(cp); - cp += 2; + uint16_t rate = GET_BE_U_2(cp); + OF_FWD(2); if (rate > 1000) - ND_PRINT((ndo, ", rate disabled")); + ND_PRINT(", rate disabled"); else - ND_PRINT((ndo, ", rate %u.%u%%", rate / 10, rate % 10)); + ND_PRINT(", rate %u.%u%%", rate / 10, rate % 10); /* pad */ - ND_TCHECK2(*cp, 6); - cp += 6; + /* Sometimes the last field, check bounds. */ + OF_CHK_FWD(6); } -next_property: - len -= plen; } /* while */ - return cp; + return; invalid: /* skip the rest of queue properties */ - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp0, len0); - return cp0 + len0; -trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } /* ibid */ -static const u_char * +static void of10_queues_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, u_int len) + const u_char *cp, u_int len) { - const u_char *cp0 = cp; - const u_int len0 = len; - uint16_t desclen; - while (len) { - if (len < OF_PACKET_QUEUE_LEN) + uint16_t desclen; + + if (len < OF_PACKET_QUEUE_MINLEN) goto invalid; /* queue_id */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, "\n\t queue_id %u", EXTRACT_32BITS(cp))); - cp += 4; + ND_PRINT("\n\t queue_id %u", GET_BE_U_4(cp)); + OF_FWD(4); /* len */ - ND_TCHECK2(*cp, 2); - desclen = EXTRACT_16BITS(cp); - cp += 2; - ND_PRINT((ndo, ", len %u", desclen)); - if (desclen < OF_PACKET_QUEUE_LEN || desclen > len) + desclen = GET_BE_U_2(cp); + OF_FWD(2); + ND_PRINT(", len %u", desclen); + if (desclen < OF_PACKET_QUEUE_MINLEN || desclen > len + 6) goto invalid; /* pad */ - ND_TCHECK2(*cp, 2); - cp += 2; + /* Sometimes the last field, check bounds. */ + OF_CHK_FWD(2); /* properties */ - if (ndo->ndo_vflag < 2) { - ND_TCHECK2(*cp, desclen - OF_PACKET_QUEUE_LEN); - cp += desclen - OF_PACKET_QUEUE_LEN; - goto next_queue; - } - if (ep == (cp = of10_queue_props_print(ndo, cp, ep, desclen - OF_PACKET_QUEUE_LEN))) - return ep; /* end of snapshot */ -next_queue: - len -= desclen; + if (ndo->ndo_vflag >= 2) + of10_queue_props_print(ndo, cp, desclen - OF_PACKET_QUEUE_MINLEN); + else + ND_TCHECK_LEN(cp, desclen - OF_PACKET_QUEUE_MINLEN); + OF_FWD(desclen - OF_PACKET_QUEUE_MINLEN); } /* while */ - return cp; + return; invalid: /* skip the rest of queues */ - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp0, len0); - return cp0 + len0; -trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } /* [OF10] Section 5.2.3 */ -static const u_char * +static void of10_match_print(netdissect_options *ndo, - const char *pfx, const u_char *cp, const u_char *ep) + const char *pfx, const u_char *cp) { uint32_t wildcards; uint16_t dl_type; uint8_t nw_proto; - u_char nw_bits; + u_int nw_bits; const char *field_name; /* wildcards */ - ND_TCHECK2(*cp, 4); - wildcards = EXTRACT_32BITS(cp); + wildcards = GET_BE_U_4(cp); if (wildcards & OFPFW_U) - ND_PRINT((ndo, "%swildcards 0x%08x (bogus)", pfx, wildcards)); + ND_PRINT("%swildcards 0x%08x (bogus)", pfx, wildcards); cp += 4; /* in_port */ - ND_TCHECK2(*cp, 2); if (! (wildcards & OFPFW_IN_PORT)) - ND_PRINT((ndo, "%smatch in_port %s", pfx, tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); + ND_PRINT("%smatch in_port %s", pfx, + tok2str(ofpp_str, "%u", GET_BE_U_2(cp))); cp += 2; /* dl_src */ - ND_TCHECK2(*cp, ETHER_ADDR_LEN); if (! (wildcards & OFPFW_DL_SRC)) - ND_PRINT((ndo, "%smatch dl_src %s", pfx, etheraddr_string(ndo, cp))); - cp += ETHER_ADDR_LEN; + ND_PRINT("%smatch dl_src %s", pfx, GET_ETHERADDR_STRING(cp)); + cp += MAC_ADDR_LEN; /* dl_dst */ - ND_TCHECK2(*cp, ETHER_ADDR_LEN); if (! (wildcards & OFPFW_DL_DST)) - ND_PRINT((ndo, "%smatch dl_dst %s", pfx, etheraddr_string(ndo, cp))); - cp += ETHER_ADDR_LEN; + ND_PRINT("%smatch dl_dst %s", pfx, GET_ETHERADDR_STRING(cp)); + cp += MAC_ADDR_LEN; /* dl_vlan */ - ND_TCHECK2(*cp, 2); if (! (wildcards & OFPFW_DL_VLAN)) - ND_PRINT((ndo, "%smatch dl_vlan %s", pfx, vlan_str(EXTRACT_16BITS(cp)))); + ND_PRINT("%smatch dl_vlan %s", pfx, vlan_str(GET_BE_U_2(cp))); cp += 2; /* dl_vlan_pcp */ - ND_TCHECK2(*cp, 1); if (! (wildcards & OFPFW_DL_VLAN_PCP)) - ND_PRINT((ndo, "%smatch dl_vlan_pcp %s", pfx, pcp_str(*cp))); + ND_PRINT("%smatch dl_vlan_pcp %s", pfx, pcp_str(GET_U_1(cp))); cp += 1; /* pad1 */ - ND_TCHECK2(*cp, 1); cp += 1; /* dl_type */ - ND_TCHECK2(*cp, 2); - dl_type = EXTRACT_16BITS(cp); + dl_type = GET_BE_U_2(cp); cp += 2; if (! (wildcards & OFPFW_DL_TYPE)) - ND_PRINT((ndo, "%smatch dl_type 0x%04x", pfx, dl_type)); + ND_PRINT("%smatch dl_type 0x%04x", pfx, dl_type); /* nw_tos */ - ND_TCHECK2(*cp, 1); if (! (wildcards & OFPFW_NW_TOS)) - ND_PRINT((ndo, "%smatch nw_tos 0x%02x", pfx, *cp)); + ND_PRINT("%smatch nw_tos 0x%02x", pfx, GET_U_1(cp)); cp += 1; /* nw_proto */ - ND_TCHECK2(*cp, 1); - nw_proto = *cp; + nw_proto = GET_U_1(cp); cp += 1; if (! (wildcards & OFPFW_NW_PROTO)) { field_name = ! (wildcards & OFPFW_DL_TYPE) && dl_type == ETHERTYPE_ARP ? "arp_opcode" : "nw_proto"; - ND_PRINT((ndo, "%smatch %s %u", pfx, field_name, nw_proto)); + ND_PRINT("%smatch %s %u", pfx, field_name, nw_proto); } /* pad2 */ - ND_TCHECK2(*cp, 2); cp += 2; /* nw_src */ - ND_TCHECK2(*cp, 4); nw_bits = (wildcards & OFPFW_NW_SRC_MASK) >> OFPFW_NW_SRC_SHIFT; if (nw_bits < 32) - ND_PRINT((ndo, "%smatch nw_src %s/%u", pfx, ipaddr_string(ndo, cp), 32 - nw_bits)); + ND_PRINT("%smatch nw_src %s/%u", pfx, GET_IPADDR_STRING(cp), 32 - nw_bits); cp += 4; /* nw_dst */ - ND_TCHECK2(*cp, 4); nw_bits = (wildcards & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT; if (nw_bits < 32) - ND_PRINT((ndo, "%smatch nw_dst %s/%u", pfx, ipaddr_string(ndo, cp), 32 - nw_bits)); + ND_PRINT("%smatch nw_dst %s/%u", pfx, GET_IPADDR_STRING(cp), 32 - nw_bits); cp += 4; /* tp_src */ - ND_TCHECK2(*cp, 2); if (! (wildcards & OFPFW_TP_SRC)) { field_name = ! (wildcards & OFPFW_DL_TYPE) && dl_type == ETHERTYPE_IP && ! (wildcards & OFPFW_NW_PROTO) && nw_proto == IPPROTO_ICMP ? "icmp_type" : "tp_src"; - ND_PRINT((ndo, "%smatch %s %u", pfx, field_name, EXTRACT_16BITS(cp))); + ND_PRINT("%smatch %s %u", pfx, field_name, GET_BE_U_2(cp)); } cp += 2; /* tp_dst */ - ND_TCHECK2(*cp, 2); + /* The last unconditional check was at nw_proto, so have an "else" here. */ if (! (wildcards & OFPFW_TP_DST)) { field_name = ! (wildcards & OFPFW_DL_TYPE) && dl_type == ETHERTYPE_IP && ! (wildcards & OFPFW_NW_PROTO) && nw_proto == IPPROTO_ICMP ? "icmp_code" : "tp_dst"; - ND_PRINT((ndo, "%smatch %s %u", pfx, field_name, EXTRACT_16BITS(cp))); + ND_PRINT("%smatch %s %u", pfx, field_name, GET_BE_U_2(cp)); } - return cp + 2; - -trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; + else + ND_TCHECK_2(cp); } /* [OF10] Section 5.2.4 */ -static const u_char * +static void of10_actions_print(netdissect_options *ndo, - const char *pfx, const u_char *cp, const u_char *ep, - u_int len) + const char *pfx, const u_char *cp, u_int len) { - const u_char *cp0 = cp; - const u_int len0 = len; - uint16_t type, alen, output_port; - while (len) { + uint16_t type, alen, output_port; u_char alen_bogus = 0, skip = 0; - if (len < OF_ACTION_HEADER_LEN) + if (len < OF_ACTION_MINLEN) goto invalid; /* type */ - ND_TCHECK2(*cp, 2); - type = EXTRACT_16BITS(cp); - cp += 2; - ND_PRINT((ndo, "%saction type %s", pfx, tok2str(ofpat_str, "invalid (0x%04x)", type))); + type = GET_BE_U_2(cp); + OF_FWD(2); + ND_PRINT("%saction type %s", pfx, tok2str(ofpat_str, "invalid (0x%04x)", type)); /* length */ - ND_TCHECK2(*cp, 2); - alen = EXTRACT_16BITS(cp); - cp += 2; - ND_PRINT((ndo, ", len %u", alen)); + alen = GET_BE_U_2(cp); + OF_FWD(2); + ND_PRINT(", len %u", alen); + /* + * The 4-byte "pad" in the specification is not a field of the + * action header, but a placeholder to illustrate the 64-bit + * alignment requirement. Action type specific case blocks + * below fetch these 4 bytes. + */ + /* On action size underrun/overrun skip the rest of the action list. */ - if (alen < OF_ACTION_HEADER_LEN || alen > len) + if (alen < OF_ACTION_MINLEN || alen > len + 4) goto invalid; - /* On action size inappropriate for the given type or invalid type just skip - * the current action, as the basic length constraint has been met. */ + /* + * After validating the basic length constraint it will be safe + * to skip the current action if the action size is not valid + * for the type or the type is invalid. + */ switch (type) { case OFPAT_OUTPUT: case OFPAT_SET_VLAN_VID: @@ -1494,710 +1339,622 @@ of10_actions_print(netdissect_options *ndo, skip = 1; } if (alen_bogus) { - ND_PRINT((ndo, " (bogus)")); + ND_PRINT(" (bogus)"); skip = 1; } if (skip) { - ND_TCHECK2(*cp, alen - 4); - cp += alen - 4; - goto next_action; + /* + * alen >= OF_ACTION_MINLEN + * cp is 4 bytes in + */ + OF_CHK_FWD(alen - 4); + continue; } /* OK to decode the rest of the action structure */ switch (type) { case OFPAT_OUTPUT: /* port */ - ND_TCHECK2(*cp, 2); - output_port = EXTRACT_16BITS(cp); - cp += 2; - ND_PRINT((ndo, ", port %s", tok2str(ofpp_str, "%u", output_port))); + output_port = GET_BE_U_2(cp); + OF_FWD(2); + ND_PRINT(", port %s", tok2str(ofpp_str, "%u", output_port)); /* max_len */ - ND_TCHECK2(*cp, 2); if (output_port == OFPP_CONTROLLER) - ND_PRINT((ndo, ", max_len %u", EXTRACT_16BITS(cp))); - cp += 2; + ND_PRINT(", max_len %u", GET_BE_U_2(cp)); + else + ND_TCHECK_2(cp); + OF_FWD(2); break; case OFPAT_SET_VLAN_VID: /* vlan_vid */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, ", vlan_vid %s", vlan_str(EXTRACT_16BITS(cp)))); - cp += 2; + ND_PRINT(", vlan_vid %s", vlan_str(GET_BE_U_2(cp))); + OF_FWD(2); /* pad */ - ND_TCHECK2(*cp, 2); - cp += 2; + /* Sometimes the last field, check bounds. */ + OF_CHK_FWD(2); break; case OFPAT_SET_VLAN_PCP: /* vlan_pcp */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, ", vlan_pcp %s", pcp_str(*cp))); - cp += 1; + ND_PRINT(", vlan_pcp %s", pcp_str(GET_U_1(cp))); + OF_FWD(1); /* pad */ - ND_TCHECK2(*cp, 3); - cp += 3; + /* Sometimes the last field, check bounds. */ + OF_CHK_FWD(3); break; case OFPAT_SET_DL_SRC: case OFPAT_SET_DL_DST: /* dl_addr */ - ND_TCHECK2(*cp, ETHER_ADDR_LEN); - ND_PRINT((ndo, ", dl_addr %s", etheraddr_string(ndo, cp))); - cp += ETHER_ADDR_LEN; + ND_PRINT(", dl_addr %s", GET_ETHERADDR_STRING(cp)); + OF_FWD(MAC_ADDR_LEN); /* pad */ - ND_TCHECK2(*cp, 6); - cp += 6; + /* Sometimes the last field, check bounds. */ + OF_CHK_FWD(6); break; case OFPAT_SET_NW_SRC: case OFPAT_SET_NW_DST: /* nw_addr */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, ", nw_addr %s", ipaddr_string(ndo, cp))); - cp += 4; + ND_PRINT(", nw_addr %s", GET_IPADDR_STRING(cp)); + OF_FWD(4); break; case OFPAT_SET_NW_TOS: /* nw_tos */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, ", nw_tos 0x%02x", *cp)); - cp += 1; + ND_PRINT(", nw_tos 0x%02x", GET_U_1(cp)); + OF_FWD(1); /* pad */ - ND_TCHECK2(*cp, 3); - cp += 3; + /* Sometimes the last field, check bounds. */ + OF_CHK_FWD(3); break; case OFPAT_SET_TP_SRC: case OFPAT_SET_TP_DST: /* nw_tos */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, ", tp_port %u", EXTRACT_16BITS(cp))); - cp += 2; + ND_PRINT(", tp_port %u", GET_BE_U_2(cp)); + OF_FWD(2); /* pad */ - ND_TCHECK2(*cp, 2); - cp += 2; + /* Sometimes the last field, check bounds. */ + OF_CHK_FWD(2); break; case OFPAT_ENQUEUE: /* port */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, ", port %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); - cp += 2; + ND_PRINT(", port %s", + tok2str(ofpp_str, "%u", GET_BE_U_2(cp))); + OF_FWD(2); /* pad */ - ND_TCHECK2(*cp, 6); - cp += 6; + OF_FWD(6); /* queue_id */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, ", queue_id %s", tok2str(ofpq_str, "%u", EXTRACT_32BITS(cp)))); - cp += 4; + ND_PRINT(", queue_id %s", + tok2str(ofpq_str, "%u", GET_BE_U_4(cp))); + OF_FWD(4); break; case OFPAT_VENDOR: - if (ep == (cp = of10_vendor_action_print(ndo, cp, ep, alen - 4))) - return ep; /* end of snapshot */ + of10_vendor_action_print(ndo, cp, alen - 4); + OF_FWD(alen - 4); break; case OFPAT_STRIP_VLAN: /* pad */ - ND_TCHECK2(*cp, 4); - cp += 4; + /* Sometimes the last field, check bounds. */ + OF_CHK_FWD(4); break; } /* switch */ -next_action: - len -= alen; } /* while */ - return cp; + return; invalid: /* skip the rest of actions */ - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp0, len0); - return cp0 + len0; -trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } /* [OF10] Section 5.3.1 */ -static const u_char * +static void of10_features_reply_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, const u_int len) + const u_char *cp, u_int len) { /* datapath_id */ - ND_TCHECK2(*cp, 8); - ND_PRINT((ndo, "\n\t dpid 0x%016" PRIx64, EXTRACT_64BITS(cp))); - cp += 8; + ND_PRINT("\n\t dpid 0x%016" PRIx64, GET_BE_U_8(cp)); + OF_FWD(8); /* n_buffers */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, ", n_buffers %u", EXTRACT_32BITS(cp))); - cp += 4; + ND_PRINT(", n_buffers %u", GET_BE_U_4(cp)); + OF_FWD(4); /* n_tables */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, ", n_tables %u", *cp)); - cp += 1; + ND_PRINT(", n_tables %u", GET_U_1(cp)); + OF_FWD(1); /* pad */ - ND_TCHECK2(*cp, 3); - cp += 3; + OF_FWD(3); /* capabilities */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, "\n\t capabilities 0x%08x", EXTRACT_32BITS(cp))); - of10_bitmap_print(ndo, ofp_capabilities_bm, EXTRACT_32BITS(cp), OFPCAP_U); - cp += 4; + ND_PRINT("\n\t capabilities 0x%08x", GET_BE_U_4(cp)); + of_bitmap_print(ndo, ofp_capabilities_bm, GET_BE_U_4(cp), OFPCAP_U); + OF_FWD(4); /* actions */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, "\n\t actions 0x%08x", EXTRACT_32BITS(cp))); - of10_bitmap_print(ndo, ofpat_bm, EXTRACT_32BITS(cp), OFPAT_U); - cp += 4; + ND_PRINT("\n\t actions 0x%08x", GET_BE_U_4(cp)); + of_bitmap_print(ndo, ofpat_bm, GET_BE_U_4(cp), OFPAT_U); + OF_FWD(4); /* ports */ - return of10_phy_ports_print(ndo, cp, ep, len - OF_SWITCH_FEATURES_LEN); + while (len) { + if (len < OF_PHY_PORT_FIXLEN) + goto invalid; + of10_phy_port_print(ndo, cp); + OF_FWD(OF_PHY_PORT_FIXLEN); + } + return; -trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; +invalid: /* skip the undersized trailing data */ + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); +} + +/* [OF10] Section 5.3.2 */ +static void +of10_switch_config_msg_print(netdissect_options *ndo, + const u_char *cp, u_int len _U_) +{ + /* flags */ + ND_PRINT("\n\t flags %s", + tok2str(ofp_config_str, "invalid (0x%04x)", GET_BE_U_2(cp))); + cp += 2; + /* miss_send_len */ + ND_PRINT(", miss_send_len %u", GET_BE_U_2(cp)); } /* [OF10] Section 5.3.3 */ -static const u_char * +static void of10_flow_mod_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, const u_int len) + const u_char *cp, u_int len) { uint16_t command; /* match */ - if (ep == (cp = of10_match_print(ndo, "\n\t ", cp, ep))) - return ep; /* end of snapshot */ + of10_match_print(ndo, "\n\t ", cp); + OF_FWD(OF_MATCH_FIXLEN); /* cookie */ - ND_TCHECK2(*cp, 8); - ND_PRINT((ndo, "\n\t cookie 0x%016" PRIx64, EXTRACT_64BITS(cp))); - cp += 8; + ND_PRINT("\n\t cookie 0x%016" PRIx64, GET_BE_U_8(cp)); + OF_FWD(8); /* command */ - ND_TCHECK2(*cp, 2); - command = EXTRACT_16BITS(cp); - ND_PRINT((ndo, ", command %s", tok2str(ofpfc_str, "invalid (0x%04x)", command))); - cp += 2; + command = GET_BE_U_2(cp); + ND_PRINT(", command %s", tok2str(ofpfc_str, "invalid (0x%04x)", command)); + OF_FWD(2); /* idle_timeout */ - ND_TCHECK2(*cp, 2); - if (EXTRACT_16BITS(cp)) - ND_PRINT((ndo, ", idle_timeout %u", EXTRACT_16BITS(cp))); - cp += 2; + if (GET_BE_U_2(cp)) + ND_PRINT(", idle_timeout %u", GET_BE_U_2(cp)); + OF_FWD(2); /* hard_timeout */ - ND_TCHECK2(*cp, 2); - if (EXTRACT_16BITS(cp)) - ND_PRINT((ndo, ", hard_timeout %u", EXTRACT_16BITS(cp))); - cp += 2; + if (GET_BE_U_2(cp)) + ND_PRINT(", hard_timeout %u", GET_BE_U_2(cp)); + OF_FWD(2); /* priority */ - ND_TCHECK2(*cp, 2); - if (EXTRACT_16BITS(cp)) - ND_PRINT((ndo, ", priority %u", EXTRACT_16BITS(cp))); - cp += 2; + if (GET_BE_U_2(cp)) + ND_PRINT(", priority %u", GET_BE_U_2(cp)); + OF_FWD(2); /* buffer_id */ - ND_TCHECK2(*cp, 4); if (command == OFPFC_ADD || command == OFPFC_MODIFY || command == OFPFC_MODIFY_STRICT) - ND_PRINT((ndo, ", buffer_id %s", tok2str(bufferid_str, "0x%08x", EXTRACT_32BITS(cp)))); - cp += 4; + ND_PRINT(", buffer_id %s", + tok2str(bufferid_str, "0x%08x", GET_BE_U_4(cp))); + OF_FWD(4); /* out_port */ - ND_TCHECK2(*cp, 2); if (command == OFPFC_DELETE || command == OFPFC_DELETE_STRICT) - ND_PRINT((ndo, ", out_port %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); - cp += 2; + ND_PRINT(", out_port %s", + tok2str(ofpp_str, "%u", GET_BE_U_2(cp))); + OF_FWD(2); /* flags */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, ", flags 0x%04x", EXTRACT_16BITS(cp))); - of10_bitmap_print(ndo, ofpff_bm, EXTRACT_16BITS(cp), OFPFF_U); - cp += 2; + ND_PRINT(", flags 0x%04x", GET_BE_U_2(cp)); + of_bitmap_print(ndo, ofpff_bm, GET_BE_U_2(cp), OFPFF_U); + OF_FWD(2); /* actions */ - return of10_actions_print(ndo, "\n\t ", cp, ep, len - OF_FLOW_MOD_LEN); - -trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; + of10_actions_print(ndo, "\n\t ", cp, len); } /* ibid */ -static const u_char * +static void of10_port_mod_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep) + const u_char *cp, u_int len _U_) { /* port_no */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, "\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); + ND_PRINT("\n\t port_no %s", tok2str(ofpp_str, "%u", GET_BE_U_2(cp))); cp += 2; /* hw_addr */ - ND_TCHECK2(*cp, ETHER_ADDR_LEN); - ND_PRINT((ndo, ", hw_addr %s", etheraddr_string(ndo, cp))); - cp += ETHER_ADDR_LEN; + ND_PRINT(", hw_addr %s", GET_ETHERADDR_STRING(cp)); + cp += MAC_ADDR_LEN; /* config */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, "\n\t config 0x%08x", EXTRACT_32BITS(cp))); - of10_bitmap_print(ndo, ofppc_bm, EXTRACT_32BITS(cp), OFPPC_U); + ND_PRINT("\n\t config 0x%08x", GET_BE_U_4(cp)); + of_bitmap_print(ndo, ofppc_bm, GET_BE_U_4(cp), OFPPC_U); cp += 4; /* mask */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, "\n\t mask 0x%08x", EXTRACT_32BITS(cp))); - of10_bitmap_print(ndo, ofppc_bm, EXTRACT_32BITS(cp), OFPPC_U); + ND_PRINT("\n\t mask 0x%08x", GET_BE_U_4(cp)); + of_bitmap_print(ndo, ofppc_bm, GET_BE_U_4(cp), OFPPC_U); cp += 4; /* advertise */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, "\n\t advertise 0x%08x", EXTRACT_32BITS(cp))); - of10_bitmap_print(ndo, ofppf_bm, EXTRACT_32BITS(cp), OFPPF_U); + ND_PRINT("\n\t advertise 0x%08x", GET_BE_U_4(cp)); + of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U); cp += 4; /* pad */ - ND_TCHECK2(*cp, 4); - return cp + 4; + /* Always the last field, check bounds. */ + ND_TCHECK_4(cp); +} -trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; +/* [OF10] Section 5.3.4 */ +static void +of10_queue_get_config_request_print(netdissect_options *ndo, + const u_char *cp, u_int len _U_) +{ + /* port */ + ND_PRINT("\n\t port %s", tok2str(ofpp_str, "%u", GET_BE_U_2(cp))); + cp += 2; + /* pad */ + /* Always the last field, check bounds. */ + ND_TCHECK_2(cp); +} + +/* ibid */ +static void +of10_queue_get_config_reply_print(netdissect_options *ndo, + const u_char *cp, u_int len) +{ + /* port */ + ND_PRINT("\n\t port %s", tok2str(ofpp_str, "%u", GET_BE_U_2(cp))); + OF_FWD(2); + /* pad */ + /* Sometimes the last field, check bounds. */ + OF_CHK_FWD(6); + /* queues */ + of10_queues_print(ndo, cp, len); } /* [OF10] Section 5.3.5 */ -static const u_char * +static void of10_stats_request_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, u_int len) + const u_char *cp, u_int len) { - const u_char *cp0 = cp; - const u_int len0 = len; uint16_t type; /* type */ - ND_TCHECK2(*cp, 2); - type = EXTRACT_16BITS(cp); - cp += 2; - ND_PRINT((ndo, "\n\t type %s", tok2str(ofpst_str, "invalid (0x%04x)", type))); + type = GET_BE_U_2(cp); + OF_FWD(2); + ND_PRINT("\n\t type %s", tok2str(ofpst_str, "invalid (0x%04x)", type)); /* flags */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, ", flags 0x%04x", EXTRACT_16BITS(cp))); - if (EXTRACT_16BITS(cp)) - ND_PRINT((ndo, " (bogus)")); - cp += 2; + ND_PRINT(", flags 0x%04x", GET_BE_U_2(cp)); + if (GET_BE_U_2(cp)) + ND_PRINT(" (bogus)"); + OF_FWD(2); /* type-specific body of one of fixed lengths */ - len -= OF_STATS_REQUEST_LEN; switch(type) { case OFPST_DESC: case OFPST_TABLE: if (len) goto invalid; - return cp; + return; case OFPST_FLOW: case OFPST_AGGREGATE: - if (len != OF_FLOW_STATS_REQUEST_LEN) + if (len != OF_FLOW_STATS_REQUEST_FIXLEN) goto invalid; /* match */ - if (ep == (cp = of10_match_print(ndo, "\n\t ", cp, ep))) - return ep; /* end of snapshot */ + of10_match_print(ndo, "\n\t ", cp); + OF_FWD(OF_MATCH_FIXLEN); /* table_id */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, "\n\t table_id %s", tok2str(tableid_str, "%u", *cp))); - cp += 1; + ND_PRINT("\n\t table_id %s", + tok2str(tableid_str, "%u", GET_U_1(cp))); + OF_FWD(1); /* pad */ - ND_TCHECK2(*cp, 1); - cp += 1; + OF_FWD(1); /* out_port */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, ", out_port %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); - return cp + 2; + ND_PRINT(", out_port %s", + tok2str(ofpp_str, "%u", GET_BE_U_2(cp))); + return; case OFPST_PORT: - if (len != OF_PORT_STATS_REQUEST_LEN) + if (len != OF_PORT_STATS_REQUEST_FIXLEN) goto invalid; /* port_no */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, "\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); - cp += 2; + ND_PRINT("\n\t port_no %s", + tok2str(ofpp_str, "%u", GET_BE_U_2(cp))); + OF_FWD(2); /* pad */ - ND_TCHECK2(*cp, 6); - return cp + 6; + /* Always the last field, check bounds. */ + OF_CHK_FWD(6); + return; case OFPST_QUEUE: - if (len != OF_QUEUE_STATS_REQUEST_LEN) + if (len != OF_QUEUE_STATS_REQUEST_FIXLEN) goto invalid; /* port_no */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, "\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); - cp += 2; + ND_PRINT("\n\t port_no %s", + tok2str(ofpp_str, "%u", GET_BE_U_2(cp))); + OF_FWD(2); /* pad */ - ND_TCHECK2(*cp, 2); - cp += 2; + OF_FWD(2); /* queue_id */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, ", queue_id %s", tok2str(ofpq_str, "%u", EXTRACT_32BITS(cp)))); - return cp + 4; + ND_PRINT(", queue_id %s", + tok2str(ofpq_str, "%u", GET_BE_U_4(cp))); + return; case OFPST_VENDOR: - return of10_vendor_data_print(ndo, cp, ep, len); + of10_vendor_data_print(ndo, cp, len); + return; } - return cp; + return; invalid: /* skip the message body */ - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp0, len0); - return cp0 + len0; -trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } /* ibid */ -static const u_char * +static void of10_desc_stats_reply_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, const u_int len) + const u_char *cp, u_int len) { - if (len != OF_DESC_STATS_LEN) + if (len != OF_DESC_STATS_REPLY_FIXLEN) goto invalid; /* mfr_desc */ - ND_TCHECK2(*cp, DESC_STR_LEN); - ND_PRINT((ndo, "\n\t mfr_desc '")); - fn_print(ndo, cp, cp + DESC_STR_LEN); - ND_PRINT((ndo, "'")); - cp += DESC_STR_LEN; + ND_PRINT("\n\t mfr_desc '"); + nd_printjnp(ndo, cp, DESC_STR_LEN); + ND_PRINT("'"); + OF_FWD(DESC_STR_LEN); /* hw_desc */ - ND_TCHECK2(*cp, DESC_STR_LEN); - ND_PRINT((ndo, "\n\t hw_desc '")); - fn_print(ndo, cp, cp + DESC_STR_LEN); - ND_PRINT((ndo, "'")); - cp += DESC_STR_LEN; + ND_PRINT("\n\t hw_desc '"); + nd_printjnp(ndo, cp, DESC_STR_LEN); + ND_PRINT("'"); + OF_FWD(DESC_STR_LEN); /* sw_desc */ - ND_TCHECK2(*cp, DESC_STR_LEN); - ND_PRINT((ndo, "\n\t sw_desc '")); - fn_print(ndo, cp, cp + DESC_STR_LEN); - ND_PRINT((ndo, "'")); - cp += DESC_STR_LEN; + ND_PRINT("\n\t sw_desc '"); + nd_printjnp(ndo, cp, DESC_STR_LEN); + ND_PRINT("'"); + OF_FWD(DESC_STR_LEN); /* serial_num */ - ND_TCHECK2(*cp, SERIAL_NUM_LEN); - ND_PRINT((ndo, "\n\t serial_num '")); - fn_print(ndo, cp, cp + SERIAL_NUM_LEN); - ND_PRINT((ndo, "'")); - cp += SERIAL_NUM_LEN; + ND_PRINT("\n\t serial_num '"); + nd_printjnp(ndo, cp, SERIAL_NUM_LEN); + ND_PRINT("'"); + OF_FWD(SERIAL_NUM_LEN); /* dp_desc */ - ND_TCHECK2(*cp, DESC_STR_LEN); - ND_PRINT((ndo, "\n\t dp_desc '")); - fn_print(ndo, cp, cp + DESC_STR_LEN); - ND_PRINT((ndo, "'")); - return cp + DESC_STR_LEN; + ND_PRINT("\n\t dp_desc '"); + nd_printjnp(ndo, cp, DESC_STR_LEN); + ND_PRINT("'"); + return; invalid: /* skip the message body */ - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp, len); - return cp + len; -trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } /* ibid */ -static const u_char * +static void of10_flow_stats_reply_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, u_int len) + const u_char *cp, u_int len) { - const u_char *cp0 = cp; - const u_int len0 = len; - uint16_t entry_len; - while (len) { - if (len < OF_FLOW_STATS_LEN) + uint16_t entry_len; + + if (len < OF_FLOW_STATS_REPLY_MINLEN) goto invalid; /* length */ - ND_TCHECK2(*cp, 2); - entry_len = EXTRACT_16BITS(cp); - ND_PRINT((ndo, "\n\t length %u", entry_len)); - if (entry_len < OF_FLOW_STATS_LEN || entry_len > len) + entry_len = GET_BE_U_2(cp); + ND_PRINT("\n\t length %u", entry_len); + if (entry_len < OF_FLOW_STATS_REPLY_MINLEN || entry_len > len) goto invalid; - cp += 2; + OF_FWD(2); /* table_id */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, ", table_id %s", tok2str(tableid_str, "%u", *cp))); - cp += 1; + ND_PRINT(", table_id %s", + tok2str(tableid_str, "%u", GET_U_1(cp))); + OF_FWD(1); /* pad */ - ND_TCHECK2(*cp, 1); - cp += 1; + OF_FWD(1); /* match */ - if (ep == (cp = of10_match_print(ndo, "\n\t ", cp, ep))) - return ep; /* end of snapshot */ + of10_match_print(ndo, "\n\t ", cp); + OF_FWD(OF_MATCH_FIXLEN); /* duration_sec */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, "\n\t duration_sec %u", EXTRACT_32BITS(cp))); - cp += 4; + ND_PRINT("\n\t duration_sec %u", GET_BE_U_4(cp)); + OF_FWD(4); /* duration_nsec */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, ", duration_nsec %u", EXTRACT_32BITS(cp))); - cp += 4; + ND_PRINT(", duration_nsec %u", GET_BE_U_4(cp)); + OF_FWD(4); /* priority */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, ", priority %u", EXTRACT_16BITS(cp))); - cp += 2; + ND_PRINT(", priority %u", GET_BE_U_2(cp)); + OF_FWD(2); /* idle_timeout */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, ", idle_timeout %u", EXTRACT_16BITS(cp))); - cp += 2; + ND_PRINT(", idle_timeout %u", GET_BE_U_2(cp)); + OF_FWD(2); /* hard_timeout */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, ", hard_timeout %u", EXTRACT_16BITS(cp))); - cp += 2; + ND_PRINT(", hard_timeout %u", GET_BE_U_2(cp)); + OF_FWD(2); /* pad2 */ - ND_TCHECK2(*cp, 6); - cp += 6; + OF_FWD(6); /* cookie */ - ND_TCHECK2(*cp, 8); - ND_PRINT((ndo, ", cookie 0x%016" PRIx64, EXTRACT_64BITS(cp))); - cp += 8; + ND_PRINT(", cookie 0x%016" PRIx64, GET_BE_U_8(cp)); + OF_FWD(8); /* packet_count */ - ND_TCHECK2(*cp, 8); - ND_PRINT((ndo, ", packet_count %" PRIu64, EXTRACT_64BITS(cp))); - cp += 8; + ND_PRINT(", packet_count %" PRIu64, GET_BE_U_8(cp)); + OF_FWD(8); /* byte_count */ - ND_TCHECK2(*cp, 8); - ND_PRINT((ndo, ", byte_count %" PRIu64, EXTRACT_64BITS(cp))); - cp += 8; + ND_PRINT(", byte_count %" PRIu64, GET_BE_U_8(cp)); + OF_FWD(8); /* actions */ - if (ep == (cp = of10_actions_print(ndo, "\n\t ", cp, ep, entry_len - OF_FLOW_STATS_LEN))) - return ep; /* end of snapshot */ - - len -= entry_len; + of10_actions_print(ndo, "\n\t ", cp, entry_len - OF_FLOW_STATS_REPLY_MINLEN); + OF_FWD(entry_len - OF_FLOW_STATS_REPLY_MINLEN); } /* while */ - return cp; + return; invalid: /* skip the rest of flow statistics entries */ - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp0, len0); - return cp0 + len0; -trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } /* ibid */ -static const u_char * +static void of10_aggregate_stats_reply_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, - const u_int len) + const u_char *cp, u_int len) { - if (len != OF_AGGREGATE_STATS_REPLY_LEN) + if (len != OF_AGGREGATE_STATS_REPLY_FIXLEN) goto invalid; /* packet_count */ - ND_TCHECK2(*cp, 8); - ND_PRINT((ndo, "\n\t packet_count %" PRIu64, EXTRACT_64BITS(cp))); - cp += 8; + ND_PRINT("\n\t packet_count %" PRIu64, GET_BE_U_8(cp)); + OF_FWD(8); /* byte_count */ - ND_TCHECK2(*cp, 8); - ND_PRINT((ndo, ", byte_count %" PRIu64, EXTRACT_64BITS(cp))); - cp += 8; + ND_PRINT(", byte_count %" PRIu64, GET_BE_U_8(cp)); + OF_FWD(8); /* flow_count */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, ", flow_count %u", EXTRACT_32BITS(cp))); - cp += 4; + ND_PRINT(", flow_count %u", GET_BE_U_4(cp)); + OF_FWD(4); /* pad */ - ND_TCHECK2(*cp, 4); - return cp + 4; + /* Always the last field, check bounds. */ + ND_TCHECK_4(cp); + return; invalid: /* skip the message body */ - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp, len); - return cp + len; -trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } /* ibid */ -static const u_char * +static void of10_table_stats_reply_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, u_int len) + const u_char *cp, u_int len) { - const u_char *cp0 = cp; - const u_int len0 = len; - while (len) { - if (len < OF_TABLE_STATS_LEN) + if (len < OF_TABLE_STATS_REPLY_FIXLEN) goto invalid; /* table_id */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, "\n\t table_id %s", tok2str(tableid_str, "%u", *cp))); - cp += 1; + ND_PRINT("\n\t table_id %s", + tok2str(tableid_str, "%u", GET_U_1(cp))); + OF_FWD(1); /* pad */ - ND_TCHECK2(*cp, 3); - cp += 3; + OF_FWD(3); /* name */ - ND_TCHECK2(*cp, OFP_MAX_TABLE_NAME_LEN); - ND_PRINT((ndo, ", name '")); - fn_print(ndo, cp, cp + OFP_MAX_TABLE_NAME_LEN); - ND_PRINT((ndo, "'")); - cp += OFP_MAX_TABLE_NAME_LEN; + ND_PRINT(", name '"); + nd_printjnp(ndo, cp, OFP_MAX_TABLE_NAME_LEN); + ND_PRINT("'"); + OF_FWD(OFP_MAX_TABLE_NAME_LEN); /* wildcards */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, "\n\t wildcards 0x%08x", EXTRACT_32BITS(cp))); - of10_bitmap_print(ndo, ofpfw_bm, EXTRACT_32BITS(cp), OFPFW_U); - cp += 4; + ND_PRINT("\n\t wildcards 0x%08x", GET_BE_U_4(cp)); + of_bitmap_print(ndo, ofpfw_bm, GET_BE_U_4(cp), OFPFW_U); + OF_FWD(4); /* max_entries */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, "\n\t max_entries %u", EXTRACT_32BITS(cp))); - cp += 4; + ND_PRINT("\n\t max_entries %u", GET_BE_U_4(cp)); + OF_FWD(4); /* active_count */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, ", active_count %u", EXTRACT_32BITS(cp))); - cp += 4; + ND_PRINT(", active_count %u", GET_BE_U_4(cp)); + OF_FWD(4); /* lookup_count */ - ND_TCHECK2(*cp, 8); - ND_PRINT((ndo, ", lookup_count %" PRIu64, EXTRACT_64BITS(cp))); - cp += 8; + ND_PRINT(", lookup_count %" PRIu64, GET_BE_U_8(cp)); + OF_FWD(8); /* matched_count */ - ND_TCHECK2(*cp, 8); - ND_PRINT((ndo, ", matched_count %" PRIu64, EXTRACT_64BITS(cp))); - cp += 8; - - len -= OF_TABLE_STATS_LEN; + ND_PRINT(", matched_count %" PRIu64, GET_BE_U_8(cp)); + OF_FWD(8); } /* while */ - return cp; + return; invalid: /* skip the undersized trailing data */ - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp0, len0); - return cp0 + len0; -trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } /* ibid */ -static const u_char * +static void of10_port_stats_reply_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, u_int len) + const u_char *cp, u_int len) { - const u_char *cp0 = cp; - const u_int len0 = len; - while (len) { - if (len < OF_PORT_STATS_LEN) + if (len < OF_PORT_STATS_REPLY_FIXLEN) goto invalid; /* port_no */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, "\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); - cp += 2; + ND_PRINT("\n\t port_no %s", + tok2str(ofpp_str, "%u", GET_BE_U_2(cp))); + OF_FWD(2); if (ndo->ndo_vflag < 2) { - ND_TCHECK2(*cp, OF_PORT_STATS_LEN - 2); - cp += OF_PORT_STATS_LEN - 2; - goto next_port; + OF_CHK_FWD(OF_PORT_STATS_REPLY_FIXLEN - 2); + continue; } /* pad */ - ND_TCHECK2(*cp, 6); - cp += 6; + OF_FWD(6); /* rx_packets */ - ND_TCHECK2(*cp, 8); - ND_PRINT((ndo, ", rx_packets %" PRIu64, EXTRACT_64BITS(cp))); - cp += 8; + ND_PRINT(", rx_packets %" PRIu64, GET_BE_U_8(cp)); + OF_FWD(8); /* tx_packets */ - ND_TCHECK2(*cp, 8); - ND_PRINT((ndo, ", tx_packets %" PRIu64, EXTRACT_64BITS(cp))); - cp += 8; + ND_PRINT(", tx_packets %" PRIu64, GET_BE_U_8(cp)); + OF_FWD(8); /* rx_bytes */ - ND_TCHECK2(*cp, 8); - ND_PRINT((ndo, ", rx_bytes %" PRIu64, EXTRACT_64BITS(cp))); - cp += 8; + ND_PRINT(", rx_bytes %" PRIu64, GET_BE_U_8(cp)); + OF_FWD(8); /* tx_bytes */ - ND_TCHECK2(*cp, 8); - ND_PRINT((ndo, ", tx_bytes %" PRIu64, EXTRACT_64BITS(cp))); - cp += 8; + ND_PRINT(", tx_bytes %" PRIu64, GET_BE_U_8(cp)); + OF_FWD(8); /* rx_dropped */ - ND_TCHECK2(*cp, 8); - ND_PRINT((ndo, ", rx_dropped %" PRIu64, EXTRACT_64BITS(cp))); - cp += 8; + ND_PRINT(", rx_dropped %" PRIu64, GET_BE_U_8(cp)); + OF_FWD(8); /* tx_dropped */ - ND_TCHECK2(*cp, 8); - ND_PRINT((ndo, ", tx_dropped %" PRIu64, EXTRACT_64BITS(cp))); - cp += 8; + ND_PRINT(", tx_dropped %" PRIu64, GET_BE_U_8(cp)); + OF_FWD(8); /* rx_errors */ - ND_TCHECK2(*cp, 8); - ND_PRINT((ndo, ", rx_errors %" PRIu64, EXTRACT_64BITS(cp))); - cp += 8; + ND_PRINT(", rx_errors %" PRIu64, GET_BE_U_8(cp)); + OF_FWD(8); /* tx_errors */ - ND_TCHECK2(*cp, 8); - ND_PRINT((ndo, ", tx_errors %" PRIu64, EXTRACT_64BITS(cp))); - cp += 8; + ND_PRINT(", tx_errors %" PRIu64, GET_BE_U_8(cp)); + OF_FWD(8); /* rx_frame_err */ - ND_TCHECK2(*cp, 8); - ND_PRINT((ndo, ", rx_frame_err %" PRIu64, EXTRACT_64BITS(cp))); - cp += 8; + ND_PRINT(", rx_frame_err %" PRIu64, GET_BE_U_8(cp)); + OF_FWD(8); /* rx_over_err */ - ND_TCHECK2(*cp, 8); - ND_PRINT((ndo, ", rx_over_err %" PRIu64, EXTRACT_64BITS(cp))); - cp += 8; + ND_PRINT(", rx_over_err %" PRIu64, GET_BE_U_8(cp)); + OF_FWD(8); /* rx_crc_err */ - ND_TCHECK2(*cp, 8); - ND_PRINT((ndo, ", rx_crc_err %" PRIu64, EXTRACT_64BITS(cp))); - cp += 8; + ND_PRINT(", rx_crc_err %" PRIu64, GET_BE_U_8(cp)); + OF_FWD(8); /* collisions */ - ND_TCHECK2(*cp, 8); - ND_PRINT((ndo, ", collisions %" PRIu64, EXTRACT_64BITS(cp))); - cp += 8; -next_port: - len -= OF_PORT_STATS_LEN; + ND_PRINT(", collisions %" PRIu64, GET_BE_U_8(cp)); + OF_FWD(8); } /* while */ - return cp; + return; invalid: /* skip the undersized trailing data */ - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp0, len0); - return cp0 + len0; -trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } /* ibid */ -static const u_char * +static void of10_queue_stats_reply_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, u_int len) + const u_char *cp, u_int len) { - const u_char *cp0 = cp; - const u_int len0 = len; - while (len) { - if (len < OF_QUEUE_STATS_LEN) + if (len < OF_QUEUE_STATS_REPLY_FIXLEN) goto invalid; /* port_no */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, "\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); - cp += 2; + ND_PRINT("\n\t port_no %s", + tok2str(ofpp_str, "%u", GET_BE_U_2(cp))); + OF_FWD(2); /* pad */ - ND_TCHECK2(*cp, 2); - cp += 2; + OF_FWD(2); /* queue_id */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, ", queue_id %u", EXTRACT_32BITS(cp))); - cp += 4; + ND_PRINT(", queue_id %u", GET_BE_U_4(cp)); + OF_FWD(4); /* tx_bytes */ - ND_TCHECK2(*cp, 8); - ND_PRINT((ndo, ", tx_bytes %" PRIu64, EXTRACT_64BITS(cp))); - cp += 8; + ND_PRINT(", tx_bytes %" PRIu64, GET_BE_U_8(cp)); + OF_FWD(8); /* tx_packets */ - ND_TCHECK2(*cp, 8); - ND_PRINT((ndo, ", tx_packets %" PRIu64, EXTRACT_64BITS(cp))); - cp += 8; + ND_PRINT(", tx_packets %" PRIu64, GET_BE_U_8(cp)); + OF_FWD(8); /* tx_errors */ - ND_TCHECK2(*cp, 8); - ND_PRINT((ndo, ", tx_errors %" PRIu64, EXTRACT_64BITS(cp))); - cp += 8; - - len -= OF_QUEUE_STATS_LEN; + ND_PRINT(", tx_errors %" PRIu64, GET_BE_U_8(cp)); + OF_FWD(8); } /* while */ - return cp; + return; invalid: /* skip the undersized trailing data */ - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp0, len0); - return cp0 + len0; -trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } /* ibid */ -static const u_char * +static void of10_stats_reply_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, const u_int len) + const u_char *cp, u_int len) { - const u_char *cp0 = cp; uint16_t type; /* type */ - ND_TCHECK2(*cp, 2); - type = EXTRACT_16BITS(cp); - ND_PRINT((ndo, "\n\t type %s", tok2str(ofpst_str, "invalid (0x%04x)", type))); - cp += 2; + type = GET_BE_U_2(cp); + ND_PRINT("\n\t type %s", tok2str(ofpst_str, "invalid (0x%04x)", type)); + OF_FWD(2); /* flags */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, ", flags 0x%04x", EXTRACT_16BITS(cp))); - of10_bitmap_print(ndo, ofpsf_reply_bm, EXTRACT_16BITS(cp), OFPSF_REPLY_U); - cp += 2; + ND_PRINT(", flags 0x%04x", GET_BE_U_2(cp)); + of_bitmap_print(ndo, ofpsf_reply_bm, GET_BE_U_2(cp), OFPSF_REPLY_U); + OF_FWD(2); if (ndo->ndo_vflag > 0) { - const u_char *(*decoder)(netdissect_options *, const u_char *, const u_char *, u_int) = + void (*decoder)(netdissect_options *, const u_char *, u_int) = type == OFPST_DESC ? of10_desc_stats_reply_print : type == OFPST_FLOW ? of10_flow_stats_reply_print : type == OFPST_AGGREGATE ? of10_aggregate_stats_reply_print : @@ -2206,355 +1963,336 @@ of10_stats_reply_print(netdissect_options *ndo, type == OFPST_QUEUE ? of10_queue_stats_reply_print : type == OFPST_VENDOR ? of10_vendor_data_print : NULL; - if (decoder != NULL) - return decoder(ndo, cp, ep, len - OF_STATS_REPLY_LEN); + if (decoder != NULL) { + decoder(ndo, cp, len); + return; + } } - ND_TCHECK2(*cp0, len); - return cp0 + len; - -trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; + ND_TCHECK_LEN(cp, len); } /* [OF10] Section 5.3.6 */ -static const u_char * +static void of10_packet_out_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, const u_int len) + const u_char *cp, u_int len) { - const u_char *cp0 = cp; - const u_int len0 = len; uint16_t actions_len; /* buffer_id */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, "\n\t buffer_id 0x%08x", EXTRACT_32BITS(cp))); - cp += 4; + ND_PRINT("\n\t buffer_id 0x%08x", GET_BE_U_4(cp)); + OF_FWD(4); /* in_port */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, ", in_port %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); - cp += 2; + ND_PRINT(", in_port %s", tok2str(ofpp_str, "%u", GET_BE_U_2(cp))); + OF_FWD(2); /* actions_len */ - ND_TCHECK2(*cp, 2); - actions_len = EXTRACT_16BITS(cp); - cp += 2; - if (actions_len > len - OF_PACKET_OUT_LEN) + actions_len = GET_BE_U_2(cp); + OF_FWD(2); + if (actions_len > len) goto invalid; /* actions */ - if (ep == (cp = of10_actions_print(ndo, "\n\t ", cp, ep, actions_len))) - return ep; /* end of snapshot */ + of10_actions_print(ndo, "\n\t ", cp, actions_len); + OF_FWD(actions_len); /* data */ - return of10_packet_data_print(ndo, cp, ep, len - OF_PACKET_OUT_LEN - actions_len); + of10_packet_data_print(ndo, cp, len); + return; invalid: /* skip the rest of the message body */ - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp0, len0); - return cp0 + len0; -trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } /* [OF10] Section 5.4.1 */ -static const u_char * +static void of10_packet_in_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, const u_int len) + const u_char *cp, u_int len) { /* buffer_id */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, "\n\t buffer_id %s", tok2str(bufferid_str, "0x%08x", EXTRACT_32BITS(cp)))); - cp += 4; + ND_PRINT("\n\t buffer_id %s", + tok2str(bufferid_str, "0x%08x", GET_BE_U_4(cp))); + OF_FWD(4); /* total_len */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, ", total_len %u", EXTRACT_16BITS(cp))); - cp += 2; + ND_PRINT(", total_len %u", GET_BE_U_2(cp)); + OF_FWD(2); /* in_port */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, ", in_port %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); - cp += 2; + ND_PRINT(", in_port %s", tok2str(ofpp_str, "%u", GET_BE_U_2(cp))); + OF_FWD(2); /* reason */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, ", reason %s", tok2str(ofpr_str, "invalid (0x%02x)", *cp))); - cp += 1; + ND_PRINT(", reason %s", + tok2str(ofpr_str, "invalid (0x%02x)", GET_U_1(cp))); + OF_FWD(1); /* pad */ - ND_TCHECK2(*cp, 1); - cp += 1; + /* Sometimes the last field, check bounds. */ + OF_CHK_FWD(1); /* data */ - /* 2 mock octets count in OF_PACKET_IN_LEN but not in len */ - return of10_packet_data_print(ndo, cp, ep, len - (OF_PACKET_IN_LEN - 2)); - -trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; + of10_packet_data_print(ndo, cp, len); } /* [OF10] Section 5.4.2 */ -static const u_char * +static void of10_flow_removed_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep) + const u_char *cp, u_int len _U_) { /* match */ - if (ep == (cp = of10_match_print(ndo, "\n\t ", cp, ep))) - return ep; /* end of snapshot */ + of10_match_print(ndo, "\n\t ", cp); + cp += OF_MATCH_FIXLEN; /* cookie */ - ND_TCHECK2(*cp, 8); - ND_PRINT((ndo, "\n\t cookie 0x%016" PRIx64, EXTRACT_64BITS(cp))); + ND_PRINT("\n\t cookie 0x%016" PRIx64, GET_BE_U_8(cp)); cp += 8; /* priority */ - ND_TCHECK2(*cp, 2); - if (EXTRACT_16BITS(cp)) - ND_PRINT((ndo, ", priority %u", EXTRACT_16BITS(cp))); + if (GET_BE_U_2(cp)) + ND_PRINT(", priority %u", GET_BE_U_2(cp)); cp += 2; /* reason */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, ", reason %s", tok2str(ofprr_str, "unknown (0x%02x)", *cp))); + ND_PRINT(", reason %s", + tok2str(ofprr_str, "unknown (0x%02x)", GET_U_1(cp))); cp += 1; /* pad */ - ND_TCHECK2(*cp, 1); cp += 1; /* duration_sec */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, ", duration_sec %u", EXTRACT_32BITS(cp))); + ND_PRINT(", duration_sec %u", GET_BE_U_4(cp)); cp += 4; /* duration_nsec */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, ", duration_nsec %u", EXTRACT_32BITS(cp))); + ND_PRINT(", duration_nsec %u", GET_BE_U_4(cp)); cp += 4; /* idle_timeout */ - ND_TCHECK2(*cp, 2); - if (EXTRACT_16BITS(cp)) - ND_PRINT((ndo, ", idle_timeout %u", EXTRACT_16BITS(cp))); + if (GET_BE_U_2(cp)) + ND_PRINT(", idle_timeout %u", GET_BE_U_2(cp)); cp += 2; /* pad2 */ - ND_TCHECK2(*cp, 2); cp += 2; /* packet_count */ - ND_TCHECK2(*cp, 8); - ND_PRINT((ndo, ", packet_count %" PRIu64, EXTRACT_64BITS(cp))); + ND_PRINT(", packet_count %" PRIu64, GET_BE_U_8(cp)); cp += 8; /* byte_count */ - ND_TCHECK2(*cp, 8); - ND_PRINT((ndo, ", byte_count %" PRIu64, EXTRACT_64BITS(cp))); - return cp + 8; + ND_PRINT(", byte_count %" PRIu64, GET_BE_U_8(cp)); +} -trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; +/* [OF10] Section 5.4.3 */ +static void +of10_port_status_print(netdissect_options *ndo, + const u_char *cp, u_int len _U_) +{ + /* reason */ + ND_PRINT("\n\t reason %s", + tok2str(ofppr_str, "invalid (0x%02x)", GET_U_1(cp))); + cp += 1; + /* pad */ + /* No need to check bounds, more data follows. */ + cp += 7; + /* desc */ + of10_phy_port_print(ndo, cp); } /* [OF10] Section 5.4.4 */ -static const u_char * +static void of10_error_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, const u_int len) + const u_char *cp, u_int len) { - uint16_t type; + uint16_t type, code; const struct tok *code_str; /* type */ - ND_TCHECK2(*cp, 2); - type = EXTRACT_16BITS(cp); - cp += 2; - ND_PRINT((ndo, "\n\t type %s", tok2str(ofpet_str, "invalid (0x%04x)", type))); + type = GET_BE_U_2(cp); + OF_FWD(2); + ND_PRINT("\n\t type %s", tok2str(ofpet_str, "invalid (0x%04x)", type)); /* code */ - ND_TCHECK2(*cp, 2); - code_str = - type == OFPET_HELLO_FAILED ? ofphfc_str : - type == OFPET_BAD_REQUEST ? ofpbrc_str : - type == OFPET_BAD_ACTION ? ofpbac_str : - type == OFPET_FLOW_MOD_FAILED ? ofpfmfc_str : - type == OFPET_PORT_MOD_FAILED ? ofppmfc_str : - type == OFPET_QUEUE_OP_FAILED ? ofpqofc_str : - empty_str; - ND_PRINT((ndo, ", code %s", tok2str(code_str, "invalid (0x%04x)", EXTRACT_16BITS(cp)))); - cp += 2; + code = GET_BE_U_2(cp); + OF_FWD(2); + code_str = uint2tokary(of10_ofpet2tokary, type); + if (code_str != NULL) + ND_PRINT(", code %s", + tok2str(code_str, "invalid (0x%04x)", code)); + else + ND_PRINT(", code invalid (0x%04x)", code); /* data */ - return of10_data_print(ndo, cp, ep, len - OF_ERROR_MSG_LEN); - -trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; + of_data_print(ndo, cp, len); } -const u_char * -of10_header_body_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, const uint8_t type, - const uint16_t len, const uint32_t xid) -{ - const u_char *cp0 = cp; - const u_int len0 = len; - /* Thus far message length is not less than the basic header size, but most - * message types have additional assorted constraints on the length. Wherever - * possible, check that message length meets the constraint, in remaining - * cases check that the length is OK to begin decoding and leave any final - * verification up to a lower-layer function. When the current message is - * invalid, proceed to the next message. */ - - /* [OF10] Section 5.1 */ - ND_PRINT((ndo, "\n\tversion 1.0, type %s, length %u, xid 0x%08x", - tok2str(ofpt_str, "invalid (0x%02x)", type), len, xid)); - switch (type) { - /* OpenFlow header only. */ - case OFPT_FEATURES_REQUEST: /* [OF10] Section 5.3.1 */ - case OFPT_GET_CONFIG_REQUEST: /* [OF10] Section 5.3.2 */ - case OFPT_BARRIER_REQUEST: /* [OF10] Section 5.3.7 */ - case OFPT_BARRIER_REPLY: /* ibid */ - if (len != OF_HEADER_LEN) - goto invalid; - break; - - /* OpenFlow header and fixed-size message body. */ - case OFPT_SET_CONFIG: /* [OF10] Section 5.3.2 */ - case OFPT_GET_CONFIG_REPLY: /* ibid */ - if (len != OF_SWITCH_CONFIG_LEN) - goto invalid; - if (ndo->ndo_vflag < 1) - goto next_message; - /* flags */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, "\n\t flags %s", tok2str(ofp_config_str, "invalid (0x%04x)", EXTRACT_16BITS(cp)))); - cp += 2; - /* miss_send_len */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, ", miss_send_len %u", EXTRACT_16BITS(cp))); - return cp + 2; - case OFPT_PORT_MOD: - if (len != OF_PORT_MOD_LEN) - goto invalid; - if (ndo->ndo_vflag < 1) - goto next_message; - return of10_port_mod_print(ndo, cp, ep); - case OFPT_QUEUE_GET_CONFIG_REQUEST: /* [OF10] Section 5.3.4 */ - if (len != OF_QUEUE_GET_CONFIG_REQUEST_LEN) - goto invalid; - if (ndo->ndo_vflag < 1) - goto next_message; - /* port */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, "\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); - cp += 2; - /* pad */ - ND_TCHECK2(*cp, 2); - return cp + 2; - case OFPT_FLOW_REMOVED: - if (len != OF_FLOW_REMOVED_LEN) - goto invalid; - if (ndo->ndo_vflag < 1) - goto next_message; - return of10_flow_removed_print(ndo, cp, ep); - case OFPT_PORT_STATUS: /* [OF10] Section 5.4.3 */ - if (len != OF_PORT_STATUS_LEN) - goto invalid; - if (ndo->ndo_vflag < 1) - goto next_message; - /* reason */ - ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, "\n\t reason %s", tok2str(ofppr_str, "invalid (0x%02x)", *cp))); - cp += 1; - /* pad */ - ND_TCHECK2(*cp, 7); - cp += 7; - /* desc */ - return of10_phy_ports_print(ndo, cp, ep, OF_PHY_PORT_LEN); - - /* OpenFlow header, fixed-size message body and n * fixed-size data units. */ - case OFPT_FEATURES_REPLY: - if (len < OF_SWITCH_FEATURES_LEN) - goto invalid; - if (ndo->ndo_vflag < 1) - goto next_message; - return of10_features_reply_print(ndo, cp, ep, len); - - /* OpenFlow header and variable-size data. */ - case OFPT_HELLO: /* [OF10] Section 5.5.1 */ - case OFPT_ECHO_REQUEST: /* [OF10] Section 5.5.2 */ - case OFPT_ECHO_REPLY: /* [OF10] Section 5.5.3 */ - if (ndo->ndo_vflag < 1) - goto next_message; - return of10_data_print(ndo, cp, ep, len - OF_HEADER_LEN); - - /* OpenFlow header, fixed-size message body and variable-size data. */ - case OFPT_ERROR: - if (len < OF_ERROR_MSG_LEN) - goto invalid; - if (ndo->ndo_vflag < 1) - goto next_message; - return of10_error_print(ndo, cp, ep, len); - case OFPT_VENDOR: - /* [OF10] Section 5.5.4 */ - if (len < OF_VENDOR_HEADER_LEN) - goto invalid; - if (ndo->ndo_vflag < 1) - goto next_message; - return of10_vendor_message_print(ndo, cp, ep, len - OF_HEADER_LEN); - case OFPT_PACKET_IN: - /* 2 mock octets count in OF_PACKET_IN_LEN but not in len */ - if (len < OF_PACKET_IN_LEN - 2) - goto invalid; - if (ndo->ndo_vflag < 1) - goto next_message; - return of10_packet_in_print(ndo, cp, ep, len); - - /* a. OpenFlow header. */ - /* b. OpenFlow header and one of the fixed-size message bodies. */ - /* c. OpenFlow header, fixed-size message body and variable-size data. */ - case OFPT_STATS_REQUEST: - if (len < OF_STATS_REQUEST_LEN) - goto invalid; - if (ndo->ndo_vflag < 1) - goto next_message; - return of10_stats_request_print(ndo, cp, ep, len); - - /* a. OpenFlow header and fixed-size message body. */ - /* b. OpenFlow header and n * fixed-size data units. */ - /* c. OpenFlow header and n * variable-size data units. */ - /* d. OpenFlow header, fixed-size message body and variable-size data. */ - case OFPT_STATS_REPLY: - if (len < OF_STATS_REPLY_LEN) - goto invalid; - if (ndo->ndo_vflag < 1) - goto next_message; - return of10_stats_reply_print(ndo, cp, ep, len); - - /* OpenFlow header and n * variable-size data units and variable-size data. */ - case OFPT_PACKET_OUT: - if (len < OF_PACKET_OUT_LEN) - goto invalid; - if (ndo->ndo_vflag < 1) - goto next_message; - return of10_packet_out_print(ndo, cp, ep, len); - - /* OpenFlow header, fixed-size message body and n * variable-size data units. */ - case OFPT_FLOW_MOD: - if (len < OF_FLOW_MOD_LEN) - goto invalid; - if (ndo->ndo_vflag < 1) - goto next_message; - return of10_flow_mod_print(ndo, cp, ep, len); - - /* OpenFlow header, fixed-size message body and n * variable-size data units. */ - case OFPT_QUEUE_GET_CONFIG_REPLY: /* [OF10] Section 5.3.4 */ - if (len < OF_QUEUE_GET_CONFIG_REPLY_LEN) - goto invalid; - if (ndo->ndo_vflag < 1) - goto next_message; - /* port */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, "\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); - cp += 2; - /* pad */ - ND_TCHECK2(*cp, 6); - cp += 6; - /* queues */ - return of10_queues_print(ndo, cp, ep, len - OF_QUEUE_GET_CONFIG_REPLY_LEN); - } /* switch (type) */ - goto next_message; +static const struct of_msgtypeinfo of10_msgtypeinfo[OFPT_MAX + 1] = { + /* + * [OF10] Section 5.5.1 + * Variable-size data. + */ + { + "HELLO", of_data_print, + REQ_MINLEN, 0 + }, + /* + * [OF10] Section 5.4.4 + * A fixed-size message body and variable-size data. + */ + { + "ERROR", of10_error_print, + REQ_MINLEN, OF_ERROR_MSG_MINLEN + }, + /* + * [OF10] Section 5.5.2 + * Variable-size data. + */ + { + "ECHO_REQUEST", of_data_print, + REQ_MINLEN, 0 + }, + /* + * [OF10] Section 5.5.3 + * Variable-size data. + */ + { + "ECHO_REPLY", of_data_print, + REQ_MINLEN, 0 + }, + /* + * [OF10] Section 5.5.4 + * A fixed-size message body and variable-size data. + */ + { + "VENDOR", of10_vendor_message_print, + REQ_MINLEN, OF_VENDOR_MINLEN + }, + /* + * [OF10] Section 5.3.1 + * No message body. + */ + { + "FEATURES_REQUEST", NULL, + REQ_FIXLEN, 0 + }, + /* + * [OF10] Section 5.3.1 + * A fixed-size message body and n * fixed-size data units. + */ + { + "FEATURES_REPLY", of10_features_reply_print, + REQ_MINLEN, OF_FEATURES_REPLY_MINLEN + }, + /* + * [OF10] Section 5.3.2 + * No message body. + */ + { + "GET_CONFIG_REQUEST", NULL, + REQ_FIXLEN, 0 + }, + /* + * [OF10] Section 5.3.2 + * A fixed-size message body. + */ + { + "GET_CONFIG_REPLY", of10_switch_config_msg_print, + REQ_FIXLEN, OF_SWITCH_CONFIG_FIXLEN + }, + /* + * [OF10] Section 5.3.2 + * A fixed-size message body. + */ + { + "SET_CONFIG", of10_switch_config_msg_print, + REQ_FIXLEN, OF_SWITCH_CONFIG_FIXLEN + }, + /* + * [OF10] Section 5.4.1 + * A fixed-size message body and variable-size data. + * (The 2 mock octets count in OF_PACKET_IN_MINLEN only.) + */ + { + "PACKET_IN", of10_packet_in_print, + REQ_MINLEN, OF_PACKET_IN_MINLEN - 2 + }, + /* + * [OF10] Section 5.4.2 + * A fixed-size message body. + */ + { + "FLOW_REMOVED", of10_flow_removed_print, + REQ_FIXLEN, OF_FLOW_REMOVED_FIXLEN + }, + /* + * [OF10] Section 5.4.3 + * A fixed-size message body. + */ + { + "PORT_STATUS", of10_port_status_print, + REQ_FIXLEN, OF_PORT_STATUS_FIXLEN + }, + /* + * [OF10] Section 5.3.6 + * A fixed-size message body, n * variable-size data units and + * variable-size data. + */ + { + "PACKET_OUT", of10_packet_out_print, + REQ_MINLEN, OF_PACKET_OUT_MINLEN + }, + /* + * [OF10] Section 5.3.3 + * A fixed-size message body and n * variable-size data units. + */ + { + "FLOW_MOD", of10_flow_mod_print, + REQ_MINLEN, OF_FLOW_MOD_MINLEN + }, + /* + * [OF10] Section 5.3.3 + * A fixed-size message body. + */ + { + "PORT_MOD", of10_port_mod_print, + REQ_FIXLEN, OF_PORT_MOD_FIXLEN + }, + /* + * [OF10] Section 5.3.5 + * A fixed-size message body and possibly more data of varying size + * and structure. + */ + { + "STATS_REQUEST", of10_stats_request_print, + REQ_MINLEN, OF_STATS_REQUEST_MINLEN + }, + /* + * [OF10] Section 5.3.5 + * A fixed-size message body and possibly more data of varying size + * and structure. + */ + { + "STATS_REPLY", of10_stats_reply_print, + REQ_MINLEN, OF_STATS_REPLY_MINLEN + }, + /* + * [OF10] Section 5.3.7 + * No message body. + */ + { + "BARRIER_REQUEST", NULL, + REQ_FIXLEN, 0 + }, + /* + * [OF10] Section 5.3.7 + * No message body. + */ + { + "BARRIER_REPLY", NULL, + REQ_FIXLEN, 0 + }, + /* + * [OF10] Section 5.3.4 + * A fixed-size message body. + */ + { + "QUEUE_GET_CONFIG_REQUEST", of10_queue_get_config_request_print, + REQ_FIXLEN, OF_QUEUE_GET_CONFIG_REQUEST_FIXLEN + }, + /* + * [OF10] Section 5.3.4 + * A fixed-size message body and n * variable-size data units. + */ + { + "QUEUE_GET_CONFIG_REPLY", of10_queue_get_config_reply_print, + REQ_MINLEN, OF_QUEUE_GET_CONFIG_REPLY_MINLEN + }, +}; -invalid: /* skip the message body */ - ND_PRINT((ndo, "%s", istr)); -next_message: - ND_TCHECK2(*cp0, len0 - OF_HEADER_LEN); - return cp0 + len0 - OF_HEADER_LEN; -trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; +const struct of_msgtypeinfo * +of10_identify_msgtype(const uint8_t type) +{ + return type <= OFPT_MAX ? &of10_msgtypeinfo[type] : NULL; } diff --git a/contrib/tcpdump/print-openflow-1.3.c b/contrib/tcpdump/print-openflow-1.3.c new file mode 100644 index 0000000000..9e76ba1b29 --- /dev/null +++ b/contrib/tcpdump/print-openflow-1.3.c @@ -0,0 +1,1209 @@ +/* + * This module implements decoding of OpenFlow protocol version 1.3 (wire + * protocol 0x04). It is based on the implementation conventions explained in + * print-openflow-1.0.c. + * + * [OF13] https://www.opennetworking.org/wp-content/uploads/2014/10/openflow-switch-v1.3.5.pdf + * + * Copyright (c) 2020 The TCPDUMP project + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +/* \summary: OpenFlow protocol version 1.3 printer */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "netdissect-stdinc.h" + +#define ND_LONGJMP_FROM_TCHECK +#include "netdissect.h" +#include "extract.h" +#include "addrtoname.h" +#include "openflow.h" + +#define OFPT_HELLO 0U +#define OFPT_ERROR 1U +#define OFPT_ECHO_REQUEST 2U +#define OFPT_ECHO_REPLY 3U +#define OFPT_EXPERIMENTER 4U +#define OFPT_FEATURES_REQUEST 5U +#define OFPT_FEATURES_REPLY 6U +#define OFPT_GET_CONFIG_REQUEST 7U +#define OFPT_GET_CONFIG_REPLY 8U +#define OFPT_SET_CONFIG 9U +#define OFPT_PACKET_IN 10U +#define OFPT_FLOW_REMOVED 11U +#define OFPT_PORT_STATUS 12U +#define OFPT_PACKET_OUT 13U +#define OFPT_FLOW_MOD 14U +#define OFPT_GROUP_MOD 15U +#define OFPT_PORT_MOD 16U +#define OFPT_TABLE_MOD 17U +#define OFPT_MULTIPART_REQUEST 18U +#define OFPT_MULTIPART_REPLY 19U +#define OFPT_BARRIER_REQUEST 20U +#define OFPT_BARRIER_REPLY 21U +#define OFPT_QUEUE_GET_CONFIG_REQUEST 22U +#define OFPT_QUEUE_GET_CONFIG_REPLY 23U +#define OFPT_ROLE_REQUEST 24U +#define OFPT_ROLE_REPLY 25U +#define OFPT_GET_ASYNC_REQUEST 26U +#define OFPT_GET_ASYNC_REPLY 27U +#define OFPT_SET_ASYNC 28U +#define OFPT_METER_MOD 29U +#define OFPT_MAX OFPT_METER_MOD + +#define OFPC_FLOW_STATS (1U <<0) +#define OFPC_TABLE_STATS (1U <<1) +#define OFPC_PORT_STATS (1U <<2) +#define OFPC_GROUP_STATS (1U <<3) +#define OFPC_IP_REASM (1U <<5) +#define OFPC_QUEUE_STATS (1U <<6) +#define OFPC_PORT_BLOCKED (1U <<8) +static const struct tok ofp_capabilities_bm[] = { + { OFPC_FLOW_STATS, "FLOW_STATS" }, + { OFPC_TABLE_STATS, "TABLE_STATS" }, + { OFPC_PORT_STATS, "PORT_STATS" }, + { OFPC_GROUP_STATS, "GROUP_STATS" }, + { OFPC_IP_REASM, "IP_REASM" }, + { OFPC_QUEUE_STATS, "QUEUE_STATS" }, + { OFPC_PORT_BLOCKED, "PORT_BLOCKED" }, + { 0, NULL } +}; +#define OFPCAP_U (~(OFPC_FLOW_STATS | OFPC_TABLE_STATS | OFPC_PORT_STATS | \ + OFPC_GROUP_STATS | OFPC_IP_REASM | OFPC_QUEUE_STATS | \ + OFPC_PORT_BLOCKED)) + +#define OFPC_FRAG_NORMAL 0U +#define OFPC_FRAG_DROP 1U +#define OFPC_FRAG_REASM 2U +static const struct tok ofp_config_str[] = { + { OFPC_FRAG_NORMAL, "FRAG_NORMAL" }, + { OFPC_FRAG_DROP, "FRAG_DROP" }, + { OFPC_FRAG_REASM, "FRAG_REASM" }, + { 0, NULL } +}; + +#define OFPTT_MAX 0xfeU +#define OFPTT_ALL 0xffU +static const struct tok ofptt_str[] = { + { OFPTT_MAX, "MAX" }, + { OFPTT_ALL, "ALL" }, + { 0, NULL }, +}; + +#define OFPCML_MAX 0xffe5U +#define OFPCML_NO_BUFFER 0xffffU +static const struct tok ofpcml_str[] = { + { OFPCML_MAX, "MAX" }, + { OFPCML_NO_BUFFER, "NO_BUFFER" }, + { 0, NULL } +}; + +#define OFPPC_PORT_DOWN (1U <<0) +#define OFPPC_NO_RECV (1U <<2) +#define OFPPC_NO_FWD (1U <<5) +#define OFPPC_NO_PACKET_IN (1U <<6) +static const struct tok ofppc_bm[] = { + { OFPPC_PORT_DOWN, "PORT_DOWN" }, + { OFPPC_NO_RECV, "NO_RECV" }, + { OFPPC_NO_FWD, "NO_FWD" }, + { OFPPC_NO_PACKET_IN, "NO_PACKET_IN" }, + { 0, NULL } +}; +#define OFPPC_U (~(OFPPC_PORT_DOWN | OFPPC_NO_RECV | OFPPC_NO_FWD | \ + OFPPC_NO_PACKET_IN)) + +#define OFPPS_LINK_DOWN (1U << 0) +#define OFPPS_BLOCKED (1U << 1) +#define OFPPS_LIVE (1U << 2) +static const struct tok ofpps_bm[] = { + { OFPPS_LINK_DOWN, "LINK_DOWN" }, + { OFPPS_BLOCKED, "BLOCKED" }, + { OFPPS_LIVE, "LIVE" }, + { 0, NULL } +}; +#define OFPPS_U (~(OFPPS_LINK_DOWN | OFPPS_BLOCKED | OFPPS_LIVE)) + +#define OFPPF_10MB_HD (1U << 0) +#define OFPPF_10MB_FD (1U << 1) +#define OFPPF_100MB_HD (1U << 2) +#define OFPPF_100MB_FD (1U << 3) +#define OFPPF_1GB_HD (1U << 4) +#define OFPPF_1GB_FD (1U << 5) +#define OFPPF_10GB_FD (1U << 6) +#define OFPPF_40GB_FD (1U << 7) +#define OFPPF_100GB_FD (1U << 8) +#define OFPPF_1TB_FD (1U << 9) +#define OFPPF_OTHER (1U << 10) +#define OFPPF_COPPER (1U << 11) +#define OFPPF_FIBER (1U << 12) +#define OFPPF_AUTONEG (1U << 13) +#define OFPPF_PAUSE (1U << 14) +#define OFPPF_PAUSE_ASYM (1U << 15) +static const struct tok ofppf_bm[] = { + { OFPPF_10MB_HD, "10MB_HD" }, + { OFPPF_10MB_FD, "10MB_FD" }, + { OFPPF_100MB_HD, "100MB_HD" }, + { OFPPF_100MB_FD, "100MB_FD" }, + { OFPPF_1GB_HD, "1GB_HD" }, + { OFPPF_1GB_FD, "1GB_FD" }, + { OFPPF_10GB_FD, "10GB_FD" }, + { OFPPF_40GB_FD, "40GB_FD" }, + { OFPPF_100GB_FD, "100GB_FD" }, + { OFPPF_1TB_FD, "1TB_FD" }, + { OFPPF_OTHER, "OTHER" }, + { OFPPF_COPPER, "COPPER" }, + { OFPPF_FIBER, "FIBER" }, + { OFPPF_AUTONEG, "AUTONEG" }, + { OFPPF_PAUSE, "PAUSE" }, + { OFPPF_PAUSE_ASYM, "PAUSE_ASYM" }, + { 0, NULL } +}; +#define OFPPF_U (~(OFPPF_10MB_HD | OFPPF_10MB_FD | OFPPF_100MB_HD | \ + OFPPF_100MB_FD | OFPPF_1GB_HD | OFPPF_1GB_FD | \ + OFPPF_10GB_FD | OFPPF_40GB_FD | OFPPF_100GB_FD | \ + OFPPF_1TB_FD | OFPPF_OTHER | OFPPF_COPPER | OFPPF_FIBER | \ + OFPPF_AUTONEG | OFPPF_PAUSE | OFPPF_PAUSE_ASYM)) + +#define OFPHET_VERSIONBITMAP 1U +static const struct tok ofphet_str[] = { + { OFPHET_VERSIONBITMAP, "VERSIONBITMAP" }, + { 0, NULL } +}; + +#define OFPP_MAX 0xffffff00U +#define OFPP_IN_PORT 0xfffffff8U +#define OFPP_TABLE 0xfffffff9U +#define OFPP_NORMAL 0xfffffffaU +#define OFPP_FLOOD 0xfffffffbU +#define OFPP_ALL 0xfffffffcU +#define OFPP_CONTROLLER 0xfffffffdU +#define OFPP_LOCAL 0xfffffffeU +#define OFPP_ANY 0xffffffffU +static const struct tok ofpp_str[] = { + { OFPP_MAX, "MAX" }, + { OFPP_IN_PORT, "IN_PORT" }, + { OFPP_TABLE, "TABLE" }, + { OFPP_NORMAL, "NORMAL" }, + { OFPP_FLOOD, "FLOOD" }, + { OFPP_ALL, "ALL" }, + { OFPP_CONTROLLER, "CONTROLLER" }, + { OFPP_LOCAL, "LOCAL" }, + { OFPP_ANY, "ANY" }, + { 0, NULL } +}; + +#define OFPCR_ROLE_NOCHANGE 0U +#define OFPCR_ROLE_EQUAL 1U +#define OFPCR_ROLE_MASTER 2U +#define OFPCR_ROLE_SLAVE 3U +static const struct tok ofpcr_str[] = { + { OFPCR_ROLE_NOCHANGE, "NOCHANGE" }, + { OFPCR_ROLE_EQUAL, "EQUAL" }, + { OFPCR_ROLE_MASTER, "MASTER" }, + { OFPCR_ROLE_SLAVE, "SLAVE" }, + { 0, NULL } +}; + +#define OF_BIT_VER_1_0 (1U << (OF_VER_1_0 - 1)) +#define OF_BIT_VER_1_1 (1U << (OF_VER_1_1 - 1)) +#define OF_BIT_VER_1_2 (1U << (OF_VER_1_2 - 1)) +#define OF_BIT_VER_1_3 (1U << (OF_VER_1_3 - 1)) +#define OF_BIT_VER_1_4 (1U << (OF_VER_1_4 - 1)) +#define OF_BIT_VER_1_5 (1U << (OF_VER_1_5 - 1)) +static const struct tok ofverbm_str[] = { + { OF_BIT_VER_1_0, "1.0" }, + { OF_BIT_VER_1_1, "1.1" }, + { OF_BIT_VER_1_2, "1.2" }, + { OF_BIT_VER_1_3, "1.3" }, + { OF_BIT_VER_1_4, "1.4" }, + { OF_BIT_VER_1_5, "1.5" }, + { 0, NULL } +}; +#define OF_BIT_VER_U (~(OF_BIT_VER_1_0 | OF_BIT_VER_1_1 | OF_BIT_VER_1_2 | \ + OF_BIT_VER_1_3 | OF_BIT_VER_1_4 | OF_BIT_VER_1_5)) + +#define OFPR_NO_MATCH 0U +#define OFPR_ACTION 1U +#define OFPR_INVALID_TTL 2U +#if 0 /* for OFPT_PACKET_IN */ +static const struct tok ofpr_str[] = { + { OFPR_NO_MATCH, "NO_MATCH" }, + { OFPR_ACTION, "ACTION" }, + { OFPR_INVALID_TTL, "OFPR_INVALID_TTL" }, + { 0, NULL } +}; +#endif + +#define ASYNC_OFPR_NO_MATCH (1U << OFPR_NO_MATCH ) +#define ASYNC_OFPR_ACTION (1U << OFPR_ACTION ) +#define ASYNC_OFPR_INVALID_TTL (1U << OFPR_INVALID_TTL) +static const struct tok async_ofpr_bm[] = { + { ASYNC_OFPR_NO_MATCH, "NO_MATCH" }, + { ASYNC_OFPR_ACTION, "ACTION" }, + { ASYNC_OFPR_INVALID_TTL, "INVALID_TTL" }, + { 0, NULL } +}; +#define ASYNC_OFPR_U (~(ASYNC_OFPR_NO_MATCH | ASYNC_OFPR_ACTION | \ + ASYNC_OFPR_INVALID_TTL)) + +#define OFPPR_ADD 0U +#define OFPPR_DELETE 1U +#define OFPPR_MODIFY 2U +static const struct tok ofppr_str[] = { + { OFPPR_ADD, "ADD" }, + { OFPPR_DELETE, "DELETE" }, + { OFPPR_MODIFY, "MODIFY" }, + { 0, NULL } +}; + +#define ASYNC_OFPPR_ADD (1U << OFPPR_ADD ) +#define ASYNC_OFPPR_DELETE (1U << OFPPR_DELETE) +#define ASYNC_OFPPR_MODIFY (1U << OFPPR_MODIFY) +static const struct tok async_ofppr_bm[] = { + { ASYNC_OFPPR_ADD, "ADD" }, + { ASYNC_OFPPR_DELETE, "DELETE" }, + { ASYNC_OFPPR_MODIFY, "MODIFY" }, + { 0, NULL } +}; +#define ASYNC_OFPPR_U (~(ASYNC_OFPPR_ADD | ASYNC_OFPPR_DELETE | \ + ASYNC_OFPPR_MODIFY)) + +#define OFPET_HELLO_FAILED 0U +#define OFPET_BAD_REQUEST 1U +#define OFPET_BAD_ACTION 2U +#define OFPET_BAD_INSTRUCTION 3U +#define OFPET_BAD_MATCH 4U +#define OFPET_FLOW_MOD_FAILED 5U +#define OFPET_GROUP_MOD_FAILED 6U +#define OFPET_PORT_MOD_FAILED 7U +#define OFPET_TABLE_MOD_FAILED 8U +#define OFPET_QUEUE_OP_FAILED 9U +#define OFPET_SWITCH_CONFIG_FAILED 10U +#define OFPET_ROLE_REQUEST_FAILED 11U +#define OFPET_METER_MOD_FAILED 12U +#define OFPET_TABLE_FEATURES_FAILED 13U +#define OFPET_EXPERIMENTER 0xffffU /* a special case */ +static const struct tok ofpet_str[] = { + { OFPET_HELLO_FAILED, "HELLO_FAILED" }, + { OFPET_BAD_REQUEST, "BAD_REQUEST" }, + { OFPET_BAD_ACTION, "BAD_ACTION" }, + { OFPET_BAD_INSTRUCTION, "BAD_INSTRUCTION" }, + { OFPET_BAD_MATCH, "BAD_MATCH" }, + { OFPET_FLOW_MOD_FAILED, "FLOW_MOD_FAILED" }, + { OFPET_GROUP_MOD_FAILED, "GROUP_MOD_FAILED" }, + { OFPET_PORT_MOD_FAILED, "PORT_MOD_FAILED" }, + { OFPET_TABLE_MOD_FAILED, "TABLE_MOD_FAILED" }, + { OFPET_QUEUE_OP_FAILED, "QUEUE_OP_FAILED" }, + { OFPET_SWITCH_CONFIG_FAILED, "SWITCH_CONFIG_FAILED" }, + { OFPET_ROLE_REQUEST_FAILED, "ROLE_REQUEST_FAILED" }, + { OFPET_METER_MOD_FAILED, "METER_MOD_FAILED" }, + { OFPET_TABLE_FEATURES_FAILED, "TABLE_FEATURES_FAILED" }, + { OFPET_EXPERIMENTER, "EXPERIMENTER" }, + { 0, NULL } +}; + +#define OFPHFC_INCOMPATIBLE 0U +#define OFPHFC_EPERM 1U +static const struct tok ofphfc_str[] = { + { OFPHFC_INCOMPATIBLE, "INCOMPATIBLE" }, + { OFPHFC_EPERM, "EPERM" }, + { 0, NULL } +}; + +#define OFPBRC_BAD_VERSION 0U +#define OFPBRC_BAD_TYPE 1U +#define OFPBRC_BAD_MULTIPART 2U +#define OFPBRC_BAD_EXPERIMENTER 3U +#define OFPBRC_BAD_EXP_TYPE 4U +#define OFPBRC_EPERM 5U +#define OFPBRC_BAD_LEN 6U +#define OFPBRC_BUFFER_EMPTY 7U +#define OFPBRC_BUFFER_UNKNOWN 8U +#define OFPBRC_BAD_TABLE_ID 9U +#define OFPBRC_IS_SLAVE 10U +#define OFPBRC_BAD_PORT 11U +#define OFPBRC_BAD_PACKET 12U +#define OFPBRC_MULTIPART_BUFFER_OVERFLOW 13U +static const struct tok ofpbrc_str[] = { + { OFPBRC_BAD_VERSION, "BAD_VERSION" }, + { OFPBRC_BAD_TYPE, "BAD_TYPE" }, + { OFPBRC_BAD_MULTIPART, "BAD_MULTIPART" }, + { OFPBRC_BAD_EXPERIMENTER, "BAD_EXPERIMENTER" }, + { OFPBRC_BAD_EXP_TYPE, "BAD_EXP_TYPE" }, + { OFPBRC_EPERM, "EPERM" }, + { OFPBRC_BAD_LEN, "BAD_LEN" }, + { OFPBRC_BUFFER_EMPTY, "BUFFER_EMPTY" }, + { OFPBRC_BUFFER_UNKNOWN, "BUFFER_UNKNOWN" }, + { OFPBRC_BAD_TABLE_ID, "BAD_TABLE_ID" }, + { OFPBRC_IS_SLAVE, "IS_SLAVE" }, + { OFPBRC_BAD_PORT, "BAD_PORT" }, + { OFPBRC_BAD_PACKET, "BAD_PACKET" }, + { OFPBRC_MULTIPART_BUFFER_OVERFLOW, "MULTIPART_BUFFER_OVERFLOW" }, + { 0, NULL } +}; + +#define OFPBAC_BAD_TYPE 0U +#define OFPBAC_BAD_LEN 1U +#define OFPBAC_BAD_EXPERIMENTER 2U +#define OFPBAC_BAD_EXP_TYPE 3U +#define OFPBAC_BAD_OUT_PORT 4U +#define OFPBAC_BAD_ARGUMENT 5U +#define OFPBAC_EPERM 6U +#define OFPBAC_TOO_MANY 7U +#define OFPBAC_BAD_QUEUE 8U +#define OFPBAC_BAD_OUT_GROUP 9U +#define OFPBAC_MATCH_INCONSISTENT 10U +#define OFPBAC_UNSUPPORTED_ORDER 11U +#define OFPBAC_BAD_TAG 12U +#define OFPBAC_BAD_SET_TYPE 13U +#define OFPBAC_BAD_SET_LEN 14U +#define OFPBAC_BAD_SET_ARGUMENT 15U +static const struct tok ofpbac_str[] = { + { OFPBAC_BAD_TYPE, "BAD_TYPE" }, + { OFPBAC_BAD_LEN, "BAD_LEN" }, + { OFPBAC_BAD_EXPERIMENTER, "BAD_EXPERIMENTER" }, + { OFPBAC_BAD_EXP_TYPE, "BAD_EXP_TYPE" }, + { OFPBAC_BAD_OUT_PORT, "BAD_OUT_PORT" }, + { OFPBAC_BAD_ARGUMENT, "BAD_ARGUMENT" }, + { OFPBAC_EPERM, "EPERM" }, + { OFPBAC_TOO_MANY, "TOO_MANY" }, + { OFPBAC_BAD_QUEUE, "BAD_QUEUE" }, + { OFPBAC_BAD_OUT_GROUP, "BAD_OUT_GROUP" }, + { OFPBAC_MATCH_INCONSISTENT, "MATCH_INCONSISTENT" }, + { OFPBAC_UNSUPPORTED_ORDER, "UNSUPPORTED_ORDER" }, + { OFPBAC_BAD_TAG, "BAD_TAG" }, + { OFPBAC_BAD_SET_TYPE, "BAD_SET_TYPE" }, + { OFPBAC_BAD_SET_LEN, "BAD_SET_LEN" }, + { OFPBAC_BAD_SET_ARGUMENT, "BAD_SET_ARGUMENT" }, + { 0, NULL } +}; + +#define OFPBIC_UNKNOWN_INST 0U +#define OFPBIC_UNSUP_INST 1U +#define OFPBIC_BAD_TABLE_ID 2U +#define OFPBIC_UNSUP_METADATA 3U +#define OFPBIC_UNSUP_METADATA_MASK 4U +#define OFPBIC_BAD_EXPERIMENTER 5U +#define OFPBIC_BAD_EXP_TYPE 6U +#define OFPBIC_BAD_LEN 7U +#define OFPBIC_EPERM 8U +static const struct tok ofpbic_str[] = { + { OFPBIC_UNKNOWN_INST, "UNKNOWN_INST" }, + { OFPBIC_UNSUP_INST, "UNSUP_INST" }, + { OFPBIC_BAD_TABLE_ID, "BAD_TABLE_ID" }, + { OFPBIC_UNSUP_METADATA, "UNSUP_METADATA" }, + { OFPBIC_UNSUP_METADATA_MASK, "UNSUP_METADATA_MASK" }, + { OFPBIC_BAD_EXPERIMENTER, "BAD_EXPERIMENTER" }, + { OFPBIC_BAD_EXP_TYPE, "BAD_EXP_TYPE" }, + { OFPBIC_BAD_LEN, "BAD_LEN" }, + { OFPBIC_EPERM, "EPERM" }, + { 0, NULL } +}; + +#define OFPBMC_BAD_TYPE 0U +#define OFPBMC_BAD_LEN 1U +#define OFPBMC_BAD_TAG 2U +#define OFPBMC_BAD_DL_ADDR_MASK 3U +#define OFPBMC_BAD_NW_ADDR_MASK 4U +#define OFPBMC_BAD_WILDCARDS 5U +#define OFPBMC_BAD_FIELD 6U +#define OFPBMC_BAD_VALUE 7U +#define OFPBMC_BAD_MASK 8U +#define OFPBMC_BAD_PREREQ 9U +#define OFPBMC_DUP_FIELD 10U +#define OFPBMC_EPERM 11U +static const struct tok ofpbmc_str[] = { + { OFPBMC_BAD_TYPE, "BAD_TYPE" }, + { OFPBMC_BAD_LEN, "BAD_LEN" }, + { OFPBMC_BAD_TAG, "BAD_TAG" }, + { OFPBMC_BAD_DL_ADDR_MASK, "BAD_DL_ADDR_MASK" }, + { OFPBMC_BAD_NW_ADDR_MASK, "BAD_NW_ADDR_MASK" }, + { OFPBMC_BAD_WILDCARDS, "BAD_WILDCARDS" }, + { OFPBMC_BAD_FIELD, "BAD_FIELD" }, + { OFPBMC_BAD_VALUE, "BAD_VALUE" }, + { OFPBMC_BAD_MASK, "BAD_MASK" }, + { OFPBMC_BAD_PREREQ, "BAD_PREREQ" }, + { OFPBMC_DUP_FIELD, "DUP_FIELD" }, + { OFPBMC_EPERM, "EPERM" }, + { 0, NULL } +}; + +#define OFPFMFC_UNKNOWN 0U +#define OFPFMFC_TABLE_FULL 1U +#define OFPFMFC_BAD_TABLE_ID 2U +#define OFPFMFC_OVERLAP 3U +#define OFPFMFC_EPERM 4U +#define OFPFMFC_BAD_TIMEOUT 5U +#define OFPFMFC_BAD_COMMAND 6U +#define OFPFMFC_BAD_FLAGS 7U +static const struct tok ofpfmfc_str[] = { + { OFPFMFC_UNKNOWN, "UNKNOWN" }, + { OFPFMFC_TABLE_FULL, "TABLE_FULL" }, + { OFPFMFC_BAD_TABLE_ID, "BAD_TABLE_ID" }, + { OFPFMFC_OVERLAP, "OVERLAP" }, + { OFPFMFC_EPERM, "EPERM" }, + { OFPFMFC_BAD_TIMEOUT, "BAD_TIMEOUT" }, + { OFPFMFC_BAD_COMMAND, "BAD_COMMAND" }, + { OFPFMFC_BAD_FLAGS, "BAD_FLAGS" }, + { 0, NULL } +}; + +#define OFPGMFC_GROUP_EXISTS 0U +#define OFPGMFC_INVALID_GROUP 1U +#define OFPGMFC_WEIGHT_UNSUPPORTED 2U +#define OFPGMFC_OUT_OF_GROUPS 3U +#define OFPGMFC_OUT_OF_BUCKETS 4U +#define OFPGMFC_CHAINING_UNSUPPORTED 5U +#define OFPGMFC_WATCH_UNSUPPORTED 6U +#define OFPGMFC_LOOP 7U +#define OFPGMFC_UNKNOWN_GROUP 8U +#define OFPGMFC_CHAINED_GROUP 9U +#define OFPGMFC_BAD_TYPE 10U +#define OFPGMFC_BAD_COMMAND 11U +#define OFPGMFC_BAD_BUCKET 12U +#define OFPGMFC_BAD_MATCH 13U +#define OFPGMFC_EPERM 14U +static const struct tok ofpgmfc_str[] = { + { OFPGMFC_GROUP_EXISTS, "GROUP_EXISTS" }, + { OFPGMFC_INVALID_GROUP, "INVALID_GROUP" }, + { OFPGMFC_WEIGHT_UNSUPPORTED, "WEIGHT_UNSUPPORTED" }, + { OFPGMFC_OUT_OF_GROUPS, "OUT_OF_GROUPS" }, + { OFPGMFC_OUT_OF_BUCKETS, "OUT_OF_BUCKETS" }, + { OFPGMFC_CHAINING_UNSUPPORTED, "CHAINING_UNSUPPORTED" }, + { OFPGMFC_WATCH_UNSUPPORTED, "WATCH_UNSUPPORTED" }, + { OFPGMFC_LOOP, "LOOP" }, + { OFPGMFC_UNKNOWN_GROUP, "UNKNOWN_GROUP" }, + { OFPGMFC_CHAINED_GROUP, "CHAINED_GROUP" }, + { OFPGMFC_BAD_TYPE, "BAD_TYPE" }, + { OFPGMFC_BAD_COMMAND, "BAD_COMMAND" }, + { OFPGMFC_BAD_BUCKET, "BAD_BUCKET" }, + { OFPGMFC_BAD_MATCH, "BAD_MATCH" }, + { OFPGMFC_EPERM, "EPERM" }, + { 0, NULL } +}; + +#define OFPPMFC_BAD_PORT 0U +#define OFPPMFC_BAD_HW_ADDR 1U +#define OFPPMFC_BAD_CONFIG 2U +#define OFPPMFC_BAD_ADVERTISE 3U +#define OFPPMFC_EPERM 4U +static const struct tok ofppmfc_str[] = { + { OFPPMFC_BAD_PORT, "BAD_PORT" }, + { OFPPMFC_BAD_HW_ADDR, "BAD_HW_ADDR" }, + { OFPPMFC_BAD_CONFIG, "BAD_CONFIG" }, + { OFPPMFC_BAD_ADVERTISE, "BAD_ADVERTISE" }, + { OFPPMFC_EPERM, "EPERM" }, + { 0, NULL } +}; + +#define OFPTMFC_BAD_TABLE 0U +#define OFPTMFC_BAD_CONFIG 1U +#define OFPTMFC_EPERM 2U +static const struct tok ofptmfc_str[] = { + { OFPTMFC_BAD_TABLE, "BAD_TABLE" }, + { OFPTMFC_BAD_CONFIG, "BAD_CONFIG" }, + { OFPTMFC_EPERM, "EPERM" }, + { 0, NULL } +}; + +#define OFPQOFC_BAD_PORT 0U +#define OFPQOFC_BAD_QUEUE 1U +#define OFPQOFC_EPERM 2U +static const struct tok ofpqofc_str[] = { + { OFPQOFC_BAD_PORT, "BAD_PORT" }, + { OFPQOFC_BAD_QUEUE, "BAD_QUEUE" }, + { OFPQOFC_EPERM, "EPERM" }, + { 0, NULL } +}; + +#define OFPSCFC_BAD_FLAGS 0U +#define OFPSCFC_BAD_LEN 1U +#define OFPSCFC_EPERM 2U +static const struct tok ofpscfc_str[] = { + { OFPSCFC_BAD_FLAGS, "BAD_FLAGS" }, + { OFPSCFC_BAD_LEN, "BAD_LEN" }, + { OFPSCFC_EPERM, "EPERM" }, + { 0, NULL } +}; + +#define OFPRRFC_STALE 0U +#define OFPRRFC_UNSUP 1U +#define OFPRRFC_BAD_ROLE 2U +static const struct tok ofprrfc_str[] = { + { OFPRRFC_STALE, "STALE" }, + { OFPRRFC_UNSUP, "UNSUP" }, + { OFPRRFC_BAD_ROLE, "BAD_ROLE" }, + { 0, NULL } +}; + +#define OFPMMFC_UNKNOWN 0U +#define OFPMMFC_METER_EXISTS 1U +#define OFPMMFC_INVALID_METER 2U +#define OFPMMFC_UNKNOWN_METER 3U +#define OFPMMFC_BAD_COMMAND 4U +#define OFPMMFC_BAD_FLAGS 5U +#define OFPMMFC_BAD_RATE 6U +#define OFPMMFC_BAD_BURST 7U +#define OFPMMFC_BAD_BAND 8U +#define OFPMMFC_BAD_BAND_VALUE 9U +#define OFPMMFC_OUT_OF_METERS 10U +#define OFPMMFC_OUT_OF_BANDS 11U +static const struct tok ofpmmfc_str[] = { + { OFPMMFC_UNKNOWN, "UNKNOWN" }, + { OFPMMFC_METER_EXISTS, "METER_EXISTS" }, + { OFPMMFC_INVALID_METER, "INVALID_METER" }, + { OFPMMFC_UNKNOWN_METER, "UNKNOWN_METER" }, + { OFPMMFC_BAD_COMMAND, "BAD_COMMAND" }, + { OFPMMFC_BAD_FLAGS, "BAD_FLAGS" }, + { OFPMMFC_BAD_RATE, "BAD_RATE" }, + { OFPMMFC_BAD_BURST, "BAD_BURST" }, + { OFPMMFC_BAD_BAND, "BAD_BAND" }, + { OFPMMFC_BAD_BAND_VALUE, "BAD_BAND_VALUE" }, + { OFPMMFC_OUT_OF_METERS, "OUT_OF_METERS" }, + { OFPMMFC_OUT_OF_BANDS, "OUT_OF_BANDS" }, + { 0, NULL } +}; + +#define OFPTFFC_BAD_TABLE 0U +#define OFPTFFC_BAD_METADATA 1U +#define OFPTFFC_BAD_TYPE 2U +#define OFPTFFC_BAD_LEN 3U +#define OFPTFFC_BAD_ARGUMENT 4U +#define OFPTFFC_EPERM 5U +static const struct tok ofptffc_str[] = { + { OFPTFFC_BAD_TABLE, "BAD_TABLE" }, + { OFPTFFC_BAD_METADATA, "BAD_METADATA" }, + { OFPTFFC_BAD_TYPE, "BAD_TYPE" }, + { OFPTFFC_BAD_LEN, "BAD_LEN" }, + { OFPTFFC_BAD_ARGUMENT, "BAD_ARGUMENT" }, + { OFPTFFC_EPERM, "EPERM" }, + { 0, NULL } +}; + +static const struct uint_tokary of13_ofpet2tokary[] = { + { OFPET_HELLO_FAILED, ofphfc_str }, + { OFPET_BAD_REQUEST, ofpbrc_str }, + { OFPET_BAD_ACTION, ofpbac_str }, + { OFPET_BAD_INSTRUCTION, ofpbic_str }, + { OFPET_BAD_MATCH, ofpbmc_str }, + { OFPET_FLOW_MOD_FAILED, ofpfmfc_str }, + { OFPET_GROUP_MOD_FAILED, ofpgmfc_str }, + { OFPET_PORT_MOD_FAILED, ofppmfc_str }, + { OFPET_TABLE_MOD_FAILED, ofptmfc_str }, + { OFPET_QUEUE_OP_FAILED, ofpqofc_str }, + { OFPET_SWITCH_CONFIG_FAILED, ofpscfc_str }, + { OFPET_ROLE_REQUEST_FAILED, ofprrfc_str }, + { OFPET_METER_MOD_FAILED, ofpmmfc_str }, + { OFPET_TABLE_FEATURES_FAILED, ofptffc_str }, + { OFPET_EXPERIMENTER, NULL }, /* defines no codes */ + /* uint2tokary() does not use array termination. */ +}; + +/* lengths (fixed or minimal) of particular message types, where not 0 */ +#define OF_ERROR_MSG_MINLEN (12U - OF_HEADER_FIXLEN) +#define OF_FEATURES_REPLY_FIXLEN (32U - OF_HEADER_FIXLEN) +#define OF_PORT_MOD_FIXLEN (40U - OF_HEADER_FIXLEN) +#define OF_SWITCH_CONFIG_MSG_FIXLEN (12U - OF_HEADER_FIXLEN) +#define OF_TABLE_MOD_FIXLEN (16U - OF_HEADER_FIXLEN) +#define OF_QUEUE_GET_CONFIG_REQUEST_FIXLEN (16U - OF_HEADER_FIXLEN) +#define OF_ROLE_MSG_FIXLEN (24U - OF_HEADER_FIXLEN) +#define OF_ASYNC_MSG_FIXLEN (32U - OF_HEADER_FIXLEN) +#define OF_PORT_STATUS_FIXLEN (80U - OF_HEADER_FIXLEN) +#define OF_EXPERIMENTER_MSG_MINLEN (16U - OF_HEADER_FIXLEN) + +/* lengths (fixed or minimal) of particular protocol structures */ +#define OF_HELLO_ELEM_MINSIZE 4U + +/* miscellaneous constants from [OF13] */ +#define OFP_MAX_PORT_NAME_LEN 16U + +/* [OF13] Section 7.2.1 */ +static void +of13_port_print(netdissect_options *ndo, + const u_char *cp) +{ + /* port_no */ + ND_PRINT("\n\t port_no %s", + tok2str(ofpp_str, "%u", GET_BE_U_4(cp))); + cp += 4; + /* pad */ + cp += 4; + /* hw_addr */ + ND_PRINT(", hw_addr %s", GET_ETHERADDR_STRING(cp)); + cp += MAC_ADDR_LEN; + /* pad2 */ + cp += 2; + /* name */ + ND_PRINT(", name '"); + nd_printjnp(ndo, cp, OFP_MAX_PORT_NAME_LEN); + ND_PRINT("'"); + cp += OFP_MAX_PORT_NAME_LEN; + + if (ndo->ndo_vflag < 2) { + ND_TCHECK_LEN(cp, 32); + return; + } + + /* config */ + ND_PRINT("\n\t config 0x%08x", GET_BE_U_4(cp)); + of_bitmap_print(ndo, ofppc_bm, GET_BE_U_4(cp), OFPPC_U); + cp += 4; + /* state */ + ND_PRINT("\n\t state 0x%08x", GET_BE_U_4(cp)); + of_bitmap_print(ndo, ofpps_bm, GET_BE_U_4(cp), OFPPS_U);; + cp += 4; + /* curr */ + ND_PRINT("\n\t curr 0x%08x", GET_BE_U_4(cp)); + of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U); + cp += 4; + /* advertised */ + ND_PRINT("\n\t advertised 0x%08x", GET_BE_U_4(cp)); + of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U); + cp += 4; + /* supported */ + ND_PRINT("\n\t supported 0x%08x", GET_BE_U_4(cp)); + of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U); + cp += 4; + /* peer */ + ND_PRINT("\n\t peer 0x%08x", GET_BE_U_4(cp)); + of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U); + cp += 4; + /* curr_speed */ + ND_PRINT("\n\t curr_speed %ukbps", GET_BE_U_4(cp)); + cp += 4; + /* max_speed */ + ND_PRINT("\n\t max_speed %ukbps", GET_BE_U_4(cp)); +} + +/* [OF13] Section 7.3.1 */ +static void +of13_features_reply_print(netdissect_options *ndo, + const u_char *cp, u_int len _U_) +{ + /* datapath_id */ + ND_PRINT("\n\t dpid 0x%016" PRIx64, GET_BE_U_8(cp)); + cp += 8; + /* n_buffers */ + ND_PRINT(", n_buffers %u", GET_BE_U_4(cp)); + cp += 4; + /* n_tables */ + ND_PRINT(", n_tables %u", GET_U_1(cp)); + cp += 1; + /* auxiliary_id */ + ND_PRINT(", auxiliary_id %u", GET_U_1(cp)); + cp += 1; + /* pad */ + cp += 2; + /* capabilities */ + ND_PRINT("\n\t capabilities 0x%08x", GET_BE_U_4(cp)); + of_bitmap_print(ndo, ofp_capabilities_bm, GET_BE_U_4(cp), OFPCAP_U); + cp += 4; + /* reserved */ + ND_TCHECK_4(cp); +} + +/* [OF13] Section 7.3.2 */ +static void +of13_switch_config_msg_print(netdissect_options *ndo, + const u_char *cp, u_int len _U_) +{ + /* flags */ + ND_PRINT("\n\t flags %s", + tok2str(ofp_config_str, "invalid (0x%04x)", GET_BE_U_2(cp))); + cp += 2; + /* miss_send_len */ + ND_PRINT(", miss_send_len %s", + tok2str(ofpcml_str, "%u", GET_BE_U_2(cp))); +} + +/* [OF13] Section 7.3.3 */ +static void +of13_table_mod_print(netdissect_options *ndo, + const u_char *cp, u_int len _U_) +{ + /* table_id */ + ND_PRINT("\n\t table_id %s", tok2str(ofptt_str, "%u", GET_U_1(cp))); + cp += 1; + /* pad */ + cp += 3; + /* config */ + ND_PRINT(", config 0x%08x", GET_BE_U_4(cp)); +} + +/* [OF13] Section 7.3.9 */ +static void +of13_role_msg_print(netdissect_options *ndo, + const u_char *cp, u_int len _U_) +{ + /* role */ + ND_PRINT("\n\t role %s", + tok2str(ofpcr_str, "invalid (0x%08x)", GET_BE_U_4(cp))); + cp += 4; + /* pad */ + cp += 4; + /* generation_id */ + ND_PRINT(", generation_id 0x%016" PRIx64, GET_BE_U_8(cp)); +} + +/* [OF13] Section 7.3.10 */ +static void +of13_async_msg_print(netdissect_options *ndo, + const u_char *cp, u_int len _U_) +{ + /* packet_in_mask[0] */ + ND_PRINT("\n\t packet_in_mask[EM] 0x%08x", GET_BE_U_4(cp)); + of_bitmap_print(ndo, async_ofpr_bm, GET_BE_U_4(cp), ASYNC_OFPR_U); + cp += 4; + /* packet_in_mask[1] */ + ND_PRINT("\n\t packet_in_mask[S] 0x%08x", GET_BE_U_4(cp)); + of_bitmap_print(ndo, async_ofpr_bm, GET_BE_U_4(cp), ASYNC_OFPR_U); + cp += 4; + /* port_status_mask[0] */ + ND_PRINT("\n\t port_status_mask[EM] 0x%08x", GET_BE_U_4(cp)); + of_bitmap_print(ndo, async_ofppr_bm, GET_BE_U_4(cp), ASYNC_OFPPR_U); + cp += 4; + /* port_status_mask[1] */ + ND_PRINT("\n\t port_status_mask[S] 0x%08x", GET_BE_U_4(cp)); + of_bitmap_print(ndo, async_ofppr_bm, GET_BE_U_4(cp), ASYNC_OFPPR_U); + cp += 4; + /* flow_removed_mask[0] */ + ND_PRINT("\n\t flow_removed_mask[EM] 0x%08x", GET_BE_U_4(cp)); + of_bitmap_print(ndo, async_ofppr_bm, GET_BE_U_4(cp), ASYNC_OFPPR_U); + cp += 4; + /* flow_removed_mask[1] */ + ND_PRINT("\n\t flow_removed_mask[S] 0x%08x", GET_BE_U_4(cp)); + of_bitmap_print(ndo, async_ofppr_bm, GET_BE_U_4(cp), ASYNC_OFPPR_U); +} + +/* [OF13] Section 7.3.4.3 */ +static void +of13_port_mod_print(netdissect_options *ndo, + const u_char *cp, u_int len _U_) +{ + /* port_no */ + ND_PRINT("\n\t port_no %s", tok2str(ofpp_str, "%u", GET_BE_U_4(cp))); + cp += 4; + /* pad */ + cp += 4; + /* hw_addr */ + ND_PRINT(", hw_addr %s", GET_ETHERADDR_STRING(cp)); + cp += MAC_ADDR_LEN; + /* pad2 */ + cp += 2; + /* config */ + ND_PRINT("\n\t config 0x%08x", GET_BE_U_4(cp)); + of_bitmap_print(ndo, ofppc_bm, GET_BE_U_4(cp), OFPPC_U); + cp += 4; + /* mask */ + ND_PRINT("\n\t mask 0x%08x", GET_BE_U_4(cp)); + of_bitmap_print(ndo, ofppc_bm, GET_BE_U_4(cp), OFPPC_U); + cp += 4; + /* advertise */ + ND_PRINT("\n\t advertise 0x%08x", GET_BE_U_4(cp)); + of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U); + cp += 4; + /* pad3 */ + /* Always the last field, check bounds. */ + ND_TCHECK_4(cp); +} + +/* [OF13] Section 7.4.3 */ +static void +of13_port_status_print(netdissect_options *ndo, + const u_char *cp, u_int len _U_) +{ + /* reason */ + ND_PRINT("\n\t reason %s", + tok2str(ofppr_str, "invalid (0x02x)", GET_U_1(cp))); + cp += 1; + /* pad */ + cp += 7; + /* desc */ + of13_port_print(ndo, cp); +} + +/* [OF13] Section 7.5.1 */ +static void +of13_hello_elements_print(netdissect_options *ndo, + const u_char *cp, u_int len) +{ + while (len) { + uint16_t type, bmlen; + + if (len < OF_HELLO_ELEM_MINSIZE) + goto invalid; + /* type */ + type = GET_BE_U_2(cp); + OF_FWD(2); + ND_PRINT("\n\t type %s", + tok2str(ofphet_str, "unknown (0x%04x)", type)); + /* length */ + bmlen = GET_BE_U_2(cp); + OF_FWD(2); + ND_PRINT(", length %u", bmlen); + /* cp is OF_HELLO_ELEM_MINSIZE bytes in */ + if (bmlen < OF_HELLO_ELEM_MINSIZE || + bmlen > OF_HELLO_ELEM_MINSIZE + len) + goto invalid; + switch (type) { + case OFPHET_VERSIONBITMAP: + /* + * The specification obviously overprovisions the space + * for version bitmaps in this element ("ofp versions + * 32 to 63 are encoded in the second bitmap and so + * on"). Keep this code simple for now and recognize + * only a single bitmap with no padding. + */ + if (bmlen == OF_HELLO_ELEM_MINSIZE + 4) { + uint32_t bitmap = GET_BE_U_4(cp); + ND_PRINT(", bitmap 0x%08x", bitmap); + of_bitmap_print(ndo, ofverbm_str, bitmap, + OF_BIT_VER_U); + } else { + ND_PRINT(" (bogus)"); + ND_TCHECK_LEN(cp, bmlen - OF_HELLO_ELEM_MINSIZE); + } + break; + default: + ND_TCHECK_LEN(cp, bmlen - OF_HELLO_ELEM_MINSIZE); + } + OF_FWD(bmlen - OF_HELLO_ELEM_MINSIZE); + } + return; + +invalid: + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); +} + +/* [OF13] Section 7.5.4 */ +static void +of13_experimenter_message_print(netdissect_options *ndo, + const u_char *cp, u_int len) +{ + uint32_t experimenter; + + /* experimenter */ + experimenter = GET_BE_U_4(cp); + OF_FWD(4); + ND_PRINT("\n\t experimenter 0x%08x (%s)", experimenter, + of_vendor_name(experimenter)); + /* exp_type */ + ND_PRINT(", exp_type 0x%08x", GET_BE_U_4(cp)); + OF_FWD(4); + /* data */ + of_data_print(ndo, cp, len); +} + +/* [OF13] Section 7.3.6 */ +static void +of13_queue_get_config_request_print(netdissect_options *ndo, + const u_char *cp, u_int len _U_) +{ + /* port */ + ND_PRINT("\n\t port %s", tok2str(ofpp_str, "%u", GET_BE_U_4(cp))); + cp += 4; + /* pad */ + /* Always the last field, check bounds. */ + ND_TCHECK_4(cp); +} + +/* [OF13] Section 7.4.4 */ +static void +of13_error_print(netdissect_options *ndo, + const u_char *cp, u_int len) +{ + uint16_t type, code; + const struct tok *code_str; + + /* type */ + type = GET_BE_U_2(cp); + OF_FWD(2); + ND_PRINT("\n\t type %s", tok2str(ofpet_str, "invalid (0x%04x)", type)); + /* code */ + code = GET_BE_U_2(cp); + OF_FWD(2); + code_str = uint2tokary(of13_ofpet2tokary, type); + if (code_str != NULL) + ND_PRINT(", code %s", + tok2str(code_str, "invalid (0x%04x)", code)); + else + ND_PRINT(", code invalid (0x%04x)", code); + /* data */ + of_data_print(ndo, cp, len); +} + +static const struct of_msgtypeinfo of13_msgtypeinfo[OFPT_MAX + 1] = { + /* + * [OF13] Section 7.5.1 + * n * variable-size data units. + */ + { + "HELLO", of13_hello_elements_print, + REQ_MINLEN, 0 + }, + /* + * [OF13] Section 7.4.4 + * A fixed-size message body and variable-size data. + */ + { + "ERROR", of13_error_print, + REQ_MINLEN, OF_ERROR_MSG_MINLEN + }, + /* + * [OF13] Section 7.5.2 + * Variable-size data. + */ + { + "ECHO_REQUEST", of_data_print, + REQ_MINLEN, 0 + }, + /* + * [OF13] Section 7.5.3 + * Variable-size data. + */ + { + "ECHO_REPLY", of_data_print, + REQ_MINLEN, 0 + }, + /* + * [OF13] Section 7.5.4 + * A fixed-size message body and variable-size data. + */ + { + "EXPERIMENTER", of13_experimenter_message_print, + REQ_MINLEN, OF_EXPERIMENTER_MSG_MINLEN + }, + /* + * [OF13] Section 7.3.1 + * No message body. + */ + { + "FEATURES_REQUEST", NULL, + REQ_FIXLEN, 0 + }, + /* + * [OF13] Section 7.3.1 + * A fixed-size message body. + */ + { + "FEATURES_REPLY", of13_features_reply_print, + REQ_FIXLEN, OF_FEATURES_REPLY_FIXLEN + }, + /* + * [OF13] Section 7.3.2 + * No message body. + */ + { + "GET_CONFIG_REQUEST", NULL, + REQ_FIXLEN, 0 + }, + /* + * [OF13] Section 7.3.2 + * A fixed-size message body. + */ + { + "GET_CONFIG_REPLY", of13_switch_config_msg_print, + REQ_FIXLEN, OF_SWITCH_CONFIG_MSG_FIXLEN + }, + /* + * [OF13] Section 7.3.2 + * A fixed-size message body. + */ + { + "SET_CONFIG", of13_switch_config_msg_print, + REQ_FIXLEN, OF_SWITCH_CONFIG_MSG_FIXLEN + }, + /* + * [OF13] Section 7.4.1 + * (to be done) + */ + { + "PACKET_IN", NULL, + REQ_NONE, 0 + }, + /* + * [OF13] Section 7.4.2 + * (to be done) + */ + { + "FLOW_REMOVED", NULL, + REQ_NONE, 0 + }, + /* + * [OF13] Section 7.4.3 + * A fixed-size message body. + */ + { + "PORT_STATUS", of13_port_status_print, + REQ_FIXLEN, OF_PORT_STATUS_FIXLEN + }, + /* + * [OF13] Section 7.3.7 + * (to be done) + */ + { + "PACKET_OUT", NULL, + REQ_NONE, 0 + }, + /* + * [OF13] Section 7.3.4.1 + * (to be done) + */ + { + "FLOW_MOD", NULL, + REQ_NONE, 0 + }, + /* + * [OF13] Section 7.3.4.2 + * (to be done) + */ + { + "GROUP_MOD", NULL, + REQ_NONE, 0 + }, + /* + * [OF13] Section 7.3.4.3 + * A fixed-size message body. + */ + { + "PORT_MOD", of13_port_mod_print, + REQ_FIXLEN, OF_PORT_MOD_FIXLEN + }, + /* + * [OF13] Section 7.3.3 + * A fixed-size message body. + */ + { + "TABLE_MOD", of13_table_mod_print, + REQ_FIXLEN, OF_TABLE_MOD_FIXLEN + }, + /* + * [OF13] Section 7.3.5 + * (to be done) + */ + { + "MULTIPART_REQUEST", NULL, + REQ_NONE, 0 + }, + /* + * [OF13] Section 7.3.5 + * (to be done) + */ + { + "MULTIPART_REPLY", NULL, + REQ_NONE, 0 + }, + /* + * [OF13] Section 7.3.8 + * No message body. + */ + { + "BARRIER_REQUEST", NULL, + REQ_FIXLEN, 0 + }, + /* + * [OF13] Section 7.3.8 + * No message body. + */ + { + "BARRIER_REPLY", NULL, + REQ_FIXLEN, 0 + }, + /* + * [OF13] Section 7.3.6 + * A fixed-size message body. + */ + { + "QUEUE_GET_CONFIG_REQUEST", of13_queue_get_config_request_print, + REQ_FIXLEN, OF_QUEUE_GET_CONFIG_REQUEST_FIXLEN + }, + /* + * [OF13] Section 7.3.6 + * (to be done) + */ + { + "QUEUE_GET_CONFIG_REPLY", NULL, + REQ_NONE, 0 + }, + /* + * [OF13] Section 7.3.9 + * A fixed-size message body. + */ + { + "ROLE_REQUEST", of13_role_msg_print, + REQ_FIXLEN, OF_ROLE_MSG_FIXLEN + }, + /* + * [OF13] Section 7.3.9 + * A fixed-size message body. + */ + { + "ROLE_REPLY", of13_role_msg_print, + REQ_FIXLEN, OF_ROLE_MSG_FIXLEN + }, + /* + * [OF13] Section 7.3.10 + * No message body. + */ + { + "GET_ASYNC_REQUEST", NULL, + REQ_FIXLEN, 0 + }, + /* + * [OF13] Section 7.3.10 + * A fixed-size message body. + */ + { + "GET_ASYNC_REPLY", of13_async_msg_print, + REQ_FIXLEN, OF_ASYNC_MSG_FIXLEN + }, + /* + * [OF13] Section 7.3.10 + * A fixed-size message body. + */ + { + "SET_ASYNC", of13_async_msg_print, + REQ_FIXLEN, OF_ASYNC_MSG_FIXLEN + }, + /* + * [OF13] Section 7.3.4.4 + * (to be done) + */ + { + "METER_MOD", NULL, + REQ_NONE, 0 + }, +}; + +const struct of_msgtypeinfo * +of13_identify_msgtype(const uint8_t type) +{ + return type <= OFPT_MAX ? &of13_msgtypeinfo[type] : NULL; +} diff --git a/contrib/tcpdump/print-openflow.c b/contrib/tcpdump/print-openflow.c index 0b80981ee0..6024a215a1 100644 --- a/contrib/tcpdump/print-openflow.c +++ b/contrib/tcpdump/print-openflow.c @@ -33,19 +33,27 @@ /* \summary: version-independent OpenFlow printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" #include "openflow.h" #include "oui.h" -static const char tstr[] = " [|openflow]"; -#define OF_VER_1_0 0x01 +static const struct tok ofver_str[] = { + { OF_VER_1_0, "1.0" }, + { OF_VER_1_1, "1.1" }, + { OF_VER_1_2, "1.2" }, + { OF_VER_1_3, "1.3" }, + { OF_VER_1_4, "1.4" }, + { OF_VER_1_5, "1.5" }, + { 0, NULL } +}; const struct tok onf_exp_str[] = { { ONF_EXP_ONF, "ONF Extensions" }, @@ -56,6 +64,9 @@ const struct tok onf_exp_str[] = { { ONF_EXP_WMOB, "Wireless and Mobility Extensions" }, { ONF_EXP_FABS, "Forwarding Abstractions Extensions" }, { ONF_EXP_OTRANS, "Optical Transport Extensions" }, + { ONF_EXP_NBLNCTU, "Network Benchmarking Lab, NCTU" }, + { ONF_EXP_MPCE, "Mobile Packet Core Extensions" }, + { ONF_EXP_MPLSTPSPTN, "MPLS-TP OpenFlow Extensions for SPTN" }, { 0, NULL } }; @@ -66,75 +77,152 @@ of_vendor_name(const uint32_t vendor) return tok2str(table, "unknown", vendor); } -static void -of_header_print(netdissect_options *ndo, const uint8_t version, const uint8_t type, - const uint16_t length, const uint32_t xid) +void +of_bitmap_print(netdissect_options *ndo, + const struct tok *t, const uint32_t v, const uint32_t u) { - ND_PRINT((ndo, "\n\tversion unknown (0x%02x), type 0x%02x, length %u, xid 0x%08x", - version, type, length, xid)); + /* Assigned bits? */ + if (v & ~u) + ND_PRINT(" (%s)", bittok2str(t, "", v)); + /* Unassigned bits? */ + if (v & u) + ND_PRINT(" (bogus)"); } -/* Print a single OpenFlow message. */ -static const u_char * -of_header_body_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) +void +of_data_print(netdissect_options *ndo, + const u_char *cp, const u_int len) { - uint8_t version, type; - uint16_t length; - uint32_t xid; + if (len == 0) + return; + /* data */ + ND_PRINT("\n\t data (%u octets)", len); + if (ndo->ndo_vflag >= 2) + hex_and_ascii_print(ndo, "\n\t ", cp, len); + else + ND_TCHECK_LEN(cp, len); +} - if (ep < cp + OF_HEADER_LEN) - goto invalid; - /* version */ - ND_TCHECK2(*cp, 1); - version = *cp; - cp += 1; - /* type */ - ND_TCHECK2(*cp, 1); - type = *cp; - cp += 1; - /* length */ - ND_TCHECK2(*cp, 2); - length = EXTRACT_16BITS(cp); - cp += 2; - /* xid */ - ND_TCHECK2(*cp, 4); - xid = EXTRACT_32BITS(cp); - cp += 4; - /* Message length includes the header length and a message always includes - * the basic header. A message length underrun fails decoding of the rest of - * the current packet. At the same time, try decoding as much of the current - * message as possible even when it does not end within the current TCP - * segment. */ - if (length < OF_HEADER_LEN) { - of_header_print(ndo, version, type, length, xid); +static void +of_message_print(netdissect_options *ndo, + const u_char *cp, uint16_t len, + const struct of_msgtypeinfo *mti) +{ + /* + * Here "cp" and "len" stand for the message part beyond the common + * OpenFlow 1.0 header, if any. + * + * Most message types are longer than just the header, and the length + * constraints may be complex. When possible, validate the constraint + * completely here (REQ_FIXLEN), otherwise check that the message is + * long enough to begin the decoding (REQ_MINLEN) and have the + * type-specific function do any remaining validation. + */ + + if (!mti) + goto tcheck_remainder; + + if ((mti->req_what == REQ_FIXLEN && len != mti->req_value) || + (mti->req_what == REQ_MINLEN && len < mti->req_value)) goto invalid; - } - /* Decode known protocol versions further without printing the header (the - * type decoding is version-specific. */ - switch (version) { - case OF_VER_1_0: - return of10_header_body_print(ndo, cp, ep, type, length, xid); - default: - of_header_print(ndo, version, type, length, xid); - ND_TCHECK2(*cp, length - OF_HEADER_LEN); - return cp + length - OF_HEADER_LEN; /* done with current message */ - } - -invalid: /* fail current packet */ - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*cp, ep - cp); - return ep; -trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; + + if (!ndo->ndo_vflag || !mti->decoder) + goto tcheck_remainder; + + mti->decoder(ndo, cp, len); + return; + +invalid: + nd_print_invalid(ndo); +tcheck_remainder: + ND_TCHECK_LEN(cp, len); } /* Print a TCP segment worth of OpenFlow messages presuming the segment begins * on a message boundary. */ void -openflow_print(netdissect_options *ndo, const u_char *cp, const u_int len _U_) +openflow_print(netdissect_options *ndo, const u_char *cp, u_int len) { - ND_PRINT((ndo, ": OpenFlow")); - while (cp < ndo->ndo_snapend) - cp = of_header_body_print(ndo, cp, ndo->ndo_snapend); + ndo->ndo_protocol = "openflow"; + ND_PRINT(": OpenFlow"); + while (len) { + /* Print a single OpenFlow message. */ + uint8_t version, type; + uint16_t length; + const struct of_msgtypeinfo *mti; + + /* version */ + version = GET_U_1(cp); + OF_FWD(1); + ND_PRINT("\n\tversion %s", + tok2str(ofver_str, "unknown (0x%02x)", version)); + /* type */ + if (len < 1) + goto partial_header; + type = GET_U_1(cp); + OF_FWD(1); + mti = + version == OF_VER_1_0 ? of10_identify_msgtype(type) : + version == OF_VER_1_3 ? of13_identify_msgtype(type) : + NULL; + if (mti && mti->name) + ND_PRINT(", type %s", mti->name); + else + ND_PRINT(", type unknown (0x%02x)", type); + /* length */ + if (len < 2) + goto partial_header; + length = GET_BE_U_2(cp); + OF_FWD(2); + ND_PRINT(", length %u%s", length, + length < OF_HEADER_FIXLEN ? " (too short!)" : ""); + /* xid */ + if (len < 4) + goto partial_header; + ND_PRINT(", xid 0x%08x", GET_BE_U_4(cp)); + OF_FWD(4); + + /* + * When a TCP packet can contain several protocol messages, + * and at the same time a protocol message can span several + * TCP packets, decoding an incomplete message at the end of + * a TCP packet requires attention to detail in this loop. + * + * Message length includes the header length and a message + * always includes the basic header. A message length underrun + * fails decoding of the rest of the current packet. At the + * same time, try decoding as much of the current message as + * possible even when it does not end within the current TCP + * segment. + * + * Specifically, to try to process the message body in this + * iteration do NOT require the header "length" to be small + * enough for the full declared OpenFlow message to fit into + * the remainder of the declared TCP segment, same as the full + * declared TCP segment is not required to fit into the + * captured packet buffer. + * + * But DO require the same at the end of this iteration to + * decrement "len" and to proceed to the next iteration. + * (Ideally the declared TCP payload end will be at or after + * the captured packet buffer end, but stay safe even when + * that's somehow not the case.) + */ + if (length < OF_HEADER_FIXLEN) + goto invalid; + + of_message_print(ndo, cp, length - OF_HEADER_FIXLEN, mti); + if (length - OF_HEADER_FIXLEN > len) + break; + OF_FWD(length - OF_HEADER_FIXLEN); + } /* while (len) */ + return; + +partial_header: + ND_PRINT(" (end of TCP payload)"); + ND_TCHECK_LEN(cp, len); + return; +invalid: /* fail the current packet */ + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); } diff --git a/contrib/tcpdump/print-ospf.c b/contrib/tcpdump/print-ospf.c index 4c09912a98..c370bda71b 100644 --- a/contrib/tcpdump/print-ospf.c +++ b/contrib/tcpdump/print-ospf.c @@ -24,10 +24,10 @@ /* \summary: Open Shortest Path First (OSPF) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "addrtoname.h" @@ -36,14 +36,13 @@ #include "ospf.h" -static const char tstr[] = " [|ospf2]"; static const struct tok ospf_option_values[] = { - { OSPF_OPTION_T, "MultiTopology" }, /* draft-ietf-ospf-mt-09 */ + { OSPF_OPTION_MT, "MultiTopology" }, /* draft-ietf-ospf-mt-09 */ { OSPF_OPTION_E, "External" }, { OSPF_OPTION_MC, "Multicast" }, { OSPF_OPTION_NP, "NSSA" }, - { OSPF_OPTION_L, "LLS" }, + { OSPF_OPTION_L, "LLS" }, { OSPF_OPTION_DC, "Demand Circuit" }, { OSPF_OPTION_O, "Opaque" }, { OSPF_OPTION_DN, "Up/Down" }, @@ -66,7 +65,6 @@ static const struct tok ospf_rla_flag_values[] = { }; static const struct tok type2str[] = { - { OSPF_TYPE_UMD, "UMD" }, { OSPF_TYPE_HELLO, "Hello" }, { OSPF_TYPE_DD, "Database Description" }, { OSPF_TYPE_LS_REQ, "LS-Request" }, @@ -181,31 +179,31 @@ static const struct tok ospf_lls_eo_options[] = { }; int -ospf_print_grace_lsa(netdissect_options *ndo, - const uint8_t *tptr, u_int ls_length) +ospf_grace_lsa_print(netdissect_options *ndo, + const u_char *tptr, u_int ls_length) { u_int tlv_type, tlv_length; while (ls_length > 0) { - ND_TCHECK2(*tptr, 4); + ND_TCHECK_4(tptr); if (ls_length < 4) { - ND_PRINT((ndo, "\n\t Remaining LS length %u < 4", ls_length)); + ND_PRINT("\n\t Remaining LS length %u < 4", ls_length); return -1; } - tlv_type = EXTRACT_16BITS(tptr); - tlv_length = EXTRACT_16BITS(tptr+2); + tlv_type = GET_BE_U_2(tptr); + tlv_length = GET_BE_U_2(tptr + 2); tptr+=4; ls_length-=4; - ND_PRINT((ndo, "\n\t %s TLV (%u), length %u, value: ", + ND_PRINT("\n\t %s TLV (%u), length %u, value: ", tok2str(lsa_opaque_grace_tlv_values,"unknown",tlv_type), tlv_type, - tlv_length)); + tlv_length); if (tlv_length > ls_length) { - ND_PRINT((ndo, "\n\t Bogus length %u > %u", tlv_length, - ls_length)); + ND_PRINT("\n\t Bogus length %u > %u", tlv_length, + ls_length); return -1; } @@ -214,33 +212,33 @@ ospf_print_grace_lsa(netdissect_options *ndo, return -1; } - ND_TCHECK2(*tptr, tlv_length); + ND_TCHECK_LEN(tptr, tlv_length); switch(tlv_type) { case LS_OPAQUE_GRACE_TLV_PERIOD: if (tlv_length != 4) { - ND_PRINT((ndo, "\n\t Bogus length %u != 4", tlv_length)); + ND_PRINT("\n\t Bogus length %u != 4", tlv_length); return -1; } - ND_PRINT((ndo, "%us", EXTRACT_32BITS(tptr))); + ND_PRINT("%us", GET_BE_U_4(tptr)); break; case LS_OPAQUE_GRACE_TLV_REASON: if (tlv_length != 1) { - ND_PRINT((ndo, "\n\t Bogus length %u != 1", tlv_length)); + ND_PRINT("\n\t Bogus length %u != 1", tlv_length); return -1; } - ND_PRINT((ndo, "%s (%u)", - tok2str(lsa_opaque_grace_tlv_reason_values, "Unknown", *tptr), - *tptr)); + ND_PRINT("%s (%u)", + tok2str(lsa_opaque_grace_tlv_reason_values, "Unknown", GET_U_1(tptr)), + GET_U_1(tptr)); break; case LS_OPAQUE_GRACE_TLV_INT_ADDRESS: if (tlv_length != 4) { - ND_PRINT((ndo, "\n\t Bogus length %u != 4", tlv_length)); + ND_PRINT("\n\t Bogus length %u != 4", tlv_length); return -1; } - ND_PRINT((ndo, "%s", ipaddr_string(ndo, tptr))); + ND_PRINT("%s", GET_IPADDR_STRING(tptr)); break; default: @@ -264,8 +262,8 @@ trunc: } int -ospf_print_te_lsa(netdissect_options *ndo, - const uint8_t *tptr, u_int ls_length) +ospf_te_lsa_print(netdissect_options *ndo, + const u_char *tptr, u_int ls_length) { u_int tlv_type, tlv_length, subtlv_type, subtlv_length; u_int priority_level, te_class, count_srlg; @@ -275,24 +273,24 @@ ospf_print_te_lsa(netdissect_options *ndo, } bw; while (ls_length != 0) { - ND_TCHECK2(*tptr, 4); + ND_TCHECK_4(tptr); if (ls_length < 4) { - ND_PRINT((ndo, "\n\t Remaining LS length %u < 4", ls_length)); + ND_PRINT("\n\t Remaining LS length %u < 4", ls_length); return -1; } - tlv_type = EXTRACT_16BITS(tptr); - tlv_length = EXTRACT_16BITS(tptr+2); + tlv_type = GET_BE_U_2(tptr); + tlv_length = GET_BE_U_2(tptr + 2); tptr+=4; ls_length-=4; - ND_PRINT((ndo, "\n\t %s TLV (%u), length: %u", + ND_PRINT("\n\t %s TLV (%u), length: %u", tok2str(lsa_opaque_te_tlv_values,"unknown",tlv_type), tlv_type, - tlv_length)); + tlv_length); if (tlv_length > ls_length) { - ND_PRINT((ndo, "\n\t Bogus length %u > %u", tlv_length, - ls_length)); + ND_PRINT("\n\t Bogus length %u > %u", tlv_length, + ls_length); return -1; } @@ -303,15 +301,14 @@ ospf_print_te_lsa(netdissect_options *ndo, switch(tlv_type) { case LS_OPAQUE_TE_TLV_LINK: - while (tlv_length >= sizeof(subtlv_type) + sizeof(subtlv_length)) { + while (tlv_length != 0) { if (tlv_length < 4) { - ND_PRINT((ndo, "\n\t Remaining TLV length %u < 4", - tlv_length)); + ND_PRINT("\n\t Remaining TLV length %u < 4", + tlv_length); return -1; } - ND_TCHECK2(*tptr, 4); - subtlv_type = EXTRACT_16BITS(tptr); - subtlv_length = EXTRACT_16BITS(tptr+2); + subtlv_type = GET_BE_U_2(tptr); + subtlv_length = GET_BE_U_2(tptr + 2); tptr+=4; tlv_length-=4; @@ -319,146 +316,151 @@ ospf_print_te_lsa(netdissect_options *ndo, if (subtlv_type == 0 || subtlv_length == 0) goto invalid; - ND_PRINT((ndo, "\n\t %s subTLV (%u), length: %u", + ND_PRINT("\n\t %s subTLV (%u), length: %u", tok2str(lsa_opaque_te_link_tlv_subtlv_values,"unknown",subtlv_type), subtlv_type, - subtlv_length)); + subtlv_length); - ND_TCHECK2(*tptr, subtlv_length); + if (tlv_length < subtlv_length) { + ND_PRINT("\n\t Remaining TLV length %u < %u", + tlv_length + 4, subtlv_length + 4); + return -1; + } + ND_TCHECK_LEN(tptr, subtlv_length); switch(subtlv_type) { case LS_OPAQUE_TE_LINK_SUBTLV_ADMIN_GROUP: if (subtlv_length != 4) { - ND_PRINT((ndo, " != 4")); + ND_PRINT(" != 4"); goto invalid; } - ND_PRINT((ndo, ", 0x%08x", EXTRACT_32BITS(tptr))); + ND_PRINT(", 0x%08x", GET_BE_U_4(tptr)); break; case LS_OPAQUE_TE_LINK_SUBTLV_LINK_ID: case LS_OPAQUE_TE_LINK_SUBTLV_LINK_LOCAL_REMOTE_ID: if (subtlv_length != 4 && subtlv_length != 8) { - ND_PRINT((ndo, " != 4 && != 8")); + ND_PRINT(" != 4 && != 8"); goto invalid; } - ND_PRINT((ndo, ", %s (0x%08x)", - ipaddr_string(ndo, tptr), - EXTRACT_32BITS(tptr))); + ND_PRINT(", %s (0x%08x)", + GET_IPADDR_STRING(tptr), + GET_BE_U_4(tptr)); if (subtlv_length == 8) /* rfc4203 */ - ND_PRINT((ndo, ", %s (0x%08x)", - ipaddr_string(ndo, tptr+4), - EXTRACT_32BITS(tptr + 4))); + ND_PRINT(", %s (0x%08x)", + GET_IPADDR_STRING(tptr+4), + GET_BE_U_4(tptr + 4)); break; case LS_OPAQUE_TE_LINK_SUBTLV_LOCAL_IP: case LS_OPAQUE_TE_LINK_SUBTLV_REMOTE_IP: if (subtlv_length != 4) { - ND_PRINT((ndo, " != 4")); + ND_PRINT(" != 4"); goto invalid; } - ND_PRINT((ndo, ", %s", ipaddr_string(ndo, tptr))); + ND_PRINT(", %s", GET_IPADDR_STRING(tptr)); break; case LS_OPAQUE_TE_LINK_SUBTLV_MAX_BW: case LS_OPAQUE_TE_LINK_SUBTLV_MAX_RES_BW: if (subtlv_length != 4) { - ND_PRINT((ndo, " != 4")); + ND_PRINT(" != 4"); goto invalid; } - bw.i = EXTRACT_32BITS(tptr); - ND_PRINT((ndo, ", %.3f Mbps", bw.f * 8 / 1000000)); + bw.i = GET_BE_U_4(tptr); + ND_PRINT(", %.3f Mbps", bw.f * 8 / 1000000); break; case LS_OPAQUE_TE_LINK_SUBTLV_UNRES_BW: if (subtlv_length != 32) { - ND_PRINT((ndo, " != 32")); + ND_PRINT(" != 32"); goto invalid; } for (te_class = 0; te_class < 8; te_class++) { - bw.i = EXTRACT_32BITS(tptr+te_class*4); - ND_PRINT((ndo, "\n\t\tTE-Class %u: %.3f Mbps", + bw.i = GET_BE_U_4(tptr + te_class * 4); + ND_PRINT("\n\t\tTE-Class %u: %.3f Mbps", te_class, - bw.f * 8 / 1000000)); + bw.f * 8 / 1000000); } break; case LS_OPAQUE_TE_LINK_SUBTLV_BW_CONSTRAINTS: if (subtlv_length < 4) { - ND_PRINT((ndo, " < 4")); + ND_PRINT(" < 4"); goto invalid; } /* BC Model Id (1 octet) + Reserved (3 octets) */ - ND_PRINT((ndo, "\n\t\tBandwidth Constraints Model ID: %s (%u)", - tok2str(diffserv_te_bc_values, "unknown", *tptr), - *tptr)); + ND_PRINT("\n\t\tBandwidth Constraints Model ID: %s (%u)", + tok2str(diffserv_te_bc_values, "unknown", GET_U_1(tptr)), + GET_U_1(tptr)); if (subtlv_length % 4 != 0) { - ND_PRINT((ndo, "\n\t\tlength %u != N x 4", subtlv_length)); + ND_PRINT("\n\t\tlength %u != N x 4", subtlv_length); goto invalid; } if (subtlv_length > 36) { - ND_PRINT((ndo, "\n\t\tlength %u > 36", subtlv_length)); + ND_PRINT("\n\t\tlength %u > 36", subtlv_length); goto invalid; } /* decode BCs until the subTLV ends */ for (te_class = 0; te_class < (subtlv_length-4)/4; te_class++) { - bw.i = EXTRACT_32BITS(tptr+4+te_class*4); - ND_PRINT((ndo, "\n\t\t Bandwidth constraint CT%u: %.3f Mbps", + bw.i = GET_BE_U_4(tptr + 4 + te_class * 4); + ND_PRINT("\n\t\t Bandwidth constraint CT%u: %.3f Mbps", te_class, - bw.f * 8 / 1000000)); + bw.f * 8 / 1000000); } break; case LS_OPAQUE_TE_LINK_SUBTLV_TE_METRIC: if (subtlv_length != 4) { - ND_PRINT((ndo, " != 4")); + ND_PRINT(" != 4"); goto invalid; } - ND_PRINT((ndo, ", Metric %u", EXTRACT_32BITS(tptr))); + ND_PRINT(", Metric %u", GET_BE_U_4(tptr)); break; case LS_OPAQUE_TE_LINK_SUBTLV_LINK_PROTECTION_TYPE: /* Protection Cap (1 octet) + Reserved ((3 octets) */ if (subtlv_length != 4) { - ND_PRINT((ndo, " != 4")); + ND_PRINT(" != 4"); goto invalid; } - ND_PRINT((ndo, ", %s", - bittok2str(gmpls_link_prot_values, "none", *tptr))); + ND_PRINT(", %s", + bittok2str(gmpls_link_prot_values, "none", GET_U_1(tptr))); break; case LS_OPAQUE_TE_LINK_SUBTLV_INTF_SW_CAP_DESCR: if (subtlv_length < 36) { - ND_PRINT((ndo, " < 36")); + ND_PRINT(" < 36"); goto invalid; } /* Switching Cap (1 octet) + Encoding (1) + Reserved (2) */ - ND_PRINT((ndo, "\n\t\tInterface Switching Capability: %s", - tok2str(gmpls_switch_cap_values, "Unknown", *(tptr)))); - ND_PRINT((ndo, "\n\t\tLSP Encoding: %s\n\t\tMax LSP Bandwidth:", - tok2str(gmpls_encoding_values, "Unknown", *(tptr + 1)))); + ND_PRINT("\n\t\tInterface Switching Capability: %s", + tok2str(gmpls_switch_cap_values, "Unknown", GET_U_1((tptr)))); + ND_PRINT("\n\t\tLSP Encoding: %s\n\t\tMax LSP Bandwidth:", + tok2str(gmpls_encoding_values, "Unknown", GET_U_1((tptr + 1)))); for (priority_level = 0; priority_level < 8; priority_level++) { - bw.i = EXTRACT_32BITS(tptr+4+(priority_level*4)); - ND_PRINT((ndo, "\n\t\t priority level %d: %.3f Mbps", + bw.i = GET_BE_U_4(tptr + 4 + (priority_level * 4)); + ND_PRINT("\n\t\t priority level %u: %.3f Mbps", priority_level, - bw.f * 8 / 1000000)); + bw.f * 8 / 1000000); } break; case LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE: if (subtlv_length != 1) { - ND_PRINT((ndo, " != 1")); + ND_PRINT(" != 1"); goto invalid; } - ND_PRINT((ndo, ", %s (%u)", - tok2str(lsa_opaque_te_tlv_link_type_sub_tlv_values,"unknown",*tptr), - *tptr)); + ND_PRINT(", %s (%u)", + tok2str(lsa_opaque_te_tlv_link_type_sub_tlv_values,"unknown",GET_U_1(tptr)), + GET_U_1(tptr)); break; case LS_OPAQUE_TE_LINK_SUBTLV_SHARED_RISK_GROUP: if (subtlv_length % 4 != 0) { - ND_PRINT((ndo, " != N x 4")); + ND_PRINT(" != N x 4"); goto invalid; } count_srlg = subtlv_length / 4; if (count_srlg != 0) - ND_PRINT((ndo, "\n\t\t Shared risk group: ")); + ND_PRINT("\n\t\t Shared risk group: "); while (count_srlg > 0) { - bw.i = EXTRACT_32BITS(tptr); - ND_PRINT((ndo, "%d", bw.i)); + bw.i = GET_BE_U_4(tptr); + ND_PRINT("%u", bw.i); tptr+=4; count_srlg--; if (count_srlg > 0) - ND_PRINT((ndo, ", ")); + ND_PRINT(", "); } break; @@ -473,6 +475,11 @@ ospf_print_te_lsa(netdissect_options *ndo, if (subtlv_length%4 != 0) subtlv_length+=4-(subtlv_length%4); + if (tlv_length < subtlv_length) { + ND_PRINT("\n\t Remaining TLV length %u < %u", + tlv_length + 4, subtlv_length + 4); + return -1; + } tlv_length-=subtlv_length; tptr+=subtlv_length; @@ -481,11 +488,10 @@ ospf_print_te_lsa(netdissect_options *ndo, case LS_OPAQUE_TE_TLV_ROUTER: if (tlv_length < 4) { - ND_PRINT((ndo, "\n\t TLV length %u < 4", tlv_length)); + ND_PRINT("\n\t TLV length %u < 4", tlv_length); return -1; } - ND_TCHECK2(*tptr, 4); - ND_PRINT((ndo, ", %s", ipaddr_string(ndo, tptr))); + ND_PRINT(", %s", GET_IPADDR_STRING(tptr)); break; default: @@ -498,6 +504,11 @@ ospf_print_te_lsa(netdissect_options *ndo, /* in OSPF everything has to be 32-bit aligned, including TLVs */ if (tlv_length%4 != 0) tlv_length+=4-(tlv_length%4); + if (tlv_length > ls_length) { + ND_PRINT("\n\t Bogus padded length %u > %u", tlv_length, + ls_length); + return -1; + } ls_length-=tlv_length; tptr+=tlv_length; } @@ -505,65 +516,59 @@ ospf_print_te_lsa(netdissect_options *ndo, trunc: return -1; invalid: - ND_PRINT((ndo, "%s", istr)); + nd_print_invalid(ndo); return -1; } static int ospf_print_lshdr(netdissect_options *ndo, - register const struct lsa_hdr *lshp) + const struct lsa_hdr *lshp) { + u_int ls_type; u_int ls_length; - ND_TCHECK(lshp->ls_length); - ls_length = EXTRACT_16BITS(&lshp->ls_length); + ls_length = GET_BE_U_2(lshp->ls_length); if (ls_length < sizeof(struct lsa_hdr)) { - ND_PRINT((ndo, "\n\t Bogus length %u < header (%lu)", ls_length, - (unsigned long)sizeof(struct lsa_hdr))); + ND_PRINT("\n\t Bogus length %u < header (%zu)", ls_length, + sizeof(struct lsa_hdr)); return(-1); } - - ND_TCHECK(lshp->ls_seq); /* XXX - ls_length check checked this */ - ND_PRINT((ndo, "\n\t Advertising Router %s, seq 0x%08x, age %us, length %u", - ipaddr_string(ndo, &lshp->ls_router), - EXTRACT_32BITS(&lshp->ls_seq), - EXTRACT_16BITS(&lshp->ls_age), - ls_length - (u_int)sizeof(struct lsa_hdr))); - - ND_TCHECK(lshp->ls_type); /* XXX - ls_length check checked this */ - switch (lshp->ls_type) { + ND_PRINT("\n\t Advertising Router %s, seq 0x%08x, age %us, length %zu", + GET_IPADDR_STRING(lshp->ls_router), + GET_BE_U_4(lshp->ls_seq), + GET_BE_U_2(lshp->ls_age), + ls_length - sizeof(struct lsa_hdr)); + ls_type = GET_U_1(lshp->ls_type); + switch (ls_type) { /* the LSA header for opaque LSAs was slightly changed */ case LS_TYPE_OPAQUE_LL: case LS_TYPE_OPAQUE_AL: case LS_TYPE_OPAQUE_DW: - ND_PRINT((ndo, "\n\t %s LSA (%d), Opaque-Type %s LSA (%u), Opaque-ID %u", - tok2str(lsa_values,"unknown",lshp->ls_type), - lshp->ls_type, + ND_PRINT("\n\t %s LSA (%u), Opaque-Type %s LSA (%u), Opaque-ID %u", + tok2str(lsa_values,"unknown",ls_type), + ls_type, tok2str(lsa_opaque_values, "unknown", - *(&lshp->un_lsa_id.opaque_field.opaque_type)), - *(&lshp->un_lsa_id.opaque_field.opaque_type), - EXTRACT_24BITS(&lshp->un_lsa_id.opaque_field.opaque_id) + GET_U_1(lshp->un_lsa_id.opaque_field.opaque_type)), + GET_U_1(lshp->un_lsa_id.opaque_field.opaque_type), + GET_BE_U_3(lshp->un_lsa_id.opaque_field.opaque_id) - )); + ); break; /* all other LSA types use regular style LSA headers */ default: - ND_PRINT((ndo, "\n\t %s LSA (%d), LSA-ID: %s", - tok2str(lsa_values,"unknown",lshp->ls_type), - lshp->ls_type, - ipaddr_string(ndo, &lshp->un_lsa_id.lsa_id))); + ND_PRINT("\n\t %s LSA (%u), LSA-ID: %s", + tok2str(lsa_values,"unknown",ls_type), + ls_type, + GET_IPADDR_STRING(lshp->un_lsa_id.lsa_id)); break; } - - ND_TCHECK(lshp->ls_options); /* XXX - ls_length check checked this */ - ND_PRINT((ndo, "\n\t Options: [%s]", bittok2str(ospf_option_values, "none", lshp->ls_options))); + ND_PRINT("\n\t Options: [%s]", + bittok2str(ospf_option_values, "none", GET_U_1(lshp->ls_options))); return (ls_length); -trunc: - return (-1); } /* draft-ietf-ospf-mt-09 */ @@ -577,33 +582,31 @@ static const struct tok ospf_topology_values[] = { /* * Print all the per-topology metrics. */ -static int +static void ospf_print_tos_metrics(netdissect_options *ndo, const union un_tos *tos) { - int metric_count; - int toscount; + u_int metric_count; + u_int toscount; + u_int tos_type; - toscount = tos->link.link_tos_count+1; + toscount = GET_U_1(tos->link.link_tos_count)+1; metric_count = 0; /* * All but the first metric contain a valid topology id. */ - while (toscount > 0) { - ND_TCHECK(*tos); - ND_PRINT((ndo, "\n\t\ttopology %s (%u), metric %u", + while (toscount != 0) { + tos_type = GET_U_1(tos->metrics.tos_type); + ND_PRINT("\n\t\ttopology %s (%u), metric %u", tok2str(ospf_topology_values, "Unknown", - metric_count ? tos->metrics.tos_type : 0), - metric_count ? tos->metrics.tos_type : 0, - EXTRACT_16BITS(&tos->metrics.tos_metric))); + metric_count ? tos_type : 0), + metric_count ? tos_type : 0, + GET_BE_U_2(tos->metrics.tos_metric)); metric_count++; tos++; toscount--; } - return 0; -trunc: - return 1; } /* @@ -613,157 +616,154 @@ trunc: */ static const uint8_t * ospf_print_lsa(netdissect_options *ndo, - register const struct lsa *lsap) + const struct lsa *lsap) { - register const uint8_t *ls_end; - register const struct rlalink *rlp; - register const struct in_addr *ap; - register const struct aslametric *almp; - register const struct mcla *mcp; - register const uint32_t *lp; - register int j, tlv_type, tlv_length, topology; - register int ls_length; + const uint8_t *ls_end; + const struct rlalink *rlp; + const nd_ipv4 *ap; + const struct aslametric *almp; + const struct mcla *mcp; + const uint8_t *lp; + u_int tlv_type, tlv_length, rla_count, topology; + int ospf_print_lshdr_ret; + u_int ls_length; const uint8_t *tptr; tptr = (const uint8_t *)lsap->lsa_un.un_unknown; /* squelch compiler warnings */ - ls_length = ospf_print_lshdr(ndo, &lsap->ls_hdr); - if (ls_length == -1) - return(NULL); + ospf_print_lshdr_ret = ospf_print_lshdr(ndo, &lsap->ls_hdr); + if (ospf_print_lshdr_ret < 0) + return(NULL); + ls_length = (u_int)ospf_print_lshdr_ret; ls_end = (const uint8_t *)lsap + ls_length; + /* + * ospf_print_lshdr() returns -1 if the length is too short, + * so we know ls_length is >= sizeof(struct lsa_hdr). + */ ls_length -= sizeof(struct lsa_hdr); - switch (lsap->ls_hdr.ls_type) { + switch (GET_U_1(lsap->ls_hdr.ls_type)) { case LS_TYPE_ROUTER: - ND_TCHECK(lsap->lsa_un.un_rla.rla_flags); - ND_PRINT((ndo, "\n\t Router LSA Options: [%s]", - bittok2str(ospf_rla_flag_values, "none", lsap->lsa_un.un_rla.rla_flags))); + ND_PRINT("\n\t Router LSA Options: [%s]", + bittok2str(ospf_rla_flag_values, "none", GET_U_1(lsap->lsa_un.un_rla.rla_flags))); - ND_TCHECK(lsap->lsa_un.un_rla.rla_count); - j = EXTRACT_16BITS(&lsap->lsa_un.un_rla.rla_count); - ND_TCHECK(lsap->lsa_un.un_rla.rla_link); + rla_count = GET_BE_U_2(lsap->lsa_un.un_rla.rla_count); + ND_TCHECK_SIZE(lsap->lsa_un.un_rla.rla_link); rlp = lsap->lsa_un.un_rla.rla_link; - while (j--) { - ND_TCHECK(*rlp); - switch (rlp->un_tos.link.link_type) { + for (u_int i = rla_count; i != 0; i--) { + ND_TCHECK_SIZE(rlp); + switch (GET_U_1(rlp->un_tos.link.link_type)) { case RLA_TYPE_VIRTUAL: - ND_PRINT((ndo, "\n\t Virtual Link: Neighbor Router-ID: %s, Interface Address: %s", - ipaddr_string(ndo, &rlp->link_id), - ipaddr_string(ndo, &rlp->link_data))); + ND_PRINT("\n\t Virtual Link: Neighbor Router-ID: %s, Interface Address: %s", + GET_IPADDR_STRING(rlp->link_id), + GET_IPADDR_STRING(rlp->link_data)); break; case RLA_TYPE_ROUTER: - ND_PRINT((ndo, "\n\t Neighbor Router-ID: %s, Interface Address: %s", - ipaddr_string(ndo, &rlp->link_id), - ipaddr_string(ndo, &rlp->link_data))); + ND_PRINT("\n\t Neighbor Router-ID: %s, Interface Address: %s", + GET_IPADDR_STRING(rlp->link_id), + GET_IPADDR_STRING(rlp->link_data)); break; case RLA_TYPE_TRANSIT: - ND_PRINT((ndo, "\n\t Neighbor Network-ID: %s, Interface Address: %s", - ipaddr_string(ndo, &rlp->link_id), - ipaddr_string(ndo, &rlp->link_data))); + ND_PRINT("\n\t Neighbor Network-ID: %s, Interface Address: %s", + GET_IPADDR_STRING(rlp->link_id), + GET_IPADDR_STRING(rlp->link_data)); break; case RLA_TYPE_STUB: - ND_PRINT((ndo, "\n\t Stub Network: %s, Mask: %s", - ipaddr_string(ndo, &rlp->link_id), - ipaddr_string(ndo, &rlp->link_data))); + ND_PRINT("\n\t Stub Network: %s, Mask: %s", + GET_IPADDR_STRING(rlp->link_id), + GET_IPADDR_STRING(rlp->link_data)); break; default: - ND_PRINT((ndo, "\n\t Unknown Router Link Type (%u)", - rlp->un_tos.link.link_type)); + ND_PRINT("\n\t Unknown Router Link Type (%u)", + GET_U_1(rlp->un_tos.link.link_type)); return (ls_end); } - if (ospf_print_tos_metrics(ndo, &rlp->un_tos)) - goto trunc; + ospf_print_tos_metrics(ndo, &rlp->un_tos); rlp = (const struct rlalink *)((const u_char *)(rlp + 1) + - ((rlp->un_tos.link.link_tos_count) * sizeof(union un_tos))); + (GET_U_1(rlp->un_tos.link.link_tos_count) * sizeof(union un_tos))); } break; case LS_TYPE_NETWORK: - ND_TCHECK(lsap->lsa_un.un_nla.nla_mask); - ND_PRINT((ndo, "\n\t Mask %s\n\t Connected Routers:", - ipaddr_string(ndo, &lsap->lsa_un.un_nla.nla_mask))); + ND_PRINT("\n\t Mask %s\n\t Connected Routers:", + GET_IPADDR_STRING(lsap->lsa_un.un_nla.nla_mask)); ap = lsap->lsa_un.un_nla.nla_router; while ((const u_char *)ap < ls_end) { - ND_TCHECK(*ap); - ND_PRINT((ndo, "\n\t %s", ipaddr_string(ndo, ap))); + ND_TCHECK_SIZE(ap); + ND_PRINT("\n\t %s", GET_IPADDR_STRING(*ap)); ++ap; } break; case LS_TYPE_SUM_IP: - ND_TCHECK(lsap->lsa_un.un_nla.nla_mask); - ND_PRINT((ndo, "\n\t Mask %s", - ipaddr_string(ndo, &lsap->lsa_un.un_sla.sla_mask))); - ND_TCHECK(lsap->lsa_un.un_sla.sla_tosmetric); - lp = lsap->lsa_un.un_sla.sla_tosmetric; - while ((const u_char *)lp < ls_end) { - register uint32_t ul; - - ND_TCHECK_32BITS(lp); - ul = EXTRACT_32BITS(lp); + ND_TCHECK_4(lsap->lsa_un.un_nla.nla_mask); + ND_PRINT("\n\t Mask %s", + GET_IPADDR_STRING(lsap->lsa_un.un_sla.sla_mask)); + ND_TCHECK_SIZE(lsap->lsa_un.un_sla.sla_tosmetric); + lp = (const uint8_t *)lsap->lsa_un.un_sla.sla_tosmetric; + while (lp < ls_end) { + uint32_t ul; + + ul = GET_BE_U_4(lp); topology = (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS; - ND_PRINT((ndo, "\n\t\ttopology %s (%u) metric %d", + ND_PRINT("\n\t\ttopology %s (%u) metric %u", tok2str(ospf_topology_values, "Unknown", topology), topology, - ul & SLA_MASK_METRIC)); - ++lp; + ul & SLA_MASK_METRIC); + lp += 4; } break; case LS_TYPE_SUM_ABR: - ND_TCHECK(lsap->lsa_un.un_sla.sla_tosmetric); - lp = lsap->lsa_un.un_sla.sla_tosmetric; - while ((const u_char *)lp < ls_end) { - register uint32_t ul; + ND_TCHECK_SIZE(lsap->lsa_un.un_sla.sla_tosmetric); + lp = (const uint8_t *)lsap->lsa_un.un_sla.sla_tosmetric; + while (lp < ls_end) { + uint32_t ul; - ND_TCHECK_32BITS(lp); - ul = EXTRACT_32BITS(lp); + ul = GET_BE_U_4(lp); topology = (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS; - ND_PRINT((ndo, "\n\t\ttopology %s (%u) metric %d", + ND_PRINT("\n\t\ttopology %s (%u) metric %u", tok2str(ospf_topology_values, "Unknown", topology), topology, - ul & SLA_MASK_METRIC)); - ++lp; + ul & SLA_MASK_METRIC); + lp += 4; } break; case LS_TYPE_ASE: case LS_TYPE_NSSA: /* fall through - those LSAs share the same format */ - ND_TCHECK(lsap->lsa_un.un_nla.nla_mask); - ND_PRINT((ndo, "\n\t Mask %s", - ipaddr_string(ndo, &lsap->lsa_un.un_asla.asla_mask))); + ND_TCHECK_4(lsap->lsa_un.un_nla.nla_mask); + ND_PRINT("\n\t Mask %s", + GET_IPADDR_STRING(lsap->lsa_un.un_asla.asla_mask)); - ND_TCHECK(lsap->lsa_un.un_sla.sla_tosmetric); + ND_TCHECK_SIZE(lsap->lsa_un.un_sla.sla_tosmetric); almp = lsap->lsa_un.un_asla.asla_metric; while ((const u_char *)almp < ls_end) { - register uint32_t ul; + uint32_t ul; - ND_TCHECK(almp->asla_tosmetric); - ul = EXTRACT_32BITS(&almp->asla_tosmetric); + ul = GET_BE_U_4(almp->asla_tosmetric); topology = ((ul & ASLA_MASK_TOS) >> ASLA_SHIFT_TOS); - ND_PRINT((ndo, "\n\t\ttopology %s (%u), type %d, metric", + ND_PRINT("\n\t\ttopology %s (%u), type %u, metric", tok2str(ospf_topology_values, "Unknown", topology), topology, - (ul & ASLA_FLAG_EXTERNAL) ? 2 : 1)); + (ul & ASLA_FLAG_EXTERNAL) ? 2 : 1); if ((ul & ASLA_MASK_METRIC) == 0xffffff) - ND_PRINT((ndo, " infinite")); + ND_PRINT(" infinite"); else - ND_PRINT((ndo, " %d", (ul & ASLA_MASK_METRIC))); + ND_PRINT(" %u", (ul & ASLA_MASK_METRIC)); - ND_TCHECK(almp->asla_forward); - if (almp->asla_forward.s_addr) { - ND_PRINT((ndo, ", forward %s", ipaddr_string(ndo, &almp->asla_forward))); + if (GET_IPV4_TO_NETWORK_ORDER(almp->asla_forward) != 0) { + ND_PRINT(", forward %s", GET_IPADDR_STRING(almp->asla_forward)); } - ND_TCHECK(almp->asla_tag); - if (almp->asla_tag.s_addr) { - ND_PRINT((ndo, ", tag %s", ipaddr_string(ndo, &almp->asla_tag))); + if (GET_IPV4_TO_NETWORK_ORDER(almp->asla_tag) != 0) { + ND_PRINT(", tag %s", GET_IPADDR_STRING(almp->asla_tag)); } ++almp; } @@ -773,22 +773,21 @@ ospf_print_lsa(netdissect_options *ndo, /* Multicast extensions as of 23 July 1991 */ mcp = lsap->lsa_un.un_mcla; while ((const u_char *)mcp < ls_end) { - ND_TCHECK(mcp->mcla_vid); - switch (EXTRACT_32BITS(&mcp->mcla_vtype)) { + switch (GET_BE_U_4(mcp->mcla_vtype)) { case MCLA_VERTEX_ROUTER: - ND_PRINT((ndo, "\n\t Router Router-ID %s", - ipaddr_string(ndo, &mcp->mcla_vid))); + ND_PRINT("\n\t Router Router-ID %s", + GET_IPADDR_STRING(mcp->mcla_vid)); break; case MCLA_VERTEX_NETWORK: - ND_PRINT((ndo, "\n\t Network Designated Router %s", - ipaddr_string(ndo, &mcp->mcla_vid))); + ND_PRINT("\n\t Network Designated Router %s", + GET_IPADDR_STRING(mcp->mcla_vid)); break; default: - ND_PRINT((ndo, "\n\t unknown VertexType (%u)", - EXTRACT_32BITS(&mcp->mcla_vtype))); + ND_PRINT("\n\t unknown VertexType (%u)", + GET_BE_U_4(mcp->mcla_vtype)); break; } ++mcp; @@ -799,41 +798,42 @@ ospf_print_lsa(netdissect_options *ndo, case LS_TYPE_OPAQUE_AL: case LS_TYPE_OPAQUE_DW: - switch (*(&lsap->ls_hdr.un_lsa_id.opaque_field.opaque_type)) { + switch (GET_U_1(lsap->ls_hdr.un_lsa_id.opaque_field.opaque_type)) { case LS_OPAQUE_TYPE_RI: - tptr = (const uint8_t *)(&lsap->lsa_un.un_ri_tlv.type); + tptr = (const uint8_t *)(lsap->lsa_un.un_ri_tlv); - while (ls_length != 0) { - ND_TCHECK2(*tptr, 4); - if (ls_length < 4) { - ND_PRINT((ndo, "\n\t Remaining LS length %u < 4", ls_length)); + u_int ls_length_remaining = ls_length; + while (ls_length_remaining != 0) { + ND_TCHECK_4(tptr); + if (ls_length_remaining < 4) { + ND_PRINT("\n\t Remaining LS length %u < 4", ls_length_remaining); return(ls_end); } - tlv_type = EXTRACT_16BITS(tptr); - tlv_length = EXTRACT_16BITS(tptr+2); + tlv_type = GET_BE_U_2(tptr); + tlv_length = GET_BE_U_2(tptr + 2); tptr+=4; - ls_length-=4; + ls_length_remaining-=4; - ND_PRINT((ndo, "\n\t %s TLV (%u), length: %u, value: ", + ND_PRINT("\n\t %s TLV (%u), length: %u, value: ", tok2str(lsa_opaque_ri_tlv_values,"unknown",tlv_type), tlv_type, - tlv_length)); + tlv_length); - if (tlv_length > ls_length) { - ND_PRINT((ndo, "\n\t Bogus length %u > %u", tlv_length, - ls_length)); + if (tlv_length > ls_length_remaining) { + ND_PRINT("\n\t Bogus length %u > remaining LS length %u", tlv_length, + ls_length_remaining); return(ls_end); } - ND_TCHECK2(*tptr, tlv_length); + ND_TCHECK_LEN(tptr, tlv_length); switch(tlv_type) { case LS_OPAQUE_RI_TLV_CAP: if (tlv_length != 4) { - ND_PRINT((ndo, "\n\t Bogus length %u != 4", tlv_length)); + ND_PRINT("\n\t Bogus length %u != 4", tlv_length); return(ls_end); } - ND_PRINT((ndo, "Capabilities: %s", - bittok2str(lsa_opaque_ri_tlv_cap_values, "Unknown", EXTRACT_32BITS(tptr)))); + ND_PRINT("Capabilities: %s", + bittok2str(lsa_opaque_ri_tlv_cap_values, "Unknown", GET_BE_U_4(tptr))); break; default: if (ndo->ndo_vflag <= 1) { @@ -844,19 +844,19 @@ ospf_print_lsa(netdissect_options *ndo, } tptr+=tlv_length; - ls_length-=tlv_length; + ls_length_remaining-=tlv_length; } break; case LS_OPAQUE_TYPE_GRACE: - if (ospf_print_grace_lsa(ndo, (const uint8_t *)(&lsap->lsa_un.un_grace_tlv.type), + if (ospf_grace_lsa_print(ndo, (const u_char *)(lsap->lsa_un.un_grace_tlv), ls_length) == -1) { return(ls_end); } break; case LS_OPAQUE_TYPE_TE: - if (ospf_print_te_lsa(ndo, (const uint8_t *)(&lsap->lsa_un.un_te_lsa_tlv.type), + if (ospf_te_lsa_print(ndo, (const u_char *)(lsap->lsa_un.un_te_lsa_tlv), ls_length) == -1) { return(ls_end); } @@ -884,162 +884,137 @@ trunc: return (NULL); } -static int +static void ospf_decode_lls(netdissect_options *ndo, - register const struct ospfhdr *op, register u_int length) + const struct ospfhdr *op, u_int length) { - register const u_char *dptr; - register const u_char *dataend; - register u_int length2; - register uint16_t lls_type, lls_len; - register uint32_t lls_flags; + const u_char *dptr; + const u_char *dataend; + u_int length2; + uint16_t lls_type, lls_len; + uint32_t lls_flags; - switch (op->ospf_type) { + switch (GET_U_1(op->ospf_type)) { case OSPF_TYPE_HELLO: - if (!(op->ospf_hello.hello_options & OSPF_OPTION_L)) - return (0); + if (!(GET_U_1(op->ospf_hello.hello_options) & OSPF_OPTION_L)) + return; break; case OSPF_TYPE_DD: - if (!(op->ospf_db.db_options & OSPF_OPTION_L)) - return (0); + if (!(GET_U_1(op->ospf_db.db_options) & OSPF_OPTION_L)) + return; break; default: - return (0); + return; } /* dig deeper if LLS data is available; see RFC4813 */ - length2 = EXTRACT_16BITS(&op->ospf_len); + length2 = GET_BE_U_2(op->ospf_len); dptr = (const u_char *)op + length2; dataend = (const u_char *)op + length; - if (EXTRACT_16BITS(&op->ospf_authtype) == OSPF_AUTH_MD5) { - dptr = dptr + op->ospf_authdata[3]; - length2 += op->ospf_authdata[3]; + if (GET_BE_U_2(op->ospf_authtype) == OSPF_AUTH_MD5) { + dptr = dptr + GET_U_1(op->ospf_authdata + 3); + length2 += GET_U_1(op->ospf_authdata + 3); } if (length2 >= length) { - ND_PRINT((ndo, "\n\t[LLS truncated]")); - return (1); + ND_PRINT("\n\t[LLS truncated]"); + return; } - ND_TCHECK2(*dptr, 2); - ND_PRINT((ndo, "\n\t LLS: checksum: 0x%04x", (u_int)EXTRACT_16BITS(dptr))); + ND_PRINT("\n\t LLS: checksum: 0x%04x", (u_int) GET_BE_U_2(dptr)); dptr += 2; - ND_TCHECK2(*dptr, 2); - length2 = EXTRACT_16BITS(dptr); - ND_PRINT((ndo, ", length: %u", length2)); + length2 = GET_BE_U_2(dptr); + ND_PRINT(", length: %u", length2); dptr += 2; - ND_TCHECK(*dptr); while (dptr < dataend) { - ND_TCHECK2(*dptr, 2); - lls_type = EXTRACT_16BITS(dptr); - ND_PRINT((ndo, "\n\t %s (%u)", + lls_type = GET_BE_U_2(dptr); + ND_PRINT("\n\t %s (%u)", tok2str(ospf_lls_tlv_values,"Unknown TLV",lls_type), - lls_type)); + lls_type); dptr += 2; - ND_TCHECK2(*dptr, 2); - lls_len = EXTRACT_16BITS(dptr); - ND_PRINT((ndo, ", length: %u", lls_len)); + lls_len = GET_BE_U_2(dptr); + ND_PRINT(", length: %u", lls_len); dptr += 2; switch (lls_type) { case OSPF_LLS_EO: if (lls_len != 4) { - ND_PRINT((ndo, " [should be 4]")); + ND_PRINT(" [should be 4]"); lls_len = 4; } - ND_TCHECK2(*dptr, 4); - lls_flags = EXTRACT_32BITS(dptr); - ND_PRINT((ndo, "\n\t Options: 0x%08x [%s]", lls_flags, - bittok2str(ospf_lls_eo_options, "?", lls_flags))); + lls_flags = GET_BE_U_4(dptr); + ND_PRINT("\n\t Options: 0x%08x [%s]", lls_flags, + bittok2str(ospf_lls_eo_options, "?", lls_flags)); break; case OSPF_LLS_MD5: if (lls_len != 20) { - ND_PRINT((ndo, " [should be 20]")); + ND_PRINT(" [should be 20]"); lls_len = 20; } - ND_TCHECK2(*dptr, 4); - ND_PRINT((ndo, "\n\t Sequence number: 0x%08x", EXTRACT_32BITS(dptr))); + ND_PRINT("\n\t Sequence number: 0x%08x", GET_BE_U_4(dptr)); break; } dptr += lls_len; } - - return (0); -trunc: - return (1); } static int ospf_decode_v2(netdissect_options *ndo, - register const struct ospfhdr *op, register const u_char *dataend) + const struct ospfhdr *op, const u_char *dataend) { - register const struct in_addr *ap; - register const struct lsr *lsrp; - register const struct lsa_hdr *lshp; - register const struct lsa *lsap; - register uint32_t lsa_count,lsa_count_max; - - switch (op->ospf_type) { - - case OSPF_TYPE_UMD: - /* - * Rob Coltun's special monitoring packets; - * do nothing - */ - break; + const nd_ipv4 *ap; + const struct lsr *lsrp; + const struct lsa_hdr *lshp; + const struct lsa *lsap; + uint32_t lsa_count,lsa_count_max; + + switch (GET_U_1(op->ospf_type)) { case OSPF_TYPE_HELLO: - ND_TCHECK(op->ospf_hello.hello_options); - ND_PRINT((ndo, "\n\tOptions [%s]", - bittok2str(ospf_option_values,"none",op->ospf_hello.hello_options))); - - ND_TCHECK(op->ospf_hello.hello_deadint); - ND_PRINT((ndo, "\n\t Hello Timer %us, Dead Timer %us, Mask %s, Priority %u", - EXTRACT_16BITS(&op->ospf_hello.hello_helloint), - EXTRACT_32BITS(&op->ospf_hello.hello_deadint), - ipaddr_string(ndo, &op->ospf_hello.hello_mask), - op->ospf_hello.hello_priority)); - - ND_TCHECK(op->ospf_hello.hello_dr); - if (op->ospf_hello.hello_dr.s_addr != 0) - ND_PRINT((ndo, "\n\t Designated Router %s", - ipaddr_string(ndo, &op->ospf_hello.hello_dr))); - - ND_TCHECK(op->ospf_hello.hello_bdr); - if (op->ospf_hello.hello_bdr.s_addr != 0) - ND_PRINT((ndo, ", Backup Designated Router %s", - ipaddr_string(ndo, &op->ospf_hello.hello_bdr))); + ND_PRINT("\n\tOptions [%s]", + bittok2str(ospf_option_values,"none",GET_U_1(op->ospf_hello.hello_options))); + + ND_PRINT("\n\t Hello Timer %us, Dead Timer %us, Mask %s, Priority %u", + GET_BE_U_2(op->ospf_hello.hello_helloint), + GET_BE_U_4(op->ospf_hello.hello_deadint), + GET_IPADDR_STRING(op->ospf_hello.hello_mask), + GET_U_1(op->ospf_hello.hello_priority)); + + if (GET_IPV4_TO_NETWORK_ORDER(op->ospf_hello.hello_dr) != 0) + ND_PRINT("\n\t Designated Router %s", + GET_IPADDR_STRING(op->ospf_hello.hello_dr)); + + if (GET_IPV4_TO_NETWORK_ORDER(op->ospf_hello.hello_bdr) != 0) + ND_PRINT(", Backup Designated Router %s", + GET_IPADDR_STRING(op->ospf_hello.hello_bdr)); ap = op->ospf_hello.hello_neighbor; if ((const u_char *)ap < dataend) - ND_PRINT((ndo, "\n\t Neighbor List:")); + ND_PRINT("\n\t Neighbor List:"); while ((const u_char *)ap < dataend) { - ND_TCHECK(*ap); - ND_PRINT((ndo, "\n\t %s", ipaddr_string(ndo, ap))); + ND_TCHECK_SIZE(ap); + ND_PRINT("\n\t %s", GET_IPADDR_STRING(*ap)); ++ap; } break; /* HELLO */ case OSPF_TYPE_DD: - ND_TCHECK(op->ospf_db.db_options); - ND_PRINT((ndo, "\n\tOptions [%s]", - bittok2str(ospf_option_values, "none", op->ospf_db.db_options))); - ND_TCHECK(op->ospf_db.db_flags); - ND_PRINT((ndo, ", DD Flags [%s]", - bittok2str(ospf_dd_flag_values, "none", op->ospf_db.db_flags))); - ND_TCHECK(op->ospf_db.db_ifmtu); - if (op->ospf_db.db_ifmtu) { - ND_PRINT((ndo, ", MTU: %u", EXTRACT_16BITS(&op->ospf_db.db_ifmtu))); + ND_PRINT("\n\tOptions [%s]", + bittok2str(ospf_option_values, "none", GET_U_1(op->ospf_db.db_options))); + ND_PRINT(", DD Flags [%s]", + bittok2str(ospf_dd_flag_values, "none", GET_U_1(op->ospf_db.db_flags))); + if (GET_BE_U_2(op->ospf_db.db_ifmtu)) { + ND_PRINT(", MTU: %u", + GET_BE_U_2(op->ospf_db.db_ifmtu)); } - ND_TCHECK(op->ospf_db.db_seq); - ND_PRINT((ndo, ", Sequence: 0x%08x", EXTRACT_32BITS(&op->ospf_db.db_seq))); + ND_PRINT(", Sequence: 0x%08x", GET_BE_U_4(op->ospf_db.db_seq)); /* Print all the LS adv's */ lshp = op->ospf_db.db_lshdr; @@ -1051,26 +1026,26 @@ ospf_decode_v2(netdissect_options *ndo, case OSPF_TYPE_LS_REQ: lsrp = op->ospf_lsr; while ((const u_char *)lsrp < dataend) { - ND_TCHECK(*lsrp); + ND_TCHECK_SIZE(lsrp); - ND_PRINT((ndo, "\n\t Advertising Router: %s, %s LSA (%u)", - ipaddr_string(ndo, &lsrp->ls_router), - tok2str(lsa_values,"unknown",EXTRACT_32BITS(lsrp->ls_type)), - EXTRACT_32BITS(&lsrp->ls_type))); + ND_PRINT("\n\t Advertising Router: %s, %s LSA (%u)", + GET_IPADDR_STRING(lsrp->ls_router), + tok2str(lsa_values,"unknown",GET_BE_U_4(lsrp->ls_type)), + GET_BE_U_4(lsrp->ls_type)); - switch (EXTRACT_32BITS(lsrp->ls_type)) { + switch (GET_BE_U_4(lsrp->ls_type)) { /* the LSA header for opaque LSAs was slightly changed */ case LS_TYPE_OPAQUE_LL: case LS_TYPE_OPAQUE_AL: case LS_TYPE_OPAQUE_DW: - ND_PRINT((ndo, ", Opaque-Type: %s LSA (%u), Opaque-ID: %u", - tok2str(lsa_opaque_values, "unknown",lsrp->un_ls_stateid.opaque_field.opaque_type), - lsrp->un_ls_stateid.opaque_field.opaque_type, - EXTRACT_24BITS(&lsrp->un_ls_stateid.opaque_field.opaque_id))); + ND_PRINT(", Opaque-Type: %s LSA (%u), Opaque-ID: %u", + tok2str(lsa_opaque_values, "unknown",GET_U_1(lsrp->un_ls_stateid.opaque_field.opaque_type)), + GET_U_1(lsrp->un_ls_stateid.opaque_field.opaque_type), + GET_BE_U_3(lsrp->un_ls_stateid.opaque_field.opaque_id)); break; default: - ND_PRINT((ndo, ", LSA-ID: %s", - ipaddr_string(ndo, &lsrp->un_ls_stateid.ls_stateid))); + ND_PRINT(", LSA-ID: %s", + GET_IPADDR_STRING(lsrp->un_ls_stateid.ls_stateid)); break; } @@ -1080,11 +1055,10 @@ ospf_decode_v2(netdissect_options *ndo, case OSPF_TYPE_LS_UPDATE: lsap = op->ospf_lsu.lsu_lsa; - ND_TCHECK(op->ospf_lsu.lsu_count); - lsa_count_max = EXTRACT_32BITS(&op->ospf_lsu.lsu_count); - ND_PRINT((ndo, ", %d LSA%s", lsa_count_max, PLURAL_SUFFIX(lsa_count_max))); + lsa_count_max = GET_BE_U_4(op->ospf_lsu.lsu_count); + ND_PRINT(", %u LSA%s", lsa_count_max, PLURAL_SUFFIX(lsa_count_max)); for (lsa_count=1;lsa_count <= lsa_count_max;lsa_count++) { - ND_PRINT((ndo, "\n\t LSA #%u", lsa_count)); + ND_PRINT("\n\t LSA #%u", lsa_count); lsap = (const struct lsa *)ospf_print_lsa(ndo, lsap); if (lsap == NULL) goto trunc; @@ -1108,27 +1082,27 @@ trunc: void ospf_print(netdissect_options *ndo, - register const u_char *bp, register u_int length, + const u_char *bp, u_int length, const u_char *bp2 _U_) { - register const struct ospfhdr *op; - register const u_char *dataend; - register const char *cp; + const struct ospfhdr *op; + const u_char *dataend; + const char *cp; + ndo->ndo_protocol = "ospf2"; op = (const struct ospfhdr *)bp; /* XXX Before we do anything else, strip off the MD5 trailer */ - ND_TCHECK(op->ospf_authtype); - if (EXTRACT_16BITS(&op->ospf_authtype) == OSPF_AUTH_MD5) { + if (GET_BE_U_2(op->ospf_authtype) == OSPF_AUTH_MD5) { length -= OSPF_AUTH_MD5_LEN; ndo->ndo_snapend -= OSPF_AUTH_MD5_LEN; } /* If the type is valid translate it, or just print the type */ /* value. If it's not valid, say so and return */ - ND_TCHECK(op->ospf_type); - cp = tok2str(type2str, "unknown LS-type", op->ospf_type); - ND_PRINT((ndo, "OSPFv%u, %s, length %u", op->ospf_version, cp, length)); + cp = tok2str(type2str, "unknown LS-type %u", GET_U_1(op->ospf_type)); + ND_PRINT("OSPFv%u, %s, length %u", GET_U_1(op->ospf_version), cp, + length); if (*cp == 'u') return; @@ -1136,49 +1110,46 @@ ospf_print(netdissect_options *ndo, return; } - ND_TCHECK(op->ospf_len); - if (length != EXTRACT_16BITS(&op->ospf_len)) { - ND_PRINT((ndo, " [len %d]", EXTRACT_16BITS(&op->ospf_len))); + if (length != GET_BE_U_2(op->ospf_len)) { + ND_PRINT(" [len %u]", GET_BE_U_2(op->ospf_len)); } - if (length > EXTRACT_16BITS(&op->ospf_len)) { - dataend = bp + EXTRACT_16BITS(&op->ospf_len); + if (length > GET_BE_U_2(op->ospf_len)) { + dataend = bp + GET_BE_U_2(op->ospf_len); } else { dataend = bp + length; } - ND_TCHECK(op->ospf_routerid); - ND_PRINT((ndo, "\n\tRouter-ID %s", ipaddr_string(ndo, &op->ospf_routerid))); + ND_PRINT("\n\tRouter-ID %s", GET_IPADDR_STRING(op->ospf_routerid)); - ND_TCHECK(op->ospf_areaid); - if (op->ospf_areaid.s_addr != 0) - ND_PRINT((ndo, ", Area %s", ipaddr_string(ndo, &op->ospf_areaid))); + if (GET_IPV4_TO_NETWORK_ORDER(op->ospf_areaid) != 0) + ND_PRINT(", Area %s", GET_IPADDR_STRING(op->ospf_areaid)); else - ND_PRINT((ndo, ", Backbone Area")); + ND_PRINT(", Backbone Area"); if (ndo->ndo_vflag) { /* Print authentication data (should we really do this?) */ - ND_TCHECK2(op->ospf_authdata[0], sizeof(op->ospf_authdata)); + ND_TCHECK_LEN(op->ospf_authdata, sizeof(op->ospf_authdata)); - ND_PRINT((ndo, ", Authentication Type: %s (%u)", - tok2str(ospf_authtype_values, "unknown", EXTRACT_16BITS(&op->ospf_authtype)), - EXTRACT_16BITS(&op->ospf_authtype))); + ND_PRINT(", Authentication Type: %s (%u)", + tok2str(ospf_authtype_values, "unknown", GET_BE_U_2(op->ospf_authtype)), + GET_BE_U_2(op->ospf_authtype)); - switch (EXTRACT_16BITS(&op->ospf_authtype)) { + switch (GET_BE_U_2(op->ospf_authtype)) { case OSPF_AUTH_NONE: break; case OSPF_AUTH_SIMPLE: - ND_PRINT((ndo, "\n\tSimple text password: ")); - safeputs(ndo, op->ospf_authdata, OSPF_AUTH_SIMPLE_LEN); + ND_PRINT("\n\tSimple text password: "); + nd_printjnp(ndo, op->ospf_authdata, OSPF_AUTH_SIMPLE_LEN); break; case OSPF_AUTH_MD5: - ND_PRINT((ndo, "\n\tKey-ID: %u, Auth-Length: %u, Crypto Sequence Number: 0x%08x", - *((op->ospf_authdata) + 2), - *((op->ospf_authdata) + 3), - EXTRACT_32BITS((op->ospf_authdata) + 4))); + ND_PRINT("\n\tKey-ID: %u, Auth-Length: %u, Crypto Sequence Number: 0x%08x", + GET_U_1(op->ospf_authdata + 2), + GET_U_1(op->ospf_authdata + 3), + GET_BE_U_4((op->ospf_authdata) + 4)); break; default: @@ -1186,24 +1157,22 @@ ospf_print(netdissect_options *ndo, } } /* Do rest according to version. */ - switch (op->ospf_version) { + switch (GET_U_1(op->ospf_version)) { case 2: /* ospf version 2 */ if (ospf_decode_v2(ndo, op, dataend)) goto trunc; - if (length > EXTRACT_16BITS(&op->ospf_len)) { - if (ospf_decode_lls(ndo, op, length)) - goto trunc; - } + if (length > GET_BE_U_2(op->ospf_len)) + ospf_decode_lls(ndo, op, length); break; default: - ND_PRINT((ndo, " ospf [version %d]", op->ospf_version)); + ND_PRINT(" ospf [version %u]", GET_U_1(op->ospf_version)); break; } /* end switch on version */ return; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_trunc_longjmp(ndo); } diff --git a/contrib/tcpdump/print-ospf6.c b/contrib/tcpdump/print-ospf6.c index 66ab2f75ff..1bdcd68169 100644 --- a/contrib/tcpdump/print-ospf6.c +++ b/contrib/tcpdump/print-ospf6.c @@ -24,10 +24,10 @@ /* \summary: IPv6 Open Shortest Path First (OSPFv3) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include @@ -95,7 +95,7 @@ #define RLA_FLAG_E 0x02 #define RLA_FLAG_V 0x04 #define RLA_FLAG_W 0x08 -#define RLA_FLAG_N 0x10 +#define RLA_FLAG_Nt 0x10 /* lsa_prefix options */ #define LSA_PREFIX_OPT_NU 0x01 @@ -103,6 +103,7 @@ #define LSA_PREFIX_OPT_MC 0x04 #define LSA_PREFIX_OPT_P 0x08 #define LSA_PREFIX_OPT_DN 0x10 +#define LSA_PREFIX_OPT_N 0x20 /* sla_tosmetric breakdown */ #define SLA_MASK_TOS 0x7f000000 @@ -118,27 +119,27 @@ #define OSPF6_AT_HDRLEN 16U #define OSPF6_AUTH_TYPE_HMAC 0x0001 -typedef uint32_t rtrid_t; +typedef nd_uint32_t rtrid_t; /* link state advertisement header */ struct lsa6_hdr { - uint16_t ls_age; - uint16_t ls_type; + nd_uint16_t ls_age; + nd_uint16_t ls_type; rtrid_t ls_stateid; rtrid_t ls_router; - uint32_t ls_seq; - uint16_t ls_chksum; - uint16_t ls_length; + nd_uint32_t ls_seq; + nd_uint16_t ls_chksum; + nd_uint16_t ls_length; }; /* Length of an IPv6 address, in bytes. */ #define IPV6_ADDR_LEN_BYTES (128/8) struct lsa6_prefix { - uint8_t lsa_p_len; - uint8_t lsa_p_opt; - uint16_t lsa_p_metric; - uint8_t lsa_p_prefix[IPV6_ADDR_LEN_BYTES]; /* maximum length */ + nd_uint8_t lsa_p_len; + nd_uint8_t lsa_p_opt; + nd_uint16_t lsa_p_metric; + nd_byte lsa_p_prefix[IPV6_ADDR_LEN_BYTES]; /* maximum length */ }; /* link state advertisement */ @@ -150,36 +151,36 @@ struct lsa6 { /* Router links advertisements */ struct { union { - uint8_t flg; - uint32_t opt; + nd_uint8_t flg; + nd_uint32_t opt; } rla_flgandopt; #define rla_flags rla_flgandopt.flg #define rla_options rla_flgandopt.opt struct rlalink6 { - uint8_t link_type; - uint8_t link_zero[1]; - uint16_t link_metric; - uint32_t link_ifid; - uint32_t link_nifid; + nd_uint8_t link_type; + nd_byte link_zero; + nd_uint16_t link_metric; + nd_uint32_t link_ifid; + nd_uint32_t link_nifid; rtrid_t link_nrtid; } rla_link[1]; /* may repeat */ } un_rla; /* Network links advertisements */ struct { - uint32_t nla_options; + nd_uint32_t nla_options; rtrid_t nla_router[1]; /* may repeat */ } un_nla; /* Inter Area Prefix LSA */ struct { - uint32_t inter_ap_metric; + nd_uint32_t inter_ap_metric; struct lsa6_prefix inter_ap_prefix[1]; } un_inter_ap; /* AS external links advertisements */ struct { - uint32_t asla_metric; + nd_uint32_t asla_metric; struct lsa6_prefix asla_prefix[1]; /* some optional fields follow */ } un_asla; @@ -187,14 +188,14 @@ struct lsa6 { #if 0 /* Summary links advertisements */ struct { - struct in_addr sla_mask; - uint32_t sla_tosmetric[1]; /* may repeat */ + nd_ipv4 sla_mask; + nd_uint32_t sla_tosmetric[1]; /* may repeat */ } un_sla; /* Multicast group membership */ struct mcla { - uint32_t mcla_vtype; - struct in_addr mcla_vid; + nd_uint32_t mcla_vtype; + nd_ipv4 mcla_vid; } un_mcla[1]; #endif @@ -203,20 +204,20 @@ struct lsa6 { /* Link LSA */ struct llsa { union { - uint8_t pri; - uint32_t opt; + nd_uint8_t pri; + nd_uint32_t opt; } llsa_priandopt; #define llsa_priority llsa_priandopt.pri #define llsa_options llsa_priandopt.opt - struct in6_addr llsa_lladdr; - uint32_t llsa_nprefix; + nd_ipv6 llsa_lladdr; + nd_uint32_t llsa_nprefix; struct lsa6_prefix llsa_prefix[1]; } un_llsa; /* Intra-Area-Prefix */ struct { - uint16_t intra_ap_nprefix; - uint16_t intra_ap_lstype; + nd_uint16_t intra_ap_nprefix; + nd_uint16_t intra_ap_lstype; rtrid_t intra_ap_lsid; rtrid_t intra_ap_rtid; struct lsa6_prefix intra_ap_prefix[1]; @@ -228,14 +229,14 @@ struct lsa6 { * the main header */ struct ospf6hdr { - uint8_t ospf6_version; - uint8_t ospf6_type; - uint16_t ospf6_len; + nd_uint8_t ospf6_version; + nd_uint8_t ospf6_type; + nd_uint16_t ospf6_len; rtrid_t ospf6_routerid; rtrid_t ospf6_areaid; - uint16_t ospf6_chksum; - uint8_t ospf6_instanceid; - uint8_t ospf6_rsvd; + nd_uint16_t ospf6_chksum; + nd_uint8_t ospf6_instanceid; + nd_uint8_t ospf6_rsvd; }; /* @@ -246,15 +247,15 @@ struct ospf6hdr { /* Hello packet */ struct hello6 { - uint32_t hello_ifid; + nd_uint32_t hello_ifid; union { - uint8_t pri; - uint32_t opt; + nd_uint8_t pri; + nd_uint32_t opt; } hello_priandopt; #define hello_priority hello_priandopt.pri #define hello_options hello_priandopt.opt - uint16_t hello_helloint; - uint16_t hello_deadint; + nd_uint16_t hello_helloint; + nd_uint16_t hello_deadint; rtrid_t hello_dr; rtrid_t hello_bdr; rtrid_t hello_neighbor[1]; /* may repeat */ @@ -262,29 +263,28 @@ struct hello6 { /* Database Description packet */ struct dd6 { - uint32_t db_options; - uint16_t db_mtu; - uint8_t db_mbz; - uint8_t db_flags; - uint32_t db_seq; + nd_uint32_t db_options; + nd_uint16_t db_mtu; + nd_uint8_t db_mbz; + nd_uint8_t db_flags; + nd_uint32_t db_seq; struct lsa6_hdr db_lshdr[1]; /* may repeat */ }; /* Link State Request */ struct lsr6 { - uint16_t ls_mbz; - uint16_t ls_type; + nd_uint16_t ls_mbz; + nd_uint16_t ls_type; rtrid_t ls_stateid; rtrid_t ls_router; }; /* Link State Update */ struct lsu6 { - uint32_t lsu_count; + nd_uint32_t lsu_count; struct lsa6 lsu_lsa[1]; /* may repeat */ }; -static const char tstr[] = " [|ospf3]"; static const struct tok ospf6_option_values[] = { { OSPF6_OPTION_V6, "V6" }, @@ -303,8 +303,8 @@ static const struct tok ospf6_rla_flag_values[] = { { RLA_FLAG_B, "ABR" }, { RLA_FLAG_E, "External" }, { RLA_FLAG_V, "Virtual-Link Endpoint" }, - { RLA_FLAG_W, "Wildcard Receiver" }, - { RLA_FLAG_N, "NSSA Translator" }, + { RLA_FLAG_W, "Deprecated" }, + { RLA_FLAG_Nt, "NSSA Translator" }, { 0, NULL } }; @@ -363,6 +363,7 @@ static const struct tok ospf6_lsa_prefix_option_values[] = { { LSA_PREFIX_OPT_MC, "Deprecated" }, { LSA_PREFIX_OPT_P, "Propagate" }, { LSA_PREFIX_OPT_DN, "Down" }, + { LSA_PREFIX_OPT_N, "N-bit" }, { 0, NULL } }; @@ -373,31 +374,31 @@ static const struct tok ospf6_auth_type_str[] = { static void ospf6_print_ls_type(netdissect_options *ndo, - register u_int ls_type, register const rtrid_t *ls_stateid) + u_int ls_type, const rtrid_t *ls_stateid) { - ND_PRINT((ndo, "\n\t %s LSA (%d), %s Scope%s, LSA-ID %s", + ND_PRINT("\n\t %s LSA (%u), %s Scope%s, LSA-ID %s", tok2str(ospf6_lsa_values, "Unknown", ls_type & LS_TYPE_MASK), ls_type & LS_TYPE_MASK, tok2str(ospf6_ls_scope_values, "Unknown", ls_type & LS_SCOPE_MASK), ls_type &0x8000 ? ", transitive" : "", /* U-bit */ - ipaddr_string(ndo, ls_stateid))); + GET_IPADDR_STRING((const u_char *)ls_stateid)); } static int ospf6_print_lshdr(netdissect_options *ndo, - register const struct lsa6_hdr *lshp, const u_char *dataend) + const struct lsa6_hdr *lshp, const u_char *dataend) { if ((const u_char *)(lshp + 1) > dataend) goto trunc; - ND_TCHECK(lshp->ls_length); /* last field of struct lsa6_hdr */ - ND_PRINT((ndo, "\n\t Advertising Router %s, seq 0x%08x, age %us, length %u", - ipaddr_string(ndo, &lshp->ls_router), - EXTRACT_32BITS(&lshp->ls_seq), - EXTRACT_16BITS(&lshp->ls_age), - EXTRACT_16BITS(&lshp->ls_length)-(u_int)sizeof(struct lsa6_hdr))); + ND_PRINT("\n\t Advertising Router %s, seq 0x%08x, age %us, length %zu", + GET_IPADDR_STRING(lshp->ls_router), + GET_BE_U_4(lshp->ls_seq), + GET_BE_U_2(lshp->ls_age), + GET_BE_U_2(lshp->ls_length)-sizeof(struct lsa6_hdr)); - ospf6_print_ls_type(ndo, EXTRACT_16BITS(&lshp->ls_type), &lshp->ls_stateid); + ospf6_print_ls_type(ndo, GET_BE_U_2(lshp->ls_type), + &lshp->ls_stateid); return (0); trunc: @@ -410,31 +411,30 @@ ospf6_print_lsaprefix(netdissect_options *ndo, { const struct lsa6_prefix *lsapp = (const struct lsa6_prefix *)tptr; u_int wordlen; - struct in6_addr prefix; + nd_ipv6 prefix; if (lsa_length < sizeof (*lsapp) - IPV6_ADDR_LEN_BYTES) goto trunc; lsa_length -= sizeof (*lsapp) - IPV6_ADDR_LEN_BYTES; - ND_TCHECK2(*lsapp, sizeof (*lsapp) - IPV6_ADDR_LEN_BYTES); - wordlen = (lsapp->lsa_p_len + 31) / 32; - if (wordlen * 4 > sizeof(struct in6_addr)) { - ND_PRINT((ndo, " bogus prefixlen /%d", lsapp->lsa_p_len)); + ND_TCHECK_LEN(lsapp, sizeof(*lsapp) - IPV6_ADDR_LEN_BYTES); + wordlen = (GET_U_1(lsapp->lsa_p_len) + 31) / 32; + if (wordlen * 4 > sizeof(nd_ipv6)) { + ND_PRINT(" bogus prefixlen /%u", GET_U_1(lsapp->lsa_p_len)); goto trunc; } if (lsa_length < wordlen * 4) goto trunc; lsa_length -= wordlen * 4; - ND_TCHECK2(lsapp->lsa_p_prefix, wordlen * 4); - memset(&prefix, 0, sizeof(prefix)); - memcpy(&prefix, lsapp->lsa_p_prefix, wordlen * 4); - ND_PRINT((ndo, "\n\t\t%s/%d", ip6addr_string(ndo, &prefix), - lsapp->lsa_p_len)); - if (lsapp->lsa_p_opt) { - ND_PRINT((ndo, ", Options [%s]", + memset(prefix, 0, sizeof(prefix)); + GET_CPY_BYTES(prefix, lsapp->lsa_p_prefix, wordlen * 4); + ND_PRINT("\n\t\t%s/%u", ip6addr_string(ndo, prefix), /* local buffer, not packet data; don't use GET_IP6ADDR_STRING() */ + GET_U_1(lsapp->lsa_p_len)); + if (GET_U_1(lsapp->lsa_p_opt)) { + ND_PRINT(", Options [%s]", bittok2str(ospf6_lsa_prefix_option_values, - "none", lsapp->lsa_p_opt))); + "none", GET_U_1(lsapp->lsa_p_opt))); } - ND_PRINT((ndo, ", metric %u", EXTRACT_16BITS(&lsapp->lsa_p_metric))); + ND_PRINT(", metric %u", GET_BE_U_2(lsapp->lsa_p_metric)); return sizeof(*lsapp) - IPV6_ADDR_LEN_BYTES + wordlen * 4; trunc: @@ -447,32 +447,31 @@ trunc: */ static int ospf6_print_lsa(netdissect_options *ndo, - register const struct lsa6 *lsap, const u_char *dataend) + const struct lsa6 *lsap, const u_char *dataend) { - register const struct rlalink6 *rlp; + const struct rlalink6 *rlp; #if 0 - register const struct tos_metric *tosp; + const struct tos_metric *tosp; #endif - register const rtrid_t *ap; + const rtrid_t *ap; #if 0 - register const struct aslametric *almp; - register const struct mcla *mcp; + const struct aslametric *almp; + const struct mcla *mcp; #endif - register const struct llsa *llsap; - register const struct lsa6_prefix *lsapp; + const struct llsa *llsap; + const struct lsa6_prefix *lsapp; #if 0 - register const uint32_t *lp; + const uint32_t *lp; #endif - register u_int prefixes; - register int bytelen; - register u_int length, lsa_length; + u_int prefixes; + int bytelen; + u_int length, lsa_length; uint32_t flags32; const uint8_t *tptr; if (ospf6_print_lshdr(ndo, &lsap->ls_hdr, dataend)) return (1); - ND_TCHECK(lsap->ls_hdr.ls_length); - length = EXTRACT_16BITS(&lsap->ls_hdr.ls_length); + length = GET_BE_U_2(lsap->ls_hdr.ls_length); /* * The LSA length includes the length of the header; @@ -481,61 +480,60 @@ ospf6_print_lsa(netdissect_options *ndo, * header. */ if (length < sizeof(struct lsa6_hdr) || (const u_char *)lsap + length > dataend) - return (1); + return (1); lsa_length = length - sizeof(struct lsa6_hdr); tptr = (const uint8_t *)lsap+sizeof(struct lsa6_hdr); - switch (EXTRACT_16BITS(&lsap->ls_hdr.ls_type)) { + switch (GET_BE_U_2(lsap->ls_hdr.ls_type)) { case LS_TYPE_ROUTER | LS_SCOPE_AREA: if (lsa_length < sizeof (lsap->lsa_un.un_rla.rla_options)) return (1); lsa_length -= sizeof (lsap->lsa_un.un_rla.rla_options); - ND_TCHECK(lsap->lsa_un.un_rla.rla_options); - ND_PRINT((ndo, "\n\t Options [%s]", + ND_PRINT("\n\t Options [%s]", bittok2str(ospf6_option_values, "none", - EXTRACT_32BITS(&lsap->lsa_un.un_rla.rla_options)))); - ND_PRINT((ndo, ", RLA-Flags [%s]", + GET_BE_U_4(lsap->lsa_un.un_rla.rla_options))); + ND_PRINT(", RLA-Flags [%s]", bittok2str(ospf6_rla_flag_values, "none", - lsap->lsa_un.un_rla.rla_flags))); + GET_U_1(lsap->lsa_un.un_rla.rla_flags))); rlp = lsap->lsa_un.un_rla.rla_link; while (lsa_length != 0) { if (lsa_length < sizeof (*rlp)) return (1); lsa_length -= sizeof (*rlp); - ND_TCHECK(*rlp); - switch (rlp->link_type) { + ND_TCHECK_SIZE(rlp); + switch (GET_U_1(rlp->link_type)) { case RLA_TYPE_VIRTUAL: - ND_PRINT((ndo, "\n\t Virtual Link: Neighbor Router-ID %s" + ND_PRINT("\n\t Virtual Link: Neighbor Router-ID %s" "\n\t Neighbor Interface-ID %s, Interface %s", - ipaddr_string(ndo, &rlp->link_nrtid), - ipaddr_string(ndo, &rlp->link_nifid), - ipaddr_string(ndo, &rlp->link_ifid))); + GET_IPADDR_STRING(rlp->link_nrtid), + GET_IPADDR_STRING(rlp->link_nifid), + GET_IPADDR_STRING(rlp->link_ifid)); break; case RLA_TYPE_ROUTER: - ND_PRINT((ndo, "\n\t Neighbor Router-ID %s" + ND_PRINT("\n\t Neighbor Router-ID %s" "\n\t Neighbor Interface-ID %s, Interface %s", - ipaddr_string(ndo, &rlp->link_nrtid), - ipaddr_string(ndo, &rlp->link_nifid), - ipaddr_string(ndo, &rlp->link_ifid))); + GET_IPADDR_STRING(rlp->link_nrtid), + GET_IPADDR_STRING(rlp->link_nifid), + GET_IPADDR_STRING(rlp->link_ifid)); break; case RLA_TYPE_TRANSIT: - ND_PRINT((ndo, "\n\t Neighbor Network-ID %s" + ND_PRINT("\n\t Neighbor Network-ID %s" "\n\t Neighbor Interface-ID %s, Interface %s", - ipaddr_string(ndo, &rlp->link_nrtid), - ipaddr_string(ndo, &rlp->link_nifid), - ipaddr_string(ndo, &rlp->link_ifid))); + GET_IPADDR_STRING(rlp->link_nrtid), + GET_IPADDR_STRING(rlp->link_nifid), + GET_IPADDR_STRING(rlp->link_ifid)); break; default: - ND_PRINT((ndo, "\n\t Unknown Router Links Type 0x%02x", - rlp->link_type)); + ND_PRINT("\n\t Unknown Router Links Type 0x%02x", + GET_U_1(rlp->link_type)); return (0); } - ND_PRINT((ndo, ", metric %d", EXTRACT_16BITS(&rlp->link_metric))); + ND_PRINT(", metric %u", GET_BE_U_2(rlp->link_metric)); rlp++; } break; @@ -544,19 +542,18 @@ ospf6_print_lsa(netdissect_options *ndo, if (lsa_length < sizeof (lsap->lsa_un.un_nla.nla_options)) return (1); lsa_length -= sizeof (lsap->lsa_un.un_nla.nla_options); - ND_TCHECK(lsap->lsa_un.un_nla.nla_options); - ND_PRINT((ndo, "\n\t Options [%s]", + ND_PRINT("\n\t Options [%s]", bittok2str(ospf6_option_values, "none", - EXTRACT_32BITS(&lsap->lsa_un.un_nla.nla_options)))); + GET_BE_U_4(lsap->lsa_un.un_nla.nla_options))); - ND_PRINT((ndo, "\n\t Connected Routers:")); + ND_PRINT("\n\t Connected Routers:"); ap = lsap->lsa_un.un_nla.nla_router; while (lsa_length != 0) { if (lsa_length < sizeof (*ap)) return (1); lsa_length -= sizeof (*ap); - ND_TCHECK(*ap); - ND_PRINT((ndo, "\n\t\t%s", ipaddr_string(ndo, ap))); + ND_TCHECK_SIZE(ap); + ND_PRINT("\n\t\t%s", GET_IPADDR_STRING(*ap)); ++ap; } break; @@ -565,15 +562,19 @@ ospf6_print_lsa(netdissect_options *ndo, if (lsa_length < sizeof (lsap->lsa_un.un_inter_ap.inter_ap_metric)) return (1); lsa_length -= sizeof (lsap->lsa_un.un_inter_ap.inter_ap_metric); - ND_TCHECK(lsap->lsa_un.un_inter_ap.inter_ap_metric); - ND_PRINT((ndo, ", metric %u", - EXTRACT_32BITS(&lsap->lsa_un.un_inter_ap.inter_ap_metric) & SLA_MASK_METRIC)); + ND_PRINT(", metric %u", + GET_BE_U_4(lsap->lsa_un.un_inter_ap.inter_ap_metric) & SLA_MASK_METRIC); tptr = (const uint8_t *)lsap->lsa_un.un_inter_ap.inter_ap_prefix; while (lsa_length != 0) { bytelen = ospf6_print_lsaprefix(ndo, tptr, lsa_length); if (bytelen < 0) goto trunc; + /* + * ospf6_print_lsaprefix() will return -1 if + * the length is too high, so this will not + * underflow. + */ lsa_length -= bytelen; tptr += bytelen; } @@ -583,52 +584,50 @@ ospf6_print_lsa(netdissect_options *ndo, if (lsa_length < sizeof (lsap->lsa_un.un_asla.asla_metric)) return (1); lsa_length -= sizeof (lsap->lsa_un.un_asla.asla_metric); - ND_TCHECK(lsap->lsa_un.un_asla.asla_metric); - flags32 = EXTRACT_32BITS(&lsap->lsa_un.un_asla.asla_metric); - ND_PRINT((ndo, "\n\t Flags [%s]", - bittok2str(ospf6_asla_flag_values, "none", flags32))); - ND_PRINT((ndo, " metric %u", - EXTRACT_32BITS(&lsap->lsa_un.un_asla.asla_metric) & - ASLA_MASK_METRIC)); + flags32 = GET_BE_U_4(lsap->lsa_un.un_asla.asla_metric); + ND_PRINT("\n\t Flags [%s]", + bittok2str(ospf6_asla_flag_values, "none", flags32)); + ND_PRINT(" metric %u", + GET_BE_U_4(lsap->lsa_un.un_asla.asla_metric) & + ASLA_MASK_METRIC); tptr = (const uint8_t *)lsap->lsa_un.un_asla.asla_prefix; lsapp = (const struct lsa6_prefix *)tptr; bytelen = ospf6_print_lsaprefix(ndo, tptr, lsa_length); if (bytelen < 0) goto trunc; + /* + * ospf6_print_lsaprefix() will return -1 if + * the length is too high, so this will not + * underflow. + */ lsa_length -= bytelen; tptr += bytelen; if ((flags32 & ASLA_FLAG_FWDADDR) != 0) { - const struct in6_addr *fwdaddr6; - - fwdaddr6 = (const struct in6_addr *)tptr; - if (lsa_length < sizeof (*fwdaddr6)) + if (lsa_length < sizeof (nd_ipv6)) return (1); - lsa_length -= sizeof (*fwdaddr6); - ND_TCHECK(*fwdaddr6); - ND_PRINT((ndo, " forward %s", - ip6addr_string(ndo, fwdaddr6))); - tptr += sizeof(*fwdaddr6); + lsa_length -= sizeof (nd_ipv6); + ND_PRINT(" forward %s", + GET_IP6ADDR_STRING(tptr)); + tptr += sizeof(nd_ipv6); } if ((flags32 & ASLA_FLAG_ROUTETAG) != 0) { if (lsa_length < sizeof (uint32_t)) return (1); lsa_length -= sizeof (uint32_t); - ND_TCHECK(*(const uint32_t *)tptr); - ND_PRINT((ndo, " tag %s", - ipaddr_string(ndo, (const uint32_t *)tptr))); + ND_PRINT(" tag %s", + GET_IPADDR_STRING(tptr)); tptr += sizeof(uint32_t); } - if (lsapp->lsa_p_metric) { + if (GET_U_1(lsapp->lsa_p_metric)) { if (lsa_length < sizeof (uint32_t)) return (1); lsa_length -= sizeof (uint32_t); - ND_TCHECK(*(const uint32_t *)tptr); - ND_PRINT((ndo, " RefLSID: %s", - ipaddr_string(ndo, (const uint32_t *)tptr))); + ND_PRINT(" RefLSID: %s", + GET_IPADDR_STRING(tptr)); tptr += sizeof(uint32_t); } break; @@ -639,20 +638,19 @@ ospf6_print_lsa(netdissect_options *ndo, if (lsa_length < sizeof (llsap->llsa_priandopt)) return (1); lsa_length -= sizeof (llsap->llsa_priandopt); - ND_TCHECK(llsap->llsa_priandopt); - ND_PRINT((ndo, "\n\t Options [%s]", + ND_TCHECK_SIZE(&llsap->llsa_priandopt); + ND_PRINT("\n\t Options [%s]", bittok2str(ospf6_option_values, "none", - EXTRACT_32BITS(&llsap->llsa_options)))); + GET_BE_U_4(llsap->llsa_options))); if (lsa_length < sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix)) return (1); lsa_length -= sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix); - ND_TCHECK(llsap->llsa_nprefix); - prefixes = EXTRACT_32BITS(&llsap->llsa_nprefix); - ND_PRINT((ndo, "\n\t Priority %d, Link-local address %s, Prefixes %d:", - llsap->llsa_priority, - ip6addr_string(ndo, &llsap->llsa_lladdr), - prefixes)); + prefixes = GET_BE_U_4(llsap->llsa_nprefix); + ND_PRINT("\n\t Priority %u, Link-local address %s, Prefixes %u:", + GET_U_1(llsap->llsa_priority), + GET_IP6ADDR_STRING(llsap->llsa_lladdr), + prefixes); tptr = (const uint8_t *)llsap->llsa_prefix; while (prefixes > 0) { @@ -660,6 +658,11 @@ ospf6_print_lsa(netdissect_options *ndo, if (bytelen < 0) goto trunc; prefixes--; + /* + * ospf6_print_lsaprefix() will return -1 if + * the length is too high, so this will not + * underflow. + */ lsa_length -= bytelen; tptr += bytelen; } @@ -670,17 +673,16 @@ ospf6_print_lsa(netdissect_options *ndo, if (lsa_length < sizeof (lsap->lsa_un.un_intra_ap.intra_ap_rtid)) return (1); lsa_length -= sizeof (lsap->lsa_un.un_intra_ap.intra_ap_rtid); - ND_TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_rtid); + ND_TCHECK_4(lsap->lsa_un.un_intra_ap.intra_ap_rtid); ospf6_print_ls_type(ndo, - EXTRACT_16BITS(&lsap->lsa_un.un_intra_ap.intra_ap_lstype), + GET_BE_U_2(lsap->lsa_un.un_intra_ap.intra_ap_lstype), &lsap->lsa_un.un_intra_ap.intra_ap_lsid); if (lsa_length < sizeof (lsap->lsa_un.un_intra_ap.intra_ap_nprefix)) return (1); lsa_length -= sizeof (lsap->lsa_un.un_intra_ap.intra_ap_nprefix); - ND_TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_nprefix); - prefixes = EXTRACT_16BITS(&lsap->lsa_un.un_intra_ap.intra_ap_nprefix); - ND_PRINT((ndo, "\n\t Prefixes %d:", prefixes)); + prefixes = GET_BE_U_2(lsap->lsa_un.un_intra_ap.intra_ap_nprefix); + ND_PRINT("\n\t Prefixes %u:", prefixes); tptr = (const uint8_t *)lsap->lsa_un.un_intra_ap.intra_ap_prefix; while (prefixes > 0) { @@ -688,19 +690,24 @@ ospf6_print_lsa(netdissect_options *ndo, if (bytelen < 0) goto trunc; prefixes--; + /* + * ospf6_print_lsaprefix() will return -1 if + * the length is too high, so this will not + * underflow. + */ lsa_length -= bytelen; tptr += bytelen; } break; case LS_TYPE_GRACE | LS_SCOPE_LINKLOCAL: - if (ospf_print_grace_lsa(ndo, tptr, lsa_length) == -1) { + if (ospf_grace_lsa_print(ndo, tptr, lsa_length) == -1) { return 1; } break; case LS_TYPE_INTRA_ATE | LS_SCOPE_LINKLOCAL: - if (ospf_print_te_lsa(ndo, tptr, lsa_length) == -1) { + if (ospf_te_lsa_print(ndo, tptr, lsa_length) == -1) { return 1; } break; @@ -721,46 +728,42 @@ trunc: static int ospf6_decode_v3(netdissect_options *ndo, - register const struct ospf6hdr *op, - register const u_char *dataend) + const struct ospf6hdr *op, + const u_char *dataend) { - register const rtrid_t *ap; - register const struct lsr6 *lsrp; - register const struct lsa6_hdr *lshp; - register const struct lsa6 *lsap; - register int i; + const rtrid_t *ap; + const struct lsr6 *lsrp; + const struct lsa6_hdr *lshp; + const struct lsa6 *lsap; + int i; - switch (op->ospf6_type) { + switch (GET_U_1(op->ospf6_type)) { case OSPF_TYPE_HELLO: { - register const struct hello6 *hellop = (const struct hello6 *)((const uint8_t *)op + OSPF6HDR_LEN); + const struct hello6 *hellop = (const struct hello6 *)((const uint8_t *)op + OSPF6HDR_LEN); - ND_TCHECK_32BITS(&hellop->hello_options); - ND_PRINT((ndo, "\n\tOptions [%s]", + ND_PRINT("\n\tOptions [%s]", bittok2str(ospf6_option_values, "none", - EXTRACT_32BITS(&hellop->hello_options)))); - - ND_TCHECK(hellop->hello_deadint); - ND_PRINT((ndo, "\n\t Hello Timer %us, Dead Timer %us, Interface-ID %s, Priority %u", - EXTRACT_16BITS(&hellop->hello_helloint), - EXTRACT_16BITS(&hellop->hello_deadint), - ipaddr_string(ndo, &hellop->hello_ifid), - hellop->hello_priority)); - - ND_TCHECK(hellop->hello_dr); - if (EXTRACT_32BITS(&hellop->hello_dr) != 0) - ND_PRINT((ndo, "\n\t Designated Router %s", - ipaddr_string(ndo, &hellop->hello_dr))); - ND_TCHECK(hellop->hello_bdr); - if (EXTRACT_32BITS(&hellop->hello_bdr) != 0) - ND_PRINT((ndo, ", Backup Designated Router %s", - ipaddr_string(ndo, &hellop->hello_bdr))); + GET_BE_U_4(hellop->hello_options))); + + ND_PRINT("\n\t Hello Timer %us, Dead Timer %us, Interface-ID %s, Priority %u", + GET_BE_U_2(hellop->hello_helloint), + GET_BE_U_2(hellop->hello_deadint), + GET_IPADDR_STRING(hellop->hello_ifid), + GET_U_1(hellop->hello_priority)); + + if (GET_BE_U_4(hellop->hello_dr) != 0) + ND_PRINT("\n\t Designated Router %s", + GET_IPADDR_STRING(hellop->hello_dr)); + if (GET_BE_U_4(hellop->hello_bdr) != 0) + ND_PRINT(", Backup Designated Router %s", + GET_IPADDR_STRING(hellop->hello_bdr)); if (ndo->ndo_vflag > 1) { - ND_PRINT((ndo, "\n\t Neighbor List:")); + ND_PRINT("\n\t Neighbor List:"); ap = hellop->hello_neighbor; while ((const u_char *)ap < dataend) { - ND_TCHECK(*ap); - ND_PRINT((ndo, "\n\t %s", ipaddr_string(ndo, ap))); + ND_TCHECK_SIZE(ap); + ND_PRINT("\n\t %s", GET_IPADDR_STRING(*ap)); ++ap; } } @@ -768,20 +771,17 @@ ospf6_decode_v3(netdissect_options *ndo, } case OSPF_TYPE_DD: { - register const struct dd6 *ddp = (const struct dd6 *)((const uint8_t *)op + OSPF6HDR_LEN); + const struct dd6 *ddp = (const struct dd6 *)((const uint8_t *)op + OSPF6HDR_LEN); - ND_TCHECK(ddp->db_options); - ND_PRINT((ndo, "\n\tOptions [%s]", + ND_PRINT("\n\tOptions [%s]", bittok2str(ospf6_option_values, "none", - EXTRACT_32BITS(&ddp->db_options)))); - ND_TCHECK(ddp->db_flags); - ND_PRINT((ndo, ", DD Flags [%s]", - bittok2str(ospf6_dd_flag_values,"none",ddp->db_flags))); - - ND_TCHECK(ddp->db_seq); - ND_PRINT((ndo, ", MTU %u, DD-Sequence 0x%08x", - EXTRACT_16BITS(&ddp->db_mtu), - EXTRACT_32BITS(&ddp->db_seq))); + GET_BE_U_4(ddp->db_options))); + ND_PRINT(", DD Flags [%s]", + bittok2str(ospf6_dd_flag_values,"none",GET_U_1(ddp->db_flags))); + + ND_PRINT(", MTU %u, DD-Sequence 0x%08x", + GET_BE_U_2(ddp->db_mtu), + GET_BE_U_4(ddp->db_seq)); if (ndo->ndo_vflag > 1) { /* Print all the LS adv's */ lshp = ddp->db_lshdr; @@ -797,10 +797,11 @@ ospf6_decode_v3(netdissect_options *ndo, if (ndo->ndo_vflag > 1) { lsrp = (const struct lsr6 *)((const uint8_t *)op + OSPF6HDR_LEN); while ((const u_char *)lsrp < dataend) { - ND_TCHECK(*lsrp); - ND_PRINT((ndo, "\n\t Advertising Router %s", - ipaddr_string(ndo, &lsrp->ls_router))); - ospf6_print_ls_type(ndo, EXTRACT_16BITS(&lsrp->ls_type), + ND_TCHECK_SIZE(lsrp); + ND_PRINT("\n\t Advertising Router %s", + GET_IPADDR_STRING(lsrp->ls_router)); + ospf6_print_ls_type(ndo, + GET_BE_U_2(lsrp->ls_type), &lsrp->ls_stateid); ++lsrp; } @@ -809,16 +810,15 @@ ospf6_decode_v3(netdissect_options *ndo, case OSPF_TYPE_LS_UPDATE: if (ndo->ndo_vflag > 1) { - register const struct lsu6 *lsup = (const struct lsu6 *)((const uint8_t *)op + OSPF6HDR_LEN); + const struct lsu6 *lsup = (const struct lsu6 *)((const uint8_t *)op + OSPF6HDR_LEN); - ND_TCHECK(lsup->lsu_count); - i = EXTRACT_32BITS(&lsup->lsu_count); + i = GET_BE_U_4(lsup->lsu_count); lsap = lsup->lsu_lsa; while ((const u_char *)lsap < dataend && i--) { if (ospf6_print_lsa(ndo, lsap, dataend)) goto trunc; lsap = (const struct lsa6 *)((const u_char *)lsap + - EXTRACT_16BITS(&lsap->ls_hdr.ls_length)); + GET_BE_U_2(lsap->ls_hdr.ls_length)); } } break; @@ -853,18 +853,16 @@ ospf6_print_lls(netdissect_options *ndo, if (len < OSPF_LLS_HDRLEN) goto trunc; /* Checksum */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, "\n\tLLS Checksum 0x%04x", EXTRACT_16BITS(cp))); + ND_PRINT("\n\tLLS Checksum 0x%04x", GET_BE_U_2(cp)); cp += 2; /* LLS Data Length */ - ND_TCHECK2(*cp, 2); - llsdatalen = EXTRACT_16BITS(cp); - ND_PRINT((ndo, ", Data Length %u", llsdatalen)); + llsdatalen = GET_BE_U_2(cp); + ND_PRINT(", Data Length %u", llsdatalen); if (llsdatalen < OSPF_LLS_HDRLEN || llsdatalen > len) goto trunc; cp += 2; /* LLS TLVs */ - ND_TCHECK2(*cp, llsdatalen - OSPF_LLS_HDRLEN); + ND_TCHECK_LEN(cp, llsdatalen - OSPF_LLS_HDRLEN); /* FIXME: code in print-ospf.c can be reused to decode the TLVs */ return llsdatalen; @@ -884,33 +882,28 @@ ospf6_decode_at(netdissect_options *ndo, if (len < OSPF6_AT_HDRLEN) goto trunc; /* Authentication Type */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, "\n\tAuthentication Type %s", tok2str(ospf6_auth_type_str, "unknown (0x%04x)", EXTRACT_16BITS(cp)))); + ND_PRINT("\n\tAuthentication Type %s", + tok2str(ospf6_auth_type_str, "unknown (0x%04x)", GET_BE_U_2(cp))); cp += 2; /* Auth Data Len */ - ND_TCHECK2(*cp, 2); - authdatalen = EXTRACT_16BITS(cp); - ND_PRINT((ndo, ", Length %u", authdatalen)); + authdatalen = GET_BE_U_2(cp); + ND_PRINT(", Length %u", authdatalen); if (authdatalen < OSPF6_AT_HDRLEN || authdatalen > len) goto trunc; cp += 2; /* Reserved */ - ND_TCHECK2(*cp, 2); cp += 2; /* Security Association ID */ - ND_TCHECK2(*cp, 2); - ND_PRINT((ndo, ", SAID %u", EXTRACT_16BITS(cp))); + ND_PRINT(", SAID %u", GET_BE_U_2(cp)); cp += 2; /* Cryptographic Sequence Number (High-Order 32 Bits) */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, ", CSN 0x%08x", EXTRACT_32BITS(cp))); + ND_PRINT(", CSN 0x%08x", GET_BE_U_4(cp)); cp += 4; /* Cryptographic Sequence Number (Low-Order 32 Bits) */ - ND_TCHECK2(*cp, 4); - ND_PRINT((ndo, ":%08x", EXTRACT_32BITS(cp))); + ND_PRINT(":%08x", GET_BE_U_4(cp)); cp += 4; /* Authentication Data */ - ND_TCHECK2(*cp, authdatalen - OSPF6_AT_HDRLEN); + ND_TCHECK_LEN(cp, authdatalen - OSPF6_AT_HDRLEN); if (ndo->ndo_vflag > 1) print_unknown_data(ndo,cp, "\n\tAuthentication Data ", authdatalen - OSPF6_AT_HDRLEN); return 0; @@ -928,19 +921,19 @@ static int ospf6_decode_v3_trailer(netdissect_options *ndo, const struct ospf6hdr *op, const u_char *cp, const unsigned len) { + uint8_t type; int llslen = 0; int lls_hello = 0; int lls_dd = 0; - if (op->ospf6_type == OSPF_TYPE_HELLO) { + type = GET_U_1(op->ospf6_type); + if (type == OSPF_TYPE_HELLO) { const struct hello6 *hellop = (const struct hello6 *)((const uint8_t *)op + OSPF6HDR_LEN); - ND_TCHECK(hellop->hello_options); - if (EXTRACT_32BITS(&hellop->hello_options) & OSPF6_OPTION_L) + if (GET_BE_U_4(hellop->hello_options) & OSPF6_OPTION_L) lls_hello = 1; - } else if (op->ospf6_type == OSPF_TYPE_DD) { + } else if (type == OSPF_TYPE_DD) { const struct dd6 *ddp = (const struct dd6 *)((const uint8_t *)op + OSPF6HDR_LEN); - ND_TCHECK(ddp->db_options); - if (EXTRACT_32BITS(&ddp->db_options) & OSPF6_OPTION_L) + if (GET_BE_U_4(ddp->db_options) & OSPF6_OPTION_L) lls_dd = 1; } if ((lls_hello || lls_dd) && (llslen = ospf6_print_lls(ndo, cp, len)) < 0) @@ -953,20 +946,22 @@ trunc: void ospf6_print(netdissect_options *ndo, - register const u_char *bp, register u_int length) + const u_char *bp, u_int length) { - register const struct ospf6hdr *op; - register const u_char *dataend; - register const char *cp; + const struct ospf6hdr *op; + const u_char *dataend; + const char *cp; uint16_t datalen; + ndo->ndo_protocol = "ospf3"; op = (const struct ospf6hdr *)bp; /* If the type is valid translate it, or just print the type */ /* value. If it's not valid, say so and return */ - ND_TCHECK(op->ospf6_type); - cp = tok2str(ospf6_type_values, "unknown packet type (%u)", op->ospf6_type); - ND_PRINT((ndo, "OSPFv%u, %s, length %d", op->ospf6_version, cp, length)); + cp = tok2str(ospf6_type_values, "unknown packet type (%u)", + GET_U_1(op->ospf6_type)); + ND_PRINT("OSPFv%u, %s, length %u", GET_U_1(op->ospf6_version), cp, + length); if (*cp == 'u') { return; } @@ -976,28 +971,24 @@ ospf6_print(netdissect_options *ndo, } /* OSPFv3 data always comes first and optional trailing data may follow. */ - ND_TCHECK(op->ospf6_len); - datalen = EXTRACT_16BITS(&op->ospf6_len); + datalen = GET_BE_U_2(op->ospf6_len); if (datalen > length) { - ND_PRINT((ndo, " [len %d]", datalen)); + ND_PRINT(" [len %u]", datalen); return; } dataend = bp + datalen; - ND_TCHECK(op->ospf6_routerid); - ND_PRINT((ndo, "\n\tRouter-ID %s", ipaddr_string(ndo, &op->ospf6_routerid))); + ND_PRINT("\n\tRouter-ID %s", GET_IPADDR_STRING(op->ospf6_routerid)); - ND_TCHECK(op->ospf6_areaid); - if (EXTRACT_32BITS(&op->ospf6_areaid) != 0) - ND_PRINT((ndo, ", Area %s", ipaddr_string(ndo, &op->ospf6_areaid))); + if (GET_BE_U_4(op->ospf6_areaid) != 0) + ND_PRINT(", Area %s", GET_IPADDR_STRING(op->ospf6_areaid)); else - ND_PRINT((ndo, ", Backbone Area")); - ND_TCHECK(op->ospf6_instanceid); - if (op->ospf6_instanceid) - ND_PRINT((ndo, ", Instance %u", op->ospf6_instanceid)); + ND_PRINT(", Backbone Area"); + if (GET_U_1(op->ospf6_instanceid)) + ND_PRINT(", Instance %u", GET_U_1(op->ospf6_instanceid)); /* Do rest according to version. */ - switch (op->ospf6_version) { + switch (GET_U_1(op->ospf6_version)) { case 3: /* ospf version 3 */ @@ -1009,5 +1000,5 @@ ospf6_print(netdissect_options *ndo, return; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); } diff --git a/contrib/tcpdump/print-otv.c b/contrib/tcpdump/print-otv.c index 5a82752c19..a0fe9d0eb5 100644 --- a/contrib/tcpdump/print-otv.c +++ b/contrib/tcpdump/print-otv.c @@ -18,14 +18,17 @@ /* specification: draft-hasmit-otv-04 */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" +#define OTV_HDR_LEN 8 + /* * OTV header, draft-hasmit-otv-04 * @@ -43,30 +46,31 @@ otv_print(netdissect_options *ndo, const u_char *bp, u_int len) { uint8_t flags; - ND_PRINT((ndo, "OTV, ")); - if (len < 8) - goto trunc; + ndo->ndo_protocol = "otv"; + ND_PRINT("OTV, "); + if (len < OTV_HDR_LEN) { + ND_PRINT("[length %u < %u]", len, OTV_HDR_LEN); + goto invalid; + } - ND_TCHECK(*bp); - flags = *bp; - ND_PRINT((ndo, "flags [%s] (0x%02x), ", flags & 0x08 ? "I" : ".", flags)); + flags = GET_U_1(bp); + ND_PRINT("flags [%s] (0x%02x), ", flags & 0x08 ? "I" : ".", flags); bp += 1; - ND_TCHECK2(*bp, 3); - ND_PRINT((ndo, "overlay %u, ", EXTRACT_24BITS(bp))); + ND_PRINT("overlay %u, ", GET_BE_U_3(bp)); bp += 3; - ND_TCHECK2(*bp, 3); - ND_PRINT((ndo, "instance %u\n", EXTRACT_24BITS(bp))); + ND_PRINT("instance %u\n", GET_BE_U_3(bp)); bp += 3; /* Reserved */ - ND_TCHECK(*bp); + ND_TCHECK_1(bp); bp += 1; - ether_print(ndo, bp, len - 8, ndo->ndo_snapend - bp, NULL, NULL); + ether_print(ndo, bp, len - OTV_HDR_LEN, ND_BYTES_AVAILABLE_AFTER(bp), NULL, NULL); return; -trunc: - ND_PRINT((ndo, " [|OTV]")); +invalid: + nd_print_invalid(ndo); + ND_TCHECK_LEN(bp, len); } diff --git a/contrib/tcpdump/print-pflog.c b/contrib/tcpdump/print-pflog.c index 265efd3c86..eb1b1766db 100644 --- a/contrib/tcpdump/print-pflog.c +++ b/contrib/tcpdump/print-pflog.c @@ -22,7 +22,7 @@ /* \summary: OpenBSD packet filter log file printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif #ifndef HAVE_NET_PFVAR_H @@ -34,12 +34,11 @@ #include #include -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "extract.h" -static const char tstr[] = "[|pflog]"; static const struct tok pf_reasons[] = { { 0, "0(match)" }, @@ -90,23 +89,28 @@ pflog_print(netdissect_options *ndo, const struct pfloghdr *hdr) { uint32_t rulenr, subrulenr; - rulenr = EXTRACT_32BITS(&hdr->rulenr); - subrulenr = EXTRACT_32BITS(&hdr->subrulenr); + ndo->ndo_protocol = "pflog"; + rulenr = GET_BE_U_4(&hdr->rulenr); + subrulenr = GET_BE_U_4(&hdr->subrulenr); if (subrulenr == (uint32_t)-1) - ND_PRINT((ndo, "rule %u/", rulenr)); - else - ND_PRINT((ndo, "rule %u.%s.%u/", rulenr, hdr->ruleset, subrulenr)); - - ND_PRINT((ndo, "%s: %s %s on %s: ", - tok2str(pf_reasons, "unkn(%u)", hdr->reason), - tok2str(pf_actions, "unkn(%u)", hdr->action), - tok2str(pf_directions, "unkn(%u)", hdr->dir), - hdr->ifname)); + ND_PRINT("rule %u/", rulenr); + else { + ND_PRINT("rule %u.", rulenr); + nd_printjnp(ndo, (const u_char*)hdr->ruleset, PFLOG_RULESET_NAME_SIZE); + ND_PRINT(".%u/", subrulenr); + } + + ND_PRINT("%s: %s %s on ", + tok2str(pf_reasons, "unkn(%u)", GET_U_1(&hdr->reason)), + tok2str(pf_actions, "unkn(%u)", GET_U_1(&hdr->action)), + tok2str(pf_directions, "unkn(%u)", GET_U_1(&hdr->dir))); + nd_printjnp(ndo, (const u_char*)hdr->ifname, IFNAMSIZ); + ND_PRINT(": "); } -u_int +void pflog_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, - register const u_char *p) + const u_char *p) { u_int length = h->len; u_int hdrlen; @@ -114,32 +118,36 @@ pflog_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const struct pfloghdr *hdr; uint8_t af; + ndo->ndo_protocol = "pflog"; /* check length */ if (caplen < sizeof(uint8_t)) { - ND_PRINT((ndo, "%s", tstr)); - return (caplen); + nd_print_trunc(ndo); + ndo->ndo_ll_hdr_len += h->caplen; + return; } #define MIN_PFLOG_HDRLEN 45 hdr = (const struct pfloghdr *)p; - if (hdr->length < MIN_PFLOG_HDRLEN) { - ND_PRINT((ndo, "[pflog: invalid header length!]")); - return (hdr->length); /* XXX: not really */ + if (GET_U_1(&hdr->length) < MIN_PFLOG_HDRLEN) { + ND_PRINT("[pflog: invalid header length!]"); + ndo->ndo_ll_hdr_len += GET_U_1(&hdr->length); /* XXX: not really */ + return; } hdrlen = BPF_WORDALIGN(hdr->length); if (caplen < hdrlen) { - ND_PRINT((ndo, "%s", tstr)); - return (hdrlen); /* XXX: true? */ + nd_print_trunc(ndo); + ndo->ndo_ll_hdr_len += hdrlen; /* XXX: true? */ + return; } /* print what we know */ - ND_TCHECK(*hdr); + ND_TCHECK_SIZE(hdr); if (ndo->ndo_eflag) pflog_print(ndo, hdr); /* skip to the real packet */ - af = hdr->af; + af = GET_U_1(&hdr->af); length -= hdrlen; caplen -= hdrlen; p += hdrlen; @@ -171,15 +179,9 @@ pflog_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, ND_DEFAULTPRINT(p, caplen); } - return (hdrlen); + ndo->ndo_ll_hdr_len += hdrlen; + return; trunc: - ND_PRINT((ndo, "%s", tstr)); - return (hdrlen); + nd_print_trunc(ndo); + ndo->ndo_ll_hdr_len += hdrlen; } - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/print-pgm.c b/contrib/tcpdump/print-pgm.c index 8340f2c3eb..ccb0b46afe 100644 --- a/contrib/tcpdump/print-pgm.c +++ b/contrib/tcpdump/print-pgm.c @@ -16,10 +16,10 @@ /* \summary: Pragmatic General Multicast (PGM) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "extract.h" @@ -35,29 +35,29 @@ * PGM header (RFC 3208) */ struct pgm_header { - uint16_t pgm_sport; - uint16_t pgm_dport; - uint8_t pgm_type; - uint8_t pgm_options; - uint16_t pgm_sum; - uint8_t pgm_gsid[6]; - uint16_t pgm_length; + nd_uint16_t pgm_sport; + nd_uint16_t pgm_dport; + nd_uint8_t pgm_type; + nd_uint8_t pgm_options; + nd_uint16_t pgm_sum; + nd_byte pgm_gsid[6]; + nd_uint16_t pgm_length; }; struct pgm_spm { - uint32_t pgms_seq; - uint32_t pgms_trailseq; - uint32_t pgms_leadseq; - uint16_t pgms_nla_afi; - uint16_t pgms_reserved; + nd_uint32_t pgms_seq; + nd_uint32_t pgms_trailseq; + nd_uint32_t pgms_leadseq; + nd_uint16_t pgms_nla_afi; + nd_uint16_t pgms_reserved; /* ... uint8_t pgms_nla[0]; */ /* ... options */ }; struct pgm_nak { - uint32_t pgmn_seq; - uint16_t pgmn_source_afi; - uint16_t pgmn_reserved; + nd_uint32_t pgmn_seq; + nd_uint16_t pgmn_source_afi; + nd_uint16_t pgmn_reserved; /* ... uint8_t pgmn_source[0]; */ /* ... uint16_t pgmn_group_afi */ /* ... uint16_t pgmn_reserved2; */ @@ -66,31 +66,31 @@ struct pgm_nak { }; struct pgm_ack { - uint32_t pgma_rx_max_seq; - uint32_t pgma_bitmap; + nd_uint32_t pgma_rx_max_seq; + nd_uint32_t pgma_bitmap; /* ... options */ }; struct pgm_poll { - uint32_t pgmp_seq; - uint16_t pgmp_round; - uint16_t pgmp_reserved; + nd_uint32_t pgmp_seq; + nd_uint16_t pgmp_round; + nd_uint16_t pgmp_subtype; + nd_uint16_t pgmp_nla_afi; + nd_uint16_t pgmp_reserved; + /* ... uint8_t pgmp_nla[0]; */ /* ... options */ }; struct pgm_polr { - uint32_t pgmp_seq; - uint16_t pgmp_round; - uint16_t pgmp_subtype; - uint16_t pgmp_nla_afi; - uint16_t pgmp_reserved; - /* ... uint8_t pgmp_nla[0]; */ + nd_uint32_t pgmp_seq; + nd_uint16_t pgmp_round; + nd_uint16_t pgmp_reserved; /* ... options */ }; struct pgm_data { - uint32_t pgmd_seq; - uint32_t pgmd_trailseq; + nd_uint32_t pgmd_seq; + nd_uint32_t pgmd_trailseq; /* ... options */ }; @@ -144,172 +144,172 @@ typedef enum _pgm_type { void pgm_print(netdissect_options *ndo, - register const u_char *bp, register u_int length, - register const u_char *bp2) + const u_char *bp, u_int length, + const u_char *bp2) { - register const struct pgm_header *pgm; - register const struct ip *ip; - register char ch; + const struct pgm_header *pgm; + const struct ip *ip; + uint8_t pgm_type_val; uint16_t sport, dport; u_int nla_afnum; char nla_buf[INET6_ADDRSTRLEN]; - register const struct ip6_hdr *ip6; + const struct ip6_hdr *ip6; uint8_t opt_type, opt_len; uint32_t seq, opts_len, len, offset; + ndo->ndo_protocol = "pgm"; pgm = (const struct pgm_header *)bp; ip = (const struct ip *)bp2; if (IP_V(ip) == 6) ip6 = (const struct ip6_hdr *)bp2; else ip6 = NULL; - ch = '\0'; - if (!ND_TTEST(pgm->pgm_dport)) { + if (!ND_TTEST_2(pgm->pgm_dport)) { if (ip6) { - ND_PRINT((ndo, "%s > %s: [|pgm]", - ip6addr_string(ndo, &ip6->ip6_src), - ip6addr_string(ndo, &ip6->ip6_dst))); + ND_PRINT("%s > %s:", + GET_IP6ADDR_STRING(ip6->ip6_src), + GET_IP6ADDR_STRING(ip6->ip6_dst)); } else { - ND_PRINT((ndo, "%s > %s: [|pgm]", - ipaddr_string(ndo, &ip->ip_src), - ipaddr_string(ndo, &ip->ip_dst))); + ND_PRINT("%s > %s:", + GET_IPADDR_STRING(ip->ip_src), + GET_IPADDR_STRING(ip->ip_dst)); } + nd_print_trunc(ndo); return; } - sport = EXTRACT_16BITS(&pgm->pgm_sport); - dport = EXTRACT_16BITS(&pgm->pgm_dport); + sport = GET_BE_U_2(pgm->pgm_sport); + dport = GET_BE_U_2(pgm->pgm_dport); if (ip6) { - if (ip6->ip6_nxt == IPPROTO_PGM) { - ND_PRINT((ndo, "%s.%s > %s.%s: ", - ip6addr_string(ndo, &ip6->ip6_src), + if (GET_U_1(ip6->ip6_nxt) == IPPROTO_PGM) { + ND_PRINT("%s.%s > %s.%s: ", + GET_IP6ADDR_STRING(ip6->ip6_src), tcpport_string(ndo, sport), - ip6addr_string(ndo, &ip6->ip6_dst), - tcpport_string(ndo, dport))); + GET_IP6ADDR_STRING(ip6->ip6_dst), + tcpport_string(ndo, dport)); } else { - ND_PRINT((ndo, "%s > %s: ", - tcpport_string(ndo, sport), tcpport_string(ndo, dport))); + ND_PRINT("%s > %s: ", + tcpport_string(ndo, sport), tcpport_string(ndo, dport)); } } else { - if (ip->ip_p == IPPROTO_PGM) { - ND_PRINT((ndo, "%s.%s > %s.%s: ", - ipaddr_string(ndo, &ip->ip_src), + if (GET_U_1(ip->ip_p) == IPPROTO_PGM) { + ND_PRINT("%s.%s > %s.%s: ", + GET_IPADDR_STRING(ip->ip_src), tcpport_string(ndo, sport), - ipaddr_string(ndo, &ip->ip_dst), - tcpport_string(ndo, dport))); + GET_IPADDR_STRING(ip->ip_dst), + tcpport_string(ndo, dport)); } else { - ND_PRINT((ndo, "%s > %s: ", - tcpport_string(ndo, sport), tcpport_string(ndo, dport))); + ND_PRINT("%s > %s: ", + tcpport_string(ndo, sport), tcpport_string(ndo, dport)); } } - ND_TCHECK(*pgm); + ND_TCHECK_SIZE(pgm); - ND_PRINT((ndo, "PGM, length %u", EXTRACT_16BITS(&pgm->pgm_length))); + ND_PRINT("PGM, length %u", GET_BE_U_2(pgm->pgm_length)); if (!ndo->ndo_vflag) return; - ND_PRINT((ndo, " 0x%02x%02x%02x%02x%02x%02x ", + pgm_type_val = GET_U_1(pgm->pgm_type); + ND_PRINT(" 0x%02x%02x%02x%02x%02x%02x ", pgm->pgm_gsid[0], pgm->pgm_gsid[1], pgm->pgm_gsid[2], pgm->pgm_gsid[3], pgm->pgm_gsid[4], - pgm->pgm_gsid[5])); - switch (pgm->pgm_type) { + pgm->pgm_gsid[5]); + switch (pgm_type_val) { case PGM_SPM: { const struct pgm_spm *spm; spm = (const struct pgm_spm *)(pgm + 1); - ND_TCHECK(*spm); + ND_TCHECK_SIZE(spm); bp = (const u_char *) (spm + 1); - switch (EXTRACT_16BITS(&spm->pgms_nla_afi)) { + switch (GET_BE_U_2(spm->pgms_nla_afi)) { case AFNUM_INET: - ND_TCHECK2(*bp, sizeof(struct in_addr)); + ND_TCHECK_LEN(bp, sizeof(nd_ipv4)); addrtostr(bp, nla_buf, sizeof(nla_buf)); - bp += sizeof(struct in_addr); + bp += sizeof(nd_ipv4); break; case AFNUM_INET6: - ND_TCHECK2(*bp, sizeof(struct in6_addr)); + ND_TCHECK_LEN(bp, sizeof(nd_ipv6)); addrtostr6(bp, nla_buf, sizeof(nla_buf)); - bp += sizeof(struct in6_addr); + bp += sizeof(nd_ipv6); break; default: goto trunc; break; } - ND_PRINT((ndo, "SPM seq %u trail %u lead %u nla %s", - EXTRACT_32BITS(&spm->pgms_seq), - EXTRACT_32BITS(&spm->pgms_trailseq), - EXTRACT_32BITS(&spm->pgms_leadseq), - nla_buf)); + ND_PRINT("SPM seq %u trail %u lead %u nla %s", + GET_BE_U_4(spm->pgms_seq), + GET_BE_U_4(spm->pgms_trailseq), + GET_BE_U_4(spm->pgms_leadseq), + nla_buf); break; } case PGM_POLL: { - const struct pgm_poll *poll_msg; - - poll_msg = (const struct pgm_poll *)(pgm + 1); - ND_TCHECK(*poll_msg); - ND_PRINT((ndo, "POLL seq %u round %u", - EXTRACT_32BITS(&poll_msg->pgmp_seq), - EXTRACT_16BITS(&poll_msg->pgmp_round))); - bp = (const u_char *) (poll_msg + 1); - break; - } - case PGM_POLR: { - const struct pgm_polr *polr; + const struct pgm_poll *pgm_poll; uint32_t ivl, rnd, mask; - polr = (const struct pgm_polr *)(pgm + 1); - ND_TCHECK(*polr); - bp = (const u_char *) (polr + 1); + pgm_poll = (const struct pgm_poll *)(pgm + 1); + ND_TCHECK_SIZE(pgm_poll); + bp = (const u_char *) (pgm_poll + 1); - switch (EXTRACT_16BITS(&polr->pgmp_nla_afi)) { + switch (GET_BE_U_2(pgm_poll->pgmp_nla_afi)) { case AFNUM_INET: - ND_TCHECK2(*bp, sizeof(struct in_addr)); + ND_TCHECK_LEN(bp, sizeof(nd_ipv4)); addrtostr(bp, nla_buf, sizeof(nla_buf)); - bp += sizeof(struct in_addr); + bp += sizeof(nd_ipv4); break; case AFNUM_INET6: - ND_TCHECK2(*bp, sizeof(struct in6_addr)); + ND_TCHECK_LEN(bp, sizeof(nd_ipv6)); addrtostr6(bp, nla_buf, sizeof(nla_buf)); - bp += sizeof(struct in6_addr); + bp += sizeof(nd_ipv6); break; default: goto trunc; break; } - ND_TCHECK2(*bp, sizeof(uint32_t)); - ivl = EXTRACT_32BITS(bp); + ivl = GET_BE_U_4(bp); bp += sizeof(uint32_t); - ND_TCHECK2(*bp, sizeof(uint32_t)); - rnd = EXTRACT_32BITS(bp); + rnd = GET_BE_U_4(bp); bp += sizeof(uint32_t); - ND_TCHECK2(*bp, sizeof(uint32_t)); - mask = EXTRACT_32BITS(bp); + mask = GET_BE_U_4(bp); bp += sizeof(uint32_t); - ND_PRINT((ndo, "POLR seq %u round %u nla %s ivl %u rnd 0x%08x " - "mask 0x%08x", EXTRACT_32BITS(&polr->pgmp_seq), - EXTRACT_16BITS(&polr->pgmp_round), nla_buf, ivl, rnd, mask)); + ND_PRINT("POLL seq %u round %u nla %s ivl %u rnd 0x%08x " + "mask 0x%08x", GET_BE_U_4(pgm_poll->pgmp_seq), + GET_BE_U_2(pgm_poll->pgmp_round), nla_buf, ivl, rnd, + mask); + break; + } + case PGM_POLR: { + const struct pgm_polr *polr_msg; + + polr_msg = (const struct pgm_polr *)(pgm + 1); + ND_TCHECK_SIZE(polr_msg); + ND_PRINT("POLR seq %u round %u", + GET_BE_U_4(polr_msg->pgmp_seq), + GET_BE_U_2(polr_msg->pgmp_round)); + bp = (const u_char *) (polr_msg + 1); break; } case PGM_ODATA: { const struct pgm_data *odata; odata = (const struct pgm_data *)(pgm + 1); - ND_TCHECK(*odata); - ND_PRINT((ndo, "ODATA trail %u seq %u", - EXTRACT_32BITS(&odata->pgmd_trailseq), - EXTRACT_32BITS(&odata->pgmd_seq))); + ND_TCHECK_SIZE(odata); + ND_PRINT("ODATA trail %u seq %u", + GET_BE_U_4(odata->pgmd_trailseq), + GET_BE_U_4(odata->pgmd_seq)); bp = (const u_char *) (odata + 1); break; } @@ -318,10 +318,10 @@ pgm_print(netdissect_options *ndo, const struct pgm_data *rdata; rdata = (const struct pgm_data *)(pgm + 1); - ND_TCHECK(*rdata); - ND_PRINT((ndo, "RDATA trail %u seq %u", - EXTRACT_32BITS(&rdata->pgmd_trailseq), - EXTRACT_32BITS(&rdata->pgmd_seq))); + ND_TCHECK_SIZE(rdata); + ND_PRINT("RDATA trail %u seq %u", + GET_BE_U_4(rdata->pgmd_trailseq), + GET_BE_U_4(rdata->pgmd_seq)); bp = (const u_char *) (rdata + 1); break; } @@ -333,23 +333,23 @@ pgm_print(netdissect_options *ndo, char source_buf[INET6_ADDRSTRLEN], group_buf[INET6_ADDRSTRLEN]; nak = (const struct pgm_nak *)(pgm + 1); - ND_TCHECK(*nak); + ND_TCHECK_SIZE(nak); bp = (const u_char *) (nak + 1); /* * Skip past the source, saving info along the way * and stopping if we don't have enough. */ - switch (EXTRACT_16BITS(&nak->pgmn_source_afi)) { + switch (GET_BE_U_2(nak->pgmn_source_afi)) { case AFNUM_INET: - ND_TCHECK2(*bp, sizeof(struct in_addr)); + ND_TCHECK_LEN(bp, sizeof(nd_ipv4)); addrtostr(bp, source_buf, sizeof(source_buf)); - bp += sizeof(struct in_addr); + bp += sizeof(nd_ipv4); break; case AFNUM_INET6: - ND_TCHECK2(*bp, sizeof(struct in6_addr)); + ND_TCHECK_LEN(bp, sizeof(nd_ipv6)); addrtostr6(bp, source_buf, sizeof(source_buf)); - bp += sizeof(struct in6_addr); + bp += sizeof(nd_ipv6); break; default: goto trunc; @@ -361,17 +361,16 @@ pgm_print(netdissect_options *ndo, * and stopping if we don't have enough. */ bp += (2 * sizeof(uint16_t)); - ND_TCHECK_16BITS(bp); - switch (EXTRACT_16BITS(bp)) { + switch (GET_BE_U_2(bp)) { case AFNUM_INET: - ND_TCHECK2(*bp, sizeof(struct in_addr)); + ND_TCHECK_LEN(bp, sizeof(nd_ipv4)); addrtostr(bp, group_buf, sizeof(group_buf)); - bp += sizeof(struct in_addr); + bp += sizeof(nd_ipv4); break; case AFNUM_INET6: - ND_TCHECK2(*bp, sizeof(struct in6_addr)); + ND_TCHECK_LEN(bp, sizeof(nd_ipv6)); addrtostr6(bp, group_buf, sizeof(group_buf)); - bp += sizeof(struct in6_addr); + bp += sizeof(nd_ipv6); break; default: goto trunc; @@ -381,21 +380,21 @@ pgm_print(netdissect_options *ndo, /* * Options decoding can go here. */ - switch (pgm->pgm_type) { + switch (pgm_type_val) { case PGM_NAK: - ND_PRINT((ndo, "NAK ")); + ND_PRINT("NAK "); break; case PGM_NULLNAK: - ND_PRINT((ndo, "NNAK ")); + ND_PRINT("NNAK "); break; case PGM_NCF: - ND_PRINT((ndo, "NCF ")); + ND_PRINT("NCF "); break; default: break; } - ND_PRINT((ndo, "(%s -> %s), seq %u", - source_buf, group_buf, EXTRACT_32BITS(&nak->pgmn_seq))); + ND_PRINT("(%s -> %s), seq %u", + source_buf, group_buf, GET_BE_U_4(nak->pgmn_seq)); break; } @@ -403,89 +402,83 @@ pgm_print(netdissect_options *ndo, const struct pgm_ack *ack; ack = (const struct pgm_ack *)(pgm + 1); - ND_TCHECK(*ack); - ND_PRINT((ndo, "ACK seq %u", - EXTRACT_32BITS(&ack->pgma_rx_max_seq))); + ND_TCHECK_SIZE(ack); + ND_PRINT("ACK seq %u", + GET_BE_U_4(ack->pgma_rx_max_seq)); bp = (const u_char *) (ack + 1); break; } case PGM_SPMR: - ND_PRINT((ndo, "SPMR")); + ND_PRINT("SPMR"); break; default: - ND_PRINT((ndo, "UNKNOWN type 0x%02x", pgm->pgm_type)); + ND_PRINT("UNKNOWN type 0x%02x", pgm_type_val); break; } - if (pgm->pgm_options & PGM_OPT_BIT_PRESENT) { + if (GET_U_1(pgm->pgm_options) & PGM_OPT_BIT_PRESENT) { /* * make sure there's enough for the first option header */ - if (!ND_TTEST2(*bp, PGM_MIN_OPT_LEN)) { - ND_PRINT((ndo, "[|OPT]")); - return; - } + ND_TCHECK_LEN(bp, PGM_MIN_OPT_LEN); /* * That option header MUST be an OPT_LENGTH option * (see the first paragraph of section 9.1 in RFC 3208). */ - opt_type = *bp++; + opt_type = GET_U_1(bp); + bp++; if ((opt_type & PGM_OPT_MASK) != PGM_OPT_LENGTH) { - ND_PRINT((ndo, "[First option bad, should be PGM_OPT_LENGTH, is %u]", opt_type & PGM_OPT_MASK)); + ND_PRINT("[First option bad, should be PGM_OPT_LENGTH, is %u]", opt_type & PGM_OPT_MASK); return; } - opt_len = *bp++; + opt_len = GET_U_1(bp); + bp++; if (opt_len != 4) { - ND_PRINT((ndo, "[Bad OPT_LENGTH option, length %u != 4]", opt_len)); + ND_PRINT("[Bad OPT_LENGTH option, length %u != 4]", opt_len); return; } - opts_len = EXTRACT_16BITS(bp); + opts_len = GET_BE_U_2(bp); + bp += sizeof(uint16_t); if (opts_len < 4) { - ND_PRINT((ndo, "[Bad total option length %u < 4]", opts_len)); + ND_PRINT("[Bad total option length %u < 4]", opts_len); return; } - bp += sizeof(uint16_t); - ND_PRINT((ndo, " OPTS LEN %d", opts_len)); + ND_PRINT(" OPTS LEN %u", opts_len); opts_len -= 4; while (opts_len) { if (opts_len < PGM_MIN_OPT_LEN) { - ND_PRINT((ndo, "[Total option length leaves no room for final option]")); + ND_PRINT("[Total option length leaves no room for final option]"); return; } - if (!ND_TTEST2(*bp, 2)) { - ND_PRINT((ndo, " [|OPT]")); - return; - } - opt_type = *bp++; - opt_len = *bp++; + opt_type = GET_U_1(bp); + bp++; + opt_len = GET_U_1(bp); + bp++; if (opt_len < PGM_MIN_OPT_LEN) { - ND_PRINT((ndo, "[Bad option, length %u < %u]", opt_len, - PGM_MIN_OPT_LEN)); + ND_PRINT("[Bad option, length %u < %u]", opt_len, + PGM_MIN_OPT_LEN); break; } if (opts_len < opt_len) { - ND_PRINT((ndo, "[Total option length leaves no room for final option]")); - return; - } - if (!ND_TTEST2(*bp, opt_len - 2)) { - ND_PRINT((ndo, " [|OPT]")); + ND_PRINT("[Total option length leaves no room for final option]"); return; } + ND_TCHECK_LEN(bp, opt_len - 2); switch (opt_type & PGM_OPT_MASK) { case PGM_OPT_LENGTH: #define PGM_OPT_LENGTH_LEN (2+2) if (opt_len != PGM_OPT_LENGTH_LEN) { - ND_PRINT((ndo, "[Bad OPT_LENGTH option, length %u != %u]", - opt_len, PGM_OPT_LENGTH_LEN)); + ND_PRINT("[Bad OPT_LENGTH option, length %u != %u]", + opt_len, PGM_OPT_LENGTH_LEN); return; } - ND_PRINT((ndo, " OPTS LEN (extra?) %d", EXTRACT_16BITS(bp))); + ND_PRINT(" OPTS LEN (extra?) %u", GET_BE_U_2(bp)); bp += 2; opts_len -= PGM_OPT_LENGTH_LEN; break; @@ -493,32 +486,31 @@ pgm_print(netdissect_options *ndo, case PGM_OPT_FRAGMENT: #define PGM_OPT_FRAGMENT_LEN (2+2+4+4+4) if (opt_len != PGM_OPT_FRAGMENT_LEN) { - ND_PRINT((ndo, "[Bad OPT_FRAGMENT option, length %u != %u]", - opt_len, PGM_OPT_FRAGMENT_LEN)); + ND_PRINT("[Bad OPT_FRAGMENT option, length %u != %u]", + opt_len, PGM_OPT_FRAGMENT_LEN); return; } bp += 2; - seq = EXTRACT_32BITS(bp); + seq = GET_BE_U_4(bp); bp += 4; - offset = EXTRACT_32BITS(bp); + offset = GET_BE_U_4(bp); bp += 4; - len = EXTRACT_32BITS(bp); + len = GET_BE_U_4(bp); bp += 4; - ND_PRINT((ndo, " FRAG seq %u off %u len %u", seq, offset, len)); + ND_PRINT(" FRAG seq %u off %u len %u", seq, offset, len); opts_len -= PGM_OPT_FRAGMENT_LEN; break; case PGM_OPT_NAK_LIST: bp += 2; opt_len -= 4; /* option header */ - ND_PRINT((ndo, " NAK LIST")); + ND_PRINT(" NAK LIST"); while (opt_len) { if (opt_len < 4) { - ND_PRINT((ndo, "[Option length not a multiple of 4]")); + ND_PRINT("[Option length not a multiple of 4]"); return; } - ND_TCHECK2(*bp, 4); - ND_PRINT((ndo, " %u", EXTRACT_32BITS(bp))); + ND_PRINT(" %u", GET_BE_U_4(bp)); bp += 4; opt_len -= 4; opts_len -= 4; @@ -528,146 +520,146 @@ pgm_print(netdissect_options *ndo, case PGM_OPT_JOIN: #define PGM_OPT_JOIN_LEN (2+2+4) if (opt_len != PGM_OPT_JOIN_LEN) { - ND_PRINT((ndo, "[Bad OPT_JOIN option, length %u != %u]", - opt_len, PGM_OPT_JOIN_LEN)); + ND_PRINT("[Bad OPT_JOIN option, length %u != %u]", + opt_len, PGM_OPT_JOIN_LEN); return; } bp += 2; - seq = EXTRACT_32BITS(bp); + seq = GET_BE_U_4(bp); bp += 4; - ND_PRINT((ndo, " JOIN %u", seq)); + ND_PRINT(" JOIN %u", seq); opts_len -= PGM_OPT_JOIN_LEN; break; case PGM_OPT_NAK_BO_IVL: #define PGM_OPT_NAK_BO_IVL_LEN (2+2+4+4) if (opt_len != PGM_OPT_NAK_BO_IVL_LEN) { - ND_PRINT((ndo, "[Bad OPT_NAK_BO_IVL option, length %u != %u]", - opt_len, PGM_OPT_NAK_BO_IVL_LEN)); + ND_PRINT("[Bad OPT_NAK_BO_IVL option, length %u != %u]", + opt_len, PGM_OPT_NAK_BO_IVL_LEN); return; } bp += 2; - offset = EXTRACT_32BITS(bp); + offset = GET_BE_U_4(bp); bp += 4; - seq = EXTRACT_32BITS(bp); + seq = GET_BE_U_4(bp); bp += 4; - ND_PRINT((ndo, " BACKOFF ivl %u ivlseq %u", offset, seq)); + ND_PRINT(" BACKOFF ivl %u ivlseq %u", offset, seq); opts_len -= PGM_OPT_NAK_BO_IVL_LEN; break; case PGM_OPT_NAK_BO_RNG: #define PGM_OPT_NAK_BO_RNG_LEN (2+2+4+4) if (opt_len != PGM_OPT_NAK_BO_RNG_LEN) { - ND_PRINT((ndo, "[Bad OPT_NAK_BO_RNG option, length %u != %u]", - opt_len, PGM_OPT_NAK_BO_RNG_LEN)); + ND_PRINT("[Bad OPT_NAK_BO_RNG option, length %u != %u]", + opt_len, PGM_OPT_NAK_BO_RNG_LEN); return; } bp += 2; - offset = EXTRACT_32BITS(bp); + offset = GET_BE_U_4(bp); bp += 4; - seq = EXTRACT_32BITS(bp); + seq = GET_BE_U_4(bp); bp += 4; - ND_PRINT((ndo, " BACKOFF max %u min %u", offset, seq)); + ND_PRINT(" BACKOFF max %u min %u", offset, seq); opts_len -= PGM_OPT_NAK_BO_RNG_LEN; break; case PGM_OPT_REDIRECT: #define PGM_OPT_REDIRECT_FIXED_LEN (2+2+2+2) if (opt_len < PGM_OPT_REDIRECT_FIXED_LEN) { - ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u < %u]", - opt_len, PGM_OPT_REDIRECT_FIXED_LEN)); + ND_PRINT("[Bad OPT_REDIRECT option, length %u < %u]", + opt_len, PGM_OPT_REDIRECT_FIXED_LEN); return; } bp += 2; - nla_afnum = EXTRACT_16BITS(bp); + nla_afnum = GET_BE_U_2(bp); bp += 2+2; switch (nla_afnum) { case AFNUM_INET: - if (opt_len != PGM_OPT_REDIRECT_FIXED_LEN + sizeof(struct in_addr)) { - ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u != %u + address size]", - opt_len, PGM_OPT_REDIRECT_FIXED_LEN)); + if (opt_len != PGM_OPT_REDIRECT_FIXED_LEN + sizeof(nd_ipv4)) { + ND_PRINT("[Bad OPT_REDIRECT option, length %u != %u + address size]", + opt_len, PGM_OPT_REDIRECT_FIXED_LEN); return; } - ND_TCHECK2(*bp, sizeof(struct in_addr)); + ND_TCHECK_LEN(bp, sizeof(nd_ipv4)); addrtostr(bp, nla_buf, sizeof(nla_buf)); - bp += sizeof(struct in_addr); - opts_len -= PGM_OPT_REDIRECT_FIXED_LEN + sizeof(struct in_addr); + bp += sizeof(nd_ipv4); + opts_len -= PGM_OPT_REDIRECT_FIXED_LEN + sizeof(nd_ipv4); break; case AFNUM_INET6: - if (opt_len != PGM_OPT_REDIRECT_FIXED_LEN + sizeof(struct in6_addr)) { - ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u != %u + address size]", - PGM_OPT_REDIRECT_FIXED_LEN, opt_len)); + if (opt_len != PGM_OPT_REDIRECT_FIXED_LEN + sizeof(nd_ipv6)) { + ND_PRINT("[Bad OPT_REDIRECT option, length %u != %u + address size]", + opt_len, PGM_OPT_REDIRECT_FIXED_LEN); return; } - ND_TCHECK2(*bp, sizeof(struct in6_addr)); + ND_TCHECK_LEN(bp, sizeof(nd_ipv6)); addrtostr6(bp, nla_buf, sizeof(nla_buf)); - bp += sizeof(struct in6_addr); - opts_len -= PGM_OPT_REDIRECT_FIXED_LEN + sizeof(struct in6_addr); + bp += sizeof(nd_ipv6); + opts_len -= PGM_OPT_REDIRECT_FIXED_LEN + sizeof(nd_ipv6); break; default: goto trunc; break; } - ND_PRINT((ndo, " REDIRECT %s", nla_buf)); + ND_PRINT(" REDIRECT %s", nla_buf); break; case PGM_OPT_PARITY_PRM: #define PGM_OPT_PARITY_PRM_LEN (2+2+4) if (opt_len != PGM_OPT_PARITY_PRM_LEN) { - ND_PRINT((ndo, "[Bad OPT_PARITY_PRM option, length %u != %u]", - opt_len, PGM_OPT_PARITY_PRM_LEN)); + ND_PRINT("[Bad OPT_PARITY_PRM option, length %u != %u]", + opt_len, PGM_OPT_PARITY_PRM_LEN); return; } bp += 2; - len = EXTRACT_32BITS(bp); + len = GET_BE_U_4(bp); bp += 4; - ND_PRINT((ndo, " PARITY MAXTGS %u", len)); + ND_PRINT(" PARITY MAXTGS %u", len); opts_len -= PGM_OPT_PARITY_PRM_LEN; break; case PGM_OPT_PARITY_GRP: #define PGM_OPT_PARITY_GRP_LEN (2+2+4) if (opt_len != PGM_OPT_PARITY_GRP_LEN) { - ND_PRINT((ndo, "[Bad OPT_PARITY_GRP option, length %u != %u]", - opt_len, PGM_OPT_PARITY_GRP_LEN)); + ND_PRINT("[Bad OPT_PARITY_GRP option, length %u != %u]", + opt_len, PGM_OPT_PARITY_GRP_LEN); return; } bp += 2; - seq = EXTRACT_32BITS(bp); + seq = GET_BE_U_4(bp); bp += 4; - ND_PRINT((ndo, " PARITY GROUP %u", seq)); + ND_PRINT(" PARITY GROUP %u", seq); opts_len -= PGM_OPT_PARITY_GRP_LEN; break; case PGM_OPT_CURR_TGSIZE: #define PGM_OPT_CURR_TGSIZE_LEN (2+2+4) if (opt_len != PGM_OPT_CURR_TGSIZE_LEN) { - ND_PRINT((ndo, "[Bad OPT_CURR_TGSIZE option, length %u != %u]", - opt_len, PGM_OPT_CURR_TGSIZE_LEN)); + ND_PRINT("[Bad OPT_CURR_TGSIZE option, length %u != %u]", + opt_len, PGM_OPT_CURR_TGSIZE_LEN); return; } bp += 2; - len = EXTRACT_32BITS(bp); + len = GET_BE_U_4(bp); bp += 4; - ND_PRINT((ndo, " PARITY ATGS %u", len)); + ND_PRINT(" PARITY ATGS %u", len); opts_len -= PGM_OPT_CURR_TGSIZE_LEN; break; case PGM_OPT_NBR_UNREACH: #define PGM_OPT_NBR_UNREACH_LEN (2+2) if (opt_len != PGM_OPT_NBR_UNREACH_LEN) { - ND_PRINT((ndo, "[Bad OPT_NBR_UNREACH option, length %u != %u]", - opt_len, PGM_OPT_NBR_UNREACH_LEN)); + ND_PRINT("[Bad OPT_NBR_UNREACH option, length %u != %u]", + opt_len, PGM_OPT_NBR_UNREACH_LEN); return; } bp += 2; - ND_PRINT((ndo, " NBR_UNREACH")); + ND_PRINT(" NBR_UNREACH"); opts_len -= PGM_OPT_NBR_UNREACH_LEN; break; case PGM_OPT_PATH_NLA: - ND_PRINT((ndo, " PATH_NLA [%d]", opt_len)); + ND_PRINT(" PATH_NLA [%u]", opt_len); bp += opt_len; opts_len -= opt_len; break; @@ -675,41 +667,41 @@ pgm_print(netdissect_options *ndo, case PGM_OPT_SYN: #define PGM_OPT_SYN_LEN (2+2) if (opt_len != PGM_OPT_SYN_LEN) { - ND_PRINT((ndo, "[Bad OPT_SYN option, length %u != %u]", - opt_len, PGM_OPT_SYN_LEN)); + ND_PRINT("[Bad OPT_SYN option, length %u != %u]", + opt_len, PGM_OPT_SYN_LEN); return; } bp += 2; - ND_PRINT((ndo, " SYN")); + ND_PRINT(" SYN"); opts_len -= PGM_OPT_SYN_LEN; break; case PGM_OPT_FIN: #define PGM_OPT_FIN_LEN (2+2) if (opt_len != PGM_OPT_FIN_LEN) { - ND_PRINT((ndo, "[Bad OPT_FIN option, length %u != %u]", - opt_len, PGM_OPT_FIN_LEN)); + ND_PRINT("[Bad OPT_FIN option, length %u != %u]", + opt_len, PGM_OPT_FIN_LEN); return; } bp += 2; - ND_PRINT((ndo, " FIN")); + ND_PRINT(" FIN"); opts_len -= PGM_OPT_FIN_LEN; break; case PGM_OPT_RST: #define PGM_OPT_RST_LEN (2+2) if (opt_len != PGM_OPT_RST_LEN) { - ND_PRINT((ndo, "[Bad OPT_RST option, length %u != %u]", - opt_len, PGM_OPT_RST_LEN)); + ND_PRINT("[Bad OPT_RST option, length %u != %u]", + opt_len, PGM_OPT_RST_LEN); return; } bp += 2; - ND_PRINT((ndo, " RST")); + ND_PRINT(" RST"); opts_len -= PGM_OPT_RST_LEN; break; case PGM_OPT_CR: - ND_PRINT((ndo, " CR")); + ND_PRINT(" CR"); bp += opt_len; opts_len -= opt_len; break; @@ -717,103 +709,103 @@ pgm_print(netdissect_options *ndo, case PGM_OPT_CRQST: #define PGM_OPT_CRQST_LEN (2+2) if (opt_len != PGM_OPT_CRQST_LEN) { - ND_PRINT((ndo, "[Bad OPT_CRQST option, length %u != %u]", - opt_len, PGM_OPT_CRQST_LEN)); + ND_PRINT("[Bad OPT_CRQST option, length %u != %u]", + opt_len, PGM_OPT_CRQST_LEN); return; } bp += 2; - ND_PRINT((ndo, " CRQST")); + ND_PRINT(" CRQST"); opts_len -= PGM_OPT_CRQST_LEN; break; case PGM_OPT_PGMCC_DATA: #define PGM_OPT_PGMCC_DATA_FIXED_LEN (2+2+4+2+2) if (opt_len < PGM_OPT_PGMCC_DATA_FIXED_LEN) { - ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u < %u]", - opt_len, PGM_OPT_PGMCC_DATA_FIXED_LEN)); + ND_PRINT("[Bad OPT_PGMCC_DATA option, length %u < %u]", + opt_len, PGM_OPT_PGMCC_DATA_FIXED_LEN); return; } bp += 2; - offset = EXTRACT_32BITS(bp); + offset = GET_BE_U_4(bp); bp += 4; - nla_afnum = EXTRACT_16BITS(bp); + nla_afnum = GET_BE_U_2(bp); bp += 2+2; switch (nla_afnum) { case AFNUM_INET: - if (opt_len != PGM_OPT_PGMCC_DATA_FIXED_LEN + sizeof(struct in_addr)) { - ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != %u + address size]", - opt_len, PGM_OPT_PGMCC_DATA_FIXED_LEN)); + if (opt_len != PGM_OPT_PGMCC_DATA_FIXED_LEN + sizeof(nd_ipv4)) { + ND_PRINT("[Bad OPT_PGMCC_DATA option, length %u != %u + address size]", + opt_len, PGM_OPT_PGMCC_DATA_FIXED_LEN); return; } - ND_TCHECK2(*bp, sizeof(struct in_addr)); + ND_TCHECK_LEN(bp, sizeof(nd_ipv4)); addrtostr(bp, nla_buf, sizeof(nla_buf)); - bp += sizeof(struct in_addr); - opts_len -= PGM_OPT_PGMCC_DATA_FIXED_LEN + sizeof(struct in_addr); + bp += sizeof(nd_ipv4); + opts_len -= PGM_OPT_PGMCC_DATA_FIXED_LEN + sizeof(nd_ipv4); break; case AFNUM_INET6: - if (opt_len != PGM_OPT_PGMCC_DATA_FIXED_LEN + sizeof(struct in6_addr)) { - ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != %u + address size]", - opt_len, PGM_OPT_PGMCC_DATA_FIXED_LEN)); + if (opt_len != PGM_OPT_PGMCC_DATA_FIXED_LEN + sizeof(nd_ipv6)) { + ND_PRINT("[Bad OPT_PGMCC_DATA option, length %u != %u + address size]", + opt_len, PGM_OPT_PGMCC_DATA_FIXED_LEN); return; } - ND_TCHECK2(*bp, sizeof(struct in6_addr)); + ND_TCHECK_LEN(bp, sizeof(nd_ipv6)); addrtostr6(bp, nla_buf, sizeof(nla_buf)); - bp += sizeof(struct in6_addr); - opts_len -= PGM_OPT_PGMCC_DATA_FIXED_LEN + sizeof(struct in6_addr); + bp += sizeof(nd_ipv6); + opts_len -= PGM_OPT_PGMCC_DATA_FIXED_LEN + sizeof(nd_ipv6); break; default: goto trunc; break; } - ND_PRINT((ndo, " PGMCC DATA %u %s", offset, nla_buf)); + ND_PRINT(" PGMCC DATA %u %s", offset, nla_buf); break; case PGM_OPT_PGMCC_FEEDBACK: #define PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN (2+2+4+2+2) if (opt_len < PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN) { - ND_PRINT((ndo, "[Bad PGM_OPT_PGMCC_FEEDBACK option, length %u < %u]", - opt_len, PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN)); + ND_PRINT("[Bad PGM_OPT_PGMCC_FEEDBACK option, length %u < %u]", + opt_len, PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN); return; } bp += 2; - offset = EXTRACT_32BITS(bp); + offset = GET_BE_U_4(bp); bp += 4; - nla_afnum = EXTRACT_16BITS(bp); + nla_afnum = GET_BE_U_2(bp); bp += 2+2; switch (nla_afnum) { case AFNUM_INET: - if (opt_len != PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN + sizeof(struct in_addr)) { - ND_PRINT((ndo, "[Bad OPT_PGMCC_FEEDBACK option, length %u != %u + address size]", - opt_len, PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN)); + if (opt_len != PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN + sizeof(nd_ipv4)) { + ND_PRINT("[Bad OPT_PGMCC_FEEDBACK option, length %u != %u + address size]", + opt_len, PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN); return; } - ND_TCHECK2(*bp, sizeof(struct in_addr)); + ND_TCHECK_LEN(bp, sizeof(nd_ipv4)); addrtostr(bp, nla_buf, sizeof(nla_buf)); - bp += sizeof(struct in_addr); - opts_len -= PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN + sizeof(struct in_addr); + bp += sizeof(nd_ipv4); + opts_len -= PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN + sizeof(nd_ipv4); break; case AFNUM_INET6: - if (opt_len != PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN + sizeof(struct in6_addr)) { - ND_PRINT((ndo, "[Bad OPT_PGMCC_FEEDBACK option, length %u != %u + address size]", - opt_len, PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN)); + if (opt_len != PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN + sizeof(nd_ipv6)) { + ND_PRINT("[Bad OPT_PGMCC_FEEDBACK option, length %u != %u + address size]", + opt_len, PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN); return; } - ND_TCHECK2(*bp, sizeof(struct in6_addr)); + ND_TCHECK_LEN(bp, sizeof(nd_ipv6)); addrtostr6(bp, nla_buf, sizeof(nla_buf)); - bp += sizeof(struct in6_addr); - opts_len -= PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN + sizeof(struct in6_addr); + bp += sizeof(nd_ipv6); + opts_len -= PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN + sizeof(nd_ipv6); break; default: goto trunc; break; } - ND_PRINT((ndo, " PGMCC FEEDBACK %u %s", offset, nla_buf)); + ND_PRINT(" PGMCC FEEDBACK %u %s", offset, nla_buf); break; default: - ND_PRINT((ndo, " OPT_%02X [%d] ", opt_type, opt_len)); + ND_PRINT(" OPT_%02X [%u] ", opt_type, opt_len); bp += opt_len; opts_len -= opt_len; break; @@ -824,15 +816,14 @@ pgm_print(netdissect_options *ndo, } } - ND_PRINT((ndo, " [%u]", length)); + ND_PRINT(" [%u]", length); if (ndo->ndo_packettype == PT_PGM_ZMTP1 && - (pgm->pgm_type == PGM_ODATA || pgm->pgm_type == PGM_RDATA)) - zmtp1_print_datagram(ndo, bp, EXTRACT_16BITS(&pgm->pgm_length)); + (pgm_type_val == PGM_ODATA || pgm_type_val == PGM_RDATA)) + zmtp1_datagram_print(ndo, bp, + GET_BE_U_2(pgm->pgm_length)); return; trunc: - ND_PRINT((ndo, "[|pgm]")); - if (ch != '\0') - ND_PRINT((ndo, ">")); + nd_print_trunc(ndo); } diff --git a/contrib/tcpdump/print-pim.c b/contrib/tcpdump/print-pim.c index 9c8ca547fa..f2db8c7681 100644 --- a/contrib/tcpdump/print-pim.c +++ b/contrib/tcpdump/print-pim.c @@ -22,10 +22,10 @@ /* \summary: Protocol Independent Multicast (PIM) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "addrtoname.h" @@ -118,13 +118,30 @@ static const struct tok pimv2_register_flag_values[] = { { 0, NULL} }; +#define PIMV2_DF_ELECTION_OFFER 1 +#define PIMV2_DF_ELECTION_WINNER 2 +#define PIMV2_DF_ELECTION_BACKOFF 3 +#define PIMV2_DF_ELECTION_PASS 4 + +static const struct tok pimv2_df_election_flag_values[] = { + { PIMV2_DF_ELECTION_OFFER, "Offer" }, + { PIMV2_DF_ELECTION_WINNER, "Winner" }, + { PIMV2_DF_ELECTION_BACKOFF, "Backoff" }, + { PIMV2_DF_ELECTION_PASS, "Pass" }, + { 0, NULL} +}; + +#define PIMV2_DF_ELECTION_PASS_BACKOFF_STR(x) ( \ + x == PIMV2_DF_ELECTION_BACKOFF ? "offer" : "new winner" ) + + /* * XXX: We consider a case where IPv6 is not ready yet for portability, - * but PIM dependent defintions should be independent of IPv6... + * but PIM dependent definitions should be independent of IPv6... */ struct pim { - uint8_t pim_typever; + nd_uint8_t pim_typever; /* upper 4bit: PIM version number; 2 for PIMv2 */ /* lower 4bit: the PIM message type, currently they are: * Hello, Register, Register-Stop, Join/Prune, @@ -133,57 +150,56 @@ struct pim { */ #define PIM_VER(x) (((x) & 0xf0) >> 4) #define PIM_TYPE(x) ((x) & 0x0f) - u_char pim_rsv; /* Reserved */ - u_short pim_cksum; /* IP style check sum */ + nd_uint8_t pim_rsv; /* Reserved in v1, subtype+address length in v2 */ +#define PIM_SUBTYPE(x) (((x) & 0xf0) >> 4) + nd_uint16_t pim_cksum; /* IP style check sum */ }; -static void pimv2_print(netdissect_options *, register const u_char *bp, register u_int len, const u_char *); +static void pimv2_print(netdissect_options *, const u_char *bp, u_int len, const u_char *); static void pimv1_join_prune_print(netdissect_options *ndo, - register const u_char *bp, register u_int len) + const u_char *bp, u_int len) { - int ngroups, njoin, nprune; - int njp; + u_int ngroups, njoin, nprune; + u_int njp; /* If it's a single group and a single source, use 1-line output. */ - if (ND_TTEST2(bp[0], 30) && bp[11] == 1 && - ((njoin = EXTRACT_16BITS(&bp[20])) + EXTRACT_16BITS(&bp[22])) == 1) { - int hold; + if (ND_TTEST_LEN(bp, 30) && GET_U_1(bp + 11) == 1 && + ((njoin = GET_BE_U_2(bp + 20)) + GET_BE_U_2(bp + 22)) == 1) { + u_int hold; - ND_PRINT((ndo, " RPF %s ", ipaddr_string(ndo, bp))); - hold = EXTRACT_16BITS(&bp[6]); + ND_PRINT(" RPF %s ", GET_IPADDR_STRING(bp)); + hold = GET_BE_U_2(bp + 6); if (hold != 180) { - ND_PRINT((ndo, "Hold ")); + ND_PRINT("Hold "); unsigned_relts_print(ndo, hold); } - ND_PRINT((ndo, "%s (%s/%d, %s", njoin ? "Join" : "Prune", - ipaddr_string(ndo, &bp[26]), bp[25] & 0x3f, - ipaddr_string(ndo, &bp[12]))); - if (EXTRACT_32BITS(&bp[16]) != 0xffffffff) - ND_PRINT((ndo, "/%s", ipaddr_string(ndo, &bp[16]))); - ND_PRINT((ndo, ") %s%s %s", - (bp[24] & 0x01) ? "Sparse" : "Dense", - (bp[25] & 0x80) ? " WC" : "", - (bp[25] & 0x40) ? "RP" : "SPT")); + ND_PRINT("%s (%s/%u, %s", njoin ? "Join" : "Prune", + GET_IPADDR_STRING(bp + 26), GET_U_1(bp + 25) & 0x3f, + GET_IPADDR_STRING(bp + 12)); + if (GET_BE_U_4(bp + 16) != 0xffffffff) + ND_PRINT("/%s", GET_IPADDR_STRING(bp + 16)); + ND_PRINT(") %s%s %s", + (GET_U_1(bp + 24) & 0x01) ? "Sparse" : "Dense", + (GET_U_1(bp + 25) & 0x80) ? " WC" : "", + (GET_U_1(bp + 25) & 0x40) ? "RP" : "SPT"); return; } - if (len < sizeof(struct in_addr)) + if (len < sizeof(nd_ipv4)) goto trunc; - ND_TCHECK2(bp[0], sizeof(struct in_addr)); if (ndo->ndo_vflag > 1) - ND_PRINT((ndo, "\n")); - ND_PRINT((ndo, " Upstream Nbr: %s", ipaddr_string(ndo, bp))); + ND_PRINT("\n"); + ND_PRINT(" Upstream Nbr: %s", GET_IPADDR_STRING(bp)); bp += 4; len -= 4; if (len < 4) goto trunc; - ND_TCHECK2(bp[2], 2); if (ndo->ndo_vflag > 1) - ND_PRINT((ndo, "\n")); - ND_PRINT((ndo, " Hold time: ")); - unsigned_relts_print(ndo, EXTRACT_16BITS(&bp[2])); + ND_PRINT("\n"); + ND_PRINT(" Hold time: "); + unsigned_relts_print(ndo, GET_BE_U_2(bp + 2)); if (ndo->ndo_vflag < 2) return; bp += 4; @@ -191,34 +207,30 @@ pimv1_join_prune_print(netdissect_options *ndo, if (len < 4) goto trunc; - ND_TCHECK2(bp[0], 4); - ngroups = bp[3]; + ngroups = GET_U_1(bp + 3); bp += 4; len -= 4; - while (ngroups--) { + while (ngroups != 0) { /* * XXX - does the address have length "addrlen" and the * mask length "maddrlen"? */ if (len < 4) goto trunc; - ND_TCHECK2(bp[0], sizeof(struct in_addr)); - ND_PRINT((ndo, "\n\tGroup: %s", ipaddr_string(ndo, bp))); + ND_PRINT("\n\tGroup: %s", GET_IPADDR_STRING(bp)); bp += 4; len -= 4; if (len < 4) goto trunc; - ND_TCHECK2(bp[0], sizeof(struct in_addr)); - if (EXTRACT_32BITS(&bp[0]) != 0xffffffff) - ND_PRINT((ndo, "/%s", ipaddr_string(ndo, &bp[0]))); + if (GET_BE_U_4(bp) != 0xffffffff) + ND_PRINT("/%s", GET_IPADDR_STRING(bp)); bp += 4; len -= 4; if (len < 4) goto trunc; - ND_TCHECK2(bp[0], 4); - njoin = EXTRACT_16BITS(&bp[0]); - nprune = EXTRACT_16BITS(&bp[2]); - ND_PRINT((ndo, " joined: %d pruned: %d", njoin, nprune)); + njoin = GET_BE_U_2(bp); + nprune = GET_BE_U_2(bp + 2); + ND_PRINT(" joined: %u pruned: %u", njoin, nprune); bp += 4; len -= 4; for (njp = 0; njp < (njoin + nprune); njp++) { @@ -230,90 +242,84 @@ pimv1_join_prune_print(netdissect_options *ndo, type = "Prune"; if (len < 6) goto trunc; - ND_TCHECK2(bp[0], 6); - ND_PRINT((ndo, "\n\t%s %s%s%s%s/%d", type, - (bp[0] & 0x01) ? "Sparse " : "Dense ", - (bp[1] & 0x80) ? "WC " : "", - (bp[1] & 0x40) ? "RP " : "SPT ", - ipaddr_string(ndo, &bp[2]), - bp[1] & 0x3f)); + ND_PRINT("\n\t%s %s%s%s%s/%u", type, + (GET_U_1(bp) & 0x01) ? "Sparse " : "Dense ", + (GET_U_1(bp + 1) & 0x80) ? "WC " : "", + (GET_U_1(bp + 1) & 0x40) ? "RP " : "SPT ", + GET_IPADDR_STRING(bp + 2), + GET_U_1(bp + 1) & 0x3f); bp += 6; len -= 6; } + ngroups--; } return; trunc: - ND_PRINT((ndo, "[|pim]")); - return; + nd_print_trunc(ndo); } void pimv1_print(netdissect_options *ndo, - register const u_char *bp, register u_int len) + const u_char *bp, u_int len) { - register u_char type; + u_char type; - ND_TCHECK(bp[1]); - type = bp[1]; + ndo->ndo_protocol = "pimv1"; + type = GET_U_1(bp + 1); - ND_PRINT((ndo, " %s", tok2str(pimv1_type_str, "[type %u]", type))); + ND_PRINT(" %s", tok2str(pimv1_type_str, "[type %u]", type)); switch (type) { case PIMV1_TYPE_QUERY: - if (ND_TTEST(bp[8])) { - switch (bp[8] >> 4) { + if (ND_TTEST_1(bp + 8)) { + switch (GET_U_1(bp + 8) >> 4) { case 0: - ND_PRINT((ndo, " Dense-mode")); + ND_PRINT(" Dense-mode"); break; case 1: - ND_PRINT((ndo, " Sparse-mode")); + ND_PRINT(" Sparse-mode"); break; case 2: - ND_PRINT((ndo, " Sparse-Dense-mode")); + ND_PRINT(" Sparse-Dense-mode"); break; default: - ND_PRINT((ndo, " mode-%d", bp[8] >> 4)); + ND_PRINT(" mode-%u", GET_U_1(bp + 8) >> 4); break; } } if (ndo->ndo_vflag) { - ND_TCHECK2(bp[10],2); - ND_PRINT((ndo, " (Hold-time ")); - unsigned_relts_print(ndo, EXTRACT_16BITS(&bp[10])); - ND_PRINT((ndo, ")")); + ND_PRINT(" (Hold-time "); + unsigned_relts_print(ndo, GET_BE_U_2(bp + 10)); + ND_PRINT(")"); } break; case PIMV1_TYPE_REGISTER: - ND_TCHECK2(bp[8], 20); /* ip header */ - ND_PRINT((ndo, " for %s > %s", ipaddr_string(ndo, &bp[20]), - ipaddr_string(ndo, &bp[24]))); + ND_TCHECK_LEN(bp + 8, 20); /* ip header */ + ND_PRINT(" for %s > %s", GET_IPADDR_STRING(bp + 20), + GET_IPADDR_STRING(bp + 24)); break; case PIMV1_TYPE_REGISTER_STOP: - ND_TCHECK2(bp[12], sizeof(struct in_addr)); - ND_PRINT((ndo, " for %s > %s", ipaddr_string(ndo, &bp[8]), - ipaddr_string(ndo, &bp[12]))); + ND_PRINT(" for %s > %s", GET_IPADDR_STRING(bp + 8), + GET_IPADDR_STRING(bp + 12)); break; case PIMV1_TYPE_RP_REACHABILITY: if (ndo->ndo_vflag) { - ND_TCHECK2(bp[22], 2); - ND_PRINT((ndo, " group %s", ipaddr_string(ndo, &bp[8]))); - if (EXTRACT_32BITS(&bp[12]) != 0xffffffff) - ND_PRINT((ndo, "/%s", ipaddr_string(ndo, &bp[12]))); - ND_PRINT((ndo, " RP %s hold ", ipaddr_string(ndo, &bp[16]))); - unsigned_relts_print(ndo, EXTRACT_16BITS(&bp[22])); + ND_PRINT(" group %s", GET_IPADDR_STRING(bp + 8)); + if (GET_BE_U_4(bp + 12) != 0xffffffff) + ND_PRINT("/%s", GET_IPADDR_STRING(bp + 12)); + ND_PRINT(" RP %s hold ", GET_IPADDR_STRING(bp + 16)); + unsigned_relts_print(ndo, GET_BE_U_2(bp + 22)); } break; case PIMV1_TYPE_ASSERT: - ND_TCHECK2(bp[16], sizeof(struct in_addr)); - ND_PRINT((ndo, " for %s > %s", ipaddr_string(ndo, &bp[16]), - ipaddr_string(ndo, &bp[8]))); - if (EXTRACT_32BITS(&bp[12]) != 0xffffffff) - ND_PRINT((ndo, "/%s", ipaddr_string(ndo, &bp[12]))); - ND_TCHECK2(bp[24], 4); - ND_PRINT((ndo, " %s pref %d metric %d", - (bp[20] & 0x80) ? "RP-tree" : "SPT", - EXTRACT_32BITS(&bp[20]) & 0x7fffffff, - EXTRACT_32BITS(&bp[24]))); + ND_PRINT(" for %s > %s", GET_IPADDR_STRING(bp + 16), + GET_IPADDR_STRING(bp + 8)); + if (GET_BE_U_4(bp + 12) != 0xffffffff) + ND_PRINT("/%s", GET_IPADDR_STRING(bp + 12)); + ND_PRINT(" %s pref %u metric %u", + (GET_U_1(bp + 20) & 0x80) ? "RP-tree" : "SPT", + GET_BE_U_4(bp + 20) & 0x7fffffff, + GET_BE_U_4(bp + 24)); break; case PIMV1_TYPE_JOIN_PRUNE: case PIMV1_TYPE_GRAFT: @@ -321,18 +327,16 @@ pimv1_print(netdissect_options *ndo, if (ndo->ndo_vflag) { if (len < 8) goto trunc; - pimv1_join_prune_print(ndo, &bp[8], len - 8); + pimv1_join_prune_print(ndo, bp + 8, len - 8); } break; } - ND_TCHECK(bp[4]); - if ((bp[4] >> 4) != 1) - ND_PRINT((ndo, " [v%d]", bp[4] >> 4)); + if ((GET_U_1(bp + 4) >> 4) != 1) + ND_PRINT(" [v%u]", GET_U_1(bp + 4) >> 4); return; trunc: - ND_PRINT((ndo, "[|pim]")); - return; + nd_print_trunc(ndo); } /* @@ -343,39 +347,37 @@ trunc: */ void cisco_autorp_print(netdissect_options *ndo, - register const u_char *bp, register u_int len) + const u_char *bp, u_int len) { - int type; - int numrps; - int hold; + u_int type; + u_int numrps; + u_int hold; + ndo->ndo_protocol = "cisco_autorp"; if (len < 8) goto trunc; - ND_TCHECK(bp[0]); - ND_PRINT((ndo, " auto-rp ")); - type = bp[0]; + ND_PRINT(" auto-rp "); + type = GET_U_1(bp); switch (type) { case 0x11: - ND_PRINT((ndo, "candidate-advert")); + ND_PRINT("candidate-advert"); break; case 0x12: - ND_PRINT((ndo, "mapping")); + ND_PRINT("mapping"); break; default: - ND_PRINT((ndo, "type-0x%02x", type)); + ND_PRINT("type-0x%02x", type); break; } - ND_TCHECK(bp[1]); - numrps = bp[1]; + numrps = GET_U_1(bp + 1); - ND_TCHECK2(bp[2], 2); - ND_PRINT((ndo, " Hold ")); - hold = EXTRACT_16BITS(&bp[2]); + ND_PRINT(" Hold "); + hold = GET_BE_U_2(bp + 2); if (hold) - unsigned_relts_print(ndo, EXTRACT_16BITS(&bp[2])); + unsigned_relts_print(ndo, GET_BE_U_2(bp + 2)); else - ND_PRINT((ndo, "FOREVER")); + ND_PRINT("FOREVER"); /* Next 4 bytes are reserved. */ @@ -394,101 +396,92 @@ cisco_autorp_print(netdissect_options *ndo, * 8 bits: mask 32 bits: source * lather, rinse, repeat. */ - while (numrps--) { - int nentries; + while (numrps != 0) { + u_int nentries; char s; if (len < 4) goto trunc; - ND_TCHECK2(bp[0], 4); - ND_PRINT((ndo, " RP %s", ipaddr_string(ndo, bp))); + ND_PRINT(" RP %s", GET_IPADDR_STRING(bp)); bp += 4; len -= 4; if (len < 1) goto trunc; - ND_TCHECK(bp[0]); - switch (bp[0] & 0x3) { - case 0: ND_PRINT((ndo, " PIMv?")); + switch (GET_U_1(bp) & 0x3) { + case 0: ND_PRINT(" PIMv?"); break; - case 1: ND_PRINT((ndo, " PIMv1")); + case 1: ND_PRINT(" PIMv1"); break; - case 2: ND_PRINT((ndo, " PIMv2")); + case 2: ND_PRINT(" PIMv2"); break; - case 3: ND_PRINT((ndo, " PIMv1+2")); + case 3: ND_PRINT(" PIMv1+2"); break; } - if (bp[0] & 0xfc) - ND_PRINT((ndo, " [rsvd=0x%02x]", bp[0] & 0xfc)); + if (GET_U_1(bp) & 0xfc) + ND_PRINT(" [rsvd=0x%02x]", GET_U_1(bp) & 0xfc); bp += 1; len -= 1; if (len < 1) goto trunc; - ND_TCHECK(bp[0]); - nentries = bp[0]; + nentries = GET_U_1(bp); bp += 1; len -= 1; s = ' '; - for (; nentries; nentries--) { + while (nentries != 0) { if (len < 6) goto trunc; - ND_TCHECK2(bp[0], 6); - ND_PRINT((ndo, "%c%s%s/%d", s, bp[0] & 1 ? "!" : "", - ipaddr_string(ndo, &bp[2]), bp[1])); - if (bp[0] & 0x02) { - ND_PRINT((ndo, " bidir")); + ND_PRINT("%c%s%s/%u", s, GET_U_1(bp) & 1 ? "!" : "", + GET_IPADDR_STRING(bp + 2), GET_U_1(bp + 1)); + if (GET_U_1(bp) & 0x02) { + ND_PRINT(" bidir"); } - if (bp[0] & 0xfc) { - ND_PRINT((ndo, "[rsvd=0x%02x]", bp[0] & 0xfc)); + if (GET_U_1(bp) & 0xfc) { + ND_PRINT("[rsvd=0x%02x]", GET_U_1(bp) & 0xfc); } s = ','; bp += 6; len -= 6; + nentries--; } + numrps--; } return; trunc: - ND_PRINT((ndo, "[|autorp]")); - return; + nd_print_trunc(ndo); } void pim_print(netdissect_options *ndo, - register const u_char *bp, register u_int len, const u_char *bp2) + const u_char *bp, u_int len, const u_char *bp2) { - register const struct pim *pim = (const struct pim *)bp; + const struct pim *pim = (const struct pim *)bp; + uint8_t pim_typever; -#ifdef notyet /* currently we see only version and type */ - ND_TCHECK(pim->pim_rsv); -#endif + ndo->ndo_protocol = "pim"; - ND_TCHECK(pim->pim_typever); - switch (PIM_VER(pim->pim_typever)) { + pim_typever = GET_U_1(pim->pim_typever); + switch (PIM_VER(pim_typever)) { case 2: if (!ndo->ndo_vflag) { - ND_PRINT((ndo, "PIMv%u, %s, length %u", - PIM_VER(pim->pim_typever), - tok2str(pimv2_type_values,"Unknown Type",PIM_TYPE(pim->pim_typever)), - len)); + ND_PRINT("PIMv%u, %s, length %u", + PIM_VER(pim_typever), + tok2str(pimv2_type_values,"Unknown Type",PIM_TYPE(pim_typever)), + len); return; } else { - ND_PRINT((ndo, "PIMv%u, length %u\n\t%s", - PIM_VER(pim->pim_typever), + ND_PRINT("PIMv%u, length %u\n\t%s", + PIM_VER(pim_typever), len, - tok2str(pimv2_type_values,"Unknown Type",PIM_TYPE(pim->pim_typever)))); + tok2str(pimv2_type_values,"Unknown Type",PIM_TYPE(pim_typever))); pimv2_print(ndo, bp, len, bp2); } break; default: - ND_PRINT((ndo, "PIMv%u, length %u", - PIM_VER(pim->pim_typever), - len)); + ND_PRINT("PIMv%u, length %u", + PIM_VER(pim_typever), + len); break; } - return; - -trunc: - ND_PRINT((ndo, "[|pim]")); - return; } /* @@ -560,34 +553,33 @@ pimv2_addr_print(netdissect_options *ndo, const u_char *bp, u_int len, enum pimv2_addrtype at, u_int addr_len, int silent) { - int af; + u_int af; int hdrlen; if (addr_len == 0) { if (len < 2) goto trunc; - ND_TCHECK(bp[1]); - switch (bp[0]) { + switch (GET_U_1(bp)) { case 1: af = AF_INET; - addr_len = (u_int)sizeof(struct in_addr); + addr_len = (u_int)sizeof(nd_ipv4); break; case 2: af = AF_INET6; - addr_len = (u_int)sizeof(struct in6_addr); + addr_len = (u_int)sizeof(nd_ipv6); break; default: return -1; } - if (bp[1] != 0) + if (GET_U_1(bp + 1) != 0) return -1; hdrlen = 2; } else { switch (addr_len) { - case sizeof(struct in_addr): + case sizeof(nd_ipv4): af = AF_INET; break; - case sizeof(struct in6_addr): + case sizeof(nd_ipv6): af = AF_INET6; break; default: @@ -603,47 +595,48 @@ pimv2_addr_print(netdissect_options *ndo, case pimv2_unicast: if (len < addr_len) goto trunc; - ND_TCHECK2(bp[0], addr_len); + ND_TCHECK_LEN(bp, addr_len); if (af == AF_INET) { if (!silent) - ND_PRINT((ndo, "%s", ipaddr_string(ndo, bp))); + ND_PRINT("%s", GET_IPADDR_STRING(bp)); } else if (af == AF_INET6) { if (!silent) - ND_PRINT((ndo, "%s", ip6addr_string(ndo, bp))); + ND_PRINT("%s", GET_IP6ADDR_STRING(bp)); } return hdrlen + addr_len; case pimv2_group: case pimv2_source: if (len < addr_len + 2) goto trunc; - ND_TCHECK2(bp[0], addr_len + 2); + ND_TCHECK_LEN(bp, addr_len + 2); if (af == AF_INET) { if (!silent) { - ND_PRINT((ndo, "%s", ipaddr_string(ndo, bp + 2))); - if (bp[1] != 32) - ND_PRINT((ndo, "/%u", bp[1])); + ND_PRINT("%s", GET_IPADDR_STRING(bp + 2)); + if (GET_U_1(bp + 1) != 32) + ND_PRINT("/%u", GET_U_1(bp + 1)); } } else if (af == AF_INET6) { if (!silent) { - ND_PRINT((ndo, "%s", ip6addr_string(ndo, bp + 2))); - if (bp[1] != 128) - ND_PRINT((ndo, "/%u", bp[1])); + ND_PRINT("%s", GET_IP6ADDR_STRING(bp + 2)); + if (GET_U_1(bp + 1) != 128) + ND_PRINT("/%u", GET_U_1(bp + 1)); } } - if (bp[0] && !silent) { + if (GET_U_1(bp) && !silent) { if (at == pimv2_group) { - ND_PRINT((ndo, "(0x%02x)", bp[0])); + ND_PRINT("(0x%02x)", GET_U_1(bp)); } else { - ND_PRINT((ndo, "(%s%s%s", - bp[0] & 0x04 ? "S" : "", - bp[0] & 0x02 ? "W" : "", - bp[0] & 0x01 ? "R" : "")); - if (bp[0] & 0xf8) { - ND_PRINT((ndo, "+0x%02x", bp[0] & 0xf8)); + ND_PRINT("(%s%s%s", + GET_U_1(bp) & 0x04 ? "S" : "", + GET_U_1(bp) & 0x02 ? "W" : "", + GET_U_1(bp) & 0x01 ? "R" : ""); + if (GET_U_1(bp) & 0xf8) { + ND_PRINT("+0x%02x", + GET_U_1(bp) & 0xf8); } - ND_PRINT((ndo, ")")); + ND_PRINT(")"); } } return hdrlen + 2 + addr_len; @@ -667,7 +660,7 @@ pimv2_check_checksum(netdissect_options *ndo, const u_char *bp, const struct ip *ip; u_int cksum; - if (!ND_TTEST2(bp[0], len)) { + if (!ND_TTEST_LEN(bp, len)) { /* We don't have all the data. */ return (UNVERIFIED); } @@ -692,28 +685,37 @@ pimv2_check_checksum(netdissect_options *ndo, const u_char *bp, static void pimv2_print(netdissect_options *ndo, - register const u_char *bp, register u_int len, const u_char *bp2) + const u_char *bp, u_int len, const u_char *bp2) { - register const struct pim *pim = (const struct pim *)bp; + const struct pim *pim = (const struct pim *)bp; int advance; + int subtype; enum checksum_status cksum_status; - int pimv2_addr_len; + u_int pim_typever; + u_int pimv2_addr_len; - if (len < 2) - goto trunc; - ND_TCHECK(pim->pim_rsv); - pimv2_addr_len = pim->pim_rsv; + ndo->ndo_protocol = "pimv2"; + if (len < 2) { + ND_PRINT("[length %u < 2]", len); + nd_print_invalid(ndo); + return; + } + pim_typever = GET_U_1(pim->pim_typever); + /* RFC5015 allocates the high 4 bits of pim_rsv for "subtype". */ + pimv2_addr_len = GET_U_1(pim->pim_rsv) & 0x0f; if (pimv2_addr_len != 0) - ND_PRINT((ndo, ", RFC2117-encoding")); + ND_PRINT(", RFC2117-encoding"); - if (len < 4) - goto trunc; - ND_TCHECK(pim->pim_cksum); - ND_PRINT((ndo, ", cksum 0x%04x ", EXTRACT_16BITS(&pim->pim_cksum))); - if (EXTRACT_16BITS(&pim->pim_cksum) == 0) { - ND_PRINT((ndo, "(unverified)")); + if (len < 4) { + ND_PRINT("[length %u < 4]", len); + nd_print_invalid(ndo); + return; + } + ND_PRINT(", cksum 0x%04x ", GET_BE_U_2(pim->pim_cksum)); + if (GET_BE_U_2(pim->pim_cksum) == 0) { + ND_PRINT("(unverified)"); } else { - if (PIM_TYPE(pim->pim_typever) == PIMV2_TYPE_REGISTER) { + if (PIM_TYPE(pim_typever) == PIMV2_TYPE_REGISTER) { /* * The checksum only covers the packet header, * not the encapsulated packet. @@ -737,62 +739,66 @@ pimv2_print(netdissect_options *ndo, switch (cksum_status) { case CORRECT: - ND_PRINT((ndo, "(correct)")); + ND_PRINT("(correct)"); break; case INCORRECT: - ND_PRINT((ndo, "(incorrect)")); + ND_PRINT("(incorrect)"); break; case UNVERIFIED: - ND_PRINT((ndo, "(unverified)")); + ND_PRINT("(unverified)"); break; } } bp += 4; len -= 4; - switch (PIM_TYPE(pim->pim_typever)) { + switch (PIM_TYPE(pim_typever)) { case PIMV2_TYPE_HELLO: { uint16_t otype, olen; while (len > 0) { if (len < 4) goto trunc; - ND_TCHECK2(bp[0], 4); - otype = EXTRACT_16BITS(&bp[0]); - olen = EXTRACT_16BITS(&bp[2]); - ND_PRINT((ndo, "\n\t %s Option (%u), length %u, Value: ", + otype = GET_BE_U_2(bp); + olen = GET_BE_U_2(bp + 2); + ND_PRINT("\n\t %s Option (%u), length %u, Value: ", tok2str(pimv2_hello_option_values, "Unknown", otype), otype, - olen)); + olen); bp += 4; len -= 4; if (len < olen) goto trunc; - ND_TCHECK2(bp[0], olen); + ND_TCHECK_LEN(bp, olen); switch (otype) { case PIMV2_HELLO_OPTION_HOLDTIME: if (olen != 2) { - ND_PRINT((ndo, "ERROR: Option Length != 2 Bytes (%u)", olen)); + ND_PRINT("[option length %u != 2]", olen); + nd_print_invalid(ndo); + return; } else { - unsigned_relts_print(ndo, EXTRACT_16BITS(bp)); + unsigned_relts_print(ndo, + GET_BE_U_2(bp)); } break; case PIMV2_HELLO_OPTION_LANPRUNEDELAY: if (olen != 4) { - ND_PRINT((ndo, "ERROR: Option Length != 4 Bytes (%u)", olen)); + ND_PRINT("[option length %u != 4]", olen); + nd_print_invalid(ndo); + return; } else { char t_bit; uint16_t lan_delay, override_interval; - lan_delay = EXTRACT_16BITS(bp); - override_interval = EXTRACT_16BITS(bp+2); + lan_delay = GET_BE_U_2(bp); + override_interval = GET_BE_U_2(bp + 2); t_bit = (lan_delay & 0x8000)? 1 : 0; lan_delay &= ~0x8000; - ND_PRINT((ndo, "\n\t T-bit=%d, LAN delay %dms, Override interval %dms", - t_bit, lan_delay, override_interval)); + ND_PRINT("\n\t T-bit=%u, LAN delay %ums, Override interval %ums", + t_bit, lan_delay, override_interval); } break; @@ -800,36 +806,44 @@ pimv2_print(netdissect_options *ndo, case PIMV2_HELLO_OPTION_DR_PRIORITY: switch (olen) { case 0: - ND_PRINT((ndo, "Bi-Directional Capability (Old)")); + ND_PRINT("Bi-Directional Capability (Old)"); break; case 4: - ND_PRINT((ndo, "%u", EXTRACT_32BITS(bp))); + ND_PRINT("%u", GET_BE_U_4(bp)); break; default: - ND_PRINT((ndo, "ERROR: Option Length != 4 Bytes (%u)", olen)); + ND_PRINT("[option length %u != 4]", olen); + nd_print_invalid(ndo); + return; break; } break; case PIMV2_HELLO_OPTION_GENID: if (olen != 4) { - ND_PRINT((ndo, "ERROR: Option Length != 4 Bytes (%u)", olen)); + ND_PRINT("[option length %u != 4]", olen); + nd_print_invalid(ndo); + return; } else { - ND_PRINT((ndo, "0x%08x", EXTRACT_32BITS(bp))); + ND_PRINT("0x%08x", GET_BE_U_4(bp)); } break; case PIMV2_HELLO_OPTION_REFRESH_CAP: if (olen != 4) { - ND_PRINT((ndo, "ERROR: Option Length != 4 Bytes (%u)", olen)); + ND_PRINT("[option length %u != 4]", olen); + nd_print_invalid(ndo); + return; } else { - ND_PRINT((ndo, "v%d", *bp)); - if (*(bp+1) != 0) { - ND_PRINT((ndo, ", interval ")); - unsigned_relts_print(ndo, *(bp+1)); + ND_PRINT("v%u", GET_U_1(bp)); + if (GET_U_1(bp + 1) != 0) { + ND_PRINT(", interval "); + unsigned_relts_print(ndo, + GET_U_1(bp + 1)); } - if (EXTRACT_16BITS(bp+2) != 0) { - ND_PRINT((ndo, " ?0x%04x?", EXTRACT_16BITS(bp+2))); + if (GET_BE_U_2(bp + 2) != 0) { + ND_PRINT(" ?0x%04x?", + GET_BE_U_2(bp + 2)); } } break; @@ -843,7 +857,7 @@ pimv2_print(netdissect_options *ndo, const u_char *ptr = bp; u_int plen = len; while (ptr < (bp+olen)) { - ND_PRINT((ndo, "\n\t ")); + ND_PRINT("\n\t "); advance = pimv2_addr_print(ndo, ptr, plen, pimv2_unicast, pimv2_addr_len, 0); if (advance < 0) goto trunc; @@ -872,25 +886,23 @@ pimv2_print(netdissect_options *ndo, if (len < 4) goto trunc; - ND_TCHECK2(*bp, PIMV2_REGISTER_FLAG_LEN); + ND_TCHECK_LEN(bp, PIMV2_REGISTER_FLAG_LEN); - ND_PRINT((ndo, ", Flags [ %s ]\n\t", + ND_PRINT(", Flags [ %s ]\n\t", tok2str(pimv2_register_flag_values, "none", - EXTRACT_32BITS(bp)))); + GET_BE_U_4(bp))); bp += 4; len -= 4; /* encapsulated multicast packet */ if (len == 0) goto trunc; ip = (const struct ip *)bp; - ND_TCHECK(ip->ip_vhl); switch (IP_V(ip)) { case 0: /* Null header */ - ND_TCHECK(ip->ip_dst); - ND_PRINT((ndo, "IP-Null-header %s > %s", - ipaddr_string(ndo, &ip->ip_src), - ipaddr_string(ndo, &ip->ip_dst))); + ND_PRINT("IP-Null-header %s > %s", + GET_IPADDR_STRING(ip->ip_src), + GET_IPADDR_STRING(ip->ip_dst)); break; case 4: /* IPv4 */ @@ -902,18 +914,18 @@ pimv2_print(netdissect_options *ndo, break; default: - ND_PRINT((ndo, "IP ver %d", IP_V(ip))); + ND_PRINT("IP ver %u", IP_V(ip)); break; } break; } case PIMV2_TYPE_REGISTER_STOP: - ND_PRINT((ndo, " group=")); + ND_PRINT(" group="); if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0) goto trunc; bp += advance; len -= advance; - ND_PRINT((ndo, " source=")); + ND_PRINT(" source="); if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0) goto trunc; bp += advance; len -= advance; @@ -964,48 +976,48 @@ pimv2_print(netdissect_options *ndo, uint16_t holdtime; uint16_t njoin; uint16_t nprune; - int i, j; + u_int i, j; - if (PIM_TYPE(pim->pim_typever) != 7) { /*not for Graft-ACK*/ - ND_PRINT((ndo, ", upstream-neighbor: ")); + if (PIM_TYPE(pim_typever) != 7) { /*not for Graft-ACK*/ + ND_PRINT(", upstream-neighbor: "); if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0) goto trunc; bp += advance; len -= advance; } if (len < 4) goto trunc; - ND_TCHECK2(*bp, 4); - ngroup = bp[1]; - holdtime = EXTRACT_16BITS(&bp[2]); - ND_PRINT((ndo, "\n\t %u group(s)", ngroup)); - if (PIM_TYPE(pim->pim_typever) != 7) { /*not for Graft-ACK*/ - ND_PRINT((ndo, ", holdtime: ")); + ND_TCHECK_4(bp); + ngroup = GET_U_1(bp + 1); + holdtime = GET_BE_U_2(bp + 2); + ND_PRINT("\n\t %u group(s)", ngroup); + if (PIM_TYPE(pim_typever) != 7) { /*not for Graft-ACK*/ + ND_PRINT(", holdtime: "); if (holdtime == 0xffff) - ND_PRINT((ndo, "infinite")); + ND_PRINT("infinite"); else unsigned_relts_print(ndo, holdtime); } bp += 4; len -= 4; for (i = 0; i < ngroup; i++) { - ND_PRINT((ndo, "\n\t group #%u: ", i+1)); + ND_PRINT("\n\t group #%u: ", i+1); if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0) goto trunc; bp += advance; len -= advance; if (len < 4) goto trunc; - ND_TCHECK2(*bp, 4); - njoin = EXTRACT_16BITS(&bp[0]); - nprune = EXTRACT_16BITS(&bp[2]); - ND_PRINT((ndo, ", joined sources: %u, pruned sources: %u", njoin, nprune)); + ND_TCHECK_4(bp); + njoin = GET_BE_U_2(bp); + nprune = GET_BE_U_2(bp + 2); + ND_PRINT(", joined sources: %u, pruned sources: %u", njoin, nprune); bp += 4; len -= 4; for (j = 0; j < njoin; j++) { - ND_PRINT((ndo, "\n\t joined source #%u: ", j+1)); + ND_PRINT("\n\t joined source #%u: ", j+1); if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_source, pimv2_addr_len, 0)) < 0) goto trunc; bp += advance; len -= advance; } for (j = 0; j < nprune; j++) { - ND_PRINT((ndo, "\n\t pruned source #%u: ", j+1)); + ND_PRINT("\n\t pruned source #%u: ", j+1); if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_source, pimv2_addr_len, 0)) < 0) goto trunc; bp += advance; len -= advance; @@ -1016,28 +1028,26 @@ pimv2_print(netdissect_options *ndo, case PIMV2_TYPE_BOOTSTRAP: { - int i, j, frpcnt; + u_int i, j, frpcnt; /* Fragment Tag, Hash Mask len, and BSR-priority */ if (len < 2) goto trunc; - ND_TCHECK_16BITS(bp); - ND_PRINT((ndo, " tag=%x", EXTRACT_16BITS(bp))); + ND_PRINT(" tag=%x", GET_BE_U_2(bp)); bp += 2; len -= 2; if (len < 1) goto trunc; - ND_TCHECK(bp[0]); - ND_PRINT((ndo, " hashmlen=%d", bp[0])); + ND_PRINT(" hashmlen=%u", GET_U_1(bp)); if (len < 2) goto trunc; - ND_TCHECK(bp[2]); - ND_PRINT((ndo, " BSRprio=%d", bp[1])); + ND_TCHECK_1(bp + 2); + ND_PRINT(" BSRprio=%u", GET_U_1(bp + 1)); bp += 2; len -= 2; /* Encoded-Unicast-BSR-Address */ - ND_PRINT((ndo, " BSR=")); + ND_PRINT(" BSR="); if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0) goto trunc; bp += advance; @@ -1045,7 +1055,7 @@ pimv2_print(netdissect_options *ndo, for (i = 0; len > 0; i++) { /* Encoded-Group Address */ - ND_PRINT((ndo, " (group%d: ", i)); + ND_PRINT(" (group%u: ", i); if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0) goto trunc; bp += advance; @@ -1054,12 +1064,11 @@ pimv2_print(netdissect_options *ndo, /* RP-Count, Frag RP-Cnt, and rsvd */ if (len < 1) goto trunc; - ND_TCHECK(bp[0]); - ND_PRINT((ndo, " RPcnt=%d", bp[0])); + ND_PRINT(" RPcnt=%u", GET_U_1(bp)); if (len < 2) goto trunc; - ND_TCHECK(bp[1]); - ND_PRINT((ndo, " FRPcnt=%d", frpcnt = bp[1])); + frpcnt = GET_U_1(bp + 1); + ND_PRINT(" FRPcnt=%u", frpcnt); if (len < 4) goto trunc; bp += 4; @@ -1067,7 +1076,7 @@ pimv2_print(netdissect_options *ndo, for (j = 0; j < frpcnt && len > 0; j++) { /* each RP info */ - ND_PRINT((ndo, " RP%d=", j)); + ND_PRINT(" RP%u=", j); if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, @@ -1078,64 +1087,60 @@ pimv2_print(netdissect_options *ndo, if (len < 2) goto trunc; - ND_TCHECK_16BITS(bp); - ND_PRINT((ndo, ",holdtime=")); - unsigned_relts_print(ndo, EXTRACT_16BITS(bp)); + ND_PRINT(",holdtime="); + unsigned_relts_print(ndo, + GET_BE_U_2(bp)); if (len < 3) goto trunc; - ND_TCHECK(bp[2]); - ND_PRINT((ndo, ",prio=%d", bp[2])); + ND_PRINT(",prio=%u", GET_U_1(bp + 2)); if (len < 4) goto trunc; bp += 4; len -= 4; } - ND_PRINT((ndo, ")")); + ND_PRINT(")"); } break; } case PIMV2_TYPE_ASSERT: - ND_PRINT((ndo, " group=")); + ND_PRINT(" group="); if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0) goto trunc; bp += advance; len -= advance; - ND_PRINT((ndo, " src=")); + ND_PRINT(" src="); if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0) goto trunc; bp += advance; len -= advance; if (len < 8) goto trunc; - ND_TCHECK2(*bp, 8); - if (bp[0] & 0x80) - ND_PRINT((ndo, " RPT")); - ND_PRINT((ndo, " pref=%u", EXTRACT_32BITS(&bp[0]) & 0x7fffffff)); - ND_PRINT((ndo, " metric=%u", EXTRACT_32BITS(&bp[4]))); + ND_TCHECK_8(bp); + if (GET_U_1(bp) & 0x80) + ND_PRINT(" RPT"); + ND_PRINT(" pref=%u", GET_BE_U_4(bp) & 0x7fffffff); + ND_PRINT(" metric=%u", GET_BE_U_4(bp + 4)); break; case PIMV2_TYPE_CANDIDATE_RP: { - int i, pfxcnt; + u_int i, pfxcnt; /* Prefix-Cnt, Priority, and Holdtime */ if (len < 1) goto trunc; - ND_TCHECK(bp[0]); - ND_PRINT((ndo, " prefix-cnt=%d", bp[0])); - pfxcnt = bp[0]; + ND_PRINT(" prefix-cnt=%u", GET_U_1(bp)); + pfxcnt = GET_U_1(bp); if (len < 2) goto trunc; - ND_TCHECK(bp[1]); - ND_PRINT((ndo, " prio=%d", bp[1])); + ND_PRINT(" prio=%u", GET_U_1(bp + 1)); if (len < 4) goto trunc; - ND_TCHECK_16BITS(&bp[2]); - ND_PRINT((ndo, " holdtime=")); - unsigned_relts_print(ndo, EXTRACT_16BITS(&bp[2])); + ND_PRINT(" holdtime="); + unsigned_relts_print(ndo, GET_BE_U_2(bp + 2)); bp += 4; len -= 4; /* Encoded-Unicast-RP-Address */ - ND_PRINT((ndo, " RP=")); + ND_PRINT(" RP="); if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0) goto trunc; bp += advance; @@ -1143,7 +1148,7 @@ pimv2_print(netdissect_options *ndo, /* Encoded-Group Addresses */ for (i = 0; i < pfxcnt && len > 0; i++) { - ND_PRINT((ndo, " Group%d=", i)); + ND_PRINT(" Group%u=", i); if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0) goto trunc; bp += advance; @@ -1153,43 +1158,77 @@ pimv2_print(netdissect_options *ndo, } case PIMV2_TYPE_PRUNE_REFRESH: - ND_PRINT((ndo, " src=")); + ND_PRINT(" src="); if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0) goto trunc; bp += advance; len -= advance; - ND_PRINT((ndo, " grp=")); + ND_PRINT(" grp="); if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0) goto trunc; bp += advance; len -= advance; - ND_PRINT((ndo, " forwarder=")); + ND_PRINT(" forwarder="); if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0) goto trunc; bp += advance; len -= advance; if (len < 2) goto trunc; - ND_TCHECK_16BITS(bp); - ND_PRINT((ndo, " TUNR ")); - unsigned_relts_print(ndo, EXTRACT_16BITS(bp)); + ND_PRINT(" TUNR "); + unsigned_relts_print(ndo, GET_BE_U_2(bp)); break; + case PIMV2_TYPE_DF_ELECTION: + subtype = PIM_SUBTYPE(GET_U_1(pim->pim_rsv)); + ND_PRINT("\n\t %s,", tok2str( pimv2_df_election_flag_values, + "Unknown", subtype) ); + + ND_PRINT(" rpa="); + if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0) { + goto trunc; + } + bp += advance; + len -= advance; + ND_PRINT(" sender pref=%u", GET_BE_U_4(bp) ); + ND_PRINT(" sender metric=%u", GET_BE_U_4(bp + 4)); + + bp += 8; + len -= 8; + + switch (subtype) { + case PIMV2_DF_ELECTION_BACKOFF: + case PIMV2_DF_ELECTION_PASS: + ND_PRINT("\n\t %s addr=", PIMV2_DF_ELECTION_PASS_BACKOFF_STR(subtype)); + if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0) { + goto trunc; + } + bp += advance; + len -= advance; + + ND_PRINT(" %s pref=%u", PIMV2_DF_ELECTION_PASS_BACKOFF_STR(subtype), GET_BE_U_4(bp) ); + ND_PRINT(" %s metric=%u", PIMV2_DF_ELECTION_PASS_BACKOFF_STR(subtype), GET_BE_U_4(bp + 4)); + + bp += 8; + len -= 8; + + if (subtype == PIMV2_DF_ELECTION_BACKOFF) { + ND_PRINT(" interval %dms", GET_BE_U_2(bp)); + } + + break; + default: + break; + } + break; default: - ND_PRINT((ndo, " [type %d]", PIM_TYPE(pim->pim_typever))); + ND_PRINT(" [type %u]", PIM_TYPE(pim_typever)); break; } return; trunc: - ND_PRINT((ndo, "[|pim]")); + nd_print_trunc(ndo); } - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/print-pktap.c b/contrib/tcpdump/print-pktap.c index 4a295fdf63..05ce5f9978 100644 --- a/contrib/tcpdump/print-pktap.c +++ b/contrib/tcpdump/print-pktap.c @@ -22,11 +22,12 @@ /* \summary: Apple's DLT_PKTAP printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" @@ -44,20 +45,20 @@ * to host byte order in libpcap. */ typedef struct pktap_header { - uint32_t pkt_len; /* length of pktap header */ - uint32_t pkt_rectype; /* type of record */ - uint32_t pkt_dlt; /* DLT type of this packet */ + nd_uint32_t pkt_len; /* length of pktap header */ + nd_uint32_t pkt_rectype; /* type of record */ + nd_uint32_t pkt_dlt; /* DLT type of this packet */ char pkt_ifname[24]; /* interface name */ - uint32_t pkt_flags; - uint32_t pkt_pfamily; /* "protocol family" */ - uint32_t pkt_llhdrlen; /* link-layer header length? */ - uint32_t pkt_lltrlrlen; /* link-layer trailer length? */ - uint32_t pkt_pid; /* process ID */ + nd_uint32_t pkt_flags; + nd_uint32_t pkt_pfamily; /* "protocol family" */ + nd_uint32_t pkt_llhdrlen; /* link-layer header length? */ + nd_uint32_t pkt_lltrlrlen; /* link-layer trailer length? */ + nd_uint32_t pkt_pid; /* process ID */ char pkt_cmdname[20]; /* command name */ - uint32_t pkt_svc_class; /* "service class" */ - uint16_t pkt_iftype; /* "interface type" */ - uint16_t pkt_ifunit; /* unit number of interface? */ - uint32_t pkt_epid; /* "effective process ID" */ + nd_uint32_t pkt_svc_class; /* "service class" */ + nd_uint16_t pkt_iftype; /* "interface type" */ + nd_uint16_t pkt_ifunit; /* unit number of interface? */ + nd_uint32_t pkt_epid; /* "effective process ID" */ char pkt_ecmdname[20]; /* "effective command name" */ } pktap_header_t; @@ -67,7 +68,7 @@ typedef struct pktap_header { #define PKT_REC_NONE 0 /* nothing follows the header */ #define PKT_REC_PACKET 1 /* a packet follows the header */ -static inline void +static void pktap_header_print(netdissect_options *ndo, const u_char *bp, u_int length) { const pktap_header_t *hdr; @@ -76,17 +77,17 @@ pktap_header_print(netdissect_options *ndo, const u_char *bp, u_int length) hdr = (const pktap_header_t *)bp; - dlt = EXTRACT_LE_32BITS(&hdr->pkt_dlt); - hdrlen = EXTRACT_LE_32BITS(&hdr->pkt_len); + dlt = GET_LE_U_4(hdr->pkt_dlt); + hdrlen = GET_LE_U_4(hdr->pkt_len); dltname = pcap_datalink_val_to_name(dlt); if (!ndo->ndo_qflag) { - ND_PRINT((ndo,"DLT %s (%d) len %d", - (dltname != NULL ? dltname : "UNKNOWN"), dlt, hdrlen)); + ND_PRINT("DLT %s (%u) len %u", + (dltname != NULL ? dltname : "UNKNOWN"), dlt, hdrlen); } else { - ND_PRINT((ndo,"%s", (dltname != NULL ? dltname : "UNKNOWN"))); + ND_PRINT("%s", (dltname != NULL ? dltname : "UNKNOWN")); } - ND_PRINT((ndo, ", length %u: ", length)); + ND_PRINT(", length %u: ", length); } /* @@ -95,7 +96,7 @@ pktap_header_print(netdissect_options *ndo, const u_char *bp, u_int length) * 'h->len' is the length of the packet off the wire, and 'h->caplen' * is the number of bytes actually captured. */ -u_int +void pktap_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { @@ -106,13 +107,15 @@ pktap_if_print(netdissect_options *ndo, const pktap_header_t *hdr; struct pcap_pkthdr nhdr; - if (caplen < sizeof(pktap_header_t) || length < sizeof(pktap_header_t)) { - ND_PRINT((ndo, "[|pktap]")); - return (0); + ndo->ndo_protocol = "pktap"; + if (length < sizeof(pktap_header_t)) { + ND_PRINT(" (packet too short, %u < %zu)", + length, sizeof(pktap_header_t)); + goto invalid; } hdr = (const pktap_header_t *)p; - dlt = EXTRACT_LE_32BITS(&hdr->pkt_dlt); - hdrlen = EXTRACT_LE_32BITS(&hdr->pkt_len); + dlt = GET_LE_U_4(hdr->pkt_dlt); + hdrlen = GET_LE_U_4(hdr->pkt_len); if (hdrlen < sizeof(pktap_header_t)) { /* * Claimed header length < structure length. @@ -121,13 +124,16 @@ pktap_if_print(netdissect_options *ndo, * is the length supplied so that the header can * be expanded in the future)? */ - ND_PRINT((ndo, "[|pktap]")); - return (0); + ND_PRINT(" (pkt_len too small, %u < %zu)", + hdrlen, sizeof(pktap_header_t)); + goto invalid; } - if (caplen < hdrlen || length < hdrlen) { - ND_PRINT((ndo, "[|pktap]")); - return (hdrlen); + if (hdrlen > length) { + ND_PRINT(" (pkt_len too big, %u > %u)", + hdrlen, length); + goto invalid; } + ND_TCHECK_LEN(p, hdrlen); if (ndo->ndo_eflag) pktap_header_print(ndo, p, length); @@ -136,19 +142,21 @@ pktap_if_print(netdissect_options *ndo, caplen -= hdrlen; p += hdrlen; - rectype = EXTRACT_LE_32BITS(&hdr->pkt_rectype); + rectype = GET_LE_U_4(hdr->pkt_rectype); switch (rectype) { case PKT_REC_NONE: - ND_PRINT((ndo, "no data")); + ND_PRINT("no data"); break; case PKT_REC_PACKET: - if ((printer = lookup_printer(dlt)) != NULL) { + printer = lookup_printer(dlt); + if (printer != NULL) { nhdr = *h; nhdr.caplen = caplen; nhdr.len = length; - hdrlen += printer(ndo, &nhdr, p); + printer(ndo, &nhdr, p); + hdrlen += ndo->ndo_ll_hdr_len; } else { if (!ndo->ndo_eflag) pktap_header_print(ndo, (const u_char *)hdr, @@ -160,14 +168,10 @@ pktap_if_print(netdissect_options *ndo, break; } - return (hdrlen); -} - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ + ndo->ndo_ll_hdr_len += hdrlen; + return; +invalid: + nd_print_invalid(ndo); +} #endif /* DLT_PKTAP */ diff --git a/contrib/tcpdump/print-ppi.c b/contrib/tcpdump/print-ppi.c index 66b7582150..774edfbaf8 100644 --- a/contrib/tcpdump/print-ppi.c +++ b/contrib/tcpdump/print-ppi.c @@ -2,29 +2,37 @@ * Oracle */ -/* \summary: Oracle DLT_PPI printer */ +/* \summary: Per-Packet Information (DLT_PPI) printer */ + +/* Specification: + * Per-Packet Information Header Specification - Version 1.0.7 + * https://web.archive.org/web/20160328114748/http://www.cacetech.com/documents/PPI%20Header%20format%201.0.7.pdf + */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "extract.h" + typedef struct ppi_header { - uint8_t ppi_ver; - uint8_t ppi_flags; - uint16_t ppi_len; - uint32_t ppi_dlt; + nd_uint8_t ppi_ver; /* Version. Currently 0 */ + nd_uint8_t ppi_flags; /* Flags. */ + nd_uint16_t ppi_len; /* Length of entire message, including + * this header and TLV payload. */ + nd_uint32_t ppi_dlt; /* Data Link Type of the captured + * packet data. */ } ppi_header_t; #define PPI_HDRLEN 8 #ifdef DLT_PPI -static inline void +static void ppi_header_print(netdissect_options *ndo, const u_char *bp, u_int length) { const ppi_header_t *hdr; @@ -34,24 +42,30 @@ ppi_header_print(netdissect_options *ndo, const u_char *bp, u_int length) hdr = (const ppi_header_t *)bp; - len = EXTRACT_LE_16BITS(&hdr->ppi_len); - dlt = EXTRACT_LE_32BITS(&hdr->ppi_dlt); + len = GET_LE_U_2(hdr->ppi_len); + dlt = GET_LE_U_4(hdr->ppi_dlt); dltname = pcap_datalink_val_to_name(dlt); if (!ndo->ndo_qflag) { - ND_PRINT((ndo, "V.%d DLT %s (%d) len %d", hdr->ppi_ver, + ND_PRINT("V.%u DLT %s (%u) len %u", GET_U_1(hdr->ppi_ver), (dltname != NULL ? dltname : "UNKNOWN"), dlt, - len)); + len); } else { - ND_PRINT((ndo, "%s", (dltname != NULL ? dltname : "UNKNOWN"))); + ND_PRINT("%s", (dltname != NULL ? dltname : "UNKNOWN")); } - ND_PRINT((ndo, ", length %u: ", length)); + ND_PRINT(", length %u: ", length); } -static u_int -ppi_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, const u_char *p) +/* + * 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. + */ +void +ppi_if_print(netdissect_options *ndo, + const struct pcap_pkthdr *h, const u_char *p) { if_printer printer; const ppi_header_t *hdr; @@ -62,28 +76,33 @@ ppi_print(netdissect_options *ndo, uint32_t hdrlen; struct pcap_pkthdr nhdr; + ndo->ndo_protocol = "ppi"; if (caplen < sizeof(ppi_header_t)) { - ND_PRINT((ndo, "[|ppi]")); - return (caplen); + nd_print_trunc(ndo); + ndo->ndo_ll_hdr_len += caplen; + return; } hdr = (const ppi_header_t *)p; - ND_TCHECK_16BITS(&hdr->ppi_len); - len = EXTRACT_LE_16BITS(&hdr->ppi_len); + len = GET_LE_U_2(hdr->ppi_len); + if (len < sizeof(ppi_header_t) || len > 65532) { + /* It MUST be between 8 and 65,532 inclusive (spec 3.1.3) */ + ND_PRINT(" [length %u < %zu or > 65532]", len, + sizeof(ppi_header_t)); + nd_print_invalid(ndo); + ndo->ndo_ll_hdr_len += caplen; + return; + } if (caplen < len) { /* * If we don't have the entire PPI header, don't * bother. */ - ND_PRINT((ndo, "[|ppi]")); - return (caplen); - } - if (len < sizeof(ppi_header_t)) { - ND_PRINT((ndo, "[|ppi]")); - return (len); + nd_print_trunc(ndo); + ndo->ndo_ll_hdr_len += caplen; + return; } - ND_TCHECK_32BITS(&hdr->ppi_dlt); - dlt = EXTRACT_LE_32BITS(&hdr->ppi_dlt); + dlt = GET_LE_U_4(hdr->ppi_dlt); if (ndo->ndo_eflag) ppi_header_print(ndo, p, length); @@ -92,11 +111,13 @@ ppi_print(netdissect_options *ndo, caplen -= len; p += len; - if ((printer = lookup_printer(dlt)) != NULL) { + printer = lookup_printer(dlt); + if (printer != NULL) { nhdr = *h; nhdr.caplen = caplen; nhdr.len = length; - hdrlen = printer(ndo, &nhdr, p); + printer(ndo, &nhdr, p); + hdrlen = ndo->ndo_ll_hdr_len; } else { if (!ndo->ndo_eflag) ppi_header_print(ndo, (const u_char *)hdr, length + len); @@ -105,29 +126,6 @@ ppi_print(netdissect_options *ndo, ND_DEFAULTPRINT(p, caplen); hdrlen = 0; } - return (len + hdrlen); -trunc: - return (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(netdissect_options *ndo, - const struct pcap_pkthdr *h, const u_char *p) -{ - return (ppi_print(ndo, h, p)); + ndo->ndo_ll_hdr_len += len + hdrlen; } - -/* - * 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 891761728b..baeb4f0049 100644 --- a/contrib/tcpdump/print-ppp.c +++ b/contrib/tcpdump/print-ppp.c @@ -32,18 +32,16 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #ifdef __bsdi__ #include #include #endif -#include - #include "netdissect.h" #include "extract.h" #include "addrtoname.h" @@ -51,10 +49,11 @@ #include "chdlc.h" #include "ethertype.h" #include "oui.h" +#include "netdissect-alloc.h" /* - * The following constatns are defined by IANA. Please refer to - * http://www.isi.edu/in-notes/iana/assignments/ppp-numbers + * The following constants are defined by IANA. Please refer to + * https://www.isi.edu/in-notes/iana/assignments/ppp-numbers * for the up-to-date information. */ @@ -179,9 +178,6 @@ static const struct tok cpcodes[] = { #define LCPOPT_SDLOS 29 #define LCPOPT_PPPMUX 30 -#define LCPOPT_MIN LCPOPT_VEXT -#define LCPOPT_MAX LCPOPT_PPPMUX - static const char *lcpconfopts[] = { "Vend-Ext", /* (0) */ "MRU", /* (1) */ @@ -216,6 +212,8 @@ static const char *lcpconfopts[] = { "PPP-Muxing", /* (30) */ }; +#define NUM_LCPOPTS (sizeof(lcpconfopts) / sizeof(lcpconfopts[0])) + /* ECP - to be supported */ /* CCP Config Options */ @@ -402,52 +400,64 @@ static const struct tok papcode_values[] = { #define BAP_CSIND 7 #define BAP_CSRES 8 -static int print_lcp_config_options(netdissect_options *, const u_char *p, int); -static int print_ipcp_config_options(netdissect_options *, const u_char *p, int); -static int print_ip6cp_config_options(netdissect_options *, const u_char *p, int); -static int print_ccp_config_options(netdissect_options *, const u_char *p, int); -static int print_bacp_config_options(netdissect_options *, const u_char *p, int); -static void handle_ppp(netdissect_options *, u_int proto, const u_char *p, int length); +static u_int print_lcp_config_options(netdissect_options *, const u_char *p, u_int); +static u_int print_ipcp_config_options(netdissect_options *, const u_char *p, u_int); +static u_int print_ip6cp_config_options(netdissect_options *, const u_char *p, u_int); +static u_int print_ccp_config_options(netdissect_options *, const u_char *p, u_int); +static u_int print_bacp_config_options(netdissect_options *, const u_char *p, u_int); +static void handle_ppp(netdissect_options *, u_int proto, const u_char *p, u_int length); /* generic Control Protocol (e.g. LCP, IPCP, CCP, etc.) handler */ static void handle_ctrl_proto(netdissect_options *ndo, - u_int proto, const u_char *pptr, int length) + u_int proto, const u_char *pptr, u_int length) { const char *typestr; u_int code, len; - int (*pfunc)(netdissect_options *, const u_char *, int); - int x, j; + u_int (*pfunc)(netdissect_options *, const u_char *, u_int); + u_int tlen, advance; const u_char *tptr; tptr=pptr; typestr = tok2str(ppptype2str, "unknown ctrl-proto (0x%04x)", proto); - ND_PRINT((ndo, "%s, ", typestr)); + ND_PRINT("%s, ", typestr); if (length < 4) /* FIXME weak boundary checking */ goto trunc; - ND_TCHECK2(*tptr, 2); + ND_TCHECK_2(tptr); - code = *tptr++; + code = GET_U_1(tptr); + tptr++; - ND_PRINT((ndo, "%s (0x%02x), id %u, length %u", + ND_PRINT("%s (0x%02x), id %u, length %u", tok2str(cpcodes, "Unknown Opcode",code), code, - *tptr++, /* ID */ - length + 2)); + GET_U_1(tptr), /* ID */ + length + 2); + tptr++; if (!ndo->ndo_vflag) return; - if (length <= 4) - return; /* there may be a NULL confreq etc. */ - - ND_TCHECK2(*tptr, 2); - len = EXTRACT_16BITS(tptr); + len = GET_BE_U_2(tptr); tptr += 2; - ND_PRINT((ndo, "\n\tencoded length %u (=Option(s) length %u)", len, len - 4)); + if (len < 4) { + ND_PRINT("\n\tencoded length %u (< 4))", len); + return; + } + + if (len > length) { + ND_PRINT("\n\tencoded length %u (> packet length %u))", len, length); + return; + } + length = len; + + ND_PRINT("\n\tencoded length %u (=Option(s) length %u)", len, len - 4); + + if (length == 4) + return; /* there may be a NULL confreq etc. */ if (ndo->ndo_vflag > 1) print_unknown_data(ndo, pptr - 2, "\n\t", 6); @@ -457,20 +467,18 @@ handle_ctrl_proto(netdissect_options *ndo, case CPCODES_VEXT: if (length < 11) break; - ND_TCHECK2(*tptr, 4); - ND_PRINT((ndo, "\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr))); + ND_PRINT("\n\t Magic-Num 0x%08x", GET_BE_U_4(tptr)); tptr += 4; - ND_TCHECK2(*tptr, 3); - ND_PRINT((ndo, " Vendor: %s (%u)", - tok2str(oui_values,"Unknown",EXTRACT_24BITS(tptr)), - EXTRACT_24BITS(tptr))); + ND_PRINT(" Vendor: %s (%u)", + tok2str(oui_values,"Unknown",GET_BE_U_3(tptr)), + GET_BE_U_3(tptr)); /* XXX: need to decode Kind and Value(s)? */ break; case CPCODES_CONF_REQ: case CPCODES_CONF_ACK: case CPCODES_CONF_NAK: case CPCODES_CONF_REJ: - x = len - 4; /* Code(1), Identifier(1) and Length(2) */ + tlen = len - 4; /* Code(1), Identifier(1) and Length(2) */ do { switch (proto) { case PPP_LCP: @@ -500,11 +508,17 @@ handle_ctrl_proto(netdissect_options *ndo, if (pfunc == NULL) /* catch the above null pointer if unknown CP */ break; - if ((j = (*pfunc)(ndo, tptr, len)) == 0) + if ((advance = (*pfunc)(ndo, tptr, len)) == 0) break; - x -= j; - tptr += j; - } while (x > 0); + if (tlen < advance) { + ND_PRINT(" [remaining options length %u < %u]", + tlen, advance); + nd_print_invalid(ndo); + break; + } + tlen -= advance; + tptr += advance; + } while (tlen != 0); break; case CPCODES_TERM_REQ: @@ -517,13 +531,12 @@ handle_ctrl_proto(netdissect_options *ndo, case CPCODES_PROT_REJ: if (length < 6) break; - ND_TCHECK2(*tptr, 2); - ND_PRINT((ndo, "\n\t Rejected %s Protocol (0x%04x)", - tok2str(ppptype2str,"unknown", EXTRACT_16BITS(tptr)), - EXTRACT_16BITS(tptr))); + ND_PRINT("\n\t Rejected %s Protocol (0x%04x)", + tok2str(ppptype2str,"unknown", GET_BE_U_2(tptr)), + GET_BE_U_2(tptr)); /* XXX: need to decode Rejected-Information? - hexdump for now */ if (len > 6) { - ND_PRINT((ndo, "\n\t Rejected Packet")); + ND_PRINT("\n\t Rejected Packet"); print_unknown_data(ndo, tptr + 2, "\n\t ", len - 2); } break; @@ -532,34 +545,30 @@ handle_ctrl_proto(netdissect_options *ndo, case CPCODES_DISC_REQ: if (length < 8) break; - ND_TCHECK2(*tptr, 4); - ND_PRINT((ndo, "\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr))); + ND_PRINT("\n\t Magic-Num 0x%08x", GET_BE_U_4(tptr)); /* XXX: need to decode Data? - hexdump for now */ if (len > 8) { - ND_PRINT((ndo, "\n\t -----trailing data-----")); - ND_TCHECK2(tptr[4], len - 8); + ND_PRINT("\n\t -----trailing data-----"); + ND_TCHECK_LEN(tptr + 4, len - 8); print_unknown_data(ndo, tptr + 4, "\n\t ", len - 8); } break; case CPCODES_ID: if (length < 8) break; - ND_TCHECK2(*tptr, 4); - ND_PRINT((ndo, "\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr))); + ND_PRINT("\n\t Magic-Num 0x%08x", GET_BE_U_4(tptr)); /* RFC 1661 says this is intended to be human readable */ if (len > 8) { - ND_PRINT((ndo, "\n\t Message\n\t ")); - if (fn_printn(ndo, tptr + 4, len - 4, ndo->ndo_snapend)) + ND_PRINT("\n\t Message\n\t "); + if (nd_printn(ndo, tptr + 4, len - 4, ndo->ndo_snapend)) goto trunc; } break; case CPCODES_TIME_REM: if (length < 12) break; - ND_TCHECK2(*tptr, 4); - ND_PRINT((ndo, "\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr))); - ND_TCHECK2(*(tptr + 4), 4); - ND_PRINT((ndo, ", Seconds-Remaining %us", EXTRACT_32BITS(tptr + 4))); + ND_PRINT("\n\t Magic-Num 0x%08x", GET_BE_U_4(tptr)); + ND_PRINT(", Seconds-Remaining %us", GET_BE_U_4(tptr + 4)); /* XXX: need to decode Message? */ break; default: @@ -573,86 +582,81 @@ handle_ctrl_proto(netdissect_options *ndo, return; trunc: - ND_PRINT((ndo, "[|%s]", typestr)); + ND_PRINT("[|%s]", typestr); } /* LCP config options */ -static int +static u_int print_lcp_config_options(netdissect_options *ndo, - const u_char *p, int length) + const u_char *p, u_int length) { - int len, opt; + u_int opt, len; if (length < 2) return 0; - ND_TCHECK2(*p, 2); - len = p[1]; - opt = p[0]; + ND_TCHECK_2(p); + opt = GET_U_1(p); + len = GET_U_1(p + 1); if (length < len) return 0; if (len < 2) { - if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX)) - ND_PRINT((ndo, "\n\t %s Option (0x%02x), length %u (length bogus, should be >= 2)", - lcpconfopts[opt], opt, len)); + if (opt < NUM_LCPOPTS) + ND_PRINT("\n\t %s Option (0x%02x), length %u (length bogus, should be >= 2)", + lcpconfopts[opt], opt, len); else - ND_PRINT((ndo, "\n\tunknown LCP option 0x%02x", opt)); + ND_PRINT("\n\tunknown LCP option 0x%02x", opt); return 0; } - if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX)) - ND_PRINT((ndo, "\n\t %s Option (0x%02x), length %u", lcpconfopts[opt], opt, len)); + if (opt < NUM_LCPOPTS) + ND_PRINT("\n\t %s Option (0x%02x), length %u", lcpconfopts[opt], opt, len); else { - ND_PRINT((ndo, "\n\tunknown LCP option 0x%02x", opt)); + ND_PRINT("\n\tunknown LCP option 0x%02x", opt); return len; } switch (opt) { case LCPOPT_VEXT: if (len < 6) { - ND_PRINT((ndo, " (length bogus, should be >= 6)")); + ND_PRINT(" (length bogus, should be >= 6)"); return len; } - ND_TCHECK_24BITS(p + 2); - ND_PRINT((ndo, ": Vendor: %s (%u)", - tok2str(oui_values,"Unknown",EXTRACT_24BITS(p+2)), - EXTRACT_24BITS(p + 2))); + ND_PRINT(": Vendor: %s (%u)", + tok2str(oui_values,"Unknown",GET_BE_U_3(p + 2)), + GET_BE_U_3(p + 2)); #if 0 - ND_TCHECK(p[5]); - ND_PRINT((ndo, ", kind: 0x%02x", p[5])); - ND_PRINT((ndo, ", Value: 0x")); + ND_PRINT(", kind: 0x%02x", GET_U_1(p + 5)); + ND_PRINT(", Value: 0x"); for (i = 0; i < len - 6; i++) { - ND_TCHECK(p[6 + i]); - ND_PRINT((ndo, "%02x", p[6 + i])); + ND_PRINT("%02x", GET_U_1(p + 6 + i)); } #endif break; case LCPOPT_MRU: if (len != 4) { - ND_PRINT((ndo, " (length bogus, should be = 4)")); + ND_PRINT(" (length bogus, should be = 4)"); return len; } - ND_TCHECK_16BITS(p + 2); - ND_PRINT((ndo, ": %u", EXTRACT_16BITS(p + 2))); + ND_PRINT(": %u", GET_BE_U_2(p + 2)); break; case LCPOPT_ACCM: if (len != 6) { - ND_PRINT((ndo, " (length bogus, should be = 6)")); + ND_PRINT(" (length bogus, should be = 6)"); return len; } - ND_TCHECK_32BITS(p + 2); - ND_PRINT((ndo, ": 0x%08x", EXTRACT_32BITS(p + 2))); + ND_PRINT(": 0x%08x", GET_BE_U_4(p + 2)); break; case LCPOPT_AP: if (len < 4) { - ND_PRINT((ndo, " (length bogus, should be >= 4)")); + ND_PRINT(" (length bogus, should be >= 4)"); return len; } - ND_TCHECK_16BITS(p + 2); - ND_PRINT((ndo, ": %s", tok2str(ppptype2str, "Unknown Auth Proto (0x04x)", EXTRACT_16BITS(p + 2)))); + ND_PRINT(": %s", + tok2str(ppptype2str, "Unknown Auth Proto (0x04x)", GET_BE_U_2(p + 2))); - switch (EXTRACT_16BITS(p+2)) { + switch (GET_BE_U_2(p + 2)) { case PPP_CHAP: - ND_TCHECK(p[4]); - ND_PRINT((ndo, ", %s", tok2str(authalg_values, "Unknown Auth Alg %u", p[4]))); + ND_PRINT(", %s", + tok2str(authalg_values, "Unknown Auth Alg %u", GET_U_1(p + 4))); break; case PPP_PAP: /* fall through */ case PPP_EAP: @@ -665,22 +669,20 @@ print_lcp_config_options(netdissect_options *ndo, break; case LCPOPT_QP: if (len < 4) { - ND_PRINT((ndo, " (length bogus, should be >= 4)")); + ND_PRINT(" (length bogus, should be >= 4)"); return 0; } - ND_TCHECK_16BITS(p+2); - if (EXTRACT_16BITS(p+2) == PPP_LQM) - ND_PRINT((ndo, ": LQR")); + if (GET_BE_U_2(p + 2) == PPP_LQM) + ND_PRINT(": LQR"); else - ND_PRINT((ndo, ": unknown")); + ND_PRINT(": unknown"); break; case LCPOPT_MN: if (len != 6) { - ND_PRINT((ndo, " (length bogus, should be = 6)")); + ND_PRINT(" (length bogus, should be = 6)"); return 0; } - ND_TCHECK_32BITS(p + 2); - ND_PRINT((ndo, ": 0x%08x", EXTRACT_32BITS(p + 2))); + ND_PRINT(": 0x%08x", GET_BE_U_4(p + 2)); break; case LCPOPT_PFC: break; @@ -688,68 +690,62 @@ print_lcp_config_options(netdissect_options *ndo, break; case LCPOPT_LD: if (len != 4) { - ND_PRINT((ndo, " (length bogus, should be = 4)")); + ND_PRINT(" (length bogus, should be = 4)"); return 0; } - ND_TCHECK_16BITS(p + 2); - ND_PRINT((ndo, ": 0x%04x", EXTRACT_16BITS(p + 2))); + ND_PRINT(": 0x%04x", GET_BE_U_2(p + 2)); break; case LCPOPT_CBACK: if (len < 3) { - ND_PRINT((ndo, " (length bogus, should be >= 3)")); + ND_PRINT(" (length bogus, should be >= 3)"); return 0; } - ND_PRINT((ndo, ": ")); - ND_TCHECK(p[2]); - ND_PRINT((ndo, ": Callback Operation %s (%u)", - tok2str(ppp_callback_values, "Unknown", p[2]), - p[2])); + ND_PRINT(": "); + ND_PRINT(": Callback Operation %s (%u)", + tok2str(ppp_callback_values, "Unknown", GET_U_1(p + 2)), + GET_U_1(p + 2)); break; case LCPOPT_MLMRRU: if (len != 4) { - ND_PRINT((ndo, " (length bogus, should be = 4)")); + ND_PRINT(" (length bogus, should be = 4)"); return 0; } - ND_TCHECK_16BITS(p + 2); - ND_PRINT((ndo, ": %u", EXTRACT_16BITS(p + 2))); + ND_PRINT(": %u", GET_BE_U_2(p + 2)); break; case LCPOPT_MLED: if (len < 3) { - ND_PRINT((ndo, " (length bogus, should be >= 3)")); + ND_PRINT(" (length bogus, should be >= 3)"); return 0; } - ND_TCHECK(p[2]); - switch (p[2]) { /* class */ + switch (GET_U_1(p + 2)) { /* class */ case MEDCLASS_NULL: - ND_PRINT((ndo, ": Null")); + ND_PRINT(": Null"); break; case MEDCLASS_LOCAL: - ND_PRINT((ndo, ": Local")); /* XXX */ + ND_PRINT(": Local"); /* XXX */ break; case MEDCLASS_IPV4: if (len != 7) { - ND_PRINT((ndo, " (length bogus, should be = 7)")); + ND_PRINT(" (length bogus, should be = 7)"); return 0; } - ND_TCHECK2(*(p + 3), 4); - ND_PRINT((ndo, ": IPv4 %s", ipaddr_string(ndo, p + 3))); + ND_PRINT(": IPv4 %s", GET_IPADDR_STRING(p + 3)); break; case MEDCLASS_MAC: if (len != 9) { - ND_PRINT((ndo, " (length bogus, should be = 9)")); + ND_PRINT(" (length bogus, should be = 9)"); return 0; } - ND_TCHECK2(*(p + 3), 6); - ND_PRINT((ndo, ": MAC %s", etheraddr_string(ndo, p + 3))); + ND_PRINT(": MAC %s", GET_ETHERADDR_STRING(p + 3)); break; case MEDCLASS_MNB: - ND_PRINT((ndo, ": Magic-Num-Block")); /* XXX */ + ND_PRINT(": Magic-Num-Block"); /* XXX */ break; case MEDCLASS_PSNDN: - ND_PRINT((ndo, ": PSNDN")); /* XXX */ + ND_PRINT(": PSNDN"); /* XXX */ break; default: - ND_PRINT((ndo, ": Unknown class %u", p[2])); + ND_PRINT(": Unknown class %u", GET_U_1(p + 2)); break; } break; @@ -783,17 +779,17 @@ print_lcp_config_options(netdissect_options *ndo, * not going to do so below. */ if (ndo->ndo_vflag < 2) - print_unknown_data(ndo, &p[2], "\n\t ", len - 2); + print_unknown_data(ndo, p + 2, "\n\t ", len - 2); break; } if (ndo->ndo_vflag > 1) - print_unknown_data(ndo, &p[2], "\n\t ", len - 2); /* exclude TLV header */ + print_unknown_data(ndo, p + 2, "\n\t ", len - 2); /* exclude TLV header */ return len; trunc: - ND_PRINT((ndo, "[|lcp]")); + ND_PRINT("[|lcp]"); return 0; } @@ -806,59 +802,56 @@ static const struct tok ppp_ml_flag_values[] = { static void handle_mlppp(netdissect_options *ndo, - const u_char *p, int length) + const u_char *p, u_int length) { if (!ndo->ndo_eflag) - ND_PRINT((ndo, "MLPPP, ")); + ND_PRINT("MLPPP, "); if (length < 2) { - ND_PRINT((ndo, "[|mlppp]")); + ND_PRINT("[|mlppp]"); return; } - if (!ND_TTEST_16BITS(p)) { - ND_PRINT((ndo, "[|mlppp]")); + if (!ND_TTEST_2(p)) { + ND_PRINT("[|mlppp]"); return; } - ND_PRINT((ndo, "seq 0x%03x, Flags [%s], length %u", - (EXTRACT_16BITS(p))&0x0fff, /* only support 12-Bit sequence space for now */ - bittok2str(ppp_ml_flag_values, "none", *p & 0xc0), - length)); + ND_PRINT("seq 0x%03x, Flags [%s], length %u", + (GET_BE_U_2(p))&0x0fff, + /* only support 12-Bit sequence space for now */ + bittok2str(ppp_ml_flag_values, "none", GET_U_1(p) & 0xc0), + length); } /* CHAP */ static void handle_chap(netdissect_options *ndo, - const u_char *p, int length) + const u_char *p, u_int length) { u_int code, len; - int val_size, name_size, msg_size; + u_int val_size, name_size, msg_size; const u_char *p0; - int i; + u_int i; p0 = p; if (length < 1) { - ND_PRINT((ndo, "[|chap]")); + ND_PRINT("[|chap]"); return; } else if (length < 4) { - ND_TCHECK(*p); - ND_PRINT((ndo, "[|chap 0x%02x]", *p)); + ND_PRINT("[|chap 0x%02x]", GET_U_1(p)); return; } - ND_TCHECK(*p); - code = *p; - ND_PRINT((ndo, "CHAP, %s (0x%02x)", + code = GET_U_1(p); + ND_PRINT("CHAP, %s (0x%02x)", tok2str(chapcode_values,"unknown",code), - code)); + code); p++; - ND_TCHECK(*p); - ND_PRINT((ndo, ", id %u", *p)); /* ID */ + ND_PRINT(", id %u", GET_U_1(p)); /* ID */ p++; - ND_TCHECK2(*p, 2); - len = EXTRACT_16BITS(p); + len = GET_BE_U_2(p); p += 2; /* @@ -873,81 +866,72 @@ handle_chap(netdissect_options *ndo, case CHAP_RESP: if (length - (p - p0) < 1) return; - ND_TCHECK(*p); - val_size = *p; /* value size */ + val_size = GET_U_1(p); /* value size */ p++; if (length - (p - p0) < val_size) return; - ND_PRINT((ndo, ", Value ")); + ND_PRINT(", Value "); for (i = 0; i < val_size; i++) { - ND_TCHECK(*p); - ND_PRINT((ndo, "%02x", *p++)); + ND_PRINT("%02x", GET_U_1(p)); + p++; } - name_size = len - (p - p0); - ND_PRINT((ndo, ", Name ")); + name_size = len - (u_int)(p - p0); + ND_PRINT(", Name "); for (i = 0; i < name_size; i++) { - ND_TCHECK(*p); - safeputchar(ndo, *p++); + fn_print_char(ndo, GET_U_1(p)); + p++; } break; case CHAP_SUCC: case CHAP_FAIL: - msg_size = len - (p - p0); - ND_PRINT((ndo, ", Msg ")); + msg_size = len - (u_int)(p - p0); + ND_PRINT(", Msg "); for (i = 0; i< msg_size; i++) { - ND_TCHECK(*p); - safeputchar(ndo, *p++); + fn_print_char(ndo, GET_U_1(p)); + p++; } break; } - return; - -trunc: - ND_PRINT((ndo, "[|chap]")); } /* PAP (see RFC 1334) */ static void handle_pap(netdissect_options *ndo, - const u_char *p, int length) + const u_char *p, u_int length) { u_int code, len; - int peerid_len, passwd_len, msg_len; + u_int peerid_len, passwd_len, msg_len; const u_char *p0; - int i; + u_int i; p0 = p; if (length < 1) { - ND_PRINT((ndo, "[|pap]")); + ND_PRINT("[|pap]"); return; } else if (length < 4) { - ND_TCHECK(*p); - ND_PRINT((ndo, "[|pap 0x%02x]", *p)); + ND_PRINT("[|pap 0x%02x]", GET_U_1(p)); return; } - ND_TCHECK(*p); - code = *p; - ND_PRINT((ndo, "PAP, %s (0x%02x)", + code = GET_U_1(p); + ND_PRINT("PAP, %s (0x%02x)", tok2str(papcode_values, "unknown", code), - code)); + code); p++; - ND_TCHECK(*p); - ND_PRINT((ndo, ", id %u", *p)); /* ID */ + ND_PRINT(", id %u", GET_U_1(p)); /* ID */ p++; - ND_TCHECK2(*p, 2); - len = EXTRACT_16BITS(p); + len = GET_BE_U_2(p); p += 2; - if ((int)len > length) { - ND_PRINT((ndo, ", length %u > packet size", len)); + if (len > length) { + ND_PRINT(", length %u > packet size", len); return; } length = len; - if (length < (p - p0)) { - ND_PRINT((ndo, ", length %u < PAP header length", length)); + if (length < (size_t)(p - p0)) { + ND_PRINT(", length %u < PAP header length", length); return; } @@ -958,28 +942,26 @@ handle_pap(netdissect_options *ndo, goto trunc; if (length - (p - p0) < 1) return; - ND_TCHECK(*p); - peerid_len = *p; /* Peer-ID Length */ + peerid_len = GET_U_1(p); /* Peer-ID Length */ p++; if (length - (p - p0) < peerid_len) return; - ND_PRINT((ndo, ", Peer ")); + ND_PRINT(", Peer "); for (i = 0; i < peerid_len; i++) { - ND_TCHECK(*p); - safeputchar(ndo, *p++); + fn_print_char(ndo, GET_U_1(p)); + p++; } if (length - (p - p0) < 1) return; - ND_TCHECK(*p); - passwd_len = *p; /* Password Length */ + passwd_len = GET_U_1(p); /* Password Length */ p++; if (length - (p - p0) < passwd_len) return; - ND_PRINT((ndo, ", Name ")); + ND_PRINT(", Name "); for (i = 0; i < passwd_len; i++) { - ND_TCHECK(*p); - safeputchar(ndo, *p++); + fn_print_char(ndo, GET_U_1(p)); + p++; } break; case PAP_AACK: @@ -993,83 +975,80 @@ handle_pap(netdissect_options *ndo, goto trunc; if (length - (p - p0) < 1) return; - ND_TCHECK(*p); - msg_len = *p; /* Msg-Length */ + msg_len = GET_U_1(p); /* Msg-Length */ p++; if (length - (p - p0) < msg_len) return; - ND_PRINT((ndo, ", Msg ")); + ND_PRINT(", Msg "); for (i = 0; i< msg_len; i++) { - ND_TCHECK(*p); - safeputchar(ndo, *p++); + fn_print_char(ndo, GET_U_1(p)); + p++; } break; } return; trunc: - ND_PRINT((ndo, "[|pap]")); + ND_PRINT("[|pap]"); } /* BAP */ static void handle_bap(netdissect_options *ndo _U_, - const u_char *p _U_, int length _U_) + const u_char *p _U_, u_int length _U_) { /* XXX: to be supported!! */ } /* IPCP config options */ -static int +static u_int print_ipcp_config_options(netdissect_options *ndo, - const u_char *p, int length) + const u_char *p, u_int length) { - int len, opt; + u_int opt, len; u_int compproto, ipcomp_subopttotallen, ipcomp_subopt, ipcomp_suboptlen; if (length < 2) return 0; - ND_TCHECK2(*p, 2); - len = p[1]; - opt = p[0]; + ND_TCHECK_2(p); + opt = GET_U_1(p); + len = GET_U_1(p + 1); if (length < len) return 0; if (len < 2) { - ND_PRINT((ndo, "\n\t %s Option (0x%02x), length %u (length bogus, should be >= 2)", + ND_PRINT("\n\t %s Option (0x%02x), length %u (length bogus, should be >= 2)", tok2str(ipcpopt_values,"unknown",opt), opt, - len)); + len); return 0; } - ND_PRINT((ndo, "\n\t %s Option (0x%02x), length %u", + ND_PRINT("\n\t %s Option (0x%02x), length %u", tok2str(ipcpopt_values,"unknown",opt), opt, - len)); + len); switch (opt) { case IPCPOPT_2ADDR: /* deprecated */ if (len != 10) { - ND_PRINT((ndo, " (length bogus, should be = 10)")); + ND_PRINT(" (length bogus, should be = 10)"); return len; } - ND_TCHECK2(*(p + 6), 4); - ND_PRINT((ndo, ": src %s, dst %s", - ipaddr_string(ndo, p + 2), - ipaddr_string(ndo, p + 6))); + ND_PRINT(": src %s, dst %s", + GET_IPADDR_STRING(p + 2), + GET_IPADDR_STRING(p + 6)); break; case IPCPOPT_IPCOMP: if (len < 4) { - ND_PRINT((ndo, " (length bogus, should be >= 4)")); + ND_PRINT(" (length bogus, should be >= 4)"); return 0; } - ND_TCHECK_16BITS(p+2); - compproto = EXTRACT_16BITS(p+2); + compproto = GET_BE_U_2(p + 2); - ND_PRINT((ndo, ": %s (0x%02x):", + ND_PRINT(": %s (0x%02x):", tok2str(ipcpopt_compproto_values, "Unknown", compproto), - compproto)); + compproto); switch (compproto) { case PPP_VJC: @@ -1077,31 +1056,31 @@ print_ipcp_config_options(netdissect_options *ndo, break; case IPCPOPT_IPCOMP_HDRCOMP: if (len < IPCPOPT_IPCOMP_MINLEN) { - ND_PRINT((ndo, " (length bogus, should be >= %u)", - IPCPOPT_IPCOMP_MINLEN)); - return 0; + ND_PRINT(" (length bogus, should be >= %u)", + IPCPOPT_IPCOMP_MINLEN); + return 0; } - ND_TCHECK2(*(p + 2), IPCPOPT_IPCOMP_MINLEN); - ND_PRINT((ndo, "\n\t TCP Space %u, non-TCP Space %u" \ + ND_TCHECK_LEN(p + 2, IPCPOPT_IPCOMP_MINLEN); + ND_PRINT("\n\t TCP Space %u, non-TCP Space %u" ", maxPeriod %u, maxTime %u, maxHdr %u", - EXTRACT_16BITS(p+4), - EXTRACT_16BITS(p+6), - EXTRACT_16BITS(p+8), - EXTRACT_16BITS(p+10), - EXTRACT_16BITS(p+12))); + GET_BE_U_2(p + 4), + GET_BE_U_2(p + 6), + GET_BE_U_2(p + 8), + GET_BE_U_2(p + 10), + GET_BE_U_2(p + 12)); /* suboptions present ? */ if (len > IPCPOPT_IPCOMP_MINLEN) { ipcomp_subopttotallen = len - IPCPOPT_IPCOMP_MINLEN; p += IPCPOPT_IPCOMP_MINLEN; - ND_PRINT((ndo, "\n\t Suboptions, length %u", ipcomp_subopttotallen)); + ND_PRINT("\n\t Suboptions, length %u", ipcomp_subopttotallen); while (ipcomp_subopttotallen >= 2) { - ND_TCHECK2(*p, 2); - ipcomp_subopt = *p; - ipcomp_suboptlen = *(p+1); + ND_TCHECK_2(p); + ipcomp_subopt = GET_U_1(p); + ipcomp_suboptlen = GET_U_1(p + 1); /* sanity check */ if (ipcomp_subopt == 0 || @@ -1109,13 +1088,18 @@ print_ipcp_config_options(netdissect_options *ndo, break; /* XXX: just display the suboptions for now */ - ND_PRINT((ndo, "\n\t\t%s Suboption #%u, length %u", + ND_PRINT("\n\t\t%s Suboption #%u, length %u", tok2str(ipcpopt_compproto_subopt_values, "Unknown", ipcomp_subopt), ipcomp_subopt, - ipcomp_suboptlen)); - + ipcomp_suboptlen); + if (ipcomp_subopttotallen < ipcomp_suboptlen) { + ND_PRINT(" [remaining suboptions length %u < %u]", + ipcomp_subopttotallen, ipcomp_suboptlen); + nd_print_invalid(ndo); + break; + } ipcomp_subopttotallen -= ipcomp_suboptlen; p += ipcomp_suboptlen; } @@ -1133,11 +1117,10 @@ print_ipcp_config_options(netdissect_options *ndo, case IPCPOPT_SECDNS: case IPCPOPT_SECNBNS: if (len != 6) { - ND_PRINT((ndo, " (length bogus, should be = 6)")); + ND_PRINT(" (length bogus, should be = 6)"); return 0; } - ND_TCHECK2(*(p + 2), 4); - ND_PRINT((ndo, ": %s", ipaddr_string(ndo, p + 2))); + ND_PRINT(": %s", GET_IPADDR_STRING(p + 2)); break; default: /* @@ -1145,57 +1128,57 @@ print_ipcp_config_options(netdissect_options *ndo, * not going to do so below. */ if (ndo->ndo_vflag < 2) - print_unknown_data(ndo, &p[2], "\n\t ", len - 2); + print_unknown_data(ndo, p + 2, "\n\t ", len - 2); break; } if (ndo->ndo_vflag > 1) - print_unknown_data(ndo, &p[2], "\n\t ", len - 2); /* exclude TLV header */ + print_unknown_data(ndo, p + 2, "\n\t ", len - 2); /* exclude TLV header */ return len; trunc: - ND_PRINT((ndo, "[|ipcp]")); + ND_PRINT("[|ipcp]"); return 0; } /* IP6CP config options */ -static int +static u_int print_ip6cp_config_options(netdissect_options *ndo, - const u_char *p, int length) + const u_char *p, u_int length) { - int len, opt; + u_int opt, len; if (length < 2) return 0; - ND_TCHECK2(*p, 2); - len = p[1]; - opt = p[0]; + ND_TCHECK_2(p); + opt = GET_U_1(p); + len = GET_U_1(p + 1); if (length < len) return 0; if (len < 2) { - ND_PRINT((ndo, "\n\t %s Option (0x%02x), length %u (length bogus, should be >= 2)", + ND_PRINT("\n\t %s Option (0x%02x), length %u (length bogus, should be >= 2)", tok2str(ip6cpopt_values,"unknown",opt), opt, - len)); + len); return 0; } - ND_PRINT((ndo, "\n\t %s Option (0x%02x), length %u", + ND_PRINT("\n\t %s Option (0x%02x), length %u", tok2str(ip6cpopt_values,"unknown",opt), opt, - len)); + len); switch (opt) { case IP6CP_IFID: if (len != 10) { - ND_PRINT((ndo, " (length bogus, should be = 10)")); + ND_PRINT(" (length bogus, should be = 10)"); return len; } - ND_TCHECK2(*(p + 2), 8); - ND_PRINT((ndo, ": %04x:%04x:%04x:%04x", - EXTRACT_16BITS(p + 2), - EXTRACT_16BITS(p + 4), - EXTRACT_16BITS(p + 6), - EXTRACT_16BITS(p + 8))); + ND_TCHECK_8(p + 2); + ND_PRINT(": %04x:%04x:%04x:%04x", + GET_BE_U_2(p + 2), + GET_BE_U_2(p + 4), + GET_BE_U_2(p + 6), + GET_BE_U_2(p + 8)); break; default: /* @@ -1203,78 +1186,79 @@ print_ip6cp_config_options(netdissect_options *ndo, * not going to do so below. */ if (ndo->ndo_vflag < 2) - print_unknown_data(ndo, &p[2], "\n\t ", len - 2); + print_unknown_data(ndo, p + 2, "\n\t ", len - 2); break; } if (ndo->ndo_vflag > 1) - print_unknown_data(ndo, &p[2], "\n\t ", len - 2); /* exclude TLV header */ + print_unknown_data(ndo, p + 2, "\n\t ", len - 2); /* exclude TLV header */ return len; trunc: - ND_PRINT((ndo, "[|ip6cp]")); + ND_PRINT("[|ip6cp]"); return 0; } /* CCP config options */ -static int +static u_int print_ccp_config_options(netdissect_options *ndo, - const u_char *p, int length) + const u_char *p, u_int length) { - int len, opt; + u_int opt, len; if (length < 2) return 0; - ND_TCHECK2(*p, 2); - len = p[1]; - opt = p[0]; + ND_TCHECK_2(p); + opt = GET_U_1(p); + len = GET_U_1(p + 1); if (length < len) return 0; if (len < 2) { - ND_PRINT((ndo, "\n\t %s Option (0x%02x), length %u (length bogus, should be >= 2)", + ND_PRINT("\n\t %s Option (0x%02x), length %u (length bogus, should be >= 2)", tok2str(ccpconfopts_values, "Unknown", opt), opt, - len)); + len); return 0; } - ND_PRINT((ndo, "\n\t %s Option (0x%02x), length %u", + ND_PRINT("\n\t %s Option (0x%02x), length %u", tok2str(ccpconfopts_values, "Unknown", opt), opt, - len)); + len); switch (opt) { case CCPOPT_BSDCOMP: if (len < 3) { - ND_PRINT((ndo, " (length bogus, should be >= 3)")); + ND_PRINT(" (length bogus, should be >= 3)"); return len; } - ND_TCHECK(p[2]); - ND_PRINT((ndo, ": Version: %u, Dictionary Bits: %u", - p[2] >> 5, p[2] & 0x1f)); + ND_PRINT(": Version: %u, Dictionary Bits: %u", + GET_U_1(p + 2) >> 5, + GET_U_1(p + 2) & 0x1f); break; case CCPOPT_MVRCA: if (len < 4) { - ND_PRINT((ndo, " (length bogus, should be >= 4)")); + ND_PRINT(" (length bogus, should be >= 4)"); return len; } - ND_TCHECK(p[3]); - ND_PRINT((ndo, ": Features: %u, PxP: %s, History: %u, #CTX-ID: %u", - (p[2] & 0xc0) >> 6, - (p[2] & 0x20) ? "Enabled" : "Disabled", - p[2] & 0x1f, p[3])); + ND_PRINT(": Features: %u, PxP: %s, History: %u, #CTX-ID: %u", + (GET_U_1(p + 2) & 0xc0) >> 6, + (GET_U_1(p + 2) & 0x20) ? "Enabled" : "Disabled", + GET_U_1(p + 2) & 0x1f, + GET_U_1(p + 3)); break; case CCPOPT_DEFLATE: if (len < 4) { - ND_PRINT((ndo, " (length bogus, should be >= 4)")); + ND_PRINT(" (length bogus, should be >= 4)"); return len; } - ND_TCHECK(p[3]); - ND_PRINT((ndo, ": Window: %uK, Method: %s (0x%x), MBZ: %u, CHK: %u", - (p[2] & 0xf0) >> 4, - ((p[2] & 0x0f) == 8) ? "zlib" : "unknown", - p[2] & 0x0f, (p[3] & 0xfc) >> 2, p[3] & 0x03)); + ND_PRINT(": Window: %uK, Method: %s (0x%x), MBZ: %u, CHK: %u", + (GET_U_1(p + 2) & 0xf0) >> 4, + ((GET_U_1(p + 2) & 0x0f) == 8) ? "zlib" : "unknown", + GET_U_1(p + 2) & 0x0f, + (GET_U_1(p + 3) & 0xfc) >> 2, + GET_U_1(p + 3) & 0x03); break; /* XXX: to be supported */ @@ -1299,54 +1283,53 @@ print_ccp_config_options(netdissect_options *ndo, * not going to do so below. */ if (ndo->ndo_vflag < 2) - print_unknown_data(ndo, &p[2], "\n\t ", len - 2); + print_unknown_data(ndo, p + 2, "\n\t ", len - 2); break; } if (ndo->ndo_vflag > 1) - print_unknown_data(ndo, &p[2], "\n\t ", len - 2); /* exclude TLV header */ + print_unknown_data(ndo, p + 2, "\n\t ", len - 2); /* exclude TLV header */ return len; trunc: - ND_PRINT((ndo, "[|ccp]")); + ND_PRINT("[|ccp]"); return 0; } /* BACP config options */ -static int +static u_int print_bacp_config_options(netdissect_options *ndo, - const u_char *p, int length) + const u_char *p, u_int length) { - int len, opt; + u_int opt, len; if (length < 2) return 0; - ND_TCHECK2(*p, 2); - len = p[1]; - opt = p[0]; + ND_TCHECK_2(p); + opt = GET_U_1(p); + len = GET_U_1(p + 1); if (length < len) return 0; if (len < 2) { - ND_PRINT((ndo, "\n\t %s Option (0x%02x), length %u (length bogus, should be >= 2)", + ND_PRINT("\n\t %s Option (0x%02x), length %u (length bogus, should be >= 2)", tok2str(bacconfopts_values, "Unknown", opt), opt, - len)); + len); return 0; } - ND_PRINT((ndo, "\n\t %s Option (0x%02x), length %u", + ND_PRINT("\n\t %s Option (0x%02x), length %u", tok2str(bacconfopts_values, "Unknown", opt), opt, - len)); + len); switch (opt) { case BACPOPT_FPEER: if (len != 6) { - ND_PRINT((ndo, " (length bogus, should be = 6)")); + ND_PRINT(" (length bogus, should be = 6)"); return len; } - ND_TCHECK_32BITS(p + 2); - ND_PRINT((ndo, ": Magic-Num 0x%08x", EXTRACT_32BITS(p + 2))); + ND_PRINT(": Magic-Num 0x%08x", GET_BE_U_4(p + 2)); break; default: /* @@ -1354,59 +1337,73 @@ print_bacp_config_options(netdissect_options *ndo, * not going to do so below. */ if (ndo->ndo_vflag < 2) - print_unknown_data(ndo, &p[2], "\n\t ", len - 2); + print_unknown_data(ndo, p + 2, "\n\t ", len - 2); break; } if (ndo->ndo_vflag > 1) - print_unknown_data(ndo, &p[2], "\n\t ", len - 2); /* exclude TLV header */ + print_unknown_data(ndo, p + 2, "\n\t ", len - 2); /* exclude TLV header */ return len; trunc: - ND_PRINT((ndo, "[|bacp]")); + ND_PRINT("[|bacp]"); return 0; } +/* + * Un-escape RFC 1662 PPP in HDLC-like framing, with octet escapes. + * The length argument is the on-the-wire length, not the captured + * length; we can only un-escape the captured part. + */ static void ppp_hdlc(netdissect_options *ndo, - const u_char *p, int length) + const u_char *p, u_int length) { + u_int caplen = ND_BYTES_AVAILABLE_AFTER(p); u_char *b, *t, c; const u_char *s; - int i, proto; + u_int i, proto; const void *se; - if (length <= 0) + if (caplen == 0) + return; + + if (length == 0) return; - b = (u_char *)malloc(length); + b = (u_char *)nd_malloc(ndo, caplen); if (b == NULL) return; /* * Unescape all the data into a temporary, private, buffer. - * Do this so that we dont overwrite the original packet + * Do this so that we don't overwrite the original packet * contents. */ - for (s = p, t = b, i = length; i > 0 && ND_TTEST(*s); i--) { - c = *s++; + for (s = p, t = b, i = caplen; i != 0; i--) { + c = GET_U_1(s); + s++; if (c == 0x7d) { - if (i <= 1 || !ND_TTEST(*s)) + if (i <= 1) break; i--; - c = *s++ ^ 0x20; + c = GET_U_1(s) ^ 0x20; + s++; } *t++ = c; } + /* + * Change the end pointer, so bounds checks work. + */ se = ndo->ndo_snapend; ndo->ndo_snapend = t; - length = t - b; + length = ND_BYTES_AVAILABLE_AFTER(b); /* now lets guess about the payload codepoint format */ if (length < 1) goto trunc; - proto = *b; /* start with a one-octet codepoint guess */ + proto = GET_U_1(b); /* start with a one-octet codepoint guess */ switch (proto) { case PPP_IP: @@ -1421,13 +1418,13 @@ ppp_hdlc(netdissect_options *ndo, if (length < 2) goto trunc; - proto = EXTRACT_16BITS(b); /* next guess - load two octets */ + proto = GET_BE_U_2(b); /* next guess - load two octets */ switch (proto) { case (PPP_ADDRESS << 8 | PPP_CONTROL): /* looks like a PPP frame */ if (length < 4) goto trunc; - proto = EXTRACT_16BITS(b+2); /* load the PPP proto-id */ + proto = GET_BE_U_2(b + 2); /* load the PPP proto-id */ handle_ppp(ndo, proto, b + 4, length - 4); break; default: /* last guess - proto must be a PPP proto-id */ @@ -1437,20 +1434,18 @@ ppp_hdlc(netdissect_options *ndo, cleanup: ndo->ndo_snapend = se; - free(b); return; trunc: ndo->ndo_snapend = se; - free(b); - ND_PRINT((ndo, "[|ppp]")); + nd_print_trunc(ndo); } /* PPP */ static void handle_ppp(netdissect_options *ndo, - u_int proto, const u_char *p, int length) + u_int proto, const u_char *p, u_int length) { if ((proto & 0xff00) == 0x7e00) { /* is this an escape code ? */ ppp_hdlc(ndo, p - 1, length); @@ -1500,10 +1495,10 @@ handle_ppp(netdissect_options *ndo, mpls_print(ndo, p, length); break; case PPP_COMP: - ND_PRINT((ndo, "compressed PPP data")); + ND_PRINT("compressed PPP data"); break; default: - ND_PRINT((ndo, "%s ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", proto))); + ND_PRINT("%s ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", proto)); print_unknown_data(ndo, p, "\n\t", length); break; } @@ -1512,30 +1507,30 @@ handle_ppp(netdissect_options *ndo, /* Standard PPP printer */ u_int ppp_print(netdissect_options *ndo, - register const u_char *p, u_int length) + const u_char *p, u_int length) { u_int proto,ppp_header; u_int olen = length; /* _o_riginal length */ u_int hdr_len = 0; + ndo->ndo_protocol = "ppp"; /* * Here, we assume that p points to the Address and Control * field (if they present). */ if (length < 2) goto trunc; - ND_TCHECK2(*p, 2); - ppp_header = EXTRACT_16BITS(p); + ppp_header = GET_BE_U_2(p); switch(ppp_header) { - case (PPP_WITHDIRECTION_IN << 8 | PPP_CONTROL): - if (ndo->ndo_eflag) ND_PRINT((ndo, "In ")); + case (PPP_PPPD_IN << 8 | PPP_CONTROL): + if (ndo->ndo_eflag) ND_PRINT("In "); p += 2; length -= 2; hdr_len += 2; break; - case (PPP_WITHDIRECTION_OUT << 8 | PPP_CONTROL): - if (ndo->ndo_eflag) ND_PRINT((ndo, "Out ")); + case (PPP_PPPD_OUT << 8 | PPP_CONTROL): + if (ndo->ndo_eflag) ND_PRINT("Out "); p += 2; length -= 2; hdr_len += 2; @@ -1552,46 +1547,47 @@ ppp_print(netdissect_options *ndo, if (length < 2) goto trunc; - ND_TCHECK(*p); - if (*p % 2) { - proto = *p; /* PFC is used */ + if (GET_U_1(p) % 2) { + proto = GET_U_1(p); /* PFC is used */ p++; length--; hdr_len++; } else { - ND_TCHECK2(*p, 2); - proto = EXTRACT_16BITS(p); + proto = GET_BE_U_2(p); p += 2; length -= 2; hdr_len += 2; } if (ndo->ndo_eflag) - ND_PRINT((ndo, "%s (0x%04x), length %u: ", + ND_PRINT("%s (0x%04x), length %u: ", tok2str(ppptype2str, "unknown", proto), proto, - olen)); + olen); handle_ppp(ndo, proto, p, length); return (hdr_len); trunc: - ND_PRINT((ndo, "[|ppp]")); + nd_print_trunc(ndo); return (0); } /* PPP I/F printer */ -u_int +void ppp_if_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, register const u_char *p) + const struct pcap_pkthdr *h, const u_char *p) { - register u_int length = h->len; - register u_int caplen = h->caplen; + u_int length = h->len; + u_int caplen = h->caplen; + ndo->ndo_protocol = "ppp"; if (caplen < PPP_HDRLEN) { - ND_PRINT((ndo, "[|ppp]")); - return (caplen); + nd_print_trunc(ndo); + ndo->ndo_ll_hdr_len += caplen; + return; } + ndo->ndo_ll_hdr_len += PPP_HDRLEN; #if 0 /* @@ -1631,12 +1627,11 @@ ppp_if_print(netdissect_options *ndo, * BSD/OS, is?) */ if (ndo->ndo_eflag) - ND_PRINT((ndo, "%c %4d %02x ", p[0] ? 'O' : 'I', length, p[1])); + ND_PRINT("%c %4d %02x ", GET_U_1(p) ? 'O' : 'I', + length, GET_U_1(p + 1)); #endif ppp_print(ndo, p, length); - - return (0); } /* @@ -1648,55 +1643,62 @@ ppp_if_print(netdissect_options *ndo, * * This handles, for example, DLT_PPP_SERIAL in NetBSD. */ -u_int +void ppp_hdlc_if_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, register const u_char *p) + const struct pcap_pkthdr *h, const u_char *p) { - register u_int length = h->len; - register u_int caplen = h->caplen; + u_int length = h->len; + u_int caplen = h->caplen; u_int proto; u_int hdrlen = 0; + ndo->ndo_protocol = "ppp_hdlc"; if (caplen < 2) { - ND_PRINT((ndo, "[|ppp]")); - return (caplen); + nd_print_trunc(ndo); + ndo->ndo_ll_hdr_len += caplen; + return; } - switch (p[0]) { + switch (GET_U_1(p)) { case PPP_ADDRESS: if (caplen < 4) { - ND_PRINT((ndo, "[|ppp]")); - return (caplen); + nd_print_trunc(ndo); + ndo->ndo_ll_hdr_len += caplen; + return; } if (ndo->ndo_eflag) - ND_PRINT((ndo, "%02x %02x %d ", p[0], p[1], length)); + ND_PRINT("%02x %02x %u ", GET_U_1(p), + GET_U_1(p + 1), length); p += 2; length -= 2; hdrlen += 2; - proto = EXTRACT_16BITS(p); + proto = GET_BE_U_2(p); p += 2; length -= 2; hdrlen += 2; - ND_PRINT((ndo, "%s: ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", proto))); + ND_PRINT("%s: ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", proto)); handle_ppp(ndo, proto, p, length); break; case CHDLC_UNICAST: case CHDLC_BCAST: - return (chdlc_if_print(ndo, h, p)); + chdlc_if_print(ndo, h, p); + return; default: if (caplen < 4) { - ND_PRINT((ndo, "[|ppp]")); - return (caplen); + nd_print_trunc(ndo); + ndo->ndo_ll_hdr_len += caplen; + return; } if (ndo->ndo_eflag) - ND_PRINT((ndo, "%02x %02x %d ", p[0], p[1], length)); + ND_PRINT("%02x %02x %u ", GET_U_1(p), + GET_U_1(p + 1), length); p += 2; hdrlen += 2; @@ -1705,66 +1707,73 @@ ppp_hdlc_if_print(netdissect_options *ndo, * the next two octets as an Ethernet type; does that * ever happen? */ - ND_PRINT((ndo, "unknown addr %02x; ctrl %02x", p[0], p[1])); + ND_PRINT("unknown addr %02x; ctrl %02x", GET_U_1(p), + GET_U_1(p + 1)); break; } - return (hdrlen); + ndo->ndo_ll_hdr_len += hdrlen; } #define PPP_BSDI_HDRLEN 24 /* BSD/OS specific PPP printer */ -u_int -ppp_bsdos_if_print(netdissect_options *ndo _U_, - const struct pcap_pkthdr *h _U_, register const u_char *p _U_) +void +ppp_bsdos_if_print(netdissect_options *ndo, + const struct pcap_pkthdr *h _U_, const u_char *p _U_) { - register int hdrlength; + u_int hdrlength; #ifdef __bsdi__ - register u_int length = h->len; - register u_int caplen = h->caplen; + u_int length = h->len; + u_int caplen = h->caplen; uint16_t ptype; + uint8_t llhl; const u_char *q; - int i; + u_int i; + ndo->ndo_protocol = "ppp_bsdos"; if (caplen < PPP_BSDI_HDRLEN) { - ND_PRINT((ndo, "[|ppp]")); - return (caplen) + nd_print_trunc(ndo); + ndo->ndo_ll_hdr_len += caplen; + return; } hdrlength = 0; #if 0 - if (p[0] == PPP_ADDRESS && p[1] == PPP_CONTROL) { + if (GET_U_1(p) == PPP_ADDRESS && + GET_U_1(p + 1) == PPP_CONTROL) { if (ndo->ndo_eflag) - ND_PRINT((ndo, "%02x %02x ", p[0], p[1])); + ND_PRINT("%02x %02x ", GET_U_1(p), + GET_U_1(p + 1)); p += 2; hdrlength = 2; } if (ndo->ndo_eflag) - ND_PRINT((ndo, "%d ", length)); + ND_PRINT("%u ", length); /* Retrieve the protocol type */ - if (*p & 01) { + if (GET_U_1(p) & 01) { /* Compressed protocol field */ - ptype = *p; + ptype = GET_U_1(p); if (ndo->ndo_eflag) - ND_PRINT((ndo, "%02x ", ptype)); + ND_PRINT("%02x ", ptype); p++; hdrlength += 1; } else { /* Un-compressed protocol field */ - ptype = EXTRACT_16BITS(p); + ptype = GET_BE_U_2(p); if (ndo->ndo_eflag) - ND_PRINT((ndo, "%04x ", ptype)); + ND_PRINT("%04x ", ptype); p += 2; hdrlength += 2; } #else ptype = 0; /*XXX*/ if (ndo->ndo_eflag) - ND_PRINT((ndo, "%c ", p[SLC_DIR] ? 'O' : 'I')); - if (p[SLC_LLHL]) { + ND_PRINT("%c ", GET_U_1(p + SLC_DIR) ? 'O' : 'I'); + llhl = GET_U_1(p + SLC_LLHL); + if (llhl) { /* link level header */ struct ppp_header *ph; @@ -1773,25 +1782,26 @@ ppp_bsdos_if_print(netdissect_options *ndo _U_, if (ph->phdr_addr == PPP_ADDRESS && ph->phdr_ctl == PPP_CONTROL) { if (ndo->ndo_eflag) - ND_PRINT((ndo, "%02x %02x ", q[0], q[1])); - ptype = EXTRACT_16BITS(&ph->phdr_type); + ND_PRINT("%02x %02x ", GET_U_1(q), + GET_U_1(q + 1)); + ptype = GET_BE_U_2(&ph->phdr_type); if (ndo->ndo_eflag && (ptype == PPP_VJC || ptype == PPP_VJNC)) { - ND_PRINT((ndo, "%s ", tok2str(ppptype2str, - "proto-#%d", ptype))); + ND_PRINT("%s ", tok2str(ppptype2str, + "proto-#%u", ptype)); } } else { if (ndo->ndo_eflag) { - ND_PRINT((ndo, "LLH=[")); - for (i = 0; i < p[SLC_LLHL]; i++) - ND_PRINT((ndo, "%02x", q[i])); - ND_PRINT((ndo, "] ")); + ND_PRINT("LLH=["); + for (i = 0; i < llhl; i++) + ND_PRINT("%02x", GET_U_1(q + i)); + ND_PRINT("] "); } } } if (ndo->ndo_eflag) - ND_PRINT((ndo, "%d ", length)); - if (p[SLC_CHL]) { - q = p + SLC_BPFHDRLEN + p[SLC_LLHL]; + ND_PRINT("%u ", length); + if (GET_U_1(p + SLC_CHL)) { + q = p + SLC_BPFHDRLEN + llhl; switch (ptype) { case PPP_VJC: @@ -1830,10 +1840,11 @@ ppp_bsdos_if_print(netdissect_options *ndo _U_, goto printx; default: if (ndo->ndo_eflag) { - ND_PRINT((ndo, "CH=[")); - for (i = 0; i < p[SLC_LLHL]; i++) - ND_PRINT((ndo, "%02x", q[i])); - ND_PRINT((ndo, "] ")); + ND_PRINT("CH=["); + for (i = 0; i < llhl; i++) + ND_PRINT("%02x", + GET_U_1(q + i)); + ND_PRINT("] "); } break; } @@ -1857,20 +1868,12 @@ ppp_bsdos_if_print(netdissect_options *ndo _U_, mpls_print(ndo, p, length); break; default: - ND_PRINT((ndo, "%s ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", ptype))); + ND_PRINT("%s ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", ptype)); } printx: #else /* __bsdi */ hdrlength = 0; #endif /* __bsdi__ */ - return (hdrlength); + ndo->ndo_ll_hdr_len += hdrlength; } - - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/print-pppoe.c b/contrib/tcpdump/print-pppoe.c index 23d9a238e0..65518dff16 100644 --- a/contrib/tcpdump/print-pppoe.c +++ b/contrib/tcpdump/print-pppoe.c @@ -24,11 +24,14 @@ /* \summary: PPP-over-Ethernet (PPPoE) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#include "netdissect-ctype.h" + +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" @@ -84,50 +87,52 @@ static const struct tok pppoetag2str[] = { #define PPPOE_HDRLEN 6 #define MAXTAGPRINT 80 -u_int -pppoe_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, register const u_char *p) +void +pppoe_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { - return (pppoe_print(ndo, p, h->len)); + ndo->ndo_protocol = "pppoe"; + ndo->ndo_ll_hdr_len += pppoe_print(ndo, p, h->len); } u_int -pppoe_print(netdissect_options *ndo, register const u_char *bp, u_int length) +pppoe_print(netdissect_options *ndo, const u_char *bp, u_int length) { uint16_t pppoe_ver, pppoe_type, pppoe_code, pppoe_sessionid; u_int pppoe_length; const u_char *pppoe_packet, *pppoe_payload; + ndo->ndo_protocol = "pppoe"; if (length < PPPOE_HDRLEN) { - ND_PRINT((ndo, "truncated-pppoe %u", length)); - return (length); + ND_PRINT(" (length %u < %u)", length, PPPOE_HDRLEN); + goto invalid; } length -= PPPOE_HDRLEN; pppoe_packet = bp; - ND_TCHECK2(*pppoe_packet, PPPOE_HDRLEN); - pppoe_ver = (pppoe_packet[0] & 0xF0) >> 4; - pppoe_type = (pppoe_packet[0] & 0x0F); - pppoe_code = pppoe_packet[1]; - pppoe_sessionid = EXTRACT_16BITS(pppoe_packet + 2); - pppoe_length = EXTRACT_16BITS(pppoe_packet + 4); + ND_TCHECK_LEN(pppoe_packet, PPPOE_HDRLEN); + pppoe_ver = (GET_U_1(pppoe_packet) & 0xF0) >> 4; + pppoe_type = (GET_U_1(pppoe_packet) & 0x0F); + pppoe_code = GET_U_1(pppoe_packet + 1); + pppoe_sessionid = GET_BE_U_2(pppoe_packet + 2); + pppoe_length = GET_BE_U_2(pppoe_packet + 4); pppoe_payload = pppoe_packet + PPPOE_HDRLEN; if (pppoe_ver != 1) { - ND_PRINT((ndo, " [ver %d]",pppoe_ver)); + ND_PRINT(" [ver %u]",pppoe_ver); } if (pppoe_type != 1) { - ND_PRINT((ndo, " [type %d]",pppoe_type)); + ND_PRINT(" [type %u]",pppoe_type); } - ND_PRINT((ndo, "PPPoE %s", tok2str(pppoecode2str, "PAD-%x", pppoe_code))); + ND_PRINT("PPPoE %s", tok2str(pppoecode2str, "PAD-%x", pppoe_code)); if (pppoe_code == PPPOE_PADI && pppoe_length > 1484 - PPPOE_HDRLEN) { - ND_PRINT((ndo, " [len %u!]",pppoe_length)); + ND_PRINT(" [len %u!]",pppoe_length); } if (pppoe_length > length) { - ND_PRINT((ndo, " [len %u > %u!]", pppoe_length, length)); + ND_PRINT(" [len %u > %u!]", pppoe_length, length); pppoe_length = length; } if (pppoe_sessionid) { - ND_PRINT((ndo, " [ses 0x%x]", pppoe_sessionid)); + ND_PRINT(" [ses 0x%x]", pppoe_sessionid); } if (pppoe_code) { @@ -141,9 +146,8 @@ pppoe_print(netdissect_options *ndo, register const u_char *bp, u_int length) * tag_type is previous tag or 0xffff for first iteration */ while (tag_type && p < pppoe_payload + pppoe_length) { - ND_TCHECK2(*p, 4); - tag_type = EXTRACT_16BITS(p); - tag_len = EXTRACT_16BITS(p + 2); + tag_type = GET_BE_U_2(p); + tag_len = GET_BE_U_2(p + 2); p += 4; /* p points to tag_value */ @@ -154,10 +158,10 @@ pppoe_print(netdissect_options *ndo, register const u_char *bp, u_int length) unsigned tag_str_len = 0; /* TODO print UTF-8 decoded text */ - ND_TCHECK2(*p, tag_len); + ND_TCHECK_LEN(p, tag_len); for (v = p; v < p + tag_len && tag_str_len < MAXTAGPRINT-1; v++) - if (*v >= 32 && *v < 127) { - tag_str[tag_str_len++] = *v; + if (ND_ASCII_ISPRINT(GET_U_1(v))) { + tag_str[tag_str_len++] = GET_U_1(v); ascii_count++; } else { tag_str[tag_str_len++] = '.'; @@ -166,36 +170,37 @@ pppoe_print(netdissect_options *ndo, register const u_char *bp, u_int length) tag_str[tag_str_len] = 0; if (ascii_count > garbage_count) { - ND_PRINT((ndo, " [%s \"%*.*s\"]", + ND_PRINT(" [%s \"%*.*s\"]", tok2str(pppoetag2str, "TAG-0x%x", tag_type), (int)tag_str_len, (int)tag_str_len, - tag_str)); + tag_str); } else { /* Print hex, not fast to abuse printf but this doesn't get used much */ - ND_PRINT((ndo, " [%s 0x", tok2str(pppoetag2str, "TAG-0x%x", tag_type))); + ND_PRINT(" [%s 0x", tok2str(pppoetag2str, "TAG-0x%x", tag_type)); for (v=p; v #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "extract.h" -static const char tstr[] = " [|pptp]"; #define PPTP_MSG_TYPE_CTRL 1 /* Control Message */ #define PPTP_MSG_TYPE_MGMT 2 /* Management Message (currently not used */ @@ -85,153 +86,153 @@ static const char *pptp_message_type_string[] = { /* common for all PPTP control messages */ struct pptp_hdr { - uint16_t length; - uint16_t msg_type; - uint32_t magic_cookie; - uint16_t ctrl_msg_type; - uint16_t reserved0; + nd_uint16_t length; + nd_uint16_t msg_type; + nd_uint32_t magic_cookie; + nd_uint16_t ctrl_msg_type; + nd_uint16_t reserved0; }; struct pptp_msg_sccrq { - uint16_t proto_ver; - uint16_t reserved1; - uint32_t framing_cap; - uint32_t bearer_cap; - uint16_t max_channel; - uint16_t firm_rev; - u_char hostname[64]; - u_char vendor[64]; + nd_uint16_t proto_ver; + nd_uint16_t reserved1; + nd_uint32_t framing_cap; + nd_uint32_t bearer_cap; + nd_uint16_t max_channel; + nd_uint16_t firm_rev; + nd_byte hostname[64]; + nd_byte vendor[64]; }; struct pptp_msg_sccrp { - uint16_t proto_ver; - uint8_t result_code; - uint8_t err_code; - uint32_t framing_cap; - uint32_t bearer_cap; - uint16_t max_channel; - uint16_t firm_rev; - u_char hostname[64]; - u_char vendor[64]; + nd_uint16_t proto_ver; + nd_uint8_t result_code; + nd_uint8_t err_code; + nd_uint32_t framing_cap; + nd_uint32_t bearer_cap; + nd_uint16_t max_channel; + nd_uint16_t firm_rev; + nd_byte hostname[64]; + nd_byte vendor[64]; }; struct pptp_msg_stopccrq { - uint8_t reason; - uint8_t reserved1; - uint16_t reserved2; + nd_uint8_t reason; + nd_uint8_t reserved1; + nd_uint16_t reserved2; }; struct pptp_msg_stopccrp { - uint8_t result_code; - uint8_t err_code; - uint16_t reserved1; + nd_uint8_t result_code; + nd_uint8_t err_code; + nd_uint16_t reserved1; }; struct pptp_msg_echorq { - uint32_t id; + nd_uint32_t id; }; struct pptp_msg_echorp { - uint32_t id; - uint8_t result_code; - uint8_t err_code; - uint16_t reserved1; + nd_uint32_t id; + nd_uint8_t result_code; + nd_uint8_t err_code; + nd_uint16_t reserved1; }; struct pptp_msg_ocrq { - uint16_t call_id; - uint16_t call_ser; - uint32_t min_bps; - uint32_t max_bps; - uint32_t bearer_type; - uint32_t framing_type; - uint16_t recv_winsiz; - uint16_t pkt_proc_delay; - uint16_t phone_no_len; - uint16_t reserved1; - u_char phone_no[64]; - u_char subaddr[64]; + nd_uint16_t call_id; + nd_uint16_t call_ser; + nd_uint32_t min_bps; + nd_uint32_t max_bps; + nd_uint32_t bearer_type; + nd_uint32_t framing_type; + nd_uint16_t recv_winsiz; + nd_uint16_t pkt_proc_delay; + nd_uint16_t phone_no_len; + nd_uint16_t reserved1; + nd_byte phone_no[64]; + nd_byte subaddr[64]; }; struct pptp_msg_ocrp { - uint16_t call_id; - uint16_t peer_call_id; - uint8_t result_code; - uint8_t err_code; - uint16_t cause_code; - uint32_t conn_speed; - uint16_t recv_winsiz; - uint16_t pkt_proc_delay; - uint32_t phy_chan_id; + nd_uint16_t call_id; + nd_uint16_t peer_call_id; + nd_uint8_t result_code; + nd_uint8_t err_code; + nd_uint16_t cause_code; + nd_uint32_t conn_speed; + nd_uint16_t recv_winsiz; + nd_uint16_t pkt_proc_delay; + nd_uint32_t phy_chan_id; }; struct pptp_msg_icrq { - uint16_t call_id; - uint16_t call_ser; - uint32_t bearer_type; - uint32_t phy_chan_id; - uint16_t dialed_no_len; - uint16_t dialing_no_len; - u_char dialed_no[64]; /* DNIS */ - u_char dialing_no[64]; /* CLID */ - u_char subaddr[64]; + nd_uint16_t call_id; + nd_uint16_t call_ser; + nd_uint32_t bearer_type; + nd_uint32_t phy_chan_id; + nd_uint16_t dialed_no_len; + nd_uint16_t dialing_no_len; + nd_byte dialed_no[64]; /* DNIS */ + nd_byte dialing_no[64]; /* CLID */ + nd_byte subaddr[64]; }; struct pptp_msg_icrp { - uint16_t call_id; - uint16_t peer_call_id; - uint8_t result_code; - uint8_t err_code; - uint16_t recv_winsiz; - uint16_t pkt_proc_delay; - uint16_t reserved1; + nd_uint16_t call_id; + nd_uint16_t peer_call_id; + nd_uint8_t result_code; + nd_uint8_t err_code; + nd_uint16_t recv_winsiz; + nd_uint16_t pkt_proc_delay; + nd_uint16_t reserved1; }; struct pptp_msg_iccn { - uint16_t peer_call_id; - uint16_t reserved1; - uint32_t conn_speed; - uint16_t recv_winsiz; - uint16_t pkt_proc_delay; - uint32_t framing_type; + nd_uint16_t peer_call_id; + nd_uint16_t reserved1; + nd_uint32_t conn_speed; + nd_uint16_t recv_winsiz; + nd_uint16_t pkt_proc_delay; + nd_uint32_t framing_type; }; struct pptp_msg_ccrq { - uint16_t call_id; - uint16_t reserved1; + nd_uint16_t call_id; + nd_uint16_t reserved1; }; struct pptp_msg_cdn { - uint16_t call_id; - uint8_t result_code; - uint8_t err_code; - uint16_t cause_code; - uint16_t reserved1; - u_char call_stats[128]; + nd_uint16_t call_id; + nd_uint8_t result_code; + nd_uint8_t err_code; + nd_uint16_t cause_code; + nd_uint16_t reserved1; + nd_byte call_stats[128]; }; struct pptp_msg_wen { - uint16_t peer_call_id; - uint16_t reserved1; - uint32_t crc_err; - uint32_t framing_err; - uint32_t hardware_overrun; - uint32_t buffer_overrun; - uint32_t timeout_err; - uint32_t align_err; + nd_uint16_t peer_call_id; + nd_uint16_t reserved1; + nd_uint32_t crc_err; + nd_uint32_t framing_err; + nd_uint32_t hardware_overrun; + nd_uint32_t buffer_overrun; + nd_uint32_t timeout_err; + nd_uint32_t align_err; }; struct pptp_msg_sli { - uint16_t peer_call_id; - uint16_t reserved1; - uint32_t send_accm; - uint32_t recv_accm; + nd_uint16_t peer_call_id; + nd_uint16_t reserved1; + nd_uint32_t send_accm; + nd_uint32_t recv_accm; }; /* attributes that appear more than once in above messages: Number of - occurence attributes + occurrence attributes -------------------------------------- 2 uint32_t bearer_cap; 2 uint32_t bearer_type; @@ -261,21 +262,27 @@ struct pptp_msg_sli { reserved*). */ +#define PRINT_RESERVED_IF_NOT_ZERO_1(reserved) \ + if (GET_U_1(reserved)) \ + ND_PRINT(" [ERROR: reserved=%u must be zero]", \ + GET_U_1(reserved)); + +#define PRINT_RESERVED_IF_NOT_ZERO_2(reserved) \ + if (GET_BE_U_2(reserved)) \ + ND_PRINT(" [ERROR: reserved=%u must be zero]", \ + GET_BE_U_2(reserved)); + /******************************************/ /* Attribute-specific print out functions */ /******************************************/ -/* In these attribute-specific print-out functions, it't not necessary - to do ND_TCHECK because they are already checked in the caller of - these functions. */ - static void pptp_bearer_cap_print(netdissect_options *ndo, - const uint32_t *bearer_cap) + const nd_uint32_t bearer_cap) { - ND_PRINT((ndo, " BEARER_CAP(%s%s)", - EXTRACT_32BITS(bearer_cap) & PPTP_BEARER_CAP_DIGITAL_MASK ? "D" : "", - EXTRACT_32BITS(bearer_cap) & PPTP_BEARER_CAP_ANALOG_MASK ? "A" : "")); + ND_PRINT(" BEARER_CAP(%s%s)", + GET_BE_U_4(bearer_cap) & PPTP_BEARER_CAP_DIGITAL_MASK ? "D" : "", + GET_BE_U_4(bearer_cap) & PPTP_BEARER_CAP_ANALOG_MASK ? "A" : ""); } static const struct tok pptp_btype_str[] = { @@ -287,38 +294,38 @@ static const struct tok pptp_btype_str[] = { static void pptp_bearer_type_print(netdissect_options *ndo, - const uint32_t *bearer_type) + const nd_uint32_t bearer_type) { - ND_PRINT((ndo, " BEARER_TYPE(%s)", - tok2str(pptp_btype_str, "?", EXTRACT_32BITS(bearer_type)))); + ND_PRINT(" BEARER_TYPE(%s)", + tok2str(pptp_btype_str, "?", GET_BE_U_4(bearer_type))); } static void pptp_call_id_print(netdissect_options *ndo, - const uint16_t *call_id) + const nd_uint16_t call_id) { - ND_PRINT((ndo, " CALL_ID(%u)", EXTRACT_16BITS(call_id))); + ND_PRINT(" CALL_ID(%u)", GET_BE_U_2(call_id)); } static void pptp_call_ser_print(netdissect_options *ndo, - const uint16_t *call_ser) + const nd_uint16_t call_ser) { - ND_PRINT((ndo, " CALL_SER_NUM(%u)", EXTRACT_16BITS(call_ser))); + ND_PRINT(" CALL_SER_NUM(%u)", GET_BE_U_2(call_ser)); } static void pptp_cause_code_print(netdissect_options *ndo, - const uint16_t *cause_code) + const nd_uint16_t cause_code) { - ND_PRINT((ndo, " CAUSE_CODE(%u)", EXTRACT_16BITS(cause_code))); + ND_PRINT(" CAUSE_CODE(%u)", GET_BE_U_2(cause_code)); } static void pptp_conn_speed_print(netdissect_options *ndo, - const uint32_t *conn_speed) + const nd_uint32_t conn_speed) { - ND_PRINT((ndo, " CONN_SPEED(%u)", EXTRACT_32BITS(conn_speed))); + ND_PRINT(" CONN_SPEED(%u)", GET_BE_U_4(conn_speed)); } static const struct tok pptp_errcode_str[] = { @@ -334,34 +341,35 @@ static const struct tok pptp_errcode_str[] = { static void pptp_err_code_print(netdissect_options *ndo, - const uint8_t *err_code) + const nd_uint8_t err_code) { - ND_PRINT((ndo, " ERR_CODE(%u", *err_code)); + ND_PRINT(" ERR_CODE(%u", GET_U_1(err_code)); if (ndo->ndo_vflag) { - ND_PRINT((ndo, ":%s", tok2str(pptp_errcode_str, "?", *err_code))); + ND_PRINT(":%s", + tok2str(pptp_errcode_str, "?", GET_U_1(err_code))); } - ND_PRINT((ndo, ")")); + ND_PRINT(")"); } static void pptp_firm_rev_print(netdissect_options *ndo, - const uint16_t *firm_rev) + const nd_uint16_t firm_rev) { - ND_PRINT((ndo, " FIRM_REV(%u)", EXTRACT_16BITS(firm_rev))); + ND_PRINT(" FIRM_REV(%u)", GET_BE_U_2(firm_rev)); } static void pptp_framing_cap_print(netdissect_options *ndo, - const uint32_t *framing_cap) + const nd_uint32_t framing_cap) { - ND_PRINT((ndo, " FRAME_CAP(")); - if (EXTRACT_32BITS(framing_cap) & PPTP_FRAMING_CAP_ASYNC_MASK) { - ND_PRINT((ndo, "A")); /* Async */ + ND_PRINT(" FRAME_CAP("); + if (GET_BE_U_4(framing_cap) & PPTP_FRAMING_CAP_ASYNC_MASK) { + ND_PRINT("A"); /* Async */ } - if (EXTRACT_32BITS(framing_cap) & PPTP_FRAMING_CAP_SYNC_MASK) { - ND_PRINT((ndo, "S")); /* Sync */ + if (GET_BE_U_4(framing_cap) & PPTP_FRAMING_CAP_SYNC_MASK) { + ND_PRINT("S"); /* Sync */ } - ND_PRINT((ndo, ")")); + ND_PRINT(")"); } static const struct tok pptp_ftype_str[] = { @@ -373,68 +381,70 @@ static const struct tok pptp_ftype_str[] = { static void pptp_framing_type_print(netdissect_options *ndo, - const uint32_t *framing_type) + const nd_uint32_t framing_type) { - ND_PRINT((ndo, " FRAME_TYPE(%s)", - tok2str(pptp_ftype_str, "?", EXTRACT_32BITS(framing_type)))); + ND_PRINT(" FRAME_TYPE(%s)", + tok2str(pptp_ftype_str, "?", GET_BE_U_4(framing_type))); } static void pptp_hostname_print(netdissect_options *ndo, const u_char *hostname) { - ND_PRINT((ndo, " HOSTNAME(%.64s)", hostname)); + ND_PRINT(" HOSTNAME("); + nd_printjnp(ndo, hostname, 64); + ND_PRINT(")"); } static void pptp_id_print(netdissect_options *ndo, - const uint32_t *id) + const nd_uint32_t id) { - ND_PRINT((ndo, " ID(%u)", EXTRACT_32BITS(id))); + ND_PRINT(" ID(%u)", GET_BE_U_4(id)); } static void pptp_max_channel_print(netdissect_options *ndo, - const uint16_t *max_channel) + const nd_uint16_t max_channel) { - ND_PRINT((ndo, " MAX_CHAN(%u)", EXTRACT_16BITS(max_channel))); + ND_PRINT(" MAX_CHAN(%u)", GET_BE_U_2(max_channel)); } static void pptp_peer_call_id_print(netdissect_options *ndo, - const uint16_t *peer_call_id) + const nd_uint16_t peer_call_id) { - ND_PRINT((ndo, " PEER_CALL_ID(%u)", EXTRACT_16BITS(peer_call_id))); + ND_PRINT(" PEER_CALL_ID(%u)", GET_BE_U_2(peer_call_id)); } static void pptp_phy_chan_id_print(netdissect_options *ndo, - const uint32_t *phy_chan_id) + const nd_uint32_t phy_chan_id) { - ND_PRINT((ndo, " PHY_CHAN_ID(%u)", EXTRACT_32BITS(phy_chan_id))); + ND_PRINT(" PHY_CHAN_ID(%u)", GET_BE_U_4(phy_chan_id)); } static void pptp_pkt_proc_delay_print(netdissect_options *ndo, - const uint16_t *pkt_proc_delay) + const nd_uint16_t pkt_proc_delay) { - ND_PRINT((ndo, " PROC_DELAY(%u)", EXTRACT_16BITS(pkt_proc_delay))); + ND_PRINT(" PROC_DELAY(%u)", GET_BE_U_2(pkt_proc_delay)); } static void pptp_proto_ver_print(netdissect_options *ndo, - const uint16_t *proto_ver) + const nd_uint16_t proto_ver) { - ND_PRINT((ndo, " PROTO_VER(%u.%u)", /* Version.Revision */ - EXTRACT_16BITS(proto_ver) >> 8, - EXTRACT_16BITS(proto_ver) & 0xff)); + ND_PRINT(" PROTO_VER(%u.%u)", /* Version.Revision */ + GET_BE_U_2(proto_ver) >> 8, + GET_BE_U_2(proto_ver) & 0xff); } static void pptp_recv_winsiz_print(netdissect_options *ndo, - const uint16_t *recv_winsiz) + const nd_uint16_t recv_winsiz) { - ND_PRINT((ndo, " RECV_WIN(%u)", EXTRACT_16BITS(recv_winsiz))); + ND_PRINT(" RECV_WIN(%u)", GET_BE_U_2(recv_winsiz)); } static const struct tok pptp_scrrp_str[] = { @@ -480,9 +490,9 @@ static const struct tok pptp_cdn_str[] = { static void pptp_result_code_print(netdissect_options *ndo, - const uint8_t *result_code, int ctrl_msg_type) + const nd_uint8_t result_code, int ctrl_msg_type) { - ND_PRINT((ndo, " RESULT_CODE(%u", *result_code)); + ND_PRINT(" RESULT_CODE(%u", GET_U_1(result_code)); if (ndo->ndo_vflag) { const struct tok *dict = ctrl_msg_type == PPTP_CTRL_MSG_TYPE_SCCRP ? pptp_scrrp_str : @@ -493,23 +503,28 @@ pptp_result_code_print(netdissect_options *ndo, ctrl_msg_type == PPTP_CTRL_MSG_TYPE_CDN ? pptp_cdn_str : NULL; /* assertion error */ if (dict != NULL) - ND_PRINT((ndo, ":%s", tok2str(dict, "?", *result_code))); + ND_PRINT(":%s", + tok2str(dict, "?", GET_U_1(result_code))); } - ND_PRINT((ndo, ")")); + ND_PRINT(")"); } static void pptp_subaddr_print(netdissect_options *ndo, const u_char *subaddr) { - ND_PRINT((ndo, " SUB_ADDR(%.64s)", subaddr)); + ND_PRINT(" SUB_ADDR("); + nd_printjnp(ndo, subaddr, 64); + ND_PRINT(")"); } static void pptp_vendor_print(netdissect_options *ndo, const u_char *vendor) { - ND_PRINT((ndo, " VENDOR(%.64s)", vendor)); + ND_PRINT(" VENDOR("); + nd_printjnp(ndo, vendor, 64); + ND_PRINT(")"); } /************************************/ @@ -521,26 +536,14 @@ pptp_sccrq_print(netdissect_options *ndo, { const struct pptp_msg_sccrq *ptr = (const struct pptp_msg_sccrq *)dat; - ND_TCHECK(ptr->proto_ver); - pptp_proto_ver_print(ndo, &ptr->proto_ver); - ND_TCHECK(ptr->reserved1); - ND_TCHECK(ptr->framing_cap); - pptp_framing_cap_print(ndo, &ptr->framing_cap); - ND_TCHECK(ptr->bearer_cap); - pptp_bearer_cap_print(ndo, &ptr->bearer_cap); - ND_TCHECK(ptr->max_channel); - pptp_max_channel_print(ndo, &ptr->max_channel); - ND_TCHECK(ptr->firm_rev); - pptp_firm_rev_print(ndo, &ptr->firm_rev); - ND_TCHECK(ptr->hostname); - pptp_hostname_print(ndo, &ptr->hostname[0]); - ND_TCHECK(ptr->vendor); - pptp_vendor_print(ndo, &ptr->vendor[0]); - - return; - -trunc: - ND_PRINT((ndo, "%s", tstr)); + pptp_proto_ver_print(ndo, ptr->proto_ver); + PRINT_RESERVED_IF_NOT_ZERO_2(ptr->reserved1); + pptp_framing_cap_print(ndo, ptr->framing_cap); + pptp_bearer_cap_print(ndo, ptr->bearer_cap); + pptp_max_channel_print(ndo, ptr->max_channel); + pptp_firm_rev_print(ndo, ptr->firm_rev); + pptp_hostname_print(ndo, ptr->hostname); + pptp_vendor_print(ndo, ptr->vendor); } static void @@ -549,29 +552,15 @@ pptp_sccrp_print(netdissect_options *ndo, { const struct pptp_msg_sccrp *ptr = (const struct pptp_msg_sccrp *)dat; - ND_TCHECK(ptr->proto_ver); - pptp_proto_ver_print(ndo, &ptr->proto_ver); - ND_TCHECK(ptr->result_code); - pptp_result_code_print(ndo, &ptr->result_code, PPTP_CTRL_MSG_TYPE_SCCRP); - ND_TCHECK(ptr->err_code); - pptp_err_code_print(ndo, &ptr->err_code); - ND_TCHECK(ptr->framing_cap); - pptp_framing_cap_print(ndo, &ptr->framing_cap); - ND_TCHECK(ptr->bearer_cap); - pptp_bearer_cap_print(ndo, &ptr->bearer_cap); - ND_TCHECK(ptr->max_channel); - pptp_max_channel_print(ndo, &ptr->max_channel); - ND_TCHECK(ptr->firm_rev); - pptp_firm_rev_print(ndo, &ptr->firm_rev); - ND_TCHECK(ptr->hostname); - pptp_hostname_print(ndo, &ptr->hostname[0]); - ND_TCHECK(ptr->vendor); - pptp_vendor_print(ndo, &ptr->vendor[0]); - - return; - -trunc: - ND_PRINT((ndo, "%s", tstr)); + pptp_proto_ver_print(ndo, ptr->proto_ver); + pptp_result_code_print(ndo, ptr->result_code, PPTP_CTRL_MSG_TYPE_SCCRP); + pptp_err_code_print(ndo, ptr->err_code); + pptp_framing_cap_print(ndo, ptr->framing_cap); + pptp_bearer_cap_print(ndo, ptr->bearer_cap); + pptp_max_channel_print(ndo, ptr->max_channel); + pptp_firm_rev_print(ndo, ptr->firm_rev); + pptp_hostname_print(ndo, ptr->hostname); + pptp_vendor_print(ndo, ptr->vendor); } static void @@ -580,32 +569,26 @@ pptp_stopccrq_print(netdissect_options *ndo, { const struct pptp_msg_stopccrq *ptr = (const struct pptp_msg_stopccrq *)dat; - ND_TCHECK(ptr->reason); - ND_PRINT((ndo, " REASON(%u", ptr->reason)); + ND_PRINT(" REASON(%u", GET_U_1(ptr->reason)); if (ndo->ndo_vflag) { - switch (ptr->reason) { + switch (GET_U_1(ptr->reason)) { case 1: - ND_PRINT((ndo, ":None")); + ND_PRINT(":None"); break; case 2: - ND_PRINT((ndo, ":Stop-Protocol")); + ND_PRINT(":Stop-Protocol"); break; case 3: - ND_PRINT((ndo, ":Stop-Local-Shutdown")); + ND_PRINT(":Stop-Local-Shutdown"); break; default: - ND_PRINT((ndo, ":?")); + ND_PRINT(":?"); break; } } - ND_PRINT((ndo, ")")); - ND_TCHECK(ptr->reserved1); - ND_TCHECK(ptr->reserved2); - - return; - -trunc: - ND_PRINT((ndo, "%s", tstr)); + ND_PRINT(")"); + PRINT_RESERVED_IF_NOT_ZERO_1(ptr->reserved1); + PRINT_RESERVED_IF_NOT_ZERO_2(ptr->reserved2); } static void @@ -614,16 +597,9 @@ pptp_stopccrp_print(netdissect_options *ndo, { const struct pptp_msg_stopccrp *ptr = (const struct pptp_msg_stopccrp *)dat; - ND_TCHECK(ptr->result_code); - pptp_result_code_print(ndo, &ptr->result_code, PPTP_CTRL_MSG_TYPE_StopCCRP); - ND_TCHECK(ptr->err_code); - pptp_err_code_print(ndo, &ptr->err_code); - ND_TCHECK(ptr->reserved1); - - return; - -trunc: - ND_PRINT((ndo, "%s", tstr)); + pptp_result_code_print(ndo, ptr->result_code, PPTP_CTRL_MSG_TYPE_StopCCRP); + pptp_err_code_print(ndo, ptr->err_code); + PRINT_RESERVED_IF_NOT_ZERO_2(ptr->reserved1); } static void @@ -632,13 +608,7 @@ pptp_echorq_print(netdissect_options *ndo, { const struct pptp_msg_echorq *ptr = (const struct pptp_msg_echorq *)dat; - ND_TCHECK(ptr->id); - pptp_id_print(ndo, &ptr->id); - - return; - -trunc: - ND_PRINT((ndo, "%s", tstr)); + pptp_id_print(ndo, ptr->id); } static void @@ -647,18 +617,10 @@ pptp_echorp_print(netdissect_options *ndo, { const struct pptp_msg_echorp *ptr = (const struct pptp_msg_echorp *)dat; - ND_TCHECK(ptr->id); - pptp_id_print(ndo, &ptr->id); - ND_TCHECK(ptr->result_code); - pptp_result_code_print(ndo, &ptr->result_code, PPTP_CTRL_MSG_TYPE_ECHORP); - ND_TCHECK(ptr->err_code); - pptp_err_code_print(ndo, &ptr->err_code); - ND_TCHECK(ptr->reserved1); - - return; - -trunc: - ND_PRINT((ndo, "%s", tstr)); + pptp_id_print(ndo, ptr->id); + pptp_result_code_print(ndo, ptr->result_code, PPTP_CTRL_MSG_TYPE_ECHORP); + pptp_err_code_print(ndo, ptr->err_code); + PRINT_RESERVED_IF_NOT_ZERO_2(ptr->reserved1); } static void @@ -667,34 +629,21 @@ pptp_ocrq_print(netdissect_options *ndo, { const struct pptp_msg_ocrq *ptr = (const struct pptp_msg_ocrq *)dat; - ND_TCHECK(ptr->call_id); - pptp_call_id_print(ndo, &ptr->call_id); - ND_TCHECK(ptr->call_ser); - pptp_call_ser_print(ndo, &ptr->call_ser); - ND_TCHECK(ptr->min_bps); - ND_PRINT((ndo, " MIN_BPS(%u)", EXTRACT_32BITS(&ptr->min_bps))); - ND_TCHECK(ptr->max_bps); - ND_PRINT((ndo, " MAX_BPS(%u)", EXTRACT_32BITS(&ptr->max_bps))); - ND_TCHECK(ptr->bearer_type); - pptp_bearer_type_print(ndo, &ptr->bearer_type); - ND_TCHECK(ptr->framing_type); - pptp_framing_type_print(ndo, &ptr->framing_type); - ND_TCHECK(ptr->recv_winsiz); - pptp_recv_winsiz_print(ndo, &ptr->recv_winsiz); - ND_TCHECK(ptr->pkt_proc_delay); - pptp_pkt_proc_delay_print(ndo, &ptr->pkt_proc_delay); - ND_TCHECK(ptr->phone_no_len); - ND_PRINT((ndo, " PHONE_NO_LEN(%u)", EXTRACT_16BITS(&ptr->phone_no_len))); - ND_TCHECK(ptr->reserved1); - ND_TCHECK(ptr->phone_no); - ND_PRINT((ndo, " PHONE_NO(%.64s)", ptr->phone_no)); - ND_TCHECK(ptr->subaddr); - pptp_subaddr_print(ndo, &ptr->subaddr[0]); - - return; - -trunc: - ND_PRINT((ndo, "%s", tstr)); + pptp_call_id_print(ndo, ptr->call_id); + pptp_call_ser_print(ndo, ptr->call_ser); + ND_PRINT(" MIN_BPS(%u)", GET_BE_U_4(ptr->min_bps)); + ND_PRINT(" MAX_BPS(%u)", GET_BE_U_4(ptr->max_bps)); + pptp_bearer_type_print(ndo, ptr->bearer_type); + pptp_framing_type_print(ndo, ptr->framing_type); + pptp_recv_winsiz_print(ndo, ptr->recv_winsiz); + pptp_pkt_proc_delay_print(ndo, ptr->pkt_proc_delay); + ND_PRINT(" PHONE_NO_LEN(%u)", GET_BE_U_2(ptr->phone_no_len)); + PRINT_RESERVED_IF_NOT_ZERO_2(ptr->reserved1); + ND_PRINT(" PHONE_NO("); + nd_printjnp(ndo, ptr->phone_no, + ND_MIN(64, GET_BE_U_2(ptr->phone_no_len))); + ND_PRINT(")"); + pptp_subaddr_print(ndo, ptr->subaddr); } static void @@ -703,29 +652,15 @@ pptp_ocrp_print(netdissect_options *ndo, { const struct pptp_msg_ocrp *ptr = (const struct pptp_msg_ocrp *)dat; - ND_TCHECK(ptr->call_id); - pptp_call_id_print(ndo, &ptr->call_id); - ND_TCHECK(ptr->peer_call_id); - pptp_peer_call_id_print(ndo, &ptr->peer_call_id); - ND_TCHECK(ptr->result_code); - pptp_result_code_print(ndo, &ptr->result_code, PPTP_CTRL_MSG_TYPE_OCRP); - ND_TCHECK(ptr->err_code); - pptp_err_code_print(ndo, &ptr->err_code); - ND_TCHECK(ptr->cause_code); - pptp_cause_code_print(ndo, &ptr->cause_code); - ND_TCHECK(ptr->conn_speed); - pptp_conn_speed_print(ndo, &ptr->conn_speed); - ND_TCHECK(ptr->recv_winsiz); - pptp_recv_winsiz_print(ndo, &ptr->recv_winsiz); - ND_TCHECK(ptr->pkt_proc_delay); - pptp_pkt_proc_delay_print(ndo, &ptr->pkt_proc_delay); - ND_TCHECK(ptr->phy_chan_id); - pptp_phy_chan_id_print(ndo, &ptr->phy_chan_id); - - return; - -trunc: - ND_PRINT((ndo, "%s", tstr)); + pptp_call_id_print(ndo, ptr->call_id); + pptp_peer_call_id_print(ndo, ptr->peer_call_id); + pptp_result_code_print(ndo, ptr->result_code, PPTP_CTRL_MSG_TYPE_OCRP); + pptp_err_code_print(ndo, ptr->err_code); + pptp_cause_code_print(ndo, ptr->cause_code); + pptp_conn_speed_print(ndo, ptr->conn_speed); + pptp_recv_winsiz_print(ndo, ptr->recv_winsiz); + pptp_pkt_proc_delay_print(ndo, ptr->pkt_proc_delay); + pptp_phy_chan_id_print(ndo, ptr->phy_chan_id); } static void @@ -734,29 +669,21 @@ pptp_icrq_print(netdissect_options *ndo, { const struct pptp_msg_icrq *ptr = (const struct pptp_msg_icrq *)dat; - ND_TCHECK(ptr->call_id); - pptp_call_id_print(ndo, &ptr->call_id); - ND_TCHECK(ptr->call_ser); - pptp_call_ser_print(ndo, &ptr->call_ser); - ND_TCHECK(ptr->bearer_type); - pptp_bearer_type_print(ndo, &ptr->bearer_type); - ND_TCHECK(ptr->phy_chan_id); - pptp_phy_chan_id_print(ndo, &ptr->phy_chan_id); - ND_TCHECK(ptr->dialed_no_len); - ND_PRINT((ndo, " DIALED_NO_LEN(%u)", EXTRACT_16BITS(&ptr->dialed_no_len))); - ND_TCHECK(ptr->dialing_no_len); - ND_PRINT((ndo, " DIALING_NO_LEN(%u)", EXTRACT_16BITS(&ptr->dialing_no_len))); - ND_TCHECK(ptr->dialed_no); - ND_PRINT((ndo, " DIALED_NO(%.64s)", ptr->dialed_no)); - ND_TCHECK(ptr->dialing_no); - ND_PRINT((ndo, " DIALING_NO(%.64s)", ptr->dialing_no)); - ND_TCHECK(ptr->subaddr); - pptp_subaddr_print(ndo, &ptr->subaddr[0]); - - return; - -trunc: - ND_PRINT((ndo, "%s", tstr)); + pptp_call_id_print(ndo, ptr->call_id); + pptp_call_ser_print(ndo, ptr->call_ser); + pptp_bearer_type_print(ndo, ptr->bearer_type); + pptp_phy_chan_id_print(ndo, ptr->phy_chan_id); + ND_PRINT(" DIALED_NO_LEN(%u)", GET_BE_U_2(ptr->dialed_no_len)); + ND_PRINT(" DIALING_NO_LEN(%u)", GET_BE_U_2(ptr->dialing_no_len)); + ND_PRINT(" DIALED_NO("); + nd_printjnp(ndo, ptr->dialed_no, + ND_MIN(64, GET_BE_U_2(ptr->dialed_no_len))); + ND_PRINT(")"); + ND_PRINT(" DIALING_NO("); + nd_printjnp(ndo, ptr->dialing_no, + ND_MIN(64, GET_BE_U_2(ptr->dialing_no_len))); + ND_PRINT(")"); + pptp_subaddr_print(ndo, ptr->subaddr); } static void @@ -765,24 +692,13 @@ pptp_icrp_print(netdissect_options *ndo, { const struct pptp_msg_icrp *ptr = (const struct pptp_msg_icrp *)dat; - ND_TCHECK(ptr->call_id); - pptp_call_id_print(ndo, &ptr->call_id); - ND_TCHECK(ptr->peer_call_id); - pptp_peer_call_id_print(ndo, &ptr->peer_call_id); - ND_TCHECK(ptr->result_code); - pptp_result_code_print(ndo, &ptr->result_code, PPTP_CTRL_MSG_TYPE_ICRP); - ND_TCHECK(ptr->err_code); - pptp_err_code_print(ndo, &ptr->err_code); - ND_TCHECK(ptr->recv_winsiz); - pptp_recv_winsiz_print(ndo, &ptr->recv_winsiz); - ND_TCHECK(ptr->pkt_proc_delay); - pptp_pkt_proc_delay_print(ndo, &ptr->pkt_proc_delay); - ND_TCHECK(ptr->reserved1); - - return; - -trunc: - ND_PRINT((ndo, "%s", tstr)); + pptp_call_id_print(ndo, ptr->call_id); + pptp_peer_call_id_print(ndo, ptr->peer_call_id); + pptp_result_code_print(ndo, ptr->result_code, PPTP_CTRL_MSG_TYPE_ICRP); + pptp_err_code_print(ndo, ptr->err_code); + pptp_recv_winsiz_print(ndo, ptr->recv_winsiz); + pptp_pkt_proc_delay_print(ndo, ptr->pkt_proc_delay); + PRINT_RESERVED_IF_NOT_ZERO_2(ptr->reserved1); } static void @@ -791,22 +707,12 @@ pptp_iccn_print(netdissect_options *ndo, { const struct pptp_msg_iccn *ptr = (const struct pptp_msg_iccn *)dat; - ND_TCHECK(ptr->peer_call_id); - pptp_peer_call_id_print(ndo, &ptr->peer_call_id); - ND_TCHECK(ptr->reserved1); - ND_TCHECK(ptr->conn_speed); - pptp_conn_speed_print(ndo, &ptr->conn_speed); - ND_TCHECK(ptr->recv_winsiz); - pptp_recv_winsiz_print(ndo, &ptr->recv_winsiz); - ND_TCHECK(ptr->pkt_proc_delay); - pptp_pkt_proc_delay_print(ndo, &ptr->pkt_proc_delay); - ND_TCHECK(ptr->framing_type); - pptp_framing_type_print(ndo, &ptr->framing_type); - - return; - -trunc: - ND_PRINT((ndo, "%s", tstr)); + pptp_peer_call_id_print(ndo, ptr->peer_call_id); + PRINT_RESERVED_IF_NOT_ZERO_2(ptr->reserved1); + pptp_conn_speed_print(ndo, ptr->conn_speed); + pptp_recv_winsiz_print(ndo, ptr->recv_winsiz); + pptp_pkt_proc_delay_print(ndo, ptr->pkt_proc_delay); + pptp_framing_type_print(ndo, ptr->framing_type); } static void @@ -815,14 +721,8 @@ pptp_ccrq_print(netdissect_options *ndo, { const struct pptp_msg_ccrq *ptr = (const struct pptp_msg_ccrq *)dat; - ND_TCHECK(ptr->call_id); - pptp_call_id_print(ndo, &ptr->call_id); - ND_TCHECK(ptr->reserved1); - - return; - -trunc: - ND_PRINT((ndo, "%s", tstr)); + pptp_call_id_print(ndo, ptr->call_id); + PRINT_RESERVED_IF_NOT_ZERO_2(ptr->reserved1); } static void @@ -831,22 +731,14 @@ pptp_cdn_print(netdissect_options *ndo, { const struct pptp_msg_cdn *ptr = (const struct pptp_msg_cdn *)dat; - ND_TCHECK(ptr->call_id); - pptp_call_id_print(ndo, &ptr->call_id); - ND_TCHECK(ptr->result_code); - pptp_result_code_print(ndo, &ptr->result_code, PPTP_CTRL_MSG_TYPE_CDN); - ND_TCHECK(ptr->err_code); - pptp_err_code_print(ndo, &ptr->err_code); - ND_TCHECK(ptr->cause_code); - pptp_cause_code_print(ndo, &ptr->cause_code); - ND_TCHECK(ptr->reserved1); - ND_TCHECK(ptr->call_stats); - ND_PRINT((ndo, " CALL_STATS(%.128s)", ptr->call_stats)); - - return; - -trunc: - ND_PRINT((ndo, "%s", tstr)); + pptp_call_id_print(ndo, ptr->call_id); + pptp_result_code_print(ndo, ptr->result_code, PPTP_CTRL_MSG_TYPE_CDN); + pptp_err_code_print(ndo, ptr->err_code); + pptp_cause_code_print(ndo, ptr->cause_code); + PRINT_RESERVED_IF_NOT_ZERO_2(ptr->reserved1); + ND_PRINT(" CALL_STATS("); + nd_printjnp(ndo, ptr->call_stats, 128); + ND_PRINT(")"); } static void @@ -855,26 +747,14 @@ pptp_wen_print(netdissect_options *ndo, { const struct pptp_msg_wen *ptr = (const struct pptp_msg_wen *)dat; - ND_TCHECK(ptr->peer_call_id); - pptp_peer_call_id_print(ndo, &ptr->peer_call_id); - ND_TCHECK(ptr->reserved1); - ND_TCHECK(ptr->crc_err); - ND_PRINT((ndo, " CRC_ERR(%u)", EXTRACT_32BITS(&ptr->crc_err))); - ND_TCHECK(ptr->framing_err); - ND_PRINT((ndo, " FRAMING_ERR(%u)", EXTRACT_32BITS(&ptr->framing_err))); - ND_TCHECK(ptr->hardware_overrun); - ND_PRINT((ndo, " HARDWARE_OVERRUN(%u)", EXTRACT_32BITS(&ptr->hardware_overrun))); - ND_TCHECK(ptr->buffer_overrun); - ND_PRINT((ndo, " BUFFER_OVERRUN(%u)", EXTRACT_32BITS(&ptr->buffer_overrun))); - ND_TCHECK(ptr->timeout_err); - ND_PRINT((ndo, " TIMEOUT_ERR(%u)", EXTRACT_32BITS(&ptr->timeout_err))); - ND_TCHECK(ptr->align_err); - ND_PRINT((ndo, " ALIGN_ERR(%u)", EXTRACT_32BITS(&ptr->align_err))); - - return; - -trunc: - ND_PRINT((ndo, "%s", tstr)); + pptp_peer_call_id_print(ndo, ptr->peer_call_id); + PRINT_RESERVED_IF_NOT_ZERO_2(ptr->reserved1); + ND_PRINT(" CRC_ERR(%u)", GET_BE_U_4(ptr->crc_err)); + ND_PRINT(" FRAMING_ERR(%u)", GET_BE_U_4(ptr->framing_err)); + ND_PRINT(" HARDWARE_OVERRUN(%u)", GET_BE_U_4(ptr->hardware_overrun)); + ND_PRINT(" BUFFER_OVERRUN(%u)", GET_BE_U_4(ptr->buffer_overrun)); + ND_PRINT(" TIMEOUT_ERR(%u)", GET_BE_U_4(ptr->timeout_err)); + ND_PRINT(" ALIGN_ERR(%u)", GET_BE_U_4(ptr->align_err)); } static void @@ -883,18 +763,10 @@ pptp_sli_print(netdissect_options *ndo, { const struct pptp_msg_sli *ptr = (const struct pptp_msg_sli *)dat; - ND_TCHECK(ptr->peer_call_id); - pptp_peer_call_id_print(ndo, &ptr->peer_call_id); - ND_TCHECK(ptr->reserved1); - ND_TCHECK(ptr->send_accm); - ND_PRINT((ndo, " SEND_ACCM(0x%08x)", EXTRACT_32BITS(&ptr->send_accm))); - ND_TCHECK(ptr->recv_accm); - ND_PRINT((ndo, " RECV_ACCM(0x%08x)", EXTRACT_32BITS(&ptr->recv_accm))); - - return; - -trunc: - ND_PRINT((ndo, "%s", tstr)); + pptp_peer_call_id_print(ndo, ptr->peer_call_id); + PRINT_RESERVED_IF_NOT_ZERO_2(ptr->reserved1); + ND_PRINT(" SEND_ACCM(0x%08x)", GET_BE_U_4(ptr->send_accm)); + ND_PRINT(" RECV_ACCM(0x%08x)", GET_BE_U_4(ptr->recv_accm)); } void @@ -905,46 +777,44 @@ pptp_print(netdissect_options *ndo, uint32_t mc; uint16_t ctrl_msg_type; - ND_PRINT((ndo, ": pptp")); + ndo->ndo_protocol = "pptp"; + ND_PRINT(": "); + nd_print_protocol(ndo); hdr = (const struct pptp_hdr *)dat; - ND_TCHECK(hdr->length); if (ndo->ndo_vflag) { - ND_PRINT((ndo, " Length=%u", EXTRACT_16BITS(&hdr->length))); + ND_PRINT(" Length=%u", GET_BE_U_2(hdr->length)); } - ND_TCHECK(hdr->msg_type); if (ndo->ndo_vflag) { - switch(EXTRACT_16BITS(&hdr->msg_type)) { + switch(GET_BE_U_2(hdr->msg_type)) { case PPTP_MSG_TYPE_CTRL: - ND_PRINT((ndo, " CTRL-MSG")); + ND_PRINT(" CTRL-MSG"); break; case PPTP_MSG_TYPE_MGMT: - ND_PRINT((ndo, " MGMT-MSG")); + ND_PRINT(" MGMT-MSG"); break; default: - ND_PRINT((ndo, " UNKNOWN-MSG-TYPE")); + ND_PRINT(" UNKNOWN-MSG-TYPE"); break; } } - ND_TCHECK(hdr->magic_cookie); - mc = EXTRACT_32BITS(&hdr->magic_cookie); + mc = GET_BE_U_4(hdr->magic_cookie); if (mc != PPTP_MAGIC_COOKIE) { - ND_PRINT((ndo, " UNEXPECTED Magic-Cookie!!(%08x)", mc)); + ND_PRINT(" UNEXPECTED Magic-Cookie!!(%08x)", mc); } if (ndo->ndo_vflag || mc != PPTP_MAGIC_COOKIE) { - ND_PRINT((ndo, " Magic-Cookie=%08x", mc)); + ND_PRINT(" Magic-Cookie=%08x", mc); } - ND_TCHECK(hdr->ctrl_msg_type); - ctrl_msg_type = EXTRACT_16BITS(&hdr->ctrl_msg_type); + ctrl_msg_type = GET_BE_U_2(hdr->ctrl_msg_type); if (ctrl_msg_type < PPTP_MAX_MSGTYPE_INDEX) { - ND_PRINT((ndo, " CTRL_MSGTYPE=%s", - pptp_message_type_string[ctrl_msg_type])); + ND_PRINT(" CTRL_MSGTYPE=%s", + pptp_message_type_string[ctrl_msg_type]); } else { - ND_PRINT((ndo, " UNKNOWN_CTRL_MSGTYPE(%u)", ctrl_msg_type)); + ND_PRINT(" UNKNOWN_CTRL_MSGTYPE(%u)", ctrl_msg_type); } - ND_TCHECK(hdr->reserved0); + PRINT_RESERVED_IF_NOT_ZERO_2(hdr->reserved0); dat += 12; @@ -998,9 +868,4 @@ pptp_print(netdissect_options *ndo, /* do nothing */ break; } - - return; - -trunc: - ND_PRINT((ndo, "%s", tstr)); } diff --git a/contrib/tcpdump/print-ptp.c b/contrib/tcpdump/print-ptp.c new file mode 100644 index 0000000000..6f12b90afb --- /dev/null +++ b/contrib/tcpdump/print-ptp.c @@ -0,0 +1,620 @@ +/* + * 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. + * + * Original code by Partha S. Ghosh (psglinux dot gmail dot com) + */ + +/* \summary: Precision Time Protocol (PTP) printer */ + +/* specification: https://standards.ieee.org/findstds/standard/1588-2008.html*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "netdissect-stdinc.h" +#include "netdissect.h" +#include "extract.h" + +/* + * PTP header + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | R | |msgtype| version | Msg Len | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | domain No | rsvd1 | flag Field | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Correction NS | + * | Correction Sub NS | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Reserved2 | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Clock Identity | + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Port Identity | Sequence ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | control | log msg int | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * 0 1 2 3 + * + * Announce Message (msg type=0xB) + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + * | Seconds | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Nano Seconds | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Origin Cur UTC Offset | Reserved | GM Prio 1 | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |GM Clock Class | GM Clock Accu | GM Clock Variance | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | GM Prio 2 | | + * +-+-+-+-+-+-+-+-+ + + * | GM Clock Identity | + * + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | Steps Removed | Time Source | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * 0 1 2 3 + * + * Sync Message (msg type=0x0) + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + * | Seconds | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Nano Seconds | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Delay Request Message (msg type=0x1) + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + * | Origin Time Stamp Seconds | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Nano Seconds | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Followup Message (msg type=0x8) + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + * | Precise Origin Time Stamp Seconds | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Nano Seconds | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Delay Resp Message (msg type=0x9) + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + * | Seconds | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Nano Seconds | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Port Identity | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * PDelay Request Message (msg type=0x2) + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + * | Origin Time Stamp Seconds | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Origin Time Stamp Nano Seconds | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Port Identity | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * PDelay Response Message (msg type=0x3) + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + * | Request receipt Time Stamp Seconds | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Nano Seconds | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Requesting Port Identity | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * PDelay Resp Follow up Message (msg type=0xA) + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + * | Response Origin Time Stamp Seconds | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Nano Seconds | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Requesting Port Identity | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Signalling Message (msg type=0xC) + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Requesting Port Identity | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Management Message (msg type=0xD) + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Requesting Port Identity | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |Start Bndry Hps| Boundary Hops | flags | Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + */ + +#define M_SYNC 0x0 +#define M_DELAY_REQ 0x1 +#define M_PDELAY_REQ 0x2 +#define M_PDELAY_RESP 0x3 +#define M_OTHER 0x5 +#define M_FOLLOW_UP 0x8 +#define M_DELAY_RESP 0x9 +#define M_PDELAY_RESP_FOLLOW_UP 0xA +#define M_ANNOUNCE 0xB +#define M_SIGNALLING 0xC +#define M_MANAGEMENT 0xD + +static const struct tok ptp_msg_type[] = { + { M_SYNC ,"sync msg"}, + { M_DELAY_REQ ,"delay req msg"}, + { M_PDELAY_REQ ,"peer delay req msg"}, + { M_PDELAY_RESP ,"peer delay resp msg"}, + { M_OTHER, "Other"}, + { M_FOLLOW_UP ,"follow up msg"}, + { M_DELAY_RESP ,"delay resp msg"}, + { M_PDELAY_RESP_FOLLOW_UP ,"pdelay resp fup msg"}, + { M_ANNOUNCE ,"announce msg"}, + { M_SIGNALLING ,"signalling msg"}, + { M_MANAGEMENT ,"management msg"}, + { 0, NULL} +}; + + +#define PTP_TRUE 1 +#define PTP_FALSE !PTP_TRUE + +#define PTP_HDR_LEN 0x22 + +/* mask based on the first byte */ +#define PTP_VERS_MASK 0xFF +#define PTP_V1_COMPAT 0x10 +#define PTP_MSG_TYPE_MASK 0x0F + +/*mask based 2byte */ +#define PTP_DOMAIN_MASK 0xFF00 +#define PTP_RSVD1_MASK 0xFF +#define PTP_CONTROL_MASK 0xFF +#define PTP_LOGMSG_MASK 0xFF + +/* mask based on the flags 2 bytes */ + +#define PTP_L161_MASK 0x1 +#define PTP_L1_59_MASK 0x2 +#define PTP_UTC_REASONABLE_MASK 0x4 +#define PTP_TIMESCALE_MASK 0x8 +#define PTP_TIME_TRACABLE_MASK 0x10 +#define PTP_FREQUENCY_TRACABLE_MASK 0x20 +#define PTP_ALTERNATE_MASTER_MASK 0x100 +#define PTP_TWO_STEP_MASK 0x200 +#define PTP_UNICAST_MASK 0x400 +#define PTP_PROFILE_SPEC_1_MASK 0x1000 +#define PTP_PROFILE_SPEC_2_MASK 0x2000 +#define PTP_SECURITY_MASK 0x4000 +#define PTP_FLAGS_UNKNOWN_MASK 0x18C0 + + +static const struct tok ptp_flag_values[] = { + { PTP_L161_MASK ,"l1 61"}, + { PTP_L1_59_MASK ,"l1 59"}, + { PTP_UTC_REASONABLE_MASK ,"utc reasonable"}, + { PTP_TIMESCALE_MASK ,"timescale"}, + { PTP_TIME_TRACABLE_MASK ,"time tracable"}, + { PTP_FREQUENCY_TRACABLE_MASK ,"frequency tracable"}, + { PTP_ALTERNATE_MASTER_MASK ,"alternate master"}, + { PTP_TWO_STEP_MASK ,"two step"}, + { PTP_UNICAST_MASK ,"unicast"}, + { PTP_PROFILE_SPEC_1_MASK ,"profile specific 1"}, + { PTP_PROFILE_SPEC_2_MASK ,"profile specific 2"}, + { PTP_SECURITY_MASK ,"security mask"}, + { PTP_FLAGS_UNKNOWN_MASK , "unknown"}, + {0, NULL} +}; + +#define PTP_PRINT_MSG_TYPE(e) \ + { \ + ND_PRINT("(%s)", tok2str(ptp_msg_type, "unknown", e)); \ + } + +static const char *p_porigin_ts = "preciseOriginTimeStamp"; +static const char *p_origin_ts = "originTimeStamp"; +static const char *p_recv_ts = "receiveTimeStamp"; + +#define PTP_VER_1 0x1 +#define PTP_VER_2 0x2 + +#define PTP_UCHAR_LEN sizeof(uint8_t) +#define PTP_UINT16_LEN sizeof(uint16_t) +#define PTP_UINT32_LEN sizeof(uint32_t) +#define PTP_6BYTES_LEN sizeof(uint32_t)+sizeof(uint16_t) +#define PTP_UINT64_LEN sizeof(uint64_t) + + + +static void ptp_print_1(netdissect_options *ndo); +static void ptp_print_2(netdissect_options *ndo, const u_char *bp, u_int len); + +static void ptp_print_timestamp(netdissect_options *ndo, const u_char *bp, u_int *len, const char *stype); +static void ptp_print_timestamp_identity(netdissect_options *ndo, const u_char *bp, u_int *len, const char *ttype); +static void ptp_print_announce_msg(netdissect_options *ndo, const u_char *bp, u_int *len); +static void ptp_print_port_id(netdissect_options *ndo, const u_char *bp, u_int *len); +static void ptp_print_mgmt_msg(netdissect_options *ndo, const u_char *bp, u_int *len); + +static void +print_field(netdissect_options *ndo, const char *st, uint32_t flen, + const u_char *bp, u_int *len, uint8_t hex) +{ + uint8_t u8_val; + uint16_t u16_val; + uint32_t u32_val; + uint64_t u64_val; + + switch(flen) { + case PTP_UCHAR_LEN: + u8_val = GET_U_1(bp); + ND_PRINT(", %s", st); + if (hex) + ND_PRINT(" 0x%x", u8_val); + else + ND_PRINT(" %u", u8_val); + *len -= 1; bp += 1; + break; + case PTP_UINT16_LEN: + u16_val = GET_BE_U_2(bp); + ND_PRINT(", %s", st); + if (hex) + ND_PRINT(" 0x%x", u16_val); + else + ND_PRINT(" %u", u16_val); + *len -= 2; bp += 2; + break; + case PTP_UINT32_LEN: + u32_val = GET_BE_U_4(bp); + ND_PRINT(", %s", st); + if (hex) + ND_PRINT(" 0x%x", u32_val); + else + ND_PRINT(" %u", u32_val); + *len -= 4; bp += 4; + break; + case PTP_UINT64_LEN: + u64_val = GET_BE_U_8(bp); + ND_PRINT(", %s", st); + if (hex) + ND_PRINT(" 0x%"PRIx64, u64_val); + else + ND_PRINT(" 0x%"PRIu64, u64_val); + *len -= 8; bp += 8; + break; + default: + break; + } +} + +static void +ptp_print_1(netdissect_options *ndo) +{ + ND_PRINT(" (not implemented)"); +} + +static void +ptp_print_2(netdissect_options *ndo, const u_char *bp, u_int length) +{ + u_int len = length; + uint16_t msg_len, flags, port_id, seq_id; + uint8_t foct, domain_no, msg_type, v1_compat, rsvd1, lm_int, control; + uint32_t ns_corr, sns_corr, rsvd2; + uint64_t clk_id; + + foct = GET_U_1(bp); + v1_compat = foct & PTP_V1_COMPAT; + ND_PRINT(", v1 compat : %s", v1_compat?"yes":"no"); + msg_type = foct & PTP_MSG_TYPE_MASK; + ND_PRINT(", msg type : %s", tok2str(ptp_msg_type, "none", msg_type)); + + /* msg length */ + len -= 2; bp += 2; msg_len = GET_BE_U_2(bp); ND_PRINT(", length : %u", msg_len); + + /* domain */ + len -= 2; bp += 2; domain_no = (GET_BE_U_2(bp) & PTP_DOMAIN_MASK) >> 8; ND_PRINT(", domain : %u", domain_no); + + /* rsvd 1*/ + rsvd1 = GET_BE_U_2(bp) & PTP_RSVD1_MASK; + ND_PRINT(", reserved1 : %u", rsvd1); + + /* flags */ + len -= 2; bp += 2; flags = GET_BE_U_2(bp); ND_PRINT(", Flags [%s]", bittok2str(ptp_flag_values, "none", flags)); + + /* correction NS */ + len -= 2; bp += 2; ns_corr = GET_BE_U_4(bp); ND_PRINT(", NS correction : %u", ns_corr); + + /* correction sub NS */ + len -= 4; bp += 4; sns_corr = GET_BE_U_4(bp); ND_PRINT(", sub NS correction : %u", sns_corr); + + /* Reserved 2 */ + len -= 4; bp += 4; rsvd2 = GET_BE_U_4(bp); ND_PRINT(", reserved2 : %u", rsvd2); + + /* clock identity */ + len -= 4; bp += 4; clk_id = GET_BE_U_8(bp); ND_PRINT(", clock identity : 0x%"PRIx64, clk_id); + + /* port identity */ + len -= 8; bp += 8; port_id = GET_BE_U_2(bp); ND_PRINT(", port id : %u", port_id); + + /* sequence ID */ + len -= 2; bp += 2; seq_id = GET_BE_U_2(bp); ND_PRINT(", seq id : %u", seq_id); + + /* control */ + len -= 2; bp += 2; control = GET_U_1(bp) ; + ND_PRINT(", control : %u (%s)", control, tok2str(ptp_msg_type, "none", control)); + + /* log message interval */ + lm_int = GET_BE_U_2(bp) & PTP_LOGMSG_MASK; ND_PRINT(", log message interval : %u", lm_int); len -= 2; bp += 2; + + switch(msg_type) { + case M_SYNC: + ptp_print_timestamp(ndo, bp, &len, p_origin_ts); + break; + case M_DELAY_REQ: + ptp_print_timestamp(ndo, bp, &len, p_origin_ts); + break; + case M_PDELAY_REQ: + ptp_print_timestamp_identity(ndo, bp, &len, p_porigin_ts); + break; + case M_PDELAY_RESP: + ptp_print_timestamp_identity(ndo, bp, &len, p_recv_ts); + break; + case M_FOLLOW_UP: + ptp_print_timestamp(ndo, bp, &len, p_porigin_ts); + break; + case M_DELAY_RESP: + ptp_print_timestamp_identity(ndo, bp, &len, p_recv_ts); + break; + case M_PDELAY_RESP_FOLLOW_UP: + ptp_print_timestamp_identity(ndo, bp, &len, p_porigin_ts); + break; + case M_ANNOUNCE: + ptp_print_announce_msg(ndo, bp, &len); + break; + case M_SIGNALLING: + ptp_print_port_id(ndo, bp, &len); + break; + case M_MANAGEMENT: + ptp_print_mgmt_msg(ndo, bp, &len); + break; + default: + break; + } +} +/* + * PTP general message + */ +void +ptp_print(netdissect_options *ndo, const u_char *bp, u_int len) +{ + u_int vers; + + ndo->ndo_protocol = "ptp"; + if (len < PTP_HDR_LEN) { + goto trunc; + } + vers = GET_BE_U_2(bp) & PTP_VERS_MASK; + ND_PRINT("PTPv%u",vers); + switch(vers) { + case PTP_VER_1: + ptp_print_1(ndo); + break; + case PTP_VER_2: + ptp_print_2(ndo, bp, len); + break; + default: + //ND_PRINT("ERROR: unknown-version\n"); + break; + } + return; + +trunc: + nd_print_trunc(ndo); +} + +static void +ptp_print_timestamp(netdissect_options *ndo, const u_char *bp, u_int *len, const char *stype) +{ + uint64_t secs; + uint32_t nsecs; + + ND_PRINT(", %s :", stype); + /* sec time stamp 6 bytes */ + secs = GET_BE_U_6(bp); + ND_PRINT(" %"PRIu64" seconds,", secs); + *len -= 6; + bp += 6; + + /* NS time stamp 4 bytes */ + nsecs = GET_BE_U_4(bp); + ND_PRINT(" %u nanoseconds", nsecs); + *len -= 4; + bp += 4; +} +static void +ptp_print_timestamp_identity(netdissect_options *ndo, + const u_char *bp, u_int *len, const char *ttype) +{ + uint64_t secs; + uint32_t nsecs; + uint16_t port_id; + uint64_t port_identity; + + ND_PRINT(", %s :", ttype); + /* sec time stamp 6 bytes */ + secs = GET_BE_U_6(bp); + ND_PRINT(" %"PRIu64" seconds,", secs); + *len -= 6; + bp += 6; + + /* NS time stamp 4 bytes */ + nsecs = GET_BE_U_4(bp); + ND_PRINT(" %u nanoseconds", nsecs); + *len -= 4; + bp += 4; + + /* port identity*/ + port_identity = GET_BE_U_8(bp); + ND_PRINT(", port identity : 0x%"PRIx64, port_identity); + *len -= 8; + bp += 8; + + /* port id */ + port_id = GET_BE_U_2(bp); + ND_PRINT(", port id : %u", port_id); + *len -= 2; + bp += 2; +} +static void +ptp_print_announce_msg(netdissect_options *ndo, const u_char *bp, u_int *len) +{ + uint8_t rsvd, gm_prio_1, gm_prio_2, gm_clk_cls, gm_clk_acc, time_src; + uint16_t origin_cur_utc, gm_clk_var, steps_removed; + uint64_t gm_clock_id; + uint64_t secs; + uint32_t nsecs; + + ND_PRINT(", %s :", p_origin_ts); + /* sec time stamp 6 bytes */ + secs = GET_BE_U_6(bp); + ND_PRINT(" %"PRIu64" seconds", secs); + *len -= 6; + bp += 6; + + /* NS time stamp 4 bytes */ + nsecs = GET_BE_U_4(bp); + ND_PRINT(" %u nanoseconds", nsecs); + *len -= 4; + bp += 4; + + /* origin cur utc */ + origin_cur_utc = GET_BE_U_2(bp); + ND_PRINT(", origin cur utc :%u", origin_cur_utc); + *len -= 2; + bp += 2; + + /* rsvd */ + rsvd = GET_U_1(bp); + ND_PRINT(", rsvd : %u", rsvd); + *len -= 1; + bp += 1; + + /* gm prio */ + gm_prio_1 = GET_U_1(bp); + ND_PRINT(", gm priority_1 : %u", gm_prio_1); + *len -= 1; + bp += 1; + + /* GM clock class */ + gm_clk_cls = GET_U_1(bp); + ND_PRINT(", gm clock class : %u", gm_clk_cls); + *len -= 1; + bp += 1; + /* GM clock accuracy */ + gm_clk_acc = GET_U_1(bp); + ND_PRINT(", gm clock accuracy : %u", gm_clk_acc); + *len -= 1; + bp += 1; + /* GM clock variance */ + gm_clk_var = GET_BE_U_2(bp); + ND_PRINT(", gm clock variance : %u", gm_clk_var); + *len -= 2; + bp += 2; + /* GM Prio 2 */ + gm_prio_2 = GET_U_1(bp); + ND_PRINT(", gm priority_2 : %u", gm_prio_2); + *len -= 1; + bp += 1; + + /* GM Clock Identity */ + gm_clock_id = GET_BE_U_8(bp); + ND_PRINT(", gm clock id : 0x%"PRIx64, gm_clock_id); + *len -= 8; + bp += 8; + /* steps removed */ + steps_removed = GET_BE_U_2(bp); + ND_PRINT(", steps removed : %u", steps_removed); + *len -= 2; + bp += 2; + /* Time source */ + time_src = GET_U_1(bp); + ND_PRINT(", time source : 0x%x", time_src); + *len -= 1; + bp += 1; + +} +static void +ptp_print_port_id(netdissect_options *ndo, const u_char *bp, u_int *len) +{ + uint16_t port_id; + uint64_t port_identity; + + /* port identity*/ + port_identity = GET_BE_U_8(bp); + ND_PRINT(", port identity : 0x%"PRIx64, port_identity); + *len -= 8; + bp += 8; + + /* port id */ + port_id = GET_BE_U_2(bp); + ND_PRINT(", port id : %u", port_id); + *len -= 2; + bp += 2; + +} + +static void +ptp_print_mgmt_msg(netdissect_options *ndo, const u_char *bp, u_int *len) +{ + ptp_print_port_id(ndo, bp, len); + print_field(ndo, ", start boundary hops ", PTP_UCHAR_LEN, bp, len, PTP_FALSE); + print_field(ndo, ", boundary hops ", PTP_UCHAR_LEN, bp, len, PTP_FALSE); + print_field(ndo, ", flags ", PTP_UCHAR_LEN, bp, len, PTP_TRUE); + print_field(ndo, ", reserved ", PTP_UCHAR_LEN, bp, len, PTP_TRUE); +} diff --git a/contrib/tcpdump/print-radius.c b/contrib/tcpdump/print-radius.c index 682cad6163..c87fa900f3 100644 --- a/contrib/tcpdump/print-radius.c +++ b/contrib/tcpdump/print-radius.c @@ -40,48 +40,78 @@ * RFC 2869: * "RADIUS Extensions" * + * RFC 3162: + * "RADIUS and IPv6" + * * RFC 3580: * "IEEE 802.1X Remote Authentication Dial In User Service (RADIUS)" * "Usage Guidelines" * + * RFC 4072: + * "Diameter Extensible Authentication Protocol (EAP) Application" + * * RFC 4675: * "RADIUS Attributes for Virtual LAN and Priority Support" * + * RFC 4818: + * "RADIUS Delegated-IPv6-Prefix Attribute" + * + * RFC 4849: + * "RADIUS Filter Rule Attribute" + * + * RFC 5090: + * "RADIUS Extension for Digest Authentication" + * * RFC 5176: * "Dynamic Authorization Extensions to RADIUS" * + * RFC 5447: + * "Diameter Mobile IPv6" + * + * RFC 5580: + * "Carrying Location Objects in RADIUS and Diameter" + * + * RFC 6572: + * "RADIUS Support for Proxy Mobile IPv6" + * + * RFC 7155: + * "Diameter Network Access Server Application" + * * Alfredo Andres Omella (aandres@s21sec.com) v0.1 2000/09/15 * * TODO: Among other things to print ok MacIntosh and Vendor values */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include +#include "netdissect-ctype.h" + #include "netdissect.h" #include "addrtoname.h" #include "extract.h" #include "oui.h" +#include "ntp.h" -static const char tstr[] = " [|radius]"; #define TAM_SIZE(x) (sizeof(x)/sizeof(x[0]) ) #define PRINT_HEX(bytes_len, ptr_data) \ while(bytes_len) \ { \ - ND_PRINT((ndo, "%02X", *ptr_data )); \ + ND_PRINT("%02X", *ptr_data ); \ ptr_data++; \ bytes_len--; \ } /* Radius packet codes */ +/* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-27 */ #define RADCMD_ACCESS_REQ 1 /* Access-Request */ #define RADCMD_ACCESS_ACC 2 /* Access-Accept */ #define RADCMD_ACCESS_REJ 3 /* Access-Reject */ @@ -145,6 +175,8 @@ static const struct tok radius_command_values[] = { #define ARAP_PASS 70 #define ARAP_FEATURES 71 +#define EAP_MESSAGE 79 + #define TUNNEL_PRIV_GROUP 81 #define TUNNEL_ASSIGN_ID 82 #define TUNNEL_PREFERENCE 83 @@ -154,6 +186,8 @@ static const struct tok radius_command_values[] = { #define TUNNEL_CLIENT_AUTH 90 #define TUNNEL_SERVER_AUTH 91 + +#define ERROR_CAUSE 101 /********************************/ /* End Radius Attribute types */ /********************************/ @@ -168,28 +202,37 @@ static const struct tok rfc4675_tagged[] = { }; -static void print_attr_string(netdissect_options *, register const u_char *, u_int, u_short ); -static void print_attr_num(netdissect_options *, register const u_char *, u_int, u_short ); -static void print_vendor_attr(netdissect_options *, register const u_char *, u_int, u_short ); -static void print_attr_address(netdissect_options *, register const u_char *, u_int, u_short); -static void print_attr_time(netdissect_options *, register const u_char *, u_int, u_short); -static void print_attr_strange(netdissect_options *, register const u_char *, u_int, u_short); - - -struct radius_hdr { uint8_t code; /* Radius packet code */ - uint8_t id; /* Radius packet id */ - uint16_t len; /* Radius total length */ - uint8_t auth[16]; /* Authenticator */ +static void print_attr_string(netdissect_options *, const u_char *, u_int, u_short ); +static void print_attr_num(netdissect_options *, const u_char *, u_int, u_short ); +static void print_vendor_attr(netdissect_options *, const u_char *, u_int, u_short ); +static void print_attr_address(netdissect_options *, const u_char *, u_int, u_short); +static void print_attr_address6(netdissect_options *, const u_char *, u_int, u_short); +static void print_attr_netmask6(netdissect_options *, const u_char *, u_int, u_short); +static void print_attr_mip6_home_link_prefix(netdissect_options *, const u_char *, u_int, u_short); +static void print_attr_operator_name(netdissect_options *, const u_char *, u_int, u_short); +static void print_attr_location_information(netdissect_options *, const u_char *, u_int, u_short); +static void print_attr_location_data(netdissect_options *, const u_char *, u_int, u_short); +static void print_basic_location_policy_rules(netdissect_options *, const u_char *, u_int, u_short); +static void print_attr_time(netdissect_options *, const u_char *, u_int, u_short); +static void print_attr_vector64(netdissect_options *, register const u_char *, u_int, u_short); +static void print_attr_strange(netdissect_options *, const u_char *, u_int, u_short); + + +struct radius_hdr { nd_uint8_t code; /* Radius packet code */ + nd_uint8_t id; /* Radius packet id */ + nd_uint16_t len; /* Radius total length */ + nd_byte auth[16]; /* Authenticator */ }; #define MIN_RADIUS_LEN 20 -struct radius_attr { uint8_t type; /* Attribute type */ - uint8_t len; /* Attribute length */ +struct radius_attr { nd_uint8_t type; /* Attribute type */ + nd_uint8_t len; /* Attribute length */ }; /* Service-Type Attribute standard values */ +/* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-4 */ static const char *serv_type[]={ NULL, "Login", "Framed", @@ -200,11 +243,22 @@ static const char *serv_type[]={ NULL, "NAS Prompt", "Authenticate Only", "Callback NAS Prompt", + /* ^ [0, 9] ^ */ "Call Check", "Callback Administrative", + "Voice", + "Fax", + "Modem Relay", + "IAPP-Register", + "IAPP-AP-Check", + "Authorize Only", + "Framed-Management", + "Additional-Authorization", + /* ^ [10, 19] ^ */ }; /* Framed-Protocol Attribute standard values */ +/* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-5 */ static const char *frm_proto[]={ NULL, "PPP", "SLIP", @@ -212,9 +266,11 @@ static const char *frm_proto[]={ NULL, "Gandalf proprietary", "Xylogics IPX/SLIP", "X.75 Synchronous", + "GPRS PDP Context", }; /* Framed-Routing Attribute standard values */ +/* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-6 */ static const char *frm_routing[]={ "None", "Send", "Listen", @@ -222,6 +278,7 @@ static const char *frm_routing[]={ "None", }; /* Framed-Compression Attribute standard values */ +/* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-7 */ static const char *frm_comp[]={ "None", "VJ TCP/IP", "IPX", @@ -229,6 +286,7 @@ static const char *frm_comp[]={ "None", }; /* Login-Service Attribute standard values */ +/* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-8 */ static const char *login_serv[]={ "Telnet", "Rlogin", "TCP Clear", @@ -242,6 +300,7 @@ static const char *login_serv[]={ "Telnet", /* Termination-Action Attribute standard values */ +/* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-9 */ static const char *term_action[]={ "Default", "RADIUS-Request", }; @@ -253,6 +312,7 @@ static const char *ingress_filters[]={ NULL, }; /* NAS-Port-Type Attribute standard values */ +/* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-13 */ static const char *nas_port_type[]={ "Async", "Sync", "ISDN Sync", @@ -263,6 +323,7 @@ static const char *nas_port_type[]={ "Async", "HDLC Clear Channel", "X.25", "X.75", + /* ^ [0, 9] ^ */ "G.3 Fax", "SDSL", "ADSL-CAP", @@ -273,9 +334,37 @@ static const char *nas_port_type[]={ "Async", "Cable", "Wireless - Other", "Wireless - IEEE 802.11", + /* ^ [10, 19] ^ */ + "Token-Ring", + "FDDI", + "Wireless - CDMA200", + "Wireless - UMTS", + "Wireless - 1X-EV", + "IAPP", + "FTTP", + "Wireless - IEEE 802.16", + "Wireless - IEEE 802.20", + "Wireless - IEEE 802.22", + /* ^ [20, 29] ^ */ + "PPPoA", + "PPPoEoA", + "PPPoEoE", + "PPPoEoVLAN", + "PPPoEoQinQ", + "xPON", + "Wireless - XGP", + "WiMAX Pre-Release 8 IWK Function", + "WIMAX-WIFI-IWK", + "WIMAX-SFF", + /* ^ [30, 39] ^ */ + "WIMAX-HA-LMA", + "WIMAX-DHCP", + "WIMAX-LBS", + "WIMAX-WVS", }; /* Acct-Status-Type Accounting Attribute standard values */ +/* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-10 */ static const char *acct_status[]={ NULL, "Start", "Stop", @@ -286,6 +375,7 @@ static const char *acct_status[]={ NULL, "Accounting-On", "Accounting-Off", "Tunnel-Start", + /* ^ [0, 9] ^ */ "Tunnel-Stop", "Tunnel-Reject", "Tunnel-Link-Start", @@ -295,13 +385,16 @@ static const char *acct_status[]={ NULL, }; /* Acct-Authentic Accounting Attribute standard values */ +/* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-11 */ static const char *acct_auth[]={ NULL, "RADIUS", "Local", "Remote", + "Diameter", }; /* Acct-Terminate-Cause Accounting Attribute standard values */ +/* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-12 */ static const char *acct_term[]={ NULL, "User Request", "Lost Carrier", @@ -312,6 +405,7 @@ static const char *acct_term[]={ NULL, "Admin Reboot", "Port Error", "NAS Error", + /* ^ [0, 9] ^ */ "NAS Request", "NAS Reboot", "Port Unneeded", @@ -321,9 +415,16 @@ static const char *acct_term[]={ NULL, "Callback", "User Error", "Host Request", + "Supplicant Restart", + /* ^ [10, 19] ^ */ + "Reauthentication Failure", + "Port Reinitialized", + "Port Administratively Disabled", + "Lost Power", }; /* Tunnel-Type Attribute standard values */ +/* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-14 */ static const char *tunnel_type[]={ NULL, "PPTP", "L2F", @@ -334,6 +435,7 @@ static const char *tunnel_type[]={ NULL, "IP-IP", "MIN-IP-IP", "ESP", + /* ^ [0, 9] ^ */ "GRE", "DVS", "IP-in-IP Tunneling", @@ -341,6 +443,7 @@ static const char *tunnel_type[]={ NULL, }; /* Tunnel-Medium-Type Attribute standard values */ +/* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-15 */ static const char *tunnel_medium[]={ NULL, "IPv4", "IPv6", @@ -351,6 +454,7 @@ static const char *tunnel_medium[]={ NULL, "E.163", "E.164", "F.69", + /* ^ [0, 9] ^ */ "X.121", "IPX", "Appletalk", @@ -360,6 +464,7 @@ static const char *tunnel_medium[]={ NULL, }; /* ARAP-Zone-Access Attribute standard values */ +/* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-16 */ static const char *arap_zone[]={ NULL, "Only access to dfl zone", "Use zone filter inc.", @@ -367,17 +472,144 @@ static const char *arap_zone[]={ NULL, "Use zone filter exc.", }; +/* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-17 */ static const char *prompt[]={ "No Echo", "Echo", }; +/* Error-Cause standard values */ +/* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-18 */ +#define ERROR_CAUSE_RESIDUAL_CONTEXT_REMOVED 201 +#define ERROR_CAUSE_INVALID_EAP_PACKET 202 +#define ERROR_CAUSE_UNSUPPORTED_ATTRIBUTE 401 +#define ERROR_CAUSE_MISSING_ATTRIBUTE 402 +#define ERROR_CAUSE_NAS_IDENTIFICATION_MISMATCH 403 +#define ERROR_CAUSE_INVALID_REQUEST 404 +#define ERROR_CAUSE_UNSUPPORTED_SERVICE 405 +#define ERROR_CAUSE_UNSUPPORTED_EXTENSION 406 +#define ERROR_CAUSE_INVALID_ATTRIBUTE_VALUE 407 +#define ERROR_CAUSE_ADMINISTRATIVELY_PROHIBITED 501 +#define ERROR_CAUSE_PROXY_REQUEST_NOT_ROUTABLE 502 +#define ERROR_CAUSE_SESSION_CONTEXT_NOT_FOUND 503 +#define ERROR_CAUSE_SESSION_CONTEXT_NOT_REMOVABLE 504 +#define ERROR_CAUSE_PROXY_PROCESSING_ERROR 505 +#define ERROR_CAUSE_RESOURCES_UNAVAILABLE 506 +#define ERROR_CAUSE_REQUEST_INITIATED 507 +#define ERROR_CAUSE_MULTIPLE_SESSION_SELECTION_UNSUPPORTED 508 +#define ERROR_CAUSE_LOCATION_INFO_REQUIRED 509 +static const struct tok errorcausetype[] = { + { ERROR_CAUSE_RESIDUAL_CONTEXT_REMOVED, "Residual Session Context Removed" }, + { ERROR_CAUSE_INVALID_EAP_PACKET, "Invalid EAP Packet (Ignored)" }, + { ERROR_CAUSE_UNSUPPORTED_ATTRIBUTE, "Unsupported Attribute" }, + { ERROR_CAUSE_MISSING_ATTRIBUTE, "Missing Attribute" }, + { ERROR_CAUSE_NAS_IDENTIFICATION_MISMATCH, "NAS Identification Mismatch" }, + { ERROR_CAUSE_INVALID_REQUEST, "Invalid Request" }, + { ERROR_CAUSE_UNSUPPORTED_SERVICE, "Unsupported Service" }, + { ERROR_CAUSE_UNSUPPORTED_EXTENSION, "Unsupported Extension" }, + { ERROR_CAUSE_INVALID_ATTRIBUTE_VALUE, "Invalid Attribute Value" }, + { ERROR_CAUSE_ADMINISTRATIVELY_PROHIBITED, "Administratively Prohibited" }, + { ERROR_CAUSE_PROXY_REQUEST_NOT_ROUTABLE, "Request Not Routable (Proxy)" }, + { ERROR_CAUSE_SESSION_CONTEXT_NOT_FOUND, "Session Context Not Found" }, + { ERROR_CAUSE_SESSION_CONTEXT_NOT_REMOVABLE, "Session Context Not Removable" }, + { ERROR_CAUSE_PROXY_PROCESSING_ERROR, "Other Proxy Processing Error" }, + { ERROR_CAUSE_RESOURCES_UNAVAILABLE, "Resources Unavailable" }, + { ERROR_CAUSE_REQUEST_INITIATED, "Request Initiated" }, + { ERROR_CAUSE_MULTIPLE_SESSION_SELECTION_UNSUPPORTED, "Multiple Session Selection Unsupported" }, + { ERROR_CAUSE_LOCATION_INFO_REQUIRED, "Location Info Required" }, + { 0, NULL } + }; + +/* MIP6-Feature-Vector standard values */ +/* https://www.iana.org/assignments/aaa-parameters/aaa-parameters.xhtml */ +#define MIP6_INTEGRATED 0x0000000000000001 +#define LOCAL_HOME_AGENT_ASSIGNMENT 0x0000000000000002 +#define PMIP6_SUPPORTED 0x0000010000000000 +#define IP4_HOA_SUPPORTED 0x0000020000000000 +#define LOCAL_MAG_ROUTING_SUPPORTED 0x0000040000000000 +#define ASSIGN_LOCAL_IP 0x0000080000000000 +#define MIP4_SUPPORTED 0x0000100000000000 +#define OPTIMIZED_IDLE_MODE_MOBILITY 0x0000200000000000 +#define GTPv2_SUPPORTED 0x0000400000000000 +#define IP4_TRANSPORT_SUPPORTED 0x0000800000000000 +#define IP4_HOA_ONLY_SUPPORTED 0x0001000000000000 +#define INTER_MAG_ROUTING_SUPPORTED 0x0002000000000000 +static const struct mip6_feature_vector { + uint64_t v; + const char *s; + } mip6_feature_vector[] = { + { MIP6_INTEGRATED, "MIP6_INTEGRATED" }, + { LOCAL_HOME_AGENT_ASSIGNMENT, "LOCAL_HOME_AGENT_ASSIGNMENT" }, + { PMIP6_SUPPORTED, "PMIP6_SUPPORTED" }, + { IP4_HOA_SUPPORTED, "IP4_HOA_SUPPORTED" }, + { LOCAL_MAG_ROUTING_SUPPORTED, "LOCAL_MAG_ROUTING_SUPPORTED" }, + { ASSIGN_LOCAL_IP, "ASSIGN_LOCAL_IP" }, + { MIP4_SUPPORTED, "MIP4_SUPPORTED" }, + { OPTIMIZED_IDLE_MODE_MOBILITY, "OPTIMIZED_IDLE_MODE_MOBILITY" }, + { GTPv2_SUPPORTED, "GTPv2_SUPPORTED" }, + { IP4_TRANSPORT_SUPPORTED, "IP4_TRANSPORT_SUPPORTED" }, + { IP4_HOA_ONLY_SUPPORTED, "IP4_HOA_ONLY_SUPPORTED" }, + { INTER_MAG_ROUTING_SUPPORTED, "INTER_MAG_ROUTING_SUPPORTED" }, + }; -static struct attrtype { +/* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-19 */ +#define OPERATOR_NAME_TADIG 0x30 +#define OPERATOR_NAME_REALM 0x31 +#define OPERATOR_NAME_E212 0x32 +#define OPERATOR_NAME_ICC 0x33 +static const struct tok operator_name_vector[] = { + { OPERATOR_NAME_TADIG, "TADIG" }, + { OPERATOR_NAME_REALM, "REALM" }, + { OPERATOR_NAME_E212, "E212" }, + { OPERATOR_NAME_ICC, "ICC" }, + { 0, NULL } + }; + +/* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-20 */ +#define LOCATION_INFORMATION_CODE_CIVIC 0 +#define LOCATION_INFORMATION_CODE_GEOSPATIAL 1 +static const struct tok location_information_code_vector[] = { + { LOCATION_INFORMATION_CODE_CIVIC , "Civic" }, + { LOCATION_INFORMATION_CODE_GEOSPATIAL, "Geospatial" }, + { 0, NULL } + }; + +/* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-21 */ +#define LOCATION_INFORMATION_ENTITY_USER 0 +#define LOCATION_INFORMATION_ENTITY_RADIUS 1 +static const struct tok location_information_entity_vector[] = { + { LOCATION_INFORMATION_ENTITY_USER, "User" }, + { LOCATION_INFORMATION_ENTITY_RADIUS, "RADIUS" }, + { 0, NULL } + }; + +/* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-22 */ +static const struct tok blpr_bm[] = { + { 0x0001, "MBZ-15" }, + { 0x0002, "MBZ-14" }, + { 0x0004, "MBZ-13" }, + { 0x0008, "MBZ-12" }, + { 0x0010, "MBZ-11" }, + { 0x0020, "MBZ-10" }, + { 0x0040, "MBZ-9" }, + { 0x0080, "MBZ-8" }, + { 0x0100, "MBZ-7" }, + { 0x0200, "MBZ-6" }, + { 0x0400, "MBZ-5" }, + { 0x0800, "MBZ-4" }, + { 0x1000, "MBZ-3" }, + { 0x2000, "MBZ-2" }, + { 0x4000, "MBZ-1" }, + { 0x8000, "Retransmission Allowed" }, + { 0, NULL } + }; + +/* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-2 */ +static const struct attrtype { const char *name; /* Attribute name */ const char **subtypes; /* Standard Values (if any) */ u_char siz_subtypes; /* Size of total standard values */ u_char first_subtype; /* First standard value is 0 or 1 */ - void (*print_func)(netdissect_options *, register const u_char *, u_int, u_short); + void (*print_func)(netdissect_options *, const u_char *, u_int, u_short); } attr_type[]= { { NULL, NULL, 0, 0, NULL }, @@ -390,6 +622,7 @@ static struct attrtype { { "Framed-Protocol", frm_proto, TAM_SIZE(frm_proto)-1, 1, print_attr_num }, { "Framed-IP-Address", NULL, 0, 0, print_attr_address }, { "Framed-IP-Netmask", NULL, 0, 0, print_attr_address }, + /* ^ [0, 9] ^ */ { "Framed-Routing", frm_routing, TAM_SIZE(frm_routing), 0, print_attr_num }, { "Filter-Id", NULL, 0, 0, print_attr_string }, { "Framed-MTU", NULL, 0, 0, print_attr_num }, @@ -400,6 +633,7 @@ static struct attrtype { { "Unassigned", NULL, 0, 0, NULL }, /*17*/ { "Reply-Message", NULL, 0, 0, print_attr_string }, { "Callback-Number", NULL, 0, 0, print_attr_string }, + /* ^ [10, 19] ^ */ { "Callback-Id", NULL, 0, 0, print_attr_string }, { "Unassigned", NULL, 0, 0, NULL }, /*21*/ { "Framed-Route", NULL, 0, 0, print_attr_string }, @@ -410,6 +644,7 @@ static struct attrtype { { "Session-Timeout", NULL, 0, 0, print_attr_num }, { "Idle-Timeout", NULL, 0, 0, print_attr_num }, { "Termination-Action", term_action, TAM_SIZE(term_action), 0, print_attr_num }, + /* ^ [20, 29] ^ */ { "Called-Station-Id", NULL, 0, 0, print_attr_string }, { "Calling-Station-Id", NULL, 0, 0, print_attr_string }, { "NAS-Identifier", NULL, 0, 0, print_attr_string }, @@ -420,6 +655,7 @@ static struct attrtype { { "Framed-AppleTalk-Link", NULL, 0, 0, print_attr_num }, { "Framed-AppleTalk-Network", NULL, 0, 0, print_attr_num }, { "Framed-AppleTalk-Zone", NULL, 0, 0, print_attr_string }, + /* ^ [30, 39] ^ */ { "Acct-Status-Type", acct_status, TAM_SIZE(acct_status)-1, 1, print_attr_num }, { "Acct-Delay-Time", NULL, 0, 0, print_attr_num }, { "Acct-Input-Octets", NULL, 0, 0, print_attr_num }, @@ -430,6 +666,7 @@ static struct attrtype { { "Acct-Input-Packets", NULL, 0, 0, print_attr_num }, { "Acct-Output-Packets", NULL, 0, 0, print_attr_num }, { "Acct-Terminate-Cause", acct_term, TAM_SIZE(acct_term)-1, 1, print_attr_num }, + /* ^ [40, 49] ^ */ { "Acct-Multi-Session-Id", NULL, 0, 0, print_attr_string }, { "Acct-Link-Count", NULL, 0, 0, print_attr_num }, { "Acct-Input-Gigawords", NULL, 0, 0, print_attr_num }, @@ -440,6 +677,7 @@ static struct attrtype { { "Ingress-Filters", ingress_filters, TAM_SIZE(ingress_filters)-1, 1, print_attr_num }, { "Egress-VLAN-Name", NULL, 0, 0, print_attr_string }, { "User-Priority-Table", NULL, 0, 0, NULL }, + /* ^ [50, 59] ^ */ { "CHAP-Challenge", NULL, 0, 0, print_attr_string }, { "NAS-Port-Type", nas_port_type, TAM_SIZE(nas_port_type), 0, print_attr_num }, { "Port-Limit", NULL, 0, 0, print_attr_num }, @@ -450,6 +688,7 @@ static struct attrtype { { "Tunnel-Server-Endpoint", NULL, 0, 0, print_attr_string }, { "Acct-Tunnel-Connection", NULL, 0, 0, print_attr_string }, { "Tunnel-Password", NULL, 0, 0, print_attr_string }, + /* ^ [60, 69] ^ */ { "ARAP-Password", NULL, 0, 0, print_attr_strange }, { "ARAP-Features", NULL, 0, 0, print_attr_strange }, { "ARAP-Zone-Access", arap_zone, TAM_SIZE(arap_zone)-1, 1, print_attr_num }, /*72*/ @@ -460,6 +699,7 @@ static struct attrtype { { "Connect-Info", NULL, 0, 0, print_attr_string }, { "Configuration-Token", NULL, 0, 0, print_attr_string }, { "EAP-Message", NULL, 0, 0, print_attr_string }, + /* ^ [70, 79] ^ */ { "Message-Authenticator", NULL, 0, 0, print_attr_string }, /*80*/ { "Tunnel-Private-Group-ID", NULL, 0, 0, print_attr_string }, { "Tunnel-Assignment-ID", NULL, 0, 0, print_attr_string }, @@ -470,10 +710,51 @@ static struct attrtype { { "NAS-Port-Id", NULL, 0, 0, print_attr_string }, { "Framed-Pool", NULL, 0, 0, print_attr_string }, { "CUI", NULL, 0, 0, print_attr_string }, + /* ^ [80, 89] ^ */ { "Tunnel-Client-Auth-ID", NULL, 0, 0, print_attr_string }, { "Tunnel-Server-Auth-ID", NULL, 0, 0, print_attr_string }, - { "Unassigned", NULL, 0, 0, NULL }, /*92*/ - { "Unassigned", NULL, 0, 0, NULL } /*93*/ + { "NAS-Filter-Rule", NULL, 0, 0, print_attr_string }, + { "Unassigned", NULL, 0, 0, NULL }, /*93*/ + { "Originating-Line-Info", NULL, 0, 0, NULL }, + { "NAS-IPv6-Address", NULL, 0, 0, print_attr_address6 }, + { "Framed-Interface-ID", NULL, 0, 0, NULL }, + { "Framed-IPv6-Prefix", NULL, 0, 0, print_attr_netmask6 }, + { "Login-IPv6-Host", NULL, 0, 0, print_attr_address6 }, + { "Framed-IPv6-Route", NULL, 0, 0, print_attr_string }, + /* ^ [90, 99] ^ */ + { "Framed-IPv6-Pool", NULL, 0, 0, print_attr_string }, + { "Error-Cause", NULL, 0, 0, print_attr_strange }, + { "EAP-Key-Name", NULL, 0, 0, NULL }, + { "Digest-Response", NULL, 0, 0, print_attr_string }, + { "Digest-Realm", NULL, 0, 0, print_attr_string }, + { "Digest-Nonce", NULL, 0, 0, print_attr_string }, + { "Digest-Response-Auth", NULL, 0, 0, print_attr_string }, + { "Digest-Nextnonce", NULL, 0, 0, print_attr_string }, + { "Digest-Method", NULL, 0, 0, print_attr_string }, + { "Digest-URI", NULL, 0, 0, print_attr_string }, + /* ^ [100, 109] ^ */ + { "Digest-Qop", NULL, 0, 0, print_attr_string }, + { "Digest-Algorithm", NULL, 0, 0, print_attr_string }, + { "Digest-Entity-Body-Hash", NULL, 0, 0, print_attr_string }, + { "Digest-CNonce", NULL, 0, 0, print_attr_string }, + { "Digest-Nonce-Count", NULL, 0, 0, print_attr_string }, + { "Digest-Username", NULL, 0, 0, print_attr_string }, + { "Digest-Opaque", NULL, 0, 0, print_attr_string }, + { "Digest-Auth-Param", NULL, 0, 0, print_attr_string }, + { "Digest-AKA-Auts", NULL, 0, 0, print_attr_string }, + { "Digest-Domain", NULL, 0, 0, print_attr_string }, + /* ^ [110, 119] ^ */ + { "Digest-Stale", NULL, 0, 0, print_attr_string }, + { "Digest-HA1", NULL, 0, 0, print_attr_string }, + { "SIP-AOR", NULL, 0, 0, print_attr_string }, + { "Delegated-IPv6-Prefix", NULL, 0, 0, print_attr_netmask6 }, + { "MIP6-Feature-Vector", NULL, 0, 0, print_attr_vector64 }, + { "MIP6-Home-Link-Prefix", NULL, 0, 0, print_attr_mip6_home_link_prefix }, + { "Operator-Name", NULL, 0, 0, print_attr_operator_name }, + { "Location-Information", NULL, 0, 0, print_attr_location_information }, + { "Location-Data", NULL, 0, 0, print_attr_location_data }, + { "Basic-Location-Policy-Rules", NULL, 0, 0, print_basic_location_policy_rules } + /* ^ [120, 129] ^ */ }; @@ -486,24 +767,24 @@ static struct attrtype { /*****************************/ static void print_attr_string(netdissect_options *ndo, - register const u_char *data, u_int length, u_short attr_code) + const u_char *data, u_int length, u_short attr_code) { - register u_int i; + u_int i; - ND_TCHECK2(data[0],length); + ND_TCHECK_LEN(data, length); switch(attr_code) { case TUNNEL_PASS: if (length < 3) goto trunc; - if (*data && (*data <=0x1F) ) - ND_PRINT((ndo, "Tag[%u] ", *data)); + if (GET_U_1(data) && (GET_U_1(data) <= 0x1F)) + ND_PRINT("Tag[%u] ", GET_U_1(data)); else - ND_PRINT((ndo, "Tag[Unused] ")); + ND_PRINT("Tag[Unused] "); data++; length--; - ND_PRINT((ndo, "Salt %u ", EXTRACT_16BITS(data))); + ND_PRINT("Salt %u ", GET_BE_U_2(data)); data+=2; length-=2; break; @@ -513,14 +794,14 @@ print_attr_string(netdissect_options *ndo, case TUNNEL_ASSIGN_ID: case TUNNEL_CLIENT_AUTH: case TUNNEL_SERVER_AUTH: - if (*data <= 0x1F) + if (GET_U_1(data) <= 0x1F) { if (length < 1) goto trunc; - if (*data) - ND_PRINT((ndo, "Tag[%u] ", *data)); + if (GET_U_1(data)) + ND_PRINT("Tag[%u] ", GET_U_1(data)); else - ND_PRINT((ndo, "Tag[Unused] ")); + ND_PRINT("Tag[Unused] "); data++; length--; } @@ -528,21 +809,26 @@ print_attr_string(netdissect_options *ndo, case EGRESS_VLAN_NAME: if (length < 1) goto trunc; - ND_PRINT((ndo, "%s (0x%02x) ", - tok2str(rfc4675_tagged,"Unknown tag",*data), - *data)); + ND_PRINT("%s (0x%02x) ", + tok2str(rfc4675_tagged,"Unknown tag",GET_U_1(data)), + GET_U_1(data)); data++; length--; break; + case EAP_MESSAGE: + if (length < 1) + goto trunc; + eap_print(ndo, data, length); + return; } - for (i=0; i < length && *data; i++, data++) - ND_PRINT((ndo, "%c", (*data < 32 || *data > 126) ? '.' : *data)); + for (i=0; i < length && GET_U_1(data); i++, data++) + ND_PRINT("%c", ND_ASCII_ISPRINT(GET_U_1(data)) ? GET_U_1(data) : '.'); return; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); } /* @@ -550,7 +836,7 @@ print_attr_string(netdissect_options *ndo, */ static void print_vendor_attr(netdissect_options *ndo, - register const u_char *data, u_int length, u_short attr_code _U_) + const u_char *data, u_int length, u_short attr_code _U_) { u_int idx; u_int vendor_id; @@ -559,51 +845,48 @@ print_vendor_attr(netdissect_options *ndo, if (length < 4) goto trunc; - ND_TCHECK2(*data, 4); - vendor_id = EXTRACT_32BITS(data); + vendor_id = GET_BE_U_4(data); data+=4; length-=4; - ND_PRINT((ndo, "Vendor: %s (%u)", + ND_PRINT("Vendor: %s (%u)", tok2str(smi_values,"Unknown",vendor_id), - vendor_id)); + vendor_id); while (length >= 2) { - ND_TCHECK2(*data, 2); - - vendor_type = *(data); - vendor_length = *(data+1); + vendor_type = GET_U_1(data); + vendor_length = GET_U_1(data + 1); if (vendor_length < 2) { - ND_PRINT((ndo, "\n\t Vendor Attribute: %u, Length: %u (bogus, must be >= 2)", + ND_PRINT("\n\t Vendor Attribute: %u, Length: %u (bogus, must be >= 2)", vendor_type, - vendor_length)); + vendor_length); return; } if (vendor_length > length) { - ND_PRINT((ndo, "\n\t Vendor Attribute: %u, Length: %u (bogus, goes past end of vendor-specific attribute)", + ND_PRINT("\n\t Vendor Attribute: %u, Length: %u (bogus, goes past end of vendor-specific attribute)", vendor_type, - vendor_length)); + vendor_length); return; } data+=2; vendor_length-=2; length-=2; - ND_TCHECK2(*data, vendor_length); + ND_TCHECK_LEN(data, vendor_length); - ND_PRINT((ndo, "\n\t Vendor Attribute: %u, Length: %u, Value: ", + ND_PRINT("\n\t Vendor Attribute: %u, Length: %u, Value: ", vendor_type, - vendor_length)); + vendor_length); for (idx = 0; idx < vendor_length ; idx++, data++) - ND_PRINT((ndo, "%c", (*data < 32 || *data > 126) ? '.' : *data)); + ND_PRINT("%c", ND_ASCII_ISPRINT(GET_U_1(data)) ? GET_U_1(data) : '.'); length-=vendor_length; } return; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); } /******************************/ @@ -615,17 +898,16 @@ print_vendor_attr(netdissect_options *ndo, /******************************/ static void print_attr_num(netdissect_options *ndo, - register const u_char *data, u_int length, u_short attr_code) + const u_char *data, u_int length, u_short attr_code) { uint32_t timeout; if (length != 4) { - ND_PRINT((ndo, "ERROR: length %u != 4", length)); + ND_PRINT("ERROR: length %u != 4", length); return; } - ND_TCHECK2(data[0],4); /* This attribute has standard values */ if (attr_type[attr_code].siz_subtypes) { @@ -635,33 +917,33 @@ print_attr_num(netdissect_options *ndo, if ( (attr_code == TUNNEL_TYPE) || (attr_code == TUNNEL_MEDIUM) ) { - if (!*data) - ND_PRINT((ndo, "Tag[Unused] ")); + if (!GET_U_1(data)) + ND_PRINT("Tag[Unused] "); else - ND_PRINT((ndo, "Tag[%d] ", *data)); + ND_PRINT("Tag[%u] ", GET_U_1(data)); data++; - data_value = EXTRACT_24BITS(data); + data_value = GET_BE_U_3(data); } else { - data_value = EXTRACT_32BITS(data); + data_value = GET_BE_U_4(data); } if ( data_value <= (uint32_t)(attr_type[attr_code].siz_subtypes - 1 + attr_type[attr_code].first_subtype) && data_value >= attr_type[attr_code].first_subtype ) - ND_PRINT((ndo, "%s", table[data_value])); + ND_PRINT("%s", table[data_value]); else - ND_PRINT((ndo, "#%u", data_value)); + ND_PRINT("#%u", data_value); } else { switch(attr_code) /* Be aware of special cases... */ { case FRM_IPX: - if (EXTRACT_32BITS( data) == 0xFFFFFFFE ) - ND_PRINT((ndo, "NAS Select")); + if (GET_BE_U_4(data) == 0xFFFFFFFE ) + ND_PRINT("NAS Select"); else - ND_PRINT((ndo, "%d", EXTRACT_32BITS(data))); + ND_PRINT("%u", GET_BE_U_4(data)); break; case SESSION_TIMEOUT: @@ -669,64 +951,59 @@ print_attr_num(netdissect_options *ndo, case ACCT_DELAY: case ACCT_SESSION_TIME: case ACCT_INT_INTERVAL: - timeout = EXTRACT_32BITS( data); + timeout = GET_BE_U_4(data); if ( timeout < 60 ) - ND_PRINT((ndo, "%02d secs", timeout)); + ND_PRINT("%02d secs", timeout); else { if ( timeout < 3600 ) - ND_PRINT((ndo, "%02d:%02d min", - timeout / 60, timeout % 60)); + ND_PRINT("%02d:%02d min", + timeout / 60, timeout % 60); else - ND_PRINT((ndo, "%02d:%02d:%02d hours", + ND_PRINT("%02d:%02d:%02d hours", timeout / 3600, (timeout % 3600) / 60, - timeout % 60)); + timeout % 60); } break; case FRM_ATALK_LINK: - if (EXTRACT_32BITS(data) ) - ND_PRINT((ndo, "%d", EXTRACT_32BITS(data))); + if (GET_BE_U_4(data)) + ND_PRINT("%u", GET_BE_U_4(data)); else - ND_PRINT((ndo, "Unnumbered")); + ND_PRINT("Unnumbered"); break; case FRM_ATALK_NETWORK: - if (EXTRACT_32BITS(data) ) - ND_PRINT((ndo, "%d", EXTRACT_32BITS(data))); + if (GET_BE_U_4(data)) + ND_PRINT("%u", GET_BE_U_4(data)); else - ND_PRINT((ndo, "NAS assigned")); + ND_PRINT("NAS assigned"); break; case TUNNEL_PREFERENCE: - if (*data) - ND_PRINT((ndo, "Tag[%d] ", *data)); + if (GET_U_1(data)) + ND_PRINT("Tag[%u] ", GET_U_1(data)); else - ND_PRINT((ndo, "Tag[Unused] ")); + ND_PRINT("Tag[Unused] "); data++; - ND_PRINT((ndo, "%d", EXTRACT_24BITS(data))); + ND_PRINT("%u", GET_BE_U_3(data)); break; case EGRESS_VLAN_ID: - ND_PRINT((ndo, "%s (0x%02x) ", - tok2str(rfc4675_tagged,"Unknown tag",*data), - *data)); + ND_PRINT("%s (0x%02x) ", + tok2str(rfc4675_tagged,"Unknown tag",GET_U_1(data)), + GET_U_1(data)); data++; - ND_PRINT((ndo, "%d", EXTRACT_24BITS(data))); + ND_PRINT("%u", GET_BE_U_3(data)); break; default: - ND_PRINT((ndo, "%d", EXTRACT_32BITS(data))); + ND_PRINT("%u", GET_BE_U_4(data)); break; } /* switch */ } /* if-else */ - - return; - - trunc: - ND_PRINT((ndo, "%s", tstr)); } /*****************************/ @@ -738,40 +1015,249 @@ print_attr_num(netdissect_options *ndo, /*****************************/ static void print_attr_address(netdissect_options *ndo, - register const u_char *data, u_int length, u_short attr_code) + const u_char *data, u_int length, u_short attr_code) { if (length != 4) { - ND_PRINT((ndo, "ERROR: length %u != 4", length)); + ND_PRINT("ERROR: length %u != 4", length); return; } - ND_TCHECK2(data[0],4); - switch(attr_code) { case FRM_IPADDR: case LOG_IPHOST: - if (EXTRACT_32BITS(data) == 0xFFFFFFFF ) - ND_PRINT((ndo, "User Selected")); + if (GET_BE_U_4(data) == 0xFFFFFFFF ) + ND_PRINT("User Selected"); else - if (EXTRACT_32BITS(data) == 0xFFFFFFFE ) - ND_PRINT((ndo, "NAS Select")); + if (GET_BE_U_4(data) == 0xFFFFFFFE ) + ND_PRINT("NAS Select"); else - ND_PRINT((ndo, "%s",ipaddr_string(ndo, data))); + ND_PRINT("%s",GET_IPADDR_STRING(data)); break; default: - ND_PRINT((ndo, "%s", ipaddr_string(ndo, data))); + ND_PRINT("%s", GET_IPADDR_STRING(data)); break; } +} + +/*****************************/ +/* Print an attribute IPv6 */ +/* address value pointed by */ +/* 'data' and 'length' size. */ +/*****************************/ +/* Returns nothing. */ +/*****************************/ +static void +print_attr_address6(netdissect_options *ndo, + const u_char *data, u_int length, u_short attr_code _U_) +{ + if (length != 16) + { + ND_PRINT("ERROR: length %u != 16", length); + return; + } + + ND_PRINT("%s", GET_IP6ADDR_STRING(data)); +} + +static void +print_attr_netmask6(netdissect_options *ndo, + const u_char *data, u_int length, u_short attr_code _U_) +{ + u_char data2[16]; + + if (length < 2 || length > 18) + { + ND_PRINT("ERROR: length %u not in range (2..18)", length); + return; + } + ND_TCHECK_LEN(data, length); + if (GET_U_1(data + 1) > 128) + { + ND_PRINT("ERROR: netmask %u not in range (0..128)", GET_U_1(data + 1)); + return; + } + + memset(data2, 0, sizeof(data2)); + if (length > 2) + memcpy(data2, data+2, length-2); + + ND_PRINT("%s/%u", ip6addr_string(ndo, data2), GET_U_1(data + 1)); + + if (GET_U_1(data + 1) > 8 * (length - 2)) + ND_PRINT(" (inconsistent prefix length)"); + + return; + + trunc: + nd_print_trunc(ndo); +} + +static void +print_attr_mip6_home_link_prefix(netdissect_options *ndo, + const u_char *data, u_int length, u_short attr_code _U_) +{ + if (length != 17) + { + ND_PRINT("ERROR: length %u != 17", length); + return; + } + ND_TCHECK_LEN(data, length); + if (GET_U_1(data) > 128) + { + ND_PRINT("ERROR: netmask %u not in range (0..128)", GET_U_1(data)); + return; + } + + ND_PRINT("%s/%u", GET_IP6ADDR_STRING(data + 1), GET_U_1(data)); + + return; + + trunc: + nd_print_trunc(ndo); +} + +static void +print_attr_operator_name(netdissect_options *ndo, + const u_char *data, u_int length, u_short attr_code _U_) +{ + u_int namespace_value; + + ND_TCHECK_LEN(data, length); + if (length < 2) + { + ND_PRINT("ERROR: length %u < 2", length); + return; + } + namespace_value = GET_U_1(data); + data++; + ND_PRINT("[%s] ", tok2str(operator_name_vector, "unknown namespace %u", namespace_value)); + + (void)nd_printn(ndo, data, length - 1, NULL); + + return; + + trunc: + nd_print_trunc(ndo); +} + +static void +print_attr_location_information(netdissect_options *ndo, + const u_char *data, u_int length, u_short attr_code _U_) +{ + uint16_t index; + uint8_t code, entity; + + ND_TCHECK_LEN(data, length); + if (length < 21) + { + ND_PRINT("ERROR: length %u < 21", length); + return; + } + + index = GET_BE_U_2(data); + data += 2; + + code = GET_U_1(data); + data++; + + entity = GET_U_1(data); + data++; + + ND_PRINT("index %u, code %s, entity %s, ", + index, + tok2str(location_information_code_vector, "Unknown (%u)", code), + tok2str(location_information_entity_vector, "Unknown (%u)", entity) + ); + + ND_PRINT("sighting time "); + p_ntp_time(ndo, (const struct l_fixedpt *)data); + ND_PRINT(", "); + data += 8; + + ND_PRINT("time to live "); + p_ntp_time(ndo, (const struct l_fixedpt *)data); + ND_PRINT(", "); + data += 8; + + ND_PRINT("method \""); + (void)nd_printn(ndo, data, length - 20, NULL); + ND_PRINT("\""); + + return; + + trunc: + nd_print_trunc(ndo); +} + +static void +print_attr_location_data(netdissect_options *ndo, + const u_char *data, u_int length, u_short attr_code _U_) +{ + uint16_t index; + + ND_TCHECK_LEN(data, length); + if (length < 3) + { + ND_PRINT("ERROR: length %u < 3", length); + return; + } + + index = GET_BE_U_2(data); + data += 2; + ND_PRINT("index %u, location", index); + + /* The Location field of the String field of the Location-Data attribute + * can have two completely different structures depending on the value of + * the Code field of a Location-Info attribute, which supposedly precedes + * the current attribute. Unfortunately, this choice of encoding makes it + * non-trivial to decode the Location field without preserving some state + * between the attributes. + */ + hex_and_ascii_print(ndo, "\n\t ", data, length - 2); + + return; + + trunc: + nd_print_trunc(ndo); +} + +static void +print_basic_location_policy_rules(netdissect_options *ndo, + const u_char *data, u_int length, u_short attr_code _U_) +{ + uint16_t flags; + + ND_TCHECK_LEN(data, length); + if (length < 10) + { + ND_PRINT("ERROR: length %u < 10", length); + return; + } + + flags = GET_BE_U_2(data); + data += 2; + ND_PRINT("flags [%s], ", bittok2str(blpr_bm, "none", flags)); + + ND_PRINT("retention expires "); + p_ntp_time(ndo, (const struct l_fixedpt *)data); + data += 8; + + if (length > 10) { + ND_PRINT(", note well \""); + (void)nd_printn(ndo, data, length - 10, NULL); + ND_PRINT("\""); + } return; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); } + /*************************************/ /* Print an attribute of 'secs since */ /* January 1, 1970 00:00 UTC' value */ @@ -782,28 +1268,52 @@ print_attr_address(netdissect_options *ndo, /*************************************/ static void print_attr_time(netdissect_options *ndo, - register const u_char *data, u_int length, u_short attr_code _U_) + const u_char *data, u_int length, u_short attr_code _U_) { time_t attr_time; char string[26]; if (length != 4) { - ND_PRINT((ndo, "ERROR: length %u != 4", length)); + ND_PRINT("ERROR: length %u != 4", length); return; } - ND_TCHECK2(data[0],4); - - attr_time = EXTRACT_32BITS(data); + attr_time = GET_BE_U_4(data); strlcpy(string, ctime(&attr_time), sizeof(string)); /* Get rid of the newline */ string[24] = '\0'; - ND_PRINT((ndo, "%.24s", string)); - return; + ND_PRINT("%.24s", string); +} - trunc: - ND_PRINT((ndo, "%s", tstr)); +static void +print_attr_vector64(netdissect_options *ndo, + register const u_char *data, u_int length, u_short attr_code _U_) +{ + uint64_t data_value, i; + const char *sep = ""; + + if (length != 8) + { + ND_PRINT("ERROR: length %u != 8", length); + return; + } + + ND_PRINT("["); + + data_value = GET_BE_U_8(data); + /* Print the 64-bit field in a format similar to bittok2str(), less + * flagging any unknown bits. This way it should be easier to replace + * the custom code with a library function later. + */ + for (i = 0; i < TAM_SIZE(mip6_feature_vector); i++) { + if (data_value & mip6_feature_vector[i].v) { + ND_PRINT("%s%s", sep, mip6_feature_vector[i].s); + sep = ", "; + } + } + + ND_PRINT("]"); } /***********************************/ @@ -815,54 +1325,53 @@ print_attr_time(netdissect_options *ndo, /***********************************/ static void print_attr_strange(netdissect_options *ndo, - register const u_char *data, u_int length, u_short attr_code) + const u_char *data, u_int length, u_short attr_code) { u_short len_data; + u_int error_cause_value; switch(attr_code) { case ARAP_PASS: if (length != 16) { - ND_PRINT((ndo, "ERROR: length %u != 16", length)); + ND_PRINT("ERROR: length %u != 16", length); return; } - ND_PRINT((ndo, "User_challenge (")); - ND_TCHECK2(data[0],8); + ND_PRINT("User_challenge ("); + ND_TCHECK_8(data); len_data = 8; PRINT_HEX(len_data, data); - ND_PRINT((ndo, ") User_resp(")); - ND_TCHECK2(data[0],8); + ND_PRINT(") User_resp("); + ND_TCHECK_8(data); len_data = 8; PRINT_HEX(len_data, data); - ND_PRINT((ndo, ")")); + ND_PRINT(")"); break; case ARAP_FEATURES: if (length != 14) { - ND_PRINT((ndo, "ERROR: length %u != 14", length)); + ND_PRINT("ERROR: length %u != 14", length); return; } - ND_TCHECK2(data[0],1); - if (*data) - ND_PRINT((ndo, "User can change password")); + if (GET_U_1(data)) + ND_PRINT("User can change password"); else - ND_PRINT((ndo, "User cannot change password")); + ND_PRINT("User cannot change password"); data++; - ND_TCHECK2(data[0],1); - ND_PRINT((ndo, ", Min password length: %d", *data)); + ND_PRINT(", Min password length: %u", GET_U_1(data)); data++; - ND_PRINT((ndo, ", created at: ")); - ND_TCHECK2(data[0],4); + ND_PRINT(", created at: "); + ND_TCHECK_4(data); len_data = 4; PRINT_HEX(len_data, data); - ND_PRINT((ndo, ", expires in: ")); - ND_TCHECK2(data[0],4); + ND_PRINT(", expires in: "); + ND_TCHECK_4(data); len_data = 4; PRINT_HEX(len_data, data); - ND_PRINT((ndo, ", Current Time: ")); - ND_TCHECK2(data[0],4); + ND_PRINT(", Current Time: "); + ND_TCHECK_4(data); len_data = 4; PRINT_HEX(len_data, data); break; @@ -870,95 +1379,106 @@ print_attr_strange(netdissect_options *ndo, case ARAP_CHALLENGE_RESP: if (length < 8) { - ND_PRINT((ndo, "ERROR: length %u != 8", length)); + ND_PRINT("ERROR: length %u != 8", length); return; } - ND_TCHECK2(data[0],8); + ND_TCHECK_8(data); len_data = 8; PRINT_HEX(len_data, data); break; + + case ERROR_CAUSE: + if (length != 4) + { + ND_PRINT("Error: length %u != 4", length); + return; + } + + error_cause_value = GET_BE_U_4(data); + ND_PRINT("Error cause %u: %s", error_cause_value, tok2str(errorcausetype, "Error-Cause %u not known", error_cause_value)); + break; } return; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); } static void radius_attrs_print(netdissect_options *ndo, - register const u_char *attr, u_int length) + const u_char *attr, u_int length) { - register const struct radius_attr *rad_attr = (const struct radius_attr *)attr; + const struct radius_attr *rad_attr = (const struct radius_attr *)attr; const char *attr_string; + uint8_t type, len; while (length > 0) { if (length < 2) goto trunc; - ND_TCHECK(*rad_attr); + ND_TCHECK_SIZE(rad_attr); - if (rad_attr->type > 0 && rad_attr->type < TAM_SIZE(attr_type)) - attr_string = attr_type[rad_attr->type].name; + type = GET_U_1(rad_attr->type); + len = GET_U_1(rad_attr->len); + if (type != 0 && type < TAM_SIZE(attr_type)) + attr_string = attr_type[type].name; else attr_string = "Unknown"; - if (rad_attr->len < 2) - { - ND_PRINT((ndo, "\n\t %s Attribute (%u), length: %u (bogus, must be >= 2)", + + ND_PRINT("\n\t %s Attribute (%u), length: %u", attr_string, - rad_attr->type, - rad_attr->len)); - return; + type, + len); + if (len < 2) + { + ND_PRINT(" (bogus, must be >= 2)"); + return; } - if (rad_attr->len > length) + if (len > length) { - ND_PRINT((ndo, "\n\t %s Attribute (%u), length: %u (bogus, goes past end of packet)", - attr_string, - rad_attr->type, - rad_attr->len)); + ND_PRINT(" (bogus, goes past end of packet)"); return; } - ND_PRINT((ndo, "\n\t %s Attribute (%u), length: %u, Value: ", - attr_string, - rad_attr->type, - rad_attr->len)); + ND_PRINT(", Value: "); - if (rad_attr->type < TAM_SIZE(attr_type)) + if (type < TAM_SIZE(attr_type)) { - if (rad_attr->len > 2) + if (len > 2) { - if ( attr_type[rad_attr->type].print_func ) - (*attr_type[rad_attr->type].print_func)( + if ( attr_type[type].print_func ) + (*attr_type[type].print_func)( ndo, ((const u_char *)(rad_attr+1)), - rad_attr->len - 2, rad_attr->type); + len - 2, type); } } /* do we also want to see a hex dump ? */ if (ndo->ndo_vflag> 1) - print_unknown_data(ndo, (const u_char *)rad_attr+2, "\n\t ", (rad_attr->len)-2); + print_unknown_data(ndo, (const u_char *)rad_attr+2, "\n\t ", (len)-2); - length-=(rad_attr->len); - rad_attr = (const struct radius_attr *)( ((const char *)(rad_attr))+rad_attr->len); + length-=(len); + rad_attr = (const struct radius_attr *)( ((const char *)(rad_attr))+len); } return; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); } void radius_print(netdissect_options *ndo, const u_char *dat, u_int length) { - register const struct radius_hdr *rad; + const struct radius_hdr *rad; u_int len, auth_idx; - ND_TCHECK2(*dat, MIN_RADIUS_LEN); + ndo->ndo_protocol = "radius"; + ND_TCHECK_LEN(dat, MIN_RADIUS_LEN); rad = (const struct radius_hdr *)dat; - len = EXTRACT_16BITS(&rad->len); + len = GET_BE_U_2(rad->len); if (len < MIN_RADIUS_LEN) { - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return; } @@ -966,22 +1486,22 @@ radius_print(netdissect_options *ndo, len = length; if (ndo->ndo_vflag < 1) { - ND_PRINT((ndo, "RADIUS, %s (%u), id: 0x%02x length: %u", - tok2str(radius_command_values,"Unknown Command",rad->code), - rad->code, - rad->id, - len)); + ND_PRINT("RADIUS, %s (%u), id: 0x%02x length: %u", + tok2str(radius_command_values,"Unknown Command",GET_U_1(rad->code)), + GET_U_1(rad->code), + GET_U_1(rad->id), + len); return; } else { - ND_PRINT((ndo, "RADIUS, length: %u\n\t%s (%u), id: 0x%02x, Authenticator: ", + ND_PRINT("RADIUS, length: %u\n\t%s (%u), id: 0x%02x, Authenticator: ", len, - tok2str(radius_command_values,"Unknown Command",rad->code), - rad->code, - rad->id)); + tok2str(radius_command_values,"Unknown Command",GET_U_1(rad->code)), + GET_U_1(rad->code), + GET_U_1(rad->id)); for(auth_idx=0; auth_idx < 16; auth_idx++) - ND_PRINT((ndo, "%02x", rad->auth[auth_idx])); + ND_PRINT("%02x", rad->auth[auth_idx]); } if (len > MIN_RADIUS_LEN) @@ -989,5 +1509,5 @@ radius_print(netdissect_options *ndo, return; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); } diff --git a/contrib/tcpdump/print-raw.c b/contrib/tcpdump/print-raw.c index 463aa41f64..9c6558fede 100644 --- a/contrib/tcpdump/print-raw.c +++ b/contrib/tcpdump/print-raw.c @@ -22,10 +22,10 @@ /* \summary: Raw IP printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" @@ -33,13 +33,13 @@ * The DLT_RAW packet has no header. It contains a raw IP packet. */ -u_int +void raw_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { + ndo->ndo_protocol = "raw"; + ndo->ndo_ll_hdr_len += 0; if (ndo->ndo_eflag) - ND_PRINT((ndo, "ip: ")); + ND_PRINT("ip: "); ipN_print(ndo, p, h->len); - - return (0); } diff --git a/contrib/tcpdump/print-resp.c b/contrib/tcpdump/print-resp.c index cc72124113..00a6e257d4 100644 --- a/contrib/tcpdump/print-resp.c +++ b/contrib/tcpdump/print-resp.c @@ -30,22 +30,18 @@ /* \summary: REdis Serialization Protocol (RESP) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include -#include -#include -#include #include "extract.h" -static const char tstr[] = " [|RESP]"; /* - * For information regarding RESP, see: http://redis.io/topics/protocol + * For information regarding RESP, see: https://redis.io/topics/protocol */ #define RESP_SIMPLE_STRING '+' @@ -54,22 +50,21 @@ static const char tstr[] = " [|RESP]"; #define RESP_BULK_STRING '$' #define RESP_ARRAY '*' -#define resp_print_empty(ndo) ND_PRINT((ndo, " empty")) -#define resp_print_null(ndo) ND_PRINT((ndo, " null")) -#define resp_print_length_too_large(ndo) ND_PRINT((ndo, " length too large")) -#define resp_print_length_negative(ndo) ND_PRINT((ndo, " length negative and not -1")) -#define resp_print_invalid(ndo) ND_PRINT((ndo, " invalid")) - -void resp_print(netdissect_options *, const u_char *, u_int); -static int resp_parse(netdissect_options *, register const u_char *, int); -static int resp_print_string_error_integer(netdissect_options *, register const u_char *, int); -static int resp_print_simple_string(netdissect_options *, register const u_char *, int); -static int resp_print_integer(netdissect_options *, register const u_char *, int); -static int resp_print_error(netdissect_options *, register const u_char *, int); -static int resp_print_bulk_string(netdissect_options *, register const u_char *, int); -static int resp_print_bulk_array(netdissect_options *, register const u_char *, int); -static int resp_print_inline(netdissect_options *, register const u_char *, int); -static int resp_get_length(netdissect_options *, register const u_char *, int, const u_char **); +#define resp_print_empty(ndo) ND_PRINT(" empty") +#define resp_print_null(ndo) ND_PRINT(" null") +#define resp_print_length_too_large(ndo) ND_PRINT(" length too large") +#define resp_print_length_negative(ndo) ND_PRINT(" length negative and not -1") +#define resp_print_invalid(ndo) ND_PRINT(" invalid") + +static int resp_parse(netdissect_options *, const u_char *, int); +static int resp_print_string_error_integer(netdissect_options *, const u_char *, int); +static int resp_print_simple_string(netdissect_options *, const u_char *, int); +static int resp_print_integer(netdissect_options *, const u_char *, int); +static int resp_print_error(netdissect_options *, const u_char *, int); +static int resp_print_bulk_string(netdissect_options *, const u_char *, int); +static int resp_print_bulk_array(netdissect_options *, const u_char *, int); +static int resp_print_inline(netdissect_options *, const u_char *, int); +static int resp_get_length(netdissect_options *, const u_char *, int, const u_char **); #define LCHECK2(_tot_len, _len) \ { \ @@ -90,8 +85,9 @@ static int resp_get_length(netdissect_options *, register const u_char *, int, c #define FIND_CRLF(_ptr, _len) \ for (;;) { \ LCHECK2(_len, 2); \ - ND_TCHECK2(*_ptr, 2); \ - if (*_ptr == '\r' && *(_ptr+1) == '\n') \ + ND_TCHECK_2(_ptr); \ + if (GET_U_1(_ptr) == '\r' && \ + GET_U_1(_ptr+1) == '\n') \ break; \ _ptr++; \ _len--; \ @@ -116,8 +112,8 @@ static int resp_get_length(netdissect_options *, register const u_char *, int, c #define FIND_CR_OR_LF(_ptr, _len) \ for (;;) { \ LCHECK(_len); \ - ND_TCHECK(*_ptr); \ - if (*_ptr == '\r' || *_ptr == '\n') \ + if (GET_U_1(_ptr) == '\r' || \ + GET_U_1(_ptr) == '\n') \ break; \ _ptr++; \ _len--; \ @@ -136,7 +132,7 @@ static int resp_get_length(netdissect_options *, register const u_char *, int, c /* \ * Have we hit the end of data? \ */ \ - if (_len == 0 || !ND_TTEST(*_ptr)) { \ + if (_len == 0 || !ND_TTEST_1(_ptr)) {\ /* \ * Yes. Have we seen a \r \ * or \n? \ @@ -152,7 +148,8 @@ static int resp_get_length(netdissect_options *, register const u_char *, int, c */ \ goto trunc; \ } \ - if (*_ptr != '\r' && *_ptr != '\n') \ + if (GET_U_1(_ptr) != '\r' && \ + GET_U_1(_ptr) != '\n') \ break; \ _found_cr_or_lf = 1; \ _ptr++; \ @@ -204,8 +201,8 @@ static int resp_get_length(netdissect_options *, register const u_char *, int, c * Assumes the data has already been verified as present. */ #define RESP_PRINT_SEGMENT(_ndo, _bp, _len) \ - ND_PRINT((_ndo, " \"")); \ - if (fn_printn(_ndo, _bp, _len, _ndo->ndo_snapend)) \ + ND_PRINT(" \""); \ + if (nd_printn(_ndo, _bp, _len, _ndo->ndo_snapend)) \ goto trunc; \ fn_print_char(_ndo, '"'); @@ -214,10 +211,11 @@ resp_print(netdissect_options *ndo, const u_char *bp, u_int length) { int ret_len = 0, length_cur = length; + ndo->ndo_protocol = "resp"; if(!bp || length <= 0) return; - ND_PRINT((ndo, ": RESP")); + ND_PRINT(": RESP"); while (length_cur > 0) { /* * This block supports redis pipelining. @@ -237,18 +235,17 @@ resp_print(netdissect_options *ndo, const u_char *bp, u_int length) return; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); } static int -resp_parse(netdissect_options *ndo, register const u_char *bp, int length) +resp_parse(netdissect_options *ndo, const u_char *bp, int length) { u_char op; int ret_len; LCHECK2(length, 1); - ND_TCHECK(*bp); - op = *bp; + op = GET_U_1(bp); /* bp now points to the op, so these routines must skip it */ switch(op) { @@ -272,22 +269,22 @@ trunc: } static int -resp_print_simple_string(netdissect_options *ndo, register const u_char *bp, int length) { +resp_print_simple_string(netdissect_options *ndo, const u_char *bp, int length) { return resp_print_string_error_integer(ndo, bp, length); } static int -resp_print_integer(netdissect_options *ndo, register const u_char *bp, int length) { +resp_print_integer(netdissect_options *ndo, const u_char *bp, int length) { return resp_print_string_error_integer(ndo, bp, length); } static int -resp_print_error(netdissect_options *ndo, register const u_char *bp, int length) { +resp_print_error(netdissect_options *ndo, const u_char *bp, int length) { return resp_print_string_error_integer(ndo, bp, length); } static int -resp_print_string_error_integer(netdissect_options *ndo, register const u_char *bp, int length) { +resp_print_string_error_integer(netdissect_options *ndo, const u_char *bp, int length) { int length_cur = length, len, ret_len; const u_char *bp_ptr; @@ -311,7 +308,7 @@ resp_print_string_error_integer(netdissect_options *ndo, register const u_char * * preceding the \r\n. That includes the opcode, so don't print * that. */ - len = (bp_ptr - bp); + len = ND_BYTES_BETWEEN(bp_ptr, bp); RESP_PRINT_SEGMENT(ndo, bp, len); ret_len = 1 /**/ + len /**/ + 2 /**/; @@ -322,7 +319,7 @@ trunc: } static int -resp_print_bulk_string(netdissect_options *ndo, register const u_char *bp, int length) { +resp_print_bulk_string(netdissect_options *ndo, const u_char *bp, int length) { int length_cur = length, string_len; /* bp points to the op; skip it */ @@ -337,7 +334,7 @@ resp_print_bulk_string(netdissect_options *ndo, register const u_char *bp, int l resp_print_empty(ndo); else { LCHECK2(length_cur, string_len); - ND_TCHECK2(*bp, string_len); + ND_TCHECK_LEN(bp, string_len); RESP_PRINT_SEGMENT(ndo, bp, string_len); bp += string_len; length_cur -= string_len; @@ -368,7 +365,7 @@ trunc: } static int -resp_print_bulk_array(netdissect_options *ndo, register const u_char *bp, int length) { +resp_print_bulk_array(netdissect_options *ndo, const u_char *bp, int length) { u_int length_cur = length; int array_len, i, ret_len; @@ -407,7 +404,7 @@ trunc: } static int -resp_print_inline(netdissect_options *ndo, register const u_char *bp, int length) { +resp_print_inline(netdissect_options *ndo, const u_char *bp, int length) { int length_cur = length; int len; const u_char *bp_ptr; @@ -434,9 +431,9 @@ resp_print_inline(netdissect_options *ndo, register const u_char *bp, int length /* * Found it; bp_ptr points to the \r or \n, so bp_ptr - bp is the - * Length of the line text that preceeds it. Print it. + * Length of the line text that precedes it. Print it. */ - len = (bp_ptr - bp); + len = ND_BYTES_BETWEEN(bp_ptr, bp); RESP_PRINT_SEGMENT(ndo, bp, len); /* @@ -454,7 +451,7 @@ trunc: } static int -resp_get_length(netdissect_options *ndo, register const u_char *bp, int len, const u_char **endp) +resp_get_length(netdissect_options *ndo, const u_char *bp, int len, const u_char **endp) { int result; u_char c; @@ -464,10 +461,9 @@ resp_get_length(netdissect_options *ndo, register const u_char *bp, int len, con if (len == 0) goto trunc; - ND_TCHECK(*bp); too_large = 0; neg = 0; - if (*bp == '-') { + if (GET_U_1(bp) == '-') { neg = 1; bp++; len--; @@ -478,8 +474,7 @@ resp_get_length(netdissect_options *ndo, register const u_char *bp, int len, con for (;;) { if (len == 0) goto trunc; - ND_TCHECK(*bp); - c = *bp; + c = GET_U_1(bp); if (!(c >= '0' && c <= '9')) { if (!saw_digit) { bp++; @@ -508,7 +503,7 @@ resp_get_length(netdissect_options *ndo, register const u_char *bp, int len, con * OK, we found a non-digit character. It should be a \r, followed * by a \n. */ - if (*bp != '\r') { + if (GET_U_1(bp) != '\r') { bp++; goto invalid; } @@ -516,8 +511,7 @@ resp_get_length(netdissect_options *ndo, register const u_char *bp, int len, con len--; if (len == 0) goto trunc; - ND_TCHECK(*bp); - if (*bp != '\n') { + if (GET_U_1(bp) != '\n') { bp++; goto invalid; } diff --git a/contrib/tcpdump/print-rip.c b/contrib/tcpdump/print-rip.c index cf661d03b3..fca534fb10 100644 --- a/contrib/tcpdump/print-rip.c +++ b/contrib/tcpdump/print-rip.c @@ -21,13 +21,13 @@ /* \summary: Routing Information Protocol (RIP) printer */ +/* specification: RFC 1058, RFC 2453, RFC 4822 */ + #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include - -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "addrtoname.h" @@ -35,12 +35,20 @@ #include "af.h" -static const char tstr[] = "[|rip]"; +/* + * RFC 1058 and RFC 2453 header of packet. + * + * 0 1 2 3 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Command (1) | Version (1) | unused | + * +---------------+---------------+-------------------------------+ + */ struct rip { - uint8_t rip_cmd; /* request/response */ - uint8_t rip_vers; /* protocol version # */ - uint8_t unused[2]; /* unused */ + nd_uint8_t rip_cmd; /* request/response */ + nd_uint8_t rip_vers; /* protocol version # */ + nd_byte unused[2]; /* unused */ }; #define RIPCMD_REQUEST 1 /* want info */ @@ -64,13 +72,46 @@ static const struct tok rip_cmd_values[] = { #define RIP_ROUTELEN 20 /* - * rfc 1723 + * First 4 bytes of all RIPv1/RIPv2 entries. + */ +struct rip_entry_header { + nd_uint16_t rip_family; + nd_uint16_t rip_tag; +}; + +/* + * RFC 1058 entry. + * + * 0 1 2 3 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Address Family Identifier (2) | must be zero (2) | + * +-------------------------------+-------------------------------+ + * | IP Address (4) | + * +---------------------------------------------------------------+ + * | must be zero (4) | + * +---------------------------------------------------------------+ + * | must be zero (4) | + * +---------------------------------------------------------------+ + * | Metric (4) | + * +---------------------------------------------------------------+ + */ +struct rip_netinfo_v1 { + nd_uint16_t rip_family; + nd_byte rip_mbz1[2]; + nd_ipv4 rip_dest; + nd_byte rip_mbz2[4]; + nd_byte rip_mbz3[4]; + nd_uint32_t rip_metric; /* cost of route */ +}; + + +/* + * RFC 2453 route entry * * 0 1 2 3 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Command (1) | Version (1) | unused | - * +---------------+---------------+-------------------------------+ * | Address Family Identifier (2) | Route Tag (2) | * +-------------------------------+-------------------------------+ * | IP Address (4) | @@ -84,125 +125,199 @@ static const struct tok rip_cmd_values[] = { * */ -struct rip_netinfo { - uint16_t rip_family; - uint16_t rip_tag; - uint32_t rip_dest; - uint32_t rip_dest_mask; - uint32_t rip_router; - uint32_t rip_metric; /* cost of route */ +struct rip_netinfo_v2 { + nd_uint16_t rip_family; + nd_uint16_t rip_tag; + nd_ipv4 rip_dest; + nd_uint32_t rip_dest_mask; + nd_ipv4 rip_router; + nd_uint32_t rip_metric; /* cost of route */ +}; + +/* + * RFC 2453 authentication entry + * + * 0 1 2 3 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | 0xFFFF | Authentication Type (2) | + * +-------------------------------+-------------------------------+ + * - Authentication (16) - + * +---------------------------------------------------------------+ + */ + +struct rip_auth_v2 { + nd_uint16_t rip_family; + nd_uint16_t rip_tag; + nd_byte rip_auth[16]; }; -static void -rip_entry_print_v1(netdissect_options *ndo, - register const struct rip_netinfo *ni) +/* + * RFC 4822 Cryptographic Authentication entry. + * + * 0 1 2 3 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | RIPv2 Packet Length | Key ID | Auth Data Len | + * +---------------+---------------+---------------+---------------+ + * | Sequence Number (non-decreasing) | + * +---------------+---------------+---------------+---------------+ + * | reserved must be zero | + * +---------------+---------------+---------------+---------------+ + * | reserved must be zero | + * +---------------+---------------+---------------+---------------+ + */ +struct rip_auth_crypto_v2 { + nd_uint16_t rip_packet_len; + nd_uint8_t rip_key_id; + nd_uint8_t rip_auth_data_len; + nd_uint32_t rip_seq_num; + nd_byte rip_mbz1[4]; + nd_byte rip_mbz2[4]; +}; + +static unsigned +rip_entry_print_v1(netdissect_options *ndo, const u_char *p, + unsigned remaining) { - register u_short family; + const struct rip_entry_header *eh = (const struct rip_entry_header *)p; + u_short family; + const struct rip_netinfo_v1 *ni = (const struct rip_netinfo_v1 *)p; /* RFC 1058 */ - family = EXTRACT_16BITS(&ni->rip_family); + if (remaining < RIP_ROUTELEN) + return (0); + ND_TCHECK_SIZE(ni); + family = GET_BE_U_2(ni->rip_family); if (family != BSD_AFNUM_INET && family != 0) { - ND_PRINT((ndo, "\n\t AFI %s, ", tok2str(bsd_af_values, "Unknown (%u)", family))); - print_unknown_data(ndo, (const uint8_t *)&ni->rip_family, "\n\t ", RIP_ROUTELEN); - return; + ND_PRINT("\n\t AFI %s, ", tok2str(bsd_af_values, "Unknown (%u)", family)); + print_unknown_data(ndo, p + sizeof(*eh), "\n\t ", RIP_ROUTELEN - sizeof(*eh)); + return (RIP_ROUTELEN); } - if (EXTRACT_16BITS(&ni->rip_tag) || - EXTRACT_32BITS(&ni->rip_dest_mask) || - EXTRACT_32BITS(&ni->rip_router)) { + if (GET_BE_U_2(ni->rip_mbz1) || + GET_BE_U_4(ni->rip_mbz2) || + GET_BE_U_4(ni->rip_mbz3)) { /* MBZ fields not zero */ - print_unknown_data(ndo, (const uint8_t *)&ni->rip_family, "\n\t ", RIP_ROUTELEN); - return; + print_unknown_data(ndo, p, "\n\t ", RIP_ROUTELEN); + return (RIP_ROUTELEN); } if (family == 0) { - ND_PRINT((ndo, "\n\t AFI 0, %s, metric: %u", - ipaddr_string(ndo, &ni->rip_dest), - EXTRACT_32BITS(&ni->rip_metric))); - return; + ND_PRINT("\n\t AFI 0, %s, metric: %u", + GET_IPADDR_STRING(ni->rip_dest), + GET_BE_U_4(ni->rip_metric)); + return (RIP_ROUTELEN); } /* BSD_AFNUM_INET */ - ND_PRINT((ndo, "\n\t %s, metric: %u", - ipaddr_string(ndo, &ni->rip_dest), - EXTRACT_32BITS(&ni->rip_metric))); + ND_PRINT("\n\t %s, metric: %u", + GET_IPADDR_STRING(ni->rip_dest), + GET_BE_U_4(ni->rip_metric)); + return (RIP_ROUTELEN); +trunc: + return 0; } static unsigned -rip_entry_print_v2(netdissect_options *ndo, - register const struct rip_netinfo *ni, const unsigned remaining) +rip_entry_print_v2(netdissect_options *ndo, const u_char *p, + unsigned remaining) { - register u_short family; + const struct rip_entry_header *eh = (const struct rip_entry_header *)p; + u_short family; + const struct rip_netinfo_v2 *ni; - family = EXTRACT_16BITS(&ni->rip_family); + if (remaining < sizeof(*eh)) + return (0); + ND_TCHECK_SIZE(eh); + family = GET_BE_U_2(eh->rip_family); if (family == 0xFFFF) { /* variable-sized authentication structures */ - uint16_t auth_type = EXTRACT_16BITS(&ni->rip_tag); + uint16_t auth_type = GET_BE_U_2(eh->rip_tag); + + p += sizeof(*eh); + remaining -= sizeof(*eh); if (auth_type == 2) { - register const u_char *p = (const u_char *)&ni->rip_dest; - u_int i = 0; - ND_PRINT((ndo, "\n\t Simple Text Authentication data: ")); - for (; i < RIP_AUTHLEN; p++, i++) - ND_PRINT((ndo, "%c", ND_ISPRINT(*p) ? *p : '.')); + ND_PRINT("\n\t Simple Text Authentication data: "); + nd_printjnp(ndo, p, RIP_AUTHLEN); } else if (auth_type == 3) { - ND_PRINT((ndo, "\n\t Auth header:")); - ND_PRINT((ndo, " Packet Len %u,", EXTRACT_16BITS((const uint8_t *)ni + 4))); - ND_PRINT((ndo, " Key-ID %u,", *((const uint8_t *)ni + 6))); - ND_PRINT((ndo, " Auth Data Len %u,", *((const uint8_t *)ni + 7))); - ND_PRINT((ndo, " SeqNo %u,", EXTRACT_32BITS(&ni->rip_dest_mask))); - ND_PRINT((ndo, " MBZ %u,", EXTRACT_32BITS(&ni->rip_router))); - ND_PRINT((ndo, " MBZ %u", EXTRACT_32BITS(&ni->rip_metric))); + const struct rip_auth_crypto_v2 *ch; + + ch = (const struct rip_auth_crypto_v2 *)p; + ND_TCHECK_SIZE(ch); + if (remaining < sizeof(*ch)) + return (0); + ND_PRINT("\n\t Auth header:"); + ND_PRINT(" Packet Len %u,", + GET_BE_U_2(ch->rip_packet_len)); + ND_PRINT(" Key-ID %u,", GET_U_1(ch->rip_key_id)); + ND_PRINT(" Auth Data Len %u,", + GET_U_1(ch->rip_auth_data_len)); + ND_PRINT(" SeqNo %u,", GET_BE_U_4(ch->rip_seq_num)); + ND_PRINT(" MBZ %u,", GET_BE_U_4(ch->rip_mbz1)); + ND_PRINT(" MBZ %u", GET_BE_U_4(ch->rip_mbz2)); } else if (auth_type == 1) { - ND_PRINT((ndo, "\n\t Auth trailer:")); - print_unknown_data(ndo, (const uint8_t *)&ni->rip_dest, "\n\t ", remaining); - return remaining; /* AT spans till the packet end */ + ND_PRINT("\n\t Auth trailer:"); + print_unknown_data(ndo, p, "\n\t ", remaining); + return (sizeof(*eh) + remaining); /* AT spans till the packet end */ } else { - ND_PRINT((ndo, "\n\t Unknown (%u) Authentication data:", - EXTRACT_16BITS(&ni->rip_tag))); - print_unknown_data(ndo, (const uint8_t *)&ni->rip_dest, "\n\t ", remaining); + ND_PRINT("\n\t Unknown (%u) Authentication data:", + auth_type); + print_unknown_data(ndo, p, "\n\t ", remaining); + return (sizeof(*eh) + remaining); /* we don't know how long this is, so we go to the packet end */ } } else if (family != BSD_AFNUM_INET && family != 0) { - ND_PRINT((ndo, "\n\t AFI %s", tok2str(bsd_af_values, "Unknown (%u)", family))); - print_unknown_data(ndo, (const uint8_t *)&ni->rip_tag, "\n\t ", RIP_ROUTELEN-2); + ND_PRINT("\n\t AFI %s", tok2str(bsd_af_values, "Unknown (%u)", family)); + print_unknown_data(ndo, p + sizeof(*eh), "\n\t ", RIP_ROUTELEN - sizeof(*eh)); } else { /* BSD_AFNUM_INET or AFI 0 */ - ND_PRINT((ndo, "\n\t AFI %s, %15s/%-2d, tag 0x%04x, metric: %u, next-hop: ", - tok2str(bsd_af_values, "%u", family), - ipaddr_string(ndo, &ni->rip_dest), - mask2plen(EXTRACT_32BITS(&ni->rip_dest_mask)), - EXTRACT_16BITS(&ni->rip_tag), - EXTRACT_32BITS(&ni->rip_metric))); - if (EXTRACT_32BITS(&ni->rip_router)) - ND_PRINT((ndo, "%s", ipaddr_string(ndo, &ni->rip_router))); + ni = (const struct rip_netinfo_v2 *)p; + ND_TCHECK_SIZE(ni); + if (remaining < sizeof(*ni)) + return (0); + ND_PRINT("\n\t AFI %s, %15s/%-2d, tag 0x%04x, metric: %u, next-hop: ", + tok2str(bsd_af_values, "%u", family), + GET_IPADDR_STRING(ni->rip_dest), + mask2plen(GET_BE_U_4(ni->rip_dest_mask)), + GET_BE_U_2(ni->rip_tag), + GET_BE_U_4(ni->rip_metric)); + if (GET_BE_U_4(ni->rip_router)) + ND_PRINT("%s", GET_IPADDR_STRING(ni->rip_router)); else - ND_PRINT((ndo, "self")); + ND_PRINT("self"); } - return sizeof (*ni); + return (RIP_ROUTELEN); +trunc: + return 0; } void rip_print(netdissect_options *ndo, - const u_char *dat, u_int length) + const u_char *dat, u_int length) { - register const struct rip *rp; - register const struct rip_netinfo *ni; - register u_int i, j; + const struct rip *rp; + uint8_t vers, cmd; + const u_char *p; + u_int len, routecount; + unsigned entry_size; + ndo->ndo_protocol = "rip"; if (ndo->ndo_snapend < dat) { - ND_PRINT((ndo, " %s", tstr)); + nd_print_trunc(ndo); return; } - i = ndo->ndo_snapend - dat; - if (i > length) - i = length; - if (i < sizeof(*rp)) { - ND_PRINT((ndo, " %s", tstr)); + len = ND_BYTES_AVAILABLE_AFTER(dat); + if (len > length) + len = length; + if (len < sizeof(*rp)) { + nd_print_trunc(ndo); return; } - i -= sizeof(*rp); + len -= sizeof(*rp); rp = (const struct rip *)dat; - ND_PRINT((ndo, "%sRIPv%u", - (ndo->ndo_vflag >= 1) ? "\n\t" : "", - rp->rip_vers)); + ND_TCHECK_SIZE(rp); + vers = GET_U_1(rp->rip_vers); + ND_PRINT("%sRIPv%u", + (ndo->ndo_vflag >= 1) ? "\n\t" : "", + vers); - switch (rp->rip_vers) { - case 0: + if (vers == 0) { /* * RFC 1058. * @@ -214,60 +329,94 @@ rip_print(netdissect_options *ndo, * * so perhaps we should just dump the packet, in hex. */ - print_unknown_data(ndo, (const uint8_t *)&rp->rip_cmd, "\n\t", length); - break; - default: - /* dump version and lets see if we know the commands name*/ - ND_PRINT((ndo, ", %s, length: %u", - tok2str(rip_cmd_values, - "unknown command (%u)", - rp->rip_cmd), - length)); - - if (ndo->ndo_vflag < 1) - return; - - switch (rp->rip_cmd) { - case RIPCMD_REQUEST: - case RIPCMD_RESPONSE: - j = length / sizeof(*ni); - ND_PRINT((ndo, ", routes: %u%s", j, rp->rip_vers == 2 ? " or less" : "")); - ni = (const struct rip_netinfo *)(rp + 1); - for (; i >= sizeof(*ni); ++ni) { - if (rp->rip_vers == 1) - { - rip_entry_print_v1(ndo, ni); - i -= sizeof(*ni); + print_unknown_data(ndo, (const uint8_t *)&rp->rip_cmd, "\n\t", length); + return; + } + + /* dump version and lets see if we know the commands name*/ + cmd = GET_U_1(rp->rip_cmd); + ND_PRINT(", %s, length: %u", + tok2str(rip_cmd_values, "unknown command (%u)", cmd), + length); + + if (ndo->ndo_vflag < 1) + return; + + switch (cmd) { + + case RIPCMD_REQUEST: + case RIPCMD_RESPONSE: + switch (vers) { + + case 1: + routecount = length / RIP_ROUTELEN; + ND_PRINT(", routes: %u", routecount); + p = (const u_char *)(rp + 1); + while (len != 0) { + entry_size = rip_entry_print_v1(ndo, p, len); + if (entry_size == 0) { + /* Error */ + nd_print_trunc(ndo); + break; } - else if (rp->rip_vers == 2) - i -= rip_entry_print_v2(ndo, ni, i); - else - break; + if (len < entry_size) { + ND_PRINT(" [remaining entries length %u < %u]", + len, entry_size); + nd_print_invalid(ndo); + break; + } + p += entry_size; + len -= entry_size; } - if (i) - ND_PRINT((ndo, "%s", tstr)); break; - case RIPCMD_TRACEOFF: - case RIPCMD_POLL: - case RIPCMD_POLLENTRY: + case 2: + routecount = length / RIP_ROUTELEN; + ND_PRINT(", routes: %u or less", routecount); + p = (const u_char *)(rp + 1); + while (len != 0) { + entry_size = rip_entry_print_v2(ndo, p, len); + if (entry_size == 0) { + /* Error */ + nd_print_trunc(ndo); + break; + } + if (len < entry_size) { + ND_PRINT(" [remaining entries length %u < %u]", + len, entry_size); + nd_print_invalid(ndo); + break; + } + p += entry_size; + len -= entry_size; + } break; - case RIPCMD_TRACEON: - /* fall through */ - default: - if (ndo->ndo_vflag <= 1) { - if(!print_unknown_data(ndo, (const uint8_t *)rp, "\n\t", length)) - return; - } - break; - } - /* do we want to see an additionally hexdump ? */ - if (ndo->ndo_vflag> 1) { - if(!print_unknown_data(ndo, (const uint8_t *)rp, "\n\t", length)) - return; - } - } -} + default: + ND_PRINT(", unknown version"); + break; + } + break; + case RIPCMD_TRACEOFF: + case RIPCMD_POLL: + case RIPCMD_POLLENTRY: + break; + case RIPCMD_TRACEON: + /* fall through */ + default: + if (ndo->ndo_vflag <= 1) { + if (!print_unknown_data(ndo, (const uint8_t *)rp, "\n\t", length)) + return; + } + break; + } + /* do we want to see an additionally hexdump ? */ + if (ndo->ndo_vflag> 1) { + if (!print_unknown_data(ndo, (const uint8_t *)rp, "\n\t", length)) + return; + } +trunc: + return; +} diff --git a/contrib/tcpdump/print-ripng.c b/contrib/tcpdump/print-ripng.c index 7113239ad5..c4f4ea3a1d 100644 --- a/contrib/tcpdump/print-ripng.c +++ b/contrib/tcpdump/print-ripng.c @@ -21,11 +21,13 @@ /* \summary: IPv6 Routing Information Protocol (RIPng) printer */ +/* specification: RFC 2080 */ + #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "addrtoname.h" @@ -65,119 +67,117 @@ #define RIP6_RESPONSE 2 struct netinfo6 { - struct in6_addr rip6_dest; - uint16_t rip6_tag; - uint8_t rip6_plen; - uint8_t rip6_metric; + nd_ipv6 rip6_dest; + nd_uint16_t rip6_tag; + nd_uint8_t rip6_plen; + nd_uint8_t rip6_metric; }; struct rip6 { - uint8_t rip6_cmd; - uint8_t rip6_vers; - uint8_t rip6_res1[2]; - union { - struct netinfo6 ru6_nets[1]; - char ru6_tracefile[1]; - } rip6un; -#define rip6_nets rip6un.ru6_nets -#define rip6_tracefile rip6un.ru6_tracefile + nd_uint8_t rip6_cmd; + nd_uint8_t rip6_vers; + nd_byte rip6_res1[2]; + struct netinfo6 rip6_nets[1]; }; #define HOPCNT_INFINITY6 16 -#if !defined(IN6_IS_ADDR_UNSPECIFIED) && !defined(_MSC_VER) /* MSVC inline */ -static int IN6_IS_ADDR_UNSPECIFIED(const struct in6_addr *addr) +static int ND_IN6_IS_ADDR_UNSPECIFIED(const nd_ipv6 *addr) { - static const struct in6_addr in6addr_any; /* :: */ - return (memcmp(addr, &in6addr_any, sizeof(*addr)) == 0); + static const nd_ipv6 in6addr_any_val = { 0 }; /* :: */ + return (memcmp(addr, &in6addr_any_val, sizeof(*addr)) == 0); } -#endif -static int -rip6_entry_print(netdissect_options *ndo, register const struct netinfo6 *ni, int metric) +static void +rip6_entry_print(netdissect_options *ndo, + const struct netinfo6 *ni, const u_int print_metric) { - int l; - l = ND_PRINT((ndo, "%s/%d", ip6addr_string(ndo, &ni->rip6_dest), ni->rip6_plen)); - if (ni->rip6_tag) - l += ND_PRINT((ndo, " [%d]", EXTRACT_16BITS(&ni->rip6_tag))); - if (metric) - l += ND_PRINT((ndo, " (%d)", ni->rip6_metric)); - return l; + uint16_t tag; + uint8_t metric; + + ND_PRINT("%s/%u", GET_IP6ADDR_STRING(ni->rip6_dest), + GET_U_1(ni->rip6_plen)); + tag = GET_BE_U_2(ni->rip6_tag); + if (tag) + ND_PRINT(" [%u]", tag); + metric = GET_U_1(ni->rip6_metric); + if (metric && print_metric) + ND_PRINT(" (%u)", metric); } void ripng_print(netdissect_options *ndo, const u_char *dat, unsigned int length) { - register const struct rip6 *rp = (const struct rip6 *)dat; - register const struct netinfo6 *ni; + const struct rip6 *rp = (const struct rip6 *)dat; + uint8_t cmd, vers; + const struct netinfo6 *ni; unsigned int length_left; u_int j; - ND_TCHECK(rp->rip6_cmd); - switch (rp->rip6_cmd) { + ndo->ndo_protocol = "ripng"; + vers = GET_U_1(rp->rip6_vers); + if (vers != RIP6_VERSION) { + ND_PRINT(" [vers %u]", vers); + goto invalid; + } + cmd = GET_U_1(rp->rip6_cmd); + switch (cmd) { case RIP6_REQUEST: length_left = length; if (length_left < (sizeof(struct rip6) - sizeof(struct netinfo6))) - goto trunc; + goto invalid; length_left -= (sizeof(struct rip6) - sizeof(struct netinfo6)); j = length_left / sizeof(*ni); if (j == 1) { - ND_TCHECK(rp->rip6_nets); - if (rp->rip6_nets->rip6_metric == HOPCNT_INFINITY6 - && IN6_IS_ADDR_UNSPECIFIED(&rp->rip6_nets->rip6_dest)) { - ND_PRINT((ndo, " ripng-req dump")); + if (GET_U_1(rp->rip6_nets->rip6_metric) == HOPCNT_INFINITY6 + && ND_IN6_IS_ADDR_UNSPECIFIED(&rp->rip6_nets->rip6_dest)) { + ND_PRINT(" ripng-req dump"); break; } } if (j * sizeof(*ni) != length_left) - ND_PRINT((ndo, " ripng-req %u[%u]:", j, length)); + ND_PRINT(" ripng-req %u[%u]:", j, length); else - ND_PRINT((ndo, " ripng-req %u:", j)); + ND_PRINT(" ripng-req %u:", j); for (ni = rp->rip6_nets; length_left >= sizeof(*ni); length_left -= sizeof(*ni), ++ni) { - ND_TCHECK(*ni); if (ndo->ndo_vflag > 1) - ND_PRINT((ndo, "\n\t")); + ND_PRINT("\n\t"); else - ND_PRINT((ndo, " ")); - rip6_entry_print(ndo, ni, 0); + ND_PRINT(" "); + rip6_entry_print(ndo, ni, FALSE); } if (length_left != 0) - goto trunc; + goto invalid; break; case RIP6_RESPONSE: length_left = length; if (length_left < (sizeof(struct rip6) - sizeof(struct netinfo6))) - goto trunc; + goto invalid; length_left -= (sizeof(struct rip6) - sizeof(struct netinfo6)); j = length_left / sizeof(*ni); if (j * sizeof(*ni) != length_left) - ND_PRINT((ndo, " ripng-resp %d[%u]:", j, length)); + ND_PRINT(" ripng-resp %u[%u]:", j, length); else - ND_PRINT((ndo, " ripng-resp %d:", j)); + ND_PRINT(" ripng-resp %u:", j); for (ni = rp->rip6_nets; length_left >= sizeof(*ni); length_left -= sizeof(*ni), ++ni) { - ND_TCHECK(*ni); if (ndo->ndo_vflag > 1) - ND_PRINT((ndo, "\n\t")); + ND_PRINT("\n\t"); else - ND_PRINT((ndo, " ")); - rip6_entry_print(ndo, ni, ni->rip6_metric); + ND_PRINT(" "); + rip6_entry_print(ndo, ni, TRUE); } if (length_left != 0) - goto trunc; + goto invalid; break; default: - ND_PRINT((ndo, " ripng-%d ?? %u", rp->rip6_cmd, length)); - break; + ND_PRINT(" ripng-%u ?? %u", cmd, length); + goto invalid; } - ND_TCHECK(rp->rip6_vers); - if (rp->rip6_vers != RIP6_VERSION) - ND_PRINT((ndo, " [vers %d]", rp->rip6_vers)); return; -trunc: - ND_PRINT((ndo, "[|ripng]")); - return; +invalid: + nd_print_invalid(ndo); } diff --git a/contrib/tcpdump/print-rpki-rtr.c b/contrib/tcpdump/print-rpki-rtr.c index 8e4c73f109..36be3998a3 100644 --- a/contrib/tcpdump/print-rpki-rtr.c +++ b/contrib/tcpdump/print-rpki-rtr.c @@ -20,18 +20,16 @@ /* specification: RFC 6810 */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include - -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" #include "addrtoname.h" -static const char tstr[] = "[|RPKI-RTR]"; /* * RPKI/Router PDU header @@ -40,27 +38,26 @@ static const char tstr[] = "[|RPKI-RTR]"; * 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 */ + nd_uint8_t version; /* Version number */ + nd_uint8_t pdu_type; /* PDU type */ union { - u_char session_id[2]; /* Session id */ - u_char error_code[2]; /* Error code */ + nd_uint16_t session_id; /* Session id */ + nd_uint16_t error_code; /* Error code */ } u; - u_char length[4]; + nd_uint32_t length; } 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]; + nd_uint8_t flags; + nd_uint8_t prefix_length; + nd_uint8_t max_length; + nd_uint8_t zero; + nd_ipv4 prefix; + nd_uint32_t as; } rpki_rtr_pdu_ipv4_prefix; /* @@ -68,12 +65,12 @@ typedef struct rpki_rtr_pdu_ipv4_prefix_ { */ 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]; + nd_uint8_t flags; + nd_uint8_t prefix_length; + nd_uint8_t max_length; + nd_uint8_t zero; + nd_ipv6 prefix; + nd_uint32_t as; } rpki_rtr_pdu_ipv6_prefix; /* @@ -81,7 +78,7 @@ typedef struct rpki_rtr_pdu_ipv6_prefix_ { */ typedef struct rpki_rtr_pdu_error_report_ { rpki_rtr_pdu pdu_header; - u_char encapsulated_pdu_length[4]; /* Encapsulated PDU length */ + nd_uint32_t encapsulated_pdu_length; /* Encapsulated PDU length */ /* Copy of Erroneous PDU (variable, optional) */ /* Length of Error Text (4 octets in network byte order) */ /* Arbitrary Text of Error Diagnostic Message (variable, optional) */ @@ -175,44 +172,43 @@ indent_string (u_int indent) * Print a single PDU. */ static u_int -rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, const u_int len, - const u_char recurse, const u_int indent) +rpki_rtr_pdu_print(netdissect_options *ndo, const u_char *tptr, const u_int len, + const u_char recurse, const u_int indent) { const rpki_rtr_pdu *pdu_header; u_int pdu_type, pdu_len, hexdump; const u_char *msg; /* Protocol Version */ - ND_TCHECK_8BITS(tptr); - if (*tptr != 0) { + if (GET_U_1(tptr) != 0) { /* Skip the rest of the input buffer because even if this is * a well-formed PDU of a future RPKI-Router protocol version * followed by a well-formed PDU of RPKI-Router protocol * version 0, there is no way to know exactly how to skip the * current PDU. */ - ND_PRINT((ndo, "%sRPKI-RTRv%u (unknown)", indent_string(8), *tptr)); + ND_PRINT("%sRPKI-RTRv%u (unknown)", indent_string(8), GET_U_1(tptr)); return len; } if (len < sizeof(rpki_rtr_pdu)) { - ND_PRINT((ndo, "(%u bytes is too few to decode)", len)); + ND_PRINT("(%u bytes is too few to decode)", len); goto invalid; } - ND_TCHECK2(*tptr, sizeof(rpki_rtr_pdu)); + ND_TCHECK_LEN(tptr, sizeof(rpki_rtr_pdu)); pdu_header = (const rpki_rtr_pdu *)tptr; - pdu_type = pdu_header->pdu_type; - pdu_len = EXTRACT_32BITS(pdu_header->length); + pdu_type = GET_U_1(pdu_header->pdu_type); + pdu_len = GET_BE_U_4(pdu_header->length); /* Do not check bounds with pdu_len yet, do it in the case blocks * below to make it possible to decode at least the beginning of * a truncated Error Report PDU or a truncated encapsulated PDU. */ hexdump = FALSE; - ND_PRINT((ndo, "%sRPKI-RTRv%u, %s PDU (%u), length: %u", + ND_PRINT("%sRPKI-RTRv%u, %s PDU (%u), length: %u", indent_string(8), - pdu_header->version, + GET_U_1(pdu_header->version), tok2str(rpki_rtr_pdu_values, "Unknown", pdu_type), - pdu_type, pdu_len)); + pdu_type, pdu_len); if (pdu_len < sizeof(rpki_rtr_pdu) || pdu_len > len) goto invalid; @@ -226,12 +222,11 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, const u_int len case RPKI_RTR_END_OF_DATA_PDU: if (pdu_len != sizeof(rpki_rtr_pdu) + 4) goto invalid; - ND_TCHECK2(*tptr, pdu_len); msg = (const u_char *)(pdu_header + 1); - ND_PRINT((ndo, "%sSession ID: 0x%04x, Serial: %u", + ND_PRINT("%sSession ID: 0x%04x, Serial: %u", indent_string(indent+2), - EXTRACT_16BITS(pdu_header->u.session_id), - EXTRACT_32BITS(msg))); + GET_BE_U_2(pdu_header->u.session_id), + GET_BE_U_4(msg)); break; /* @@ -252,24 +247,23 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, const u_int len if (pdu_len != sizeof(rpki_rtr_pdu)) goto invalid; /* no additional boundary to check */ - ND_PRINT((ndo, "%sSession ID: 0x%04x", + ND_PRINT("%sSession ID: 0x%04x", indent_string(indent+2), - EXTRACT_16BITS(pdu_header->u.session_id))); + GET_BE_U_2(pdu_header->u.session_id)); break; case RPKI_RTR_IPV4_PREFIX_PDU: { const rpki_rtr_pdu_ipv4_prefix *pdu; - if (pdu_len != sizeof(rpki_rtr_pdu) + 12) + if (pdu_len != sizeof(rpki_rtr_pdu_ipv4_prefix)) goto invalid; - ND_TCHECK2(*tptr, pdu_len); pdu = (const rpki_rtr_pdu_ipv4_prefix *)tptr; - ND_PRINT((ndo, "%sIPv4 Prefix %s/%u-%u, origin-as %u, flags 0x%02x", + ND_PRINT("%sIPv4 Prefix %s/%u-%u, origin-as %u, flags 0x%02x", indent_string(indent+2), - ipaddr_string(ndo, pdu->prefix), - pdu->prefix_length, pdu->max_length, - EXTRACT_32BITS(pdu->as), pdu->flags)); + GET_IPADDR_STRING(pdu->prefix), + GET_U_1(pdu->prefix_length), GET_U_1(pdu->max_length), + GET_BE_U_4(pdu->as), GET_U_1(pdu->flags)); } break; @@ -277,15 +271,14 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, const u_int len { const rpki_rtr_pdu_ipv6_prefix *pdu; - if (pdu_len != sizeof(rpki_rtr_pdu) + 24) + if (pdu_len != sizeof(rpki_rtr_pdu_ipv6_prefix)) goto invalid; - ND_TCHECK2(*tptr, pdu_len); pdu = (const rpki_rtr_pdu_ipv6_prefix *)tptr; - ND_PRINT((ndo, "%sIPv6 Prefix %s/%u-%u, origin-as %u, flags 0x%02x", + ND_PRINT("%sIPv6 Prefix %s/%u-%u, origin-as %u, flags 0x%02x", indent_string(indent+2), - ip6addr_string(ndo, pdu->prefix), - pdu->prefix_length, pdu->max_length, - EXTRACT_32BITS(pdu->as), pdu->flags)); + GET_IP6ADDR_STRING(pdu->prefix), + GET_U_1(pdu->prefix_length), GET_U_1(pdu->max_length), + GET_BE_U_4(pdu->as), GET_U_1(pdu->flags)); } break; @@ -298,19 +291,19 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, const u_int len /* Do not test for the "Length of Error Text" data element yet. */ if (pdu_len < tlen + 4) goto invalid; - ND_TCHECK2(*tptr, tlen + 4); + ND_TCHECK_LEN(tptr, tlen + 4); /* Safe up to and including the "Length of Encapsulated PDU" * data element, more data elements may be present. */ pdu = (const rpki_rtr_pdu_error_report *)tptr; - encapsulated_pdu_length = EXTRACT_32BITS(pdu->encapsulated_pdu_length); + encapsulated_pdu_length = GET_BE_U_4(pdu->encapsulated_pdu_length); tlen += 4; - error_code = EXTRACT_16BITS(pdu->pdu_header.u.error_code); - ND_PRINT((ndo, "%sError code: %s (%u), Encapsulated PDU length: %u", + error_code = GET_BE_U_2(pdu->pdu_header.u.error_code); + ND_PRINT("%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)); + error_code, encapsulated_pdu_length); if (encapsulated_pdu_length) { /* Section 5.10 of RFC 6810 says: @@ -328,10 +321,10 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, const u_int len if (pdu_len < tlen + encapsulated_pdu_length) goto invalid; if (! recurse) { - ND_TCHECK2(*tptr, tlen + encapsulated_pdu_length); + ND_TCHECK_LEN(tptr, tlen + encapsulated_pdu_length); } else { - ND_PRINT((ndo, "%s-----encapsulated PDU-----", indent_string(indent+4))); + ND_PRINT("%s-----encapsulated PDU-----", indent_string(indent+4)); rpki_rtr_pdu_print(ndo, tptr + tlen, encapsulated_pdu_length, 0, indent + 2); } @@ -340,7 +333,7 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, const u_int len if (pdu_len < tlen + 4) goto invalid; - ND_TCHECK2(*tptr, tlen + 4); + ND_TCHECK_LEN(tptr, tlen + 4); /* Safe up to and including the "Length of Error Text" data element, * one more data element may be present. */ @@ -348,22 +341,21 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, const u_int len /* * Extract, trail-zero and print the Error message. */ - text_length = EXTRACT_32BITS(tptr + tlen); + text_length = GET_BE_U_4(tptr + tlen); tlen += 4; if (text_length) { if (pdu_len < tlen + text_length) goto invalid; - /* fn_printn() makes the bounds check */ - ND_PRINT((ndo, "%sError text: ", indent_string(indent+2))); - if (fn_printn(ndo, tptr + tlen, text_length, ndo->ndo_snapend)) - goto trunc; + /* nd_printn() makes the bounds check */ + ND_PRINT("%sError text: ", indent_string(indent+2)); + (void)nd_printn(ndo, tptr + tlen, text_length, NULL); } } break; default: - ND_TCHECK2(*tptr, pdu_len); + ND_TCHECK_LEN(tptr, pdu_len); /* * Unknown data, please hexdump. @@ -378,19 +370,17 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, const u_int len return pdu_len; invalid: - ND_PRINT((ndo, "%s", istr)); - ND_TCHECK2(*tptr, len); - return len; -trunc: - ND_PRINT((ndo, "\n\t%s", tstr)); + nd_print_invalid(ndo); + ND_TCHECK_LEN(tptr, len); return len; } void -rpki_rtr_print(netdissect_options *ndo, register const u_char *pptr, register u_int len) +rpki_rtr_print(netdissect_options *ndo, const u_char *pptr, u_int len) { + ndo->ndo_protocol = "rpki_rtr"; if (!ndo->ndo_vflag) { - ND_PRINT((ndo, ", RPKI-RTR")); + ND_PRINT(", RPKI-RTR"); return; } while (len) { @@ -399,10 +389,3 @@ rpki_rtr_print(netdissect_options *ndo, register const u_char *pptr, register u_ pptr += pdu_len; } } - -/* - * 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 936b3ea72c..9803f75fe4 100644 --- a/contrib/tcpdump/print-rrcp.c +++ b/contrib/tcpdump/print-rrcp.c @@ -23,16 +23,32 @@ /* \summary: Realtek Remote Control Protocol (RRCP) printer */ +/* + * See, for example, section 8.20 "Realtek Remote Control Protocol" of + * + * http://realtek.info/pdf/rtl8324.pdf + * + * and section 7.22 "Realtek Remote Control Protocol" of + * + * http://realtek.info/pdf/rtl8326.pdf + * + * and this page on the OpenRRCP Wiki: + * + * http://openrrcp.org.ru/wiki/rrcp_protocol + * + * NOTE: none of them indicate the byte order of multi-byte fields in any + * obvious fashion. + */ + #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "addrtoname.h" #include "extract.h" -#include "ether.h" #define RRCP_OPCODE_MASK 0x7F /* 0x00 = hello, 0x01 = get, 0x02 = set */ #define RRCP_ISREPLY 0x80 /* 0 = request to switch, 0x80 = reply from switch */ @@ -72,7 +88,7 @@ static const struct tok opcode_values[] = { */ void rrcp_print(netdissect_options *ndo, - register const u_char *cp, + const u_char *cp, u_int length _U_, const struct lladdr_info *src, const struct lladdr_info *dst) @@ -80,50 +96,41 @@ rrcp_print(netdissect_options *ndo, uint8_t rrcp_proto; uint8_t rrcp_opcode; - ND_TCHECK(*(cp + RRCP_PROTO_OFFSET)); - rrcp_proto = *(cp + RRCP_PROTO_OFFSET); - ND_TCHECK(*(cp + RRCP_OPCODE_ISREPLY_OFFSET)); - rrcp_opcode = (*(cp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_OPCODE_MASK; + ndo->ndo_protocol = "rrcp"; + rrcp_proto = GET_U_1(cp + RRCP_PROTO_OFFSET); + rrcp_opcode = GET_U_1((cp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_OPCODE_MASK; if (src != NULL && dst != NULL) { - ND_PRINT((ndo, "%s > %s, ", + ND_PRINT("%s > %s, ", (src->addr_string)(ndo, src->addr), - (dst->addr_string)(ndo, dst->addr))); + (dst->addr_string)(ndo, dst->addr)); } - ND_PRINT((ndo, "%s %s", + ND_PRINT("%s %s", tok2str(proto_values,"RRCP-0x%02x",rrcp_proto), - ((*(cp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY) ? "reply" : "query")); + ((GET_U_1(cp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY) ? "reply" : "query"); if (rrcp_proto==1){ - ND_PRINT((ndo, ": %s", - tok2str(opcode_values,"unknown opcode (0x%02x)",rrcp_opcode))); + ND_PRINT(": %s", + tok2str(opcode_values,"unknown opcode (0x%02x)",rrcp_opcode)); } if (rrcp_opcode==1 || rrcp_opcode==2){ - ND_TCHECK2(*(cp + RRCP_REG_ADDR_OFFSET), 6); - ND_PRINT((ndo, " addr=0x%04x, data=0x%08x", - EXTRACT_LE_16BITS(cp + RRCP_REG_ADDR_OFFSET), - EXTRACT_LE_32BITS(cp + RRCP_REG_DATA_OFFSET))); + ND_PRINT(" addr=0x%04x, data=0x%08x", + GET_LE_U_2(cp + RRCP_REG_ADDR_OFFSET), + GET_LE_U_4(cp + RRCP_REG_DATA_OFFSET)); } if (rrcp_proto==1){ - ND_TCHECK2(*(cp + RRCP_AUTHKEY_OFFSET), 2); - ND_PRINT((ndo, ", auth=0x%04x", - EXTRACT_16BITS(cp + RRCP_AUTHKEY_OFFSET))); + ND_PRINT(", auth=0x%04x", + GET_BE_U_2(cp + RRCP_AUTHKEY_OFFSET)); } if (rrcp_proto==1 && rrcp_opcode==0 && - ((*(cp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY)){ - ND_TCHECK2(*(cp + RRCP_VENDOR_ID_OFFSET), 4); - ND_PRINT((ndo, " downlink_port=%d, uplink_port=%d, uplink_mac=%s, vendor_id=%08x ,chip_id=%04x ", - *(cp + RRCP_DOWNLINK_PORT_OFFSET), - *(cp + RRCP_UPLINK_PORT_OFFSET), - etheraddr_string(ndo, cp + RRCP_UPLINK_MAC_OFFSET), - EXTRACT_32BITS(cp + RRCP_VENDOR_ID_OFFSET), - EXTRACT_16BITS(cp + RRCP_CHIP_ID_OFFSET))); + ((GET_U_1(cp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY)){ + ND_PRINT(" downlink_port=%u, uplink_port=%u, uplink_mac=%s, vendor_id=%08x ,chip_id=%04x ", + GET_U_1(cp + RRCP_DOWNLINK_PORT_OFFSET), + GET_U_1(cp + RRCP_UPLINK_PORT_OFFSET), + GET_ETHERADDR_STRING(cp + RRCP_UPLINK_MAC_OFFSET), + GET_BE_U_4(cp + RRCP_VENDOR_ID_OFFSET), + GET_BE_U_2(cp + RRCP_CHIP_ID_OFFSET)); }else if (rrcp_opcode==1 || rrcp_opcode==2 || rrcp_proto==2){ - ND_TCHECK2(*(cp + RRCP_COOKIE2_OFFSET), 4); - ND_PRINT((ndo, ", cookie=0x%08x%08x ", - EXTRACT_32BITS(cp + RRCP_COOKIE2_OFFSET), - EXTRACT_32BITS(cp + RRCP_COOKIE1_OFFSET))); + ND_PRINT(", cookie=0x%08x%08x ", + GET_BE_U_4(cp + RRCP_COOKIE2_OFFSET), + GET_BE_U_4(cp + RRCP_COOKIE1_OFFSET)); } - return; - -trunc: - ND_PRINT((ndo, "[|rrcp]")); } diff --git a/contrib/tcpdump/print-rsvp.c b/contrib/tcpdump/print-rsvp.c index 438761ea36..23b6d5a773 100644 --- a/contrib/tcpdump/print-rsvp.c +++ b/contrib/tcpdump/print-rsvp.c @@ -17,11 +17,13 @@ /* \summary: Resource ReSerVation Protocol (RSVP) printer */ +/* specification: RFC 2205 */ + #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "extract.h" @@ -31,7 +33,6 @@ #include "af.h" #include "signature.h" -static const char tstr[] = " [|rsvp]"; /* * RFC 2205 common header @@ -46,12 +47,12 @@ static const char tstr[] = " [|rsvp]"; */ struct rsvp_common_header { - uint8_t version_flags; - uint8_t msg_type; - uint8_t checksum[2]; - uint8_t ttl; - uint8_t reserved; - uint8_t length[2]; + nd_uint8_t version_flags; + nd_uint8_t msg_type; + nd_uint16_t checksum; + nd_uint8_t ttl; + nd_byte reserved[1]; + nd_uint16_t length; }; /* @@ -69,9 +70,9 @@ struct rsvp_common_header { */ struct rsvp_object_header { - uint8_t length[2]; - uint8_t class_num; - uint8_t ctype; + nd_uint16_t length; + nd_uint8_t class_num; + nd_uint8_t ctype; }; #define RSVP_VERSION 1 @@ -112,6 +113,13 @@ static const struct tok rsvp_header_flag_values[] = { { 0, NULL} }; +static const struct tok rsvp_obj_capability_flag_values[] = { + { 0x0004, "RecoveryPath Transmit Enabled" }, + { 0x0002, "RecoveryPath Desired" }, + { 0x0001, "RecoveryPath Srefresh Capable" }, + { 0, NULL} +}; + #define RSVP_OBJ_SESSION 1 /* rfc2205 */ #define RSVP_OBJ_RSVP_HOP 3 /* rfc2205, rfc3473 */ #define RSVP_OBJ_INTEGRITY 4 /* rfc2747 */ @@ -139,16 +147,17 @@ static const struct tok rsvp_header_flag_values[] = { #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_DETOUR 63 /* rfc4090 */ #define RSVP_OBJ_CLASSTYPE 66 /* rfc4124 */ #define RSVP_OBJ_CLASSTYPE_OLD 125 /* draft-ietf-tewg-diff-te-proto-07 */ #define RSVP_OBJ_SUGGESTED_LABEL 129 /* rfc3473 */ #define RSVP_OBJ_ACCEPT_LABEL_SET 130 /* rfc3473 */ #define RSVP_OBJ_RESTART_CAPABILITY 131 /* rfc3473 */ +#define RSVP_OBJ_CAPABILITY 134 /* rfc5063 */ #define RSVP_OBJ_NOTIFY_REQ 195 /* rfc3473 */ #define RSVP_OBJ_ADMIN_STATUS 196 /* rfc3473 */ #define RSVP_OBJ_PROPERTIES 204 /* juniper proprietary */ -#define RSVP_OBJ_FASTREROUTE 205 /* draft-ietf-mpls-rsvp-lsp-fastreroute-07 */ +#define RSVP_OBJ_FASTREROUTE 205 /* rfc4090 */ #define RSVP_OBJ_SESSION_ATTRIBUTE 207 /* rfc3209 */ #define RSVP_OBJ_GENERALIZED_UNI 229 /* OIF RSVP extensions UNI 1.0 Signaling, Rel. 2 */ #define RSVP_OBJ_CALL_ID 230 /* rfc3474 */ @@ -192,6 +201,7 @@ static const struct tok rsvp_obj_values[] = { { RSVP_OBJ_CALL_ID, "Call-ID" }, { RSVP_OBJ_CALL_OPS, "Call Capability" }, { RSVP_OBJ_RESTART_CAPABILITY, "Restart Capability" }, + { RSVP_OBJ_CAPABILITY, "Capability" }, { RSVP_OBJ_NOTIFY_REQ, "Notify Request" }, { RSVP_OBJ_PROTECTION, "Protection" }, { RSVP_OBJ_ADMIN_STATUS, "Administrative Status" }, @@ -279,6 +289,7 @@ static const struct tok rsvp_ctype_values[] = { { 256*RSVP_OBJ_ERROR_SPEC+RSVP_CTYPE_3, "IPv4 plus opt. TLVs" }, { 256*RSVP_OBJ_ERROR_SPEC+RSVP_CTYPE_4, "IPv6 plus opt. TLVs" }, { 256*RSVP_OBJ_RESTART_CAPABILITY+RSVP_CTYPE_1, "IPv4" }, + { 256*RSVP_OBJ_CAPABILITY+RSVP_CTYPE_1, "1" }, { 256*RSVP_OBJ_SESSION_ATTRIBUTE+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" }, { 256*RSVP_OBJ_FASTREROUTE+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" }, /* old style*/ { 256*RSVP_OBJ_FASTREROUTE+RSVP_CTYPE_1, "1" }, /* new style */ @@ -294,6 +305,14 @@ static const struct tok rsvp_ctype_values[] = { { 0, NULL} }; +/* + * XXX - this assumes a 16-byte digest, which is true for HMAC-MD5, but + * isn't necessarily the case for other hash algorithms. + * + * Unless I've missed something, there's nothing in RFC 2747 to indicate + * the hash algorithm being used, so it's presumably something set up + * out-of-band, or negotiated by other RSVP objects. + */ struct rsvp_obj_integrity_t { uint8_t flags; uint8_t res; @@ -322,6 +341,8 @@ struct rsvp_obj_frr_t { #define RSVP_OBJ_XRO_MASK_SUBOBJ(x) ((x)&0x7f) #define RSVP_OBJ_XRO_MASK_LOOSE(x) ((x)&0x80) +#define RSVP_OBJ_CAPABILITY_FLAGS_MASK 0x7U + #define RSVP_OBJ_XRO_RES 0 #define RSVP_OBJ_XRO_IPV4 1 #define RSVP_OBJ_XRO_IPV6 2 @@ -339,7 +360,7 @@ static const struct tok rsvp_obj_xro_values[] = { { 0, NULL} }; -/* draft-ietf-mpls-rsvp-lsp-fastreroute-07.txt */ +/* RFC4090 */ static const struct tok rsvp_obj_rro_flag_values[] = { { 0x01, "Local protection available" }, { 0x02, "Local protection in use" }, @@ -487,11 +508,11 @@ static const struct tok rsvp_obj_generalized_uni_values[] = { * it is called from various rsvp objects; * returns the amount of bytes being processed */ -static int +static u_int rsvp_intserv_print(netdissect_options *ndo, - const u_char *tptr, u_short obj_tlen) + const u_char *tptr, u_int obj_tlen) { - int parameter_id,parameter_length; + u_int parameter_id,parameter_length; union { float f; uint32_t i; @@ -499,16 +520,14 @@ rsvp_intserv_print(netdissect_options *ndo, if (obj_tlen < 4) return 0; - ND_TCHECK_8BITS(tptr); - parameter_id = *(tptr); - ND_TCHECK2(*(tptr + 2), 2); - parameter_length = EXTRACT_16BITS(tptr+2)<<2; /* convert wordcount to bytecount */ + parameter_id = GET_U_1(tptr); + parameter_length = GET_BE_U_2(tptr + 2)<<2; /* convert wordcount to bytecount */ - ND_PRINT((ndo, "\n\t Parameter ID: %s (%u), length: %u, Flags: [0x%02x]", + ND_PRINT("\n\t Parameter ID: %s (%u), length: %u, Flags: [0x%02x]", tok2str(rsvp_intserv_parameter_id_values,"unknown",parameter_id), parameter_id, parameter_length, - *(tptr + 1))); + GET_U_1(tptr + 1)); if (obj_tlen < parameter_length+4) return 0; @@ -523,8 +542,7 @@ rsvp_intserv_print(netdissect_options *ndo, * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ if (parameter_length == 4) { - ND_TCHECK2(*(tptr + 4), 4); - ND_PRINT((ndo, "\n\t\tIS hop count: %u", EXTRACT_32BITS(tptr + 4))); + ND_PRINT("\n\t\tIS hop count: %u", GET_BE_U_4(tptr + 4)); } break; @@ -537,9 +555,8 @@ rsvp_intserv_print(netdissect_options *ndo, * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ if (parameter_length == 4) { - ND_TCHECK2(*(tptr + 4), 4); - bw.i = EXTRACT_32BITS(tptr+4); - ND_PRINT((ndo, "\n\t\tPath b/w estimate: %.10g Mbps", bw.f / 125000)); + bw.i = GET_BE_U_4(tptr + 4); + ND_PRINT("\n\t\tPath b/w estimate: %.10g Mbps", bw.f / 125000); } break; @@ -552,12 +569,11 @@ rsvp_intserv_print(netdissect_options *ndo, * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ if (parameter_length == 4) { - ND_TCHECK2(*(tptr + 4), 4); - ND_PRINT((ndo, "\n\t\tMinimum path latency: ")); - if (EXTRACT_32BITS(tptr+4) == 0xffffffff) - ND_PRINT((ndo, "don't care")); + ND_PRINT("\n\t\tMinimum path latency: "); + if (GET_BE_U_4(tptr + 4) == 0xffffffff) + ND_PRINT("don't care"); else - ND_PRINT((ndo, "%u", EXTRACT_32BITS(tptr + 4))); + ND_PRINT("%u", GET_BE_U_4(tptr + 4)); } break; @@ -571,8 +587,7 @@ rsvp_intserv_print(netdissect_options *ndo, * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ if (parameter_length == 4) { - ND_TCHECK2(*(tptr + 4), 4); - ND_PRINT((ndo, "\n\t\tComposed MTU: %u bytes", EXTRACT_32BITS(tptr + 4))); + ND_PRINT("\n\t\tComposed MTU: %u bytes", GET_BE_U_4(tptr + 4)); } break; case 127: @@ -593,15 +608,17 @@ rsvp_intserv_print(netdissect_options *ndo, */ if (parameter_length == 20) { - ND_TCHECK2(*(tptr + 4), 20); - bw.i = EXTRACT_32BITS(tptr+4); - ND_PRINT((ndo, "\n\t\tToken Bucket Rate: %.10g Mbps", bw.f / 125000)); - bw.i = EXTRACT_32BITS(tptr+8); - ND_PRINT((ndo, "\n\t\tToken Bucket Size: %.10g bytes", bw.f)); - bw.i = EXTRACT_32BITS(tptr+12); - ND_PRINT((ndo, "\n\t\tPeak Data Rate: %.10g Mbps", bw.f / 125000)); - ND_PRINT((ndo, "\n\t\tMinimum Policed Unit: %u bytes", EXTRACT_32BITS(tptr + 16))); - ND_PRINT((ndo, "\n\t\tMaximum Packet Size: %u bytes", EXTRACT_32BITS(tptr + 20))); + ND_TCHECK_LEN(tptr + 4, 20); + bw.i = GET_BE_U_4(tptr + 4); + ND_PRINT("\n\t\tToken Bucket Rate: %.10g Mbps", bw.f / 125000); + bw.i = GET_BE_U_4(tptr + 8); + ND_PRINT("\n\t\tToken Bucket Size: %.10g bytes", bw.f); + bw.i = GET_BE_U_4(tptr + 12); + ND_PRINT("\n\t\tPeak Data Rate: %.10g Mbps", bw.f / 125000); + ND_PRINT("\n\t\tMinimum Policed Unit: %u bytes", + GET_BE_U_4(tptr + 16)); + ND_PRINT("\n\t\tMaximum Packet Size: %u bytes", + GET_BE_U_4(tptr + 20)); } break; @@ -617,10 +634,10 @@ rsvp_intserv_print(netdissect_options *ndo, */ if (parameter_length == 8) { - ND_TCHECK2(*(tptr + 4), 8); - bw.i = EXTRACT_32BITS(tptr+4); - ND_PRINT((ndo, "\n\t\tRate: %.10g Mbps", bw.f / 125000)); - ND_PRINT((ndo, "\n\t\tSlack Term: %u", EXTRACT_32BITS(tptr + 8))); + ND_TCHECK_8(tptr + 4); + bw.i = GET_BE_U_4(tptr + 4); + ND_PRINT("\n\t\tRate: %.10g Mbps", bw.f / 125000); + ND_PRINT("\n\t\tSlack Term: %u", GET_BE_U_4(tptr + 8)); } break; @@ -629,8 +646,7 @@ rsvp_intserv_print(netdissect_options *ndo, case 135: case 136: if (parameter_length == 4) { - ND_TCHECK2(*(tptr + 4), 4); - ND_PRINT((ndo, "\n\t\tValue: %u", EXTRACT_32BITS(tptr + 4))); + ND_PRINT("\n\t\tValue: %u", GET_BE_U_4(tptr + 4)); } break; @@ -641,7 +657,7 @@ rsvp_intserv_print(netdissect_options *ndo, return (parameter_length+4); /* header length 4 bytes */ trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return 0; } @@ -660,7 +676,7 @@ rsvp_clear_checksum(void *header) static int rsvp_obj_print(netdissect_options *ndo, const u_char *pptr, u_int plen, const u_char *tptr, - const char *ident, u_int tlen, + const char *indent, u_int tlen, const struct rsvp_common_header *rsvp_com_header) { const struct rsvp_object_header *rsvp_obj_header; @@ -670,55 +686,57 @@ rsvp_obj_print(netdissect_options *ndo, const struct rsvp_obj_frr_t *rsvp_obj_frr; } obj_ptr; - u_short rsvp_obj_len,rsvp_obj_ctype,obj_tlen,intserv_serv_tlen; - int hexdump,processed,padbytes,error_code,error_value,i,sigcheck; + u_short rsvp_obj_len,rsvp_obj_ctype,rsvp_obj_class_num; + u_int obj_tlen,intserv_serv_tlen; + int hexdump; + u_int processed,padbytes,error_code,error_value,i,sigcheck; union { float f; uint32_t i; } bw; - uint8_t namelen; + u_int namelen; u_int action, subchannel; while(tlen>=sizeof(struct rsvp_object_header)) { /* did we capture enough for fully decoding the object header ? */ - ND_TCHECK2(*tptr, sizeof(struct rsvp_object_header)); + ND_TCHECK_LEN(tptr, sizeof(struct rsvp_object_header)); rsvp_obj_header = (const struct rsvp_object_header *)tptr; - rsvp_obj_len=EXTRACT_16BITS(rsvp_obj_header->length); - rsvp_obj_ctype=rsvp_obj_header->ctype; + rsvp_obj_len=GET_BE_U_2(rsvp_obj_header->length); + rsvp_obj_ctype=GET_U_1(rsvp_obj_header->ctype); if(rsvp_obj_len % 4) { - ND_PRINT((ndo, "%sERROR: object header size %u not a multiple of 4", ident, rsvp_obj_len)); + ND_PRINT("%sERROR: object header size %u not a multiple of 4", indent, rsvp_obj_len); return -1; } if(rsvp_obj_len < sizeof(struct rsvp_object_header)) { - ND_PRINT((ndo, "%sERROR: object header too short %u < %lu", ident, rsvp_obj_len, - (unsigned long)sizeof(const struct rsvp_object_header))); + ND_PRINT("%sERROR: object header too short %u < %zu", indent, rsvp_obj_len, + sizeof(struct rsvp_object_header)); return -1; } - ND_PRINT((ndo, "%s%s Object (%u) Flags: [%s", - ident, + rsvp_obj_class_num = GET_U_1(rsvp_obj_header->class_num); + ND_PRINT("%s%s Object (%u) Flags: [%s", + indent, tok2str(rsvp_obj_values, "Unknown", - rsvp_obj_header->class_num), - rsvp_obj_header->class_num, - ((rsvp_obj_header->class_num) & 0x80) ? "ignore" : "reject")); - - if (rsvp_obj_header->class_num > 128) - ND_PRINT((ndo, " %s", - ((rsvp_obj_header->class_num) & 0x40) ? "and forward" : "silently")); - - ND_PRINT((ndo, " if unknown], Class-Type: %s (%u), length: %u", + rsvp_obj_class_num), + rsvp_obj_class_num, + (rsvp_obj_class_num & 0x80) ? + ((rsvp_obj_class_num & 0x40) ? "ignore and forward" : + "ignore silently") : + "reject"); + + ND_PRINT(" if unknown], Class-Type: %s (%u), length: %u", tok2str(rsvp_ctype_values, "Unknown", - ((rsvp_obj_header->class_num)<<8)+rsvp_obj_ctype), + (rsvp_obj_class_num<<8)+rsvp_obj_ctype), rsvp_obj_ctype, - rsvp_obj_len)); + rsvp_obj_len); if(tlen < rsvp_obj_len) { - ND_PRINT((ndo, "%sERROR: object goes past end of objects TLV", ident)); + ND_PRINT("%sERROR: object goes past end of objects TLV", indent); return -1; } @@ -726,85 +744,84 @@ rsvp_obj_print(netdissect_options *ndo, obj_tlen=rsvp_obj_len-sizeof(struct rsvp_object_header); /* did we capture enough for fully decoding the object ? */ - if (!ND_TTEST2(*tptr, rsvp_obj_len)) - return -1; + ND_TCHECK_LEN(tptr, rsvp_obj_len); hexdump=FALSE; - switch(rsvp_obj_header->class_num) { + switch(rsvp_obj_class_num) { case RSVP_OBJ_SESSION: switch(rsvp_obj_ctype) { case RSVP_CTYPE_IPV4: if (obj_tlen < 8) - return -1; - ND_PRINT((ndo, "%s IPv4 DestAddress: %s, Protocol ID: 0x%02x", - ident, - ipaddr_string(ndo, obj_tptr), - *(obj_tptr + sizeof(struct in_addr)))); - ND_PRINT((ndo, "%s Flags: [0x%02x], DestPort %u", - ident, - *(obj_tptr+5), - EXTRACT_16BITS(obj_tptr + 6))); + goto obj_tooshort; + ND_PRINT("%s IPv4 DestAddress: %s, Protocol ID: 0x%02x", + indent, + GET_IPADDR_STRING(obj_tptr), + GET_U_1(obj_tptr + sizeof(nd_ipv4))); + ND_PRINT("%s Flags: [0x%02x], DestPort %u", + indent, + GET_U_1((obj_tptr + 5)), + GET_BE_U_2(obj_tptr + 6)); obj_tlen-=8; obj_tptr+=8; break; case RSVP_CTYPE_IPV6: if (obj_tlen < 20) - return -1; - ND_PRINT((ndo, "%s IPv6 DestAddress: %s, Protocol ID: 0x%02x", - ident, - ip6addr_string(ndo, obj_tptr), - *(obj_tptr + sizeof(struct in6_addr)))); - ND_PRINT((ndo, "%s Flags: [0x%02x], DestPort %u", - ident, - *(obj_tptr+sizeof(struct in6_addr)+1), - EXTRACT_16BITS(obj_tptr + sizeof(struct in6_addr) + 2))); + goto obj_tooshort; + ND_PRINT("%s IPv6 DestAddress: %s, Protocol ID: 0x%02x", + indent, + GET_IP6ADDR_STRING(obj_tptr), + GET_U_1(obj_tptr + sizeof(nd_ipv6))); + ND_PRINT("%s Flags: [0x%02x], DestPort %u", + indent, + GET_U_1((obj_tptr + sizeof(nd_ipv6) + 1)), + GET_BE_U_2(obj_tptr + sizeof(nd_ipv6) + 2)); obj_tlen-=20; obj_tptr+=20; break; case RSVP_CTYPE_TUNNEL_IPV6: if (obj_tlen < 36) - return -1; - ND_PRINT((ndo, "%s IPv6 Tunnel EndPoint: %s, Tunnel ID: 0x%04x, Extended Tunnel ID: %s", - ident, - ip6addr_string(ndo, obj_tptr), - EXTRACT_16BITS(obj_tptr+18), - ip6addr_string(ndo, obj_tptr + 20))); + goto obj_tooshort; + ND_PRINT("%s IPv6 Tunnel EndPoint: %s, Tunnel ID: 0x%04x, Extended Tunnel ID: %s", + indent, + GET_IP6ADDR_STRING(obj_tptr), + GET_BE_U_2(obj_tptr + 18), + GET_IP6ADDR_STRING(obj_tptr + 20)); obj_tlen-=36; obj_tptr+=36; break; case RSVP_CTYPE_14: /* IPv6 p2mp LSP Tunnel */ if (obj_tlen < 26) - return -1; - ND_PRINT((ndo, "%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(ndo, obj_tptr + 8))); + goto obj_tooshort; + ND_PRINT("%s IPv6 P2MP LSP ID: 0x%08x, Tunnel ID: 0x%04x, Extended Tunnel ID: %s", + indent, + GET_BE_U_4(obj_tptr), + GET_BE_U_2(obj_tptr + 6), + GET_IP6ADDR_STRING(obj_tptr + 8)); obj_tlen-=26; obj_tptr+=26; break; case RSVP_CTYPE_13: /* IPv4 p2mp LSP Tunnel */ if (obj_tlen < 12) - return -1; - ND_PRINT((ndo, "%s IPv4 P2MP LSP ID: %s, Tunnel ID: 0x%04x, Extended Tunnel ID: %s", - ident, - ipaddr_string(ndo, obj_tptr), - EXTRACT_16BITS(obj_tptr+6), - ipaddr_string(ndo, obj_tptr + 8))); + goto obj_tooshort; + ND_PRINT("%s IPv4 P2MP LSP ID: %s, Tunnel ID: 0x%04x, Extended Tunnel ID: %s", + indent, + GET_IPADDR_STRING(obj_tptr), + GET_BE_U_2(obj_tptr + 6), + GET_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) - return -1; - ND_PRINT((ndo, "%s IPv4 Tunnel EndPoint: %s, Tunnel ID: 0x%04x, Extended Tunnel ID: %s", - ident, - ipaddr_string(ndo, obj_tptr), - EXTRACT_16BITS(obj_tptr+6), - ipaddr_string(ndo, obj_tptr + 8))); + goto obj_tooshort; + ND_PRINT("%s IPv4 Tunnel EndPoint: %s, Tunnel ID: 0x%04x, Extended Tunnel ID: %s", + indent, + GET_IPADDR_STRING(obj_tptr), + GET_BE_U_2(obj_tptr + 6), + GET_IPADDR_STRING(obj_tptr + 8)); obj_tlen-=12; obj_tptr+=12; break; @@ -816,22 +833,22 @@ rsvp_obj_print(netdissect_options *ndo, case RSVP_OBJ_CONFIRM: switch(rsvp_obj_ctype) { case RSVP_CTYPE_IPV4: - if (obj_tlen < sizeof(struct in_addr)) - return -1; - ND_PRINT((ndo, "%s IPv4 Receiver Address: %s", - ident, - ipaddr_string(ndo, obj_tptr))); - obj_tlen-=sizeof(struct in_addr); - obj_tptr+=sizeof(struct in_addr); + if (obj_tlen < sizeof(nd_ipv4)) + goto obj_tooshort; + ND_PRINT("%s IPv4 Receiver Address: %s", + indent, + GET_IPADDR_STRING(obj_tptr)); + obj_tlen-=sizeof(nd_ipv4); + obj_tptr+=sizeof(nd_ipv4); break; case RSVP_CTYPE_IPV6: - if (obj_tlen < sizeof(struct in6_addr)) - return -1; - ND_PRINT((ndo, "%s IPv6 Receiver Address: %s", - ident, - ip6addr_string(ndo, obj_tptr))); - obj_tlen-=sizeof(struct in6_addr); - obj_tptr+=sizeof(struct in6_addr); + if (obj_tlen < sizeof(nd_ipv6)) + goto obj_tooshort; + ND_PRINT("%s IPv6 Receiver Address: %s", + indent, + GET_IP6ADDR_STRING(obj_tptr)); + obj_tlen-=sizeof(nd_ipv6); + obj_tptr+=sizeof(nd_ipv6); break; default: hexdump=TRUE; @@ -841,22 +858,22 @@ rsvp_obj_print(netdissect_options *ndo, case RSVP_OBJ_NOTIFY_REQ: switch(rsvp_obj_ctype) { case RSVP_CTYPE_IPV4: - if (obj_tlen < sizeof(struct in_addr)) - return -1; - ND_PRINT((ndo, "%s IPv4 Notify Node Address: %s", - ident, - ipaddr_string(ndo, obj_tptr))); - obj_tlen-=sizeof(struct in_addr); - obj_tptr+=sizeof(struct in_addr); + if (obj_tlen < sizeof(nd_ipv4)) + goto obj_tooshort; + ND_PRINT("%s IPv4 Notify Node Address: %s", + indent, + GET_IPADDR_STRING(obj_tptr)); + obj_tlen-=sizeof(nd_ipv4); + obj_tptr+=sizeof(nd_ipv4); break; case RSVP_CTYPE_IPV6: - if (obj_tlen < sizeof(struct in6_addr)) - return-1; - ND_PRINT((ndo, "%s IPv6 Notify Node Address: %s", - ident, - ip6addr_string(ndo, obj_tptr))); - obj_tlen-=sizeof(struct in6_addr); - obj_tptr+=sizeof(struct in6_addr); + if (obj_tlen < sizeof(nd_ipv6)) + goto obj_tooshort; + ND_PRINT("%s IPv6 Notify Node Address: %s", + indent, + GET_IP6ADDR_STRING(obj_tptr)); + obj_tlen-=sizeof(nd_ipv6); + obj_tptr+=sizeof(nd_ipv6); break; default: hexdump=TRUE; @@ -870,29 +887,29 @@ rsvp_obj_print(netdissect_options *ndo, switch(rsvp_obj_ctype) { case RSVP_CTYPE_1: while(obj_tlen >= 4 ) { - ND_PRINT((ndo, "%s Label: %u", ident, EXTRACT_32BITS(obj_tptr))); + ND_PRINT("%s Label: %u", indent, GET_BE_U_4(obj_tptr)); obj_tlen-=4; obj_tptr+=4; } break; case RSVP_CTYPE_2: if (obj_tlen < 4) - return-1; - ND_PRINT((ndo, "%s Generalized Label: %u", - ident, - EXTRACT_32BITS(obj_tptr))); + goto obj_tooshort; + ND_PRINT("%s Generalized Label: %u", + indent, + GET_BE_U_4(obj_tptr)); obj_tlen-=4; obj_tptr+=4; break; case RSVP_CTYPE_3: if (obj_tlen < 12) - return-1; - ND_PRINT((ndo, "%s Waveband ID: %u%s Start Label: %u, Stop Label: %u", - ident, - EXTRACT_32BITS(obj_tptr), - ident, - EXTRACT_32BITS(obj_tptr+4), - EXTRACT_32BITS(obj_tptr + 8))); + goto obj_tooshort; + ND_PRINT("%s Waveband ID: %u%s Start Label: %u, Stop Label: %u", + indent, + GET_BE_U_4(obj_tptr), + indent, + GET_BE_U_4(obj_tptr + 4), + GET_BE_U_4(obj_tptr + 8)); obj_tlen-=12; obj_tptr+=12; break; @@ -905,13 +922,13 @@ rsvp_obj_print(netdissect_options *ndo, switch(rsvp_obj_ctype) { case RSVP_CTYPE_1: if (obj_tlen < 4) - return-1; - ND_PRINT((ndo, "%s Reservation Style: %s, Flags: [0x%02x]", - ident, + goto obj_tooshort; + ND_PRINT("%s Reservation Style: %s, Flags: [0x%02x]", + indent, tok2str(rsvp_resstyle_values, "Unknown", - EXTRACT_24BITS(obj_tptr+1)), - *(obj_tptr))); + GET_BE_U_3(obj_tptr + 1)), + GET_U_1(obj_tptr)); obj_tlen-=4; obj_tptr+=4; break; @@ -924,59 +941,59 @@ rsvp_obj_print(netdissect_options *ndo, switch(rsvp_obj_ctype) { case RSVP_CTYPE_IPV4: if (obj_tlen < 8) - return-1; - ND_PRINT((ndo, "%s Source Address: %s, Source Port: %u", - ident, - ipaddr_string(ndo, obj_tptr), - EXTRACT_16BITS(obj_tptr + 6))); + goto obj_tooshort; + ND_PRINT("%s Source Address: %s, Source Port: %u", + indent, + GET_IPADDR_STRING(obj_tptr), + GET_BE_U_2(obj_tptr + 6)); obj_tlen-=8; obj_tptr+=8; break; case RSVP_CTYPE_IPV6: if (obj_tlen < 20) - return-1; - ND_PRINT((ndo, "%s Source Address: %s, Source Port: %u", - ident, - ip6addr_string(ndo, obj_tptr), - EXTRACT_16BITS(obj_tptr + 18))); + goto obj_tooshort; + ND_PRINT("%s Source Address: %s, Source Port: %u", + indent, + GET_IP6ADDR_STRING(obj_tptr), + GET_BE_U_2(obj_tptr + 18)); obj_tlen-=20; obj_tptr+=20; break; case RSVP_CTYPE_13: /* IPv6 p2mp LSP tunnel */ if (obj_tlen < 40) - return-1; - ND_PRINT((ndo, "%s IPv6 Tunnel Sender Address: %s, LSP ID: 0x%04x" + goto obj_tooshort; + ND_PRINT("%s IPv6 Tunnel Sender Address: %s, LSP ID: 0x%04x" "%s Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x", - ident, - ip6addr_string(ndo, obj_tptr), - EXTRACT_16BITS(obj_tptr+18), - ident, - ip6addr_string(ndo, obj_tptr+20), - EXTRACT_16BITS(obj_tptr + 38))); + indent, + GET_IP6ADDR_STRING(obj_tptr), + GET_BE_U_2(obj_tptr + 18), + indent, + GET_IP6ADDR_STRING(obj_tptr+20), + GET_BE_U_2(obj_tptr + 38)); obj_tlen-=40; obj_tptr+=40; break; case RSVP_CTYPE_TUNNEL_IPV4: if (obj_tlen < 8) - return-1; - ND_PRINT((ndo, "%s IPv4 Tunnel Sender Address: %s, LSP-ID: 0x%04x", - ident, - ipaddr_string(ndo, obj_tptr), - EXTRACT_16BITS(obj_tptr + 6))); + goto obj_tooshort; + ND_PRINT("%s IPv4 Tunnel Sender Address: %s, LSP-ID: 0x%04x", + indent, + GET_IPADDR_STRING(obj_tptr), + GET_BE_U_2(obj_tptr + 6)); obj_tlen-=8; obj_tptr+=8; break; case RSVP_CTYPE_12: /* IPv4 p2mp LSP tunnel */ if (obj_tlen < 16) - return-1; - ND_PRINT((ndo, "%s IPv4 Tunnel Sender Address: %s, LSP ID: 0x%04x" + goto obj_tooshort; + ND_PRINT("%s IPv4 Tunnel Sender Address: %s, LSP ID: 0x%04x" "%s Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x", - ident, - ipaddr_string(ndo, obj_tptr), - EXTRACT_16BITS(obj_tptr+6), - ident, - ipaddr_string(ndo, obj_tptr+8), - EXTRACT_16BITS(obj_tptr + 12))); + indent, + GET_IPADDR_STRING(obj_tptr), + GET_BE_U_2(obj_tptr + 6), + indent, + GET_IPADDR_STRING(obj_tptr+8), + GET_BE_U_2(obj_tptr + 12)); obj_tlen-=16; obj_tptr+=16; break; @@ -989,71 +1006,72 @@ rsvp_obj_print(netdissect_options *ndo, switch(rsvp_obj_ctype) { case RSVP_CTYPE_1: while(obj_tlen >= 4 ) { - ND_PRINT((ndo, "%s L3 Protocol ID: %s", - ident, + ND_PRINT("%s L3 Protocol ID: %s", + indent, tok2str(ethertype_values, "Unknown Protocol (0x%04x)", - EXTRACT_16BITS(obj_tptr + 2)))); + GET_BE_U_2(obj_tptr + 2))); obj_tlen-=4; obj_tptr+=4; } break; case RSVP_CTYPE_2: if (obj_tlen < 12) - return-1; - ND_PRINT((ndo, "%s L3 Protocol ID: %s", - ident, + goto obj_tooshort; + ND_PRINT("%s L3 Protocol ID: %s", + indent, tok2str(ethertype_values, "Unknown Protocol (0x%04x)", - EXTRACT_16BITS(obj_tptr + 2)))); - ND_PRINT((ndo, ",%s merge capability",((*(obj_tptr + 4)) & 0x80) ? "no" : "" )); - ND_PRINT((ndo, "%s Minimum VPI/VCI: %u/%u", - ident, - (EXTRACT_16BITS(obj_tptr+4))&0xfff, - (EXTRACT_16BITS(obj_tptr + 6)) & 0xfff)); - ND_PRINT((ndo, "%s Maximum VPI/VCI: %u/%u", - ident, - (EXTRACT_16BITS(obj_tptr+8))&0xfff, - (EXTRACT_16BITS(obj_tptr + 10)) & 0xfff)); + GET_BE_U_2(obj_tptr + 2))); + ND_PRINT(",%s merge capability", + ((GET_U_1(obj_tptr + 4)) & 0x80) ? "no" : "" ); + ND_PRINT("%s Minimum VPI/VCI: %u/%u", + indent, + (GET_BE_U_2(obj_tptr + 4))&0xfff, + (GET_BE_U_2(obj_tptr + 6)) & 0xfff); + ND_PRINT("%s Maximum VPI/VCI: %u/%u", + indent, + (GET_BE_U_2(obj_tptr + 8))&0xfff, + (GET_BE_U_2(obj_tptr + 10)) & 0xfff); obj_tlen-=12; obj_tptr+=12; break; case RSVP_CTYPE_3: if (obj_tlen < 12) - return-1; - ND_PRINT((ndo, "%s L3 Protocol ID: %s", - ident, + goto obj_tooshort; + ND_PRINT("%s L3 Protocol ID: %s", + indent, tok2str(ethertype_values, "Unknown Protocol (0x%04x)", - EXTRACT_16BITS(obj_tptr + 2)))); - ND_PRINT((ndo, "%s Minimum/Maximum DLCI: %u/%u, %s%s bit DLCI", - ident, - (EXTRACT_32BITS(obj_tptr+4))&0x7fffff, - (EXTRACT_32BITS(obj_tptr+8))&0x7fffff, - (((EXTRACT_16BITS(obj_tptr+4)>>7)&3) == 0 ) ? "10" : "", - (((EXTRACT_16BITS(obj_tptr + 4) >> 7) & 3) == 2 ) ? "23" : "")); + GET_BE_U_2(obj_tptr + 2))); + ND_PRINT("%s Minimum/Maximum DLCI: %u/%u, %s%s bit DLCI", + indent, + (GET_BE_U_4(obj_tptr + 4))&0x7fffff, + (GET_BE_U_4(obj_tptr + 8))&0x7fffff, + (((GET_BE_U_2(obj_tptr + 4)>>7)&3) == 0 ) ? "10" : "", + (((GET_BE_U_2(obj_tptr + 4) >> 7) & 3) == 2 ) ? "23" : ""); obj_tlen-=12; obj_tptr+=12; break; case RSVP_CTYPE_4: if (obj_tlen < 4) - return-1; - ND_PRINT((ndo, "%s LSP Encoding Type: %s (%u)", - ident, + goto obj_tooshort; + ND_PRINT("%s LSP Encoding Type: %s (%u)", + indent, tok2str(gmpls_encoding_values, "Unknown", - *obj_tptr), - *obj_tptr)); - ND_PRINT((ndo, "%s Switching Type: %s (%u), Payload ID: %s (0x%04x)", - ident, + GET_U_1(obj_tptr)), + GET_U_1(obj_tptr)); + ND_PRINT("%s Switching Type: %s (%u), Payload ID: %s (0x%04x)", + indent, tok2str(gmpls_switch_cap_values, "Unknown", - *(obj_tptr+1)), - *(obj_tptr+1), + GET_U_1((obj_tptr + 1))), + GET_U_1(obj_tptr + 1), tok2str(gmpls_payload_values, "Unknown", - EXTRACT_16BITS(obj_tptr+2)), - EXTRACT_16BITS(obj_tptr + 2))); + GET_BE_U_2(obj_tptr + 2)), + GET_BE_U_2(obj_tptr + 2)); obj_tlen-=4; obj_tptr+=4; break; @@ -1069,62 +1087,66 @@ rsvp_obj_print(netdissect_options *ndo, while(obj_tlen >= 4 ) { u_char length; - ND_TCHECK2(*obj_tptr, 4); - length = *(obj_tptr + 1); - ND_PRINT((ndo, "%s Subobject Type: %s, length %u", - ident, + ND_TCHECK_4(obj_tptr); + length = GET_U_1(obj_tptr + 1); + ND_PRINT("%s Subobject Type: %s, length %u", + indent, tok2str(rsvp_obj_xro_values, "Unknown %u", - RSVP_OBJ_XRO_MASK_SUBOBJ(*obj_tptr)), - length)); + RSVP_OBJ_XRO_MASK_SUBOBJ(GET_U_1(obj_tptr))), + length); + if (obj_tlen < length) { + ND_PRINT("%s ERROR: ERO subobject length > object length", indent); + break; + } if (length == 0) { /* prevent infinite loops */ - ND_PRINT((ndo, "%s ERROR: zero length ERO subtype", ident)); + ND_PRINT("%s ERROR: zero length ERO subtype", indent); break; } - switch(RSVP_OBJ_XRO_MASK_SUBOBJ(*obj_tptr)) { + switch(RSVP_OBJ_XRO_MASK_SUBOBJ(GET_U_1(obj_tptr))) { u_char prefix_length; case RSVP_OBJ_XRO_IPV4: if (length != 8) { - ND_PRINT((ndo, " ERROR: length != 8")); + ND_PRINT(" ERROR: length != 8"); goto invalid; } - ND_TCHECK2(*obj_tptr, 8); - prefix_length = *(obj_tptr+6); + ND_TCHECK_8(obj_tptr); + prefix_length = GET_U_1(obj_tptr + 6); if (prefix_length != 32) { - ND_PRINT((ndo, " ERROR: Prefix length %u != 32", - prefix_length)); + ND_PRINT(" ERROR: Prefix length %u != 32", + prefix_length); goto invalid; } - ND_PRINT((ndo, ", %s, %s/%u, Flags: [%s]", - RSVP_OBJ_XRO_MASK_LOOSE(*obj_tptr) ? "Loose" : "Strict", - ipaddr_string(ndo, obj_tptr+2), - *(obj_tptr+6), + ND_PRINT(", %s, %s/%u, Flags: [%s]", + RSVP_OBJ_XRO_MASK_LOOSE(GET_U_1(obj_tptr)) ? "Loose" : "Strict", + GET_IPADDR_STRING(obj_tptr+2), + GET_U_1((obj_tptr + 6)), bittok2str(rsvp_obj_rro_flag_values, "none", - *(obj_tptr + 7)))); /* rfc3209 says that this field is rsvd. */ + GET_U_1((obj_tptr + 7)))); /* rfc3209 says that this field is rsvd. */ break; case RSVP_OBJ_XRO_LABEL: if (length != 8) { - ND_PRINT((ndo, " ERROR: length != 8")); + ND_PRINT(" ERROR: length != 8"); goto invalid; } - ND_TCHECK2(*obj_tptr, 8); - ND_PRINT((ndo, ", Flags: [%s] (%#x), Class-Type: %s (%u), %u", + ND_TCHECK_8(obj_tptr); + ND_PRINT(", Flags: [%s] (%#x), Class-Type: %s (%u), %u", bittok2str(rsvp_obj_rro_label_flag_values, "none", - *(obj_tptr+2)), - *(obj_tptr+2), + GET_U_1((obj_tptr + 2))), + GET_U_1(obj_tptr + 2), tok2str(rsvp_ctype_values, "Unknown", - *(obj_tptr+3) + 256*RSVP_OBJ_RRO), - *(obj_tptr+3), - EXTRACT_32BITS(obj_tptr + 4))); + GET_U_1((obj_tptr + 3)) + (256 * RSVP_OBJ_RRO)), + GET_U_1((obj_tptr + 3)), + GET_BE_U_4(obj_tptr + 4)); } - obj_tlen-=*(obj_tptr+1); - obj_tptr+=*(obj_tptr+1); + obj_tlen-=length; + obj_tptr+=length; } break; default: @@ -1137,11 +1159,11 @@ rsvp_obj_print(netdissect_options *ndo, case RSVP_CTYPE_1: case RSVP_CTYPE_2: if (obj_tlen < 8) - return-1; - ND_PRINT((ndo, "%s Source Instance: 0x%08x, Destination Instance: 0x%08x", - ident, - EXTRACT_32BITS(obj_tptr), - EXTRACT_32BITS(obj_tptr + 4))); + goto obj_tooshort; + ND_PRINT("%s Source Instance: 0x%08x, Destination Instance: 0x%08x", + indent, + GET_BE_U_4(obj_tptr), + GET_BE_U_4(obj_tptr + 4)); obj_tlen-=8; obj_tptr+=8; break; @@ -1154,11 +1176,11 @@ rsvp_obj_print(netdissect_options *ndo, switch(rsvp_obj_ctype) { case RSVP_CTYPE_1: if (obj_tlen < 8) - return-1; - ND_PRINT((ndo, "%s Restart Time: %ums, Recovery Time: %ums", - ident, - EXTRACT_32BITS(obj_tptr), - EXTRACT_32BITS(obj_tptr + 4))); + goto obj_tooshort; + ND_PRINT("%s Restart Time: %ums, Recovery Time: %ums", + indent, + GET_BE_U_4(obj_tptr), + GET_BE_U_4(obj_tptr + 4)); obj_tlen-=8; obj_tptr+=8; break; @@ -1167,27 +1189,49 @@ rsvp_obj_print(netdissect_options *ndo, } break; + case RSVP_OBJ_CAPABILITY: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_1: + if (obj_tlen < 4) + goto obj_tooshort; + uint32_t unused_and_flags = GET_BE_U_4(obj_tptr); + if (unused_and_flags & ~RSVP_OBJ_CAPABILITY_FLAGS_MASK) + ND_PRINT("%s [reserved=0x%08x must be zero]", indent, + unused_and_flags & ~RSVP_OBJ_CAPABILITY_FLAGS_MASK); + ND_PRINT("%s Flags: [%s]", + indent, + bittok2str(rsvp_obj_capability_flag_values, + "none", + (unused_and_flags & RSVP_OBJ_CAPABILITY_FLAGS_MASK))); + obj_tlen-=4; + obj_tptr+=4; + break; + default: + hexdump=TRUE; + } + break; + case RSVP_OBJ_SESSION_ATTRIBUTE: switch(rsvp_obj_ctype) { case RSVP_CTYPE_TUNNEL_IPV4: if (obj_tlen < 4) - return-1; - namelen = *(obj_tptr+3); + goto obj_tooshort; + namelen = GET_U_1(obj_tptr + 3); if (obj_tlen < 4+namelen) - return-1; - ND_PRINT((ndo, "%s Session Name: ", ident)); + goto obj_tooshort; + ND_PRINT("%s Session Name: ", indent); for (i = 0; i < namelen; i++) - safeputchar(ndo, *(obj_tptr + 4 + i)); - ND_PRINT((ndo, "%s Setup Priority: %u, Holding Priority: %u, Flags: [%s] (%#x)", - ident, - (int)*obj_tptr, - (int)*(obj_tptr+1), + fn_print_char(ndo, GET_U_1(obj_tptr + 4 + i)); + ND_PRINT("%s Setup Priority: %u, Holding Priority: %u, Flags: [%s] (%#x)", + indent, + GET_U_1(obj_tptr), + GET_U_1(obj_tptr + 1), bittok2str(rsvp_session_attribute_flag_values, "none", - *(obj_tptr+2)), - *(obj_tptr + 2))); - obj_tlen-=4+*(obj_tptr+3); - obj_tptr+=4+*(obj_tptr+3); + GET_U_1((obj_tptr + 2))), + GET_U_1(obj_tptr + 2)); + obj_tlen-=4+namelen; + obj_tptr+=4+namelen; break; default: hexdump=TRUE; @@ -1196,12 +1240,12 @@ rsvp_obj_print(netdissect_options *ndo, case RSVP_OBJ_GENERALIZED_UNI: switch(rsvp_obj_ctype) { - int subobj_type,af,subobj_len,total_subobj_len; + u_int subobj_type,af,subobj_len,total_subobj_len; case RSVP_CTYPE_1: if (obj_tlen < 4) - return-1; + goto obj_tooshort; /* read variable length subobjects */ total_subobj_len = obj_tlen; @@ -1217,24 +1261,45 @@ rsvp_obj_print(netdissect_options *ndo, */ if (total_subobj_len < 4) goto invalid; - subobj_len = EXTRACT_16BITS(obj_tptr); - subobj_type = (EXTRACT_16BITS(obj_tptr+2))>>8; - af = (EXTRACT_16BITS(obj_tptr+2))&0x00FF; + subobj_len = GET_BE_U_2(obj_tptr); + subobj_type = (GET_BE_U_2(obj_tptr + 2))>>8; + af = (GET_BE_U_2(obj_tptr + 2))&0x00FF; - ND_PRINT((ndo, "%s Subobject Type: %s (%u), AF: %s (%u), length: %u", - ident, + ND_PRINT("%s Subobject Type: %s (%u), AF: %s (%u), length: %u", + indent, tok2str(rsvp_obj_generalized_uni_values, "Unknown", subobj_type), subobj_type, tok2str(af_values, "Unknown", af), af, - subobj_len)); + subobj_len); /* In addition to what is explained above, the same spec does not * explicitly say that the same Length field includes the 4-octet * sub-object header, but as long as this while loop implements it * as it does include, let's keep the check below consistent with * the rest of the code. + * + * XXX - RFC 3476 Section 3.1 says "The contents of these + * sub-objects are described in [8]", where [8] is + * UNI 1.0 Signaling Specification, The Optical + * Internetworking Forum. The URL they give for that + * document is + * + * http://www.oiforum.com/public/UNI_1.0_ia.html + * + * but that doesn't work; the new URL appears to be + * + * https://web.archive.org/web/20160401194747/http://www.oiforum.com/public/documents/OIF-UNI-01.0.pdf + * + * and *that* document, in section 12.5.2.3 + * "GENERALIZED_UNI Object (Class-Num=11bbbbbb (TBA))", + * says nothing about the length field in general, but + * some of the examples it gives in subsections have + * length field values that clearly includes the length + * of the sub-object header as well as the length of the + * value. */ - if(subobj_len < 4 || subobj_len > total_subobj_len) + if(subobj_len < 4 || subobj_len > total_subobj_len || + obj_tlen < subobj_len) goto invalid; switch(subobj_type) { @@ -1244,15 +1309,15 @@ rsvp_obj_print(netdissect_options *ndo, switch(af) { case AFNUM_INET: if (subobj_len < 8) - return -1; - ND_PRINT((ndo, "%s UNI IPv4 TNA address: %s", - ident, ipaddr_string(ndo, obj_tptr + 4))); + goto subobj_tooshort; + ND_PRINT("%s UNI IPv4 TNA address: %s", + indent, GET_IPADDR_STRING(obj_tptr + 4)); break; case AFNUM_INET6: if (subobj_len < 20) - return -1; - ND_PRINT((ndo, "%s UNI IPv6 TNA address: %s", - ident, ip6addr_string(ndo, obj_tptr + 4))); + goto subobj_tooshort; + ND_PRINT("%s UNI IPv6 TNA address: %s", + indent, GET_IP6ADDR_STRING(obj_tptr + 4)); break; case AFNUM_NSAP: if (subobj_len) { @@ -1264,7 +1329,7 @@ rsvp_obj_print(netdissect_options *ndo, break; case RSVP_GEN_UNI_SUBOBJ_DIVERSITY: - if (subobj_len) { + if (subobj_len > 4) { /* unless we have a TLV parser lets just hexdump */ hexdump=TRUE; } @@ -1272,24 +1337,24 @@ rsvp_obj_print(netdissect_options *ndo, case RSVP_GEN_UNI_SUBOBJ_EGRESS_LABEL: if (subobj_len < 16) { - return -1; + goto subobj_tooshort; } - ND_PRINT((ndo, "%s U-bit: %x, Label type: %u, Logical port id: %u, Label: %u", - ident, - ((EXTRACT_32BITS(obj_tptr+4))>>31), - ((EXTRACT_32BITS(obj_tptr+4))&0xFF), - EXTRACT_32BITS(obj_tptr+8), - EXTRACT_32BITS(obj_tptr + 12))); + ND_PRINT("%s U-bit: %x, Label type: %u, Logical port id: %u, Label: %u", + indent, + ((GET_BE_U_4(obj_tptr + 4))>>31), + ((GET_BE_U_4(obj_tptr + 4))&0xFF), + GET_BE_U_4(obj_tptr + 8), + GET_BE_U_4(obj_tptr + 12)); break; case RSVP_GEN_UNI_SUBOBJ_SERVICE_LEVEL: if (subobj_len < 8) { - return -1; + goto subobj_tooshort; } - ND_PRINT((ndo, "%s Service level: %u", - ident, (EXTRACT_32BITS(obj_tptr + 4)) >> 24)); + ND_PRINT("%s Service level: %u", + indent, (GET_BE_U_4(obj_tptr + 4)) >> 24); break; default: @@ -1300,11 +1365,6 @@ rsvp_obj_print(netdissect_options *ndo, obj_tptr+=subobj_len; obj_tlen+=subobj_len; } - - if (total_subobj_len) { - /* unless we have a TLV parser lets just hexdump */ - hexdump=TRUE; - } break; default: @@ -1317,11 +1377,11 @@ rsvp_obj_print(netdissect_options *ndo, case RSVP_CTYPE_3: /* fall through - FIXME add TLV parser */ case RSVP_CTYPE_IPV4: if (obj_tlen < 8) - return-1; - ND_PRINT((ndo, "%s Previous/Next Interface: %s, Logical Interface Handle: 0x%08x", - ident, - ipaddr_string(ndo, obj_tptr), - EXTRACT_32BITS(obj_tptr + 4))); + goto obj_tooshort; + ND_PRINT("%s Previous/Next Interface: %s, Logical Interface Handle: 0x%08x", + indent, + GET_IPADDR_STRING(obj_tptr), + GET_BE_U_4(obj_tptr + 4)); obj_tlen-=8; obj_tptr+=8; if (obj_tlen) @@ -1330,11 +1390,11 @@ rsvp_obj_print(netdissect_options *ndo, case RSVP_CTYPE_4: /* fall through - FIXME add TLV parser */ case RSVP_CTYPE_IPV6: if (obj_tlen < 20) - return-1; - ND_PRINT((ndo, "%s Previous/Next Interface: %s, Logical Interface Handle: 0x%08x", - ident, - ip6addr_string(ndo, obj_tptr), - EXTRACT_32BITS(obj_tptr + 16))); + goto obj_tooshort; + ND_PRINT("%s Previous/Next Interface: %s, Logical Interface Handle: 0x%08x", + indent, + GET_IP6ADDR_STRING(obj_tptr), + GET_BE_U_4(obj_tptr + 16)); obj_tlen-=20; obj_tptr+=20; hexdump=TRUE; /* unless we have a TLV parser lets just hexdump */ @@ -1348,10 +1408,10 @@ rsvp_obj_print(netdissect_options *ndo, switch(rsvp_obj_ctype) { case RSVP_CTYPE_1: if (obj_tlen < 4) - return-1; - ND_PRINT((ndo, "%s Refresh Period: %ums", - ident, - EXTRACT_32BITS(obj_tptr))); + goto obj_tooshort; + ND_PRINT("%s Refresh Period: %ums", + indent, + GET_BE_U_4(obj_tptr)); obj_tlen-=4; obj_tptr+=4; break; @@ -1367,22 +1427,22 @@ rsvp_obj_print(netdissect_options *ndo, switch(rsvp_obj_ctype) { case RSVP_CTYPE_2: if (obj_tlen < 4) - return-1; - ND_PRINT((ndo, "%s Msg-Version: %u, length: %u", - ident, - (*obj_tptr & 0xf0) >> 4, - EXTRACT_16BITS(obj_tptr + 2) << 2)); + goto obj_tooshort; + ND_PRINT("%s Msg-Version: %u, length: %u", + indent, + (GET_U_1(obj_tptr) & 0xf0) >> 4, + GET_BE_U_2(obj_tptr + 2) << 2); obj_tptr+=4; /* get to the start of the service header */ obj_tlen-=4; while (obj_tlen >= 4) { - intserv_serv_tlen=EXTRACT_16BITS(obj_tptr+2)<<2; - ND_PRINT((ndo, "%s Service Type: %s (%u), break bit %s set, Service length: %u", - ident, - tok2str(rsvp_intserv_service_type_values,"unknown",*(obj_tptr)), - *(obj_tptr), - (*(obj_tptr+1)&0x80) ? "" : "not", - intserv_serv_tlen)); + intserv_serv_tlen=GET_BE_U_2(obj_tptr + 2)<<2; + ND_PRINT("%s Service Type: %s (%u), break bit %sset, Service length: %u", + indent, + tok2str(rsvp_intserv_service_type_values,"unknown",GET_U_1((obj_tptr))), + GET_U_1(obj_tptr), + (GET_U_1(obj_tptr + 1)&0x80) ? "" : "not ", + intserv_serv_tlen); obj_tptr+=4; /* get to the start of the parameter list */ obj_tlen-=4; @@ -1406,79 +1466,79 @@ rsvp_obj_print(netdissect_options *ndo, switch(rsvp_obj_ctype) { case RSVP_CTYPE_IPV4: if (obj_tlen < 8) - return-1; - ND_PRINT((ndo, "%s Source Address: %s, Source Port: %u", - ident, - ipaddr_string(ndo, obj_tptr), - EXTRACT_16BITS(obj_tptr + 6))); + goto obj_tooshort; + ND_PRINT("%s Source Address: %s, Source Port: %u", + indent, + GET_IPADDR_STRING(obj_tptr), + GET_BE_U_2(obj_tptr + 6)); obj_tlen-=8; obj_tptr+=8; break; case RSVP_CTYPE_IPV6: if (obj_tlen < 20) - return-1; - ND_PRINT((ndo, "%s Source Address: %s, Source Port: %u", - ident, - ip6addr_string(ndo, obj_tptr), - EXTRACT_16BITS(obj_tptr + 18))); + goto obj_tooshort; + ND_PRINT("%s Source Address: %s, Source Port: %u", + indent, + GET_IP6ADDR_STRING(obj_tptr), + GET_BE_U_2(obj_tptr + 18)); obj_tlen-=20; obj_tptr+=20; break; case RSVP_CTYPE_3: if (obj_tlen < 20) - return-1; - ND_PRINT((ndo, "%s Source Address: %s, Flow Label: %u", - ident, - ip6addr_string(ndo, obj_tptr), - EXTRACT_24BITS(obj_tptr + 17))); + goto obj_tooshort; + ND_PRINT("%s Source Address: %s, Flow Label: %u", + indent, + GET_IP6ADDR_STRING(obj_tptr), + GET_BE_U_3(obj_tptr + 17)); obj_tlen-=20; obj_tptr+=20; break; case RSVP_CTYPE_TUNNEL_IPV6: if (obj_tlen < 20) - return-1; - ND_PRINT((ndo, "%s Source Address: %s, LSP-ID: 0x%04x", - ident, - ipaddr_string(ndo, obj_tptr), - EXTRACT_16BITS(obj_tptr + 18))); + goto obj_tooshort; + ND_PRINT("%s Source Address: %s, LSP-ID: 0x%04x", + indent, + GET_IPADDR_STRING(obj_tptr), + GET_BE_U_2(obj_tptr + 18)); obj_tlen-=20; obj_tptr+=20; break; case RSVP_CTYPE_13: /* IPv6 p2mp LSP tunnel */ if (obj_tlen < 40) - return-1; - ND_PRINT((ndo, "%s IPv6 Tunnel Sender Address: %s, LSP ID: 0x%04x" + goto obj_tooshort; + ND_PRINT("%s IPv6 Tunnel Sender Address: %s, LSP ID: 0x%04x" "%s Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x", - ident, - ip6addr_string(ndo, obj_tptr), - EXTRACT_16BITS(obj_tptr+18), - ident, - ip6addr_string(ndo, obj_tptr+20), - EXTRACT_16BITS(obj_tptr + 38))); + indent, + GET_IP6ADDR_STRING(obj_tptr), + GET_BE_U_2(obj_tptr + 18), + indent, + GET_IP6ADDR_STRING(obj_tptr+20), + GET_BE_U_2(obj_tptr + 38)); obj_tlen-=40; obj_tptr+=40; break; case RSVP_CTYPE_TUNNEL_IPV4: if (obj_tlen < 8) - return-1; - ND_PRINT((ndo, "%s Source Address: %s, LSP-ID: 0x%04x", - ident, - ipaddr_string(ndo, obj_tptr), - EXTRACT_16BITS(obj_tptr + 6))); + goto obj_tooshort; + ND_PRINT("%s Source Address: %s, LSP-ID: 0x%04x", + indent, + GET_IPADDR_STRING(obj_tptr), + GET_BE_U_2(obj_tptr + 6)); obj_tlen-=8; obj_tptr+=8; break; case RSVP_CTYPE_12: /* IPv4 p2mp LSP tunnel */ if (obj_tlen < 16) - return-1; - ND_PRINT((ndo, "%s IPv4 Tunnel Sender Address: %s, LSP ID: 0x%04x" + goto obj_tooshort; + ND_PRINT("%s IPv4 Tunnel Sender Address: %s, LSP ID: 0x%04x" "%s Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x", - ident, - ipaddr_string(ndo, obj_tptr), - EXTRACT_16BITS(obj_tptr+6), - ident, - ipaddr_string(ndo, obj_tptr+8), - EXTRACT_16BITS(obj_tptr + 12))); + indent, + GET_IPADDR_STRING(obj_tptr), + GET_BE_U_2(obj_tptr + 6), + indent, + GET_IPADDR_STRING(obj_tptr+8), + GET_BE_U_2(obj_tptr + 12)); obj_tlen-=16; obj_tptr+=16; break; @@ -1494,37 +1554,37 @@ rsvp_obj_print(netdissect_options *ndo, switch(rsvp_obj_ctype) { case RSVP_CTYPE_1: /* new style */ if (obj_tlen < sizeof(struct rsvp_obj_frr_t)) - return-1; - bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth); - ND_PRINT((ndo, "%s Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps", - ident, - (int)obj_ptr.rsvp_obj_frr->setup_prio, - (int)obj_ptr.rsvp_obj_frr->hold_prio, - (int)obj_ptr.rsvp_obj_frr->hop_limit, - bw.f * 8 / 1000000)); - ND_PRINT((ndo, "%s Include-any: 0x%08x, Exclude-any: 0x%08x, Include-all: 0x%08x", - ident, - EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->include_any), - EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->exclude_any), - EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->include_all))); + goto obj_tooshort; + bw.i = GET_BE_U_4(obj_ptr.rsvp_obj_frr->bandwidth); + ND_PRINT("%s Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps", + indent, + obj_ptr.rsvp_obj_frr->setup_prio, + obj_ptr.rsvp_obj_frr->hold_prio, + obj_ptr.rsvp_obj_frr->hop_limit, + bw.f * 8 / 1000000); + ND_PRINT("%s Include-any: 0x%08x, Exclude-any: 0x%08x, Include-all: 0x%08x", + indent, + GET_BE_U_4(obj_ptr.rsvp_obj_frr->include_any), + GET_BE_U_4(obj_ptr.rsvp_obj_frr->exclude_any), + GET_BE_U_4(obj_ptr.rsvp_obj_frr->include_all)); obj_tlen-=sizeof(struct rsvp_obj_frr_t); obj_tptr+=sizeof(struct rsvp_obj_frr_t); break; case RSVP_CTYPE_TUNNEL_IPV4: /* old style */ if (obj_tlen < 16) - return-1; - bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth); - ND_PRINT((ndo, "%s Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps", - ident, - (int)obj_ptr.rsvp_obj_frr->setup_prio, - (int)obj_ptr.rsvp_obj_frr->hold_prio, - (int)obj_ptr.rsvp_obj_frr->hop_limit, - bw.f * 8 / 1000000)); - ND_PRINT((ndo, "%s Include Colors: 0x%08x, Exclude Colors: 0x%08x", - ident, - EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->include_any), - EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->exclude_any))); + goto obj_tooshort; + bw.i = GET_BE_U_4(obj_ptr.rsvp_obj_frr->bandwidth); + ND_PRINT("%s Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps", + indent, + obj_ptr.rsvp_obj_frr->setup_prio, + obj_ptr.rsvp_obj_frr->hold_prio, + obj_ptr.rsvp_obj_frr->hop_limit, + bw.f * 8 / 1000000); + ND_PRINT("%s Include Colors: 0x%08x, Exclude Colors: 0x%08x", + indent, + GET_BE_U_4(obj_ptr.rsvp_obj_frr->include_any), + GET_BE_U_4(obj_ptr.rsvp_obj_frr->exclude_any)); obj_tlen-=16; obj_tptr+=16; break; @@ -1538,10 +1598,10 @@ rsvp_obj_print(netdissect_options *ndo, switch(rsvp_obj_ctype) { case RSVP_CTYPE_TUNNEL_IPV4: while(obj_tlen >= 8) { - ND_PRINT((ndo, "%s PLR-ID: %s, Avoid-Node-ID: %s", - ident, - ipaddr_string(ndo, obj_tptr), - ipaddr_string(ndo, obj_tptr + 4))); + ND_PRINT("%s PLR-ID: %s, Avoid-Node-ID: %s", + indent, + GET_IPADDR_STRING(obj_tptr), + GET_IPADDR_STRING(obj_tptr + 4)); obj_tlen-=8; obj_tptr+=8; } @@ -1555,10 +1615,11 @@ rsvp_obj_print(netdissect_options *ndo, case RSVP_OBJ_CLASSTYPE_OLD: /* fall through */ switch(rsvp_obj_ctype) { case RSVP_CTYPE_1: - ND_TCHECK_32BITS(obj_tptr); - ND_PRINT((ndo, "%s CT: %u", - ident, - EXTRACT_32BITS(obj_tptr) & 0x7)); + if (obj_tlen < 4) + goto obj_tooshort; + ND_PRINT("%s CT: %u", + indent, + GET_BE_U_4(obj_tptr) & 0x7); obj_tlen-=4; obj_tptr+=4; break; @@ -1572,30 +1633,30 @@ rsvp_obj_print(netdissect_options *ndo, case RSVP_CTYPE_3: /* fall through - FIXME add TLV parser */ case RSVP_CTYPE_IPV4: if (obj_tlen < 8) - return-1; - error_code=*(obj_tptr+5); - error_value=EXTRACT_16BITS(obj_tptr+6); - ND_PRINT((ndo, "%s Error Node Address: %s, Flags: [0x%02x]%s Error Code: %s (%u)", - ident, - ipaddr_string(ndo, obj_tptr), - *(obj_tptr+4), - ident, + goto obj_tooshort; + error_code=GET_U_1(obj_tptr + 5); + error_value=GET_BE_U_2(obj_tptr + 6); + ND_PRINT("%s Error Node Address: %s, Flags: [0x%02x]%s Error Code: %s (%u)", + indent, + GET_IPADDR_STRING(obj_tptr), + GET_U_1(obj_tptr + 4), + indent, tok2str(rsvp_obj_error_code_values,"unknown",error_code), - error_code)); + error_code); switch (error_code) { case RSVP_OBJ_ERROR_SPEC_CODE_ROUTING: - ND_PRINT((ndo, ", Error Value: %s (%u)", + ND_PRINT(", Error Value: %s (%u)", tok2str(rsvp_obj_error_code_routing_values,"unknown",error_value), - error_value)); + error_value); break; case RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE: /* fall through */ case RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE_OLD: - ND_PRINT((ndo, ", Error Value: %s (%u)", + ND_PRINT(", Error Value: %s (%u)", tok2str(rsvp_obj_error_code_diffserv_te_values,"unknown",error_value), - error_value)); + error_value); break; default: - ND_PRINT((ndo, ", Unknown Error Value (%u)", error_value)); + ND_PRINT(", Unknown Error Value (%u)", error_value); break; } obj_tlen-=8; @@ -1604,22 +1665,22 @@ rsvp_obj_print(netdissect_options *ndo, case RSVP_CTYPE_4: /* fall through - FIXME add TLV parser */ case RSVP_CTYPE_IPV6: if (obj_tlen < 20) - return-1; - error_code=*(obj_tptr+17); - error_value=EXTRACT_16BITS(obj_tptr+18); - ND_PRINT((ndo, "%s Error Node Address: %s, Flags: [0x%02x]%s Error Code: %s (%u)", - ident, - ip6addr_string(ndo, obj_tptr), - *(obj_tptr+16), - ident, + goto obj_tooshort; + error_code=GET_U_1(obj_tptr + 17); + error_value=GET_BE_U_2(obj_tptr + 18); + ND_PRINT("%s Error Node Address: %s, Flags: [0x%02x]%s Error Code: %s (%u)", + indent, + GET_IP6ADDR_STRING(obj_tptr), + GET_U_1(obj_tptr + 16), + indent, tok2str(rsvp_obj_error_code_values,"unknown",error_code), - error_code)); + error_code); switch (error_code) { case RSVP_OBJ_ERROR_SPEC_CODE_ROUTING: - ND_PRINT((ndo, ", Error Value: %s (%u)", + ND_PRINT(", Error Value: %s (%u)", tok2str(rsvp_obj_error_code_routing_values,"unknown",error_value), - error_value)); + error_value); break; default: break; @@ -1636,28 +1697,31 @@ rsvp_obj_print(netdissect_options *ndo, switch(rsvp_obj_ctype) { case RSVP_CTYPE_1: if (obj_tlen < 4) - return-1; - padbytes = EXTRACT_16BITS(obj_tptr+2); - ND_PRINT((ndo, "%s TLV count: %u, padding bytes: %u", - ident, - EXTRACT_16BITS(obj_tptr), - padbytes)); + goto obj_tooshort; + padbytes = GET_BE_U_2(obj_tptr + 2); + ND_PRINT("%s TLV count: %u, padding bytes: %u", + indent, + GET_BE_U_2(obj_tptr), + padbytes); obj_tlen-=4; obj_tptr+=4; /* loop through as long there is anything longer than the TLV header (2) */ while(obj_tlen >= 2 + padbytes) { - ND_PRINT((ndo, "%s %s TLV (0x%02x), length: %u", /* length includes header */ - ident, - tok2str(rsvp_obj_prop_tlv_values,"unknown",*obj_tptr), - *obj_tptr, - *(obj_tptr + 1))); - if (obj_tlen < *(obj_tptr+1)) - return-1; - if (*(obj_tptr+1) < 2) + ND_PRINT("%s %s TLV (0x%02x), length: %u", /* length includes header */ + indent, + tok2str(rsvp_obj_prop_tlv_values,"unknown",GET_U_1(obj_tptr)), + GET_U_1(obj_tptr), + GET_U_1(obj_tptr + 1)); + if (obj_tlen < GET_U_1(obj_tptr + 1)) + goto obj_tooshort; + if (GET_U_1(obj_tptr + 1) < 2) { + ND_PRINT("%sERROR: property TLV is too short", indent); return -1; - print_unknown_data(ndo, obj_tptr + 2, "\n\t\t", *(obj_tptr + 1) - 2); - obj_tlen-=*(obj_tptr+1); - obj_tptr+=*(obj_tptr+1); + } + print_unknown_data(ndo, obj_tptr + 2, "\n\t\t", + GET_U_1(obj_tptr + 1) - 2); + obj_tlen-=GET_U_1(obj_tptr + 1); + obj_tptr+=GET_U_1(obj_tptr + 1); } break; default: @@ -1671,20 +1735,20 @@ rsvp_obj_print(netdissect_options *ndo, switch(rsvp_obj_ctype) { case RSVP_CTYPE_1: case RSVP_CTYPE_2: - if (obj_tlen < 8) - return-1; - ND_PRINT((ndo, "%s Flags [0x%02x], epoch: %u", - ident, - *obj_tptr, - EXTRACT_24BITS(obj_tptr + 1))); + if (obj_tlen < 4) + goto obj_tooshort; + ND_PRINT("%s Flags [0x%02x], epoch: %u", + indent, + GET_U_1(obj_tptr), + GET_BE_U_3(obj_tptr + 1)); obj_tlen-=4; obj_tptr+=4; /* loop through as long there are no messages left */ while(obj_tlen >= 4) { - ND_PRINT((ndo, "%s Message-ID 0x%08x (%u)", - ident, - EXTRACT_32BITS(obj_tptr), - EXTRACT_32BITS(obj_tptr))); + ND_PRINT("%s Message-ID 0x%08x (%u)", + indent, + GET_BE_U_4(obj_tptr), + GET_BE_U_4(obj_tptr)); obj_tlen-=4; obj_tptr+=4; } @@ -1698,29 +1762,29 @@ rsvp_obj_print(netdissect_options *ndo, switch(rsvp_obj_ctype) { case RSVP_CTYPE_1: if (obj_tlen < sizeof(struct rsvp_obj_integrity_t)) - return-1; + goto obj_tooshort; obj_ptr.rsvp_obj_integrity = (const struct rsvp_obj_integrity_t *)obj_tptr; - ND_PRINT((ndo, "%s Key-ID 0x%04x%08x, Sequence 0x%08x%08x, Flags [%s]", - ident, - EXTRACT_16BITS(obj_ptr.rsvp_obj_integrity->key_id), - EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->key_id+2), - EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->sequence), - EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->sequence+4), + ND_PRINT("%s Key-ID 0x%04x%08x, Sequence 0x%08x%08x, Flags [%s]", + indent, + GET_BE_U_2(obj_ptr.rsvp_obj_integrity->key_id), + GET_BE_U_4(obj_ptr.rsvp_obj_integrity->key_id + 2), + GET_BE_U_4(obj_ptr.rsvp_obj_integrity->sequence), + GET_BE_U_4(obj_ptr.rsvp_obj_integrity->sequence + 4), bittok2str(rsvp_obj_integrity_flag_values, "none", - obj_ptr.rsvp_obj_integrity->flags))); - ND_PRINT((ndo, "%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))); + obj_ptr.rsvp_obj_integrity->flags)); + ND_PRINT("%s MD5-sum 0x%08x%08x%08x%08x ", + indent, + GET_BE_U_4(obj_ptr.rsvp_obj_integrity->digest), + GET_BE_U_4(obj_ptr.rsvp_obj_integrity->digest + 4), + GET_BE_U_4(obj_ptr.rsvp_obj_integrity->digest + 8), + GET_BE_U_4(obj_ptr.rsvp_obj_integrity->digest + 12)); sigcheck = signature_verify(ndo, pptr, plen, obj_ptr.rsvp_obj_integrity->digest, rsvp_clear_checksum, rsvp_com_header); - ND_PRINT((ndo, " (%s)", tok2str(signature_check_values, "Unknown", sigcheck))); + ND_PRINT(" (%s)", tok2str(signature_check_values, "Unknown", sigcheck)); obj_tlen+=sizeof(struct rsvp_obj_integrity_t); obj_tptr+=sizeof(struct rsvp_obj_integrity_t); @@ -1734,10 +1798,10 @@ rsvp_obj_print(netdissect_options *ndo, switch(rsvp_obj_ctype) { case RSVP_CTYPE_1: if (obj_tlen < 4) - return-1; - ND_PRINT((ndo, "%s Flags [%s]", ident, + goto obj_tooshort; + ND_PRINT("%s Flags [%s]", indent, bittok2str(rsvp_obj_admin_status_flag_values, "none", - EXTRACT_32BITS(obj_tptr)))); + GET_BE_U_4(obj_tptr))); obj_tlen-=4; obj_tptr+=4; break; @@ -1750,12 +1814,12 @@ rsvp_obj_print(netdissect_options *ndo, switch(rsvp_obj_ctype) { case RSVP_CTYPE_1: if (obj_tlen < 4) - return-1; - action = (EXTRACT_16BITS(obj_tptr)>>8); + goto obj_tooshort; + action = (GET_BE_U_2(obj_tptr)>>8); - ND_PRINT((ndo, "%s Action: %s (%u), Label type: %u", ident, + ND_PRINT("%s Action: %s (%u), Label type: %u", indent, tok2str(rsvp_obj_label_set_action_values, "Unknown", action), - action, ((EXTRACT_32BITS(obj_tptr) & 0x7F)))); + action, (GET_BE_U_4(obj_tptr) & 0x7F)); switch (action) { case LABEL_SET_INCLUSIVE_RANGE: @@ -1763,10 +1827,10 @@ rsvp_obj_print(netdissect_options *ndo, /* only a couple of subchannels are expected */ if (obj_tlen < 12) - return -1; - ND_PRINT((ndo, "%s Start range: %u, End range: %u", ident, - EXTRACT_32BITS(obj_tptr+4), - EXTRACT_32BITS(obj_tptr + 8))); + goto obj_tooshort; + ND_PRINT("%s Start range: %u, End range: %u", indent, + GET_BE_U_4(obj_tptr + 4), + GET_BE_U_4(obj_tptr + 8)); obj_tlen-=12; obj_tptr+=12; break; @@ -1776,8 +1840,8 @@ rsvp_obj_print(netdissect_options *ndo, obj_tptr+=4; subchannel = 1; while(obj_tlen >= 4 ) { - ND_PRINT((ndo, "%s Subchannel #%u: %u", ident, subchannel, - EXTRACT_32BITS(obj_tptr))); + ND_PRINT("%s Subchannel #%u: %u", indent, subchannel, + GET_BE_U_4(obj_tptr)); obj_tptr+=4; obj_tlen-=4; subchannel++; @@ -1788,23 +1852,24 @@ rsvp_obj_print(netdissect_options *ndo, default: hexdump=TRUE; } + break; case RSVP_OBJ_S2L: switch (rsvp_obj_ctype) { case RSVP_CTYPE_IPV4: if (obj_tlen < 4) - return-1; - ND_PRINT((ndo, "%s Sub-LSP destination address: %s", - ident, ipaddr_string(ndo, obj_tptr))); + goto obj_tooshort; + ND_PRINT("%s Sub-LSP destination address: %s", + indent, GET_IPADDR_STRING(obj_tptr)); obj_tlen-=4; obj_tptr+=4; break; case RSVP_CTYPE_IPV6: if (obj_tlen < 16) - return-1; - ND_PRINT((ndo, "%s Sub-LSP destination address: %s", - ident, ip6addr_string(ndo, obj_tptr))); + goto obj_tooshort; + ND_PRINT("%s Sub-LSP destination address: %s", + indent, GET_IP6ADDR_STRING(obj_tptr)); obj_tlen-=16; obj_tptr+=16; @@ -1812,6 +1877,7 @@ rsvp_obj_print(netdissect_options *ndo, default: hexdump=TRUE; } + break; /* * FIXME those are the defined objects that lack a decoder @@ -1836,69 +1902,79 @@ rsvp_obj_print(netdissect_options *ndo, tlen-=rsvp_obj_len; } return 0; +subobj_tooshort: + ND_PRINT("%sERROR: sub-object is too short", indent); + return -1; +obj_tooshort: + ND_PRINT("%sERROR: object is too short", indent); + return -1; invalid: - ND_PRINT((ndo, "%s", istr)); + nd_print_invalid(ndo); return -1; trunc: - ND_PRINT((ndo, "\n\t\t")); - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return -1; } void rsvp_print(netdissect_options *ndo, - register const u_char *pptr, register u_int len) + const u_char *pptr, u_int len) { const struct rsvp_common_header *rsvp_com_header; + uint8_t version_flags, msg_type; const u_char *tptr; u_short plen, tlen; + ndo->ndo_protocol = "rsvp"; tptr=pptr; rsvp_com_header = (const struct rsvp_common_header *)pptr; - ND_TCHECK(*rsvp_com_header); + ND_TCHECK_SIZE(rsvp_com_header); + version_flags = GET_U_1(rsvp_com_header->version_flags); /* * Sanity checking of the header. */ - if (RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags) != RSVP_VERSION) { - ND_PRINT((ndo, "ERROR: RSVP version %u packet not supported", - RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags))); + if (RSVP_EXTRACT_VERSION(version_flags) != RSVP_VERSION) { + ND_PRINT("ERROR: RSVP version %u packet not supported", + RSVP_EXTRACT_VERSION(version_flags)); return; } + msg_type = GET_U_1(rsvp_com_header->msg_type); + /* in non-verbose mode just lets print the basic Message Type*/ if (ndo->ndo_vflag < 1) { - ND_PRINT((ndo, "RSVPv%u %s Message, length: %u", - RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags), - tok2str(rsvp_msg_type_values, "unknown (%u)",rsvp_com_header->msg_type), - len)); + ND_PRINT("RSVPv%u %s Message, length: %u", + RSVP_EXTRACT_VERSION(version_flags), + tok2str(rsvp_msg_type_values, "unknown (%u)",msg_type), + len); return; } /* ok they seem to want to know everything - lets fully decode it */ - plen = tlen = EXTRACT_16BITS(rsvp_com_header->length); + plen = tlen = GET_BE_U_2(rsvp_com_header->length); - ND_PRINT((ndo, "\n\tRSVPv%u %s Message (%u), Flags: [%s], length: %u, ttl: %u, checksum: 0x%04x", - RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags), - tok2str(rsvp_msg_type_values, "unknown, type: %u",rsvp_com_header->msg_type), - rsvp_com_header->msg_type, - bittok2str(rsvp_header_flag_values,"none",RSVP_EXTRACT_FLAGS(rsvp_com_header->version_flags)), + ND_PRINT("\n\tRSVPv%u %s Message (%u), Flags: [%s], length: %u, ttl: %u, checksum: 0x%04x", + RSVP_EXTRACT_VERSION(version_flags), + tok2str(rsvp_msg_type_values, "unknown, type: %u",msg_type), + msg_type, + bittok2str(rsvp_header_flag_values,"none",RSVP_EXTRACT_FLAGS(version_flags)), tlen, - rsvp_com_header->ttl, - EXTRACT_16BITS(rsvp_com_header->checksum))); + GET_U_1(rsvp_com_header->ttl), + GET_BE_U_2(rsvp_com_header->checksum)); - if (tlen < sizeof(const struct rsvp_common_header)) { - ND_PRINT((ndo, "ERROR: common header too short %u < %lu", tlen, - (unsigned long)sizeof(const struct rsvp_common_header))); + if (tlen < sizeof(struct rsvp_common_header)) { + ND_PRINT("ERROR: common header too short %u < %zu", tlen, + sizeof(struct rsvp_common_header)); return; } - tptr+=sizeof(const struct rsvp_common_header); - tlen-=sizeof(const struct rsvp_common_header); + tptr+=sizeof(struct rsvp_common_header); + tlen-=sizeof(struct rsvp_common_header); - switch(rsvp_com_header->msg_type) { + switch(msg_type) { case RSVP_MSGTYPE_BUNDLE: /* @@ -1913,42 +1989,44 @@ rsvp_print(netdissect_options *ndo, subtptr=subpptr; rsvp_com_header = (const struct rsvp_common_header *)subpptr; - ND_TCHECK(*rsvp_com_header); + ND_TCHECK_SIZE(rsvp_com_header); + version_flags = GET_U_1(rsvp_com_header->version_flags); /* * Sanity checking of the header. */ - if (RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags) != RSVP_VERSION) { - ND_PRINT((ndo, "ERROR: RSVP version %u packet not supported", - RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags))); + if (RSVP_EXTRACT_VERSION(version_flags) != RSVP_VERSION) { + ND_PRINT("ERROR: RSVP version %u packet not supported", + RSVP_EXTRACT_VERSION(version_flags)); return; } - subplen = subtlen = EXTRACT_16BITS(rsvp_com_header->length); + subplen = subtlen = GET_BE_U_2(rsvp_com_header->length); - ND_PRINT((ndo, "\n\t RSVPv%u %s Message (%u), Flags: [%s], length: %u, ttl: %u, checksum: 0x%04x", - RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags), - tok2str(rsvp_msg_type_values, "unknown, type: %u",rsvp_com_header->msg_type), - rsvp_com_header->msg_type, - bittok2str(rsvp_header_flag_values,"none",RSVP_EXTRACT_FLAGS(rsvp_com_header->version_flags)), + msg_type = GET_U_1(rsvp_com_header->msg_type); + ND_PRINT("\n\t RSVPv%u %s Message (%u), Flags: [%s], length: %u, ttl: %u, checksum: 0x%04x", + RSVP_EXTRACT_VERSION(version_flags), + tok2str(rsvp_msg_type_values, "unknown, type: %u",msg_type), + msg_type, + bittok2str(rsvp_header_flag_values,"none",RSVP_EXTRACT_FLAGS(version_flags)), subtlen, - rsvp_com_header->ttl, - EXTRACT_16BITS(rsvp_com_header->checksum))); + GET_U_1(rsvp_com_header->ttl), + GET_BE_U_2(rsvp_com_header->checksum)); - if (subtlen < sizeof(const struct rsvp_common_header)) { - ND_PRINT((ndo, "ERROR: common header too short %u < %lu", subtlen, - (unsigned long)sizeof(const struct rsvp_common_header))); + if (subtlen < sizeof(struct rsvp_common_header)) { + ND_PRINT("ERROR: common header too short %u < %zu", subtlen, + sizeof(struct rsvp_common_header)); return; } if (tlen < subtlen) { - ND_PRINT((ndo, "ERROR: common header too large %u > %u", subtlen, - tlen)); + ND_PRINT("ERROR: common header too large %u > %u", subtlen, + tlen); return; } - subtptr+=sizeof(const struct rsvp_common_header); - subtlen-=sizeof(const struct rsvp_common_header); + subtptr+=sizeof(struct rsvp_common_header); + subtlen-=sizeof(struct rsvp_common_header); /* * Print all objects in the submessage. @@ -1956,8 +2034,8 @@ rsvp_print(netdissect_options *ndo, if (rsvp_obj_print(ndo, subpptr, subplen, subtptr, "\n\t ", subtlen, rsvp_com_header) == -1) return; - tptr+=subtlen+sizeof(const struct rsvp_common_header); - tlen-=subtlen+sizeof(const struct rsvp_common_header); + tptr+=subtlen+sizeof(struct rsvp_common_header); + tlen-=subtlen+sizeof(struct rsvp_common_header); } break; @@ -1987,6 +2065,5 @@ rsvp_print(netdissect_options *ndo, return; trunc: - ND_PRINT((ndo, "\n\t\t")); - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); } diff --git a/contrib/tcpdump/print-rt6.c b/contrib/tcpdump/print-rt6.c index 78a6a57be2..096a96286c 100644 --- a/contrib/tcpdump/print-rt6.c +++ b/contrib/tcpdump/print-rt6.c @@ -22,12 +22,10 @@ /* \summary: IPv6 routing header printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include - -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "addrtoname.h" @@ -36,58 +34,82 @@ #include "ip6.h" int -rt6_print(netdissect_options *ndo, register const u_char *bp, const u_char *bp2 _U_) +rt6_print(netdissect_options *ndo, const u_char *bp, const u_char *bp2 _U_) { - register const struct ip6_rthdr *dp; - register const struct ip6_rthdr0 *dp0; - register const u_char *ep; - int i, len; - register const struct in6_addr *addr; - - dp = (const struct ip6_rthdr *)bp; + const struct ip6_rthdr *dp; + const struct ip6_rthdr0 *dp0; + const struct ip6_srh *srh; + u_int i, len, type; + const u_char *p; - /* 'ep' points to the end of available data. */ - ep = ndo->ndo_snapend; + ndo->ndo_protocol = "rt6"; - ND_TCHECK(dp->ip6r_segleft); + nd_print_protocol_caps(ndo); + dp = (const struct ip6_rthdr *)bp; - len = dp->ip6r_len; - ND_PRINT((ndo, "srcrt (len=%d", dp->ip6r_len)); /*)*/ - ND_PRINT((ndo, ", type=%d", dp->ip6r_type)); - ND_PRINT((ndo, ", segleft=%d", dp->ip6r_segleft)); + len = GET_U_1(dp->ip6r_len); + ND_PRINT(" (len=%u", len); /*)*/ + type = GET_U_1(dp->ip6r_type); + ND_PRINT(", type=%u", type); + if (type == IPV6_RTHDR_TYPE_0) + ND_PRINT(" [Deprecated]"); + ND_PRINT(", segleft=%u", GET_U_1(dp->ip6r_segleft)); - switch (dp->ip6r_type) { + switch (type) { case IPV6_RTHDR_TYPE_0: case IPV6_RTHDR_TYPE_2: /* Mobile IPv6 ID-20 */ dp0 = (const struct ip6_rthdr0 *)dp; - ND_TCHECK(dp0->ip6r0_reserved); - if (EXTRACT_32BITS(dp0->ip6r0_reserved) || ndo->ndo_vflag) { - ND_PRINT((ndo, ", rsv=0x%0x", - EXTRACT_32BITS(&dp0->ip6r0_reserved))); + if (GET_BE_U_4(dp0->ip6r0_reserved) || ndo->ndo_vflag) { + ND_PRINT(", rsv=0x%0x", + GET_BE_U_4(dp0->ip6r0_reserved)); } - if (len % 2 == 1) - goto trunc; + if (len % 2 == 1) { + ND_PRINT(" (invalid length %u)", len); + goto invalid; + } len >>= 1; - addr = &dp0->ip6r0_addr[0]; + p = (const u_char *) dp0->ip6r0_addr; for (i = 0; i < len; i++) { - if ((const u_char *)(addr + 1) > ep) - goto trunc; + ND_PRINT(", [%u]%s", i, GET_IP6ADDR_STRING(p)); + p += 16; + } + /*(*/ + ND_PRINT(") "); + return((GET_U_1(dp0->ip6r0_len) + 1) << 3); + break; + case IPV6_RTHDR_TYPE_4: + srh = (const struct ip6_srh *)dp; + ND_PRINT(", last-entry=%u", GET_U_1(srh->srh_last_ent)); - ND_PRINT((ndo, ", [%d]%s", i, ip6addr_string(ndo, addr))); - addr++; + if (GET_U_1(srh->srh_flags) || ndo->ndo_vflag) { + ND_PRINT(", flags=0x%0x", + GET_U_1(srh->srh_flags)); + } + + ND_PRINT(", tag=%x", GET_BE_U_2(srh->srh_tag)); + + if (len % 2 == 1) { + ND_PRINT(" (invalid length %u)", len); + goto invalid; + } + len >>= 1; + p = (const u_char *) srh->srh_segments; + for (i = 0; i < len; i++) { + ND_PRINT(", [%u]%s", i, GET_IP6ADDR_STRING(p)); + p += 16; } /*(*/ - ND_PRINT((ndo, ") ")); - return((dp0->ip6r0_len + 1) << 3); + ND_PRINT(") "); + return((GET_U_1(srh->srh_len) + 1) << 3); break; default: - goto trunc; - break; + ND_PRINT(" (unknown type)"); + goto invalid; } - trunc: - ND_PRINT((ndo, "[|srcrt]")); +invalid: + nd_print_invalid(ndo); return -1; } diff --git a/contrib/tcpdump/print-rtsp.c b/contrib/tcpdump/print-rtsp.c index 54cc930ed0..626a5ed9c8 100644 --- a/contrib/tcpdump/print-rtsp.c +++ b/contrib/tcpdump/print-rtsp.c @@ -14,16 +14,12 @@ /* \summary: Real Time Streaming Protocol (RTSP) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include - -#include -#include +#include "netdissect-stdinc.h" #include "netdissect.h" -#include "extract.h" static const char *rtspcmds[] = { "DESCRIBE", @@ -43,5 +39,6 @@ static const char *rtspcmds[] = { void rtsp_print(netdissect_options *ndo, const u_char *pptr, u_int len) { - txtproto_print(ndo, pptr, len, "rtsp", rtspcmds, RESP_CODE_SECOND_TOKEN); + ndo->ndo_protocol = "rtsp"; + txtproto_print(ndo, pptr, len, rtspcmds, RESP_CODE_SECOND_TOKEN); } diff --git a/contrib/tcpdump/print-rx.c b/contrib/tcpdump/print-rx.c index bf2af0cb76..b8ee5a839b 100644 --- a/contrib/tcpdump/print-rx.c +++ b/contrib/tcpdump/print-rx.c @@ -36,13 +36,12 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif #include -#include #include -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "addrtoname.h" @@ -59,12 +58,13 @@ #define ERROR_RX_PORT 7006 /* Doesn't seem to be used */ #define BOS_RX_PORT 7007 -#define AFSNAMEMAX 256 #define AFSOPAQUEMAX 1024 +#define AFSNAMEMAX 256 /* Must be >= PRNAMEMAX + 1, VLNAMEMAX + 1, and 32 + 1 */ #define PRNAMEMAX 64 #define VLNAMEMAX 65 #define KANAMEMAX 64 #define BOSNAMEMAX 256 +#define USERNAMEMAX 1024 /* AFSOPAQUEMAX was used for this; does it need to be this big? */ #define PRSFS_READ 1 /* Read files */ #define PRSFS_WRITE 2 /* Write files */ @@ -112,15 +112,18 @@ struct rx_header { #define RX_MAXACKS 255 struct rx_ackPacket { - uint16_t bufferSpace; /* Number of packet buffers available */ - uint16_t maxSkew; /* Max diff between ack'd packet and */ + nd_uint16_t bufferSpace; /* Number of packet buffers available */ + nd_uint16_t maxSkew; /* Max diff between ack'd packet and */ /* highest packet received */ - uint32_t firstPacket; /* The first packet in ack list */ - uint32_t previousPacket; /* Previous packet recv'd (obsolete) */ - uint32_t serial; /* # of packet that prompted the ack */ - uint8_t reason; /* Reason for acknowledgement */ - uint8_t nAcks; /* Number of acknowledgements */ + nd_uint32_t firstPacket; /* The first packet in ack list */ + nd_uint32_t previousPacket; /* Previous packet recv'd (obsolete) */ + nd_uint32_t serial; /* # of packet that prompted the ack */ + nd_uint8_t reason; /* Reason for acknowledgement */ + nd_uint8_t nAcks; /* Number of acknowledgements */ + /* Followed by nAcks acknowledgments */ +#if 0 uint8_t acks[RX_MAXACKS]; /* Up to RX_MAXACKS acknowledgements */ +#endif }; /* @@ -145,8 +148,8 @@ static const struct tok rx_types[] = { }; static const struct double_tok { - int flag; /* Rx flag */ - int packetType; /* Packet type */ + uint32_t flag; /* Rx flag */ + uint32_t packetType; /* Packet type */ const char *s; /* Flag string */ } rx_flags[] = { { RX_CLIENT_INITIATED, 0, "client-init" }, @@ -477,10 +480,10 @@ static const struct tok rx_ack_reasons[] = { struct rx_cache_entry { uint32_t callnum; /* Call number (net order) */ - struct in_addr client; /* client IP address (net order) */ - struct in_addr server; /* server IP address (net order) */ - int dport; /* server port (host order) */ - u_short serviceId; /* Service identifier (net order) */ + uint32_t client; /* client IP address (net order) */ + uint32_t server; /* server IP address (net order) */ + uint16_t dport; /* server UDP port (host order) */ + uint16_t serviceId; /* Service identifier (net order) */ uint32_t opcode; /* RX opcode (host order) */ }; @@ -488,31 +491,31 @@ struct rx_cache_entry { static struct rx_cache_entry rx_cache[RX_CACHE_SIZE]; -static int rx_cache_next = 0; -static int rx_cache_hint = 0; -static void rx_cache_insert(netdissect_options *, const u_char *, const struct ip *, int); -static int rx_cache_find(const struct rx_header *, const struct ip *, - int, int32_t *); - -static void fs_print(netdissect_options *, const u_char *, int); -static void fs_reply_print(netdissect_options *, const u_char *, int, int32_t); -static void acl_print(netdissect_options *, u_char *, int, u_char *); -static void cb_print(netdissect_options *, const u_char *, int); -static void cb_reply_print(netdissect_options *, const u_char *, int, int32_t); -static void prot_print(netdissect_options *, const u_char *, int); -static void prot_reply_print(netdissect_options *, const u_char *, int, int32_t); -static void vldb_print(netdissect_options *, const u_char *, int); -static void vldb_reply_print(netdissect_options *, const u_char *, int, int32_t); -static void kauth_print(netdissect_options *, const u_char *, int); -static void kauth_reply_print(netdissect_options *, const u_char *, int, int32_t); -static void vol_print(netdissect_options *, const u_char *, int); -static void vol_reply_print(netdissect_options *, const u_char *, int, int32_t); -static void bos_print(netdissect_options *, const u_char *, int); -static void bos_reply_print(netdissect_options *, const u_char *, int, int32_t); +static uint32_t rx_cache_next = 0; +static uint32_t rx_cache_hint = 0; +static void rx_cache_insert(netdissect_options *, const u_char *, const struct ip *, uint16_t); +static int rx_cache_find(netdissect_options *, const struct rx_header *, + const struct ip *, uint16_t, uint32_t *); + +static void fs_print(netdissect_options *, const u_char *, u_int); +static void fs_reply_print(netdissect_options *, const u_char *, u_int, uint32_t); +static void acl_print(netdissect_options *, u_char *, u_char *); +static void cb_print(netdissect_options *, const u_char *, u_int); +static void cb_reply_print(netdissect_options *, const u_char *, u_int, uint32_t); +static void prot_print(netdissect_options *, const u_char *, u_int); +static void prot_reply_print(netdissect_options *, const u_char *, u_int, uint32_t); +static void vldb_print(netdissect_options *, const u_char *, u_int); +static void vldb_reply_print(netdissect_options *, const u_char *, u_int, uint32_t); +static void kauth_print(netdissect_options *, const u_char *, u_int); +static void kauth_reply_print(netdissect_options *, const u_char *, u_int, uint32_t); +static void vol_print(netdissect_options *, const u_char *, u_int); +static void vol_reply_print(netdissect_options *, const u_char *, u_int, uint32_t); +static void bos_print(netdissect_options *, const u_char *, u_int); +static void bos_reply_print(netdissect_options *, const u_char *, u_int, uint32_t); static void ubik_print(netdissect_options *, const u_char *); -static void ubik_reply_print(netdissect_options *, const u_char *, int, int32_t); +static void ubik_reply_print(netdissect_options *, const u_char *, u_int, uint32_t); -static void rx_ack_print(netdissect_options *, const u_char *, int); +static void rx_ack_print(netdissect_options *, const u_char *, u_int); static int is_ubik(uint32_t); @@ -523,51 +526,55 @@ static int is_ubik(uint32_t); void rx_print(netdissect_options *ndo, - register const u_char *bp, int length, int sport, int dport, + const u_char *bp, u_int length, uint16_t sport, uint16_t dport, const u_char *bp2) { - register const struct rx_header *rxh; - int i; - int32_t opcode; + const struct rx_header *rxh; + uint32_t i; + uint8_t type, flags; + uint32_t opcode; - if (ndo->ndo_snapend - bp < (int)sizeof (struct rx_header)) { - ND_PRINT((ndo, " [|rx] (%d)", length)); + ndo->ndo_protocol = "rx"; + if (!ND_TTEST_LEN(bp, sizeof(struct rx_header))) { + ND_PRINT(" [|rx] (%u)", length); return; } rxh = (const struct rx_header *) bp; - ND_PRINT((ndo, " rx %s", tok2str(rx_types, "type %d", rxh->type))); + type = GET_U_1(rxh->type); + ND_PRINT(" rx %s", tok2str(rx_types, "type %u", type)); + flags = GET_U_1(rxh->flags); if (ndo->ndo_vflag) { int firstflag = 0; if (ndo->ndo_vflag > 1) - ND_PRINT((ndo, " cid %08x call# %d", - (int) EXTRACT_32BITS(&rxh->cid), - (int) EXTRACT_32BITS(&rxh->callNumber))); + ND_PRINT(" cid %08x call# %u", + GET_BE_U_4(rxh->cid), + GET_BE_U_4(rxh->callNumber)); - ND_PRINT((ndo, " seq %d ser %d", - (int) EXTRACT_32BITS(&rxh->seq), - (int) EXTRACT_32BITS(&rxh->serial))); + ND_PRINT(" seq %u ser %u", + GET_BE_U_4(rxh->seq), + GET_BE_U_4(rxh->serial)); if (ndo->ndo_vflag > 2) - ND_PRINT((ndo, " secindex %d serviceid %hu", - (int) rxh->securityIndex, - EXTRACT_16BITS(&rxh->serviceId))); + ND_PRINT(" secindex %u serviceid %hu", + GET_U_1(rxh->securityIndex), + GET_BE_U_2(rxh->serviceId)); if (ndo->ndo_vflag > 1) for (i = 0; i < NUM_RX_FLAGS; i++) { - if (rxh->flags & rx_flags[i].flag && + if (flags & rx_flags[i].flag && (!rx_flags[i].packetType || - rxh->type == rx_flags[i].packetType)) { + type == rx_flags[i].packetType)) { if (!firstflag) { firstflag = 1; - ND_PRINT((ndo, " ")); + ND_PRINT(" "); } else { - ND_PRINT((ndo, ",")); + ND_PRINT(","); } - ND_PRINT((ndo, "<%s>", rx_flags[i].s)); + ND_PRINT("<%s>", rx_flags[i].s); } } } @@ -581,9 +588,9 @@ rx_print(netdissect_options *ndo, * as well. */ - if (rxh->type == RX_PACKET_TYPE_DATA && - EXTRACT_32BITS(&rxh->seq) == 1 && - rxh->flags & RX_CLIENT_INITIATED) { + if (type == RX_PACKET_TYPE_DATA && + GET_BE_U_4(rxh->seq) == 1 && + flags & RX_CLIENT_INITIATED) { /* * Insert this call into the call cache table, so we @@ -625,11 +632,11 @@ rx_print(netdissect_options *ndo, * because printing out the return code can be useful at times. */ - } else if (((rxh->type == RX_PACKET_TYPE_DATA && - EXTRACT_32BITS(&rxh->seq) == 1) || - rxh->type == RX_PACKET_TYPE_ABORT) && - (rxh->flags & RX_CLIENT_INITIATED) == 0 && - rx_cache_find(rxh, (const struct ip *) bp2, + } else if (((type == RX_PACKET_TYPE_DATA && + GET_BE_U_4(rxh->seq) == 1) || + type == RX_PACKET_TYPE_ABORT) && + (flags & RX_CLIENT_INITIATED) == 0 && + rx_cache_find(ndo, rxh, (const struct ip *) bp2, sport, &opcode)) { switch (sport) { @@ -664,11 +671,11 @@ rx_print(netdissect_options *ndo, * ack packet, so we can use one for all AFS services) */ - } else if (rxh->type == RX_PACKET_TYPE_ACK) + } else if (type == RX_PACKET_TYPE_ACK) rx_ack_print(ndo, bp, length); - ND_PRINT((ndo, " (%d)", length)); + ND_PRINT(" (%u)", length); } /* @@ -677,12 +684,12 @@ rx_print(netdissect_options *ndo, static void rx_cache_insert(netdissect_options *ndo, - const u_char *bp, const struct ip *ip, int dport) + const u_char *bp, const struct ip *ip, uint16_t dport) { struct rx_cache_entry *rxent; const struct rx_header *rxh = (const struct rx_header *) bp; - if (ndo->ndo_snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) + if (!ND_TTEST_4(bp + sizeof(struct rx_header))) return; rxent = &rx_cache[rx_cache_next]; @@ -690,12 +697,12 @@ rx_cache_insert(netdissect_options *ndo, if (++rx_cache_next >= RX_CACHE_SIZE) rx_cache_next = 0; - rxent->callnum = EXTRACT_32BITS(&rxh->callNumber); - UNALIGNED_MEMCPY(&rxent->client, &ip->ip_src, sizeof(uint32_t)); - UNALIGNED_MEMCPY(&rxent->server, &ip->ip_dst, sizeof(uint32_t)); + rxent->callnum = GET_BE_U_4(rxh->callNumber); + rxent->client = GET_IPV4_TO_NETWORK_ORDER(ip->ip_src); + rxent->server = GET_IPV4_TO_NETWORK_ORDER(ip->ip_dst); rxent->dport = dport; - rxent->serviceId = EXTRACT_16BITS(&rxh->serviceId); - rxent->opcode = EXTRACT_32BITS(bp + sizeof(struct rx_header)); + rxent->serviceId = GET_BE_U_2(rxh->serviceId); + rxent->opcode = GET_BE_U_4(bp + sizeof(struct rx_header)); } /* @@ -706,26 +713,26 @@ rx_cache_insert(netdissect_options *ndo, */ static int -rx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport, - int32_t *opcode) +rx_cache_find(netdissect_options *ndo, const struct rx_header *rxh, + const struct ip *ip, uint16_t sport, uint32_t *opcode) { - int i; + uint32_t i; struct rx_cache_entry *rxent; uint32_t clip; uint32_t sip; - UNALIGNED_MEMCPY(&clip, &ip->ip_dst, sizeof(uint32_t)); - UNALIGNED_MEMCPY(&sip, &ip->ip_src, sizeof(uint32_t)); + clip = GET_IPV4_TO_NETWORK_ORDER(ip->ip_dst); + sip = GET_IPV4_TO_NETWORK_ORDER(ip->ip_src); /* Start the search where we last left off */ i = rx_cache_hint; do { rxent = &rx_cache[i]; - if (rxent->callnum == EXTRACT_32BITS(&rxh->callNumber) && - rxent->client.s_addr == clip && - rxent->server.s_addr == sip && - rxent->serviceId == EXTRACT_16BITS(&rxh->serviceId) && + if (rxent->callnum == GET_BE_U_4(rxh->callNumber) && + rxent->client == clip && + rxent->server == sip && + rxent->serviceId == GET_BE_U_2(rxh->serviceId) && rxent->dport == sport) { /* We got a match! */ @@ -743,138 +750,132 @@ rx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport, } /* - * These extrememly grody macros handle the printing of various AFS stuff. + * These extremely grody macros handle the printing of various AFS stuff. */ -#define FIDOUT() { unsigned long n1, n2, n3; \ - ND_TCHECK2(bp[0], sizeof(int32_t) * 3); \ - n1 = EXTRACT_32BITS(bp); \ - bp += sizeof(int32_t); \ - n2 = EXTRACT_32BITS(bp); \ - bp += sizeof(int32_t); \ - n3 = EXTRACT_32BITS(bp); \ - bp += sizeof(int32_t); \ - ND_PRINT((ndo, " fid %d/%d/%d", (int) n1, (int) n2, (int) n3)); \ +#define FIDOUT() { uint32_t n1, n2, n3; \ + ND_TCHECK_LEN(bp, sizeof(uint32_t) * 3); \ + n1 = GET_BE_U_4(bp); \ + bp += sizeof(uint32_t); \ + n2 = GET_BE_U_4(bp); \ + bp += sizeof(uint32_t); \ + n3 = GET_BE_U_4(bp); \ + bp += sizeof(uint32_t); \ + ND_PRINT(" fid %u/%u/%u", n1, n2, n3); \ } -#define STROUT(MAX) { unsigned int _i; \ - ND_TCHECK2(bp[0], sizeof(int32_t)); \ - _i = EXTRACT_32BITS(bp); \ +#define STROUT(MAX) { uint32_t _i; \ + _i = GET_BE_U_4(bp); \ if (_i > (MAX)) \ goto trunc; \ - bp += sizeof(int32_t); \ - ND_PRINT((ndo, " \"")); \ - if (fn_printn(ndo, bp, _i, ndo->ndo_snapend)) \ + bp += sizeof(uint32_t); \ + ND_PRINT(" \""); \ + if (nd_printn(ndo, bp, _i, ndo->ndo_snapend)) \ goto trunc; \ - ND_PRINT((ndo, "\"")); \ - bp += ((_i + sizeof(int32_t) - 1) / sizeof(int32_t)) * sizeof(int32_t); \ + ND_PRINT("\""); \ + bp += ((_i + sizeof(uint32_t) - 1) / sizeof(uint32_t)) * sizeof(uint32_t); \ } -#define INTOUT() { int _i; \ - ND_TCHECK2(bp[0], sizeof(int32_t)); \ - _i = (int) EXTRACT_32BITS(bp); \ +#define INTOUT() { int32_t _i; \ + _i = GET_BE_S_4(bp); \ bp += sizeof(int32_t); \ - ND_PRINT((ndo, " %d", _i)); \ + ND_PRINT(" %d", _i); \ } -#define UINTOUT() { unsigned long _i; \ - ND_TCHECK2(bp[0], sizeof(int32_t)); \ - _i = EXTRACT_32BITS(bp); \ - bp += sizeof(int32_t); \ - ND_PRINT((ndo, " %lu", _i)); \ +#define UINTOUT() { uint32_t _i; \ + _i = GET_BE_U_4(bp); \ + bp += sizeof(uint32_t); \ + ND_PRINT(" %u", _i); \ } #define UINT64OUT() { uint64_t _i; \ - ND_TCHECK2(bp[0], sizeof(uint64_t)); \ - _i = EXTRACT_64BITS(bp); \ + _i = GET_BE_U_8(bp); \ bp += sizeof(uint64_t); \ - ND_PRINT((ndo, " %" PRIu64, _i)); \ + ND_PRINT(" %" PRIu64, _i); \ } #define DATEOUT() { time_t _t; struct tm *tm; char str[256]; \ - ND_TCHECK2(bp[0], sizeof(int32_t)); \ - _t = (time_t) EXTRACT_32BITS(bp); \ + _t = (time_t) GET_BE_S_4(bp); \ bp += sizeof(int32_t); \ tm = localtime(&_t); \ strftime(str, 256, "%Y/%m/%d %H:%M:%S", tm); \ - ND_PRINT((ndo, " %s", str)); \ + ND_PRINT(" %s", str); \ } -#define STOREATTROUT() { unsigned long mask, _i; \ - ND_TCHECK2(bp[0], (sizeof(int32_t)*6)); \ - mask = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ - if (mask) ND_PRINT((ndo, " StoreStatus")); \ - if (mask & 1) { ND_PRINT((ndo, " date")); DATEOUT(); } \ - else bp += sizeof(int32_t); \ - _i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ - if (mask & 2) ND_PRINT((ndo, " owner %lu", _i)); \ - _i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ - if (mask & 4) ND_PRINT((ndo, " group %lu", _i)); \ - _i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ - if (mask & 8) ND_PRINT((ndo, " mode %lo", _i & 07777)); \ - _i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ - if (mask & 16) ND_PRINT((ndo, " segsize %lu", _i)); \ +#define STOREATTROUT() { uint32_t mask, _i; \ + ND_TCHECK_LEN(bp, (sizeof(uint32_t) * 6)); \ + mask = GET_BE_U_4(bp); bp += sizeof(uint32_t); \ + if (mask) ND_PRINT(" StoreStatus"); \ + if (mask & 1) { ND_PRINT(" date"); DATEOUT(); } \ + else bp += sizeof(uint32_t); \ + _i = GET_BE_U_4(bp); bp += sizeof(uint32_t); \ + if (mask & 2) ND_PRINT(" owner %u", _i); \ + _i = GET_BE_U_4(bp); bp += sizeof(uint32_t); \ + if (mask & 4) ND_PRINT(" group %u", _i); \ + _i = GET_BE_U_4(bp); bp += sizeof(uint32_t); \ + if (mask & 8) ND_PRINT(" mode %o", _i & 07777); \ + _i = GET_BE_U_4(bp); bp += sizeof(uint32_t); \ + if (mask & 16) ND_PRINT(" segsize %u", _i); \ /* undocumented in 3.3 docu */ \ - if (mask & 1024) ND_PRINT((ndo, " fsync")); \ + if (mask & 1024) ND_PRINT(" fsync"); \ } -#define UBIK_VERSIONOUT() {int32_t epoch; int32_t counter; \ - ND_TCHECK2(bp[0], sizeof(int32_t) * 2); \ - epoch = EXTRACT_32BITS(bp); \ - bp += sizeof(int32_t); \ - counter = EXTRACT_32BITS(bp); \ - bp += sizeof(int32_t); \ - ND_PRINT((ndo, " %d.%d", epoch, counter)); \ +#define UBIK_VERSIONOUT() {uint32_t epoch; uint32_t counter; \ + ND_TCHECK_LEN(bp, sizeof(uint32_t) * 2); \ + epoch = GET_BE_U_4(bp); \ + bp += sizeof(uint32_t); \ + counter = GET_BE_U_4(bp); \ + bp += sizeof(uint32_t); \ + ND_PRINT(" %u.%u", epoch, counter); \ } #define AFSUUIDOUT() {uint32_t temp; int _i; \ - ND_TCHECK2(bp[0], 11*sizeof(uint32_t)); \ - temp = EXTRACT_32BITS(bp); \ + ND_TCHECK_LEN(bp, 11 * sizeof(uint32_t)); \ + temp = GET_BE_U_4(bp); \ bp += sizeof(uint32_t); \ - ND_PRINT((ndo, " %08x", temp)); \ - temp = EXTRACT_32BITS(bp); \ + ND_PRINT(" %08x", temp); \ + temp = GET_BE_U_4(bp); \ bp += sizeof(uint32_t); \ - ND_PRINT((ndo, "%04x", temp)); \ - temp = EXTRACT_32BITS(bp); \ + ND_PRINT("%04x", temp); \ + temp = GET_BE_U_4(bp); \ bp += sizeof(uint32_t); \ - ND_PRINT((ndo, "%04x", temp)); \ + ND_PRINT("%04x", temp); \ for (_i = 0; _i < 8; _i++) { \ - temp = EXTRACT_32BITS(bp); \ + temp = GET_BE_U_4(bp); \ bp += sizeof(uint32_t); \ - ND_PRINT((ndo, "%02x", (unsigned char) temp)); \ + ND_PRINT("%02x", (unsigned char) temp); \ } \ } /* * This is the sickest one of all + * MAX is expected to be a constant here */ #define VECOUT(MAX) { u_char *sp; \ - u_char s[AFSNAMEMAX]; \ - int k; \ - if ((MAX) + 1 > sizeof(s)) \ - goto trunc; \ - ND_TCHECK2(bp[0], (MAX) * sizeof(int32_t)); \ + u_char s[(MAX) + 1]; \ + uint32_t k; \ + ND_TCHECK_LEN(bp, (MAX) * sizeof(uint32_t)); \ sp = s; \ for (k = 0; k < (MAX); k++) { \ - *sp++ = (u_char) EXTRACT_32BITS(bp); \ - bp += sizeof(int32_t); \ + *sp++ = (u_char) GET_BE_U_4(bp); \ + bp += sizeof(uint32_t); \ } \ s[(MAX)] = '\0'; \ - ND_PRINT((ndo, " \"")); \ - fn_print(ndo, s, NULL); \ - ND_PRINT((ndo, "\"")); \ + ND_PRINT(" \""); \ + fn_print_str(ndo, s); \ + ND_PRINT("\""); \ } -#define DESTSERVEROUT() { unsigned long n1, n2, n3; \ - ND_TCHECK2(bp[0], sizeof(int32_t) * 3); \ - n1 = EXTRACT_32BITS(bp); \ - bp += sizeof(int32_t); \ - n2 = EXTRACT_32BITS(bp); \ - bp += sizeof(int32_t); \ - n3 = EXTRACT_32BITS(bp); \ - bp += sizeof(int32_t); \ - ND_PRINT((ndo, " server %d:%d:%d", (int) n1, (int) n2, (int) n3)); \ +#define DESTSERVEROUT() { uint32_t n1, n2, n3; \ + ND_TCHECK_LEN(bp, sizeof(uint32_t) * 3); \ + n1 = GET_BE_U_4(bp); \ + bp += sizeof(uint32_t); \ + n2 = GET_BE_U_4(bp); \ + bp += sizeof(uint32_t); \ + n3 = GET_BE_U_4(bp); \ + bp += sizeof(uint32_t); \ + ND_PRINT(" server %u:%u:%u", n1, n2, n3); \ } /* @@ -883,26 +884,22 @@ rx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport, static void fs_print(netdissect_options *ndo, - register const u_char *bp, int length) + const u_char *bp, u_int length) { - int fs_op; - unsigned long i; + uint32_t fs_op; + uint32_t i; - if (length <= (int)sizeof(struct rx_header)) + if (length <= sizeof(struct rx_header)) return; - if (ndo->ndo_snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { - goto trunc; - } - /* * Print out the afs call we're invoking. The table used here was * gleaned from fsint/afsint.xg */ - fs_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); + fs_op = GET_BE_U_4(bp + sizeof(struct rx_header)); - ND_PRINT((ndo, " fs call %s", tok2str(fs_req, "op#%d", fs_op))); + ND_PRINT(" fs call %s", tok2str(fs_req, "op#%u", fs_op)); /* * Print out arguments to some of the AFS calls. This stuff is @@ -918,9 +915,9 @@ fs_print(netdissect_options *ndo, switch (fs_op) { case 130: /* Fetch data */ FIDOUT(); - ND_PRINT((ndo, " offset")); + ND_PRINT(" offset"); UINTOUT(); - ND_PRINT((ndo, " length")); + ND_PRINT(" length"); UINTOUT(); break; case 131: /* Fetch ACL */ @@ -940,25 +937,24 @@ fs_print(netdissect_options *ndo, case 133: /* Store data */ FIDOUT(); STOREATTROUT(); - ND_PRINT((ndo, " offset")); + ND_PRINT(" offset"); UINTOUT(); - ND_PRINT((ndo, " length")); + ND_PRINT(" length"); UINTOUT(); - ND_PRINT((ndo, " flen")); + ND_PRINT(" flen"); UINTOUT(); break; case 134: /* Store ACL */ { char a[AFSOPAQUEMAX+1]; FIDOUT(); - ND_TCHECK2(bp[0], 4); - i = EXTRACT_32BITS(bp); - bp += sizeof(int32_t); - ND_TCHECK2(bp[0], i); - i = min(AFSOPAQUEMAX, i); + i = GET_BE_U_4(bp); + bp += sizeof(uint32_t); + ND_TCHECK_LEN(bp, i); + i = ND_MIN(AFSOPAQUEMAX, i); strncpy(a, (const char *) bp, i); a[i] = '\0'; - acl_print(ndo, (u_char *) a, sizeof(a), (u_char *) a + i); + acl_print(ndo, (u_char *) a, (u_char *) a + i); break; } case 137: /* Create file */ @@ -973,23 +969,23 @@ fs_print(netdissect_options *ndo, STROUT(AFSNAMEMAX); break; case 138: /* Rename file */ - ND_PRINT((ndo, " old")); + ND_PRINT(" old"); FIDOUT(); STROUT(AFSNAMEMAX); - ND_PRINT((ndo, " new")); + ND_PRINT(" new"); FIDOUT(); STROUT(AFSNAMEMAX); break; case 139: /* Symlink */ FIDOUT(); STROUT(AFSNAMEMAX); - ND_PRINT((ndo, " link to")); + ND_PRINT(" link to"); STROUT(AFSNAMEMAX); break; case 140: /* Link */ FIDOUT(); STROUT(AFSNAMEMAX); - ND_PRINT((ndo, " link to")); + ND_PRINT(" link to"); FIDOUT(); break; case 148: /* Get volume info */ @@ -997,49 +993,48 @@ fs_print(netdissect_options *ndo, break; case 149: /* Get volume stats */ case 150: /* Set volume stats */ - ND_PRINT((ndo, " volid")); + ND_PRINT(" volid"); UINTOUT(); break; case 154: /* New get volume info */ - ND_PRINT((ndo, " volname")); + ND_PRINT(" volname"); STROUT(AFSNAMEMAX); break; case 155: /* Bulk stat */ case 65536: /* Inline bulk stat */ { - unsigned long j; - ND_TCHECK2(bp[0], 4); - j = EXTRACT_32BITS(bp); - bp += sizeof(int32_t); + uint32_t j; + j = GET_BE_U_4(bp); + bp += sizeof(uint32_t); for (i = 0; i < j; i++) { FIDOUT(); if (i != j - 1) - ND_PRINT((ndo, ",")); + ND_PRINT(","); } if (j == 0) - ND_PRINT((ndo, " ")); + ND_PRINT(" "); break; } case 65537: /* Fetch data 64 */ FIDOUT(); - ND_PRINT((ndo, " offset")); + ND_PRINT(" offset"); UINT64OUT(); - ND_PRINT((ndo, " length")); + ND_PRINT(" length"); UINT64OUT(); break; case 65538: /* Store data 64 */ FIDOUT(); STOREATTROUT(); - ND_PRINT((ndo, " offset")); + ND_PRINT(" offset"); UINT64OUT(); - ND_PRINT((ndo, " length")); + ND_PRINT(" length"); UINT64OUT(); - ND_PRINT((ndo, " flen")); + ND_PRINT(" flen"); UINT64OUT(); break; case 65541: /* CallBack rx conn address */ - ND_PRINT((ndo, " addr")); + ND_PRINT(" addr"); UINTOUT(); default: ; @@ -1048,7 +1043,7 @@ fs_print(netdissect_options *ndo, return; trunc: - ND_PRINT((ndo, " [|fs]")); + ND_PRINT(" [|fs]"); } /* @@ -1057,12 +1052,13 @@ trunc: static void fs_reply_print(netdissect_options *ndo, - register const u_char *bp, int length, int32_t opcode) + const u_char *bp, u_int length, uint32_t opcode) { - unsigned long i; + uint32_t i; const struct rx_header *rxh; + uint8_t type; - if (length <= (int)sizeof(struct rx_header)) + if (length <= sizeof(struct rx_header)) return; rxh = (const struct rx_header *) bp; @@ -1072,36 +1068,36 @@ fs_reply_print(netdissect_options *ndo, * gleaned from fsint/afsint.xg */ - ND_PRINT((ndo, " fs reply %s", tok2str(fs_req, "op#%d", opcode))); + ND_PRINT(" fs reply %s", tok2str(fs_req, "op#%u", opcode)); + type = GET_U_1(rxh->type); bp += sizeof(struct rx_header); /* * If it was a data packet, interpret the response */ - if (rxh->type == RX_PACKET_TYPE_DATA) { + if (type == RX_PACKET_TYPE_DATA) { switch (opcode) { case 131: /* Fetch ACL */ { char a[AFSOPAQUEMAX+1]; - ND_TCHECK2(bp[0], 4); - i = EXTRACT_32BITS(bp); - bp += sizeof(int32_t); - ND_TCHECK2(bp[0], i); - i = min(AFSOPAQUEMAX, i); + i = GET_BE_U_4(bp); + bp += sizeof(uint32_t); + ND_TCHECK_LEN(bp, i); + i = ND_MIN(AFSOPAQUEMAX, i); strncpy(a, (const char *) bp, i); a[i] = '\0'; - acl_print(ndo, (u_char *) a, sizeof(a), (u_char *) a + i); + acl_print(ndo, (u_char *) a, (u_char *) a + i); break; } case 137: /* Create file */ case 141: /* MakeDir */ - ND_PRINT((ndo, " new")); + ND_PRINT(" new"); FIDOUT(); break; case 151: /* Get root volume */ - ND_PRINT((ndo, " root volume")); + ND_PRINT(" root volume"); STROUT(AFSNAMEMAX); break; case 153: /* Get time */ @@ -1110,23 +1106,24 @@ fs_reply_print(netdissect_options *ndo, default: ; } - } else if (rxh->type == RX_PACKET_TYPE_ABORT) { + } else if (type == RX_PACKET_TYPE_ABORT) { /* * Otherwise, just print out the return code */ - ND_TCHECK2(bp[0], sizeof(int32_t)); - i = (int) EXTRACT_32BITS(bp); + int32_t errcode; + + errcode = GET_BE_S_4(bp); bp += sizeof(int32_t); - ND_PRINT((ndo, " error %s", tok2str(afs_fs_errors, "#%d", i))); + ND_PRINT(" error %s", tok2str(afs_fs_errors, "#%d", errcode)); } else { - ND_PRINT((ndo, " strange fs reply of type %d", rxh->type)); + ND_PRINT(" strange fs reply of type %u", type); } return; trunc: - ND_PRINT((ndo, " [|fs]")); + ND_PRINT(" [|fs]"); } /* @@ -1139,75 +1136,67 @@ trunc: * * "positive" and "negative" are integers which contain the number of * positive and negative ACL's in the string. The uid/aclbits pair are - * ASCII strings containing the UID/PTS record and and a ascii number + * ASCII strings containing the UID/PTS record and an ASCII number * representing a logical OR of all the ACL permission bits */ +#define NUMSTRINGIFY(x) XSTRINGIFY(x) + static void acl_print(netdissect_options *ndo, - u_char *s, int maxsize, u_char *end) + u_char *s, u_char *end) { int pos, neg, acl; int n, i; - char *user; - char fmt[1024]; - - if ((user = (char *)malloc(maxsize)) == NULL) - return; + char user[USERNAMEMAX+1]; if (sscanf((char *) s, "%d %d\n%n", &pos, &neg, &n) != 2) - goto finish; + return; s += n; if (s > end) - goto finish; + return; /* * This wacky order preserves the order used by the "fs" command */ #define ACLOUT(acl) \ - ND_PRINT((ndo, "%s%s%s%s%s%s%s", \ + ND_PRINT("%s%s%s%s%s%s%s", \ acl & PRSFS_READ ? "r" : "", \ acl & PRSFS_LOOKUP ? "l" : "", \ acl & PRSFS_INSERT ? "i" : "", \ acl & PRSFS_DELETE ? "d" : "", \ acl & PRSFS_WRITE ? "w" : "", \ acl & PRSFS_LOCK ? "k" : "", \ - acl & PRSFS_ADMINISTER ? "a" : "")); + acl & PRSFS_ADMINISTER ? "a" : ""); for (i = 0; i < pos; i++) { - snprintf(fmt, sizeof(fmt), "%%%ds %%d\n%%n", maxsize - 1); - if (sscanf((char *) s, fmt, user, &acl, &n) != 2) - goto finish; + if (sscanf((char *) s, "%" NUMSTRINGIFY(USERNAMEMAX) "s %d\n%n", user, &acl, &n) != 2) + return; s += n; - ND_PRINT((ndo, " +{")); - fn_print(ndo, (u_char *)user, NULL); - ND_PRINT((ndo, " ")); + ND_PRINT(" +{"); + fn_print_str(ndo, (u_char *)user); + ND_PRINT(" "); ACLOUT(acl); - ND_PRINT((ndo, "}")); + ND_PRINT("}"); if (s > end) - goto finish; + return; } for (i = 0; i < neg; i++) { - snprintf(fmt, sizeof(fmt), "%%%ds %%d\n%%n", maxsize - 1); - if (sscanf((char *) s, fmt, user, &acl, &n) != 2) - goto finish; + if (sscanf((char *) s, "%" NUMSTRINGIFY(USERNAMEMAX) "s %d\n%n", user, &acl, &n) != 2) + return; s += n; - ND_PRINT((ndo, " -{")); - fn_print(ndo, (u_char *)user, NULL); - ND_PRINT((ndo, " ")); + ND_PRINT(" -{"); + fn_print_str(ndo, (u_char *)user); + ND_PRINT(" "); ACLOUT(acl); - ND_PRINT((ndo, "}")); + ND_PRINT("}"); if (s > end) - goto finish; + return; } - -finish: - free(user); - return; } #undef ACLOUT @@ -1218,26 +1207,22 @@ finish: static void cb_print(netdissect_options *ndo, - register const u_char *bp, int length) + const u_char *bp, u_int length) { - int cb_op; - unsigned long i; + uint32_t cb_op; + uint32_t i; - if (length <= (int)sizeof(struct rx_header)) + if (length <= sizeof(struct rx_header)) return; - if (ndo->ndo_snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { - goto trunc; - } - /* * Print out the afs call we're invoking. The table used here was * gleaned from fsint/afscbint.xg */ - cb_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); + cb_op = GET_BE_U_4(bp + sizeof(struct rx_header)); - ND_PRINT((ndo, " cb call %s", tok2str(cb_req, "op#%d", cb_op))); + ND_PRINT(" cb call %s", tok2str(cb_req, "op#%u", cb_op)); bp += sizeof(struct rx_header) + 4; @@ -1249,41 +1234,38 @@ cb_print(netdissect_options *ndo, switch (cb_op) { case 204: /* Callback */ { - unsigned long j, t; - ND_TCHECK2(bp[0], 4); - j = EXTRACT_32BITS(bp); - bp += sizeof(int32_t); + uint32_t j, t; + j = GET_BE_U_4(bp); + bp += sizeof(uint32_t); for (i = 0; i < j; i++) { FIDOUT(); if (i != j - 1) - ND_PRINT((ndo, ",")); + ND_PRINT(","); } if (j == 0) - ND_PRINT((ndo, " ")); + ND_PRINT(" "); - ND_TCHECK_32BITS(bp); - j = EXTRACT_32BITS(bp); - bp += sizeof(int32_t); + j = GET_BE_U_4(bp); + bp += sizeof(uint32_t); if (j != 0) - ND_PRINT((ndo, ";")); + ND_PRINT(";"); for (i = 0; i < j; i++) { - ND_PRINT((ndo, " ver")); + ND_PRINT(" ver"); INTOUT(); - ND_PRINT((ndo, " expires")); + ND_PRINT(" expires"); DATEOUT(); - ND_TCHECK2(bp[0], 4); - t = EXTRACT_32BITS(bp); - bp += sizeof(int32_t); - tok2str(cb_types, "type %d", t); + t = GET_BE_U_4(bp); + bp += sizeof(uint32_t); + tok2str(cb_types, "type %u", t); } break; } case 214: { - ND_PRINT((ndo, " afsuuid")); + ND_PRINT(" afsuuid"); AFSUUIDOUT(); break; } @@ -1294,7 +1276,7 @@ cb_print(netdissect_options *ndo, return; trunc: - ND_PRINT((ndo, " [|cb]")); + ND_PRINT(" [|cb]"); } /* @@ -1303,11 +1285,12 @@ trunc: static void cb_reply_print(netdissect_options *ndo, - register const u_char *bp, int length, int32_t opcode) + const u_char *bp, u_int length, uint32_t opcode) { const struct rx_header *rxh; + uint8_t type; - if (length <= (int)sizeof(struct rx_header)) + if (length <= sizeof(struct rx_header)) return; rxh = (const struct rx_header *) bp; @@ -1317,15 +1300,16 @@ cb_reply_print(netdissect_options *ndo, * gleaned from fsint/afscbint.xg */ - ND_PRINT((ndo, " cb reply %s", tok2str(cb_req, "op#%d", opcode))); + ND_PRINT(" cb reply %s", tok2str(cb_req, "op#%u", opcode)); + type = GET_U_1(rxh->type); bp += sizeof(struct rx_header); /* * If it was a data packet, interpret the response. */ - if (rxh->type == RX_PACKET_TYPE_DATA) + if (type == RX_PACKET_TYPE_DATA) switch (opcode) { case 213: /* InitCallBackState3 */ AFSUUIDOUT(); @@ -1337,14 +1321,14 @@ cb_reply_print(netdissect_options *ndo, /* * Otherwise, just print out the return code */ - ND_PRINT((ndo, " errcode")); + ND_PRINT(" errcode"); INTOUT(); } return; trunc: - ND_PRINT((ndo, " [|cb]")); + ND_PRINT(" [|cb]"); } /* @@ -1353,33 +1337,29 @@ trunc: static void prot_print(netdissect_options *ndo, - register const u_char *bp, int length) + const u_char *bp, u_int length) { - unsigned long i; - int pt_op; + uint32_t i; + uint32_t pt_op; - if (length <= (int)sizeof(struct rx_header)) + if (length <= sizeof(struct rx_header)) return; - if (ndo->ndo_snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { - goto trunc; - } - /* * Print out the afs call we're invoking. The table used here was * gleaned from ptserver/ptint.xg */ - pt_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); + pt_op = GET_BE_U_4(bp + sizeof(struct rx_header)); - ND_PRINT((ndo, " pt")); + ND_PRINT(" pt"); if (is_ubik(pt_op)) { ubik_print(ndo, bp); return; } - ND_PRINT((ndo, " call %s", tok2str(pt_req, "op#%d", pt_op))); + ND_PRINT(" call %s", tok2str(pt_req, "op#%u", pt_op)); /* * Decode some of the arguments to the PT calls @@ -1390,9 +1370,9 @@ prot_print(netdissect_options *ndo, switch (pt_op) { case 500: /* I New User */ STROUT(PRNAMEMAX); - ND_PRINT((ndo, " id")); + ND_PRINT(" id"); INTOUT(); - ND_PRINT((ndo, " oldid")); + ND_PRINT(" oldid"); INTOUT(); break; case 501: /* Where is it */ @@ -1404,27 +1384,26 @@ prot_print(netdissect_options *ndo, case 518: /* Get CPS2 */ case 519: /* Get host CPS */ case 530: /* List super groups */ - ND_PRINT((ndo, " id")); + ND_PRINT(" id"); INTOUT(); break; case 502: /* Dump entry */ - ND_PRINT((ndo, " pos")); + ND_PRINT(" pos"); INTOUT(); break; case 503: /* Add to group */ case 507: /* Remove from group */ case 515: /* Is a member of? */ - ND_PRINT((ndo, " uid")); + ND_PRINT(" uid"); INTOUT(); - ND_PRINT((ndo, " gid")); + ND_PRINT(" gid"); INTOUT(); break; case 504: /* Name to ID */ { - unsigned long j; - ND_TCHECK2(bp[0], 4); - j = EXTRACT_32BITS(bp); - bp += sizeof(int32_t); + uint32_t j; + j = GET_BE_U_4(bp); + bp += sizeof(uint32_t); /* * Who designed this chicken-shit protocol? @@ -1437,46 +1416,45 @@ prot_print(netdissect_options *ndo, VECOUT(PRNAMEMAX); } if (j == 0) - ND_PRINT((ndo, " ")); + ND_PRINT(" "); } break; case 505: /* Id to name */ { - unsigned long j; - ND_PRINT((ndo, " ids:")); - ND_TCHECK2(bp[0], 4); - i = EXTRACT_32BITS(bp); - bp += sizeof(int32_t); + uint32_t j; + ND_PRINT(" ids:"); + i = GET_BE_U_4(bp); + bp += sizeof(uint32_t); for (j = 0; j < i; j++) INTOUT(); if (j == 0) - ND_PRINT((ndo, " ")); + ND_PRINT(" "); } break; case 509: /* New entry */ STROUT(PRNAMEMAX); - ND_PRINT((ndo, " flag")); + ND_PRINT(" flag"); INTOUT(); - ND_PRINT((ndo, " oid")); + ND_PRINT(" oid"); INTOUT(); break; case 511: /* Set max */ - ND_PRINT((ndo, " id")); + ND_PRINT(" id"); INTOUT(); - ND_PRINT((ndo, " gflag")); + ND_PRINT(" gflag"); INTOUT(); break; case 513: /* Change entry */ - ND_PRINT((ndo, " id")); + ND_PRINT(" id"); INTOUT(); STROUT(PRNAMEMAX); - ND_PRINT((ndo, " oldid")); + ND_PRINT(" oldid"); INTOUT(); - ND_PRINT((ndo, " newid")); + ND_PRINT(" newid"); INTOUT(); break; case 520: /* Update entry */ - ND_PRINT((ndo, " id")); + ND_PRINT(" id"); INTOUT(); STROUT(PRNAMEMAX); break; @@ -1488,7 +1466,7 @@ prot_print(netdissect_options *ndo, return; trunc: - ND_PRINT((ndo, " [|pt]")); + ND_PRINT(" [|pt]"); } /* @@ -1497,12 +1475,13 @@ trunc: static void prot_reply_print(netdissect_options *ndo, - register const u_char *bp, int length, int32_t opcode) + const u_char *bp, u_int length, uint32_t opcode) { const struct rx_header *rxh; - unsigned long i; + uint8_t type; + uint32_t i; - if (length < (int)sizeof(struct rx_header)) + if (length < sizeof(struct rx_header)) return; rxh = (const struct rx_header *) bp; @@ -1513,42 +1492,41 @@ prot_reply_print(netdissect_options *ndo, * Ubik call, however. */ - ND_PRINT((ndo, " pt")); + ND_PRINT(" pt"); if (is_ubik(opcode)) { ubik_reply_print(ndo, bp, length, opcode); return; } - ND_PRINT((ndo, " reply %s", tok2str(pt_req, "op#%d", opcode))); + ND_PRINT(" reply %s", tok2str(pt_req, "op#%u", opcode)); + type = GET_U_1(rxh->type); bp += sizeof(struct rx_header); /* * If it was a data packet, interpret the response */ - if (rxh->type == RX_PACKET_TYPE_DATA) + if (type == RX_PACKET_TYPE_DATA) switch (opcode) { case 504: /* Name to ID */ { - unsigned long j; - ND_PRINT((ndo, " ids:")); - ND_TCHECK2(bp[0], 4); - i = EXTRACT_32BITS(bp); - bp += sizeof(int32_t); + uint32_t j; + ND_PRINT(" ids:"); + i = GET_BE_U_4(bp); + bp += sizeof(uint32_t); for (j = 0; j < i; j++) INTOUT(); if (j == 0) - ND_PRINT((ndo, " ")); + ND_PRINT(" "); } break; case 505: /* ID to name */ { - unsigned long j; - ND_TCHECK2(bp[0], 4); - j = EXTRACT_32BITS(bp); - bp += sizeof(int32_t); + uint32_t j; + j = GET_BE_U_4(bp); + bp += sizeof(uint32_t); /* * Who designed this chicken-shit protocol? @@ -1561,7 +1539,7 @@ prot_reply_print(netdissect_options *ndo, VECOUT(PRNAMEMAX); } if (j == 0) - ND_PRINT((ndo, " ")); + ND_PRINT(" "); } break; case 508: /* Get CPS */ @@ -1570,21 +1548,20 @@ prot_reply_print(netdissect_options *ndo, case 518: /* Get CPS2 */ case 519: /* Get host CPS */ { - unsigned long j; - ND_TCHECK2(bp[0], 4); - j = EXTRACT_32BITS(bp); - bp += sizeof(int32_t); + uint32_t j; + j = GET_BE_U_4(bp); + bp += sizeof(uint32_t); for (i = 0; i < j; i++) { INTOUT(); } if (j == 0) - ND_PRINT((ndo, " ")); + ND_PRINT(" "); } break; case 510: /* List max */ - ND_PRINT((ndo, " maxuid")); + ND_PRINT(" maxuid"); INTOUT(); - ND_PRINT((ndo, " maxgid")); + ND_PRINT(" maxgid"); INTOUT(); break; default: @@ -1594,14 +1571,14 @@ prot_reply_print(netdissect_options *ndo, /* * Otherwise, just print out the return code */ - ND_PRINT((ndo, " errcode")); + ND_PRINT(" errcode"); INTOUT(); } return; trunc: - ND_PRINT((ndo, " [|pt]")); + ND_PRINT(" [|pt]"); } /* @@ -1610,32 +1587,28 @@ trunc: static void vldb_print(netdissect_options *ndo, - register const u_char *bp, int length) + const u_char *bp, u_int length) { - int vldb_op; - unsigned long i; + uint32_t vldb_op; + uint32_t i; - if (length <= (int)sizeof(struct rx_header)) + if (length <= sizeof(struct rx_header)) return; - if (ndo->ndo_snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { - goto trunc; - } - /* * Print out the afs call we're invoking. The table used here was * gleaned from vlserver/vldbint.xg */ - vldb_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); + vldb_op = GET_BE_U_4(bp + sizeof(struct rx_header)); - ND_PRINT((ndo, " vldb")); + ND_PRINT(" vldb"); if (is_ubik(vldb_op)) { ubik_print(ndo, bp); return; } - ND_PRINT((ndo, " call %s", tok2str(vldb_req, "op#%d", vldb_op))); + ND_PRINT(" call %s", tok2str(vldb_req, "op#%u", vldb_op)); /* * Decode some of the arguments to the VLDB calls @@ -1654,13 +1627,12 @@ vldb_print(netdissect_options *ndo, case 508: /* Set lock */ case 509: /* Release lock */ case 518: /* Get entry by ID N */ - ND_PRINT((ndo, " volid")); + ND_PRINT(" volid"); INTOUT(); - ND_TCHECK2(bp[0], sizeof(int32_t)); - i = EXTRACT_32BITS(bp); - bp += sizeof(int32_t); + i = GET_BE_U_4(bp); + bp += sizeof(uint32_t); if (i <= 2) - ND_PRINT((ndo, " type %s", voltype[i])); + ND_PRINT(" type %s", voltype[i]); break; case 504: /* Get entry by name */ case 519: /* Get entry by name N */ @@ -1669,23 +1641,22 @@ vldb_print(netdissect_options *ndo, STROUT(VLNAMEMAX); break; case 505: /* Get new vol id */ - ND_PRINT((ndo, " bump")); + ND_PRINT(" bump"); INTOUT(); break; case 506: /* Replace entry */ case 520: /* Replace entry N */ - ND_PRINT((ndo, " volid")); + ND_PRINT(" volid"); INTOUT(); - ND_TCHECK2(bp[0], sizeof(int32_t)); - i = EXTRACT_32BITS(bp); - bp += sizeof(int32_t); + i = GET_BE_U_4(bp); + bp += sizeof(uint32_t); if (i <= 2) - ND_PRINT((ndo, " type %s", voltype[i])); + ND_PRINT(" type %s", voltype[i]); VECOUT(VLNAMEMAX); break; case 510: /* List entry */ case 521: /* List entry N */ - ND_PRINT((ndo, " index")); + ND_PRINT(" index"); INTOUT(); break; default: @@ -1695,7 +1666,7 @@ vldb_print(netdissect_options *ndo, return; trunc: - ND_PRINT((ndo, " [|vldb]")); + ND_PRINT(" [|vldb]"); } /* @@ -1704,12 +1675,13 @@ trunc: static void vldb_reply_print(netdissect_options *ndo, - register const u_char *bp, int length, int32_t opcode) + const u_char *bp, u_int length, uint32_t opcode) { const struct rx_header *rxh; - unsigned long i; + uint8_t type; + uint32_t i; - if (length < (int)sizeof(struct rx_header)) + if (length < sizeof(struct rx_header)) return; rxh = (const struct rx_header *) bp; @@ -1720,154 +1692,149 @@ vldb_reply_print(netdissect_options *ndo, * Ubik call, however. */ - ND_PRINT((ndo, " vldb")); + ND_PRINT(" vldb"); if (is_ubik(opcode)) { ubik_reply_print(ndo, bp, length, opcode); return; } - ND_PRINT((ndo, " reply %s", tok2str(vldb_req, "op#%d", opcode))); + ND_PRINT(" reply %s", tok2str(vldb_req, "op#%u", opcode)); + type = GET_U_1(rxh->type); bp += sizeof(struct rx_header); /* * If it was a data packet, interpret the response */ - if (rxh->type == RX_PACKET_TYPE_DATA) + if (type == RX_PACKET_TYPE_DATA) switch (opcode) { case 510: /* List entry */ - ND_PRINT((ndo, " count")); + ND_PRINT(" count"); INTOUT(); - ND_PRINT((ndo, " nextindex")); + ND_PRINT(" nextindex"); INTOUT(); - /*FALLTHROUGH*/ + ND_FALL_THROUGH; case 503: /* Get entry by id */ case 504: /* Get entry by name */ - { unsigned long nservers, j; + { uint32_t nservers, j; VECOUT(VLNAMEMAX); - ND_TCHECK2(bp[0], sizeof(int32_t)); - bp += sizeof(int32_t); - ND_PRINT((ndo, " numservers")); - ND_TCHECK2(bp[0], sizeof(int32_t)); - nservers = EXTRACT_32BITS(bp); - bp += sizeof(int32_t); - ND_PRINT((ndo, " %lu", nservers)); - ND_PRINT((ndo, " servers")); + ND_TCHECK_4(bp); + bp += sizeof(uint32_t); + ND_PRINT(" numservers"); + nservers = GET_BE_U_4(bp); + bp += sizeof(uint32_t); + ND_PRINT(" %u", nservers); + ND_PRINT(" servers"); for (i = 0; i < 8; i++) { - ND_TCHECK2(bp[0], sizeof(int32_t)); + ND_TCHECK_4(bp); if (i < nservers) - ND_PRINT((ndo, " %s", - intoa(((const struct in_addr *) bp)->s_addr))); - bp += sizeof(int32_t); + ND_PRINT(" %s", + intoa(GET_IPV4_TO_NETWORK_ORDER(bp))); + bp += sizeof(nd_ipv4); } - ND_PRINT((ndo, " partitions")); + ND_PRINT(" partitions"); for (i = 0; i < 8; i++) { - ND_TCHECK2(bp[0], sizeof(int32_t)); - j = EXTRACT_32BITS(bp); + j = GET_BE_U_4(bp); if (i < nservers && j <= 26) - ND_PRINT((ndo, " %c", 'a' + (int)j)); + ND_PRINT(" %c", 'a' + j); else if (i < nservers) - ND_PRINT((ndo, " %lu", j)); - bp += sizeof(int32_t); + ND_PRINT(" %u", j); + bp += sizeof(uint32_t); } - ND_TCHECK2(bp[0], 8 * sizeof(int32_t)); - bp += 8 * sizeof(int32_t); - ND_PRINT((ndo, " rwvol")); + ND_TCHECK_LEN(bp, 8 * sizeof(uint32_t)); + bp += 8 * sizeof(uint32_t); + ND_PRINT(" rwvol"); UINTOUT(); - ND_PRINT((ndo, " rovol")); + ND_PRINT(" rovol"); UINTOUT(); - ND_PRINT((ndo, " backup")); + ND_PRINT(" backup"); UINTOUT(); } break; case 505: /* Get new volume ID */ - ND_PRINT((ndo, " newvol")); + ND_PRINT(" newvol"); UINTOUT(); break; case 521: /* List entry */ case 529: /* List entry U */ - ND_PRINT((ndo, " count")); + ND_PRINT(" count"); INTOUT(); - ND_PRINT((ndo, " nextindex")); + ND_PRINT(" nextindex"); INTOUT(); - /*FALLTHROUGH*/ + ND_FALL_THROUGH; case 518: /* Get entry by ID N */ case 519: /* Get entry by name N */ - { unsigned long nservers, j; + { uint32_t nservers, j; VECOUT(VLNAMEMAX); - ND_PRINT((ndo, " numservers")); - ND_TCHECK2(bp[0], sizeof(int32_t)); - nservers = EXTRACT_32BITS(bp); - bp += sizeof(int32_t); - ND_PRINT((ndo, " %lu", nservers)); - ND_PRINT((ndo, " servers")); + ND_PRINT(" numservers"); + nservers = GET_BE_U_4(bp); + bp += sizeof(uint32_t); + ND_PRINT(" %u", nservers); + ND_PRINT(" servers"); for (i = 0; i < 13; i++) { - ND_TCHECK2(bp[0], sizeof(int32_t)); + ND_TCHECK_4(bp); if (i < nservers) - ND_PRINT((ndo, " %s", - intoa(((const struct in_addr *) bp)->s_addr))); - bp += sizeof(int32_t); + ND_PRINT(" %s", + intoa(GET_IPV4_TO_NETWORK_ORDER(bp))); + bp += sizeof(nd_ipv4); } - ND_PRINT((ndo, " partitions")); + ND_PRINT(" partitions"); for (i = 0; i < 13; i++) { - ND_TCHECK2(bp[0], sizeof(int32_t)); - j = EXTRACT_32BITS(bp); + j = GET_BE_U_4(bp); if (i < nservers && j <= 26) - ND_PRINT((ndo, " %c", 'a' + (int)j)); + ND_PRINT(" %c", 'a' + j); else if (i < nservers) - ND_PRINT((ndo, " %lu", j)); - bp += sizeof(int32_t); + ND_PRINT(" %u", j); + bp += sizeof(uint32_t); } - ND_TCHECK2(bp[0], 13 * sizeof(int32_t)); - bp += 13 * sizeof(int32_t); - ND_PRINT((ndo, " rwvol")); + ND_TCHECK_LEN(bp, 13 * sizeof(uint32_t)); + bp += 13 * sizeof(uint32_t); + ND_PRINT(" rwvol"); UINTOUT(); - ND_PRINT((ndo, " rovol")); + ND_PRINT(" rovol"); UINTOUT(); - ND_PRINT((ndo, " backup")); + ND_PRINT(" backup"); UINTOUT(); } break; case 526: /* Get entry by ID U */ case 527: /* Get entry by name U */ - { unsigned long nservers, j; + { uint32_t nservers, j; VECOUT(VLNAMEMAX); - ND_PRINT((ndo, " numservers")); - ND_TCHECK2(bp[0], sizeof(int32_t)); - nservers = EXTRACT_32BITS(bp); - bp += sizeof(int32_t); - ND_PRINT((ndo, " %lu", nservers)); - ND_PRINT((ndo, " servers")); + ND_PRINT(" numservers"); + nservers = GET_BE_U_4(bp); + bp += sizeof(uint32_t); + ND_PRINT(" %u", nservers); + ND_PRINT(" servers"); for (i = 0; i < 13; i++) { if (i < nservers) { - ND_PRINT((ndo, " afsuuid")); + ND_PRINT(" afsuuid"); AFSUUIDOUT(); } else { - ND_TCHECK2(bp[0], 44); + ND_TCHECK_LEN(bp, 44); bp += 44; } } - ND_TCHECK2(bp[0], 4 * 13); + ND_TCHECK_LEN(bp, 4 * 13); bp += 4 * 13; - ND_PRINT((ndo, " partitions")); + ND_PRINT(" partitions"); for (i = 0; i < 13; i++) { - ND_TCHECK2(bp[0], sizeof(int32_t)); - j = EXTRACT_32BITS(bp); + j = GET_BE_U_4(bp); if (i < nservers && j <= 26) - ND_PRINT((ndo, " %c", 'a' + (int)j)); + ND_PRINT(" %c", 'a' + j); else if (i < nservers) - ND_PRINT((ndo, " %lu", j)); - bp += sizeof(int32_t); + ND_PRINT(" %u", j); + bp += sizeof(uint32_t); } - ND_TCHECK2(bp[0], 13 * sizeof(int32_t)); - bp += 13 * sizeof(int32_t); - ND_PRINT((ndo, " rwvol")); + ND_TCHECK_LEN(bp, 13 * sizeof(uint32_t)); + bp += 13 * sizeof(uint32_t); + ND_PRINT(" rwvol"); UINTOUT(); - ND_PRINT((ndo, " rovol")); + ND_PRINT(" rovol"); UINTOUT(); - ND_PRINT((ndo, " backup")); + ND_PRINT(" backup"); UINTOUT(); } default: @@ -1878,14 +1845,14 @@ vldb_reply_print(netdissect_options *ndo, /* * Otherwise, just print out the return code */ - ND_PRINT((ndo, " errcode")); + ND_PRINT(" errcode"); INTOUT(); } return; trunc: - ND_PRINT((ndo, " [|vldb]")); + ND_PRINT(" [|vldb]"); } /* @@ -1894,25 +1861,21 @@ trunc: static void kauth_print(netdissect_options *ndo, - register const u_char *bp, int length) + const u_char *bp, u_int length) { - int kauth_op; + uint32_t kauth_op; - if (length <= (int)sizeof(struct rx_header)) + if (length <= sizeof(struct rx_header)) return; - if (ndo->ndo_snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { - goto trunc; - } - /* * Print out the afs call we're invoking. The table used here was * gleaned from kauth/kauth.rg */ - kauth_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); + kauth_op = GET_BE_U_4(bp + sizeof(struct rx_header)); - ND_PRINT((ndo, " kauth")); + ND_PRINT(" kauth"); if (is_ubik(kauth_op)) { ubik_print(ndo, bp); @@ -1920,7 +1883,7 @@ kauth_print(netdissect_options *ndo, } - ND_PRINT((ndo, " call %s", tok2str(kauth_req, "op#%d", kauth_op))); + ND_PRINT(" call %s", tok2str(kauth_req, "op#%u", kauth_op)); /* * Decode some of the arguments to the KA calls @@ -1939,37 +1902,36 @@ kauth_print(netdissect_options *ndo, case 8: /* Get entry */ case 14: /* Unlock */ case 15: /* Lock status */ - ND_PRINT((ndo, " principal")); + ND_PRINT(" principal"); STROUT(KANAMEMAX); STROUT(KANAMEMAX); break; case 3: /* GetTicket-old */ case 23: /* GetTicket */ { - int i; - ND_PRINT((ndo, " kvno")); + uint32_t i; + ND_PRINT(" kvno"); INTOUT(); - ND_PRINT((ndo, " domain")); + ND_PRINT(" domain"); STROUT(KANAMEMAX); - ND_TCHECK2(bp[0], sizeof(int32_t)); - i = (int) EXTRACT_32BITS(bp); - bp += sizeof(int32_t); - ND_TCHECK2(bp[0], i); + i = GET_BE_U_4(bp); + bp += sizeof(uint32_t); + ND_TCHECK_LEN(bp, i); bp += i; - ND_PRINT((ndo, " principal")); + ND_PRINT(" principal"); STROUT(KANAMEMAX); STROUT(KANAMEMAX); break; } case 4: /* Set Password */ - ND_PRINT((ndo, " principal")); + ND_PRINT(" principal"); STROUT(KANAMEMAX); STROUT(KANAMEMAX); - ND_PRINT((ndo, " kvno")); + ND_PRINT(" kvno"); INTOUT(); break; case 12: /* Get password */ - ND_PRINT((ndo, " name")); + ND_PRINT(" name"); STROUT(KANAMEMAX); break; default: @@ -1979,7 +1941,7 @@ kauth_print(netdissect_options *ndo, return; trunc: - ND_PRINT((ndo, " [|kauth]")); + ND_PRINT(" [|kauth]"); } /* @@ -1988,11 +1950,12 @@ trunc: static void kauth_reply_print(netdissect_options *ndo, - register const u_char *bp, int length, int32_t opcode) + const u_char *bp, u_int length, uint32_t opcode) { const struct rx_header *rxh; + uint8_t type; - if (length <= (int)sizeof(struct rx_header)) + if (length <= sizeof(struct rx_header)) return; rxh = (const struct rx_header *) bp; @@ -2002,36 +1965,32 @@ kauth_reply_print(netdissect_options *ndo, * gleaned from kauth/kauth.rg */ - ND_PRINT((ndo, " kauth")); + ND_PRINT(" kauth"); if (is_ubik(opcode)) { ubik_reply_print(ndo, bp, length, opcode); return; } - ND_PRINT((ndo, " reply %s", tok2str(kauth_req, "op#%d", opcode))); + ND_PRINT(" reply %s", tok2str(kauth_req, "op#%u", opcode)); + type = GET_U_1(rxh->type); bp += sizeof(struct rx_header); /* * If it was a data packet, interpret the response. */ - if (rxh->type == RX_PACKET_TYPE_DATA) + if (type == RX_PACKET_TYPE_DATA) /* Well, no, not really. Leave this for later */ ; else { /* * Otherwise, just print out the return code */ - ND_PRINT((ndo, " errcode")); + ND_PRINT(" errcode"); INTOUT(); } - - return; - -trunc: - ND_PRINT((ndo, " [|kauth]")); } /* @@ -2040,144 +1999,140 @@ trunc: static void vol_print(netdissect_options *ndo, - register const u_char *bp, int length) + const u_char *bp, u_int length) { - int vol_op; + uint32_t vol_op; - if (length <= (int)sizeof(struct rx_header)) + if (length <= sizeof(struct rx_header)) return; - if (ndo->ndo_snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { - goto trunc; - } - /* * Print out the afs call we're invoking. The table used here was * gleaned from volser/volint.xg */ - vol_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); + vol_op = GET_BE_U_4(bp + sizeof(struct rx_header)); - ND_PRINT((ndo, " vol call %s", tok2str(vol_req, "op#%d", vol_op))); + ND_PRINT(" vol call %s", tok2str(vol_req, "op#%u", vol_op)); bp += sizeof(struct rx_header) + 4; switch (vol_op) { case 100: /* Create volume */ - ND_PRINT((ndo, " partition")); + ND_PRINT(" partition"); UINTOUT(); - ND_PRINT((ndo, " name")); + ND_PRINT(" name"); STROUT(AFSNAMEMAX); - ND_PRINT((ndo, " type")); + ND_PRINT(" type"); UINTOUT(); - ND_PRINT((ndo, " parent")); + ND_PRINT(" parent"); UINTOUT(); break; case 101: /* Delete volume */ case 107: /* Get flags */ - ND_PRINT((ndo, " trans")); + ND_PRINT(" trans"); UINTOUT(); break; case 102: /* Restore */ - ND_PRINT((ndo, " totrans")); + ND_PRINT(" totrans"); UINTOUT(); - ND_PRINT((ndo, " flags")); + ND_PRINT(" flags"); UINTOUT(); break; case 103: /* Forward */ - ND_PRINT((ndo, " fromtrans")); + ND_PRINT(" fromtrans"); UINTOUT(); - ND_PRINT((ndo, " fromdate")); + ND_PRINT(" fromdate"); DATEOUT(); DESTSERVEROUT(); - ND_PRINT((ndo, " desttrans")); + ND_PRINT(" desttrans"); INTOUT(); break; case 104: /* End trans */ - ND_PRINT((ndo, " trans")); + ND_PRINT(" trans"); UINTOUT(); break; case 105: /* Clone */ - ND_PRINT((ndo, " trans")); + ND_PRINT(" trans"); UINTOUT(); - ND_PRINT((ndo, " purgevol")); + ND_PRINT(" purgevol"); UINTOUT(); - ND_PRINT((ndo, " newtype")); + ND_PRINT(" newtype"); UINTOUT(); - ND_PRINT((ndo, " newname")); + ND_PRINT(" newname"); STROUT(AFSNAMEMAX); break; case 106: /* Set flags */ - ND_PRINT((ndo, " trans")); + ND_PRINT(" trans"); UINTOUT(); - ND_PRINT((ndo, " flags")); + ND_PRINT(" flags"); UINTOUT(); break; case 108: /* Trans create */ - ND_PRINT((ndo, " vol")); + ND_PRINT(" vol"); UINTOUT(); - ND_PRINT((ndo, " partition")); + ND_PRINT(" partition"); UINTOUT(); - ND_PRINT((ndo, " flags")); + ND_PRINT(" flags"); UINTOUT(); break; case 109: /* Dump */ case 655537: /* Get size */ - ND_PRINT((ndo, " fromtrans")); + ND_PRINT(" fromtrans"); UINTOUT(); - ND_PRINT((ndo, " fromdate")); + ND_PRINT(" fromdate"); DATEOUT(); break; case 110: /* Get n-th volume */ - ND_PRINT((ndo, " index")); + ND_PRINT(" index"); UINTOUT(); break; case 111: /* Set forwarding */ - ND_PRINT((ndo, " tid")); + ND_PRINT(" tid"); UINTOUT(); - ND_PRINT((ndo, " newsite")); + ND_PRINT(" newsite"); UINTOUT(); break; case 112: /* Get name */ case 113: /* Get status */ - ND_PRINT((ndo, " tid")); + ND_PRINT(" tid"); break; case 114: /* Signal restore */ - ND_PRINT((ndo, " name")); + ND_PRINT(" name"); STROUT(AFSNAMEMAX); - ND_PRINT((ndo, " type")); + ND_PRINT(" type"); UINTOUT(); - ND_PRINT((ndo, " pid")); + ND_PRINT(" pid"); UINTOUT(); - ND_PRINT((ndo, " cloneid")); + ND_PRINT(" cloneid"); UINTOUT(); break; case 116: /* List volumes */ - ND_PRINT((ndo, " partition")); + ND_PRINT(" partition"); UINTOUT(); - ND_PRINT((ndo, " flags")); + ND_PRINT(" flags"); UINTOUT(); break; case 117: /* Set id types */ - ND_PRINT((ndo, " tid")); + ND_PRINT(" tid"); UINTOUT(); - ND_PRINT((ndo, " name")); + ND_PRINT(" name"); STROUT(AFSNAMEMAX); - ND_PRINT((ndo, " type")); + ND_PRINT(" type"); UINTOUT(); - ND_PRINT((ndo, " pid")); + ND_PRINT(" pid"); UINTOUT(); - ND_PRINT((ndo, " clone")); + ND_PRINT(" clone"); UINTOUT(); - ND_PRINT((ndo, " backup")); + ND_PRINT(" backup"); UINTOUT(); break; case 119: /* Partition info */ - ND_PRINT((ndo, " name")); + ND_PRINT(" name"); STROUT(AFSNAMEMAX); break; case 120: /* Reclone */ - ND_PRINT((ndo, " tid")); + ND_PRINT(" tid"); UINTOUT(); break; case 121: /* List one volume */ @@ -2185,46 +2140,45 @@ vol_print(netdissect_options *ndo, case 124: /* Extended List volumes */ case 125: /* Extended List one volume */ case 65536: /* Convert RO to RW volume */ - ND_PRINT((ndo, " partid")); + ND_PRINT(" partid"); UINTOUT(); - ND_PRINT((ndo, " volid")); + ND_PRINT(" volid"); UINTOUT(); break; case 123: /* Set date */ - ND_PRINT((ndo, " tid")); + ND_PRINT(" tid"); UINTOUT(); - ND_PRINT((ndo, " date")); + ND_PRINT(" date"); DATEOUT(); break; case 126: /* Set info */ - ND_PRINT((ndo, " tid")); + ND_PRINT(" tid"); UINTOUT(); break; case 128: /* Forward multiple */ - ND_PRINT((ndo, " fromtrans")); + ND_PRINT(" fromtrans"); UINTOUT(); - ND_PRINT((ndo, " fromdate")); + ND_PRINT(" fromdate"); DATEOUT(); { - unsigned long i, j; - ND_TCHECK2(bp[0], 4); - j = EXTRACT_32BITS(bp); - bp += sizeof(int32_t); + uint32_t i, j; + j = GET_BE_U_4(bp); + bp += sizeof(uint32_t); for (i = 0; i < j; i++) { DESTSERVEROUT(); if (i != j - 1) - ND_PRINT((ndo, ",")); + ND_PRINT(","); } if (j == 0) - ND_PRINT((ndo, " ")); + ND_PRINT(" "); } break; case 65538: /* Dump version 2 */ - ND_PRINT((ndo, " fromtrans")); + ND_PRINT(" fromtrans"); UINTOUT(); - ND_PRINT((ndo, " fromdate")); + ND_PRINT(" fromdate"); DATEOUT(); - ND_PRINT((ndo, " flags")); + ND_PRINT(" flags"); UINTOUT(); break; default: @@ -2233,7 +2187,7 @@ vol_print(netdissect_options *ndo, return; trunc: - ND_PRINT((ndo, " [|vol]")); + ND_PRINT(" [|vol]"); } /* @@ -2242,11 +2196,12 @@ trunc: static void vol_reply_print(netdissect_options *ndo, - register const u_char *bp, int length, int32_t opcode) + const u_char *bp, u_int length, uint32_t opcode) { const struct rx_header *rxh; + uint8_t type; - if (length <= (int)sizeof(struct rx_header)) + if (length <= sizeof(struct rx_header)) return; rxh = (const struct rx_header *) bp; @@ -2256,77 +2211,78 @@ vol_reply_print(netdissect_options *ndo, * gleaned from volser/volint.xg */ - ND_PRINT((ndo, " vol reply %s", tok2str(vol_req, "op#%d", opcode))); + ND_PRINT(" vol reply %s", tok2str(vol_req, "op#%u", opcode)); + type = GET_U_1(rxh->type); bp += sizeof(struct rx_header); /* * If it was a data packet, interpret the response. */ - if (rxh->type == RX_PACKET_TYPE_DATA) { + if (type == RX_PACKET_TYPE_DATA) { switch (opcode) { case 100: /* Create volume */ - ND_PRINT((ndo, " volid")); + ND_PRINT(" volid"); UINTOUT(); - ND_PRINT((ndo, " trans")); + ND_PRINT(" trans"); UINTOUT(); break; case 104: /* End transaction */ UINTOUT(); break; case 105: /* Clone */ - ND_PRINT((ndo, " newvol")); + ND_PRINT(" newvol"); UINTOUT(); break; case 107: /* Get flags */ UINTOUT(); break; case 108: /* Transaction create */ - ND_PRINT((ndo, " trans")); + ND_PRINT(" trans"); UINTOUT(); break; case 110: /* Get n-th volume */ - ND_PRINT((ndo, " volume")); + ND_PRINT(" volume"); UINTOUT(); - ND_PRINT((ndo, " partition")); + ND_PRINT(" partition"); UINTOUT(); break; case 112: /* Get name */ STROUT(AFSNAMEMAX); break; case 113: /* Get status */ - ND_PRINT((ndo, " volid")); + ND_PRINT(" volid"); UINTOUT(); - ND_PRINT((ndo, " nextuniq")); + ND_PRINT(" nextuniq"); UINTOUT(); - ND_PRINT((ndo, " type")); + ND_PRINT(" type"); UINTOUT(); - ND_PRINT((ndo, " parentid")); + ND_PRINT(" parentid"); UINTOUT(); - ND_PRINT((ndo, " clone")); + ND_PRINT(" clone"); UINTOUT(); - ND_PRINT((ndo, " backup")); + ND_PRINT(" backup"); UINTOUT(); - ND_PRINT((ndo, " restore")); + ND_PRINT(" restore"); UINTOUT(); - ND_PRINT((ndo, " maxquota")); + ND_PRINT(" maxquota"); UINTOUT(); - ND_PRINT((ndo, " minquota")); + ND_PRINT(" minquota"); UINTOUT(); - ND_PRINT((ndo, " owner")); + ND_PRINT(" owner"); UINTOUT(); - ND_PRINT((ndo, " create")); + ND_PRINT(" create"); DATEOUT(); - ND_PRINT((ndo, " access")); + ND_PRINT(" access"); DATEOUT(); - ND_PRINT((ndo, " update")); + ND_PRINT(" update"); DATEOUT(); - ND_PRINT((ndo, " expire")); + ND_PRINT(" expire"); DATEOUT(); - ND_PRINT((ndo, " backup")); + ND_PRINT(" backup"); DATEOUT(); - ND_PRINT((ndo, " copy")); + ND_PRINT(" copy"); DATEOUT(); break; case 115: /* Old list partitions */ @@ -2334,22 +2290,21 @@ vol_reply_print(netdissect_options *ndo, case 116: /* List volumes */ case 121: /* List one volume */ { - unsigned long i, j; - ND_TCHECK2(bp[0], 4); - j = EXTRACT_32BITS(bp); - bp += sizeof(int32_t); + uint32_t i, j; + j = GET_BE_U_4(bp); + bp += sizeof(uint32_t); for (i = 0; i < j; i++) { - ND_PRINT((ndo, " name")); + ND_PRINT(" name"); VECOUT(32); - ND_PRINT((ndo, " volid")); + ND_PRINT(" volid"); UINTOUT(); - ND_PRINT((ndo, " type")); - bp += sizeof(int32_t) * 21; + ND_PRINT(" type"); + bp += sizeof(uint32_t) * 21; if (i != j - 1) - ND_PRINT((ndo, ",")); + ND_PRINT(","); } if (j == 0) - ND_PRINT((ndo, " ")); + ND_PRINT(" "); } break; @@ -2361,14 +2316,14 @@ vol_reply_print(netdissect_options *ndo, /* * Otherwise, just print out the return code */ - ND_PRINT((ndo, " errcode")); + ND_PRINT(" errcode"); INTOUT(); } return; trunc: - ND_PRINT((ndo, " [|vol]")); + ND_PRINT(" [|vol]"); } /* @@ -2377,25 +2332,21 @@ trunc: static void bos_print(netdissect_options *ndo, - register const u_char *bp, int length) + const u_char *bp, u_int length) { - int bos_op; + uint32_t bos_op; - if (length <= (int)sizeof(struct rx_header)) + if (length <= sizeof(struct rx_header)) return; - if (ndo->ndo_snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { - goto trunc; - } - /* * Print out the afs call we're invoking. The table used here was * gleaned from bozo/bosint.xg */ - bos_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); + bos_op = GET_BE_U_4(bp + sizeof(struct rx_header)); - ND_PRINT((ndo, " bos call %s", tok2str(bos_req, "op#%d", bos_op))); + ND_PRINT(" bos call %s", tok2str(bos_req, "op#%u", bos_op)); /* * Decode some of the arguments to the BOS calls @@ -2405,9 +2356,9 @@ bos_print(netdissect_options *ndo, switch (bos_op) { case 80: /* Create B node */ - ND_PRINT((ndo, " type")); + ND_PRINT(" type"); STROUT(BOSNAMEMAX); - ND_PRINT((ndo, " instance")); + ND_PRINT(" instance"); STROUT(BOSNAMEMAX); break; case 81: /* Delete B node */ @@ -2428,12 +2379,12 @@ bos_print(netdissect_options *ndo, case 82: /* Set status */ case 98: /* Set T status */ STROUT(BOSNAMEMAX); - ND_PRINT((ndo, " status")); + ND_PRINT(" status"); INTOUT(); break; case 86: /* Get instance parm */ STROUT(BOSNAMEMAX); - ND_PRINT((ndo, " num")); + ND_PRINT(" num"); INTOUT(); break; case 84: /* Enumerate instance */ @@ -2446,11 +2397,11 @@ bos_print(netdissect_options *ndo, break; case 105: /* Install */ STROUT(BOSNAMEMAX); - ND_PRINT((ndo, " size")); + ND_PRINT(" size"); INTOUT(); - ND_PRINT((ndo, " flags")); + ND_PRINT(" flags"); INTOUT(); - ND_PRINT((ndo, " date")); + ND_PRINT(" date"); INTOUT(); break; default: @@ -2460,7 +2411,7 @@ bos_print(netdissect_options *ndo, return; trunc: - ND_PRINT((ndo, " [|bos]")); + ND_PRINT(" [|bos]"); } /* @@ -2469,11 +2420,12 @@ trunc: static void bos_reply_print(netdissect_options *ndo, - register const u_char *bp, int length, int32_t opcode) + const u_char *bp, u_int length, uint32_t opcode) { const struct rx_header *rxh; + uint8_t type; - if (length <= (int)sizeof(struct rx_header)) + if (length <= sizeof(struct rx_header)) return; rxh = (const struct rx_header *) bp; @@ -2483,29 +2435,25 @@ bos_reply_print(netdissect_options *ndo, * gleaned from volser/volint.xg */ - ND_PRINT((ndo, " bos reply %s", tok2str(bos_req, "op#%d", opcode))); + ND_PRINT(" bos reply %s", tok2str(bos_req, "op#%u", opcode)); + type = GET_U_1(rxh->type); bp += sizeof(struct rx_header); /* * If it was a data packet, interpret the response. */ - if (rxh->type == RX_PACKET_TYPE_DATA) + if (type == RX_PACKET_TYPE_DATA) /* Well, no, not really. Leave this for later */ ; else { /* * Otherwise, just print out the return code */ - ND_PRINT((ndo, " errcode")); + ND_PRINT(" errcode"); INTOUT(); } - - return; - -trunc: - ND_PRINT((ndo, " [|bos]")); } /* @@ -2528,10 +2476,10 @@ is_ubik(uint32_t opcode) static void ubik_print(netdissect_options *ndo, - register const u_char *bp) + const u_char *bp) { - int ubik_op; - int32_t temp; + uint32_t ubik_op; + uint32_t temp; /* * Print out the afs call we're invoking. The table used here was @@ -2542,9 +2490,9 @@ ubik_print(netdissect_options *ndo, * for (sizeof(rx_header) + 4) bytes, so long as it remains this way * the line below will not over-read. */ - ubik_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); + ubik_op = GET_BE_U_4(bp + sizeof(struct rx_header)); - ND_PRINT((ndo, " ubik call %s", tok2str(ubik_req, "op#%d", ubik_op))); + ND_PRINT(" ubik call %s", tok2str(ubik_req, "op#%u", ubik_op)); /* * Decode some of the arguments to the Ubik calls @@ -2554,19 +2502,18 @@ ubik_print(netdissect_options *ndo, switch (ubik_op) { case 10000: /* Beacon */ - ND_TCHECK2(bp[0], 4); - temp = EXTRACT_32BITS(bp); - bp += sizeof(int32_t); - ND_PRINT((ndo, " syncsite %s", temp ? "yes" : "no")); - ND_PRINT((ndo, " votestart")); + temp = GET_BE_U_4(bp); + bp += sizeof(uint32_t); + ND_PRINT(" syncsite %s", temp ? "yes" : "no"); + ND_PRINT(" votestart"); DATEOUT(); - ND_PRINT((ndo, " dbversion")); + ND_PRINT(" dbversion"); UBIK_VERSIONOUT(); - ND_PRINT((ndo, " tid")); + ND_PRINT(" tid"); UBIK_VERSIONOUT(); break; case 10003: /* Get sync site */ - ND_PRINT((ndo, " site")); + ND_PRINT(" site"); UINTOUT(); break; case 20000: /* Begin */ @@ -2574,57 +2521,56 @@ ubik_print(netdissect_options *ndo, case 20007: /* Abort */ case 20008: /* Release locks */ case 20010: /* Writev */ - ND_PRINT((ndo, " tid")); + ND_PRINT(" tid"); UBIK_VERSIONOUT(); break; case 20002: /* Lock */ - ND_PRINT((ndo, " tid")); + ND_PRINT(" tid"); UBIK_VERSIONOUT(); - ND_PRINT((ndo, " file")); + ND_PRINT(" file"); INTOUT(); - ND_PRINT((ndo, " pos")); + ND_PRINT(" pos"); INTOUT(); - ND_PRINT((ndo, " length")); + ND_PRINT(" length"); INTOUT(); - ND_TCHECK_32BITS(bp); - temp = EXTRACT_32BITS(bp); - bp += sizeof(int32_t); - tok2str(ubik_lock_types, "type %d", temp); + temp = GET_BE_U_4(bp); + bp += sizeof(uint32_t); + tok2str(ubik_lock_types, "type %u", temp); break; case 20003: /* Write */ - ND_PRINT((ndo, " tid")); + ND_PRINT(" tid"); UBIK_VERSIONOUT(); - ND_PRINT((ndo, " file")); + ND_PRINT(" file"); INTOUT(); - ND_PRINT((ndo, " pos")); + ND_PRINT(" pos"); INTOUT(); break; case 20005: /* Get file */ - ND_PRINT((ndo, " file")); + ND_PRINT(" file"); INTOUT(); break; case 20006: /* Send file */ - ND_PRINT((ndo, " file")); + ND_PRINT(" file"); INTOUT(); - ND_PRINT((ndo, " length")); + ND_PRINT(" length"); INTOUT(); - ND_PRINT((ndo, " dbversion")); + ND_PRINT(" dbversion"); UBIK_VERSIONOUT(); break; case 20009: /* Truncate */ - ND_PRINT((ndo, " tid")); + ND_PRINT(" tid"); UBIK_VERSIONOUT(); - ND_PRINT((ndo, " file")); + ND_PRINT(" file"); INTOUT(); - ND_PRINT((ndo, " length")); + ND_PRINT(" length"); INTOUT(); break; case 20012: /* Set version */ - ND_PRINT((ndo, " tid")); + ND_PRINT(" tid"); UBIK_VERSIONOUT(); - ND_PRINT((ndo, " oldversion")); + ND_PRINT(" oldversion"); UBIK_VERSIONOUT(); - ND_PRINT((ndo, " newversion")); + ND_PRINT(" newversion"); UBIK_VERSIONOUT(); break; default: @@ -2634,7 +2580,7 @@ ubik_print(netdissect_options *ndo, return; trunc: - ND_PRINT((ndo, " [|ubik]")); + ND_PRINT(" [|ubik]"); } /* @@ -2643,11 +2589,12 @@ trunc: static void ubik_reply_print(netdissect_options *ndo, - register const u_char *bp, int length, int32_t opcode) + const u_char *bp, u_int length, uint32_t opcode) { const struct rx_header *rxh; + uint8_t type; - if (length < (int)sizeof(struct rx_header)) + if (length < sizeof(struct rx_header)) return; rxh = (const struct rx_header *) bp; @@ -2657,21 +2604,22 @@ ubik_reply_print(netdissect_options *ndo, * from ubik/ubik_int.xg */ - ND_PRINT((ndo, " ubik reply %s", tok2str(ubik_req, "op#%d", opcode))); + ND_PRINT(" ubik reply %s", tok2str(ubik_req, "op#%u", opcode)); + type = GET_U_1(rxh->type); bp += sizeof(struct rx_header); /* * If it was a data packet, print out the arguments to the Ubik calls */ - if (rxh->type == RX_PACKET_TYPE_DATA) + if (type == RX_PACKET_TYPE_DATA) switch (opcode) { case 10000: /* Beacon */ - ND_PRINT((ndo, " vote no")); + ND_PRINT(" vote no"); break; case 20004: /* Get version */ - ND_PRINT((ndo, " dbversion")); + ND_PRINT(" dbversion"); UBIK_VERSIONOUT(); break; default: @@ -2679,7 +2627,7 @@ ubik_reply_print(netdissect_options *ndo, } /* - * Otherwise, print out "yes" it it was a beacon packet (because + * Otherwise, print out "yes" if it was a beacon packet (because * that's how yes votes are returned, go figure), otherwise * just print out the error code. */ @@ -2687,18 +2635,18 @@ ubik_reply_print(netdissect_options *ndo, else switch (opcode) { case 10000: /* Beacon */ - ND_PRINT((ndo, " vote yes until")); + ND_PRINT(" vote yes until"); DATEOUT(); break; default: - ND_PRINT((ndo, " errcode")); + ND_PRINT(" errcode"); INTOUT(); } return; trunc: - ND_PRINT((ndo, " [|ubik]")); + ND_PRINT(" [|ubik]"); } /* @@ -2707,43 +2655,36 @@ trunc: static void rx_ack_print(netdissect_options *ndo, - register const u_char *bp, int length) + const u_char *bp, u_int length) { const struct rx_ackPacket *rxa; + uint8_t nAcks; int i, start, last; uint32_t firstPacket; - if (length < (int)sizeof(struct rx_header)) + if (length < sizeof(struct rx_header)) return; bp += sizeof(struct rx_header); - /* - * This may seem a little odd .... the rx_ackPacket structure - * contains an array of individual packet acknowledgements - * (used for selective ack/nack), but since it's variable in size, - * we don't want to truncate based on the size of the whole - * rx_ackPacket structure. - */ - - ND_TCHECK2(bp[0], sizeof(struct rx_ackPacket) - RX_MAXACKS); + ND_TCHECK_LEN(bp, sizeof(struct rx_ackPacket)); rxa = (const struct rx_ackPacket *) bp; - bp += (sizeof(struct rx_ackPacket) - RX_MAXACKS); + bp += sizeof(struct rx_ackPacket); /* * Print out a few useful things from the ack packet structure */ if (ndo->ndo_vflag > 2) - ND_PRINT((ndo, " bufspace %d maxskew %d", - (int) EXTRACT_16BITS(&rxa->bufferSpace), - (int) EXTRACT_16BITS(&rxa->maxSkew))); + ND_PRINT(" bufspace %u maxskew %u", + GET_BE_U_2(rxa->bufferSpace), + GET_BE_U_2(rxa->maxSkew)); - firstPacket = EXTRACT_32BITS(&rxa->firstPacket); - ND_PRINT((ndo, " first %d serial %d reason %s", - firstPacket, EXTRACT_32BITS(&rxa->serial), - tok2str(rx_ack_reasons, "#%d", (int) rxa->reason))); + firstPacket = GET_BE_U_4(rxa->firstPacket); + ND_PRINT(" first %u serial %u reason %s", + firstPacket, GET_BE_U_4(rxa->serial), + tok2str(rx_ack_reasons, "#%u", GET_U_1(rxa->reason))); /* * Okay, now we print out the ack array. The way _this_ works @@ -2764,17 +2705,18 @@ rx_ack_print(netdissect_options *ndo, * to bp after this, so bp ends up at the right spot. Go figure. */ - if (rxa->nAcks != 0) { + nAcks = GET_U_1(rxa->nAcks); + if (nAcks != 0) { - ND_TCHECK2(bp[0], rxa->nAcks); + ND_TCHECK_LEN(bp, nAcks); /* * Sigh, this is gross, but it seems to work to collapse * ranges correctly. */ - for (i = 0, start = last = -2; i < rxa->nAcks; i++) - if (rxa->acks[i] == RX_ACK_TYPE_ACK) { + for (i = 0, start = last = -2; i < nAcks; i++) + if (GET_U_1(bp + i) == RX_ACK_TYPE_ACK) { /* * I figured this deserved _some_ explanation. @@ -2784,7 +2726,7 @@ rx_ack_print(netdissect_options *ndo, */ if (last == -2) { - ND_PRINT((ndo, " acked %d", firstPacket + i)); + ND_PRINT(" acked %u", firstPacket + i); start = i; } @@ -2793,12 +2735,12 @@ rx_ack_print(netdissect_options *ndo, * the range (such as an nacked packet in * the middle of some acked packets), * then print the current packet number - * seperated from the last number by + * separated from the last number by * a comma. */ else if (last != i - 1) { - ND_PRINT((ndo, ",%d", firstPacket + i)); + ND_PRINT(",%u", firstPacket + i); start = i; } @@ -2816,7 +2758,7 @@ rx_ack_print(netdissect_options *ndo, * we hit a nack ... in _this_ case we * want to print out the range of packets * that were acked, so we need to print - * the _previous_ packet number seperated + * the _previous_ packet number separated * from the first by a dash (-). Since we * already printed the first packet above, * just print the final packet. Don't @@ -2824,7 +2766,7 @@ rx_ack_print(netdissect_options *ndo, * range. */ } else if (last == i - 1 && start != last) - ND_PRINT((ndo, "-%d", firstPacket + i - 1)); + ND_PRINT("-%u", firstPacket + i - 1); /* * So, what's going on here? We ran off the end of the @@ -2838,31 +2780,33 @@ rx_ack_print(netdissect_options *ndo, */ if (last == i - 1 && start != last) - ND_PRINT((ndo, "-%d", firstPacket + i - 1)); + ND_PRINT("-%u", firstPacket + i - 1); /* * Same as above, just without comments */ - for (i = 0, start = last = -2; i < rxa->nAcks; i++) - if (rxa->acks[i] == RX_ACK_TYPE_NACK) { + for (i = 0, start = last = -2; i < nAcks; i++) + if (GET_U_1(bp + i) == RX_ACK_TYPE_NACK) { if (last == -2) { - ND_PRINT((ndo, " nacked %d", firstPacket + i)); + ND_PRINT(" nacked %u", firstPacket + i); start = i; } else if (last != i - 1) { - ND_PRINT((ndo, ",%d", firstPacket + i)); + ND_PRINT(",%u", firstPacket + i); start = i; } last = i; } else if (last == i - 1 && start != last) - ND_PRINT((ndo, "-%d", firstPacket + i - 1)); + ND_PRINT("-%u", firstPacket + i - 1); if (last == i - 1 && start != last) - ND_PRINT((ndo, "-%d", firstPacket + i - 1)); + ND_PRINT("-%u", firstPacket + i - 1); - bp += rxa->nAcks; + bp += nAcks; } + /* Padding. */ + bp += 3; /* * These are optional fields; depending on your version of AFS, @@ -2873,25 +2817,25 @@ rx_ack_print(netdissect_options *ndo, if (ndo->ndo_vflag > 1) { TRUNCRET(4); - ND_PRINT((ndo, " ifmtu")); - INTOUT(); + ND_PRINT(" ifmtu"); + UINTOUT(); TRUNCRET(4); - ND_PRINT((ndo, " maxmtu")); - INTOUT(); + ND_PRINT(" maxmtu"); + UINTOUT(); TRUNCRET(4); - ND_PRINT((ndo, " rwind")); - INTOUT(); + ND_PRINT(" rwind"); + UINTOUT(); TRUNCRET(4); - ND_PRINT((ndo, " maxpackets")); - INTOUT(); + ND_PRINT(" maxpackets"); + UINTOUT(); } return; trunc: - ND_PRINT((ndo, " [|ack]")); + ND_PRINT(" [|ack]"); } #undef TRUNCRET diff --git a/contrib/tcpdump/print-sctp.c b/contrib/tcpdump/print-sctp.c index f625dce67b..ad0f785188 100644 --- a/contrib/tcpdump/print-sctp.c +++ b/contrib/tcpdump/print-sctp.c @@ -36,10 +36,10 @@ /* \summary: Stream Control Transmission Protocol (SCTP) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "addrtoname.h" @@ -89,7 +89,7 @@ * qxie1@email.mot.com * * Any bugs reported given to us we will try to fix... any fixes shared will - * be incorperated into the next SCTP release. + * be incorporated into the next SCTP release. */ /* The valid defines for all message @@ -153,36 +153,36 @@ static const struct tok sctp_chunkid_str[] = { /* the sctp common header */ struct sctpHeader{ - uint16_t source; - uint16_t destination; - uint32_t verificationTag; - uint32_t adler32; + nd_uint16_t source; + nd_uint16_t destination; + nd_uint32_t verificationTag; + nd_uint32_t adler32; }; /* various descriptor parsers */ struct sctpChunkDesc{ - uint8_t chunkID; - uint8_t chunkFlg; - uint16_t chunkLength; + nd_uint8_t chunkID; + nd_uint8_t chunkFlg; + nd_uint16_t chunkLength; }; struct sctpParamDesc{ - uint16_t paramType; - uint16_t paramLength; + nd_uint16_t paramType; + nd_uint16_t paramLength; }; struct sctpRelChunkDesc{ struct sctpChunkDesc chk; - uint32_t serialNumber; + nd_uint32_t serialNumber; }; struct sctpVendorSpecificParam { struct sctpParamDesc p; /* type must be 0xfffe */ - uint32_t vendorId; /* vendor ID from RFC 1700 */ - uint16_t vendorSpecificType; - uint16_t vendorSpecificLen; + nd_uint32_t vendorId; /* vendor ID from RFC 1700 */ + nd_uint16_t vendorSpecificType; + nd_uint16_t vendorSpecificLen; }; @@ -194,57 +194,40 @@ struct sctpVendorSpecificParam { /* this is used for init ack, too */ struct sctpInitiation{ - uint32_t initTag; /* tag of mine */ - uint32_t rcvWindowCredit; /* rwnd */ - uint16_t NumPreopenStreams; /* OS */ - uint16_t MaxInboundStreams; /* MIS */ - uint32_t initialTSN; + nd_uint32_t initTag; /* tag of mine */ + nd_uint32_t rcvWindowCredit; /* rwnd */ + nd_uint16_t NumPreopenStreams; /* OS */ + nd_uint16_t MaxInboundStreams; /* MIS */ + nd_uint32_t initialTSN; /* optional param's follow in sctpParamDesc form */ }; struct sctpV4IpAddress{ struct sctpParamDesc p; /* type is set to SCTP_IPV4_PARAM_TYPE, len=10 */ - uint32_t ipAddress; + nd_ipv4 ipAddress; }; struct sctpV6IpAddress{ struct sctpParamDesc p; /* type is set to SCTP_IPV6_PARAM_TYPE, len=22 */ - uint8_t ipAddress[16]; + nd_ipv6 ipAddress; }; struct sctpDNSName{ struct sctpParamDesc param; - uint8_t name[1]; + nd_byte name[1]; }; struct sctpCookiePreserve{ struct sctpParamDesc p; /* type is set to SCTP_COOKIE_PRESERVE, len=8 */ - uint32_t extraTime; + nd_uint32_t extraTime; }; struct sctpTimeStamp{ - uint32_t ts_sec; - uint32_t ts_usec; -}; - -/* wire structure of my cookie */ -struct cookieMessage{ - uint32_t TieTag_curTag; /* copied from assoc if present */ - uint32_t TieTag_hisTag; /* copied from assoc if present */ - int32_t cookieLife; /* life I will award this cookie */ - struct sctpTimeStamp timeEnteringState; /* the time I built cookie */ - struct sctpInitiation initAckISent; /* the INIT-ACK that I sent to my peer */ - uint32_t addressWhereISent[4]; /* I make this 4 ints so I get 128bits for future */ - int32_t addrtype; /* address type */ - uint16_t locScope; /* V6 local scope flag */ - uint16_t siteScope; /* V6 site scope flag */ - /* at the end is tacked on the INIT chunk sent in - * its entirety and of course our - * signature. - */ + nd_uint32_t ts_sec; + nd_uint32_t ts_usec; }; @@ -266,21 +249,21 @@ struct sctpSendableInit{ /* Selective Acknowledgement * has the following structure with - * a optional ammount of trailing int's + * a optional amount of trailing int's * on the last part (based on the numberOfDesc * field). */ struct sctpSelectiveAck{ - uint32_t highestConseqTSN; - uint32_t updatedRwnd; - uint16_t numberOfdesc; - uint16_t numDupTsns; + nd_uint32_t highestConseqTSN; + nd_uint32_t updatedRwnd; + nd_uint16_t numberOfdesc; + nd_uint16_t numDupTsns; }; struct sctpSelectiveFrag{ - uint16_t fragmentStart; - uint16_t fragmentEnd; + nd_uint16_t fragmentStart; + nd_uint16_t fragmentEnd; }; @@ -289,33 +272,6 @@ struct sctpUnifiedSack{ struct sctpSelectiveAck sack; }; -/* for both RTT request/response the - * following is sent - */ - -struct sctpHBrequest { - uint32_t time_value_1; - uint32_t time_value_2; -}; - -/* here is what I read and respond with to. */ -struct sctpHBunified{ - struct sctpChunkDesc hdr; - struct sctpParamDesc hb; -}; - - -/* here is what I send */ -struct sctpHBsender{ - struct sctpChunkDesc hdr; - struct sctpParamDesc hb; - struct sctpHBrequest rtt; - int8_t addrFmt[SCTP_ADDRMAX]; - uint16_t userreq; -}; - - - /* for the abort and shutdown ACK * we must carry the init tag in the common header. Just the * common header is all that is needed with a chunk descriptor. @@ -332,15 +288,15 @@ struct sctpUnifiedAbortLight{ struct sctpUnifiedAbortHeavy{ struct sctpHeader mh; struct sctpChunkDesc uh; - uint16_t causeCode; - uint16_t causeLen; + nd_uint16_t causeCode; + nd_uint16_t causeLen; }; /* For the graceful shutdown we must carry * the tag (in common header) and the highest consequitive acking value */ struct sctpShutdown { - uint32_t TSN_Seen; + nd_uint32_t TSN_Seen; }; struct sctpUnifiedShutdown{ @@ -353,8 +309,8 @@ struct sctpUnifiedShutdown{ * that is defined as a operation error. */ struct sctpOpErrorCause{ - uint16_t cause; - uint16_t causeLen; + nd_uint16_t cause; + nd_uint16_t causeLen; }; struct sctpUnifiedOpError{ @@ -366,15 +322,15 @@ struct sctpUnifiedStreamError{ struct sctpHeader mh; struct sctpChunkDesc uh; struct sctpOpErrorCause c; - uint16_t strmNum; - uint16_t reserved; + nd_uint16_t strmNum; + nd_uint16_t reserved; }; struct staleCookieMsg{ struct sctpHeader mh; struct sctpChunkDesc uh; struct sctpOpErrorCause c; - uint32_t moretime; + nd_uint32_t moretime; }; /* the following is used in all sends @@ -387,10 +343,10 @@ struct sctpUnifiedSingleMsg{ }; struct sctpDataPart{ - uint32_t TSN; - uint16_t streamId; - uint16_t sequence; - uint32_t payloadtype; + nd_uint32_t TSN; + nd_uint16_t streamId; + nd_uint16_t sequence; + nd_uint32_t payloadtype; }; struct sctpUnifiedDatagram{ @@ -400,13 +356,13 @@ struct sctpUnifiedDatagram{ struct sctpECN_echo{ struct sctpChunkDesc uh; - uint32_t Lowest_TSN; + nd_uint32_t Lowest_TSN; }; struct sctpCWR{ struct sctpChunkDesc uh; - uint32_t TSN_reduced_at; + nd_uint32_t TSN_reduced_at; }; static const struct tok ForCES_channels[] = { @@ -478,7 +434,8 @@ static const struct tok PayloadProto_idents[] = { }; -static inline int isForCES_port(u_short Port) +static int +isForCES_port(u_short Port) { if (Port == CHAN_HP) return 1; @@ -490,33 +447,36 @@ static inline int isForCES_port(u_short Port) return 0; } -void sctp_print(netdissect_options *ndo, - const u_char *bp, /* beginning of sctp packet */ - const u_char *bp2, /* beginning of enclosing */ - u_int sctpPacketLength) /* ip packet */ +void +sctp_print(netdissect_options *ndo, + const u_char *bp, /* beginning of sctp packet */ + const u_char *bp2, /* beginning of enclosing */ + u_int sctpPacketLength) /* ip packet */ { u_int sctpPacketLengthRemaining; const struct sctpHeader *sctpPktHdr; const struct ip *ip; const struct ip6_hdr *ip6; + uint8_t chunkID; u_short sourcePort, destPort; - int chunkCount; + u_int chunkCount; const struct sctpChunkDesc *chunkDescPtr; const char *sep; int isforces = 0; + ndo->ndo_protocol = "sctp"; if (sctpPacketLength < sizeof(struct sctpHeader)) { - ND_PRINT((ndo, "truncated-sctp - %ld bytes missing!", - (long)(sizeof(struct sctpHeader) - sctpPacketLength))); + ND_PRINT("truncated-sctp - %zu bytes missing!", + sizeof(struct sctpHeader) - sctpPacketLength); return; } sctpPktHdr = (const struct sctpHeader*) bp; - ND_TCHECK(*sctpPktHdr); + ND_TCHECK_SIZE(sctpPktHdr); sctpPacketLengthRemaining = sctpPacketLength; - sourcePort = EXTRACT_16BITS(&sctpPktHdr->source); - destPort = EXTRACT_16BITS(&sctpPktHdr->destination); + sourcePort = GET_BE_U_2(sctpPktHdr->source); + destPort = GET_BE_U_2(sctpPktHdr->destination); ip = (const struct ip *)bp2; if (IP_V(ip) == 6) @@ -525,27 +485,26 @@ void sctp_print(netdissect_options *ndo, ip6 = NULL; if (ip6) { - ND_PRINT((ndo, "%s.%d > %s.%d: sctp", - ip6addr_string(ndo, &ip6->ip6_src), + ND_PRINT("%s.%u > %s.%u: sctp", + GET_IP6ADDR_STRING(ip6->ip6_src), sourcePort, - ip6addr_string(ndo, &ip6->ip6_dst), - destPort)); - } else - { - ND_PRINT((ndo, "%s.%d > %s.%d: sctp", - ipaddr_string(ndo, &ip->ip_src), + GET_IP6ADDR_STRING(ip6->ip6_dst), + destPort); + } else { + ND_PRINT("%s.%u > %s.%u: sctp", + GET_IPADDR_STRING(ip->ip_src), sourcePort, - ipaddr_string(ndo, &ip->ip_dst), - destPort)); + GET_IPADDR_STRING(ip->ip_dst), + destPort); } if (isForCES_port(sourcePort)) { - ND_PRINT((ndo, "[%s]", tok2str(ForCES_channels, NULL, sourcePort))); - isforces = 1; + ND_PRINT("[%s]", tok2str(ForCES_channels, NULL, sourcePort)); + isforces = 1; } if (isForCES_port(destPort)) { - ND_PRINT((ndo, "[%s]", tok2str(ForCES_channels, NULL, destPort))); - isforces = 1; + ND_PRINT("[%s]", tok2str(ForCES_channels, NULL, destPort)); + isforces = 1; } bp += sizeof(struct sctpHeader); @@ -565,14 +524,14 @@ void sctp_print(netdissect_options *ndo, chunkDescPtr = (const struct sctpChunkDesc *)bp; if (sctpPacketLengthRemaining < sizeof(*chunkDescPtr)) { - ND_PRINT((ndo, "%s%d) [chunk descriptor cut off at end of packet]", sep, chunkCount+1)); - break; + ND_PRINT("%s%u) [chunk descriptor cut off at end of packet]", sep, chunkCount+1); + break; } - ND_TCHECK(*chunkDescPtr); - chunkLength = EXTRACT_16BITS(&chunkDescPtr->chunkLength); + ND_TCHECK_SIZE(chunkDescPtr); + chunkLength = GET_BE_U_2(chunkDescPtr->chunkLength); if (chunkLength < sizeof(*chunkDescPtr)) { - ND_PRINT((ndo, "%s%d) [Bad chunk length %u, < size of chunk descriptor]", sep, chunkCount+1, chunkLength)); - break; + ND_PRINT("%s%u) [Bad chunk length %u, < size of chunk descriptor]", sep, chunkCount+1, chunkLength); + break; } chunkLengthRemaining = chunkLength; @@ -581,61 +540,56 @@ void sctp_print(netdissect_options *ndo, align = 4 - align; if (sctpPacketLengthRemaining < align) { - ND_PRINT((ndo, "%s%d) [Bad chunk length %u, > remaining data in packet]", sep, chunkCount+1, chunkLength)); - break; + ND_PRINT("%s%u) [Bad chunk length %u, > remaining data in packet]", sep, chunkCount+1, chunkLength); + break; } - ND_TCHECK2(*bp, chunkLength); + ND_TCHECK_LEN(bp, chunkLength); bp += sizeof(*chunkDescPtr); sctpPacketLengthRemaining -= sizeof(*chunkDescPtr); chunkLengthRemaining -= sizeof(*chunkDescPtr); - ND_PRINT((ndo, "%s%d) ", sep, chunkCount+1)); - ND_PRINT((ndo, "[%s] ", tok2str(sctp_chunkid_str, "Unknown chunk type: 0x%x", - chunkDescPtr->chunkID))); - switch (chunkDescPtr->chunkID) + ND_PRINT("%s%u) ", sep, chunkCount+1); + chunkID = GET_U_1(chunkDescPtr->chunkID); + ND_PRINT("[%s] ", tok2str(sctp_chunkid_str, "Unknown chunk type: 0x%x", + chunkID)); + switch (chunkID) { case SCTP_DATA : { const struct sctpDataPart *dataHdrPtr; + uint8_t chunkFlg; uint32_t ppid; - u_int payload_size; - - if ((chunkDescPtr->chunkFlg & SCTP_DATA_UNORDERED) - == SCTP_DATA_UNORDERED) - ND_PRINT((ndo, "(U)")); - - if ((chunkDescPtr->chunkFlg & SCTP_DATA_FIRST_FRAG) - == SCTP_DATA_FIRST_FRAG) - ND_PRINT((ndo, "(B)")); - - if ((chunkDescPtr->chunkFlg & SCTP_DATA_LAST_FRAG) - == SCTP_DATA_LAST_FRAG) - ND_PRINT((ndo, "(E)")); - - if( ((chunkDescPtr->chunkFlg & SCTP_DATA_UNORDERED) - == SCTP_DATA_UNORDERED) - || - ((chunkDescPtr->chunkFlg & SCTP_DATA_FIRST_FRAG) - == SCTP_DATA_FIRST_FRAG) - || - ((chunkDescPtr->chunkFlg & SCTP_DATA_LAST_FRAG) - == SCTP_DATA_LAST_FRAG) ) - ND_PRINT((ndo, " ")); + uint16_t payload_size; + + chunkFlg = GET_U_1(chunkDescPtr->chunkFlg); + if ((chunkFlg & SCTP_DATA_UNORDERED) == SCTP_DATA_UNORDERED) + ND_PRINT("(U)"); + + if ((chunkFlg & SCTP_DATA_FIRST_FRAG) == SCTP_DATA_FIRST_FRAG) + ND_PRINT("(B)"); + + if ((chunkFlg & SCTP_DATA_LAST_FRAG) == SCTP_DATA_LAST_FRAG) + ND_PRINT("(E)"); + + if( ((chunkFlg & SCTP_DATA_UNORDERED) == SCTP_DATA_UNORDERED) || + ((chunkFlg & SCTP_DATA_FIRST_FRAG) == SCTP_DATA_FIRST_FRAG) || + ((chunkFlg & SCTP_DATA_LAST_FRAG) == SCTP_DATA_LAST_FRAG) ) + ND_PRINT(" "); if (chunkLengthRemaining < sizeof(*dataHdrPtr)) { - ND_PRINT((ndo, "bogus chunk length %u]", chunkLength)); + ND_PRINT("bogus chunk length %u]", chunkLength); return; } dataHdrPtr=(const struct sctpDataPart*)bp; - ppid = EXTRACT_32BITS(&dataHdrPtr->payloadtype); - ND_PRINT((ndo, "[TSN: %u] ", EXTRACT_32BITS(&dataHdrPtr->TSN))); - ND_PRINT((ndo, "[SID: %u] ", EXTRACT_16BITS(&dataHdrPtr->streamId))); - ND_PRINT((ndo, "[SSEQ %u] ", EXTRACT_16BITS(&dataHdrPtr->sequence))); - ND_PRINT((ndo, "[PPID %s] ", - tok2str(PayloadProto_idents, "0x%x", ppid))); + ppid = GET_BE_U_4(dataHdrPtr->payloadtype); + ND_PRINT("[TSN: %u] ", GET_BE_U_4(dataHdrPtr->TSN)); + ND_PRINT("[SID: %u] ", GET_BE_U_2(dataHdrPtr->streamId)); + ND_PRINT("[SSEQ %u] ", GET_BE_U_2(dataHdrPtr->sequence)); + ND_PRINT("[PPID %s] ", + tok2str(PayloadProto_idents, "0x%x", ppid)); if (!isforces) { isforces = (ppid == SCTP_PPID_FORCES_HP) || @@ -648,25 +602,29 @@ void sctp_print(netdissect_options *ndo, chunkLengthRemaining -= sizeof(*dataHdrPtr); payload_size = chunkLengthRemaining; if (payload_size == 0) { - ND_PRINT((ndo, "bogus chunk length %u]", chunkLength)); + ND_PRINT("bogus chunk length %u]", chunkLength); return; } if (isforces) { forces_print(ndo, bp, payload_size); + /* ndo_protocol reassignment after forces_print() call */ + ndo->ndo_protocol = "sctp"; } else if (ndo->ndo_vflag >= 2) { /* if verbose output is specified */ /* at the command line */ switch (ppid) { case SCTP_PPID_M3UA : m3ua_print(ndo, bp, payload_size); + /* ndo_protocol reassignment after m3ua_print() call */ + ndo->ndo_protocol = "sctp"; break; default: - ND_PRINT((ndo, "[Payload")); + ND_PRINT("[Payload"); if (!ndo->ndo_suppress_default_print) { - ND_PRINT((ndo, ":")); + ND_PRINT(":"); ND_DEFAULTPRINT(bp, payload_size); } - ND_PRINT((ndo, "]")); + ND_PRINT("]"); break; } } @@ -680,27 +638,27 @@ void sctp_print(netdissect_options *ndo, const struct sctpInitiation *init; if (chunkLengthRemaining < sizeof(*init)) { - ND_PRINT((ndo, "bogus chunk length %u]", chunkLength)); + ND_PRINT("bogus chunk length %u]", chunkLength); return; } init=(const struct sctpInitiation*)bp; - ND_PRINT((ndo, "[init tag: %u] ", EXTRACT_32BITS(&init->initTag))); - ND_PRINT((ndo, "[rwnd: %u] ", EXTRACT_32BITS(&init->rcvWindowCredit))); - ND_PRINT((ndo, "[OS: %u] ", EXTRACT_16BITS(&init->NumPreopenStreams))); - ND_PRINT((ndo, "[MIS: %u] ", EXTRACT_16BITS(&init->MaxInboundStreams))); - ND_PRINT((ndo, "[init TSN: %u] ", EXTRACT_32BITS(&init->initialTSN))); + ND_PRINT("[init tag: %u] ", GET_BE_U_4(init->initTag)); + ND_PRINT("[rwnd: %u] ", GET_BE_U_4(init->rcvWindowCredit)); + ND_PRINT("[OS: %u] ", GET_BE_U_2(init->NumPreopenStreams)); + ND_PRINT("[MIS: %u] ", GET_BE_U_2(init->MaxInboundStreams)); + ND_PRINT("[init TSN: %u] ", GET_BE_U_4(init->initialTSN)); bp += sizeof(*init); - sctpPacketLengthRemaining -= sizeof(*init); + sctpPacketLengthRemaining -= sizeof(*init); chunkLengthRemaining -= sizeof(*init); #if 0 /* ALC you can add code for optional params here */ if( chunkLengthRemaining != 0 ) - ND_PRINT((ndo, " @@@@@ UNFINISHED @@@@@@%s\n", - "Optional params present, but not printed.")); + ND_PRINT(" @@@@@ UNFINISHED @@@@@@%s\n", + "Optional params present, but not printed."); #endif - bp += chunkLengthRemaining; + bp += chunkLengthRemaining; sctpPacketLengthRemaining -= chunkLengthRemaining; - chunkLengthRemaining = 0; + chunkLengthRemaining = 0; break; } case SCTP_INITIATION_ACK : @@ -708,84 +666,84 @@ void sctp_print(netdissect_options *ndo, const struct sctpInitiation *init; if (chunkLengthRemaining < sizeof(*init)) { - ND_PRINT((ndo, "bogus chunk length %u]", chunkLength)); + ND_PRINT("bogus chunk length %u]", chunkLength); return; } init=(const struct sctpInitiation*)bp; - ND_PRINT((ndo, "[init tag: %u] ", EXTRACT_32BITS(&init->initTag))); - ND_PRINT((ndo, "[rwnd: %u] ", EXTRACT_32BITS(&init->rcvWindowCredit))); - ND_PRINT((ndo, "[OS: %u] ", EXTRACT_16BITS(&init->NumPreopenStreams))); - ND_PRINT((ndo, "[MIS: %u] ", EXTRACT_16BITS(&init->MaxInboundStreams))); - ND_PRINT((ndo, "[init TSN: %u] ", EXTRACT_32BITS(&init->initialTSN))); - bp += sizeof(*init); - sctpPacketLengthRemaining -= sizeof(*init); - chunkLengthRemaining -= sizeof(*init); + ND_PRINT("[init tag: %u] ", GET_BE_U_4(init->initTag)); + ND_PRINT("[rwnd: %u] ", GET_BE_U_4(init->rcvWindowCredit)); + ND_PRINT("[OS: %u] ", GET_BE_U_2(init->NumPreopenStreams)); + ND_PRINT("[MIS: %u] ", GET_BE_U_2(init->MaxInboundStreams)); + ND_PRINT("[init TSN: %u] ", GET_BE_U_4(init->initialTSN)); + bp += sizeof(*init); + sctpPacketLengthRemaining -= sizeof(*init); + chunkLengthRemaining -= sizeof(*init); #if 0 /* ALC you can add code for optional params here */ if( chunkLengthRemaining != 0 ) - ND_PRINT((ndo, " @@@@@ UNFINISHED @@@@@@%s\n", - "Optional params present, but not printed.")); + ND_PRINT(" @@@@@ UNFINISHED @@@@@@%s\n", + "Optional params present, but not printed."); #endif - bp += chunkLengthRemaining; + bp += chunkLengthRemaining; sctpPacketLengthRemaining -= chunkLengthRemaining; - chunkLengthRemaining = 0; + chunkLengthRemaining = 0; break; } case SCTP_SELECTIVE_ACK: { const struct sctpSelectiveAck *sack; const struct sctpSelectiveFrag *frag; - int fragNo, tsnNo; + u_int fragNo, tsnNo; const u_char *dupTSN; if (chunkLengthRemaining < sizeof(*sack)) { - ND_PRINT((ndo, "bogus chunk length %u]", chunkLength)); + ND_PRINT("bogus chunk length %u]", chunkLength); return; } sack=(const struct sctpSelectiveAck*)bp; - ND_PRINT((ndo, "[cum ack %u] ", EXTRACT_32BITS(&sack->highestConseqTSN))); - ND_PRINT((ndo, "[a_rwnd %u] ", EXTRACT_32BITS(&sack->updatedRwnd))); - ND_PRINT((ndo, "[#gap acks %u] ", EXTRACT_16BITS(&sack->numberOfdesc))); - ND_PRINT((ndo, "[#dup tsns %u] ", EXTRACT_16BITS(&sack->numDupTsns))); - bp += sizeof(*sack); + ND_PRINT("[cum ack %u] ", GET_BE_U_4(sack->highestConseqTSN)); + ND_PRINT("[a_rwnd %u] ", GET_BE_U_4(sack->updatedRwnd)); + ND_PRINT("[#gap acks %u] ", GET_BE_U_2(sack->numberOfdesc)); + ND_PRINT("[#dup tsns %u] ", GET_BE_U_2(sack->numDupTsns)); + bp += sizeof(*sack); sctpPacketLengthRemaining -= sizeof(*sack); - chunkLengthRemaining -= sizeof(*sack); + chunkLengthRemaining -= sizeof(*sack); /* print gaps */ for (fragNo=0; - chunkLengthRemaining != 0 && fragNo < EXTRACT_16BITS(&sack->numberOfdesc); + chunkLengthRemaining != 0 && fragNo < GET_BE_U_2(sack->numberOfdesc); bp += sizeof(*frag), sctpPacketLengthRemaining -= sizeof(*frag), chunkLengthRemaining -= sizeof(*frag), fragNo++) { if (chunkLengthRemaining < sizeof(*frag)) { - ND_PRINT((ndo, "bogus chunk length %u]", chunkLength)); + ND_PRINT("bogus chunk length %u]", chunkLength); return; } frag = (const struct sctpSelectiveFrag *)bp; - ND_PRINT((ndo, "\n\t\t[gap ack block #%d: start = %u, end = %u] ", + ND_PRINT("\n\t\t[gap ack block #%u: start = %u, end = %u] ", fragNo+1, - EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentStart), - EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentEnd))); + GET_BE_U_4(sack->highestConseqTSN) + GET_BE_U_2(frag->fragmentStart), + GET_BE_U_4(sack->highestConseqTSN) + GET_BE_U_2(frag->fragmentEnd)); } /* print duplicate TSNs */ for (tsnNo=0; - chunkLengthRemaining != 0 && tsnNonumDupTsns); + chunkLengthRemaining != 0 && tsnNonumDupTsns); bp += 4, sctpPacketLengthRemaining -= 4, chunkLengthRemaining -= 4, tsnNo++) { if (chunkLengthRemaining < 4) { - ND_PRINT((ndo, "bogus chunk length %u]", chunkLength)); + ND_PRINT("bogus chunk length %u]", chunkLength); return; } - dupTSN = (const u_char *)bp; - ND_PRINT((ndo, "\n\t\t[dup TSN #%u: %u] ", tsnNo+1, - EXTRACT_32BITS(dupTSN))); + dupTSN = (const u_char *)bp; + ND_PRINT("\n\t\t[dup TSN #%u: %u] ", tsnNo+1, + GET_BE_U_4(dupTSN)); } break; } default : { - bp += chunkLengthRemaining; - sctpPacketLengthRemaining -= chunkLengthRemaining; - chunkLengthRemaining = 0; + bp += chunkLengthRemaining; + sctpPacketLengthRemaining -= chunkLengthRemaining; + chunkLengthRemaining = 0; break; } } @@ -798,14 +756,14 @@ void sctp_print(netdissect_options *ndo, sctpPacketLengthRemaining -= chunkLengthRemaining; if (ndo->ndo_vflag < 2) - sep = ", ("; + sep = ", ("; if (align != 0) { /* * Fail if the alignment padding isn't in the captured data. * Otherwise, skip it. */ - ND_TCHECK2(*bp, align); + ND_TCHECK_LEN(bp, align); bp += align; sctpPacketLengthRemaining -= align; } @@ -813,5 +771,5 @@ void sctp_print(netdissect_options *ndo, return; trunc: - ND_PRINT((ndo, "[|sctp]")); + nd_print_trunc(ndo); } diff --git a/contrib/tcpdump/print-sflow.c b/contrib/tcpdump/print-sflow.c index dcaf28e864..51325e2822 100644 --- a/contrib/tcpdump/print-sflow.c +++ b/contrib/tcpdump/print-sflow.c @@ -19,14 +19,15 @@ /* \summary: sFlow protocol printer */ -/* specification: http://www.sflow.org/developers/specifications.php */ +/* specification: https://sflow.org/developers/specifications.php */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" #include "addrtoname.h" @@ -55,18 +56,18 @@ */ struct sflow_datagram_t { - uint8_t version[4]; - uint8_t ip_version[4]; - uint8_t agent[4]; - uint8_t agent_id[4]; - uint8_t seqnum[4]; - uint8_t uptime[4]; - uint8_t samples[4]; + nd_uint32_t version; + nd_uint32_t ip_version; + nd_ipv4 agent; + nd_uint32_t agent_id; + nd_uint32_t seqnum; + nd_uint32_t uptime; + nd_uint32_t samples; }; struct sflow_sample_header { - uint8_t format[4]; - uint8_t len[4]; + nd_uint32_t format; + nd_uint32_t len; }; #define SFLOW_FLOW_SAMPLE 1 @@ -83,29 +84,30 @@ static const struct tok sflow_format_values[] = { }; struct sflow_flow_sample_t { - uint8_t seqnum[4]; - uint8_t typesource[4]; - uint8_t rate[4]; - uint8_t pool[4]; - uint8_t drops[4]; - uint8_t in_interface[4]; - uint8_t out_interface[4]; - uint8_t records[4]; + nd_uint32_t seqnum; + nd_uint8_t type; + nd_uint24_t index; + nd_uint32_t rate; + nd_uint32_t pool; + nd_uint32_t drops; + nd_uint32_t in_interface; + nd_uint32_t out_interface; + nd_uint32_t records; }; struct sflow_expanded_flow_sample_t { - uint8_t seqnum[4]; - uint8_t type[4]; - uint8_t index[4]; - uint8_t rate[4]; - uint8_t pool[4]; - uint8_t drops[4]; - uint8_t in_interface_format[4]; - uint8_t in_interface_value[4]; - uint8_t out_interface_format[4]; - uint8_t out_interface_value[4]; - uint8_t records[4]; + nd_uint32_t seqnum; + nd_uint32_t type; + nd_uint32_t index; + nd_uint32_t rate; + nd_uint32_t pool; + nd_uint32_t drops; + nd_uint32_t in_interface_format; + nd_uint32_t in_interface_value; + nd_uint32_t out_interface_format; + nd_uint32_t out_interface_value; + nd_uint32_t records; }; #define SFLOW_FLOW_RAW_PACKET 1 @@ -157,47 +159,48 @@ static const struct tok sflow_flow_raw_protocol_values[] = { }; struct sflow_expanded_flow_raw_t { - uint8_t protocol[4]; - uint8_t length[4]; - uint8_t stripped_bytes[4]; - uint8_t header_size[4]; + nd_uint32_t protocol; + nd_uint32_t length; + nd_uint32_t stripped_bytes; + nd_uint32_t header_size; }; struct sflow_ethernet_frame_t { - uint8_t length[4]; - uint8_t src_mac[8]; - uint8_t dst_mac[8]; - uint8_t type[4]; + nd_uint32_t length; + nd_byte src_mac[8]; + nd_byte dst_mac[8]; + nd_uint32_t type; }; struct sflow_extended_switch_data_t { - uint8_t src_vlan[4]; - uint8_t src_pri[4]; - uint8_t dst_vlan[4]; - uint8_t dst_pri[4]; + nd_uint32_t src_vlan; + nd_uint32_t src_pri; + nd_uint32_t dst_vlan; + nd_uint32_t dst_pri; }; struct sflow_counter_record_t { - uint8_t format[4]; - uint8_t length[4]; + nd_uint32_t format; + nd_uint32_t length; }; struct sflow_flow_record_t { - uint8_t format[4]; - uint8_t length[4]; + nd_uint32_t format; + nd_uint32_t length; }; struct sflow_counter_sample_t { - uint8_t seqnum[4]; - uint8_t typesource[4]; - uint8_t records[4]; + nd_uint32_t seqnum; + nd_uint8_t type; + nd_uint24_t index; + nd_uint32_t records; }; struct sflow_expanded_counter_sample_t { - uint8_t seqnum[4]; - uint8_t type[4]; - uint8_t index[4]; - uint8_t records[4]; + nd_uint32_t seqnum; + nd_uint32_t type; + nd_uint32_t index; + nd_uint32_t records; }; #define SFLOW_COUNTER_GENERIC 1 @@ -233,67 +236,67 @@ static const struct tok sflow_iface_direction_values[] = { }; struct sflow_generic_counter_t { - uint8_t ifindex[4]; - uint8_t iftype[4]; - uint8_t ifspeed[8]; - uint8_t ifdirection[4]; - uint8_t ifstatus[4]; - uint8_t ifinoctets[8]; - uint8_t ifinunicastpkts[4]; - uint8_t ifinmulticastpkts[4]; - uint8_t ifinbroadcastpkts[4]; - uint8_t ifindiscards[4]; - uint8_t ifinerrors[4]; - uint8_t ifinunkownprotos[4]; - uint8_t ifoutoctets[8]; - uint8_t ifoutunicastpkts[4]; - uint8_t ifoutmulticastpkts[4]; - uint8_t ifoutbroadcastpkts[4]; - uint8_t ifoutdiscards[4]; - uint8_t ifouterrors[4]; - uint8_t ifpromiscmode[4]; + nd_uint32_t ifindex; + nd_uint32_t iftype; + nd_uint64_t ifspeed; + nd_uint32_t ifdirection; + nd_uint32_t ifstatus; + nd_uint64_t ifinoctets; + nd_uint32_t ifinunicastpkts; + nd_uint32_t ifinmulticastpkts; + nd_uint32_t ifinbroadcastpkts; + nd_uint32_t ifindiscards; + nd_uint32_t ifinerrors; + nd_uint32_t ifinunkownprotos; + nd_uint64_t ifoutoctets; + nd_uint32_t ifoutunicastpkts; + nd_uint32_t ifoutmulticastpkts; + nd_uint32_t ifoutbroadcastpkts; + nd_uint32_t ifoutdiscards; + nd_uint32_t ifouterrors; + nd_uint32_t ifpromiscmode; }; struct sflow_ethernet_counter_t { - uint8_t alignerrors[4]; - uint8_t fcserrors[4]; - uint8_t single_collision_frames[4]; - uint8_t multiple_collision_frames[4]; - uint8_t test_errors[4]; - uint8_t deferred_transmissions[4]; - uint8_t late_collisions[4]; - uint8_t excessive_collisions[4]; - uint8_t mac_transmit_errors[4]; - uint8_t carrier_sense_errors[4]; - uint8_t frame_too_longs[4]; - uint8_t mac_receive_errors[4]; - uint8_t symbol_errors[4]; + nd_uint32_t alignerrors; + nd_uint32_t fcserrors; + nd_uint32_t single_collision_frames; + nd_uint32_t multiple_collision_frames; + nd_uint32_t test_errors; + nd_uint32_t deferred_transmissions; + nd_uint32_t late_collisions; + nd_uint32_t excessive_collisions; + nd_uint32_t mac_transmit_errors; + nd_uint32_t carrier_sense_errors; + nd_uint32_t frame_too_longs; + nd_uint32_t mac_receive_errors; + nd_uint32_t symbol_errors; }; struct sflow_100basevg_counter_t { - uint8_t in_highpriority_frames[4]; - uint8_t in_highpriority_octets[8]; - uint8_t in_normpriority_frames[4]; - uint8_t in_normpriority_octets[8]; - uint8_t in_ipmerrors[4]; - uint8_t in_oversized[4]; - uint8_t in_data_errors[4]; - uint8_t in_null_addressed_frames[4]; - uint8_t out_highpriority_frames[4]; - uint8_t out_highpriority_octets[8]; - uint8_t transitioninto_frames[4]; - uint8_t hc_in_highpriority_octets[8]; - uint8_t hc_in_normpriority_octets[8]; - uint8_t hc_out_highpriority_octets[8]; + nd_uint32_t in_highpriority_frames; + nd_uint64_t in_highpriority_octets; + nd_uint32_t in_normpriority_frames; + nd_uint64_t in_normpriority_octets; + nd_uint32_t in_ipmerrors; + nd_uint32_t in_oversized; + nd_uint32_t in_data_errors; + nd_uint32_t in_null_addressed_frames; + nd_uint32_t out_highpriority_frames; + nd_uint64_t out_highpriority_octets; + nd_uint32_t transitioninto_frames; + nd_uint64_t hc_in_highpriority_octets; + nd_uint64_t hc_in_normpriority_octets; + nd_uint64_t hc_out_highpriority_octets; }; struct sflow_vlan_counter_t { - uint8_t vlan_id[4]; - uint8_t octets[8]; - uint8_t unicast_pkt[4]; - uint8_t multicast_pkt[4]; - uint8_t broadcast_pkt[4]; - uint8_t discards[4]; + nd_uint32_t vlan_id; + nd_uint64_t octets; + nd_uint32_t unicast_pkt; + nd_uint32_t multicast_pkt; + nd_uint32_t broadcast_pkt; + nd_uint32_t discards; }; static int @@ -306,43 +309,39 @@ print_sflow_counter_generic(netdissect_options *ndo, return 1; sflow_gen_counter = (const struct sflow_generic_counter_t *)pointer; - ND_TCHECK(*sflow_gen_counter); - ND_PRINT((ndo, "\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), + ND_PRINT("\n\t ifindex %u, iftype %u, ifspeed %" PRIu64 ", ifdirection %u (%s)", + GET_BE_U_4(sflow_gen_counter->ifindex), + GET_BE_U_4(sflow_gen_counter->iftype), + GET_BE_U_8(sflow_gen_counter->ifspeed), + GET_BE_U_4(sflow_gen_counter->ifdirection), tok2str(sflow_iface_direction_values, "Unknown", - EXTRACT_32BITS(sflow_gen_counter->ifdirection)))); - ND_PRINT((ndo, "\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")); - ND_PRINT((ndo, "\n\t In octets %" PRIu64 + GET_BE_U_4(sflow_gen_counter->ifdirection))); + ND_PRINT("\n\t ifstatus %u, adminstatus: %s, operstatus: %s", + GET_BE_U_4(sflow_gen_counter->ifstatus), + GET_BE_U_4(sflow_gen_counter->ifstatus)&1 ? "up" : "down", + (GET_BE_U_4(sflow_gen_counter->ifstatus)>>1)&1 ? "up" : "down"); + ND_PRINT("\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))); - ND_PRINT((ndo, "\n\t In errors %u, unknown protos %u", - EXTRACT_32BITS(sflow_gen_counter->ifinerrors), - EXTRACT_32BITS(sflow_gen_counter->ifinunkownprotos))); - ND_PRINT((ndo, "\n\t Out octets %" PRIu64 + GET_BE_U_8(sflow_gen_counter->ifinoctets), + GET_BE_U_4(sflow_gen_counter->ifinunicastpkts), + GET_BE_U_4(sflow_gen_counter->ifinmulticastpkts), + GET_BE_U_4(sflow_gen_counter->ifinbroadcastpkts), + GET_BE_U_4(sflow_gen_counter->ifindiscards)); + ND_PRINT("\n\t In errors %u, unknown protos %u", + GET_BE_U_4(sflow_gen_counter->ifinerrors), + GET_BE_U_4(sflow_gen_counter->ifinunkownprotos)); + ND_PRINT("\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))); - ND_PRINT((ndo, "\n\t Out errors %u, promisc mode %u", - EXTRACT_32BITS(sflow_gen_counter->ifouterrors), - EXTRACT_32BITS(sflow_gen_counter->ifpromiscmode))); + GET_BE_U_8(sflow_gen_counter->ifoutoctets), + GET_BE_U_4(sflow_gen_counter->ifoutunicastpkts), + GET_BE_U_4(sflow_gen_counter->ifoutmulticastpkts), + GET_BE_U_4(sflow_gen_counter->ifoutbroadcastpkts), + GET_BE_U_4(sflow_gen_counter->ifoutdiscards)); + ND_PRINT("\n\t Out errors %u, promisc mode %u", + GET_BE_U_4(sflow_gen_counter->ifouterrors), + GET_BE_U_4(sflow_gen_counter->ifpromiscmode)); return 0; - -trunc: - return 1; } static int @@ -355,28 +354,24 @@ print_sflow_counter_ethernet(netdissect_options *ndo, return 1; sflow_eth_counter = (const struct sflow_ethernet_counter_t *)pointer; - ND_TCHECK(*sflow_eth_counter); - ND_PRINT((ndo, "\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))); - ND_PRINT((ndo, "\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))); - ND_PRINT((ndo, "\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))); + ND_PRINT("\n\t align errors %u, fcs errors %u, single collision %u, multiple collision %u, test error %u", + GET_BE_U_4(sflow_eth_counter->alignerrors), + GET_BE_U_4(sflow_eth_counter->fcserrors), + GET_BE_U_4(sflow_eth_counter->single_collision_frames), + GET_BE_U_4(sflow_eth_counter->multiple_collision_frames), + GET_BE_U_4(sflow_eth_counter->test_errors)); + ND_PRINT("\n\t deferred %u, late collision %u, excessive collision %u, mac trans error %u", + GET_BE_U_4(sflow_eth_counter->deferred_transmissions), + GET_BE_U_4(sflow_eth_counter->late_collisions), + GET_BE_U_4(sflow_eth_counter->excessive_collisions), + GET_BE_U_4(sflow_eth_counter->mac_transmit_errors)); + ND_PRINT("\n\t carrier error %u, frames too long %u, mac receive errors %u, symbol errors %u", + GET_BE_U_4(sflow_eth_counter->carrier_sense_errors), + GET_BE_U_4(sflow_eth_counter->frame_too_longs), + GET_BE_U_4(sflow_eth_counter->mac_receive_errors), + GET_BE_U_4(sflow_eth_counter->symbol_errors)); return 0; - -trunc: - return 1; } static int @@ -396,34 +391,30 @@ print_sflow_counter_basevg(netdissect_options *ndo, return 1; sflow_100basevg_counter = (const struct sflow_100basevg_counter_t *)pointer; - ND_TCHECK(*sflow_100basevg_counter); - ND_PRINT((ndo, "\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))); - ND_PRINT((ndo, "\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))); - ND_PRINT((ndo, "\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))); - ND_PRINT((ndo, "\n\t out high prio frames %u, out high prio octets %" PRIu64 + ND_PRINT("\n\t in high prio frames %u, in high prio octets %" PRIu64, + GET_BE_U_4(sflow_100basevg_counter->in_highpriority_frames), + GET_BE_U_8(sflow_100basevg_counter->in_highpriority_octets)); + ND_PRINT("\n\t in norm prio frames %u, in norm prio octets %" PRIu64, + GET_BE_U_4(sflow_100basevg_counter->in_normpriority_frames), + GET_BE_U_8(sflow_100basevg_counter->in_normpriority_octets)); + ND_PRINT("\n\t in ipm errors %u, oversized %u, in data errors %u, null addressed frames %u", + GET_BE_U_4(sflow_100basevg_counter->in_ipmerrors), + GET_BE_U_4(sflow_100basevg_counter->in_oversized), + GET_BE_U_4(sflow_100basevg_counter->in_data_errors), + GET_BE_U_4(sflow_100basevg_counter->in_null_addressed_frames)); + ND_PRINT("\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))); - ND_PRINT((ndo, "\n\t in hc high prio octets %" PRIu64 + GET_BE_U_4(sflow_100basevg_counter->out_highpriority_frames), + GET_BE_U_8(sflow_100basevg_counter->out_highpriority_octets), + GET_BE_U_4(sflow_100basevg_counter->transitioninto_frames)); + ND_PRINT("\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))); + GET_BE_U_8(sflow_100basevg_counter->hc_in_highpriority_octets), + GET_BE_U_8(sflow_100basevg_counter->hc_in_normpriority_octets), + GET_BE_U_8(sflow_100basevg_counter->hc_out_highpriority_octets)); return 0; - -trunc: - return 1; } static int @@ -436,28 +427,24 @@ print_sflow_counter_vlan(netdissect_options *ndo, return 1; sflow_vlan_counter = (const struct sflow_vlan_counter_t *)pointer; - ND_TCHECK(*sflow_vlan_counter); - ND_PRINT((ndo, "\n\t vlan_id %u, octets %" PRIu64 + ND_PRINT("\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))); + GET_BE_U_4(sflow_vlan_counter->vlan_id), + GET_BE_U_8(sflow_vlan_counter->octets), + GET_BE_U_4(sflow_vlan_counter->unicast_pkt), + GET_BE_U_4(sflow_vlan_counter->multicast_pkt), + GET_BE_U_4(sflow_vlan_counter->broadcast_pkt), + GET_BE_U_4(sflow_vlan_counter->discards)); return 0; - -trunc: - return 1; } struct sflow_processor_counter_t { - uint8_t five_sec_util[4]; - uint8_t one_min_util[4]; - uint8_t five_min_util[4]; - uint8_t total_memory[8]; - uint8_t free_memory[8]; + nd_uint32_t five_sec_util; + nd_uint32_t one_min_util; + nd_uint32_t five_min_util; + nd_uint64_t total_memory; + nd_uint64_t free_memory; }; static int @@ -470,19 +457,15 @@ print_sflow_counter_processor(netdissect_options *ndo, return 1; sflow_processor_counter = (const struct sflow_processor_counter_t *)pointer; - ND_TCHECK(*sflow_processor_counter); - ND_PRINT((ndo, "\n\t 5sec %u, 1min %u, 5min %u, total_mem %" PRIu64 + ND_PRINT("\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))); + GET_BE_U_4(sflow_processor_counter->five_sec_util), + GET_BE_U_4(sflow_processor_counter->one_min_util), + GET_BE_U_4(sflow_processor_counter->five_min_util), + GET_BE_U_8(sflow_processor_counter->total_memory), + GET_BE_U_8(sflow_processor_counter->free_memory)); return 0; - -trunc: - return 1; } static int @@ -506,17 +489,16 @@ sflow_print_counter_records(netdissect_options *ndo, if (tlen < sizeof(struct sflow_counter_record_t)) return 1; sflow_counter_record = (const struct sflow_counter_record_t *)tptr; - ND_TCHECK(*sflow_counter_record); - enterprise = EXTRACT_32BITS(sflow_counter_record->format); + enterprise = GET_BE_U_4(sflow_counter_record->format); counter_type = enterprise & 0x0FFF; enterprise = enterprise >> 20; - counter_len = EXTRACT_32BITS(sflow_counter_record->length); - ND_PRINT((ndo, "\n\t enterprise %u, %s (%u) length %u", + counter_len = GET_BE_U_4(sflow_counter_record->length); + ND_PRINT("\n\t enterprise %u, %s (%u) length %u", enterprise, (enterprise == 0) ? tok2str(sflow_counter_type_values,"Unknown",counter_type) : "Unknown", counter_type, - counter_len)); + counter_len); tptr += sizeof(struct sflow_counter_record_t); tlen -= sizeof(struct sflow_counter_record_t); @@ -562,9 +544,6 @@ sflow_print_counter_records(netdissect_options *ndo, } return 0; - -trunc: - return 1; } static int @@ -573,33 +552,23 @@ sflow_print_counter_sample(netdissect_options *ndo, { 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; - ND_TCHECK(*sflow_counter_sample); - typesource = EXTRACT_32BITS(sflow_counter_sample->typesource); - nrecords = EXTRACT_32BITS(sflow_counter_sample->records); - type = typesource >> 24; - index = typesource & 0x0FFF; + nrecords = GET_BE_U_4(sflow_counter_sample->records); - ND_PRINT((ndo, " seqnum %u, type %u, idx %u, records %u", - EXTRACT_32BITS(sflow_counter_sample->seqnum), - type, - index, - nrecords)); + ND_PRINT(" seqnum %u, type %u, idx %u, records %u", + GET_BE_U_4(sflow_counter_sample->seqnum), + GET_U_1(sflow_counter_sample->type), + GET_BE_U_3(sflow_counter_sample->index), + nrecords); return sflow_print_counter_records(ndo, pointer + sizeof(struct sflow_counter_sample_t), len - sizeof(struct sflow_counter_sample_t), nrecords); - -trunc: - return 1; } static int @@ -614,22 +583,18 @@ sflow_print_expanded_counter_sample(netdissect_options *ndo, return 1; sflow_expanded_counter_sample = (const struct sflow_expanded_counter_sample_t *)pointer; - ND_TCHECK(*sflow_expanded_counter_sample); - nrecords = EXTRACT_32BITS(sflow_expanded_counter_sample->records); + nrecords = GET_BE_U_4(sflow_expanded_counter_sample->records); - ND_PRINT((ndo, " 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)); + ND_PRINT(" seqnum %u, type %u, idx %u, records %u", + GET_BE_U_4(sflow_expanded_counter_sample->seqnum), + GET_BE_U_4(sflow_expanded_counter_sample->type), + GET_BE_U_4(sflow_expanded_counter_sample->index), + nrecords); return sflow_print_counter_records(ndo, pointer + sizeof(struct sflow_expanded_counter_sample_t), len - sizeof(struct sflow_expanded_counter_sample_t), nrecords); - -trunc: - return 1; } static int @@ -642,21 +607,17 @@ print_sflow_raw_packet(netdissect_options *ndo, return 1; sflow_flow_raw = (const struct sflow_expanded_flow_raw_t *)pointer; - ND_TCHECK(*sflow_flow_raw); - ND_PRINT((ndo, "\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))); + ND_PRINT("\n\t protocol %s (%u), length %u, stripped bytes %u, header_size %u", + tok2str(sflow_flow_raw_protocol_values,"Unknown",GET_BE_U_4(sflow_flow_raw->protocol)), + GET_BE_U_4(sflow_flow_raw->protocol), + GET_BE_U_4(sflow_flow_raw->length), + GET_BE_U_4(sflow_flow_raw->stripped_bytes), + GET_BE_U_4(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... */ + assuming of course there is enough data present to do so... */ return 0; - -trunc: - return 1; } static int @@ -669,16 +630,12 @@ print_sflow_ethernet_frame(netdissect_options *ndo, return 1; sflow_ethernet_frame = (const struct sflow_ethernet_frame_t *)pointer; - ND_TCHECK(*sflow_ethernet_frame); - ND_PRINT((ndo, "\n\t frame len %u, type %u", - EXTRACT_32BITS(sflow_ethernet_frame->length), - EXTRACT_32BITS(sflow_ethernet_frame->type))); + ND_PRINT("\n\t frame len %u, type %u", + GET_BE_U_4(sflow_ethernet_frame->length), + GET_BE_U_4(sflow_ethernet_frame->type)); return 0; - -trunc: - return 1; } static int @@ -691,17 +648,13 @@ print_sflow_extended_switch_data(netdissect_options *ndo, return 1; sflow_extended_sw_data = (const struct sflow_extended_switch_data_t *)pointer; - ND_TCHECK(*sflow_extended_sw_data); - ND_PRINT((ndo, "\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))); + ND_PRINT("\n\t src vlan %u, src pri %u, dst vlan %u, dst pri %u", + GET_BE_U_4(sflow_extended_sw_data->src_vlan), + GET_BE_U_4(sflow_extended_sw_data->src_pri), + GET_BE_U_4(sflow_extended_sw_data->dst_vlan), + GET_BE_U_4(sflow_extended_sw_data->dst_pri)); return 0; - -trunc: - return 1; } static int @@ -726,20 +679,19 @@ sflow_print_flow_records(netdissect_options *ndo, return 1; sflow_flow_record = (const struct sflow_flow_record_t *)tptr; - ND_TCHECK(*sflow_flow_record); /* so, the funky encoding means we cannot blythly mask-off bits, we must also check the enterprise. */ - enterprise = EXTRACT_32BITS(sflow_flow_record->format); + enterprise = GET_BE_U_4(sflow_flow_record->format); flow_type = enterprise & 0x0FFF; enterprise = enterprise >> 12; - flow_len = EXTRACT_32BITS(sflow_flow_record->length); - ND_PRINT((ndo, "\n\t enterprise %u %s (%u) length %u", + flow_len = GET_BE_U_4(sflow_flow_record->length); + ND_PRINT("\n\t enterprise %u %s (%u) length %u", enterprise, (enterprise == 0) ? tok2str(sflow_flow_type_values,"Unknown",flow_type) : "Unknown", flow_type, - flow_len)); + flow_len); tptr += sizeof(struct sflow_flow_record_t); tlen -= sizeof(struct sflow_flow_record_t); @@ -789,9 +741,6 @@ sflow_print_flow_records(netdissect_options *ndo, } return 0; - -trunc: - return 1; } static int @@ -800,38 +749,28 @@ sflow_print_flow_sample(netdissect_options *ndo, { 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 = (const struct sflow_flow_sample_t *)pointer; - ND_TCHECK(*sflow_flow_sample); - - typesource = EXTRACT_32BITS(sflow_flow_sample->typesource); - nrecords = EXTRACT_32BITS(sflow_flow_sample->records); - type = typesource >> 24; - index = typesource & 0x0FFF; - - ND_PRINT((ndo, " 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)); + + nrecords = GET_BE_U_4(sflow_flow_sample->records); + + ND_PRINT(" seqnum %u, type %u, idx %u, rate %u, pool %u, drops %u, input %u output %u records %u", + GET_BE_U_4(sflow_flow_sample->seqnum), + GET_U_1(sflow_flow_sample->type), + GET_BE_U_3(sflow_flow_sample->index), + GET_BE_U_4(sflow_flow_sample->rate), + GET_BE_U_4(sflow_flow_sample->pool), + GET_BE_U_4(sflow_flow_sample->drops), + GET_BE_U_4(sflow_flow_sample->in_interface), + GET_BE_U_4(sflow_flow_sample->out_interface), + nrecords); return sflow_print_flow_records(ndo, pointer + sizeof(struct sflow_flow_sample_t), len - sizeof(struct sflow_flow_sample_t), nrecords); - -trunc: - return 1; } static int @@ -845,25 +784,21 @@ sflow_print_expanded_flow_sample(netdissect_options *ndo, return 1; sflow_expanded_flow_sample = (const struct sflow_expanded_flow_sample_t *)pointer; - ND_TCHECK(*sflow_expanded_flow_sample); - nrecords = EXTRACT_32BITS(sflow_expanded_flow_sample->records); + nrecords = GET_BE_U_4(sflow_expanded_flow_sample->records); - ND_PRINT((ndo, " 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))); + ND_PRINT(" seqnum %u, type %u, idx %u, rate %u, pool %u, drops %u, records %u", + GET_BE_U_4(sflow_expanded_flow_sample->seqnum), + GET_BE_U_4(sflow_expanded_flow_sample->type), + GET_BE_U_4(sflow_expanded_flow_sample->index), + GET_BE_U_4(sflow_expanded_flow_sample->rate), + GET_BE_U_4(sflow_expanded_flow_sample->pool), + GET_BE_U_4(sflow_expanded_flow_sample->drops), + nrecords); return sflow_print_flow_records(ndo, pointer + sizeof(struct sflow_expanded_flow_sample_t), len - sizeof(struct sflow_expanded_flow_sample_t), nrecords); - -trunc: - return 1; } void @@ -878,73 +813,69 @@ sflow_print(netdissect_options *ndo, uint32_t sflow_sample_type, sflow_sample_len; uint32_t nsamples; + ndo->ndo_protocol = "sflow"; tptr = pptr; tlen = len; sflow_datagram = (const struct sflow_datagram_t *)pptr; if (len < sizeof(struct sflow_datagram_t)) { - ND_TCHECK(sflow_datagram->version); - ND_PRINT((ndo, "sFlowv%u", EXTRACT_32BITS(sflow_datagram->version))); - ND_PRINT((ndo, " [length %u < %zu]", - len, sizeof(struct sflow_datagram_t))); - ND_PRINT((ndo, " (invalid)")); + ND_PRINT("sFlowv%u", GET_BE_U_4(sflow_datagram->version)); + ND_PRINT(" [length %u < %zu]", len, sizeof(struct sflow_datagram_t)); + nd_print_invalid(ndo); return; } - ND_TCHECK(*sflow_datagram); + ND_TCHECK_SIZE(sflow_datagram); /* * Sanity checking of the header. */ - if (EXTRACT_32BITS(sflow_datagram->version) != 5) { - ND_PRINT((ndo, "sFlow version %u packet not supported", - EXTRACT_32BITS(sflow_datagram->version))); + if (GET_BE_U_4(sflow_datagram->version) != 5) { + ND_PRINT("sFlow version %u packet not supported", + GET_BE_U_4(sflow_datagram->version)); return; } if (ndo->ndo_vflag < 1) { - ND_PRINT((ndo, "sFlowv%u, %s agent %s, agent-id %u, length %u", - EXTRACT_32BITS(sflow_datagram->version), - EXTRACT_32BITS(sflow_datagram->ip_version) == 1 ? "IPv4" : "IPv6", - ipaddr_string(ndo, sflow_datagram->agent), - EXTRACT_32BITS(sflow_datagram->agent_id), - len)); + ND_PRINT("sFlowv%u, %s agent %s, agent-id %u, length %u", + GET_BE_U_4(sflow_datagram->version), + GET_BE_U_4(sflow_datagram->ip_version) == 1 ? "IPv4" : "IPv6", + GET_IPADDR_STRING(sflow_datagram->agent), + GET_BE_U_4(sflow_datagram->agent_id), + len); return; } /* ok they seem to want to know everything - lets fully decode it */ - nsamples=EXTRACT_32BITS(sflow_datagram->samples); - ND_PRINT((ndo, "sFlowv%u, %s agent %s, agent-id %u, seqnum %u, uptime %u, samples %u, length %u", - EXTRACT_32BITS(sflow_datagram->version), - EXTRACT_32BITS(sflow_datagram->ip_version) == 1 ? "IPv4" : "IPv6", - ipaddr_string(ndo, sflow_datagram->agent), - EXTRACT_32BITS(sflow_datagram->agent_id), - EXTRACT_32BITS(sflow_datagram->seqnum), - EXTRACT_32BITS(sflow_datagram->uptime), + nsamples=GET_BE_U_4(sflow_datagram->samples); + ND_PRINT("sFlowv%u, %s agent %s, agent-id %u, seqnum %u, uptime %u, samples %u, length %u", + GET_BE_U_4(sflow_datagram->version), + GET_BE_U_4(sflow_datagram->ip_version) == 1 ? "IPv4" : "IPv6", + GET_IPADDR_STRING(sflow_datagram->agent), + GET_BE_U_4(sflow_datagram->agent_id), + GET_BE_U_4(sflow_datagram->seqnum), + GET_BE_U_4(sflow_datagram->uptime), nsamples, - len)); + len); /* skip Common header */ - tptr += sizeof(const struct sflow_datagram_t); - - if(tlen <= sizeof(const struct sflow_datagram_t)) goto trunc; - tlen -= sizeof(const struct sflow_datagram_t); + tptr += sizeof(struct sflow_datagram_t); + tlen -= sizeof(struct sflow_datagram_t); while (nsamples > 0 && tlen > 0) { sflow_sample = (const struct sflow_sample_header *)tptr; - ND_TCHECK(*sflow_sample); - sflow_sample_type = (EXTRACT_32BITS(sflow_sample->format)&0x0FFF); - sflow_sample_len = EXTRACT_32BITS(sflow_sample->len); + sflow_sample_type = (GET_BE_U_4(sflow_sample->format)&0x0FFF); + sflow_sample_len = GET_BE_U_4(sflow_sample->len); if (tlen < sizeof(struct sflow_sample_header)) - goto trunc; + goto invalid; tptr += sizeof(struct sflow_sample_header); tlen -= sizeof(struct sflow_sample_header); - ND_PRINT((ndo, "\n\t%s (%u), length %u,", + ND_PRINT("\n\t%s (%u), length %u,", tok2str(sflow_format_values, "Unknown", sflow_sample_type), sflow_sample_type, - sflow_sample_len)); + sflow_sample_len); /* basic sanity check */ if (sflow_sample_type == 0 || sflow_sample_len ==0) { @@ -952,30 +883,30 @@ sflow_print(netdissect_options *ndo, } if (tlen < sflow_sample_len) - goto trunc; + goto invalid; /* did we capture enough for fully decoding the sample ? */ - ND_TCHECK2(*tptr, sflow_sample_len); + ND_TCHECK_LEN(tptr, sflow_sample_len); switch(sflow_sample_type) { case SFLOW_FLOW_SAMPLE: if (sflow_print_flow_sample(ndo, tptr, tlen)) - goto trunc; + goto invalid; break; case SFLOW_COUNTER_SAMPLE: if (sflow_print_counter_sample(ndo, tptr,tlen)) - goto trunc; + goto invalid; break; case SFLOW_EXPANDED_FLOW_SAMPLE: if (sflow_print_expanded_flow_sample(ndo, tptr, tlen)) - goto trunc; + goto invalid; break; case SFLOW_EXPANDED_COUNTER_SAMPLE: if (sflow_print_expanded_counter_sample(ndo, tptr,tlen)) - goto trunc; + goto invalid; break; default: @@ -989,13 +920,7 @@ sflow_print(netdissect_options *ndo, } return; - trunc: - ND_PRINT((ndo, "[|SFLOW]")); +invalid: + nd_print_invalid(ndo); + ND_TCHECK_LEN(tptr, tlen); } - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 4 - * End: - */ diff --git a/contrib/tcpdump/print-sip.c b/contrib/tcpdump/print-sip.c index a617d23dbf..bfbfddfd47 100644 --- a/contrib/tcpdump/print-sip.c +++ b/contrib/tcpdump/print-sip.c @@ -18,13 +18,12 @@ /* \summary: Session Initiation Protocol (SIP) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" -#include "extract.h" static const char *sipcmds[] = { "ACK", @@ -50,5 +49,6 @@ static const char *sipcmds[] = { void sip_print(netdissect_options *ndo, const u_char *pptr, u_int len) { - txtproto_print(ndo, pptr, len, "sip", sipcmds, RESP_CODE_SECOND_TOKEN); + ndo->ndo_protocol = "sip"; + txtproto_print(ndo, pptr, len, sipcmds, RESP_CODE_SECOND_TOKEN); } diff --git a/contrib/tcpdump/print-sl.c b/contrib/tcpdump/print-sl.c index 301c86ce9a..85b762496d 100644 --- a/contrib/tcpdump/print-sl.c +++ b/contrib/tcpdump/print-sl.c @@ -22,11 +22,12 @@ /* \summary: Compressed Serial Line Internet Protocol printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" @@ -42,47 +43,34 @@ #define SLX_DIR 0 #define SLX_CHDR 1 -#define CHDR_LEN 15 #define SLIPDIR_IN 0 #define SLIPDIR_OUT 1 -static const char tstr[] = "[|slip]"; static u_int lastlen[2][256]; static u_int lastconn = 255; -static int sliplink_print(netdissect_options *, const u_char *, const struct ip *, u_int); -static int compressed_sl_print(netdissect_options *, const u_char *, const struct ip *, u_int, int); +static void sliplink_print(netdissect_options *, const u_char *, const struct ip *, u_int); +static void compressed_sl_print(netdissect_options *, const u_char *, const struct ip *, u_int, int); -u_int +void sl_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { - register u_int caplen = h->caplen; - register u_int length = h->len; - register const struct ip *ip; + u_int length = h->len; + const struct ip *ip; - if (caplen < SLIP_HDRLEN || length < SLIP_HDRLEN) { - ND_PRINT((ndo, "%s", tstr)); - return (caplen); - } + ndo->ndo_protocol = "slip"; + ND_TCHECK_LEN(p, SLIP_HDRLEN); + ndo->ndo_ll_hdr_len += SLIP_HDRLEN; - caplen -= SLIP_HDRLEN; length -= SLIP_HDRLEN; ip = (const struct ip *)(p + SLIP_HDRLEN); if (ndo->ndo_eflag) - if (sliplink_print(ndo, p, ip, length) == -1) { - ND_PRINT((ndo, "%s", tstr)); - return (caplen + SLIP_HDRLEN); - } - - if (caplen < 1 || length < 1) { - ND_PRINT((ndo, "%s", tstr)); - return (caplen + SLIP_HDRLEN); - } + sliplink_print(ndo, p, ip, length); switch (IP_V(ip)) { case 4: @@ -92,24 +80,20 @@ sl_if_print(netdissect_options *ndo, ip6_print(ndo, (const u_char *)ip, length); break; default: - ND_PRINT((ndo, "ip v%d", IP_V(ip))); + ND_PRINT("ip v%u", IP_V(ip)); } - - return (SLIP_HDRLEN); } -u_int +void sl_bsdos_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { - register u_int caplen = h->caplen; - register u_int length = h->len; - register const struct ip *ip; + u_int length = h->len; + const struct ip *ip; - if (caplen < SLIP_HDRLEN) { - ND_PRINT((ndo, "%s", tstr)); - return (caplen); - } + ndo->ndo_protocol = "slip_bsdos"; + ND_TCHECK_LEN(p, SLIP_HDRLEN); + ndo->ndo_ll_hdr_len += SLIP_HDRLEN; length -= SLIP_HDRLEN; @@ -121,47 +105,36 @@ sl_bsdos_if_print(netdissect_options *ndo, #endif ip_print(ndo, (const u_char *)ip, length); - - return (SLIP_HDRLEN); } -static int +static void sliplink_print(netdissect_options *ndo, - register const u_char *p, register const struct ip *ip, - register u_int length) + const u_char *p, const struct ip *ip, + u_int length) { int dir; u_int hlen; - dir = p[SLX_DIR]; + dir = GET_U_1(p + SLX_DIR); switch (dir) { case SLIPDIR_IN: - ND_PRINT((ndo, "I ")); + ND_PRINT("I "); break; case SLIPDIR_OUT: - ND_PRINT((ndo, "O ")); + ND_PRINT("O "); break; default: - ND_PRINT((ndo, "Invalid direction %d ", dir)); + ND_PRINT("Invalid direction %d ", dir); dir = -1; break; } - if (ndo->ndo_nflag) { - /* XXX just dump the header */ - register int i; - - for (i = SLX_CHDR; i < SLX_CHDR + CHDR_LEN - 1; ++i) - ND_PRINT((ndo, "%02x.", p[i])); - ND_PRINT((ndo, "%02x: ", p[SLX_CHDR + CHDR_LEN - 1])); - return 0; - } - switch (p[SLX_CHDR] & 0xf0) { + switch (GET_U_1(p + SLX_CHDR) & 0xf0) { case TYPE_IP: - ND_PRINT((ndo, "ip %d: ", length + SLIP_HDRLEN)); + ND_PRINT("ip %u: ", length + SLIP_HDRLEN); break; case TYPE_UNCOMPRESSED_TCP: @@ -170,15 +143,15 @@ sliplink_print(netdissect_options *ndo, * Get it from the link layer since sl_uncompress_tcp() * has restored the IP header copy to IPPROTO_TCP. */ - lastconn = ((const struct ip *)&p[SLX_CHDR])->ip_p; - ND_PRINT((ndo, "utcp %d: ", lastconn)); + lastconn = GET_U_1(((const struct ip *)(p + SLX_CHDR))->ip_p); + ND_PRINT("utcp %u: ", lastconn); if (dir == -1) { /* Direction is bogus, don't use it */ - return 0; + return; } - ND_TCHECK(*ip); + ND_TCHECK_SIZE(ip); hlen = IP_HL(ip); - ND_TCHECK(*((const struct tcphdr *)&((const int *)ip)[hlen])); + ND_TCHECK_SIZE((const struct tcphdr *)&((const int *)ip)[hlen]); hlen += TH_OFF((const struct tcphdr *)&((const int *)ip)[hlen]); lastlen[dir][lastconn] = length - (hlen << 2); break; @@ -186,77 +159,76 @@ sliplink_print(netdissect_options *ndo, default: if (dir == -1) { /* Direction is bogus, don't use it */ - return 0; + return; } - if (p[SLX_CHDR] & TYPE_COMPRESSED_TCP) { - if (compressed_sl_print(ndo, &p[SLX_CHDR], ip, - length, dir) == -1) - goto trunc; - ND_PRINT((ndo, ": ")); + if (GET_U_1(p + SLX_CHDR) & TYPE_COMPRESSED_TCP) { + compressed_sl_print(ndo, p + SLX_CHDR, ip, length, dir); + ND_PRINT(": "); } else - ND_PRINT((ndo, "slip-%d!: ", p[SLX_CHDR])); + ND_PRINT("slip-%u!: ", GET_U_1(p + SLX_CHDR)); } - return 0; -trunc: - return -1; } static const u_char * print_sl_change(netdissect_options *ndo, - const char *str, register const u_char *cp) + const char *str, const u_char *cp) { - register u_int i; + u_int i; - if ((i = *cp++) == 0) { - i = EXTRACT_16BITS(cp); + if ((i = GET_U_1(cp)) == 0) { + cp++; + i = GET_BE_U_2(cp); cp += 2; } - ND_PRINT((ndo, " %s%d", str, i)); + ND_PRINT(" %s%u", str, i); return (cp); } static const u_char * print_sl_winchange(netdissect_options *ndo, - register const u_char *cp) + const u_char *cp) { - register short i; + int16_t i; - if ((i = *cp++) == 0) { - i = EXTRACT_16BITS(cp); + if ((i = GET_U_1(cp)) == 0) { + cp++; + i = GET_BE_S_2(cp); cp += 2; } if (i >= 0) - ND_PRINT((ndo, " W+%d", i)); + ND_PRINT(" W+%d", i); else - ND_PRINT((ndo, " W%d", i)); + ND_PRINT(" W%d", i); return (cp); } -static int +static void compressed_sl_print(netdissect_options *ndo, const u_char *chdr, const struct ip *ip, u_int length, int dir) { - register const u_char *cp = chdr; - register u_int flags, hlen; + const u_char *cp = chdr; + u_int flags, hlen; - flags = *cp++; + flags = GET_U_1(cp); + cp++; if (flags & NEW_C) { - lastconn = *cp++; - ND_PRINT((ndo, "ctcp %d", lastconn)); + lastconn = GET_U_1(cp); + cp++; + ND_PRINT("ctcp %u", lastconn); } else - ND_PRINT((ndo, "ctcp *")); + ND_PRINT("ctcp *"); /* skip tcp checksum */ cp += 2; switch (flags & SPECIALS_MASK) { case SPECIAL_I: - ND_PRINT((ndo, " *SA+%d", lastlen[dir][lastconn])); + ND_PRINT(" *SA+%u", lastlen[dir][lastconn]); break; case SPECIAL_D: - ND_PRINT((ndo, " *S+%d", lastlen[dir][lastconn])); + ND_PRINT(" *S+%u", lastlen[dir][lastconn]); break; default: @@ -278,13 +250,10 @@ compressed_sl_print(netdissect_options *ndo, * 'cp - chdr' is the length of the compressed header. * 'length - hlen' is the amount of data in the packet. */ - ND_TCHECK(*ip); + ND_TCHECK_SIZE(ip); hlen = IP_HL(ip); - ND_TCHECK(*((const struct tcphdr *)&((const int32_t *)ip)[hlen])); + ND_TCHECK_SIZE((const struct tcphdr *)&((const int32_t *)ip)[hlen]); hlen += TH_OFF((const struct tcphdr *)&((const int32_t *)ip)[hlen]); lastlen[dir][lastconn] = length - (hlen << 2); - ND_PRINT((ndo, " %d (%ld)", lastlen[dir][lastconn], (long)(cp - chdr))); - return 0; -trunc: - return -1; + ND_PRINT(" %u (%ld)", lastlen[dir][lastconn], (long)(cp - chdr)); } diff --git a/contrib/tcpdump/print-sll.c b/contrib/tcpdump/print-sll.c index 9bc5d2015e..19d2973eda 100644 --- a/contrib/tcpdump/print-sll.c +++ b/contrib/tcpdump/print-sll.c @@ -22,18 +22,21 @@ /* \summary: Linux cooked sockets capture printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#ifdef HAVE_NET_IF_H +#include +#endif + +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "addrtoname.h" #include "ethertype.h" #include "extract.h" -#include "ether.h" - /* * For captures on Linux cooked sockets, we construct a fake header * that includes: @@ -79,11 +82,26 @@ #define SLL_ADDRLEN 8 /* length of address field */ struct sll_header { - uint16_t sll_pkttype; /* packet type */ - uint16_t sll_hatype; /* link-layer address type */ - uint16_t sll_halen; /* link-layer address length */ - uint8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */ - uint16_t sll_protocol; /* protocol */ + nd_uint16_t sll_pkttype; /* packet type */ + nd_uint16_t sll_hatype; /* link-layer address type */ + nd_uint16_t sll_halen; /* link-layer address length */ + nd_byte sll_addr[SLL_ADDRLEN]; /* link-layer address */ + nd_uint16_t sll_protocol; /* protocol */ +}; + +/* + * A DLT_LINUX_SLL2 fake link-layer header. + */ +#define SLL2_HDR_LEN 20 /* total header length */ + +struct sll2_header { + nd_uint16_t sll2_protocol; /* protocol */ + nd_uint16_t sll2_reserved_mbz; /* reserved - must be zero */ + nd_uint32_t sll2_if_index; /* 1-based interface index */ + nd_uint16_t sll2_hatype; /* link-layer address type */ + nd_uint8_t sll2_pkttype; /* packet type */ + nd_uint8_t sll2_halen; /* link-layer address length */ + nd_byte sll2_addr[SLL_ADDRLEN]; /* link-layer address */ }; /* @@ -131,25 +149,27 @@ static const struct tok sll_pkttype_values[] = { { 0, NULL} }; -static inline void -sll_print(netdissect_options *ndo, register const struct sll_header *sllp, u_int length) +static void +sll_print(netdissect_options *ndo, const struct sll_header *sllp, u_int length) { u_short ether_type; - ND_PRINT((ndo, "%3s ",tok2str(sll_pkttype_values,"?",EXTRACT_16BITS(&sllp->sll_pkttype)))); + ndo->ndo_protocol = "sll"; + ND_PRINT("%3s ", + tok2str(sll_pkttype_values,"?",GET_BE_U_2(sllp->sll_pkttype))); /* * XXX - check the link-layer address type value? * For now, we just assume 6 means Ethernet. * XXX - print others as strings of hex? */ - if (EXTRACT_16BITS(&sllp->sll_halen) == 6) - ND_PRINT((ndo, "%s ", etheraddr_string(ndo, sllp->sll_addr))); + if (GET_BE_U_2(sllp->sll_halen) == MAC_ADDR_LEN) + ND_PRINT("%s ", GET_ETHERADDR_STRING(sllp->sll_addr)); if (!ndo->ndo_qflag) { - ether_type = EXTRACT_16BITS(&sllp->sll_protocol); + ether_type = GET_BE_U_2(sllp->sll_protocol); - if (ether_type <= ETHERMTU) { + if (ether_type <= MAX_ETHERNET_LENGTH_VAL) { /* * Not an Ethernet type; what type is it? */ @@ -159,30 +179,30 @@ sll_print(netdissect_options *ndo, register const struct sll_header *sllp, u_int /* * Ethernet_802.3 IPX frame. */ - ND_PRINT((ndo, "802.3")); + ND_PRINT("802.3"); break; case LINUX_SLL_P_802_2: /* * 802.2. */ - ND_PRINT((ndo, "802.2")); + ND_PRINT("802.2"); break; default: /* * What is it? */ - ND_PRINT((ndo, "ethertype Unknown (0x%04x)", - ether_type)); + ND_PRINT("ethertype Unknown (0x%04x)", + ether_type); break; } } else { - ND_PRINT((ndo, "ethertype %s (0x%04x)", + ND_PRINT("ethertype %s (0x%04x)", tok2str(ethertype_values, "Unknown", ether_type), - ether_type)); + ether_type); } - ND_PRINT((ndo, ", length %u: ", length)); + ND_PRINT(", length %u: ", length); } } @@ -192,26 +212,19 @@ sll_print(netdissect_options *ndo, register const struct sll_header *sllp, u_int * 'h->len' is the length of the packet off the wire, and 'h->caplen' * is the number of bytes actually captured. */ -u_int +void sll_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { u_int caplen = h->caplen; u_int length = h->len; - register const struct sll_header *sllp; + const struct sll_header *sllp; u_short hatype; u_short ether_type; int llc_hdrlen; u_int hdrlen; - if (caplen < SLL_HDR_LEN) { - /* - * XXX - this "can't happen" because "pcap-linux.c" always - * adds this many bytes of header to every packet in a - * cooked socket capture. - */ - ND_PRINT((ndo, "[|sll]")); - return (caplen); - } + ndo->ndo_protocol = "sll"; + ND_TCHECK_LEN(p, SLL_HDR_LEN); sllp = (const struct sll_header *)p; @@ -226,7 +239,7 @@ sll_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char p += SLL_HDR_LEN; hdrlen = SLL_HDR_LEN; - hatype = EXTRACT_16BITS(&sllp->sll_hatype); + hatype = GET_BE_U_2(sllp->sll_hatype); switch (hatype) { case 803: @@ -234,16 +247,18 @@ sll_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char * This is an packet with a radiotap header; * just dissect the payload as such. */ - return (SLL_HDR_LEN + ieee802_11_radio_print(ndo, p, length, caplen)); + ndo->ndo_ll_hdr_len += SLL_HDR_LEN; + ndo->ndo_ll_hdr_len += ieee802_11_radio_print(ndo, p, length, caplen); + return; } - ether_type = EXTRACT_16BITS(&sllp->sll_protocol); + ether_type = GET_BE_U_2(sllp->sll_protocol); recurse: /* * Is it (gag) an 802.3 encapsulation, or some non-Ethernet * packet type? */ - if (ether_type <= ETHERMTU) { + if (ether_type <= MAX_ETHERNET_LENGTH_VAL) { /* * Yes - what type is it? */ @@ -282,25 +297,23 @@ recurse: * the enclosed type field. */ if (caplen < 4) { - ND_PRINT((ndo, "[|vlan]")); - return (hdrlen + caplen); - } - if (length < 4) { - ND_PRINT((ndo, "[|vlan]")); - return (hdrlen + length); + ndo->ndo_protocol = "vlan"; + nd_print_trunc(ndo); + ndo->ndo_ll_hdr_len += hdrlen + caplen; + return; } if (ndo->ndo_eflag) { - uint16_t tag = EXTRACT_16BITS(p); + uint16_t tag = GET_BE_U_2(p); - ND_PRINT((ndo, "%s, ", ieee8021q_tci_string(tag))); + ND_PRINT("%s, ", ieee8021q_tci_string(tag)); } - ether_type = EXTRACT_16BITS(p + 2); - if (ether_type <= ETHERMTU) + ether_type = GET_BE_U_2(p + 2); + if (ether_type <= MAX_ETHERNET_LENGTH_VAL) ether_type = LINUX_SLL_P_802_2; if (!ndo->ndo_qflag) { - ND_PRINT((ndo, "ethertype %s, ", - tok2str(ethertype_values, "Unknown", ether_type))); + ND_PRINT("ethertype %s, ", + tok2str(ethertype_values, "Unknown", ether_type)); } p += 4; length -= 4; @@ -317,5 +330,201 @@ recurse: } } - return (hdrlen); + ndo->ndo_ll_hdr_len += hdrlen; +} + +static void +sll2_print(netdissect_options *ndo, const struct sll2_header *sllp, u_int length) +{ + u_short ether_type; + + ndo->ndo_protocol = "sll2"; + ND_PRINT("ifindex %u ", GET_BE_U_4(sllp->sll2_if_index)); + + /* + * XXX - check the link-layer address type value? + * For now, we just assume 6 means Ethernet. + * XXX - print others as strings of hex? + */ + if (GET_U_1(sllp->sll2_halen) == MAC_ADDR_LEN) + ND_PRINT("%s ", GET_ETHERADDR_STRING(sllp->sll2_addr)); + + if (!ndo->ndo_qflag) { + ether_type = GET_BE_U_2(sllp->sll2_protocol); + + if (ether_type <= MAX_ETHERNET_LENGTH_VAL) { + /* + * Not an Ethernet type; what type is it? + */ + switch (ether_type) { + + case LINUX_SLL_P_802_3: + /* + * Ethernet_802.3 IPX frame. + */ + ND_PRINT("802.3"); + break; + + case LINUX_SLL_P_802_2: + /* + * 802.2. + */ + ND_PRINT("802.2"); + break; + + default: + /* + * What is it? + */ + ND_PRINT("ethertype Unknown (0x%04x)", + ether_type); + break; + } + } else { + ND_PRINT("ethertype %s (0x%04x)", + tok2str(ethertype_values, "Unknown", ether_type), + ether_type); + } + ND_PRINT(", length %u: ", length); + } +} + +/* + * This is the top level routine of the printer. 'p' points to the + * Linux "cooked capture" 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. + */ +void +sll2_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) +{ + u_int caplen = h->caplen; + u_int length = h->len; + const struct sll2_header *sllp; + u_short hatype; + u_short ether_type; + int llc_hdrlen; + u_int hdrlen; +#ifdef HAVE_NET_IF_H + uint32_t if_index; + char ifname[IF_NAMESIZE]; +#endif + + ndo->ndo_protocol = "sll2"; + ND_TCHECK_LEN(p, SLL2_HDR_LEN); + + sllp = (const struct sll2_header *)p; +#ifdef HAVE_NET_IF_H + if_index = GET_BE_U_4(sllp->sll2_if_index); + if (!if_indextoname(if_index, ifname)) + strncpy(ifname, "?", 2); + ND_PRINT("%-5s ", ifname); +#endif + + ND_PRINT("%-3s ", + tok2str(sll_pkttype_values, "?", GET_U_1(sllp->sll2_pkttype))); + + if (ndo->ndo_eflag) + sll2_print(ndo, sllp, length); + + /* + * Go past the cooked-mode header. + */ + length -= SLL2_HDR_LEN; + caplen -= SLL2_HDR_LEN; + p += SLL2_HDR_LEN; + hdrlen = SLL2_HDR_LEN; + + hatype = GET_BE_U_2(sllp->sll2_hatype); + switch (hatype) { + + case 803: + /* + * This is an packet with a radiotap header; + * just dissect the payload as such. + */ + ndo->ndo_ll_hdr_len += SLL2_HDR_LEN; + ndo->ndo_ll_hdr_len += ieee802_11_radio_print(ndo, p, length, caplen); + return; + } + ether_type = GET_BE_U_2(sllp->sll2_protocol); + +recurse: + /* + * Is it (gag) an 802.3 encapsulation, or some non-Ethernet + * packet type? + */ + if (ether_type <= MAX_ETHERNET_LENGTH_VAL) { + /* + * Yes - what type is it? + */ + switch (ether_type) { + + case LINUX_SLL_P_802_3: + /* + * Ethernet_802.3 IPX frame. + */ + ipx_print(ndo, p, length); + break; + + case LINUX_SLL_P_802_2: + /* + * 802.2. + * Try to print the LLC-layer header & higher layers. + */ + llc_hdrlen = llc_print(ndo, p, length, caplen, NULL, NULL); + if (llc_hdrlen < 0) + goto unknown; /* unknown LLC type */ + hdrlen += llc_hdrlen; + break; + + default: + /*FALLTHROUGH*/ + + unknown: + /* packet type not known, print raw packet */ + if (!ndo->ndo_suppress_default_print) + ND_DEFAULTPRINT(p, caplen); + break; + } + } else if (ether_type == ETHERTYPE_8021Q) { + /* + * Print VLAN information, and then go back and process + * the enclosed type field. + */ + if (caplen < 4) { + ndo->ndo_protocol = "vlan"; + nd_print_trunc(ndo); + ndo->ndo_ll_hdr_len += hdrlen + caplen; + return; + } + if (ndo->ndo_eflag) { + uint16_t tag = GET_BE_U_2(p); + + ND_PRINT("%s, ", ieee8021q_tci_string(tag)); + } + + ether_type = GET_BE_U_2(p + 2); + if (ether_type <= MAX_ETHERNET_LENGTH_VAL) + ether_type = LINUX_SLL_P_802_2; + if (!ndo->ndo_qflag) { + ND_PRINT("ethertype %s, ", + tok2str(ethertype_values, "Unknown", ether_type)); + } + p += 4; + length -= 4; + caplen -= 4; + hdrlen += 4; + goto recurse; + } else { + if (ethertype_print(ndo, ether_type, p, length, caplen, NULL, NULL) == 0) { + /* ether_type not known, print raw packet */ + if (!ndo->ndo_eflag) + sll2_print(ndo, sllp, length + SLL2_HDR_LEN); + if (!ndo->ndo_suppress_default_print) + ND_DEFAULTPRINT(p, caplen); + } + } + + ndo->ndo_ll_hdr_len += hdrlen; } diff --git a/contrib/tcpdump/print-slow.c b/contrib/tcpdump/print-slow.c index d1484790ce..118381808f 100644 --- a/contrib/tcpdump/print-slow.c +++ b/contrib/tcpdump/print-slow.c @@ -21,17 +21,18 @@ /* \summary: IEEE "slow protocols" (802.3ad/802.3ah) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" #include "addrtoname.h" -#include "ether.h" #include "oui.h" + #define SLOW_PROTO_LACP 1 #define SLOW_PROTO_MARKER 2 #define SLOW_PROTO_OAM 3 @@ -75,15 +76,15 @@ static const struct tok slow_oam_code_values[] = { }; struct slow_oam_info_t { - uint8_t info_type; - uint8_t info_length; - uint8_t oam_version; - uint8_t revision[2]; - uint8_t state; - uint8_t oam_config; - uint8_t oam_pdu_config[2]; - uint8_t oui[3]; - uint8_t vendor_private[4]; + nd_uint8_t info_type; + nd_uint8_t info_length; + nd_uint8_t oam_version; + nd_uint16_t revision; + nd_uint8_t state; + nd_uint8_t oam_config; + nd_uint16_t oam_pdu_config; + nd_uint24_t oui; + nd_uint32_t vendor_private; }; #define SLOW_OAM_INFO_TYPE_END_OF_TLV 0x00 @@ -145,29 +146,29 @@ static const struct tok slow_oam_link_event_values[] = { }; struct slow_oam_link_event_t { - uint8_t event_type; - uint8_t event_length; - uint8_t time_stamp[2]; - uint8_t window[8]; - uint8_t threshold[8]; - uint8_t errors[8]; - uint8_t errors_running_total[8]; - uint8_t event_running_total[4]; + nd_uint8_t event_type; + nd_uint8_t event_length; + nd_uint16_t time_stamp; + nd_uint64_t window; + nd_uint64_t threshold; + nd_uint64_t errors; + nd_uint64_t errors_running_total; + nd_uint32_t event_running_total; }; struct slow_oam_variablerequest_t { - uint8_t branch; - uint8_t leaf[2]; + nd_uint8_t branch; + nd_uint16_t leaf; }; struct slow_oam_variableresponse_t { - uint8_t branch; - uint8_t leaf[2]; - uint8_t length; + nd_uint8_t branch; + nd_uint16_t leaf; + nd_uint8_t length; }; struct slow_oam_loopbackctrl_t { - uint8_t command; + nd_uint8_t command; }; static const struct tok slow_oam_loopbackctrl_cmd_values[] = { @@ -177,8 +178,8 @@ static const struct tok slow_oam_loopbackctrl_cmd_values[] = { }; struct tlv_header_t { - uint8_t type; - uint8_t length; + nd_uint8_t type; + nd_uint8_t length; }; #define LACP_MARKER_TLV_TERMINATOR 0x00 /* same code for LACP and Marker */ @@ -201,13 +202,13 @@ static const struct tok slow_tlv_values[] = { }; struct lacp_tlv_actor_partner_info_t { - uint8_t sys_pri[2]; - uint8_t sys[ETHER_ADDR_LEN]; - uint8_t key[2]; - uint8_t port_pri[2]; - uint8_t port[2]; - uint8_t state; - uint8_t pad[3]; + nd_uint16_t sys_pri; + nd_mac_addr sys; + nd_uint16_t key; + nd_uint16_t port_pri; + nd_uint16_t port; + nd_uint8_t state; + nd_byte pad[3]; }; static const struct tok lacp_tlv_actor_partner_info_state_values[] = { @@ -223,35 +224,35 @@ static const struct tok lacp_tlv_actor_partner_info_state_values[] = { }; struct lacp_tlv_collector_info_t { - uint8_t max_delay[2]; - uint8_t pad[12]; + nd_uint16_t max_delay; + nd_byte pad[12]; }; struct marker_tlv_marker_info_t { - uint8_t req_port[2]; - uint8_t req_sys[ETHER_ADDR_LEN]; - uint8_t req_trans_id[4]; - uint8_t pad[2]; + nd_uint16_t req_port; + nd_mac_addr req_sys; + nd_uint32_t req_trans_id; + nd_byte pad[2]; }; struct lacp_marker_tlv_terminator_t { - uint8_t pad[50]; + nd_byte pad[50]; }; -static void slow_marker_lacp_print(netdissect_options *, register const u_char *, register u_int, u_int); -static void slow_oam_print(netdissect_options *, register const u_char *, register u_int); +static void slow_marker_lacp_print(netdissect_options *, const u_char *, u_int, u_int); +static void slow_oam_print(netdissect_options *, const u_char *, u_int); void slow_print(netdissect_options *ndo, - register const u_char *pptr, register u_int len) + const u_char *pptr, u_int len) { int print_version; u_int subtype; + ndo->ndo_protocol = "slow"; if (len < 1) goto tooshort; - ND_TCHECK(*pptr); - subtype = *pptr; + subtype = GET_U_1(pptr); /* * Sanity checking of the header. @@ -260,9 +261,9 @@ slow_print(netdissect_options *ndo, case SLOW_PROTO_LACP: if (len < 2) goto tooshort; - ND_TCHECK(*(pptr+1)); - if (*(pptr+1) != LACP_VERSION) { - ND_PRINT((ndo, "LACP version %u packet not supported", *(pptr+1))); + if (GET_U_1(pptr + 1) != LACP_VERSION) { + ND_PRINT("LACP version %u packet not supported", + GET_U_1(pptr + 1)); return; } print_version = 1; @@ -271,9 +272,9 @@ slow_print(netdissect_options *ndo, case SLOW_PROTO_MARKER: if (len < 2) goto tooshort; - ND_TCHECK(*(pptr+1)); - if (*(pptr+1) != MARKER_VERSION) { - ND_PRINT((ndo, "MARKER version %u packet not supported", *(pptr+1))); + if (GET_U_1(pptr + 1) != MARKER_VERSION) { + ND_PRINT("MARKER version %u packet not supported", + GET_U_1(pptr + 1)); return; } print_version = 1; @@ -290,15 +291,15 @@ slow_print(netdissect_options *ndo, } if (print_version == 1) { - ND_PRINT((ndo, "%sv%u, length %u", + ND_PRINT("%sv%u, length %u", tok2str(slow_proto_values, "unknown (%u)", subtype), - *(pptr+1), - len)); + GET_U_1((pptr + 1)), + len); } else { /* some slow protos don't have a version number in the header */ - ND_PRINT((ndo, "%s, length %u", + ND_PRINT("%s, length %u", tok2str(slow_proto_values, "unknown (%u)", subtype), - len)); + len); } /* unrecognized subtype */ @@ -333,26 +334,19 @@ slow_print(netdissect_options *ndo, tooshort: if (!ndo->ndo_vflag) - ND_PRINT((ndo, " (packet is too short)")); - else - ND_PRINT((ndo, "\n\t\t packet is too short")); - return; - -trunc: - if (!ndo->ndo_vflag) - ND_PRINT((ndo, " (packet exceeded snapshot)")); + ND_PRINT(" (packet is too short)"); else - ND_PRINT((ndo, "\n\t\t packet exceeded snapshot")); + ND_PRINT("\n\t\t packet is too short"); } static void slow_marker_lacp_print(netdissect_options *ndo, - register const u_char *tptr, register u_int tlen, + const u_char *tptr, u_int tlen, u_int proto_subtype) { const struct tlv_header_t *tlv_header; const u_char *tlv_tptr; - u_int tlv_len, tlv_tlen; + u_int tlv_type, tlv_len, tlv_tlen; union { const struct lacp_marker_tlv_terminator_t *lacp_marker_tlv_terminator; @@ -366,18 +360,18 @@ slow_marker_lacp_print(netdissect_options *ndo, if (tlen < sizeof(struct tlv_header_t)) goto tooshort; /* did we capture enough for fully decoding the tlv header ? */ - ND_TCHECK2(*tptr, sizeof(struct tlv_header_t)); tlv_header = (const struct tlv_header_t *)tptr; - tlv_len = tlv_header->length; + tlv_type = GET_U_1(tlv_header->type); + tlv_len = GET_U_1(tlv_header->length); - ND_PRINT((ndo, "\n\t%s TLV (0x%02x), length %u", + ND_PRINT("\n\t%s TLV (0x%02x), length %u", tok2str(slow_tlv_values, "Unknown", - (proto_subtype << 8) + tlv_header->type), - tlv_header->type, - tlv_len)); + (proto_subtype << 8) + tlv_type), + tlv_type, + tlv_len); - if (tlv_header->type == LACP_MARKER_TLV_TERMINATOR) { + if (tlv_type == LACP_MARKER_TLV_TERMINATOR) { /* * This TLV has a length of zero, and means there are no * more TLVs to process. @@ -387,8 +381,8 @@ slow_marker_lacp_print(netdissect_options *ndo, /* length includes the type and length fields */ if (tlv_len < sizeof(struct tlv_header_t)) { - ND_PRINT((ndo, "\n\t ERROR: illegal length - should be >= %lu", - (unsigned long) sizeof(struct tlv_header_t))); + ND_PRINT("\n\t ERROR: illegal length - should be >= %zu", + sizeof(struct tlv_header_t)); return; } @@ -396,67 +390,67 @@ slow_marker_lacp_print(netdissect_options *ndo, if (tlen < tlv_len) goto tooshort; /* did we capture enough for fully decoding the tlv ? */ - ND_TCHECK2(*tptr, tlv_len); + ND_TCHECK_LEN(tptr, tlv_len); tlv_tptr=tptr+sizeof(struct tlv_header_t); tlv_tlen=tlv_len-sizeof(struct tlv_header_t); - switch((proto_subtype << 8) + tlv_header->type) { + switch((proto_subtype << 8) + tlv_type) { /* those two TLVs have the same structure -> fall through */ case ((SLOW_PROTO_LACP << 8) + LACP_TLV_ACTOR_INFO): case ((SLOW_PROTO_LACP << 8) + LACP_TLV_PARTNER_INFO): if (tlv_tlen != sizeof(struct lacp_tlv_actor_partner_info_t)) { - ND_PRINT((ndo, "\n\t ERROR: illegal length - should be %lu", - (unsigned long) (sizeof(struct tlv_header_t) + sizeof(struct lacp_tlv_actor_partner_info_t)))); + ND_PRINT("\n\t ERROR: illegal length - should be %zu", + sizeof(struct tlv_header_t) + sizeof(struct lacp_tlv_actor_partner_info_t)); goto badlength; } tlv_ptr.lacp_tlv_actor_partner_info = (const struct lacp_tlv_actor_partner_info_t *)tlv_tptr; - ND_PRINT((ndo, "\n\t System %s, System Priority %u, Key %u" \ + ND_PRINT("\n\t System %s, System Priority %u, Key %u" ", Port %u, Port Priority %u\n\t State Flags [%s]", - etheraddr_string(ndo, tlv_ptr.lacp_tlv_actor_partner_info->sys), - EXTRACT_16BITS(tlv_ptr.lacp_tlv_actor_partner_info->sys_pri), - EXTRACT_16BITS(tlv_ptr.lacp_tlv_actor_partner_info->key), - EXTRACT_16BITS(tlv_ptr.lacp_tlv_actor_partner_info->port), - EXTRACT_16BITS(tlv_ptr.lacp_tlv_actor_partner_info->port_pri), + GET_ETHERADDR_STRING(tlv_ptr.lacp_tlv_actor_partner_info->sys), + GET_BE_U_2(tlv_ptr.lacp_tlv_actor_partner_info->sys_pri), + GET_BE_U_2(tlv_ptr.lacp_tlv_actor_partner_info->key), + GET_BE_U_2(tlv_ptr.lacp_tlv_actor_partner_info->port), + GET_BE_U_2(tlv_ptr.lacp_tlv_actor_partner_info->port_pri), bittok2str(lacp_tlv_actor_partner_info_state_values, "none", - tlv_ptr.lacp_tlv_actor_partner_info->state))); + GET_U_1(tlv_ptr.lacp_tlv_actor_partner_info->state))); break; case ((SLOW_PROTO_LACP << 8) + LACP_TLV_COLLECTOR_INFO): if (tlv_tlen != sizeof(struct lacp_tlv_collector_info_t)) { - ND_PRINT((ndo, "\n\t ERROR: illegal length - should be %lu", - (unsigned long) (sizeof(struct tlv_header_t) + sizeof(struct lacp_tlv_collector_info_t)))); + ND_PRINT("\n\t ERROR: illegal length - should be %zu", + sizeof(struct tlv_header_t) + sizeof(struct lacp_tlv_collector_info_t)); goto badlength; } tlv_ptr.lacp_tlv_collector_info = (const struct lacp_tlv_collector_info_t *)tlv_tptr; - ND_PRINT((ndo, "\n\t Max Delay %u", - EXTRACT_16BITS(tlv_ptr.lacp_tlv_collector_info->max_delay))); + ND_PRINT("\n\t Max Delay %u", + GET_BE_U_2(tlv_ptr.lacp_tlv_collector_info->max_delay)); break; case ((SLOW_PROTO_MARKER << 8) + MARKER_TLV_MARKER_INFO): if (tlv_tlen != sizeof(struct marker_tlv_marker_info_t)) { - ND_PRINT((ndo, "\n\t ERROR: illegal length - should be %lu", - (unsigned long) (sizeof(struct tlv_header_t) + sizeof(struct marker_tlv_marker_info_t)))); + ND_PRINT("\n\t ERROR: illegal length - should be %zu", + sizeof(struct tlv_header_t) + sizeof(struct marker_tlv_marker_info_t)); goto badlength; } tlv_ptr.marker_tlv_marker_info = (const struct marker_tlv_marker_info_t *)tlv_tptr; - ND_PRINT((ndo, "\n\t Request System %s, Request Port %u, Request Transaction ID 0x%08x", - etheraddr_string(ndo, tlv_ptr.marker_tlv_marker_info->req_sys), - EXTRACT_16BITS(tlv_ptr.marker_tlv_marker_info->req_port), - EXTRACT_32BITS(tlv_ptr.marker_tlv_marker_info->req_trans_id))); + ND_PRINT("\n\t Request System %s, Request Port %u, Request Transaction ID 0x%08x", + GET_ETHERADDR_STRING(tlv_ptr.marker_tlv_marker_info->req_sys), + GET_BE_U_2(tlv_ptr.marker_tlv_marker_info->req_port), + GET_BE_U_4(tlv_ptr.marker_tlv_marker_info->req_trans_id)); break; @@ -479,27 +473,27 @@ slow_marker_lacp_print(netdissect_options *ndo, return; tooshort: - ND_PRINT((ndo, "\n\t\t packet is too short")); - return; - -trunc: - ND_PRINT((ndo, "\n\t\t packet exceeded snapshot")); + ND_PRINT("\n\t\t packet is too short"); } static void slow_oam_print(netdissect_options *ndo, - register const u_char *tptr, register u_int tlen) + const u_char *tptr, u_int tlen) { + uint8_t code; + uint8_t type, length; + uint8_t state; + uint8_t command; u_int hexdump; struct slow_oam_common_header_t { - uint8_t flags[2]; - uint8_t code; + nd_uint16_t flags; + nd_uint8_t code; }; struct slow_oam_tlv_header_t { - uint8_t type; - uint8_t length; + nd_uint8_t type; + nd_uint8_t length; }; union { @@ -508,7 +502,7 @@ slow_oam_print(netdissect_options *ndo, } ptr; union { - const struct slow_oam_info_t *slow_oam_info; + const struct slow_oam_info_t *slow_oam_info; const struct slow_oam_link_event_t *slow_oam_link_event; const struct slow_oam_variablerequest_t *slow_oam_variablerequest; const struct slow_oam_variableresponse_t *slow_oam_variableresponse; @@ -518,30 +512,32 @@ slow_oam_print(netdissect_options *ndo, ptr.slow_oam_common_header = (const struct slow_oam_common_header_t *)tptr; if (tlen < sizeof(*ptr.slow_oam_common_header)) goto tooshort; - ND_TCHECK(*ptr.slow_oam_common_header); + ND_TCHECK_SIZE(ptr.slow_oam_common_header); tptr += sizeof(struct slow_oam_common_header_t); tlen -= sizeof(struct slow_oam_common_header_t); - ND_PRINT((ndo, "\n\tCode %s OAM PDU, Flags [%s]", - tok2str(slow_oam_code_values, "Unknown (%u)", ptr.slow_oam_common_header->code), + code = GET_U_1(ptr.slow_oam_common_header->code); + ND_PRINT("\n\tCode %s OAM PDU, Flags [%s]", + tok2str(slow_oam_code_values, "Unknown (%u)", code), bittok2str(slow_oam_flag_values, "none", - EXTRACT_16BITS(&ptr.slow_oam_common_header->flags)))); + GET_BE_U_2(ptr.slow_oam_common_header->flags))); - switch (ptr.slow_oam_common_header->code) { + switch (code) { case SLOW_OAM_CODE_INFO: while (tlen > 0) { ptr.slow_oam_tlv_header = (const struct slow_oam_tlv_header_t *)tptr; if (tlen < sizeof(*ptr.slow_oam_tlv_header)) goto tooshort; - ND_TCHECK(*ptr.slow_oam_tlv_header); - ND_PRINT((ndo, "\n\t %s Information Type (%u), length %u", - tok2str(slow_oam_info_type_values, "Reserved", - ptr.slow_oam_tlv_header->type), - ptr.slow_oam_tlv_header->type, - ptr.slow_oam_tlv_header->length)); - - if (ptr.slow_oam_tlv_header->type == SLOW_OAM_INFO_TYPE_END_OF_TLV) { + ND_TCHECK_SIZE(ptr.slow_oam_tlv_header); + type = GET_U_1(ptr.slow_oam_tlv_header->type); + length = GET_U_1(ptr.slow_oam_tlv_header->length); + ND_PRINT("\n\t %s Information Type (%u), length %u", + tok2str(slow_oam_info_type_values, "Reserved", type), + type, + length); + + if (type == SLOW_OAM_INFO_TYPE_END_OF_TLV) { /* * As IEEE Std 802.3-2015 says for the End of TLV Marker, * "(the length and value of the Type 0x00 TLV can be ignored)". @@ -550,49 +546,50 @@ slow_oam_print(netdissect_options *ndo, } /* length includes the type and length fields */ - if (ptr.slow_oam_tlv_header->length < sizeof(struct slow_oam_tlv_header_t)) { - ND_PRINT((ndo, "\n\t ERROR: illegal length - should be >= %u", - (u_int)sizeof(struct slow_oam_tlv_header_t))); + if (length < sizeof(struct slow_oam_tlv_header_t)) { + ND_PRINT("\n\t ERROR: illegal length - should be >= %zu", + sizeof(struct slow_oam_tlv_header_t)); return; } - if (tlen < ptr.slow_oam_tlv_header->length) + if (tlen < length) goto tooshort; - ND_TCHECK2(*tptr, ptr.slow_oam_tlv_header->length); + ND_TCHECK_LEN(tptr, length); hexdump = FALSE; - switch (ptr.slow_oam_tlv_header->type) { + switch (type) { case SLOW_OAM_INFO_TYPE_LOCAL: /* identical format - fall through */ case SLOW_OAM_INFO_TYPE_REMOTE: tlv.slow_oam_info = (const struct slow_oam_info_t *)tptr; - if (tlv.slow_oam_info->info_length != + if (GET_U_1(tlv.slow_oam_info->info_length) != sizeof(struct slow_oam_info_t)) { - ND_PRINT((ndo, "\n\t ERROR: illegal length - should be %lu", - (unsigned long) sizeof(struct slow_oam_info_t))); + ND_PRINT("\n\t ERROR: illegal length - should be %zu", + sizeof(struct slow_oam_info_t)); hexdump = TRUE; goto badlength_code_info; } - ND_PRINT((ndo, "\n\t OAM-Version %u, Revision %u", - tlv.slow_oam_info->oam_version, - EXTRACT_16BITS(&tlv.slow_oam_info->revision))); + ND_PRINT("\n\t OAM-Version %u, Revision %u", + GET_U_1(tlv.slow_oam_info->oam_version), + GET_BE_U_2(tlv.slow_oam_info->revision)); - ND_PRINT((ndo, "\n\t State-Parser-Action %s, State-MUX-Action %s", + state = GET_U_1(tlv.slow_oam_info->state); + ND_PRINT("\n\t State-Parser-Action %s, State-MUX-Action %s", tok2str(slow_oam_info_type_state_parser_values, "Reserved", - tlv.slow_oam_info->state & OAM_INFO_TYPE_PARSER_MASK), + state & OAM_INFO_TYPE_PARSER_MASK), tok2str(slow_oam_info_type_state_mux_values, "Reserved", - tlv.slow_oam_info->state & OAM_INFO_TYPE_MUX_MASK))); - ND_PRINT((ndo, "\n\t OAM-Config Flags [%s], OAM-PDU-Config max-PDU size %u", + state & OAM_INFO_TYPE_MUX_MASK)); + ND_PRINT("\n\t OAM-Config Flags [%s], OAM-PDU-Config max-PDU size %u", bittok2str(slow_oam_info_type_oam_config_values, "none", - tlv.slow_oam_info->oam_config), - EXTRACT_16BITS(&tlv.slow_oam_info->oam_pdu_config) & - OAM_INFO_TYPE_PDU_SIZE_MASK)); - ND_PRINT((ndo, "\n\t OUI %s (0x%06x), Vendor-Private 0x%08x", + GET_U_1(tlv.slow_oam_info->oam_config)), + GET_BE_U_2(tlv.slow_oam_info->oam_pdu_config) & + OAM_INFO_TYPE_PDU_SIZE_MASK); + ND_PRINT("\n\t OUI %s (0x%06x), Vendor-Private 0x%08x", tok2str(oui_values, "Unknown", - EXTRACT_24BITS(&tlv.slow_oam_info->oui)), - EXTRACT_24BITS(&tlv.slow_oam_info->oui), - EXTRACT_32BITS(&tlv.slow_oam_info->vendor_private))); + GET_BE_U_3(tlv.slow_oam_info->oui)), + GET_BE_U_3(tlv.slow_oam_info->oui), + GET_BE_U_4(tlv.slow_oam_info->vendor_private)); break; case SLOW_OAM_INFO_TYPE_ORG_SPECIFIC: @@ -608,11 +605,11 @@ slow_oam_print(netdissect_options *ndo, /* do we also want to see a hex dump ? */ if (ndo->ndo_vflag > 1 || hexdump==TRUE) { print_unknown_data(ndo, tptr, "\n\t ", - ptr.slow_oam_tlv_header->length); + length); } - tlen -= ptr.slow_oam_tlv_header->length; - tptr += ptr.slow_oam_tlv_header->length; + tlen -= length; + tptr += length; } break; @@ -620,8 +617,7 @@ slow_oam_print(netdissect_options *ndo, /* Sequence number */ if (tlen < 2) goto tooshort; - ND_TCHECK2(*tptr, 2); - ND_PRINT((ndo, "\n\t Sequence Number %u", EXTRACT_16BITS(tptr))); + ND_PRINT("\n\t Sequence Number %u", GET_BE_U_2(tptr)); tlen -= 2; tptr += 2; @@ -630,14 +626,15 @@ slow_oam_print(netdissect_options *ndo, ptr.slow_oam_tlv_header = (const struct slow_oam_tlv_header_t *)tptr; if (tlen < sizeof(*ptr.slow_oam_tlv_header)) goto tooshort; - ND_TCHECK(*ptr.slow_oam_tlv_header); - ND_PRINT((ndo, "\n\t %s Link Event Type (%u), length %u", + type = GET_U_1(ptr.slow_oam_tlv_header->type); + length = GET_U_1(ptr.slow_oam_tlv_header->length); + ND_PRINT("\n\t %s Link Event Type (%u), length %u", tok2str(slow_oam_link_event_values, "Reserved", - ptr.slow_oam_tlv_header->type), - ptr.slow_oam_tlv_header->type, - ptr.slow_oam_tlv_header->length)); + type), + type, + length); - if (ptr.slow_oam_tlv_header->type == SLOW_OAM_INFO_TYPE_END_OF_TLV) { + if (type == SLOW_OAM_INFO_TYPE_END_OF_TLV) { /* * As IEEE Std 802.3-2015 says for the End of TLV Marker, * "(the length and value of the Type 0x00 TLV can be ignored)". @@ -646,43 +643,43 @@ slow_oam_print(netdissect_options *ndo, } /* length includes the type and length fields */ - if (ptr.slow_oam_tlv_header->length < sizeof(struct slow_oam_tlv_header_t)) { - ND_PRINT((ndo, "\n\t ERROR: illegal length - should be >= %u", - (u_int)sizeof(struct slow_oam_tlv_header_t))); + if (length < sizeof(struct slow_oam_tlv_header_t)) { + ND_PRINT("\n\t ERROR: illegal length - should be >= %zu", + sizeof(struct slow_oam_tlv_header_t)); return; } - if (tlen < ptr.slow_oam_tlv_header->length) + if (tlen < length) goto tooshort; - ND_TCHECK2(*tptr, ptr.slow_oam_tlv_header->length); + ND_TCHECK_LEN(tptr, length); hexdump = FALSE; - switch (ptr.slow_oam_tlv_header->type) { + switch (type) { case SLOW_OAM_LINK_EVENT_ERR_SYM_PER: /* identical format - fall through */ case SLOW_OAM_LINK_EVENT_ERR_FRM: case SLOW_OAM_LINK_EVENT_ERR_FRM_PER: case SLOW_OAM_LINK_EVENT_ERR_FRM_SUMM: tlv.slow_oam_link_event = (const struct slow_oam_link_event_t *)tptr; - if (tlv.slow_oam_link_event->event_length != + if (GET_U_1(tlv.slow_oam_link_event->event_length) != sizeof(struct slow_oam_link_event_t)) { - ND_PRINT((ndo, "\n\t ERROR: illegal length - should be %lu", - (unsigned long) sizeof(struct slow_oam_link_event_t))); + ND_PRINT("\n\t ERROR: illegal length - should be %zu", + sizeof(struct slow_oam_link_event_t)); hexdump = TRUE; goto badlength_event_notif; } - ND_PRINT((ndo, "\n\t Timestamp %u ms, Errored Window %" PRIu64 + ND_PRINT("\n\t Timestamp %u ms, Errored Window %" PRIu64 "\n\t Errored Threshold %" PRIu64 "\n\t Errors %" PRIu64 "\n\t Error Running Total %" PRIu64 "\n\t Event Running Total %u", - EXTRACT_16BITS(&tlv.slow_oam_link_event->time_stamp)*100, - EXTRACT_64BITS(&tlv.slow_oam_link_event->window), - EXTRACT_64BITS(&tlv.slow_oam_link_event->threshold), - EXTRACT_64BITS(&tlv.slow_oam_link_event->errors), - EXTRACT_64BITS(&tlv.slow_oam_link_event->errors_running_total), - EXTRACT_32BITS(&tlv.slow_oam_link_event->event_running_total))); + GET_BE_U_2(tlv.slow_oam_link_event->time_stamp)*100, + GET_BE_U_8(tlv.slow_oam_link_event->window), + GET_BE_U_8(tlv.slow_oam_link_event->threshold), + GET_BE_U_8(tlv.slow_oam_link_event->errors), + GET_BE_U_8(tlv.slow_oam_link_event->errors_running_total), + GET_BE_U_4(tlv.slow_oam_link_event->event_running_total)); break; case SLOW_OAM_LINK_EVENT_ORG_SPECIFIC: @@ -698,11 +695,11 @@ slow_oam_print(netdissect_options *ndo, /* do we also want to see a hex dump ? */ if (ndo->ndo_vflag > 1 || hexdump==TRUE) { print_unknown_data(ndo, tptr, "\n\t ", - ptr.slow_oam_tlv_header->length); + length); } - tlen -= ptr.slow_oam_tlv_header->length; - tptr += ptr.slow_oam_tlv_header->length; + tlen -= length; + tptr += length; } break; @@ -710,12 +707,12 @@ slow_oam_print(netdissect_options *ndo, tlv.slow_oam_loopbackctrl = (const struct slow_oam_loopbackctrl_t *)tptr; if (tlen < sizeof(*tlv.slow_oam_loopbackctrl)) goto tooshort; - ND_TCHECK(*tlv.slow_oam_loopbackctrl); - ND_PRINT((ndo, "\n\t Command %s (%u)", + command = GET_U_1(tlv.slow_oam_loopbackctrl->command); + ND_PRINT("\n\t Command %s (%u)", tok2str(slow_oam_loopbackctrl_cmd_values, "Unknown", - tlv.slow_oam_loopbackctrl->command), - tlv.slow_oam_loopbackctrl->command)); + command), + command); tptr ++; tlen --; break; @@ -736,9 +733,5 @@ slow_oam_print(netdissect_options *ndo, return; tooshort: - ND_PRINT((ndo, "\n\t\t packet is too short")); - return; - -trunc: - ND_PRINT((ndo, "\n\t\t packet exceeded snapshot")); + ND_PRINT("\n\t\t packet is too short"); } diff --git a/contrib/tcpdump/print-smb.c b/contrib/tcpdump/print-smb.c index 944b8d28ab..bcd7363dec 100644 --- a/contrib/tcpdump/print-smb.c +++ b/contrib/tcpdump/print-smb.c @@ -9,10 +9,10 @@ /* \summary: SMB/CIFS printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include @@ -20,11 +20,12 @@ #include "extract.h" #include "smb.h" -static const char tstr[] = "[|SMB]"; static int request = 0; static int unicodestr = 0; +extern const u_char *startbuf; + const u_char *startbuf = NULL; struct smbdescript { @@ -40,7 +41,7 @@ struct smbdescriptint { const char *req_f2; const char *rep_f1; const char *rep_f2; - void (*fn)(netdissect_options *, const u_char *, const u_char *, int, int); + void (*fn)(netdissect_options *, const u_char *, const u_char *, u_int, u_int); }; struct smbfns @@ -89,44 +90,43 @@ smbfindint(int id, const struct smbfnsint *list) static void trans2_findfirst(netdissect_options *ndo, - const u_char *param, const u_char *data, int pcnt, int dcnt) + const u_char *param, const u_char *data, u_int pcnt, u_int dcnt) { const char *fmt; if (request) - fmt = "Attribute=[A]\nSearchCount=[d]\nFlags=[w]\nLevel=[dP4]\nFile=[S]\n"; + fmt = "Attribute=[A]\nSearchCount=[u]\nFlags=[w]\nLevel=[uP4]\nFile=[S]\n"; else - fmt = "Handle=[w]\nCount=[d]\nEOS=[w]\nEoffset=[d]\nLastNameOfs=[w]\n"; + fmt = "Handle=[w]\nCount=[u]\nEOS=[w]\nEoffset=[u]\nLastNameOfs=[w]\n"; smb_fdata(ndo, param, fmt, param + pcnt, unicodestr); if (dcnt) { - ND_PRINT((ndo, "data:\n")); - smb_print_data(ndo, data, dcnt); + ND_PRINT("data:\n"); + smb_data_print(ndo, data, dcnt); } } static void trans2_qfsinfo(netdissect_options *ndo, - const u_char *param, const u_char *data, int pcnt, int dcnt) + const u_char *param, const u_char *data, u_int pcnt, u_int dcnt) { - static int level = 0; + static u_int level = 0; const char *fmt=""; if (request) { - ND_TCHECK2(*param, 2); - level = EXTRACT_LE_16BITS(param); - fmt = "InfoLevel=[d]\n"; + level = GET_LE_U_2(param); + fmt = "InfoLevel=[u]\n"; smb_fdata(ndo, param, fmt, param + pcnt, unicodestr); } else { switch (level) { case 1: - fmt = "idFileSystem=[W]\nSectorUnit=[D]\nUnit=[D]\nAvail=[D]\nSectorSize=[d]\n"; + fmt = "idFileSystem=[W]\nSectorUnit=[U]\nUnit=[U]\nAvail=[U]\nSectorSize=[u]\n"; break; case 2: fmt = "CreationTime=[T2]VolNameLength=[lb]\nVolumeLabel=[c]\n"; break; case 0x105: - fmt = "Capabilities=[W]\nMaxFileLen=[D]\nVolNameLen=[lD]\nVolume=[C]\n"; + fmt = "Capabilities=[W]\nMaxFileLen=[U]\nVolNameLen=[lU]\nVolume=[C]\n"; break; default: fmt = "UnknownLevel\n"; @@ -135,19 +135,16 @@ trans2_qfsinfo(netdissect_options *ndo, smb_fdata(ndo, data, fmt, data + dcnt, unicodestr); } if (dcnt) { - ND_PRINT((ndo, "data:\n")); - smb_print_data(ndo, data, dcnt); + ND_PRINT("data:\n"); + smb_data_print(ndo, data, dcnt); } - return; -trunc: - ND_PRINT((ndo, "%s", tstr)); } static const struct smbfnsint trans2_fns[] = { { 0, "TRANSACT2_OPEN", 0, - { "Flags2=[w]\nMode=[w]\nSearchAttrib=[A]\nAttrib=[A]\nTime=[T2]\nOFun=[w]\nSize=[D]\nRes=([w, w, w, w, w])\nPath=[S]", + { "Flags2=[w]\nMode=[w]\nSearchAttrib=[A]\nAttrib=[A]\nTime=[T2]\nOFun=[w]\nSize=[U]\nRes=([w, w, w, w, w])\nPath=[S]", NULL, - "Handle=[d]\nAttrib=[A]\nTime=[T2]\nSize=[D]\nAccess=[w]\nType=[w]\nState=[w]\nAction=[w]\nInode=[W]\nOffErr=[d]\n|EALength=[d]\n", + "Handle=[u]\nAttrib=[A]\nTime=[T2]\nSize=[U]\nAccess=[w]\nType=[w]\nState=[w]\nAction=[w]\nInode=[W]\nOffErr=[u]\n|EALength=[u]\n", NULL, NULL }}, { 1, "TRANSACT2_FINDFIRST", 0, { NULL, NULL, NULL, NULL, trans2_findfirst }}, @@ -177,55 +174,54 @@ print_trans2(netdissect_options *ndo, const u_char *data, *param; const u_char *w = words + 1; const char *f1 = NULL, *f2 = NULL; - int pcnt, dcnt; + u_int pcnt, dcnt; - ND_TCHECK(words[0]); + ND_TCHECK_1(words); if (request) { - ND_TCHECK2(w[14 * 2], 2); - pcnt = EXTRACT_LE_16BITS(w + 9 * 2); - param = buf + EXTRACT_LE_16BITS(w + 10 * 2); - dcnt = EXTRACT_LE_16BITS(w + 11 * 2); - data = buf + EXTRACT_LE_16BITS(w + 12 * 2); - fn = smbfindint(EXTRACT_LE_16BITS(w + 14 * 2), trans2_fns); + ND_TCHECK_2(w + (14 * 2)); + pcnt = GET_LE_U_2(w + 9 * 2); + param = buf + GET_LE_U_2(w + 10 * 2); + dcnt = GET_LE_U_2(w + 11 * 2); + data = buf + GET_LE_U_2(w + 12 * 2); + fn = smbfindint(GET_LE_U_2(w + 14 * 2), trans2_fns); } else { - if (words[0] == 0) { - ND_PRINT((ndo, "%s\n", fn->name)); - ND_PRINT((ndo, "Trans2Interim\n")); + if (GET_U_1(words) == 0) { + ND_PRINT("%s\n", fn->name); + ND_PRINT("Trans2Interim\n"); return; } - ND_TCHECK2(w[7 * 2], 2); - pcnt = EXTRACT_LE_16BITS(w + 3 * 2); - param = buf + EXTRACT_LE_16BITS(w + 4 * 2); - dcnt = EXTRACT_LE_16BITS(w + 6 * 2); - data = buf + EXTRACT_LE_16BITS(w + 7 * 2); + ND_TCHECK_2(w + (7 * 2)); + pcnt = GET_LE_U_2(w + 3 * 2); + param = buf + GET_LE_U_2(w + 4 * 2); + dcnt = GET_LE_U_2(w + 6 * 2); + data = buf + GET_LE_U_2(w + 7 * 2); } - ND_PRINT((ndo, "%s param_length=%d data_length=%d\n", fn->name, pcnt, dcnt)); + ND_PRINT("%s param_length=%u data_length=%u\n", fn->name, pcnt, dcnt); if (request) { - if (words[0] == 8) { + if (GET_U_1(words) == 8) { smb_fdata(ndo, words + 1, - "Trans2Secondary\nTotParam=[d]\nTotData=[d]\nParamCnt=[d]\nParamOff=[d]\nParamDisp=[d]\nDataCnt=[d]\nDataOff=[d]\nDataDisp=[d]\nHandle=[d]\n", + "Trans2Secondary\nTotParam=[u]\nTotData=[u]\nParamCnt=[u]\nParamOff=[u]\nParamDisp=[u]\nDataCnt=[u]\nDataOff=[u]\nDataDisp=[u]\nHandle=[u]\n", maxbuf, unicodestr); return; } else { smb_fdata(ndo, words + 1, - "TotParam=[d]\nTotData=[d]\nMaxParam=[d]\nMaxData=[d]\nMaxSetup=[b][P1]\nFlags=[w]\nTimeOut=[D]\nRes1=[w]\nParamCnt=[d]\nParamOff=[d]\nDataCnt=[d]\nDataOff=[d]\nSetupCnt=[b][P1]\n", + "TotParam=[u]\nTotData=[u]\nMaxParam=[u]\nMaxData=[u]\nMaxSetup=[b][P1]\nFlags=[w]\nTimeOut=[D]\nRes1=[w]\nParamCnt=[u]\nParamOff=[u]\nDataCnt=[u]\nDataOff=[u]\nSetupCnt=[b][P1]\n", words + 1 + 14 * 2, unicodestr); } f1 = fn->descript.req_f1; f2 = fn->descript.req_f2; } else { smb_fdata(ndo, words + 1, - "TotParam=[d]\nTotData=[d]\nRes1=[w]\nParamCnt=[d]\nParamOff=[d]\nParamDisp[d]\nDataCnt=[d]\nDataOff=[d]\nDataDisp=[d]\nSetupCnt=[b][P1]\n", + "TotParam=[u]\nTotData=[u]\nRes1=[w]\nParamCnt=[u]\nParamOff=[u]\nParamDisp[u]\nDataCnt=[u]\nDataOff=[u]\nDataDisp=[u]\nSetupCnt=[b][P1]\n", words + 1 + 10 * 2, unicodestr); f1 = fn->descript.rep_f1; f2 = fn->descript.rep_f2; } - ND_TCHECK2(*dat, 2); - bcc = EXTRACT_LE_16BITS(dat); - ND_PRINT((ndo, "smb_bcc=%u\n", bcc)); + bcc = GET_LE_U_2(dat); + ND_PRINT("smb_bcc=%u\n", bcc); if (fn->descript.fn) (*fn->descript.fn)(ndo, param, data, pcnt, dcnt); else { @@ -234,31 +230,30 @@ print_trans2(netdissect_options *ndo, } return; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); } static void print_browse(netdissect_options *ndo, - const u_char *param, int paramlen, const u_char *data, int datalen) + const u_char *param, u_int paramlen, const u_char *data, u_int datalen) { const u_char *maxbuf = data + datalen; - int command; + u_int command; - ND_TCHECK(data[0]); - command = data[0]; + command = GET_U_1(data); smb_fdata(ndo, param, "BROWSE PACKET\n|Param ", param+paramlen, unicodestr); switch (command) { case 0xF: data = smb_fdata(ndo, data, - "BROWSE PACKET:\nType=[B] (LocalMasterAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[d]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nElectionVersion=[w]\nBrowserConstant=[w]\n", + "BROWSE PACKET:\nType=[B] (LocalMasterAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[u]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nElectionVersion=[w]\nBrowserConstant=[w]\n", maxbuf, unicodestr); break; case 0x1: data = smb_fdata(ndo, data, - "BROWSE PACKET:\nType=[B] (HostAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[d]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nElectionVersion=[w]\nBrowserConstant=[w]\n", + "BROWSE PACKET:\nType=[B] (HostAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[u]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nElectionVersion=[w]\nBrowserConstant=[w]\n", maxbuf, unicodestr); break; @@ -270,7 +265,7 @@ print_browse(netdissect_options *ndo, case 0xc: data = smb_fdata(ndo, data, - "BROWSE PACKET:\nType=[B] (WorkgroupAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[d]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nCommentPointer=[W]\nServerName=[S]\n", + "BROWSE PACKET:\nType=[B] (WorkgroupAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[u]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nCommentPointer=[W]\nServerName=[S]\n", maxbuf, unicodestr); break; @@ -313,15 +308,12 @@ print_browse(netdissect_options *ndo, data = smb_fdata(ndo, data, "Unknown Browser Frame ", maxbuf, unicodestr); break; } - return; -trunc: - ND_PRINT((ndo, "%s", tstr)); } static void print_ipc(netdissect_options *ndo, - const u_char *param, int paramlen, const u_char *data, int datalen) + const u_char *param, u_int paramlen, const u_char *data, u_int datalen) { if (paramlen) smb_fdata(ndo, param, "Command=[w]\nStr1=[S]\nStr2=[S]\n", param + paramlen, @@ -339,40 +331,41 @@ print_trans(netdissect_options *ndo, const char *f1, *f2, *f3, *f4; const u_char *data, *param; const u_char *w = words + 1; - int datalen, paramlen; + u_int datalen, paramlen; if (request) { - ND_TCHECK2(w[12 * 2], 2); - paramlen = EXTRACT_LE_16BITS(w + 9 * 2); - param = buf + EXTRACT_LE_16BITS(w + 10 * 2); - datalen = EXTRACT_LE_16BITS(w + 11 * 2); - data = buf + EXTRACT_LE_16BITS(w + 12 * 2); - f1 = "TotParamCnt=[d] \nTotDataCnt=[d] \nMaxParmCnt=[d] \nMaxDataCnt=[d]\nMaxSCnt=[d] \nTransFlags=[w] \nRes1=[w] \nRes2=[w] \nRes3=[w]\nParamCnt=[d] \nParamOff=[d] \nDataCnt=[d] \nDataOff=[d] \nSUCnt=[d]\n"; + ND_TCHECK_2(w + (12 * 2)); + paramlen = GET_LE_U_2(w + 9 * 2); + param = buf + GET_LE_U_2(w + 10 * 2); + datalen = GET_LE_U_2(w + 11 * 2); + data = buf + GET_LE_U_2(w + 12 * 2); + f1 = "TotParamCnt=[u]\nTotDataCnt=[u]\nMaxParmCnt=[u]\nMaxDataCnt=[u]\nMaxSCnt=[u]\nTransFlags=[w]\nRes1=[w]\nRes2=[w]\nRes3=[w]\nParamCnt=[u]\nParamOff=[u]\nDataCnt=[u]\nDataOff=[u]\nSUCnt=[u]\n"; f2 = "|Name=[S]\n"; f3 = "|Param "; f4 = "|Data "; } else { - ND_TCHECK2(w[7 * 2], 2); - paramlen = EXTRACT_LE_16BITS(w + 3 * 2); - param = buf + EXTRACT_LE_16BITS(w + 4 * 2); - datalen = EXTRACT_LE_16BITS(w + 6 * 2); - data = buf + EXTRACT_LE_16BITS(w + 7 * 2); - f1 = "TotParamCnt=[d] \nTotDataCnt=[d] \nRes1=[d]\nParamCnt=[d] \nParamOff=[d] \nRes2=[d] \nDataCnt=[d] \nDataOff=[d] \nRes3=[d]\nLsetup=[d]\n"; + ND_TCHECK_2(w + (7 * 2)); + paramlen = GET_LE_U_2(w + 3 * 2); + param = buf + GET_LE_U_2(w + 4 * 2); + datalen = GET_LE_U_2(w + 6 * 2); + data = buf + GET_LE_U_2(w + 7 * 2); + f1 = "TotParamCnt=[u]\nTotDataCnt=[u]\nRes1=[u]\nParamCnt=[u]\nParamOff=[u]\nRes2=[u]\nDataCnt=[u]\nDataOff=[u]\nRes3=[u]\nLsetup=[u]\n"; f2 = "|Unknown "; f3 = "|Param "; f4 = "|Data "; } - smb_fdata(ndo, words + 1, f1, min(words + 1 + 2 * words[0], maxbuf), - unicodestr); + smb_fdata(ndo, words + 1, f1, + ND_MIN(words + 1 + 2 * GET_U_1(words), maxbuf), + unicodestr); - ND_TCHECK2(*data1, 2); - bcc = EXTRACT_LE_16BITS(data1); - ND_PRINT((ndo, "smb_bcc=%u\n", bcc)); + bcc = GET_LE_U_2(data1); + ND_PRINT("smb_bcc=%u\n", bcc); if (bcc > 0) { smb_fdata(ndo, data1 + 2, f2, maxbuf - (paramlen + datalen), unicodestr); + #define MAILSLOT_BROWSE_STR "\\MAILSLOT\\BROWSE" - ND_TCHECK2(*(data1 + 2), strlen(MAILSLOT_BROWSE_STR) + 1); + ND_TCHECK_LEN(data1 + 2, strlen(MAILSLOT_BROWSE_STR) + 1); if (strcmp((const char *)(data1 + 2), MAILSLOT_BROWSE_STR) == 0) { print_browse(ndo, param, paramlen, data, datalen); return; @@ -380,7 +373,7 @@ print_trans(netdissect_options *ndo, #undef MAILSLOT_BROWSE_STR #define PIPE_LANMAN_STR "\\PIPE\\LANMAN" - ND_TCHECK2(*(data1 + 2), strlen(PIPE_LANMAN_STR) + 1); + ND_TCHECK_LEN(data1 + 2, strlen(PIPE_LANMAN_STR) + 1); if (strcmp((const char *)(data1 + 2), PIPE_LANMAN_STR) == 0) { print_ipc(ndo, param, paramlen, data, datalen); return; @@ -388,13 +381,13 @@ print_trans(netdissect_options *ndo, #undef PIPE_LANMAN_STR if (paramlen) - smb_fdata(ndo, param, f3, min(param + paramlen, maxbuf), unicodestr); + smb_fdata(ndo, param, f3, ND_MIN(param + paramlen, maxbuf), unicodestr); if (datalen) - smb_fdata(ndo, data, f4, min(data + datalen, maxbuf), unicodestr); + smb_fdata(ndo, data, f4, ND_MIN(data + datalen, maxbuf), unicodestr); } return; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); } @@ -405,38 +398,34 @@ print_negprot(netdissect_options *ndo, u_int wct, bcc; const char *f1 = NULL, *f2 = NULL; - ND_TCHECK(words[0]); - wct = words[0]; + wct = GET_U_1(words); if (request) f2 = "*|Dialect=[Y]\n"; else { if (wct == 1) - f1 = "Core Protocol\nDialectIndex=[d]"; + f1 = "Core Protocol\nDialectIndex=[u]"; else if (wct == 17) - f1 = "NT1 Protocol\nDialectIndex=[d]\nSecMode=[B]\nMaxMux=[d]\nNumVcs=[d]\nMaxBuffer=[D]\nRawSize=[D]\nSessionKey=[W]\nCapabilities=[W]\nServerTime=[T3]TimeZone=[d]\nCryptKey="; + f1 = "NT1 Protocol\nDialectIndex=[u]\nSecMode=[B]\nMaxMux=[u]\nNumVcs=[u]\nMaxBuffer=[U]\nRawSize=[U]\nSessionKey=[W]\nCapabilities=[W]\nServerTime=[T3]TimeZone=[u]\nCryptKey="; else if (wct == 13) - f1 = "Coreplus/Lanman1/Lanman2 Protocol\nDialectIndex=[d]\nSecMode=[w]\nMaxXMit=[d]\nMaxMux=[d]\nMaxVcs=[d]\nBlkMode=[w]\nSessionKey=[W]\nServerTime=[T1]TimeZone=[d]\nRes=[W]\nCryptKey="; + f1 = "Coreplus/Lanman1/Lanman2 Protocol\nDialectIndex=[u]\nSecMode=[w]\nMaxXMit=[u]\nMaxMux=[u]\nMaxVcs=[u]\nBlkMode=[w]\nSessionKey=[W]\nServerTime=[T1]TimeZone=[u]\nRes=[W]\nCryptKey="; } if (f1) - smb_fdata(ndo, words + 1, f1, min(words + 1 + wct * 2, maxbuf), + smb_fdata(ndo, words + 1, f1, ND_MIN(words + 1 + wct * 2, maxbuf), unicodestr); else - smb_print_data(ndo, words + 1, min(wct * 2, PTR_DIFF(maxbuf, words + 1))); + smb_data_print(ndo, words + 1, ND_MIN(wct * 2, ND_BYTES_BETWEEN(maxbuf, words + 1))); - ND_TCHECK2(*data, 2); - bcc = EXTRACT_LE_16BITS(data); - ND_PRINT((ndo, "smb_bcc=%u\n", bcc)); + bcc = GET_LE_U_2(data); + ND_PRINT("smb_bcc=%u\n", bcc); if (bcc > 0) { if (f2) - smb_fdata(ndo, data + 2, f2, min(data + 2 + EXTRACT_LE_16BITS(data), - maxbuf), unicodestr); + smb_fdata(ndo, data + 2, f2, ND_MIN(data + 2 + GET_LE_U_2(data), + maxbuf), unicodestr); else - smb_print_data(ndo, data + 2, min(EXTRACT_LE_16BITS(data), PTR_DIFF(maxbuf, data + 2))); + smb_data_print(ndo, data + 2, + ND_MIN(GET_LE_U_2(data), ND_BYTES_BETWEEN(maxbuf, data + 2))); } - return; -trunc: - ND_PRINT((ndo, "%s", tstr)); } static void @@ -446,41 +435,37 @@ print_sesssetup(netdissect_options *ndo, u_int wct, bcc; const char *f1 = NULL, *f2 = NULL; - ND_TCHECK(words[0]); - wct = words[0]; + wct = GET_U_1(words); if (request) { if (wct == 10) - f1 = "Com2=[w]\nOff2=[d]\nBufSize=[d]\nMpxMax=[d]\nVcNum=[d]\nSessionKey=[W]\nPassLen=[d]\nCryptLen=[d]\nCryptOff=[d]\nPass&Name=\n"; + f1 = "Com2=[w]\nOff2=[u]\nBufSize=[u]\nMpxMax=[u]\nVcNum=[u]\nSessionKey=[W]\nPassLen=[u]\nCryptLen=[u]\nCryptOff=[u]\nPass&Name=\n"; else - f1 = "Com2=[B]\nRes1=[B]\nOff2=[d]\nMaxBuffer=[d]\nMaxMpx=[d]\nVcNumber=[d]\nSessionKey=[W]\nCaseInsensitivePasswordLength=[d]\nCaseSensitivePasswordLength=[d]\nRes=[W]\nCapabilities=[W]\nPass1&Pass2&Account&Domain&OS&LanMan=\n"; + f1 = "Com2=[B]\nRes1=[B]\nOff2=[u]\nMaxBuffer=[u]\nMaxMpx=[u]\nVcNumber=[u]\nSessionKey=[W]\nCaseInsensitivePasswordLength=[u]\nCaseSensitivePasswordLength=[u]\nRes=[W]\nCapabilities=[W]\nPass1&Pass2&Account&Domain&OS&LanMan=\n"; } else { if (wct == 3) { - f1 = "Com2=[w]\nOff2=[d]\nAction=[w]\n"; + f1 = "Com2=[w]\nOff2=[u]\nAction=[w]\n"; } else if (wct == 13) { - f1 = "Com2=[B]\nRes=[B]\nOff2=[d]\nAction=[w]\n"; + f1 = "Com2=[B]\nRes=[B]\nOff2=[u]\nAction=[w]\n"; f2 = "NativeOS=[S]\nNativeLanMan=[S]\nPrimaryDomain=[S]\n"; } } if (f1) - smb_fdata(ndo, words + 1, f1, min(words + 1 + wct * 2, maxbuf), + smb_fdata(ndo, words + 1, f1, ND_MIN(words + 1 + wct * 2, maxbuf), unicodestr); else - smb_print_data(ndo, words + 1, min(wct * 2, PTR_DIFF(maxbuf, words + 1))); + smb_data_print(ndo, words + 1, ND_MIN(wct * 2, ND_BYTES_BETWEEN(maxbuf, words + 1))); - ND_TCHECK2(*data, 2); - bcc = EXTRACT_LE_16BITS(data); - ND_PRINT((ndo, "smb_bcc=%u\n", bcc)); + bcc = GET_LE_U_2(data); + ND_PRINT("smb_bcc=%u\n", bcc); if (bcc > 0) { if (f2) - smb_fdata(ndo, data + 2, f2, min(data + 2 + EXTRACT_LE_16BITS(data), - maxbuf), unicodestr); + smb_fdata(ndo, data + 2, f2, ND_MIN(data + 2 + GET_LE_U_2(data), + maxbuf), unicodestr); else - smb_print_data(ndo, data + 2, min(EXTRACT_LE_16BITS(data), PTR_DIFF(maxbuf, data + 2))); + smb_data_print(ndo, data + 2, + ND_MIN(GET_LE_U_2(data), ND_BYTES_BETWEEN(maxbuf, data + 2))); } - return; -trunc: - ND_PRINT((ndo, "%s", tstr)); } static void @@ -491,36 +476,31 @@ print_lockingandx(netdissect_options *ndo, const u_char *maxwords; const char *f1 = NULL, *f2 = NULL; - ND_TCHECK(words[0]); - wct = words[0]; + wct = GET_U_1(words); if (request) { - f1 = "Com2=[w]\nOff2=[d]\nHandle=[d]\nLockType=[w]\nTimeOut=[D]\nUnlockCount=[d]\nLockCount=[d]\n"; - ND_TCHECK(words[7]); - if (words[7] & 0x10) - f2 = "*Process=[d]\n[P2]Offset=[M]\nLength=[M]\n"; + f1 = "Com2=[w]\nOff2=[u]\nHandle=[u]\nLockType=[w]\nTimeOut=[D]\nUnlockCount=[u]\nLockCount=[u]\n"; + if (GET_U_1(words + 7) & 0x10) + f2 = "*Process=[u]\n[P2]Offset=[M]\nLength=[M]\n"; else - f2 = "*Process=[d]\nOffset=[D]\nLength=[D]\n"; + f2 = "*Process=[u]\nOffset=[D]\nLength=[U]\n"; } else { - f1 = "Com2=[w]\nOff2=[d]\n"; + f1 = "Com2=[w]\nOff2=[u]\n"; } - maxwords = min(words + 1 + wct * 2, maxbuf); + maxwords = ND_MIN(words + 1 + wct * 2, maxbuf); if (wct) smb_fdata(ndo, words + 1, f1, maxwords, unicodestr); - ND_TCHECK2(*data, 2); - bcc = EXTRACT_LE_16BITS(data); - ND_PRINT((ndo, "smb_bcc=%u\n", bcc)); + bcc = GET_LE_U_2(data); + ND_PRINT("smb_bcc=%u\n", bcc); if (bcc > 0) { if (f2) - smb_fdata(ndo, data + 2, f2, min(data + 2 + EXTRACT_LE_16BITS(data), - maxbuf), unicodestr); + smb_fdata(ndo, data + 2, f2, ND_MIN(data + 2 + GET_LE_U_2(data), + maxbuf), unicodestr); else - smb_print_data(ndo, data + 2, min(EXTRACT_LE_16BITS(data), PTR_DIFF(maxbuf, data + 2))); + smb_data_print(ndo, data + 2, + ND_MIN(GET_LE_U_2(data), ND_BYTES_BETWEEN(maxbuf, data + 2))); } - return; -trunc: - ND_PRINT((ndo, "%s", tstr)); } @@ -529,7 +509,7 @@ static const struct smbfns smb_fns[] = { { SMBtcon, "SMBtcon", 0, { NULL, "Path=[Z]\nPassword=[Z]\nDevice=[Z]\n", - "MaxXmit=[d]\nTreeId=[d]\n", NULL, + "MaxXmit=[u]\nTreeId=[u]\n", NULL, NULL } }, { SMBtdis, "SMBtdis", 0, DEFDESCRIPT }, @@ -537,15 +517,15 @@ static const struct smbfns smb_fns[] = { { SMBioctl, "SMBioctl", 0, DEFDESCRIPT }, { SMBecho, "SMBecho", 0, - { "ReverbCount=[d]\n", NULL, - "SequenceNum=[d]\n", NULL, + { "ReverbCount=[u]\n", NULL, + "SequenceNum=[u]\n", NULL, NULL } }, { SMBulogoffX, "SMBulogoffX", FLG_CHAIN, DEFDESCRIPT }, { SMBgetatr, "SMBgetatr", 0, { NULL, "Path=[Z]\n", - "Attribute=[A]\nTime=[T2]Size=[D]\nRes=([w,w,w,w,w])\n", NULL, + "Attribute=[A]\nTime=[T2]Size=[U]\nRes=([w,w,w,w,w])\n", NULL, NULL } }, { SMBsetatr, "SMBsetatr", 0, @@ -556,36 +536,36 @@ static const struct smbfns smb_fns[] = { { NULL, "Path=[Z]\n", NULL, NULL, NULL } }, { SMBsearch, "SMBsearch", 0, - { "Count=[d]\nAttrib=[A]\n", - "Path=[Z]\nBlkType=[B]\nBlkLen=[d]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\n", - "Count=[d]\n", - "BlkType=[B]\nBlkLen=[d]\n*\nRes1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\nAttrib=[a]\nTime=[T1]Size=[D]\nName=[s13]\n", + { "Count=[u]\nAttrib=[A]\n", + "Path=[Z]\nBlkType=[B]\nBlkLen=[u]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[u]\nSrv2=[w]\nRes2=[W]\n", + "Count=[u]\n", + "BlkType=[B]\nBlkLen=[u]\n*\nRes1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[u]\nSrv2=[w]\nRes2=[W]\nAttrib=[a]\nTime=[T1]Size=[U]\nName=[s13]\n", NULL } }, { SMBopen, "SMBopen", 0, { "Mode=[w]\nAttribute=[A]\n", "Path=[Z]\n", - "Handle=[d]\nOAttrib=[A]\nTime=[T2]Size=[D]\nAccess=[w]\n", + "Handle=[u]\nOAttrib=[A]\nTime=[T2]Size=[U]\nAccess=[w]\n", NULL, NULL } }, { SMBcreate, "SMBcreate", 0, - { "Attrib=[A]\nTime=[T2]", "Path=[Z]\n", "Handle=[d]\n", NULL, NULL } }, + { "Attrib=[A]\nTime=[T2]", "Path=[Z]\n", "Handle=[u]\n", NULL, NULL } }, { SMBmknew, "SMBmknew", 0, - { "Attrib=[A]\nTime=[T2]", "Path=[Z]\n", "Handle=[d]\n", NULL, NULL } }, + { "Attrib=[A]\nTime=[T2]", "Path=[Z]\n", "Handle=[u]\n", NULL, NULL } }, { SMBunlink, "SMBunlink", 0, { "Attrib=[A]\n", "Path=[Z]\n", NULL, NULL, NULL } }, { SMBread, "SMBread", 0, - { "Handle=[d]\nByteCount=[d]\nOffset=[D]\nCountLeft=[d]\n", NULL, - "Count=[d]\nRes=([w,w,w,w])\n", NULL, NULL } }, + { "Handle=[u]\nByteCount=[u]\nOffset=[D]\nCountLeft=[u]\n", NULL, + "Count=[u]\nRes=([w,w,w,w])\n", NULL, NULL } }, { SMBwrite, "SMBwrite", 0, - { "Handle=[d]\nByteCount=[d]\nOffset=[D]\nCountLeft=[d]\n", NULL, - "Count=[d]\n", NULL, NULL } }, + { "Handle=[u]\nByteCount=[u]\nOffset=[D]\nCountLeft=[u]\n", NULL, + "Count=[u]\n", NULL, NULL } }, { SMBclose, "SMBclose", 0, - { "Handle=[d]\nTime=[T2]", NULL, NULL, NULL, NULL } }, + { "Handle=[u]\nTime=[T2]", NULL, NULL, NULL, NULL } }, { SMBmkdir, "SMBmkdir", 0, { NULL, "Path=[Z]\n", NULL, NULL, NULL } }, @@ -595,7 +575,7 @@ static const struct smbfns smb_fns[] = { { SMBdskattr, "SMBdskattr", 0, { NULL, NULL, - "TotalUnits=[d]\nBlocksPerUnit=[d]\nBlockSize=[d]\nFreeUnits=[d]\nMedia=[w]\n", + "TotalUnits=[u]\nBlocksPerUnit=[u]\nBlockSize=[u]\nFreeUnits=[u]\nMedia=[w]\n", NULL, NULL } }, { SMBmv, "SMBmv", 0, @@ -608,147 +588,147 @@ static const struct smbfns smb_fns[] = { { pSETDIR, "SMBsetdir", 0, { NULL, "Path=[Z]\n", NULL, NULL, NULL } }, { SMBlseek, "SMBlseek", 0, - { "Handle=[d]\nMode=[w]\nOffset=[D]\n", "Offset=[D]\n", NULL, NULL, NULL } }, + { "Handle=[u]\nMode=[w]\nOffset=[D]\n", "Offset=[D]\n", NULL, NULL, NULL } }, - { SMBflush, "SMBflush", 0, { "Handle=[d]\n", NULL, NULL, NULL, NULL } }, + { SMBflush, "SMBflush", 0, { "Handle=[u]\n", NULL, NULL, NULL, NULL } }, { SMBsplopen, "SMBsplopen", 0, - { "SetupLen=[d]\nMode=[w]\n", "Ident=[Z]\n", "Handle=[d]\n", + { "SetupLen=[u]\nMode=[w]\n", "Ident=[Z]\n", "Handle=[u]\n", NULL, NULL } }, { SMBsplclose, "SMBsplclose", 0, - { "Handle=[d]\n", NULL, NULL, NULL, NULL } }, + { "Handle=[u]\n", NULL, NULL, NULL, NULL } }, { SMBsplretq, "SMBsplretq", 0, - { "MaxCount=[d]\nStartIndex=[d]\n", NULL, - "Count=[d]\nIndex=[d]\n", - "*Time=[T2]Status=[B]\nJobID=[d]\nSize=[D]\nRes=[B]Name=[s16]\n", + { "MaxCount=[u]\nStartIndex=[u]\n", NULL, + "Count=[u]\nIndex=[u]\n", + "*Time=[T2]Status=[B]\nJobID=[u]\nSize=[U]\nRes=[B]Name=[s16]\n", NULL } }, { SMBsplwr, "SMBsplwr", 0, - { "Handle=[d]\n", NULL, NULL, NULL, NULL } }, + { "Handle=[u]\n", NULL, NULL, NULL, NULL } }, { SMBlock, "SMBlock", 0, - { "Handle=[d]\nCount=[D]\nOffset=[D]\n", NULL, NULL, NULL, NULL } }, + { "Handle=[u]\nCount=[U]\nOffset=[D]\n", NULL, NULL, NULL, NULL } }, { SMBunlock, "SMBunlock", 0, - { "Handle=[d]\nCount=[D]\nOffset=[D]\n", NULL, NULL, NULL, NULL } }, + { "Handle=[u]\nCount=[U]\nOffset=[D]\n", NULL, NULL, NULL, NULL } }, /* CORE+ PROTOCOL FOLLOWS */ { SMBreadbraw, "SMBreadbraw", 0, - { "Handle=[d]\nOffset=[D]\nMaxCount=[d]\nMinCount=[d]\nTimeOut=[D]\nRes=[d]\n", + { "Handle=[u]\nOffset=[D]\nMaxCount=[u]\nMinCount=[u]\nTimeOut=[D]\nRes=[u]\n", NULL, NULL, NULL, NULL } }, { SMBwritebraw, "SMBwritebraw", 0, - { "Handle=[d]\nTotalCount=[d]\nRes=[w]\nOffset=[D]\nTimeOut=[D]\nWMode=[w]\nRes2=[W]\n|DataSize=[d]\nDataOff=[d]\n", + { "Handle=[u]\nTotalCount=[u]\nRes=[w]\nOffset=[D]\nTimeOut=[D]\nWMode=[w]\nRes2=[W]\n|DataSize=[u]\nDataOff=[u]\n", NULL, "WriteRawAck", NULL, NULL } }, { SMBwritec, "SMBwritec", 0, - { NULL, NULL, "Count=[d]\n", NULL, NULL } }, + { NULL, NULL, "Count=[u]\n", NULL, NULL } }, { SMBwriteclose, "SMBwriteclose", 0, - { "Handle=[d]\nCount=[d]\nOffset=[D]\nTime=[T2]Res=([w,w,w,w,w,w])", - NULL, "Count=[d]\n", NULL, NULL } }, + { "Handle=[u]\nCount=[u]\nOffset=[D]\nTime=[T2]Res=([w,w,w,w,w,w])", + NULL, "Count=[u]\n", NULL, NULL } }, { SMBlockread, "SMBlockread", 0, - { "Handle=[d]\nByteCount=[d]\nOffset=[D]\nCountLeft=[d]\n", NULL, - "Count=[d]\nRes=([w,w,w,w])\n", NULL, NULL } }, + { "Handle=[u]\nByteCount=[u]\nOffset=[D]\nCountLeft=[u]\n", NULL, + "Count=[u]\nRes=([w,w,w,w])\n", NULL, NULL } }, { SMBwriteunlock, "SMBwriteunlock", 0, - { "Handle=[d]\nByteCount=[d]\nOffset=[D]\nCountLeft=[d]\n", NULL, - "Count=[d]\n", NULL, NULL } }, + { "Handle=[u]\nByteCount=[u]\nOffset=[D]\nCountLeft=[u]\n", NULL, + "Count=[u]\n", NULL, NULL } }, { SMBreadBmpx, "SMBreadBmpx", 0, - { "Handle=[d]\nOffset=[D]\nMaxCount=[d]\nMinCount=[d]\nTimeOut=[D]\nRes=[w]\n", + { "Handle=[u]\nOffset=[D]\nMaxCount=[u]\nMinCount=[u]\nTimeOut=[D]\nRes=[w]\n", NULL, - "Offset=[D]\nTotCount=[d]\nRemaining=[d]\nRes=([w,w])\nDataSize=[d]\nDataOff=[d]\n", + "Offset=[D]\nTotCount=[u]\nRemaining=[u]\nRes=([w,w])\nDataSize=[u]\nDataOff=[u]\n", NULL, NULL } }, { SMBwriteBmpx, "SMBwriteBmpx", 0, - { "Handle=[d]\nTotCount=[d]\nRes=[w]\nOffset=[D]\nTimeOut=[D]\nWMode=[w]\nRes2=[W]\nDataSize=[d]\nDataOff=[d]\n", NULL, - "Remaining=[d]\n", NULL, NULL } }, + { "Handle=[u]\nTotCount=[u]\nRes=[w]\nOffset=[D]\nTimeOut=[D]\nWMode=[w]\nRes2=[W]\nDataSize=[u]\nDataOff=[u]\n", NULL, + "Remaining=[u]\n", NULL, NULL } }, { SMBwriteBs, "SMBwriteBs", 0, - { "Handle=[d]\nTotCount=[d]\nOffset=[D]\nRes=[W]\nDataSize=[d]\nDataOff=[d]\n", - NULL, "Count=[d]\n", NULL, NULL } }, + { "Handle=[u]\nTotCount=[u]\nOffset=[D]\nRes=[W]\nDataSize=[u]\nDataOff=[u]\n", + NULL, "Count=[u]\n", NULL, NULL } }, { SMBsetattrE, "SMBsetattrE", 0, - { "Handle=[d]\nCreationTime=[T2]AccessTime=[T2]ModifyTime=[T2]", NULL, + { "Handle=[u]\nCreationTime=[T2]AccessTime=[T2]ModifyTime=[T2]", NULL, NULL, NULL, NULL } }, { SMBgetattrE, "SMBgetattrE", 0, - { "Handle=[d]\n", NULL, - "CreationTime=[T2]AccessTime=[T2]ModifyTime=[T2]Size=[D]\nAllocSize=[D]\nAttribute=[A]\n", + { "Handle=[u]\n", NULL, + "CreationTime=[T2]AccessTime=[T2]ModifyTime=[T2]Size=[U]\nAllocSize=[U]\nAttribute=[A]\n", NULL, NULL } }, { SMBtranss, "SMBtranss", 0, DEFDESCRIPT }, { SMBioctls, "SMBioctls", 0, DEFDESCRIPT }, { SMBcopy, "SMBcopy", 0, - { "TreeID2=[d]\nOFun=[w]\nFlags=[w]\n", "Path=[S]\nNewPath=[S]\n", - "CopyCount=[d]\n", "|ErrStr=[S]\n", NULL } }, + { "TreeID2=[u]\nOFun=[w]\nFlags=[w]\n", "Path=[S]\nNewPath=[S]\n", + "CopyCount=[u]\n", "|ErrStr=[S]\n", NULL } }, { SMBmove, "SMBmove", 0, - { "TreeID2=[d]\nOFun=[w]\nFlags=[w]\n", "Path=[S]\nNewPath=[S]\n", - "MoveCount=[d]\n", "|ErrStr=[S]\n", NULL } }, + { "TreeID2=[u]\nOFun=[w]\nFlags=[w]\n", "Path=[S]\nNewPath=[S]\n", + "MoveCount=[u]\n", "|ErrStr=[S]\n", NULL } }, { SMBopenX, "SMBopenX", FLG_CHAIN, - { "Com2=[w]\nOff2=[d]\nFlags=[w]\nMode=[w]\nSearchAttrib=[A]\nAttrib=[A]\nTime=[T2]OFun=[w]\nSize=[D]\nTimeOut=[D]\nRes=[W]\n", + { "Com2=[w]\nOff2=[u]\nFlags=[w]\nMode=[w]\nSearchAttrib=[A]\nAttrib=[A]\nTime=[T2]OFun=[w]\nSize=[U]\nTimeOut=[D]\nRes=[W]\n", "Path=[S]\n", - "Com2=[w]\nOff2=[d]\nHandle=[d]\nAttrib=[A]\nTime=[T2]Size=[D]\nAccess=[w]\nType=[w]\nState=[w]\nAction=[w]\nFileID=[W]\nRes=[w]\n", + "Com2=[w]\nOff2=[u]\nHandle=[u]\nAttrib=[A]\nTime=[T2]Size=[U]\nAccess=[w]\nType=[w]\nState=[w]\nAction=[w]\nFileID=[W]\nRes=[w]\n", NULL, NULL } }, { SMBreadX, "SMBreadX", FLG_CHAIN, - { "Com2=[w]\nOff2=[d]\nHandle=[d]\nOffset=[D]\nMaxCount=[d]\nMinCount=[d]\nTimeOut=[D]\nCountLeft=[d]\n", + { "Com2=[w]\nOff2=[u]\nHandle=[u]\nOffset=[D]\nMaxCount=[u]\nMinCount=[u]\nTimeOut=[D]\nCountLeft=[u]\n", NULL, - "Com2=[w]\nOff2=[d]\nRemaining=[d]\nRes=[W]\nDataSize=[d]\nDataOff=[d]\nRes=([w,w,w,w])\n", + "Com2=[w]\nOff2=[u]\nRemaining=[u]\nRes=[W]\nDataSize=[u]\nDataOff=[u]\nRes=([w,w,w,w])\n", NULL, NULL } }, { SMBwriteX, "SMBwriteX", FLG_CHAIN, - { "Com2=[w]\nOff2=[d]\nHandle=[d]\nOffset=[D]\nTimeOut=[D]\nWMode=[w]\nCountLeft=[d]\nRes=[w]\nDataSize=[d]\nDataOff=[d]\n", + { "Com2=[w]\nOff2=[u]\nHandle=[u]\nOffset=[D]\nTimeOut=[D]\nWMode=[w]\nCountLeft=[u]\nRes=[w]\nDataSize=[u]\nDataOff=[u]\n", NULL, - "Com2=[w]\nOff2=[d]\nCount=[d]\nRemaining=[d]\nRes=[W]\n", + "Com2=[w]\nOff2=[u]\nCount=[u]\nRemaining=[u]\nRes=[W]\n", NULL, NULL } }, { SMBffirst, "SMBffirst", 0, - { "Count=[d]\nAttrib=[A]\n", - "Path=[Z]\nBlkType=[B]\nBlkLen=[d]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\n", - "Count=[d]\n", - "BlkType=[B]\nBlkLen=[d]\n*\nRes1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\nAttrib=[a]\nTime=[T1]Size=[D]\nName=[s13]\n", + { "Count=[u]\nAttrib=[A]\n", + "Path=[Z]\nBlkType=[B]\nBlkLen=[u]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[u]\nSrv2=[w]\n", + "Count=[u]\n", + "BlkType=[B]\nBlkLen=[u]\n*\nRes1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[u]\nSrv2=[w]\nRes2=[W]\nAttrib=[a]\nTime=[T1]Size=[U]\nName=[s13]\n", NULL } }, { SMBfunique, "SMBfunique", 0, - { "Count=[d]\nAttrib=[A]\n", - "Path=[Z]\nBlkType=[B]\nBlkLen=[d]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\n", - "Count=[d]\n", - "BlkType=[B]\nBlkLen=[d]\n*\nRes1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\nAttrib=[a]\nTime=[T1]Size=[D]\nName=[s13]\n", + { "Count=[u]\nAttrib=[A]\n", + "Path=[Z]\nBlkType=[B]\nBlkLen=[u]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[u]\nSrv2=[w]\n", + "Count=[u]\n", + "BlkType=[B]\nBlkLen=[u]\n*\nRes1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[u]\nSrv2=[w]\nRes2=[W]\nAttrib=[a]\nTime=[T1]Size=[U]\nName=[s13]\n", NULL } }, { SMBfclose, "SMBfclose", 0, - { "Count=[d]\nAttrib=[A]\n", - "Path=[Z]\nBlkType=[B]\nBlkLen=[d]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\n", - "Count=[d]\n", - "BlkType=[B]\nBlkLen=[d]\n*\nRes1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\nAttrib=[a]\nTime=[T1]Size=[D]\nName=[s13]\n", + { "Count=[u]\nAttrib=[A]\n", + "Path=[Z]\nBlkType=[B]\nBlkLen=[u]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[u]\nSrv2=[w]\n", + "Count=[u]\n", + "BlkType=[B]\nBlkLen=[u]\n*\nRes1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[u]\nSrv2=[w]\nRes2=[W]\nAttrib=[a]\nTime=[T1]Size=[U]\nName=[s13]\n", NULL } }, { SMBfindnclose, "SMBfindnclose", 0, - { "Handle=[d]\n", NULL, NULL, NULL, NULL } }, + { "Handle=[u]\n", NULL, NULL, NULL, NULL } }, { SMBfindclose, "SMBfindclose", 0, - { "Handle=[d]\n", NULL, NULL, NULL, NULL } }, + { "Handle=[u]\n", NULL, NULL, NULL, NULL } }, { SMBsends, "SMBsends", 0, { NULL, "Source=[Z]\nDest=[Z]\n", NULL, NULL, NULL } }, { SMBsendstrt, "SMBsendstrt", 0, - { NULL, "Source=[Z]\nDest=[Z]\n", "GroupID=[d]\n", NULL, NULL } }, + { NULL, "Source=[Z]\nDest=[Z]\n", "GroupID=[u]\n", NULL, NULL } }, { SMBsendend, "SMBsendend", 0, - { "GroupID=[d]\n", NULL, NULL, NULL, NULL } }, + { "GroupID=[u]\n", NULL, NULL, NULL, NULL } }, { SMBsendtxt, "SMBsendtxt", 0, - { "GroupID=[d]\n", NULL, NULL, NULL, NULL } }, + { "GroupID=[u]\n", NULL, NULL, NULL, NULL } }, { SMBsendb, "SMBsendb", 0, { NULL, "Source=[Z]\nDest=[Z]\n", NULL, NULL, NULL } }, @@ -764,8 +744,8 @@ static const struct smbfns smb_fns[] = { { NULL, NULL, NULL, NULL, print_sesssetup } }, { SMBtconX, "SMBtconX", FLG_CHAIN, - { "Com2=[w]\nOff2=[d]\nFlags=[w]\nPassLen=[d]\nPasswd&Path&Device=\n", - NULL, "Com2=[w]\nOff2=[d]\n", "ServiceType=[R]\n", NULL } }, + { "Com2=[w]\nOff2=[u]\nFlags=[w]\nPassLen=[u]\nPasswd&Path&Device=\n", + NULL, "Com2=[w]\nOff2=[u]\n", "ServiceType=[R]\n", NULL } }, { SMBlockingX, "SMBlockingX", FLG_CHAIN, { NULL, NULL, NULL, NULL, print_lockingandx } }, @@ -781,9 +761,9 @@ static const struct smbfns smb_fns[] = { { SMBnttranss, "SMBnttranss", 0, DEFDESCRIPT }, { SMBntcreateX, "SMBntcreateX", FLG_CHAIN, - { "Com2=[w]\nOff2=[d]\nRes=[b]\nNameLen=[ld]\nFlags=[W]\nRootDirectoryFid=[D]\nAccessMask=[W]\nAllocationSize=[L]\nExtFileAttributes=[W]\nShareAccess=[W]\nCreateDisposition=[W]\nCreateOptions=[W]\nImpersonationLevel=[W]\nSecurityFlags=[b]\n", + { "Com2=[w]\nOff2=[u]\nRes=[b]\nNameLen=[lu]\nFlags=[W]\nRootDirectoryFid=[U]\nAccessMask=[W]\nAllocationSize=[L]\nExtFileAttributes=[W]\nShareAccess=[W]\nCreateDisposition=[W]\nCreateOptions=[W]\nImpersonationLevel=[W]\nSecurityFlags=[b]\n", "Path=[C]\n", - "Com2=[w]\nOff2=[d]\nOplockLevel=[b]\nFid=[d]\nCreateAction=[W]\nCreateTime=[T3]LastAccessTime=[T3]LastWriteTime=[T3]ChangeTime=[T3]ExtFileAttributes=[W]\nAllocationSize=[L]\nEndOfFile=[L]\nFileType=[w]\nDeviceState=[w]\nDirectory=[b]\n", + "Com2=[w]\nOff2=[u]\nOplockLevel=[b]\nFid=[u]\nCreateAction=[W]\nCreateTime=[T3]LastAccessTime=[T3]LastWriteTime=[T3]ChangeTime=[T3]ExtFileAttributes=[W]\nAllocationSize=[L]\nEndOfFile=[L]\nFileType=[w]\nDeviceState=[w]\nDirectory=[b]\n", NULL, NULL } }, { SMBntcancel, "SMBntcancel", 0, DEFDESCRIPT }, @@ -800,33 +780,34 @@ print_smb(netdissect_options *ndo, const u_char *buf, const u_char *maxbuf) { uint16_t flags2; - int nterrcodes; - int command; + u_int nterrcodes; + u_int command; uint32_t nterror; const u_char *words, *maxwords, *data; const struct smbfns *fn; const char *fmt_smbheader = - "[P4]SMB Command = [B]\nError class = [BP1]\nError code = [d]\nFlags1 = [B]\nFlags2 = [B][P13]\nTree ID = [d]\nProc ID = [d]\nUID = [d]\nMID = [d]\nWord Count = [b]\n"; - int smboffset; + "[P4]SMB Command = [B]\nError class = [BP1]\nError code = [u]\nFlags1 = [B]\nFlags2 = [B][P13]\nTree ID = [u]\nProc ID = [u]\nUID = [u]\nMID = [u]\nWord Count = [b]\n"; + u_int smboffset; + + ndo->ndo_protocol = "smb"; - ND_TCHECK(buf[9]); - request = (buf[9] & 0x80) ? 0 : 1; + request = (GET_U_1(buf + 9) & 0x80) ? 0 : 1; startbuf = buf; - command = buf[4]; + command = GET_U_1(buf + 4); fn = smbfind(command, smb_fns); if (ndo->ndo_vflag > 1) - ND_PRINT((ndo, "\n")); + ND_PRINT("\n"); - ND_PRINT((ndo, "SMB PACKET: %s (%s)\n", fn->name, request ? "REQUEST" : "REPLY")); + ND_PRINT("SMB PACKET: %s (%s)", fn->name, request ? "REQUEST" : "REPLY"); if (ndo->ndo_vflag < 2) return; - ND_TCHECK_16BITS(&buf[10]); - flags2 = EXTRACT_LE_16BITS(&buf[10]); + ND_PRINT("\n"); + flags2 = GET_LE_U_2(buf + 10); unicodestr = flags2 & 0x8000; nterrcodes = flags2 & 0x4000; @@ -834,12 +815,13 @@ print_smb(netdissect_options *ndo, smb_fdata(ndo, buf, fmt_smbheader, buf + 33, unicodestr); if (nterrcodes) { - nterror = EXTRACT_LE_32BITS(&buf[5]); + nterror = GET_LE_U_4(buf + 5); if (nterror) - ND_PRINT((ndo, "NTError = %s\n", nt_errstr(nterror))); + ND_PRINT("NTError = %s\n", nt_errstr(nterror)); } else { - if (buf[5]) - ND_PRINT((ndo, "SMBError = %s\n", smb_errstr(buf[5], EXTRACT_LE_16BITS(&buf[7])))); + if (GET_U_1(buf + 5)) + ND_PRINT("SMBError = %s\n", smb_errstr(GET_U_1(buf + 5), + GET_LE_U_2(buf + 7))); } smboffset = 32; @@ -848,13 +830,12 @@ print_smb(netdissect_options *ndo, const char *f1, *f2; int wct; u_int bcc; - int newsmboffset; + u_int newsmboffset; words = buf + smboffset; - ND_TCHECK(words[0]); - wct = words[0]; + wct = GET_U_1(words); data = words + 1 + wct * 2; - maxwords = min(data, maxbuf); + maxwords = ND_MIN(data, maxbuf); if (request) { f1 = fn->descript.req_f1; @@ -864,6 +845,7 @@ print_smb(netdissect_options *ndo, f2 = fn->descript.rep_f2; } + smb_reset(); if (fn->descript.fn) (*fn->descript.fn)(ndo, words, data, buf, maxbuf); else { @@ -871,27 +853,25 @@ print_smb(netdissect_options *ndo, if (f1) smb_fdata(ndo, words + 1, f1, words + 1 + wct * 2, unicodestr); else { - int i; - int v; + u_int i; + u_int v; - for (i = 0; &words[1 + 2 * i] < maxwords; i++) { - ND_TCHECK2(words[1 + 2 * i], 2); - v = EXTRACT_LE_16BITS(words + 1 + 2 * i); - ND_PRINT((ndo, "smb_vwv[%d]=%d (0x%X)\n", i, v, v)); + for (i = 0; words + 1 + 2 * i < maxwords; i++) { + v = GET_LE_U_2(words + 1 + 2 * i); + ND_PRINT("smb_vwv[%u]=%u (0x%X)\n", i, v, v); } } } - ND_TCHECK2(*data, 2); - bcc = EXTRACT_LE_16BITS(data); - ND_PRINT((ndo, "smb_bcc=%u\n", bcc)); + bcc = GET_LE_U_2(data); + ND_PRINT("smb_bcc=%u\n", bcc); if (f2) { if (bcc > 0) smb_fdata(ndo, data + 2, f2, data + 2 + bcc, unicodestr); } else { if (bcc > 0) { - ND_PRINT((ndo, "smb_buf[]=\n")); - smb_print_data(ndo, data + 2, min(bcc, PTR_DIFF(maxbuf, data + 2))); + ND_PRINT("smb_buf[]=\n"); + smb_data_print(ndo, data + 2, ND_MIN(bcc, ND_BYTES_BETWEEN(maxbuf, data + 2))); } } } @@ -900,28 +880,21 @@ print_smb(netdissect_options *ndo, break; if (wct == 0) break; - ND_TCHECK(words[1]); - command = words[1]; + command = GET_U_1(words + 1); if (command == 0xFF) break; - ND_TCHECK2(words[3], 2); - newsmboffset = EXTRACT_LE_16BITS(words + 3); + newsmboffset = GET_LE_U_2(words + 3); fn = smbfind(command, smb_fns); - ND_PRINT((ndo, "\nSMB PACKET: %s (%s) (CHAINED)\n", - fn->name, request ? "REQUEST" : "REPLY")); + ND_PRINT("\nSMB PACKET: %s (%s) (CHAINED)\n", + fn->name, request ? "REQUEST" : "REPLY"); if (newsmboffset <= smboffset) { - ND_PRINT((ndo, "Bad andX offset: %u <= %u\n", newsmboffset, smboffset)); + ND_PRINT("Bad andX offset: %u <= %u\n", newsmboffset, smboffset); break; } smboffset = newsmboffset; } - - ND_PRINT((ndo, "\n")); - return; -trunc: - ND_PRINT((ndo, "%s", tstr)); } @@ -930,48 +903,47 @@ trunc: */ void nbt_tcp_print(netdissect_options *ndo, - const u_char *data, int length) + const u_char *data, u_int length) { - int caplen; - int type; + u_int caplen; + u_int type; u_int nbt_len; const u_char *maxbuf; + ndo->ndo_protocol = "nbt_tcp"; if (length < 4) goto trunc; if (ndo->ndo_snapend < data) goto trunc; - caplen = ndo->ndo_snapend - data; + caplen = ND_BYTES_AVAILABLE_AFTER(data); if (caplen < 4) goto trunc; maxbuf = data + caplen; - ND_TCHECK_8BITS(data); - type = data[0]; - ND_TCHECK_16BITS(data + 2); - nbt_len = EXTRACT_16BITS(data + 2); + type = GET_U_1(data); + nbt_len = GET_BE_U_2(data + 2); length -= 4; caplen -= 4; startbuf = data; if (ndo->ndo_vflag < 2) { - ND_PRINT((ndo, " NBT Session Packet: ")); + ND_PRINT(" NBT Session Packet: "); switch (type) { case 0x00: - ND_PRINT((ndo, "Session Message")); + ND_PRINT("Session Message"); break; case 0x81: - ND_PRINT((ndo, "Session Request")); + ND_PRINT("Session Request"); break; case 0x82: - ND_PRINT((ndo, "Session Granted")); + ND_PRINT("Session Granted"); break; case 0x83: { - int ecode; + u_int ecode; if (nbt_len < 4) goto trunc; @@ -979,31 +951,31 @@ nbt_tcp_print(netdissect_options *ndo, goto trunc; if (caplen < 4) goto trunc; - ecode = data[4]; + ecode = GET_U_1(data + 4); - ND_PRINT((ndo, "Session Reject, ")); + ND_PRINT("Session Reject, "); switch (ecode) { case 0x80: - ND_PRINT((ndo, "Not listening on called name")); + ND_PRINT("Not listening on called name"); break; case 0x81: - ND_PRINT((ndo, "Not listening for calling name")); + ND_PRINT("Not listening for calling name"); break; case 0x82: - ND_PRINT((ndo, "Called name not present")); + ND_PRINT("Called name not present"); break; case 0x83: - ND_PRINT((ndo, "Called name present, but insufficient resources")); + ND_PRINT("Called name present, but insufficient resources"); break; default: - ND_PRINT((ndo, "Unspecified error 0x%X", ecode)); + ND_PRINT("Unspecified error 0x%X", ecode); break; } } break; case 0x85: - ND_PRINT((ndo, "Session Keepalive")); + ND_PRINT("Session Keepalive"); break; default: @@ -1011,63 +983,63 @@ nbt_tcp_print(netdissect_options *ndo, break; } } else { - ND_PRINT((ndo, "\n>>> NBT Session Packet\n")); + ND_PRINT("\n>>> NBT Session Packet\n"); switch (type) { case 0x00: - data = smb_fdata(ndo, data, "[P1]NBT Session Message\nFlags=[B]\nLength=[rd]\n", + data = smb_fdata(ndo, data, "[P1]NBT Session Message\nFlags=[B]\nLength=[ru]\n", data + 4, 0); if (data == NULL) break; if (nbt_len >= 4 && caplen >= 4 && memcmp(data,"\377SMB",4) == 0) { - if ((int)nbt_len > caplen) { - if ((int)nbt_len > length) - ND_PRINT((ndo, "WARNING: Packet is continued in later TCP segments\n")); + if (nbt_len > caplen) { + if (nbt_len > length) + ND_PRINT("WARNING: Packet is continued in later TCP segments\n"); else - ND_PRINT((ndo, "WARNING: Short packet. Try increasing the snap length by %d\n", - nbt_len - caplen)); + ND_PRINT("WARNING: Short packet. Try increasing the snap length by %u\n", + nbt_len - caplen); } print_smb(ndo, data, maxbuf > data + nbt_len ? data + nbt_len : maxbuf); } else - ND_PRINT((ndo, "Session packet:(raw data or continuation?)\n")); + ND_PRINT("Session packet:(raw data or continuation?)\n"); break; case 0x81: data = smb_fdata(ndo, data, - "[P1]NBT Session Request\nFlags=[B]\nLength=[rd]\nDestination=[n1]\nSource=[n1]\n", + "[P1]NBT Session Request\nFlags=[B]\nLength=[ru]\nDestination=[n1]\nSource=[n1]\n", maxbuf, 0); break; case 0x82: - data = smb_fdata(ndo, data, "[P1]NBT Session Granted\nFlags=[B]\nLength=[rd]\n", maxbuf, 0); + data = smb_fdata(ndo, data, "[P1]NBT Session Granted\nFlags=[B]\nLength=[ru]\n", maxbuf, 0); break; case 0x83: { const u_char *origdata; - int ecode; + u_int ecode; origdata = data; - data = smb_fdata(ndo, data, "[P1]NBT SessionReject\nFlags=[B]\nLength=[rd]\nReason=[B]\n", + data = smb_fdata(ndo, data, "[P1]NBT SessionReject\nFlags=[B]\nLength=[ru]\nReason=[B]\n", maxbuf, 0); if (data == NULL) break; if (nbt_len >= 1 && caplen >= 1) { - ecode = origdata[4]; + ecode = GET_U_1(origdata + 4); switch (ecode) { case 0x80: - ND_PRINT((ndo, "Not listening on called name\n")); + ND_PRINT("Not listening on called name\n"); break; case 0x81: - ND_PRINT((ndo, "Not listening for calling name\n")); + ND_PRINT("Not listening for calling name\n"); break; case 0x82: - ND_PRINT((ndo, "Called name not present\n")); + ND_PRINT("Called name not present\n"); break; case 0x83: - ND_PRINT((ndo, "Called name present, but insufficient resources\n")); + ND_PRINT("Called name present, but insufficient resources\n"); break; default: - ND_PRINT((ndo, "Unspecified error 0x%X\n", ecode)); + ND_PRINT("Unspecified error 0x%X\n", ecode); break; } } @@ -1075,18 +1047,17 @@ nbt_tcp_print(netdissect_options *ndo, break; case 0x85: - data = smb_fdata(ndo, data, "[P1]NBT Session Keepalive\nFlags=[B]\nLength=[rd]\n", maxbuf, 0); + data = smb_fdata(ndo, data, "[P1]NBT Session Keepalive\nFlags=[B]\nLength=[ru]\n", maxbuf, 0); break; default: data = smb_fdata(ndo, data, "NBT - Unknown packet type\nType=[B]\n", maxbuf, 0); break; } - ND_PRINT((ndo, "\n")); } return; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); } static const struct tok opcode_str[] = { @@ -1105,57 +1076,57 @@ static const struct tok opcode_str[] = { */ void nbt_udp137_print(netdissect_options *ndo, - const u_char *data, int length) + const u_char *data, u_int length) { const u_char *maxbuf = data + length; - int name_trn_id, response, opcode, nm_flags, rcode; - int qdcount, ancount, nscount, arcount; + u_int name_trn_id, response, opcode, nm_flags, rcode; + u_int qdcount, ancount, nscount, arcount; const u_char *p; - int total, i; - - ND_TCHECK2(data[10], 2); - name_trn_id = EXTRACT_16BITS(data); - response = (data[2] >> 7); - opcode = (data[2] >> 3) & 0xF; - nm_flags = ((data[2] & 0x7) << 4) + (data[3] >> 4); - rcode = data[3] & 0xF; - qdcount = EXTRACT_16BITS(data + 4); - ancount = EXTRACT_16BITS(data + 6); - nscount = EXTRACT_16BITS(data + 8); - arcount = EXTRACT_16BITS(data + 10); + u_int total, i; + + ndo->ndo_protocol = "nbt_udp137"; + name_trn_id = GET_BE_U_2(data); + response = (GET_U_1(data + 2) >> 7); + opcode = (GET_U_1(data + 2) >> 3) & 0xF; + nm_flags = ((GET_U_1(data + 2) & 0x7) << 4) + (GET_U_1(data + 3) >> 4); + rcode = GET_U_1(data + 3) & 0xF; + qdcount = GET_BE_U_2(data + 4); + ancount = GET_BE_U_2(data + 6); + nscount = GET_BE_U_2(data + 8); + arcount = GET_BE_U_2(data + 10); startbuf = data; if (maxbuf <= data) return; if (ndo->ndo_vflag > 1) - ND_PRINT((ndo, "\n>>> ")); + ND_PRINT("\n>>> "); - ND_PRINT((ndo, "NBT UDP PACKET(137): %s", tok2str(opcode_str, "OPUNKNOWN", opcode))); + ND_PRINT("NBT UDP PACKET(137): %s", tok2str(opcode_str, "OPUNKNOWN", opcode)); if (response) { - ND_PRINT((ndo, "; %s", rcode ? "NEGATIVE" : "POSITIVE")); + ND_PRINT("; %s", rcode ? "NEGATIVE" : "POSITIVE"); } - ND_PRINT((ndo, "; %s; %s", response ? "RESPONSE" : "REQUEST", - (nm_flags & 1) ? "BROADCAST" : "UNICAST")); + ND_PRINT("; %s; %s", response ? "RESPONSE" : "REQUEST", + (nm_flags & 1) ? "BROADCAST" : "UNICAST"); if (ndo->ndo_vflag < 2) return; - ND_PRINT((ndo, "\nTrnID=0x%X\nOpCode=%d\nNmFlags=0x%X\nRcode=%d\nQueryCount=%d\nAnswerCount=%d\nAuthorityCount=%d\nAddressRecCount=%d\n", + ND_PRINT("\nTrnID=0x%X\nOpCode=%u\nNmFlags=0x%X\nRcode=%u\nQueryCount=%u\nAnswerCount=%u\nAuthorityCount=%u\nAddressRecCount=%u\n", name_trn_id, opcode, nm_flags, rcode, qdcount, ancount, nscount, - arcount)); + arcount); p = data + 12; total = ancount + nscount + arcount; if (qdcount > 100 || total > 100) { - ND_PRINT((ndo, "Corrupt packet??\n")); + ND_PRINT("Corrupt packet??\n"); return; } if (qdcount) { - ND_PRINT((ndo, "QuestionRecords:\n")); + ND_PRINT("QuestionRecords:\n"); for (i = 0; i < qdcount; i++) { p = smb_fdata(ndo, p, "|Name=[n1]\nQuestionType=[rw]\nQuestionClass=[rw]\n#", @@ -1166,22 +1137,20 @@ nbt_udp137_print(netdissect_options *ndo, } if (total) { - ND_PRINT((ndo, "\nResourceRecords:\n")); + ND_PRINT("\nResourceRecords:\n"); for (i = 0; i < total; i++) { - int rdlen; - int restype; + u_int rdlen; + u_int restype; p = smb_fdata(ndo, p, "Name=[n1]\n#", maxbuf, 0); if (p == NULL) goto out; - ND_TCHECK_16BITS(p); - restype = EXTRACT_16BITS(p); - p = smb_fdata(ndo, p, "ResType=[rw]\nResClass=[rw]\nTTL=[rD]\n", p + 8, 0); + restype = GET_BE_U_2(p); + p = smb_fdata(ndo, p, "ResType=[rw]\nResClass=[rw]\nTTL=[rU]\n", p + 8, 0); if (p == NULL) goto out; - ND_TCHECK_16BITS(p); - rdlen = EXTRACT_16BITS(p); - ND_PRINT((ndo, "ResourceLength=%d\nResourceData=\n", rdlen)); + rdlen = GET_BE_U_2(p); + ND_PRINT("ResourceLength=%u\nResourceData=\n", rdlen); p += 2; if (rdlen == 6) { p = smb_fdata(ndo, p, "AddrType=[rw]\nAddress=[b.b.b.b]\n", p + rdlen, 0); @@ -1189,39 +1158,43 @@ nbt_udp137_print(netdissect_options *ndo, goto out; } else { if (restype == 0x21) { - int numnames; + u_int numnames; - ND_TCHECK(*p); - numnames = p[0]; + numnames = GET_U_1(p); p = smb_fdata(ndo, p, "NumNames=[B]\n", p + 1, 0); if (p == NULL) goto out; - while (numnames--) { + while (numnames) { p = smb_fdata(ndo, p, "Name=[n2]\t#", maxbuf, 0); if (p == NULL) goto out; - ND_TCHECK(*p); - if (p[0] & 0x80) - ND_PRINT((ndo, " ")); - switch (p[0] & 0x60) { - case 0x00: ND_PRINT((ndo, "B ")); break; - case 0x20: ND_PRINT((ndo, "P ")); break; - case 0x40: ND_PRINT((ndo, "M ")); break; - case 0x60: ND_PRINT((ndo, "_ ")); break; + ND_TCHECK_1(p); + if (p >= maxbuf) + goto out; + if (GET_U_1(p) & 0x80) + ND_PRINT(" "); + switch (GET_U_1(p) & 0x60) { + case 0x00: ND_PRINT("B "); break; + case 0x20: ND_PRINT("P "); break; + case 0x40: ND_PRINT("M "); break; + case 0x60: ND_PRINT("_ "); break; } - if (p[0] & 0x10) - ND_PRINT((ndo, " ")); - if (p[0] & 0x08) - ND_PRINT((ndo, " ")); - if (p[0] & 0x04) - ND_PRINT((ndo, " ")); - if (p[0] & 0x02) - ND_PRINT((ndo, " ")); - ND_PRINT((ndo, "\n")); + if (GET_U_1(p) & 0x10) + ND_PRINT(" "); + if (GET_U_1(p) & 0x08) + ND_PRINT(" "); + if (GET_U_1(p) & 0x04) + ND_PRINT(" "); + if (GET_U_1(p) & 0x02) + ND_PRINT(" "); + ND_PRINT("\n"); p += 2; + numnames--; } } else { - smb_print_data(ndo, p, min(rdlen, length - (p - data))); + if (p >= maxbuf) + goto out; + smb_data_print(ndo, p, ND_MIN(rdlen, length - ND_BYTES_BETWEEN(p, data))); p += rdlen; } } @@ -1232,10 +1205,9 @@ nbt_udp137_print(netdissect_options *ndo, smb_fdata(ndo, p, "AdditionalData:\n", maxbuf, 0); out: - ND_PRINT((ndo, "\n")); return; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); } /* @@ -1243,21 +1215,22 @@ trunc: */ void smb_tcp_print(netdissect_options *ndo, - const u_char * data, int length) + const u_char * data, u_int length) { - int caplen; + u_int caplen; u_int smb_len; const u_char *maxbuf; + ndo->ndo_protocol = "smb_tcp"; if (length < 4) goto trunc; if (ndo->ndo_snapend < data) goto trunc; - caplen = ndo->ndo_snapend - data; + caplen = ND_BYTES_AVAILABLE_AFTER(data); if (caplen < 4) goto trunc; maxbuf = data + caplen; - smb_len = EXTRACT_24BITS(data + 1); + smb_len = GET_BE_U_3(data + 1); length -= 4; caplen -= 4; @@ -1265,20 +1238,20 @@ smb_tcp_print(netdissect_options *ndo, data += 4; if (smb_len >= 4 && caplen >= 4 && memcmp(data,"\377SMB",4) == 0) { - if ((int)smb_len > caplen) { - if ((int)smb_len > length) - ND_PRINT((ndo, " WARNING: Packet is continued in later TCP segments\n")); + if (smb_len > caplen) { + if (smb_len > length) + ND_PRINT(" WARNING: Packet is continued in later TCP segments\n"); else - ND_PRINT((ndo, " WARNING: Short packet. Try increasing the snap length by %d\n", - smb_len - caplen)); + ND_PRINT(" WARNING: Short packet. Try increasing the snap length by %u\n", + smb_len - caplen); } else - ND_PRINT((ndo, " ")); + ND_PRINT(" "); print_smb(ndo, data, maxbuf > data + smb_len ? data + smb_len : maxbuf); } else - ND_PRINT((ndo, " SMB-over-TCP packet:(raw data or continuation?)\n")); + ND_PRINT(" SMB-over-TCP packet:(raw data or continuation?)\n"); return; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); } /* @@ -1286,10 +1259,11 @@ trunc: */ void nbt_udp138_print(netdissect_options *ndo, - const u_char *data, int length) + const u_char *data, u_int length) { const u_char *maxbuf = data + length; + ndo->ndo_protocol = "nbt_udp138"; if (maxbuf > ndo->ndo_snapend) maxbuf = ndo->ndo_snapend; if (maxbuf <= data) @@ -1297,24 +1271,24 @@ nbt_udp138_print(netdissect_options *ndo, startbuf = data; if (ndo->ndo_vflag < 2) { - ND_PRINT((ndo, "NBT UDP PACKET(138)")); + ND_PRINT("NBT UDP PACKET(138)"); return; } data = smb_fdata(ndo, data, - "\n>>> NBT UDP PACKET(138) Res=[rw] ID=[rw] IP=[b.b.b.b] Port=[rd] Length=[rd] Res2=[rw]\nSourceName=[n1]\nDestName=[n1]\n#", + "\n>>> NBT UDP PACKET(138) Res=[rw] ID=[rw] IP=[b.b.b.b] Port=[ru] Length=[ru] Res2=[rw]\nSourceName=[n1]\nDestName=[n1]\n#", maxbuf, 0); if (data != NULL) { /* If there isn't enough data for "\377SMB", don't check for it. */ - if (&data[3] >= maxbuf) + if ((data + 3) >= maxbuf) goto out; if (memcmp(data, "\377SMB",4) == 0) print_smb(ndo, data, maxbuf); } out: - ND_PRINT((ndo, "\n")); + return; } @@ -1378,19 +1352,19 @@ static struct nbf_strings { void netbeui_print(netdissect_options *ndo, - u_short control, const u_char *data, int length) + u_short control, const u_char *data, u_int length) { const u_char *maxbuf = data + length; - int len; - int command; + u_int len; + u_int command; const u_char *data2; int is_truncated = 0; + ndo->ndo_protocol = "netbeui"; if (maxbuf > ndo->ndo_snapend) maxbuf = ndo->ndo_snapend; - ND_TCHECK(data[4]); - len = EXTRACT_LE_16BITS(data); - command = data[4]; + len = GET_LE_U_2(data); + command = GET_U_1(data + 4); data2 = data + len; if (data2 >= maxbuf) { data2 = maxbuf; @@ -1400,11 +1374,11 @@ netbeui_print(netdissect_options *ndo, startbuf = data; if (ndo->ndo_vflag < 2) { - ND_PRINT((ndo, "NBF Packet: ")); + ND_PRINT("NBF Packet: "); data = smb_fdata(ndo, data, "[P5]#", maxbuf, 0); } else { - ND_PRINT((ndo, "\n>>> NBF Packet\nType=0x%X ", control)); - data = smb_fdata(ndo, data, "Length=[d] Signature=[w] Command=[B]\n#", maxbuf, 0); + ND_PRINT("\n>>> NBF Packet\nType=0x%X ", control); + data = smb_fdata(ndo, data, "Length=[u] Signature=[w] Command=[B]\n#", maxbuf, 0); } if (data == NULL) goto out; @@ -1416,15 +1390,15 @@ netbeui_print(netdissect_options *ndo, data = smb_fdata(ndo, data, "Unknown NBF Command\n", data2, 0); } else { if (ndo->ndo_vflag < 2) { - ND_PRINT((ndo, "%s", nbf_strings[command].name)); + ND_PRINT("%s", nbf_strings[command].name); if (nbf_strings[command].nonverbose != NULL) data = smb_fdata(ndo, data, nbf_strings[command].nonverbose, data2, 0); } else { - ND_PRINT((ndo, "%s:\n", nbf_strings[command].name)); + ND_PRINT("%s:\n", nbf_strings[command].name); if (nbf_strings[command].verbose != NULL) data = smb_fdata(ndo, data, nbf_strings[command].verbose, data2, 0); else - ND_PRINT((ndo, "\n")); + ND_PRINT("\n"); } } @@ -1445,29 +1419,26 @@ netbeui_print(netdissect_options *ndo, goto out; /* If there isn't enough data for "\377SMB", don't look for it. */ - if (&data2[3] >= maxbuf) + if ((data2 + 3) >= maxbuf) goto out; if (memcmp(data2, "\377SMB",4) == 0) print_smb(ndo, data2, maxbuf); else { - int i; + u_int i; for (i = 0; i < 128; i++) { - if (&data2[i + 3] >= maxbuf) + if ((data2 + i + 3) >= maxbuf) break; - if (memcmp(&data2[i], "\377SMB", 4) == 0) { - ND_PRINT((ndo, "found SMB packet at %d\n", i)); - print_smb(ndo, &data2[i], maxbuf); + if (memcmp(data2 + i, "\377SMB", 4) == 0) { + ND_PRINT("found SMB packet at %u\n", i); + print_smb(ndo, data2 + i, maxbuf); break; } } } out: - ND_PRINT((ndo, "\n")); return; -trunc: - ND_PRINT((ndo, "%s", tstr)); } @@ -1482,21 +1453,21 @@ ipx_netbios_print(netdissect_options *ndo, * this is a hack till I work out how to parse the rest of the * NetBIOS-over-IPX stuff */ - int i; + u_int i; const u_char *maxbuf; + ndo->ndo_protocol = "ipx_netbios"; maxbuf = data + length; /* Don't go past the end of the captured data in the packet. */ if (maxbuf > ndo->ndo_snapend) maxbuf = ndo->ndo_snapend; startbuf = data; for (i = 0; i < 128; i++) { - if (&data[i + 4] > maxbuf) + if ((data + i + 4) > maxbuf) break; - if (memcmp(&data[i], "\377SMB", 4) == 0) { - smb_fdata(ndo, data, "\n>>> IPX transport ", &data[i], 0); - print_smb(ndo, &data[i], maxbuf); - ND_PRINT((ndo, "\n")); + if (memcmp(data + i, "\377SMB", 4) == 0) { + smb_fdata(ndo, data, "\n>>> IPX transport ", data + i, 0); + print_smb(ndo, data + i, maxbuf); break; } } diff --git a/contrib/tcpdump/print-smtp.c b/contrib/tcpdump/print-smtp.c index 0cdcf1d92c..4acf87c962 100644 --- a/contrib/tcpdump/print-smtp.c +++ b/contrib/tcpdump/print-smtp.c @@ -14,19 +14,16 @@ /* \summary: Simple Mail Transfer Protocol (SMTP) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include - -#include -#include +#include "netdissect-stdinc.h" #include "netdissect.h" -#include "extract.h" void smtp_print(netdissect_options *ndo, const u_char *pptr, u_int len) { - txtproto_print(ndo, pptr, len, "smtp", NULL, 0); + ndo->ndo_protocol = "smtp"; + txtproto_print(ndo, pptr, len, NULL, 0); } diff --git a/contrib/tcpdump/print-snmp.c b/contrib/tcpdump/print-snmp.c index 1b096dcfe5..a38fee2e4f 100644 --- a/contrib/tcpdump/print-snmp.c +++ b/contrib/tcpdump/print-snmp.c @@ -59,10 +59,10 @@ /* \summary: Simple Network Management Protocol (SNMP) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include #include @@ -71,11 +71,13 @@ #include #endif +#include "netdissect-ctype.h" + #include "netdissect.h" +#include "extract.h" #undef OPAQUE /* defined in */ -static const char tstr[] = "[|snmp]"; /* * Universal ASN.1 types @@ -331,10 +333,10 @@ static const struct obj_abrev { } while ((objp = objp->next) != NULL); \ } \ if (objp) { \ - ND_PRINT((ndo, suppressdot?"%s":".%s", objp->desc)); \ + ND_PRINT(suppressdot?"%s":".%s", objp->desc); \ objp = objp->child; \ } else \ - ND_PRINT((ndo, suppressdot?"%u":".%u", (o))); \ + ND_PRINT(suppressdot?"%u":".%u", (o)); \ } /* @@ -417,18 +419,17 @@ static const char *SnmpVersion[] = { */ static int asn1_parse(netdissect_options *ndo, - register const u_char *p, u_int len, struct be *elem) + const u_char *p, u_int len, struct be *elem) { u_char form, class, id; - int i, hdr; + u_int i, hdr; elem->asnlen = 0; elem->type = BE_ANY; if (len < 1) { - ND_PRINT((ndo, "[nothing to parse]")); + ND_PRINT("[nothing to parse]"); return -1; } - ND_TCHECK(*p); /* * it would be nice to use a bit field, but you can't depend on them. @@ -437,14 +438,14 @@ asn1_parse(netdissect_options *ndo, * +---+---+---+---+---+---+---+---+ * 7 6 5 4 3 2 1 0 */ - id = *p & ASN_ID_BITS; /* lower 5 bits, range 00-1f */ + id = GET_U_1(p) & ASN_ID_BITS; /* lower 5 bits, range 00-1f */ #ifdef notdef - form = (*p & 0xe0) >> 5; /* move upper 3 bits to lower 3 */ + form = (GET_U_1(p) & 0xe0) >> 5; /* move upper 3 bits to lower 3 */ class = form >> 1; /* bits 7&6 -> bits 1&0, range 0-3 */ form &= 0x1; /* bit 5 -> bit 0, range 0-1 */ #else - form = (u_char)(*p & ASN_FORM_BITS) >> ASN_FORM_SHIFT; - class = (u_char)(*p & ASN_CLASS_BITS) >> ASN_CLASS_SHIFT; + form = (u_char)(GET_U_1(p) & ASN_FORM_BITS) >> ASN_FORM_SHIFT; + class = (u_char)(GET_U_1(p) & ASN_CLASS_BITS) >> ASN_CLASS_SHIFT; #endif elem->form = form; elem->class = class; @@ -463,63 +464,61 @@ asn1_parse(netdissect_options *ndo, * that won't fit in 32 bits. */ id = 0; - ND_TCHECK(*p); - while (*p & ASN_BIT8) { + while (GET_U_1(p) & ASN_BIT8) { if (len < 1) { - ND_PRINT((ndo, "[Xtagfield?]")); + ND_PRINT("[Xtagfield?]"); return -1; } - id = (id << 7) | (*p & ~ASN_BIT8); + id = (id << 7) | (GET_U_1(p) & ~ASN_BIT8); len--; hdr++; p++; - ND_TCHECK(*p); } if (len < 1) { - ND_PRINT((ndo, "[Xtagfield?]")); + ND_PRINT("[Xtagfield?]"); return -1; } - ND_TCHECK(*p); - elem->id = id = (id << 7) | *p; + elem->id = id = (id << 7) | GET_U_1(p); --len; ++hdr; ++p; } if (len < 1) { - ND_PRINT((ndo, "[no asnlen]")); + ND_PRINT("[no asnlen]"); return -1; } - ND_TCHECK(*p); - elem->asnlen = *p; + elem->asnlen = GET_U_1(p); p++; len--; hdr++; if (elem->asnlen & ASN_BIT8) { uint32_t noct = elem->asnlen % ASN_BIT8; elem->asnlen = 0; if (len < noct) { - ND_PRINT((ndo, "[asnlen? %d<%d]", len, noct)); + ND_PRINT("[asnlen? %d<%d]", len, noct); return -1; } - ND_TCHECK2(*p, noct); - for (; noct-- > 0; len--, hdr++) - elem->asnlen = (elem->asnlen << ASN_SHIFT8) | *p++; + ND_TCHECK_LEN(p, noct); + for (; noct != 0; len--, hdr++, noct--) { + elem->asnlen = (elem->asnlen << ASN_SHIFT8) | GET_U_1(p); + p++; + } } if (len < elem->asnlen) { - ND_PRINT((ndo, "[len%dasnlen)); + ND_PRINT("[len%dasnlen); return -1; } if (form >= sizeof(Form)/sizeof(Form[0])) { - ND_PRINT((ndo, "[form?%d]", form)); + ND_PRINT("[form?%d]", form); return -1; } if (class >= sizeof(Class)/sizeof(Class[0])) { - ND_PRINT((ndo, "[class?%c/%d]", *Form[form], class)); + ND_PRINT("[class?%c/%d]", *Form[form], class); return -1; } if ((int)id >= Class[class].numIDs) { - ND_PRINT((ndo, "[id?%c/%s/%d]", *Form[form], Class[class].name, id)); + ND_PRINT("[id?%c/%s/%d]", *Form[form], Class[class].name, id); return -1; } - ND_TCHECK2(*p, elem->asnlen); + ND_TCHECK_LEN(p, elem->asnlen); switch (form) { case PRIMITIVE: @@ -532,18 +531,18 @@ asn1_parse(netdissect_options *ndo, break; case INTEGER: { - register int32_t data; + int32_t data; elem->type = BE_INT; data = 0; if (elem->asnlen == 0) { - ND_PRINT((ndo, "[asnlen=0]")); + ND_PRINT("[asnlen=0]"); return -1; } - if (*p & ASN_BIT8) /* negative */ + if (GET_U_1(p) & ASN_BIT8) /* negative */ data = -1; - for (i = elem->asnlen; i-- > 0; p++) - data = (data << ASN_SHIFT8) | *p; + for (i = elem->asnlen; i != 0; p++, i--) + data = (data << ASN_SHIFT8) | GET_U_1(p); elem->data.integer = data; break; } @@ -561,7 +560,7 @@ asn1_parse(netdissect_options *ndo, default: elem->type = BE_OCTET; elem->data.raw = (const uint8_t *)p; - ND_PRINT((ndo, "[P/U/%s]", Class[class].Id[id])); + ND_PRINT("[P/U/%s]", Class[class].Id[id]); break; } break; @@ -576,21 +575,21 @@ asn1_parse(netdissect_options *ndo, case COUNTER: case GAUGE: case TIMETICKS: { - register uint32_t data; + uint32_t data; elem->type = BE_UNS; data = 0; - for (i = elem->asnlen; i-- > 0; p++) - data = (data << 8) + *p; + for (i = elem->asnlen; i != 0; p++, i--) + data = (data << 8) + GET_U_1(p); elem->data.uns = data; break; } case COUNTER64: { - register uint64_t data64; + uint64_t data64; elem->type = BE_UNS64; data64 = 0; - for (i = elem->asnlen; i-- > 0; p++) - data64 = (data64 << 8) + *p; + for (i = elem->asnlen; i != 0; p++, i--) + data64 = (data64 << 8) + GET_U_1(p); elem->data.uns64 = data64; break; } @@ -598,8 +597,8 @@ asn1_parse(netdissect_options *ndo, default: elem->type = BE_OCTET; elem->data.raw = (const uint8_t *)p; - ND_PRINT((ndo, "[P/A/%s]", - Class[class].Id[id])); + ND_PRINT("[P/A/%s]", + Class[class].Id[id]); break; } break; @@ -624,7 +623,7 @@ asn1_parse(netdissect_options *ndo, break; default: - ND_PRINT((ndo, "[P/%s/%s]", Class[class].name, Class[class].Id[id])); + ND_PRINT("[P/%s/%s]", Class[class].name, Class[class].Id[id]); elem->type = BE_OCTET; elem->data.raw = (const uint8_t *)p; break; @@ -643,7 +642,7 @@ asn1_parse(netdissect_options *ndo, default: elem->type = BE_OCTET; elem->data.raw = (const uint8_t *)p; - ND_PRINT((ndo, "C/U/%s", Class[class].Id[id])); + ND_PRINT("C/U/%s", Class[class].Id[id]); break; } break; @@ -656,7 +655,7 @@ asn1_parse(netdissect_options *ndo, default: elem->type = BE_OCTET; elem->data.raw = (const uint8_t *)p; - ND_PRINT((ndo, "C/%s/%s", Class[class].name, Class[class].Id[id])); + ND_PRINT("C/%s/%s", Class[class].name, Class[class].Id[id]); break; } break; @@ -666,7 +665,7 @@ asn1_parse(netdissect_options *ndo, return elem->asnlen + hdr; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return -1; } @@ -677,46 +676,46 @@ asn1_print_octets(netdissect_options *ndo, struct be *elem) uint32_t asnlen = elem->asnlen; uint32_t i; - ND_TCHECK2(*p, asnlen); - for (i = asnlen; i-- > 0; p++) - ND_PRINT((ndo, "_%.2x", *p)); + ND_TCHECK_LEN(p, asnlen); + for (i = asnlen; i != 0; p++, i--) + ND_PRINT("_%.2x", GET_U_1(p)); return 0; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return -1; } static int asn1_print_string(netdissect_options *ndo, struct be *elem) { - register int printable = 1, first = 1; + int printable = 1, first = 1; const u_char *p; uint32_t asnlen = elem->asnlen; uint32_t i; p = elem->data.str; - ND_TCHECK2(*p, asnlen); - for (i = asnlen; printable && i-- > 0; p++) - printable = ND_ISPRINT(*p); + ND_TCHECK_LEN(p, asnlen); + for (i = asnlen; printable && i != 0; p++, i--) + printable = ND_ASCII_ISPRINT(GET_U_1(p)); p = elem->data.str; if (printable) { - ND_PRINT((ndo, "\"")); - if (fn_printn(ndo, p, asnlen, ndo->ndo_snapend)) { - ND_PRINT((ndo, "\"")); + ND_PRINT("\""); + if (nd_printn(ndo, p, asnlen, ndo->ndo_snapend)) { + ND_PRINT("\""); goto trunc; } - ND_PRINT((ndo, "\"")); + ND_PRINT("\""); } else { - for (i = asnlen; i-- > 0; p++) { - ND_PRINT((ndo, first ? "%.2x" : "_%.2x", *p)); + for (i = asnlen; i != 0; p++, i--) { + ND_PRINT(first ? "%.2x" : "_%.2x", GET_U_1(p)); first = 0; } } return 0; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return -1; } @@ -753,23 +752,22 @@ asn1_print(netdissect_options *ndo, for (; a->node; a++) { if (i < a->oid_len) continue; - if (!ND_TTEST2(*p, a->oid_len)) + if (!ND_TTEST_LEN(p, a->oid_len)) continue; if (memcmp(a->oid, p, a->oid_len) == 0) { objp = a->node->child; i -= a->oid_len; p += a->oid_len; - ND_PRINT((ndo, "%s", a->prefix)); + ND_PRINT("%s", a->prefix); first = 1; break; } } } - for (; i-- > 0; p++) { - ND_TCHECK(*p); - o = (o << ASN_SHIFT7) + (*p & ~ASN_BIT8); - if (*p & ASN_LONGLEN) + for (; i != 0; p++, i--) { + o = (o << ASN_SHIFT7) + (GET_U_1(p) & ~ASN_BIT8); + if (GET_U_1(p) & ASN_LONGLEN) continue; /* @@ -796,15 +794,15 @@ asn1_print(netdissect_options *ndo, } case BE_INT: - ND_PRINT((ndo, "%d", elem->data.integer)); + ND_PRINT("%d", elem->data.integer); break; case BE_UNS: - ND_PRINT((ndo, "%u", elem->data.uns)); + ND_PRINT("%u", elem->data.uns); break; case BE_UNS64: - ND_PRINT((ndo, "%" PRIu64, elem->data.uns64)); + ND_PRINT("%" PRIu64, elem->data.uns64); break; case BE_STR: @@ -813,41 +811,41 @@ asn1_print(netdissect_options *ndo, break; case BE_SEQ: - ND_PRINT((ndo, "Seq(%u)", elem->asnlen)); + ND_PRINT("Seq(%u)", elem->asnlen); break; case BE_INETADDR: if (asnlen != ASNLEN_INETADDR) - ND_PRINT((ndo, "[inetaddr len!=%d]", ASNLEN_INETADDR)); + ND_PRINT("[inetaddr len!=%d]", ASNLEN_INETADDR); p = (const u_char *)elem->data.raw; - ND_TCHECK2(*p, asnlen); - for (i = asnlen; i-- != 0; p++) { - ND_PRINT((ndo, (i == asnlen-1) ? "%u" : ".%u", *p)); + ND_TCHECK_LEN(p, asnlen); + for (i = asnlen; i != 0; p++, i--) { + ND_PRINT((i == asnlen) ? "%u" : ".%u", GET_U_1(p)); } break; case BE_NOSUCHOBJECT: case BE_NOSUCHINST: case BE_ENDOFMIBVIEW: - ND_PRINT((ndo, "[%s]", Class[EXCEPTIONS].Id[elem->id])); + ND_PRINT("[%s]", Class[EXCEPTIONS].Id[elem->id]); break; case BE_PDU: - ND_PRINT((ndo, "%s(%u)", Class[CONTEXT].Id[elem->id], elem->asnlen)); + ND_PRINT("%s(%u)", Class[CONTEXT].Id[elem->id], elem->asnlen); break; case BE_ANY: - ND_PRINT((ndo, "[BE_ANY!?]")); + ND_PRINT("[BE_ANY!?]"); break; default: - ND_PRINT((ndo, "[be!?]")); + ND_PRINT("[be!?]"); break; } return 0; trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return -1; } @@ -870,13 +868,13 @@ asn1_decode(u_char *p, u_int length) while (i >= 0 && length > 0) { i = asn1_parse(ndo, p, length, &elem); if (i >= 0) { - ND_PRINT((ndo, " ")); + ND_PRINT(" "); if (asn1_print(ndo, &elem) < 0) return; if (elem.type == BE_SEQ || elem.type == BE_PDU) { - ND_PRINT((ndo, " {")); + ND_PRINT(" {"); asn1_decode(elem.data.raw, elem.asnlen); - ND_PRINT((ndo, " }")); + ND_PRINT(" }"); } length -= i; p += i; @@ -915,13 +913,13 @@ smi_decode_oid(netdissect_options *ndo, { const u_char *p = (const u_char *)elem->data.raw; uint32_t asnlen = elem->asnlen; - int o = 0, first = -1, i = asnlen; + uint32_t i = asnlen; + int o = 0, first = -1; unsigned int firstval; - for (*oidlen = 0; i-- > 0; p++) { - ND_TCHECK(*p); - o = (o << ASN_SHIFT7) + (*p & ~ASN_BIT8); - if (*p & ASN_LONGLEN) + for (*oidlen = 0; i != 0; p++, i--) { + o = (o << ASN_SHIFT7) + (GET_U_1(p) & ~ASN_BIT8); + if (GET_U_1(p) & ASN_LONGLEN) continue; /* @@ -929,7 +927,7 @@ smi_decode_oid(netdissect_options *ndo, * (see X.690:1997 clause 8.19 for the details) */ if (first < 0) { - first = 0; + first = 0; firstval = o / OIDMUX; if (firstval > 2) firstval = 2; o -= firstval * OIDMUX; @@ -943,10 +941,6 @@ smi_decode_oid(netdissect_options *ndo, o = 0; } return 0; - -trunc: - ND_PRINT((ndo, "%s", tstr)); - return -1; } static int smi_check_type(SmiBasetype basetype, int be) @@ -1061,12 +1055,12 @@ smi_print_variable(netdissect_options *ndo, return NULL; } if (ndo->ndo_vflag) { - ND_PRINT((ndo, "%s::", smiGetNodeModule(smiNode)->name)); + ND_PRINT("%s::", smiGetNodeModule(smiNode)->name); } - ND_PRINT((ndo, "%s", smiNode->name)); + ND_PRINT("%s", smiNode->name); if (smiNode->oidlen < oidlen) { for (i = smiNode->oidlen; i < oidlen; i++) { - ND_PRINT((ndo, ".%u", oid[i])); + ND_PRINT(".%u", oid[i]); } } *status = 0; @@ -1094,20 +1088,20 @@ smi_print_value(netdissect_options *ndo, } if (NOTIFY_CLASS(pduid) && smiNode->access < SMI_ACCESS_NOTIFY) { - ND_PRINT((ndo, "[notNotifyable]")); + ND_PRINT("[notNotifyable]"); } if (READ_CLASS(pduid) && smiNode->access < SMI_ACCESS_READ_ONLY) { - ND_PRINT((ndo, "[notReadable]")); + ND_PRINT("[notReadable]"); } if (WRITE_CLASS(pduid) && smiNode->access < SMI_ACCESS_READ_WRITE) { - ND_PRINT((ndo, "[notWritable]")); + ND_PRINT("[notWritable]"); } if (RESPONSE_CLASS(pduid) && smiNode->access == SMI_ACCESS_NOT_ACCESSIBLE) { - ND_PRINT((ndo, "[noAccess]")); + ND_PRINT("[noAccess]"); } smiType = smiGetNodeType(smiNode); @@ -1116,11 +1110,11 @@ smi_print_value(netdissect_options *ndo, } if (! smi_check_type(smiType->basetype, elem->type)) { - ND_PRINT((ndo, "[wrongType]")); + ND_PRINT("[wrongType]"); } if (! smi_check_range(smiType, elem)) { - ND_PRINT((ndo, "[outOfRange]")); + ND_PRINT("[outOfRange]"); } /* resolve bits to named bits */ @@ -1143,13 +1137,13 @@ smi_print_value(netdissect_options *ndo, smiNode = smiGetNodeByOID(oidlen, oid); if (smiNode) { if (ndo->ndo_vflag) { - ND_PRINT((ndo, "%s::", smiGetNodeModule(smiNode)->name)); + ND_PRINT("%s::", smiGetNodeModule(smiNode)->name); } - ND_PRINT((ndo, "%s", smiNode->name)); + ND_PRINT("%s", smiNode->name); if (smiNode->oidlen < oidlen) { for (i = smiNode->oidlen; i < oidlen; i++) { - ND_PRINT((ndo, ".%u", oid[i])); + ND_PRINT(".%u", oid[i]); } } done++; @@ -1165,8 +1159,8 @@ smi_print_value(netdissect_options *ndo, nn = smiGetNextNamedNumber(nn)) { if (nn->value.value.integer32 == elem->data.integer) { - ND_PRINT((ndo, "%s", nn->name)); - ND_PRINT((ndo, "(%d)", elem->data.integer)); + ND_PRINT("%s", nn->name); + ND_PRINT("(%d)", elem->data.integer); done++; break; } @@ -1233,12 +1227,12 @@ varbind_print(netdissect_options *ndo, if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_SEQ) { - ND_PRINT((ndo, "[!SEQ of varbind]")); + ND_PRINT("[!SEQ of varbind]"); asn1_print(ndo, &elem); return; } if ((u_int)count < length) - ND_PRINT((ndo, "[%d extra after SEQ of varbind]", length - count)); + ND_PRINT("[%d extra after SEQ of varbind]", length - count); /* descend */ length = elem.asnlen; np = (const u_char *)elem.data.raw; @@ -1247,13 +1241,13 @@ varbind_print(netdissect_options *ndo, const u_char *vbend; u_int vblength; - ND_PRINT((ndo, " ")); + ND_PRINT(" "); /* Sequence */ if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_SEQ) { - ND_PRINT((ndo, "[!varbind]")); + ND_PRINT("[!varbind]"); asn1_print(ndo, &elem); return; } @@ -1267,7 +1261,7 @@ varbind_print(netdissect_options *ndo, if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_OID) { - ND_PRINT((ndo, "[objName!=OID]")); + ND_PRINT("[objName!=OID]"); asn1_print(ndo, &elem); return; } @@ -1283,7 +1277,7 @@ varbind_print(netdissect_options *ndo, if (pduid != GETREQ && pduid != GETNEXTREQ && pduid != GETBULKREQ) - ND_PRINT((ndo, "=")); + ND_PRINT("="); /* objVal (ANY) */ if ((count = asn1_parse(ndo, np, length, &elem)) < 0) @@ -1291,7 +1285,7 @@ varbind_print(netdissect_options *ndo, if (pduid == GETREQ || pduid == GETNEXTREQ || pduid == GETBULKREQ) { if (elem.type != BE_NULL) { - ND_PRINT((ndo, "[objVal!=NULL]")); + ND_PRINT("[objVal!=NULL]"); if (asn1_print(ndo, &elem) < 0) return; } @@ -1326,12 +1320,12 @@ snmppdu_print(netdissect_options *ndo, if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_INT) { - ND_PRINT((ndo, "[reqId!=INT]")); + ND_PRINT("[reqId!=INT]"); asn1_print(ndo, &elem); return; } if (ndo->ndo_vflag) - ND_PRINT((ndo, "R=%d ", elem.data.integer)); + ND_PRINT("R=%d ", elem.data.integer); length -= count; np += count; @@ -1339,7 +1333,7 @@ snmppdu_print(netdissect_options *ndo, if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_INT) { - ND_PRINT((ndo, "[errorStatus!=INT]")); + ND_PRINT("[errorStatus!=INT]"); asn1_print(ndo, &elem); return; } @@ -1348,13 +1342,13 @@ snmppdu_print(netdissect_options *ndo, || pduid == INFORMREQ || pduid == V2TRAP || pduid == REPORT) && elem.data.integer != 0) { char errbuf[20]; - ND_PRINT((ndo, "[errorStatus(%s)!=0]", - DECODE_ErrorStatus(elem.data.integer))); + ND_PRINT("[errorStatus(%s)!=0]", + DECODE_ErrorStatus(elem.data.integer)); } else if (pduid == GETBULKREQ) { - ND_PRINT((ndo, " N=%d", elem.data.integer)); + ND_PRINT(" N=%d", elem.data.integer); } else if (elem.data.integer != 0) { char errbuf[20]; - ND_PRINT((ndo, " %s", DECODE_ErrorStatus(elem.data.integer))); + ND_PRINT(" %s", DECODE_ErrorStatus(elem.data.integer)); error_status = elem.data.integer; } length -= count; @@ -1364,29 +1358,28 @@ snmppdu_print(netdissect_options *ndo, if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_INT) { - ND_PRINT((ndo, "[errorIndex!=INT]")); + ND_PRINT("[errorIndex!=INT]"); asn1_print(ndo, &elem); return; } if ((pduid == GETREQ || pduid == GETNEXTREQ || pduid == SETREQ || pduid == INFORMREQ || pduid == V2TRAP || pduid == REPORT) && elem.data.integer != 0) - ND_PRINT((ndo, "[errorIndex(%d)!=0]", elem.data.integer)); + ND_PRINT("[errorIndex(%d)!=0]", elem.data.integer); else if (pduid == GETBULKREQ) - ND_PRINT((ndo, " M=%d", elem.data.integer)); + ND_PRINT(" M=%d", elem.data.integer); else if (elem.data.integer != 0) { if (!error_status) - ND_PRINT((ndo, "[errorIndex(%d) w/o errorStatus]", elem.data.integer)); + ND_PRINT("[errorIndex(%d) w/o errorStatus]", elem.data.integer); else - ND_PRINT((ndo, "@%d", elem.data.integer)); + ND_PRINT("@%d", elem.data.integer); } else if (error_status) { - ND_PRINT((ndo, "[errorIndex==0]")); + ND_PRINT("[errorIndex==0]"); } length -= count; np += count; varbind_print(ndo, pduid, np, length); - return; } /* @@ -1399,13 +1392,13 @@ trappdu_print(netdissect_options *ndo, struct be elem; int count = 0, generic; - ND_PRINT((ndo, " ")); + ND_PRINT(" "); /* enterprise (oid) */ if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_OID) { - ND_PRINT((ndo, "[enterprise!=OID]")); + ND_PRINT("[enterprise!=OID]"); asn1_print(ndo, &elem); return; } @@ -1414,13 +1407,13 @@ trappdu_print(netdissect_options *ndo, length -= count; np += count; - ND_PRINT((ndo, " ")); + ND_PRINT(" "); /* agent-addr (inetaddr) */ if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_INETADDR) { - ND_PRINT((ndo, "[agent-addr!=INETADDR]")); + ND_PRINT("[agent-addr!=INETADDR]"); asn1_print(ndo, &elem); return; } @@ -1433,14 +1426,14 @@ trappdu_print(netdissect_options *ndo, if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_INT) { - ND_PRINT((ndo, "[generic-trap!=INT]")); + ND_PRINT("[generic-trap!=INT]"); asn1_print(ndo, &elem); return; } generic = elem.data.integer; { char buf[20]; - ND_PRINT((ndo, " %s", DECODE_GenericTrap(generic))); + ND_PRINT(" %s", DECODE_GenericTrap(generic)); } length -= count; np += count; @@ -1449,25 +1442,25 @@ trappdu_print(netdissect_options *ndo, if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_INT) { - ND_PRINT((ndo, "[specific-trap!=INT]")); + ND_PRINT("[specific-trap!=INT]"); asn1_print(ndo, &elem); return; } if (generic != GT_ENTERPRISE) { if (elem.data.integer != 0) - ND_PRINT((ndo, "[specific-trap(%d)!=0]", elem.data.integer)); + ND_PRINT("[specific-trap(%d)!=0]", elem.data.integer); } else - ND_PRINT((ndo, " s=%d", elem.data.integer)); + ND_PRINT(" s=%d", elem.data.integer); length -= count; np += count; - ND_PRINT((ndo, " ")); + ND_PRINT(" "); /* time-stamp (TimeTicks) */ if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_UNS) { /* XXX */ - ND_PRINT((ndo, "[time-stamp!=TIMETICKS]")); + ND_PRINT("[time-stamp!=TIMETICKS]"); asn1_print(ndo, &elem); return; } @@ -1477,7 +1470,6 @@ trappdu_print(netdissect_options *ndo, np += count; varbind_print(ndo, TRAP, np, length); - return; } /* @@ -1494,17 +1486,17 @@ pdu_print(netdissect_options *ndo, if ((count = asn1_parse(ndo, np, length, &pdu)) < 0) return; if (pdu.type != BE_PDU) { - ND_PRINT((ndo, "[no PDU]")); + ND_PRINT("[no PDU]"); return; } if ((u_int)count < length) - ND_PRINT((ndo, "[%d extra after PDU]", length - count)); + ND_PRINT("[%d extra after PDU]", length - count); if (ndo->ndo_vflag) { - ND_PRINT((ndo, "{ ")); + ND_PRINT("{ "); } if (asn1_print(ndo, &pdu) < 0) return; - ND_PRINT((ndo, " ")); + ND_PRINT(" "); /* descend into PDU */ length = pdu.asnlen; np = (const u_char *)pdu.data.raw; @@ -1512,12 +1504,12 @@ pdu_print(netdissect_options *ndo, if (version == SNMP_VERSION_1 && (pdu.id == GETBULKREQ || pdu.id == INFORMREQ || pdu.id == V2TRAP || pdu.id == REPORT)) { - ND_PRINT((ndo, "[v2 PDU in v1 message]")); + ND_PRINT("[v2 PDU in v1 message]"); return; } if (version == SNMP_VERSION_2 && pdu.id == TRAP) { - ND_PRINT((ndo, "[v1 PDU in v2 message]")); + ND_PRINT("[v1 PDU in v2 message]"); return; } @@ -1538,7 +1530,7 @@ pdu_print(netdissect_options *ndo, } if (ndo->ndo_vflag) { - ND_PRINT((ndo, " } ")); + ND_PRINT(" } "); } } @@ -1556,7 +1548,7 @@ scopedpdu_print(netdissect_options *ndo, if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_SEQ) { - ND_PRINT((ndo, "[!scoped PDU]")); + ND_PRINT("[!scoped PDU]"); asn1_print(ndo, &elem); return; } @@ -1567,33 +1559,33 @@ scopedpdu_print(netdissect_options *ndo, if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_STR) { - ND_PRINT((ndo, "[contextEngineID!=STR]")); + ND_PRINT("[contextEngineID!=STR]"); asn1_print(ndo, &elem); return; } length -= count; np += count; - ND_PRINT((ndo, "E=")); + ND_PRINT("E="); if (asn1_print_octets(ndo, &elem) == -1) return; - ND_PRINT((ndo, " ")); + ND_PRINT(" "); /* contextName (OCTET STRING) */ if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_STR) { - ND_PRINT((ndo, "[contextName!=STR]")); + ND_PRINT("[contextName!=STR]"); asn1_print(ndo, &elem); return; } length -= count; np += count; - ND_PRINT((ndo, "C=")); + ND_PRINT("C="); if (asn1_print_string(ndo, &elem) == -1) return; - ND_PRINT((ndo, " ")); + ND_PRINT(" "); pdu_print(ndo, np, length, version); } @@ -1612,7 +1604,7 @@ community_print(netdissect_options *ndo, if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_STR) { - ND_PRINT((ndo, "[comm!=STR]")); + ND_PRINT("[comm!=STR]"); asn1_print(ndo, &elem); return; } @@ -1621,10 +1613,10 @@ community_print(netdissect_options *ndo, strncmp((const char *)elem.data.str, DEF_COMMUNITY, sizeof(DEF_COMMUNITY) - 1) == 0)) { /* ! "public" */ - ND_PRINT((ndo, "C=")); + ND_PRINT("C="); if (asn1_print_string(ndo, &elem) == -1) return; - ND_PRINT((ndo, " ")); + ND_PRINT(" "); } length -= count; np += count; @@ -1646,7 +1638,7 @@ usm_print(netdissect_options *ndo, if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_SEQ) { - ND_PRINT((ndo, "[!usm]")); + ND_PRINT("[!usm]"); asn1_print(ndo, &elem); return; } @@ -1657,7 +1649,7 @@ usm_print(netdissect_options *ndo, if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_STR) { - ND_PRINT((ndo, "[msgAuthoritativeEngineID!=STR]")); + ND_PRINT("[msgAuthoritativeEngineID!=STR]"); asn1_print(ndo, &elem); return; } @@ -1668,12 +1660,12 @@ usm_print(netdissect_options *ndo, if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_INT) { - ND_PRINT((ndo, "[msgAuthoritativeEngineBoots!=INT]")); + ND_PRINT("[msgAuthoritativeEngineBoots!=INT]"); asn1_print(ndo, &elem); return; } if (ndo->ndo_vflag) - ND_PRINT((ndo, "B=%d ", elem.data.integer)); + ND_PRINT("B=%d ", elem.data.integer); length -= count; np += count; @@ -1681,12 +1673,12 @@ usm_print(netdissect_options *ndo, if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_INT) { - ND_PRINT((ndo, "[msgAuthoritativeEngineTime!=INT]")); + ND_PRINT("[msgAuthoritativeEngineTime!=INT]"); asn1_print(ndo, &elem); return; } if (ndo->ndo_vflag) - ND_PRINT((ndo, "T=%d ", elem.data.integer)); + ND_PRINT("T=%d ", elem.data.integer); length -= count; np += count; @@ -1694,23 +1686,23 @@ usm_print(netdissect_options *ndo, if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_STR) { - ND_PRINT((ndo, "[msgUserName!=STR]")); + ND_PRINT("[msgUserName!=STR]"); asn1_print(ndo, &elem); return; } length -= count; np += count; - ND_PRINT((ndo, "U=")); + ND_PRINT("U="); if (asn1_print_string(ndo, &elem) == -1) return; - ND_PRINT((ndo, " ")); + ND_PRINT(" "); /* msgAuthenticationParameters (OCTET STRING) */ if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_STR) { - ND_PRINT((ndo, "[msgAuthenticationParameters!=STR]")); + ND_PRINT("[msgAuthenticationParameters!=STR]"); asn1_print(ndo, &elem); return; } @@ -1721,7 +1713,7 @@ usm_print(netdissect_options *ndo, if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_STR) { - ND_PRINT((ndo, "[msgPrivacyParameters!=STR]")); + ND_PRINT("[msgPrivacyParameters!=STR]"); asn1_print(ndo, &elem); return; } @@ -1729,7 +1721,7 @@ usm_print(netdissect_options *ndo, np += count; if ((u_int)count < length) - ND_PRINT((ndo, "[%d extra after usm SEQ]", length - count)); + ND_PRINT("[%d extra after usm SEQ]", length - count); } /* @@ -1750,7 +1742,7 @@ v3msg_print(netdissect_options *ndo, if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_SEQ) { - ND_PRINT((ndo, "[!message]")); + ND_PRINT("[!message]"); asn1_print(ndo, &elem); return; } @@ -1758,14 +1750,14 @@ v3msg_print(netdissect_options *ndo, np = (const u_char *)elem.data.raw; if (ndo->ndo_vflag) { - ND_PRINT((ndo, "{ ")); + ND_PRINT("{ "); } /* msgID (INTEGER) */ if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_INT) { - ND_PRINT((ndo, "[msgID!=INT]")); + ND_PRINT("[msgID!=INT]"); asn1_print(ndo, &elem); return; } @@ -1776,7 +1768,7 @@ v3msg_print(netdissect_options *ndo, if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_INT) { - ND_PRINT((ndo, "[msgMaxSize!=INT]")); + ND_PRINT("[msgMaxSize!=INT]"); asn1_print(ndo, &elem); return; } @@ -1787,33 +1779,33 @@ v3msg_print(netdissect_options *ndo, if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_STR) { - ND_PRINT((ndo, "[msgFlags!=STR]")); + ND_PRINT("[msgFlags!=STR]"); asn1_print(ndo, &elem); return; } if (elem.asnlen != 1) { - ND_PRINT((ndo, "[msgFlags size %d]", elem.asnlen)); + ND_PRINT("[msgFlags size %d]", elem.asnlen); return; } - flags = elem.data.str[0]; + flags = GET_U_1(elem.data.str); if (flags != 0x00 && flags != 0x01 && flags != 0x03 && flags != 0x04 && flags != 0x05 && flags != 0x07) { - ND_PRINT((ndo, "[msgFlags=0x%02X]", flags)); + ND_PRINT("[msgFlags=0x%02X]", flags); return; } length -= count; np += count; - ND_PRINT((ndo, "F=%s%s%s ", + ND_PRINT("F=%s%s%s ", flags & 0x01 ? "a" : "", flags & 0x02 ? "p" : "", - flags & 0x04 ? "r" : "")); + flags & 0x04 ? "r" : ""); /* msgSecurityModel (INTEGER) */ if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_INT) { - ND_PRINT((ndo, "[msgSecurityModel!=INT]")); + ND_PRINT("[msgSecurityModel!=INT]"); asn1_print(ndo, &elem); return; } @@ -1822,18 +1814,18 @@ v3msg_print(netdissect_options *ndo, np += count; if ((u_int)count < length) - ND_PRINT((ndo, "[%d extra after message SEQ]", length - count)); + ND_PRINT("[%d extra after message SEQ]", length - count); if (ndo->ndo_vflag) { - ND_PRINT((ndo, "} ")); + ND_PRINT("} "); } if (model == 3) { if (ndo->ndo_vflag) { - ND_PRINT((ndo, "{ USM ")); + ND_PRINT("{ USM "); } } else { - ND_PRINT((ndo, "[security model %d]", model)); + ND_PRINT("[security model %d]", model); return; } @@ -1844,7 +1836,7 @@ v3msg_print(netdissect_options *ndo, if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_STR) { - ND_PRINT((ndo, "[msgSecurityParameters!=STR]")); + ND_PRINT("[msgSecurityParameters!=STR]"); asn1_print(ndo, &elem); return; } @@ -1854,18 +1846,18 @@ v3msg_print(netdissect_options *ndo, if (model == 3) { usm_print(ndo, elem.data.str, elem.asnlen); if (ndo->ndo_vflag) { - ND_PRINT((ndo, "} ")); + ND_PRINT("} "); } } if (ndo->ndo_vflag) { - ND_PRINT((ndo, "{ ScopedPDU ")); + ND_PRINT("{ ScopedPDU "); } scopedpdu_print(ndo, np, length, 3); if (ndo->ndo_vflag) { - ND_PRINT((ndo, "} ")); + ND_PRINT("} "); } } @@ -1880,18 +1872,19 @@ snmp_print(netdissect_options *ndo, int count = 0; int version = 0; - ND_PRINT((ndo, " ")); + ndo->ndo_protocol = "snmp"; + ND_PRINT(" "); /* initial Sequence */ if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_SEQ) { - ND_PRINT((ndo, "[!init SEQ]")); + ND_PRINT("[!init SEQ]"); asn1_print(ndo, &elem); return; } if ((u_int)count < length) - ND_PRINT((ndo, "[%d extra after iSEQ]", length - count)); + ND_PRINT("[%d extra after iSEQ]", length - count); /* descend */ length = elem.asnlen; np = (const u_char *)elem.data.raw; @@ -1900,7 +1893,7 @@ snmp_print(netdissect_options *ndo, if ((count = asn1_parse(ndo, np, length, &elem)) < 0) return; if (elem.type != BE_INT) { - ND_PRINT((ndo, "[version!=INT]")); + ND_PRINT("[version!=INT]"); asn1_print(ndo, &elem); return; } @@ -1910,10 +1903,10 @@ snmp_print(netdissect_options *ndo, case SNMP_VERSION_2: case SNMP_VERSION_3: if (ndo->ndo_vflag) - ND_PRINT((ndo, "{ %s ", SnmpVersion[elem.data.integer])); + ND_PRINT("{ %s ", SnmpVersion[elem.data.integer]); break; default: - ND_PRINT((ndo, "SNMP [version = %d]", elem.data.integer)); + ND_PRINT("SNMP [version = %d]", elem.data.integer); return; } version = elem.data.integer; @@ -1929,11 +1922,11 @@ snmp_print(netdissect_options *ndo, v3msg_print(ndo, np, length); break; default: - ND_PRINT((ndo, "[version = %d]", elem.data.integer)); + ND_PRINT("[version = %d]", elem.data.integer); break; } if (ndo->ndo_vflag) { - ND_PRINT((ndo, "} ")); + ND_PRINT("} "); } } diff --git a/contrib/tcpdump/print-someip.c b/contrib/tcpdump/print-someip.c new file mode 100644 index 0000000000..210e413f64 --- /dev/null +++ b/contrib/tcpdump/print-someip.c @@ -0,0 +1,142 @@ +/* + * 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. + * + * Original code by Francesco Fondelli (francesco dot fondelli, gmail dot com) + */ + +/* \summary: Autosar SOME/IP Protocol printer */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "netdissect-stdinc.h" +#include "netdissect.h" +#include "extract.h" +#include "udp.h" + +/* + * SOMEIP Header (R19-11) + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Message ID (Service ID/Method ID) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Request ID (Client ID/Session ID) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Protocol Ver | Interface Ver | Message Type | Return Code | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Payload | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +static const struct tok message_type_values[] = { + { 0x00, "REQUEST" }, + { 0x01, "REQUEST_NO_RETURN" }, + { 0x02, "NOTIFICATION" }, + { 0x80, "RESPONSE" }, + { 0x81, "ERROR" }, + { 0x20, "TP_REQUEST" }, + { 0x21, "TP_REQUEST_NO_RETURN" }, + { 0x22, "TP_NOTIFICATION" }, + { 0xa0, "TP_RESPONSE" }, + { 0xa1, "TP_ERROR" }, + { 0, NULL } +}; + +static const struct tok return_code_values[] = { + { 0x00, "E_OK" }, + { 0x01, "E_NOT_OK" }, + { 0x02, "E_UNKNOWN_SERVICE" }, + { 0x03, "E_UNKNOWN_METHOD" }, + { 0x04, "E_NOT_READY" }, + { 0x05, "E_NOT_REACHABLE" }, + { 0x06, "E_TIMEOUT" }, + { 0x07, "E_WRONG_PROTOCOL_VERSION" }, + { 0x08, "E_WRONG_INTERFACE_VERSION" }, + { 0x09, "E_MALFORMED_MESSAGE" }, + { 0x0a, "E_WRONG_MESSAGE_TYPE" }, + { 0x0b, "E_E2E_REPEATED" }, + { 0x0c, "E_E2E_WRONG_SEQUENCE" }, + { 0x0d, "E_E2E" }, + { 0x0e, "E_E2E_NOT_AVAILABLE" }, + { 0x0f, "E_E2E_NO_NEW_DATA" }, + { 0, NULL } +}; + +void +someip_print(netdissect_options *ndo, const u_char *bp, const u_int len) +{ + uint32_t message_id; + uint16_t service_id; + uint16_t method_or_event_id; + uint8_t event_flag; + uint32_t message_len; + uint32_t request_id; + uint16_t client_id; + uint16_t session_id; + uint8_t protocol_version; + uint8_t interface_version; + uint8_t message_type; + uint8_t return_code; + + ndo->ndo_protocol = "someip"; + nd_print_protocol_caps(ndo); + + if (len < 16) { + goto invalid; + } + + message_id = GET_BE_U_4(bp); + service_id = message_id >> 16; + event_flag = (message_id & 0x00008000) >> 15; + method_or_event_id = message_id & 0x00007FFF; + bp += 4; + ND_PRINT(", service %u, %s %u", + service_id, event_flag ? "event" : "method", method_or_event_id); + + message_len = GET_BE_U_4(bp); + bp += 4; + ND_PRINT(", len %u", message_len); + + request_id = GET_BE_U_4(bp); + client_id = request_id >> 16; + session_id = request_id & 0x0000FFFF; + bp += 4; + ND_PRINT(", client %u, session %u", client_id, session_id); + + protocol_version = GET_U_1(bp); + bp += 1; + ND_PRINT(", pver %u", protocol_version); + + interface_version = GET_U_1(bp); + bp += 1; + ND_PRINT(", iver %u", interface_version); + + message_type = GET_U_1(bp); + bp += 1; + ND_PRINT(", msgtype %s", + tok2str(message_type_values, "Unknown", message_type)); + + return_code = GET_U_1(bp); + bp += 1; + ND_PRINT(", retcode %s\n", + tok2str(return_code_values, "Unknown", return_code)); + + return; + +invalid: + nd_print_invalid(ndo); +} diff --git a/contrib/tcpdump/print-ssh.c b/contrib/tcpdump/print-ssh.c new file mode 100644 index 0000000000..5207c52ee2 --- /dev/null +++ b/contrib/tcpdump/print-ssh.c @@ -0,0 +1,99 @@ +/* + * 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. + */ + +/* \summary: Secure Shell (SSH) printer */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "netdissect-stdinc.h" +#include "netdissect-ctype.h" + +#include "netdissect.h" +#include "extract.h" + +static int +ssh_print_version(netdissect_options *ndo, const u_char *pptr, u_int len) +{ + u_int idx = 0; + + if ( GET_U_1(pptr+idx) != 'S' ) + return 0; + idx++; + if ( GET_U_1(pptr+idx) != 'S' ) + return 0; + idx++; + if ( GET_U_1(pptr+idx) != 'H' ) + return 0; + idx++; + if ( GET_U_1(pptr+idx) != '-' ) + return 0; + idx++; + + while (idx < len) { + u_char c; + + c = GET_U_1(pptr + idx); + if (c == '\n') { + /* + * LF without CR; end of line. + * Skip the LF and print the line, with the + * exception of the LF. + */ + goto print; + } else if (c == '\r') { + /* CR - any LF? */ + if ((idx+1) >= len) { + /* not in this packet */ + goto trunc; + } + if (GET_U_1(pptr + idx + 1) == '\n') { + /* + * CR-LF; end of line. + * Skip the CR-LF and print the line, with + * the exception of the CR-LF. + */ + goto print; + } + + /* + * CR followed by something else; treat this as + * if it were binary data and don't print it. + */ + goto trunc; + } else if (!ND_ASCII_ISPRINT(c) ) { + /* + * Not a printable ASCII character; treat this + * as if it were binary data and don't print it. + */ + goto trunc; + } + idx++; + } +trunc: + return -1; +print: + ND_PRINT(": "); + nd_print_protocol_caps(ndo); + ND_PRINT(": %.*s", (int)idx, pptr); + return idx; +} + +void +ssh_print(netdissect_options *ndo, const u_char *pptr, u_int len) +{ + ndo->ndo_protocol = "ssh"; + + ssh_print_version(ndo, pptr, len); +} diff --git a/contrib/tcpdump/print-stp.c b/contrib/tcpdump/print-stp.c index ee0627ca88..5030b2193f 100644 --- a/contrib/tcpdump/print-stp.c +++ b/contrib/tcpdump/print-stp.c @@ -11,10 +11,10 @@ /* \summary: IEEE 802.1d Spanning Tree Protocol (STP) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include @@ -27,19 +27,19 @@ #define STP_BPDU_MSTP_MIN_LEN 102 struct stp_bpdu_ { - uint8_t protocol_id[2]; - uint8_t protocol_version; - uint8_t bpdu_type; - uint8_t flags; - uint8_t root_id[8]; - uint8_t root_path_cost[4]; - uint8_t bridge_id[8]; - uint8_t port_id[2]; - uint8_t message_age[2]; - uint8_t max_age[2]; - uint8_t hello_time[2]; - uint8_t forward_delay[2]; - uint8_t v1_length; + nd_uint16_t protocol_id; + nd_uint8_t protocol_version; + nd_uint8_t bpdu_type; + nd_uint8_t flags; + nd_byte root_id[8]; + nd_uint32_t root_path_cost; + nd_byte bridge_id[8]; + nd_uint16_t port_id; + nd_uint16_t message_age; + nd_uint16_t max_age; + nd_uint16_t hello_time; + nd_uint16_t forward_delay; + nd_uint8_t v1_length; }; #define STP_PROTO_REGULAR 0x00 @@ -84,60 +84,56 @@ static const struct tok rstp_obj_port_role_values[] = { { 0, NULL} }; -#define ND_TCHECK_BRIDGE_ID(p) ND_TCHECK2(*(p), 8) - static char * -stp_print_bridge_id(const u_char *p) +stp_print_bridge_id(netdissect_options *ndo, const u_char *p) { static char bridge_id_str[sizeof("pppp.aa:bb:cc:dd:ee:ff")]; snprintf(bridge_id_str, sizeof(bridge_id_str), "%.2x%.2x.%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); + GET_U_1(p), GET_U_1(p + 1), GET_U_1(p + 2), + GET_U_1(p + 3), GET_U_1(p + 4), GET_U_1(p + 5), + GET_U_1(p + 6), GET_U_1(p + 7)); return bridge_id_str; } -static int +static void stp_print_config_bpdu(netdissect_options *ndo, const struct stp_bpdu_ *stp_bpdu, u_int length) { - ND_TCHECK(stp_bpdu->flags); - ND_PRINT((ndo, ", Flags [%s]", - bittok2str(stp_bpdu_flag_values, "none", stp_bpdu->flags))); + uint8_t bpdu_flags; + + bpdu_flags = GET_U_1(stp_bpdu->flags); + ND_PRINT(", Flags [%s]", + bittok2str(stp_bpdu_flag_values, "none", bpdu_flags)); - ND_TCHECK(stp_bpdu->port_id); - ND_PRINT((ndo, ", bridge-id %s.%04x, length %u", - stp_print_bridge_id((const u_char *)&stp_bpdu->bridge_id), - EXTRACT_16BITS(&stp_bpdu->port_id), length)); + ND_PRINT(", bridge-id %s.%04x, length %u", + stp_print_bridge_id(ndo, stp_bpdu->bridge_id), + GET_BE_U_2(stp_bpdu->port_id), length); /* in non-verbose mode just print the bridge-id */ if (!ndo->ndo_vflag) { - return 1; + return; } - ND_TCHECK(stp_bpdu->forward_delay); - ND_PRINT((ndo, "\n\tmessage-age %.2fs, max-age %.2fs" + ND_PRINT("\n\tmessage-age %.2fs, max-age %.2fs" ", hello-time %.2fs, forwarding-delay %.2fs", - (float)EXTRACT_16BITS(&stp_bpdu->message_age) / STP_TIME_BASE, - (float)EXTRACT_16BITS(&stp_bpdu->max_age) / STP_TIME_BASE, - (float)EXTRACT_16BITS(&stp_bpdu->hello_time) / STP_TIME_BASE, - (float)EXTRACT_16BITS(&stp_bpdu->forward_delay) / STP_TIME_BASE)); + (float) GET_BE_U_2(stp_bpdu->message_age) / STP_TIME_BASE, + (float) GET_BE_U_2(stp_bpdu->max_age) / STP_TIME_BASE, + (float) GET_BE_U_2(stp_bpdu->hello_time) / STP_TIME_BASE, + (float) GET_BE_U_2(stp_bpdu->forward_delay) / STP_TIME_BASE); - ND_PRINT((ndo, "\n\troot-id %s, root-pathcost %u", - stp_print_bridge_id((const u_char *)&stp_bpdu->root_id), - EXTRACT_32BITS(&stp_bpdu->root_path_cost))); + ND_PRINT("\n\troot-id %s, root-pathcost %u", + stp_print_bridge_id(ndo, stp_bpdu->root_id), + GET_BE_U_4(stp_bpdu->root_path_cost)); /* Port role is only valid for 802.1w */ - if (stp_bpdu->protocol_version == STP_PROTO_RAPID) { - ND_PRINT((ndo, ", port-role %s", + if (GET_U_1(stp_bpdu->protocol_version) == STP_PROTO_RAPID) { + ND_PRINT(", port-role %s", tok2str(rstp_obj_port_role_values, "Unknown", - RSTP_EXTRACT_PORT_ROLE(stp_bpdu->flags)))); + RSTP_EXTRACT_PORT_ROLE(bpdu_flags))); } - return 1; - -trunc: - return 0; } /* @@ -207,7 +203,7 @@ trunc: #define MST_BPDU_MSTI_LENGTH 16 #define MST_BPDU_CONFIG_INFO_LENGTH 64 -/* Offsets of fields from the begginning for the packet */ +/* Offsets of fields from the beginning for the packet */ #define MST_BPDU_VER3_LEN_OFFSET 36 #define MST_BPDU_CONFIG_NAME_OFFSET 39 #define MST_BPDU_CONFIG_DIGEST_OFFSET 73 @@ -235,115 +231,99 @@ trunc: #define SPB_BPDU_AGREEMENT_RES2_OFFSET SPB_BPDU_AGREEMENT_RES1_OFFSET + 4 #define SPB_BPDU_AGREEMENT_DIGEST_OFFSET SPB_BPDU_AGREEMENT_RES2_OFFSET + 4 -static int +static void stp_print_mstp_bpdu(netdissect_options *ndo, const struct stp_bpdu_ *stp_bpdu, u_int length) { const u_char *ptr; + uint8_t bpdu_flags; uint16_t v3len; uint16_t len; uint16_t msti; u_int offset; ptr = (const u_char *)stp_bpdu; - ND_PRINT((ndo, ", CIST Flags [%s], length %u", - bittok2str(stp_bpdu_flag_values, "none", stp_bpdu->flags), length)); + bpdu_flags = GET_U_1(stp_bpdu->flags); + ND_PRINT(", CIST Flags [%s], length %u", + bittok2str(stp_bpdu_flag_values, "none", bpdu_flags), length); /* * in non-verbose mode just print the flags. */ if (!ndo->ndo_vflag) { - return 1; + return; } - ND_TCHECK(stp_bpdu->flags); - ND_PRINT((ndo, "\n\tport-role %s, ", + ND_PRINT("\n\tport-role %s, ", tok2str(rstp_obj_port_role_values, "Unknown", - RSTP_EXTRACT_PORT_ROLE(stp_bpdu->flags)))); + RSTP_EXTRACT_PORT_ROLE(bpdu_flags))); - ND_TCHECK(stp_bpdu->root_path_cost); - ND_PRINT((ndo, "CIST root-id %s, CIST ext-pathcost %u", - stp_print_bridge_id((const u_char *)&stp_bpdu->root_id), - EXTRACT_32BITS(&stp_bpdu->root_path_cost))); + ND_PRINT("CIST root-id %s, CIST ext-pathcost %u", + stp_print_bridge_id(ndo, stp_bpdu->root_id), + GET_BE_U_4(stp_bpdu->root_path_cost)); - ND_TCHECK(stp_bpdu->bridge_id); - ND_PRINT((ndo, "\n\tCIST regional-root-id %s, ", - stp_print_bridge_id((const u_char *)&stp_bpdu->bridge_id))); + ND_PRINT("\n\tCIST regional-root-id %s, ", + stp_print_bridge_id(ndo, stp_bpdu->bridge_id)); - ND_TCHECK(stp_bpdu->port_id); - ND_PRINT((ndo, "CIST port-id %04x,", EXTRACT_16BITS(&stp_bpdu->port_id))); + ND_PRINT("CIST port-id %04x,", GET_BE_U_2(stp_bpdu->port_id)); - ND_TCHECK(stp_bpdu->forward_delay); - ND_PRINT((ndo, "\n\tmessage-age %.2fs, max-age %.2fs" + ND_PRINT("\n\tmessage-age %.2fs, max-age %.2fs" ", hello-time %.2fs, forwarding-delay %.2fs", - (float)EXTRACT_16BITS(&stp_bpdu->message_age) / STP_TIME_BASE, - (float)EXTRACT_16BITS(&stp_bpdu->max_age) / STP_TIME_BASE, - (float)EXTRACT_16BITS(&stp_bpdu->hello_time) / STP_TIME_BASE, - (float)EXTRACT_16BITS(&stp_bpdu->forward_delay) / STP_TIME_BASE)); - - ND_TCHECK_16BITS(ptr + MST_BPDU_VER3_LEN_OFFSET); - ND_PRINT((ndo, "\n\tv3len %d, ", EXTRACT_16BITS(ptr + MST_BPDU_VER3_LEN_OFFSET))); - ND_TCHECK_32BITS(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 12); - ND_PRINT((ndo, "MCID Name ")); - if (fn_printzp(ndo, ptr + MST_BPDU_CONFIG_NAME_OFFSET, 32, ndo->ndo_snapend)) - goto trunc; - ND_PRINT((ndo, ", rev %u," + (float) GET_BE_U_2(stp_bpdu->message_age) / STP_TIME_BASE, + (float) GET_BE_U_2(stp_bpdu->max_age) / STP_TIME_BASE, + (float) GET_BE_U_2(stp_bpdu->hello_time) / STP_TIME_BASE, + (float) GET_BE_U_2(stp_bpdu->forward_delay) / STP_TIME_BASE); + + ND_PRINT("\n\tv3len %u, ", GET_BE_U_2(ptr + MST_BPDU_VER3_LEN_OFFSET)); + ND_PRINT("MCID Name "); + nd_printjnp(ndo, ptr + MST_BPDU_CONFIG_NAME_OFFSET, 32); + ND_PRINT(", rev %u," "\n\t\tdigest %08x%08x%08x%08x, ", - EXTRACT_16BITS(ptr + MST_BPDU_CONFIG_NAME_OFFSET + 32), - EXTRACT_32BITS(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET), - EXTRACT_32BITS(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 4), - EXTRACT_32BITS(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 8), - EXTRACT_32BITS(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 12))); + GET_BE_U_2(ptr + MST_BPDU_CONFIG_NAME_OFFSET + 32), + GET_BE_U_4(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET), + GET_BE_U_4(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 4), + GET_BE_U_4(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 8), + GET_BE_U_4(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 12)); - ND_TCHECK_32BITS(ptr + MST_BPDU_CIST_INT_PATH_COST_OFFSET); - ND_PRINT((ndo, "CIST int-root-pathcost %u,", - EXTRACT_32BITS(ptr + MST_BPDU_CIST_INT_PATH_COST_OFFSET))); + ND_PRINT("CIST int-root-pathcost %u,", + GET_BE_U_4(ptr + MST_BPDU_CIST_INT_PATH_COST_OFFSET)); - ND_TCHECK_BRIDGE_ID(ptr + MST_BPDU_CIST_BRIDGE_ID_OFFSET); - ND_PRINT((ndo, "\n\tCIST bridge-id %s, ", - stp_print_bridge_id(ptr + MST_BPDU_CIST_BRIDGE_ID_OFFSET))); + ND_PRINT("\n\tCIST bridge-id %s, ", + stp_print_bridge_id(ndo, ptr + MST_BPDU_CIST_BRIDGE_ID_OFFSET)); - ND_TCHECK(ptr[MST_BPDU_CIST_REMAIN_HOPS_OFFSET]); - ND_PRINT((ndo, "CIST remaining-hops %d", ptr[MST_BPDU_CIST_REMAIN_HOPS_OFFSET])); + ND_PRINT("CIST remaining-hops %u", + GET_U_1(ptr + MST_BPDU_CIST_REMAIN_HOPS_OFFSET)); /* Dump all MSTI's */ - ND_TCHECK_16BITS(ptr + MST_BPDU_VER3_LEN_OFFSET); - v3len = EXTRACT_16BITS(ptr + MST_BPDU_VER3_LEN_OFFSET); + v3len = GET_BE_U_2(ptr + MST_BPDU_VER3_LEN_OFFSET); if (v3len > MST_BPDU_CONFIG_INFO_LENGTH) { len = v3len - MST_BPDU_CONFIG_INFO_LENGTH; offset = MST_BPDU_MSTI_OFFSET; while (len >= MST_BPDU_MSTI_LENGTH) { - ND_TCHECK2(*(ptr + offset), MST_BPDU_MSTI_LENGTH); - - msti = EXTRACT_16BITS(ptr + offset + - MST_BPDU_MSTI_ROOT_PRIO_OFFSET); + msti = GET_BE_U_2(ptr + offset + MST_BPDU_MSTI_ROOT_PRIO_OFFSET); msti = msti & 0x0FFF; - ND_PRINT((ndo, "\n\tMSTI %d, Flags [%s], port-role %s", - msti, bittok2str(stp_bpdu_flag_values, "none", ptr[offset]), + ND_PRINT("\n\tMSTI %u, Flags [%s], port-role %s", + msti, + bittok2str(stp_bpdu_flag_values, "none", GET_U_1(ptr + offset)), tok2str(rstp_obj_port_role_values, "Unknown", - RSTP_EXTRACT_PORT_ROLE(ptr[offset])))); - ND_PRINT((ndo, "\n\t\tMSTI regional-root-id %s, pathcost %u", - stp_print_bridge_id(ptr + offset + + RSTP_EXTRACT_PORT_ROLE(GET_U_1(ptr + offset)))); + ND_PRINT("\n\t\tMSTI regional-root-id %s, pathcost %u", + stp_print_bridge_id(ndo, ptr + offset + MST_BPDU_MSTI_ROOT_PRIO_OFFSET), - EXTRACT_32BITS(ptr + offset + - MST_BPDU_MSTI_ROOT_PATH_COST_OFFSET))); - ND_PRINT((ndo, "\n\t\tMSTI bridge-prio %d, port-prio %d, hops %d", - ptr[offset + MST_BPDU_MSTI_BRIDGE_PRIO_OFFSET] >> 4, - ptr[offset + MST_BPDU_MSTI_PORT_PRIO_OFFSET] >> 4, - ptr[offset + MST_BPDU_MSTI_REMAIN_HOPS_OFFSET])); + GET_BE_U_4(ptr + offset + MST_BPDU_MSTI_ROOT_PATH_COST_OFFSET)); + ND_PRINT("\n\t\tMSTI bridge-prio %u, port-prio %u, hops %u", + GET_U_1(ptr + offset + MST_BPDU_MSTI_BRIDGE_PRIO_OFFSET) >> 4, + GET_U_1(ptr + offset + MST_BPDU_MSTI_PORT_PRIO_OFFSET) >> 4, + GET_U_1(ptr + offset + MST_BPDU_MSTI_REMAIN_HOPS_OFFSET)); len -= MST_BPDU_MSTI_LENGTH; offset += MST_BPDU_MSTI_LENGTH; } } - return 1; - -trunc: - return 0; } -static int +static void stp_print_spb_bpdu(netdissect_options *ndo, const struct stp_bpdu_ *stp_bpdu, u_int offset) { @@ -353,46 +333,39 @@ stp_print_spb_bpdu(netdissect_options *ndo, const struct stp_bpdu_ *stp_bpdu, * in non-verbose mode don't print anything. */ if (!ndo->ndo_vflag) { - return 1; + return; } ptr = (const u_char *)stp_bpdu; - ND_TCHECK_32BITS(ptr + offset + SPB_BPDU_AGREEMENT_DIGEST_OFFSET + 16); - - ND_PRINT((ndo, "\n\tv4len %d, ", EXTRACT_16BITS (ptr + offset))); - ND_PRINT((ndo, "AUXMCID Name ")); - if (fn_printzp(ndo, ptr + offset + SPB_BPDU_CONFIG_NAME_OFFSET, 32, - ndo->ndo_snapend)) - goto trunc; - ND_PRINT((ndo, ", Rev %u,\n\t\tdigest %08x%08x%08x%08x", - EXTRACT_16BITS(ptr + offset + SPB_BPDU_CONFIG_REV_OFFSET), - EXTRACT_32BITS(ptr + offset + SPB_BPDU_CONFIG_DIGEST_OFFSET), - EXTRACT_32BITS(ptr + offset + SPB_BPDU_CONFIG_DIGEST_OFFSET + 4), - EXTRACT_32BITS(ptr + offset + SPB_BPDU_CONFIG_DIGEST_OFFSET + 8), - EXTRACT_32BITS(ptr + offset + SPB_BPDU_CONFIG_DIGEST_OFFSET + 12))); - - ND_PRINT((ndo, "\n\tAgreement num %d, Discarded Agreement num %d, Agreement valid-" - "flag %d,\n\tRestricted role-flag: %d, Format id %d cap %d, " - "Convention id %d cap %d,\n\tEdge count %d, " - "Agreement digest %08x%08x%08x%08x%08x\n", - ptr[offset + SPB_BPDU_AGREEMENT_OFFSET]>>6, - ptr[offset + SPB_BPDU_AGREEMENT_OFFSET]>>4 & 0x3, - ptr[offset + SPB_BPDU_AGREEMENT_OFFSET]>>3 & 0x1, - ptr[offset + SPB_BPDU_AGREEMENT_OFFSET]>>2 & 0x1, - ptr[offset + SPB_BPDU_AGREEMENT_FORMAT_OFFSET]>>4, - ptr[offset + SPB_BPDU_AGREEMENT_FORMAT_OFFSET]&0x00ff, - ptr[offset + SPB_BPDU_AGREEMENT_CON_OFFSET]>>4, - ptr[offset + SPB_BPDU_AGREEMENT_CON_OFFSET]&0x00ff, - EXTRACT_16BITS(ptr + offset + SPB_BPDU_AGREEMENT_EDGE_OFFSET), - EXTRACT_32BITS(ptr + offset + SPB_BPDU_AGREEMENT_DIGEST_OFFSET), - EXTRACT_32BITS(ptr + offset + SPB_BPDU_AGREEMENT_DIGEST_OFFSET+4), - EXTRACT_32BITS(ptr + offset + SPB_BPDU_AGREEMENT_DIGEST_OFFSET+8), - EXTRACT_32BITS(ptr + offset + SPB_BPDU_AGREEMENT_DIGEST_OFFSET+12), - EXTRACT_32BITS(ptr + offset + SPB_BPDU_AGREEMENT_DIGEST_OFFSET+16))); - return 1; - -trunc: - return 0; + + ND_PRINT("\n\tv4len %u, ", GET_BE_U_2(ptr + offset)); + ND_PRINT("AUXMCID Name "); + nd_printjnp(ndo, ptr + offset + SPB_BPDU_CONFIG_NAME_OFFSET, 32); + ND_PRINT(", Rev %u,\n\t\tdigest %08x%08x%08x%08x", + GET_BE_U_2(ptr + offset + SPB_BPDU_CONFIG_REV_OFFSET), + GET_BE_U_4(ptr + offset + SPB_BPDU_CONFIG_DIGEST_OFFSET), + GET_BE_U_4(ptr + offset + SPB_BPDU_CONFIG_DIGEST_OFFSET + 4), + GET_BE_U_4(ptr + offset + SPB_BPDU_CONFIG_DIGEST_OFFSET + 8), + GET_BE_U_4(ptr + offset + SPB_BPDU_CONFIG_DIGEST_OFFSET + 12)); + + ND_PRINT("\n\tAgreement num %u, Discarded Agreement num %u, Agreement valid-" + "flag %u,\n\tRestricted role-flag: %u, Format id %u cap %u, " + "Convention id %u cap %u,\n\tEdge count %u, " + "Agreement digest %08x%08x%08x%08x%08x", + GET_U_1(ptr + offset + SPB_BPDU_AGREEMENT_OFFSET)>>6, + GET_U_1(ptr + offset + SPB_BPDU_AGREEMENT_OFFSET)>>4 & 0x3, + GET_U_1(ptr + offset + SPB_BPDU_AGREEMENT_OFFSET)>>3 & 0x1, + GET_U_1(ptr + offset + SPB_BPDU_AGREEMENT_OFFSET)>>2 & 0x1, + GET_U_1(ptr + offset + SPB_BPDU_AGREEMENT_FORMAT_OFFSET)>>4, + GET_U_1(ptr + offset + SPB_BPDU_AGREEMENT_FORMAT_OFFSET)&0x00ff, + GET_U_1(ptr + offset + SPB_BPDU_AGREEMENT_CON_OFFSET)>>4, + GET_U_1(ptr + offset + SPB_BPDU_AGREEMENT_CON_OFFSET)&0x00ff, + GET_BE_U_2(ptr + offset + SPB_BPDU_AGREEMENT_EDGE_OFFSET), + GET_BE_U_4(ptr + offset + SPB_BPDU_AGREEMENT_DIGEST_OFFSET), + GET_BE_U_4(ptr + offset + SPB_BPDU_AGREEMENT_DIGEST_OFFSET + 4), + GET_BE_U_4(ptr + offset + SPB_BPDU_AGREEMENT_DIGEST_OFFSET + 8), + GET_BE_U_4(ptr + offset + SPB_BPDU_AGREEMENT_DIGEST_OFFSET + 12), + GET_BE_U_4(ptr + offset + SPB_BPDU_AGREEMENT_DIGEST_OFFSET + 16)); } /* @@ -402,26 +375,28 @@ void stp_print(netdissect_options *ndo, const u_char *p, u_int length) { const struct stp_bpdu_ *stp_bpdu; + u_int protocol_version; + u_int bpdu_type; u_int mstp_len; u_int spb_len; + ndo->ndo_protocol = "stp"; stp_bpdu = (const struct stp_bpdu_*)p; /* Minimum STP Frame size. */ if (length < 4) - goto trunc; + goto invalid; - ND_TCHECK(stp_bpdu->protocol_id); - if (EXTRACT_16BITS(&stp_bpdu->protocol_id)) { - ND_PRINT((ndo, "unknown STP version, length %u", length)); + if (GET_BE_U_2(stp_bpdu->protocol_id)) { + ND_PRINT("unknown STP version, length %u", length); return; } - ND_TCHECK(stp_bpdu->protocol_version); - ND_PRINT((ndo, "STP %s", tok2str(stp_proto_values, "Unknown STP protocol (0x%02x)", - stp_bpdu->protocol_version))); + protocol_version = GET_U_1(stp_bpdu->protocol_version); + ND_PRINT("STP %s", tok2str(stp_proto_values, "Unknown STP protocol (0x%02x)", + protocol_version)); - switch (stp_bpdu->protocol_version) { + switch (protocol_version) { case STP_PROTO_REGULAR: case STP_PROTO_RAPID: case STP_PROTO_MSTP: @@ -431,60 +406,53 @@ stp_print(netdissect_options *ndo, const u_char *p, u_int length) return; } - ND_TCHECK(stp_bpdu->bpdu_type); - ND_PRINT((ndo, ", %s", tok2str(stp_bpdu_type_values, "Unknown BPDU Type (0x%02x)", - stp_bpdu->bpdu_type))); + bpdu_type = GET_U_1(stp_bpdu->bpdu_type); + ND_PRINT(", %s", tok2str(stp_bpdu_type_values, "Unknown BPDU Type (0x%02x)", + bpdu_type)); - switch (stp_bpdu->bpdu_type) { + switch (bpdu_type) { case STP_BPDU_TYPE_CONFIG: if (length < sizeof(struct stp_bpdu_) - 1) { - goto trunc; + goto invalid; } - if (!stp_print_config_bpdu(ndo, stp_bpdu, length)) - goto trunc; + stp_print_config_bpdu(ndo, stp_bpdu, length); break; case STP_BPDU_TYPE_RSTP: - if (stp_bpdu->protocol_version == STP_PROTO_RAPID) { + if (protocol_version == STP_PROTO_RAPID) { if (length < sizeof(struct stp_bpdu_)) { - goto trunc; + goto invalid; } - if (!stp_print_config_bpdu(ndo, stp_bpdu, length)) - goto trunc; - } else if (stp_bpdu->protocol_version == STP_PROTO_MSTP || - stp_bpdu->protocol_version == STP_PROTO_SPB) { + stp_print_config_bpdu(ndo, stp_bpdu, length); + } else if (protocol_version == STP_PROTO_MSTP || + protocol_version == STP_PROTO_SPB) { if (length < STP_BPDU_MSTP_MIN_LEN) { - goto trunc; + goto invalid; } - ND_TCHECK(stp_bpdu->v1_length); - if (stp_bpdu->v1_length != 0) { + if (GET_U_1(stp_bpdu->v1_length) != 0) { /* FIX ME: Emit a message here ? */ - goto trunc; + goto invalid; } /* Validate v3 length */ - ND_TCHECK_16BITS(p + MST_BPDU_VER3_LEN_OFFSET); - mstp_len = EXTRACT_16BITS(p + MST_BPDU_VER3_LEN_OFFSET); + mstp_len = GET_BE_U_2(p + MST_BPDU_VER3_LEN_OFFSET); mstp_len += 2; /* length encoding itself is 2 bytes */ if (length < (sizeof(struct stp_bpdu_) + mstp_len)) { - goto trunc; + goto invalid; } - if (!stp_print_mstp_bpdu(ndo, stp_bpdu, length)) - goto trunc; + stp_print_mstp_bpdu(ndo, stp_bpdu, length); - if (stp_bpdu->protocol_version == STP_PROTO_SPB) + if (protocol_version == STP_PROTO_SPB) { /* Validate v4 length */ - ND_TCHECK_16BITS(p + MST_BPDU_VER3_LEN_OFFSET + mstp_len); - spb_len = EXTRACT_16BITS (p + MST_BPDU_VER3_LEN_OFFSET + mstp_len); + spb_len = GET_BE_U_2(p + MST_BPDU_VER3_LEN_OFFSET + mstp_len); spb_len += 2; if (length < (sizeof(struct stp_bpdu_) + mstp_len + spb_len) || spb_len < SPB_BPDU_MIN_LEN) { - goto trunc; + goto invalid; } - if (!stp_print_spb_bpdu(ndo, stp_bpdu, (sizeof(struct stp_bpdu_) + mstp_len))) - goto trunc; + stp_print_spb_bpdu(ndo, stp_bpdu, (sizeof(struct stp_bpdu_) + mstp_len)); } } break; @@ -496,15 +464,8 @@ stp_print(netdissect_options *ndo, const u_char *p, u_int length) default: break; } - return; -trunc: - ND_PRINT((ndo, "[|stp %d]", length)); -} -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 4 - * End: - */ +invalid: + nd_print_invalid(ndo); +} diff --git a/contrib/tcpdump/print-sunatm.c b/contrib/tcpdump/print-sunatm.c index a587e50938..0fe5eee8e4 100644 --- a/contrib/tcpdump/print-sunatm.c +++ b/contrib/tcpdump/print-sunatm.c @@ -33,14 +33,12 @@ /* \summary: SunATM DLPI capture printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include - -struct mbuf; -struct rtentry; +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" @@ -62,7 +60,7 @@ struct rtentry; * 'h->len' is the length of the packet off the wire, and 'h->caplen' * is the number of bytes actually captured. */ -u_int +void sunatm_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { @@ -72,16 +70,13 @@ sunatm_if_print(netdissect_options *ndo, u_char vpi; u_int traftype; - if (caplen < PKT_BEGIN_POS) { - ND_PRINT((ndo, "[|atm]")); - return (caplen); - } + ndo->ndo_protocol = "sunatm"; if (ndo->ndo_eflag) { - ND_PRINT((ndo, p[DIR_POS] & 0x80 ? "Tx: " : "Rx: ")); + ND_PRINT(GET_U_1(p + DIR_POS) & 0x80 ? "Tx: " : "Rx: "); } - switch (p[DIR_POS] & 0x0f) { + switch (GET_U_1(p + DIR_POS) & 0x0f) { case PT_LANE: traftype = ATM_LANE; @@ -96,13 +91,12 @@ sunatm_if_print(netdissect_options *ndo, break; } - vci = EXTRACT_16BITS(&p[VCI_POS]); - vpi = p[VPI_POS]; + vpi = GET_U_1(p + VPI_POS); + vci = GET_BE_U_2(p + VCI_POS); p += PKT_BEGIN_POS; caplen -= PKT_BEGIN_POS; length -= PKT_BEGIN_POS; + ndo->ndo_ll_hdr_len += PKT_BEGIN_POS; atm_print(ndo, vpi, vci, traftype, p, length, caplen); - - return (PKT_BEGIN_POS); } diff --git a/contrib/tcpdump/print-sunrpc.c b/contrib/tcpdump/print-sunrpc.c index d2366c783b..82bfd8a9d9 100644 --- a/contrib/tcpdump/print-sunrpc.c +++ b/contrib/tcpdump/print-sunrpc.c @@ -22,7 +22,7 @@ /* \summary: Sun Remote Procedure Call printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif /* @@ -40,7 +40,7 @@ */ #undef _XOPEN_SOURCE_EXTENDED -#include +#include "netdissect-stdinc.h" #if defined(HAVE_GETRPCBYNUMBER) && defined(HAVE_RPC_RPC_H) #include @@ -52,6 +52,7 @@ #include #include +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "addrtoname.h" #include "extract.h" @@ -133,10 +134,6 @@ */ #define SUNRPC_PMAPPORT ((uint16_t)111) -#define SUNRPC_PMAPPROG ((uint32_t)100000) -#define SUNRPC_PMAPVERS ((uint32_t)2) -#define SUNRPC_PMAPVERS_PROTO ((uint32_t)2) -#define SUNRPC_PMAPVERS_ORIG ((uint32_t)1) #define SUNRPC_PMAPPROC_NULL ((uint32_t)0) #define SUNRPC_PMAPPROC_SET ((uint32_t)1) #define SUNRPC_PMAPPROC_UNSET ((uint32_t)2) @@ -144,13 +141,6 @@ #define SUNRPC_PMAPPROC_DUMP ((uint32_t)4) #define SUNRPC_PMAPPROC_CALLIT ((uint32_t)5) -struct sunrpc_pmap { - uint32_t pm_prog; - uint32_t pm_vers; - uint32_t pm_prot; - uint32_t pm_port; -}; - static const struct tok proc2str[] = { { SUNRPC_PMAPPROC_NULL, "null" }, { SUNRPC_PMAPPROC_SET, "set" }, @@ -165,63 +155,65 @@ static const struct tok proc2str[] = { static char *progstr(uint32_t); void -sunrpcrequest_print(netdissect_options *ndo, register const u_char *bp, - register u_int length, register const u_char *bp2) +sunrpc_print(netdissect_options *ndo, const u_char *bp, + u_int length, const u_char *bp2) { - register const struct sunrpc_msg *rp; - register const struct ip *ip; - register const struct ip6_hdr *ip6; + const struct sunrpc_msg *rp; + const struct ip *ip; + const struct ip6_hdr *ip6; uint32_t x; char srcid[20], dstid[20]; /*fits 32bit*/ + ndo->ndo_protocol = "sunrpc"; rp = (const struct sunrpc_msg *)bp; + ND_TCHECK_SIZE(rp); if (!ndo->ndo_nflag) { snprintf(srcid, sizeof(srcid), "0x%x", - EXTRACT_32BITS(&rp->rm_xid)); + GET_BE_U_4(rp->rm_xid)); strlcpy(dstid, "sunrpc", sizeof(dstid)); } else { snprintf(srcid, sizeof(srcid), "0x%x", - EXTRACT_32BITS(&rp->rm_xid)); + GET_BE_U_4(rp->rm_xid)); snprintf(dstid, sizeof(dstid), "0x%x", SUNRPC_PMAPPORT); } switch (IP_V((const struct ip *)bp2)) { case 4: ip = (const struct ip *)bp2; - ND_PRINT((ndo, "%s.%s > %s.%s: %d", - ipaddr_string(ndo, &ip->ip_src), srcid, - ipaddr_string(ndo, &ip->ip_dst), dstid, length)); + ND_PRINT("%s.%s > %s.%s: %u", + GET_IPADDR_STRING(ip->ip_src), srcid, + GET_IPADDR_STRING(ip->ip_dst), dstid, length); break; case 6: ip6 = (const struct ip6_hdr *)bp2; - ND_PRINT((ndo, "%s.%s > %s.%s: %d", - ip6addr_string(ndo, &ip6->ip6_src), srcid, - ip6addr_string(ndo, &ip6->ip6_dst), dstid, length)); + ND_PRINT("%s.%s > %s.%s: %u", + GET_IP6ADDR_STRING(ip6->ip6_src), srcid, + GET_IP6ADDR_STRING(ip6->ip6_dst), dstid, length); break; default: - ND_PRINT((ndo, "%s.%s > %s.%s: %d", "?", srcid, "?", dstid, length)); + ND_PRINT("%s.%s > %s.%s: %u", "?", srcid, "?", dstid, length); break; } - ND_PRINT((ndo, " %s", tok2str(proc2str, " proc #%u", - EXTRACT_32BITS(&rp->rm_call.cb_proc)))); - x = EXTRACT_32BITS(&rp->rm_call.cb_rpcvers); - if (x != 2) - ND_PRINT((ndo, " [rpcver %u]", x)); + ND_PRINT(" %s", tok2str(proc2str, " proc #%u", + GET_BE_U_4(rp->rm_call.cb_proc))); + x = GET_BE_U_4(rp->rm_call.cb_rpcvers); + if (x != SUNRPC_MSG_VERSION) + ND_PRINT(" [rpcver %u]", x); - switch (EXTRACT_32BITS(&rp->rm_call.cb_proc)) { + switch (GET_BE_U_4(rp->rm_call.cb_proc)) { case SUNRPC_PMAPPROC_SET: case SUNRPC_PMAPPROC_UNSET: case SUNRPC_PMAPPROC_GETPORT: case SUNRPC_PMAPPROC_CALLIT: - x = EXTRACT_32BITS(&rp->rm_call.cb_prog); + x = GET_BE_U_4(rp->rm_call.cb_prog); if (!ndo->ndo_nflag) - ND_PRINT((ndo, " %s", progstr(x))); + ND_PRINT(" %s", progstr(x)); else - ND_PRINT((ndo, " %u", x)); - ND_PRINT((ndo, ".%u", EXTRACT_32BITS(&rp->rm_call.cb_vers))); + ND_PRINT(" %u", x); + ND_PRINT(".%u", GET_BE_U_4(rp->rm_call.cb_vers)); break; } } @@ -230,7 +222,7 @@ static char * progstr(uint32_t prog) { #if defined(HAVE_GETRPCBYNUMBER) && defined(HAVE_RPC_RPC_H) - register struct rpcent *rp; + struct rpcent *rp; #endif static char buf[32]; static uint32_t lastprog = 0; @@ -239,12 +231,11 @@ progstr(uint32_t prog) return (buf); #if defined(HAVE_GETRPCBYNUMBER) && defined(HAVE_RPC_RPC_H) rp = getrpcbynumber(prog); - if (rp == NULL) -#endif - (void) snprintf(buf, sizeof(buf), "#%u", prog); -#if defined(HAVE_GETRPCBYNUMBER) && defined(HAVE_RPC_RPC_H) - else + if (rp != NULL) strlcpy(buf, rp->r_name, sizeof(buf)); + else #endif + (void) snprintf(buf, sizeof(buf), "#%u", prog); + lastprog = prog; return (buf); } diff --git a/contrib/tcpdump/print-symantec.c b/contrib/tcpdump/print-symantec.c index 9e9f8f33f0..0d394e30f2 100644 --- a/contrib/tcpdump/print-symantec.c +++ b/contrib/tcpdump/print-symantec.c @@ -22,47 +22,46 @@ /* \summary: Symantec Enterprise Firewall printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" #include "ethertype.h" -#include "ether.h" - struct symantec_header { - uint8_t stuff1[6]; - uint16_t ether_type; - uint8_t stuff2[36]; + nd_byte stuff1[6]; + nd_uint16_t ether_type; + nd_byte stuff2[36]; }; -static inline void -symantec_hdr_print(netdissect_options *ndo, register const u_char *bp, u_int length) +static void +symantec_hdr_print(netdissect_options *ndo, const u_char *bp, u_int length) { - register const struct symantec_header *sp; + const struct symantec_header *sp; uint16_t etype; sp = (const struct symantec_header *)bp; - etype = EXTRACT_16BITS(&sp->ether_type); + etype = GET_BE_U_2(sp->ether_type); if (!ndo->ndo_qflag) { - if (etype <= ETHERMTU) - ND_PRINT((ndo, "invalid ethertype %u", etype)); + if (etype <= MAX_ETHERNET_LENGTH_VAL) + ND_PRINT("invalid ethertype %u", etype); else - ND_PRINT((ndo, "ethertype %s (0x%04x)", + ND_PRINT("ethertype %s (0x%04x)", tok2str(ethertype_values,"Unknown", etype), - etype)); + etype); } else { - if (etype <= ETHERMTU) - ND_PRINT((ndo, "invalid ethertype %u", etype)); + if (etype <= MAX_ETHERNET_LENGTH_VAL) + ND_PRINT("invalid ethertype %u", etype); else - ND_PRINT((ndo, "%s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", etype))); + ND_PRINT("%s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", etype)); } - ND_PRINT((ndo, ", length %u: ", length)); + ND_PRINT(", length %u: ", length); } /* @@ -71,7 +70,7 @@ symantec_hdr_print(netdissect_options *ndo, register const u_char *bp, u_int len * 'h->len' is the length of the packet off the wire, and 'h->caplen' * is the number of bytes actually captured. */ -u_int +void symantec_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { u_int length = h->len; @@ -79,11 +78,10 @@ symantec_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_ const struct symantec_header *sp; u_short ether_type; - if (caplen < sizeof (struct symantec_header)) { - ND_PRINT((ndo, "[|symantec]")); - return caplen; - } + ndo->ndo_protocol = "symantec"; + ND_TCHECK_LEN(p, sizeof(struct symantec_header)); + ndo->ndo_ll_hdr_len += sizeof (struct symantec_header); if (ndo->ndo_eflag) symantec_hdr_print(ndo, p, length); @@ -92,9 +90,9 @@ symantec_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_ sp = (const struct symantec_header *)p; p += sizeof (struct symantec_header); - ether_type = EXTRACT_16BITS(&sp->ether_type); + ether_type = GET_BE_U_2(sp->ether_type); - if (ether_type <= ETHERMTU) { + if (ether_type <= MAX_ETHERNET_LENGTH_VAL) { /* ether_type not known, print raw packet */ if (!ndo->ndo_eflag) symantec_hdr_print(ndo, (const u_char *)sp, length + sizeof (struct symantec_header)); @@ -109,6 +107,4 @@ symantec_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_ if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); } - - return (sizeof (struct symantec_header)); } diff --git a/contrib/tcpdump/print-syslog.c b/contrib/tcpdump/print-syslog.c index 1756aa6f0b..b0e1c91aa7 100644 --- a/contrib/tcpdump/print-syslog.c +++ b/contrib/tcpdump/print-syslog.c @@ -15,17 +15,17 @@ */ /* \summary: Syslog protocol printer */ +/* specification: RFC 3164 (not RFC 5424) */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "extract.h" -static const char tstr[] = "[|syslog]"; /* * tokenlists and #defines taken from Ethereal - Network traffic analyzer @@ -34,7 +34,7 @@ static const char tstr[] = "[|syslog]"; #define SYSLOG_SEVERITY_MASK 0x0007 /* 0000 0000 0000 0111 */ #define SYSLOG_FACILITY_MASK 0x03f8 /* 0000 0011 1111 1000 */ -#define SYSLOG_MAX_DIGITS 3 /* The maximum number if priority digits to read in. */ +#define SYSLOG_MAX_DIGITS 3 /* The maximum number of priority digits to read in. */ static const struct tok syslog_severity_values[] = { { 0, "emergency" }, @@ -78,69 +78,73 @@ static const struct tok syslog_facility_values[] = { void syslog_print(netdissect_options *ndo, - register const u_char *pptr, register u_int len) + const u_char *pptr, u_int len) { uint16_t msg_off = 0; uint16_t pri = 0; uint16_t facility,severity; + ndo->ndo_protocol = "syslog"; /* extract decimal figures that are * encapsulated within < > tags * based on this decimal figure extract the * severity and facility values */ - ND_TCHECK2(*pptr, 1); - if (*(pptr+msg_off) == '<') { - msg_off++; - ND_TCHECK2(*(pptr + msg_off), 1); - while ( *(pptr+msg_off) >= '0' && - *(pptr+msg_off) <= '9' && - msg_off <= SYSLOG_MAX_DIGITS) { - pri = pri * 10 + (*(pptr+msg_off) - '0'); - msg_off++; - ND_TCHECK2(*(pptr + msg_off), 1); - } - if (*(pptr+msg_off) != '>') { - ND_PRINT((ndo, "%s", tstr)); - return; - } + if (GET_U_1(pptr) != '<') + goto invalid; + msg_off++; + + while (msg_off <= SYSLOG_MAX_DIGITS && + GET_U_1(pptr + msg_off) >= '0' && + GET_U_1(pptr + msg_off) <= '9') { + pri = pri * 10 + (GET_U_1(pptr + msg_off) - '0'); msg_off++; - } else { - ND_PRINT((ndo, "%s", tstr)); - return; } + if (GET_U_1(pptr + msg_off) != '>') + goto invalid; + msg_off++; + facility = (pri & SYSLOG_FACILITY_MASK) >> 3; severity = pri & SYSLOG_SEVERITY_MASK; if (ndo->ndo_vflag < 1 ) { - ND_PRINT((ndo, "SYSLOG %s.%s, length: %u", + ND_PRINT("SYSLOG %s.%s, length: %u", tok2str(syslog_facility_values, "unknown (%u)", facility), tok2str(syslog_severity_values, "unknown (%u)", severity), - len)); + len); return; } - ND_PRINT((ndo, "SYSLOG, length: %u\n\tFacility %s (%u), Severity %s (%u)\n\tMsg: ", + ND_PRINT("SYSLOG, length: %u\n\tFacility %s (%u), Severity %s (%u)\n\tMsg: ", len, tok2str(syslog_facility_values, "unknown (%u)", facility), facility, tok2str(syslog_severity_values, "unknown (%u)", severity), - severity)); + severity); /* print the syslog text in verbose mode */ - for (; msg_off < len; msg_off++) { - ND_TCHECK2(*(pptr + msg_off), 1); - safeputchar(ndo, *(pptr + msg_off)); - } + /* + * RFC 3164 Section 4.1.3: "There is no ending delimiter to this part. + * The MSG part of the syslog packet MUST contain visible (printing) + * characters." + * + * RFC 5424 Section 8.2: "This document does not impose any mandatory + * restrictions on the MSG or PARAM-VALUE content. As such, they MAY + * contain control characters, including the NUL character." + * + * Hence, to aid in protocol debugging, print the full MSG without + * beautification to make it clear what was transmitted on the wire. + */ + if (len > msg_off) + (void)nd_printn(ndo, pptr + msg_off, len - msg_off, NULL); if (ndo->ndo_vflag > 1) print_unknown_data(ndo, pptr, "\n\t", len); - return; -trunc: - ND_PRINT((ndo, "%s", tstr)); +invalid: + nd_print_invalid(ndo); } diff --git a/contrib/tcpdump/print-tcp.c b/contrib/tcpdump/print-tcp.c index b80a2f264d..a2238a86a8 100644 --- a/contrib/tcpdump/print-tcp.c +++ b/contrib/tcpdump/print-tcp.c @@ -31,10 +31,10 @@ __RCSID("$NetBSD: print-tcp.c,v 1.8 2007/07/24 11:53:48 drochner Exp $"); #endif #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include #include @@ -57,45 +57,45 @@ __RCSID("$NetBSD: print-tcp.c,v 1.8 2007/07/24 11:53:48 drochner Exp $"); static int tcp_verify_signature(netdissect_options *ndo, const struct ip *ip, const struct tcphdr *tp, - const u_char *data, int length, const u_char *rcvsig); + const u_char *data, u_int length, const u_char *rcvsig); #endif -static void print_tcp_rst_data(netdissect_options *, register const u_char *sp, u_int length); -static void print_tcp_fastopen_option(netdissect_options *ndo, register const u_char *cp, +static void print_tcp_rst_data(netdissect_options *, const u_char *sp, u_int length); +static void print_tcp_fastopen_option(netdissect_options *ndo, const u_char *cp, u_int datalen, int exp); #define MAX_RST_DATA_LEN 30 struct tha { - struct in_addr src; - struct in_addr dst; + nd_ipv4 src; + nd_ipv4 dst; u_int port; }; struct tcp_seq_hash { struct tcp_seq_hash *nxt; struct tha addr; - tcp_seq seq; - tcp_seq ack; + uint32_t seq; + uint32_t ack; }; struct tha6 { - struct in6_addr src; - struct in6_addr dst; + nd_ipv6 src; + nd_ipv6 dst; u_int port; }; struct tcp_seq_hash6 { struct tcp_seq_hash6 *nxt; struct tha6 addr; - tcp_seq seq; - tcp_seq ack; + uint32_t seq; + uint32_t ack; }; #define TSEQ_HASHSIZE 919 -/* These tcp optinos do not have the size octet */ +/* These tcp options do not have the size octet */ #define ZEROLENOPT(o) ((o) == TCPOPT_EOL || (o) == TCPOPT_NOP) static struct tcp_seq_hash tcp_seq_hash4[TSEQ_HASHSIZE]; @@ -136,43 +136,45 @@ static const struct tok tcp_option_values[] = { { 0, NULL } }; -static int +static uint16_t tcp_cksum(netdissect_options *ndo, - register const struct ip *ip, - register const struct tcphdr *tp, - register u_int len) + const struct ip *ip, + const struct tcphdr *tp, + u_int len) { - return nextproto4_cksum(ndo, ip, (const uint8_t *)tp, len, len, - IPPROTO_TCP); + return nextproto4_cksum(ndo, ip, (const uint8_t *)tp, len, len, + IPPROTO_TCP); } -static int +static uint16_t tcp6_cksum(netdissect_options *ndo, - register const struct ip6_hdr *ip6, - register const struct tcphdr *tp, - register u_int len) + const struct ip6_hdr *ip6, + const struct tcphdr *tp, + u_int len) { - return nextproto6_cksum(ndo, ip6, (const uint8_t *)tp, len, len, - IPPROTO_TCP); + return nextproto6_cksum(ndo, ip6, (const uint8_t *)tp, len, len, + IPPROTO_TCP); } void tcp_print(netdissect_options *ndo, - register const u_char *bp, register u_int length, - register const u_char *bp2, int fragmented) + const u_char *bp, u_int length, + const u_char *bp2, int fragmented) { - register const struct tcphdr *tp; - register const struct ip *ip; - register u_char flags; - register u_int hlen; - register char ch; + const struct tcphdr *tp; + const struct ip *ip; + u_char flags; + u_int hlen; + char ch; uint16_t sport, dport, win, urp; uint32_t seq, ack, thseq, thack; u_int utoval; uint16_t magic; - register int rev; - register const struct ip6_hdr *ip6; + int rev; + const struct ip6_hdr *ip6; + u_int header_len; /* Header length in bytes */ + ndo->ndo_protocol = "tcp"; tp = (const struct tcphdr *)bp; ip = (const struct ip *)bp2; if (IP_V(ip) == 6) @@ -180,66 +182,73 @@ tcp_print(netdissect_options *ndo, else ip6 = NULL; ch = '\0'; - if (!ND_TTEST(tp->th_dport)) { - ND_PRINT((ndo, "%s > %s: [|tcp]", - ipaddr_string(ndo, &ip->ip_src), - ipaddr_string(ndo, &ip->ip_dst))); + if (!ND_TTEST_2(tp->th_dport)) { + if (ip6) { + ND_PRINT("%s > %s:", + GET_IP6ADDR_STRING(ip6->ip6_src), + GET_IP6ADDR_STRING(ip6->ip6_dst)); + } else { + ND_PRINT("%s > %s:", + GET_IPADDR_STRING(ip->ip_src), + GET_IPADDR_STRING(ip->ip_dst)); + } + nd_print_trunc(ndo); return; } - sport = EXTRACT_16BITS(&tp->th_sport); - dport = EXTRACT_16BITS(&tp->th_dport); + sport = GET_BE_U_2(tp->th_sport); + dport = GET_BE_U_2(tp->th_dport); if (ip6) { - if (ip6->ip6_nxt == IPPROTO_TCP) { - ND_PRINT((ndo, "%s.%s > %s.%s: ", - ip6addr_string(ndo, &ip6->ip6_src), - tcpport_string(ndo, sport), - ip6addr_string(ndo, &ip6->ip6_dst), - tcpport_string(ndo, dport))); + if (GET_U_1(ip6->ip6_nxt) == IPPROTO_TCP) { + ND_PRINT("%s.%s > %s.%s: ", + GET_IP6ADDR_STRING(ip6->ip6_src), + tcpport_string(ndo, sport), + GET_IP6ADDR_STRING(ip6->ip6_dst), + tcpport_string(ndo, dport)); } else { - ND_PRINT((ndo, "%s > %s: ", - tcpport_string(ndo, sport), tcpport_string(ndo, dport))); + ND_PRINT("%s > %s: ", + tcpport_string(ndo, sport), tcpport_string(ndo, dport)); } } else { - if (ip->ip_p == IPPROTO_TCP) { - ND_PRINT((ndo, "%s.%s > %s.%s: ", - ipaddr_string(ndo, &ip->ip_src), - tcpport_string(ndo, sport), - ipaddr_string(ndo, &ip->ip_dst), - tcpport_string(ndo, dport))); + if (GET_U_1(ip->ip_p) == IPPROTO_TCP) { + ND_PRINT("%s.%s > %s.%s: ", + GET_IPADDR_STRING(ip->ip_src), + tcpport_string(ndo, sport), + GET_IPADDR_STRING(ip->ip_dst), + tcpport_string(ndo, dport)); } else { - ND_PRINT((ndo, "%s > %s: ", - tcpport_string(ndo, sport), tcpport_string(ndo, dport))); + ND_PRINT("%s > %s: ", + tcpport_string(ndo, sport), tcpport_string(ndo, dport)); } } - ND_TCHECK(*tp); + ND_TCHECK_SIZE(tp); hlen = TH_OFF(tp) * 4; if (hlen < sizeof(*tp)) { - ND_PRINT((ndo, " tcp %d [bad hdr length %u - too short, < %lu]", - length - hlen, hlen, (unsigned long)sizeof(*tp))); + ND_PRINT(" tcp %u [bad hdr length %u - too short, < %zu]", + length - hlen, hlen, sizeof(*tp)); return; } - seq = EXTRACT_32BITS(&tp->th_seq); - ack = EXTRACT_32BITS(&tp->th_ack); - win = EXTRACT_16BITS(&tp->th_win); - urp = EXTRACT_16BITS(&tp->th_urp); + seq = GET_BE_U_4(tp->th_seq); + ack = GET_BE_U_4(tp->th_ack); + win = GET_BE_U_2(tp->th_win); + urp = GET_BE_U_2(tp->th_urp); if (ndo->ndo_qflag) { - ND_PRINT((ndo, "tcp %d", length - hlen)); + ND_PRINT("tcp %u", length - hlen); if (hlen > length) { - ND_PRINT((ndo, " [bad hdr length %u - too long, > %u]", - hlen, length)); + ND_PRINT(" [bad hdr length %u - too long, > %u]", + hlen, length); } return; } - flags = tp->th_flags; - ND_PRINT((ndo, "Flags [%s]", bittok2str_nosep(tcp_flag_values, "none", flags))); + flags = GET_U_1(tp->th_flags); + ND_PRINT("Flags [%s]", bittok2str_nosep(tcp_flag_values, "none", flags)); if (!ndo->ndo_Sflag && (flags & TH_ACK)) { /* @@ -250,27 +259,27 @@ tcp_print(netdissect_options *ndo, */ rev = 0; if (ip6) { - register struct tcp_seq_hash6 *th; + struct tcp_seq_hash6 *th; struct tcp_seq_hash6 *tcp_seq_hash; - const struct in6_addr *src, *dst; + const void *src, *dst; struct tha6 tha; tcp_seq_hash = tcp_seq_hash6; - src = &ip6->ip6_src; - dst = &ip6->ip6_dst; + src = (const void *)ip6->ip6_src; + dst = (const void *)ip6->ip6_dst; if (sport > dport) rev = 1; else if (sport == dport) { - if (UNALIGNED_MEMCMP(src, dst, sizeof ip6->ip6_dst) > 0) + if (UNALIGNED_MEMCMP(src, dst, sizeof(ip6->ip6_dst)) > 0) rev = 1; } if (rev) { - UNALIGNED_MEMCPY(&tha.src, dst, sizeof ip6->ip6_dst); - UNALIGNED_MEMCPY(&tha.dst, src, sizeof ip6->ip6_src); + UNALIGNED_MEMCPY(&tha.src, dst, sizeof(ip6->ip6_dst)); + UNALIGNED_MEMCPY(&tha.dst, src, sizeof(ip6->ip6_src)); tha.port = ((u_int)dport) << 16 | sport; } else { - UNALIGNED_MEMCPY(&tha.dst, dst, sizeof ip6->ip6_dst); - UNALIGNED_MEMCPY(&tha.src, src, sizeof ip6->ip6_src); + UNALIGNED_MEMCPY(&tha.dst, dst, sizeof(ip6->ip6_dst)); + UNALIGNED_MEMCPY(&tha.src, src, sizeof(ip6->ip6_src)); tha.port = ((u_int)sport) << 16 | dport; } @@ -282,12 +291,15 @@ tcp_print(netdissect_options *ndo, if (!th->nxt || (flags & TH_SYN)) { /* didn't find it or new conversation */ + /* calloc() return used by the 'tcp_seq_hash6' + hash table: do not free() */ if (th->nxt == NULL) { th->nxt = (struct tcp_seq_hash6 *) calloc(1, sizeof(*th)); if (th->nxt == NULL) (*ndo->ndo_error)(ndo, - "tcp_print: calloc"); + S_ERR_ND_MEM_ALLOC, + "%s: calloc", __func__); } th->addr = tha; if (rev) @@ -304,7 +316,7 @@ tcp_print(netdissect_options *ndo, thseq = th->seq; thack = th->ack; } else { - register struct tcp_seq_hash *th; + struct tcp_seq_hash *th; struct tcp_seq_hash *tcp_seq_hash; struct tha tha; @@ -312,16 +324,20 @@ tcp_print(netdissect_options *ndo, if (sport > dport) rev = 1; else if (sport == dport) { - if (UNALIGNED_MEMCMP(&ip->ip_src, &ip->ip_dst, sizeof ip->ip_dst) > 0) + if (UNALIGNED_MEMCMP(ip->ip_src, ip->ip_dst, sizeof(ip->ip_dst)) > 0) rev = 1; } if (rev) { - UNALIGNED_MEMCPY(&tha.src, &ip->ip_dst, sizeof ip->ip_dst); - UNALIGNED_MEMCPY(&tha.dst, &ip->ip_src, sizeof ip->ip_src); + UNALIGNED_MEMCPY(&tha.src, ip->ip_dst, + sizeof(ip->ip_dst)); + UNALIGNED_MEMCPY(&tha.dst, ip->ip_src, + sizeof(ip->ip_src)); tha.port = ((u_int)dport) << 16 | sport; } else { - UNALIGNED_MEMCPY(&tha.dst, &ip->ip_dst, sizeof ip->ip_dst); - UNALIGNED_MEMCPY(&tha.src, &ip->ip_src, sizeof ip->ip_src); + UNALIGNED_MEMCPY(&tha.dst, ip->ip_dst, + sizeof(ip->ip_dst)); + UNALIGNED_MEMCPY(&tha.src, ip->ip_src, + sizeof(ip->ip_src)); tha.port = ((u_int)sport) << 16 | dport; } @@ -333,12 +349,15 @@ tcp_print(netdissect_options *ndo, if (!th->nxt || (flags & TH_SYN)) { /* didn't find it or new conversation */ + /* calloc() return used by the 'tcp_seq_hash4' + hash table: do not free() */ if (th->nxt == NULL) { th->nxt = (struct tcp_seq_hash *) calloc(1, sizeof(*th)); if (th->nxt == NULL) (*ndo->ndo_error)(ndo, - "tcp_print: calloc"); + S_ERR_ND_MEM_ALLOC, + "%s: calloc", __func__); } th->addr = tha; if (rev) @@ -360,8 +379,8 @@ tcp_print(netdissect_options *ndo, thseq = thack = rev = 0; } if (hlen > length) { - ND_PRINT((ndo, " [bad hdr length %u - too long, > %u]", - hlen, length)); + ND_PRINT(" [bad hdr length %u - too long, > %u]", + hlen, length); return; } @@ -370,28 +389,28 @@ tcp_print(netdissect_options *ndo, uint16_t sum, tcp_sum; if (IP_V(ip) == 4) { - if (ND_TTEST2(tp->th_sport, length)) { + if (ND_TTEST_LEN(tp->th_sport, length)) { sum = tcp_cksum(ndo, ip, tp, length); - tcp_sum = EXTRACT_16BITS(&tp->th_sum); + tcp_sum = GET_BE_U_2(tp->th_sum); - ND_PRINT((ndo, ", cksum 0x%04x", tcp_sum)); + ND_PRINT(", cksum 0x%04x", tcp_sum); if (sum != 0) - ND_PRINT((ndo, " (incorrect -> 0x%04x)", - in_cksum_shouldbe(tcp_sum, sum))); + ND_PRINT(" (incorrect -> 0x%04x)", + in_cksum_shouldbe(tcp_sum, sum)); else - ND_PRINT((ndo, " (correct)")); + ND_PRINT(" (correct)"); } - } else if (IP_V(ip) == 6 && ip6->ip6_plen) { - if (ND_TTEST2(tp->th_sport, length)) { + } else if (IP_V(ip) == 6) { + if (ND_TTEST_LEN(tp->th_sport, length)) { sum = tcp6_cksum(ndo, ip6, tp, length); - tcp_sum = EXTRACT_16BITS(&tp->th_sum); + tcp_sum = GET_BE_U_2(tp->th_sum); - ND_PRINT((ndo, ", cksum 0x%04x", tcp_sum)); + ND_PRINT(", cksum 0x%04x", tcp_sum); if (sum != 0) - ND_PRINT((ndo, " (incorrect -> 0x%04x)", - in_cksum_shouldbe(tcp_sum, sum))); + ND_PRINT(" (incorrect -> 0x%04x)", + in_cksum_shouldbe(tcp_sum, sum)); else - ND_PRINT((ndo, " (correct)")); + ND_PRINT(" (correct)"); } } @@ -399,42 +418,42 @@ tcp_print(netdissect_options *ndo, length -= hlen; if (ndo->ndo_vflag > 1 || length > 0 || flags & (TH_SYN | TH_FIN | TH_RST)) { - ND_PRINT((ndo, ", seq %u", seq)); + ND_PRINT(", seq %u", seq); if (length > 0) { - ND_PRINT((ndo, ":%u", seq + length)); + ND_PRINT(":%u", seq + length); } } if (flags & TH_ACK) { - ND_PRINT((ndo, ", ack %u", ack)); + ND_PRINT(", ack %u", ack); } - ND_PRINT((ndo, ", win %d", win)); + ND_PRINT(", win %u", win); if (flags & TH_URG) - ND_PRINT((ndo, ", urg %d", urp)); + ND_PRINT(", urg %u", urp); /* * Handle any options. */ if (hlen > sizeof(*tp)) { - register const u_char *cp; - register u_int i, opt, datalen; - register u_int len; + const u_char *cp; + u_int i, opt, datalen; + u_int len; hlen -= sizeof(*tp); cp = (const u_char *)tp + sizeof(*tp); - ND_PRINT((ndo, ", options [")); + ND_PRINT(", options ["); while (hlen > 0) { if (ch != '\0') - ND_PRINT((ndo, "%c", ch)); - ND_TCHECK(*cp); - opt = *cp++; + ND_PRINT("%c", ch); + opt = GET_U_1(cp); + cp++; if (ZEROLENOPT(opt)) len = 1; else { - ND_TCHECK(*cp); - len = *cp++; /* total including type, len */ + len = GET_U_1(cp); + cp++; /* total including type, len */ if (len < 2 || len > hlen) goto bad; --hlen; /* account for length byte */ @@ -443,38 +462,38 @@ tcp_print(netdissect_options *ndo, datalen = 0; /* Bail if "l" bytes of data are not left or were not captured */ -#define LENCHECK(l) { if ((l) > hlen) goto bad; ND_TCHECK2(*cp, l); } +#define LENCHECK(l) { if ((l) > hlen) goto bad; ND_TCHECK_LEN(cp, l); } - ND_PRINT((ndo, "%s", tok2str(tcp_option_values, "unknown-%u", opt))); + ND_PRINT("%s", tok2str(tcp_option_values, "unknown-%u", opt)); switch (opt) { case TCPOPT_MAXSEG: datalen = 2; LENCHECK(datalen); - ND_PRINT((ndo, " %u", EXTRACT_16BITS(cp))); + ND_PRINT(" %u", GET_BE_U_2(cp)); break; case TCPOPT_WSCALE: datalen = 1; LENCHECK(datalen); - ND_PRINT((ndo, " %u", *cp)); + ND_PRINT(" %u", GET_U_1(cp)); break; case TCPOPT_SACK: datalen = len - 2; if (datalen % 8 != 0) { - ND_PRINT((ndo, " invalid sack")); + ND_PRINT(" invalid sack"); } else { uint32_t s, e; - ND_PRINT((ndo, " %d ", datalen / 8)); + ND_PRINT(" %u ", datalen / 8); for (i = 0; i < datalen; i += 8) { LENCHECK(i + 4); - s = EXTRACT_32BITS(cp + i); + s = GET_BE_U_4(cp + i); LENCHECK(i + 8); - e = EXTRACT_32BITS(cp + i + 4); + e = GET_BE_U_4(cp + i + 4); if (rev) { s -= thseq; e -= thseq; @@ -482,7 +501,7 @@ tcp_print(netdissect_options *ndo, s -= thack; e -= thack; } - ND_PRINT((ndo, "{%u:%u}", s, e)); + ND_PRINT("{%u:%u}", s, e); } } break; @@ -499,49 +518,51 @@ tcp_print(netdissect_options *ndo, */ datalen = 4; LENCHECK(datalen); - ND_PRINT((ndo, " %u", EXTRACT_32BITS(cp))); + ND_PRINT(" %u", GET_BE_U_4(cp)); break; case TCPOPT_TIMESTAMP: datalen = 8; LENCHECK(datalen); - ND_PRINT((ndo, " val %u ecr %u", - EXTRACT_32BITS(cp), - EXTRACT_32BITS(cp + 4))); + ND_PRINT(" val %u ecr %u", + GET_BE_U_4(cp), + GET_BE_U_4(cp + 4)); break; case TCPOPT_SIGNATURE: datalen = TCP_SIGLEN; LENCHECK(datalen); - ND_PRINT((ndo, " ")); + ND_PRINT(" "); #ifdef HAVE_LIBCRYPTO switch (tcp_verify_signature(ndo, ip, tp, bp + TH_OFF(tp) * 4, length, cp)) { case SIGNATURE_VALID: - ND_PRINT((ndo, "valid")); + ND_PRINT("valid"); break; case SIGNATURE_INVALID: - ND_PRINT((ndo, "invalid")); + nd_print_invalid(ndo); break; case CANT_CHECK_SIGNATURE: - ND_PRINT((ndo, "can't check - ")); + ND_PRINT("can't check - "); for (i = 0; i < TCP_SIGLEN; ++i) - ND_PRINT((ndo, "%02x", cp[i])); + ND_PRINT("%02x", + GET_U_1(cp + i)); break; } #else for (i = 0; i < TCP_SIGLEN; ++i) - ND_PRINT((ndo, "%02x", cp[i])); + ND_PRINT("%02x", GET_U_1(cp + i)); #endif break; case TCPOPT_SCPS: datalen = 2; LENCHECK(datalen); - ND_PRINT((ndo, " cap %02x id %u", cp[0], cp[1])); + ND_PRINT(" cap %02x id %u", GET_U_1(cp), + GET_U_1(cp + 1)); break; case TCPOPT_TCPAO: @@ -552,17 +573,19 @@ tcp_print(netdissect_options *ndo, * at this point.) */ if (datalen < 2) { - ND_PRINT((ndo, " invalid")); + nd_print_invalid(ndo); } else { LENCHECK(1); - ND_PRINT((ndo, " keyid %u", cp[0])); + ND_PRINT(" keyid %u", GET_U_1(cp)); LENCHECK(2); - ND_PRINT((ndo, " rnextkeyid %u", cp[1])); + ND_PRINT(" rnextkeyid %u", + GET_U_1(cp + 1)); if (datalen > 2) { - ND_PRINT((ndo, " mac 0x")); + ND_PRINT(" mac 0x"); for (i = 2; i < datalen; i++) { LENCHECK(i + 1); - ND_PRINT((ndo, "%02x", cp[i])); + ND_PRINT("%02x", + GET_U_1(cp + i)); } } } @@ -580,26 +603,43 @@ tcp_print(netdissect_options *ndo, case TCPOPT_UTO: datalen = 2; LENCHECK(datalen); - utoval = EXTRACT_16BITS(cp); - ND_PRINT((ndo, " 0x%x", utoval)); + utoval = GET_BE_U_2(cp); + ND_PRINT(" 0x%x", utoval); if (utoval & 0x0001) utoval = (utoval >> 1) * 60; else utoval >>= 1; - ND_PRINT((ndo, " %u", utoval)); + ND_PRINT(" %u", utoval); break; case TCPOPT_MPTCP: + { + const u_char *snapend_save; + int ret; + datalen = len - 2; LENCHECK(datalen); - if (!mptcp_print(ndo, cp-2, len, flags)) + /* Update the snapend to the end of the option + * before calling mptcp_print(). Some options + * (MPTCP or others) may be present after a + * MPTCP option. This prevents that, in + * mptcp_print(), the remaining length < the + * remaining caplen. + */ + snapend_save = ndo->ndo_snapend; + ndo->ndo_snapend = ND_MIN(cp - 2 + len, + ndo->ndo_snapend); + ret = mptcp_print(ndo, cp - 2, len, flags); + ndo->ndo_snapend = snapend_save; + if (!ret) goto bad; break; + } case TCPOPT_FASTOPEN: datalen = len - 2; LENCHECK(datalen); - ND_PRINT((ndo, " ")); + ND_PRINT(" "); print_tcp_fastopen_option(ndo, cp, datalen, FALSE); break; @@ -609,8 +649,8 @@ tcp_print(netdissect_options *ndo, if (datalen < 2) goto bad; /* RFC6994 */ - magic = EXTRACT_16BITS(cp); - ND_PRINT((ndo, "-")); + magic = GET_BE_U_2(cp); + ND_PRINT("-"); switch(magic) { @@ -620,7 +660,7 @@ tcp_print(netdissect_options *ndo, default: /* Unknown magic number */ - ND_PRINT((ndo, "%04x", magic)); + ND_PRINT("%04x", magic); break; } break; @@ -628,10 +668,10 @@ tcp_print(netdissect_options *ndo, default: datalen = len - 2; if (datalen) - ND_PRINT((ndo, " 0x")); + ND_PRINT(" 0x"); for (i = 0; i < datalen; ++i) { LENCHECK(i + 1); - ND_PRINT((ndo, "%02x", cp[i])); + ND_PRINT("%02x", GET_U_1(cp + i)); } break; } @@ -641,22 +681,22 @@ tcp_print(netdissect_options *ndo, hlen -= datalen; /* Check specification against observed length */ - ++datalen; /* option octet */ + ++datalen; /* option octet */ if (!ZEROLENOPT(opt)) - ++datalen; /* size octet */ + ++datalen; /* size octet */ if (datalen != len) - ND_PRINT((ndo, "[len %d]", len)); + ND_PRINT("[len %u]", len); ch = ','; if (opt == TCPOPT_EOL) break; } - ND_PRINT((ndo, "]")); + ND_PRINT("]"); } /* * Print length field before crawling down the stack. */ - ND_PRINT((ndo, ", length %u", length)); + ND_PRINT(", length %u", length); if (length <= 0) return; @@ -664,7 +704,17 @@ tcp_print(netdissect_options *ndo, /* * Decode payload if necessary. */ - bp += TH_OFF(tp) * 4; + header_len = TH_OFF(tp) * 4; + /* + * Do a bounds check before decoding the payload. + * At least the header data is required. + */ + if (!ND_TTEST_LEN(bp, header_len)) { + ND_PRINT(" [remaining caplen(%u) < header length(%u)]", + ND_BYTES_AVAILABLE_AFTER(bp), header_len); + nd_trunc_longjmp(ndo); + } + bp += header_len; if ((flags & TH_RST) && ndo->ndo_vflag) { print_tcp_rst_data(ndo, bp, length); return; @@ -678,6 +728,10 @@ tcp_print(netdissect_options *ndo, case PT_RESP: resp_print(ndo, bp, length); break; + case PT_DOMAIN: + /* over_tcp: TRUE, is_mdns: FALSE */ + domain_print(ndo, bp, length, TRUE, FALSE); + break; } return; } @@ -685,56 +739,50 @@ tcp_print(netdissect_options *ndo, if (IS_SRC_OR_DST_PORT(TELNET_PORT)) { telnet_print(ndo, bp, length); } else if (IS_SRC_OR_DST_PORT(SMTP_PORT)) { - ND_PRINT((ndo, ": ")); + ND_PRINT(": "); smtp_print(ndo, bp, length); + } else if (IS_SRC_OR_DST_PORT(WHOIS_PORT)) { + ND_PRINT(": "); + ndo->ndo_protocol = "whois"; /* needed by txtproto_print() */ + txtproto_print(ndo, bp, length, NULL, 0); /* RFC 3912 */ } else if (IS_SRC_OR_DST_PORT(BGP_PORT)) bgp_print(ndo, bp, length); else if (IS_SRC_OR_DST_PORT(PPTP_PORT)) pptp_print(ndo, bp); else if (IS_SRC_OR_DST_PORT(REDIS_PORT)) resp_print(ndo, bp, length); + else if (IS_SRC_OR_DST_PORT(SSH_PORT)) + ssh_print(ndo, bp, length); #ifdef ENABLE_SMB else if (IS_SRC_OR_DST_PORT(NETBIOS_SSN_PORT)) nbt_tcp_print(ndo, bp, length); - else if (IS_SRC_OR_DST_PORT(SMB_PORT)) - smb_tcp_print(ndo, bp, length); + else if (IS_SRC_OR_DST_PORT(SMB_PORT)) + smb_tcp_print(ndo, bp, length); #endif else if (IS_SRC_OR_DST_PORT(BEEP_PORT)) beep_print(ndo, bp, length); else if (IS_SRC_OR_DST_PORT(OPENFLOW_PORT_OLD) || IS_SRC_OR_DST_PORT(OPENFLOW_PORT_IANA)) openflow_print(ndo, bp, length); else if (IS_SRC_OR_DST_PORT(FTP_PORT)) { - ND_PRINT((ndo, ": ")); + ND_PRINT(": "); ftp_print(ndo, bp, length); } else if (IS_SRC_OR_DST_PORT(HTTP_PORT) || IS_SRC_OR_DST_PORT(HTTP_PORT_ALT)) { - ND_PRINT((ndo, ": ")); + ND_PRINT(": "); http_print(ndo, bp, length); } else if (IS_SRC_OR_DST_PORT(RTSP_PORT) || IS_SRC_OR_DST_PORT(RTSP_PORT_ALT)) { - ND_PRINT((ndo, ": ")); + ND_PRINT(": "); rtsp_print(ndo, bp, length); - } else if (length > 2 && - (IS_SRC_OR_DST_PORT(NAMESERVER_PORT))) { - /* domain_print() assumes it does not have to prepend a space before its - * own output to separate it from the output of the calling function. This - * works well with udp_print(), but requires a small prop here. - */ - ND_PRINT((ndo, " ")); - - /* - * TCP DNS query has 2byte length at the head. - * XXX packet could be unaligned, it can go strange - */ - ns_print(ndo, bp + 2, length - 2, 0); + } else if (IS_SRC_OR_DST_PORT(NAMESERVER_PORT)) { + /* over_tcp: TRUE, is_mdns: FALSE */ + domain_print(ndo, bp, length, TRUE, FALSE); } else if (IS_SRC_OR_DST_PORT(MSDP_PORT)) { msdp_print(ndo, bp, length); } else if (IS_SRC_OR_DST_PORT(RPKI_RTR_PORT)) { rpki_rtr_print(ndo, bp, length); - } - else if (length > 0 && (IS_SRC_OR_DST_PORT(LDP_PORT))) { + } else if (IS_SRC_OR_DST_PORT(LDP_PORT)) { ldp_print(ndo, bp, length); - } - else if ((IS_SRC_OR_DST_PORT(NFS_PORT)) && - length >= 4 && ND_TTEST2(*bp, 4)) { + } else if ((IS_SRC_OR_DST_PORT(NFS_PORT)) && + length >= 4 && ND_TTEST_4(bp)) { /* * If data present, header length valid, and NFS port used, * assume NFS. @@ -742,38 +790,40 @@ tcp_print(netdissect_options *ndo, * to NFS print routines. */ uint32_t fraglen; - register const struct sunrpc_msg *rp; + const struct sunrpc_msg *rp; enum sunrpc_msg_type direction; - fraglen = EXTRACT_32BITS(bp) & 0x7FFFFFFF; + fraglen = GET_BE_U_4(bp) & 0x7FFFFFFF; if (fraglen > (length) - 4) fraglen = (length) - 4; rp = (const struct sunrpc_msg *)(bp + 4); - if (ND_TTEST(rp->rm_direction)) { - direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction); + if (ND_TTEST_4(rp->rm_direction)) { + direction = (enum sunrpc_msg_type) GET_BE_U_4(rp->rm_direction); if (dport == NFS_PORT && direction == SUNRPC_CALL) { - ND_PRINT((ndo, ": NFS request xid %u ", EXTRACT_32BITS(&rp->rm_xid))); - nfsreq_print_noaddr(ndo, (const u_char *)rp, fraglen, (const u_char *)ip); + ND_PRINT(": NFS request xid %u ", + GET_BE_U_4(rp->rm_xid)); + nfsreq_noaddr_print(ndo, (const u_char *)rp, fraglen, (const u_char *)ip); return; } if (sport == NFS_PORT && direction == SUNRPC_REPLY) { - ND_PRINT((ndo, ": NFS reply xid %u ", EXTRACT_32BITS(&rp->rm_xid))); - nfsreply_print_noaddr(ndo, (const u_char *)rp, fraglen, (const u_char *)ip); + ND_PRINT(": NFS reply xid %u ", + GET_BE_U_4(rp->rm_xid)); + nfsreply_noaddr_print(ndo, (const u_char *)rp, fraglen, (const u_char *)ip); return; } } } return; - bad: - ND_PRINT((ndo, "[bad opt]")); +bad: + ND_PRINT("[bad opt]"); if (ch != '\0') - ND_PRINT((ndo, ">")); + ND_PRINT("]"); return; - trunc: - ND_PRINT((ndo, "[|tcp]")); +trunc: + nd_print_trunc(ndo); if (ch != '\0') - ND_PRINT((ndo, ">")); + ND_PRINT(">"); } /* @@ -793,43 +843,45 @@ tcp_print(netdissect_options *ndo, static void print_tcp_rst_data(netdissect_options *ndo, - register const u_char *sp, u_int length) + const u_char *sp, u_int length) { - int c; + u_char c; - ND_PRINT((ndo, ND_TTEST2(*sp, length) ? " [RST" : " [!RST")); + ND_PRINT(ND_TTEST_LEN(sp, length) ? " [RST" : " [!RST"); if (length > MAX_RST_DATA_LEN) { length = MAX_RST_DATA_LEN; /* can use -X for longer */ - ND_PRINT((ndo, "+")); /* indicate we truncate */ + ND_PRINT("+"); /* indicate we truncate */ } - ND_PRINT((ndo, " ")); - while (length-- && sp < ndo->ndo_snapend) { - c = *sp++; - safeputchar(ndo, c); + ND_PRINT(" "); + while (length && sp < ndo->ndo_snapend) { + c = GET_U_1(sp); + sp++; + fn_print_char(ndo, c); + length--; } - ND_PRINT((ndo, "]")); + ND_PRINT("]"); } static void -print_tcp_fastopen_option(netdissect_options *ndo, register const u_char *cp, +print_tcp_fastopen_option(netdissect_options *ndo, const u_char *cp, u_int datalen, int exp) { u_int i; if (exp) - ND_PRINT((ndo, "tfo")); + ND_PRINT("tfo"); if (datalen == 0) { /* Fast Open Cookie Request */ - ND_PRINT((ndo, " cookiereq")); + ND_PRINT(" cookiereq"); } else { /* Fast Open Cookie */ if (datalen % 2 != 0 || datalen < 4 || datalen > 16) { - ND_PRINT((ndo, " invalid")); + nd_print_invalid(ndo); } else { - ND_PRINT((ndo, " cookie ")); + ND_PRINT(" cookie "); for (i = 0; i < datalen; ++i) - ND_PRINT((ndo, "%02x", cp[i])); + ND_PRINT("%02x", GET_U_1(cp + i)); } } } @@ -839,7 +891,7 @@ USES_APPLE_DEPRECATED_API static int tcp_verify_signature(netdissect_options *ndo, const struct ip *ip, const struct tcphdr *tp, - const u_char *data, int length, const u_char *rcvsig) + const u_char *data, u_int length, const u_char *rcvsig) { struct tcphdr tp1; u_char sig[TCP_SIGLEN]; @@ -850,15 +902,15 @@ tcp_verify_signature(netdissect_options *ndo, uint32_t len32; uint8_t nxt; - if (data + length > ndo->ndo_snapend) { - ND_PRINT((ndo, "snaplen too short, ")); - return (CANT_CHECK_SIGNATURE); - } + if (data + length > ndo->ndo_snapend) { + ND_PRINT("snaplen too short, "); + return (CANT_CHECK_SIGNATURE); + } tp1 = *tp; if (ndo->ndo_sigsecret == NULL) { - ND_PRINT((ndo, "shared secret not supplied with -M, ")); + ND_PRINT("shared secret not supplied with -M, "); return (CANT_CHECK_SIGNATURE); } @@ -871,14 +923,14 @@ tcp_verify_signature(netdissect_options *ndo, MD5_Update(&ctx, (const char *)&ip->ip_dst, sizeof(ip->ip_dst)); MD5_Update(&ctx, (const char *)&zero_proto, sizeof(zero_proto)); MD5_Update(&ctx, (const char *)&ip->ip_p, sizeof(ip->ip_p)); - tlen = EXTRACT_16BITS(&ip->ip_len) - IP_HL(ip) * 4; + tlen = GET_BE_U_2(ip->ip_len) - IP_HL(ip) * 4; tlen = htons(tlen); MD5_Update(&ctx, (const char *)&tlen, sizeof(tlen)); } else if (IP_V(ip) == 6) { ip6 = (const struct ip6_hdr *)ip; MD5_Update(&ctx, (const char *)&ip6->ip6_src, sizeof(ip6->ip6_src)); MD5_Update(&ctx, (const char *)&ip6->ip6_dst, sizeof(ip6->ip6_dst)); - len32 = htonl(EXTRACT_16BITS(&ip6->ip6_plen)); + len32 = htonl(GET_BE_U_2(ip6->ip6_plen)); MD5_Update(&ctx, (const char *)&len32, sizeof(len32)); nxt = 0; MD5_Update(&ctx, (const char *)&nxt, sizeof(nxt)); @@ -887,7 +939,7 @@ tcp_verify_signature(netdissect_options *ndo, nxt = IPPROTO_TCP; MD5_Update(&ctx, (const char *)&nxt, sizeof(nxt)); } else { - ND_PRINT((ndo, "IP version not 4 or 6, ")); + ND_PRINT("IP version not 4 or 6, "); return (CANT_CHECK_SIGNATURE); } @@ -895,10 +947,10 @@ tcp_verify_signature(netdissect_options *ndo, * Step 2: Update MD5 hash with TCP header, excluding options. * The TCP checksum must be set to zero. */ - savecsum = tp1.th_sum; - tp1.th_sum = 0; + memcpy(&savecsum, tp1.th_sum, sizeof(savecsum)); + memset(tp1.th_sum, 0, sizeof(tp1.th_sum)); MD5_Update(&ctx, (const char *)&tp1, sizeof(struct tcphdr)); - tp1.th_sum = savecsum; + memcpy(tp1.th_sum, &savecsum, sizeof(tp1.th_sum)); /* * Step 3: Update MD5 hash with TCP segment data, if present. */ @@ -917,10 +969,3 @@ tcp_verify_signature(netdissect_options *ndo, } USES_APPLE_RST #endif /* HAVE_LIBCRYPTO */ - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/print-telnet.c b/contrib/tcpdump/print-telnet.c index 10fad9fef7..b0283f2047 100644 --- a/contrib/tcpdump/print-telnet.c +++ b/contrib/tcpdump/print-telnet.c @@ -48,19 +48,16 @@ /* \summary: Telnet option printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include #include "netdissect.h" +#include "extract.h" -static const char tstr[] = " [|telnet]"; - -#define TELCMDS -#define TELOPTS /* NetBSD: telnet.h,v 1.9 2001/06/11 01:50:50 wiz Exp */ @@ -90,15 +87,11 @@ static const char tstr[] = " [|telnet]"; #define SYNCH 242 /* for telfunc calls */ -#ifdef TELCMDS static const char *telcmds[] = { "EOF", "SUSP", "ABORT", "EOR", "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC", "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", 0, }; -#else -extern char *telcmds[]; -#endif #define TELCMD_FIRST xEOF #define TELCMD_LAST IAC @@ -151,7 +144,6 @@ extern char *telcmds[]; #define NTELOPTS (1+TELOPT_NEW_ENVIRON) -#ifdef TELOPTS static const char *telopts[NTELOPTS+1] = { "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME", "STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP", @@ -169,7 +161,6 @@ static const char *telopts[NTELOPTS+1] = { #define TELOPT_LAST TELOPT_NEW_ENVIRON #define TELOPT_OK(x) ((unsigned int)(x) <= TELOPT_LAST) #define TELOPT(x) telopts[(x)-TELOPT_FIRST] -#endif /* sub-option qualifiers */ #define TELQUAL_IS 0 /* option is... */ @@ -396,8 +387,8 @@ telnet_parse(netdissect_options *ndo, const u_char *sp, u_int length, int print) do { \ if (length < 1) \ goto pktend; \ - ND_TCHECK(*sp); \ - c = *sp++; \ + c = GET_U_1(sp); \ + sp++; \ length--; \ } while (0) @@ -409,7 +400,7 @@ telnet_parse(netdissect_options *ndo, const u_char *sp, u_int length, int print) FETCH(c, sp, length); if (c == IAC) { /* ! */ if (print) - ND_PRINT((ndo, "IAC IAC")); + ND_PRINT("IAC IAC"); goto done; } @@ -427,23 +418,21 @@ telnet_parse(netdissect_options *ndo, const u_char *sp, u_int length, int print) FETCH(x, sp, length); if (x >= 0 && x < NTELOPTS) { if (print) - ND_PRINT((ndo, "%s %s", telcmds[i], telopts[x])); + ND_PRINT("%s %s", telcmds[i], telopts[x]); } else { if (print) - ND_PRINT((ndo, "%s %#x", telcmds[i], x)); + ND_PRINT("%s %#x", telcmds[i], x); } if (c != SB) break; /* IAC SB .... IAC SE */ p = sp; while (length > (u_int)(p + 1 - sp)) { - ND_TCHECK2(*p, 2); - if (p[0] == IAC && p[1] == SE) + if (GET_U_1(p) == IAC && GET_U_1(p + 1) == SE) break; p++; } - ND_TCHECK(*p); - if (*p != IAC) + if (GET_U_1(p) != IAC) goto pktend; switch (x) { @@ -452,54 +441,52 @@ telnet_parse(netdissect_options *ndo, const u_char *sp, u_int length, int print) break; FETCH(c, sp, length); if (print) - ND_PRINT((ndo, " %s", STR_OR_ID(c, authcmd))); + ND_PRINT(" %s", STR_OR_ID(c, authcmd)); if (p <= sp) break; FETCH(c, sp, length); if (print) - ND_PRINT((ndo, " %s", STR_OR_ID(c, authtype))); + ND_PRINT(" %s", STR_OR_ID(c, authtype)); break; case TELOPT_ENCRYPT: if (p <= sp) break; FETCH(c, sp, length); if (print) - ND_PRINT((ndo, " %s", STR_OR_ID(c, enccmd))); + ND_PRINT(" %s", STR_OR_ID(c, enccmd)); if (p <= sp) break; FETCH(c, sp, length); if (print) - ND_PRINT((ndo, " %s", STR_OR_ID(c, enctype))); + ND_PRINT(" %s", STR_OR_ID(c, enctype)); break; default: if (p <= sp) break; FETCH(c, sp, length); if (print) - ND_PRINT((ndo, " %s", STR_OR_ID(c, cmds))); + ND_PRINT(" %s", STR_OR_ID(c, cmds)); break; } while (p > sp) { FETCH(x, sp, length); if (print) - ND_PRINT((ndo, " %#x", x)); + ND_PRINT(" %#x", x); } /* terminating IAC SE */ if (print) - ND_PRINT((ndo, " SE")); + ND_PRINT(" SE"); sp += 2; break; default: if (print) - ND_PRINT((ndo, "%s", telcmds[i])); + ND_PRINT("%s", telcmds[i]); goto done; } done: - return sp - osp; + return (int)(sp - osp); -trunc: - ND_PRINT((ndo, "%s", tstr)); pktend: return -1; #undef FETCH @@ -512,10 +499,10 @@ telnet_print(netdissect_options *ndo, const u_char *sp, u_int length) const u_char *osp; int l; + ndo->ndo_protocol = "telnet"; osp = sp; - ND_TCHECK(*sp); - while (length > 0 && *sp == IAC) { + while (length > 0 && GET_U_1(sp) == IAC) { /* * Parse the Telnet command without printing it, * to determine its length. @@ -529,29 +516,25 @@ telnet_print(netdissect_options *ndo, const u_char *sp, u_int length) */ if (ndo->ndo_Xflag && 2 < ndo->ndo_vflag) { if (first) - ND_PRINT((ndo, "\nTelnet:")); - hex_print_with_offset(ndo, "\n", sp, l, sp - osp); + ND_PRINT("\nTelnet:"); + hex_print_with_offset(ndo, "\n", sp, l, (u_int)(sp - osp)); if (l > 8) - ND_PRINT((ndo, "\n\t\t\t\t")); + ND_PRINT("\n\t\t\t\t"); else - ND_PRINT((ndo, "%*s\t", (8 - l) * 3, "")); + ND_PRINT("%*s\t", (8 - l) * 3, ""); } else - ND_PRINT((ndo, "%s", (first) ? " [telnet " : ", ")); + ND_PRINT("%s", (first) ? " [telnet " : ", "); (void)telnet_parse(ndo, sp, length, 1); first = 0; sp += l; length -= l; - ND_TCHECK(*sp); } if (!first) { if (ndo->ndo_Xflag && 2 < ndo->ndo_vflag) - ND_PRINT((ndo, "\n")); + ND_PRINT("\n"); else - ND_PRINT((ndo, "]")); + ND_PRINT("]"); } - return; -trunc: - ND_PRINT((ndo, "%s", tstr)); } diff --git a/contrib/tcpdump/print-tftp.c b/contrib/tcpdump/print-tftp.c index 6600c9cf67..39fc6964b8 100644 --- a/contrib/tcpdump/print-tftp.c +++ b/contrib/tcpdump/print-tftp.c @@ -22,12 +22,10 @@ /* \summary: Trivial File Transfer Protocol (TFTP) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include - -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "extract.h" @@ -58,7 +56,6 @@ #define EEXISTS 6 /* file already exists */ #define ENOUSER 7 /* no such user */ -static const char tstr[] = " [|tftp]"; /* op code to string mapping */ static const struct tok op2str[] = { @@ -89,22 +86,25 @@ static const struct tok err2str[] = { */ void tftp_print(netdissect_options *ndo, - register const u_char *bp, u_int length) + const u_char *bp, u_int length) { - register const char *cp; - register int opcode; + const char *cp; + u_int opcode; u_int ui; + ndo->ndo_protocol = "tftp"; + + /* Print protocol */ + nd_print_protocol_caps(ndo); /* Print length */ - ND_PRINT((ndo, " %d", length)); + ND_PRINT(", length %u", length); /* Print tftp request type */ if (length < 2) goto trunc; - ND_TCHECK_16BITS(bp); - opcode = EXTRACT_16BITS(bp); - cp = tok2str(op2str, "tftp-#%d", opcode); - ND_PRINT((ndo, " %s", cp)); + opcode = GET_BE_U_2(bp); + cp = tok2str(op2str, "tftp-#%u", opcode); + ND_PRINT(", %s", cp); /* Bail if bogus opcode */ if (*cp == 't') return; @@ -117,11 +117,11 @@ tftp_print(netdissect_options *ndo, case WRQ: if (length == 0) goto trunc; - ND_PRINT((ndo, " ")); + ND_PRINT(" "); /* Print filename */ - ND_PRINT((ndo, "\"")); - ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend); - ND_PRINT((ndo, "\"")); + ND_PRINT("\""); + ui = nd_printztn(ndo, bp, length, ndo->ndo_snapend); + ND_PRINT("\""); if (ui == 0) goto trunc; bp += ui; @@ -130,8 +130,8 @@ tftp_print(netdissect_options *ndo, /* Print the mode - RRQ and WRQ only */ if (length == 0) goto trunc; /* no mode */ - ND_PRINT((ndo, " ")); - ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend); + ND_PRINT(" "); + ui = nd_printztn(ndo, bp, length, ndo->ndo_snapend); if (ui == 0) goto trunc; bp += ui; @@ -139,10 +139,9 @@ tftp_print(netdissect_options *ndo, /* Print options, if any */ while (length != 0) { - ND_TCHECK(*bp); - if (*bp != '\0') - ND_PRINT((ndo, " ")); - ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend); + if (GET_U_1(bp) != '\0') + ND_PRINT(" "); + ui = nd_printztn(ndo, bp, length, ndo->ndo_snapend); if (ui == 0) goto trunc; bp += ui; @@ -153,10 +152,9 @@ tftp_print(netdissect_options *ndo, case OACK: /* Print options */ while (length != 0) { - ND_TCHECK(*bp); - if (*bp != '\0') - ND_PRINT((ndo, " ")); - ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend); + if (GET_U_1(bp) != '\0') + ND_PRINT(" "); + ui = nd_printztn(ndo, bp, length, ndo->ndo_snapend); if (ui == 0) goto trunc; bp += ui; @@ -168,36 +166,33 @@ tftp_print(netdissect_options *ndo, case DATA: if (length < 2) goto trunc; /* no block number */ - ND_TCHECK_16BITS(bp); - ND_PRINT((ndo, " block %d", EXTRACT_16BITS(bp))); + ND_PRINT(" block %u", GET_BE_U_2(bp)); break; case TFTP_ERROR: /* Print error code string */ if (length < 2) goto trunc; /* no error code */ - ND_TCHECK_16BITS(bp); - ND_PRINT((ndo, " %s", tok2str(err2str, "tftp-err-#%d \"", - EXTRACT_16BITS(bp)))); + ND_PRINT(" %s", tok2str(err2str, "tftp-err-#%u \"", + GET_BE_U_2(bp))); bp += 2; length -= 2; /* Print error message string */ if (length == 0) goto trunc; /* no error message */ - ND_PRINT((ndo, " \"")); - ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend); - ND_PRINT((ndo, "\"")); + ND_PRINT(" \""); + ui = nd_printztn(ndo, bp, length, ndo->ndo_snapend); + ND_PRINT("\""); if (ui == 0) goto trunc; break; default: /* We shouldn't get here */ - ND_PRINT((ndo, "(unknown #%d)", opcode)); + ND_PRINT("(unknown #%u)", opcode); break; } return; trunc: - ND_PRINT((ndo, "%s", tstr)); - return; + nd_print_trunc(ndo); } diff --git a/contrib/tcpdump/print-timed.c b/contrib/tcpdump/print-timed.c index 6aa7a821eb..ebd0ac8adc 100644 --- a/contrib/tcpdump/print-timed.c +++ b/contrib/tcpdump/print-timed.c @@ -19,37 +19,33 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -/* \summary: BSD time daemon protocol printer */ +/* \summary: Berkeley UNIX Time Synchronization Protocol */ + +/* specification: https://docs.freebsd.org/44doc/smm/12.timed/paper.pdf */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "extract.h" -/* - * Time Synchronization Protocol - * - * http://docs.freebsd.org/44doc/smm/12.timed/paper.pdf - */ - struct tsp_timeval { - uint32_t tv_sec; - uint32_t tv_usec; + nd_int32_t tv_sec; + nd_int32_t tv_usec; }; struct tsp { - uint8_t tsp_type; - uint8_t tsp_vers; - uint16_t tsp_seq; + nd_uint8_t tsp_type; + nd_uint8_t tsp_vers; + nd_uint16_t tsp_seq; union { struct tsp_timeval tspu_time; - int8_t tspu_hopcnt; + nd_int8_t tspu_hopcnt; } tsp_u; - int8_t tsp_name[256]; + nd_byte tsp_name[256]; /* null-terminated string up to 256 */ }; #define tsp_time tsp_u.tspu_time @@ -83,68 +79,75 @@ struct tsp { #define TSP_SETDATE 22 /* New from date command */ #define TSP_SETDATEREQ 23 /* New remote for above */ #define TSP_LOOP 24 /* loop detection packet */ - -#define TSPTYPENUMBER 25 - -static const char tstr[] = "[|timed]"; - -static const char *tsptype[TSPTYPENUMBER] = - { "ANY", "ADJTIME", "ACK", "MASTERREQ", "MASTERACK", "SETTIME", "MASTERUP", - "SLAVEUP", "ELECTION", "ACCEPT", "REFUSE", "CONFLICT", "RESOLVE", "QUIT", - "DATE", "DATEREQ", "DATEACK", "TRACEON", "TRACEOFF", "MSITE", "MSITEREQ", - "TEST", "SETDATE", "SETDATEREQ", "LOOP" }; +static const struct tok tsptype_str[] = { + { TSP_ANY, "TSP_ANY" }, + { TSP_ADJTIME, "TSP_ADJTIME" }, + { TSP_ACK, "TSP_ACK" }, + { TSP_MASTERREQ, "TSP_MASTERREQ" }, + { TSP_MASTERACK, "TSP_MASTERACK" }, + { TSP_SETTIME, "TSP_SETTIME" }, + { TSP_MASTERUP, "TSP_MASTERUP" }, + { TSP_SLAVEUP, "TSP_SLAVEUP" }, + { TSP_ELECTION, "TSP_ELECTION" }, + { TSP_ACCEPT, "TSP_ACCEPT" }, + { TSP_REFUSE, "TSP_REFUSE" }, + { TSP_CONFLICT, "TSP_CONFLICT" }, + { TSP_RESOLVE, "TSP_RESOLVE" }, + { TSP_QUIT, "TSP_QUIT" }, + { TSP_DATE, "TSP_DATE" }, + { TSP_DATEREQ, "TSP_DATEREQ" }, + { TSP_DATEACK, "TSP_DATEACK" }, + { TSP_TRACEON, "TSP_TRACEON" }, + { TSP_TRACEOFF, "TSP_TRACEOFF" }, + { TSP_MSITE, "TSP_MSITE" }, + { TSP_MSITEREQ, "TSP_MSITEREQ" }, + { TSP_TEST, "TSP_TEST" }, + { TSP_SETDATE, "TSP_SETDATE" }, + { TSP_SETDATEREQ, "TSP_SETDATEREQ" }, + { TSP_LOOP, "TSP_LOOP" }, + { 0, NULL } +}; void timed_print(netdissect_options *ndo, - register const u_char *bp) + const u_char *bp) { const struct tsp *tsp = (const struct tsp *)bp; - long sec, usec; + uint8_t tsp_type; + int sec, usec; - ND_TCHECK(tsp->tsp_type); - if (tsp->tsp_type < TSPTYPENUMBER) - ND_PRINT((ndo, "TSP_%s", tsptype[tsp->tsp_type])); - else - ND_PRINT((ndo, "(tsp_type %#x)", tsp->tsp_type)); + ndo->ndo_protocol = "timed"; + tsp_type = GET_U_1(tsp->tsp_type); + ND_PRINT("%s", tok2str(tsptype_str, "(tsp_type %#x)", tsp_type)); - ND_TCHECK(tsp->tsp_vers); - ND_PRINT((ndo, " vers %u", tsp->tsp_vers)); + ND_PRINT(" vers %u", GET_U_1(tsp->tsp_vers)); - ND_TCHECK(tsp->tsp_seq); - ND_PRINT((ndo, " seq %u", tsp->tsp_seq)); + ND_PRINT(" seq %u", GET_BE_U_2(tsp->tsp_seq)); - switch (tsp->tsp_type) { + switch (tsp_type) { case TSP_LOOP: - ND_TCHECK(tsp->tsp_hopcnt); - ND_PRINT((ndo, " hopcnt %u", tsp->tsp_hopcnt)); + ND_PRINT(" hopcnt %u", GET_U_1(tsp->tsp_hopcnt)); break; case TSP_SETTIME: case TSP_ADJTIME: case TSP_SETDATE: case TSP_SETDATEREQ: - ND_TCHECK(tsp->tsp_time); - sec = EXTRACT_32BITS(&tsp->tsp_time.tv_sec); - usec = EXTRACT_32BITS(&tsp->tsp_time.tv_usec); + sec = GET_BE_S_4(tsp->tsp_time.tv_sec); + usec = GET_BE_S_4(tsp->tsp_time.tv_usec); /* XXX The comparison below is always false? */ if (usec < 0) /* invalid, skip the rest of the packet */ return; - ND_PRINT((ndo, " time ")); + ND_PRINT(" time "); if (sec < 0 && usec != 0) { sec++; if (sec == 0) - ND_PRINT((ndo, "-")); + ND_PRINT("-"); usec = 1000000 - usec; } - ND_PRINT((ndo, "%ld.%06ld", sec, usec)); + ND_PRINT("%d.%06d", sec, usec); break; } - ND_TCHECK(tsp->tsp_name); - ND_PRINT((ndo, " name ")); - if (fn_print(ndo, (const u_char *)tsp->tsp_name, (const u_char *)tsp->tsp_name + sizeof(tsp->tsp_name))) - goto trunc; - return; - -trunc: - ND_PRINT((ndo, " %s", tstr)); + ND_PRINT(" name "); + nd_printjnp(ndo, tsp->tsp_name, sizeof(tsp->tsp_name)); } diff --git a/contrib/tcpdump/print-tipc.c b/contrib/tcpdump/print-tipc.c index 4d8848fc06..54179a4ea6 100644 --- a/contrib/tcpdump/print-tipc.c +++ b/contrib/tcpdump/print-tipc.c @@ -23,22 +23,20 @@ /* * specification: - * http://tipc.sourceforge.net/doc/draft-spec-tipc-07.html - * http://tipc.sourceforge.net/doc/tipc_message_formats.html + * https://web.archive.org/web/20150302152944/http://tipc.sourceforge.net/doc/draft-spec-tipc-07.html + * https://web.archive.org/web/20161025110514/http://tipc.sourceforge.net/doc/tipc_message_formats.html */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" -#include "ether.h" #include "ethertype.h" #include "extract.h" -static const char tstr[] = "[|TIPC]"; #define TIPC_USER_LOW_IMPORTANCE 0 #define TIPC_USER_MEDIUM_IMPORTANCE 1 @@ -63,14 +61,14 @@ static const char tstr[] = "[|TIPC]"; #define TIPC_NODE(addr) (((addr) >> 0) & 0xFFF) struct tipc_pkthdr { - uint32_t w0; - uint32_t w1; + nd_uint32_t w0; + nd_uint32_t w1; }; #define TIPC_VER(w0) (((w0) >> 29) & 0x07) #define TIPC_USER(w0) (((w0) >> 25) & 0x0F) #define TIPC_HSIZE(w0) (((w0) >> 21) & 0x0F) -#define TIPC_MSIZE(w0) (((w0) >> 0) & 0xFFFF) +#define TIPC_MSIZE(w0) (((w0) >> 0) & 0x1FFFF) #define TIPC_MTYPE(w1) (((w1) >> 29) & 0x07) #define TIPC_BROADCAST_ACK(w1) (((w1) >> 0) & 0xFFFF) #define TIPC_LINK_ACK(w2) (((w2) >> 16) & 0xFFFF) @@ -107,30 +105,30 @@ static const struct tok tipc_linkconf_mtype_values[] = { }; struct payload_tipc_pkthdr { - uint32_t w0; - uint32_t w1; - uint32_t w2; - uint32_t prev_node; - uint32_t orig_port; - uint32_t dest_port; - uint32_t orig_node; - uint32_t dest_node; - uint32_t name_type; - uint32_t w9; - uint32_t wA; + nd_uint32_t w0; + nd_uint32_t w1; + nd_uint32_t w2; + nd_uint32_t prev_node; + nd_uint32_t orig_port; + nd_uint32_t dest_port; + nd_uint32_t orig_node; + nd_uint32_t dest_node; + nd_uint32_t name_type; + nd_uint32_t w9; + nd_uint32_t wA; }; struct internal_tipc_pkthdr { - uint32_t w0; - uint32_t w1; - uint32_t w2; - uint32_t prev_node; - uint32_t w4; - uint32_t w5; - uint32_t orig_node; - uint32_t dest_node; - uint32_t trans_seq; - uint32_t w9; + nd_uint32_t w0; + nd_uint32_t w1; + nd_uint32_t w2; + nd_uint32_t prev_node; + nd_uint32_t w4; + nd_uint32_t w5; + nd_uint32_t orig_node; + nd_uint32_t dest_node; + nd_uint32_t trans_seq; + nd_uint32_t w9; }; #define TIPC_SEQ_GAP(w1) (((w1) >> 16) & 0x1FFF) @@ -143,13 +141,13 @@ struct internal_tipc_pkthdr { #define TIPC_LINK_TOL(w9) (((w9) >> 0) & 0xFFFF) struct link_conf_tipc_pkthdr { - uint32_t w0; - uint32_t w1; - uint32_t dest_domain; - uint32_t prev_node; - uint32_t ntwrk_id; - uint32_t w5; - uint8_t media_address[16]; + nd_uint32_t w0; + nd_uint32_t w1; + nd_uint32_t dest_domain; + nd_uint32_t prev_node; + nd_uint32_t ntwrk_id; + nd_uint32_t w5; + nd_byte media_address[16]; }; #define TIPC_NODE_SIG(w1) (((w1) >> 0) & 0xFFFF) @@ -172,29 +170,27 @@ print_payload(netdissect_options *ndo, const struct payload_tipc_pkthdr *ap) u_int orig_node; u_int dest_node; - ND_TCHECK(ap->dest_port); - w0 = EXTRACT_32BITS(&ap->w0); + w0 = GET_BE_U_4(ap->w0); user = TIPC_USER(w0); hsize = TIPC_HSIZE(w0); msize = TIPC_MSIZE(w0); - w1 = EXTRACT_32BITS(&ap->w1); + w1 = GET_BE_U_4(ap->w1); mtype = TIPC_MTYPE(w1); - prev_node = EXTRACT_32BITS(&ap->prev_node); - orig_port = EXTRACT_32BITS(&ap->orig_port); - dest_port = EXTRACT_32BITS(&ap->dest_port); + prev_node = GET_BE_U_4(ap->prev_node); + orig_port = GET_BE_U_4(ap->orig_port); + dest_port = GET_BE_U_4(ap->dest_port); if (hsize <= 6) { - ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u:%u > %u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s", + ND_PRINT("TIPC v%u.0 %u.%u.%u:%u > %u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s", TIPC_VER(w0), TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node), orig_port, dest_port, hsize*4, msize, tok2str(tipcuser_values, "unknown", user), - tok2str(tipcmtype_values, "Unknown", mtype))); + tok2str(tipcmtype_values, "Unknown", mtype)); } else { - ND_TCHECK(ap->dest_node); - orig_node = EXTRACT_32BITS(&ap->orig_node); - dest_node = EXTRACT_32BITS(&ap->dest_node); - ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u:%u > %u.%u.%u:%u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s", + orig_node = GET_BE_U_4(ap->orig_node); + dest_node = GET_BE_U_4(ap->dest_node); + ND_PRINT("TIPC v%u.0 %u.%u.%u:%u > %u.%u.%u:%u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s", TIPC_VER(w0), TIPC_ZONE(orig_node), TIPC_CLUSTER(orig_node), TIPC_NODE(orig_node), orig_port, @@ -202,22 +198,18 @@ print_payload(netdissect_options *ndo, const struct payload_tipc_pkthdr *ap) dest_port, hsize*4, msize, tok2str(tipcuser_values, "unknown", user), - tok2str(tipcmtype_values, "Unknown", mtype))); + tok2str(tipcmtype_values, "Unknown", mtype)); if (ndo->ndo_vflag) { broadcast_ack = TIPC_BROADCAST_ACK(w1); - w2 = EXTRACT_32BITS(&ap->w2); + w2 = GET_BE_U_4(ap->w2); link_ack = TIPC_LINK_ACK(w2); link_seq = TIPC_LINK_SEQ(w2); - ND_PRINT((ndo, "\n\tPrevious Node %u.%u.%u, Broadcast Ack %u, Link Ack %u, Link Sequence %u", + ND_PRINT("\n\tPrevious Node %u.%u.%u, Broadcast Ack %u, Link Ack %u, Link Sequence %u", TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node), - broadcast_ack, link_ack, link_seq)); + broadcast_ack, link_ack, link_seq); } } - return; - -trunc: - ND_PRINT((ndo, "%s", tstr)); } static void @@ -242,50 +234,44 @@ print_internal(netdissect_options *ndo, const struct internal_tipc_pkthdr *ap) u_int msg_cnt; u_int link_tol; - ND_TCHECK(ap->dest_node); - w0 = EXTRACT_32BITS(&ap->w0); + w0 = GET_BE_U_4(ap->w0); user = TIPC_USER(w0); hsize = TIPC_HSIZE(w0); msize = TIPC_MSIZE(w0); - w1 = EXTRACT_32BITS(&ap->w1); + w1 = GET_BE_U_4(ap->w1); mtype = TIPC_MTYPE(w1); - orig_node = EXTRACT_32BITS(&ap->orig_node); - dest_node = EXTRACT_32BITS(&ap->dest_node); - ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u > %u.%u.%u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s (0x%08x)", + orig_node = GET_BE_U_4(ap->orig_node); + dest_node = GET_BE_U_4(ap->dest_node); + ND_PRINT("TIPC v%u.0 %u.%u.%u > %u.%u.%u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s (0x%08x)", TIPC_VER(w0), TIPC_ZONE(orig_node), TIPC_CLUSTER(orig_node), TIPC_NODE(orig_node), TIPC_ZONE(dest_node), TIPC_CLUSTER(dest_node), TIPC_NODE(dest_node), hsize*4, msize, tok2str(tipcuser_values, "unknown", user), - tok2str(tipcmtype_values, "Unknown", mtype), w1)); + tok2str(tipcmtype_values, "Unknown", mtype), w1); if (ndo->ndo_vflag) { - ND_TCHECK(*ap); seq_gap = TIPC_SEQ_GAP(w1); broadcast_ack = TIPC_BROADCAST_ACK(w1); - w2 = EXTRACT_32BITS(&ap->w2); + w2 = GET_BE_U_4(ap->w2); bc_gap_after = TIPC_BC_GAP_AFTER(w2); bc_gap_to = TIPC_BC_GAP_TO(w2); - prev_node = EXTRACT_32BITS(&ap->prev_node); - w4 = EXTRACT_32BITS(&ap->w4); + prev_node = GET_BE_U_4(ap->prev_node); + w4 = GET_BE_U_4(ap->w4); last_sent_frag = TIPC_LAST_SENT_FRAG(w4); next_sent_frag = TIPC_NEXT_SENT_FRAG(w4); - w5 = EXTRACT_32BITS(&ap->w5); + w5 = GET_BE_U_4(ap->w5); sess_no = TIPC_SESS_NO(w5); - trans_seq = EXTRACT_32BITS(&ap->trans_seq); - w9 = EXTRACT_32BITS(&ap->w9); + trans_seq = GET_BE_U_4(ap->trans_seq); + w9 = GET_BE_U_4(ap->w9); msg_cnt = TIPC_MSG_CNT(w9); link_tol = TIPC_LINK_TOL(w9); - ND_PRINT((ndo, "\n\tPrevious Node %u.%u.%u, Session No. %u, Broadcast Ack %u, Sequence Gap %u, Broadcast Gap After %u, Broadcast Gap To %u, Last Sent Packet No. %u, Next sent Packet No. %u, Transport Sequence %u, msg_count %u, Link Tolerance %u", + ND_PRINT("\n\tPrevious Node %u.%u.%u, Session No. %u, Broadcast Ack %u, Sequence Gap %u, Broadcast Gap After %u, Broadcast Gap To %u, Last Sent Packet No. %u, Next sent Packet No. %u, Transport Sequence %u, msg_count %u, Link Tolerance %u", TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node), sess_no, broadcast_ack, seq_gap, bc_gap_after, bc_gap_to, last_sent_frag, next_sent_frag, trans_seq, msg_cnt, - link_tol)); + link_tol); } - return; - -trunc: - ND_PRINT((ndo, "%s", tstr)); } static void @@ -302,36 +288,30 @@ print_link_conf(netdissect_options *ndo, const struct link_conf_tipc_pkthdr *ap) u_int ntwrk_id; u_int media_id; - ND_TCHECK(ap->prev_node); - w0 = EXTRACT_32BITS(&ap->w0); + w0 = GET_BE_U_4(ap->w0); user = TIPC_USER(w0); hsize = TIPC_HSIZE(w0); msize = TIPC_MSIZE(w0); - w1 = EXTRACT_32BITS(&ap->w1); + w1 = GET_BE_U_4(ap->w1); mtype = TIPC_MTYPE(w1); - dest_domain = EXTRACT_32BITS(&ap->dest_domain); - prev_node = EXTRACT_32BITS(&ap->prev_node); + dest_domain = GET_BE_U_4(ap->dest_domain); + prev_node = GET_BE_U_4(ap->prev_node); - ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u > %u.%u.%u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s", + ND_PRINT("TIPC v%u.0 %u.%u.%u > %u.%u.%u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s", TIPC_VER(w0), TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node), TIPC_ZONE(dest_domain), TIPC_CLUSTER(dest_domain), TIPC_NODE(dest_domain), hsize*4, msize, tok2str(tipcuser_values, "unknown", user), - tok2str(tipc_linkconf_mtype_values, "Unknown", mtype))); + tok2str(tipc_linkconf_mtype_values, "Unknown", mtype)); if (ndo->ndo_vflag) { - ND_TCHECK(ap->w5); node_sig = TIPC_NODE_SIG(w1); - ntwrk_id = EXTRACT_32BITS(&ap->ntwrk_id); - w5 = EXTRACT_32BITS(&ap->w5); + ntwrk_id = GET_BE_U_4(ap->ntwrk_id); + w5 = GET_BE_U_4(ap->w5); media_id = TIPC_MEDIA_ID(w5); - ND_PRINT((ndo, "\n\tNodeSignature %u, network_id %u, media_id %u", - node_sig, ntwrk_id, media_id)); + ND_PRINT("\n\tNodeSignature %u, network_id %u, media_id %u", + node_sig, ntwrk_id, media_id); } - return; - -trunc: - ND_PRINT((ndo, "%s", tstr)); } void @@ -342,9 +322,9 @@ tipc_print(netdissect_options *ndo, const u_char *bp, u_int length _U_, uint32_t w0; u_int user; + ndo->ndo_protocol = "tipc"; ap = (const struct tipc_pkthdr *)bp; - ND_TCHECK(ap->w0); - w0 = EXTRACT_32BITS(&ap->w0); + w0 = GET_BE_U_4(ap->w0); user = TIPC_USER(w0); switch (user) @@ -371,15 +351,4 @@ tipc_print(netdissect_options *ndo, const u_char *bp, u_int length _U_, break; } - return; - -trunc: - ND_PRINT((ndo, "%s", tstr)); } - -/* - * Local Variables: - * c-style: bsd - * End: - */ - diff --git a/contrib/tcpdump/print-token.c b/contrib/tcpdump/print-token.c index faffd4b13c..bcb72584c2 100644 --- a/contrib/tcpdump/print-token.c +++ b/contrib/tcpdump/print-token.c @@ -27,17 +27,16 @@ /* \summary: Token Ring printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include #include "netdissect.h" #include "extract.h" #include "addrtoname.h" -#include "ether.h" /* * Copyright (c) 1998, Larry Lile @@ -68,33 +67,31 @@ */ #define TOKEN_HDRLEN 14 -#define TOKEN_RING_MAC_LEN 6 #define ROUTING_SEGMENT_MAX 16 #define IS_SOURCE_ROUTED(trp) ((trp)->token_shost[0] & 0x80) -#define FRAME_TYPE(trp) (((trp)->token_fc & 0xC0) >> 6) +#define FRAME_TYPE(trp) ((GET_U_1((trp)->token_fc) & 0xC0) >> 6) #define TOKEN_FC_LLC 1 -#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 BROADCAST(trp) ((GET_BE_U_2((trp)->token_rcf) & 0xE000) >> 13) +#define RIF_LENGTH(trp) ((GET_BE_U_2((trp)->token_rcf) & 0x1f00) >> 8) +#define DIRECTION(trp) ((GET_BE_U_2((trp)->token_rcf) & 0x0080) >> 7) +#define LARGEST_FRAME(trp) ((GET_BE_U_2((trp)->token_rcf) & 0x0070) >> 4) +#define RING_NUMBER(trp, x) ((GET_BE_U_2((trp)->token_rseg[x]) & 0xfff0) >> 4) +#define BRIDGE_NUMBER(trp, x) (GET_BE_U_2((trp)->token_rseg[x]) & 0x000f) #define SEGMENT_COUNT(trp) ((int)((RIF_LENGTH(trp) - 2) / 2)) struct token_header { - uint8_t token_ac; - uint8_t token_fc; - uint8_t token_dhost[TOKEN_RING_MAC_LEN]; - uint8_t token_shost[TOKEN_RING_MAC_LEN]; - uint16_t token_rcf; - uint16_t token_rseg[ROUTING_SEGMENT_MAX]; + nd_uint8_t token_ac; + nd_uint8_t token_fc; + nd_mac_addr token_dhost; + nd_mac_addr token_shost; + nd_uint16_t token_rcf; + nd_uint16_t token_rseg[ROUTING_SEGMENT_MAX]; }; -static const char tstr[] = "[|token-ring]"; /* Extract src, dst addresses */ -static inline void +static void extract_token_addrs(const struct token_header *trp, char *fsrc, char *fdst) { memcpy(fdst, (const char *)trp->token_dhost, 6); @@ -104,10 +101,10 @@ extract_token_addrs(const struct token_header *trp, char *fsrc, char *fdst) /* * Print the TR MAC header */ -static inline void +static void token_hdr_print(netdissect_options *ndo, - register const struct token_header *trp, register u_int length, - register const u_char *fsrc, register const u_char *fdst) + const struct token_header *trp, u_int length, + const u_char *fsrc, const u_char *fdst) { const char *srcname, *dstname; @@ -115,12 +112,12 @@ token_hdr_print(netdissect_options *ndo, dstname = etheraddr_string(ndo, fdst); if (!ndo->ndo_qflag) - ND_PRINT((ndo, "%02x %02x ", - trp->token_ac, - trp->token_fc)); - ND_PRINT((ndo, "%s > %s, length %u: ", + ND_PRINT("%02x %02x ", + GET_U_1(trp->token_ac), + GET_U_1(trp->token_fc)); + ND_PRINT("%s > %s, length %u: ", srcname, dstname, - length)); + length); } static const char *broadcast_indicator[] = { @@ -150,63 +147,65 @@ token_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen { const struct token_header *trp; int llc_hdrlen; - struct ether_header ehdr; + nd_mac_addr srcmac, dstmac; struct lladdr_info src, dst; u_int route_len = 0, hdr_len = TOKEN_HDRLEN; int seg; + ndo->ndo_protocol = "token-ring"; trp = (const struct token_header *)p; if (caplen < TOKEN_HDRLEN) { - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return hdr_len; } /* * Get the TR addresses into a canonical form */ - extract_token_addrs(trp, (char*)ESRC(&ehdr), (char*)EDST(&ehdr)); + extract_token_addrs(trp, (char*)srcmac, (char*)dstmac); /* Adjust for source routing information in the MAC header */ if (IS_SOURCE_ROUTED(trp)) { /* Clear source-routed bit */ - *ESRC(&ehdr) &= 0x7f; + srcmac[0] &= 0x7f; if (ndo->ndo_eflag) - token_hdr_print(ndo, trp, length, ESRC(&ehdr), EDST(&ehdr)); + token_hdr_print(ndo, trp, length, srcmac, dstmac); if (caplen < TOKEN_HDRLEN + 2) { - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return hdr_len; } route_len = RIF_LENGTH(trp); hdr_len += route_len; if (caplen < hdr_len) { - ND_PRINT((ndo, "%s", tstr)); + nd_print_trunc(ndo); return hdr_len; } if (ndo->ndo_vflag) { - ND_PRINT((ndo, "%s ", broadcast_indicator[BROADCAST(trp)])); - ND_PRINT((ndo, "%s", direction[DIRECTION(trp)])); + ND_PRINT("%s ", broadcast_indicator[BROADCAST(trp)]); + ND_PRINT("%s", direction[DIRECTION(trp)]); for (seg = 0; seg < SEGMENT_COUNT(trp); seg++) - ND_PRINT((ndo, " [%d:%d]", RING_NUMBER(trp, seg), - BRIDGE_NUMBER(trp, seg))); + ND_PRINT(" [%u:%u]", RING_NUMBER(trp, seg), + BRIDGE_NUMBER(trp, seg)); } else { - ND_PRINT((ndo, "rt = %x", EXTRACT_16BITS(&trp->token_rcf))); + ND_PRINT("rt = %x", GET_BE_U_2(trp->token_rcf)); for (seg = 0; seg < SEGMENT_COUNT(trp); seg++) - ND_PRINT((ndo, ":%x", EXTRACT_16BITS(&trp->token_rseg[seg]))); + ND_PRINT(":%x", + GET_BE_U_2(trp->token_rseg[seg])); } - ND_PRINT((ndo, " (%s) ", largest_frame[LARGEST_FRAME(trp)])); + ND_PRINT(" (%s) ", largest_frame[LARGEST_FRAME(trp)]); } else { if (ndo->ndo_eflag) - token_hdr_print(ndo, trp, length, ESRC(&ehdr), EDST(&ehdr)); + token_hdr_print(ndo, trp, length, srcmac, dstmac); } - src.addr = ESRC(&ehdr); + src.addr = srcmac; src.addr_string = etheraddr_string; - dst.addr = EDST(&ehdr); + dst.addr = dstmac; dst.addr_string = etheraddr_string; /* Skip over token ring MAC header and routing information */ @@ -230,7 +229,7 @@ token_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen /* XXX - dissect MAC packets if frame type is 0 */ if (!ndo->ndo_eflag) token_hdr_print(ndo, trp, length + TOKEN_HDRLEN + route_len, - ESRC(&ehdr), EDST(&ehdr)); + srcmac, dstmac); if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); } @@ -243,8 +242,9 @@ token_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen * 'h->len' is the length of the packet off the wire, and 'h->caplen' * is the number of bytes actually captured. */ -u_int +void token_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { - return (token_print(ndo, p, h->len, h->caplen)); + ndo->ndo_protocol = "token-ring"; + ndo->ndo_ll_hdr_len += token_print(ndo, p, h->len, h->caplen); } diff --git a/contrib/tcpdump/print-udld.c b/contrib/tcpdump/print-udld.c index 02921d0e44..aec1d9e572 100644 --- a/contrib/tcpdump/print-udld.c +++ b/contrib/tcpdump/print-udld.c @@ -20,17 +20,18 @@ /* specification: RFC 5171 */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" -static const char tstr[] = " [|udld]"; #define UDLD_HEADER_LEN 4 +#define UDLD_TLV_HEADER_LEN 4 #define UDLD_DEVICE_ID_TLV 0x0001 #define UDLD_PORT_ID_TLV 0x0002 #define UDLD_ECHO_TLV 0x0003 @@ -58,9 +59,15 @@ static const struct tok udld_code_values[] = { { 0, NULL} }; -static const struct tok udld_flags_values[] = { - { 0x00, "RT"}, - { 0x01, "RSY"}, +static const struct tok udld_flags_bitmap_str[] = { + { 1U << 0, "RT" }, + { 1U << 1, "RSY" }, + { 1U << 2, "MBZ-2" }, + { 1U << 3, "MBZ-3" }, + { 1U << 4, "MBZ-4" }, + { 1U << 5, "MBZ-5" }, + { 1U << 6, "MBZ-6" }, + { 1U << 7, "MBZ-7" }, { 0, NULL} }; @@ -94,105 +101,107 @@ static const struct tok udld_flags_values[] = { #define UDLD_EXTRACT_OPCODE(x) ((x)&0x1f) void -udld_print (netdissect_options *ndo, const u_char *pptr, u_int length) +udld_print(netdissect_options *ndo, + const u_char *tptr, u_int length) { - int code, type, len; - const u_char *tptr; + uint8_t ver, code, flags; + ndo->ndo_protocol = "udld"; if (length < UDLD_HEADER_LEN) - goto trunc; + goto invalid; - tptr = pptr; + ver = UDLD_EXTRACT_VERSION(GET_U_1(tptr)); + code = UDLD_EXTRACT_OPCODE(GET_U_1(tptr)); + tptr += 1; + length -= 1; - ND_TCHECK2(*tptr, UDLD_HEADER_LEN); + flags = GET_U_1(tptr); + tptr += 1; + length -= 1; - code = UDLD_EXTRACT_OPCODE(*tptr); - - ND_PRINT((ndo, "UDLDv%u, Code %s (%x), Flags [%s] (0x%02x), length %u", - UDLD_EXTRACT_VERSION(*tptr), + ND_PRINT("UDLDv%u, Code %s (%x), Flags [%s] (0x%02x), length %u", + ver, tok2str(udld_code_values, "Reserved", code), code, - bittok2str(udld_flags_values, "none", *(tptr+1)), - *(tptr+1), - length)); + bittok2str(udld_flags_bitmap_str, "none", flags), + flags, + length + 2); /* * In non-verbose mode, just print version and opcode type */ if (ndo->ndo_vflag < 1) { - return; + goto tcheck_remainder; } - ND_PRINT((ndo, "\n\tChecksum 0x%04x (unverified)", EXTRACT_16BITS(tptr+2))); + ND_PRINT("\n\tChecksum 0x%04x (unverified)", GET_BE_U_2(tptr)); + tptr += 2; + length -= 2; - tptr += UDLD_HEADER_LEN; + while (length) { + uint16_t type, len; - while (tptr < (pptr+length)) { + if (length < UDLD_TLV_HEADER_LEN) + goto invalid; - ND_TCHECK2(*tptr, 4); - type = EXTRACT_16BITS(tptr); - len = EXTRACT_16BITS(tptr+2); + type = GET_BE_U_2(tptr); + tptr += 2; + length -= 2; - ND_PRINT((ndo, "\n\t%s (0x%04x) TLV, length %u", - tok2str(udld_tlv_values, "Unknown", type), - type, len)); + len = GET_BE_U_2(tptr); + tptr += 2; + length -= 2; - if (type == 0) - goto invalid; + ND_PRINT("\n\t%s (0x%04x) TLV, length %u", + tok2str(udld_tlv_values, "Unknown", type), + type, len); /* infinite loop check */ - if (len <= 4) + if (len <= UDLD_TLV_HEADER_LEN) goto invalid; - len -= 4; - tptr += 4; - - ND_TCHECK2(*tptr, len); + len -= UDLD_TLV_HEADER_LEN; + if (length < len) + goto invalid; switch (type) { case UDLD_DEVICE_ID_TLV: case UDLD_PORT_ID_TLV: case UDLD_DEVICE_NAME_TLV: - ND_PRINT((ndo, ", ")); - fn_printzp(ndo, tptr, len, NULL); + ND_PRINT(", "); + nd_printjnp(ndo, tptr, len); break; case UDLD_ECHO_TLV: - ND_PRINT((ndo, ", ")); - (void)fn_printn(ndo, tptr, len, NULL); + ND_PRINT(", "); + (void)nd_printn(ndo, tptr, len, NULL); break; case UDLD_MESSAGE_INTERVAL_TLV: case UDLD_TIMEOUT_INTERVAL_TLV: if (len != 1) goto invalid; - ND_PRINT((ndo, ", %us", (*tptr))); + ND_PRINT(", %us", (GET_U_1(tptr))); break; case UDLD_SEQ_NUMBER_TLV: if (len != 4) goto invalid; - ND_PRINT((ndo, ", %u", EXTRACT_32BITS(tptr))); + ND_PRINT(", %u", GET_BE_U_4(tptr)); break; default: + ND_TCHECK_LEN(tptr, len); break; } tptr += len; + length -= len; } return; invalid: - ND_PRINT((ndo, "%s", istr)); - return; -trunc: - ND_PRINT((ndo, "%s", tstr)); + nd_print_invalid(ndo); +tcheck_remainder: + ND_TCHECK_LEN(tptr, length); } - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 4 - * End: - */ diff --git a/contrib/tcpdump/print-udp.c b/contrib/tcpdump/print-udp.c index 5a74ff2fc6..0efb0f1e8d 100644 --- a/contrib/tcpdump/print-udp.c +++ b/contrib/tcpdump/print-udp.c @@ -22,10 +22,10 @@ /* \summary: UDP printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "addrtoname.h" @@ -42,30 +42,26 @@ #include "nfs.h" -static const char vat_tstr[] = " [|vat]"; -static const char rtp_tstr[] = " [|rtp]"; -static const char rtcp_tstr[] = " [|rtcp]"; -static const char udp_tstr[] = " [|udp]"; struct rtcphdr { - uint16_t rh_flags; /* T:2 P:1 CNT:5 PT:8 */ - uint16_t rh_len; /* length of message (in words) */ - uint32_t rh_ssrc; /* synchronization src id */ + nd_uint16_t rh_flags; /* T:2 P:1 CNT:5 PT:8 */ + nd_uint16_t rh_len; /* length of message (in words) */ + nd_uint32_t rh_ssrc; /* synchronization src id */ }; typedef struct { - uint32_t upper; /* more significant 32 bits */ - uint32_t lower; /* less significant 32 bits */ + nd_uint32_t upper; /* more significant 32 bits */ + nd_uint32_t lower; /* less significant 32 bits */ } ntp64; /* * Sender report. */ struct rtcp_sr { - ntp64 sr_ntp; /* 64-bit ntp timestamp */ - uint32_t sr_ts; /* reference media timestamp */ - uint32_t sr_np; /* no. packets sent */ - uint32_t sr_nb; /* no. bytes sent */ + ntp64 sr_ntp; /* 64-bit ntp timestamp */ + nd_uint32_t sr_ts; /* reference media timestamp */ + nd_uint32_t sr_np; /* no. packets sent */ + nd_uint32_t sr_nb; /* no. bytes sent */ }; /* @@ -73,12 +69,12 @@ struct rtcp_sr { * Time stamps are middle 32-bits of ntp timestamp. */ struct rtcp_rr { - uint32_t rr_srcid; /* sender being reported */ - uint32_t rr_nl; /* no. packets lost */ - uint32_t rr_ls; /* extended last seq number received */ - uint32_t rr_dv; /* jitter (delay variance) */ - uint32_t rr_lsr; /* orig. ts from last rr from this src */ - uint32_t rr_dlsr; /* time from recpt of last rr to xmit time */ + nd_uint32_t rr_srcid; /* sender being reported */ + nd_uint32_t rr_nl; /* no. packets lost */ + nd_uint32_t rr_ls; /* extended last seq number received */ + nd_uint32_t rr_dv; /* jitter (delay variance) */ + nd_uint32_t rr_lsr; /* orig. ts from last rr from this src */ + nd_uint32_t rr_dlsr; /* time from recpt of last rr to xmit time */ }; /*XXX*/ @@ -97,46 +93,46 @@ struct rtcp_rr { #define RTCP_PT_APP 204 static void -vat_print(netdissect_options *ndo, const void *hdr, register const struct udphdr *up) +vat_print(netdissect_options *ndo, const u_char *hdr, u_int length) { /* vat/vt audio */ u_int ts; - ND_TCHECK_16BITS((const u_int *)hdr); - ts = EXTRACT_16BITS(hdr); + ndo->ndo_protocol = "vat"; + if (length < 2) { + ND_PRINT("udp/va/vat, length %u < 2", length); + return; + } + ts = GET_BE_U_2(hdr); if ((ts & 0xf060) != 0) { /* probably vt */ - ND_TCHECK_16BITS(&up->uh_ulen); - ND_PRINT((ndo, "udp/vt %u %d / %d", - (uint32_t)(EXTRACT_16BITS(&up->uh_ulen) - sizeof(*up)), - ts & 0x3ff, ts >> 10)); + ND_PRINT("udp/vt %u %u / %u", + length, + ts & 0x3ff, ts >> 10); } else { /* probably vat */ uint32_t i0, i1; - ND_TCHECK_32BITS(&((const u_int *)hdr)[0]); - i0 = EXTRACT_32BITS(&((const u_int *)hdr)[0]); - ND_TCHECK_32BITS(&((const u_int *)hdr)[1]); - i1 = EXTRACT_32BITS(&((const u_int *)hdr)[1]); - ND_TCHECK_16BITS(&up->uh_ulen); - ND_PRINT((ndo, "udp/vat %u c%d %u%s", - (uint32_t)(EXTRACT_16BITS(&up->uh_ulen) - sizeof(*up) - 8), + if (length < 8) { + ND_PRINT("udp/vat, length %u < 8", length); + return; + } + i0 = GET_BE_U_4(&((const u_int *)hdr)[0]); + i1 = GET_BE_U_4(&((const u_int *)hdr)[1]); + ND_PRINT("udp/vat %u c%u %u%s", + length - 8, i0 & 0xffff, - i1, i0 & 0x800000? "*" : "")); + i1, i0 & 0x800000? "*" : ""); /* audio format */ if (i0 & 0x1f0000) - ND_PRINT((ndo, " f%d", (i0 >> 16) & 0x1f)); + ND_PRINT(" f%u", (i0 >> 16) & 0x1f); if (i0 & 0x3f000000) - ND_PRINT((ndo, " s%d", (i0 >> 24) & 0x3f)); + ND_PRINT(" s%u", (i0 >> 24) & 0x3f); } - -trunc: - ND_PRINT((ndo, "%s", vat_tstr)); } static void -rtp_print(netdissect_options *ndo, const void *hdr, u_int len, - register const struct udphdr *up) +rtp_print(netdissect_options *ndo, const u_char *hdr, u_int len) { /* rtp v1 or v2 */ const u_int *ip = (const u_int *)hdr; @@ -144,12 +140,14 @@ rtp_print(netdissect_options *ndo, const void *hdr, u_int len, uint32_t i0, i1; const char * ptype; - ND_TCHECK_32BITS(&((const u_int *)hdr)[0]); - i0 = EXTRACT_32BITS(&((const u_int *)hdr)[0]); - ND_TCHECK_32BITS(&((const u_int *)hdr)[1]); - i1 = EXTRACT_32BITS(&((const u_int *)hdr)[1]); - ND_TCHECK_16BITS(&up->uh_ulen); - dlen = EXTRACT_16BITS(&up->uh_ulen) - sizeof(*up) - 8; + ndo->ndo_protocol = "rtp"; + if (len < 8) { + ND_PRINT("udp/rtp, length %u < 8", len); + return; + } + i0 = GET_BE_U_4(&((const u_int *)hdr)[0]); + i1 = GET_BE_U_4(&((const u_int *)hdr)[1]); + dlen = len - 8; ip += 2; len >>= 2; len -= 2; @@ -163,6 +161,10 @@ rtp_print(netdissect_options *ndo, const void *hdr, u_int len, ptype = "rtpv1"; } else { /* rtp v2 - RFC 3550 */ + if (dlen < 4) { + ND_PRINT("udp/rtp, length %u < 12", dlen + 8); + return; + } hasext = i0 & 0x10000000; contype = (i0 >> 16) & 0x7f; hasmarker = i0 & 0x800000; @@ -171,25 +173,23 @@ rtp_print(netdissect_options *ndo, const void *hdr, u_int len, ip += 1; len -= 1; } - ND_PRINT((ndo, "udp/%s %d c%d %s%s %d %u", + ND_PRINT("udp/%s %u c%u %s%s %u %u", ptype, dlen, contype, (hasopt || hasext)? "+" : "", hasmarker? "*" : "", i0 & 0xffff, - i1)); + i1); if (ndo->ndo_vflag) { - ND_TCHECK_32BITS(&((const u_int *)hdr)[2]); - ND_PRINT((ndo, " %u", EXTRACT_32BITS(&((const u_int *)hdr)[2]))); + ND_PRINT(" %u", GET_BE_U_4(&((const u_int *)hdr)[2])); if (hasopt) { u_int i2, optlen; do { - ND_TCHECK_32BITS(ip); - i2 = EXTRACT_32BITS(ip); + i2 = GET_BE_U_4(ip); optlen = (i2 >> 16) & 0xff; if (optlen == 0 || optlen > len) { - ND_PRINT((ndo, " !opt")); + ND_PRINT(" !opt"); return; } ip += optlen; @@ -198,22 +198,17 @@ rtp_print(netdissect_options *ndo, const void *hdr, u_int len, } if (hasext) { u_int i2, extlen; - ND_TCHECK_32BITS(ip); - i2 = EXTRACT_32BITS(ip); + i2 = GET_BE_U_4(ip); extlen = (i2 & 0xffff) + 1; if (extlen > len) { - ND_PRINT((ndo, " !ext")); + ND_PRINT(" !ext"); return; } ip += extlen; } - ND_TCHECK_32BITS(ip); if (contype == 0x1f) /*XXX H.261 */ - ND_PRINT((ndo, " 0x%04x", EXTRACT_32BITS(ip) >> 16)); + ND_PRINT(" 0x%04x", GET_BE_U_4(ip) >> 16); } - -trunc: - ND_PRINT((ndo, "%s", rtp_tstr)); } static const u_char * @@ -225,88 +220,91 @@ rtcp_print(netdissect_options *ndo, const u_char *hdr, const u_char *ep) const struct rtcphdr *rh = (const struct rtcphdr *)hdr; u_int len; uint16_t flags; - int cnt; + u_int cnt; double ts, dts; + + ndo->ndo_protocol = "rtcp"; if ((const u_char *)(rh + 1) > ep) goto trunc; - ND_TCHECK(*rh); - len = (EXTRACT_16BITS(&rh->rh_len) + 1) * 4; - flags = EXTRACT_16BITS(&rh->rh_flags); + ND_TCHECK_SIZE(rh); + len = (GET_BE_U_2(rh->rh_len) + 1) * 4; + flags = GET_BE_U_2(rh->rh_flags); cnt = (flags >> 8) & 0x1f; switch (flags & 0xff) { case RTCP_PT_SR: sr = (const struct rtcp_sr *)(rh + 1); - ND_PRINT((ndo, " sr")); + ND_PRINT(" sr"); if (len != cnt * sizeof(*rr) + sizeof(*sr) + sizeof(*rh)) - ND_PRINT((ndo, " [%d]", len)); + ND_PRINT(" [%u]", len); if (ndo->ndo_vflag) - ND_PRINT((ndo, " %u", EXTRACT_32BITS(&rh->rh_ssrc))); + ND_PRINT(" %u", GET_BE_U_4(rh->rh_ssrc)); if ((const u_char *)(sr + 1) > ep) goto trunc; - ND_TCHECK(*sr); - ts = (double)(EXTRACT_32BITS(&sr->sr_ntp.upper)) + - ((double)(EXTRACT_32BITS(&sr->sr_ntp.lower)) / - 4294967296.0); - ND_PRINT((ndo, " @%.2f %u %up %ub", ts, EXTRACT_32BITS(&sr->sr_ts), - EXTRACT_32BITS(&sr->sr_np), EXTRACT_32BITS(&sr->sr_nb))); + ND_TCHECK_SIZE(sr); + ts = (double)(GET_BE_U_4(sr->sr_ntp.upper)) + + ((double)(GET_BE_U_4(sr->sr_ntp.lower)) / + FMAXINT); + ND_PRINT(" @%.2f %u %up %ub", ts, GET_BE_U_4(sr->sr_ts), + GET_BE_U_4(sr->sr_np), GET_BE_U_4(sr->sr_nb)); rr = (const struct rtcp_rr *)(sr + 1); break; case RTCP_PT_RR: - ND_PRINT((ndo, " rr")); + ND_PRINT(" rr"); if (len != cnt * sizeof(*rr) + sizeof(*rh)) - ND_PRINT((ndo, " [%d]", len)); + ND_PRINT(" [%u]", len); rr = (const struct rtcp_rr *)(rh + 1); if (ndo->ndo_vflag) - ND_PRINT((ndo, " %u", EXTRACT_32BITS(&rh->rh_ssrc))); + ND_PRINT(" %u", GET_BE_U_4(rh->rh_ssrc)); break; case RTCP_PT_SDES: - ND_PRINT((ndo, " sdes %d", len)); + ND_PRINT(" sdes %u", len); if (ndo->ndo_vflag) - ND_PRINT((ndo, " %u", EXTRACT_32BITS(&rh->rh_ssrc))); + ND_PRINT(" %u", GET_BE_U_4(rh->rh_ssrc)); cnt = 0; break; case RTCP_PT_BYE: - ND_PRINT((ndo, " bye %d", len)); + ND_PRINT(" bye %u", len); if (ndo->ndo_vflag) - ND_PRINT((ndo, " %u", EXTRACT_32BITS(&rh->rh_ssrc))); + ND_PRINT(" %u", GET_BE_U_4(rh->rh_ssrc)); cnt = 0; break; default: - ND_PRINT((ndo, " type-0x%x %d", flags & 0xff, len)); + ND_PRINT(" type-0x%x %u", flags & 0xff, len); cnt = 0; break; } if (cnt > 1) - ND_PRINT((ndo, " c%d", cnt)); - while (--cnt >= 0) { + ND_PRINT(" c%u", cnt); + while (cnt != 0) { if ((const u_char *)(rr + 1) > ep) goto trunc; - ND_TCHECK(*rr); + ND_TCHECK_SIZE(rr); if (ndo->ndo_vflag) - ND_PRINT((ndo, " %u", EXTRACT_32BITS(&rr->rr_srcid))); - ts = (double)(EXTRACT_32BITS(&rr->rr_lsr)) / 65536.; - dts = (double)(EXTRACT_32BITS(&rr->rr_dlsr)) / 65536.; - ND_PRINT((ndo, " %ul %us %uj @%.2f+%.2f", - EXTRACT_32BITS(&rr->rr_nl) & 0x00ffffff, - EXTRACT_32BITS(&rr->rr_ls), - EXTRACT_32BITS(&rr->rr_dv), ts, dts)); + ND_PRINT(" %u", GET_BE_U_4(rr->rr_srcid)); + ts = (double)(GET_BE_U_4(rr->rr_lsr)) / 65536.; + dts = (double)(GET_BE_U_4(rr->rr_dlsr)) / 65536.; + ND_PRINT(" %ul %us %uj @%.2f+%.2f", + GET_BE_U_4(rr->rr_nl) & 0x00ffffff, + GET_BE_U_4(rr->rr_ls), + GET_BE_U_4(rr->rr_dv), ts, dts); + cnt--; } return (hdr + len); trunc: - ND_PRINT((ndo, "%s", rtcp_tstr)); + nd_print_trunc(ndo); return ep; } -static int udp_cksum(netdissect_options *ndo, register const struct ip *ip, - register const struct udphdr *up, - register u_int len) +static uint16_t udp_cksum(netdissect_options *ndo, const struct ip *ip, + const struct udphdr *up, + u_int len) { return nextproto4_cksum(ndo, ip, (const uint8_t *)(const void *)up, len, len, IPPROTO_UDP); } -static int udp6_cksum(netdissect_options *ndo, const struct ip6_hdr *ip6, +static uint16_t udp6_cksum(netdissect_options *ndo, const struct ip6_hdr *ip6, const struct udphdr *up, u_int len) { return nextproto6_cksum(ndo, ip6, (const uint8_t *)(const void *)up, len, len, @@ -324,88 +322,95 @@ udpipaddr_print(netdissect_options *ndo, const struct ip *ip, int sport, int dpo ip6 = NULL; if (ip6) { - if (ip6->ip6_nxt == IPPROTO_UDP) { + if (GET_U_1(ip6->ip6_nxt) == IPPROTO_UDP) { if (sport == -1) { - ND_PRINT((ndo, "%s > %s: ", - ip6addr_string(ndo, &ip6->ip6_src), - ip6addr_string(ndo, &ip6->ip6_dst))); + ND_PRINT("%s > %s: ", + GET_IP6ADDR_STRING(ip6->ip6_src), + GET_IP6ADDR_STRING(ip6->ip6_dst)); } else { - ND_PRINT((ndo, "%s.%s > %s.%s: ", - ip6addr_string(ndo, &ip6->ip6_src), - udpport_string(ndo, sport), - ip6addr_string(ndo, &ip6->ip6_dst), - udpport_string(ndo, dport))); + ND_PRINT("%s.%s > %s.%s: ", + GET_IP6ADDR_STRING(ip6->ip6_src), + udpport_string(ndo, (uint16_t)sport), + GET_IP6ADDR_STRING(ip6->ip6_dst), + udpport_string(ndo, (uint16_t)dport)); } } else { if (sport != -1) { - ND_PRINT((ndo, "%s > %s: ", - udpport_string(ndo, sport), - udpport_string(ndo, dport))); + ND_PRINT("%s > %s: ", + udpport_string(ndo, (uint16_t)sport), + udpport_string(ndo, (uint16_t)dport)); } } } else { - if (ip->ip_p == IPPROTO_UDP) { + if (GET_U_1(ip->ip_p) == IPPROTO_UDP) { if (sport == -1) { - ND_PRINT((ndo, "%s > %s: ", - ipaddr_string(ndo, &ip->ip_src), - ipaddr_string(ndo, &ip->ip_dst))); + ND_PRINT("%s > %s: ", + GET_IPADDR_STRING(ip->ip_src), + GET_IPADDR_STRING(ip->ip_dst)); } else { - ND_PRINT((ndo, "%s.%s > %s.%s: ", - ipaddr_string(ndo, &ip->ip_src), - udpport_string(ndo, sport), - ipaddr_string(ndo, &ip->ip_dst), - udpport_string(ndo, dport))); + ND_PRINT("%s.%s > %s.%s: ", + GET_IPADDR_STRING(ip->ip_src), + udpport_string(ndo, (uint16_t)sport), + GET_IPADDR_STRING(ip->ip_dst), + udpport_string(ndo, (uint16_t)dport)); } } else { if (sport != -1) { - ND_PRINT((ndo, "%s > %s: ", - udpport_string(ndo, sport), - udpport_string(ndo, dport))); + ND_PRINT("%s > %s: ", + udpport_string(ndo, (uint16_t)sport), + udpport_string(ndo, (uint16_t)dport)); } } } } void -udp_print(netdissect_options *ndo, register const u_char *bp, u_int length, - register const u_char *bp2, int fragmented) +udp_print(netdissect_options *ndo, const u_char *bp, u_int length, + const u_char *bp2, int fragmented, u_int ttl_hl) { - register const struct udphdr *up; - register const struct ip *ip; - register const u_char *cp; - register const u_char *ep = bp + length; - uint16_t sport, dport, ulen; - register const struct ip6_hdr *ip6; - - if (ep > ndo->ndo_snapend) - ep = ndo->ndo_snapend; + const struct udphdr *up; + const struct ip *ip; + const u_char *cp; + const u_char *ep = ndo->ndo_snapend; + uint16_t sport, dport; + u_int ulen; + const struct ip6_hdr *ip6; + + ndo->ndo_protocol = "udp"; up = (const struct udphdr *)bp; ip = (const struct ip *)bp2; if (IP_V(ip) == 6) ip6 = (const struct ip6_hdr *)bp2; else ip6 = NULL; - if (!ND_TTEST(up->uh_dport)) { + if (!ND_TTEST_2(up->uh_dport)) { udpipaddr_print(ndo, ip, -1, -1); goto trunc; } - sport = EXTRACT_16BITS(&up->uh_sport); - dport = EXTRACT_16BITS(&up->uh_dport); + sport = GET_BE_U_2(up->uh_sport); + dport = GET_BE_U_2(up->uh_dport); if (length < sizeof(struct udphdr)) { udpipaddr_print(ndo, ip, sport, dport); - ND_PRINT((ndo, "truncated-udp %d", length)); + ND_PRINT("truncated-udp %u", length); return; } - if (!ND_TTEST(up->uh_ulen)) { + if (!ND_TTEST_2(up->uh_ulen)) { udpipaddr_print(ndo, ip, sport, dport); goto trunc; } - ulen = EXTRACT_16BITS(&up->uh_ulen); + ulen = GET_BE_U_2(up->uh_ulen); + /* + * IPv6 Jumbo Datagrams; see RFC 2675. + * If the length is zero, and the length provided to us is + * > 65535, use the provided length as the length. + */ + if (ulen == 0 && length > 65535) + ulen = length; if (ulen < sizeof(struct udphdr)) { udpipaddr_print(ndo, ip, sport, dport); - ND_PRINT((ndo, "truncated-udplength %d", ulen)); + ND_PRINT("truncated-udplength %u", ulen); return; } ulen -= sizeof(struct udphdr); @@ -420,26 +425,26 @@ udp_print(netdissect_options *ndo, register const u_char *bp, u_int length, } if (ndo->ndo_packettype) { - register const struct sunrpc_msg *rp; + const struct sunrpc_msg *rp; enum sunrpc_msg_type direction; switch (ndo->ndo_packettype) { case PT_VAT: udpipaddr_print(ndo, ip, sport, dport); - vat_print(ndo, (const void *)(up + 1), up); + vat_print(ndo, cp, length); break; case PT_WB: udpipaddr_print(ndo, ip, sport, dport); - wb_print(ndo, (const void *)(up + 1), length); + wb_print(ndo, cp, length); break; case PT_RPC: - rp = (const struct sunrpc_msg *)(up + 1); - direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction); + rp = (const struct sunrpc_msg *)cp; + direction = (enum sunrpc_msg_type) GET_BE_U_4(rp->rm_direction); if (direction == SUNRPC_CALL) - sunrpcrequest_print(ndo, (const u_char *)rp, length, + sunrpc_print(ndo, (const u_char *)rp, length, (const u_char *)ip); else nfsreply_print(ndo, (const u_char *)rp, length, @@ -448,7 +453,7 @@ udp_print(netdissect_options *ndo, register const u_char *bp, u_int length, case PT_RTP: udpipaddr_print(ndo, ip, sport, dport); - rtp_print(ndo, (const void *)(up + 1), length, up); + rtp_print(ndo, cp, length); break; case PT_RTCP: @@ -459,7 +464,7 @@ udp_print(netdissect_options *ndo, register const u_char *bp, u_int length, case PT_SNMP: udpipaddr_print(ndo, ip, sport, dport); - snmp_print(ndo, (const u_char *)(up + 1), length); + snmp_print(ndo, cp, length); break; case PT_CNFP: @@ -474,7 +479,7 @@ udp_print(netdissect_options *ndo, register const u_char *bp, u_int length, case PT_AODV: udpipaddr_print(ndo, ip, sport, dport); - aodv_print(ndo, (const u_char *)(up + 1), length, + aodv_print(ndo, cp, length, ip6 != NULL); break; @@ -485,7 +490,7 @@ udp_print(netdissect_options *ndo, register const u_char *bp, u_int length, case PT_VXLAN: udpipaddr_print(ndo, ip, sport, dport); - vxlan_print(ndo, (const u_char *)(up + 1), length); + vxlan_print(ndo, cp, length); break; case PT_PGM: @@ -497,33 +502,48 @@ udp_print(netdissect_options *ndo, register const u_char *bp, u_int length, udpipaddr_print(ndo, ip, sport, dport); lmp_print(ndo, cp, length); break; + case PT_PTP: + udpipaddr_print(ndo, ip, sport, dport); + ptp_print(ndo, cp, length); + break; + case PT_SOMEIP: + udpipaddr_print(ndo, ip, sport, dport); + someip_print(ndo, cp, length); + break; + case PT_DOMAIN: + udpipaddr_print(ndo, ip, sport, dport); + /* over_tcp: FALSE, is_mdns: FALSE */ + domain_print(ndo, cp, length, FALSE, FALSE); + break; } return; } udpipaddr_print(ndo, ip, sport, dport); if (!ndo->ndo_qflag) { - register const struct sunrpc_msg *rp; + const struct sunrpc_msg *rp; enum sunrpc_msg_type direction; - rp = (const struct sunrpc_msg *)(up + 1); - if (ND_TTEST(rp->rm_direction)) { - direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction); + rp = (const struct sunrpc_msg *)cp; + if (ND_TTEST_4(rp->rm_direction)) { + direction = (enum sunrpc_msg_type) GET_BE_U_4(rp->rm_direction); if (dport == NFS_PORT && direction == SUNRPC_CALL) { - ND_PRINT((ndo, "NFS request xid %u ", EXTRACT_32BITS(&rp->rm_xid))); - nfsreq_print_noaddr(ndo, (const u_char *)rp, length, + ND_PRINT("NFS request xid %u ", + GET_BE_U_4(rp->rm_xid)); + nfsreq_noaddr_print(ndo, (const u_char *)rp, length, (const u_char *)ip); return; } if (sport == NFS_PORT && direction == SUNRPC_REPLY) { - ND_PRINT((ndo, "NFS reply xid %u ", EXTRACT_32BITS(&rp->rm_xid))); - nfsreply_print_noaddr(ndo, (const u_char *)rp, length, + ND_PRINT("NFS reply xid %u ", + GET_BE_U_4(rp->rm_xid)); + nfsreply_noaddr_print(ndo, (const u_char *)rp, length, (const u_char *)ip); return; } #ifdef notdef if (dport == SUNRPC_PORT && direction == SUNRPC_CALL) { - sunrpcrequest_print((const u_char *)rp, length, (const u_char *)ip); + sunrpc_print((const u_char *)rp, length, (const u_char *)ip); return; } #endif @@ -531,188 +551,193 @@ udp_print(netdissect_options *ndo, register const u_char *bp, u_int length, } if (ndo->ndo_vflag && !ndo->ndo_Kflag && !fragmented) { - /* Check the checksum, if possible. */ - uint16_t sum, udp_sum; + /* Check the checksum, if possible. */ + uint16_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 && (ndo->ndo_vflag > 1)) { - udp_sum = EXTRACT_16BITS(&up->uh_sum); + if (IP_V(ip) == 4 && (ndo->ndo_vflag > 1)) { + udp_sum = GET_BE_U_2(up->uh_sum); if (udp_sum == 0) { - ND_PRINT((ndo, "[no cksum] ")); - } else if (ND_TTEST2(cp[0], length)) { + ND_PRINT("[no cksum] "); + } else if (ND_TTEST_LEN(cp, length)) { sum = udp_cksum(ndo, ip, up, length + sizeof(struct udphdr)); - if (sum != 0) { - ND_PRINT((ndo, "[bad udp cksum 0x%04x -> 0x%04x!] ", + if (sum != 0) { + ND_PRINT("[bad udp cksum 0x%04x -> 0x%04x!] ", udp_sum, - in_cksum_shouldbe(udp_sum, sum))); + in_cksum_shouldbe(udp_sum, sum)); } else - ND_PRINT((ndo, "[udp sum ok] ")); + ND_PRINT("[udp sum ok] "); } } - else if (IP_V(ip) == 6 && ip6->ip6_plen) { + else if (IP_V(ip) == 6) { /* for IPv6, UDP checksum is mandatory */ - if (ND_TTEST2(cp[0], length)) { + if (ND_TTEST_LEN(cp, length)) { sum = udp6_cksum(ndo, ip6, up, length + sizeof(struct udphdr)); - udp_sum = EXTRACT_16BITS(&up->uh_sum); + udp_sum = GET_BE_U_2(up->uh_sum); - if (sum != 0) { - ND_PRINT((ndo, "[bad udp cksum 0x%04x -> 0x%04x!] ", + if (sum != 0) { + ND_PRINT("[bad udp cksum 0x%04x -> 0x%04x!] ", udp_sum, - in_cksum_shouldbe(udp_sum, sum))); + in_cksum_shouldbe(udp_sum, sum)); } else - ND_PRINT((ndo, "[udp sum ok] ")); + ND_PRINT("[udp sum ok] "); } } } if (!ndo->ndo_qflag) { if (IS_SRC_OR_DST_PORT(NAMESERVER_PORT)) - ns_print(ndo, (const u_char *)(up + 1), length, 0); + /* over_tcp: FALSE, is_mdns: FALSE */ + domain_print(ndo, cp, length, FALSE, FALSE); else if (IS_SRC_OR_DST_PORT(MULTICASTDNS_PORT)) - ns_print(ndo, (const u_char *)(up + 1), length, 1); + /* over_tcp: FALSE, is_mdns: TRUE */ + domain_print(ndo, cp, length, FALSE, TRUE); else if (IS_SRC_OR_DST_PORT(TIMED_PORT)) - timed_print(ndo, (const u_char *)(up + 1)); + timed_print(ndo, (const u_char *)cp); else if (IS_SRC_OR_DST_PORT(TFTP_PORT)) - tftp_print(ndo, (const u_char *)(up + 1), length); + tftp_print(ndo, cp, length); else if (IS_SRC_OR_DST_PORT(BOOTPC_PORT) || IS_SRC_OR_DST_PORT(BOOTPS_PORT)) - bootp_print(ndo, (const u_char *)(up + 1), length); + bootp_print(ndo, cp, length); else if (IS_SRC_OR_DST_PORT(RIP_PORT)) - rip_print(ndo, (const u_char *)(up + 1), length); + rip_print(ndo, cp, length); else if (IS_SRC_OR_DST_PORT(AODV_PORT)) - aodv_print(ndo, (const u_char *)(up + 1), length, + aodv_print(ndo, cp, length, ip6 != NULL); - else if (IS_SRC_OR_DST_PORT(ISAKMP_PORT)) - isakmp_print(ndo, (const u_char *)(up + 1), length, bp2); - else if (IS_SRC_OR_DST_PORT(ISAKMP_PORT_NATT)) - isakmp_rfc3948_print(ndo, (const u_char *)(up + 1), length, bp2); -#if 1 /*???*/ - else if (IS_SRC_OR_DST_PORT(ISAKMP_PORT_USER1) || IS_SRC_OR_DST_PORT(ISAKMP_PORT_USER2)) - isakmp_print(ndo, (const u_char *)(up + 1), length, bp2); -#endif + else if (IS_SRC_OR_DST_PORT(ISAKMP_PORT)) + isakmp_print(ndo, cp, length, bp2); + else if (IS_SRC_OR_DST_PORT(ISAKMP_PORT_NATT)) + isakmp_rfc3948_print(ndo, cp, length, bp2, IP_V(ip), fragmented, ttl_hl); + else if (IS_SRC_OR_DST_PORT(ISAKMP_PORT_USER1) || IS_SRC_OR_DST_PORT(ISAKMP_PORT_USER2)) + isakmp_print(ndo, cp, length, bp2); else if (IS_SRC_OR_DST_PORT(SNMP_PORT) || IS_SRC_OR_DST_PORT(SNMPTRAP_PORT)) - snmp_print(ndo, (const u_char *)(up + 1), length); + snmp_print(ndo, cp, length); else if (IS_SRC_OR_DST_PORT(NTP_PORT)) - ntp_print(ndo, (const u_char *)(up + 1), length); + ntp_print(ndo, cp, length); else if (IS_SRC_OR_DST_PORT(KERBEROS_PORT) || IS_SRC_OR_DST_PORT(KERBEROS_SEC_PORT)) - krb_print(ndo, (const void *)(up + 1)); + krb_print(ndo, (const u_char *)cp); else if (IS_SRC_OR_DST_PORT(L2TP_PORT)) - l2tp_print(ndo, (const u_char *)(up + 1), length); + l2tp_print(ndo, cp, length); #ifdef ENABLE_SMB else if (IS_SRC_OR_DST_PORT(NETBIOS_NS_PORT)) - nbt_udp137_print(ndo, (const u_char *)(up + 1), length); + nbt_udp137_print(ndo, cp, length); else if (IS_SRC_OR_DST_PORT(NETBIOS_DGRAM_PORT)) - nbt_udp138_print(ndo, (const u_char *)(up + 1), length); + nbt_udp138_print(ndo, cp, length); #endif else if (dport == VAT_PORT) - vat_print(ndo, (const void *)(up + 1), up); + vat_print(ndo, cp, length); else if (IS_SRC_OR_DST_PORT(ZEPHYR_SRV_PORT) || IS_SRC_OR_DST_PORT(ZEPHYR_CLT_PORT)) - zephyr_print(ndo, (const void *)(up + 1), length); + zephyr_print(ndo, cp, length); /* * Since there are 10 possible ports to check, I think * a <> test would be more efficient */ else if ((sport >= RX_PORT_LOW && sport <= RX_PORT_HIGH) || (dport >= RX_PORT_LOW && dport <= RX_PORT_HIGH)) - rx_print(ndo, (const void *)(up + 1), length, sport, dport, + rx_print(ndo, cp, length, sport, dport, (const u_char *) ip); else if (IS_SRC_OR_DST_PORT(RIPNG_PORT)) - ripng_print(ndo, (const u_char *)(up + 1), length); + ripng_print(ndo, cp, length); else if (IS_SRC_OR_DST_PORT(DHCP6_SERV_PORT) || IS_SRC_OR_DST_PORT(DHCP6_CLI_PORT)) - dhcp6_print(ndo, (const u_char *)(up + 1), length); + dhcp6_print(ndo, cp, length); else if (IS_SRC_OR_DST_PORT(AHCP_PORT)) - ahcp_print(ndo, (const u_char *)(up + 1), length); + ahcp_print(ndo, cp, length); else if (IS_SRC_OR_DST_PORT(BABEL_PORT) || IS_SRC_OR_DST_PORT(BABEL_PORT_OLD)) - babel_print(ndo, (const u_char *)(up + 1), length); + babel_print(ndo, cp, length); else if (IS_SRC_OR_DST_PORT(HNCP_PORT)) - hncp_print(ndo, (const u_char *)(up + 1), length); + hncp_print(ndo, cp, length); /* * Kludge in test for whiteboard packets. */ else if (dport == WB_PORT) - wb_print(ndo, (const void *)(up + 1), length); + wb_print(ndo, cp, length); else if (IS_SRC_OR_DST_PORT(CISCO_AUTORP_PORT)) - cisco_autorp_print(ndo, (const void *)(up + 1), length); + cisco_autorp_print(ndo, cp, length); else if (IS_SRC_OR_DST_PORT(RADIUS_PORT) || IS_SRC_OR_DST_PORT(RADIUS_NEW_PORT) || IS_SRC_OR_DST_PORT(RADIUS_ACCOUNTING_PORT) || IS_SRC_OR_DST_PORT(RADIUS_NEW_ACCOUNTING_PORT) || IS_SRC_OR_DST_PORT(RADIUS_CISCO_COA_PORT) || IS_SRC_OR_DST_PORT(RADIUS_COA_PORT) ) - radius_print(ndo, (const u_char *)(up+1), length); + radius_print(ndo, cp, length); else if (dport == HSRP_PORT) - hsrp_print(ndo, (const u_char *)(up + 1), length); + hsrp_print(ndo, cp, length); else if (IS_SRC_OR_DST_PORT(LWRES_PORT)) - lwres_print(ndo, (const u_char *)(up + 1), length); + lwres_print(ndo, cp, length); else if (IS_SRC_OR_DST_PORT(LDP_PORT)) - ldp_print(ndo, (const u_char *)(up + 1), length); + ldp_print(ndo, cp, length); else if (IS_SRC_OR_DST_PORT(OLSR_PORT)) - olsr_print(ndo, (const u_char *)(up + 1), length, + olsr_print(ndo, cp, length, (IP_V(ip) == 6) ? 1 : 0); else if (IS_SRC_OR_DST_PORT(MPLS_LSP_PING_PORT)) - lspping_print(ndo, (const u_char *)(up + 1), length); + lspping_print(ndo, cp, length); + else if (sport == BCM_LI_PORT) + bcm_li_print(ndo, cp, length); else if (dport == BFD_CONTROL_PORT || + dport == BFD_MULTIHOP_PORT || + dport == BFD_LAG_PORT || dport == BFD_ECHO_PORT ) - bfd_print(ndo, (const u_char *)(up+1), length, dport); - else if (IS_SRC_OR_DST_PORT(LMP_PORT)) - lmp_print(ndo, (const u_char *)(up + 1), length); + bfd_print(ndo, cp, length, dport); + else if (IS_SRC_OR_DST_PORT(LMP_PORT)) + lmp_print(ndo, cp, length); else if (IS_SRC_OR_DST_PORT(VQP_PORT)) - vqp_print(ndo, (const u_char *)(up + 1), length); - else if (IS_SRC_OR_DST_PORT(SFLOW_PORT)) - sflow_print(ndo, (const u_char *)(up + 1), length); - else if (dport == LWAPP_CONTROL_PORT) - lwapp_control_print(ndo, (const u_char *)(up + 1), length, 1); - else if (sport == LWAPP_CONTROL_PORT) - lwapp_control_print(ndo, (const u_char *)(up + 1), length, 0); - else if (IS_SRC_OR_DST_PORT(LWAPP_DATA_PORT)) - lwapp_data_print(ndo, (const u_char *)(up + 1), length); - else if (IS_SRC_OR_DST_PORT(SIP_PORT)) - sip_print(ndo, (const u_char *)(up + 1), length); - else if (IS_SRC_OR_DST_PORT(SYSLOG_PORT)) - syslog_print(ndo, (const u_char *)(up + 1), length); - else if (IS_SRC_OR_DST_PORT(OTV_PORT)) - otv_print(ndo, (const u_char *)(up + 1), length); - else if (IS_SRC_OR_DST_PORT(VXLAN_PORT)) - vxlan_print(ndo, (const u_char *)(up + 1), length); - else if (IS_SRC_OR_DST_PORT(GENEVE_PORT)) - geneve_print(ndo, (const u_char *)(up + 1), length); + vqp_print(ndo, cp, length); + else if (IS_SRC_OR_DST_PORT(SFLOW_PORT)) + sflow_print(ndo, cp, length); + else if (dport == LWAPP_CONTROL_PORT) + lwapp_control_print(ndo, cp, length, 1); + else if (sport == LWAPP_CONTROL_PORT) + lwapp_control_print(ndo, cp, length, 0); + else if (IS_SRC_OR_DST_PORT(LWAPP_DATA_PORT)) + lwapp_data_print(ndo, cp, length); + else if (IS_SRC_OR_DST_PORT(SIP_PORT)) + sip_print(ndo, cp, length); + else if (IS_SRC_OR_DST_PORT(SYSLOG_PORT)) + syslog_print(ndo, cp, length); + else if (IS_SRC_OR_DST_PORT(OTV_PORT)) + otv_print(ndo, cp, length); + else if (IS_SRC_OR_DST_PORT(VXLAN_PORT)) + vxlan_print(ndo, cp, length); + else if (IS_SRC_OR_DST_PORT(GENEVE_PORT)) + geneve_print(ndo, cp, length); else if (IS_SRC_OR_DST_PORT(LISP_CONTROL_PORT)) - lisp_print(ndo, (const u_char *)(up + 1), length); + lisp_print(ndo, cp, length); else if (IS_SRC_OR_DST_PORT(VXLAN_GPE_PORT)) - vxlan_gpe_print(ndo, (const u_char *)(up + 1), length); - else if (ND_TTEST(((const struct LAP *)cp)->type) && - ((const struct LAP *)cp)->type == lapDDP && - (atalk_port(sport) || atalk_port(dport))) { + vxlan_gpe_print(ndo, cp, length); + else if (IS_SRC_OR_DST_PORT(ZEP_PORT)) + zep_print(ndo, cp, length); + else if (IS_SRC_OR_DST_PORT(MPLS_PORT)) + mpls_print(ndo, cp, length); + else if (ND_TTEST_1(((const struct LAP *)cp)->type) && + GET_U_1(((const struct LAP *)cp)->type) == lapDDP && + (atalk_port(sport) || atalk_port(dport))) { if (ndo->ndo_vflag) - ND_PRINT((ndo, "kip ")); + ND_PRINT("kip "); llap_print(ndo, cp, length); - } else { - if (ulen > length) - ND_PRINT((ndo, "UDP, bad length %u > %u", - ulen, length)); + } else if (IS_SRC_OR_DST_PORT(PTP_EVENT_PORT) || + IS_SRC_OR_DST_PORT(PTP_GENERAL_PORT)) { + ptp_print(ndo, cp, length); + } else if (IS_SRC_OR_DST_PORT(SOMEIP_PORT)) + someip_print(ndo, cp, length); + else { + if (ulen > length && !fragmented) + ND_PRINT("UDP, bad length %u > %u", + ulen, length); else - ND_PRINT((ndo, "UDP, length %u", ulen)); + ND_PRINT("UDP, length %u", ulen); } } else { - if (ulen > length) - ND_PRINT((ndo, "UDP, bad length %u > %u", - ulen, length)); + if (ulen > length && !fragmented) + ND_PRINT("UDP, bad length %u > %u", + ulen, length); else - ND_PRINT((ndo, "UDP, length %u", ulen)); + ND_PRINT("UDP, length %u", ulen); } return; trunc: - ND_PRINT((ndo, "%s", udp_tstr)); + nd_print_trunc(ndo); } - - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/print-smtp.c b/contrib/tcpdump/print-unsupported.c similarity index 63% copy from contrib/tcpdump/print-smtp.c copy to contrib/tcpdump/print-unsupported.c index 0cdcf1d92c..009cf6f9b9 100644 --- a/contrib/tcpdump/print-smtp.c +++ b/contrib/tcpdump/print-unsupported.c @@ -1,4 +1,7 @@ /* + * Copyright (c) 2020 The TCPDUMP project + * 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 @@ -11,22 +14,21 @@ * FOR A PARTICULAR PURPOSE. */ -/* \summary: Simple Mail Transfer Protocol (SMTP) printer */ +/* \summary: unsupported link-layer protocols printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include - -#include -#include +#include "netdissect-stdinc.h" #include "netdissect.h" -#include "extract.h" void -smtp_print(netdissect_options *ndo, const u_char *pptr, u_int len) +unsupported_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, + const u_char *p) { - txtproto_print(ndo, pptr, len, "smtp", NULL, 0); + ndo->ndo_protocol = "unsupported"; + nd_print_protocol_caps(ndo); + hex_and_ascii_print(ndo, "\n\t", p, h->caplen); } diff --git a/contrib/tcpdump/print-usb.c b/contrib/tcpdump/print-usb.c index 04eb4efb4f..3f5937ba16 100644 --- a/contrib/tcpdump/print-usb.c +++ b/contrib/tcpdump/print-usb.c @@ -22,18 +22,120 @@ /* \summary: USB printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" +#include "extract.h" +#ifdef DLT_USB_LINUX +/* + * possible transfer mode + */ +#define URB_TRANSFER_IN 0x80 +#define URB_ISOCHRONOUS 0x0 +#define URB_INTERRUPT 0x1 +#define URB_CONTROL 0x2 +#define URB_BULK 0x3 + +/* + * possible event type + */ +#define URB_SUBMIT 'S' +#define URB_COMPLETE 'C' +#define URB_ERROR 'E' + +/* + * USB setup header as defined in USB specification. + * Appears at the front of each Control S-type packet in DLT_USB captures. + */ +typedef struct _usb_setup { + nd_uint8_t bmRequestType; + nd_uint8_t bRequest; + nd_uint16_t wValue; + nd_uint16_t wIndex; + nd_uint16_t wLength; +} pcap_usb_setup; + +/* + * Information from the URB for Isochronous transfers. + */ +typedef struct _iso_rec { + nd_int32_t error_count; + nd_int32_t numdesc; +} iso_rec; + +/* + * Header prepended by linux kernel to each event. + * Appears at the front of each packet in DLT_USB_LINUX captures. + */ +typedef struct _usb_header { + nd_uint64_t id; + nd_uint8_t event_type; + nd_uint8_t transfer_type; + nd_uint8_t endpoint_number; + nd_uint8_t device_address; + nd_uint16_t bus_id; + nd_uint8_t setup_flag;/*if !=0 the urb setup header is not present*/ + nd_uint8_t data_flag; /*if !=0 no urb data is present*/ + nd_int64_t ts_sec; + nd_int32_t ts_usec; + nd_int32_t status; + nd_uint32_t urb_len; + nd_uint32_t data_len; /* amount of urb data really present in this event*/ + pcap_usb_setup setup; +} pcap_usb_header; -#if defined(HAVE_PCAP_USB_H) && defined(DLT_USB_LINUX) -#include +/* + * Header prepended by linux kernel to each event for the 2.6.31 + * and later kernels; for the 2.6.21 through 2.6.30 kernels, the + * "iso_rec" information, and the fields starting with "interval" + * are zeroed-out padding fields. + * + * Appears at the front of each packet in DLT_USB_LINUX_MMAPPED captures. + */ +typedef struct _usb_header_mmapped { + nd_uint64_t id; + nd_uint8_t event_type; + nd_uint8_t transfer_type; + nd_uint8_t endpoint_number; + nd_uint8_t device_address; + nd_uint16_t bus_id; + nd_uint8_t setup_flag;/*if !=0 the urb setup header is not present*/ + nd_uint8_t data_flag; /*if !=0 no urb data is present*/ + nd_int64_t ts_sec; + nd_int32_t ts_usec; + nd_int32_t status; + nd_uint32_t urb_len; + nd_uint32_t data_len; /* amount of urb data really present in this event*/ + union { + pcap_usb_setup setup; + iso_rec iso; + } s; + nd_int32_t interval; /* for Interrupt and Isochronous events */ + nd_int32_t start_frame; /* for Isochronous events */ + nd_uint32_t xfer_flags; /* copy of URB's transfer flags */ + nd_uint32_t ndesc; /* number of isochronous descriptors */ +} pcap_usb_header_mmapped; + +/* + * Isochronous descriptors; for isochronous transfers there might be + * one or more of these at the beginning of the packet data. The + * number of descriptors is given by the "ndesc" field in the header; + * as indicated, in older kernels that don't put the descriptors at + * the beginning of the packet, that field is zeroed out, so that field + * can be trusted even in captures from older kernels. + */ +typedef struct _usb_isodesc { + nd_int32_t status; + nd_uint32_t offset; + nd_uint32_t len; + nd_byte pad[4]; +} usb_isodesc; -static const char tstr[] = "[|usb]"; /* returns direction: 1=inbound 2=outbound -1=invalid */ static int @@ -84,46 +186,58 @@ static void usb_header_print(netdissect_options *ndo, const pcap_usb_header *uh) { int direction; + uint8_t transfer_type, event_type; - switch(uh->transfer_type) + ndo->ndo_protocol = "usb"; + + nd_print_protocol_caps(ndo); + if (ndo->ndo_qflag) + return; + + ND_PRINT(" "); + transfer_type = GET_U_1(uh->transfer_type); + switch(transfer_type) { case URB_ISOCHRONOUS: - ND_PRINT((ndo, "ISOCHRONOUS")); + ND_PRINT("ISOCHRONOUS"); break; case URB_INTERRUPT: - ND_PRINT((ndo, "INTERRUPT")); + ND_PRINT("INTERRUPT"); break; case URB_CONTROL: - ND_PRINT((ndo, "CONTROL")); + ND_PRINT("CONTROL"); break; case URB_BULK: - ND_PRINT((ndo, "BULK")); + ND_PRINT("BULK"); break; default: - ND_PRINT((ndo, " ?")); + ND_PRINT(" ?"); } - switch(uh->event_type) + event_type = GET_U_1(uh->event_type); + switch(event_type) { case URB_SUBMIT: - ND_PRINT((ndo, " SUBMIT")); + ND_PRINT(" SUBMIT"); break; case URB_COMPLETE: - ND_PRINT((ndo, " COMPLETE")); + ND_PRINT(" COMPLETE"); break; case URB_ERROR: - ND_PRINT((ndo, " ERROR")); + ND_PRINT(" ERROR"); break; default: - ND_PRINT((ndo, " ?")); + ND_PRINT(" ?"); } - direction = get_direction(uh->transfer_type, uh->event_type); + direction = get_direction(transfer_type, event_type); if(direction == 1) - ND_PRINT((ndo, " from")); + ND_PRINT(" from"); else if(direction == 2) - ND_PRINT((ndo, " to")); - ND_PRINT((ndo, " %d:%d:%d", uh->bus_id, uh->device_address, uh->endpoint_number & 0x7f)); + ND_PRINT(" to"); + ND_PRINT(" %u:%u:%u", GET_HE_U_2(uh->bus_id), + GET_U_1(uh->device_address), + GET_U_1(uh->endpoint_number) & 0x7f); } /* @@ -134,18 +248,15 @@ usb_header_print(netdissect_options *ndo, const pcap_usb_header *uh) * '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(netdissect_options *ndo, const struct pcap_pkthdr *h, - register const u_char *p) +void +usb_linux_48_byte_if_print(netdissect_options *ndo, + const struct pcap_pkthdr *h _U_, const u_char *p) { - if (h->caplen < sizeof(pcap_usb_header)) { - ND_PRINT((ndo, "%s", tstr)); - return(sizeof(pcap_usb_header)); - } + ndo->ndo_protocol = "usb_linux_48_byte"; + ND_TCHECK_LEN(p, sizeof(pcap_usb_header)); + ndo->ndo_ll_hdr_len += sizeof (pcap_usb_header); usb_header_print(ndo, (const pcap_usb_header *) p); - - return(sizeof(pcap_usb_header)); } #ifdef DLT_USB_LINUX_MMAPPED @@ -157,20 +268,17 @@ usb_linux_48_byte_print(netdissect_options *ndo, const struct pcap_pkthdr *h, * '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(netdissect_options *ndo, const struct pcap_pkthdr *h, - register const u_char *p) +void +usb_linux_64_byte_if_print(netdissect_options *ndo, + const struct pcap_pkthdr *h _U_, const u_char *p) { - if (h->caplen < sizeof(pcap_usb_header_mmapped)) { - ND_PRINT((ndo, "%s", tstr)); - return(sizeof(pcap_usb_header_mmapped)); - } + ndo->ndo_protocol = "usb_linux_64_byte"; + ND_TCHECK_LEN(p, sizeof(pcap_usb_header_mmapped)); + ndo->ndo_ll_hdr_len += sizeof (pcap_usb_header_mmapped); usb_header_print(ndo, (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) */ +#endif /* DLT_USB_LINUX */ diff --git a/contrib/tcpdump/print-vjc.c b/contrib/tcpdump/print-vjc.c index 3287b9bcf7..830330717e 100644 --- a/contrib/tcpdump/print-vjc.c +++ b/contrib/tcpdump/print-vjc.c @@ -24,12 +24,13 @@ /* specification: RFC 1144 */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" +#include "extract.h" #include "slcompress.h" #include "ppp.h" @@ -76,45 +77,46 @@ * unused argument remind us that we should fix this some day. * * XXX - also, it fetches the TCP checksum field in COMPRESSED_TCP - * packets directly, rather than with EXTRACT_16BITS(); RFC 1144 says + * packets with GET_HE_U_2, rather than with GET_BE_U_2(); RFC 1144 says * it's "the unmodified TCP checksum", which would imply that it's * big-endian, but perhaps, on the platform where this was developed, * the packets were munged by the networking stack before being handed * to the packet capture mechanism. */ int -vjc_print(netdissect_options *ndo, register const char *bp, u_short proto _U_) +vjc_print(netdissect_options *ndo, const u_char *bp, u_short proto _U_) { int i; - switch (bp[0] & 0xf0) { + ndo->ndo_protocol = "vjc"; + switch (GET_U_1(bp) & 0xf0) { case TYPE_IP: if (ndo->ndo_eflag) - ND_PRINT((ndo, "(vjc type=IP) ")); + ND_PRINT("(vjc type=IP) "); return PPP_IP; case TYPE_UNCOMPRESSED_TCP: if (ndo->ndo_eflag) - ND_PRINT((ndo, "(vjc type=raw TCP) ")); + ND_PRINT("(vjc type=raw TCP) "); return PPP_IP; case TYPE_COMPRESSED_TCP: if (ndo->ndo_eflag) - ND_PRINT((ndo, "(vjc type=compressed TCP) ")); + ND_PRINT("(vjc type=compressed TCP) "); for (i = 0; i < 8; i++) { - if (bp[1] & (0x80 >> i)) - ND_PRINT((ndo, "%c", "?CI?SAWU"[i])); + if (GET_U_1(bp + 1) & (0x80 >> i)) + ND_PRINT("%c", "?CI?SAWU"[i]); } - if (bp[1]) - ND_PRINT((ndo, " ")); - ND_PRINT((ndo, "C=0x%02x ", bp[2])); - ND_PRINT((ndo, "sum=0x%04x ", *(const u_short *)&bp[3])); + if (GET_U_1(bp + 1)) + ND_PRINT(" "); + ND_PRINT("C=0x%02x ", GET_U_1(bp + 2)); + ND_PRINT("sum=0x%04x ", GET_HE_U_2(bp + 3)); return -1; case TYPE_ERROR: if (ndo->ndo_eflag) - ND_PRINT((ndo, "(vjc type=error) ")); + ND_PRINT("(vjc type=error) "); return -1; default: if (ndo->ndo_eflag) - ND_PRINT((ndo, "(vjc type=0x%02x) ", bp[0] & 0xf0)); + ND_PRINT("(vjc type=0x%02x) ", GET_U_1(bp) & 0xf0); return -1; } } diff --git a/contrib/tcpdump/print-vqp.c b/contrib/tcpdump/print-vqp.c index 90cf8ddfef..f87898e0d3 100644 --- a/contrib/tcpdump/print-vqp.c +++ b/contrib/tcpdump/print-vqp.c @@ -18,18 +18,17 @@ /* \summary: Cisco VLAN Query Protocol (VQP) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" #include "addrtoname.h" -#include "ether.h" #define VQP_VERSION 1 -#define VQP_EXTRACT_VERSION(x) ((x)&0xFF) /* * VQP common header @@ -44,16 +43,16 @@ */ struct vqp_common_header_t { - uint8_t version; - uint8_t msg_type; - uint8_t error_code; - uint8_t nitems; - uint8_t sequence[4]; + nd_uint8_t version; + nd_uint8_t msg_type; + nd_uint8_t error_code; + nd_uint8_t nitems; + nd_uint32_t sequence; }; struct vqp_obj_tlv_t { - uint8_t obj_type[4]; - uint8_t obj_length[2]; + nd_uint32_t obj_type; + nd_uint16_t obj_length; }; #define VQP_OBJ_REQ_JOIN_PORT 0x01 @@ -98,73 +97,76 @@ static const struct tok vqp_obj_values[] = { }; void -vqp_print(netdissect_options *ndo, register const u_char *pptr, register u_int len) +vqp_print(netdissect_options *ndo, const u_char *pptr, u_int len) { const struct vqp_common_header_t *vqp_common_header; const struct vqp_obj_tlv_t *vqp_obj_tlv; const u_char *tptr; + uint8_t version; uint16_t vqp_obj_len; uint32_t vqp_obj_type; u_int tlen; uint8_t nitems; + ndo->ndo_protocol = "vqp"; tptr=pptr; tlen = len; vqp_common_header = (const struct vqp_common_header_t *)pptr; - ND_TCHECK(*vqp_common_header); + ND_TCHECK_SIZE(vqp_common_header); if (sizeof(struct vqp_common_header_t) > tlen) - goto trunc; + goto invalid; + version = GET_U_1(vqp_common_header->version); /* * Sanity checking of the header. */ - if (VQP_EXTRACT_VERSION(vqp_common_header->version) != VQP_VERSION) { - ND_PRINT((ndo, "VQP version %u packet not supported", - VQP_EXTRACT_VERSION(vqp_common_header->version))); + if (version != VQP_VERSION) { + ND_PRINT("VQP version %u packet not supported", + version); return; } /* in non-verbose mode just lets print the basic Message Type */ if (ndo->ndo_vflag < 1) { - ND_PRINT((ndo, "VQPv%u %s Message, error-code %s (%u), length %u", - VQP_EXTRACT_VERSION(vqp_common_header->version), - tok2str(vqp_msg_type_values, "unknown (%u)",vqp_common_header->msg_type), - tok2str(vqp_error_code_values, "unknown (%u)",vqp_common_header->error_code), - vqp_common_header->error_code, - len)); + ND_PRINT("VQPv%u %s Message, error-code %s (%u), length %u", + version, + tok2str(vqp_msg_type_values, "unknown (%u)",GET_U_1(vqp_common_header->msg_type)), + tok2str(vqp_error_code_values, "unknown (%u)",GET_U_1(vqp_common_header->error_code)), + GET_U_1(vqp_common_header->error_code), + len); return; } /* ok they seem to want to know everything - lets fully decode it */ - nitems = vqp_common_header->nitems; - ND_PRINT((ndo, "\n\tVQPv%u, %s Message, error-code %s (%u), seq 0x%08x, items %u, length %u", - VQP_EXTRACT_VERSION(vqp_common_header->version), - tok2str(vqp_msg_type_values, "unknown (%u)",vqp_common_header->msg_type), - tok2str(vqp_error_code_values, "unknown (%u)",vqp_common_header->error_code), - vqp_common_header->error_code, - EXTRACT_32BITS(&vqp_common_header->sequence), - nitems, - len)); + nitems = GET_U_1(vqp_common_header->nitems); + ND_PRINT("\n\tVQPv%u, %s Message, error-code %s (%u), seq 0x%08x, items %u, length %u", + version, + tok2str(vqp_msg_type_values, "unknown (%u)",GET_U_1(vqp_common_header->msg_type)), + tok2str(vqp_error_code_values, "unknown (%u)",GET_U_1(vqp_common_header->error_code)), + GET_U_1(vqp_common_header->error_code), + GET_BE_U_4(vqp_common_header->sequence), + nitems, + len); /* skip VQP Common header */ - tptr+=sizeof(const struct vqp_common_header_t); - tlen-=sizeof(const struct vqp_common_header_t); + tptr+=sizeof(struct vqp_common_header_t); + tlen-=sizeof(struct vqp_common_header_t); - while (nitems > 0 && tlen > 0) { + while (nitems != 0 && tlen != 0) { vqp_obj_tlv = (const struct vqp_obj_tlv_t *)tptr; - ND_TCHECK(*vqp_obj_tlv); + ND_TCHECK_SIZE(vqp_obj_tlv); if (sizeof(struct vqp_obj_tlv_t) > tlen) - goto trunc; - vqp_obj_type = EXTRACT_32BITS(vqp_obj_tlv->obj_type); - vqp_obj_len = EXTRACT_16BITS(vqp_obj_tlv->obj_length); + goto invalid; + vqp_obj_type = GET_BE_U_4(vqp_obj_tlv->obj_type); + vqp_obj_len = GET_BE_U_2(vqp_obj_tlv->obj_length); tptr+=sizeof(struct vqp_obj_tlv_t); tlen-=sizeof(struct vqp_obj_tlv_t); - ND_PRINT((ndo, "\n\t %s Object (0x%08x), length %u, value: ", + ND_PRINT("\n\t %s Object (0x%08x), length %u, value: ", tok2str(vqp_obj_values, "Unknown", vqp_obj_type), - vqp_obj_type, vqp_obj_len)); + vqp_obj_type, vqp_obj_len); /* basic sanity check */ if (vqp_obj_type == 0 || vqp_obj_len ==0) { @@ -172,29 +174,30 @@ vqp_print(netdissect_options *ndo, register const u_char *pptr, register u_int l } /* did we capture enough for fully decoding the object ? */ - ND_TCHECK2(*tptr, vqp_obj_len); + ND_TCHECK_LEN(tptr, vqp_obj_len); if (vqp_obj_len > tlen) - goto trunc; + goto invalid; switch(vqp_obj_type) { case VQP_OBJ_IP_ADDRESS: if (vqp_obj_len != 4) - goto trunc; - ND_PRINT((ndo, "%s (0x%08x)", ipaddr_string(ndo, tptr), EXTRACT_32BITS(tptr))); + goto invalid; + ND_PRINT("%s (0x%08x)", GET_IPADDR_STRING(tptr), + GET_BE_U_4(tptr)); break; /* those objects have similar semantics - fall through */ case VQP_OBJ_PORT_NAME: case VQP_OBJ_VLAN_NAME: case VQP_OBJ_VTP_DOMAIN: case VQP_OBJ_ETHERNET_PKT: - safeputs(ndo, tptr, vqp_obj_len); + nd_printjnp(ndo, tptr, vqp_obj_len); break; /* those objects have similar semantics - fall through */ case VQP_OBJ_MAC_ADDRESS: case VQP_OBJ_MAC_NULL: - if (vqp_obj_len != ETHER_ADDR_LEN) - goto trunc; - ND_PRINT((ndo, "%s", etheraddr_string(ndo, tptr))); + if (vqp_obj_len != MAC_ADDR_LEN) + goto invalid; + ND_PRINT("%s", GET_ETHERADDR_STRING(tptr)); break; default: if (ndo->ndo_vflag <= 1) @@ -206,6 +209,6 @@ vqp_print(netdissect_options *ndo, register const u_char *pptr, register u_int l nitems--; } return; -trunc: - ND_PRINT((ndo, "\n\t[|VQP]")); +invalid: + nd_print_invalid(ndo); } diff --git a/contrib/tcpdump/print-vrrp.c b/contrib/tcpdump/print-vrrp.c index a39766767e..ee97974ecd 100644 --- a/contrib/tcpdump/print-vrrp.c +++ b/contrib/tcpdump/print-vrrp.c @@ -26,10 +26,10 @@ /* \summary: Virtual Router Redundancy Protocol (VRRP) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "extract.h" @@ -104,84 +104,74 @@ static const struct tok auth2str[] = { void vrrp_print(netdissect_options *ndo, - register const u_char *bp, register u_int len, - register const u_char *bp2, int ttl) + const u_char *bp, u_int len, + const u_char *bp2, int ttl) { int version, type, auth_type = VRRP_AUTH_NONE; /* keep compiler happy */ const char *type_s; - ND_TCHECK(bp[0]); - version = (bp[0] & 0xf0) >> 4; - type = bp[0] & 0x0f; + ndo->ndo_protocol = "vrrp"; + version = (GET_U_1(bp) & 0xf0) >> 4; + type = GET_U_1(bp) & 0x0f; type_s = tok2str(type2str, "unknown type (%u)", type); - ND_PRINT((ndo, "VRRPv%u, %s", version, type_s)); + ND_PRINT("VRRPv%u, %s", version, type_s); if (ttl != 255) - ND_PRINT((ndo, ", (ttl %u)", ttl)); + ND_PRINT(", (ttl %u)", ttl); if (version < 2 || version > 3 || type != VRRP_TYPE_ADVERTISEMENT) return; - ND_TCHECK(bp[2]); - ND_PRINT((ndo, ", vrid %u, prio %u", bp[1], bp[2])); - ND_TCHECK(bp[5]); + ND_PRINT(", vrid %u, prio %u", GET_U_1(bp + 1), GET_U_1(bp + 2)); if (version == 2) { - auth_type = bp[4]; - ND_PRINT((ndo, ", authtype %s", tok2str(auth2str, NULL, auth_type))); - ND_PRINT((ndo, ", intvl %us, length %u", bp[5], len)); + auth_type = GET_U_1(bp + 4); + ND_PRINT(", authtype %s", tok2str(auth2str, NULL, auth_type)); + ND_PRINT(", intvl %us, length %u", GET_U_1(bp + 5), len); } else { /* version == 3 */ - uint16_t intvl = (bp[4] & 0x0f) << 8 | bp[5]; - ND_PRINT((ndo, ", intvl %ucs, length %u", intvl, len)); + uint16_t intvl = (GET_U_1(bp + 4) & 0x0f) << 8 | GET_U_1(bp + 5); + ND_PRINT(", intvl %ucs, length %u", intvl, len); } if (ndo->ndo_vflag) { - int naddrs = bp[3]; - int i; + u_int naddrs = GET_U_1(bp + 3); + u_int i; char c; - if (version == 2 && ND_TTEST2(bp[0], len)) { + if (version == 2 && ND_TTEST_LEN(bp, len)) { struct cksum_vec vec[1]; vec[0].ptr = bp; vec[0].len = len; - if (in_cksum(vec, 1)) { - ND_TCHECK_16BITS(&bp[6]); - ND_PRINT((ndo, ", (bad vrrp cksum %x)", - EXTRACT_16BITS(&bp[6]))); - } + if (in_cksum(vec, 1)) + ND_PRINT(", (bad vrrp cksum %x)", + GET_BE_U_2(bp + 6)); } - if (version == 3 && ND_TTEST2(bp[0], len)) { + if (version == 3 && ND_TTEST_LEN(bp, len)) { uint16_t cksum = nextproto4_cksum(ndo, (const struct ip *)bp2, bp, len, len, IPPROTO_VRRP); - if (cksum) { - ND_TCHECK_16BITS(&bp[6]); - ND_PRINT((ndo, ", (bad vrrp cksum %x)", - EXTRACT_16BITS(&bp[6]))); - } + if (cksum) + ND_PRINT(", (bad vrrp cksum %x)", + GET_BE_U_2(bp + 6)); } - ND_PRINT((ndo, ", addrs")); + ND_PRINT(", addrs"); if (naddrs > 1) - ND_PRINT((ndo, "(%d)", naddrs)); - ND_PRINT((ndo, ":")); + ND_PRINT("(%u)", naddrs); + ND_PRINT(":"); c = ' '; bp += 8; for (i = 0; i < naddrs; i++) { - ND_TCHECK(bp[3]); - ND_PRINT((ndo, "%c%s", c, ipaddr_string(ndo, bp))); + ND_PRINT("%c%s", c, GET_IPADDR_STRING(bp)); c = ','; bp += 4; } if (version == 2 && auth_type == VRRP_AUTH_SIMPLE) { /* simple text password */ - ND_TCHECK(bp[7]); - ND_PRINT((ndo, " auth \"")); - if (fn_printn(ndo, bp, 8, ndo->ndo_snapend)) { - ND_PRINT((ndo, "\"")); - goto trunc; - } - ND_PRINT((ndo, "\"")); + ND_PRINT(" auth \""); + /* + * RFC 2338 Section 5.3.10: "If the configured authentication string + * is shorter than 8 bytes, the remaining space MUST be zero-filled. + */ + nd_printjnp(ndo, bp, 8); + ND_PRINT("\""); } } - return; -trunc: - ND_PRINT((ndo, "[|vrrp]")); } diff --git a/contrib/tcpdump/print-vsock.c b/contrib/tcpdump/print-vsock.c new file mode 100644 index 0000000000..bb18c92b8c --- /dev/null +++ b/contrib/tcpdump/print-vsock.c @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2016 Gerard Garcia + * Copyright (c) 2017 Red Hat, Inc. + * + * 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. The names of the authors 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. + */ + +/* \summary: Linux vsock printer */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "netdissect-stdinc.h" +#include + +#include "netdissect.h" +#include "extract.h" + +enum af_vsockmon_transport { + AF_VSOCK_TRANSPORT_UNKNOWN = 0, + AF_VSOCK_TRANSPORT_NO_INFO = 1, /* No transport information */ + AF_VSOCK_TRANSPORT_VIRTIO = 2, /* Virtio transport header */ +}; + +static const struct tok vsock_transport[] = { + {AF_VSOCK_TRANSPORT_UNKNOWN, "UNKNOWN"}, + {AF_VSOCK_TRANSPORT_NO_INFO, "NO_INFO"}, + {AF_VSOCK_TRANSPORT_VIRTIO, "VIRTIO"}, + { 0, NULL } +}; + +enum af_vsockmon_op { + AF_VSOCK_OP_UNKNOWN = 0, + AF_VSOCK_OP_CONNECT = 1, + AF_VSOCK_OP_DISCONNECT = 2, + AF_VSOCK_OP_CONTROL = 3, + AF_VSOCK_OP_PAYLOAD = 4, +}; + +static const struct tok vsock_op[] = { + {AF_VSOCK_OP_UNKNOWN, "UNKNOWN"}, + {AF_VSOCK_OP_CONNECT, "CONNECT"}, + {AF_VSOCK_OP_DISCONNECT, "DISCONNECT"}, + {AF_VSOCK_OP_CONTROL, "CONTROL"}, + {AF_VSOCK_OP_PAYLOAD, "PAYLOAD"}, + { 0, NULL } +}; + +enum virtio_vsock_type { + VIRTIO_VSOCK_TYPE_STREAM = 1, +}; + +static const struct tok virtio_type[] = { + {VIRTIO_VSOCK_TYPE_STREAM, "STREAM"}, + { 0, NULL } +}; + +enum virtio_vsock_op { + VIRTIO_VSOCK_OP_INVALID = 0, + VIRTIO_VSOCK_OP_REQUEST = 1, + VIRTIO_VSOCK_OP_RESPONSE = 2, + VIRTIO_VSOCK_OP_RST = 3, + VIRTIO_VSOCK_OP_SHUTDOWN = 4, + VIRTIO_VSOCK_OP_RW = 5, + VIRTIO_VSOCK_OP_CREDIT_UPDATE = 6, + VIRTIO_VSOCK_OP_CREDIT_REQUEST = 7, +}; + +static const struct tok virtio_op[] = { + {VIRTIO_VSOCK_OP_INVALID, "INVALID"}, + {VIRTIO_VSOCK_OP_REQUEST, "REQUEST"}, + {VIRTIO_VSOCK_OP_RESPONSE, "RESPONSE"}, + {VIRTIO_VSOCK_OP_RST, "RST"}, + {VIRTIO_VSOCK_OP_SHUTDOWN, "SHUTDOWN"}, + {VIRTIO_VSOCK_OP_RW, "RW"}, + {VIRTIO_VSOCK_OP_CREDIT_UPDATE, "CREDIT UPDATE"}, + {VIRTIO_VSOCK_OP_CREDIT_REQUEST, "CREDIT REQUEST"}, + { 0, NULL } +}; + +/* All fields are little-endian */ + +struct virtio_vsock_hdr { + nd_uint64_t src_cid; + nd_uint64_t dst_cid; + nd_uint32_t src_port; + nd_uint32_t dst_port; + nd_uint32_t len; + nd_uint16_t type; /* enum virtio_vsock_type */ + nd_uint16_t op; /* enum virtio_vsock_op */ + nd_uint32_t flags; + nd_uint32_t buf_alloc; + nd_uint32_t fwd_cnt; +}; + +struct af_vsockmon_hdr { + nd_uint64_t src_cid; + nd_uint64_t dst_cid; + nd_uint32_t src_port; + nd_uint32_t dst_port; + nd_uint16_t op; /* enum af_vsockmon_op */ + nd_uint16_t transport; /* enum af_vosckmon_transport */ + nd_uint16_t len; /* size of transport header */ + nd_uint8_t reserved[2]; +}; + +static void +vsock_virtio_hdr_print(netdissect_options *ndo, const struct virtio_vsock_hdr *hdr) +{ + uint16_t u16_v; + uint32_t u32_v; + + u32_v = GET_LE_U_4(hdr->len); + ND_PRINT("len %u", u32_v); + + u16_v = GET_LE_U_2(hdr->type); + ND_PRINT(", type %s", + tok2str(virtio_type, "Invalid type (%hu)", u16_v)); + + u16_v = GET_LE_U_2(hdr->op); + ND_PRINT(", op %s", + tok2str(virtio_op, "Invalid op (%hu)", u16_v)); + + u32_v = GET_LE_U_4(hdr->flags); + ND_PRINT(", flags %x", u32_v); + + u32_v = GET_LE_U_4(hdr->buf_alloc); + ND_PRINT(", buf_alloc %u", u32_v); + + u32_v = GET_LE_U_4(hdr->fwd_cnt); + ND_PRINT(", fwd_cnt %u", u32_v); +} + +/* + * This size had better fit in a u_int. + */ +static u_int +vsock_transport_hdr_size(uint16_t transport) +{ + switch (transport) { + case AF_VSOCK_TRANSPORT_VIRTIO: + return (u_int)sizeof(struct virtio_vsock_hdr); + default: + return 0; + } +} + +/* Returns 0 on success, -1 on truncation */ +static int +vsock_transport_hdr_print(netdissect_options *ndo, uint16_t transport, + const u_char *p, const u_int caplen) +{ + u_int transport_size = vsock_transport_hdr_size(transport); + const void *hdr; + + if (caplen < sizeof(struct af_vsockmon_hdr) + transport_size) { + return -1; + } + + hdr = p + sizeof(struct af_vsockmon_hdr); + switch (transport) { + case AF_VSOCK_TRANSPORT_VIRTIO: + ND_PRINT(" ("); + vsock_virtio_hdr_print(ndo, hdr); + ND_PRINT(")"); + break; + default: + break; + } + return 0; +} + +static void +vsock_hdr_print(netdissect_options *ndo, const u_char *p, const u_int caplen) +{ + const struct af_vsockmon_hdr *hdr = (const struct af_vsockmon_hdr *)p; + uint16_t hdr_transport, hdr_op; + uint32_t hdr_src_port, hdr_dst_port; + uint64_t hdr_src_cid, hdr_dst_cid; + u_int total_hdr_size; + int ret = 0; + + hdr_transport = GET_LE_U_2(hdr->transport); + ND_PRINT("%s", + tok2str(vsock_transport, "Invalid transport (%u)", + hdr_transport)); + + /* If verbose level is more than 0 print transport details */ + if (ndo->ndo_vflag) { + ret = vsock_transport_hdr_print(ndo, hdr_transport, p, caplen); + if (ret == 0) + ND_PRINT("\n\t"); + } else + ND_PRINT(" "); + + hdr_src_cid = GET_LE_U_8(hdr->src_cid); + hdr_dst_cid = GET_LE_U_8(hdr->dst_cid); + hdr_src_port = GET_LE_U_4(hdr->src_port); + hdr_dst_port = GET_LE_U_4(hdr->dst_port); + hdr_op = GET_LE_U_2(hdr->op); + ND_PRINT("%" PRIu64 ".%u > %" PRIu64 ".%u %s, length %u", + hdr_src_cid, hdr_src_port, + hdr_dst_cid, hdr_dst_port, + tok2str(vsock_op, " invalid op (%u)", hdr_op), + caplen); + + if (ret < 0) + goto trunc; + + /* If debug level is more than 1 print payload contents */ + /* This size had better fit in a u_int */ + total_hdr_size = (u_int)sizeof(struct af_vsockmon_hdr) + + vsock_transport_hdr_size(hdr_transport); + if (ndo->ndo_vflag > 1 && hdr_op == AF_VSOCK_OP_PAYLOAD) { + if (caplen > total_hdr_size) { + const u_char *payload = p + total_hdr_size; + + ND_PRINT("\n"); + print_unknown_data(ndo, payload, "\t", + caplen - total_hdr_size); + } else + goto trunc; + } + return; + +trunc: + nd_print_trunc(ndo); +} + +void +vsock_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, + const u_char *cp) +{ + u_int caplen = h->caplen; + + ndo->ndo_protocol = "vsock"; + + if (caplen < sizeof(struct af_vsockmon_hdr)) { + nd_print_trunc(ndo); + ndo->ndo_ll_hdr_len += caplen; + return; + } + ndo->ndo_ll_hdr_len += sizeof(struct af_vsockmon_hdr); + vsock_hdr_print(ndo, cp, caplen); +} diff --git a/contrib/tcpdump/print-vtp.c b/contrib/tcpdump/print-vtp.c index d69c4093e9..bcee64cfe5 100644 --- a/contrib/tcpdump/print-vtp.c +++ b/contrib/tcpdump/print-vtp.c @@ -13,8 +13,8 @@ * FOR A PARTICULAR PURPOSE. * * Reference documentation: - * http://www.cisco.com/c/en/us/support/docs/lan-switching/vtp/10558-21.html - * http://docstore.mik.ua/univercd/cc/td/doc/product/lan/trsrb/frames.htm + * https://www.cisco.com/c/en/us/support/docs/lan-switching/vtp/10558-21.html + * https://docstore.mik.ua/univercd/cc/td/doc/product/lan/trsrb/frames.htm * * Original code ode by Carles Kishimoto */ @@ -22,11 +22,12 @@ /* \summary: Cisco VLAN Trunking Protocol (VTP) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "addrtoname.h" #include "extract.h" @@ -43,13 +44,13 @@ #define VTP_JOIN_MESSAGE 0x04 struct vtp_vlan_ { - uint8_t len; - uint8_t status; - uint8_t type; - uint8_t name_len; - uint16_t vlanid; - uint16_t mtu; - uint32_t index; + nd_uint8_t len; + nd_uint8_t status; + nd_uint8_t type; + nd_uint8_t name_len; + nd_uint16_t vlanid; + nd_uint16_t mtu; + nd_uint32_t index; }; static const struct tok vtp_message_type_values[] = { @@ -116,43 +117,44 @@ static const struct tok vtp_stp_type_values[] = { }; void -vtp_print (netdissect_options *ndo, - const u_char *pptr, u_int length) +vtp_print(netdissect_options *ndo, + const u_char *pptr, const u_int length) { - int type, len, tlv_len, tlv_value, mgmtd_len; + u_int type, len, name_len, tlv_len, tlv_value, mgmtd_len; const u_char *tptr; const struct vtp_vlan_ *vtp_vlan; + ndo->ndo_protocol = "vtp"; if (length < VTP_HEADER_LEN) - goto trunc; + goto invalid; tptr = pptr; - ND_TCHECK2(*tptr, VTP_HEADER_LEN); + ND_TCHECK_LEN(tptr, VTP_HEADER_LEN); - type = *(tptr+1); - ND_PRINT((ndo, "VTPv%u, Message %s (0x%02x), length %u", - *tptr, + type = GET_U_1(tptr + 1); + ND_PRINT("VTPv%u, Message %s (0x%02x), length %u", + GET_U_1(tptr), tok2str(vtp_message_type_values,"Unknown message type", type), type, - length)); + length); /* In non-verbose mode, just print version and message type */ if (ndo->ndo_vflag < 1) { - return; + goto tcheck_full_packet; } /* verbose mode print all fields */ - ND_PRINT((ndo, "\n\tDomain name: ")); - mgmtd_len = *(tptr + 3); - if (mgmtd_len < 1 || mgmtd_len > 32) { - ND_PRINT((ndo, " [invalid MgmtD Len %d]", mgmtd_len)); - return; + ND_PRINT("\n\tDomain name: "); + mgmtd_len = GET_U_1(tptr + 3); + if (mgmtd_len < 1 || mgmtd_len > VTP_DOMAIN_NAME_LEN) { + ND_PRINT(" [invalid MgmtD Len %u]", mgmtd_len); + goto invalid; } - fn_printzp(ndo, tptr + 4, mgmtd_len, NULL); - ND_PRINT((ndo, ", %s: %u", + nd_printjnp(ndo, tptr + 4, mgmtd_len); + ND_PRINT(", %s: %u", tok2str(vtp_header_values, "Unknown", type), - *(tptr+2))); + GET_U_1(tptr + 2)); tptr += VTP_HEADER_LEN; @@ -180,23 +182,20 @@ vtp_print (netdissect_options *ndo, * */ - ND_TCHECK2(*tptr, 8); - ND_PRINT((ndo, "\n\t Config Rev %x, Updater %s", - EXTRACT_32BITS(tptr), - ipaddr_string(ndo, tptr+4))); + ND_PRINT("\n\t Config Rev %x, Updater %s", + GET_BE_U_4(tptr), + GET_IPADDR_STRING(tptr+4)); tptr += 8; - ND_TCHECK2(*tptr, VTP_UPDATE_TIMESTAMP_LEN); - ND_PRINT((ndo, ", Timestamp 0x%08x 0x%08x 0x%08x", - EXTRACT_32BITS(tptr), - EXTRACT_32BITS(tptr + 4), - EXTRACT_32BITS(tptr + 8))); + ND_PRINT(", Timestamp 0x%08x 0x%08x 0x%08x", + GET_BE_U_4(tptr), + GET_BE_U_4(tptr + 4), + GET_BE_U_4(tptr + 8)); tptr += VTP_UPDATE_TIMESTAMP_LEN; - ND_TCHECK2(*tptr, VTP_MD5_DIGEST_LEN); - ND_PRINT((ndo, ", MD5 digest: %08x%08x%08x%08x", - EXTRACT_32BITS(tptr), - EXTRACT_32BITS(tptr + 4), - EXTRACT_32BITS(tptr + 8), - EXTRACT_32BITS(tptr + 12))); + ND_PRINT(", MD5 digest: %08x%08x%08x%08x", + GET_BE_U_4(tptr), + GET_BE_U_4(tptr + 4), + GET_BE_U_4(tptr + 8), + GET_BE_U_4(tptr + 12)); tptr += VTP_MD5_DIGEST_LEN; break; @@ -222,8 +221,7 @@ vtp_print (netdissect_options *ndo, * */ - ND_TCHECK_32BITS(tptr); - ND_PRINT((ndo, ", Config Rev %x", EXTRACT_32BITS(tptr))); + ND_PRINT(", Config Rev %x", GET_BE_U_4(tptr)); /* * VLAN INFORMATION @@ -243,35 +241,33 @@ vtp_print (netdissect_options *ndo, tptr += 4; while ((unsigned)(tptr - pptr) < length) { - ND_TCHECK_8BITS(tptr); - len = *tptr; + len = GET_U_1(tptr); if (len == 0) break; - ND_TCHECK2(*tptr, len); + ND_TCHECK_LEN(tptr, len); vtp_vlan = (const struct vtp_vlan_*)tptr; if (len < VTP_VLAN_INFO_FIXED_PART_LEN) - goto trunc; - ND_TCHECK(*vtp_vlan); - ND_PRINT((ndo, "\n\tVLAN info status %s, type %s, VLAN-id %u, MTU %u, SAID 0x%08x, Name ", - tok2str(vtp_vlan_status,"Unknown",vtp_vlan->status), - tok2str(vtp_vlan_type_values,"Unknown",vtp_vlan->type), - EXTRACT_16BITS(&vtp_vlan->vlanid), - EXTRACT_16BITS(&vtp_vlan->mtu), - EXTRACT_32BITS(&vtp_vlan->index))); + goto invalid; + ND_PRINT("\n\tVLAN info status %s, type %s, VLAN-id %u, MTU %u, SAID 0x%08x, Name ", + tok2str(vtp_vlan_status,"Unknown",GET_U_1(vtp_vlan->status)), + tok2str(vtp_vlan_type_values,"Unknown",GET_U_1(vtp_vlan->type)), + GET_BE_U_2(vtp_vlan->vlanid), + GET_BE_U_2(vtp_vlan->mtu), + GET_BE_U_4(vtp_vlan->index)); len -= VTP_VLAN_INFO_FIXED_PART_LEN; tptr += VTP_VLAN_INFO_FIXED_PART_LEN; - if (len < 4*((vtp_vlan->name_len + 3)/4)) - goto trunc; - ND_TCHECK2(*tptr, vtp_vlan->name_len); - fn_printzp(ndo, tptr, vtp_vlan->name_len, NULL); + name_len = GET_U_1(vtp_vlan->name_len); + if (len < 4*((name_len + 3)/4)) + goto invalid; + nd_printjnp(ndo, tptr, name_len); /* * Vlan names are aligned to 32-bit boundaries. */ - len -= 4*((vtp_vlan->name_len + 3)/4); - tptr += 4*((vtp_vlan->name_len + 3)/4); + len -= 4*((name_len + 3)/4); + tptr += 4*((name_len + 3)/4); /* TLV information follows */ @@ -279,64 +275,63 @@ vtp_print (netdissect_options *ndo, /* * Cisco specs say 2 bytes for type + 2 bytes for length; - * see http://docstore.mik.ua/univercd/cc/td/doc/product/lan/trsrb/frames.htm + * see https://docstore.mik.ua/univercd/cc/td/doc/product/lan/trsrb/frames.htm * However, actual packets on the wire appear to use 1 * byte for the type and 1 byte for the length, so that's * what we do. */ if (len < 2) - goto trunc; - ND_TCHECK2(*tptr, 2); - type = *tptr; - tlv_len = *(tptr+1); + goto invalid; + type = GET_U_1(tptr); + tlv_len = GET_U_1(tptr + 1); - ND_PRINT((ndo, "\n\t\t%s (0x%04x) TLV", + ND_PRINT("\n\t\t%s (0x%04x) TLV", tok2str(vtp_vlan_tlv_values, "Unknown", type), - type)); + type); if (len < tlv_len * 2 + 2) { - ND_PRINT((ndo, " (TLV goes past the end of the packet)")); - return; + ND_PRINT(" (TLV goes past the end of the packet)"); + goto invalid; } - ND_TCHECK2(*tptr, tlv_len * 2 +2); + ND_TCHECK_LEN(tptr, tlv_len * 2 + 2); /* * We assume the value is a 2-byte integer; the length is * in units of 16-bit words. */ if (tlv_len != 1) { - ND_PRINT((ndo, " (invalid TLV length %u != 1)", tlv_len)); - return; + ND_PRINT(" (invalid TLV length %u != 1)", tlv_len); + goto invalid; } else { - tlv_value = EXTRACT_16BITS(tptr+2); + tlv_value = GET_BE_U_2(tptr + 2); switch (type) { case VTP_VLAN_STE_HOP_COUNT: - ND_PRINT((ndo, ", %u", tlv_value)); + ND_PRINT(", %u", tlv_value); break; case VTP_VLAN_PRUNING: - ND_PRINT((ndo, ", %s (%u)", + ND_PRINT(", %s (%u)", tlv_value == 1 ? "Enabled" : "Disabled", - tlv_value)); + tlv_value); break; case VTP_VLAN_STP_TYPE: - ND_PRINT((ndo, ", %s (%u)", + ND_PRINT(", %s (%u)", tok2str(vtp_stp_type_values, "Unknown", tlv_value), - tlv_value)); + tlv_value); break; case VTP_VLAN_BRIDGE_TYPE: - ND_PRINT((ndo, ", %s (%u)", + ND_PRINT(", %s (%u)", tlv_value == 1 ? "SRB" : "SRT", - tlv_value)); + tlv_value); break; case VTP_VLAN_BACKUP_CRF_MODE: - ND_PRINT((ndo, ", %s (%u)", + ND_PRINT(", %s (%u)", tlv_value == 1 ? "Backup" : "Not backup", - tlv_value)); + tlv_value); break; /* @@ -376,8 +371,7 @@ vtp_print (netdissect_options *ndo, * */ - ND_TCHECK2(*tptr, 4); - ND_PRINT((ndo, "\n\tStart value: %u", EXTRACT_32BITS(tptr))); + ND_PRINT("\n\tStart value: %u", GET_BE_U_4(tptr)); break; case VTP_JOIN_MESSAGE: @@ -391,13 +385,8 @@ vtp_print (netdissect_options *ndo, return; - trunc: - ND_PRINT((ndo, "[|vtp]")); +invalid: + nd_print_invalid(ndo); +tcheck_full_packet: + ND_TCHECK_LEN(pptr, length); } - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 4 - * End: - */ diff --git a/contrib/tcpdump/print-vxlan-gpe.c b/contrib/tcpdump/print-vxlan-gpe.c index 6d170de10e..13cba42293 100644 --- a/contrib/tcpdump/print-vxlan-gpe.c +++ b/contrib/tcpdump/print-vxlan-gpe.c @@ -23,21 +23,22 @@ /* \summary: Generic Protocol Extension for VXLAN (VXLAN GPE) printer */ -/* specification: draft-ietf-nvo3-vxlan-gpe-01 */ +/* specification: draft-ietf-nvo3-vxlan-gpe-10 */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" -static const char tstr[] = " [|VXLAN-GPE]"; static const struct tok vxlan_gpe_flags [] = { { 0x08, "I" }, { 0x04, "P" }, + { 0x02, "B" }, { 0x01, "O" }, { 0, NULL } }; @@ -64,50 +65,60 @@ vxlan_gpe_print(netdissect_options *ndo, const u_char *bp, u_int len) uint8_t next_protocol; uint32_t vni; - if (len < VXLAN_GPE_HDR_LEN) - goto trunc; + ndo->ndo_protocol = "vxlan_gpe"; + ND_PRINT("VXLAN-GPE, "); + if (len < VXLAN_GPE_HDR_LEN) { + ND_PRINT(" (len %u < %u)", len, VXLAN_GPE_HDR_LEN); + goto invalid; + } - ND_TCHECK2(*bp, VXLAN_GPE_HDR_LEN); + flags = GET_U_1(bp); + bp += 1; + len -= 1; + ND_PRINT("flags [%s], ", + bittok2str_nosep(vxlan_gpe_flags, "none", flags)); - flags = *bp; - bp += 3; + /* Reserved */ + bp += 2; + len -= 2; - next_protocol = *bp; + next_protocol = GET_U_1(bp); bp += 1; + len -= 1; - vni = EXTRACT_24BITS(bp); - bp += 4; + vni = GET_BE_U_3(bp); + bp += 3; + len -= 3; - ND_PRINT((ndo, "VXLAN-GPE, ")); - ND_PRINT((ndo, "flags [%s], ", - bittok2str_nosep(vxlan_gpe_flags, "none", flags))); - ND_PRINT((ndo, "vni %u", vni)); - ND_PRINT((ndo, ndo->ndo_vflag ? "\n " : ": ")); + /* Reserved */ + ND_TCHECK_1(bp); + bp += 1; + len -= 1; + + ND_PRINT("vni %u", vni); + ND_PRINT(ndo->ndo_vflag ? "\n " : ": "); switch (next_protocol) { case 0x1: - ip_print(ndo, bp, len - 8); + ip_print(ndo, bp, len); break; case 0x2: - ip6_print(ndo, bp, len - 8); + ip6_print(ndo, bp, len); break; case 0x3: - ether_print(ndo, bp, len - 8, ndo->ndo_snapend - bp, NULL, NULL); + ether_print(ndo, bp, len, ND_BYTES_AVAILABLE_AFTER(bp), NULL, NULL); break; case 0x4: - nsh_print(ndo, bp, len - 8); - break; - case 0x5: - mpls_print(ndo, bp, len - 8); + nsh_print(ndo, bp, len); break; default: - ND_PRINT((ndo, "ERROR: unknown-next-protocol")); - return; + ND_PRINT("ERROR: unknown-next-protocol"); + goto invalid; } return; -trunc: - ND_PRINT((ndo, "%s", tstr)); +invalid: + nd_print_invalid(ndo); } diff --git a/contrib/tcpdump/print-vxlan.c b/contrib/tcpdump/print-vxlan.c index 0c2a82e2af..60dcd44def 100644 --- a/contrib/tcpdump/print-vxlan.c +++ b/contrib/tcpdump/print-vxlan.c @@ -18,16 +18,19 @@ /* specification: RFC 7348 */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "extract.h" -static const char tstr[] = " [|VXLAN]"; - +static const struct tok vxlan_flags [] = { + { 0x08, "I" }, + { 0, NULL } +}; #define VXLAN_HDR_LEN 8 /* @@ -50,25 +53,31 @@ vxlan_print(netdissect_options *ndo, const u_char *bp, u_int len) uint8_t flags; uint32_t vni; + ndo->ndo_protocol = "vxlan"; + nd_print_protocol_caps(ndo); if (len < VXLAN_HDR_LEN) - goto trunc; + goto invalid; - ND_TCHECK2(*bp, VXLAN_HDR_LEN); + flags = GET_U_1(bp); + bp += 1; + ND_PRINT(", flags [%s] (0x%02x), ", + bittok2str_nosep(vxlan_flags, "invalid", flags), flags); - flags = *bp; - bp += 4; + /* 1st Reserved */ + bp += 3; - vni = EXTRACT_24BITS(bp); - bp += 4; + vni = GET_BE_U_3(bp); + bp += 3; + ND_PRINT("vni %u\n", vni); - ND_PRINT((ndo, "VXLAN, ")); - ND_PRINT((ndo, "flags [%s] (0x%02x), ", flags & 0x08 ? "I" : ".", flags)); - ND_PRINT((ndo, "vni %u\n", vni)); + /* 2nd Reserved */ + ND_TCHECK_1(bp); + bp += 1; - ether_print(ndo, bp, len - VXLAN_HDR_LEN, ndo->ndo_snapend - bp, NULL, NULL); + ether_print(ndo, bp, len - VXLAN_HDR_LEN, ND_BYTES_AVAILABLE_AFTER(bp), NULL, NULL); return; -trunc: - ND_PRINT((ndo, "%s", tstr)); +invalid: + nd_print_invalid(ndo); } diff --git a/contrib/tcpdump/print-wb.c b/contrib/tcpdump/print-wb.c index f90170b80e..35b5a196d8 100644 --- a/contrib/tcpdump/print-wb.c +++ b/contrib/tcpdump/print-wb.c @@ -22,46 +22,45 @@ /* \summary: White Board printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "addrtoname.h" #include "extract.h" -static const char tstr[] = "[|wb]"; - -/* XXX need to add byte-swapping macros! */ -/* XXX - you mean like the ones in "extract.h"? */ +#if 0 /* * Largest packet size. Everything should fit within this space. * For instance, multiline objects are sent piecewise. */ #define MAXFRAMESIZE 1024 +#endif /* * Multiple drawing ops can be sent in one packet. Each one starts on a * an even multiple of DOP_ALIGN bytes, which must be a power of two. */ #define DOP_ALIGN 4 -#define DOP_ROUNDUP(x) ((((int)(x)) + (DOP_ALIGN - 1)) & ~(DOP_ALIGN - 1)) +#define DOP_ROUNDUP(x) roundup2(x, DOP_ALIGN) #define DOP_NEXT(d)\ ((const struct dophdr *)((const u_char *)(d) + \ - DOP_ROUNDUP(EXTRACT_16BITS(&(d)->dh_len) + sizeof(*(d))))) + DOP_ROUNDUP(GET_BE_U_2((d)->dh_len) + sizeof(*(d))))) /* * Format of the whiteboard packet header. * The transport level header. */ struct pkt_hdr { - uint32_t ph_src; /* site id of source */ - uint32_t ph_ts; /* time stamp (for skew computation) */ - uint16_t ph_version; /* version number */ - u_char ph_type; /* message type */ - u_char ph_flags; /* message flags */ + nd_uint32_t ph_src; /* site id of source */ + nd_uint32_t ph_ts; /* time stamp (for skew computation) */ + nd_uint16_t ph_version; /* version number */ + nd_uint8_t ph_type; /* message type */ + nd_uint8_t ph_flags; /* message flags */ }; /* Packet types */ @@ -73,6 +72,7 @@ struct pkt_hdr { #define PT_PREQ 5 /* page vector request */ #define PT_PREP 7 /* page vector reply */ +#if 0 #ifdef PF_USER #undef PF_USER /* {Digital,Tru64} UNIX define this, alas */ #endif @@ -80,17 +80,18 @@ struct pkt_hdr { /* flags */ #define PF_USER 0x01 /* hint that packet has interactive data */ #define PF_VIS 0x02 /* only visible ops wanted */ +#endif struct PageID { - uint32_t p_sid; /* session id of initiator */ - uint32_t p_uid; /* page number */ + nd_uint32_t p_sid; /* session id of initiator */ + nd_uint32_t p_uid; /* page number */ }; struct dophdr { - uint32_t dh_ts; /* sender's timestamp */ - uint16_t dh_len; /* body length */ - u_char dh_flags; - u_char dh_type; /* body type */ + nd_uint32_t dh_ts; /* sender's timestamp */ + nd_uint16_t dh_len; /* body length */ + nd_uint8_t dh_flags; + nd_uint8_t dh_type; /* body type */ /* body follows */ }; /* @@ -110,15 +111,31 @@ struct dophdr { #define DT_REF 13 #define DT_SKIP 14 #define DT_HOLE 15 -#define DT_MAXTYPE 15 +static const struct tok dop_str[] = { + { DT_RECT, "RECT" }, + { DT_LINE, "LINE" }, + { DT_ML, "ML" }, + { DT_DEL, "DEL" }, + { DT_XFORM, "XFORM" }, + { DT_ELL, "ELL" }, + { DT_CHAR, "CHAR" }, + { DT_STR, "STR" }, + { DT_NOP, "NOP" }, + { DT_PSCODE, "PSCODE" }, + { DT_PSCOMP, "PSCOMP" }, + { DT_REF, "REF" }, + { DT_SKIP, "SKIP" }, + { DT_HOLE, "HOLE" }, + { 0, NULL } +}; /* * A drawing operation. */ struct pkt_dop { struct PageID pd_page; /* page that operations apply to */ - uint32_t pd_sseq; /* start sequence number */ - uint32_t pd_eseq; /* end sequence number */ + nd_uint32_t pd_sseq; /* start sequence number */ + nd_uint32_t pd_eseq; /* end sequence number */ /* drawing ops follow */ }; @@ -126,31 +143,31 @@ struct pkt_dop { * A repair request. */ struct pkt_rreq { - uint32_t pr_id; /* source id of drawops to be repaired */ - struct PageID pr_page; /* page of drawops */ - uint32_t pr_sseq; /* start seqno */ - uint32_t pr_eseq; /* end seqno */ + nd_uint32_t pr_id; /* source id of drawops to be repaired */ + struct PageID pr_page; /* page of drawops */ + nd_uint32_t pr_sseq; /* start seqno */ + nd_uint32_t pr_eseq; /* end seqno */ }; /* * A repair reply. */ struct pkt_rrep { - uint32_t pr_id; /* original site id of ops */ + nd_uint32_t pr_id; /* original site id of ops */ struct pkt_dop pr_dop; /* drawing ops follow */ }; struct id_off { - uint32_t id; - uint32_t off; + nd_uint32_t id; + nd_uint32_t off; }; struct pgstate { - uint32_t slot; + nd_uint32_t slot; struct PageID page; - uint16_t nid; - uint16_t rsvd; + nd_uint16_t nid; + nd_uint16_t rsvd; /* seqptr's */ }; @@ -158,7 +175,7 @@ struct pgstate { * An announcement packet. */ struct pkt_id { - uint32_t pi_mslot; + nd_uint32_t pi_mslot; struct PageID pi_mpage; /* current page */ struct pgstate pi_ps; /* seqptr's */ @@ -167,12 +184,12 @@ struct pkt_id { struct pkt_preq { struct PageID pp_page; - uint32_t pp_low; - uint32_t pp_high; + nd_uint32_t pp_low; + nd_uint32_t pp_high; }; struct pkt_prep { - uint32_t pp_n; /* size of pageid array */ + nd_uint32_t pp_n; /* size of pageid array */ /* pgstate's follow */ }; @@ -180,62 +197,60 @@ static int wb_id(netdissect_options *ndo, const struct pkt_id *id, u_int len) { - int i; - const char *cp; + u_int i; + const u_char *sitename; const struct id_off *io; char c; - int nid; + u_int nid; - ND_PRINT((ndo, " wb-id:")); - if (len < sizeof(*id) || !ND_TTEST(*id)) + ND_PRINT(" wb-id:"); + if (len < sizeof(*id)) return (-1); len -= sizeof(*id); - ND_PRINT((ndo, " %u/%s:%u (max %u/%s:%u) ", - EXTRACT_32BITS(&id->pi_ps.slot), - ipaddr_string(ndo, &id->pi_ps.page.p_sid), - EXTRACT_32BITS(&id->pi_ps.page.p_uid), - EXTRACT_32BITS(&id->pi_mslot), - ipaddr_string(ndo, &id->pi_mpage.p_sid), - EXTRACT_32BITS(&id->pi_mpage.p_uid))); - - nid = EXTRACT_16BITS(&id->pi_ps.nid); + ND_PRINT(" %u/%s:%u (max %u/%s:%u) ", + GET_BE_U_4(id->pi_ps.slot), + GET_IPADDR_STRING(id->pi_ps.page.p_sid), + GET_BE_U_4(id->pi_ps.page.p_uid), + GET_BE_U_4(id->pi_mslot), + GET_IPADDR_STRING(id->pi_mpage.p_sid), + GET_BE_U_4(id->pi_mpage.p_uid)); + /* now the rest of the fixed-size part of struct pkt_id */ + ND_TCHECK_SIZE(id); + + nid = GET_BE_U_2(id->pi_ps.nid); + if (len < sizeof(*io) * nid) + return (-1); len -= sizeof(*io) * nid; io = (const struct id_off *)(id + 1); - cp = (const char *)(io + nid); - if (ND_TTEST2(*cp, len)) { - ND_PRINT((ndo, "\"")); - fn_print(ndo, (const u_char *)cp, (const u_char *)cp + len); - ND_PRINT((ndo, "\"")); - } + sitename = (const u_char *)(io + nid); c = '<'; - for (i = 0; i < nid && ND_TTEST(*io); ++io, ++i) { - ND_PRINT((ndo, "%c%s:%u", - c, ipaddr_string(ndo, &io->id), EXTRACT_32BITS(&io->off))); + for (i = 0; i < nid; ++io, ++i) { + ND_PRINT("%c%s:%u", + c, GET_IPADDR_STRING(io->id), GET_BE_U_4(io->off)); c = ','; } - if (i >= nid) { - ND_PRINT((ndo, ">")); - return (0); - } - return (-1); + ND_PRINT("> \""); + nd_printjnp(ndo, sitename, len); + ND_PRINT("\""); + return (0); } static int wb_rreq(netdissect_options *ndo, const struct pkt_rreq *rreq, u_int len) { - ND_PRINT((ndo, " wb-rreq:")); - if (len < sizeof(*rreq) || !ND_TTEST(*rreq)) + ND_PRINT(" wb-rreq:"); + if (len < sizeof(*rreq)) return (-1); - ND_PRINT((ndo, " please repair %s %s:%u<%u:%u>", - ipaddr_string(ndo, &rreq->pr_id), - ipaddr_string(ndo, &rreq->pr_page.p_sid), - EXTRACT_32BITS(&rreq->pr_page.p_uid), - EXTRACT_32BITS(&rreq->pr_sseq), - EXTRACT_32BITS(&rreq->pr_eseq))); + ND_PRINT(" please repair %s %s:%u<%u:%u>", + GET_IPADDR_STRING(rreq->pr_id), + GET_IPADDR_STRING(rreq->pr_page.p_sid), + GET_BE_U_4(rreq->pr_page.p_uid), + GET_BE_U_4(rreq->pr_sseq), + GET_BE_U_4(rreq->pr_eseq)); return (0); } @@ -243,14 +258,16 @@ static int wb_preq(netdissect_options *ndo, const struct pkt_preq *preq, u_int len) { - ND_PRINT((ndo, " wb-preq:")); - if (len < sizeof(*preq) || !ND_TTEST(*preq)) + ND_PRINT(" wb-preq:"); + if (len < sizeof(*preq)) return (-1); - ND_PRINT((ndo, " need %u/%s:%u", - EXTRACT_32BITS(&preq->pp_low), - ipaddr_string(ndo, &preq->pp_page.p_sid), - EXTRACT_32BITS(&preq->pp_page.p_uid))); + ND_PRINT(" need %u/%s:%u", + GET_BE_U_4(preq->pp_low), + GET_IPADDR_STRING(preq->pp_page.p_sid), + GET_BE_U_4(preq->pp_page.p_uid)); + /* now the rest of the fixed-size part of struct pkt_req */ + ND_TCHECK_SIZE(preq); return (0); } @@ -258,90 +275,63 @@ static int wb_prep(netdissect_options *ndo, const struct pkt_prep *prep, u_int len) { - int n; + u_int n; const struct pgstate *ps; - const u_char *ep = ndo->ndo_snapend; - ND_PRINT((ndo, " wb-prep:")); - if (len < sizeof(*prep) || !ND_TTEST(*prep)) + ND_PRINT(" wb-prep:"); + if (len < sizeof(*prep)) return (-1); - n = EXTRACT_32BITS(&prep->pp_n); + n = GET_BE_U_4(prep->pp_n); ps = (const struct pgstate *)(prep + 1); - while (--n >= 0 && ND_TTEST(*ps)) { + while (n != 0) { const struct id_off *io, *ie; char c = '<'; - ND_PRINT((ndo, " %u/%s:%u", - EXTRACT_32BITS(&ps->slot), - ipaddr_string(ndo, &ps->page.p_sid), - EXTRACT_32BITS(&ps->page.p_uid))); + ND_PRINT(" %u/%s:%u", + GET_BE_U_4(ps->slot), + GET_IPADDR_STRING(ps->page.p_sid), + GET_BE_U_4(ps->page.p_uid)); + /* now the rest of the fixed-size part of struct pgstate */ + ND_TCHECK_SIZE(ps); io = (const struct id_off *)(ps + 1); - for (ie = io + ps->nid; io < ie && ND_TTEST(*io); ++io) { - ND_PRINT((ndo, "%c%s:%u", c, ipaddr_string(ndo, &io->id), - EXTRACT_32BITS(&io->off))); + for (ie = io + GET_U_1(ps->nid); io < ie; ++io) { + ND_PRINT("%c%s:%u", c, GET_IPADDR_STRING(io->id), + GET_BE_U_4(io->off)); c = ','; } - ND_PRINT((ndo, ">")); + ND_PRINT(">"); ps = (const struct pgstate *)io; + n--; } - return ((const u_char *)ps <= ep? 0 : -1); + return 0; } - -static const char *dopstr[] = { - "dop-0!", - "dop-1!", - "RECT", - "LINE", - "ML", - "DEL", - "XFORM", - "ELL", - "CHAR", - "STR", - "NOP", - "PSCODE", - "PSCOMP", - "REF", - "SKIP", - "HOLE", -}; - -static int +static void wb_dops(netdissect_options *ndo, const struct pkt_dop *dop, uint32_t ss, uint32_t es) { const struct dophdr *dh = (const struct dophdr *)((const u_char *)dop + sizeof(*dop)); - ND_PRINT((ndo, " <")); + ND_PRINT(" <"); for ( ; ss <= es; ++ss) { - int t; - - if (!ND_TTEST(*dh)) { - ND_PRINT((ndo, "%s", tstr)); - break; - } - t = dh->dh_type; - - if (t > DT_MAXTYPE) - ND_PRINT((ndo, " dop-%d!", t)); - else { - ND_PRINT((ndo, " %s", dopstr[t])); - if (t == DT_SKIP || t == DT_HOLE) { - uint32_t ts = EXTRACT_32BITS(&dh->dh_ts); - ND_PRINT((ndo, "%d", ts - ss + 1)); - if (ss > ts || ts > es) { - ND_PRINT((ndo, "[|]")); - if (ts < ss) - return (0); - } - ss = ts; + u_int t; + + t = GET_U_1(dh->dh_type); + + ND_PRINT(" %s", tok2str(dop_str, "dop-%u!", t)); + if (t == DT_SKIP || t == DT_HOLE) { + uint32_t ts = GET_BE_U_4(dh->dh_ts); + ND_PRINT("%u", ts - ss + 1); + if (ss > ts || ts > es) { + ND_PRINT("[|]"); + if (ts < ss) + return; } + ss = ts; } dh = DOP_NEXT(dh); } - ND_PRINT((ndo, " >")); - return (0); + ND_PRINT(" >"); } static int @@ -350,22 +340,22 @@ wb_rrep(netdissect_options *ndo, { const struct pkt_dop *dop = &rrep->pr_dop; - ND_PRINT((ndo, " wb-rrep:")); - if (len < sizeof(*rrep) || !ND_TTEST(*rrep)) + ND_PRINT(" wb-rrep:"); + if (len < sizeof(*rrep)) return (-1); len -= sizeof(*rrep); - ND_PRINT((ndo, " for %s %s:%u<%u:%u>", - ipaddr_string(ndo, &rrep->pr_id), - ipaddr_string(ndo, &dop->pd_page.p_sid), - EXTRACT_32BITS(&dop->pd_page.p_uid), - EXTRACT_32BITS(&dop->pd_sseq), - EXTRACT_32BITS(&dop->pd_eseq))); + ND_PRINT(" for %s %s:%u<%u:%u>", + GET_IPADDR_STRING(rrep->pr_id), + GET_IPADDR_STRING(dop->pd_page.p_sid), + GET_BE_U_4(dop->pd_page.p_uid), + GET_BE_U_4(dop->pd_sseq), + GET_BE_U_4(dop->pd_eseq)); if (ndo->ndo_vflag) - return (wb_dops(ndo, dop, - EXTRACT_32BITS(&dop->pd_sseq), - EXTRACT_32BITS(&dop->pd_eseq))); + wb_dops(ndo, dop, + GET_BE_U_4(dop->pd_sseq), + GET_BE_U_4(dop->pd_eseq)); return (0); } @@ -373,21 +363,21 @@ static int wb_drawop(netdissect_options *ndo, const struct pkt_dop *dop, u_int len) { - ND_PRINT((ndo, " wb-dop:")); - if (len < sizeof(*dop) || !ND_TTEST(*dop)) + ND_PRINT(" wb-dop:"); + if (len < sizeof(*dop)) return (-1); len -= sizeof(*dop); - ND_PRINT((ndo, " %s:%u<%u:%u>", - ipaddr_string(ndo, &dop->pd_page.p_sid), - EXTRACT_32BITS(&dop->pd_page.p_uid), - EXTRACT_32BITS(&dop->pd_sseq), - EXTRACT_32BITS(&dop->pd_eseq))); + ND_PRINT(" %s:%u<%u:%u>", + GET_IPADDR_STRING(dop->pd_page.p_sid), + GET_BE_U_4(dop->pd_page.p_uid), + GET_BE_U_4(dop->pd_sseq), + GET_BE_U_4(dop->pd_eseq)); if (ndo->ndo_vflag) - return (wb_dops(ndo, dop, - EXTRACT_32BITS(&dop->pd_sseq), - EXTRACT_32BITS(&dop->pd_eseq))); + wb_dops(ndo, dop, + GET_BE_U_4(dop->pd_sseq), + GET_BE_U_4(dop->pd_eseq)); return (0); } @@ -396,63 +386,60 @@ wb_drawop(netdissect_options *ndo, */ void wb_print(netdissect_options *ndo, - register const void *hdr, register u_int len) + const u_char *hdr, u_int len) { - register const struct pkt_hdr *ph; + const struct pkt_hdr *ph; + uint8_t type; + int print_result; + ndo->ndo_protocol = "wb"; ph = (const struct pkt_hdr *)hdr; - if (len < sizeof(*ph) || !ND_TTEST(*ph)) { - ND_PRINT((ndo, "%s", tstr)); - return; - } + if (len < sizeof(*ph)) + goto invalid; + ND_TCHECK_SIZE(ph); len -= sizeof(*ph); - if (ph->ph_flags) - ND_PRINT((ndo, "*")); - switch (ph->ph_type) { + if (GET_U_1(ph->ph_flags)) + ND_PRINT("*"); + type = GET_U_1(ph->ph_type); + switch (type) { case PT_KILL: - ND_PRINT((ndo, " wb-kill")); + ND_PRINT(" wb-kill"); return; case PT_ID: - if (wb_id(ndo, (const struct pkt_id *)(ph + 1), len) >= 0) - return; - ND_PRINT((ndo, "%s", tstr)); + print_result = wb_id(ndo, (const struct pkt_id *)(ph + 1), len); break; case PT_RREQ: - if (wb_rreq(ndo, (const struct pkt_rreq *)(ph + 1), len) >= 0) - return; - ND_PRINT((ndo, "%s", tstr)); + print_result = wb_rreq(ndo, (const struct pkt_rreq *)(ph + 1), len); break; case PT_RREP: - if (wb_rrep(ndo, (const struct pkt_rrep *)(ph + 1), len) >= 0) - return; - ND_PRINT((ndo, "%s", tstr)); + print_result = wb_rrep(ndo, (const struct pkt_rrep *)(ph + 1), len); break; case PT_DRAWOP: - if (wb_drawop(ndo, (const struct pkt_dop *)(ph + 1), len) >= 0) - return; - ND_PRINT((ndo, "%s", tstr)); + print_result = wb_drawop(ndo, (const struct pkt_dop *)(ph + 1), len); break; case PT_PREQ: - if (wb_preq(ndo, (const struct pkt_preq *)(ph + 1), len) >= 0) - return; - ND_PRINT((ndo, "%s", tstr)); + print_result = wb_preq(ndo, (const struct pkt_preq *)(ph + 1), len); break; case PT_PREP: - if (wb_prep(ndo, (const struct pkt_prep *)(ph + 1), len) >= 0) - return; - ND_PRINT((ndo, "%s", tstr)); + print_result = wb_prep(ndo, (const struct pkt_prep *)(ph + 1), len); break; default: - ND_PRINT((ndo, " wb-%d!", ph->ph_type)); - return; + ND_PRINT(" wb-%u!", type); + print_result = -1; } + if (print_result < 0) + goto invalid; + return; + +invalid: + nd_print_invalid(ndo); } diff --git a/contrib/tcpdump/print-zep.c b/contrib/tcpdump/print-zep.c new file mode 100644 index 0000000000..e10ecb3577 --- /dev/null +++ b/contrib/tcpdump/print-zep.c @@ -0,0 +1,178 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 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. + */ + +/* \summary: ZigBee Encapsulation Protocol (ZEP) printer */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "netdissect-stdinc.h" + +#define ND_LONGJMP_FROM_TCHECK +#include "netdissect.h" + +#include "extract.h" + +/* From wireshark packet-zep.c: + * + *********************************************************************** + * + * ZEP Packets must be received in the following format: + * + * |UDP Header| ZEP Header |IEEE 802.15.4 Packet| + * | 8 bytes | 16/32 bytes | <= 127 bytes | + * + *********************************************************************** + * + * ZEP v1 Header will have the following format: + * |Preamble|Version|Channel ID|Device ID|CRC/LQI Mode|LQI Val|Reserved|Length| + * |2 bytes |1 byte | 1 byte | 2 bytes | 1 byte |1 byte |7 bytes |1 byte| + * + * ZEP v2 Header will have the following format (if type=1/Data): + * |Prmbl|Ver |Type |ChnlID|DevID|C/L Mode|LQI|NTP TS|Seq#|Res |Len| + * | 2 | 1 | 1 | 1 | 2 | 1 | 1 | 8 | 4 | 10 | 1 | + * + * ZEP v2 Header will have the following format (if type=2/Ack): + * |Preamble|Version| Type |Sequence#| + * |2 bytes |1 byte |1 byte| 4 bytes | + *------------------------------------------------------------ + */ + +#define JAN_1970 2208988800U + +/* Print timestamp */ +static void zep_print_ts(netdissect_options *ndo, const u_char *p) +{ + int32_t i; + uint32_t uf; + uint32_t f; + float ff; + + i = GET_BE_U_4(p); + uf = GET_BE_U_4(p + 4); + ff = (float) uf; + if (ff < 0.0) /* some compilers are buggy */ + ff += FMAXINT; + ff = (float) (ff / FMAXINT); /* shift radix point by 32 bits */ + f = (uint32_t) (ff * 1000000000.0); /* treat fraction as parts per + billion */ + ND_PRINT("%u.%09d", i, f); + +#ifdef HAVE_STRFTIME + /* + * print the time in human-readable format. + */ + if (i) { + time_t seconds = i - JAN_1970; + struct tm *tm; + char time_buf[128]; + + tm = localtime(&seconds); + strftime(time_buf, sizeof (time_buf), "%Y/%m/%d %H:%M:%S", tm); + ND_PRINT(" (%s)", time_buf); + } +#endif +} + +/* + * Main function to print packets. + */ + +void +zep_print(netdissect_options *ndo, + const u_char *bp, u_int len) +{ + uint8_t version, inner_len; + uint32_t seq_no; + + ndo->ndo_protocol = "zep"; + + nd_print_protocol_caps(ndo); + + /* Preamble Code (must be "EX") */ + if (GET_U_1(bp) != 'E' || GET_U_1(bp + 1) != 'X') { + ND_PRINT(" [Preamble Code: "); + fn_print_char(ndo, GET_U_1(bp)); + fn_print_char(ndo, GET_U_1(bp + 1)); + ND_PRINT("]"); + nd_print_invalid(ndo); + return; + } + + version = GET_U_1(bp + 2); + ND_PRINT("v%u ", version); + + if (version == 1) { + /* ZEP v1 packet. */ + ND_PRINT("Channel ID %u, Device ID 0x%04x, ", + GET_U_1(bp + 3), GET_BE_U_2(bp + 4)); + if (GET_U_1(bp + 6)) + ND_PRINT("CRC, "); + else + ND_PRINT("LQI %u, ", GET_U_1(bp + 7)); + inner_len = GET_U_1(bp + 15); + ND_PRINT("inner len = %u", inner_len); + + bp += 16; + len -= 16; + } else { + /* ZEP v2 packet. */ + if (GET_U_1(bp + 3) == 2) { + /* ZEP v2 ack. */ + seq_no = GET_BE_U_4(bp + 4); + ND_PRINT("ACK, seq# = %u", seq_no); + inner_len = 0; + bp += 8; + len -= 8; + } else { + /* ZEP v2 data, or some other. */ + ND_PRINT("Type %u, Channel ID %u, Device ID 0x%04x, ", + GET_U_1(bp + 3), GET_U_1(bp + 4), + GET_BE_U_2(bp + 5)); + if (GET_U_1(bp + 7)) + ND_PRINT("CRC, "); + else + ND_PRINT("LQI %u, ", GET_U_1(bp + 8)); + + zep_print_ts(ndo, bp + 9); + seq_no = GET_BE_U_4(bp + 17); + inner_len = GET_U_1(bp + 31); + ND_PRINT(", seq# = %u, inner len = %u", + seq_no, inner_len); + bp += 32; + len -= 32; + } + } + + if (inner_len != 0) { + /* Call 802.15.4 dissector. */ + ND_PRINT("\n\t"); + if (ieee802_15_4_print(ndo, bp, inner_len)) { + ND_TCHECK_LEN(bp, len); + bp += len; + len = 0; + } + } + + if (!ndo->ndo_suppress_default_print) + ND_DEFAULTPRINT(bp, len); +} diff --git a/contrib/tcpdump/print-zephyr.c b/contrib/tcpdump/print-zephyr.c index 735e273f07..aa552aaa65 100644 --- a/contrib/tcpdump/print-zephyr.c +++ b/contrib/tcpdump/print-zephyr.c @@ -1,7 +1,7 @@ /* * Decode and print Zephyr packets. * - * http://web.mit.edu/zephyr/doc/protocol + * https://web.mit.edu/zephyr/doc/protocol * * Copyright (c) 2001 Nickolai Zeldovich * All rights reserved. @@ -23,16 +23,19 @@ /* \summary: Zephyr printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include #include #include +#include "netdissect-ctype.h" + #include "netdissect.h" +#include "extract.h" struct z_packet { const char *version; @@ -83,7 +86,7 @@ static const struct tok z_types[] = { static char z_buf[256]; static const char * -parse_field(netdissect_options *ndo, const char **pptr, int *len, int *truncated) +parse_field(netdissect_options *ndo, const char **pptr, int *len) { const char *s; @@ -95,12 +98,7 @@ parse_field(netdissect_options *ndo, const char **pptr, int *len, int *truncated /* Ran out of packet data without finding it */ return NULL; } - if (!ND_TTEST(**pptr)) { - /* Ran out of captured data without finding it */ - *truncated = 1; - return NULL; - } - if (**pptr == '\0') { + if (GET_U_1(*pptr) == '\0') { /* Found it */ break; } @@ -134,7 +132,7 @@ str_to_lower(const char *string) zb_string = z_buf; while (*zb_string) { - *zb_string = tolower((unsigned char)(*zb_string)); + *zb_string = ND_ASCII_TOLOWER(*zb_string); zb_string++; } @@ -142,27 +140,37 @@ str_to_lower(const char *string) } void -zephyr_print(netdissect_options *ndo, const u_char *cp, int length) +zephyr_print(netdissect_options *ndo, const u_char *cp, u_int length) { - struct z_packet z; + struct z_packet z = { + NULL, /* version */ + 0, /* numfields */ + 0, /* kind */ + NULL, /* uid */ + 0, /* port */ + 0, /* auth */ + 0, /* authlen */ + NULL, /* authdata */ + NULL, /* class */ + NULL, /* inst */ + NULL, /* opcode */ + NULL, /* sender */ + NULL, /* recipient */ + NULL, /* format */ + 0, /* cksum */ + 0, /* multi */ + NULL /* multi_uid */ + }; const char *parse = (const char *) cp; int parselen = length; const char *s; int lose = 0; - int truncated = 0; + ndo->ndo_protocol = "zephyr"; /* squelch compiler warnings */ - z.kind = 0; - z.class = 0; - z.inst = 0; - z.opcode = 0; - z.sender = 0; - z.recipient = 0; - #define PARSE_STRING \ - s = parse_field(ndo, &parse, &parselen, &truncated); \ - if (truncated) goto trunc; \ + s = parse_field(ndo, &parse, &parselen); \ if (!s) lose = 1; #define PARSE_FIELD_INT(field) \ @@ -174,7 +182,9 @@ zephyr_print(netdissect_options *ndo, const u_char *cp, int length) if (!lose) field = s; PARSE_FIELD_STR(z.version); - if (lose) return; + if (lose) + goto invalid; + if (strncmp(z.version, "ZEPH", 4)) return; @@ -196,36 +206,36 @@ zephyr_print(netdissect_options *ndo, const u_char *cp, int length) PARSE_FIELD_STR(z.multi_uid); if (lose) - goto trunc; + goto invalid; - ND_PRINT((ndo, " zephyr")); + ND_PRINT(" zephyr"); if (strncmp(z.version+4, "0.2", 3)) { - ND_PRINT((ndo, " v%s", z.version+4)); + ND_PRINT(" v%s", z.version+4); return; } - ND_PRINT((ndo, " %s", tok2str(z_types, "type %d", z.kind))); + ND_PRINT(" %s", tok2str(z_types, "type %d", z.kind)); if (z.kind == Z_PACKET_SERVACK) { /* Initialization to silence warnings */ const char *ackdata = NULL; PARSE_FIELD_STR(ackdata); if (!lose && strcmp(ackdata, "SENT")) - ND_PRINT((ndo, "/%s", str_to_lower(ackdata))); + ND_PRINT("/%s", str_to_lower(ackdata)); } - if (*z.sender) ND_PRINT((ndo, " %s", z.sender)); + if (*z.sender) ND_PRINT(" %s", z.sender); if (!strcmp(z.class, "USER_LOCATE")) { if (!strcmp(z.opcode, "USER_HIDE")) - ND_PRINT((ndo, " hide")); + ND_PRINT(" hide"); else if (!strcmp(z.opcode, "USER_UNHIDE")) - ND_PRINT((ndo, " unhide")); + ND_PRINT(" unhide"); else - ND_PRINT((ndo, " locate %s", z.inst)); + ND_PRINT(" locate %s", z.inst); return; } if (!strcmp(z.class, "ZEPHYR_ADMIN")) { - ND_PRINT((ndo, " zephyr-admin %s", str_to_lower(z.opcode))); + ND_PRINT(" zephyr-admin %s", str_to_lower(z.opcode)); return; } @@ -235,79 +245,79 @@ zephyr_print(netdissect_options *ndo, const u_char *cp, int length) !strcmp(z.opcode, "SUBSCRIBE_NODEFS") || !strcmp(z.opcode, "UNSUBSCRIBE")) { - ND_PRINT((ndo, " %ssub%s", strcmp(z.opcode, "SUBSCRIBE") ? "un" : "", + ND_PRINT(" %ssub%s", strcmp(z.opcode, "SUBSCRIBE") ? "un" : "", strcmp(z.opcode, "SUBSCRIBE_NODEFS") ? "" : - "-nodefs")); + "-nodefs"); if (z.kind != Z_PACKET_SERVACK) { /* Initialization to silence warnings */ const char *c = NULL, *i = NULL, *r = NULL; PARSE_FIELD_STR(c); PARSE_FIELD_STR(i); PARSE_FIELD_STR(r); - if (!lose) ND_PRINT((ndo, " %s", z_triple(c, i, r))); + if (!lose) ND_PRINT(" %s", z_triple(c, i, r)); } return; } if (!strcmp(z.opcode, "GIMME")) { - ND_PRINT((ndo, " ret")); + ND_PRINT(" ret"); return; } if (!strcmp(z.opcode, "GIMMEDEFS")) { - ND_PRINT((ndo, " gimme-defs")); + ND_PRINT(" gimme-defs"); return; } if (!strcmp(z.opcode, "CLEARSUB")) { - ND_PRINT((ndo, " clear-subs")); + ND_PRINT(" clear-subs"); return; } - ND_PRINT((ndo, " %s", str_to_lower(z.opcode))); + ND_PRINT(" %s", str_to_lower(z.opcode)); return; } if (!strcmp(z.inst, "HM")) { - ND_PRINT((ndo, " %s", str_to_lower(z.opcode))); + ND_PRINT(" %s", str_to_lower(z.opcode)); return; } if (!strcmp(z.inst, "REALM")) { if (!strcmp(z.opcode, "ADD_SUBSCRIBE")) - ND_PRINT((ndo, " realm add-subs")); + ND_PRINT(" realm add-subs"); if (!strcmp(z.opcode, "REQ_SUBSCRIBE")) - ND_PRINT((ndo, " realm req-subs")); + ND_PRINT(" realm req-subs"); if (!strcmp(z.opcode, "RLM_SUBSCRIBE")) - ND_PRINT((ndo, " realm rlm-sub")); + ND_PRINT(" realm rlm-sub"); if (!strcmp(z.opcode, "RLM_UNSUBSCRIBE")) - ND_PRINT((ndo, " realm rlm-unsub")); + ND_PRINT(" realm rlm-unsub"); return; } } if (!strcmp(z.class, "HM_CTL")) { - ND_PRINT((ndo, " hm_ctl %s", str_to_lower(z.inst))); - ND_PRINT((ndo, " %s", str_to_lower(z.opcode))); + ND_PRINT(" hm_ctl %s", str_to_lower(z.inst)); + ND_PRINT(" %s", str_to_lower(z.opcode)); return; } if (!strcmp(z.class, "HM_STAT")) { if (!strcmp(z.inst, "HMST_CLIENT") && !strcmp(z.opcode, "GIMMESTATS")) { - ND_PRINT((ndo, " get-client-stats")); + ND_PRINT(" get-client-stats"); return; } } if (!strcmp(z.class, "WG_CTL")) { - ND_PRINT((ndo, " wg_ctl %s", str_to_lower(z.inst))); - ND_PRINT((ndo, " %s", str_to_lower(z.opcode))); + ND_PRINT(" wg_ctl %s", str_to_lower(z.inst)); + ND_PRINT(" %s", str_to_lower(z.opcode)); return; } if (!strcmp(z.class, "LOGIN")) { if (!strcmp(z.opcode, "USER_FLUSH")) { - ND_PRINT((ndo, " flush_locs")); + ND_PRINT(" flush_locs"); return; } @@ -317,7 +327,7 @@ zephyr_print(netdissect_options *ndo, const u_char *cp, int length) !strcmp(z.opcode, "REALM-ANNOUNCED") || !strcmp(z.opcode, "NET-VISIBLE") || !strcmp(z.opcode, "NET-ANNOUNCED")) { - ND_PRINT((ndo, " set-exposure %s", str_to_lower(z.opcode))); + ND_PRINT(" set-exposure %s", str_to_lower(z.opcode)); return; } } @@ -325,12 +335,11 @@ zephyr_print(netdissect_options *ndo, const u_char *cp, int length) if (!*z.recipient) z.recipient = "*"; - ND_PRINT((ndo, " to %s", z_triple(z.class, z.inst, z.recipient))); + ND_PRINT(" to %s", z_triple(z.class, z.inst, z.recipient)); if (*z.opcode) - ND_PRINT((ndo, " op %s", z.opcode)); + ND_PRINT(" op %s", z.opcode); return; -trunc: - ND_PRINT((ndo, " [|zephyr] (%d)", length)); - return; +invalid: + nd_print_invalid(ndo); } diff --git a/contrib/tcpdump/print-zeromq.c b/contrib/tcpdump/print-zeromq.c index a23d98a191..c702046822 100644 --- a/contrib/tcpdump/print-zeromq.c +++ b/contrib/tcpdump/print-zeromq.c @@ -28,15 +28,14 @@ /* \summary: ZeroMQ Message Transport Protocol (ZMTP) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "extract.h" -static const char tstr[] = " [|zmtp1]"; /* Maximum number of ZMTP/1.0 frame body bytes (without the flags) to dump in * hex and ASCII under a single "-v" flag. @@ -79,34 +78,33 @@ zmtp1_print_frame(netdissect_options *ndo, const u_char *cp, const u_char *ep) uint64_t body_len_declared, body_len_captured, header_len; uint8_t flags; - ND_PRINT((ndo, "\n\t")); - ND_TCHECK2(*cp, 1); /* length/0xFF */ + ND_PRINT("\n\t"); - if (cp[0] != 0xFF) { + if (GET_U_1(cp) != 0xFF) { /* length/0xFF */ header_len = 1; /* length */ - body_len_declared = cp[0]; - ND_PRINT((ndo, " frame flags+body (8-bit) length %" PRIu64, body_len_declared)); + body_len_declared = GET_U_1(cp); + ND_PRINT(" frame flags+body (8-bit) length %" PRIu64, body_len_declared); } else { header_len = 1 + 8; /* 0xFF, length */ - ND_PRINT((ndo, " frame flags+body (64-bit) length")); - ND_TCHECK2(*cp, header_len); /* 0xFF, length */ - body_len_declared = EXTRACT_64BITS(cp + 1); - ND_PRINT((ndo, " %" PRIu64, body_len_declared)); + ND_PRINT(" frame flags+body (64-bit) length"); + ND_TCHECK_LEN(cp, header_len); /* 0xFF, length */ + body_len_declared = GET_BE_U_8(cp + 1); + ND_PRINT(" %" PRIu64, body_len_declared); } if (body_len_declared == 0) return cp + header_len; /* skip to the next frame */ - ND_TCHECK2(*cp, header_len + 1); /* ..., flags */ - flags = cp[header_len]; + ND_TCHECK_LEN(cp, header_len + 1); /* ..., flags */ + flags = GET_U_1(cp + header_len); body_len_captured = ep - cp - header_len; if (body_len_declared > body_len_captured) - ND_PRINT((ndo, " (%" PRIu64 " captured)", body_len_captured)); - ND_PRINT((ndo, ", flags 0x%02x", flags)); + ND_PRINT(" (%" PRIu64 " captured)", body_len_captured); + ND_PRINT(", flags 0x%02x", flags); if (ndo->ndo_vflag) { - uint64_t body_len_printed = min(body_len_captured, body_len_declared); + uint64_t body_len_printed = ND_MIN(body_len_captured, body_len_declared); - ND_PRINT((ndo, " (%s|%s|%s|%s|%s|%s|%s|%s)", + ND_PRINT(" (%s|%s|%s|%s|%s|%s|%s|%s)", flags & 0x80 ? "MBZ" : "-", flags & 0x40 ? "MBZ" : "-", flags & 0x20 ? "MBZ" : "-", @@ -114,38 +112,37 @@ zmtp1_print_frame(netdissect_options *ndo, const u_char *cp, const u_char *ep) flags & 0x08 ? "MBZ" : "-", flags & 0x04 ? "MBZ" : "-", flags & 0x02 ? "MBZ" : "-", - flags & 0x01 ? "MORE" : "-")); + flags & 0x01 ? "MORE" : "-"); if (ndo->ndo_vflag == 1) - body_len_printed = min(VBYTES + 1, body_len_printed); + body_len_printed = ND_MIN(VBYTES + 1, body_len_printed); if (body_len_printed > 1) { - ND_PRINT((ndo, ", first %" PRIu64 " byte(s) of body:", body_len_printed - 1)); + ND_PRINT(", first %" PRIu64 " byte(s) of body:", body_len_printed - 1); hex_and_ascii_print(ndo, "\n\t ", cp + header_len + 1, body_len_printed - 1); - ND_PRINT((ndo, "\n")); } } /* * Do not advance cp by the sum of header_len and body_len_declared - * before each offset has successfully passed ND_TCHECK2() as the + * before each offset has successfully passed ND_TCHECK_LEN() as the * sum can roll over (9 + 0xfffffffffffffff7 = 0) and cause an * infinite loop. */ cp += header_len; - ND_TCHECK2(*cp, body_len_declared); /* Next frame within the buffer ? */ + ND_TCHECK_LEN(cp, body_len_declared); /* Next frame within the buffer ? */ return cp + body_len_declared; trunc: - ND_PRINT((ndo, "%s", tstr)); - return ep; + nd_trunc_longjmp(ndo); } void zmtp1_print(netdissect_options *ndo, const u_char *cp, u_int len) { - const u_char *ep = min(ndo->ndo_snapend, cp + len); + const u_char *ep = ND_MIN(ndo->ndo_snapend, cp + len); - ND_PRINT((ndo, ": ZMTP/1.0")); + ndo->ndo_protocol = "zmtp1"; + ND_PRINT(": ZMTP/1.0"); while (cp < ep) cp = zmtp1_print_frame(ndo, cp, ep); } @@ -170,50 +167,48 @@ static const u_char * zmtp1_print_intermediate_part(netdissect_options *ndo, const u_char *cp, const u_int len) { u_int frame_offset; - uint64_t remaining_len; + u_int remaining_len; - ND_TCHECK2(*cp, 2); - frame_offset = EXTRACT_16BITS(cp); - ND_PRINT((ndo, "\n\t frame offset 0x%04x", frame_offset)); + frame_offset = GET_BE_U_2(cp); + ND_PRINT("\n\t frame offset 0x%04x", frame_offset); cp += 2; - remaining_len = ndo->ndo_snapend - cp; /* without the frame length */ + remaining_len = ND_BYTES_AVAILABLE_AFTER(cp); /* without the frame length */ if (frame_offset == 0xFFFF) frame_offset = len - 2; /* always within the declared length */ else if (2 + frame_offset > len) { - ND_PRINT((ndo, " (exceeds datagram declared length)")); + ND_PRINT(" (exceeds datagram declared length)"); goto trunc; } /* offset within declared length of the datagram */ if (frame_offset) { - ND_PRINT((ndo, "\n\t frame intermediate part, %u bytes", frame_offset)); + ND_PRINT("\n\t frame intermediate part, %u bytes", frame_offset); if (frame_offset > remaining_len) - ND_PRINT((ndo, " (%"PRIu64" captured)", remaining_len)); + ND_PRINT(" (%u captured)", remaining_len); if (ndo->ndo_vflag) { - uint64_t len_printed = min(frame_offset, remaining_len); + u_int len_printed = ND_MIN(frame_offset, remaining_len); if (ndo->ndo_vflag == 1) - len_printed = min(VBYTES, len_printed); + len_printed = ND_MIN(VBYTES, len_printed); if (len_printed > 1) { - ND_PRINT((ndo, ", first %"PRIu64" byte(s):", len_printed)); + ND_PRINT(", first %u byte(s):", len_printed); hex_and_ascii_print(ndo, "\n\t ", cp, len_printed); - ND_PRINT((ndo, "\n")); } } } return cp + frame_offset; trunc: - ND_PRINT((ndo, "%s", tstr)); - return cp + len; + nd_trunc_longjmp(ndo); } void -zmtp1_print_datagram(netdissect_options *ndo, const u_char *cp, const u_int len) +zmtp1_datagram_print(netdissect_options *ndo, const u_char *cp, const u_int len) { - const u_char *ep = min(ndo->ndo_snapend, cp + len); + const u_char *ep = ND_MIN(ndo->ndo_snapend, cp + len); + ndo->ndo_protocol = "zmtp1"; cp = zmtp1_print_intermediate_part(ndo, cp, len); while (cp < ep) cp = zmtp1_print_frame(ndo, cp, ep); diff --git a/contrib/tcpdump/print.c b/contrib/tcpdump/print.c index c76f344117..bfc35d9c93 100644 --- a/contrib/tcpdump/print.c +++ b/contrib/tcpdump/print.c @@ -26,17 +26,21 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif #include #include +#include -#include +#include "netdissect-stdinc.h" #include "netdissect.h" #include "addrtoname.h" #include "print.h" +#include "netdissect-alloc.h" + +#include "pcap-missing.h" struct printer { if_printer f; @@ -44,71 +48,22 @@ struct printer { }; static const struct printer 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 -#if defined(DLT_NFLOG) && defined(HAVE_PCAP_NFLOG_H) - { nflog_if_print, DLT_NFLOG}, -#endif -#ifdef DLT_CIP - { cip_if_print, DLT_CIP }, -#endif -#ifdef DLT_ATM_CLIP - { cip_if_print, DLT_ATM_CLIP }, -#endif -#ifdef DLT_IP_OVER_FC - { ipfc_if_print, DLT_IP_OVER_FC }, -#endif - { null_if_print, DLT_NULL }, -#ifdef DLT_LOOP - { null_if_print, DLT_LOOP }, -#endif #ifdef DLT_APPLE_IP_OVER_IEEE1394 { ap1394_if_print, DLT_APPLE_IP_OVER_IEEE1394 }, -#endif -#if defined(DLT_BLUETOOTH_HCI_H4_WITH_PHDR) && defined(HAVE_PCAP_BLUETOOTH_H) - { bt_if_print, DLT_BLUETOOTH_HCI_H4_WITH_PHDR}, -#endif -#ifdef DLT_LANE8023 - { lane_if_print, DLT_LANE8023 }, #endif { arcnet_if_print, DLT_ARCNET }, #ifdef DLT_ARCNET_LINUX { arcnet_linux_if_print, DLT_ARCNET_LINUX }, #endif - { raw_if_print, DLT_RAW }, -#ifdef DLT_IPV4 - { raw_if_print, DLT_IPV4 }, + { atm_if_print, DLT_ATM_RFC1483 }, +#ifdef DLT_DSA_TAG_BRCM + { brcm_tag_if_print, DLT_DSA_TAG_BRCM }, #endif -#ifdef DLT_IPV6 - { raw_if_print, DLT_IPV6 }, +#ifdef DLT_DSA_TAG_BRCM_PREPEND + { brcm_tag_prepend_if_print, DLT_DSA_TAG_BRCM_PREPEND }, #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_SYMANTEC_FIREWALL - { symantec_if_print, DLT_SYMANTEC_FIREWALL }, +#ifdef DLT_BLUETOOTH_HCI_H4_WITH_PHDR + { bt_if_print, DLT_BLUETOOTH_HCI_H4_WITH_PHDR}, #endif #ifdef DLT_C_HDLC { chdlc_if_print, DLT_C_HDLC }, @@ -116,119 +71,188 @@ static const struct printer printers[] = { #ifdef DLT_HDLC { chdlc_if_print, DLT_HDLC }, #endif -#ifdef DLT_PPP_ETHER - { pppoe_if_print, DLT_PPP_ETHER }, +#ifdef DLT_ATM_CLIP + { cip_if_print, DLT_ATM_CLIP }, #endif -#if defined(DLT_PFLOG) && defined(HAVE_NET_IF_PFLOG_H) - { pflog_if_print, DLT_PFLOG }, +#ifdef DLT_CIP + { cip_if_print, DLT_CIP }, #endif - { token_if_print, DLT_IEEE802 }, - { fddi_if_print, DLT_FDDI }, -#ifdef DLT_LINUX_SLL - { sll_if_print, DLT_LINUX_SLL }, +#ifdef DLT_DSA_TAG_DSA + { dsa_if_print, DLT_DSA_TAG_DSA }, #endif +#ifdef DLT_DSA_TAG_EDSA + { edsa_if_print, DLT_DSA_TAG_EDSA }, +#endif +#ifdef DLT_ENC + { enc_if_print, DLT_ENC }, +#endif + { ether_if_print, DLT_EN10MB }, + { fddi_if_print, DLT_FDDI }, #ifdef DLT_FR { fr_if_print, DLT_FR }, #endif #ifdef DLT_FRELAY { fr_if_print, DLT_FRELAY }, #endif -#ifdef DLT_MFR - { mfr_if_print, DLT_MFR }, +#ifdef DLT_IEEE802_11 + { ieee802_11_if_print, DLT_IEEE802_11}, #endif - { atm_if_print, DLT_ATM_RFC1483 }, -#ifdef DLT_SUNATM - { sunatm_if_print, DLT_SUNATM }, +#ifdef DLT_IEEE802_11_RADIO_AVS + { ieee802_11_radio_avs_if_print, DLT_IEEE802_11_RADIO_AVS }, #endif -#ifdef DLT_ENC - { enc_if_print, DLT_ENC }, +#ifdef DLT_IEEE802_11_RADIO + { ieee802_11_radio_if_print, DLT_IEEE802_11_RADIO }, #endif - { sl_if_print, DLT_SLIP }, -#ifdef DLT_SLIP_BSDOS - { sl_bsdos_if_print, DLT_SLIP_BSDOS }, +#ifdef DLT_IEEE802_15_4 + { ieee802_15_4_if_print, DLT_IEEE802_15_4 }, #endif -#ifdef DLT_LTALK - { ltalk_if_print, DLT_LTALK }, +#ifdef DLT_IEEE802_15_4_NOFCS + { ieee802_15_4_if_print, DLT_IEEE802_15_4_NOFCS }, +#endif +#ifdef DLT_IEEE802_15_4_TAP + { ieee802_15_4_tap_if_print, DLT_IEEE802_15_4_TAP }, +#endif +#ifdef DLT_IP_OVER_FC + { ipfc_if_print, DLT_IP_OVER_FC }, +#endif +#ifdef DLT_IPNET + { ipnet_if_print, DLT_IPNET }, +#endif +#ifdef DLT_IPOIB + { ipoib_if_print, DLT_IPOIB }, #endif #ifdef DLT_JUNIPER_ATM1 - { juniper_atm1_print, DLT_JUNIPER_ATM1 }, + { juniper_atm1_if_print, DLT_JUNIPER_ATM1 }, #endif #ifdef DLT_JUNIPER_ATM2 - { juniper_atm2_print, DLT_JUNIPER_ATM2 }, + { juniper_atm2_if_print, DLT_JUNIPER_ATM2 }, +#endif +#ifdef DLT_JUNIPER_CHDLC + { juniper_chdlc_if_print, DLT_JUNIPER_CHDLC }, +#endif +#ifdef DLT_JUNIPER_ES + { juniper_es_if_print, DLT_JUNIPER_ES }, +#endif +#ifdef DLT_JUNIPER_ETHER + { juniper_ether_if_print, DLT_JUNIPER_ETHER }, +#endif +#ifdef DLT_JUNIPER_FRELAY + { juniper_frelay_if_print, DLT_JUNIPER_FRELAY }, +#endif +#ifdef DLT_JUNIPER_GGSN + { juniper_ggsn_if_print, DLT_JUNIPER_GGSN }, #endif #ifdef DLT_JUNIPER_MFR - { juniper_mfr_print, DLT_JUNIPER_MFR }, + { juniper_mfr_if_print, DLT_JUNIPER_MFR }, #endif #ifdef DLT_JUNIPER_MLFR - { juniper_mlfr_print, DLT_JUNIPER_MLFR }, + { juniper_mlfr_if_print, DLT_JUNIPER_MLFR }, #endif #ifdef DLT_JUNIPER_MLPPP - { juniper_mlppp_print, DLT_JUNIPER_MLPPP }, + { juniper_mlppp_if_print, DLT_JUNIPER_MLPPP }, #endif -#ifdef DLT_JUNIPER_PPPOE - { juniper_pppoe_print, DLT_JUNIPER_PPPOE }, +#ifdef DLT_JUNIPER_MONITOR + { juniper_monitor_if_print, DLT_JUNIPER_MONITOR }, +#endif +#ifdef DLT_JUNIPER_PPP + { juniper_ppp_if_print, DLT_JUNIPER_PPP }, #endif #ifdef DLT_JUNIPER_PPPOE_ATM - { juniper_pppoe_atm_print, DLT_JUNIPER_PPPOE_ATM }, + { juniper_pppoe_atm_if_print, DLT_JUNIPER_PPPOE_ATM }, #endif -#ifdef DLT_JUNIPER_GGSN - { juniper_ggsn_print, DLT_JUNIPER_GGSN }, +#ifdef DLT_JUNIPER_PPPOE + { juniper_pppoe_if_print, DLT_JUNIPER_PPPOE }, #endif -#ifdef DLT_JUNIPER_ES - { juniper_es_print, DLT_JUNIPER_ES }, +#ifdef DLT_JUNIPER_SERVICES + { juniper_services_if_print, DLT_JUNIPER_SERVICES }, #endif -#ifdef DLT_JUNIPER_MONITOR - { juniper_monitor_print, DLT_JUNIPER_MONITOR }, +#ifdef DLT_LTALK + { ltalk_if_print, DLT_LTALK }, #endif -#ifdef DLT_JUNIPER_SERVICES - { juniper_services_print, DLT_JUNIPER_SERVICES }, +#ifdef DLT_MFR + { mfr_if_print, DLT_MFR }, #endif -#ifdef DLT_JUNIPER_ETHER - { juniper_ether_print, DLT_JUNIPER_ETHER }, +#ifdef DLT_NETANALYZER + { netanalyzer_if_print, DLT_NETANALYZER }, #endif -#ifdef DLT_JUNIPER_PPP - { juniper_ppp_print, DLT_JUNIPER_PPP }, +#ifdef DLT_NETANALYZER_TRANSPARENT + { netanalyzer_transparent_if_print, DLT_NETANALYZER_TRANSPARENT }, #endif -#ifdef DLT_JUNIPER_FRELAY - { juniper_frelay_print, DLT_JUNIPER_FRELAY }, +#ifdef DLT_NFLOG + { nflog_if_print, DLT_NFLOG}, #endif -#ifdef DLT_JUNIPER_CHDLC - { juniper_chdlc_print, DLT_JUNIPER_CHDLC }, + { null_if_print, DLT_NULL }, +#ifdef DLT_LOOP + { null_if_print, DLT_LOOP }, +#endif +#if defined(DLT_PFLOG) && defined(HAVE_NET_IF_PFLOG_H) + { pflog_if_print, DLT_PFLOG }, #endif #ifdef DLT_PKTAP { pktap_if_print, DLT_PKTAP }, #endif -#ifdef DLT_IEEE802_11_RADIO - { ieee802_11_radio_if_print, DLT_IEEE802_11_RADIO }, +#ifdef DLT_PPI + { ppi_if_print, DLT_PPI }, #endif -#ifdef DLT_IEEE802_11 - { ieee802_11_if_print, DLT_IEEE802_11}, +#ifdef DLT_PPP_BSDOS + { ppp_bsdos_if_print, DLT_PPP_BSDOS }, #endif -#ifdef DLT_IEEE802_11_RADIO_AVS - { ieee802_11_radio_avs_if_print, DLT_IEEE802_11_RADIO_AVS }, +#ifdef DLT_PPP_SERIAL + { ppp_hdlc_if_print, DLT_PPP_SERIAL }, +#endif + { ppp_if_print, DLT_PPP }, +#ifdef DLT_PPP_PPPD + { ppp_if_print, DLT_PPP_PPPD }, +#endif +#ifdef DLT_PPP_ETHER + { pppoe_if_print, DLT_PPP_ETHER }, #endif #ifdef DLT_PRISM_HEADER { prism_if_print, DLT_PRISM_HEADER }, #endif - { ppp_if_print, DLT_PPP }, -#ifdef DLT_PPP_WITHDIRECTION - { ppp_if_print, DLT_PPP_WITHDIRECTION }, + { raw_if_print, DLT_RAW }, +#ifdef DLT_IPV4 + { raw_if_print, DLT_IPV4 }, #endif -#ifdef DLT_PPP_BSDOS - { ppp_bsdos_if_print, DLT_PPP_BSDOS }, +#ifdef DLT_IPV6 + { raw_if_print, DLT_IPV6 }, #endif -#ifdef DLT_PPP_SERIAL - { ppp_hdlc_if_print, DLT_PPP_SERIAL }, +#ifdef DLT_SLIP_BSDOS + { sl_bsdos_if_print, DLT_SLIP_BSDOS }, +#endif + { sl_if_print, DLT_SLIP }, +#ifdef DLT_LINUX_SLL + { sll_if_print, DLT_LINUX_SLL }, +#endif +#ifdef DLT_LINUX_SLL2 + { sll2_if_print, DLT_LINUX_SLL2 }, +#endif +#ifdef DLT_SUNATM + { sunatm_if_print, DLT_SUNATM }, +#endif +#ifdef DLT_SYMANTEC_FIREWALL + { symantec_if_print, DLT_SYMANTEC_FIREWALL }, +#endif + { token_if_print, DLT_IEEE802 }, +#ifdef DLT_USB_LINUX + { usb_linux_48_byte_if_print, DLT_USB_LINUX}, +#endif /* DLT_USB_LINUX */ +#ifdef DLT_USB_LINUX_MMAPPED + { usb_linux_64_byte_if_print, DLT_USB_LINUX_MMAPPED}, +#endif /* DLT_USB_LINUX_MMAPPED */ +#ifdef DLT_VSOCK + { vsock_if_print, DLT_VSOCK }, #endif - { NULL, 0 }, + { NULL, 0 }, }; static void ndo_default_print(netdissect_options *ndo, const u_char *bp, u_int length); -static void ndo_error(netdissect_options *ndo, - FORMAT_STRING(const char *fmt), ...) - NORETURN PRINTFLIKE(2, 3); +static void NORETURN ndo_error(netdissect_options *ndo, + status_exit_codes_t status, + FORMAT_STRING(const char *fmt), ...) + PRINTFLIKE(3, 4); static void ndo_warning(netdissect_options *ndo, FORMAT_STRING(const char *fmt), ...) PRINTFLIKE(2, 3); @@ -238,11 +262,9 @@ static int ndo_printf(netdissect_options *ndo, PRINTFLIKE(2, 3); void -init_print(netdissect_options *ndo, uint32_t localnet, uint32_t mask, - uint32_t timezone_offset) +init_print(netdissect_options *ndo, uint32_t localnet, uint32_t mask) { - thiszone = timezone_offset; init_addrtoname(ndo, localnet, mask); init_checksum(); } @@ -291,45 +313,121 @@ has_printer(int type) } if_printer -get_if_printer(netdissect_options *ndo, int type) +get_if_printer(int type) { - const char *dltname; if_printer printer; printer = lookup_printer(type); - if (printer == NULL) { - dltname = pcap_datalink_val_to_name(type); - if (dltname != NULL) - (*ndo->ndo_error)(ndo, - "packet printing is not supported for link type %s: use -w", - dltname); - else - (*ndo->ndo_error)(ndo, - "packet printing is not supported for link type %d: use -w", type); - } + if (printer == NULL) + printer = unsupported_if_print; return printer; } void pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h, - const u_char *sp, u_int packets_captured) + const u_char *sp, u_int packets_captured) { - u_int hdrlen; + u_int hdrlen = 0; + int invalid_header = 0; - if(ndo->ndo_packet_number) - ND_PRINT((ndo, "%5u ", packets_captured)); + if (ndo->ndo_packet_number) + ND_PRINT("%5u ", packets_captured); - ts_print(ndo, &h->ts); + /* Sanity checks on packet length / capture length */ + if (h->caplen == 0) { + invalid_header = 1; + ND_PRINT("[Invalid header: caplen==0"); + } + if (h->len == 0) { + if (!invalid_header) { + invalid_header = 1; + ND_PRINT("[Invalid header:"); + } else + ND_PRINT(","); + ND_PRINT(" len==0"); + } else if (h->len < h->caplen) { + if (!invalid_header) { + invalid_header = 1; + ND_PRINT("[Invalid header:"); + } else + ND_PRINT(","); + ND_PRINT(" len(%u) < caplen(%u)", h->len, h->caplen); + } + if (h->caplen > MAXIMUM_SNAPLEN) { + if (!invalid_header) { + invalid_header = 1; + ND_PRINT("[Invalid header:"); + } else + ND_PRINT(","); + ND_PRINT(" caplen(%u) > %u", h->caplen, MAXIMUM_SNAPLEN); + } + if (h->len > MAXIMUM_SNAPLEN) { + if (!invalid_header) { + invalid_header = 1; + ND_PRINT("[Invalid header:"); + } else + ND_PRINT(","); + ND_PRINT(" len(%u) > %u", h->len, MAXIMUM_SNAPLEN); + } + if (invalid_header) { + ND_PRINT("]\n"); + return; + } /* - * Some printers want to check that they're not walking off the - * end of the packet. + * At this point: + * capture length != 0, + * packet length != 0, + * capture length <= MAXIMUM_SNAPLEN, + * packet length <= MAXIMUM_SNAPLEN, + * packet length >= capture length. + * + * Currently, there is no D-Bus printer, thus no need for + * bigger lengths. + */ + + /* + * The header /usr/include/pcap/pcap.h in OpenBSD declares h->ts as + * struct bpf_timeval, not struct timeval. The former comes from + * /usr/include/net/bpf.h and uses 32-bit unsigned types instead of + * the types used in struct timeval. + */ + struct timeval tvbuf; + tvbuf.tv_sec = h->ts.tv_sec; + tvbuf.tv_usec = h->ts.tv_usec; + ts_print(ndo, &tvbuf); + + /* + * Printers must check that they're not walking off the end of + * the packet. * Rather than pass it all the way down, we set this member * of the netdissect_options structure. */ ndo->ndo_snapend = sp + h->caplen; - hdrlen = (ndo->ndo_if_printer)(ndo, h, sp); + ndo->ndo_protocol = ""; + ndo->ndo_ll_hdr_len = 0; + switch (setjmp(ndo->ndo_early_end)) { + case 0: + /* Print the packet. */ + (ndo->ndo_if_printer)(ndo, h, sp); + break; + case ND_TRUNCATED: + /* A printer quit because the packet was truncated; report it */ + nd_print_trunc(ndo); + /* Print the full packet */ + ndo->ndo_ll_hdr_len = 0; + break; + } + hdrlen = ndo->ndo_ll_hdr_len; + + /* + * Empty the stack of packet information, freeing all pushed buffers; + * if we got here by a printer quitting, we need to release anything + * that didn't get released because we longjmped out of the code + * before it popped the packet information. + */ + nd_pop_all_packet_info(ndo); /* * Restore the original snapend, as a printer might have @@ -353,7 +451,7 @@ pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h, */ if (h->caplen > hdrlen) hex_and_ascii_print(ndo, "\n\t", sp + hdrlen, - h->caplen - hdrlen); + h->caplen - hdrlen); } } else if (ndo->ndo_xflag) { /* @@ -363,7 +461,7 @@ pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h, /* * Include the link-layer header. */ - hex_print(ndo, "\n\t", sp, h->caplen); + hex_print(ndo, "\n\t", sp, h->caplen); } else { /* * Don't include the link-layer header - and if @@ -372,7 +470,7 @@ pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h, */ if (h->caplen > hdrlen) hex_print(ndo, "\n\t", sp + hdrlen, - h->caplen - hdrlen); + h->caplen - hdrlen); } } else if (ndo->ndo_Aflag) { /* @@ -394,7 +492,8 @@ pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h, } } - ND_PRINT((ndo, "\n")); + ND_PRINT("\n"); + nd_free_all(ndo); } /* @@ -408,11 +507,12 @@ ndo_default_print(netdissect_options *ndo, const u_char *bp, u_int length) /* VARARGS */ static void -ndo_error(netdissect_options *ndo, const char *fmt, ...) +ndo_error(netdissect_options *ndo, status_exit_codes_t status, + const char *fmt, ...) { va_list ap; - if(ndo->program_name) + if (ndo->program_name) (void)fprintf(stderr, "%s: ", ndo->program_name); va_start(ap, fmt); (void)vfprintf(stderr, fmt, ap); @@ -423,7 +523,7 @@ ndo_error(netdissect_options *ndo, const char *fmt, ...) (void)fputc('\n', stderr); } nd_cleanup(); - exit(1); + exit(status); /* NOTREACHED */ } @@ -433,7 +533,7 @@ ndo_warning(netdissect_options *ndo, const char *fmt, ...) { va_list ap; - if(ndo->program_name) + if (ndo->program_name) (void)fprintf(stderr, "%s: ", ndo->program_name); (void)fprintf(stderr, "WARNING: "); va_start(ap, fmt); @@ -457,7 +557,8 @@ ndo_printf(netdissect_options *ndo, const char *fmt, ...) va_end(args); if (ret < 0) - ndo_error(ndo, "Unable to write output: %s", pcap_strerror(errno)); + ndo_error(ndo, S_ERR_ND_WRITE_FILE, + "Unable to write output: %s", pcap_strerror(errno)); return (ret); } @@ -469,9 +570,3 @@ ndo_set_function_pointers(netdissect_options *ndo) ndo->ndo_error=ndo_error; ndo->ndo_warning=ndo_warning; } -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/print.h b/contrib/tcpdump/print.h index 9632694e86..9caba405ea 100644 --- a/contrib/tcpdump/print.h +++ b/contrib/tcpdump/print.h @@ -28,12 +28,11 @@ #ifndef print_h #define print_h -void init_print(netdissect_options *ndo, uint32_t localnet, uint32_t mask, - uint32_t timezone_offset); +void init_print(netdissect_options *ndo, uint32_t localnet, uint32_t mask); int has_printer(int type); -if_printer get_if_printer(netdissect_options *ndo, int type); +if_printer get_if_printer(int type); void pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *sp, diff --git a/contrib/tcpdump/rpc_auth.h b/contrib/tcpdump/rpc_auth.h index 3cc9b30c7b..b73e3be048 100644 --- a/contrib/tcpdump/rpc_auth.h +++ b/contrib/tcpdump/rpc_auth.h @@ -65,14 +65,7 @@ enum sunrpc_auth_stat { * Authentication info. Opaque to client. */ struct sunrpc_opaque_auth { - uint32_t oa_flavor; /* flavor of auth */ - uint32_t oa_len; /* length of opaque body */ + nd_uint32_t oa_flavor; /* flavor of auth */ + nd_uint32_t oa_len; /* length of opaque body */ /* zero or more bytes of body */ }; - -#define SUNRPC_AUTH_NONE 0 /* no authentication */ -#define SUNRPC_AUTH_NULL 0 /* backward compatibility */ -#define SUNRPC_AUTH_UNIX 1 /* unix style (uid, gids) */ -#define SUNRPC_AUTH_SYS 1 /* forward compatibility */ -#define SUNRPC_AUTH_SHORT 2 /* short hand unix style */ -#define SUNRPC_AUTH_DES 3 /* des style (encrypted timestamps) */ diff --git a/contrib/tcpdump/rpc_msg.h b/contrib/tcpdump/rpc_msg.h index 88e7319b16..ecd24cb1a1 100644 --- a/contrib/tcpdump/rpc_msg.h +++ b/contrib/tcpdump/rpc_msg.h @@ -42,7 +42,7 @@ /* * Bottom up definition of an rpc message. - * NOTE: call and reply use the same overall stuct but + * NOTE: call and reply use the same overall struct but * different parts of unions within it. */ @@ -78,13 +78,13 @@ enum sunrpc_reject_stat { * Reply to an rpc request that was rejected by the server. */ struct sunrpc_rejected_reply { - uint32_t rj_stat; /* enum reject_stat */ + nd_uint32_t rj_stat; /* enum reject_stat */ union { struct { - uint32_t low; - uint32_t high; + nd_uint32_t low; + nd_uint32_t high; } RJ_versions; - uint32_t RJ_why; /* enum auth_stat - why authentication did not work */ + nd_uint32_t RJ_why; /* enum auth_stat - why authentication did not work */ } ru; #define rj_vers ru.RJ_versions #define rj_why ru.RJ_why @@ -94,7 +94,7 @@ struct sunrpc_rejected_reply { * Body of a reply to an rpc request. */ struct sunrpc_reply_body { - uint32_t rp_stat; /* enum reply_stat */ + nd_uint32_t rp_stat; /* enum reply_stat */ struct sunrpc_rejected_reply rp_reject; /* if rejected */ }; @@ -102,10 +102,10 @@ struct sunrpc_reply_body { * Body of an rpc request call. */ struct sunrpc_call_body { - uint32_t cb_rpcvers; /* must be equal to two */ - uint32_t cb_prog; - uint32_t cb_vers; - uint32_t cb_proc; + nd_uint32_t cb_rpcvers; /* must be equal to two */ + nd_uint32_t cb_prog; + nd_uint32_t cb_vers; + nd_uint32_t cb_proc; struct sunrpc_opaque_auth cb_cred; /* followed by opaque verifier */ }; @@ -114,8 +114,8 @@ struct sunrpc_call_body { * The rpc message */ struct sunrpc_msg { - uint32_t rm_xid; - uint32_t rm_direction; /* enum msg_type */ + nd_uint32_t rm_xid; + nd_uint32_t rm_direction; /* enum msg_type */ union { struct sunrpc_call_body RM_cmb; struct sunrpc_reply_body RM_rmb; diff --git a/contrib/tcpdump/rpl.h b/contrib/tcpdump/rpl.h deleted file mode 100644 index 5ad074b4be..0000000000 --- a/contrib/tcpdump/rpl.h +++ /dev/null @@ -1,174 +0,0 @@ -#ifndef _RPL_H_ - -/* - * NOTE: the contents of this file are an interpretation of RFC6550. - * no copyright is asserted on this file, as it transcribes - * a public specification. - * - */ - -/* - * DIO: Updated to RFC6550, as published in 2012: section 6. (page 30) - */ - -#define ND_RPL_MESSAGE 155 /* 0x9B */ - -enum ND_RPL_CODE { - ND_RPL_DAG_IS=0x00, - ND_RPL_DAG_IO=0x01, - ND_RPL_DAO =0x02, - ND_RPL_DAO_ACK=0x03, - ND_RPL_SEC_DAG_IS = 0x80, - ND_RPL_SEC_DAG_IO = 0x81, - ND_RPL_SEC_DAG = 0x82, - ND_RPL_SEC_DAG_ACK= 0x83, - ND_RPL_SEC_CONSIST= 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 */ -}; - -#define DAGID_LEN 16 - -/* section 6 of draft-ietf-roll-rpl-19 */ -struct nd_rpl_security { - uint8_t rpl_sec_t_reserved; /* bit 7 is T-bit */ - uint8_t rpl_sec_algo; - uint16_t rpl_sec_kim_lvl_flags; /* bit 15/14, KIM */ - /* bit 10-8, LVL, bit 7-0 flags */ - uint32_t rpl_sec_counter; -#if 0 - uint8_t rpl_sec_ki[0]; /* depends upon kim */ -#endif -}; - -/* section 6.2.1, DODAG Information Solication (DIS_IS) */ -struct nd_rpl_dis_is { - uint8_t rpl_dis_flags; - uint8_t rpl_dis_reserved; -#if 0 - uint8_t rpl_dis_options[0]; -#endif -}; - -/* section 6.3.1, DODAG Information Object (DIO) */ -struct nd_rpl_dio { - uint8_t rpl_instanceid; - uint8_t rpl_version; - uint16_t rpl_dagrank; - uint8_t rpl_mopprf; /* bit 7=G, 5-3=MOP, 2-0=PRF */ - uint8_t rpl_dtsn; /* Dest. Advertisement Trigger Sequence Number */ - uint8_t rpl_flags; /* no flags defined yet */ - uint8_t rpl_resv1; - uint8_t rpl_dagid[DAGID_LEN]; -}; -#define RPL_DIO_GROUND_FLAG 0x80 -#define RPL_DIO_MOP_SHIFT 3 -#define RPL_DIO_MOP_MASK (7 << RPL_DIO_MOP_SHIFT) -#define RPL_DIO_PRF_SHIFT 0 -#define RPL_DIO_PRF_MASK (7 << RPL_DIO_PRF_SHIFT) -#define RPL_DIO_GROUNDED(X) ((X)&RPL_DIO_GROUND_FLAG) -#define RPL_DIO_MOP(X) (enum RPL_DIO_MOP)(((X)&RPL_DIO_MOP_MASK) >> RPL_DIO_MOP_SHIFT) -#define RPL_DIO_PRF(X) (((X)&RPL_DIO_PRF_MASK) >> RPL_DIO_PRF_SHIFT) - -enum RPL_DIO_MOP { - RPL_DIO_NONSTORING= 0x0, - RPL_DIO_STORING = 0x1, - RPL_DIO_NONSTORING_MULTICAST = 0x2, - RPL_DIO_STORING_MULTICAST = 0x3 -}; - -enum RPL_SUBOPT { - RPL_OPT_PAD0 = 0, - RPL_OPT_PADN = 1, - RPL_DIO_METRICS = 2, - RPL_DIO_ROUTINGINFO = 3, - RPL_DIO_CONFIG = 4, - RPL_DAO_RPLTARGET = 5, - RPL_DAO_TRANSITINFO = 6, - RPL_DIO_DESTPREFIX = 8, - RPL_DAO_RPLTARGET_DESC=9 -}; - -struct rpl_dio_genoption { - uint8_t rpl_dio_type; - uint8_t rpl_dio_len; /* suboption length, not including type/len */ -}; -#define RPL_DIO_GENOPTION_LEN 2 - -#define RPL_DIO_LIFETIME_INFINITE 0xffffffff -#define RPL_DIO_LIFETIME_DISCONNECT 0 - -struct rpl_dio_destprefix { - uint8_t rpl_dio_type; - uint8_t rpl_dio_len; - uint8_t rpl_dio_prefixlen; /* in bits */ - uint8_t rpl_dio_prf; /* flags, including Route Preference */ - uint32_t rpl_dio_prefixlifetime; /* in seconds */ -#if 0 - uint8_t rpl_dio_prefix[0]; /* variable number of bytes */ -#endif -}; - -/* section 6.4.1, DODAG Information Object (DIO) */ -struct nd_rpl_dao { - uint8_t rpl_instanceid; - uint8_t rpl_flags; /* bit 7=K, 6=D */ - uint8_t rpl_resv; - uint8_t rpl_daoseq; - uint8_t rpl_dagid[DAGID_LEN]; /* present when D set. */ -}; -#define ND_RPL_DAO_MIN_LEN 4 /* length without DAGID */ - -/* indicates if this DAO is to be acK'ed */ -#define RPL_DAO_K_SHIFT 7 -#define RPL_DAO_K_MASK (1 << RPL_DAO_K_SHIFT) -#define RPL_DAO_K(X) (((X)&RPL_DAO_K_MASK) >> RPL_DAO_K_SHIFT) - -/* indicates if the DAGID is present */ -#define RPL_DAO_D_SHIFT 6 -#define RPL_DAO_D_MASK (1 << RPL_DAO_D_SHIFT) -#define RPL_DAO_D(X) (((X)&RPL_DAO_D_MASK) >> RPL_DAO_D_SHIFT) - -struct rpl_dao_target { - uint8_t rpl_dao_type; - uint8_t rpl_dao_len; - uint8_t rpl_dao_flags; /* unused */ - uint8_t rpl_dao_prefixlen; /* in bits */ -#if 0 - uint8_t rpl_dao_prefix[0]; /* variable number of bytes */ -#endif -}; - -/* section 6.5.1, Destination Advertisement Object Acknowledgement (DAO-ACK) */ -struct nd_rpl_daoack { - uint8_t rpl_instanceid; - uint8_t rpl_flags; /* bit 7=D */ - uint8_t rpl_daoseq; - uint8_t rpl_status; - uint8_t rpl_dagid[DAGID_LEN]; /* present when D set. */ -}; -#define ND_RPL_DAOACK_MIN_LEN 4 /* length without DAGID */ -/* indicates if the DAGID is present */ -#define RPL_DAOACK_D_SHIFT 7 -#define RPL_DAOACK_D_MASK (1 << RPL_DAOACK_D_SHIFT) -#define RPL_DAOACK_D(X) (((X)&RPL_DAOACK_D_MASK) >> RPL_DAOACK_D_SHIFT) - - - -#define _RPL_H_ -#endif /* _RPL_H_ */ - -/* - * Local Variables: - * c-basic-offset:4 - * c-style: whitesmith - * End: - */ - diff --git a/contrib/tcpdump/setsignal.c b/contrib/tcpdump/setsignal.c deleted file mode 100644 index 4d93cebf75..0000000000 --- a/contrib/tcpdump/setsignal.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 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. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include -#ifdef HAVE_SIGACTION -#include -#endif - -#ifdef HAVE_OS_PROTO_H -#include "os-proto.h" -#endif - -#include "setsignal.h" - -/* - * An OS-independent signal() with, whenever possible, partial BSD - * semantics, i.e. the signal handler is restored following service - * of the signal, but system calls are *not* restarted, so that if - * "pcap_breakloop()" is called in a signal handler in a live capture, - * the read/recvfrom/whatever in the live capture doesn't get restarted, - * it returns -1 and sets "errno" to EINTR, so we can break out of the - * live capture loop. - * - * We use "sigaction()" if available. We don't specify that the signal - * should restart system calls, so that should always do what we want. - * - * Otherwise, if "sigset()" is available, it probably has BSD semantics - * while "signal()" has traditional semantics, so we use "sigset()"; it - * might cause system calls to be restarted for the signal, however. - * I don't know whether, in any systems where it did cause system calls to - * be restarted, there was a way to ask it not to do so; there may no - * longer be any interesting systems without "sigaction()", however, - * and, if there are, they might have "sigvec()" with SV_INTERRUPT - * (which I think first appeared in 4.3BSD). - * - * Otherwise, we use "signal()" - which means we might get traditional - * semantics, wherein system calls don't get restarted *but* the - * signal handler is reset to SIG_DFL and the signal is not blocked, - * so that a subsequent signal would kill the process immediately. - * - * Did I mention that signals suck? At least in POSIX-compliant systems - * they suck far less, as those systems have "sigaction()". - */ -RETSIGTYPE -(*setsignal (int sig, RETSIGTYPE (*func)(int)))(int) -{ -#ifdef HAVE_SIGACTION - struct sigaction old, new; - - memset(&new, 0, sizeof(new)); - new.sa_handler = func; - if (sig == SIGCHLD) - new.sa_flags = SA_RESTART; - if (sigaction(sig, &new, &old) < 0) - return (SIG_ERR); - return (old.sa_handler); - -#else -#ifdef HAVE_SIGSET - return (sigset(sig, func)); -#else - return (signal(sig, func)); -#endif -#endif -} - diff --git a/contrib/tcpdump/setsignal.h b/contrib/tcpdump/setsignal.h deleted file mode 100644 index 91a2048a16..0000000000 --- a/contrib/tcpdump/setsignal.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 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 setsignal_h -#define setsignal_h - -RETSIGTYPE (*setsignal(int, RETSIGTYPE (*)(int)))(int); -#endif diff --git a/contrib/tcpdump/signature.c b/contrib/tcpdump/signature.c index 204e3456e2..ca3aec9f45 100644 --- a/contrib/tcpdump/signature.c +++ b/contrib/tcpdump/signature.c @@ -16,10 +16,10 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include #include @@ -81,8 +81,8 @@ signature_compute_hmac_md5(const uint8_t *text, int text_len, unsigned char *key */ /* start out by storing key in pads */ - memset(k_ipad, 0, sizeof k_ipad); - memset(k_opad, 0, sizeof k_opad); + 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); @@ -130,7 +130,7 @@ signature_verify(netdissect_options *ndo, const u_char *pptr, u_int plen, /* * Do we have all the packet data to be checked? */ - if (!ND_TTEST2(*pptr, plen)) { + if (!ND_TTEST_LEN(pptr, plen)) { /* No. */ return (CANT_CHECK_SIGNATURE); } @@ -138,7 +138,7 @@ signature_verify(netdissect_options *ndo, const u_char *pptr, u_int plen, /* * Do we have the entire signature to check? */ - if (!ND_TTEST2(*sig_ptr, sizeof(sig))) { + if (!ND_TTEST_LEN(sig_ptr, sizeof(sig))) { /* No. */ return (CANT_CHECK_SIGNATURE); } @@ -190,7 +190,7 @@ signature_verify(netdissect_options *ndo, const u_char *pptr, u_int plen, } else { /* No - print the computed signature. */ for (i = 0; i < sizeof(sig); ++i) { - ND_PRINT((ndo, "%02x", sig[i])); + ND_PRINT("%02x", sig[i]); } return (SIGNATURE_INVALID); @@ -205,10 +205,3 @@ signature_verify(netdissect_options *ndo _U_, const u_char *pptr _U_, return (CANT_CHECK_SIGNATURE); } #endif - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 4 - * End: - */ diff --git a/contrib/tcpdump/smb.h b/contrib/tcpdump/smb.h index b521617fe0..40bba5004a 100644 --- a/contrib/tcpdump/smb.h +++ b/contrib/tcpdump/smb.h @@ -116,7 +116,9 @@ #define TRANSACT2_FINDNOTIFYNEXT 12 #define TRANSACT2_MKDIR 13 -#define PTR_DIFF(p1, p2) ((size_t)(((const char *)(p1)) - (const char *)(p2))) - /* some protos */ +void smb_reset(void); const u_char *smb_fdata(netdissect_options *, const u_char *, const char *, const u_char *, int); +extern void smb_data_print(netdissect_options *, const u_char *, u_int); +extern const char *smb_errstr(int, int); +extern const char *nt_errstr(uint32_t); diff --git a/contrib/tcpdump/smbutil.c b/contrib/tcpdump/smbutil.c index 525635cbc7..ff32ecce2b 100644 --- a/contrib/tcpdump/smbutil.c +++ b/contrib/tcpdump/smbutil.c @@ -7,22 +7,35 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include #include #include +#include "netdissect-ctype.h" + #include "netdissect.h" #include "extract.h" #include "smb.h" +static int stringlen_is_set; static uint32_t stringlen; extern const u_char *startbuf; +/* + * Reset SMB state. + */ +void +smb_reset(void) +{ + stringlen_is_set = 0; + stringlen = 0; +} + /* * interpret a 32 bit dos packed date/time to some parameters */ @@ -69,11 +82,11 @@ int_unix_date(uint32_t dos_date) * in network byte order */ static time_t -make_unix_date(const u_char *date_ptr) +make_unix_date(netdissect_options *ndo, const u_char *date_ptr) { uint32_t dos_date = 0; - dos_date = EXTRACT_LE_32BITS(date_ptr); + dos_date = GET_LE_U_4(date_ptr); return int_unix_date(dos_date); } @@ -83,11 +96,11 @@ make_unix_date(const u_char *date_ptr) * in halfword-swapped network byte order! */ static time_t -make_unix_date2(const u_char *date_ptr) +make_unix_date2(netdissect_options *ndo, const u_char *date_ptr) { uint32_t x, x2; - x = EXTRACT_LE_32BITS(date_ptr); + x = GET_LE_U_4(date_ptr); x2 = ((x & 0xFFFF) << 16) | ((x & 0xFFFF0000) >> 16); return int_unix_date(x2); } @@ -97,13 +110,13 @@ make_unix_date2(const u_char *date_ptr) * It's originally in "100ns units since jan 1st 1601" */ static time_t -interpret_long_date(const u_char *p) +interpret_long_date(netdissect_options *ndo, const u_char *p) { double d; time_t ret; /* this gives us seconds since jan 1st 1601 (approx) */ - d = (EXTRACT_LE_32BITS(p + 4) * 256.0 + p[3]) * (1.0e-7 * (1 << 24)); + d = (GET_LE_U_4(p + 4) * 256.0 + GET_U_1(p + 3)) * (1.0e-7 * (1 << 24)); /* now adjust by 369 years to make the secs since 1970 */ d -= 369.0 * 365.25 * 24 * 60 * 60; @@ -128,29 +141,31 @@ name_interpret(netdissect_options *ndo, const u_char *in, const u_char *maxbuf, char *out) { int ret; - int len; + u_int len; if (in >= maxbuf) return(-1); /* name goes past the end of the buffer */ - ND_TCHECK2(*in, 1); - len = (*in++) / 2; + len = GET_U_1(in) / 2; + in++; *out=0; - if (len > 30 || len < 1) + if (len > 30 || len == 0) return(0); - while (len--) { - ND_TCHECK2(*in, 2); + while (len) { + ND_TCHECK_2(in); if (in + 1 >= maxbuf) return(-1); /* name goes past the end of the buffer */ - if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') { + if (GET_U_1(in) < 'A' || GET_U_1(in) > 'P' || + GET_U_1(in + 1) < 'A' || GET_U_1(in + 1) > 'P') { *out = 0; return(0); } - *out = ((in[0] - 'A') << 4) + (in[1] - 'A'); + *out = ((GET_U_1(in) - 'A') << 4) + (GET_U_1(in + 1) - 'A'); in += 2; out++; + len--; } *out = 0; ret = out[-1]; @@ -166,7 +181,7 @@ trunc: */ static const u_char * name_ptr(netdissect_options *ndo, - const u_char *buf, int ofs, const u_char *maxbuf) + const u_char *buf, u_int ofs, const u_char *maxbuf) { const u_char *p; u_char c; @@ -174,18 +189,17 @@ name_ptr(netdissect_options *ndo, p = buf + ofs; if (p >= maxbuf) return(NULL); /* name goes past the end of the buffer */ - ND_TCHECK2(*p, 1); - c = *p; + c = GET_U_1(p); /* XXX - this should use the same code that the DNS dissector does */ if ((c & 0xC0) == 0xC0) { uint16_t l; - ND_TCHECK2(*p, 2); + ND_TCHECK_2(p); if ((p + 1) >= maxbuf) return(NULL); /* name goes past the end of the buffer */ - l = EXTRACT_16BITS(p) & 0x3FFF; + l = GET_BE_U_2(p) & 0x3FFF; if (l == 0) { /* We have a pointer that points to itself. */ return(NULL); @@ -193,7 +207,7 @@ name_ptr(netdissect_options *ndo, p = buf + l; if (p >= maxbuf) return(NULL); /* name goes past the end of the buffer */ - ND_TCHECK2(*p, 1); + ND_TCHECK_1(p); } return(p); @@ -206,7 +220,7 @@ trunc: */ static int name_extract(netdissect_options *ndo, - const u_char *buf, int ofs, const u_char *maxbuf, char *name) + const u_char *buf, u_int ofs, const u_char *maxbuf, char *name) { const u_char *p = name_ptr(ndo, buf, ofs, maxbuf); if (p == NULL) @@ -221,25 +235,23 @@ name_extract(netdissect_options *ndo, */ static int name_len(netdissect_options *ndo, - const unsigned char *s, const unsigned char *maxbuf) + const u_char *s, const u_char *maxbuf) { - const unsigned char *s0 = s; + const u_char *s0 = s; unsigned char c; if (s >= maxbuf) return(-1); /* name goes past the end of the buffer */ - ND_TCHECK2(*s, 1); - c = *s; + c = GET_U_1(s); if ((c & 0xC0) == 0xC0) return(2); - while (*s) { + while (GET_U_1(s)) { if (s >= maxbuf) return(-1); /* name goes past the end of the buffer */ - ND_TCHECK2(*s, 1); - s += (*s) + 1; - ND_TCHECK2(*s, 1); + s += GET_U_1(s) + 1; + ND_TCHECK_1(s); } - return(PTR_DIFF(s, s0) + 1); + return(ND_BYTES_BETWEEN(s, s0) + 1); trunc: return(-1); /* name goes past the end of the buffer */ @@ -247,11 +259,11 @@ trunc: static void print_asc(netdissect_options *ndo, - const unsigned char *buf, int len) + const u_char *buf, u_int len) { - int i; + u_int i; for (i = 0; i < len; i++) - safeputchar(ndo, buf[i]); + fn_print_char(ndo, GET_U_1(buf + i)); } static const char * @@ -272,51 +284,45 @@ name_type_str(int name_type) } void -smb_print_data(netdissect_options *ndo, const unsigned char *buf, int len) +smb_data_print(netdissect_options *ndo, const u_char *buf, u_int len) { - int i = 0; + u_int i = 0; - if (len <= 0) + if (len == 0) return; - ND_PRINT((ndo, "[%03X] ", i)); + ND_PRINT("[%03X] ", i); for (i = 0; i < len; /*nothing*/) { - ND_TCHECK(buf[i]); - ND_PRINT((ndo, "%02X ", buf[i] & 0xff)); + ND_PRINT("%02X ", GET_U_1(buf + i) & 0xff); i++; if (i%8 == 0) - ND_PRINT((ndo, " ")); + ND_PRINT(" "); if (i % 16 == 0) { - print_asc(ndo, &buf[i - 16], 8); - ND_PRINT((ndo, " ")); - print_asc(ndo, &buf[i - 8], 8); - ND_PRINT((ndo, "\n")); + print_asc(ndo, buf + i - 16, 8); + ND_PRINT(" "); + print_asc(ndo, buf + i - 8, 8); + ND_PRINT("\n"); if (i < len) - ND_PRINT((ndo, "[%03X] ", i)); + ND_PRINT("[%03X] ", i); } } if (i % 16) { int n; n = 16 - (i % 16); - ND_PRINT((ndo, " ")); + ND_PRINT(" "); if (n>8) - ND_PRINT((ndo, " ")); + ND_PRINT(" "); while (n--) - ND_PRINT((ndo, " ")); + ND_PRINT(" "); - n = min(8, i % 16); - print_asc(ndo, &buf[i - (i % 16)], n); - ND_PRINT((ndo, " ")); + n = ND_MIN(8, i % 16); + print_asc(ndo, buf + i - (i % 16), n); + ND_PRINT(" "); n = (i % 16) - n; if (n > 0) - print_asc(ndo, &buf[i - n], n); - ND_PRINT((ndo, "\n")); + print_asc(ndo, buf + i - n, n); + ND_PRINT("\n"); } - return; - -trunc: - ND_PRINT((ndo, "\n")); - ND_PRINT((ndo, "WARNING: Short packet. Try increasing the snap length\n")); } @@ -325,12 +331,12 @@ write_bits(netdissect_options *ndo, unsigned int val, const char *fmt) { const char *p = fmt; - int i = 0; + u_int i = 0; while ((p = strchr(fmt, '|'))) { - size_t l = PTR_DIFF(p, fmt); + u_int l = ND_BYTES_BETWEEN(p, fmt); if (l && (val & (1 << i))) - ND_PRINT((ndo, "%.*s ", (int)l, fmt)); + ND_PRINT("%.*s ", (int)l, fmt); fmt = p + 1; i++; } @@ -338,13 +344,13 @@ write_bits(netdissect_options *ndo, /* convert a UCS-2 string into an ASCII string */ #define MAX_UNISTR_SIZE 1000 -static const char * -unistr(netdissect_options *ndo, - const u_char *s, uint32_t *len, int use_unicode) +static const u_char * +unistr(netdissect_options *ndo, char (*buf)[MAX_UNISTR_SIZE+1], + const u_char *s, uint32_t strsize, int is_null_terminated, + int use_unicode) { - static char buf[MAX_UNISTR_SIZE+1]; + u_int c; size_t l = 0; - uint32_t strsize; const u_char *sp; if (use_unicode) { @@ -352,82 +358,108 @@ unistr(netdissect_options *ndo, * Skip padding that puts the string on an even boundary. */ if (((s - startbuf) % 2) != 0) { - ND_TCHECK(s[0]); + ND_TCHECK_1(s); s++; } } - if (*len == 0) { + if (is_null_terminated) { /* * Null-terminated string. + * Find the length, counting the terminating NUL. */ strsize = 0; sp = s; if (!use_unicode) { for (;;) { - ND_TCHECK(sp[0]); - *len += 1; - if (sp[0] == 0) - break; + c = GET_U_1(sp); sp++; + strsize++; + if (c == '\0') + break; } - strsize = *len - 1; } else { for (;;) { - ND_TCHECK2(sp[0], 2); - *len += 2; - if (sp[0] == 0 && sp[1] == 0) - break; + c = GET_LE_U_2(sp); sp += 2; + strsize += 2; + if (c == '\0') + break; } - strsize = *len - 2; } - } else { - /* - * Counted string. - */ - strsize = *len; } if (!use_unicode) { while (strsize != 0) { - ND_TCHECK(s[0]); - if (l >= MAX_UNISTR_SIZE) - break; - if (ND_ISPRINT(s[0])) - buf[l] = s[0]; - else { - if (s[0] == 0) - break; - buf[l] = '.'; - } - l++; + c = GET_U_1(s); s++; strsize--; - } - } else { - while (strsize != 0) { - ND_TCHECK2(s[0], 2); - if (l >= MAX_UNISTR_SIZE) + if (c == 0) { + /* + * Even counted strings may have embedded null + * terminators, so quit here, and skip past + * the rest of the data. + * + * Make sure, however, that the rest of the data + * is there, so we don't overflow the buffer when + * skipping past it. + */ + ND_TCHECK_LEN(s, strsize); + s += strsize; + strsize = 0; break; - if (s[1] == 0 && ND_ISPRINT(s[0])) { - /* It's a printable ASCII character */ - buf[l] = s[0]; - } else { - /* It's a non-ASCII character or a non-printable ASCII character */ - if (s[0] == 0 && s[1] == 0) - break; - buf[l] = '.'; } - l++; + if (l < MAX_UNISTR_SIZE) { + if (ND_ASCII_ISPRINT(c)) { + /* It's a printable ASCII character */ + (*buf)[l] = (char)c; + } else { + /* It's a non-ASCII character or a non-printable ASCII character */ + (*buf)[l] = '.'; + } + l++; + } + } + } else { + while (strsize > 1) { + c = GET_LE_U_2(s); s += 2; - if (strsize == 1) - break; strsize -= 2; + if (c == 0) { + /* + * Even counted strings may have embedded null + * terminators, so quit here, and skip past + * the rest of the data. + * + * Make sure, however, that the rest of the data + * is there, so we don't overflow the buffer when + * skipping past it. + */ + ND_TCHECK_LEN(s, strsize); + s += strsize; + strsize = 0; + break; + } + if (l < MAX_UNISTR_SIZE) { + if (ND_ASCII_ISPRINT(c)) { + /* It's a printable ASCII character */ + (*buf)[l] = (char)c; + } else { + /* It's a non-ASCII character or a non-printable ASCII character */ + (*buf)[l] = '.'; + } + l++; + } + } + if (strsize == 1) { + /* We have half of a code point; skip past it */ + ND_TCHECK_1(s); + s++; } } - buf[l] = 0; - return buf; + (*buf)[l] = 0; + return s; trunc: + (*buf)[l] = 0; return NULL; } @@ -438,19 +470,18 @@ smb_fdata1(netdissect_options *ndo, { int reverse = 0; const char *attrib_fmt = "READONLY|HIDDEN|SYSTEM|VOLUME|DIR|ARCHIVE|"; + char strbuf[MAX_UNISTR_SIZE+1]; while (*fmt && buf sizeof(bitfmt) - 1) - l = sizeof(bitfmt)-1; + if (l > sizeof(bitfmt) - 1) + l = sizeof(bitfmt)-1; strncpy(bitfmt, fmt, l); bitfmt[l] = '\0'; fmt = p + 1; - ND_TCHECK(buf[0]); - write_bits(ndo, buf[0], bitfmt); + write_bits(ndo, GET_U_1(buf), bitfmt); buf++; break; } case 'P': { - int l = atoi(fmt + 1); - if(l <= 0) goto trunc; /* actually error in fmt string */ - ND_TCHECK2(buf[0], l); + int l = atoi(fmt + 1); + ND_TCHECK_LEN(buf, l); buf += l; fmt++; - while (isdigit((unsigned char)*fmt)) - fmt++; + while (ND_ASCII_ISDIGIT(*fmt)) + fmt++; break; } case 'r': @@ -494,31 +523,28 @@ smb_fdata1(netdissect_options *ndo, case 'b': { unsigned int x; - ND_TCHECK(buf[0]); - x = buf[0]; - ND_PRINT((ndo, "%u (0x%x)", x, x)); + x = GET_U_1(buf); + ND_PRINT("%u (0x%x)", x, x); buf += 1; fmt++; break; } case 'd': { - unsigned int x; - ND_TCHECK2(buf[0], 2); - x = reverse ? EXTRACT_16BITS(buf) : - EXTRACT_LE_16BITS(buf); - ND_PRINT((ndo, "%d (0x%x)", x, x)); + int x; + x = reverse ? GET_BE_S_2(buf) : + GET_LE_S_2(buf); + ND_PRINT("%d (0x%x)", x, x); buf += 2; fmt++; break; } case 'D': { - unsigned int x; - ND_TCHECK2(buf[0], 4); - x = reverse ? EXTRACT_32BITS(buf) : - EXTRACT_LE_32BITS(buf); - ND_PRINT((ndo, "%d (0x%x)", x, x)); + int x; + x = reverse ? GET_BE_S_4(buf) : + GET_LE_S_4(buf); + ND_PRINT("%d (0x%x)", x, x); buf += 4; fmt++; break; @@ -526,26 +552,45 @@ smb_fdata1(netdissect_options *ndo, case 'L': { uint64_t x; - ND_TCHECK2(buf[0], 8); - x = reverse ? EXTRACT_64BITS(buf) : - EXTRACT_LE_64BITS(buf); - ND_PRINT((ndo, "%" PRIu64 " (0x%" PRIx64 ")", x, x)); + x = reverse ? GET_BE_U_8(buf) : + GET_LE_U_8(buf); + ND_PRINT("%" PRIu64 " (0x%" PRIx64 ")", x, x); buf += 8; fmt++; break; } + case 'u': + { + unsigned int x; + x = reverse ? GET_BE_U_2(buf) : + GET_LE_U_2(buf); + ND_PRINT("%u (0x%x)", x, x); + buf += 2; + fmt++; + break; + } + case 'U': + { + unsigned int x; + x = reverse ? GET_BE_U_4(buf) : + GET_LE_U_4(buf); + ND_PRINT("%u (0x%x)", x, x); + buf += 4; + fmt++; + break; + } case 'M': { /* Weird mixed-endian length values in 64-bit locks */ uint32_t x1, x2; uint64_t x; - ND_TCHECK2(buf[0], 8); - x1 = reverse ? EXTRACT_32BITS(buf) : - EXTRACT_LE_32BITS(buf); - x2 = reverse ? EXTRACT_32BITS(buf + 4) : - EXTRACT_LE_32BITS(buf + 4); + ND_TCHECK_8(buf); + x1 = reverse ? GET_BE_U_4(buf) : + GET_LE_U_4(buf); + x2 = reverse ? GET_BE_U_4(buf + 4) : + GET_LE_U_4(buf + 4); x = (((uint64_t)x1) << 32) | x2; - ND_PRINT((ndo, "%" PRIu64 " (0x%" PRIx64 ")", x, x)); + ND_PRINT("%" PRIu64 " (0x%" PRIx64 ")", x, x); buf += 8; fmt++; break; @@ -553,9 +598,8 @@ smb_fdata1(netdissect_options *ndo, case 'B': { unsigned int x; - ND_TCHECK(buf[0]); - x = buf[0]; - ND_PRINT((ndo, "0x%X", x)); + x = GET_U_1(buf); + ND_PRINT("0x%X", x); buf += 1; fmt++; break; @@ -563,10 +607,9 @@ smb_fdata1(netdissect_options *ndo, case 'w': { unsigned int x; - ND_TCHECK2(buf[0], 2); - x = reverse ? EXTRACT_16BITS(buf) : - EXTRACT_LE_16BITS(buf); - ND_PRINT((ndo, "0x%X", x)); + x = reverse ? GET_BE_U_2(buf) : + GET_LE_U_2(buf); + ND_PRINT("0x%X", x); buf += 2; fmt++; break; @@ -574,10 +617,9 @@ smb_fdata1(netdissect_options *ndo, case 'W': { unsigned int x; - ND_TCHECK2(buf[0], 4); - x = reverse ? EXTRACT_32BITS(buf) : - EXTRACT_LE_32BITS(buf); - ND_PRINT((ndo, "0x%X", x)); + x = reverse ? GET_BE_U_4(buf) : + GET_LE_U_4(buf); + ND_PRINT("0x%X", x); buf += 4; fmt++; break; @@ -588,25 +630,27 @@ smb_fdata1(netdissect_options *ndo, switch (*fmt) { case 'b': - ND_TCHECK(buf[0]); - stringlen = buf[0]; - ND_PRINT((ndo, "%u", stringlen)); + stringlen = GET_U_1(buf); + stringlen_is_set = 1; + ND_PRINT("%u", stringlen); buf += 1; break; case 'd': - ND_TCHECK2(buf[0], 2); - stringlen = reverse ? EXTRACT_16BITS(buf) : - EXTRACT_LE_16BITS(buf); - ND_PRINT((ndo, "%u", stringlen)); + case 'u': + stringlen = reverse ? GET_BE_U_2(buf) : + GET_LE_U_2(buf); + stringlen_is_set = 1; + ND_PRINT("%u", stringlen); buf += 2; break; case 'D': - ND_TCHECK2(buf[0], 4); - stringlen = reverse ? EXTRACT_32BITS(buf) : - EXTRACT_LE_32BITS(buf); - ND_PRINT((ndo, "%u", stringlen)); + case 'U': + stringlen = reverse ? GET_BE_U_4(buf) : + GET_LE_U_4(buf); + stringlen_is_set = 1; + ND_PRINT("%u", stringlen); buf += 4; break; } @@ -617,78 +661,75 @@ smb_fdata1(netdissect_options *ndo, case 'R': /* like 'S', but always ASCII */ { /*XXX unistr() */ - const char *s; - uint32_t len; - - len = 0; - s = unistr(ndo, buf, &len, (*fmt == 'R') ? 0 : unicodestr); - if (s == NULL) + buf = unistr(ndo, &strbuf, buf, 0, 1, (*fmt == 'R') ? 0 : unicodestr); + ND_PRINT("%s", strbuf); + if (buf == NULL) goto trunc; - ND_PRINT((ndo, "%s", s)); - buf += len; fmt++; break; } case 'Z': case 'Y': /* like 'Z', but always ASCII */ { - const char *s; - uint32_t len; - - ND_TCHECK(*buf); - if (*buf != 4 && *buf != 2) { - ND_PRINT((ndo, "Error! ASCIIZ buffer of type %u", *buf)); + if (GET_U_1(buf) != 4 && GET_U_1(buf) != 2) { + ND_PRINT("Error! ASCIIZ buffer of type %u", GET_U_1(buf)); return maxbuf; /* give up */ } - len = 0; - s = unistr(ndo, buf + 1, &len, (*fmt == 'Y') ? 0 : unicodestr); - if (s == NULL) + buf = unistr(ndo, &strbuf, buf + 1, 0, 1, (*fmt == 'Y') ? 0 : unicodestr); + ND_PRINT("%s", strbuf); + if (buf == NULL) goto trunc; - ND_PRINT((ndo, "%s", s)); - buf += len + 1; fmt++; break; } case 's': { int l = atoi(fmt + 1); - ND_TCHECK2(*buf, l); - ND_PRINT((ndo, "%-*.*s", l, l, buf)); + ND_TCHECK_LEN(buf, l); + ND_PRINT("%-*.*s", l, l, buf); buf += l; fmt++; - while (isdigit((unsigned char)*fmt)) + while (ND_ASCII_ISDIGIT(*fmt)) fmt++; break; } case 'c': { - ND_TCHECK2(*buf, stringlen); - ND_PRINT((ndo, "%-*.*s", (int)stringlen, (int)stringlen, buf)); + if (!stringlen_is_set) { + ND_PRINT("{stringlen not set}"); + goto trunc; + } + ND_TCHECK_LEN(buf, stringlen); + ND_PRINT("%-*.*s", (int)stringlen, (int)stringlen, buf); buf += stringlen; fmt++; - while (isdigit((unsigned char)*fmt)) + while (ND_ASCII_ISDIGIT(*fmt)) fmt++; break; } case 'C': { - const char *s; - s = unistr(ndo, buf, &stringlen, unicodestr); - if (s == NULL) + if (!stringlen_is_set) { + ND_PRINT("{stringlen not set}"); + goto trunc; + } + buf = unistr(ndo, &strbuf, buf, stringlen, 0, unicodestr); + ND_PRINT("%s", strbuf); + if (buf == NULL) goto trunc; - ND_PRINT((ndo, "%s", s)); - buf += stringlen; fmt++; break; } case 'h': { int l = atoi(fmt + 1); - ND_TCHECK2(*buf, l); - while (l--) - ND_PRINT((ndo, "%02x", *buf++)); + ND_TCHECK_LEN(buf, l); + while (l--) { + ND_PRINT("%02x", GET_U_1(buf)); + buf++; + } fmt++; - while (isdigit((unsigned char)*fmt)) + while (ND_ASCII_ISDIGIT(*fmt)) fmt++; break; } @@ -701,7 +742,7 @@ smb_fdata1(netdissect_options *ndo, switch (t) { case 1: - name_type = name_extract(ndo, startbuf, PTR_DIFF(buf, startbuf), + name_type = name_extract(ndo, startbuf, ND_BYTES_BETWEEN(buf, startbuf), maxbuf, nbuf); if (name_type < 0) goto trunc; @@ -709,19 +750,18 @@ smb_fdata1(netdissect_options *ndo, if (len < 0) goto trunc; buf += len; - ND_PRINT((ndo, "%-15.15s NameType=0x%02X (%s)", nbuf, name_type, - name_type_str(name_type))); + ND_PRINT("%-15.15s NameType=0x%02X (%s)", nbuf, name_type, + name_type_str(name_type)); break; case 2: - ND_TCHECK(buf[15]); - name_type = buf[15]; - ND_PRINT((ndo, "%-15.15s NameType=0x%02X (%s)", buf, name_type, - name_type_str(name_type))); + name_type = GET_U_1(buf + 15); + ND_PRINT("%-15.15s NameType=0x%02X (%s)", buf, name_type, + name_type_str(name_type)); buf += 16; break; } fmt++; - while (isdigit((unsigned char)*fmt)) + while (ND_ASCII_ISDIGIT(*fmt)) fmt++; break; } @@ -734,26 +774,24 @@ smb_fdata1(netdissect_options *ndo, switch (atoi(fmt + 1)) { case 1: - ND_TCHECK2(buf[0], 4); - x = EXTRACT_LE_32BITS(buf); + x = GET_LE_U_4(buf); if (x == 0 || x == 0xFFFFFFFF) t = 0; else - t = make_unix_date(buf); + t = make_unix_date(ndo, buf); buf += 4; break; case 2: - ND_TCHECK2(buf[0], 4); - x = EXTRACT_LE_32BITS(buf); + x = GET_LE_U_4(buf); if (x == 0 || x == 0xFFFFFFFF) t = 0; else - t = make_unix_date2(buf); + t = make_unix_date2(ndo, buf); buf += 4; break; case 3: - ND_TCHECK2(buf[0], 8); - t = interpret_long_date(buf); + ND_TCHECK_8(buf); + t = interpret_long_date(ndo, buf); buf += 8; break; default: @@ -768,27 +806,26 @@ smb_fdata1(netdissect_options *ndo, tstring = "(Can't convert time)\n"; } else tstring = "NULL\n"; - ND_PRINT((ndo, "%s", tstring)); + ND_PRINT("%s", tstring); fmt++; - while (isdigit((unsigned char)*fmt)) + while (ND_ASCII_ISDIGIT(*fmt)) fmt++; break; } default: - ND_PRINT((ndo, "%c", *fmt)); + ND_PRINT("%c", *fmt); fmt++; break; } } if (buf >= maxbuf && *fmt) - ND_PRINT((ndo, "END OF BUFFER\n")); + ND_PRINT("END OF BUFFER\n"); return(buf); trunc: - ND_PRINT((ndo, "\n")); - ND_PRINT((ndo, "WARNING: Short packet. Try increasing the snap length\n")); + nd_print_trunc(ndo); return(NULL); } @@ -798,7 +835,6 @@ smb_fdata(netdissect_options *ndo, int unicodestr) { static int depth = 0; - const u_char *buf_start = buf; char s[128]; char *p; @@ -821,7 +857,7 @@ smb_fdata(netdissect_options *ndo, * have format strings with that level of nesting. */ if (depth == 10) { - ND_PRINT((ndo, "(too many nested levels, not recursing)")); + ND_PRINT("(too many nested levels, not recursing)"); buf2 = buf; } else buf2 = smb_fdata(ndo, buf, fmt, maxbuf, unicodestr); @@ -877,7 +913,15 @@ smb_fdata(netdissect_options *ndo, s[p - fmt] = '\0'; fmt = p + 1; buf = smb_fdata1(ndo, buf, s, maxbuf, unicodestr); - if(buf < buf_start || buf == NULL) { + if (buf == NULL) { + /* + * Truncated. + * Is the next character a newline? + * If so, print it before quitting, so we don't + * get stuff in the middle of the line. + */ + if (*fmt == '\n') + ND_PRINT("\n"); return(NULL); } break; @@ -886,15 +930,15 @@ smb_fdata(netdissect_options *ndo, /* * Not a formatting character, so just print it. */ - ND_PRINT((ndo, "%c", *fmt)); + ND_PRINT("%c", *fmt); fmt++; break; } } if (!depth && buf < maxbuf) { - size_t len = PTR_DIFF(maxbuf, buf); - ND_PRINT((ndo, "Data: (%lu bytes)\n", (unsigned long)len)); - smb_print_data(ndo, buf, len); + u_int len = ND_BYTES_BETWEEN(maxbuf, buf); + ND_PRINT("Data: (%u bytes)\n", len); + smb_data_print(ndo, buf, len); return(buf + len); } return(buf); @@ -1017,7 +1061,7 @@ static const struct { /* * return a SMB error string from a SMB buffer */ -char * +const char * smb_errstr(int class, int num) { static char ret[128]; @@ -1866,7 +1910,7 @@ static const nt_err_code_struct nt_errors[] = { { 0xC002100A, "RPC_P_SEND_FAILED" }, { 0xC002100B, "RPC_P_TIMEOUT" }, { 0xC002100C, "RPC_P_SERVER_TRANSPORT_ERROR" }, - { 0xC002100E, "RPC_P_EXCEPTION_OCCURED" }, + { 0xC002100E, "RPC_P_EXCEPTION_OCCURRED" }, { 0xC0021012, "RPC_P_CONNECTION_SHUTDOWN" }, { 0xC0021015, "RPC_P_THREAD_LISTENING" }, { 0xC0030001, "RPC_NT_NO_MORE_ENTRIES" }, diff --git a/contrib/tcpdump/print-ftp.c b/contrib/tcpdump/status-exit-codes.h similarity index 56% copy from contrib/tcpdump/print-ftp.c copy to contrib/tcpdump/status-exit-codes.h index a1dd60709a..34d9d16b3c 100644 --- a/contrib/tcpdump/print-ftp.c +++ b/contrib/tcpdump/status-exit-codes.h @@ -1,4 +1,7 @@ /* + * Copyright (c) 2018 The TCPDUMP project + * 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 @@ -11,22 +14,19 @@ * FOR A PARTICULAR PURPOSE. */ -/* \summary: File Transfer Protocol (FTP) printer */ +#ifndef status_exit_codes_h +#define status_exit_codes_h -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif +/* S_ERR_ND_* are libnetdissect status */ -#include +typedef enum { + S_SUCCESS = 0, /* not a libnetdissect status */ + S_ERR_HOST_PROGRAM = 1, /* not a libnetdissect status */ + S_ERR_ND_NO_PRINTER = 11, + S_ERR_ND_MEM_ALLOC = 12, + S_ERR_ND_OPEN_FILE = 13, + S_ERR_ND_WRITE_FILE = 14, + S_ERR_ND_ESP_SECRET = 15 +} status_exit_codes_t; -#include -#include - -#include "netdissect.h" -#include "extract.h" - -void -ftp_print(netdissect_options *ndo, const u_char *pptr, u_int len) -{ - txtproto_print(ndo, pptr, len, "ftp", NULL, 0); -} +#endif /* status_exit_codes_h */ diff --git a/contrib/tcpdump/strtoaddr.c b/contrib/tcpdump/strtoaddr.c index 81a041f24b..c6f79d9a6e 100644 --- a/contrib/tcpdump/strtoaddr.c +++ b/contrib/tcpdump/strtoaddr.c @@ -16,13 +16,15 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include #include +#include "netdissect-ctype.h" + #include "strtoaddr.h" #ifndef NS_INADDRSZ @@ -42,10 +44,6 @@ * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. */ -#ifndef NS_IN6ADDRSZ -#define NS_IN6ADDRSZ 16 /* IPv6 T_AAAA */ -#endif - /* int * strtoaddr(src, dst) * convert presentation level IPv4 address to network order binary form. @@ -73,21 +71,19 @@ strtoaddr(const char *src, void *dst) * Values are specified as for C: * 0x=hex, 0=octal, isdigit=decimal. */ - if (!isdigit(c)) + if (!ND_ASCII_ISDIGIT(c)) return (0); val = 0; if (c == '0') { c = *++src; if (c == 'x' || c == 'X') return (0); - else if (isdigit(c) && c != '9') + else if (ND_ASCII_ISDIGIT(c) && c != '9') return (0); } for (;;) { - if (isdigit(c)) { + if (ND_ASCII_ISDIGIT(c)) { digit = c - '0'; - if (digit >= 10) - break; val = (val * 10) + digit; c = *++src; } else @@ -111,7 +107,7 @@ strtoaddr(const char *src, void *dst) /* * Check for trailing characters. */ - if (c != '\0' && !isspace(c)) + if (c != '\0' && c != ' ' && c != '\t') return (0); /* * Find the number of parts specified. diff --git a/contrib/tcpdump/tcp.h b/contrib/tcpdump/tcp.h index 912b5e820c..491157b0ae 100644 --- a/contrib/tcpdump/tcp.h +++ b/contrib/tcpdump/tcp.h @@ -33,24 +33,23 @@ * @(#)tcp.h 8.1 (Berkeley) 6/10/93 */ -typedef uint32_t tcp_seq; /* * TCP header. * Per RFC 793, September, 1981. */ struct tcphdr { - uint16_t th_sport; /* source port */ - uint16_t th_dport; /* destination port */ - tcp_seq th_seq; /* sequence number */ - tcp_seq th_ack; /* acknowledgement number */ - uint8_t th_offx2; /* data offset, rsvd */ - uint8_t th_flags; - uint16_t th_win; /* window */ - uint16_t th_sum; /* checksum */ - uint16_t th_urp; /* urgent pointer */ -} UNALIGNED; + nd_uint16_t th_sport; /* source port */ + nd_uint16_t th_dport; /* destination port */ + nd_uint32_t th_seq; /* sequence number */ + nd_uint32_t th_ack; /* acknowledgement number */ + nd_uint8_t th_offx2; /* data offset, rsvd */ + nd_uint8_t th_flags; + nd_uint16_t th_win; /* window */ + nd_uint16_t th_sum; /* checksum */ + nd_uint16_t th_urp; /* urgent pointer */ +}; -#define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4) +#define TH_OFF(th) ((GET_U_1((th)->th_offx2) & 0xf0) >> 4) /* TCP flags */ #define TH_FIN 0x01 @@ -104,15 +103,15 @@ struct tcphdr { #ifndef SMTP_PORT #define SMTP_PORT 25 #endif +#ifndef WHOIS_PORT +#define WHOIS_PORT 43 +#endif #ifndef NAMESERVER_PORT #define NAMESERVER_PORT 53 #endif #ifndef HTTP_PORT #define HTTP_PORT 80 #endif -#ifndef NETBIOS_NS_PORT -#define NETBIOS_NS_PORT 137 /* RFC 1001, RFC 1002 */ -#endif #ifndef NETBIOS_SSN_PORT #define NETBIOS_SSN_PORT 139 /* RFC 1001, RFC 1002 */ #endif diff --git a/contrib/tcpdump/tcpdump.1.in b/contrib/tcpdump/tcpdump.1.in index 5a2b1e2c51..355216d68d 100644 --- a/contrib/tcpdump/tcpdump.1.in +++ b/contrib/tcpdump/tcpdump.1.in @@ -20,7 +20,7 @@ .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. .\" -.TH TCPDUMP 1 "2 February 2017" +.TH TCPDUMP 1 "21 December 2020" .SH NAME tcpdump \- dump traffic on a network .SH SYNOPSIS @@ -38,24 +38,35 @@ tcpdump \- dump traffic on a network .B \-c .I count ] -.br -.ti +8 +[ +.B \-\-count +] [ .B \-C .I file_size -] [ -.B \-G -.I rotate_seconds -] [ +] +.ti +8 +[ +.B \-E +.I spi@ipaddr algo:secret,... +] +.ti +8 +[ .B \-F .I file ] -.br -.ti +8 +[ +.B \-G +.I rotate_seconds +] [ .B \-i .I interface ] +.ti +8 +[ +.B \-\-immediate\-mode +] [ .B \-j .I tstamp_type @@ -64,16 +75,18 @@ tcpdump \- dump traffic on a network .B \-m .I module ] +.ti +8 [ .B \-M .I secret ] -.br -.ti +8 [ .B \-\-number ] [ +.B \-\-print +] +[ .B \-Q .I in|out|inout ] @@ -83,10 +96,6 @@ tcpdump \- dump traffic on a network .I file ] [ -.B \-V -.I file -] -[ .B \-s .I snaplen ] @@ -95,27 +104,26 @@ tcpdump \- dump traffic on a network .I type ] [ +.B \-\-version +] +.ti +8 +[ +.B \-V +.I file +] +[ .B \-w .I file ] -.br -.ti +8 [ .B \-W .I filecount ] -.br -.ti +8 -[ -.B \-E -.I spi@ipaddr algo:secret,... -] -.br -.ti +8 [ .B \-y .I datalinktype ] +.ti +8 [ .B \-z .I postrotate-command @@ -130,10 +138,10 @@ tcpdump \- dump traffic on a network ] .ti +8 [ -.B \-\-immediate\-mode +.BI \-\-micro ] [ -.B \-\-version +.BI \-\-nano ] .ti +8 [ @@ -144,7 +152,7 @@ tcpdump \- dump traffic on a network .SH DESCRIPTION .LP \fITcpdump\fP prints out a description of the contents of packets on a -network interface that match the boolean \fIexpression\fP; the +network interface that match the Boolean \fIexpression\fP; the description is preceded by a time stamp, printed, by default, as hours, minutes, seconds, and fractions of a second since midnight. It can also be run with the @@ -204,19 +212,23 @@ is running, if the OS reports that information to applications; if not, it will be reported as 0). .LP On platforms that support the SIGINFO signal, such as most BSDs -(including Mac OS X) and Digital/Tru64 UNIX, it will report those counts +(including macOS) and Digital/Tru64 UNIX, it will report those counts when it receives a SIGINFO signal (generated, for example, by typing your ``status'' character, typically control-T, although on some -platforms, such as Mac OS X, the ``status'' character is not set by +platforms, such as macOS, the ``status'' character is not set by default, so you must set it with .BR stty (1) in order to use it) and will continue capturing packets. On platforms that do not support the SIGINFO signal, the same can be achieved by using the SIGUSR1 signal. .LP +Using the SIGUSR2 signal along with the +.B \-w +flag will forcibly flush the packet buffer into the output file. +.LP Reading packets from a network interface may require that you have special privileges; see the -.B pcap (3PCAP) +.BR pcap (3PCAP) man page for details. Reading a saved packet file doesn't require special privileges. .SH OPTIONS @@ -240,6 +252,12 @@ units of KiB (1024 bytes). .BI \-c " count" Exit after receiving \fIcount\fP packets. .TP +.BI \-\-count +Print only on stderr the packet count when reading capture file(s) instead +of parsing/printing the packets. If a filter is specified on the command +line, \fItcpdump\fP counts only packets that were matched by the filter +expression. +.TP .BI \-C " file_size" Before writing a raw packet to a savefile, check whether the file is currently larger than \fIfile_size\fP and, if so, close the current @@ -253,6 +271,33 @@ not 1,048,576 bytes). .B \-d Dump the compiled packet-matching code in a human readable form to standard output and stop. +.IP +Please mind that although code compilation is always DLT-specific, +typically it is impossible (and unnecessary) to specify which DLT to use +for the dump because \fItcpdump\fP uses either the DLT of the input pcap +file specified with +.BR -r , +or the default DLT of the network interface specified with +.BR -i , +or the particular DLT of the network interface specified with +.B -y +and +.B -i +respectively. In these cases the dump shows the same exact code that +would filter the input file or the network interface without +.BR -d . +.IP +However, when neither +.B -r +nor +.B -i +is specified, specifying +.B -d +prevents \fItcpdump\fP from guessing a suitable network interface (see +.BR -i ). +In this case the DLT defaults to EN10MB and can be set to another valid +value manually with +.BR -y . .TP .B \-dd Dump packet-matching code as a @@ -272,7 +317,7 @@ which .I tcpdump can capture packets. For each network interface, a number and an interface name, possibly followed by a text description of the -interface, is printed. The interface name or the number can be supplied +interface, are printed. The interface name or the number can be supplied to the .B \-i flag to specify an interface on which to capture. @@ -290,7 +335,7 @@ flag will not be supported if was built with an older version of .I libpcap that lacks the -.B pcap_findalldevs() +.BR pcap_findalldevs(3PCAP) function. .TP .B \-e @@ -359,6 +404,9 @@ Savefiles will have the name specified by which should include a time format as defined by .BR strftime (3). If no time format is specified, each new file will overwrite the previous. +Whenever a generated filename is not unique, tcpdump will overwrite the +pre-existing data; providing a time specification that is coarser than the +capture period is therefore not advised. .IP If used in conjunction with the .B \-C @@ -384,10 +432,13 @@ Attempt to detect 802.11s draft mesh headers. .TP .BI \-\-interface= interface .PD -Listen on \fIinterface\fP. -If unspecified, \fItcpdump\fP searches the system interface list for the -lowest numbered, configured up interface (excluding loopback), which may turn -out to be, for example, ``eth0''. +Listen, report the list of link-layer types, report the list of time +stamp types, or report the results of compiling a filter expression on +\fIinterface\fP. If unspecified and if the +.B -d +flag is not given, \fItcpdump\fP searches the system +interface list for the lowest numbered, configured up interface +(excluding loopback), which may turn out to be, for example, ``eth0''. .IP On Linux systems with 2.2 or later kernels, an .I interface @@ -463,16 +514,29 @@ accuracy to a savefile, the time stamps are written with nanosecond resolution, and the file is written with a different magic number, to indicate that the time stamps are in seconds and nanoseconds; not all programs that read pcap savefiles will be able to read those captures. -.LP +.IP When reading a savefile, convert time stamps to the precision specified by \fItimestamp_precision\fP, and display them with that resolution. If the precision specified is less than the precision of time stamps in the file, the conversion will lose precision. -.LP +.IP The supported values for \fItimestamp_precision\fP are \fBmicro\fP for microsecond resolution and \fBnano\fP for nanosecond resolution. The default is microsecond resolution. .TP +.B \-\-micro +.PD 0 +.TP +.B \-\-nano +.PD +Shorthands for \fB\-\-time\-stamp\-precision=micro\fP or +\fB\-\-time\-stamp\-precision=nano\fP, adjusting the time stamp +precision accordingly. When reading packets from a savefile, using +\fB\-\-micro\fP truncates time stamps if the savefile was created with +nanosecond precision. In contrast, a savefile created with microsecond +precision will have trailing zeroes added to the time stamp when +\fB\-\-nano\fP is used. +.TP .B \-K .PD 0 .TP @@ -579,6 +643,12 @@ Note that the interface might be in promiscuous mode for some other reason; hence, `-p' cannot be used as an abbreviation for `ether host {local-hw-addr} or ether broadcast'. .TP +.BI \-\-print +Print parsed packet output, even if the raw packets are being saved to a +file with the +.B \-w +flag. +.TP .BI \-Q " direction" .PD 0 .TP @@ -596,7 +666,7 @@ lines are shorter. .BI \-r " file" Read packets from \fIfile\fR (which was created with the .B \-w -option or by other tools that write pcap or pcap-ng files). +option or by other tools that write pcap or pcapng files). Standard input is used if \fIfile\fR is ``-''. .TP .B \-S @@ -616,14 +686,21 @@ default of 262144 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. +.IP Note that taking larger snapshots both increases the amount of time it takes to process packets and, effectively, decreases the amount of packet buffering. This may cause packets to be lost. -You should limit \fIsnaplen\fP to the smallest number that will -capture the protocol information you're interested in. -Setting +Note also that taking smaller snapshots will discard data from protocols +above the transport layer, which loses information that may be +important. NFS and AFS requests and replies, for example, are very +large, and much of the detail won't be available if a too-short snapshot +length is selected. +.IP +If you need to reduce the snapshot size below the default, you should +limit \fIsnaplen\fP to the smallest number that will capture the +protocol information you're interested in. Setting \fIsnaplen\fP to 0 sets it to the default of 262144, for backwards compatibility with recent older versions of .IR tcpdump . @@ -635,21 +712,24 @@ Currently known types are \fBaodv\fR (Ad-hoc On-demand Distance Vector protocol), \fBcarp\fR (Common Address Redundancy Protocol), \fBcnfp\fR (Cisco NetFlow protocol), +\fBdomain\fR (Domain Name System), \fBlmp\fR (Link Management Protocol), \fBpgm\fR (Pragmatic General Multicast), \fBpgm_zmtp1\fR (ZMTP/1.0 inside PGM/EPGM), -\fBresp\fR (REdis Serialization Protocol), +\fBptp\fR (Precision Time Protocol), \fBradius\fR (RADIUS), +\fBresp\fR (REdis Serialization Protocol), \fBrpc\fR (Remote Procedure Call), -\fBrtp\fR (Real-Time Applications protocol), \fBrtcp\fR (Real-Time Applications control protocol), +\fBrtp\fR (Real-Time Applications protocol), \fBsnmp\fR (Simple Network Management Protocol), +\fBsomeip\fR (SOME/IP), \fBtftp\fR (Trivial File Transfer Protocol), \fBvat\fR (Visual Audio Tool), -\fBwb\fR (distributed White Board), -\fBzmtp1\fR (ZeroMQ Message Transport Protocol 1.0) +\fBvxlan\fR (Virtual eXtensible Local Area Network), +\fBwb\fR (distributed White Board) and -\fBvxlan\fR (Virtual eXtensible Local Area Network). +\fBzmtp1\fR (ZeroMQ Message Transport Protocol 1.0). .IP Note that the \fBpgm\fR type above affects UDP interpretation only, the native PGM is always recognised as IP protocol 113 regardless. UDP-encapsulated PGM is @@ -669,16 +749,20 @@ Print the timestamp, as seconds since January 1, 1970, 00:00:00, UTC, and fractions of a second since that time, on each dump line. .TP .B \-ttt -Print a delta (micro-second resolution) between current and previous line -on each dump line. +Print a delta (microsecond or nanosecond resolution depending on the +.B \-\-time\-stamp-precision +option) between current and previous line on each dump line. +The default is microsecond resolution. .TP .B \-tttt Print a timestamp, as hours, minutes, seconds, and fractions of a second since midnight, preceded by the date, on each dump line. .TP .B \-ttttt -Print a delta (micro-second resolution) between current and first line -on each dump line. +Print a delta (microsecond or nanosecond resolution depending on the +.B \-\-time\-stamp-precision +option) between current and first line on each dump line. +The default is microsecond resolution. .TP .B \-u Print undecoded NFS handles. @@ -690,7 +774,9 @@ Print undecoded NFS handles. .PD If the .B \-w -option is not specified, make the printed packet output +option is not specified, or if it is specified but the +.B \-\-print +flag is also specified, make the printed packet output ``packet-buffered''; i.e., as the description of the contents of each packet is printed, it will be written to the standard output, rather than, when not writing to a terminal, being written only when the output @@ -710,7 +796,7 @@ flag will not be supported if was built with an older version of .I libpcap that lacks the -.B pcap_dump_flush() +.BR pcap_dump_flush(3PCAP) function. .TP .B \-v @@ -722,7 +808,12 @@ IP and ICMP header checksum. .IP When writing to a file with the .B \-w -option, report, every 10 seconds, the number of packets captured. +option and at the same time not reading from a file with the +.B \-r +option, report to stderr, once per second, the number of packets captured. In +Solaris, FreeBSD and possibly other operating systems this periodic update +currently can cause loss of captured packets on their way from the kernel to +tcpdump. .TP .B \-vv Even more verbose output. @@ -767,7 +858,7 @@ See .BR pcap-savefile (@MAN_FILE_FORMATS@) for a description of the file format. .TP -.B \-W +.BI \-W " filecount" Used in conjunction with the .B \-C option, this will limit the number @@ -780,9 +871,15 @@ files, allowing them to sort correctly. Used in conjunction with the .B \-G option, this will limit the number of rotated dump files that get -created, exiting with status 0 when reaching the limit. If used with +created, exiting with status 0 when reaching the limit. +.IP +If used in conjunction with both .B \-C -as well, the behavior will result in cyclical files per timeslice. +and +.B \-G, +the +.B \-W +option will currently be ignored, and will only affect the file name. .TP .B \-x When parsing and printing, @@ -794,6 +891,9 @@ bytes will be printed. Note that this is the entire link-layer packet, so for link layers that pad (e.g. Ethernet), the padding bytes will also be printed when the higher layer packet is shorter than the required padding. +In the current implementation this flag may have the same effect as +.B \-xx +if the packet is truncated. .TP .B \-xx When parsing and printing, @@ -807,6 +907,9 @@ When parsing and printing, in addition to printing the headers of each packet, print the data of each packet (minus its link level header) in hex and ASCII. This is very handy for analysing new protocols. +In the current implementation this flag may have the same effect as +.B \-XX +if the packet is truncated. .TP .B \-XX When parsing and printing, @@ -820,7 +923,11 @@ its link level header, in hex and ASCII. .TP .BI \-\-linktype= datalinktype .PD -Set the data link type to use while capturing packets to \fIdatalinktype\fP. +Set the data link type to use while capturing packets (see +.BR -L ) +or just compiling and dumping packet-matching code (see +.BR -d ) +to \fIdatalinktype\fP. .TP .BI \-z " postrotate-command" Used in conjunction with the @@ -939,6 +1046,16 @@ tcpdump 'tcp[tcpflags] & (tcp-syn|tcp-fin) != 0 and not src and dst net \fIlocal .fi .RE .LP +To print the TCP packets with flags RST and ACK both set. +(i.e. select only the RST and ACK flags in the flags field, and if the result +is "RST and ACK both set", match) +.RS +.nf +.B +tcpdump 'tcp[tcpflags] & (tcp-rst|tcp-ack) == (tcp-rst|tcp-ack)' +.fi +.RE +.LP To print all IPv4 HTTP packets to and from port 80, i.e. print only packets that contain data, not, for example, SYN and FIN packets and ACK-only packets. (IPv6 is left as an exercise for the reader.) @@ -1073,7 +1190,7 @@ data and 6 bytes of compressed header: .HD ARP/RARP Packets .LP -Arp/rarp output shows the type of request and its arguments. +ARP/RARP output shows the type of request and its arguments. The format is intended to be self explanatory. Here is a short sample taken from the start of an `rlogin' from @@ -1086,7 +1203,7 @@ arp reply csam is-at CSAM\fR .sp .5 .fi .RE -The first line says that rtsg sent an arp packet asking +The first line says that rtsg sent an ARP packet asking for the Ethernet address of internet host csam. Csam replies with its Ethernet address (in this example, Ethernet addresses @@ -1139,7 +1256,7 @@ those are reported as \fBECT(1)\fP, \fBECT(0)\fP, or \fBCE\fP. \fIoffset\fP is the fragment offset field; it is printed whether this is part of a fragmented datagram or not. \fIflags\fP are the MF and DF flags; \fB+\fP is reported if MF is set, -and \fBDF\P is reported if F is set. If neither are set, \fB.\fP is +and \fBDF\fP is reported if F is set. If neither are set, \fB.\fP is reported. \fIproto\fP is the protocol ID field. \fIlength\fP is the total length field. @@ -1200,7 +1317,7 @@ host \fIcsam\fP. .RS .nf .sp .5 -\s-2\f(CWIP rtsg.1023 > csam.login: Flags [S], seq 768512:768512, win 4096, opts [mss 1024] +\f(CWIP rtsg.1023 > csam.login: Flags [S], seq 768512:768512, win 4096, opts [mss 1024] IP csam.login > rtsg.1023: Flags [S.], seq, 947648:947648, ack 768513, win 4096, opts [mss 1024] IP rtsg.1023 > csam.login: Flags [.], ack 1, win 4096 IP rtsg.1023 > csam.login: Flags [P.], seq 1:2, ack 1, win 4096, length 1 @@ -1208,7 +1325,7 @@ IP csam.login > rtsg.1023: Flags [.], ack 2, win 4096 IP rtsg.1023 > csam.login: Flags [P.], seq 2:21, ack 1, win 4096, length 19 IP csam.login > rtsg.1023: Flags [P.], seq 1:2, ack 21, win 4077, length 1 IP csam.login > rtsg.1023: Flags [P.], seq 2:3, ack 21, win 4077, urg 1, length 1 -IP csam.login > rtsg.1023: Flags [P.], seq 3:4, ack 21, win 4077, urg 1, length 1\fR\s+2 +IP csam.login > rtsg.1023: Flags [P.], seq 3:4, ack 21, win 4077, urg 1, length 1\fR .sp .5 .fi .RE @@ -1219,17 +1336,17 @@ The \fBS\fP indicates that the \fISYN\fP flag was set. The packet sequence number was 768512 and it contained no data. (The notation is `first:last' which means `sequence numbers \fIfirst\fP -up to but not including \fIlast\fP.) -There was no piggy-backed ack, the available receive window was 4096 -bytes and there was a max-segment-size option requesting an mss of +up to but not including \fIlast\fP'.) +There was no piggy-backed ACK, the available receive window was 4096 +bytes and there was a max-segment-size option requesting an MSS of 1024 bytes. .LP Csam replies with a similar packet except it includes a piggy-backed -ack for rtsg's SYN. -Rtsg then acks csam's SYN. +ACK for rtsg's SYN. +Rtsg then ACKs csam's SYN. The `.' means the ACK flag was set. The packet contained no data so there is no data sequence number or length. -Note that the ack sequence +Note that the ACK sequence number is a small integer (1). The first time \fItcpdump\fP sees a TCP `conversation', it prints the sequence number from the packet. @@ -1458,7 +1575,7 @@ 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. +tcp-push, tcp-ack, tcp-urg. .PP This can be demonstrated as: .RS @@ -1481,7 +1598,7 @@ UDP format is illustrated by this rwho packet: .sp .5 .fi .RE -This says that port \fIwho\fP on host \fIactinide\fP sent a udp +This says that port \fIwho\fP on host \fIactinide\fP sent a UDP datagram to port \fIwho\fP on host \fIbroadcast\fP, the Internet broadcast address. The packet contained 84 bytes of user data. @@ -1491,13 +1608,13 @@ port number) and the higher level protocol information printed. In particular, Domain Name service requests (RFC-1034/1035) and Sun RPC calls (RFC-1050) to NFS. .HD -UDP Name Server Requests +TCP or UDP Name Server Requests .LP \fI(N.B.:The following description assumes familiarity with the Domain Service protocol described in RFC-1035. If you are not familiar with the protocol, the following description will appear to be written -in greek.)\fP +in Greek.)\fP .LP Name server requests are formatted as .RS @@ -1514,7 +1631,7 @@ address record (qtype=A) associated with the name \fIucbvax.berkeley.edu.\fP The query id was `3'. The `+' indicates the \fIrecursion desired\fP flag was set. -The query length was 37 bytes, not including the UDP and +The query length was 37 bytes, excluding the TCP or UDP and IP protocol headers. The query operation was the normal one, \fIQuery\fP, so the op field was omitted. @@ -1538,7 +1655,7 @@ If any of the response bits are set (AA, RA or rcode) or any of the `must be zero' bits are set in bytes two and three, `[b2&3=\fIx\fP]' is printed, where \fIx\fP is the hex value of header bytes two and three. .HD -UDP Name Server Responses +TCP or UDP Name Server Responses .LP Name server responses are formatted as .RS @@ -1556,7 +1673,7 @@ with 3 answer records, 3 name server records and 7 additional records. The first answer record is type A (address) and its data is internet address 128.32.137.3. The total size of the response was 273 bytes, -excluding UDP and IP headers. +excluding TCP or UDP and IP headers. The op (Query) and response code (NoError) were omitted, as was the class (C_IN) of the A record. .LP @@ -1588,8 +1705,7 @@ may take up a page or more, so only use -v if you really want all the gory details. .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. +\%https://download.samba.org/pub/samba/specs/ and other online resources. The SMB patches were written by Andrew Tridgell (tridge@samba.org). .HD @@ -1665,15 +1781,10 @@ printed, depending on the filter expression used). Because the \-v flag is given, some of the file attributes (which are returned in addition to the file data) are printed: the file type (``REG'', for regular file), -the file mode (in octal), the uid and gid, and the file size. +the file mode (in octal), the UID and GID, and the file size. .LP If the \-v flag is given more than once, even more details are printed. .LP -Note that NFS requests are very large and much of the detail won't be printed -unless \fIsnaplen\fP is increased. -Try using `\fB\-s 192\fP' to watch -NFS traffic. -.LP NFS reply packets do not explicitly identify the RPC operation. Instead, \fItcpdump\fP keeps track of ``recent'' requests, and matches them to the @@ -1737,11 +1848,6 @@ Error codes are printed for abort packets, with the exception of Ubik beacon packets (because abort packets are used to signify a yes vote for the Ubik protocol). .LP -Note that AFS requests are very large and many of the arguments won't -be printed unless \fIsnaplen\fP is increased. -Try using `\fB-s 256\fP' -to watch AFS traffic. -.LP AFS reply packets do not explicitly identify the RPC operation. Instead, \fItcpdump\fP keeps track of ``recent'' requests, and matches them to the @@ -1819,9 +1925,9 @@ protocol) and packet size. .RS .nf .sp .5 -\s-2\f(CWicsd-net.112.220 > jssmag.2: nbp-lkup 190: "=:LaserWriter@*" +\f(CWicsd-net.112.220 > jssmag.2: nbp-lkup 190: "=:LaserWriter@*" jssmag.209.2 > icsd-net.112.220: nbp-reply 190: "RM1140:LaserWriter@*" 250 -techpit.2 > icsd-net.112.220: nbp-reply 190: "techpit:LaserWriter@*" 186\fR\s+2 +techpit.2 > icsd-net.112.220: nbp-reply 190: "techpit:LaserWriter@*" 186\fR .sp .5 .fi .RE @@ -1839,7 +1945,7 @@ another reply to the same request saying host techpit has laserwriter .RS .nf .sp .5 -\s-2\f(CWjssmag.209.165 > helios.132: atp-req 12266<0-7> 0xae030001 +\f(CWjssmag.209.165 > helios.132: atp-req 12266<0-7> 0xae030001 helios.132 > jssmag.209.165: atp-resp 12266:0 (512) 0xae040000 helios.132 > jssmag.209.165: atp-resp 12266:1 (512) 0xae040000 helios.132 > jssmag.209.165: atp-resp 12266:2 (512) 0xae040000 @@ -1852,7 +1958,7 @@ jssmag.209.165 > helios.132: atp-req 12266<3,5> 0xae030001 helios.132 > jssmag.209.165: atp-resp 12266:3 (512) 0xae040000 helios.132 > jssmag.209.165: atp-resp 12266:5 (512) 0xae040000 jssmag.209.165 > helios.132: atp-rel 12266<0-7> 0xae030001 -jssmag.209.133 > helios.132: atp-req* 12267<0-7> 0xae030002\fR\s+2 +jssmag.209.133 > helios.132: atp-req* 12267<0-7> 0xae030002\fR .sp .5 .fi .RE @@ -1865,7 +1971,7 @@ Helios responds with 8 512-byte packets. The `:digit' following the transaction id gives the packet sequence number in the transaction and the number in parens is the amount of data in the packet, -excluding the atp header. +excluding the ATP header. The `*' on packet 7 indicates that the EOM bit was set. .LP @@ -1878,11 +1984,18 @@ The `*' on the request indicates that XO (`exactly once') was \fInot\fP set. .SH "SEE ALSO" -stty(1), pcap(3PCAP), bpf(4), nit(4P), \%pcap-savefile(@MAN_FILE_FORMATS@), -\%pcap-filter(@MAN_MISC_INFO@), \%pcap-tstamp(@MAN_MISC_INFO@) +.BR stty (1), +.BR pcap (3PCAP), +.BR bpf (4), +.BR nit (4P), +.BR \%pcap-savefile (@MAN_FILE_FORMATS@), +.BR \%pcap-filter (@MAN_MISC_INFO@), +.BR \%pcap-tstamp (@MAN_MISC_INFO@) .LP .RS -.I http://www.iana.org/assignments/media-types/application/vnd.tcpdump.pcap +.na +.I https://www.iana.org/assignments/media-types/application/vnd.tcpdump.pcap +.ad .RE .LP .SH AUTHORS @@ -1895,7 +2008,7 @@ Lawrence Berkeley National Laboratory, University of California, Berkeley, CA. .LP It is currently being maintained by tcpdump.org. .LP -The current version is available via http: +The current version is available via HTTPS: .LP .RS .I https://www.tcpdump.org/ @@ -1908,12 +2021,12 @@ The original distribution is available via anonymous ftp: .RE .LP IPv6/IPsec support is added by WIDE/KAME project. -This program uses Eric Young's SSLeay library, under specific configurations. +This program uses OpenSSL/LibreSSL, under specific configurations. .SH BUGS To report a security issue please send an e-mail to \%security@tcpdump.org. .LP To report bugs and other problems, contribute patches, request a -feature, provide generic feedback etc please see the file +feature, provide generic feedback etc. please see the file .I CONTRIBUTING in the tcpdump source tree root. .LP @@ -1929,7 +2042,7 @@ be copied from the kernel in order to be filtered in user mode; .IP all of a packet, not just the part that's within the snapshot length, will be copied from the kernel (the 2.0[.x] packet capture mechanism, if -asked to copy only part of a packet to userland, will not report the +asked to copy only part of a packet to userspace, will not report the true length of the packet; this would cause most IP packets to get an error from .BR tcpdump ); diff --git a/contrib/tcpdump/tcpdump.c b/contrib/tcpdump/tcpdump.c index 043bda1d7a..6476a3d484 100644 --- a/contrib/tcpdump/tcpdump.c +++ b/contrib/tcpdump/tcpdump.c @@ -25,12 +25,6 @@ * Seth Webster */ -#ifndef lint -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"; -#endif - /* * tcpdump - dump traffic on a network * @@ -40,13 +34,14 @@ The Regents of the University of California. All rights reserved.\n"; */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif /* - * Mac OS X may ship pcap.h from libpcap 0.6 with a libpcap based on - * 0.8. That means it has pcap_findalldevs() but the header doesn't - * define pcap_if_t, meaning that we can't actually *use* pcap_findalldevs(). + * Some older versions of Mac OS X may ship pcap.h from libpcap 0.6 with a + * libpcap based on 0.8. That means it has pcap_findalldevs() but the + * header doesn't define pcap_if_t, meaning that we can't actually *use* + * pcap_findalldevs(). */ #ifdef HAVE_PCAP_FINDALLDEVS #ifndef HAVE_PCAP_IF_T @@ -54,7 +49,17 @@ The Regents of the University of California. All rights reserved.\n"; #endif #endif -#include +#include "netdissect-stdinc.h" + +/* + * This must appear after including netdissect-stdinc.h, so that _U_ is + * defined. + */ +#ifndef lint +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"; +#endif #include @@ -69,18 +74,39 @@ The Regents of the University of California. All rights reserved.\n"; #ifdef HAVE_GETOPT_LONG #include #else -#include "getopt_long.h" +#include "missing/getopt_long.h" #endif /* Capsicum-specific code requires macros from , which will fail * to compile if has already been included; including the headers * in the opposite order works fine. */ #ifdef HAVE_CAPSICUM -#include +#include #include #include #include +#ifdef HAVE_CASPER +#include +#include +#include +#endif /* HAVE_CASPER */ #endif /* HAVE_CAPSICUM */ +#ifdef HAVE_PCAP_OPEN +/* + * We found pcap_open() in the capture library, so we'll be using + * the remote capture APIs; define PCAP_REMOTE before we include pcap.h, + * so we get those APIs declared, and the types and #defines that they + * use defined. + * + * WinPcap's headers require that PCAP_REMOTE be defined in order to get + * remote-capture APIs declared and types and #defines that they use + * defined. + * + * (Versions of libpcap with those APIs, and thus Npcap, which is based on + * those versions of libpcap, don't require it.) + */ +#define HAVE_REMOTE +#endif #include #include #include @@ -88,13 +114,26 @@ The Regents of the University of California. All rights reserved.\n"; #include #include #include -#ifndef _WIN32 +#ifdef _WIN32 +#include +#else +#include #include #include #include #include #endif /* _WIN32 */ +/* + * Pathname separator. + * Use this in pathnames, but do *not* use it in URLs. + */ +#ifdef _WIN32 +#define PATH_SEPARATOR '\\' +#else +#define PATH_SEPARATOR '/' +#endif + /* capabilities convenience library */ /* If a code depends on HAVE_LIBCAP_NG, it depends also on HAVE_CAP_NG_H. * If HAVE_CAP_NG_H is not defined, undefine HAVE_LIBCAP_NG. @@ -108,31 +147,52 @@ The Regents of the University of California. All rights reserved.\n"; #endif /* HAVE_CAP_NG_H */ #endif /* HAVE_LIBCAP_NG */ +#ifdef __FreeBSD__ +#include +#endif /* __FreeBSD__ */ + +#include "netdissect-stdinc.h" #include "netdissect.h" #include "interface.h" #include "addrtoname.h" #include "machdep.h" -#include "setsignal.h" -#include "gmt2local.h" #include "pcap-missing.h" #include "ascii_strcasecmp.h" #include "print.h" +#include "fptype.h" + #ifndef PATH_MAX #define PATH_MAX 1024 #endif -#ifdef SIGINFO +#if defined(SIGINFO) #define SIGNAL_REQ_INFO SIGINFO -#elif SIGUSR1 +#elif defined(SIGUSR1) #define SIGNAL_REQ_INFO SIGUSR1 #endif +#if defined(HAVE_PCAP_DUMP_FLUSH) && defined(SIGUSR2) +#define SIGNAL_FLUSH_PCAP SIGUSR2 +#endif + +#if defined(HAVE_PCAP_CREATE) || defined(_WIN32) static int Bflag; /* buffer size */ +#endif +#ifdef HAVE_PCAP_DUMP_FTELL64 +static int64_t Cflag; /* rotate dump files after this many bytes */ +#else static long Cflag; /* rotate dump files after this many bytes */ +#endif static int Cflag_count; /* Keep track of which file number we're writing */ +#ifdef HAVE_PCAP_FINDALLDEVS static int Dflag; /* list available devices and exit */ +#endif +#ifdef HAVE_PCAP_FINDALLDEVS_EX +static char *remote_interfaces_source; /* list available devices from this source and exit */ +#endif + /* * This is exported because, in some versions of libpcap, if libpcap * is built with optimizer debugging code (which is *NOT* the default @@ -145,6 +205,7 @@ static int Dflag; /* list available devices and exit */ * dflag but, instead, *if* built with optimizer debugging code, * *export* a routine to set that flag. */ +extern int dflag; int dflag; /* print filter code */ static int Gflag; /* rotate dump files after this many seconds */ static int Gflag_count; /* number of files created with Gflag rotation */ @@ -153,35 +214,52 @@ static int Lflag; /* list available data link types and exit */ static int Iflag; /* rfmon (monitor) mode */ #ifdef HAVE_PCAP_SET_TSTAMP_TYPE static int Jflag; /* list available time stamp types */ -#endif static int jflag = -1; /* packet time stamp source */ +#endif +static int lflag; /* line-buffered output */ static int pflag; /* don't go promiscuous */ #ifdef HAVE_PCAP_SETDIRECTION static int Qflag = -1; /* restrict captured packet by send/receive direction */ #endif +#ifdef HAVE_PCAP_DUMP_FLUSH static int Uflag; /* "unbuffered" output of dump files */ +#endif static int Wflag; /* recycle output files after this number of files */ static int WflagChars; static char *zflag = NULL; /* compress each savefile using a specified command (like gzip or bzip2) */ +static int timeout = 1000; /* default timeout = 1000 ms = 1 s */ +#ifdef HAVE_PCAP_SET_IMMEDIATE_MODE static int immediate_mode; +#endif +static int count_mode; static int infodelay; static int infoprint; char *program_name; +#ifdef HAVE_CASPER +cap_channel_t *capdns; +#endif + /* Forwards */ -static void error(FORMAT_STRING(const char *), ...) NORETURN PRINTFLIKE(1, 2); +static NORETURN void error(FORMAT_STRING(const char *), ...) PRINTFLIKE(1, 2); static void warning(FORMAT_STRING(const char *), ...) PRINTFLIKE(1, 2); -static void exit_tcpdump(int) NORETURN; -static RETSIGTYPE cleanup(int); -static RETSIGTYPE child_cleanup(int); -static void print_version(void); -static void print_usage(void); -static void show_tstamp_types_and_exit(pcap_t *, const char *device) NORETURN; -static void show_dlts_and_exit(pcap_t *, const char *device) NORETURN; +static NORETURN void exit_tcpdump(int); +static void (*setsignal (int sig, void (*func)(int)))(int); +static void cleanup(int); +static void child_cleanup(int); +static void print_version(FILE *); +static void print_usage(FILE *); +#ifdef HAVE_PCAP_SET_TSTAMP_TYPE +static NORETURN void show_tstamp_types_and_exit(pcap_t *, const char *device); +#endif +static NORETURN void show_dlts_and_exit(pcap_t *, const char *device); #ifdef HAVE_PCAP_FINDALLDEVS -static void show_devices_and_exit (void) NORETURN; +static NORETURN void show_devices_and_exit(void); +#endif +#ifdef HAVE_PCAP_FINDALLDEVS_EX +static NORETURN void show_remote_devices_and_exit(void); #endif static void print_packet(u_char *, const struct pcap_pkthdr *, const u_char *); @@ -190,17 +268,20 @@ static void dump_packet(u_char *, const struct pcap_pkthdr *, const u_char *); static void droproot(const char *, const char *); #ifdef SIGNAL_REQ_INFO -RETSIGTYPE requestinfo(int); +static void requestinfo(int); #endif -#if defined(USE_WIN32_MM_TIMER) - #include - static UINT timer_id; - static void CALLBACK verbose_stats_dump(UINT, UINT, DWORD_PTR, DWORD_PTR, DWORD_PTR); -#elif defined(HAVE_ALARM) - static void verbose_stats_dump(int sig); +#ifdef SIGNAL_FLUSH_PCAP +static void flushpcap(int); #endif +#ifdef _WIN32 + static HANDLE timer_handle = INVALID_HANDLE_VALUE; + static void CALLBACK verbose_stats_dump(PVOID param, BOOLEAN timer_fired); +#else /* _WIN32 */ + static void verbose_stats_dump(int sig); +#endif /* _WIN32 */ + static void info(int); static u_int packets_captured; @@ -213,11 +294,15 @@ static const struct tok status_flags[] = { { PCAP_IF_RUNNING, "Running" }, #endif { PCAP_IF_LOOPBACK, "Loopback" }, +#ifdef PCAP_IF_WIRELESS + { PCAP_IF_WIRELESS, "Wireless" }, +#endif { 0, NULL } }; #endif static pcap_t *pd; +static pcap_dumper_t *pdd = NULL; static int supports_monitor_mode; @@ -229,7 +314,8 @@ struct dump_info { char *WFileName; char *CurrentFileName; pcap_t *pd; - pcap_dumper_t *p; + pcap_dumper_t *pdd; + netdissect_options *ndo; #ifdef HAVE_CAPSICUM int dirfd; #endif @@ -301,7 +387,7 @@ error(const char *fmt, ...) if (fmt[-1] != '\n') (void)fputc('\n', stderr); } - exit_tcpdump(1); + exit_tcpdump(S_ERR_HOST_PROGRAM); /* NOTREACHED */ } @@ -345,7 +431,7 @@ show_tstamp_types_and_exit(pcap_t *pc, const char *device) if (n_tstamp_types == 0) { fprintf(stderr, "Time stamp type cannot be set for %s\n", device); - exit_tcpdump(0); + exit_tcpdump(S_SUCCESS); } fprintf(stderr, "Time stamp types for %s (use option -j to set):\n", device); @@ -359,7 +445,7 @@ show_tstamp_types_and_exit(pcap_t *pc, const char *device) } } pcap_free_tstamp_types(tstamp_types); - exit_tcpdump(0); + exit_tcpdump(S_SUCCESS); } #endif @@ -412,12 +498,12 @@ show_dlts_and_exit(pcap_t *pc, const char *device) #ifdef HAVE_PCAP_FREE_DATALINKS pcap_free_datalinks(dlts); #endif - exit_tcpdump(0); + exit_tcpdump(S_SUCCESS); } #ifdef HAVE_PCAP_FINDALLDEVS static void -show_devices_and_exit (void) +show_devices_and_exit(void) { pcap_if_t *dev, *devlist; char ebuf[PCAP_ERRBUF_SIZE]; @@ -425,6 +511,72 @@ show_devices_and_exit (void) if (pcap_findalldevs(&devlist, ebuf) < 0) error("%s", ebuf); + for (i = 0, dev = devlist; dev != NULL; i++, dev = dev->next) { + printf("%d.%s", i+1, dev->name); + if (dev->description != NULL) + printf(" (%s)", dev->description); + if (dev->flags != 0) { + printf(" ["); + printf("%s", bittok2str(status_flags, "none", dev->flags)); +#ifdef PCAP_IF_WIRELESS + if (dev->flags & PCAP_IF_WIRELESS) { + switch (dev->flags & PCAP_IF_CONNECTION_STATUS) { + + case PCAP_IF_CONNECTION_STATUS_UNKNOWN: + printf(", Association status unknown"); + break; + + case PCAP_IF_CONNECTION_STATUS_CONNECTED: + printf(", Associated"); + break; + + case PCAP_IF_CONNECTION_STATUS_DISCONNECTED: + printf(", Not associated"); + break; + + case PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE: + break; + } + } else { + switch (dev->flags & PCAP_IF_CONNECTION_STATUS) { + + case PCAP_IF_CONNECTION_STATUS_UNKNOWN: + printf(", Connection status unknown"); + break; + + case PCAP_IF_CONNECTION_STATUS_CONNECTED: + printf(", Connected"); + break; + + case PCAP_IF_CONNECTION_STATUS_DISCONNECTED: + printf(", Disconnected"); + break; + + case PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE: + break; + } + } +#endif + printf("]"); + } + printf("\n"); + } + pcap_freealldevs(devlist); + exit_tcpdump(S_SUCCESS); +} +#endif /* HAVE_PCAP_FINDALLDEVS */ + +#ifdef HAVE_PCAP_FINDALLDEVS_EX +static void +show_remote_devices_and_exit(void) +{ + pcap_if_t *dev, *devlist; + char ebuf[PCAP_ERRBUF_SIZE]; + int i; + + if (pcap_findalldevs_ex(remote_interfaces_source, NULL, &devlist, + ebuf) < 0) + error("%s", ebuf); for (i = 0, dev = devlist; dev != NULL; i++, dev = dev->next) { printf("%d.%s", i+1, dev->name); if (dev->description != NULL) @@ -434,7 +586,7 @@ show_devices_and_exit (void) printf("\n"); } pcap_freealldevs(devlist); - exit_tcpdump(0); + exit_tcpdump(S_SUCCESS); } #endif /* HAVE_PCAP_FINDALLDEVS */ @@ -446,22 +598,22 @@ show_devices_and_exit (void) * only use them for the same purposes that the other versions of tcpdump * use them: * - * OS X tcpdump uses -g to force non--v output for IP to be on one + * macOS tcpdump uses -g to force non--v output for IP to be on one * line, making it more "g"repable; * - * OS X tcpdump uses -k to specify that packet comments in pcap-ng files + * macOS tcpdump uses -k to specify that packet comments in pcapng files * should be printed; * * OpenBSD tcpdump uses -o to indicate that OS fingerprinting should be done * for hosts sending TCP SYN packets; * - * OS X tcpdump uses -P to indicate that -w should write pcap-ng rather + * macOS tcpdump uses -P to indicate that -w should write pcapng rather * than pcap files. * - * OS X tcpdump also uses -Q to specify expressions that match packet + * macOS tcpdump also uses -Q to specify expressions that match packet * metadata, including but not limited to the packet direction. * The expression syntax is different from a simple "in|out|inout", - * and those expressions aren't accepted by OS X tcpdump, but the + * and those expressions aren't accepted by macOS tcpdump, but the * equivalents would be "in" = "dir=in", "out" = "dir=out", and * "inout" = "dir=in or dir=out", and the parser could conceivably * special-case "in", "out", and "inout" as expressions for backwards @@ -480,6 +632,12 @@ show_devices_and_exit (void) #define B_FLAG_USAGE #endif /* defined(HAVE_PCAP_CREATE) || defined(_WIN32) */ +#ifdef HAVE_PCAP_FINDALLDEVS +#define D_FLAG "D" +#else +#define D_FLAG +#endif + #ifdef HAVE_PCAP_CREATE #define I_FLAG "I" #else /* HAVE_PCAP_CREATE */ @@ -496,10 +654,16 @@ show_devices_and_exit (void) #define J_FLAG #endif /* PCAP_ERROR_TSTAMP_TYPE_NOTSUP */ -#ifdef HAVE_PCAP_FINDALLDEVS -#define D_FLAG "D" +#ifdef USE_LIBSMI +#define m_FLAG_USAGE "[ -m module ] ..." +#endif + +#ifdef HAVE_PCAP_SETDIRECTION +#define Q_FLAG "Q:" +#define Q_FLAG_USAGE " [ -Q in|out|inout ]" #else -#define D_FLAG +#define Q_FLAG +#define Q_FLAG_USAGE #endif #ifdef HAVE_PCAP_DUMP_FLUSH @@ -508,12 +672,6 @@ show_devices_and_exit (void) #define U_FLAG #endif -#ifdef HAVE_PCAP_SETDIRECTION -#define Q_FLAG "Q:" -#else -#define Q_FLAG -#endif - #define SHORTOPTS "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:G:hHi:" I_FLAG j_FLAG J_FLAG "KlLm:M:nNOpq" Q_FLAG "r:s:StT:u" U_FLAG "vV:w:W:xXy:Yz:Z:#" /* @@ -536,15 +694,24 @@ show_devices_and_exit (void) * component of the entry for the long option, and have a case for that * option in the switch statement. */ -#define OPTION_VERSION 128 -#define OPTION_TSTAMP_PRECISION 129 -#define OPTION_IMMEDIATE_MODE 130 +#define OPTION_VERSION 128 +#define OPTION_TSTAMP_PRECISION 129 +#define OPTION_IMMEDIATE_MODE 130 +#define OPTION_PRINT 131 +#define OPTION_LIST_REMOTE_INTERFACES 132 +#define OPTION_TSTAMP_MICRO 133 +#define OPTION_TSTAMP_NANO 134 +#define OPTION_FP_TYPE 135 +#define OPTION_COUNT 136 static const struct option longopts[] = { #if defined(HAVE_PCAP_CREATE) || defined(_WIN32) { "buffer-size", required_argument, NULL, 'B' }, #endif { "list-interfaces", no_argument, NULL, 'D' }, +#ifdef HAVE_PCAP_FINDALLDEVS_EX + { "list-remote-interfaces", required_argument, NULL, OPTION_LIST_REMOTE_INTERFACES }, +#endif { "help", no_argument, NULL, 'h' }, { "interface", required_argument, NULL, 'i' }, #ifdef HAVE_PCAP_CREATE @@ -555,6 +722,8 @@ static const struct option longopts[] = { { "list-time-stamp-types", no_argument, NULL, 'J' }, #endif #ifdef HAVE_PCAP_SET_TSTAMP_PRECISION + { "micro", no_argument, NULL, OPTION_TSTAMP_MICRO}, + { "nano", no_argument, NULL, OPTION_TSTAMP_NANO}, { "time-stamp-precision", required_argument, NULL, OPTION_TSTAMP_PRECISION}, #endif { "dont-verify-checksums", no_argument, NULL, 'K' }, @@ -577,11 +746,26 @@ static const struct option longopts[] = { { "debug-filter-parser", no_argument, NULL, 'Y' }, #endif { "relinquish-privileges", required_argument, NULL, 'Z' }, + { "count", no_argument, NULL, OPTION_COUNT }, + { "fp-type", no_argument, NULL, OPTION_FP_TYPE }, { "number", no_argument, NULL, '#' }, + { "print", no_argument, NULL, OPTION_PRINT }, { "version", no_argument, NULL, OPTION_VERSION }, { NULL, 0, NULL, 0 } }; +#ifdef HAVE_PCAP_FINDALLDEVS_EX +#define LIST_REMOTE_INTERFACES_USAGE "[ --list-remote-interfaces remote-source ]" +#else +#define LIST_REMOTE_INTERFACES_USAGE +#endif + +#ifdef HAVE_PCAP_SET_IMMEDIATE_MODE +#define IMMEDIATE_MODE_USAGE " [ --immediate-mode ]" +#else +#define IMMEDIATE_MODE_USAGE "" +#endif + #ifndef _WIN32 /* Drop root privileges and chroot if necessary */ static void @@ -589,20 +773,15 @@ droproot(const char *username, const char *chroot_dir) { struct passwd *pw = NULL; - if (chroot_dir && !username) { - fprintf(stderr, "%s: Chroot without dropping root is insecure\n", - program_name); - exit_tcpdump(1); - } + if (chroot_dir && !username) + error("Chroot without dropping root is insecure"); pw = getpwnam(username); if (pw) { if (chroot_dir) { - if (chroot(chroot_dir) != 0 || chdir ("/") != 0) { - fprintf(stderr, "%s: Couldn't chroot/chdir to '%.64s': %s\n", - program_name, chroot_dir, pcap_strerror(errno)); - exit_tcpdump(1); - } + if (chroot(chroot_dir) != 0 || chdir ("/") != 0) + error("Couldn't chroot/chdir to '%.64s': %s", + chroot_dir, pcap_strerror(errno)); } #ifdef HAVE_LIBCAP_NG { @@ -614,26 +793,21 @@ droproot(const char *username, const char *chroot_dir) } #else if (initgroups(pw->pw_name, pw->pw_gid) != 0 || - setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) { - fprintf(stderr, "%s: Couldn't change to '%.32s' uid=%lu gid=%lu: %s\n", - program_name, username, + setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) + error("Couldn't change to '%.32s' uid=%lu gid=%lu: %s", + username, (unsigned long)pw->pw_uid, (unsigned long)pw->pw_gid, pcap_strerror(errno)); - exit_tcpdump(1); - } else { fprintf(stderr, "dropped privs to %s\n", username); } #endif /* HAVE_LIBCAP_NG */ - } - else { - fprintf(stderr, "%s: Couldn't find user '%.32s'\n", - program_name, username); - exit_tcpdump(1); - } + } else + error("Couldn't find user '%.32s'", username); #ifdef HAVE_LIBCAP_NG /* We don't need CAP_SETUID, CAP_SETGID and CAP_SYS_CHROOT any more. */ +DIAG_OFF_CLANG(assign-enum) capng_updatev( CAPNG_DROP, CAPNG_EFFECTIVE | CAPNG_PERMITTED, @@ -641,6 +815,7 @@ droproot(const char *username, const char *chroot_dir) CAP_SETGID, CAP_SYS_CHROOT, -1); +DIAG_ON_CLANG(assign-enum) capng_apply(CAPNG_SELECT_BOTH); #endif /* HAVE_LIBCAP_NG */ @@ -667,7 +842,7 @@ MakeFilename(char *buffer, char *orig_name, int cnt, int max_chars) { char *filename = malloc(PATH_MAX + 1); if (filename == NULL) - error("Makefilename: malloc"); + error("%s: malloc", __func__); /* Process with strftime if Gflag is set. */ if (Gflag != 0) { @@ -675,7 +850,7 @@ MakeFilename(char *buffer, char *orig_name, int cnt, int max_chars) /* Convert Gflag_time to a usable format */ if ((local_tm = localtime(&Gflag_time)) == NULL) { - error("MakeTimedFilename: localtime"); + error("%s: localtime", __func__); } /* There's no good way to detect an error in strftime since a return @@ -712,6 +887,35 @@ get_next_file(FILE *VFile, char *ptr) return ret; } +#ifdef HAVE_CASPER +static cap_channel_t * +capdns_setup(void) +{ + cap_channel_t *capcas, *capdnsloc; + const char *types[1]; + int families[2]; + + capcas = cap_init(); + if (capcas == NULL) + error("unable to create casper process"); + capdnsloc = cap_service_open(capcas, "system.dns"); + /* Casper capability no longer needed. */ + cap_close(capcas); + if (capdnsloc == NULL) + error("unable to open system.dns service"); + /* Limit system.dns to reverse DNS lookups. */ + types[0] = "ADDR"; + if (cap_dns_type_limit(capdnsloc, types, 1) < 0) + error("unable to limit access to system.dns service"); + families[0] = AF_INET; + families[1] = AF_INET6; + if (cap_dns_family_limit(capdnsloc, families, 2) < 0) + error("unable to limit access to system.dns service"); + + return (capdnsloc); +} +#endif /* HAVE_CASPER */ + #ifdef HAVE_PCAP_SET_TSTAMP_PRECISION static int tstamp_precision_from_string(const char *precision) @@ -748,7 +952,7 @@ tstamp_precision_to_string(int precision) * necessary to make the standard I/O library work with an fdopen()ed * FILE * from that descriptor. * - * A long time ago, in a galaxy far far away, AT&T decided that, instead + * A long time ago in a galaxy far, far away, AT&T decided that, instead * of providing separate APIs for getting and setting the FD_ flags on a * descriptor, getting and setting the O_ flags on a descriptor, and * locking files, they'd throw them all into a kitchen-sink fcntl() call @@ -816,10 +1020,10 @@ set_dumper_capsicum_rights(pcap_dumper_t *p) * Copy arg vector into a new buffer, concatenating arguments with spaces. */ static char * -copy_argv(register char **argv) +copy_argv(char **argv) { - register char **p; - register u_int len = 0; + char **p; + size_t len = 0; char *buf; char *src, *dst; @@ -832,7 +1036,7 @@ copy_argv(register char **argv) buf = (char *)malloc(len); if (buf == NULL) - error("copy_argv: malloc"); + error("%s: malloc", __func__); p = argv; dst = buf; @@ -859,17 +1063,25 @@ copy_argv(register char **argv) static char * read_infile(char *fname) { - register int i, fd, cc; - register char *cp; - struct stat buf; + int i, fd; + ssize_t cc; + char *cp; + our_statb buf; fd = open(fname, O_RDONLY|O_BINARY); if (fd < 0) error("can't open %s: %s", fname, pcap_strerror(errno)); - if (fstat(fd, &buf) < 0) + if (our_fstat(fd, &buf) < 0) error("can't stat %s: %s", fname, pcap_strerror(errno)); + /* + * Reject files whose size doesn't fit into an int; a filter + * *that* large will probably be too big. + */ + if (buf.st_size > INT_MAX) + error("%s is too large", fname); + cp = malloc((u_int)buf.st_size + 1); if (cp == NULL) error("malloc(%d) for %s: %s", (u_int)buf.st_size + 1, @@ -878,7 +1090,8 @@ read_infile(char *fname) if (cc < 0) error("read %s: %s", fname, pcap_strerror(errno)); if (cc != buf.st_size) - error("short read %s (%d != %d)", fname, cc, (int)buf.st_size); + error("short read %s (%d != %d)", fname, (int) cc, + (int)buf.st_size); close(fd); /* replace "# comment" with spaces */ @@ -895,9 +1108,35 @@ read_infile(char *fname) static long parse_interface_number(const char *device) { + const char *p; long devnum; char *end; + /* + * Search for a colon, terminating any scheme at the beginning + * of the device. + */ + p = strchr(device, ':'); + if (p != NULL) { + /* + * We found it. Is it followed by "//"? + */ + p++; /* skip the : */ + if (strncmp(p, "//", 2) == 0) { + /* + * Yes. Search for the next /, at the end of the + * authority part of the URL. + */ + p += 2; /* skip the // */ + p = strchr(p, '/'); + if (p != NULL) { + /* + * OK, past the / is the path. + */ + device = p + 1; + } + } + } devnum = strtol(device, &end, 10); if (device != end && *end == '\0') { /* @@ -920,14 +1159,61 @@ parse_interface_number(const char *device) } static char * -find_interface_by_number(long devnum) +find_interface_by_number(const char *url +#ifndef HAVE_PCAP_FINDALLDEVS_EX +_U_ +#endif +, long devnum) { pcap_if_t *dev, *devlist; long i; char ebuf[PCAP_ERRBUF_SIZE]; char *device; +#ifdef HAVE_PCAP_FINDALLDEVS_EX + const char *endp; + char *host_url; +#endif + int status; - if (pcap_findalldevs(&devlist, ebuf) < 0) +#ifdef HAVE_PCAP_FINDALLDEVS_EX + /* + * Search for a colon, terminating any scheme at the beginning + * of the URL. + */ + endp = strchr(url, ':'); + if (endp != NULL) { + /* + * We found it. Is it followed by "//"? + */ + endp++; /* skip the : */ + if (strncmp(endp, "//", 2) == 0) { + /* + * Yes. Search for the next /, at the end of the + * authority part of the URL. + */ + endp += 2; /* skip the // */ + endp = strchr(endp, '/'); + } else + endp = NULL; + } + if (endp != NULL) { + /* + * OK, everything from device to endp is a URL to hand + * to pcap_findalldevs_ex(). + */ + endp++; /* Include the trailing / in the URL; pcap_findalldevs_ex() requires it */ + host_url = malloc(endp - url + 1); + if (host_url == NULL && (endp - url + 1) > 0) + error("Invalid allocation for host"); + + memcpy(host_url, url, endp - url); + host_url[endp - url] = '\0'; + status = pcap_findalldevs_ex(host_url, NULL, &devlist, ebuf); + free(host_url); + } else +#endif + status = pcap_findalldevs(&devlist, ebuf); + if (status < 0) error("%s", ebuf); /* * Look for the devnum-th entry in the list of devices (1-based). @@ -943,6 +1229,14 @@ find_interface_by_number(long devnum) } #endif +#ifdef HAVE_PCAP_OPEN +/* + * Prefixes for rpcap URLs. + */ +static char rpcap_prefix[] = "rpcap://"; +static char rpcap_ssl_prefix[] = "rpcaps://"; +#endif + static pcap_t * open_interface(const char *device, netdissect_options *ndo, char *ebuf) { @@ -952,6 +1246,38 @@ open_interface(const char *device, netdissect_options *ndo, char *ebuf) char *cp; #endif +#ifdef HAVE_PCAP_OPEN + /* + * Is this an rpcap URL? + */ + if (strncmp(device, rpcap_prefix, sizeof(rpcap_prefix) - 1) == 0 || + strncmp(device, rpcap_ssl_prefix, sizeof(rpcap_ssl_prefix) - 1) == 0) { + /* + * Yes. Open it with pcap_open(). + */ + *ebuf = '\0'; + pc = pcap_open(device, ndo->ndo_snaplen, + pflag ? 0 : PCAP_OPENFLAG_PROMISCUOUS, timeout, NULL, + ebuf); + if (pc == NULL) { + /* + * If this failed with "No such device" or "The system + * cannot find the device specified", that means + * the interface doesn't exist; return NULL, so that + * the caller can see whether the device name is + * actually an interface index. + */ + if (strstr(ebuf, "No such device") != NULL || + strstr(ebuf, "The system cannot find the device specified") != NULL) + return (NULL); + error("%s", ebuf); + } + if (*ebuf) + warning("%s", ebuf); + return (pc); + } +#endif /* HAVE_PCAP_OPEN */ + #ifdef HAVE_PCAP_CREATE pc = pcap_create(device, ebuf); if (pc == NULL) { @@ -973,9 +1299,9 @@ open_interface(const char *device, netdissect_options *ndo, char *ebuf) status = pcap_set_tstamp_precision(pc, ndo->ndo_tstamp_precision); if (status != 0) error("%s: Can't set %ssecond time stamp precision: %s", - device, - tstamp_precision_to_string(ndo->ndo_tstamp_precision), - pcap_statustostr(status)); + device, + tstamp_precision_to_string(ndo->ndo_tstamp_precision), + pcap_statustostr(status)); #endif #ifdef HAVE_PCAP_SET_IMMEDIATE_MODE @@ -983,8 +1309,7 @@ open_interface(const char *device, netdissect_options *ndo, char *ebuf) status = pcap_set_immediate_mode(pc, 1); if (status != 0) error("%s: Can't set immediate mode: %s", - device, - pcap_statustostr(status)); + device, pcap_statustostr(status)); } #endif /* @@ -994,10 +1319,16 @@ open_interface(const char *device, netdissect_options *ndo, char *ebuf) supports_monitor_mode = 1; else supports_monitor_mode = 0; - status = pcap_set_snaplen(pc, ndo->ndo_snaplen); - if (status != 0) - error("%s: Can't set snapshot length: %s", - device, pcap_statustostr(status)); + if (ndo->ndo_snaplen != 0) { + /* + * A snapshot length was explicitly specified; + * use it. + */ + status = pcap_set_snaplen(pc, ndo->ndo_snaplen); + if (status != 0) + error("%s: Can't set snapshot length: %s", + device, pcap_statustostr(status)); + } status = pcap_set_promisc(pc, !pflag); if (status != 0) error("%s: Can't set promiscuous mode: %s", @@ -1008,7 +1339,7 @@ open_interface(const char *device, netdissect_options *ndo, char *ebuf) error("%s: Can't set monitor mode: %s", device, pcap_statustostr(status)); } - status = pcap_set_timeout(pc, 1000); + status = pcap_set_timeout(pc, timeout); if (status != 0) error("%s: pcap_set_timeout failed: %s", device, pcap_statustostr(status)); @@ -1023,11 +1354,11 @@ open_interface(const char *device, netdissect_options *ndo, char *ebuf) status = pcap_set_tstamp_type(pc, jflag); if (status < 0) error("%s: Can't set time stamp type: %s", - device, pcap_statustostr(status)); + device, pcap_statustostr(status)); else if (status > 0) warning("When trying to set timestamp type '%s' on %s: %s", - pcap_tstamp_type_val_to_name(jflag), device, - pcap_statustostr(status)); + pcap_tstamp_type_val_to_name(jflag), device, + pcap_statustostr(status)); } #endif status = pcap_activate(pc); @@ -1044,14 +1375,38 @@ open_interface(const char *device, netdissect_options *ndo, char *ebuf) */ snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s\n(%s)", device, pcap_statustostr(status), cp); - pcap_close(pc); - return (NULL); } else if (status == PCAP_ERROR_PERM_DENIED && *cp != '\0') error("%s: %s\n(%s)", device, pcap_statustostr(status), cp); +#ifdef __FreeBSD__ + else if (status == PCAP_ERROR_RFMON_NOTSUP && + strncmp(device, "wlan", 4) == 0) { + char parent[8], newdev[8]; + char sysctl[32]; + size_t s = sizeof(parent); + + snprintf(sysctl, sizeof(sysctl), + "net.wlan.%d.%%parent", atoi(device + 4)); + sysctlbyname(sysctl, parent, &s, NULL, 0); + strlcpy(newdev, device, sizeof(newdev)); + /* Suggest a new wlan device. */ + /* FIXME: incrementing the index this way is not going to work well + * when the index is 9 or greater but the only consequence in this + * specific case would be an error message that looks a bit odd. + */ + newdev[strlen(newdev)-1]++; + error("%s is not a monitor mode VAP\n" + "To create a new monitor mode VAP use:\n" + " ifconfig %s create wlandev %s wlanmode monitor\n" + "and use %s as the tcpdump interface", + device, newdev, parent, newdev); + } +#endif else error("%s: %s", device, pcap_statustostr(status)); + pcap_close(pc); + return (NULL); } else if (status > 0) { /* * pcap_activate() succeeded, but it's warning us @@ -1078,7 +1433,13 @@ open_interface(const char *device, netdissect_options *ndo, char *ebuf) #endif /* HAVE_PCAP_SETDIRECTION */ #else /* HAVE_PCAP_CREATE */ *ebuf = '\0'; - pc = pcap_open_live(device, ndo->ndo_snaplen, !pflag, 1000, ebuf); + /* + * If no snapshot length was specified, or a length of 0 was + * specified, default to 256KB. + */ + if (ndo->ndo_snaplen == 0) + ndo->ndo_snaplen = MAXIMUM_SNAPLEN; + pc = pcap_open_live(device, ndo->ndo_snaplen, !pflag, timeout, ebuf); if (pc == NULL) { /* * If this failed with "No such device", that means @@ -1100,23 +1461,25 @@ open_interface(const char *device, netdissect_options *ndo, char *ebuf) int main(int argc, char **argv) { - register int cnt, op, i; - bpf_u_int32 localnet =0 , netmask = 0; - int timezone_offset = 0; - register char *cp, *infile, *cmdbuf, *device, *RFileName, *VFileName, *WFileName; + int cnt, op, i; + bpf_u_int32 localnet = 0, netmask = 0; + char *cp, *infile, *cmdbuf, *device, *RFileName, *VFileName, *WFileName; + char *endp; pcap_handler callback; int dlt; const char *dlt_name; struct bpf_program fcode; #ifndef _WIN32 - RETSIGTYPE (*oldhandler)(int); + void (*oldhandler)(int); #endif struct dump_info dumpinfo; u_char *pcap_userdata; char ebuf[PCAP_ERRBUF_SIZE]; char VFileLine[PATH_MAX + 1]; - char *username = NULL; - char *chroot_dir = NULL; + const char *username = NULL; +#ifndef _WIN32 + const char *chroot_dir = NULL; +#endif char *ret = NULL; char *end; #ifdef HAVE_PCAP_FINDALLDEVS @@ -1132,6 +1495,7 @@ main(int argc, char **argv) int Oflag = 1; /* run filter code optimizer */ int yflag_dlt = -1; const char *yflag_dlt_name = NULL; + int print = 0; netdissect_options Ndo; netdissect_options *ndo = &Ndo; @@ -1139,12 +1503,11 @@ main(int argc, char **argv) /* * Initialize the netdissect code. */ - if (nd_init(ebuf, sizeof ebuf) == -1) + if (nd_init(ebuf, sizeof(ebuf)) == -1) error("%s", ebuf); memset(ndo, 0, sizeof(*ndo)); ndo_set_function_pointers(ndo); - ndo->ndo_snaplen = DEFAULT_SNAPLEN; cnt = -1; device = NULL; @@ -1154,15 +1517,18 @@ main(int argc, char **argv) VFile = NULL; WFileName = NULL; dlt = -1; - if ((cp = strrchr(argv[0], '/')) != NULL) + if ((cp = strrchr(argv[0], PATH_SEPARATOR)) != NULL) ndo->program_name = program_name = cp + 1; else ndo->program_name = program_name = argv[0]; -#ifdef _WIN32 +#if defined(HAVE_PCAP_WSOCKINIT) if (pcap_wsockinit() != 0) error("Attempting to initialize Winsock failed"); -#endif /* _WIN32 */ +#elif defined(HAVE_WSOCKINIT) + if (wsockinit() != 0) + error("Attempting to initialize Winsock failed"); +#endif /* * On platforms where the CPU doesn't support unaligned loads, @@ -1205,18 +1571,42 @@ main(int argc, char **argv) break; case 'C': - Cflag = atoi(optarg) * 1000000; - if (Cflag <= 0) + errno = 0; +#ifdef HAVE_PCAP_DUMP_FTELL64 + Cflag = strtoint64_t(optarg, &endp, 10); +#else + Cflag = strtol(optarg, &endp, 10); +#endif + if (endp == optarg || *endp != '\0' || errno != 0 + || Cflag <= 0) error("invalid file size %s", optarg); + /* + * Will multiplying it by 1000000 overflow? + */ +#ifdef HAVE_PCAP_DUMP_FTELL64 + if (Cflag > INT64_T_CONSTANT(0x7fffffffffffffff) / 1000000) +#else + if (Cflag > LONG_MAX / 1000000) +#endif + error("file size %s is too large", optarg); + Cflag *= 1000000; break; case 'd': ++dflag; break; +#ifdef HAVE_PCAP_FINDALLDEVS case 'D': Dflag++; break; +#endif + +#ifdef HAVE_PCAP_FINDALLDEVS_EX + case OPTION_LIST_REMOTE_INTERFACES: + remote_interfaces_source = optarg; + break; +#endif case 'L': Lflag++; @@ -1251,14 +1641,14 @@ main(int argc, char **argv) /* Grab the current time for rotation use. */ if ((Gflag_time = time(NULL)) == (time_t)-1) { - error("main: can't get current time: %s", - pcap_strerror(errno)); + error("%s: can't get current time: %s", + __func__, pcap_strerror(errno)); } break; case 'h': - print_usage(); - exit_tcpdump(0); + print_usage(stdout); + exit_tcpdump(S_SUCCESS); break; case 'H': @@ -1306,6 +1696,7 @@ main(int argc, char **argv) setvbuf(stdout, NULL, _IOLBF, 0); #endif #endif /* _WIN32 */ + lflag = 1; break; case 'K': @@ -1314,7 +1705,7 @@ main(int argc, char **argv) case 'm': if (nd_have_smi_support()) { - if (nd_load_smi_module(optarg, ebuf, sizeof ebuf) == -1) + if (nd_load_smi_module(optarg, ebuf, sizeof(ebuf)) == -1) error("%s", ebuf); } else { (void)fprintf(stderr, "%s: ignoring option `-m %s' ", @@ -1370,12 +1761,11 @@ main(int argc, char **argv) break; case 's': - ndo->ndo_snaplen = strtol(optarg, &end, 0); + ndo->ndo_snaplen = (int)strtol(optarg, &end, 0); if (optarg == end || *end != '\0' || ndo->ndo_snaplen < 0 || ndo->ndo_snaplen > MAXIMUM_SNAPLEN) - error("invalid snaplen %s", optarg); - else if (ndo->ndo_snaplen == 0) - ndo->ndo_snaplen = MAXIMUM_SNAPLEN; + error("invalid snaplen %s (must be >= 0 and <= %d)", + optarg, MAXIMUM_SNAPLEN); break; case 'S': @@ -1421,6 +1811,12 @@ main(int argc, char **argv) ndo->ndo_packettype = PT_LMP; else if (ascii_strcasecmp(optarg, "resp") == 0) ndo->ndo_packettype = PT_RESP; + else if (ascii_strcasecmp(optarg, "ptp") == 0) + ndo->ndo_packettype = PT_PTP; + else if (ascii_strcasecmp(optarg, "someip") == 0) + ndo->ndo_packettype = PT_SOMEIP; + else if (ascii_strcasecmp(optarg, "domain") == 0) + ndo->ndo_packettype = PT_DOMAIN; else error("unknown packet type `%s'", optarg); break; @@ -1493,8 +1889,8 @@ main(int argc, char **argv) break; case OPTION_VERSION: - print_version(); - exit_tcpdump(0); + print_version(stdout); + exit_tcpdump(S_SUCCESS); break; #ifdef HAVE_PCAP_SET_TSTAMP_PRECISION @@ -1511,9 +1907,38 @@ main(int argc, char **argv) break; #endif + case OPTION_PRINT: + print = 1; + break; + +#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION + case OPTION_TSTAMP_MICRO: + ndo->ndo_tstamp_precision = PCAP_TSTAMP_PRECISION_MICRO; + break; + + case OPTION_TSTAMP_NANO: + ndo->ndo_tstamp_precision = PCAP_TSTAMP_PRECISION_NANO; + break; +#endif + + case OPTION_FP_TYPE: + /* + * Print out the type of floating-point arithmetic + * we're doing; it's probably IEEE, unless somebody + * tries to run this on a VAX, but the precision + * may differ (e.g., it might be 32-bit, 64-bit, + * or 80-bit). + */ + float_type_check(0x4e93312d); + return 0; + + case OPTION_COUNT: + count_mode = 1; + break; + default: - print_usage(); - exit_tcpdump(1); + print_usage(stderr); + exit_tcpdump(S_ERR_HOST_PROGRAM); /* NOTREACHED */ } @@ -1521,18 +1946,27 @@ main(int argc, char **argv) if (Dflag) show_devices_and_exit(); #endif +#ifdef HAVE_PCAP_FINDALLDEVS_EX + if (remote_interfaces_source != NULL) + show_remote_devices_and_exit(); +#endif + +#if defined(DLT_LINUX_SLL2) && defined(HAVE_PCAP_SET_DATALINK) +/* Set default linktype DLT_LINUX_SLL2 when capturing on the "any" device */ + if (device != NULL && + strncmp (device, "any", strlen("any")) == 0 + && yflag_dlt == -1) + yflag_dlt = DLT_LINUX_SLL2; +#endif switch (ndo->ndo_tflag) { case 0: /* Default */ - case 4: /* Default + Date*/ - timezone_offset = gmt2local(0); - break; - case 1: /* No time stamp */ case 2: /* Unix timeval style */ - case 3: /* Microseconds since previous packet */ - case 5: /* Microseconds since first packet */ + case 3: /* Microseconds/nanoseconds since previous packet */ + case 4: /* Date + Default */ + case 5: /* Microseconds/nanoseconds since first packet */ break; default: /* Not supported */ @@ -1546,16 +1980,18 @@ main(int argc, char **argv) if (VFileName != NULL && RFileName != NULL) error("-V and -r are mutually exclusive."); -#ifdef HAVE_PCAP_SET_IMMEDIATE_MODE /* - * If we're printing dissected packets to the standard output - * rather than saving raw packets to a file, and the standard - * output is a terminal, use immediate mode, as the user's - * probably expecting to see packets pop up immediately. + * If we're printing dissected packets to the standard output, + * and either the standard output is a terminal or we're doing + * "line" buffering, set the capture timeout to .1 second rather + * than 1 second, as the user's probably expecting to see packets + * pop up immediately shortly after they arrive. + * + * XXX - would there be some value appropriate for all cases, + * based on, say, the buffer size and packet input rate? */ - if (WFileName == NULL && isatty(1)) - immediate_mode = 1; -#endif + if ((WFileName == NULL || print) && (isatty(1) || lflag)) + timeout = 100; #ifdef WITH_CHROOT /* if run as root, prepare for chrooting */ @@ -1631,15 +2067,41 @@ main(int argc, char **argv) #endif dlt = pcap_datalink(pd); dlt_name = pcap_datalink_val_to_name(dlt); + fprintf(stderr, "reading from file %s", RFileName); if (dlt_name == NULL) { - fprintf(stderr, "reading from file %s, link-type %u\n", - RFileName, dlt); + fprintf(stderr, ", link-type %u", dlt); } else { - fprintf(stderr, - "reading from file %s, link-type %s (%s)\n", - RFileName, dlt_name, - pcap_datalink_val_to_description(dlt)); + fprintf(stderr, ", link-type %s (%s)", dlt_name, + pcap_datalink_val_to_description(dlt)); } + fprintf(stderr, ", snapshot length %d\n", pcap_snapshot(pd)); +#ifdef DLT_LINUX_SLL2 + if (dlt == DLT_LINUX_SLL2) + fprintf(stderr, "Warning: interface names might be incorrect\n"); +#endif + } else if (dflag && !device) { + int dump_dlt = DLT_EN10MB; + /* + * We're dumping the compiled code without an explicit + * device specification. (If a device is specified, we + * definitely want to open it to use the DLT of that device.) + * Either default to DLT_EN10MB with a warning, or use + * the user-specified value if supplied. + */ + /* + * If no snapshot length was specified, or a length of 0 was + * specified, default to 256KB. + */ + if (ndo->ndo_snaplen == 0) + ndo->ndo_snaplen = MAXIMUM_SNAPLEN; + /* + * If a DLT was specified with the -y flag, use that instead. + */ + if (yflag_dlt != -1) + dump_dlt = yflag_dlt; + else + fprintf(stderr, "Warning: assuming Ethernet\n"); + pd = pcap_open_dead(dump_dlt, ndo->ndo_snaplen); } else { /* * We're doing a live capture. @@ -1653,20 +2115,21 @@ main(int argc, char **argv) * Find the list of interfaces, and pick * the first interface. */ - if (pcap_findalldevs(&devlist, ebuf) >= 0 && - devlist != NULL) { - device = strdup(devlist->name); - pcap_freealldevs(devlist); - } + if (pcap_findalldevs(&devlist, ebuf) == -1) + error("%s", ebuf); + if (devlist == NULL) + error("no interfaces available for capture"); + device = strdup(devlist->name); + pcap_freealldevs(devlist); #else /* HAVE_PCAP_FINDALLDEVS */ /* * Use whatever interface pcap_lookupdev() * chooses. */ device = pcap_lookupdev(ebuf); -#endif if (device == NULL) error("%s", ebuf); +#endif } /* @@ -1699,7 +2162,7 @@ main(int argc, char **argv) * find_interface_by_number() exits if it * couldn't be found. */ - device = find_interface_by_number(devnum); + device = find_interface_by_number(device, devnum); pd = open_interface(device, ndo, ebuf); if (pd == NULL) error("%s", ebuf); @@ -1713,7 +2176,8 @@ main(int argc, char **argv) } /* - * Let user own process after socket has been opened. + * Let user own process after capture device has + * been opened. */ #ifndef _WIN32 if (setgid(getgid()) != 0 || setuid(getuid()) != 0) @@ -1743,12 +2207,17 @@ main(int argc, char **argv) } #endif (void)fprintf(stderr, "%s: data link type %s\n", - program_name, yflag_dlt_name); + program_name, + pcap_datalink_val_to_name(yflag_dlt)); (void)fflush(stderr); } i = pcap_snapshot(pd); if (ndo->ndo_snaplen < i) { - warning("snaplen raised from %d to %d", ndo->ndo_snaplen, i); + if (ndo->ndo_snaplen != 0) + warning("snaplen raised from %d to %d", ndo->ndo_snaplen, i); + ndo->ndo_snaplen = i; + } else if (ndo->ndo_snaplen > i) { + warning("snaplen lowered from %d to %d", ndo->ndo_snaplen, i); ndo->ndo_snaplen = i; } if(ndo->ndo_fflag != 0) { @@ -1773,15 +2242,21 @@ main(int argc, char **argv) pcap_close(pd); free(cmdbuf); pcap_freecode(&fcode); - exit_tcpdump(0); + exit_tcpdump(S_SUCCESS); } - init_print(ndo, localnet, netmask, timezone_offset); + +#ifdef HAVE_CASPER + if (!ndo->ndo_nflag) + capdns = capdns_setup(); +#endif /* HAVE_CASPER */ + + init_print(ndo, localnet, netmask); #ifndef _WIN32 (void)setsignal(SIGPIPE, cleanup); (void)setsignal(SIGTERM, cleanup); - (void)setsignal(SIGINT, cleanup); #endif /* _WIN32 */ + (void)setsignal(SIGINT, cleanup); #if defined(HAVE_FORK) || defined(HAVE_VFORK) (void)setsignal(SIGCHLD, child_cleanup); #endif @@ -1815,27 +2290,33 @@ main(int argc, char **argv) /* Initialize capng */ capng_clear(CAPNG_SELECT_BOTH); if (username) { +DIAG_OFF_CLANG(assign-enum) capng_updatev( CAPNG_ADD, CAPNG_PERMITTED | CAPNG_EFFECTIVE, CAP_SETUID, CAP_SETGID, -1); +DIAG_ON_CLANG(assign-enum) } if (chroot_dir) { +DIAG_OFF_CLANG(assign-enum) capng_update( CAPNG_ADD, CAPNG_PERMITTED | CAPNG_EFFECTIVE, CAP_SYS_CHROOT ); +DIAG_ON_CLANG(assign-enum) } if (WFileName) { +DIAG_OFF_CLANG(assign-enum) capng_update( CAPNG_ADD, CAPNG_PERMITTED | CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE ); +DIAG_ON_CLANG(assign-enum) } capng_apply(CAPNG_SELECT_BOTH); #endif /* HAVE_LIBCAP_NG */ @@ -1848,7 +2329,7 @@ main(int argc, char **argv) if (pcap_setfilter(pd, &fcode) < 0) error("%s", pcap_geterr(pd)); #ifdef HAVE_CAPSICUM - if (RFileName == NULL && VFileName == NULL) { + if (RFileName == NULL && VFileName == NULL && pcap_fileno(pd) != -1) { static const unsigned long cmds[] = { BIOCGSTATS, BIOCROTZBUF }; /* @@ -1868,7 +2349,6 @@ main(int argc, char **argv) } #endif if (WFileName) { - pcap_dumper_t *p; /* Do not exceed the default PATH_MAX for files. */ dumpinfo.CurrentFileName = (char *)malloc(PATH_MAX + 1); @@ -1881,7 +2361,7 @@ main(int argc, char **argv) else MakeFilename(dumpinfo.CurrentFileName, WFileName, 0, 0); - p = pcap_dump_open(pd, dumpinfo.CurrentFileName); + pdd = pcap_dump_open(pd, dumpinfo.CurrentFileName); #ifdef HAVE_LIBCAP_NG /* Give up CAP_DAC_OVERRIDE capability. * Only allow it to be restored if the -C or -G flag have been @@ -1895,10 +2375,10 @@ main(int argc, char **argv) ); capng_apply(CAPNG_SELECT_BOTH); #endif /* HAVE_LIBCAP_NG */ - if (p == NULL) + if (pdd == NULL) error("%s", pcap_geterr(pd)); #ifdef HAVE_CAPSICUM - set_dumper_capsicum_rights(p); + set_dumper_capsicum_rights(pdd); #endif if (Cflag != 0 || Gflag != 0) { #ifdef HAVE_CAPSICUM @@ -1928,19 +2408,29 @@ main(int argc, char **argv) #endif callback = dump_packet_and_trunc; dumpinfo.pd = pd; - dumpinfo.p = p; + dumpinfo.pdd = pdd; pcap_userdata = (u_char *)&dumpinfo; } else { callback = dump_packet; - pcap_userdata = (u_char *)p; + dumpinfo.WFileName = WFileName; + dumpinfo.pd = pd; + dumpinfo.pdd = pdd; + pcap_userdata = (u_char *)&dumpinfo; } + if (print) { + dlt = pcap_datalink(pd); + ndo->ndo_if_printer = get_if_printer(dlt); + dumpinfo.ndo = ndo; + } else + dumpinfo.ndo = NULL; + #ifdef HAVE_PCAP_DUMP_FLUSH if (Uflag) - pcap_dump_flush(p); + pcap_dump_flush(pdd); #endif } else { dlt = pcap_datalink(pd); - ndo->ndo_if_printer = get_if_printer(ndo, dlt); + ndo->ndo_if_printer = get_if_printer(dlt); callback = print_packet; pcap_userdata = (u_char *)ndo; } @@ -1953,21 +2443,45 @@ main(int argc, char **argv) if (RFileName == NULL) (void)setsignal(SIGNAL_REQ_INFO, requestinfo); #endif +#ifdef SIGNAL_FLUSH_PCAP + (void)setsignal(SIGNAL_FLUSH_PCAP, flushpcap); +#endif - if (ndo->ndo_vflag > 0 && WFileName) { + if (ndo->ndo_vflag > 0 && WFileName && RFileName == NULL && !print) { + /* + * When capturing to a file, if "--print" wasn't specified, + *"-v" means tcpdump should, once per second, + * "v"erbosely report the number of packets captured. + * Except when reading from a file, because -r, -w and -v + * together used to make a corner case, in which pcap_loop() + * errored due to EINTR (see GH #155 for details). + */ +#ifdef _WIN32 /* - * When capturing to a file, "-v" means tcpdump should, - * every 10 seconds, "v"erbosely report the number of - * packets captured. + * https://blogs.msdn.microsoft.com/oldnewthing/20151230-00/?p=92741 + * + * suggests that this dates back to W2K. + * + * I don't know what a "long wait" is, but we'll assume + * that printing the stats could be a "long wait". */ -#ifdef USE_WIN32_MM_TIMER - /* call verbose_stats_dump() each 1000 +/-100msec */ - timer_id = timeSetEvent(1000, 100, verbose_stats_dump, 0, TIME_PERIODIC); + CreateTimerQueueTimer(&timer_handle, NULL, + verbose_stats_dump, NULL, 1000, 1000, + WT_EXECUTEDEFAULT|WT_EXECUTELONGFUNCTION); setvbuf(stderr, NULL, _IONBF, 0); -#elif defined(HAVE_ALARM) +#else /* _WIN32 */ + /* + * Assume this is UN*X, and that it has setitimer(); that + * dates back to UNIX 95. + */ + struct itimerval timer; (void)setsignal(SIGALRM, verbose_stats_dump); - alarm(1); -#endif + timer.it_interval.tv_sec = 1; + timer.it_interval.tv_usec = 0; + timer.it_value.tv_sec = 1; + timer.it_value.tv_usec = 1; + setitimer(ITIMER_REAL, &timer, NULL); +#endif /* _WIN32 */ } if (RFileName == NULL) { @@ -1978,25 +2492,30 @@ main(int argc, char **argv) */ if (!ndo->ndo_vflag && !WFileName) { (void)fprintf(stderr, - "%s: verbose output suppressed, use -v or -vv for full protocol decode\n", + "%s: verbose output suppressed, use -v[v]... for full protocol decode\n", program_name); } else (void)fprintf(stderr, "%s: ", program_name); dlt = pcap_datalink(pd); dlt_name = pcap_datalink_val_to_name(dlt); + (void)fprintf(stderr, "listening on %s", device); if (dlt_name == NULL) { - (void)fprintf(stderr, "listening on %s, link-type %u, capture size %u bytes\n", - device, dlt, ndo->ndo_snaplen); + (void)fprintf(stderr, ", link-type %u", dlt); } else { - (void)fprintf(stderr, "listening on %s, link-type %s (%s), capture size %u bytes\n", - device, dlt_name, - pcap_datalink_val_to_description(dlt), ndo->ndo_snaplen); + (void)fprintf(stderr, ", link-type %s (%s)", dlt_name, + pcap_datalink_val_to_description(dlt)); } + (void)fprintf(stderr, ", snapshot length %d bytes\n", ndo->ndo_snaplen); (void)fflush(stderr); } #ifdef HAVE_CAPSICUM - cansandbox = (ndo->ndo_nflag && VFileName == NULL && zflag == NULL); + cansandbox = (VFileName == NULL && zflag == NULL); +#ifdef HAVE_CASPER + cansandbox = (cansandbox && (ndo->ndo_nflag || capdns != NULL)); +#else + cansandbox = (cansandbox && ndo->ndo_nflag); +#endif /* HAVE_CASPER */ if (cansandbox && cap_enter() < 0 && errno != ENOSYS) error("unable to enter the capability mode"); #endif /* HAVE_CAPSICUM */ @@ -2087,7 +2606,7 @@ main(int argc, char **argv) * the new DLT. */ dlt = new_dlt; - ndo->ndo_if_printer = get_if_printer(ndo, dlt); + ndo->ndo_if_printer = get_if_printer(dlt); if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0) error("%s", pcap_geterr(pd)); } @@ -2102,36 +2621,69 @@ main(int argc, char **argv) * Report the new file. */ dlt_name = pcap_datalink_val_to_name(dlt); + fprintf(stderr, "reading from file %s", RFileName); if (dlt_name == NULL) { - fprintf(stderr, "reading from file %s, link-type %u\n", - RFileName, dlt); + fprintf(stderr, ", link-type %u", dlt); } else { - fprintf(stderr, - "reading from file %s, link-type %s (%s)\n", - RFileName, dlt_name, - pcap_datalink_val_to_description(dlt)); + fprintf(stderr, ", link-type %s (%s)", + dlt_name, + pcap_datalink_val_to_description(dlt)); } + fprintf(stderr, ", snapshot length %d\n", pcap_snapshot(pd)); } } } while (ret != NULL); + if (count_mode && RFileName != NULL) + fprintf(stdout, "%u packet%s\n", packets_captured, + PLURAL_SUFFIX(packets_captured)); + free(cmdbuf); pcap_freecode(&fcode); exit_tcpdump(status == -1 ? 1 : 0); } +/* + * Catch a signal. + */ +static void +(*setsignal (int sig, void (*func)(int)))(int) +{ +#ifdef _WIN32 + return (signal(sig, func)); +#else + struct sigaction old, new; + + memset(&new, 0, sizeof(new)); + new.sa_handler = func; + if (sig == SIGCHLD) + new.sa_flags = SA_RESTART; + if (sigaction(sig, &new, &old) < 0) + return (SIG_ERR); + return (old.sa_handler); +#endif +} + /* make a clean exit on interrupts */ -static RETSIGTYPE +static void cleanup(int signo _U_) { -#ifdef USE_WIN32_MM_TIMER - if (timer_id) - timeKillEvent(timer_id); - timer_id = 0; -#elif defined(HAVE_ALARM) - alarm(0); -#endif +#ifdef _WIN32 + if (timer_handle != INVALID_HANDLE_VALUE) { + DeleteTimerQueueTimer(NULL, timer_handle, NULL); + CloseHandle(timer_handle); + timer_handle = INVALID_HANDLE_VALUE; + } +#else /* _WIN32 */ + struct itimerval timer; + + timer.it_interval.tv_sec = 0; + timer.it_interval.tv_usec = 0; + timer.it_value.tv_sec = 0; + timer.it_value.tv_usec = 0; + setitimer(ITIMER_REAL, &timer, NULL); +#endif /* _WIN32 */ #ifdef HAVE_PCAP_BREAKLOOP /* @@ -2158,7 +2710,7 @@ cleanup(int signo _U_) (void)fflush(stdout); info(1); } - exit_tcpdump(0); + exit_tcpdump(S_SUCCESS); #endif } @@ -2167,7 +2719,7 @@ cleanup(int signo _U_) waiting a child processes to die */ #if defined(HAVE_FORK) || defined(HAVE_VFORK) -static RETSIGTYPE +static void child_cleanup(int signo _U_) { wait(NULL); @@ -2175,7 +2727,7 @@ child_cleanup(int signo _U_) #endif /* HAVE_FORK && HAVE_VFORK */ static void -info(register int verbose) +info(int verbose) { struct pcap_stat stats; @@ -2258,9 +2810,9 @@ compress_savefile(const char *filename) filename, pcap_strerror(errno)); #ifdef HAVE_FORK - exit(1); + exit(S_ERR_HOST_PROGRAM); #else - _exit(1); + _exit(S_ERR_HOST_PROGRAM); #endif } #else /* HAVE_FORK && HAVE_VFORK */ @@ -2297,8 +2849,8 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s /* Get the current time */ if ((t = time(NULL)) == (time_t)-1) { - error("dump_and_trunc_packet: can't get current_time: %s", - pcap_strerror(errno)); + error("%s: can't get current_time: %s", + __func__, pcap_strerror(errno)); } @@ -2316,7 +2868,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s /* * Close the current file and open a new one. */ - pcap_dump_close(dump_info->p); + pcap_dump_close(dump_info->pdd); /* * Compress the file we just closed, if the user asked for it @@ -2332,7 +2884,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s (void)fprintf(stderr, "Maximum file limit reached: %d\n", Wflag); info(1); - exit_tcpdump(0); + exit_tcpdump(S_SUCCESS); /* NOTREACHED */ } if (dump_info->CurrentFileName != NULL) @@ -2376,18 +2928,18 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s error("unable to fdopen file %s", dump_info->CurrentFileName); } - dump_info->p = pcap_dump_fopen(dump_info->pd, fp); + dump_info->pdd = pcap_dump_fopen(dump_info->pd, fp); #else /* !HAVE_CAPSICUM */ - dump_info->p = pcap_dump_open(dump_info->pd, dump_info->CurrentFileName); + dump_info->pdd = pcap_dump_open(dump_info->pd, dump_info->CurrentFileName); #endif #ifdef HAVE_LIBCAP_NG capng_update(CAPNG_DROP, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE); capng_apply(CAPNG_SELECT_BOTH); #endif /* HAVE_LIBCAP_NG */ - if (dump_info->p == NULL) + if (dump_info->pdd == NULL) error("%s", pcap_geterr(pd)); #ifdef HAVE_CAPSICUM - set_dumper_capsicum_rights(dump_info->p); + set_dumper_capsicum_rights(dump_info->pdd); #endif } } @@ -2398,7 +2950,17 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s * file could put it over Cflag. */ if (Cflag != 0) { - long size = pcap_dump_ftell(dump_info->p); +#ifdef HAVE_PCAP_DUMP_FTELL64 + int64_t size = pcap_dump_ftell64(dump_info->pdd); +#else + /* + * XXX - this only handles a Cflag value > 2^31-1 on + * LP64 platforms; to handle ILP32 (32-bit UN*X and + * Windows) or LLP64 (64-bit Windows) would require + * a version of libpcap with pcap_dump_ftell64(). + */ + long size = pcap_dump_ftell(dump_info->pdd); +#endif if (size == -1) error("ftell fails on output file"); @@ -2411,7 +2973,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s /* * Close the current file and open a new one. */ - pcap_dump_close(dump_info->p); + pcap_dump_close(dump_info->pdd); /* * Compress the file we just closed, if the user @@ -2429,7 +2991,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s free(dump_info->CurrentFileName); dump_info->CurrentFileName = (char *)malloc(PATH_MAX + 1); if (dump_info->CurrentFileName == NULL) - error("dump_packet_and_trunc: malloc"); + error("%s: malloc", __func__); MakeFilename(dump_info->CurrentFileName, dump_info->WFileName, Cflag_count, WflagChars); #ifdef HAVE_LIBCAP_NG capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE); @@ -2447,28 +3009,31 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s error("unable to fdopen file %s", dump_info->CurrentFileName); } - dump_info->p = pcap_dump_fopen(dump_info->pd, fp); + dump_info->pdd = pcap_dump_fopen(dump_info->pd, fp); #else /* !HAVE_CAPSICUM */ - dump_info->p = pcap_dump_open(dump_info->pd, dump_info->CurrentFileName); + dump_info->pdd = pcap_dump_open(dump_info->pd, dump_info->CurrentFileName); #endif #ifdef HAVE_LIBCAP_NG capng_update(CAPNG_DROP, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE); capng_apply(CAPNG_SELECT_BOTH); #endif /* HAVE_LIBCAP_NG */ - if (dump_info->p == NULL) + if (dump_info->pdd == NULL) error("%s", pcap_geterr(pd)); #ifdef HAVE_CAPSICUM - set_dumper_capsicum_rights(dump_info->p); + set_dumper_capsicum_rights(dump_info->pdd); #endif } } - pcap_dump((u_char *)dump_info->p, h, sp); + pcap_dump((u_char *)dump_info->pdd, h, sp); #ifdef HAVE_PCAP_DUMP_FLUSH if (Uflag) - pcap_dump_flush(dump_info->p); + pcap_dump_flush(dump_info->pdd); #endif + if (dump_info->ndo != NULL) + pretty_print_packet(dump_info->ndo, h, sp, packets_captured); + --infodelay; if (infoprint) info(0); @@ -2477,16 +3042,23 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s static void dump_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) { + struct dump_info *dump_info; + ++packets_captured; ++infodelay; - pcap_dump(user, h, sp); + dump_info = (struct dump_info *)user; + + pcap_dump((u_char *)dump_info->pdd, h, sp); #ifdef HAVE_PCAP_DUMP_FLUSH if (Uflag) - pcap_dump_flush((pcap_dumper_t *)user); + pcap_dump_flush(dump_info->pdd); #endif + if (dump_info->ndo != NULL) + pretty_print_packet(dump_info->ndo, h, sp, packets_captured); + --infodelay; if (infoprint) info(0); @@ -2499,42 +3071,17 @@ print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) ++infodelay; - pretty_print_packet((netdissect_options *)user, h, sp, packets_captured); + if (!count_mode) + pretty_print_packet((netdissect_options *)user, h, sp, packets_captured); --infodelay; if (infoprint) info(0); } -#ifdef _WIN32 - /* - * XXX - there should really be libpcap calls to get the version - * number as a string (the string would be generated from #defines - * at run time, so that it's not generated from string constants - * in the library, as, on many UNIX systems, those constants would - * be statically linked into the application executable image, and - * would thus reflect the version of libpcap on the system on - * which the application was *linked*, not the system on which it's - * *running*. - * - * That routine should be documented, unlike the "version[]" - * string, so that UNIX vendors providing their own libpcaps - * don't omit it (as a couple of vendors have...). - * - * Packet.dll should perhaps also export a routine to return the - * version number of the Packet.dll code, to supply the - * "Wpcap_version" information on Windows. - */ - char WDversion[]="current-git.tcpdump.org"; -#if !defined(HAVE_GENERATED_VERSION) - char version[]="current-git.tcpdump.org"; -#endif - char pcap_version[]="current-git.tcpdump.org"; - char Wpcap_version[]="3.1"; -#endif - #ifdef SIGNAL_REQ_INFO -RETSIGTYPE requestinfo(int signo _U_) +static void +requestinfo(int signo _U_) { if (infodelay) ++infoprint; @@ -2543,107 +3090,111 @@ RETSIGTYPE requestinfo(int signo _U_) } #endif +#ifdef SIGNAL_FLUSH_PCAP +static void +flushpcap(int signo _U_) +{ + if (pdd != NULL) + pcap_dump_flush(pdd); +} +#endif + +static void +print_packets_captured (void) +{ + static u_int prev_packets_captured, first = 1; + + if (infodelay == 0 && (first || packets_captured != prev_packets_captured)) { + fprintf(stderr, "Got %u\r", packets_captured); + first = 0; + prev_packets_captured = packets_captured; + } +} + /* * Called once each second in verbose mode while dumping to file */ -#ifdef USE_WIN32_MM_TIMER -void CALLBACK verbose_stats_dump (UINT timer_id _U_, UINT msg _U_, DWORD_PTR arg _U_, - DWORD_PTR dw1 _U_, DWORD_PTR dw2 _U_) +#ifdef _WIN32 +static void CALLBACK verbose_stats_dump(PVOID param _U_, + BOOLEAN timer_fired _U_) { - if (infodelay == 0) - fprintf(stderr, "Got %u\r", packets_captured); + print_packets_captured(); } -#elif defined(HAVE_ALARM) +#else /* _WIN32 */ static void verbose_stats_dump(int sig _U_) { - if (infodelay == 0) - fprintf(stderr, "Got %u\r", packets_captured); - alarm(1); + print_packets_captured(); } -#endif +#endif /* _WIN32 */ USES_APPLE_DEPRECATED_API static void -print_version(void) +print_version(FILE *f) { - extern char version[]; #ifndef HAVE_PCAP_LIB_VERSION -#if defined(_WIN32) || defined(HAVE_PCAP_VERSION) + #ifdef HAVE_PCAP_VERSION extern char pcap_version[]; -#else /* defined(_WIN32) || defined(HAVE_PCAP_VERSION) */ + #else /* HAVE_PCAP_VERSION */ static char pcap_version[] = "unknown"; -#endif /* defined(_WIN32) || defined(HAVE_PCAP_VERSION) */ + #endif /* HAVE_PCAP_VERSION */ #endif /* HAVE_PCAP_LIB_VERSION */ const char *smi_version_string; + (void)fprintf(f, "%s version " PACKAGE_VERSION "\n", program_name); #ifdef HAVE_PCAP_LIB_VERSION -#ifdef _WIN32 - (void)fprintf(stderr, "%s version %s, based on tcpdump version %s\n", program_name, WDversion, version); -#else /* _WIN32 */ - (void)fprintf(stderr, "%s version %s\n", program_name, version); -#endif /* _WIN32 */ - (void)fprintf(stderr, "%s\n",pcap_lib_version()); + (void)fprintf(f, "%s\n", pcap_lib_version()); #else /* HAVE_PCAP_LIB_VERSION */ -#ifdef _WIN32 - (void)fprintf(stderr, "%s version %s, based on tcpdump version %s\n", program_name, WDversion, version); - (void)fprintf(stderr, "WinPcap version %s, based on libpcap version %s\n",Wpcap_version, pcap_version); -#else /* _WIN32 */ - (void)fprintf(stderr, "%s version %s\n", program_name, version); - (void)fprintf(stderr, "libpcap version %s\n", pcap_version); -#endif /* _WIN32 */ + (void)fprintf(f, "libpcap version %s\n", pcap_version); #endif /* HAVE_PCAP_LIB_VERSION */ #if defined(HAVE_LIBCRYPTO) && defined(SSLEAY_VERSION) - (void)fprintf (stderr, "%s\n", SSLeay_version(SSLEAY_VERSION)); + (void)fprintf (f, "%s\n", SSLeay_version(SSLEAY_VERSION)); #endif smi_version_string = nd_smi_version_string(); if (smi_version_string != NULL) - (void)fprintf (stderr, "SMI-library: %s\n", smi_version_string); + (void)fprintf (f, "SMI-library: %s\n", smi_version_string); #if defined(__SANITIZE_ADDRESS__) - (void)fprintf (stderr, "Compiled with AddressSanitizer/GCC.\n"); + (void)fprintf (f, "Compiled with AddressSanitizer/GCC.\n"); #elif defined(__has_feature) # if __has_feature(address_sanitizer) - (void)fprintf (stderr, "Compiled with AddressSanitizer/CLang.\n"); + (void)fprintf (f, "Compiled with AddressSanitizer/Clang.\n"); +# elif __has_feature(memory_sanitizer) + (void)fprintf (f, "Compiled with MemorySanitizer/Clang.\n"); # endif #endif /* __SANITIZE_ADDRESS__ or __has_feature */ } USES_APPLE_RST static void -print_usage(void) +print_usage(FILE *f) { - print_version(); - (void)fprintf(stderr, -"Usage: %s [-aAbd" D_FLAG "efhH" I_FLAG J_FLAG "KlLnNOpqStu" U_FLAG "vxX#]" B_FLAG_USAGE " [ -c count ]\n", program_name); - (void)fprintf(stderr, + print_version(f); + (void)fprintf(f, +"Usage: %s [-Abd" D_FLAG "efhH" I_FLAG J_FLAG "KlLnNOpqStu" U_FLAG "vxX#]" B_FLAG_USAGE " [ -c count ] [--count]\n", program_name); + (void)fprintf(f, "\t\t[ -C file_size ] [ -E algo:secret ] [ -F file ] [ -G seconds ]\n"); - (void)fprintf(stderr, -"\t\t[ -i interface ]" j_FLAG_USAGE " [ -M secret ] [ --number ]\n"); -#ifdef HAVE_PCAP_SETDIRECTION - (void)fprintf(stderr, -"\t\t[ -Q in|out|inout ]\n"); -#endif - (void)fprintf(stderr, -"\t\t[ -r file ] [ -s snaplen ] "); + (void)fprintf(f, +"\t\t[ -i interface ]" IMMEDIATE_MODE_USAGE j_FLAG_USAGE "\n"); +#ifdef HAVE_PCAP_FINDALLDEVS_EX + (void)fprintf(f, +"\t\t" LIST_REMOTE_INTERFACES_USAGE "\n"); +#endif +#ifdef USE_LIBSMI + (void)fprintf(f, +"\t\t" m_FLAG_USAGE "\n"); +#endif + (void)fprintf(f, +"\t\t[ -M secret ] [ --number ] [ --print ]" Q_FLAG_USAGE "\n"); + (void)fprintf(f, +"\t\t[ -r file ] [ -s snaplen ] [ -T type ] [ --version ]\n"); + (void)fprintf(f, +"\t\t[ -V file ] [ -w file ] [ -W filecount ] [ -y datalinktype ]\n"); #ifdef HAVE_PCAP_SET_TSTAMP_PRECISION - (void)fprintf(stderr, "[ --time-stamp-precision precision ]\n"); - (void)fprintf(stderr, -"\t\t"); -#endif -#ifdef HAVE_PCAP_SET_IMMEDIATE_MODE - (void)fprintf(stderr, "[ --immediate-mode ] "); + (void)fprintf(f, +"\t\t[ --time-stamp-precision precision ] [ --micro ] [ --nano ]\n"); #endif - (void)fprintf(stderr, "[ -T type ] [ --version ] [ -V file ]\n"); - (void)fprintf(stderr, -"\t\t[ -w file ] [ -W filecount ] [ -y datalinktype ] [ -z postrotate-command ]\n"); - (void)fprintf(stderr, -"\t\t[ -Z user ] [ expression ]\n"); + (void)fprintf(f, +"\t\t[ -z postrotate-command ] [ -Z user ] [ expression ]\n"); } -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */ diff --git a/contrib/tcpdump/timeval-operations.h b/contrib/tcpdump/timeval-operations.h index 4f4e85c7ba..177027db03 100644 --- a/contrib/tcpdump/timeval-operations.h +++ b/contrib/tcpdump/timeval-operations.h @@ -30,19 +30,14 @@ /* Operations on timevals. */ -#ifndef _MICRO_PER_SEC -#define _MICRO_PER_SEC 1000000 -#endif - -#ifndef _NANO_PER_SEC -#define _NANO_PER_SEC 1000000000 -#endif +#define ND_MICRO_PER_SEC 1000000 +#define ND_NANO_PER_SEC 1000000000 #define netdissect_timevalclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0) #define netdissect_timevalisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) -#define netdissect_timevalcmp(tvp, uvp, cmp) \ +#define netdissect_timevalcmp(tvp, uvp, cmp) \ (((tvp)->tv_sec == (uvp)->tv_sec) ? \ ((tvp)->tv_usec cmp (uvp)->tv_usec) : \ ((tvp)->tv_sec cmp (uvp)->tv_sec)) @@ -52,14 +47,14 @@ (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \ (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \ if (nano_prec) { \ - if ((vvp)->tv_usec >= _NANO_PER_SEC) { \ + if ((vvp)->tv_usec >= ND_NANO_PER_SEC) { \ (vvp)->tv_sec++; \ - (vvp)->tv_usec -= _NANO_PER_SEC; \ + (vvp)->tv_usec -= ND_NANO_PER_SEC; \ } \ } else { \ - if ((vvp)->tv_usec >= _MICRO_PER_SEC) { \ + if ((vvp)->tv_usec >= ND_MICRO_PER_SEC) { \ (vvp)->tv_sec++; \ - (vvp)->tv_usec -= _MICRO_PER_SEC; \ + (vvp)->tv_usec -= ND_MICRO_PER_SEC; \ } \ } \ } while (0) @@ -70,8 +65,8 @@ (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ if ((vvp)->tv_usec < 0) { \ (vvp)->tv_sec--; \ - (vvp)->tv_usec += (nano_prec ? _NANO_PER_SEC : \ - _MICRO_PER_SEC); \ + (vvp)->tv_usec += (nano_prec ? ND_NANO_PER_SEC : \ + ND_MICRO_PER_SEC); \ } \ } while (0) diff --git a/contrib/tcpdump/udp.h b/contrib/tcpdump/udp.h index 409cc59e45..70d3315ae8 100644 --- a/contrib/tcpdump/udp.h +++ b/contrib/tcpdump/udp.h @@ -38,21 +38,15 @@ * Per RFC 768, September, 1981. */ struct udphdr { - uint16_t uh_sport; /* source port */ - uint16_t uh_dport; /* destination port */ - uint16_t uh_ulen; /* udp length */ - uint16_t uh_sum; /* udp checksum */ + nd_uint16_t uh_sport; /* source port */ + nd_uint16_t uh_dport; /* destination port */ + nd_uint16_t uh_ulen; /* udp length */ + nd_uint16_t uh_sum; /* udp checksum */ }; #ifndef NAMESERVER_PORT #define NAMESERVER_PORT 53 #endif -#ifndef TACACS_DB_PORT -#define TACACS_DB_PORT 65 /*XXX*/ -#endif -#ifndef ORACLE_SQLNET_PORT -#define ORACLE_SQLNET_PORT 66 /*XXX*/ -#endif #ifndef BOOTPS_PORT #define BOOTPS_PORT 67 /* RFC951 */ #endif @@ -77,41 +71,17 @@ struct udphdr { #ifndef NETBIOS_DGRAM_PORT #define NETBIOS_DGRAM_PORT 138 /* RFC 1001, RFC 1002 */ #endif -#ifndef NETBIOS_SSN_PORT -#define NETBIOS_SSN_PORT 139 /* RFC 1001, RFC 1002 */ -#endif #ifndef SNMP_PORT #define SNMP_PORT 161 /*XXX*/ #endif #ifndef SNMPTRAP_PORT #define SNMPTRAP_PORT 162 /*XXX*/ #endif -#ifndef BGP_PORT -#define BGP_PORT 179 /*XXX*/ -#endif -#ifndef APPLETALK_RTMP_PORT -#define APPLETALK_RTMP_PORT 201 /*XXX*/ -#endif -#ifndef APPLETALK_NB_PORT -#define APPLETALK_NB_PORT 202 /*XXX*/ -#endif -#ifndef APPLETALK_ECHO -#define APPLETALK_ECHO 204 /*XXX*/ -#endif -#ifndef APPLETALK_ZONE_INFO_PORT -#define APPLETALK_ZONE_INFO_PORT 206 /*XXX*/ -#endif -#ifndef LDAP_PORT -#define LDAP_PORT 389 /*XXX*/ +#ifndef PTP_EVENT_PORT +#define PTP_EVENT_PORT 319 /* IANA */ #endif -#ifndef HTTPS_PORT -#define HTTPS_PORT 443 /*XXX*/ -#endif -#ifndef MICROSOFT_DS_PORT -#define MICROSOFT_DS_PORT 445 /*XXX*/ -#endif -#ifndef KERBEROS5_PASSWD_PORT -#define KERBEROS5_PASSWD_PORT 464 /* PER IANA */ +#ifndef PTP_GENERAL_PORT +#define PTP_GENERAL_PORT 320 /* IANA */ #endif #ifndef CISCO_AUTORP_PORT #define CISCO_AUTORP_PORT 496 /*XXX*/ @@ -131,27 +101,15 @@ struct udphdr { #ifndef TIMED_PORT #define TIMED_PORT 525 /*XXX*/ #endif -#ifndef KERBEROS_LOGIN_PORT -#define KERBEROS_LOGIN_PORT 543 /*XXX*/ -#endif -#ifndef KERBEROS_SHELL_PORT -#define KERBEROS_SHELL_PORT 544 /*XXX*/ -#endif #ifndef DHCP6_SERV_PORT #define DHCP6_SERV_PORT 546 /*XXX*/ #endif #ifndef DHCP6_CLI_PORT #define DHCP6_CLI_PORT 547 /*XXX*/ #endif -#ifndef LDAPS_PORT -#define LDAPS_PORT 636 /*XXX - LDAP over TLS/SSL */ -#endif #ifndef LDP_PORT #define LDP_PORT 646 #endif -#ifndef DHCP_FAILOVER_PORT -#define DHCP_FAILOVER_PORT 647 /*XXX*/ -#endif #ifndef AQDV_PORT #define AODV_PORT 654 /*XXX*/ #endif @@ -161,36 +119,12 @@ struct udphdr { #ifndef LMP_PORT #define LMP_PORT 701 /* rfc4204 */ #endif -#ifndef CISCO_TDP_PORT -#define CISCO_TDP_PORT 711 /*XXX*/ -#endif -#ifndef KERBEROS_ADM_PORT -#define KERBEROS_ADM_PORT 749 /*XXX - Kerberos v5 */ -#endif #ifndef KERBEROS_SEC_PORT #define KERBEROS_SEC_PORT 750 /*XXX - Kerberos v4 */ #endif -#ifndef RSYNC_PORT -#define RSYNC_PORT 873 /*XXX*/ -#endif #ifndef LWRES_PORT #define LWRES_PORT 921 /*XXX*/ #endif -#ifndef OPENSSL_PORT -#define OPENSSL_PORT 1194 /*XXX*/ -#endif -#ifndef LOTUS_NOTES_PORT -#define LOTUS_NOTES_PORT 1352 /*XXX*/ -#endif -#ifndef MS_SQL_SERVER_PORT -#define MS_SQL_SERVER_PORT 1433 /*XXX*/ -#endif -#ifndef MS_SQL_SERVER_MONITOR -#define MS_SQL_SERVER_MONITOR 1434 /*XXX*/ -#endif -#ifndef INGRESLOCK_PORT -#define INGRESLOCK_PORT 1524 /*XXX*/ -#endif #ifndef VQP_PORT #define VQP_PORT 1589 /*XXX*/ #endif @@ -215,29 +149,20 @@ struct udphdr { #ifndef HSRP_PORT #define HSRP_PORT 1985 /*XXX*/ #endif -#ifndef NFS_DAEMON_PORT -#define NFS_DAEMON_PORT 2049 /*XXX*/ -#endif #ifndef ZEPHYR_SRV_PORT #define ZEPHYR_SRV_PORT 2103 /*XXX*/ #endif #ifndef ZEPHYR_CLI_PORT #define ZEPHYR_CLT_PORT 2104 /*XXX*/ #endif -#ifndef MYSQL_PORT -#define MYSQL_PORT 3306 /*XXX*/ -#endif -#ifndef MS_RDP_PORT -#define MS_RDP_PORT 3389 /*XXX*/ -#endif #ifndef VAT_PORT #define VAT_PORT 3456 /*XXX*/ #endif #ifndef MPLS_LSP_PING_PORT #define MPLS_LSP_PING_PORT 3503 /* draft-ietf-mpls-lsp-ping-02.txt */ #endif -#ifndef SUBVERSION_PORT -#define SUBVERSION_PORT 3690 /*XXX*/ +#ifndef BCM_LI_PORT +#define BCM_LI_PORT 49152 /* SDK default */ #endif #ifndef BFD_CONTROL_PORT #define BFD_CONTROL_PORT 3784 /* RFC 5881 */ @@ -248,9 +173,6 @@ struct udphdr { #ifndef RADIUS_COA_PORT #define RADIUS_COA_PORT 3799 /* RFC 5176 */ #endif -#ifndef NFS_LOCK_DAEMON_PORT -#define NFS_LOCK_DAEMON_PORT 4045 /*XXX*/ -#endif #ifndef LISP_CONTROL_PORT #define LISP_CONTROL_PORT 4342 /* RFC 6830 */ #endif @@ -260,15 +182,15 @@ struct udphdr { #ifndef WB_PORT #define WB_PORT 4567 #endif +#ifndef BFD_MULTIHOP_PORT +#define BFD_MULTIHOP_PORT 4784 /* RFC 5883 */ +#endif #ifndef VXLAN_PORT #define VXLAN_PORT 4789 /* RFC 7348 */ #endif #ifndef VXLAN_GPE_PORT #define VXLAN_GPE_PORT 4790 /* draft-ietf-nvo3-vxlan-gpe-01 */ #endif -#ifndef SIP_DS_PORT -#define SIP_DS_PORT 5059 /*XXX*/ -#endif #ifndef SIP_PORT #define SIP_PORT 5060 #endif @@ -282,7 +204,10 @@ struct udphdr { #define GENEVE_PORT 6081 /* draft-gross-geneve-02 */ #endif #ifndef SFLOW_PORT -#define SFLOW_PORT 6343 /* http://www.sflow.org/developers/specifications.php */ +#define SFLOW_PORT 6343 /* https://sflow.org/developers/specifications.php */ +#endif +#ifndef MPLS_PORT +#define MPLS_PORT 6635 /* RFC 7510 */ #endif #ifndef BABEL_PORT #define BABEL_PORT 6696 /* RFC 6126 errata */ @@ -290,6 +215,9 @@ struct udphdr { #ifndef BABEL_PORT_OLD #define BABEL_PORT_OLD 6697 /* RFC 6126 */ #endif +#ifndef BFD_LAG_PORT +#define BFD_LAG_PORT 6784 /* RFC 7310 */ +#endif #ifndef RX_PORT_LOW #define RX_PORT_LOW 7000 /*XXX*/ #endif @@ -314,3 +242,9 @@ struct udphdr { #ifndef LWAPP_CONTROL_PORT #define LWAPP_CONTROL_PORT 12223 /* RFC 5412 */ #endif +#ifndef ZEP_PORT +#define ZEP_PORT 17754 /* XXX */ +#endif +#ifndef SOMEIP_PORT +#define SOMEIP_PORT 30490 /* https://www.autosar.org/standards/foundation */ +#endif diff --git a/contrib/tcpdump/util-print.c b/contrib/tcpdump/util-print.c index 0e30d7900d..6f8f61d143 100644 --- a/contrib/tcpdump/util-print.c +++ b/contrib/tcpdump/util-print.c @@ -36,38 +36,33 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif -#include +#include "netdissect-stdinc.h" #include #ifdef HAVE_FCNTL_H #include #endif -#include #include #include #include #include +#include "netdissect-ctype.h" + #include "netdissect.h" +#include "extract.h" #include "ascii_strcasecmp.h" #include "timeval-operations.h" -int32_t thiszone; /* seconds offset from gmt to local time */ -/* invalid string to print '(invalid)' for malformed or corrupted packets */ -const char istr[] = " (invalid)"; - -/* - * timestamp display buffer size, the biggest size of both formats is needed - * sizeof("0000000000.000000000") > sizeof("00:00:00.000000000") - */ -#define TS_BUF_SIZE sizeof("0000000000.000000000") - #define TOKBUFSIZE 128 +enum date_flag { WITHOUT_DATE = 0, WITH_DATE = 1 }; +enum time_flag { UTC_TIME = 0, LOCAL_TIME = 1 }; + /* * Print out a character, filtering out the non-printable ones */ @@ -76,50 +71,31 @@ fn_print_char(netdissect_options *ndo, u_char c) { if (!ND_ISASCII(c)) { c = ND_TOASCII(c); - ND_PRINT((ndo, "M-")); + ND_PRINT("M-"); } - if (!ND_ISPRINT(c)) { + if (!ND_ASCII_ISPRINT(c)) { c ^= 0x40; /* DEL to ?, others to alpha */ - ND_PRINT((ndo, "^")); + ND_PRINT("^"); } - ND_PRINT((ndo, "%c", c)); + ND_PRINT("%c", c); } /* - * Print out a null-terminated filename (or other ascii string). - * If ep is NULL, assume no truncation check is needed. - * Return true if truncated. - * Stop at ep (if given) or before the null char, whichever is first. + * Print a null-terminated string, filtering out non-printable characters. + * DON'T USE IT with a pointer on the packet buffer because there is no + * truncation check. For this use, see the nd_printX() functions below. */ -int -fn_print(netdissect_options *ndo, - register const u_char *s, register const u_char *ep) +void +fn_print_str(netdissect_options *ndo, const u_char *s) { - register int ret; - register u_char c; - - ret = 1; /* assume truncated */ - while (ep == NULL || s < ep) { - c = *s++; - if (c == '\0') { - ret = 0; - break; - } - if (!ND_ISASCII(c)) { - c = ND_TOASCII(c); - ND_PRINT((ndo, "M-")); - } - if (!ND_ISPRINT(c)) { - c ^= 0x40; /* DEL to ?, others to alpha */ - ND_PRINT((ndo, "^")); - } - ND_PRINT((ndo, "%c", c)); - } - return(ret); + while (*s != '\0') { + fn_print_char(ndo, *s); + s++; + } } /* - * Print out a null-terminated filename (or other ascii string) from + * Print out a null-terminated filename (or other ASCII string) from * a fixed-length field in the packet buffer, or from what remains of * the packet. * @@ -137,11 +113,11 @@ fn_print(netdissect_options *ndo, * this will always be non-zero. Return 0 if truncated. */ u_int -fn_printztn(netdissect_options *ndo, - register const u_char *s, register u_int n, register const u_char *ep) +nd_printztn(netdissect_options *ndo, + const u_char *s, u_int n, const u_char *ep) { - register u_int bytes; - register u_char c; + u_int bytes; + u_char c; bytes = 0; for (;;) { @@ -160,162 +136,138 @@ fn_printztn(netdissect_options *ndo, break; } - c = *s++; + c = GET_U_1(s); + s++; bytes++; n--; if (c == '\0') { /* End of string */ break; } - if (!ND_ISASCII(c)) { - c = ND_TOASCII(c); - ND_PRINT((ndo, "M-")); - } - if (!ND_ISPRINT(c)) { - c ^= 0x40; /* DEL to ?, others to alpha */ - ND_PRINT((ndo, "^")); - } - ND_PRINT((ndo, "%c", c)); + fn_print_char(ndo, c); } return(bytes); } /* - * Print out a counted filename (or other ascii string). + * Print out a counted filename (or other ASCII string), part of + * the packet buffer. * If ep is NULL, assume no truncation check is needed. * Return true if truncated. * Stop at ep (if given) or after n bytes, whichever is first. */ int -fn_printn(netdissect_options *ndo, - register const u_char *s, register u_int n, register const u_char *ep) +nd_printn(netdissect_options *ndo, + const u_char *s, u_int n, const u_char *ep) { - register u_char c; + u_char c; while (n > 0 && (ep == NULL || s < ep)) { n--; - c = *s++; - if (!ND_ISASCII(c)) { - c = ND_TOASCII(c); - ND_PRINT((ndo, "M-")); - } - if (!ND_ISPRINT(c)) { - c ^= 0x40; /* DEL to ?, others to alpha */ - ND_PRINT((ndo, "^")); - } - ND_PRINT((ndo, "%c", c)); + c = GET_U_1(s); + s++; + fn_print_char(ndo, c); } return (n == 0) ? 0 : 1; } /* - * Print out a null-padded filename (or other ascii string). - * If ep is NULL, assume no truncation check is needed. - * Return true if truncated. - * Stop at ep (if given) or after n bytes or before the null char, - * whichever is first. + * Print a null-padded filename (or other ASCII string), part of + * the packet buffer, filtering out non-printable characters. + * Stop if truncated (via GET_U_1/longjmp) or after n bytes or before + * the null char, whichever occurs first. + * The suffix comes from: j:longJmp, n:after N bytes, p:null-Padded. */ -int -fn_printzp(netdissect_options *ndo, - register const u_char *s, register u_int n, - register const u_char *ep) +void +nd_printjnp(netdissect_options *ndo, const u_char *s, u_int n) { - register int ret; - register u_char c; + u_char c; - ret = 1; /* assume truncated */ - while (n > 0 && (ep == NULL || s < ep)) { - n--; - c = *s++; - if (c == '\0') { - ret = 0; + while (n > 0) { + c = GET_U_1(s); + if (c == '\0') break; - } - if (!ND_ISASCII(c)) { - c = ND_TOASCII(c); - ND_PRINT((ndo, "M-")); - } - if (!ND_ISPRINT(c)) { - c ^= 0x40; /* DEL to ?, others to alpha */ - ND_PRINT((ndo, "^")); - } - ND_PRINT((ndo, "%c", c)); + fn_print_char(ndo, c); + n--; + s++; } - return (n == 0) ? 0 : ret; } /* - * Format the timestamp + * Print the timestamp .FRAC part (Microseconds/nanoseconds) */ -static char * -ts_format(netdissect_options *ndo -#ifndef HAVE_PCAP_SET_TSTAMP_PRECISION -_U_ -#endif -, int sec, int usec, char *buf) +static void +ts_frac_print(netdissect_options *ndo, long usec) { - const char *format; - #ifdef HAVE_PCAP_SET_TSTAMP_PRECISION switch (ndo->ndo_tstamp_precision) { case PCAP_TSTAMP_PRECISION_MICRO: - format = "%02d:%02d:%02d.%06u"; + ND_PRINT(".%06u", (unsigned)usec); break; case PCAP_TSTAMP_PRECISION_NANO: - format = "%02d:%02d:%02d.%09u"; + ND_PRINT(".%09u", (unsigned)usec); break; default: - format = "%02d:%02d:%02d.{unknown}"; + ND_PRINT(".{unknown}"); break; } #else - format = "%02d:%02d:%02d.%06u"; + ND_PRINT(".%06u", (unsigned)usec); #endif - - snprintf(buf, TS_BUF_SIZE, format, - sec / 3600, (sec % 3600) / 60, sec % 60, usec); - - return buf; } /* - * Format the timestamp - Unix timeval style + * Print the timestamp as [YY:MM:DD] HH:MM:SS.FRAC. + * if time_flag == LOCAL_TIME print local time else UTC/GMT time + * if date_flag == WITH_DATE print YY:MM:DD before HH:MM:SS.FRAC */ -static char * -ts_unix_format(netdissect_options *ndo -#ifndef HAVE_PCAP_SET_TSTAMP_PRECISION -_U_ -#endif -, int sec, int usec, char *buf) +static void +ts_date_hmsfrac_print(netdissect_options *ndo, long sec, long usec, + enum date_flag date_flag, enum time_flag time_flag) { - const char *format; - -#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION - switch (ndo->ndo_tstamp_precision) { + time_t Time = sec; + struct tm *tm; + char timestr[32]; - case PCAP_TSTAMP_PRECISION_MICRO: - format = "%u.%06u"; - break; + if ((unsigned)sec & 0x80000000) { + ND_PRINT("[Error converting time]"); + return; + } - case PCAP_TSTAMP_PRECISION_NANO: - format = "%u.%09u"; - break; + if (time_flag == LOCAL_TIME) + tm = localtime(&Time); + else + tm = gmtime(&Time); - default: - format = "%u.{unknown}"; - break; + if (!tm) { + ND_PRINT("[Error converting time]"); + return; } -#else - format = "%u.%06u"; -#endif + if (date_flag == WITH_DATE) + strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", tm); + else + strftime(timestr, sizeof(timestr), "%H:%M:%S", tm); + ND_PRINT("%s", timestr); - snprintf(buf, TS_BUF_SIZE, format, - (unsigned)sec, (unsigned)usec); + ts_frac_print(ndo, usec); +} - return buf; +/* + * Print the timestamp - Unix timeval style, as SECS.FRAC. + */ +static void +ts_unix_print(netdissect_options *ndo, long sec, long usec) +{ + if ((unsigned)sec & 0x80000000) { + ND_PRINT("[Error converting time]"); + return; + } + + ND_PRINT("%u", (unsigned)sec); + ts_frac_print(ndo, usec); } /* @@ -323,12 +275,8 @@ _U_ */ void ts_print(netdissect_options *ndo, - register const struct timeval *tvp) + const struct timeval *tvp) { - register int s; - struct tm *tm; - time_t Time; - char buf[TS_BUF_SIZE]; static struct timeval tv_ref; struct timeval tv_result; int negative_offset; @@ -337,16 +285,17 @@ ts_print(netdissect_options *ndo, switch (ndo->ndo_tflag) { case 0: /* Default */ - s = (tvp->tv_sec + thiszone) % 86400; - ND_PRINT((ndo, "%s ", ts_format(ndo, s, tvp->tv_usec, buf))); + ts_date_hmsfrac_print(ndo, tvp->tv_sec, tvp->tv_usec, + WITHOUT_DATE, LOCAL_TIME); + ND_PRINT(" "); break; case 1: /* No time stamp */ break; case 2: /* Unix timeval style */ - ND_PRINT((ndo, "%s ", ts_unix_format(ndo, - tvp->tv_sec, tvp->tv_usec, buf))); + ts_unix_print(ndo, tvp->tv_sec, tvp->tv_usec); + ND_PRINT(" "); break; case 3: /* Microseconds/nanoseconds since previous packet */ @@ -375,25 +324,19 @@ ts_print(netdissect_options *ndo, else netdissect_timevalsub(tvp, &tv_ref, &tv_result, nano_prec); - ND_PRINT((ndo, (negative_offset ? "-" : " "))); - - ND_PRINT((ndo, "%s ", ts_format(ndo, - tv_result.tv_sec, tv_result.tv_usec, buf))); + ND_PRINT((negative_offset ? "-" : " ")); + ts_date_hmsfrac_print(ndo, tv_result.tv_sec, tv_result.tv_usec, + WITHOUT_DATE, UTC_TIME); + ND_PRINT(" "); if (ndo->ndo_tflag == 3) tv_ref = *tvp; /* set timestamp for previous packet */ break; - case 4: /* Default + Date */ - s = (tvp->tv_sec + thiszone) % 86400; - Time = (tvp->tv_sec + thiszone) - s; - tm = gmtime (&Time); - if (!tm) - ND_PRINT((ndo, "Date fail ")); - else - ND_PRINT((ndo, "%04d-%02d-%02d %s ", - tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, - ts_format(ndo, s, tvp->tv_usec, buf))); + case 4: /* Date + Default */ + ts_date_hmsfrac_print(ndo, tvp->tv_sec, tvp->tv_usec, + WITH_DATE, LOCAL_TIME); + ND_PRINT(" "); break; } } @@ -413,12 +356,12 @@ unsigned_relts_print(netdissect_options *ndo, const u_int *s = seconds; if (secs == 0) { - ND_PRINT((ndo, "0s")); + ND_PRINT("0s"); return; } while (secs > 0) { if (secs >= *s) { - ND_PRINT((ndo, "%d%s", secs / *s, *l)); + ND_PRINT("%u%s", secs / *s, *l); secs -= (secs / *s) * *s; } s++; @@ -436,7 +379,7 @@ signed_relts_print(netdissect_options *ndo, int32_t secs) { if (secs < 0) { - ND_PRINT((ndo, "-")); + ND_PRINT("-"); if (secs == INT32_MIN) { /* * -2^31; you can't fit its absolute value into @@ -462,6 +405,32 @@ signed_relts_print(netdissect_options *ndo, unsigned_relts_print(ndo, secs); } +/* Print the truncated string */ +void nd_print_trunc(netdissect_options *ndo) +{ + ND_PRINT(" [|%s]", ndo->ndo_protocol); +} + +/* Print the protocol name */ +void nd_print_protocol(netdissect_options *ndo) +{ + ND_PRINT("%s", ndo->ndo_protocol); +} + +/* Print the protocol name in caps (uppercases) */ +void nd_print_protocol_caps(netdissect_options *ndo) +{ + const char *p; + for (p = ndo->ndo_protocol; *p != '\0'; p++) + ND_PRINT("%c", ND_ASCII_TOUPPER(*p)); +} + +/* Print the invalid string */ +void nd_print_invalid(netdissect_options *ndo) +{ + ND_PRINT(" (invalid)"); +} + /* * this is a generic routine for printing unknown data; * we pass on the linefeed plus indentation string to @@ -469,21 +438,20 @@ signed_relts_print(netdissect_options *ndo, */ int -print_unknown_data(netdissect_options *ndo, const u_char *cp,const char *ident,int len) +print_unknown_data(netdissect_options *ndo, const u_char *cp, + const char *ident, u_int len) { - if (len < 0) { - ND_PRINT((ndo,"%sDissector error: print_unknown_data called with negative length", - ident)); - return(0); - } - if (ndo->ndo_snapend - cp < len) - len = ndo->ndo_snapend - cp; - if (len < 0) { - ND_PRINT((ndo,"%sDissector error: print_unknown_data called with pointer past end of packet", - ident)); + u_int len_to_print; + + len_to_print = len; + if (!ND_TTEST_LEN(cp, 0)) { + ND_PRINT("%sDissector error: print_unknown_data called with pointer past end of packet", + ident); return(0); } - hex_print(ndo, ident,cp,len); + if (ND_BYTES_AVAILABLE_AFTER(cp) < len_to_print) + len_to_print = ND_BYTES_AVAILABLE_AFTER(cp); + hex_print(ndo, ident, cp, len_to_print); return(1); /* everything is ok */ } @@ -491,8 +459,8 @@ print_unknown_data(netdissect_options *ndo, const u_char *cp,const char *ident,i * Convert a token value to a string; use "fmt" if not found. */ const char * -tok2strbuf(register const struct tok *lp, register const char *fmt, - register u_int v, char *buf, size_t bufsize) +tok2strbuf(const struct tok *lp, const char *fmt, + u_int v, char *buf, size_t bufsize) { if (lp != NULL) { while (lp->s != NULL) { @@ -510,10 +478,12 @@ tok2strbuf(register const struct tok *lp, register const char *fmt, /* * Convert a token value to a string; use "fmt" if not found. + * Uses tok2strbuf() on one of four local static buffers of size TOKBUFSIZE + * in round-robin fashion. */ const char * -tok2str(register const struct tok *lp, register const char *fmt, - register u_int v) +tok2str(const struct tok *lp, const char *fmt, + u_int v) { static char buf[4][TOKBUFSIZE]; static int idx = 0; @@ -526,51 +496,42 @@ tok2str(register const struct tok *lp, register const char *fmt, /* * Convert a bit token value to a string; use "fmt" if not found. - * this is useful for parsing bitfields, the output strings are seperated + * this is useful for parsing bitfields, the output strings are separated * if the s field is positive. + * + * A token matches iff it has one or more bits set and every bit that is set + * in the token is set in v. Consequently, a 0 token never matches. */ static char * -bittok2str_internal(register const struct tok *lp, register const char *fmt, - register u_int v, const char *sep) +bittok2str_internal(const struct tok *lp, const char *fmt, + u_int v, const char *sep) { static char buf[1024+1]; /* our string buffer */ char *bufp = buf; size_t space_left = sizeof(buf), string_size; - register u_int rotbit; /* this is the bit we rotate through all bitpositions */ - register u_int tokval; const char * sepstr = ""; - while (lp != NULL && lp->s != NULL) { - tokval=lp->v; /* load our first value */ - rotbit=1; - while (rotbit != 0) { - /* - * lets AND the rotating bit with our token value - * and see if we have got a match - */ - if (tokval == (v&rotbit)) { - /* ok we have found something */ - if (space_left <= 1) - return (buf); /* only enough room left for NUL, if that */ - string_size = strlcpy(bufp, sepstr, space_left); - if (string_size >= space_left) - return (buf); /* we ran out of room */ - bufp += string_size; - space_left -= string_size; - if (space_left <= 1) - return (buf); /* only enough room left for NUL, if that */ - string_size = strlcpy(bufp, lp->s, space_left); - if (string_size >= space_left) - return (buf); /* we ran out of room */ - bufp += string_size; - space_left -= string_size; - sepstr = sep; - break; - } - rotbit=rotbit<<1; /* no match - lets shift and try again */ + while (lp != NULL && lp->s != NULL) { + if (lp->v && (v & lp->v) == lp->v) { + /* ok we have found something */ + if (space_left <= 1) + return (buf); /* only enough room left for NUL, if that */ + string_size = strlcpy(bufp, sepstr, space_left); + if (string_size >= space_left) + return (buf); /* we ran out of room */ + bufp += string_size; + space_left -= string_size; + if (space_left <= 1) + return (buf); /* only enough room left for NUL, if that */ + string_size = strlcpy(bufp, lp->s, space_left); + if (string_size >= space_left) + return (buf); /* we ran out of room */ + bufp += string_size; + space_left -= string_size; + sepstr = sep; } lp++; - } + } if (bufp == buf) /* bummer - lets print the "unknown" message as advised in the fmt string if we got one */ @@ -580,22 +541,22 @@ bittok2str_internal(register const struct tok *lp, register const char *fmt, /* * Convert a bit token value to a string; use "fmt" if not found. - * this is useful for parsing bitfields, the output strings are not seperated. + * this is useful for parsing bitfields, the output strings are not separated. */ char * -bittok2str_nosep(register const struct tok *lp, register const char *fmt, - register u_int v) +bittok2str_nosep(const struct tok *lp, const char *fmt, + u_int v) { return (bittok2str_internal(lp, fmt, v, "")); } /* * Convert a bit token value to a string; use "fmt" if not found. - * this is useful for parsing bitfields, the output strings are comma seperated. + * this is useful for parsing bitfields, the output strings are comma separated. */ char * -bittok2str(register const struct tok *lp, register const char *fmt, - register u_int v) +bittok2str(const struct tok *lp, const char *fmt, + u_int v) { return (bittok2str_internal(lp, fmt, v, ", ")); } @@ -607,8 +568,8 @@ bittok2str(register const struct tok *lp, register const char *fmt, * correct for bounds-checking. */ const char * -tok2strary_internal(register const char **lp, int n, register const char *fmt, - register int v) +tok2strary_internal(const char **lp, int n, const char *fmt, + int v) { static char buf[TOKBUFSIZE]; @@ -620,6 +581,20 @@ tok2strary_internal(register const char **lp, int n, register const char *fmt, return (buf); } +const struct tok * +uint2tokary_internal(const struct uint_tokary dict[], const size_t size, + const u_int val) +{ + size_t i; + /* Try a direct lookup before the full scan. */ + if (val < size && dict[val].uintval == val) + return dict[val].tokary; /* OK if NULL */ + for (i = 0; i < size; i++) + if (dict[i].uintval == val) + return dict[i].tokary; /* OK if NULL */ + return NULL; +} + /* * Convert a 32-bit netmask to prefixlen if possible * the function returns the prefix-len; if plen == -1 @@ -698,21 +673,23 @@ fetch_token(netdissect_options *ndo, const u_char *pptr, u_int idx, u_int len, u_char *tbuf, size_t tbuflen) { size_t toklen = 0; + u_char c; for (; idx < len; idx++) { - if (!ND_TTEST(*(pptr + idx))) { + if (!ND_TTEST_1(pptr + idx)) { /* ran past end of captured data */ return (0); } - if (!isascii(*(pptr + idx))) { + c = GET_U_1(pptr + idx); + if (!ND_ISASCII(c)) { /* not an ASCII character */ return (0); } - if (isspace(*(pptr + idx))) { + if (c == ' ' || c == '\t' || c == '\r' || c == '\n') { /* end of token */ break; } - if (!isprint(*(pptr + idx))) { + if (!ND_ASCII_ISPRINT(c)) { /* not part of a command token or response code */ return (0); } @@ -720,7 +697,7 @@ fetch_token(netdissect_options *ndo, const u_char *pptr, u_int idx, u_int len, /* no room for this character and terminating '\0' */ return (0); } - tbuf[toklen] = *(pptr + idx); + tbuf[toklen] = c; toklen++; } if (toklen == 0) { @@ -734,19 +711,20 @@ fetch_token(netdissect_options *ndo, const u_char *pptr, u_int idx, u_int len, * an end-of-line (CR or LF). */ for (; idx < len; idx++) { - if (!ND_TTEST(*(pptr + idx))) { + if (!ND_TTEST_1(pptr + idx)) { /* ran past end of captured data */ break; } - if (*(pptr + idx) == '\r' || *(pptr + idx) == '\n') { + c = GET_U_1(pptr + idx); + if (c == '\r' || c == '\n') { /* end of line */ break; } - if (!isascii(*(pptr + idx)) || !isprint(*(pptr + idx))) { + if (!ND_ASCII_ISPRINT(c)) { /* not a printable ASCII character */ break; } - if (!isspace(*(pptr + idx))) { + if (c != ' ' && c != '\t' && c != '\r' && c != '\n') { /* beginning of next token */ break; } @@ -761,16 +739,17 @@ fetch_token(netdissect_options *ndo, const u_char *pptr, u_int idx, u_int len, * the line ending. */ static u_int -print_txt_line(netdissect_options *ndo, const char *protoname, - const char *prefix, const u_char *pptr, u_int idx, u_int len) +print_txt_line(netdissect_options *ndo, const char *prefix, + const u_char *pptr, u_int idx, u_int len) { u_int startidx; u_int linelen; + u_char c; startidx = idx; while (idx < len) { - ND_TCHECK(*(pptr+idx)); - if (*(pptr+idx) == '\n') { + c = GET_U_1(pptr + idx); + if (c == '\n') { /* * LF without CR; end of line. * Skip the LF and print the line, with the @@ -779,14 +758,13 @@ print_txt_line(netdissect_options *ndo, const char *protoname, linelen = idx - startidx; idx++; goto print; - } else if (*(pptr+idx) == '\r') { + } else if (c == '\r') { /* CR - any LF? */ if ((idx+1) >= len) { /* not in this packet */ return (0); } - ND_TCHECK(*(pptr+idx+1)); - if (*(pptr+idx+1) == '\n') { + if (GET_U_1(pptr + idx + 1) == '\n') { /* * CR-LF; end of line. * Skip the CR-LF and print the line, with @@ -803,8 +781,7 @@ print_txt_line(netdissect_options *ndo, const char *protoname, * it. */ return (0); - } else if (!isascii(*(pptr+idx)) || - (!isprint(*(pptr+idx)) && *(pptr+idx) != '\t')) { + } else if (!ND_ASCII_ISPRINT(c) && c != '\t') { /* * Not a printable ASCII character and not a tab; * treat this as if it were binary data, and @@ -819,32 +796,38 @@ print_txt_line(netdissect_options *ndo, const char *protoname, * All printable ASCII, but no line ending after that point * in the buffer; treat this as if it were truncated. */ -trunc: linelen = idx - startidx; - ND_PRINT((ndo, "%s%.*s[!%s]", prefix, (int)linelen, pptr + startidx, - protoname)); + ND_PRINT("%s%.*s", prefix, (int)linelen, pptr + startidx); + nd_print_trunc(ndo); return (0); print: - ND_PRINT((ndo, "%s%.*s", prefix, (int)linelen, pptr + startidx)); + ND_PRINT("%s%.*s", prefix, (int)linelen, pptr + startidx); return (idx); } +/* Assign needed before calling txtproto_print(): ndo->ndo_protocol = "proto" */ void txtproto_print(netdissect_options *ndo, const u_char *pptr, u_int len, - const char *protoname, const char **cmds, u_int flags) + const char **cmds, u_int flags) { u_int idx, eol; u_char token[MAX_TOKEN+1]; const char *cmd; - int is_reqresp = 0; - const char *pnp; + int print_this = 0; if (cmds != NULL) { /* * This protocol has more than just request and * response lines; see whether this looks like a - * request or response. + * request or response and, if so, print it and, + * in verbose mode, print everything after it. + * + * This is for HTTP-like protocols, where we + * want to print requests and responses, but + * don't want to print continuations of request + * or response bodies in packets that don't + * contain the request or response line. */ idx = fetch_token(ndo, pptr, 0, len, token, sizeof(token)); if (idx != 0) { @@ -852,7 +835,7 @@ txtproto_print(netdissect_options *ndo, const u_char *pptr, u_int len, while ((cmd = *cmds++) != NULL) { if (ascii_strcasecmp((const char *)token, cmd) == 0) { /* Yes. */ - is_reqresp = 1; + print_this = 1; break; } } @@ -871,31 +854,37 @@ txtproto_print(netdissect_options *ndo, const u_char *pptr, u_int len, sizeof(token)); } if (idx != 0) { - if (isdigit(token[0]) && isdigit(token[1]) && - isdigit(token[2]) && token[3] == '\0') { + if (ND_ASCII_ISDIGIT(token[0]) && ND_ASCII_ISDIGIT(token[1]) && + ND_ASCII_ISDIGIT(token[2]) && token[3] == '\0') { /* Yes. */ - is_reqresp = 1; + print_this = 1; } } } } else { /* - * This protocol has only request and response lines - * (e.g., FTP, where all the data goes over a - * different connection); assume the payload is - * a request or response. + * Either: + * + * 1) This protocol has only request and response lines + * (e.g., FTP, where all the data goes over a different + * connection); assume the payload is a request or + * response. + * + * or + * + * 2) This protocol is just text, so that we should + * always, at minimum, print the first line and, + * in verbose mode, print all lines. */ - is_reqresp = 1; + print_this = 1; } - /* Capitalize the protocol name */ - for (pnp = protoname; *pnp != '\0'; pnp++) - ND_PRINT((ndo, "%c", toupper((u_char)*pnp))); + nd_print_protocol_caps(ndo); - if (is_reqresp) { + if (print_this) { /* * In non-verbose mode, just print the protocol, followed - * by the first line as the request or response info. + * by the first line. * * In verbose mode, print lines as text until we run out * of characters or see something that's not a @@ -907,45 +896,52 @@ txtproto_print(netdissect_options *ndo, const u_char *pptr, u_int len, * request or response; just print the length * on the first line of the output. */ - ND_PRINT((ndo, ", length: %u", len)); + ND_PRINT(", length: %u", len); for (idx = 0; - idx < len && (eol = print_txt_line(ndo, protoname, "\n\t", pptr, idx, len)) != 0; + idx < len && (eol = print_txt_line(ndo, "\n\t", pptr, idx, len)) != 0; idx = eol) ; } else { /* * Just print the first text line. */ - print_txt_line(ndo, protoname, ": ", pptr, 0, len); + print_txt_line(ndo, ": ", pptr, 0, len); } } } -void -safeputs(netdissect_options *ndo, - const u_char *s, const u_int maxlen) -{ - u_int idx = 0; - - while (idx < maxlen && *s) { - safeputchar(ndo, *s); - idx++; - s++; - } -} - -void -safeputchar(netdissect_options *ndo, - const u_char c) -{ - ND_PRINT((ndo, (c < 0x80 && ND_ISPRINT(c)) ? "%c" : "\\0x%02x", c)); -} - -#ifdef LBL_ALIGN +#if (defined(__i386__) || defined(_M_IX86) || defined(__X86__) || defined(__x86_64__) || defined(_M_X64)) || \ + (defined(__arm__) || defined(_M_ARM) || defined(__aarch64__)) || \ + (defined(__m68k__) && (!defined(__mc68000__) && !defined(__mc68010__))) || \ + (defined(__ppc__) || defined(__ppc64__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PPC64)) || \ + (defined(__s390__) || defined(__s390x__) || defined(__zarch__)) || \ + defined(__vax__) /* - * Some compilers try to optimize memcpy(), using the alignment constraint - * on the argument pointer type. by using this function, we try to avoid the - * optimization. + * The procesor natively handles unaligned loads, so just use memcpy() + * and memcmp(), to enable those optimizations. + * + * XXX - are those all the x86 tests we need? + * XXX - do we need to worry about ARMv1 through ARMv5, which didn't + * support unaligned loads, and, if so, do we need to worry about all + * of them, or just some of them, e.g. ARMv5? + * XXX - are those the only 68k tests we need not to generated + * unaligned accesses if the target is the 68000 or 68010? + * XXX - are there any tests we don't need, because some definitions are for + * compilers that also predefine the GCC symbols? + * XXX - do we need to test for both 32-bit and 64-bit versions of those + * architectures in all cases? + */ +#else +/* + * The processor doesn't natively handle unaligned loads, + * and the compiler might "helpfully" optimize memcpy() + * and memcmp(), when handed pointers that would normally + * be properly aligned, into sequences that assume proper + * alignment. + * + * Do copies and compares of possibly-unaligned data by + * calling routines that wrap memcpy() and memcmp(), to + * prevent that optimization. */ void unaligned_memcpy(void *p, const void *q, size_t l) diff --git a/contrib/tcpdump/ether.h b/contrib/tcpdump/varattrs.h similarity index 61% rename from contrib/tcpdump/ether.h rename to contrib/tcpdump/varattrs.h index 6491678978..b3c168914a 100644 --- a/contrib/tcpdump/ether.h +++ b/contrib/tcpdump/varattrs.h @@ -1,5 +1,6 @@ +/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ /* - * Copyright (c) 1982, 1986, 1993 + * 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 @@ -12,11 +13,11 @@ * 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 product includes software developed by the Computer Systems + * Engineering Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory 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 @@ -29,29 +30,30 @@ * 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. - * - * @(#)if_ether.h 8.3 (Berkeley) 5/2/95 */ -#define ETHERMTU 1500 +#ifndef varattrs_h +#define varattrs_h -/* - * The number of bytes in an ethernet (MAC) address. - */ -#define ETHER_ADDR_LEN 6 +#include "compiler-tests.h" /* - * Structure of an Ethernet header. + * Attributes to apply to variables, using various compiler-specific + * extensions. */ -struct ether_header { - uint8_t ether_dhost[ETHER_ADDR_LEN]; - uint8_t ether_shost[ETHER_ADDR_LEN]; - uint16_t ether_length_type; -}; -/* - * Length of an Ethernet header; note that some compilers may pad - * "struct ether_header" to a multiple of 4 bytes, for example, so - * "sizeof (struct ether_header)" may not give the right answer. - */ -#define ETHER_HDRLEN 14 +#if __has_attribute(unused) \ + || ND_IS_AT_LEAST_GNUC_VERSION(2,0) + /* + * Compiler with support for __attribute__((unused)), or GCC 2.0 and + * later, so it supports __attribute__((unused)). + */ + #define _U_ __attribute__((unused)) +#else + /* + * We don't know of any way to mark a variable as unused. + */ + #define _U_ +#endif + +#endif -- 2.41.0