From ad0c9114e00a9a30168e0c13c17d8f65571aa67f Mon Sep 17 00:00:00 2001 From: glebius Date: Fri, 10 Feb 2017 07:22:12 +0000 Subject: Merge r309649, r313048, r313083, r313104: tcpdump 4.9.0 --- contrib/tcpdump/.cvsignore | 12 - contrib/tcpdump/CHANGES | 190 +++- contrib/tcpdump/CONTRIBUTING | 103 ++ contrib/tcpdump/CREDITS | 7 +- contrib/tcpdump/INSTALL.txt | 103 +- contrib/tcpdump/Makefile.in | 68 +- contrib/tcpdump/PLATFORMS | 9 + contrib/tcpdump/README | 1 + contrib/tcpdump/VERSION | 2 +- contrib/tcpdump/addrtoname.c | 246 +++-- contrib/tcpdump/addrtoname.h | 32 +- contrib/tcpdump/addrtostr.c | 214 ++++ contrib/tcpdump/addrtostr.h | 42 + contrib/tcpdump/af.c | 5 +- contrib/tcpdump/af.h | 6 +- contrib/tcpdump/ascii_strcasecmp.c | 105 ++ contrib/tcpdump/ascii_strcasecmp.h | 33 + contrib/tcpdump/atmuni31.h | 85 -- contrib/tcpdump/bpf_dump.c | 5 +- contrib/tcpdump/checksum.c | 13 +- contrib/tcpdump/config.h.in | 39 +- contrib/tcpdump/configure | 1199 ++++++++++---------- contrib/tcpdump/configure.in | 419 +++---- contrib/tcpdump/cpack.c | 19 +- contrib/tcpdump/cpack.h | 10 +- contrib/tcpdump/ether.h | 11 +- contrib/tcpdump/ethertype.h | 4 +- contrib/tcpdump/extract.h | 31 +- contrib/tcpdump/getopt_long.h | 2 +- contrib/tcpdump/gmpls.c | 5 +- contrib/tcpdump/gmt2local.c | 3 +- contrib/tcpdump/in_cksum.c | 13 +- contrib/tcpdump/interface.h | 150 --- contrib/tcpdump/ip.h | 44 +- contrib/tcpdump/ip6.h | 7 +- contrib/tcpdump/ipproto.c | 5 +- contrib/tcpdump/ipproto.h | 3 +- contrib/tcpdump/l2vpn.c | 101 +- contrib/tcpdump/l2vpn.h | 1 + contrib/tcpdump/lbl/os-solaris2.h | 1 - contrib/tcpdump/lbl/os-sunos4.h | 2 - contrib/tcpdump/lbl/os-ultrix4.h | 1 - contrib/tcpdump/machdep.c | 2 +- contrib/tcpdump/machdep.h | 4 +- contrib/tcpdump/mib.h | 2 +- contrib/tcpdump/missing/addrinfo.h | 117 -- contrib/tcpdump/missing/datalinks.c | 2 +- contrib/tcpdump/missing/dlnames.c | 5 +- contrib/tcpdump/missing/getnameinfo.c | 276 ----- contrib/tcpdump/missing/inet_aton.c | 53 - contrib/tcpdump/missing/inet_ntop.c | 216 ---- contrib/tcpdump/missing/inet_pton.c | 49 - contrib/tcpdump/missing/snprintf.c | 2 +- contrib/tcpdump/missing/strdup.c | 2 +- contrib/tcpdump/missing/strlcat.c | 6 +- contrib/tcpdump/missing/strlcpy.c | 6 +- contrib/tcpdump/missing/strsep.c | 6 +- contrib/tcpdump/nameser.h | 14 - contrib/tcpdump/netdissect-stdinc.h | 404 +++++++ contrib/tcpdump/netdissect.c | 146 +++ contrib/tcpdump/netdissect.h | 599 +++++----- contrib/tcpdump/nfs.h | 1 - contrib/tcpdump/nfsfh.h | 4 +- contrib/tcpdump/nlpid.c | 5 +- contrib/tcpdump/oui.c | 6 +- contrib/tcpdump/oui.h | 47 +- contrib/tcpdump/parsenfsfh.c | 243 +++-- contrib/tcpdump/pcap-missing.h | 15 +- contrib/tcpdump/ppp.h | 2 - contrib/tcpdump/print-802_11.c | 1931 ++++++++++++++++++++------------- contrib/tcpdump/print-802_15_4.c | 13 +- contrib/tcpdump/print-ah.c | 20 +- contrib/tcpdump/print-ahcp.c | 84 +- contrib/tcpdump/print-aodv.c | 69 +- contrib/tcpdump/print-aoe.c | 56 +- contrib/tcpdump/print-ap1394.c | 30 +- contrib/tcpdump/print-arcnet.c | 7 +- contrib/tcpdump/print-arp.c | 25 +- contrib/tcpdump/print-ascii.c | 7 +- contrib/tcpdump/print-atalk.c | 63 +- contrib/tcpdump/print-atm.c | 152 ++- contrib/tcpdump/print-babel.c | 187 +++- contrib/tcpdump/print-beep.c | 9 +- contrib/tcpdump/print-bfd.c | 186 +++- contrib/tcpdump/print-bgp.c | 499 +++++---- contrib/tcpdump/print-bootp.c | 31 +- contrib/tcpdump/print-bt.c | 7 +- contrib/tcpdump/print-calm-fast.c | 29 +- contrib/tcpdump/print-carp.c | 7 +- contrib/tcpdump/print-cdp.c | 21 +- contrib/tcpdump/print-cfm.c | 340 +++--- contrib/tcpdump/print-chdlc.c | 11 +- contrib/tcpdump/print-cip.c | 47 +- contrib/tcpdump/print-cnfp.c | 7 +- contrib/tcpdump/print-dccp.c | 48 +- contrib/tcpdump/print-decnet.c | 134 +-- contrib/tcpdump/print-dhcp6.c | 126 ++- contrib/tcpdump/print-domain.c | 26 +- contrib/tcpdump/print-dtp.c | 36 +- contrib/tcpdump/print-dvmrp.c | 9 +- contrib/tcpdump/print-eap.c | 12 +- contrib/tcpdump/print-egp.c | 36 +- contrib/tcpdump/print-eigrp.c | 7 +- contrib/tcpdump/print-enc.c | 9 +- contrib/tcpdump/print-esp.c | 152 ++- contrib/tcpdump/print-ether.c | 180 +-- contrib/tcpdump/print-fddi.c | 62 +- contrib/tcpdump/print-forces.c | 126 +-- contrib/tcpdump/print-fr.c | 447 ++++++-- contrib/tcpdump/print-frag6.c | 10 +- contrib/tcpdump/print-ftp.c | 7 +- contrib/tcpdump/print-geneve.c | 48 +- contrib/tcpdump/print-geonet.c | 29 +- contrib/tcpdump/print-gre.c | 102 +- contrib/tcpdump/print-hncp.c | 855 +++++++++++++++ contrib/tcpdump/print-hsrp.c | 13 +- contrib/tcpdump/print-http.c | 9 +- contrib/tcpdump/print-icmp.c | 43 +- contrib/tcpdump/print-icmp6.c | 203 ++-- contrib/tcpdump/print-igmp.c | 15 +- contrib/tcpdump/print-igrp.c | 25 +- contrib/tcpdump/print-ip.c | 138 +-- contrib/tcpdump/print-ip6.c | 189 +++- contrib/tcpdump/print-ip6opts.c | 13 +- contrib/tcpdump/print-ipcomp.c | 60 +- contrib/tcpdump/print-ipfc.c | 58 +- contrib/tcpdump/print-ipnet.c | 13 +- contrib/tcpdump/print-ipx.c | 28 +- contrib/tcpdump/print-isakmp.c | 464 ++++---- contrib/tcpdump/print-isoclns.c | 510 ++++----- contrib/tcpdump/print-juniper.c | 39 +- contrib/tcpdump/print-krb.c | 11 +- contrib/tcpdump/print-l2tp.c | 73 +- contrib/tcpdump/print-lane.c | 11 +- contrib/tcpdump/print-ldp.c | 27 +- contrib/tcpdump/print-lisp.c | 449 ++++++++ contrib/tcpdump/print-llc.c | 246 +++-- contrib/tcpdump/print-lldp.c | 58 +- contrib/tcpdump/print-lmp.c | 23 +- contrib/tcpdump/print-loopback.c | 36 +- contrib/tcpdump/print-lspping.c | 641 +++++++---- contrib/tcpdump/print-lwapp.c | 11 +- contrib/tcpdump/print-lwres.c | 41 +- contrib/tcpdump/print-m3ua.c | 32 +- contrib/tcpdump/print-medsa.c | 196 ++++ contrib/tcpdump/print-mobile.c | 11 +- contrib/tcpdump/print-mobility.c | 62 +- contrib/tcpdump/print-mpcp.c | 9 +- contrib/tcpdump/print-mpls.c | 27 +- contrib/tcpdump/print-mptcp.c | 31 +- contrib/tcpdump/print-msdp.c | 7 +- contrib/tcpdump/print-msnlb.c | 9 +- contrib/tcpdump/print-nflog.c | 13 +- contrib/tcpdump/print-nfs.c | 136 +-- contrib/tcpdump/print-nsh.c | 185 ++++ contrib/tcpdump/print-ntp.c | 32 +- contrib/tcpdump/print-null.c | 11 +- contrib/tcpdump/print-olsr.c | 184 +++- contrib/tcpdump/print-openflow-1.0.c | 178 +-- contrib/tcpdump/print-openflow.c | 16 +- contrib/tcpdump/print-ospf.c | 148 ++- contrib/tcpdump/print-ospf6.c | 65 +- contrib/tcpdump/print-otv.c | 41 +- contrib/tcpdump/print-pflog.c | 10 +- contrib/tcpdump/print-pfsync.c | 19 +- contrib/tcpdump/print-pgm.c | 288 +++-- contrib/tcpdump/print-pim.c | 132 ++- contrib/tcpdump/print-pktap.c | 28 +- contrib/tcpdump/print-ppi.c | 54 +- contrib/tcpdump/print-ppp.c | 24 +- contrib/tcpdump/print-pppoe.c | 17 +- contrib/tcpdump/print-pptp.c | 39 +- contrib/tcpdump/print-radius.c | 56 +- contrib/tcpdump/print-raw.c | 7 +- contrib/tcpdump/print-resp.c | 538 +++++++++ contrib/tcpdump/print-rip.c | 37 +- contrib/tcpdump/print-ripng.c | 12 +- contrib/tcpdump/print-rpki-rtr.c | 53 +- contrib/tcpdump/print-rrcp.c | 71 +- contrib/tcpdump/print-rsvp.c | 173 +-- contrib/tcpdump/print-rt6.c | 32 +- contrib/tcpdump/print-rtsp.c | 9 +- contrib/tcpdump/print-rx.c | 131 +-- contrib/tcpdump/print-sctp.c | 217 ++-- contrib/tcpdump/print-sflow.c | 68 +- contrib/tcpdump/print-sip.c | 7 +- contrib/tcpdump/print-sl.c | 33 +- contrib/tcpdump/print-sll.c | 38 +- contrib/tcpdump/print-slow.c | 274 +++-- contrib/tcpdump/print-smb.c | 37 +- contrib/tcpdump/print-smtp.c | 4 +- contrib/tcpdump/print-snmp.c | 346 +++--- contrib/tcpdump/print-stp.c | 110 +- contrib/tcpdump/print-sunatm.c | 7 +- contrib/tcpdump/print-sunrpc.c | 25 +- contrib/tcpdump/print-symantec.c | 17 +- contrib/tcpdump/print-syslog.c | 7 +- contrib/tcpdump/print-tcp.c | 281 ++--- contrib/tcpdump/print-telnet.c | 21 +- contrib/tcpdump/print-tftp.c | 93 +- contrib/tcpdump/print-timed.c | 15 +- contrib/tcpdump/print-tipc.c | 30 +- contrib/tcpdump/print-token.c | 46 +- contrib/tcpdump/print-udld.c | 71 +- contrib/tcpdump/print-udp.c | 324 +++--- contrib/tcpdump/print-usb.c | 7 +- contrib/tcpdump/print-vjc.c | 18 +- contrib/tcpdump/print-vqp.c | 9 +- contrib/tcpdump/print-vrrp.c | 9 +- contrib/tcpdump/print-vtp.c | 50 +- contrib/tcpdump/print-vxlan-gpe.c | 113 ++ contrib/tcpdump/print-vxlan.c | 28 +- contrib/tcpdump/print-wb.c | 35 +- contrib/tcpdump/print-zephyr.c | 59 +- contrib/tcpdump/print-zeromq.c | 35 +- contrib/tcpdump/print.c | 484 +++++++++ contrib/tcpdump/print.h | 44 + contrib/tcpdump/rpc_auth.h | 3 +- contrib/tcpdump/rpc_msg.h | 3 +- contrib/tcpdump/rpl.h | 8 +- contrib/tcpdump/setsignal.c | 2 +- contrib/tcpdump/signature.c | 88 +- contrib/tcpdump/signature.h | 6 +- contrib/tcpdump/smb.h | 2 +- contrib/tcpdump/smbutil.c | 10 +- contrib/tcpdump/strcasecmp.c | 88 -- contrib/tcpdump/strtoaddr.c | 239 ++++ contrib/tcpdump/strtoaddr.h | 23 + contrib/tcpdump/tcp.h | 70 +- contrib/tcpdump/tcpdump-stdinc.h | 352 ------ contrib/tcpdump/tcpdump.1.in | 31 +- contrib/tcpdump/tcpdump.c | 1841 +++++++++++++++---------------- contrib/tcpdump/timeval-operations.h | 78 ++ contrib/tcpdump/udp.h | 325 +++++- contrib/tcpdump/util-print.c | 938 ++++++++++++++++ contrib/tcpdump/util.c | 890 --------------- contrib/tcpdump/vfprintf.c | 2 +- 237 files changed, 15895 insertions(+), 10520 deletions(-) delete mode 100644 contrib/tcpdump/.cvsignore create mode 100644 contrib/tcpdump/CONTRIBUTING create mode 100644 contrib/tcpdump/PLATFORMS create mode 120000 contrib/tcpdump/README create mode 100644 contrib/tcpdump/addrtostr.c create mode 100644 contrib/tcpdump/addrtostr.h create mode 100644 contrib/tcpdump/ascii_strcasecmp.c create mode 100644 contrib/tcpdump/ascii_strcasecmp.h delete mode 100644 contrib/tcpdump/atmuni31.h delete mode 100644 contrib/tcpdump/missing/addrinfo.h delete mode 100644 contrib/tcpdump/missing/getnameinfo.c delete mode 100644 contrib/tcpdump/missing/inet_aton.c delete mode 100644 contrib/tcpdump/missing/inet_ntop.c delete mode 100644 contrib/tcpdump/missing/inet_pton.c create mode 100644 contrib/tcpdump/netdissect-stdinc.h create mode 100644 contrib/tcpdump/netdissect.c create mode 100644 contrib/tcpdump/print-hncp.c create mode 100644 contrib/tcpdump/print-lisp.c create mode 100644 contrib/tcpdump/print-medsa.c create mode 100644 contrib/tcpdump/print-nsh.c create mode 100644 contrib/tcpdump/print-resp.c create mode 100644 contrib/tcpdump/print-vxlan-gpe.c create mode 100644 contrib/tcpdump/print.c create mode 100644 contrib/tcpdump/print.h delete mode 100644 contrib/tcpdump/strcasecmp.c create mode 100644 contrib/tcpdump/strtoaddr.c create mode 100644 contrib/tcpdump/strtoaddr.h delete mode 100644 contrib/tcpdump/tcpdump-stdinc.h create mode 100644 contrib/tcpdump/timeval-operations.h create mode 100644 contrib/tcpdump/util-print.c delete mode 100644 contrib/tcpdump/util.c (limited to 'contrib/tcpdump') diff --git a/contrib/tcpdump/.cvsignore b/contrib/tcpdump/.cvsignore deleted file mode 100644 index 791f14c..0000000 --- a/contrib/tcpdump/.cvsignore +++ /dev/null @@ -1,12 +0,0 @@ -version.c -Makefile -Makefile-devel.in -config.status -config.log -config.cache -config.h -.devel -stamp-h -stamp-h.in -tcpdump -autom4te.cache diff --git a/contrib/tcpdump/CHANGES b/contrib/tcpdump/CHANGES index 38769f2..7c4be17 100644 --- a/contrib/tcpdump/CHANGES +++ b/contrib/tcpdump/CHANGES @@ -1,3 +1,187 @@ +Wednesday January 18, 2017 devel.fx.lebail@orange.fr + Summary for 4.9.0 tcpdump release + General updates: + Improve separation frontend/backend (tcpdump/libnetdissect) + Don't require IPv6 library support in order to support IPv6 addresses + Introduce data types to use for integral values in packet structures + Fix display of timestamps with -tt, -ttt and -ttttt options + Fix some heap overflows found with American Fuzzy Lop by Hanno Boeck and others + (More information in the log with CVE-2016-* and CVE-2017-*) + Change the way protocols print link-layer addresses (Fix heap overflows + in CALM-FAST and GeoNetworking printers) + Pass correct caplen value to ether_print() and some other functions + Fix lookup_nsap() to match what isonsap_string() expects + Clean up relative time stamp printing (Fix an array overflow) + Fix some alignment issues with GCC on Solaris 10 SPARC + Add some ND_TTEST_/ND_TCHECK_ macros to simplify writing bounds checks + Add a fn_printztn() which returns the number of bytes processed + Add nd_init() and nd_cleanup() functions. Improve libsmi support + Add CONTRIBUTING file + Add a summary comment in all printers + Compile with more warning options in devel mode if supported (-Wcast-qual, ...) + Fix some leaks found by Valgrind/Memcheck + Fix a bunch of de-constifications + Squelch some Coverity warnings and some compiler warnings + Update Coverity and Travis-CI setup + Update Visual Studio files + + Frontend: + Fix capsicum support to work with zerocopy buffers in bpf + Try opening interfaces by name first, then by name-as-index + Work around pcap_create() failures fetching time stamp type lists + Fix a segmentation fault with 'tcpdump -J' + Improve addrtostr6() bounds checking + Add exit_tcpdump() function + Don't drop CAP_SYS_CHROOT before chrooting + Fixes issue where statistics not reported when -G and -W options used + + New printers supporting: + Generic Protocol Extension for VXLAN (VXLAN-GPE) + Home Networking Control Protocol (HNCP), RFCs 7787 and 7788 + Locator/Identifier Separation Protocol (LISP), type 3 and type 4 packets + Marvell Extended Distributed Switch Architecture header (MEDSA) + Network Service Header (NSH) + REdis Serialization Protocol (RESP) + + Updated printers: + 802.11: Beginnings of 11ac radiotap support + 802.11: Check the Protected bit for management frames + 802.11: Do bounds checking on last_presentp before dereferencing it (Fix a heap overflow) + 802.11: Fix the radiotap printer to handle the special bits correctly + 802.11: If we have the MCS field, it's 11n + 802.11: Only print unknown frame type or subtype messages once + 802.11: Radiotap dBm values get printed as dB; Update a test output accordingly + 802.11: Source and destination addresses were backwards + AH: Add a bounds check + AH: Report to our caller that dissection failed if a bounds check fails + AP1394: Print src > dst, not dst > src + ARP: Don't assume the target hardware address is <= 6 octets long (Fix a heap overflow) + ATALK: Add bounds and length checks (Fix heap overflows) + ATM: Add some bounds checks (Fix a heap overflow) + ATM: Fix an incorrect bounds check + BFD: Update specification from draft to RFC 5880 + BFD: Update to print optional authentication field + BGP: Add decoding of ADD-PATH capability + BGP: Add support for the AIGP attribute (RFC7311) + BGP: Print LARGE_COMMUNITY Path Attribute + BGP: Update BGP numbers from IANA; Print minor values for FSM notification + BOOTP: Add a bounds check + Babel: Add decoder for source-specific extension + CDP: Filter out non-printable characters + CFM: Fixes to match the IEEE standard, additional bounds and length checks + CSLIP: Add more bounds checks (Fix a heap overflow) + ClassicalIPoATM: Add a bounds check on LLC+SNAP header (Fix a heap overflow) + DHCP: Fix MUDURL and TZ options + DHCPv6: Process MUDURL and TZ options + DHCPv6: Update Status Codes with RFCs/IANA names + DNS: Represent the "DNSSEC OK" bit as "DO" instead of "OK". Add a test case + DTP: Improve packet integrity checks + EGP: Fix bounds checks + ESP: Don't use OpenSSL_add_all_algorithms() in OpenSSL 1.1.0 or later + ESP: Handle OpenSSL 1.1.x + Ethernet: Add some bounds checking before calling isoclns_print (Fix a heap overflow) + Ethernet: Print the Length/Type field as length when needed + FDDI: Fix -e output for FDDI + FR: Add some packet-length checks and improve Q.933 printing (Fix heap overflows) + GRE: Add some bounds checks (Fix heap overflows) + Geneve: Fix error message with invalid option length; Update list option classes + HNCP: Fix incorrect time interval format. Fix handling of IPv4 prefixes + ICMP6: Fetch a 32-bit big-endian quantity with EXTRACT_32BITS() + ICMP6: dagid is always an IPv6 address, not an opaque 128-bit string + IGMP: Add a length check + IP: Add a bounds check (Fix a heap overflow) + IP: Check before fetching the protocol version (Fix a heap overflow) + IP: Don't try to dissect if IP version != 4 (Fix a heap overflow) + IP: Stop processing IPPROTO_ values once we hit IPPROTO_IPCOMP + IPComp: Check whether we have the CPI before we fetch it (Fix a heap overflow) + IPoFC: Fix -e output (IP-over-Fibre Channel) + IPv6: Don't overwrite the destination IPv6 address for routing headers + IPv6: Fix header printing + IPv6: Stop processing IPPROTO_ values once we hit IPPROTO_IPCOMP + ISAKMP: Clean up parsing of IKEv2 Security Associations + ISOCLNS/IS-IS: Add support for Purge Originator Identifier (RFC6232) and test cases + ISOCLNS/IS-IS: Don't overwrite packet data when checking the signature + ISOCLNS/IS-IS: Filter out non-printable characters + ISOCLNS/IS-IS: Fix segmentation faults + ISOCLNS/IS-IS: Have signature_verify() do the copying and clearing + ISOCLNS: Add some bounds checks + Juniper: Make sure a Juniper header TLV isn't bigger than what's left in the packet (Fix a heap overflow) + LLC/SNAP: With -e, print the LLC header before the SNAP header; without it, cut the SNAP header + LLC: Add a bounds check (Fix a heap overflow) + LLC: Clean up printing of LLC packets + LLC: Fix the printing of RFC 948-style IP packets + LLC: Skip the LLC and SNAP headers with -x for 802.11 and some other protocols + LLDP: Implement IANA OUI and LLDP MUD option + MPLS LSP ping: Update printing for RFC 4379, bug fixes, more bounds checks + MPLS: "length" is now the *remaining* packet length + MPLS: Add bounds and length checks (Fix a heap overflow) + NFS: Add a test that makes unaligned accesses + NFS: Don't assume the ONC RPC header is nicely aligned + NFS: Don't overflow the Opaque_Handle buffer (Fix a segmentation fault) + NFS: Don't run past the end of an NFSv3 file handle + OLSR: Add a test to cover a HNA sgw case + OLSR: Fix 'Advertised networks' count + OLSR: Fix printing of smart-gateway HNAs in IPv4 + OSPF: Add a bounds check for the Hello packet options + OSPF: Do more bounds checking + OSPF: Fix a segmentation fault + OSPF: Fix printing 'ospf_topology_values' default + OTV: Add missing bounds checks + PGM: Print the formatted IP address, not the raw binary address, as a string + PIM: Add some bounds checking (Fix a heap overflow) + PIMv2: Fix checksumming of Register messages + PPI: Pass an adjusted struct pcap_pkthdr to the sub-printer + PPP: Add some bounds checks (Fix a heap overflow) + PPP: Report invalid PAP AACK/ANAK packets + Q.933: Add a missing bounds check + RADIUS: Add Value 13 "VLAN" to Tunnel-Type attribute + RADIUS: Filter out non-printable characters + RADIUS: Translate UDP/1700 as RADIUS + RESP: Do better checking of RESP packets + RPKI-RTR: Add a return value check for "fn_printn" call + RPKI-RTR: Remove printing when truncated condition already detected + RPL: Fix 'Consistency Check' control code + RPL: Fix suboption print + RSVP: An INTEGRITY object in a submessage covers only the submessage + RSVP: Fix an infinite loop; Add bounds and length checks + RSVP: Fix some if statements missing brackets + RSVP: Have signature_verify() do the copying and clearing + RTCP: Add some bounds checks + RTP: Add some bounds checks, fix two segmentation faults + SCTP: Do more bounds checking + SFLOW: Fix bounds checking + SLOW: Fix bugs, add checks + SMB: Before fetching the flags2 field, make sure we have it + SMB: Do bounds checks on NBNS resource types and resource data lengths + SNMP: Clean up the "have libsmi but no modules loaded" case + SNMP: Clean up the object abbreviation list and fix the code to match them + SNMP: Do bounds checks when printing character and octet strings + SNMP: Improve ASN.1 bounds checks + SNMP: More bounds and length checks + STP: Add a bunch of bounds checks, and fix some printing (Fix heap overflows) + STP: Filter out non-printable characters + TCP: Add bounds and length checks for packets with TCP option 20 + TCP: Correct TCP option Kind value for TCP Auth and add SCPS-TP + TCP: Fix two bounds checks (Fix heap overflows) + TCP: Make sure we have the data offset field before fetching it (Fix a heap overflow) + TCP: Put TCP-AO option decoding right + TFTP: Don't use strchr() to scan packet data (Fix a heap overflow) + Telnet: Add some bounds checks + TokenRing: Fix -e output + UDLD: Fix an infinite loop + UDP: Add a bounds check (Fix a heap overflow) + UDP: Check against the packet length first + UDP: Don't do the DDP-over-UDP heuristic check up front + VAT: Add some bounds checks + VTP: Add a test on Mgmt Domain Name length + VTP: Add bounds checks and filter out non-printable characters + VXLAN: Add a bound check and a test case + ZeroMQ: Fix an infinite loop + +Tuesday April 14, 2015 guy@alum.mit.edu + Summary for 4.8.0 tcpdump release + Fix "-x" for Apple PKTAP and PPI packets + Friday April 10, 2015 guy@alum.mit.edu Summary for 4.7.4 tcpdump release RPKI to Router Protocol: Fix Segmentation Faults and other problems @@ -464,10 +648,10 @@ Wed. November 12, 2003. mcr@sandelman.ottawa.on.ca. Summary for 3.8 release Tuesday, February 25, 2003. fenner@research.att.com. 3.7.2 release - Fixed infinite loop when parsing malformed isakmp packets. + Fixed infinite loop when parsing invalid isakmp packets. (reported by iDefense; already fixed in CVS) - Fixed infinite loop when parsing malformed BGP packets. - Fixed buffer overflow with certain malformed NFS packets. + Fixed infinite loop when parsing invalid BGP packets. + Fixed buffer overflow with certain invalid NFS packets. Pretty-print unprintable network names in 802.11 printer. Handle truncated nbp (appletalk) packets. Updated DHCPv6 printer to match draft-ietf-dhc-dhcpv6-22.txt diff --git a/contrib/tcpdump/CONTRIBUTING b/contrib/tcpdump/CONTRIBUTING new file mode 100644 index 0000000..5d3b46e --- /dev/null +++ b/contrib/tcpdump/CONTRIBUTING @@ -0,0 +1,103 @@ +Some Information for Contributors +--------------------------------- +You want to contribute to Tcpdump, Thanks! +Please, read these lines. + +1) Fork the Tcpdump repository on GitHub from + https://github.com/the-tcpdump-group/tcpdump + (See https://help.github.com/articles/fork-a-repo/) + +2) Setup an optional Travis-CI build + You can setup a travis build for your fork. So, you can test your changes + on Linux and OSX before sending pull requests. + (See http://docs.travis-ci.com/user/getting-started/) + +3) Clone your repository + git clone https://github.com//tcpdump.git + +4) Do a 'touch .devel' in your working directory. + Currently, the effect is + a) add (via configure, in Makefile) some warnings options ( -Wall + -Wmissing-prototypes -Wstrict-prototypes, ...) to the compiler if it + supports these options, + b) have the Makefile support "make depend" and the configure script run it. + +5) Configure and build + ./configure && make -s && make check + +6) Add/update sample.pcap files + We use tests directory to do regression tests on the dissection of captured + packets, by running tcpdump against a savefile sample.pcap, created with -w + option and comparing the results with a text file sample.out giving the + expected results. + + Any new/updated fields in a dissector must be present in a sample.pcap file + and the corresponding output file. + + Configuration is set in tests/TESTLIST. + Each line in this file has the following format: + test-name sample.pcap sample.out tcpdump-options + + the sample.out file can be build by: + (cd tests && ../tcpdump -n -r sample.pcap tcpdump-options > sample.out) + + It is often useful to have test outputs with different verbosity levels + (none, -v, -vv, -vvv, etc.) depending on the code. + +7) Test with 'make check' + Don't send a pull request if 'make check' gives failed tests. + +8) Rebase your commits against upstream/master + (To keep linearity) + +9) Initiate and send a pull request + (See https://help.github.com/articles/using-pull-requests/) + +Some remarks +------------ +a) A thorough reading of some other printers code is useful. + +b) Put the normative reference if any as comments (RFC, etc.). + +c) Put the format of packets/headers/options as comments. + +d) The printer may receive incomplete packet in the buffer, truncated at any + random position, for example by capturing with '-s size' option. + Thus use ND_TTEST, ND_TTEST2, ND_TCHECK or ND_TCHECK2 for bound checking. + For ND_TCHECK2: + Define : static const char tstr[] = " [|protocol]"; + Define a label: trunc + Print with: ND_PRINT((ndo, "%s", tstr)); + You can test the code via: + sudo ./tcpdump -s snaplen [-v][v][...] -i lo # in a terminal + sudo tcpreplay -i lo sample.pcap # in another terminal + You should try several values for snaplen to do various truncation. + +e) Do invalid packet checks in code: Think that your code can receive in input + not only a valid packet but any arbitrary random sequence of octets (packet + - built malformed originally by the sender or by a fuzz tester, + - became corrupted in transit). + Print with: ND_PRINT((ndo, "%s", istr)); /* to print " (invalid)" */ + +f) Use 'struct tok' for indexed strings and print them with + tok2str() or bittok2str() (for flags). + +g) Avoid empty lines in output of printers. + +h) A commit message must have: + First line: Capitalized short summary in the imperative (70 chars or less) + + Body: Detailed explanatory text, if necessary. Fold it to approximately + 72 characters. There must be an empty line separating the summary from + the body. + +i) Avoid non-ASCII characters in code and commit messages. + +j) Use the style of the modified sources. + +k) Don't mix declarations and code + +l) Don't use // for comments + Not all C compilers accept C++/C99 comments by default. + +m) Avoid trailing tabs/spaces diff --git a/contrib/tcpdump/CREDITS b/contrib/tcpdump/CREDITS index a21311a..5242967 100644 --- a/contrib/tcpdump/CREDITS +++ b/contrib/tcpdump/CREDITS @@ -20,11 +20,13 @@ Additional people who have contributed patches: Andrea Bittau Andrew Brown Andrew Church + Andrew Darqui Andrew Hintz Andrew Nording Andrew Tridgell Andy Heffernan Anton Bernal + Antonin Décimo Arkadiusz Miskiewicz Armando L. Caro Jr. Arnaldo Carvalho de Melo @@ -33,6 +35,7 @@ Additional people who have contributed patches: Ben Byer Ben Smithurst Bert Vermeulen + Bill Parker Bjoern A. Zeeb Bram Brent L. Bates @@ -95,6 +98,7 @@ Additional people who have contributed patches: Jason R. Thorpe Jefferson Ogata Jeffrey Hutzelman + Jean-Raphaël Gaglione Jesper Peterson Jesse Gross Jim Hutchins @@ -119,7 +123,7 @@ Additional people who have contributed patches: Larry Lile Lennert Buytenhek Loganaden Velvindron - Longinus00 + Daniel Lee Loris Degioanni Love Hörnquist-Ã…strand Lucas C. Villa Real @@ -134,6 +138,7 @@ Additional people who have contributed patches: Markus Schöpflin Marshall Rose Martin Husemann + Matthieu Boutier Max Laier Michael A. Meffie III Michael Madore diff --git a/contrib/tcpdump/INSTALL.txt b/contrib/tcpdump/INSTALL.txt index dcb52b8..f91d004 100644 --- a/contrib/tcpdump/INSTALL.txt +++ b/contrib/tcpdump/INSTALL.txt @@ -49,9 +49,10 @@ addrtoname.c - address to hostname routines addrtoname.h - address to hostname definitions ah.h - IPSEC Authentication Header definitions appletalk.h - AppleTalk definitions +ascii_strcasecmp.c - locale-independent case-independent string comparison + routines atime.awk - TCP ack awk script atm.h - ATM traffic type definitions -atmuni31.h - ATM Q.2931 definitions bpf_dump.c - BPF program printing routines, in case libpcap doesn't have them chdlc.h - Cisco HDLC definitions @@ -100,100 +101,8 @@ pcap_dump_ftell.c - pcap_dump_ftell() implementation, in case libpcap doesn't have it pcap-missing.h - declarations of functions possibly missing from libpcap ppp.h - Point to Point Protocol definitions -print-802_11.c - IEEE 802.11 printer routines -print-ap1394.c - Apple IP-over-IEEE 1394 printer routines -print-ah.c - IPSEC Authentication Header printer routines -print-aodv.c - AODV printer routines -print-arcnet.c - ARCNET printer routines -print-arp.c - Address Resolution Protocol printer routines -print-ascii.c - ASCII packet dump routines -print-atalk.c - AppleTalk printer routines -print-atm.c - ATM printer routines -print-beep.c - BEEP printer routines -print-bgp.c - Border Gateway Protocol printer routines -print-bootp.c - BOOTP and IPv4 DHCP printer routines -print-bt.c - Bluetooth printer routines -print-cdp.c - Cisco Discovery Protocol printer routines -print-chdlc.c - Cisco HDLC printer routines -print-cip.c - Classical-IP over ATM routines -print-cnfp.c - Cisco NetFlow printer routines -print-dccp.c - DCCP printer routines -print-decnet.c - DECnet printer routines -print-dhcp6.c - IPv6 DHCP printer routines -print-domain.c - Domain Name System printer routines -print-dvmrp.c - Distance Vector Multicast Routing Protocol printer routines -print-eap.c - EAP printer routines -print-enc.c - OpenBSD IPsec encapsulation BPF layer printer routines -print-egp.c - External Gateway Protocol printer routines -print-esp.c - IPSEC Encapsulating Security Payload printer routines -print-ether.c - Ethernet printer routines -print-fddi.c - Fiber Distributed Data Interface printer routines -print-fr.c - Frame Relay printer routines -print-frag6.c - IPv6 fragmentation header printer routines -print-gre.c - Generic Routing Encapsulation printer routines -print-hsrp.c - Cisco Hot Standby Router Protocol printer routines -print-icmp.c - Internet Control Message Protocol printer routines -print-icmp6.c - IPv6 Internet Control Message Protocol printer routines -print-igmp.c - Internet Group Management Protocol printer routines -print-igrp.c - Interior Gateway Routing Protocol printer routines -print-ip.c - IP printer routines -print-ip6.c - IPv6 printer routines -print-ip6opts.c - IPv6 header option printer routines -print-ipcomp.c - IP Payload Compression Protocol printer routines -print-ipx.c - IPX printer routines -print-isakmp.c - Internet Security Association and Key Management Protocol -print-isoclns.c - ISO CLNS, ESIS, and ISIS printer routines -print-krb.c - Kerberos printer routines -print-l2tp.c - Layer Two Tunneling Protocol printer routines -print-lane.c - ATM LANE printer routines -print-llc.c - IEEE 802.2 LLC printer routines -print-lspping.c - LSPPING printer routines -print-lwres.c - Lightweight Resolver protocol printer routines -print-mobile.c - IPv4 mobility printer routines -print-mobility.c - IPv6 mobility printer routines -print-mpls.c - Multi-Protocol Label Switching printer routines -print-msdp.c - Multicast Source Discovery Protocol printer routines -print-nfs.c - Network File System printer routines -print-ntp.c - Network Time Protocol printer routines -print-null.c - BSD loopback device printer routines -print-ospf.c - Open Shortest Path First printer routines -print-ospf6.c - IPv6 Open Shortest Path First printer routines -print-pflog.c - OpenBSD packet filter log file printer routines -print-pgm.c - Pragmatic General Multicast printer routines -print-pim.c - Protocol Independent Multicast printer routines -print-ppp.c - Point to Point Protocol printer routines -print-pppoe.c - PPP-over-Ethernet printer routines -print-pptp.c - Point-to-Point Tunnelling Protocol printer routines -print-radius.c - Radius protocol printer routines -print-raw.c - Raw IP printer routines -print-rip.c - Routing Information Protocol printer routines -print-ripng.c - IPv6 Routing Information Protocol printer routines -print-rrcp.c - Realtek Remote Control Protocol routines -print-rsvp.c - Resource reSerVation Protocol (RSVP) printer routines -print-rt6.c - IPv6 routing header printer routines -print-rx.c - AFS RX printer routines -print-sctp.c - Stream Control Transmission Protocol printer routines -print-sip.c - SIP printer routines -print-sl.c - Compressed Serial Line Internet Protocol printer routines -print-sll.c - Linux "cooked" capture printer routines -print-slow.c - IEEE "slow protocol" (802.3ad) printer routines -print-smb.c - SMB/CIFS printer routines -print-snmp.c - Simple Network Management Protocol printer routines -print-stp.c - IEEE 802.1d spanning tree protocol printer routines -print-sunatm.c - SunATM DLPI capture printer routines -print-sunrpc.c - Sun Remote Procedure Call printer routines -print-symantec.c - Symantec Enterprise Firewall printer routines -print-tcp.c - TCP printer routines -print-telnet.c - Telnet option printer routines -print-tftp.c - Trivial File Transfer Protocol printer routines -print-timed.c - BSD time daemon protocol printer routines -print-token.c - Token Ring printer routines -print-udp.c - UDP printer routines -print-usb.c - USB printer routines -print-vjc.c - PPP Van Jacobson compression (RFC1144) printer routines -print-vrrp.c - Virtual Router Redundancy Protocol -print-wb.c - White Board printer routines -print-zephyr.c - Zephyr printer routines +print.c - Top-level routines for protocol printing +print-*.c - The netdissect printers rpc_auth.h - definitions for ONC RPC authentication rpc_msg.h - definitions for ONC RPC messages send-ack.awk - unidirectional tcp send/ack awk script @@ -203,11 +112,11 @@ slcompress.h - SLIP/PPP Van Jacobson compression (RFC1144) definitions smb.h - SMB/CIFS definitions smbutil.c - SMB/CIFS utility routines stime.awk - TCP send awk script -strcasecmp.c - missing routine tcp.h - TCP definitions tcpdump.1 - manual entry tcpdump.c - main program +timeval-operations.h - timeval operations macros udp.h - UDP definitions -util.c - utility routines +util-print.c - utility routines for protocol printers vfprintf.c - emulation routine win32 - headers and routines for building on Win32 systems diff --git a/contrib/tcpdump/Makefile.in b/contrib/tcpdump/Makefile.in index 1004a5d..c18d5ed 100644 --- a/contrib/tcpdump/Makefile.in +++ b/contrib/tcpdump/Makefile.in @@ -74,7 +74,9 @@ CSRC = setsignal.c tcpdump.c LIBNETDISSECT_SRC=\ addrtoname.c \ + addrtostr.c \ af.c \ + ascii_strcasecmp.c \ checksum.c \ cpack.c \ gmpls.c \ @@ -86,6 +88,7 @@ LIBNETDISSECT_SRC=\ nlpid.c \ oui.c \ parsenfsfh.c \ + print.c \ print-802_11.c \ print-802_15_4.c \ print-ah.c \ @@ -98,6 +101,7 @@ LIBNETDISSECT_SRC=\ print-ascii.c \ print-atalk.c \ print-atm.c \ + print-babel.c \ print-beep.c \ print-bfd.c \ print-bgp.c \ @@ -112,6 +116,7 @@ LIBNETDISSECT_SRC=\ print-cnfp.c \ print-dccp.c \ print-decnet.c \ + print-dhcp6.c \ print-domain.c \ print-dtp.c \ print-dvmrp.c \ @@ -124,17 +129,21 @@ LIBNETDISSECT_SRC=\ print-fddi.c \ print-forces.c \ print-fr.c \ + print-frag6.c \ print-ftp.c \ print-geneve.c \ print-geonet.c \ print-gre.c \ + print-hncp.c \ print-hsrp.c \ print-http.c \ print-icmp.c \ + print-icmp6.c \ print-igmp.c \ print-igrp.c \ print-ip.c \ print-ip6.c \ + print-ip6opts.c \ print-ipcomp.c \ print-ipfc.c \ print-ipnet.c \ @@ -146,6 +155,7 @@ LIBNETDISSECT_SRC=\ print-l2tp.c \ print-lane.c \ print-ldp.c \ + print-lisp.c \ print-llc.c \ print-lldp.c \ print-lmp.c \ @@ -154,7 +164,9 @@ LIBNETDISSECT_SRC=\ print-lwapp.c \ print-lwres.c \ print-m3ua.c \ + print-medsa.c \ print-mobile.c \ + print-mobility.c \ print-mpcp.c \ print-mpls.c \ print-mptcp.c \ @@ -162,12 +174,14 @@ LIBNETDISSECT_SRC=\ print-msnlb.c \ print-nflog.c \ print-nfs.c \ + print-nsh.c \ print-ntp.c \ print-null.c \ print-olsr.c \ print-openflow-1.0.c \ print-openflow.c \ print-ospf.c \ + print-ospf6.c \ print-otv.c \ print-pgm.c \ print-pim.c \ @@ -178,10 +192,13 @@ LIBNETDISSECT_SRC=\ print-pptp.c \ print-radius.c \ print-raw.c \ + print-resp.c \ print-rip.c \ + print-ripng.c \ print-rpki-rtr.c \ print-rrcp.c \ print-rsvp.c \ + print-rt6.c \ print-rtsp.c \ print-rx.c \ print-sctp.c \ @@ -211,11 +228,14 @@ LIBNETDISSECT_SRC=\ print-vrrp.c \ print-vtp.c \ print-vxlan.c \ + print-vxlan-gpe.c \ print-wb.c \ print-zephyr.c \ print-zeromq.c \ + netdissect.c \ signature.c \ - util.c + strtoaddr.c \ + util-print.c LOCALSRC = @LOCALSRC@ GENSRC = version.c @@ -232,11 +252,12 @@ SRC = $(CSRC) $(GENSRC) $(LOCALSRC) $(LIBNETDISSECT_SRC) OBJ = $(CSRC:.c=.o) $(GENSRC:.c=.o) $(LIBNETDISSECT_OBJ) HDR = \ addrtoname.h \ + addrtostr.h \ af.h \ ah.h \ appletalk.h \ + ascii_strcasecmp.h \ atm.h \ - atmuni31.h \ chdlc.h \ cpack.h \ ether.h \ @@ -264,6 +285,7 @@ HDR = \ oui.h \ pcap-missing.h \ ppp.h \ + print.h \ rpc_auth.h \ rpc_msg.h \ rpl.h \ @@ -271,14 +293,15 @@ HDR = \ signature.h \ slcompress.h \ smb.h \ + strtoaddr.h \ tcp.h \ - tcpdump-stdinc.h \ + netdissect-stdinc.h \ + timeval-operations.h \ udp.h TAGHDR = \ /usr/include/arpa/tftp.h \ /usr/include/net/if_arp.h \ - /usr/include/net/slip.h \ /usr/include/netinet/if_ether.h \ /usr/include/netinet/in.h \ /usr/include/netinet/ip_icmp.h \ @@ -292,11 +315,14 @@ CLEANFILES = $(PROG) $(OBJ) $(GENSRC) EXTRA_DIST = \ CHANGES \ + CONTRIBUTING \ CREDITS \ INSTALL.txt \ LICENSE \ Makefile.in \ Makefile-devel-adds \ + PLATFORMS \ + README \ README.md \ Readme.Win32 \ VERSION \ @@ -314,14 +340,9 @@ EXTRA_DIST = \ lbl/os-sunos4.h \ lbl/os-ultrix4.h \ makemib \ - missing/addrinfo.h \ missing/dlnames.c \ missing/datalinks.c \ - missing/getnameinfo.c \ missing/getopt_long.c \ - missing/inet_aton.c \ - missing/inet_ntop.c \ - missing/inet_pton.c \ missing/snprintf.c \ missing/strdup.c \ missing/strlcat.c \ @@ -330,27 +351,19 @@ EXTRA_DIST = \ mkdep \ packetdat.awk \ pcap_dump_ftell.c \ - print-babel.c \ - print-dhcp6.c \ - print-frag6.c \ - print-icmp6.c \ - print-ip6opts.c \ - print-mobility.c \ - print-ospf6.c \ print-pflog.c \ - print-ripng.c \ - print-rt6.c \ print-smb.c \ send-ack.awk \ smbutil.c \ stime.awk \ - strcasecmp.c \ tcpdump.1.in \ vfprintf.c \ - win32/Include/w32_fzs.h \ win32/prj/GNUmakefile \ win32/prj/WinDump.dsp \ - win32/prj/WinDump.dsw + win32/prj/WinDump.dsw \ + win32/prj/WinDump.sln \ + win32/prj/WinDump.vcproj \ + win32/src/ether_ntohost.c TEST_DIST= `find tests \( -name 'DIFF' -prune \) -o \( -name NEW -prune \) -o -type f \! -name '.*' \! -name '*~' -print` @@ -362,23 +375,15 @@ $(PROG): $(OBJ) @V_PCAPDEP@ $(LIBNETDISSECT): $(LIBNETDISSECT_OBJ) @rm -f $@ - $(AR) $(ARFLAGS) $@ $(LIBNETDISSECT_OBJ) + $(AR) cr $@ $(LIBNETDISSECT_OBJ) $(RANLIB) $@ datalinks.o: $(srcdir)/missing/datalinks.c $(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/datalinks.c dlnames.o: $(srcdir)/missing/dlnames.c $(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/dlnames.c -getnameinfo.o: $(srcdir)/missing/getnameinfo.c - $(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/getnameinfo.c getopt_long.o: $(srcdir)/missing/getopt_long.c $(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/getopt_long.c -inet_pton.o: $(srcdir)/missing/inet_pton.c - $(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/inet_pton.c -inet_ntop.o: $(srcdir)/missing/inet_ntop.c - $(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/inet_ntop.c -inet_aton.o: $(srcdir)/missing/inet_aton.c - $(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/inet_aton.c snprintf.o: $(srcdir)/missing/snprintf.c $(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/snprintf.c strdup.o: $(srcdir)/missing/strdup.c @@ -434,6 +439,9 @@ distclean: check: tcpdump (cd tests && ./TESTrun.sh) +extags: $(TAGFILES) + ctags $(TAGFILES) + tags: $(TAGFILES) ctags -wtd $(TAGFILES) diff --git a/contrib/tcpdump/PLATFORMS b/contrib/tcpdump/PLATFORMS new file mode 100644 index 0000000..ec85e59 --- /dev/null +++ b/contrib/tcpdump/PLATFORMS @@ -0,0 +1,9 @@ +== Tested platforms == +NetBSD 5.1/i386 (mcr - 2012/4/1) +Debian Linux (squeeze/i386) (mcr - 2012/4/1) + +--- +RedHat Linux 6.1/i386 (assar) +FreeBSD 2.2.8/i386 (itojun) + + diff --git a/contrib/tcpdump/README b/contrib/tcpdump/README new file mode 120000 index 0000000..42061c0 --- /dev/null +++ b/contrib/tcpdump/README @@ -0,0 +1 @@ +README.md \ No newline at end of file diff --git a/contrib/tcpdump/VERSION b/contrib/tcpdump/VERSION index b48b2de..6ed7776 100644 --- a/contrib/tcpdump/VERSION +++ b/contrib/tcpdump/VERSION @@ -1 +1 @@ -4.7.4 +4.9.0 diff --git a/contrib/tcpdump/addrtoname.c b/contrib/tcpdump/addrtoname.c index 2befeae..85cbf7b 100644 --- a/contrib/tcpdump/addrtoname.c +++ b/contrib/tcpdump/addrtoname.c @@ -20,11 +20,8 @@ * * Internet, ethernet, port, and protocol string to address * and address to string conversion routines - * - * $FreeBSD$ */ -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -33,7 +30,8 @@ #include #include #endif /* HAVE_CASPER */ -#include + +#include #ifdef USE_ETHER_NTOHOST #ifdef HAVE_NETINET_IF_ETHER_H @@ -64,8 +62,10 @@ extern int ether_ntohost(char *, const struct ether_addr *); #include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" +#include "addrtostr.h" +#include "ethertype.h" #include "llc.h" #include "setsignal.h" #include "extract.h" @@ -78,7 +78,7 @@ extern int ether_ntohost(char *, const struct ether_addr *); /* * hash tables for whatever-to-name translations * - * XXX there has to be error checks against strdup(3) failure + * ndo_error() called on strdup(3) failure */ #define HASHNAMESIZE 4096 @@ -96,7 +96,7 @@ static struct hnamemem eprototable[HASHNAMESIZE]; static struct hnamemem dnaddrtable[HASHNAMESIZE]; static struct hnamemem ipxsaptable[HASHNAMESIZE]; -#if defined(INET6) && defined(WIN32) +#ifdef _WIN32 /* * fake gethostbyaddr for Win2k/XP * gethostbyaddr() returns incorrect value when AF_INET6 is passed @@ -134,9 +134,8 @@ win32_gethostbyaddr(const char *addr, int len, int type) } } #define gethostbyaddr win32_gethostbyaddr -#endif /* INET6 & WIN32 */ +#endif /* _WIN32 */ -#ifdef INET6 struct h6namemem { struct in6_addr addr; char *name; @@ -144,7 +143,6 @@ struct h6namemem { }; static struct h6namemem h6nametable[HASHNAMESIZE]; -#endif /* INET6 */ struct enamemem { u_short e_addr0; @@ -214,7 +212,7 @@ extern cap_channel_t *capdns; * * 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 TCHECK{2}/TTEST{2} macros on it. Furthermore, + * *CANNOT* use the ND_TCHECK{2}/ND_TTEST{2} 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 @@ -232,7 +230,7 @@ getname(netdissect_options *ndo, const u_char *ap) { register struct hostent *hp; uint32_t addr; - static struct hnamemem *p; /* static for longjmp() */ + struct hnamemem *p; memcpy(&addr, ap, sizeof(addr)); p = &hnametable[addr & (HASHNAMESIZE-1)]; @@ -241,7 +239,7 @@ getname(netdissect_options *ndo, const u_char *ap) return (p->name); } p->addr = addr; - p->nxt = newhnamemem(); + p->nxt = newhnamemem(ndo); /* * Print names unless: @@ -263,6 +261,9 @@ getname(netdissect_options *ndo, const u_char *ap) char *dotp; p->name = strdup(hp->h_name); + if (p->name == NULL) + (*ndo->ndo_error)(ndo, + "getname: strdup(hp->h_name)"); if (ndo->ndo_Nflag) { /* Remove domain qualifications */ dotp = strchr(p->name, '.'); @@ -273,10 +274,11 @@ 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))"); return (p->name); } -#ifdef INET6 /* * Return a name for the IP6 address pointed to by ap. This address * is assumed to be in network byte order. @@ -292,7 +294,7 @@ getname6(netdissect_options *ndo, const u_char *ap) uint16_t d; } addra; } addr; - static struct h6namemem *p; /* static for longjmp() */ + struct h6namemem *p; register const char *cp; char ntop_buf[INET6_ADDRSTRLEN]; @@ -303,7 +305,7 @@ getname6(netdissect_options *ndo, const u_char *ap) return (p->name); } p->addr = addr.addr; - p->nxt = newh6namemem(); + p->nxt = newh6namemem(ndo); /* * Do not print names if -n was given. @@ -315,11 +317,15 @@ getname6(netdissect_options *ndo, const u_char *ap) sizeof(addr), AF_INET6); } else #endif - hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET6); + 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)"); if (ndo->ndo_Nflag) { /* Remove domain qualifications */ dotp = strchr(p->name, '.'); @@ -329,11 +335,12 @@ getname6(netdissect_options *ndo, const u_char *ap) return (p->name); } } - cp = inet_ntop(AF_INET6, &addr, ntop_buf, sizeof(ntop_buf)); + cp = addrtostr6(ap, ntop_buf, sizeof(ntop_buf)); p->name = strdup(cp); + if (p->name == NULL) + (*ndo->ndo_error)(ndo, "getname6: strdup(cp)"); return (p->name); } -#endif /* INET6 */ static const char hex[] = "0123456789abcdef"; @@ -341,7 +348,7 @@ static const char hex[] = "0123456789abcdef"; /* Find the hash node that corresponds the ether address 'ep' */ static inline struct enamemem * -lookup_emem(const u_char *ep) +lookup_emem(netdissect_options *ndo, const u_char *ep) { register u_int i, j, k; struct enamemem *tp; @@ -363,7 +370,7 @@ lookup_emem(const u_char *ep) tp->e_addr2 = k; tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp)); if (tp->e_nxt == NULL) - error("lookup_emem: calloc"); + (*ndo->ndo_error)(ndo, "lookup_emem: calloc"); return tp; } @@ -374,7 +381,8 @@ lookup_emem(const u_char *ep) */ static inline struct enamemem * -lookup_bytestring(register const u_char *bs, const unsigned int nlen) +lookup_bytestring(netdissect_options *ndo, register const u_char *bs, + const unsigned int nlen) { struct enamemem *tp; register u_int i, j, k; @@ -406,12 +414,12 @@ lookup_bytestring(register const u_char *bs, const unsigned int nlen) tp->e_bs = (u_char *) calloc(1, nlen + 1); if (tp->e_bs == NULL) - error("lookup_bytestring: calloc"); + (*ndo->ndo_error)(ndo, "lookup_bytestring: calloc"); memcpy(tp->e_bs, bs, nlen); tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp)); if (tp->e_nxt == NULL) - error("lookup_bytestring: calloc"); + (*ndo->ndo_error)(ndo, "lookup_bytestring: calloc"); return tp; } @@ -419,14 +427,15 @@ lookup_bytestring(register const u_char *bs, const unsigned int nlen) /* Find the hash node that corresponds the NSAP 'nsap' */ static inline struct enamemem * -lookup_nsap(register const u_char *nsap) +lookup_nsap(netdissect_options *ndo, register const u_char *nsap, + register u_int nsap_length) { register u_int i, j, k; - unsigned int nlen = *nsap; struct enamemem *tp; - const u_char *ensap = nsap + nlen - 6; + const u_char *ensap; - if (nlen > 6) { + if (nsap_length > 6) { + ensap = nsap + nsap_length - 6; k = (ensap[0] << 8) | ensap[1]; j = (ensap[2] << 8) | ensap[3]; i = (ensap[4] << 8) | ensap[5]; @@ -439,22 +448,23 @@ lookup_nsap(register const u_char *nsap) if (tp->e_addr0 == i && tp->e_addr1 == j && tp->e_addr2 == k && - tp->e_nsap[0] == nlen && + tp->e_nsap[0] == nsap_length && memcmp((const char *)&(nsap[1]), - (char *)&(tp->e_nsap[1]), nlen) == 0) + (char *)&(tp->e_nsap[1]), nsap_length) == 0) return tp; else tp = tp->e_nxt; tp->e_addr0 = i; tp->e_addr1 = j; tp->e_addr2 = k; - tp->e_nsap = (u_char *)malloc(nlen + 1); + tp->e_nsap = (u_char *)malloc(nsap_length + 1); if (tp->e_nsap == NULL) - error("lookup_nsap: malloc"); - memcpy((char *)tp->e_nsap, (const char *)nsap, nlen + 1); + (*ndo->ndo_error)(ndo, "lookup_nsap: malloc"); + 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) - error("lookup_nsap: calloc"); + (*ndo->ndo_error)(ndo, "lookup_nsap: calloc"); return tp; } @@ -462,7 +472,7 @@ lookup_nsap(register const u_char *nsap) /* Find the hash node that corresponds the protoid 'pi'. */ static inline struct protoidmem * -lookup_protoid(const u_char *pi) +lookup_protoid(netdissect_options *ndo, const u_char *pi) { register u_int i, j; struct protoidmem *tp; @@ -482,7 +492,7 @@ lookup_protoid(const u_char *pi) tp->p_proto = j; tp->p_nxt = (struct protoidmem *)calloc(1, sizeof(*tp)); if (tp->p_nxt == NULL) - error("lookup_protoid: calloc"); + (*ndo->ndo_error)(ndo, "lookup_protoid: calloc"); return tp; } @@ -496,21 +506,18 @@ etheraddr_string(netdissect_options *ndo, register const u_char *ep) int oui; char buf[BUFSIZE]; - tp = lookup_emem(ep); + tp = lookup_emem(ndo, ep); if (tp->e_name) return (tp->e_name); #ifdef USE_ETHER_NTOHOST if (!ndo->ndo_nflag) { char buf2[BUFSIZE]; - /* - * We don't cast it to "const struct ether_addr *" - * because some systems fail to declare the second - * argument as a "const" pointer, even though they - * don't modify what it points to. - */ - if (ether_ntohost(buf2, (struct ether_addr *)ep) == 0) { + if (ether_ntohost(buf2, (const struct ether_addr *)ep) == 0) { tp->e_name = strdup(buf2); + if (tp->e_name == NULL) + (*ndo->ndo_error)(ndo, + "etheraddr_string: strdup(buf2)"); return (tp->e_name); } } @@ -531,11 +538,13 @@ etheraddr_string(netdissect_options *ndo, register const u_char *ep) } else *cp = '\0'; tp->e_name = strdup(buf); + if (tp->e_name == NULL) + (*ndo->ndo_error)(ndo, "etheraddr_string: strdup(buf)"); return (tp->e_name); } const char * -le64addr_string(const u_char *ep) +le64addr_string(netdissect_options *ndo, const u_char *ep) { const unsigned int len = 8; register u_int i; @@ -543,7 +552,7 @@ le64addr_string(const u_char *ep) register struct enamemem *tp; char buf[BUFSIZE]; - tp = lookup_bytestring(ep, len); + tp = lookup_bytestring(ndo, ep, len); if (tp->e_name) return (tp->e_name); @@ -558,12 +567,15 @@ le64addr_string(const u_char *ep) *cp = '\0'; tp->e_name = strdup(buf); + if (tp->e_name == NULL) + (*ndo->ndo_error)(ndo, "le64addr_string: strdup(buf)"); return (tp->e_name); } const char * -linkaddr_string(netdissect_options *ndo, const u_char *ep, const unsigned int type, const unsigned int len) +linkaddr_string(netdissect_options *ndo, const u_char *ep, + const unsigned int type, const unsigned int len) { register u_int i; register char *cp; @@ -578,13 +590,13 @@ linkaddr_string(netdissect_options *ndo, const u_char *ep, const unsigned int ty if (type == LINKADDR_FRELAY) return (q922_string(ndo, ep, len)); - tp = lookup_bytestring(ep, len); + tp = lookup_bytestring(ndo, ep, len); if (tp->e_name) return (tp->e_name); tp->e_name = cp = (char *)malloc(len*3); if (tp->e_name == NULL) - error("linkaddr_string: malloc"); + (*ndo->ndo_error)(ndo, "linkaddr_string: malloc"); *cp++ = hex[*ep >> 4]; *cp++ = hex[*ep++ & 0xf]; for (i = len-1; i > 0 ; --i) { @@ -597,7 +609,7 @@ linkaddr_string(netdissect_options *ndo, const u_char *ep, const unsigned int ty } const char * -etherproto_string(u_short port) +etherproto_string(netdissect_options *ndo, u_short port) { register char *cp; register struct hnamemem *tp; @@ -609,7 +621,7 @@ etherproto_string(u_short port) return (tp->name); tp->addr = i; - tp->nxt = newhnamemem(); + tp->nxt = newhnamemem(ndo); cp = buf; NTOHS(port); @@ -619,18 +631,20 @@ etherproto_string(u_short port) *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(register const u_char *pi) +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(pi); + tp = lookup_protoid(ndo, pi); if (tp->p_name) return tp->p_name; @@ -646,12 +660,15 @@ protoid_string(register const u_char *pi) } *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(const u_char *nsap, register u_int nsap_length) +isonsap_string(netdissect_options *ndo, const u_char *nsap, + register u_int nsap_length) { register u_int nsap_idx; register char *cp; @@ -660,13 +677,13 @@ isonsap_string(const u_char *nsap, register u_int nsap_length) if (nsap_length < 1 || nsap_length > ISONSAP_MAX_LENGTH) return ("isonsap_string: illegal length"); - tp = lookup_nsap(nsap); + tp = lookup_nsap(ndo, nsap, nsap_length); if (tp->e_name) return tp->e_name; tp->e_name = cp = (char *)malloc(sizeof("xx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xx")); if (cp == NULL) - error("isonsap_string: malloc"); + (*ndo->ndo_error)(ndo, "isonsap_string: malloc"); for (nsap_idx = 0; nsap_idx < nsap_length; nsap_idx++) { *cp++ = hex[*nsap >> 4]; @@ -681,7 +698,7 @@ isonsap_string(const u_char *nsap, register u_int nsap_length) } const char * -tcpport_string(u_short port) +tcpport_string(netdissect_options *ndo, u_short port) { register struct hnamemem *tp; register uint32_t i = port; @@ -692,15 +709,17 @@ tcpport_string(u_short port) return (tp->name); tp->addr = i; - tp->nxt = newhnamemem(); + tp->nxt = newhnamemem(ndo); (void)snprintf(buf, sizeof(buf), "%u", i); tp->name = strdup(buf); + if (tp->name == NULL) + (*ndo->ndo_error)(ndo, "tcpport_string: strdup(buf)"); return (tp->name); } const char * -udpport_string(register u_short port) +udpport_string(netdissect_options *ndo, register u_short port) { register struct hnamemem *tp; register uint32_t i = port; @@ -711,15 +730,17 @@ udpport_string(register u_short port) return (tp->name); tp->addr = i; - tp->nxt = newhnamemem(); + tp->nxt = newhnamemem(ndo); (void)snprintf(buf, sizeof(buf), "%u", i); tp->name = strdup(buf); + if (tp->name == NULL) + (*ndo->ndo_error)(ndo, "udpport_string: strdup(buf)"); return (tp->name); } const char * -ipxsap_string(u_short port) +ipxsap_string(netdissect_options *ndo, u_short port) { register char *cp; register struct hnamemem *tp; @@ -731,7 +752,7 @@ ipxsap_string(u_short port) return (tp->name); tp->addr = i; - tp->nxt = newhnamemem(); + tp->nxt = newhnamemem(ndo); cp = buf; NTOHS(port); @@ -741,6 +762,8 @@ ipxsap_string(u_short port) *cp++ = hex[port & 0xf]; *cp++ = '\0'; tp->name = strdup(buf); + if (tp->name == NULL) + (*ndo->ndo_error)(ndo, "ipxsap_string: strdup(buf)"); return (tp->name); } @@ -769,25 +792,44 @@ init_servarray(netdissect_options *ndo) table->name = strdup(buf); } else table->name = strdup(sv->s_name); + if (table->name == NULL) + (*ndo->ndo_error)(ndo, "init_servarray: strdup"); + table->addr = port; - table->nxt = newhnamemem(); + table->nxt = newhnamemem(ndo); } endservent(); } -/* in libpcap.a (nametoaddr.c) */ -#if defined(WIN32) && !defined(USE_STATIC_LIBPCAP) -extern __declspec(dllimport) -#else -extern -#endif -const struct eproto { +static const struct eproto { const char *s; u_short p; -} eproto_db[]; +} eproto_db[] = { + { "pup", ETHERTYPE_PUP }, + { "xns", ETHERTYPE_NS }, + { "ip", ETHERTYPE_IP }, + { "ip6", ETHERTYPE_IPV6 }, + { "arp", ETHERTYPE_ARP }, + { "rarp", ETHERTYPE_REVARP }, + { "sprite", ETHERTYPE_SPRITE }, + { "mopdl", ETHERTYPE_MOPDL }, + { "moprc", ETHERTYPE_MOPRC }, + { "decnet", ETHERTYPE_DN }, + { "lat", ETHERTYPE_LAT }, + { "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(void) +init_eprotoarray(netdissect_options *ndo) { register int i; register struct hnamemem *table; @@ -799,7 +841,7 @@ init_eprotoarray(void) table = table->nxt; table->name = eproto_db[i].s; table->addr = htons(eproto_db[i].p); - table->nxt = newhnamemem(); + table->nxt = newhnamemem(ndo); } } @@ -820,7 +862,7 @@ static const struct protoidlist { * types. */ static void -init_protoidarray(void) +init_protoidarray(netdissect_options *ndo) { register int i; register struct protoidmem *tp; @@ -834,12 +876,15 @@ init_protoidarray(void) u_short etype = htons(eproto_db[i].p); memcpy((char *)&protoid[3], (char *)&etype, 2); - tp = lookup_protoid(protoid); + 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)"); } /* Hardwire some SNAP proto ID names */ for (pl = protoidlist; pl->name != NULL; ++pl) { - tp = lookup_protoid(pl->protoid); + tp = lookup_protoid(ndo, pl->protoid); /* Don't override existing name */ if (tp->p_name != NULL) continue; @@ -871,7 +916,7 @@ static const struct etherlist { * translation, so we just pcap_next_etherent as a convenience. */ static void -init_etherarray(void) +init_etherarray(netdissect_options *ndo) { register const struct etherlist *el; register struct enamemem *tp; @@ -885,8 +930,11 @@ init_etherarray(void) fp = fopen(PCAP_ETHERS_FILE, "r"); if (fp != NULL) { while ((ep = pcap_next_etherent(fp)) != NULL) { - tp = lookup_emem(ep->addr); + 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)"); } (void)fclose(fp); } @@ -894,7 +942,7 @@ init_etherarray(void) /* Hardwire some ethernet names */ for (el = etherlist; el->name != NULL; ++el) { - tp = lookup_emem(el->addr); + tp = lookup_emem(ndo, el->addr); /* Don't override existing name */ if (tp->e_name != NULL) continue; @@ -902,14 +950,12 @@ init_etherarray(void) #ifdef USE_ETHER_NTOHOST /* * Use YP/NIS version of name if available. - * - * We don't cast it to "const struct ether_addr *" - * because some systems don't modify the Ethernet - * address but fail to declare the second argument - * as a "const" pointer. */ - if (ether_ntohost(name, (struct ether_addr *)el->addr) == 0) { + if (ether_ntohost(name, (const struct ether_addr *)el->addr) == 0) { tp->e_name = strdup(name); + if (tp->e_name == NULL) + (*ndo->ndo_error)(ndo, + "init_etherarray: strdup(name)"); continue; } #endif @@ -1135,7 +1181,7 @@ static const struct tok ipxsap_db[] = { }; static void -init_ipxsaparray(void) +init_ipxsaparray(netdissect_options *ndo) { register int i; register struct hnamemem *table; @@ -1147,7 +1193,7 @@ init_ipxsaparray(void) table = table->nxt; table->name = ipxsap_db[i].s; table->addr = htons(ipxsap_db[i].v); - table->nxt = newhnamemem(); + table->nxt = newhnamemem(ndo); } } @@ -1170,11 +1216,11 @@ init_addrtoname(netdissect_options *ndo, uint32_t localnet, uint32_t mask) */ return; - init_etherarray(); + init_etherarray(ndo); init_servarray(ndo); - init_eprotoarray(); - init_protoidarray(); - init_ipxsaparray(); + init_eprotoarray(ndo); + init_protoidarray(ndo); + init_ipxsaparray(ndo); } const char * @@ -1182,24 +1228,24 @@ dnaddr_string(netdissect_options *ndo, u_short dnaddr) { register struct hnamemem *tp; - for (tp = &dnaddrtable[dnaddr & (HASHNAMESIZE-1)]; tp->nxt != 0; + for (tp = &dnaddrtable[dnaddr & (HASHNAMESIZE-1)]; tp->nxt != NULL; tp = tp->nxt) if (tp->addr == dnaddr) return (tp->name); tp->addr = dnaddr; - tp->nxt = newhnamemem(); + tp->nxt = newhnamemem(ndo); if (ndo->ndo_nflag) - tp->name = dnnum_string(dnaddr); + tp->name = dnnum_string(ndo, dnaddr); else - tp->name = dnname_string(dnaddr); + tp->name = dnname_string(ndo, dnaddr); return(tp->name); } /* Return a zero'ed hnamemem struct and cuts down on calloc() overhead */ struct hnamemem * -newhnamemem(void) +newhnamemem(netdissect_options *ndo) { register struct hnamemem *p; static struct hnamemem *ptr = NULL; @@ -1209,17 +1255,16 @@ newhnamemem(void) num = 64; ptr = (struct hnamemem *)calloc(num, sizeof (*ptr)); if (ptr == NULL) - error("newhnamemem: calloc"); + (*ndo->ndo_error)(ndo, "newhnamemem: calloc"); } --num; p = ptr++; return (p); } -#ifdef INET6 /* Return a zero'ed h6namemem struct and cuts down on calloc() overhead */ struct h6namemem * -newh6namemem(void) +newh6namemem(netdissect_options *ndo) { register struct h6namemem *p; static struct h6namemem *ptr = NULL; @@ -1229,13 +1274,12 @@ newh6namemem(void) num = 64; ptr = (struct h6namemem *)calloc(num, sizeof (*ptr)); if (ptr == NULL) - error("newh6namemem: calloc"); + (*ndo->ndo_error)(ndo, "newh6namemem: calloc"); } --num; p = ptr++; return (p); } -#endif /* INET6 */ /* Represent TCI part of the 802.1Q 4-octet tag as text. */ const char * diff --git a/contrib/tcpdump/addrtoname.h b/contrib/tcpdump/addrtoname.h index b07d8b2..72e5ef1 100644 --- a/contrib/tcpdump/addrtoname.h +++ b/contrib/tcpdump/addrtoname.h @@ -19,6 +19,14 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ +/* + * Definitions to let us compile most of the IPv6 code even on systems + * without IPv6 support. + */ +#ifndef INET6_ADDRSTRLEN +#define INET6_ADDRSTRLEN 46 +#endif + /* Name to address translation routines. */ enum { @@ -32,28 +40,22 @@ enum { 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(const u_char *); -extern const char *etherproto_string(u_short); -extern const char *tcpport_string(u_short); -extern const char *udpport_string(u_short); -extern const char *isonsap_string(const u_char *, register u_int); +extern const char *le64addr_string(netdissect_options *, const u_char *); +extern const char *etherproto_string(netdissect_options *, u_short); +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 *dnaddr_string(netdissect_options *, u_short); -extern const char *protoid_string(const u_char *); -extern const char *ipxsap_string(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 *); -#ifdef INET6 extern const char *getname6(netdissect_options *, const u_char *); -#endif extern const char *intoa(uint32_t); extern void init_addrtoname(netdissect_options *, uint32_t, uint32_t); -extern struct hnamemem *newhnamemem(void); -#ifdef INET6 -extern struct h6namemem *newh6namemem(void); -#endif +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)) -#ifdef INET6 #define ip6addr_string(ndo, p) getname6(ndo, (const u_char *)(p)) -#endif diff --git a/contrib/tcpdump/addrtostr.c b/contrib/tcpdump/addrtostr.c new file mode 100644 index 0000000..fd331a3 --- /dev/null +++ b/contrib/tcpdump/addrtostr.c @@ -0,0 +1,214 @@ +/* + * Copyright (c) 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * 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 Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "addrtostr.h" + +#include +#include + +/* + * + */ + +#ifndef IN6ADDRSZ +#define IN6ADDRSZ 16 /* IPv6 T_AAAA */ +#endif + +#ifndef INT16SZ +#define INT16SZ 2 /* word size */ +#endif + +const char * +addrtostr (const void *src, char *dst, size_t size) +{ + const u_char *srcaddr = (const u_char *)src; + const char digits[] = "0123456789"; + int i; + const char *orig_dst = dst; + + if (size < INET_ADDRSTRLEN) { + errno = ENOSPC; + return NULL; + } + for (i = 0; i < 4; ++i) { + int n = *srcaddr++; + int non_zerop = 0; + + if (non_zerop || n / 100 > 0) { + *dst++ = digits[n / 100]; + n %= 100; + non_zerop = 1; + } + if (non_zerop || n / 10 > 0) { + *dst++ = digits[n / 10]; + n %= 10; + non_zerop = 1; + } + *dst++ = digits[n]; + if (i != 3) + *dst++ = '.'; + } + *dst++ = '\0'; + return orig_dst; +} + +/* + * Convert IPv6 binary address into presentation (printable) format. + */ +const char * +addrtostr6 (const void *src, char *dst, size_t size) +{ + /* + * Note that int32_t and int16_t need only be "at least" large enough + * to contain a value of the specified size. On some systems, like + * Crays, there is no such thing as an integer variable with 16 bits. + * Keep this in mind if you think this function should have been coded + * to use pointer overlays. All the world's not a VAX. + */ + const u_char *srcaddr = (const u_char *)src; + char *dp; + size_t space_left, added_space; + int snprintfed; + struct { + long base; + long len; + } best, cur; + u_long words [IN6ADDRSZ / INT16SZ]; + int i; + + /* Preprocess: + * Copy the input (bytewise) array into a wordwise array. + * Find the longest run of 0x00's in src[] for :: shorthanding. + */ + memset (words, 0, sizeof(words)); + for (i = 0; i < IN6ADDRSZ; i++) + words[i/2] |= (srcaddr[i] << ((1 - (i % 2)) << 3)); + + best.len = 0; + best.base = -1; + cur.len = 0; + cur.base = -1; + for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) + { + if (words[i] == 0) + { + if (cur.base == -1) + cur.base = i, cur.len = 1; + else cur.len++; + } + else if (cur.base != -1) + { + if (best.base == -1 || cur.len > best.len) + best = cur; + cur.base = -1; + } + } + if ((cur.base != -1) && (best.base == -1 || cur.len > best.len)) + best = cur; + if (best.base != -1 && best.len < 2) + best.base = -1; + + /* Format the result. + */ + dp = dst; + space_left = size; +#define APPEND_CHAR(c) \ + { \ + if (space_left == 0) { \ + errno = ENOSPC; \ + return (NULL); \ + } \ + *dp++ = c; \ + space_left--; \ + } + for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) + { + /* Are we inside the best run of 0x00's? + */ + if (best.base != -1 && i >= best.base && i < (best.base + best.len)) + { + if (i == best.base) + APPEND_CHAR(':'); + continue; + } + + /* Are we following an initial run of 0x00s or any real hex? + */ + if (i != 0) + APPEND_CHAR(':'); + + /* Is this address an encapsulated IPv4? + */ + if (i == 6 && best.base == 0 && + (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) + { + if (!addrtostr(srcaddr+12, dp, space_left)) + { + errno = ENOSPC; + return (NULL); + } + added_space = strlen(dp); + dp += added_space; + space_left -= added_space; + break; + } + snprintfed = snprintf (dp, space_left, "%lx", words[i]); + if (snprintfed < 0) + return (NULL); + if ((size_t) snprintfed >= space_left) + { + errno = ENOSPC; + return (NULL); + } + dp += snprintfed; + space_left -= snprintfed; + } + + /* Was it a trailing run of 0x00's? + */ + if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) + APPEND_CHAR(':'); + APPEND_CHAR('\0'); + + return (dst); +} diff --git a/contrib/tcpdump/addrtostr.h b/contrib/tcpdump/addrtostr.h new file mode 100644 index 0000000..2b95a16 --- /dev/null +++ b/contrib/tcpdump/addrtostr.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * 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 Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ + +/* Address to printable string translation routines. */ + +extern const char *addrtostr(const void *src, char *dst, size_t size); +extern const char *addrtostr6(const void *src, char *dst, size_t size); diff --git a/contrib/tcpdump/af.c b/contrib/tcpdump/af.c index bea6d97..539ede5 100644 --- a/contrib/tcpdump/af.c +++ b/contrib/tcpdump/af.c @@ -15,13 +15,12 @@ * Original code by Hannes Gredler (hannes@juniper.net) */ -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include -#include "interface.h" +#include +#include "netdissect.h" #include "af.h" const struct tok af_values[] = { diff --git a/contrib/tcpdump/af.h b/contrib/tcpdump/af.h index bbe1a16..1bde577 100644 --- a/contrib/tcpdump/af.h +++ b/contrib/tcpdump/af.h @@ -50,6 +50,6 @@ extern const struct tok bsd_af_values[]; #define BSD_AFNUM_ISO 7 #define BSD_AFNUM_APPLETALK 16 #define BSD_AFNUM_IPX 23 -#define BSD_AFNUM_INET6_BSD 24 /* OpenBSD (and probably NetBSD), BSD/OS */ -#define BSD_AFNUM_INET6_FREEBSD 28 -#define BSD_AFNUM_INET6_DARWIN 30 +#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 */ diff --git a/contrib/tcpdump/ascii_strcasecmp.c b/contrib/tcpdump/ascii_strcasecmp.c new file mode 100644 index 0000000..b8decf1 --- /dev/null +++ b/contrib/tcpdump/ascii_strcasecmp.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 1987 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that this notice is preserved and that due credit is given + * to the University of California at Berkeley. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific written prior permission. This software + * is provided ``as is'' without express or implied warranty. + */ + +#include "ascii_strcasecmp.h" + +/* + * This array maps upper-case ASCII letters to their lower-case + * equivalents; all other byte values are mapped to themselves, + * so this is locale-independent and intended to be locale-independent, + * to avoid issues with, for example, "i" and "I" not being lower-case + * and upper-case versions of the same letter in Turkish, where + * there are separate "i with dot" and "i without dot" letters. + */ +static const unsigned char charmap[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +}; + +int +ascii_strcasecmp(const char *s1, const char *s2) +{ + register const unsigned char *cm = charmap, + *us1 = (const unsigned char *)s1, + *us2 = (const unsigned char *)s2; + + while (cm[*us1] == cm[*us2++]) + if (*us1++ == '\0') + return(0); + return(cm[*us1] - cm[*--us2]); +} + +int +ascii_strncasecmp(const char *s1, const char *s2, register size_t n) +{ + register const unsigned char *cm = charmap, + *us1 = (const unsigned char *)s1, + *us2 = (const unsigned char *)s2; + + for (;;) { + if (n == 0) { + /* + * We've run out of characters that we should + * compare, and they've all been equal; return + * 0, to indicate that the prefixes are the + * same. + */ + return(0); + } + if (cm[*us1] != cm[*us2++]) { + /* + * We've found a mismatch. + */ + break; + } + if (*us1++ == '\0') { + /* + * We've run out of characters *to* compare, + * and they've all been equal; return 0, to + * indicate that the strings are the same. + */ + return(0); + } + n--; + } + return(cm[*us1] - cm[*--us2]); +} diff --git a/contrib/tcpdump/ascii_strcasecmp.h b/contrib/tcpdump/ascii_strcasecmp.h new file mode 100644 index 0000000..7f8ddb9a --- /dev/null +++ b/contrib/tcpdump/ascii_strcasecmp.h @@ -0,0 +1,33 @@ +/* + * 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_ascii_strcasecmp_h +#define netdissect_ascii_strcasecmp_h + +#include + +extern int ascii_strcasecmp(const char *, const char *); +extern int ascii_strncasecmp(const char *, const char *, size_t); + +#endif /* netdissect_ascii_strcasecmp_h */ diff --git a/contrib/tcpdump/atmuni31.h b/contrib/tcpdump/atmuni31.h deleted file mode 100644 index 0f85430..0000000 --- a/contrib/tcpdump/atmuni31.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 1997 Yen Yen Lim and North Dakota State University - * 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 Yen Yen Lim and - North Dakota State University - * 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 - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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. - */ - -/* Based on UNI3.1 standard by ATM Forum */ - -/* ATM traffic types based on VPI=0 and (the following VCI */ -#define VCI_PPC 0x05 /* Point-to-point signal msg */ -#define VCI_BCC 0x02 /* Broadcast signal msg */ -#define VCI_OAMF4SC 0x03 /* Segment OAM F4 flow cell */ -#define VCI_OAMF4EC 0x04 /* End-to-end OAM F4 flow cell */ -#define VCI_METAC 0x01 /* Meta signal msg */ -#define VCI_ILMIC 0x10 /* ILMI msg */ - -/* Q.2931 signalling messages */ -#define CALL_PROCEED 0x02 /* call proceeding */ -#define CONNECT 0x07 /* connect */ -#define CONNECT_ACK 0x0f /* connect_ack */ -#define SETUP 0x05 /* setup */ -#define RELEASE 0x4d /* release */ -#define RELEASE_DONE 0x5a /* release_done */ -#define RESTART 0x46 /* restart */ -#define RESTART_ACK 0x4e /* restart ack */ -#define STATUS 0x7d /* status */ -#define STATUS_ENQ 0x75 /* status ack */ -#define ADD_PARTY 0x80 /* add party */ -#define ADD_PARTY_ACK 0x81 /* add party ack */ -#define ADD_PARTY_REJ 0x82 /* add party rej */ -#define DROP_PARTY 0x83 /* drop party */ -#define DROP_PARTY_ACK 0x84 /* drop party ack */ - -/* Information Element Parameters in the signalling messages */ -#define CAUSE 0x08 /* cause */ -#define ENDPT_REF 0x54 /* endpoint reference */ -#define AAL_PARA 0x58 /* ATM adaptation layer parameters */ -#define TRAFF_DESCRIP 0x59 /* atm traffic descriptors */ -#define CONNECT_ID 0x5a /* connection identifier */ -#define QOS_PARA 0x5c /* quality of service parameters */ -#define B_HIGHER 0x5d /* broadband higher layer information */ -#define B_BEARER 0x5e /* broadband bearer capability */ -#define B_LOWER 0x5f /* broadband lower information */ -#define CALLING_PARTY 0x6c /* calling party number */ -#define CALLED_PARTY 0x70 /* called party nmber */ - -#define Q2931 0x09 - -/* Q.2931 signalling general messages format */ -#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 */ -#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 diff --git a/contrib/tcpdump/bpf_dump.c b/contrib/tcpdump/bpf_dump.c index 2ef8528..9bad38d 100644 --- a/contrib/tcpdump/bpf_dump.c +++ b/contrib/tcpdump/bpf_dump.c @@ -19,16 +19,15 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" void bpf_dump(const struct bpf_program *p, int option) diff --git a/contrib/tcpdump/checksum.c b/contrib/tcpdump/checksum.c index d8263c7..0829fbe 100644 --- a/contrib/tcpdump/checksum.c +++ b/contrib/tcpdump/checksum.c @@ -17,19 +17,18 @@ * Original code by Hannes Gredler (hannes@juniper.net) */ -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include #include #include #include -#include "interface.h" +#include "netdissect.h" /* * CRC-10 table generated using the following Python snippet: @@ -146,17 +145,17 @@ create_osi_cksum (const uint8_t *pptr, int checksum_offset, int length) uint32_t c0; uint32_t c1; uint16_t checksum; - int index; + int idx; c0 = 0; c1 = 0; - for (index = 0; index < length; index++) { + for (idx = 0; idx < length; idx++) { /* * Ignore the contents of the checksum field. */ - if (index == checksum_offset || - index == checksum_offset+1) { + if (idx == checksum_offset || + idx == checksum_offset+1) { c1 += c0; pptr++; } else { diff --git a/contrib/tcpdump/config.h.in b/contrib/tcpdump/config.h.in index c289f00..27ba4b10 100644 --- a/contrib/tcpdump/config.h.in +++ b/contrib/tcpdump/config.h.in @@ -1,7 +1,7 @@ /* config.h.in. Generated from configure.in by autoheader. */ -/* define if you have the addrinfo function */ -#undef HAVE_ADDRINFO +/* define if you want to build the possibly-buggy SMB printer */ +#undef ENABLE_SMB /* Define to 1 if you have the `alarm' function. */ #undef HAVE_ALARM @@ -10,7 +10,7 @@ #undef HAVE_BPF_DUMP /* capsicum support available */ -#undef HAVE_CASPER +#undef HAVE_CAPSICUM /* Define to 1 if you have the `cap_enter' function. */ #undef HAVE_CAP_ENTER @@ -34,24 +34,21 @@ /* Define to 1 if you have the `ether_ntohost' function. */ #undef HAVE_ETHER_NTOHOST +/* Define to 1 if you have the `EVP_CIPHER_CTX_new' function. */ +#undef HAVE_EVP_CIPHER_CTX_NEW + /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* Define to 1 if you have the `fork' function. */ #undef HAVE_FORK -/* Define to 1 if you have the `getnameinfo' function. */ -#undef HAVE_GETNAMEINFO - /* Define to 1 if you have the `getopt_long' function. */ #undef HAVE_GETOPT_LONG /* define if you have getrpcbynumber() */ #undef HAVE_GETRPCBYNUMBER -/* define if you have the h_errno variable */ -#undef HAVE_H_ERRNO - /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H @@ -79,6 +76,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IF_ETHER_H +/* Define to 1 if you have the header file. */ +#undef HAVE_NET_IF_PFLOG_H + /* Define to 1 if you have the header file. */ #undef HAVE_NET_PFVAR_H @@ -88,6 +88,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_EVP_H +/* define if the OS provides AF_INET6 and struct in6_addr */ +#undef HAVE_OS_IPV6_SUPPORT + /* if there's an os_proto.h for this platform, to use additional prototypes */ #undef HAVE_OS_PROTO_H @@ -142,6 +145,12 @@ /* Define to 1 if you have the `pcap_set_immediate_mode' function. */ #undef HAVE_PCAP_SET_IMMEDIATE_MODE +/* Define to 1 if you have the `pcap_set_optimizer_debug' function. */ +#undef HAVE_PCAP_SET_OPTIMIZER_DEBUG + +/* Define to 1 if you have the `pcap_set_parser_debug' function. */ +#undef HAVE_PCAP_SET_PARSER_DEBUG + /* Define to 1 if you have the `pcap_set_tstamp_precision' function. */ #undef HAVE_PCAP_SET_TSTAMP_PRECISION @@ -184,9 +193,6 @@ /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H -/* Define to 1 if you have the `strcasecmp' function. */ -#undef HAVE_STRCASECMP - /* Define to 1 if you have the `strdup' function. */ #undef HAVE_STRDUP @@ -238,15 +244,9 @@ /* define if your compiler has __attribute__ */ #undef HAVE___ATTRIBUTE__ -/* Define if you enable IPv6 support */ -#undef INET6 - /* if unaligned access fails */ #undef LBL_ALIGN -/* define if you need to include missing/addrinfo.h */ -#undef NEED_ADDRINFO_H - /* Define to 1 if netinet/ether.h declares `ether_ntohost' */ #undef NETINET_ETHER_H_DECLARES_ETHER_NTOHOST @@ -292,9 +292,6 @@ /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS -/* define if you want to build the possibly-buggy SMB printer */ -#undef TCPDUMP_DO_SMB - /* Define to 1 if you can safely include both and . */ #undef TIME_WITH_SYS_TIME diff --git a/contrib/tcpdump/configure b/contrib/tcpdump/configure index d10f2ac..03c69c5 100755 --- a/contrib/tcpdump/configure +++ b/contrib/tcpdump/configure @@ -704,7 +704,6 @@ enable_smb with_user with_chroot with_sandbox_capsicum -enable_ipv6 with_system_libpcap with_crypto with_cap_ng @@ -1332,8 +1331,6 @@ Optional Features: --disable-universal don't build universal on OS X --enable-smb enable possibly-buggy SMB printer default=yes --disable-smb disable possibly-buggy SMB printer - --enable-ipv6 enable ipv6 (with ipv4) support - --disable-ipv6 disable ipv6 support Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -1346,7 +1343,8 @@ Optional Packages: --with-sandbox-capsicum use Capsicum security functions [default=yes, if available] --with-system-libpcap don't use local pcap library - --with-crypto use OpenSSL libcrypto [default=yes, if available] + --with-crypto[=DIR] use OpenSSL/libressl libcrypto (located in directory + DIR, if specified) [default=yes, if available] --with-cap-ng use libcap-ng [default=yes, if available] Some influential environment variables: @@ -3352,7 +3350,18 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -ffloat-store option" >&5 $as_echo_n "checking whether the compiler supports the -ffloat-store option... " >&6; } save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors -ffloat-store" + if expr "x-ffloat-store" : "x-W.*" >/dev/null + then + CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -ffloat-store" + elif expr "x-ffloat-store" : "x-f.*" >/dev/null + then + CFLAGS="$CFLAGS -Werror -ffloat-store" + elif expr "x-ffloat-store" : "x-m.*" >/dev/null + then + CFLAGS="$CFLAGS -Werror -ffloat-store" + else + CFLAGS="$CFLAGS -ffloat-store" + fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -4213,7 +4222,25 @@ fi done if test "$ac_cv_header_net_pfvar_h" = yes; then - LOCALSRC="print-pflog.c $LOCALSRC" + for ac_header in net/if_pflog.h +do : + ac_fn_c_check_header_compile "$LINENO" "net/if_pflog.h" "ac_cv_header_net_if_pflog_h" "#include + #include + #include + #include +" +if test "x$ac_cv_header_net_if_pflog_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_NET_IF_PFLOG_H 1 +_ACEOF + +fi + +done + + if test "$ac_cv_header_net_if_pflog_h" = yes; then + LOCALSRC="print-pflog.c $LOCALSRC" + fi fi for ac_header in netinet/if_ether.h do : @@ -4474,7 +4501,7 @@ $as_echo "yes" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: The SMB printer may have exploitable buffer overflows!!!" >&5 $as_echo "$as_me: WARNING: The SMB printer may have exploitable buffer overflows!!!" >&2;} -$as_echo "#define TCPDUMP_DO_SMB 1" >>confdefs.h +$as_echo "#define ENABLE_SMB 1" >>confdefs.h LOCALSRC="print-smb.c smbutil.c $LOCALSRC" ;; @@ -4566,7 +4593,7 @@ fi $as_echo_n "checking whether to sandbox using capsicum... " >&6; } if test "x$ac_lbl_capsicum_function_seen" = "xyes" -a "x$ac_lbl_capsicum_function_not_seen" != "xyes"; then -$as_echo "#define HAVE_CASPER 1" >>confdefs.h +$as_echo "#define HAVE_CAPSICUM 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } @@ -4576,9 +4603,9 @@ $as_echo "no" >&6; } fi # -# We must check this before checking whether to enable IPv6, because, -# on some platforms (such as SunOS 5.x), the test program requires -# the extra networking libraries. +# We must check this before checking whether to check the OS's IPv6, +# support because, on some platforms (such as SunOS 5.x), the test +# program requires the extra networking libraries. # # Most operating systems have gethostbyname() in the default searched @@ -4842,30 +4869,19 @@ fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable ipv6" >&5 -$as_echo_n "checking whether to enable ipv6... " >&6; } -# Check whether --enable-ipv6 was given. -if test "${enable_ipv6+set}" = set; then : - enableval=$enable_ipv6; case "$enableval" in -yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - LOCALSRC="print-ip6opts.c print-mobility.c print-ripng.c print-icmp6.c print-frag6.c print-rt6.c print-ospf6.c print-dhcp6.c print-babel.c $LOCALSRC" - -$as_echo "#define INET6 1" >>confdefs.h - - ipv6=yes - ;; -*) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - ipv6=no - ;; - esac -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +# +# Check whether AF_INET6 and struct in6_addr are defined. +# If they aren't both defined, we don't have sufficient OS +# support for IPv6, so we don't look for IPv6 support libraries, +# and we define AF_INET6 and struct in6_addr ourselves. +# +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the operating system supports IPv6" >&5 +$as_echo_n "checking whether the operating system supports IPv6... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - /* AF_INET6 available check */ + +/* AF_INET6 available check */ #include #include #include @@ -4882,21 +4898,23 @@ foo(struct in6_addr *addr) _ACEOF if ac_fn_c_try_compile "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - LOCALSRC="print-ip6opts.c print-mobility.c print-ripng.c print-icmp6.c print-frag6.c print-rt6.c print-ospf6.c print-dhcp6.c print-babel.c $LOCALSRC" -$as_echo "#define INET6 1" >>confdefs.h +$as_echo "#define HAVE_OS_IPV6_SUPPORT 1" >>confdefs.h + + ipv6=yes - ipv6=yes else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } - ipv6=no + ipv6=no + + fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - ipv6type=unknown ipv6lib=none @@ -4917,8 +4935,7 @@ yes _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then : - ipv6type=$i; - CFLAGS="-DINET6 $CFLAGS" + ipv6type=$i fi rm -f conftest* @@ -4936,8 +4953,7 @@ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ipv6type=$i; ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib; - ipv6trylibc=yes; - CFLAGS="-DINET6 $CFLAGS" + ipv6trylibc=yes fi rm -f conftest* @@ -4952,8 +4968,7 @@ yes _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then : - ipv6type=$i; - CFLAGS="-DINET6 $CFLAGS" + ipv6type=$i fi rm -f conftest* @@ -4964,7 +4979,7 @@ rm -f conftest* ipv6lib=inet6 ipv6libdir=/usr/inet6/lib ipv6trylibc=yes; - CFLAGS="-DINET6 -I/usr/inet6/include $CFLAGS" + CFLAGS="-I/usr/inet6/include $CFLAGS" fi ;; toshiba) @@ -4979,8 +4994,7 @@ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then : ipv6type=$i; ipv6lib=inet6; - ipv6libdir=/usr/local/v6/lib; - CFLAGS="-DINET6 $CFLAGS" + ipv6libdir=/usr/local/v6/lib fi rm -f conftest* @@ -5015,8 +5029,7 @@ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then : ipv6type=$i; ipv6lib=inet6; - ipv6libdir=/usr/local/v6/lib; - CFLAGS="-DINET6 $CFLAGS" + ipv6libdir=/usr/local/v6/lib fi rm -f conftest* @@ -5046,239 +5059,6 @@ if test "$ipv6" = "yes" -a "$ipv6lib" != "none"; then fi fi - -if test "$ipv6" = "yes"; then - # - # XXX - on Tru64 UNIX 5.1, there is no "getaddrinfo()" - # function in libc; there are "ngetaddrinfo()" and - # "ogetaddrinfo()" functions, and #defines - # "getaddrinfo" to be either "ngetaddrinfo" or - # "ogetaddrinfo", depending on whether _SOCKADDR_LEN - # or _XOPEN_SOURCE_EXTENDED are defined or not. - # - # So this test doesn't work on Tru64 5.1, and possibly - # on other 5.x releases. This causes the configure - # script to become confused, and results in libpcap - # being unbuildable. - # - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing getaddrinfo" >&5 -$as_echo_n "checking for library containing getaddrinfo... " >&6; } -if ${ac_cv_search_getaddrinfo+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char getaddrinfo (); -int -main () -{ -return getaddrinfo (); - ; - return 0; -} -_ACEOF -for ac_lib in '' socket; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_getaddrinfo=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_getaddrinfo+:} false; then : - break -fi -done -if ${ac_cv_search_getaddrinfo+:} false; then : - -else - ac_cv_search_getaddrinfo=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_getaddrinfo" >&5 -$as_echo "$ac_cv_search_getaddrinfo" >&6; } -ac_res=$ac_cv_search_getaddrinfo -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking getaddrinfo bug" >&5 -$as_echo_n "checking getaddrinfo bug... " >&6; } - if ${td_cv_buggygetaddrinfo+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - td_cv_buggygetaddrinfo=unknown -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#include -#include -#include -#include - -main() -{ - int passive, gaierr, inet4 = 0, inet6 = 0; - struct addrinfo hints, *ai, *aitop; - char straddr[INET6_ADDRSTRLEN], strport[16]; - - for (passive = 0; passive <= 1; passive++) { - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_flags = passive ? AI_PASSIVE : 0; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - if ((gaierr = getaddrinfo(NULL, "54321", &hints, &aitop)) != 0) { - (void)gai_strerror(gaierr); - goto bad; - } - for (ai = aitop; ai; ai = ai->ai_next) { - if (ai->ai_addr == NULL || - ai->ai_addrlen == 0 || - getnameinfo(ai->ai_addr, ai->ai_addrlen, - straddr, sizeof(straddr), strport, sizeof(strport), - NI_NUMERICHOST|NI_NUMERICSERV) != 0) { - goto bad; - } - switch (ai->ai_family) { - case AF_INET: - if (strcmp(strport, "54321") != 0) { - goto bad; - } - if (passive) { - if (strcmp(straddr, "0.0.0.0") != 0) { - goto bad; - } - } else { - if (strcmp(straddr, "127.0.0.1") != 0) { - goto bad; - } - } - inet4++; - break; - case AF_INET6: - if (strcmp(strport, "54321") != 0) { - goto bad; - } - if (passive) { - if (strcmp(straddr, "::") != 0) { - goto bad; - } - } else { - if (strcmp(straddr, "::1") != 0) { - goto bad; - } - } - inet6++; - break; - case AF_UNSPEC: - goto bad; - break; -#ifdef AF_UNIX - case AF_UNIX: -#else -#ifdef AF_LOCAL - case AF_LOCAL: -#endif -#endif - default: - /* another family support? */ - break; - } - } - } - - /* supported family should be 2, unsupported family should be 0 */ - if (!(inet4 == 0 || inet4 == 2)) - goto bad; - if (!(inet6 == 0 || inet6 == 2)) - goto bad; - - if (aitop) - freeaddrinfo(aitop); - exit(0); - - bad: - if (aitop) - freeaddrinfo(aitop); - exit(1); -} - -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - td_cv_buggygetaddrinfo=no -else - td_cv_buggygetaddrinfo=yes -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi - - if test "$td_cv_buggygetaddrinfo" = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: good" >&5 -$as_echo "good" >&6; } - elif test "$td_cv_buggygetaddrinfo" = unknown; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unknown (cross-compiling)" >&5 -$as_echo "unknown (cross-compiling)" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: buggy" >&5 -$as_echo "buggy" >&6; } - fi - - if test "$td_cv_buggygetaddrinfo" = "yes"; then - # - # XXX - it doesn't appear that "ipv6type" can ever be - # set to "linux". Should this be testing for - # "linux-glibc", or for that *or* "linux-libinet6"? - # If the latter, note that "linux-libinet6" is also - # the type given to some non-Linux OSes. - # - if test "$ipv6type" != "linux"; then - echo 'Fatal: You must get working getaddrinfo() function.' - echo ' or you can specify "--disable-ipv6"'. - exit 1 - else - echo 'Warning: getaddrinfo() implementation on your system seems be buggy.' - echo ' Better upgrade your system library to newest version' - echo ' of GNU C library (aka glibc).' - fi - fi - -fi - - ac_fn_c_check_func "$LINENO" "getnameinfo" "ac_cv_func_getnameinfo" -if test "x$ac_cv_func_getnameinfo" = xyes; then : - $as_echo "#define HAVE_GETNAMEINFO 1" >>confdefs.h - -else - case " $LIBOBJS " in - *" getnameinfo.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS getnameinfo.$ac_objext" - ;; -esac - -fi - - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_htoa declaration in netdnet/dnetdb.h" >&5 $as_echo_n "checking for dnet_htoa declaration in netdnet/dnetdb.h... " >&6; } if ${td_cv_decl_netdnet_dnetdb_h_dnet_htoa+:} false; then : @@ -5306,116 +5086,6 @@ $as_echo "#define HAVE_NETDNET_DNETDB_H_DNET_HTOA 1" >>confdefs.h fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for addrinfo" >&5 -$as_echo_n "checking for addrinfo... " >&6; } - if ${ac_cv_addrinfo+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -# include -int -main () -{ -struct addrinfo a - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_addrinfo=yes -else - ac_cv_addrinfo=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_addrinfo" >&5 -$as_echo "$ac_cv_addrinfo" >&6; } - if test $ac_cv_addrinfo = yes; then - -$as_echo "#define HAVE_ADDRINFO 1" >>confdefs.h - - else - -$as_echo "#define NEED_ADDRINFO_H 1" >>confdefs.h - - fi - -if test "$ac_cv_addrinfo" = no; then - missing_includes=yes -fi - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for NI_MAXSERV" >&5 -$as_echo_n "checking for NI_MAXSERV... " >&6; } - if ${ac_cv_maxserv+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#ifdef NI_MAXSERV -yes -#endif -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "yes" >/dev/null 2>&1; then : - ac_cv_maxserv=yes -else - ac_cv_maxserv=no -fi -rm -f conftest* - -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_maxserv" >&5 -$as_echo "$ac_cv_maxserv" >&6; } - if test $ac_cv_maxserv != yes; then - $as_echo "#define NEED_ADDRINFO_H 1" >>confdefs.h - - fi - -if test "$ac_cv_maxserv" = no; then - missing_includes=yes -fi - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for NI_NAMEREQD" >&5 -$as_echo_n "checking for NI_NAMEREQD... " >&6; } - if ${ac_cv_namereqd+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#ifdef NI_NOFQDN -yes -#endif -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "yes" >/dev/null 2>&1; then : - ac_cv_namereqd=yes -else - ac_cv_namereqd=no -fi -rm -f conftest* - -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_namereqd" >&5 -$as_echo "$ac_cv_namereqd" >&6; } - if test $ac_cv_namereqd != yes; then - $as_echo "#define NEED_ADDRINFO_H 1" >>confdefs.h - - fi - -if test "$ac_cv_namereqd" = no; then - missing_includes=yes -fi - ac_fn_c_check_func "$LINENO" "vfprintf" "ac_cv_func_vfprintf" if test "x$ac_cv_func_vfprintf" = xyes; then : $as_echo "#define HAVE_VFPRINTF 1" >>confdefs.h @@ -5429,19 +5099,6 @@ esac fi -ac_fn_c_check_func "$LINENO" "strcasecmp" "ac_cv_func_strcasecmp" -if test "x$ac_cv_func_strcasecmp" = xyes; then : - $as_echo "#define HAVE_STRCASECMP 1" >>confdefs.h - -else - case " $LIBOBJS " in - *" strcasecmp.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS strcasecmp.$ac_objext" - ;; -esac - -fi - ac_fn_c_check_func "$LINENO" "strlcat" "ac_cv_func_strlcat" if test "x$ac_cv_func_strlcat" = xyes; then : $as_echo "#define HAVE_STRLCAT 1" >>confdefs.h @@ -5794,7 +5451,6 @@ fi - LBL_LIBS="$LIBS" pfopen=/usr/examples/packetfilter/pfopen.c if test -f $pfopen ; then @@ -6163,130 +5819,22 @@ fi # Check for these after AC_LBL_LIBPCAP, so we link with the appropriate # libraries (e.g., "-lsocket -lnsl" on Solaris). # -# We don't use AC_REPLACE_FUNCS because that uses AC_CHECK_FUNCS which -# use AC_CHECK_FUNC which doesn't let us specify the right #includes -# to make this work on BSD/OS 4.x. BSD/OS 4.x ships with the BIND8 -# resolver, and the way it defines inet_{ntop,pton} is rather strange; -# it does not ship with a libc symbol "inet_ntop()", it ships with -# "_inet_ntop()", and has a #define macro in one of the system headers -# to rename it. +# You are in a twisty little maze of UN*Xes, all different. +# Some might not have ether_ntohost(). +# Some might have it, but not declare it in any header file. +# Some might have it, but declare it in . +# Some might have it, but declare it in +# (And some might have it but document it as something declared in +# , although appears to work.) # -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntop" >&5 -$as_echo_n "checking for inet_ntop... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include -#include -int -main () -{ -char src[4], dst[128]; -inet_ntop(AF_INET, src, dst, sizeof(dst)); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - case " $LIBOBJS " in - *" inet_ntop.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS inet_ntop.$ac_objext" - ;; -esac - -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_pton" >&5 -$as_echo_n "checking for inet_pton... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include -#include -int -main () -{ -char src[128], dst[4]; -inet_pton(AF_INET, src, dst); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - case " $LIBOBJS " in - *" inet_pton.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS inet_pton.$ac_objext" - ;; -esac - -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_aton" >&5 -$as_echo_n "checking for inet_aton... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include -int -main () -{ -char src[128]; -struct in_addr dst; -inet_aton(src, &dst); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - case " $LIBOBJS " in - *" inet_aton.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS inet_aton.$ac_objext" - ;; -esac - -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - -# -# Check for these after AC_LBL_LIBPCAP, for the same reason. -# -# You are in a twisty little maze of UN*Xes, all different. -# Some might not have ether_ntohost(). -# Some might have it, but not declare it in any header file. -# Some might have it, but declare it in . -# Some might have it, but declare it in -# (And some might have it but document it as something declared in -# , although appears to work.) -# -# Before you is a C compiler. -# -for ac_func in ether_ntohost -do : - ac_fn_c_check_func "$LINENO" "ether_ntohost" "ac_cv_func_ether_ntohost" -if test "x$ac_cv_func_ether_ntohost" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_ETHER_NTOHOST 1 +# Before you is a C compiler. +# +for ac_func in ether_ntohost +do : + ac_fn_c_check_func "$LINENO" "ether_ntohost" "ac_cv_func_ether_ntohost" +if test "x$ac_cv_func_ether_ntohost" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_ETHER_NTOHOST 1 _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for buggy ether_ntohost" >&5 @@ -6488,44 +6036,6 @@ if test "x$ac_cv_lib_dlpi_dlpi_walk" = xyes; then : fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if sockaddr struct has sa_len member" >&5 -$as_echo_n "checking if sockaddr struct has sa_len member... " >&6; } - if ${ac_cv_sockaddr_has_sa_len+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -# include -# include -int -main () -{ -u_int i = sizeof(((struct sockaddr *)0)->sa_len) - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_sockaddr_has_sa_len=yes -else - ac_cv_sockaddr_has_sa_len=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sockaddr_has_sa_len" >&5 -$as_echo "$ac_cv_sockaddr_has_sa_len" >&6; } - if test $ac_cv_sockaddr_has_sa_len = yes ; then - $as_echo "#define HAVE_SOCKADDR_SA_LEN 1" >>confdefs.h - - fi - -if test "$ac_cv_sockaddr_has_sa_len" = no; then - missing_includes=yes -fi - ac_fn_c_check_func "$LINENO" "pcap_list_datalinks" "ac_cv_func_pcap_list_datalinks" if test "x$ac_cv_func_pcap_list_datalinks" = xyes; then : @@ -6748,18 +6258,38 @@ $as_echo "#define HAVE_PCAP_VERSION 1" >>confdefs.h $as_echo "no" >&6; } fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pcap_debug is defined by libpcap" >&5 + +# +# Check for special debugging functions +# +for ac_func in pcap_set_parser_debug +do : + ac_fn_c_check_func "$LINENO" "pcap_set_parser_debug" "ac_cv_func_pcap_set_parser_debug" +if test "x$ac_cv_func_pcap_set_parser_debug" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_PCAP_SET_PARSER_DEBUG 1 +_ACEOF + +fi +done + +if test "$ac_cv_func_pcap_set_parser_debug" = "no" ; then + # + # OK, we don't have pcap_set_parser_debug() to set the libpcap + # filter expression parser debug flag; can we directly set the + # flag? + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pcap_debug is defined by libpcap" >&5 $as_echo_n "checking whether pcap_debug is defined by libpcap... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { - extern int pcap_debug; + extern int pcap_debug; - return pcap_debug; + return pcap_debug; ; return 0; @@ -6772,30 +6302,30 @@ else fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext -if test "$ac_lbl_cv_pcap_debug_defined" = yes ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + if test "$ac_lbl_cv_pcap_debug_defined" = yes ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAVE_PCAP_DEBUG 1" >>confdefs.h -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } - # - # OK, what about "yydebug"? - # - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether yydebug is defined by libpcap" >&5 + # + # OK, what about "yydebug"? + # + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether yydebug is defined by libpcap" >&5 $as_echo_n "checking whether yydebug is defined by libpcap... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { - extern int yydebug; + extern int yydebug; - return yydebug; + return yydebug; ; return 0; @@ -6808,17 +6338,29 @@ else fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext - if test "$ac_lbl_cv_yydebug_defined" = yes ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + if test "$ac_lbl_cv_yydebug_defined" = yes ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAVE_YYDEBUG 1" >>confdefs.h - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } + fi fi fi +for ac_func in pcap_set_optimizer_debug +do : + ac_fn_c_check_func "$LINENO" "pcap_set_optimizer_debug" "ac_cv_func_pcap_set_optimizer_debug" +if test "x$ac_cv_func_pcap_set_optimizer_debug" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_PCAP_SET_OPTIMIZER_DEBUG 1 +_ACEOF + +fi +done + ac_fn_c_check_func "$LINENO" "bpf_dump" "ac_cv_func_bpf_dump" if test "x$ac_cv_func_bpf_dump" = xyes; then : $as_echo "#define HAVE_BPF_DUMP 1" >>confdefs.h @@ -7417,7 +6959,7 @@ savedcppflags="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $V_INCLS" for ac_header in pcap/bluetooth.h do : - ac_fn_c_check_header_compile "$LINENO" "pcap/bluetooth.h" "ac_cv_header_pcap_bluetooth_h" "#include \"tcpdump-stdinc.h\" + ac_fn_c_check_header_compile "$LINENO" "pcap/bluetooth.h" "ac_cv_header_pcap_bluetooth_h" "#include \"netdissect-stdinc.h\" " if test "x$ac_cv_header_pcap_bluetooth_h" = xyes; then : cat >>confdefs.h <<_ACEOF @@ -7430,7 +6972,7 @@ done for ac_header in pcap/nflog.h do : - ac_fn_c_check_header_compile "$LINENO" "pcap/nflog.h" "ac_cv_header_pcap_nflog_h" "#include \"tcpdump-stdinc.h\" + ac_fn_c_check_header_compile "$LINENO" "pcap/nflog.h" "ac_cv_header_pcap_nflog_h" "#include \"netdissect-stdinc.h\" " if test "x$ac_cv_header_pcap_nflog_h" = xyes; then : cat >>confdefs.h <<_ACEOF @@ -7443,7 +6985,7 @@ done for ac_header in pcap/usb.h do : - ac_fn_c_check_header_compile "$LINENO" "pcap/usb.h" "ac_cv_header_pcap_usb_h" "#include \"tcpdump-stdinc.h\" + ac_fn_c_check_header_compile "$LINENO" "pcap/usb.h" "ac_cv_header_pcap_usb_h" "#include \"netdissect-stdinc.h\" " if test "x$ac_cv_header_pcap_usb_h" = xyes; then : cat >>confdefs.h <<_ACEOF @@ -7651,10 +7193,57 @@ rm -f os-proto.h # if test "$ac_lbl_cc_dont_try_gcc_dashW" != yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler fails when given an unknown warning option" >&5 +$as_echo_n "checking whether the compiler fails when given an unknown warning option... " >&6; } + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Wxyzzy-this-will-never-succeed-xyzzy" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +return 0 + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + # + # We're assuming this is clang, where + # -Werror=unknown-warning-option is the appropriate + # option to force the compiler to fail. + # + ac_lbl_unknown_warning_option_error="-Werror=unknown-warning-option" + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS="$save_CFLAGS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wall option" >&5 $as_echo_n "checking whether the compiler supports the -Wall option... " >&6; } save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors -Wall" + if expr "x-Wall" : "x-W.*" >/dev/null + then + CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -Wall" + elif expr "x-Wall" : "x-f.*" >/dev/null + then + CFLAGS="$CFLAGS -Werror -Wall" + elif expr "x-Wall" : "x-m.*" >/dev/null + then + CFLAGS="$CFLAGS -Werror -Wall" + else + CFLAGS="$CFLAGS -Wall" + fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -7686,7 +7275,18 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wmissing-prototypes option" >&5 $as_echo_n "checking whether the compiler supports the -Wmissing-prototypes option... " >&6; } save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors -Wmissing-prototypes" + if expr "x-Wmissing-prototypes" : "x-W.*" >/dev/null + then + CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -Wmissing-prototypes" + elif expr "x-Wmissing-prototypes" : "x-f.*" >/dev/null + then + CFLAGS="$CFLAGS -Werror -Wmissing-prototypes" + elif expr "x-Wmissing-prototypes" : "x-m.*" >/dev/null + then + CFLAGS="$CFLAGS -Werror -Wmissing-prototypes" + else + CFLAGS="$CFLAGS -Wmissing-prototypes" + fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -7718,7 +7318,18 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wstrict-prototypes option" >&5 $as_echo_n "checking whether the compiler supports the -Wstrict-prototypes option... " >&6; } save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors -Wstrict-prototypes" + if expr "x-Wstrict-prototypes" : "x-W.*" >/dev/null + then + CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -Wstrict-prototypes" + elif expr "x-Wstrict-prototypes" : "x-f.*" >/dev/null + then + CFLAGS="$CFLAGS -Werror -Wstrict-prototypes" + elif expr "x-Wstrict-prototypes" : "x-m.*" >/dev/null + then + CFLAGS="$CFLAGS -Werror -Wstrict-prototypes" + else + CFLAGS="$CFLAGS -Wstrict-prototypes" + fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -7750,7 +7361,18 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wwrite-strings option" >&5 $as_echo_n "checking whether the compiler supports the -Wwrite-strings option... " >&6; } save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors -Wwrite-strings" + if expr "x-Wwrite-strings" : "x-W.*" >/dev/null + then + CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -Wwrite-strings" + elif expr "x-Wwrite-strings" : "x-f.*" >/dev/null + then + CFLAGS="$CFLAGS -Werror -Wwrite-strings" + elif expr "x-Wwrite-strings" : "x-m.*" >/dev/null + then + CFLAGS="$CFLAGS -Werror -Wwrite-strings" + else + CFLAGS="$CFLAGS -Wwrite-strings" + fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -7782,7 +7404,18 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wpointer-arith option" >&5 $as_echo_n "checking whether the compiler supports the -Wpointer-arith option... " >&6; } save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors -Wpointer-arith" + if expr "x-Wpointer-arith" : "x-W.*" >/dev/null + then + CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -Wpointer-arith" + elif expr "x-Wpointer-arith" : "x-f.*" >/dev/null + then + CFLAGS="$CFLAGS -Werror -Wpointer-arith" + elif expr "x-Wpointer-arith" : "x-m.*" >/dev/null + then + CFLAGS="$CFLAGS -Werror -Wpointer-arith" + else + CFLAGS="$CFLAGS -Wpointer-arith" + fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -7811,10 +7444,279 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wcast-qual option" >&5 +$as_echo_n "checking whether the compiler supports the -Wcast-qual option... " >&6; } + save_CFLAGS="$CFLAGS" + if expr "x-Wcast-qual" : "x-W.*" >/dev/null + then + CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -Wcast-qual" + elif expr "x-Wcast-qual" : "x-f.*" >/dev/null + then + CFLAGS="$CFLAGS -Werror -Wcast-qual" + elif expr "x-Wcast-qual" : "x-m.*" >/dev/null + then + CFLAGS="$CFLAGS -Werror -Wcast-qual" + else + CFLAGS="$CFLAGS -Wcast-qual" + fi + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +return 0 + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$save_CFLAGS" + V_CCOPT="$V_CCOPT -Wcast-qual" + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$save_CFLAGS" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wshadow option" >&5 +$as_echo_n "checking whether the compiler supports the -Wshadow option... " >&6; } + save_CFLAGS="$CFLAGS" + if expr "x-Wshadow" : "x-W.*" >/dev/null + then + CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -Wshadow" + elif expr "x-Wshadow" : "x-f.*" >/dev/null + then + CFLAGS="$CFLAGS -Werror -Wshadow" + elif expr "x-Wshadow" : "x-m.*" >/dev/null + then + CFLAGS="$CFLAGS -Werror -Wshadow" + else + CFLAGS="$CFLAGS -Wshadow" + fi + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +return 0 + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$save_CFLAGS" + V_CCOPT="$V_CCOPT -Wshadow" + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$save_CFLAGS" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wdeclaration-after-statement option" >&5 +$as_echo_n "checking whether the compiler supports the -Wdeclaration-after-statement option... " >&6; } + save_CFLAGS="$CFLAGS" + if expr "x-Wdeclaration-after-statement" : "x-W.*" >/dev/null + then + CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -Wdeclaration-after-statement" + elif expr "x-Wdeclaration-after-statement" : "x-f.*" >/dev/null + then + CFLAGS="$CFLAGS -Werror -Wdeclaration-after-statement" + elif expr "x-Wdeclaration-after-statement" : "x-m.*" >/dev/null + then + CFLAGS="$CFLAGS -Werror -Wdeclaration-after-statement" + else + CFLAGS="$CFLAGS -Wdeclaration-after-statement" + fi + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +return 0 + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$save_CFLAGS" + V_CCOPT="$V_CCOPT -Wdeclaration-after-statement" + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$save_CFLAGS" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wpedantic option" >&5 +$as_echo_n "checking whether the compiler supports the -Wpedantic option... " >&6; } + save_CFLAGS="$CFLAGS" + if expr "x-Wpedantic" : "x-W.*" >/dev/null + then + CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -Wpedantic" + elif expr "x-Wpedantic" : "x-f.*" >/dev/null + then + CFLAGS="$CFLAGS -Werror -Wpedantic" + elif expr "x-Wpedantic" : "x-m.*" >/dev/null + then + CFLAGS="$CFLAGS -Werror -Wpedantic" + else + CFLAGS="$CFLAGS -Wpedantic" + fi + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +return 0 + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$save_CFLAGS" + V_CCOPT="$V_CCOPT -Wpedantic" + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$save_CFLAGS" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wold-style-definition option" >&5 +$as_echo_n "checking whether the compiler supports the -Wold-style-definition option... " >&6; } + save_CFLAGS="$CFLAGS" + if expr "x-Wold-style-definition" : "x-W.*" >/dev/null + then + CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -Wold-style-definition" + elif expr "x-Wold-style-definition" : "x-f.*" >/dev/null + then + CFLAGS="$CFLAGS -Werror -Wold-style-definition" + elif expr "x-Wold-style-definition" : "x-m.*" >/dev/null + then + CFLAGS="$CFLAGS -Werror -Wold-style-definition" + else + CFLAGS="$CFLAGS -Wold-style-definition" + fi + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +return 0 + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$save_CFLAGS" + V_CCOPT="$V_CCOPT -Wold-style-definition" + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$save_CFLAGS" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wused-but-marked-unused option" >&5 +$as_echo_n "checking whether the compiler supports the -Wused-but-marked-unused option... " >&6; } + save_CFLAGS="$CFLAGS" + if expr "x-Wused-but-marked-unused" : "x-W.*" >/dev/null + then + CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -Wused-but-marked-unused" + elif expr "x-Wused-but-marked-unused" : "x-f.*" >/dev/null + then + CFLAGS="$CFLAGS -Werror -Wused-but-marked-unused" + elif expr "x-Wused-but-marked-unused" : "x-m.*" >/dev/null + then + CFLAGS="$CFLAGS -Werror -Wused-but-marked-unused" + else + CFLAGS="$CFLAGS -Wused-but-marked-unused" + fi + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +return 0 + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$save_CFLAGS" + V_CCOPT="$V_CCOPT -Wused-but-marked-unused" + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$save_CFLAGS" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -W option" >&5 $as_echo_n "checking whether the compiler supports the -W option... " >&6; } save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors -W" + if expr "x-W" : "x-W.*" >/dev/null + then + CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -W" + elif expr "x-W" : "x-f.*" >/dev/null + then + CFLAGS="$CFLAGS -Werror -W" + elif expr "x-W" : "x-m.*" >/dev/null + then + CFLAGS="$CFLAGS -Werror -W" + else + CFLAGS="$CFLAGS -W" + fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -8092,45 +7994,9 @@ $as_echo "#define LBL_ALIGN 1" >>confdefs.h fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for h_errno" >&5 -$as_echo_n "checking for h_errno... " >&6; } - if ${ac_cv_var_h_errno+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -# include -# include -int -main () -{ -int foo = h_errno; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_var_h_errno=yes -else - ac_cv_var_h_errno=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_var_h_errno" >&5 -$as_echo "$ac_cv_var_h_errno" >&6; } - if test "$ac_cv_var_h_errno" = "yes"; then - -$as_echo "#define HAVE_H_ERRNO 1" >>confdefs.h - - fi - - -# Check for OpenSSL libcrypto -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use OpenSSL libcrypto" >&5 -$as_echo_n "checking whether to use OpenSSL libcrypto... " >&6; } +# Check for OpenSSL/libressl libcrypto +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use OpenSSL/libressl libcrypto" >&5 +$as_echo_n "checking whether to use OpenSSL/libressl libcrypto... " >&6; } # Specify location for both includes and libraries. want_libcrypto=ifavailable @@ -8139,20 +8005,38 @@ if test "${with_crypto+set}" = set; then : withval=$with_crypto; if test $withval = no then + # User doesn't want to link with libcrypto. want_libcrypto=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } elif test $withval = yes then + # User wants to link with libcrypto but hasn't specified + # a directory. want_libcrypto=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } + else + # User wants to link with libcrypto and has specified + # a directory, so use the provided value. + want_libcrypto=yes + libcrypto_root=$withval + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes, using the version installed in $withval" >&5 +$as_echo "yes, using the version installed in $withval" >&6; } + + # + # Put the subdirectories of the libcrypto root directory + # at the front of the header and library search path. + # + CFLAGS="-I$withval/include $CFLAGS" + LIBS="-L$withval/lib $LIBS" fi else # - # Use libcrypto if it's present, otherwise don't. + # Use libcrypto if it's present, otherwise don't; no directory + # was specified. # want_libcrypto=ifavailable { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes, if available" >&5 @@ -8161,7 +8045,19 @@ $as_echo "yes, if available" >&6; } fi if test "$want_libcrypto" != "no"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DES_cbc_encrypt in -lcrypto" >&5 + # + # Don't check for libcrypto unless we have its headers; + # Apple, bless their pointy little heads, apparently ship + # libcrypto as a library, but not the header files, in + # El Capitan, probably because they don't want you writing + # nasty portable code that could run on other UN*Xes, they + # want you writing code that uses their Shiny New Crypto + # Library and that only runs on OS X. + # + ac_fn_c_check_header_mongrel "$LINENO" "openssl/crypto.h" "ac_cv_header_openssl_crypto_h" "$ac_includes_default" +if test "x$ac_cv_header_openssl_crypto_h" = xyes; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DES_cbc_encrypt in -lcrypto" >&5 $as_echo_n "checking for DES_cbc_encrypt in -lcrypto... " >&6; } if ${ac_cv_lib_crypto_DES_cbc_encrypt+:} false; then : $as_echo_n "(cached) " >&6 @@ -8206,7 +8102,8 @@ _ACEOF fi - for ac_header in openssl/evp.h + if test "$ac_cv_lib_crypto_DES_cbc_encrypt" = "yes"; then + for ac_header in openssl/evp.h do : ac_fn_c_check_header_mongrel "$LINENO" "openssl/evp.h" "ac_cv_header_openssl_evp_h" "$ac_includes_default" if test "x$ac_cv_header_openssl_evp_h" = xyes; then : @@ -8218,6 +8115,28 @@ fi done + # + # OK, do we have EVP_CIPHER_CTX_new? + # If so, we use it to allocate an + # EVP_CIPHER_CTX, as EVP_CIPHER_CTX may be + # opaque; otherwise, we allocate it ourselves. + # + for ac_func in EVP_CIPHER_CTX_new +do : + ac_fn_c_check_func "$LINENO" "EVP_CIPHER_CTX_new" "ac_cv_func_EVP_CIPHER_CTX_new" +if test "x$ac_cv_func_EVP_CIPHER_CTX_new" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_EVP_CIPHER_CTX_NEW 1 +_ACEOF + +fi +done + + fi + +fi + + fi # Check for libcap-ng diff --git a/contrib/tcpdump/configure.in b/contrib/tcpdump/configure.in index b5ac48f..a78a126 100644 --- a/contrib/tcpdump/configure.in +++ b/contrib/tcpdump/configure.in @@ -37,7 +37,13 @@ AC_CHECK_HEADERS(net/pfvar.h, , , [#include #include #include ]) if test "$ac_cv_header_net_pfvar_h" = yes; then - LOCALSRC="print-pflog.c $LOCALSRC" + AC_CHECK_HEADERS(net/if_pflog.h, , , [#include + #include + #include + #include ]) + if test "$ac_cv_header_net_if_pflog_h" = yes; then + LOCALSRC="print-pflog.c $LOCALSRC" + fi fi AC_CHECK_HEADERS(netinet/if_ether.h, , , [#include #include ]) @@ -169,7 +175,7 @@ AC_ARG_ENABLE(smb, case "$enableval" in yes) AC_MSG_RESULT(yes) AC_WARN([The SMB printer may have exploitable buffer overflows!!!]) - AC_DEFINE(TCPDUMP_DO_SMB, 1, + AC_DEFINE(ENABLE_SMB, 1, [define if you want to build the possibly-buggy SMB printer]) LOCALSRC="print-smb.c smbutil.c $LOCALSRC" ;; @@ -222,39 +228,31 @@ if test ! -z "$with_sandbox-capsicum" && test "$with_sandbox-capsicum" != "no" ; fi AC_MSG_CHECKING([whether to sandbox using capsicum]) if test "x$ac_lbl_capsicum_function_seen" = "xyes" -a "x$ac_lbl_capsicum_function_not_seen" != "xyes"; then - AC_DEFINE(HAVE_CASPER, 1, [casper support available]) + AC_DEFINE(HAVE_CAPSICUM, 1, [capsicum support available]) AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi # -# We must check this before checking whether to enable IPv6, because, -# on some platforms (such as SunOS 5.x), the test program requires -# the extra networking libraries. +# We must check this before checking whether to check the OS's IPv6, +# support because, on some platforms (such as SunOS 5.x), the test +# program requires the extra networking libraries. # AC_LBL_LIBRARY_NET -AC_MSG_CHECKING([whether to enable ipv6]) -AC_ARG_ENABLE(ipv6, -[ --enable-ipv6 enable ipv6 (with ipv4) support - --disable-ipv6 disable ipv6 support], -[ case "$enableval" in -yes) AC_MSG_RESULT(yes) - LOCALSRC="print-ip6opts.c print-mobility.c print-ripng.c print-icmp6.c print-frag6.c print-rt6.c print-ospf6.c print-dhcp6.c print-babel.c $LOCALSRC" - AC_DEFINE(INET6, 1, [Define if you enable IPv6 support]) - ipv6=yes - ;; -*) - AC_MSG_RESULT(no) - ipv6=no - ;; - esac ], - - AC_COMPILE_IFELSE( +# +# Check whether AF_INET6 and struct in6_addr are defined. +# If they aren't both defined, we don't have sufficient OS +# support for IPv6, so we don't look for IPv6 support libraries, +# and we define AF_INET6 and struct in6_addr ourselves. +# +AC_MSG_CHECKING([whether the operating system supports IPv6]) +AC_COMPILE_IFELSE( [ AC_LANG_SOURCE( - [[/* AF_INET6 available check */ + [[ +/* AF_INET6 available check */ #include #include #include @@ -267,17 +265,19 @@ foo(struct in6_addr *addr) #else #error "AF_INET6 not defined" #endif - ]]) + ]]) + ], + [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_OS_IPV6_SUPPORT, 1, + [define if the OS provides AF_INET6 and struct in6_addr]) + ipv6=yes ], -[ AC_MSG_RESULT(yes) - LOCALSRC="print-ip6opts.c print-mobility.c print-ripng.c print-icmp6.c print-frag6.c print-rt6.c print-ospf6.c print-dhcp6.c print-babel.c $LOCALSRC" - AC_DEFINE(INET6, 1, [Define if you enable IPv6 support]) - ipv6=yes], -[ AC_MSG_RESULT(no) - ipv6=no], -[ AC_MSG_RESULT(no) - ipv6=no] -)) + [ + AC_MSG_RESULT(no) + ipv6=no + ] +) ipv6type=unknown ipv6lib=none @@ -294,8 +294,7 @@ if test "$ipv6" = "yes"; then #ifdef IPV6_INRIA_VERSION yes #endif], - [ipv6type=$i; - CFLAGS="-DINET6 $CFLAGS"]) + [ipv6type=$i]) ;; kame) dnl http://www.kame.net/ @@ -307,8 +306,7 @@ yes [ipv6type=$i; ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib; - ipv6trylibc=yes; - CFLAGS="-DINET6 $CFLAGS"]) + ipv6trylibc=yes]) ;; linux-glibc) dnl http://www.v6.linux.or.jp/ @@ -317,8 +315,7 @@ yes #if defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1 yes #endif], - [ipv6type=$i; - CFLAGS="-DINET6 $CFLAGS"]) + [ipv6type=$i]) ;; linux-libinet6) dnl http://www.v6.linux.or.jp/ @@ -331,7 +328,7 @@ yes ipv6lib=inet6 ipv6libdir=/usr/inet6/lib ipv6trylibc=yes; - CFLAGS="-DINET6 -I/usr/inet6/include $CFLAGS" + CFLAGS="-I/usr/inet6/include $CFLAGS" fi ;; toshiba) @@ -342,8 +339,7 @@ yes #endif], [ipv6type=$i; ipv6lib=inet6; - ipv6libdir=/usr/local/v6/lib; - CFLAGS="-DINET6 $CFLAGS"]) + ipv6libdir=/usr/local/v6/lib]) ;; v6d) AC_EGREP_CPP(yes, @@ -364,8 +360,7 @@ yes #endif], [ipv6type=$i; ipv6lib=inet6; - ipv6libdir=/usr/local/v6/lib; - CFLAGS="-DINET6 $CFLAGS"]) + ipv6libdir=/usr/local/v6/lib]) ;; esac if test "$ipv6type" != "unknown"; then @@ -391,151 +386,6 @@ if test "$ipv6" = "yes" -a "$ipv6lib" != "none"; then fi fi - -if test "$ipv6" = "yes"; then - # - # XXX - on Tru64 UNIX 5.1, there is no "getaddrinfo()" - # function in libc; there are "ngetaddrinfo()" and - # "ogetaddrinfo()" functions, and #defines - # "getaddrinfo" to be either "ngetaddrinfo" or - # "ogetaddrinfo", depending on whether _SOCKADDR_LEN - # or _XOPEN_SOURCE_EXTENDED are defined or not. - # - # So this test doesn't work on Tru64 5.1, and possibly - # on other 5.x releases. This causes the configure - # script to become confused, and results in libpcap - # being unbuildable. - # - AC_SEARCH_LIBS(getaddrinfo, socket, [dnl - AC_MSG_CHECKING(getaddrinfo bug) - AC_CACHE_VAL(td_cv_buggygetaddrinfo, [AC_TRY_RUN([ -#include -#include -#include -#include -#include - -main() -{ - int passive, gaierr, inet4 = 0, inet6 = 0; - struct addrinfo hints, *ai, *aitop; - char straddr[INET6_ADDRSTRLEN], strport[16]; - - for (passive = 0; passive <= 1; passive++) { - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_flags = passive ? AI_PASSIVE : 0; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - if ((gaierr = getaddrinfo(NULL, "54321", &hints, &aitop)) != 0) { - (void)gai_strerror(gaierr); - goto bad; - } - for (ai = aitop; ai; ai = ai->ai_next) { - if (ai->ai_addr == NULL || - ai->ai_addrlen == 0 || - getnameinfo(ai->ai_addr, ai->ai_addrlen, - straddr, sizeof(straddr), strport, sizeof(strport), - NI_NUMERICHOST|NI_NUMERICSERV) != 0) { - goto bad; - } - switch (ai->ai_family) { - case AF_INET: - if (strcmp(strport, "54321") != 0) { - goto bad; - } - if (passive) { - if (strcmp(straddr, "0.0.0.0") != 0) { - goto bad; - } - } else { - if (strcmp(straddr, "127.0.0.1") != 0) { - goto bad; - } - } - inet4++; - break; - case AF_INET6: - if (strcmp(strport, "54321") != 0) { - goto bad; - } - if (passive) { - if (strcmp(straddr, "::") != 0) { - goto bad; - } - } else { - if (strcmp(straddr, "::1") != 0) { - goto bad; - } - } - inet6++; - break; - case AF_UNSPEC: - goto bad; - break; -#ifdef AF_UNIX - case AF_UNIX: -#else -#ifdef AF_LOCAL - case AF_LOCAL: -#endif -#endif - default: - /* another family support? */ - break; - } - } - } - - /* supported family should be 2, unsupported family should be 0 */ - if (!(inet4 == 0 || inet4 == 2)) - goto bad; - if (!(inet6 == 0 || inet6 == 2)) - goto bad; - - if (aitop) - freeaddrinfo(aitop); - exit(0); - - bad: - if (aitop) - freeaddrinfo(aitop); - exit(1); -} -], - td_cv_buggygetaddrinfo=no, - td_cv_buggygetaddrinfo=yes, - td_cv_buggygetaddrinfo=unknown)]) - if test "$td_cv_buggygetaddrinfo" = no; then - AC_MSG_RESULT(good) - elif test "$td_cv_buggygetaddrinfo" = unknown; then - AC_MSG_RESULT([unknown (cross-compiling)]) - else - AC_MSG_RESULT(buggy) - fi - - if test "$td_cv_buggygetaddrinfo" = "yes"; then - # - # XXX - it doesn't appear that "ipv6type" can ever be - # set to "linux". Should this be testing for - # "linux-glibc", or for that *or* "linux-libinet6"? - # If the latter, note that "linux-libinet6" is also - # the type given to some non-Linux OSes. - # - if test "$ipv6type" != "linux"; then - echo 'Fatal: You must get working getaddrinfo() function.' - echo ' or you can specify "--disable-ipv6"'. - exit 1 - else - echo 'Warning: getaddrinfo() implementation on your system seems be buggy.' - echo ' Better upgrade your system library to newest version' - echo ' of GNU C library (aka glibc).' - fi - fi - ]) - AC_REPLACE_FUNCS(getnameinfo) -fi - AC_CACHE_CHECK([for dnet_htoa declaration in netdnet/dnetdb.h], [td_cv_decl_netdnet_dnetdb_h_dnet_htoa], [AC_EGREP_HEADER(dnet_htoa, netdnet/dnetdb.h, @@ -546,28 +396,7 @@ if test "$td_cv_decl_netdnet_dnetdb_h_dnet_htoa" = yes; then [define if you have a dnet_htoa declaration in ]) fi -dnl -dnl Checks for addrinfo structure -AC_STRUCT_ADDRINFO(ac_cv_addrinfo) -if test "$ac_cv_addrinfo" = no; then - missing_includes=yes -fi - -dnl -dnl Checks for NI_MAXSERV -AC_NI_MAXSERV(ac_cv_maxserv) -if test "$ac_cv_maxserv" = no; then - missing_includes=yes -fi - -dnl -dnl Checks for NI_NAMEREQD -AC_NI_NAMEREQD(ac_cv_namereqd) -if test "$ac_cv_namereqd" = no; then - missing_includes=yes -fi - -AC_REPLACE_FUNCS(vfprintf strcasecmp strlcat strlcpy strdup strsep getopt_long) +AC_REPLACE_FUNCS(vfprintf strlcat strlcpy strdup strsep getopt_long) AC_CHECK_FUNCS(fork vfork strftime) AC_CHECK_FUNCS(setlinebuf alarm) @@ -589,52 +418,12 @@ dnl Some platforms may need -lnsl for getrpcbynumber. AC_SEARCH_LIBS(getrpcbynumber, nsl, AC_DEFINE(HAVE_GETRPCBYNUMBER, 1, [define if you have getrpcbynumber()])) -dnl AC_CHECK_LIB(z, uncompress) -dnl AC_CHECK_HEADERS(zlib.h) - AC_LBL_LIBPCAP(V_PCAPDEP, V_INCLS) # # Check for these after AC_LBL_LIBPCAP, so we link with the appropriate # libraries (e.g., "-lsocket -lnsl" on Solaris). # -# We don't use AC_REPLACE_FUNCS because that uses AC_CHECK_FUNCS which -# use AC_CHECK_FUNC which doesn't let us specify the right #includes -# to make this work on BSD/OS 4.x. BSD/OS 4.x ships with the BIND8 -# resolver, and the way it defines inet_{ntop,pton} is rather strange; -# it does not ship with a libc symbol "inet_ntop()", it ships with -# "_inet_ntop()", and has a #define macro in one of the system headers -# to rename it. -# -dnl AC_TRY_COMPILE(inet_ntop inet_pton inet_aton) -AC_MSG_CHECKING(for inet_ntop) -AC_TRY_LINK([#include -#include -#include -#include ], [char src[4], dst[128]; -inet_ntop(AF_INET, src, dst, sizeof(dst));], - [AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no) - AC_LIBOBJ(inet_ntop)]) -AC_MSG_CHECKING(for inet_pton) -AC_TRY_LINK([#include -#include -#include -#include ], [char src[128], dst[4]; -inet_pton(AF_INET, src, dst);], - [AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no) - AC_LIBOBJ(inet_pton)]) -AC_MSG_CHECKING(for inet_aton) -AC_TRY_LINK([#include -#include -#include ], [char src[128]; -struct in_addr dst; -inet_aton(src, &dst);], - [AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no) - AC_LIBOBJ(inet_aton)]) - -# -# Check for these after AC_LBL_LIBPCAP, for the same reason. -# # You are in a twisty little maze of UN*Xes, all different. # Some might not have ether_ntohost(). # Some might have it, but not declare it in any header file. @@ -753,14 +542,6 @@ fi # libdlpi is needed for Solaris 11 and later. AC_CHECK_LIB(dlpi, dlpi_walk, LIBS="$LIBS -ldlpi" LDFLAGS="-L/lib $LDFLAGS", ,-L/lib) -dnl portability macros for getaddrinfo/getnameinfo -dnl -dnl Check for sa_len -AC_CHECK_SA_LEN(ac_cv_sockaddr_has_sa_len) -if test "$ac_cv_sockaddr_has_sa_len" = no; then - missing_includes=yes -fi - dnl dnl Check for "pcap_list_datalinks()", "pcap_set_datalink()", dnl and "pcap_datalink_name_to_val()", and use substitute versions @@ -860,39 +641,51 @@ if test $ac_cv_func_pcap_lib_version = "no" ; then AC_MSG_RESULT(no) fi fi -AC_MSG_CHECKING(whether pcap_debug is defined by libpcap) -AC_TRY_LINK([], - [ - extern int pcap_debug; - - return pcap_debug; - ], - ac_lbl_cv_pcap_debug_defined=yes, - ac_lbl_cv_pcap_debug_defined=no) -if test "$ac_lbl_cv_pcap_debug_defined" = yes ; then - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_PCAP_DEBUG, 1, [define if libpcap has pcap_debug]) -else - AC_MSG_RESULT(no) - # - # OK, what about "yydebug"? + +# +# Check for special debugging functions +# +AC_CHECK_FUNCS(pcap_set_parser_debug) +if test "$ac_cv_func_pcap_set_parser_debug" = "no" ; then # - AC_MSG_CHECKING(whether yydebug is defined by libpcap) + # OK, we don't have pcap_set_parser_debug() to set the libpcap + # filter expression parser debug flag; can we directly set the + # flag? + AC_MSG_CHECKING(whether pcap_debug is defined by libpcap) AC_TRY_LINK([], [ - extern int yydebug; + extern int pcap_debug; - return yydebug; + return pcap_debug; ], - ac_lbl_cv_yydebug_defined=yes, - ac_lbl_cv_yydebug_defined=no) - if test "$ac_lbl_cv_yydebug_defined" = yes ; then + ac_lbl_cv_pcap_debug_defined=yes, + ac_lbl_cv_pcap_debug_defined=no) + if test "$ac_lbl_cv_pcap_debug_defined" = yes ; then AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_YYDEBUG, 1, [define if libpcap has yydebug]) + AC_DEFINE(HAVE_PCAP_DEBUG, 1, [define if libpcap has pcap_debug]) else AC_MSG_RESULT(no) + # + # OK, what about "yydebug"? + # + AC_MSG_CHECKING(whether yydebug is defined by libpcap) + AC_TRY_LINK([], + [ + extern int yydebug; + + return yydebug; + ], + ac_lbl_cv_yydebug_defined=yes, + ac_lbl_cv_yydebug_defined=no) + if test "$ac_lbl_cv_yydebug_defined" = yes ; then + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_YYDEBUG, 1, [define if libpcap has yydebug]) + else + AC_MSG_RESULT(no) + fi fi fi +AC_CHECK_FUNCS(pcap_set_optimizer_debug) AC_REPLACE_FUNCS(bpf_dump) dnl moved to libpcap in 0.6 V_GROUP=0 @@ -1071,9 +864,9 @@ fi # savedcppflags="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $V_INCLS" -AC_CHECK_HEADERS(pcap/bluetooth.h,,,[#include "tcpdump-stdinc.h"]) -AC_CHECK_HEADERS(pcap/nflog.h,,,[#include "tcpdump-stdinc.h"]) -AC_CHECK_HEADERS(pcap/usb.h,,,[#include "tcpdump-stdinc.h"]) +AC_CHECK_HEADERS(pcap/bluetooth.h,,,[#include "netdissect-stdinc.h"]) +AC_CHECK_HEADERS(pcap/nflog.h,,,[#include "netdissect-stdinc.h"]) +AC_CHECK_HEADERS(pcap/usb.h,,,[#include "netdissect-stdinc.h"]) CPPFLAGS="$savedcppflags" AC_PROG_RANLIB @@ -1085,35 +878,71 @@ AC_LBL_SOCKADDR_SA_LEN AC_LBL_UNALIGNED_ACCESS -AC_VAR_H_ERRNO - -# Check for OpenSSL libcrypto -AC_MSG_CHECKING(whether to use OpenSSL libcrypto) +# Check for OpenSSL/libressl libcrypto +AC_MSG_CHECKING(whether to use OpenSSL/libressl libcrypto) # Specify location for both includes and libraries. want_libcrypto=ifavailable AC_ARG_WITH(crypto, - AS_HELP_STRING([--with-crypto], - [use OpenSSL libcrypto @<:@default=yes, if available@:>@]), + AS_HELP_STRING([--with-crypto]@<:@=DIR@:>@, + [use OpenSSL/libressl libcrypto (located in directory DIR, if specified) @<:@default=yes, if available@:>@]), [ if test $withval = no then + # User doesn't want to link with libcrypto. want_libcrypto=no AC_MSG_RESULT(no) elif test $withval = yes then + # User wants to link with libcrypto but hasn't specified + # a directory. want_libcrypto=yes AC_MSG_RESULT(yes) + else + # User wants to link with libcrypto and has specified + # a directory, so use the provided value. + want_libcrypto=yes + libcrypto_root=$withval + AC_MSG_RESULT([yes, using the version installed in $withval]) + + # + # Put the subdirectories of the libcrypto root directory + # at the front of the header and library search path. + # + CFLAGS="-I$withval/include $CFLAGS" + LIBS="-L$withval/lib $LIBS" fi ],[ # - # Use libcrypto if it's present, otherwise don't. + # Use libcrypto if it's present, otherwise don't; no directory + # was specified. # want_libcrypto=ifavailable AC_MSG_RESULT([yes, if available]) ]) if test "$want_libcrypto" != "no"; then - AC_CHECK_LIB(crypto, DES_cbc_encrypt) - AC_CHECK_HEADERS(openssl/evp.h) + # + # Don't check for libcrypto unless we have its headers; + # Apple, bless their pointy little heads, apparently ship + # libcrypto as a library, but not the header files, in + # El Capitan, probably because they don't want you writing + # nasty portable code that could run on other UN*Xes, they + # want you writing code that uses their Shiny New Crypto + # Library and that only runs on OS X. + # + AC_CHECK_HEADER(openssl/crypto.h, + [ + AC_CHECK_LIB(crypto, DES_cbc_encrypt) + if test "$ac_cv_lib_crypto_DES_cbc_encrypt" = "yes"; then + AC_CHECK_HEADERS(openssl/evp.h) + # + # OK, do we have EVP_CIPHER_CTX_new? + # If so, we use it to allocate an + # EVP_CIPHER_CTX, as EVP_CIPHER_CTX may be + # opaque; otherwise, we allocate it ourselves. + # + AC_CHECK_FUNCS(EVP_CIPHER_CTX_new) + fi + ]) fi # Check for libcap-ng diff --git a/contrib/tcpdump/cpack.c b/contrib/tcpdump/cpack.c index 16bfd15..e37d813 100644 --- a/contrib/tcpdump/cpack.c +++ b/contrib/tcpdump/cpack.c @@ -27,20 +27,19 @@ * OF SUCH DAMAGE. */ -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include -#include +#include #include "cpack.h" #include "extract.h" -uint8_t * -cpack_next_boundary(uint8_t *buf, uint8_t *p, size_t alignment) +const uint8_t * +cpack_next_boundary(const uint8_t *buf, const uint8_t *p, size_t alignment) { size_t misalignment = (size_t)(p - buf) % alignment; @@ -54,10 +53,10 @@ cpack_next_boundary(uint8_t *buf, uint8_t *p, size_t alignment) * wordsize bytes remain in the buffer after the boundary. Otherwise, * return a pointer to the boundary. */ -uint8_t * +const uint8_t * cpack_align_and_reserve(struct cpack_state *cs, size_t wordsize) { - uint8_t *next; + const uint8_t *next; /* Ensure alignment. */ next = cpack_next_boundary(cs->c_buf, cs->c_next, wordsize); @@ -81,7 +80,7 @@ cpack_advance(struct cpack_state *cs, const size_t toskip) } int -cpack_init(struct cpack_state *cs, uint8_t *buf, size_t buflen) +cpack_init(struct cpack_state *cs, const uint8_t *buf, size_t buflen) { memset(cs, 0, sizeof(*cs)); @@ -96,7 +95,7 @@ cpack_init(struct cpack_state *cs, uint8_t *buf, size_t buflen) int cpack_uint64(struct cpack_state *cs, uint64_t *u) { - uint8_t *next; + const uint8_t *next; if ((next = cpack_align_and_reserve(cs, sizeof(*u))) == NULL) return -1; @@ -112,7 +111,7 @@ cpack_uint64(struct cpack_state *cs, uint64_t *u) int cpack_uint32(struct cpack_state *cs, uint32_t *u) { - uint8_t *next; + const uint8_t *next; if ((next = cpack_align_and_reserve(cs, sizeof(*u))) == NULL) return -1; @@ -128,7 +127,7 @@ cpack_uint32(struct cpack_state *cs, uint32_t *u) int cpack_uint16(struct cpack_state *cs, uint16_t *u) { - uint8_t *next; + const uint8_t *next; if ((next = cpack_align_and_reserve(cs, sizeof(*u))) == NULL) return -1; diff --git a/contrib/tcpdump/cpack.h b/contrib/tcpdump/cpack.h index a7eb6d6..3072e0c 100644 --- a/contrib/tcpdump/cpack.h +++ b/contrib/tcpdump/cpack.h @@ -31,20 +31,20 @@ #define _CPACK_H struct cpack_state { - uint8_t *c_buf; - uint8_t *c_next; + const uint8_t *c_buf; + const uint8_t *c_next; size_t c_len; }; -int cpack_init(struct cpack_state *, uint8_t *, size_t); +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 *); -uint8_t *cpack_next_boundary(uint8_t *buf, uint8_t *p, size_t alignment); -uint8_t *cpack_align_and_reserve(struct cpack_state *cs, size_t wordsize); +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); #define cpack_int8(__s, __p) cpack_uint8((__s), (uint8_t*)(__p)) #define cpack_int16(__s, __p) cpack_uint16((__s), (uint16_t*)(__p)) diff --git a/contrib/tcpdump/ether.h b/contrib/tcpdump/ether.h index 58b92de5..6491678 100644 --- a/contrib/tcpdump/ether.h +++ b/contrib/tcpdump/ether.h @@ -41,18 +41,17 @@ #define ETHER_ADDR_LEN 6 /* - * Structure of a DEC/Intel/Xerox or 802.3 Ethernet header. + * 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_type; + uint16_t ether_length_type; }; /* - * Length of a DEC/Intel/Xerox or 802.3 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. + * 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 diff --git a/contrib/tcpdump/ethertype.h b/contrib/tcpdump/ethertype.h index e855221..2aa53a0 100644 --- a/contrib/tcpdump/ethertype.h +++ b/contrib/tcpdump/ethertype.h @@ -17,7 +17,6 @@ * 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. - * $FreeBSD$ */ /* @@ -197,5 +196,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 */ +#endif extern const struct tok ethertype_values[]; diff --git a/contrib/tcpdump/extract.h b/contrib/tcpdump/extract.h index cb62ebd..23623c2 100644 --- a/contrib/tcpdump/extract.h +++ b/contrib/tcpdump/extract.h @@ -103,7 +103,7 @@ EXTRACT_32BITS(const void *p) static inline uint64_t EXTRACT_64BITS(const void *p) { - return ((uint64_t)(((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 0)->val)) << 32 | \ + 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)); } @@ -153,7 +153,7 @@ EXTRACT_32BITS(const void *p) static inline uint64_t EXTRACT_64BITS(const void *p) { - return ((uint64_t)(((uint64_t)ntohl(*((const uint32_t *)(p) + 0))) << 32 | \ + return ((uint64_t)(((uint64_t)ntohl(*((const uint32_t *)(p) + 0))) << 32 | ((uint64_t)ntohl(*((const uint32_t *)(p) + 1))) << 0)); } @@ -215,3 +215,30 @@ 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))) + +/* + * 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_16BITS(p) ND_TTEST2(*(p), 2) +#define ND_TCHECK_16BITS(p) ND_TCHECK2(*(p), 2) + +#define ND_TTEST_24BITS(p) ND_TTEST2(*(p), 3) +#define ND_TCHECK_24BITS(p) ND_TCHECK2(*(p), 3) + +#define ND_TTEST_32BITS(p) ND_TTEST2(*(p), 4) +#define ND_TCHECK_32BITS(p) ND_TCHECK2(*(p), 4) + +#define ND_TTEST_40BITS(p) ND_TTEST2(*(p), 5) +#define ND_TCHECK_40BITS(p) ND_TCHECK2(*(p), 5) + +#define ND_TTEST_48BITS(p) ND_TTEST2(*(p), 6) +#define ND_TCHECK_48BITS(p) ND_TCHECK2(*(p), 6) + +#define ND_TTEST_56BITS(p) ND_TTEST2(*(p), 7) +#define ND_TCHECK_56BITS(p) ND_TCHECK2(*(p), 7) + +#define ND_TTEST_64BITS(p) ND_TTEST2(*(p), 8) +#define ND_TCHECK_64BITS(p) ND_TCHECK2(*(p), 8) diff --git a/contrib/tcpdump/getopt_long.h b/contrib/tcpdump/getopt_long.h index fbb94e6..6eb7dfb 100644 --- a/contrib/tcpdump/getopt_long.h +++ b/contrib/tcpdump/getopt_long.h @@ -1,5 +1,5 @@ /* $NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $ */ -/* $FreeBSD$ */ +/* $FreeBSD: stable/11/contrib/tcpdump/getopt_long.h 276788 2015-01-07 19:55:18Z delphij $ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. diff --git a/contrib/tcpdump/gmpls.c b/contrib/tcpdump/gmpls.c index c9fd9bb..23515e9 100644 --- a/contrib/tcpdump/gmpls.c +++ b/contrib/tcpdump/gmpls.c @@ -13,14 +13,13 @@ * Original code by Hannes Gredler (hannes@juniper.net) */ -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "gmpls.h" /* rfc3471 */ diff --git a/contrib/tcpdump/gmt2local.c b/contrib/tcpdump/gmt2local.c index 6958f66..d6cd93b 100644 --- a/contrib/tcpdump/gmt2local.c +++ b/contrib/tcpdump/gmt2local.c @@ -19,12 +19,11 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include diff --git a/contrib/tcpdump/in_cksum.c b/contrib/tcpdump/in_cksum.c index 171728a..e9bed22 100644 --- a/contrib/tcpdump/in_cksum.c +++ b/contrib/tcpdump/in_cksum.c @@ -35,14 +35,13 @@ * @(#)in_cksum.c 8.1 (Berkeley) 6/10/93 */ -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H # include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" /* * Checksum routine for Internet Protocol family headers (Portable Version). @@ -74,7 +73,7 @@ in_cksum(const struct cksum_vec *vec, int veclen) for (; veclen != 0; vec++, veclen--) { if (vec->len == 0) continue; - w = (const uint16_t *)(void *)vec->ptr; + w = (const uint16_t *)(const void *)vec->ptr; if (mlen == -1) { /* * The first byte of this chunk is the continuation @@ -86,18 +85,18 @@ in_cksum(const struct cksum_vec *vec, int veclen) */ s_util.c[1] = *(const uint8_t *)w; sum += s_util.s; - w = (const uint16_t *)(void *)((const uint8_t *)w + 1); + w = (const uint16_t *)(const void *)((const uint8_t *)w + 1); mlen = vec->len - 1; } else mlen = vec->len; /* * Force to even boundary. */ - if ((1 & (unsigned long) w) && (mlen > 0)) { + if ((1 & (uintptr_t) w) && (mlen > 0)) { REDUCE; sum <<= 8; s_util.c[0] = *(const uint8_t *)w; - w = (const uint16_t *)(void *)((const uint8_t *)w + 1); + w = (const uint16_t *)(const void *)((const uint8_t *)w + 1); mlen--; byte_swapped = 1; } diff --git a/contrib/tcpdump/interface.h b/contrib/tcpdump/interface.h index 59c1eef..46d338b 100644 --- a/contrib/tcpdump/interface.h +++ b/contrib/tcpdump/interface.h @@ -65,165 +65,15 @@ extern char *strdup(const char *); extern char *strsep(char **, const char *); #endif -#define PT_VAT 1 /* Visual Audio Tool */ -#define PT_WB 2 /* distributed White Board */ -#define PT_RPC 3 /* Remote Procedure Call */ -#define PT_RTP 4 /* Real-Time Applications protocol */ -#define PT_RTCP 5 /* Real-Time Applications control protocol */ -#define PT_SNMP 6 /* Simple Network Management Protocol */ -#define PT_CNFP 7 /* Cisco NetFlow protocol */ -#define PT_TFTP 8 /* trivial file transfer protocol */ -#define PT_AODV 9 /* Ad-hoc On-demand Distance Vector Protocol */ -#define PT_CARP 10 /* Common Address Redundancy Protocol */ -#define PT_RADIUS 11 /* RADIUS authentication Protocol */ -#define PT_ZMTP1 12 /* ZeroMQ Message Transport Protocol 1.0 */ -#define PT_VXLAN 13 /* Virtual eXtensible Local Area Network */ -#define PT_PGM 14 /* [UDP-encapsulated] Pragmatic General Multicast */ -#define PT_PGM_ZMTP1 15 /* ZMTP/1.0 inside PGM (native or UDP-encapsulated) */ -#define PT_LMP 16 /* Link Management Protocol */ - -#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 #endif extern char *program_name; /* used to generate self-identifying messages */ -extern int32_t thiszone; /* seconds offset from gmt to local time */ - -/* - * True if "l" bytes of "var" were captured. - * - * The "snapend - (l) <= snapend" checks to make sure "l" isn't so large - * that "snapend - (l)" underflows. - * - * The check is for <= rather than < because "l" might be 0. - * - * We cast the pointers to uintptr_t to make sure that the compiler - * doesn't optimize away any of these tests (which it is allowed to - * do, as adding an integer to, or subtracting an integer from, a - * pointer assumes that the pointer is a pointer to an element of an - * array and that the result of the addition or subtraction yields a - * pointer to another member of the array, so that, for example, if - * 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 - */ -#define TTEST2(var, l) \ - ((uintptr_t)snapend - (l) <= (uintptr_t)snapend && \ - (uintptr_t)&(var) <= (uintptr_t)snapend - (l)) - -/* True if "var" was captured */ -#define TTEST(var) TTEST2(var, sizeof(var)) - -/* Bail if "l" bytes of "var" were not captured */ -#define TCHECK2(var, l) if (!TTEST2(var, l)) goto trunc - -/* Bail if "var" was not captured */ -#define TCHECK(var) TCHECK2(var, sizeof(var)) - -extern int mask2plen(uint32_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) - -extern void error(const char *, ...) - __attribute__((noreturn)) -#ifdef __ATTRIBUTE___FORMAT_OK - __attribute__((format (printf, 1, 2))) -#endif /* __ATTRIBUTE___FORMAT_OK */ - ; -extern void warning(const char *, ...) -#ifdef __ATTRIBUTE___FORMAT_OK - __attribute__((format (printf, 1, 2))) -#endif /* __ATTRIBUTE___FORMAT_OK */ - ; - -extern char *read_infile(char *); -extern char *copy_argv(char **); - -extern const char *dnname_string(u_short); -extern const char *dnnum_string(u_short); - -/* checksum routines */ -extern void init_checksum(void); -extern uint16_t verify_crc10_cksum(uint16_t, const u_char *, int); -extern uint16_t create_osi_cksum(const uint8_t *, int, int); - -/* The printer routines. */ - #include -extern char *smb_errstr(int, int); -extern const char *nt_errstr(uint32_t); - -#ifdef INET6 -extern int mask62plen(const u_char *); -#endif /*INET6*/ - -struct cksum_vec { - const uint8_t *ptr; - int len; -}; -extern uint16_t in_cksum(const struct cksum_vec *, int); -extern uint16_t in_cksum_shouldbe(uint16_t, uint16_t); - #ifndef HAVE_BPF_DUMP struct bpf_program; extern void bpf_dump(const struct bpf_program *, int); #endif - -#include "netdissect.h" - -/* forward compatibility */ - -#ifndef NETDISSECT_REWORKED -extern netdissect_options *gndo; - -#define bflag gndo->ndo_bflag -#define eflag gndo->ndo_eflag -#define fflag gndo->ndo_fflag -#define jflag gndo->ndo_jflag -#define Kflag gndo->ndo_Kflag -#define nflag gndo->ndo_nflag -#define Nflag gndo->ndo_Nflag -#define Oflag gndo->ndo_Oflag -#define pflag gndo->ndo_pflag -#define qflag gndo->ndo_qflag -#define Rflag gndo->ndo_Rflag -#define sflag gndo->ndo_sflag -#define Sflag gndo->ndo_Sflag -#define tflag gndo->ndo_tflag -#define Uflag gndo->ndo_Uflag -#define uflag gndo->ndo_uflag -#define vflag gndo->ndo_vflag -#define xflag gndo->ndo_xflag -#define Xflag gndo->ndo_Xflag -#define Cflag gndo->ndo_Cflag -#define Gflag gndo->ndo_Gflag -#define Aflag gndo->ndo_Aflag -#define Bflag gndo->ndo_Bflag -#define Iflag gndo->ndo_Iflag -#define suppress_default_print gndo->ndo_suppress_default_print -#define packettype gndo->ndo_packettype -#define sigsecret gndo->ndo_sigsecret -#define Wflag gndo->ndo_Wflag -#define WflagChars gndo->ndo_WflagChars -#define Cflag_count gndo->ndo_Cflag_count -#define Gflag_count gndo->ndo_Gflag_count -#define Gflag_time gndo->ndo_Gflag_time -#define Hflag gndo->ndo_Hflag -#define snaplen gndo->ndo_snaplen -#define snapend gndo->ndo_snapend - -extern void default_print(const u_char *, u_int); - -#endif diff --git a/contrib/tcpdump/ip.h b/contrib/tcpdump/ip.h index 72c8972..8179061 100644 --- a/contrib/tcpdump/ip.h +++ b/contrib/tcpdump/ip.h @@ -33,10 +33,8 @@ * @(#)ip.h 8.2 (Berkeley) 6/1/94 */ -#ifndef TCPDUMP_IP_H -#define TCPDUMP_IP_H - -#include "tcpdump-stdinc.h" +#ifndef netdissect_ip_h +#define netdissect_ip_h /* * Definitions for internet protocol version 4. @@ -52,21 +50,21 @@ * against negative integers quite easily, and fail in subtle ways. */ struct ip { - uint8_t ip_vhl; /* header length, version */ + 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) - uint8_t ip_tos; /* type of service */ - uint16_t ip_len; /* total length */ - uint16_t ip_id; /* identification */ - uint16_t ip_off; /* fragment offset field */ + 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_MF 0x2000 /* more fragments flag */ #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ - uint8_t ip_ttl; /* time to live */ - uint8_t ip_p; /* protocol */ - uint16_t ip_sum; /* checksum */ - struct in_addr ip_src,ip_dst; /* source and dest address */ -} UNALIGNED; + nd_uint8_t ip_ttl; /* time to live */ + nd_uint8_t ip_p; /* protocol */ + nd_uint16_t ip_sum; /* checksum */ + nd_ipv4 ip_src,ip_dst; /* source and dest address */ +}; #define IP_MAXPACKET 65535 /* maximum packet size */ @@ -125,20 +123,20 @@ struct ip { * Time stamp option structure. */ struct ip_timestamp { - uint8_t ipt_code; /* IPOPT_TS */ - uint8_t ipt_len; /* size of structure (variable) */ - uint8_t ipt_ptr; /* index of current entry */ - uint8_t ipt_oflwflg; /* flags, overflow counter */ + nd_uint8_t ipt_code; /* IPOPT_TS */ + nd_uint8_t ipt_len; /* size of structure (variable) */ + nd_uint8_t ipt_ptr; /* index of current entry */ + nd_uint8_t ipt_oflwflg; /* flags, overflow counter */ #define IPTS_OFLW(ip) (((ipt)->ipt_oflwflg & 0xf0) >> 4) #define IPTS_FLG(ip) ((ipt)->ipt_oflwflg & 0x0f) union ipt_timestamp { - uint32_t ipt_time[1]; + nd_uint32_t ipt_time[1]; struct ipt_ta { - struct in_addr ipt_addr; - uint32_t ipt_time; + nd_ipv4 ipt_addr; + nd_uint32_t ipt_time; } ipt_ta[1]; } ipt_timestamp; -} UNALIGNED; +}; /* flag bits for ipt_flg */ #define IPOPT_TS_TSONLY 0 /* timestamps only */ @@ -163,4 +161,4 @@ struct ip_timestamp { #define IPTTLDEC 1 /* subtracted when forwarding */ #define IP_MSS 576 /* default maximum segment size */ -#endif /* TCPDUMP_IP_H */ +#endif /* netdissect_ip_h */ diff --git a/contrib/tcpdump/ip6.h b/contrib/tcpdump/ip6.h index 1ad9149..2ea1d0a 100644 --- a/contrib/tcpdump/ip6.h +++ b/contrib/tcpdump/ip6.h @@ -172,7 +172,11 @@ struct ip6_rthdr { /* followed by routing type specific data */ } UNALIGNED; +#define IPV6_RTHDR_TYPE_0 0 +#define IPV6_RTHDR_TYPE_2 2 + /* Type 0 Routing header */ +/* Also used for Type 2 */ struct ip6_rthdr0 { uint8_t ip6r0_nxt; /* next header */ uint8_t ip6r0_len; /* length in units of 8 octets */ @@ -195,7 +199,4 @@ struct ip6_frag { #define IP6F_RESERVED_MASK 0x0006 /* reserved bits in ip6f_offlg */ #define IP6F_MORE_FRAG 0x0001 /* more-fragments flag */ -/* in print-ip6.c */ -extern int nextproto6_cksum(const struct ip6_hdr *, const uint8_t *, u_int, u_int, u_int); - #endif /* not _NETINET_IP6_H_ */ diff --git a/contrib/tcpdump/ipproto.c b/contrib/tcpdump/ipproto.c index 8300d1a..a702acd 100644 --- a/contrib/tcpdump/ipproto.c +++ b/contrib/tcpdump/ipproto.c @@ -13,14 +13,13 @@ * Original code by Hannes Gredler (hannes@juniper.net) */ -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "ipproto.h" const struct tok ipproto_values[] = { diff --git a/contrib/tcpdump/ipproto.h b/contrib/tcpdump/ipproto.h index 87e2f15..dfc4f46 100644 --- a/contrib/tcpdump/ipproto.h +++ b/contrib/tcpdump/ipproto.h @@ -32,8 +32,7 @@ * * From: * @(#)in.h 8.3 (Berkeley) 1/3/94 - * $FreeBSD$ - * FreeBSD: src/sys/netinet/in.h,v 1.38.2.3 1999/08/29 16:29:34 peter Exp + * $FreeBSD: stable/11/contrib/tcpdump/ipproto.h 276788 2015-01-07 19:55:18Z delphij $ */ extern const struct tok ipproto_values[]; diff --git a/contrib/tcpdump/l2vpn.c b/contrib/tcpdump/l2vpn.c index 54037aa..3f3639f 100644 --- a/contrib/tcpdump/l2vpn.c +++ b/contrib/tcpdump/l2vpn.c @@ -13,42 +13,83 @@ * Original code by Hannes Gredler (hannes@juniper.net) */ -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include -#include "interface.h" +#include +#include "netdissect.h" #include "l2vpn.h" -/* draft-ietf-pwe3-iana-allocation-04 */ +/* + * BGP Layer 2 Encapsulation Types + * + * RFC 6624 + * + * http://www.iana.org/assignments/bgp-parameters/bgp-parameters.xhtml#bgp-l2-encapsulation-types-registry + */ const struct tok l2vpn_encaps_values[] = { - { 0x00, "Reserved"}, - { 0x01, "Frame Relay"}, - { 0x02, "ATM AAL5 VCC transport"}, - { 0x03, "ATM transparent cell transport"}, - { 0x04, "Ethernet VLAN"}, - { 0x05, "Ethernet"}, - { 0x06, "Cisco-HDLC"}, - { 0x07, "PPP"}, - { 0x08, "SONET/SDH Circuit Emulation Service over MPLS"}, - { 0x09, "ATM n-to-one VCC cell transport"}, - { 0x0a, "ATM n-to-one VPC cell transport"}, - { 0x0b, "IP Layer2 Transport"}, - { 0x0c, "ATM one-to-one VCC Cell Mode"}, - { 0x0d, "ATM one-to-one VPC Cell Mode"}, - { 0x0e, "ATM AAL5 PDU VCC transport"}, - { 0x0f, "Frame-Relay Port mode"}, - { 0x10, "SONET/SDH Circuit Emulation over Packet"}, - { 0x11, "Structure-agnostic E1 over Packet"}, - { 0x12, "Structure-agnostic T1 (DS1) over Packet"}, - { 0x13, "Structure-agnostic E3 over Packet"}, - { 0x14, "Structure-agnostic T3 (DS3) over Packet"}, - { 0x15, "CESoPSN basic mode"}, - { 0x16, "TDMoIP basic mode"}, - { 0x17, "CESoPSN TDM with CAS"}, - { 0x18, "TDMoIP TDM with CAS"}, - { 0x40, "IP-interworking"}, + { 0, "Reserved"}, + { 1, "Frame Relay"}, + { 2, "ATM AAL5 SDU VCC transport"}, + { 3, "ATM transparent cell transport"}, + { 4, "Ethernet (VLAN) Tagged Mode"}, + { 5, "Ethernet Raw Mode"}, + { 6, "Cisco HDLC"}, + { 7, "PPP"}, + { 8, "SONET/SDH Circuit Emulation Service over MPLS"}, + { 9, "ATM n-to-one VCC cell transport"}, + { 10, "ATM n-to-one VPC cell transport"}, + { 11, "IP layer 2 transport"}, + { 15, "Frame Relay Port mode"}, + { 17, "Structure-agnostic E1 over packet"}, + { 18, "Structure-agnostic T1 (DS1) over packet"}, + { 19, "VPLS"}, + { 20, "Structure-agnostic T3 (DS3) over packet"}, + { 21, "Nx64kbit/s Basic Service using Structure-aware"}, + { 25, "Frame Relay DLCI"}, + { 40, "Structure-agnostic E3 over packet"}, + { 41, "Octet-aligned playload for Structure-agnostic DS1 circuits"}, + { 42, "E1 Nx64kbit/s with CAS using Structure-aware"}, + { 43, "DS1 (ESF) Nx64kbit/s with CAS using Structure-aware"}, + { 44, "DS1 (SF) Nx64kbit/s with CAS using Structure-aware"}, + { 0, NULL} +}; + +/* + * MPLS Pseudowire Types + * + * RFC 4446 + * + * http://www.iana.org/assignments/pwe3-parameters/pwe3-parameters.xhtml#pwe3-parameters-2 + */ +const struct tok mpls_pw_types_values[] = { + { 0x0000, "Reserved"}, + { 0x0001, "Frame Relay DLCI (Martini Mode)"}, + { 0x0002, "ATM AAL5 SDU VCC transport"}, + { 0x0003, "ATM transparent cell transport"}, + { 0x0004, "Ethernet VLAN"}, + { 0x0005, "Ethernet"}, + { 0x0006, "Cisco-HDLC"}, + { 0x0007, "PPP"}, + { 0x0008, "SONET/SDH Circuit Emulation Service over MPLS"}, + { 0x0009, "ATM n-to-one VCC cell transport"}, + { 0x000a, "ATM n-to-one VPC cell transport"}, + { 0x000b, "IP Layer2 Transport"}, + { 0x000c, "ATM one-to-one VCC Cell Mode"}, + { 0x000d, "ATM one-to-one VPC Cell Mode"}, + { 0x000e, "ATM AAL5 PDU VCC transport"}, + { 0x000f, "Frame-Relay Port mode"}, + { 0x0010, "SONET/SDH Circuit Emulation over Packet"}, + { 0x0011, "Structure-agnostic E1 over Packet"}, + { 0x0012, "Structure-agnostic T1 (DS1) over Packet"}, + { 0x0013, "Structure-agnostic E3 over Packet"}, + { 0x0014, "Structure-agnostic T3 (DS3) over Packet"}, + { 0x0015, "CESoPSN basic mode"}, + { 0x0016, "TDMoIP basic mode"}, + { 0x0017, "CESoPSN TDM with CAS"}, + { 0x0018, "TDMoIP TDM with CAS"}, + { 0x0019, "Frame Relay DLCI"}, + { 0x0040, "IP-interworking"}, { 0, NULL} }; diff --git a/contrib/tcpdump/l2vpn.h b/contrib/tcpdump/l2vpn.h index 151228f..d93abf1 100644 --- a/contrib/tcpdump/l2vpn.h +++ b/contrib/tcpdump/l2vpn.h @@ -14,3 +14,4 @@ */ extern const struct tok l2vpn_encaps_values[]; +extern const struct tok mpls_pw_types_values[]; diff --git a/contrib/tcpdump/lbl/os-solaris2.h b/contrib/tcpdump/lbl/os-solaris2.h index 9f94da9..aedba4e 100644 --- a/contrib/tcpdump/lbl/os-solaris2.h +++ b/contrib/tcpdump/lbl/os-solaris2.h @@ -25,4 +25,3 @@ int setlinebuf(FILE *); #endif char *strerror(int); int snprintf(char *, size_t, const char *, ...); -int strcasecmp(const char *, const char *); diff --git a/contrib/tcpdump/lbl/os-sunos4.h b/contrib/tcpdump/lbl/os-sunos4.h index b735857..0e63270 100644 --- a/contrib/tcpdump/lbl/os-sunos4.h +++ b/contrib/tcpdump/lbl/os-sunos4.h @@ -166,12 +166,10 @@ int sscanf(char *, const char *, ...); int stat(const char *, struct stat *); int statfs(char *, struct statfs *); char *strerror(int); -int strcasecmp(const char *, const char *); #ifdef __STDC__ struct tm; #endif int strftime(char *, int, char *, struct tm *); -int strncasecmp(const char *, const char *, int); long strtol(const char *, char **, int); void sync(void); void syslog(int, const char *, ...); diff --git a/contrib/tcpdump/lbl/os-ultrix4.h b/contrib/tcpdump/lbl/os-ultrix4.h index fa1f770..891def2 100644 --- a/contrib/tcpdump/lbl/os-ultrix4.h +++ b/contrib/tcpdump/lbl/os-ultrix4.h @@ -34,4 +34,3 @@ int ioctl(int, int, caddr_t); int pfopen(char *, int); int setlinebuf(FILE *); int socket(int, int, int); -int strcasecmp(const char *, const char *); diff --git a/contrib/tcpdump/machdep.c b/contrib/tcpdump/machdep.c index 7b259ae..1f08616 100644 --- a/contrib/tcpdump/machdep.c +++ b/contrib/tcpdump/machdep.c @@ -29,7 +29,7 @@ * 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 +#include #ifndef HAVE___ATTRIBUTE__ #define __attribute__(x) diff --git a/contrib/tcpdump/machdep.h b/contrib/tcpdump/machdep.h index d1c7d4b..ba8ed38 100644 --- a/contrib/tcpdump/machdep.h +++ b/contrib/tcpdump/machdep.h @@ -18,8 +18,8 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#ifndef tcpdump_machdep_h -#define tcpdump_machdep_h +#ifndef netdissect_machdep_h +#define netdissect_machdep_h int abort_on_misalignment(char *, size_t); #endif diff --git a/contrib/tcpdump/mib.h b/contrib/tcpdump/mib.h index 92c6c2c..6c8e63c 100644 --- a/contrib/tcpdump/mib.h +++ b/contrib/tcpdump/mib.h @@ -8,7 +8,7 @@ /* parse problem: new name "mib" for mgmt.mib(1) ignored */ /* parse problem: no parent for 0.nullSpecific(0) */ -struct obj +static struct obj _proteon_obj = { "proteon", 1, 0, NULL, NULL diff --git a/contrib/tcpdump/missing/addrinfo.h b/contrib/tcpdump/missing/addrinfo.h deleted file mode 100644 index bf4bbf6..0000000 --- a/contrib/tcpdump/missing/addrinfo.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE 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. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef HAVE_ADDRINFO - -/* - * Error return codes from getaddrinfo() - */ -#define EAI_ADDRFAMILY 1 /* address family for hostname not supported */ -#define EAI_AGAIN 2 /* temporary failure in name resolution */ -#define EAI_BADFLAGS 3 /* invalid value for ai_flags */ -#define EAI_FAIL 4 /* non-recoverable failure in name resolution */ -#define EAI_FAMILY 5 /* ai_family not supported */ -#define EAI_MEMORY 6 /* memory allocation failure */ -#define EAI_NODATA 7 /* no address associated with hostname */ -#define EAI_NONAME 8 /* hostname nor servname provided, or not known */ -#define EAI_SERVICE 9 /* servname not supported for ai_socktype */ -#define EAI_SOCKTYPE 10 /* ai_socktype not supported */ -#define EAI_SYSTEM 11 /* system error returned in errno */ -#define EAI_BADHINTS 12 -#define EAI_PROTOCOL 13 -#define EAI_MAX 14 - -/* internal error */ -#define NETDB_INTERNAL -1 /* see errno */ - -/* - * Flag values for getaddrinfo() - */ -#define AI_PASSIVE 0x00000001 /* get address to use bind() */ -#define AI_CANONNAME 0x00000002 /* fill ai_canonname */ -#define AI_NUMERICHOST 0x00000004 /* prevent name resolution */ -/* valid flags for addrinfo */ -#define AI_MASK (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST) - -#define AI_ALL 0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */ -#define AI_V4MAPPED_CFG 0x00000200 /* accept IPv4-mapped if kernel supports */ -#define AI_ADDRCONFIG 0x00000400 /* only if any address is assigned */ -#define AI_V4MAPPED 0x00000800 /* accept IPv4-mapped IPv6 address */ -/* special recommended flags for getipnodebyname */ -#define AI_DEFAULT (AI_V4MAPPED_CFG | AI_ADDRCONFIG) - -struct addrinfo { - int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ - int ai_family; /* PF_xxx */ - int ai_socktype; /* SOCK_xxx */ - int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ - size_t ai_addrlen; /* length of ai_addr */ - char *ai_canonname; /* canonical name for hostname */ - struct sockaddr *ai_addr; /* binary address */ - struct addrinfo *ai_next; /* next structure in linked list */ -}; - -extern void freeaddrinfo (struct addrinfo *); -extern void freehostent (struct hostent *); -extern int getnameinfo (const struct sockaddr *, size_t, char *, - size_t, char *, size_t, int); -extern struct hostent *getipnodebyaddr (const void *, size_t, int, int *); -extern struct hostent *getipnodebyname (const char *, int, int, int *); -extern int inet_pton (int, const char *, void *); -extern const char *inet_ntop (int, const void *, char *, size_t); -#endif /* HAVE_ADDRINFO */ - -/* - * Constants for getnameinfo() - */ -#ifndef NI_MAXHOST -#define NI_MAXHOST 1025 -#endif -#ifndef NI_MAXSERV -#define NI_MAXSERV 32 -#endif - -/* - * Flag values for getnameinfo() - */ -#ifndef NI_NOFQDN -#define NI_NOFQDN 0x00000001 -#endif -#ifndef NI_NUMERICHOST -#define NI_NUMERICHOST 0x00000002 -#endif -#ifndef NI_NAMEREQD -#define NI_NAMEREQD 0x00000004 -#endif -#ifndef NI_NUMERICSERV -#define NI_NUMERICSERV 0x00000008 -#endif -#ifndef NI_DGRAM -#define NI_DGRAM 0x00000010 -#endif diff --git a/contrib/tcpdump/missing/datalinks.c b/contrib/tcpdump/missing/datalinks.c index e7d526b..4a7d6fe 100644 --- a/contrib/tcpdump/missing/datalinks.c +++ b/contrib/tcpdump/missing/datalinks.c @@ -35,7 +35,7 @@ #include "config.h" #endif -#include +#include #include #include diff --git a/contrib/tcpdump/missing/dlnames.c b/contrib/tcpdump/missing/dlnames.c index a10cd39..16bfcf7 100644 --- a/contrib/tcpdump/missing/dlnames.c +++ b/contrib/tcpdump/missing/dlnames.c @@ -35,12 +35,13 @@ #include "config.h" #endif -#include +#include #include #include #include "pcap-missing.h" +#include "ascii_strcasecmp.h" struct dlt_choice { const char *name; @@ -137,7 +138,7 @@ pcap_datalink_name_to_val(const char *name) int i; for (i = 0; dlt_choices[i].name != NULL; i++) { - if (strcasecmp(dlt_choices[i].name + sizeof("DLT_") - 1, + if (ascii_strcasecmp(dlt_choices[i].name + sizeof("DLT_") - 1, name) == 0) return (dlt_choices[i].dlt); } diff --git a/contrib/tcpdump/missing/getnameinfo.c b/contrib/tcpdump/missing/getnameinfo.c deleted file mode 100644 index 63aba73..0000000 --- a/contrib/tcpdump/missing/getnameinfo.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright (C) 1995, 1996, 1997, and 1998 WIDE 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. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Issues to be discussed: - * - Thread safe-ness must be checked - * - Return values. There seems to be no standard for return value (RFC2553) - * but INRIA implementation returns EAI_xxx defined for getaddrinfo(). - * - RFC2553 says that we should raise error on short buffer. X/Open says - * we need to truncate the result. We obey RFC2553 (and X/Open should be - * modified). - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef NEED_ADDRINFO_H -#include "addrinfo.h" -#endif - -#define SUCCESS 0 -#define ANY 0 -#define YES 1 -#define NO 0 - -static struct afd { - int a_af; - int a_addrlen; - int a_socklen; - int a_off; -} afdl [] = { -#ifdef INET6 - {PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6), - offsetof(struct sockaddr_in6, sin6_addr)}, -#endif - {PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in), - offsetof(struct sockaddr_in, sin_addr)}, - {0, 0, 0}, -}; - -struct sockinet { - u_char si_len; - u_char si_family; - u_short si_port; -}; - -#define ENI_NOSOCKET 0 -#define ENI_NOSERVNAME 1 -#define ENI_NOHOSTNAME 2 -#define ENI_MEMORY 3 -#define ENI_SYSTEM 4 -#define ENI_FAMILY 5 -#define ENI_SALEN 6 - -int -getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) - const struct sockaddr *sa; - size_t salen; - char *host; - size_t hostlen; - char *serv; - size_t servlen; - int flags; -{ - struct afd *afd; - struct servent *sp; - struct hostent *hp; - u_short port; - int family, i; - char *addr, *p; - uint32_t v4a; - int h_error; - char numserv[512]; - char numaddr[512]; - - if (sa == NULL) - return ENI_NOSOCKET; - -#ifdef HAVE_SA_LEN /*XXX*/ - if (sa->sa_len != salen) - return ENI_SALEN; -#endif - - family = sa->sa_family; - for (i = 0; afdl[i].a_af; i++) - if (afdl[i].a_af == family) { - afd = &afdl[i]; - goto found; - } - return ENI_FAMILY; - - found: - if (salen != afd->a_socklen) - return ENI_SALEN; - - port = ((struct sockinet *)sa)->si_port; /* network byte order */ - addr = (char *)sa + afd->a_off; - - if (serv == NULL || servlen == 0) { - /* - * do nothing in this case. - * in case you are wondering if "&&" is more correct than - * "||" here: RFC2553 says that serv == NULL OR servlen == 0 - * means that the caller does not want the result. - */ - } else { - if (flags & NI_NUMERICSERV) - sp = NULL; - else { - sp = getservbyport(port, - (flags & NI_DGRAM) ? "udp" : "tcp"); - } - if (sp) { - if (strlen(sp->s_name) + 1 > servlen) - return ENI_MEMORY; - strcpy(serv, sp->s_name); - } else { - snprintf(numserv, sizeof(numserv), "%d", ntohs(port)); - if (strlen(numserv) + 1 > servlen) - return ENI_MEMORY; - strcpy(serv, numserv); - } - } - - switch (sa->sa_family) { - case AF_INET: - v4a = (uint32_t) - ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr); - if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) - flags |= NI_NUMERICHOST; - v4a >>= IN_CLASSA_NSHIFT; - if (v4a == 0) - flags |= NI_NUMERICHOST; - break; -#ifdef INET6 - case AF_INET6: - { - struct sockaddr_in6 *sin6; - sin6 = (struct sockaddr_in6 *)sa; - switch (sin6->sin6_addr.s6_addr[0]) { - case 0x00: - if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) - ; - else if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr)) - ; - else - flags |= NI_NUMERICHOST; - break; - default: - if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { - flags |= NI_NUMERICHOST; - } - else if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) - flags |= NI_NUMERICHOST; - break; - } - } - break; -#endif - } - if (host == NULL || hostlen == 0) { - /* - * do nothing in this case. - * in case you are wondering if "&&" is more correct than - * "||" here: RFC2553 says that host == NULL OR hostlen == 0 - * means that the caller does not want the result. - */ - } else if (flags & NI_NUMERICHOST) { - /* NUMERICHOST and NAMEREQD conflicts with each other */ - if (flags & NI_NAMEREQD) - return ENI_NOHOSTNAME; - if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr)) - == NULL) - return ENI_SYSTEM; - if (strlen(numaddr) + 1 > hostlen) - return ENI_MEMORY; - strcpy(host, numaddr); -#if defined(INET6) && defined(NI_WITHSCOPEID) - if (afd->a_af == AF_INET6 && - (IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)addr) || - IN6_IS_ADDR_MULTICAST((struct in6_addr *)addr)) && - ((struct sockaddr_in6 *)sa)->sin6_scope_id) { -#ifndef ALWAYS_WITHSCOPE - if (flags & NI_WITHSCOPEID) -#endif /* !ALWAYS_WITHSCOPE */ - { - char *ep = strchr(host, '\0'); - unsigned int ifindex = - ((struct sockaddr_in6 *)sa)->sin6_scope_id; - - *ep = SCOPE_DELIMITER; - if ((if_indextoname(ifindex, ep + 1)) == NULL) - /* XXX what should we do? */ - strncpy(ep + 1, "???", 3); - } - } -#endif /* INET6 */ - } else { -#ifdef USE_GETIPNODEBY - hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error); -#else - hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af); -#ifdef HAVE_H_ERRNO - h_error = h_errno; -#else - h_error = EINVAL; -#endif -#endif - - if (hp) { - if (flags & NI_NOFQDN) { - p = strchr(hp->h_name, '.'); - if (p) *p = '\0'; - } - if (strlen(hp->h_name) + 1 > hostlen) { -#ifdef USE_GETIPNODEBY - freehostent(hp); -#endif - return ENI_MEMORY; - } - strcpy(host, hp->h_name); -#ifdef USE_GETIPNODEBY - freehostent(hp); -#endif - } else { - if (flags & NI_NAMEREQD) - return ENI_NOHOSTNAME; - if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr)) - == NULL) - return ENI_NOHOSTNAME; - if (strlen(numaddr) + 1 > hostlen) - return ENI_MEMORY; - strcpy(host, numaddr); - } - } - return SUCCESS; -} diff --git a/contrib/tcpdump/missing/inet_aton.c b/contrib/tcpdump/missing/inet_aton.c deleted file mode 100644 index e85ad5f..0000000 --- a/contrib/tcpdump/missing/inet_aton.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * 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 Kungliga Tekniska - * Högskolan and its contributors. - * - * 4. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - */ - -#include - -/* Minimal implementation of inet_aton. - * Cannot distinguish between failure and a local broadcast address. */ - -#ifndef INADDR_NONE -#define INADDR_NONE 0xffffffff -#endif - -int -inet_aton(const char *cp, struct in_addr *addr) -{ - addr->s_addr = inet_addr(cp); - return (addr->s_addr == INADDR_NONE) ? 0 : 1; -} diff --git a/contrib/tcpdump/missing/inet_ntop.c b/contrib/tcpdump/missing/inet_ntop.c deleted file mode 100644 index 8c6f7eb..0000000 --- a/contrib/tcpdump/missing/inet_ntop.c +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (c) 1999 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * 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 Kungliga Tekniska - * Högskolan and its contributors. - * - * 4. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include - -/* - * - */ - -#ifndef IN6ADDRSZ -#define IN6ADDRSZ 16 /* IPv6 T_AAAA */ -#endif - -#ifndef INT16SZ -#define INT16SZ 2 /* word size */ -#endif - -static const char * -inet_ntop_v4 (const void *src, char *dst, size_t size) -{ - const char digits[] = "0123456789"; - int i; - struct in_addr *addr = (struct in_addr *)src; - u_long a = ntohl(addr->s_addr); - const char *orig_dst = dst; - - if (size < INET_ADDRSTRLEN) { - errno = ENOSPC; - return NULL; - } - for (i = 0; i < 4; ++i) { - int n = (a >> (24 - i * 8)) & 0xFF; - int non_zerop = 0; - - if (non_zerop || n / 100 > 0) { - *dst++ = digits[n / 100]; - n %= 100; - non_zerop = 1; - } - if (non_zerop || n / 10 > 0) { - *dst++ = digits[n / 10]; - n %= 10; - non_zerop = 1; - } - *dst++ = digits[n]; - if (i != 3) - *dst++ = '.'; - } - *dst++ = '\0'; - return orig_dst; -} - -#ifdef INET6 -/* - * Convert IPv6 binary address into presentation (printable) format. - */ -static const char * -inet_ntop_v6 (const u_char *src, char *dst, size_t size) -{ - /* - * Note that int32_t and int16_t need only be "at least" large enough - * to contain a value of the specified size. On some systems, like - * Crays, there is no such thing as an integer variable with 16 bits. - * Keep this in mind if you think this function should have been coded - * to use pointer overlays. All the world's not a VAX. - */ - char tmp [INET6_ADDRSTRLEN+1]; - char *tp; - struct { - long base; - long len; - } best, cur; - u_long words [IN6ADDRSZ / INT16SZ]; - int i; - - /* Preprocess: - * Copy the input (bytewise) array into a wordwise array. - * Find the longest run of 0x00's in src[] for :: shorthanding. - */ - memset (words, 0, sizeof(words)); - for (i = 0; i < IN6ADDRSZ; i++) - words[i/2] |= (src[i] << ((1 - (i % 2)) << 3)); - - best.len = 0; - best.base = -1; - cur.len = 0; - cur.base = -1; - for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) - { - if (words[i] == 0) - { - if (cur.base == -1) - cur.base = i, cur.len = 1; - else cur.len++; - } - else if (cur.base != -1) - { - if (best.base == -1 || cur.len > best.len) - best = cur; - cur.base = -1; - } - } - if ((cur.base != -1) && (best.base == -1 || cur.len > best.len)) - best = cur; - if (best.base != -1 && best.len < 2) - best.base = -1; - - /* Format the result. - */ - tp = tmp; - for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) - { - /* Are we inside the best run of 0x00's? - */ - if (best.base != -1 && i >= best.base && i < (best.base + best.len)) - { - if (i == best.base) - *tp++ = ':'; - continue; - } - - /* Are we following an initial run of 0x00s or any real hex? - */ - if (i != 0) - *tp++ = ':'; - - /* Is this address an encapsulated IPv4? - */ - if (i == 6 && best.base == 0 && - (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) - { - if (!inet_ntop_v4(src+12, tp, sizeof(tmp) - (tp - tmp))) - { - errno = ENOSPC; - return (NULL); - } - tp += strlen(tp); - break; - } - tp += sprintf (tp, "%lx", words[i]); - } - - /* Was it a trailing run of 0x00's? - */ - if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) - *tp++ = ':'; - *tp++ = '\0'; - - /* Check for overflow, copy, and we're done. - */ - if ((size_t)(tp - tmp) > size) - { - errno = ENOSPC; - return (NULL); - } - return strcpy (dst, tmp); -} -#endif /* INET6 */ - - -const char * -inet_ntop(int af, const void *src, char *dst, size_t size) -{ - switch (af) { - case AF_INET : - return inet_ntop_v4 (src, dst, size); -#ifdef INET6 - case AF_INET6: - return inet_ntop_v6 ((const u_char*)src, dst, size); -#endif - default : - errno = EAFNOSUPPORT; - return NULL; - } -} diff --git a/contrib/tcpdump/missing/inet_pton.c b/contrib/tcpdump/missing/inet_pton.c deleted file mode 100644 index 3466f42..0000000 --- a/contrib/tcpdump/missing/inet_pton.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 1999 Kungliga Tekniska H�gskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * 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 Kungliga Tekniska - * H�gskolan and its contributors. - * - * 4. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - */ - -#include - -int -inet_pton(int af, const char *src, void *dst) -{ - if (af != AF_INET) { - errno = EAFNOSUPPORT; - return -1; - } - return inet_aton (src, dst); -} diff --git a/contrib/tcpdump/missing/snprintf.c b/contrib/tcpdump/missing/snprintf.c index 21d235d..921b74c 100644 --- a/contrib/tcpdump/missing/snprintf.c +++ b/contrib/tcpdump/missing/snprintf.c @@ -42,7 +42,7 @@ #include #include -#include +#include "netdissect.h" enum format_flags { minus_flag = 1, diff --git a/contrib/tcpdump/missing/strdup.c b/contrib/tcpdump/missing/strdup.c index 9fca752..9cbf35a 100644 --- a/contrib/tcpdump/missing/strdup.c +++ b/contrib/tcpdump/missing/strdup.c @@ -35,7 +35,7 @@ #include #include -#include "interface.h" +#include "netdissect.h" char * strdup(str) diff --git a/contrib/tcpdump/missing/strlcat.c b/contrib/tcpdump/missing/strlcat.c index 34f1af2..4054935 100644 --- a/contrib/tcpdump/missing/strlcat.c +++ b/contrib/tcpdump/missing/strlcat.c @@ -28,15 +28,15 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifdef HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" /* * Appends src to string dst of size siz (unlike strncat, siz is the diff --git a/contrib/tcpdump/missing/strlcpy.c b/contrib/tcpdump/missing/strlcpy.c index b0671eb..24dcca6 100644 --- a/contrib/tcpdump/missing/strlcpy.c +++ b/contrib/tcpdump/missing/strlcpy.c @@ -28,15 +28,15 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifdef HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" /* * Copy src to string dst of size siz. At most siz-1 characters diff --git a/contrib/tcpdump/missing/strsep.c b/contrib/tcpdump/missing/strsep.c index a1e6b30..2c17275 100644 --- a/contrib/tcpdump/missing/strsep.c +++ b/contrib/tcpdump/missing/strsep.c @@ -31,15 +31,15 @@ * SUCH DAMAGE. */ -#ifdef HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" /* * Get next token from string *stringp, where tokens are possibly-empty diff --git a/contrib/tcpdump/nameser.h b/contrib/tcpdump/nameser.h index 11e71ef..e075f09 100644 --- a/contrib/tcpdump/nameser.h +++ b/contrib/tcpdump/nameser.h @@ -71,20 +71,6 @@ #define RRFIXEDSZ 10 /* - * Internet nameserver port number - */ -#define NAMESERVER_PORT 53 - -/* - * Port for multicast DNS; see - * - * http://files.multicastdns.org/draft-cheshire-dnsext-multicastdns.txt - * - * for the current mDNS spec. - */ -#define MULTICASTDNS_PORT 5353 - -/* * Currently defined opcodes */ #define QUERY 0x0 /* standard query */ diff --git a/contrib/tcpdump/netdissect-stdinc.h b/contrib/tcpdump/netdissect-stdinc.h new file mode 100644 index 0000000..c7070f0 --- /dev/null +++ b/contrib/tcpdump/netdissect-stdinc.h @@ -0,0 +1,404 @@ +/* + * Copyright (c) 2002 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino 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 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 + * OWNER 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. + */ + +/* + * Include the appropriate OS header files on Windows and various flavors + * of UNIX, include various non-OS header files on Windows, and define + * various items as needed, to isolate most of netdissect's platform + * differences to this one file. + */ + +#ifndef netdissect_stdinc_h +#define netdissect_stdinc_h + +#include + +#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 + +#ifndef PRIx64 +#define PRIx64 "llx" +#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 +#endif /* _MSC_VER */ + +/* + * With MSVC, for C, __inline is used to make a function an inline. + */ +#ifdef _MSC_VER +#define inline __inline +#endif + +#ifdef AF_INET6 +#define HAVE_OS_IPV6_SUPPORT +#endif + +#ifndef INET6_ADDRSTRLEN +#define INET6_ADDRSTRLEN 46 +#endif + +/* It is in MSVC's , but not defined in MingW+Watcom. + */ +#ifndef EAFNOSUPPORT +#define EAFNOSUPPORT WSAEAFNOSUPPORT +#endif + +#ifndef caddr_t +typedef char* caddr_t; +#endif /* caddr_t */ + +#define MAXHOSTNAMELEN 64 +#define snprintf _snprintf +#define vsnprintf _vsnprintf +#define RETSIGTYPE void + +#else /* _WIN32 */ + +/* + * 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 */ + +#ifndef HAVE___ATTRIBUTE__ +#define __attribute__(x) +#endif + +/* + * Used to declare a structure unaligned, so that the C compiler, + * if necessary, generates code that doesn't assume alignment. + * This is required because there is no guarantee that the packet + * data we get from libpcap/WinPcap is properly aligned. + * + * This assumes that, for all compilers that support __attribute__: + * + * 1) they support __attribute__((packed)); + * + * 2) for all instruction set architectures requiring strict + * alignment, declaring a structure with that attribute + * causes the compiler to generate code that handles + * misaligned 2-byte, 4-byte, and 8-byte integral + * quantities. + * + * It does not (yet) handle compilers where you can get the compiler + * to generate code of that sort by some other means. + * + * This is required in order to, for example, keep the compiler from + * generating, for + * + * if (bp->bp_htype == 1 && bp->bp_hlen == 6 && bp->bp_op == BOOTPREQUEST) { + * + * in print-bootp.c, code that loads the first 4-byte word of a + * "struct bootp", masking out the bp_hops field, and comparing the result + * against 0x01010600. + * + * Note: this also requires that padding be put into the structure, + * at least for compilers where it's implemented as __attribute__((packed)). + */ +#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 + +/* + * fopen() read and write modes for text files and binary files. + */ +#if defined(_WIN32) || defined(MSDOS) + #define FOPEN_READ_TXT "rt" + #define FOPEN_READ_BIN "rb" + #define FOPEN_WRITE_TXT "wt" + #define FOPEN_WRITE_BIN "wb" +#else + #define FOPEN_READ_TXT "r" + #define FOPEN_READ_BIN FOPEN_READ_TXT + #define FOPEN_WRITE_TXT "w" + #define FOPEN_WRITE_BIN FOPEN_WRITE_TXT +#endif + +/* + * Inline x86 assembler-language versions of ntoh[ls]() and hton[ls](), + * defined if the OS doesn't provide them. These assume no more than + * 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 + * have it.) + */ +#if defined(__GNUC__) && defined(__i386__) && !defined(__APPLE__) && !defined(__ntohl) + #undef ntohl + #undef ntohs + #undef htonl + #undef htons + + static __inline__ unsigned long __ntohl (unsigned long x); + static __inline__ unsigned short __ntohs (unsigned short x); + + #define ntohl(x) __ntohl(x) + #define ntohs(x) __ntohs(x) + #define htonl(x) __ntohl(x) + #define htons(x) __ntohs(x) + + static __inline__ unsigned long __ntohl (unsigned long x) + { + __asm__ ("xchgb %b0, %h0\n\t" /* swap lower bytes */ + "rorl $16, %0\n\t" /* swap words */ + "xchgb %b0, %h0" /* swap higher bytes */ + : "=q" (x) : "0" (x)); + return (x); + } + + static __inline__ unsigned short __ntohs (unsigned short x) + { + __asm__ ("xchgb %b0, %h0" /* swap bytes */ + : "=q" (x) : "0" (x)); + return (x); + } +#endif + +/* + * If the OS doesn't define AF_INET6 and struct in6_addr: + * + * define AF_INET6, so we can use it internally as a "this is an + * IPv6 address" indication; + * + * define struct in6_addr so that we can use it for IPv6 addresses. + */ +#ifndef HAVE_OS_IPV6_SUPPORT +#ifndef AF_INET6 +#define AF_INET6 24 + +struct in6_addr { + union { + __uint8_t __u6_addr8[16]; + __uint16_t __u6_addr16[8]; + __uint32_t __u6_addr32[4]; + } __u6_addr; /* 128-bit IP6 address */ +}; +#endif +#endif + +#ifndef NI_MAXHOST +#define NI_MAXHOST 1025 +#endif + +#ifndef INET_ADDRSTRLEN +#define INET_ADDRSTRLEN 16 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +/* + * The Apple deprecation workaround macros below were adopted from the + * FreeRADIUS server code under permission of Alan DeKok and Arran Cudbard-Bell. + */ + +#define XSTRINGIFY(x) #x + +/* + * Macros for controlling warnings in GCC >= 4.2 and clang >= 2.8 + */ +#define DIAG_JOINSTR(x,y) XSTRINGIFY(x ## y) +#define DIAG_DO_PRAGMA(x) _Pragma (#x) + +#if 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)) +# define DIAG_ON(x) DIAG_PRAGMA(pop) +# else +# 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 + +/* + * For dealing with APIs which are only deprecated in OSX (like the OpenSSL API) + */ +#ifdef __APPLE__ +# define USES_APPLE_DEPRECATED_API DIAG_OFF(deprecated-declarations) +# define USES_APPLE_RST DIAG_ON(deprecated-declarations) +#else +# define USES_APPLE_DEPRECATED_API +# define USES_APPLE_RST +#endif + +/* + * end of Apple deprecation workaround macros + */ + +#ifndef min +#define min(a,b) ((a)>(b)?(b):(a)) +#endif +#ifndef max +#define max(a,b) ((b)>(a)?(b):(a)) +#endif + +#endif /* netdissect_stdinc_h */ diff --git a/contrib/tcpdump/netdissect.c b/contrib/tcpdump/netdissect.c new file mode 100644 index 0000000..0215c83 --- /dev/null +++ b/contrib/tcpdump/netdissect.c @@ -0,0 +1,146 @@ +/* + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "netdissect.h" +#include +#include + +#ifdef USE_LIBSMI +#include +#endif + +/* + * Initialize anything that must be initialized before dissecting + * packets. + * + * This should be called at the beginning of the program; it does + * not need to be called, and should not be called, for every + * netdissect_options structure. + */ +int +nd_init(char *errbuf, size_t errbuf_size) +{ +#ifdef _WIN32 + WORD wVersionRequested; + WSADATA wsaData; + int err; + + /* + * Request Winsock 2.2; we expect Winsock 2. + */ + wVersionRequested = MAKEWORD(2, 2); + err = WSAStartup(wVersionRequested, &wsaData); + if (err != 0) { + strlcpy(errbuf, "Attempting to initialize Winsock failed", + errbuf_size); + return (-1); + } +#endif /* _WIN32 */ + +#ifdef USE_LIBSMI + /* + * XXX - should we just fail if this fails? Some of the + * libsmi calls may fail. + */ + smiInit("tcpdump"); +#endif + + /* + * Clears the error buffer, and uses it so we don't get + * "unused argument" warnings at compile time. + */ + strlcpy(errbuf, "", errbuf_size); + return (0); +} + +/* + * Clean up anything that ndo_init() did. + */ +void +nd_cleanup(void) +{ +#ifdef USE_LIBSMI + /* + * This appears, in libsmi 0.4.8, to do nothing if smiInit() + * wasn't done or failed, so we call it unconditionally. + */ + smiExit(); +#endif + +#ifdef _WIN32 + /* + * Undo the WSAStartup() call above. + */ + WSACleanup(); +#endif +} + +int +nd_have_smi_support(void) +{ +#ifdef USE_LIBSMI + return (1); +#else + return (0); +#endif +} + +/* + * Indicates whether an SMI module has been loaded, so that we can use + * libsmi to translate OIDs. + */ +int nd_smi_module_loaded; + +int +nd_load_smi_module(const char *module, char *errbuf, size_t errbuf_size) +{ +#ifdef USE_LIBSMI + if (smiLoadModule(module) == 0) { + snprintf(errbuf, errbuf_size, "could not load MIB module %s", + module); + return (-1); + } + nd_smi_module_loaded = 1; + return (0); +#else + snprintf(errbuf, errbuf_size, "MIB module %s not loaded: no libsmi support", + module); + return (-1); +#endif +} + +const char * +nd_smi_version_string(void) +{ +#ifdef USE_LIBSMI + return (smi_version_string); +#else + return (NULL); +#endif +} diff --git a/contrib/tcpdump/netdissect.h b/contrib/tcpdump/netdissect.h index 0cd7c12..1d28c0b 100644 --- a/contrib/tcpdump/netdissect.h +++ b/contrib/tcpdump/netdissect.h @@ -34,11 +34,52 @@ #define __attribute__(x) #endif +/* + * Data types corresponding to multi-byte integral values within data + * structures. These are defined as arrays of octets, so that they're + * not aligned on their "natural" boundaries, and so that you *must* + * 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). + */ +typedef unsigned char nd_uint16_t[2]; +typedef unsigned char nd_uint24_t[3]; +typedef unsigned char nd_uint32_t[4]; +typedef unsigned char nd_uint40_t[5]; +typedef unsigned char nd_uint48_t[6]; +typedef unsigned char nd_uint56_t[7]; +typedef unsigned char nd_uint64_t[8]; + +/* + * 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. + */ +typedef struct { + unsigned char bytes[4]; +} nd_ipv4; + +/* + * Data types corresponding to single-byte integral values, for + * completeness. + */ +typedef unsigned char nd_uint8_t; +typedef signed char nd_int8_t; + /* snprintf et al */ #include +#include #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, const char *format, ...) @@ -54,7 +95,7 @@ int vsnprintf (char *str, size_t sz, const char *format, va_list ap) __attribute__((format (printf, 3, 0))) #endif /* __ATTRIBUTE___FORMAT_OK */ ; -#endif /* !defined(HAVE_SNPRINTF) */ +#endif /* !defined(HAVE_VSNPRINTF) */ #ifndef HAVE_STRLCAT extern size_t strlcat (char *, const char *, size_t); @@ -76,7 +117,6 @@ struct tok { const char *s; /* string */ }; -#define TOKBUFSIZE 128 extern const char *tok2strbuf(const struct tok *, const char *, u_int, char *buf, size_t bufsize); @@ -85,11 +125,27 @@ extern const char *tok2str(const struct tok *, const char *, u_int); extern char *bittok2str(const struct tok *, const char *, u_int); extern char *bittok2str_nosep(const struct tok *, const char *, u_int); +/* Initialize netdissect. */ +extern int nd_init(char *, size_t); +/* Clean up netdissect. */ +extern void nd_cleanup(void); + +/* Do we have libsmi support? */ +extern int nd_have_smi_support(void); +/* Load an SMI module. */ +extern int nd_load_smi_module(const char *, char *, size_t); +/* Flag indicating whether an SMI module has been loaded. */ +extern int nd_smi_module_loaded; +/* Version number of the SMI library, or NULL if we don't have libsmi support. */ +extern const char *nd_smi_version_string(void); 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; + struct netdissect_options { - int ndo_aflag; /* translate network and broadcast addresses */ int ndo_bflag; /* print 4 byte ASes in ASDOT notation */ int ndo_eflag; /* print ethernet header */ int ndo_fflag; /* don't translate "foreign" IP address */ @@ -97,69 +153,41 @@ struct netdissect_options { int ndo_nflag; /* leave addresses as numbers */ int ndo_Nflag; /* remove domains from printed host names */ int ndo_qflag; /* quick (shorter) output */ - int ndo_Rflag; /* print sequence # field in AH/ESP*/ - int ndo_sflag; /* use the libsmi to translate OIDs */ int ndo_Sflag; /* print raw TCP sequence numbers */ int ndo_tflag; /* print packet arrival time */ - int ndo_Uflag; /* "unbuffered" output of dump files */ int ndo_uflag; /* Print undecoded NFS handles */ - int ndo_vflag; /* verbose */ + 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, * LF, CR and SPACE as graphical chars */ - int ndo_Bflag; /* buffer size */ - int ndo_Iflag; /* rfmon (monitor) mode */ - int ndo_Oflag; /* run filter code optimizer */ - int ndo_dlt; /* if != -1, ask libpcap for the DLT it names*/ - int ndo_jflag; /* packet time stamp source */ - int ndo_pflag; /* don't go promiscuous */ - int ndo_immediate; /* use immediate mode */ - - int ndo_Cflag; /* rotate dump files after this many bytes */ - int ndo_Cflag_count; /* Keep track of which file number we're writing */ - int ndo_Gflag; /* rotate dump files after this many seconds */ - int ndo_Gflag_count; /* number of files created with Gflag rotation */ - time_t ndo_Gflag_time; /* The last time_t the dump file was rotated. */ - int ndo_Wflag; /* recycle output files after this number of files */ - int ndo_WflagChars; int ndo_Hflag; /* dissect 802.11s draft mesh standard */ int ndo_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 */ - const char *ndo_dltname; + int ndo_tstamp_precision; /* requested time stamp precision */ + const char *program_name; /* Name of the program using the library */ char *ndo_espsecret; struct sa_list *ndo_sa_list_head; /* used by print-esp.c */ struct sa_list *ndo_sa_default; - char *ndo_sigsecret; /* Signature verification secret key */ - - struct esp_algorithm *ndo_espsecret_xform; /* cache of decoded */ - char *ndo_espsecret_key; + char *ndo_sigsecret; /* Signature verification secret key */ int ndo_packettype; /* as specified by -T */ - char *ndo_program_name; /*used to generate self-identifying messages */ - - int32_t ndo_thiszone; /* seconds offset from gmt to local time */ - int ndo_snaplen; /*global pointers to beginning and end of current packet (during printing) */ const u_char *ndo_packetp; const u_char *ndo_snapend; - /* bookkeeping for ^T output */ - int ndo_infodelay; + /* 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); - - /* pointer to function to print ^T output */ - void (*ndo_info)(netdissect_options *, int verbose); + register const u_char *bp, register u_int length); /* pointer to function to do regular output */ int (*ndo_printf)(netdissect_options *, @@ -203,6 +231,7 @@ struct netdissect_options { #define PT_PGM 14 /* [UDP-encapsulated] Pragmatic General Multicast */ #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 */ #ifndef min #define min(a,b) ((a)>(b)?(b):(a)) @@ -211,6 +240,9 @@ struct netdissect_options { #define max(a,b) ((b)>(a)?(b):(a)) #endif +/* For source or destination ports tests (UDP, TCP, ...) */ +#define IS_SRC_OR_DST_PORT(p) (sport == (p) || dport == (p)) + /* * Maximum snapshot length. This should be enough to capture the full * packet on most network interfaces. @@ -271,6 +303,11 @@ struct netdissect_options { * http://www.kb.cert.org/vuls/id/162289 */ +/* + * Test in two parts to avoid these warnings: + * comparison of unsigned expression >= 0 is always true [-Wtype-limits], + * comparison is always true due to limited range of data type [-Wtype-limits]. + */ #define IS_NOT_NEGATIVE(x) (((x) > 0) || ((x) == 0)) #define ND_TTEST2(var, l) \ @@ -291,9 +328,12 @@ struct netdissect_options { #define ND_DEFAULTPRINT(ap, length) (*ndo->ndo_default_print)(ndo, ap, length) extern void ts_print(netdissect_options *, const struct timeval *); -extern void relts_print(netdissect_options *, int); +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 *); @@ -305,11 +345,6 @@ extern int fn_printzp(netdissect_options *, const u_char *, u_int, const u_char extern void txtproto_print(netdissect_options *, const u_char *, u_int, const char *, const char **, u_int); -#if 0 -extern char *read_infile(netdissect_options *, char *); -extern char *copy_argv(netdissect_options *, char **); -#endif - /* * Locale-independent macros for testing character properties and * stripping the 8th bit from characters. Assumed to be handed @@ -352,286 +387,278 @@ extern int unaligned_memcmp(const void *, const void *, size_t); #define PLURAL_SUFFIX(n) \ (((n) != 1) ? "s" : "") -#if 0 -extern const char *dnname_string(netdissect_options *, u_short); -extern const char *dnnum_string(netdissect_options *, u_short); -#endif - -/* The printer routines. */ - -#include - -extern char *q922_string(netdissect_options *ndo, const u_char *, u_int); - -typedef u_int (*if_ndo_printer)(struct netdissect_options *ndo, - const struct pcap_pkthdr *, const u_char *); -typedef u_int (*if_printer)(const struct pcap_pkthdr *, const u_char *); +extern 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) -extern if_ndo_printer lookup_ndo_printer(int); extern if_printer lookup_printer(int); -extern void eap_print(netdissect_options *,const u_char *, u_int); -extern int esp_print(netdissect_options *, - const u_char *bp, const int length, const u_char *bp2, - int *nhdr, int *padlen); -extern void arp_print(netdissect_options *,const u_char *, u_int, u_int); -extern void tipc_print(netdissect_options *, const u_char *, u_int, u_int); -extern void msnlb_print(netdissect_options *, const u_char *); -extern void icmp6_print(netdissect_options *ndo, const u_char *, - u_int, const u_char *, int); -extern void isakmp_print(netdissect_options *,const u_char *, - u_int, const u_char *); -extern void isakmp_rfc3948_print(netdissect_options *,const u_char *, - u_int, const u_char *); -extern void ip_print(netdissect_options *,const u_char *, u_int); -extern void ip_print_inner(netdissect_options *ndo, - const u_char *bp, u_int length, u_int nh, - const u_char *bp2); -extern void rrcp_print(netdissect_options *,const u_char *, u_int); -extern void loopback_print(netdissect_options *, const u_char *, const u_int); -extern void carp_print(netdissect_options *, const u_char *, u_int, int); +/* 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 ether_print(netdissect_options *, - const u_char *, u_int, u_int, - void (*)(netdissect_options *, const u_char *), - const u_char *); - -extern u_int ether_if_print(netdissect_options *, - const struct pcap_pkthdr *,const u_char *); -extern u_int netanalyzer_if_print(netdissect_options *, - const struct pcap_pkthdr *,const u_char *); -extern u_int netanalyzer_transparent_if_print(netdissect_options *, - const struct pcap_pkthdr *, - const u_char *); - -extern int ethertype_print(netdissect_options *,u_short, const u_char *, - u_int, u_int); +/* + * Structure passed to some printers to allow them to print + * link-layer address information if ndo_eflag isn't set + * (because they are for protocols that don't have their + * own addresses, so that we'd want to report link-layer + * address information). + * + * This contains a pointer to an address and a pointer to a routine + * to which we pass that pointer in order to get a string. + */ +struct lladdr_info { + const char *(*addr_string)(netdissect_options *, const u_char *); + const u_char *addr; +}; -extern int print_unknown_data(netdissect_options *,const u_char *, const char *,int); -extern void ascii_print(netdissect_options *, const u_char *, u_int); -extern void hex_print_with_offset(netdissect_options *, const char *ident, const u_char *cp, - u_int, u_int); -extern void hex_print(netdissect_options *,const char *ident, const u_char *cp,u_int); -extern void hex_and_ascii_print_with_offset(netdissect_options *, const char *, const u_char *, u_int, u_int); -extern void hex_and_ascii_print(netdissect_options *, const char *, const u_char *, u_int); +/* 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 beep_print(netdissect_options *, const u_char *, u_int); -extern void dtp_print(netdissect_options *, const u_char *, u_int); -extern u_int cip_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern int ipcomp_print(netdissect_options *, register const u_char *, int *); -extern u_int ipfc_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern void udld_print(netdissect_options *, const u_char *, u_int); -extern void hsrp_print(netdissect_options *, const u_char *, u_int); -extern void igrp_print(netdissect_options *, const u_char *, u_int); -extern void msdp_print(netdissect_options *, const u_char *, u_int); -extern u_int null_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern void mobile_print(netdissect_options *, const u_char *, u_int); -extern u_int ap1394_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern u_int bt_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern void lane_print(netdissect_options *, const u_char *, u_int, u_int); -extern u_int lane_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern void otv_print(netdissect_options *, const u_char *, u_int); extern void ahcp_print(netdissect_options *, const u_char *, const u_int); -extern void vxlan_print(netdissect_options *, const u_char *, u_int); -extern u_int arcnet_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern u_int arcnet_linux_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); +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 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 beep_print(netdissect_options *, const u_char *, u_int); extern void bfd_print(netdissect_options *, const u_char *, u_int, u_int); -extern void gre_print(netdissect_options *, const u_char *, u_int); -extern int vjc_print(netdissect_options *, register const char *, u_short); -extern void ipN_print(netdissect_options *, const u_char *, u_int); -extern u_int raw_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern u_int usb_linux_48_byte_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern u_int usb_linux_64_byte_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern u_int symantec_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern u_int chdlc_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); +extern void bgp_print(netdissect_options *, const u_char *, int); +extern 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 cfm_print(netdissect_options *, const u_char *, u_int); extern u_int chdlc_print(netdissect_options *, register 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 ipx_print(netdissect_options *, const u_char *, u_int); -extern void mpls_print(netdissect_options *, const u_char *, u_int); -extern u_int pppoe_print(netdissect_options *, const u_char *, u_int); -extern u_int pppoe_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern void sunrpcrequest_print(netdissect_options *, const u_char *, u_int, const u_char *); -extern u_int pflog_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern u_int token_print(netdissect_options *, const u_char *, u_int, u_int); -extern u_int token_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern void vqp_print(netdissect_options *, register const u_char *, register u_int); -extern void zephyr_print(netdissect_options *, const u_char *, int); -extern void fddi_print(netdissect_options *, const u_char *, u_int, u_int); -extern u_int fddi_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern void mpcp_print(netdissect_options *, const u_char *, u_int); -extern void rpki_rtr_print(netdissect_options *, const u_char *, u_int); -extern u_int sll_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern void dccp_print(netdissect_options *, const u_char *, const u_char *, u_int); -extern int llc_print(netdissect_options *, const u_char *, u_int, u_int, const u_char *, const u_char *, u_short *); -extern int snap_print(netdissect_options *, const u_char *, u_int, u_int, u_int); -extern void eigrp_print(netdissect_options *, const u_char *, u_int); -extern void stp_print(netdissect_options *, const u_char *, u_int); -extern void l2tp_print(netdissect_options *, const u_char *, u_int); -extern void udp_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 void openflow_print(netdissect_options *, const u_char *, const u_int); -extern void telnet_print(netdissect_options *, const u_char *, u_int); -extern void slow_print(netdissect_options *, const u_char *, u_int); -extern void radius_print(netdissect_options *, const u_char *, u_int); -extern void lmp_print(netdissect_options *, const u_char *, u_int); -extern u_int fr_print(netdissect_options *, register const u_char *, u_int); -extern u_int mfr_print(netdissect_options *, register const u_char *, u_int); -extern u_int fr_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern u_int mfr_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern void q933_print(netdissect_options *, const u_char *, u_int); -extern void igmp_print(netdissect_options *, const u_char *, u_int); -extern void rip_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 pgm_print(netdissect_options *, const u_char *, u_int, const u_char *); -extern void pptp_print(netdissect_options *, const u_char *); -extern void ldp_print(netdissect_options *, const u_char *, u_int); -extern void wb_print(netdissect_options *, const void *, u_int); -extern int oam_print(netdissect_options *, const u_char *, u_int, u_int); -extern void atm_print(netdissect_options *, u_int, u_int, u_int, const u_char *, u_int, u_int); -extern u_int sunatm_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern u_int atm_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern void vtp_print(netdissect_options *, const u_char *, u_int); -extern int mptcp_print(netdissect_options *, const u_char *, u_int, u_char); -extern void ntp_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 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 egp_print(netdissect_options *, const u_char *, u_int); -extern u_int enc_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern u_int sl_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern u_int sl_bsdos_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern void tftp_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 pimv1_print(netdissect_options *, const u_char *, u_int); -extern void cisco_autorp_print(netdissect_options *, const u_char *, u_int); -extern void pim_print(netdissect_options *, const u_char *, u_int, u_int); -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 bootp_print(netdissect_options *, const u_char *, u_int); -extern void sflow_print(netdissect_options *, const u_char *, u_int); -extern void aodv_print(netdissect_options *, const u_char *, u_int, int); -extern void sctp_print(netdissect_options *, const u_char *, const u_char *, u_int); -extern char *bgp_vpn_rd_print (netdissect_options *, const u_char *); -extern void bgp_print(netdissect_options *, const u_char *, int); -extern void olsr_print(netdissect_options *, const u_char *, u_int, 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 u_int ether_print(netdissect_options *, const u_char *, u_int, u_int, void (*)(netdissect_options *, const u_char *), const u_char *); +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 void lspping_print(netdissect_options *, const u_char *, u_int); +extern u_int fr_print(netdissect_options *, register 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 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); +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 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 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 isoclns_print(netdissect_options *, const u_char *, u_int, u_int); extern void krb_print(netdissect_options *, const u_char *); -extern void cdp_print(netdissect_options *, const u_char *, u_int, u_int); -extern void atalk_print(netdissect_options *, const u_char *, u_int); -extern u_int ltalk_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); +extern void l2tp_print(netdissect_options *, const u_char *, u_int); +extern void lane_print(netdissect_options *, const u_char *, u_int, u_int); +extern void ldp_print(netdissect_options *, const u_char *, u_int); +extern void lisp_print(netdissect_options *, const u_char *, u_int); extern u_int llap_print(netdissect_options *, const u_char *, u_int); -extern void aarp_print(netdissect_options *, const u_char *, u_int); -extern u_int juniper_atm1_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern u_int juniper_atm2_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern u_int juniper_mfr_print(netdissect_options *, const struct pcap_pkthdr *, register const u_char *); -extern u_int juniper_mlfr_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern u_int juniper_mlppp_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern u_int juniper_pppoe_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern u_int juniper_pppoe_atm_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern u_int juniper_ggsn_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern u_int juniper_es_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern u_int juniper_monitor_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern u_int juniper_services_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern u_int juniper_ether_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern u_int juniper_ppp_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern u_int juniper_frelay_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern u_int juniper_chdlc_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern void snmp_print(netdissect_options *, const u_char *, u_int); -extern void rx_print(netdissect_options *, register const u_char *, int, int, int, u_char *); -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 void sip_print(netdissect_options *, const u_char *, u_int); -extern void syslog_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 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 cfm_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 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); +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 smb_tcp_print(netdissect_options *, const u_char *, int); extern void netbeui_print(netdissect_options *, u_short, const u_char *, int); -extern void ipx_netbios_print(netdissect_options *, const u_char *, u_int); -extern void print_data(netdissect_options *, const unsigned char *, int); -extern void decnet_print(netdissect_options *, const u_char *, u_int, u_int); -extern void tcp_print(netdissect_options *, const u_char *, u_int, const u_char *, 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 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 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_te_lsa(netdissect_options *, const uint8_t *, u_int); 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 void otv_print(netdissect_options *, const u_char *, u_int); +extern void pfsync_ip_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_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern u_int ppp_hdlc_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern u_int ppp_bsdos_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern void lldp_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 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); +extern void rip_print(netdissect_options *, const u_char *, u_int); +extern void ripng_print(netdissect_options *, const u_char *, unsigned int); +extern void rpki_rtr_print(netdissect_options *, const u_char *, u_int); +extern void rrcp_print(netdissect_options *, const u_char *, u_int, const struct lladdr_info *, const struct lladdr_info *); extern void rsvp_print(netdissect_options *, const u_char *, u_int); -extern void timed_print(netdissect_options *, const u_char *); -extern void m3ua_print(netdissect_options *, const u_char *, const u_int); -extern void aoe_print(netdissect_options *, const u_char *, const u_int); -extern void ftp_print(netdissect_options *, const u_char *, u_int); -extern void http_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 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 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 smtp_print(netdissect_options *, const u_char *, u_int); -extern void geneve_print(netdissect_options *, const u_char *, u_int); - -extern void pfsync_ip_print(netdissect_options *, const u_char *, u_int); - -/* stuff that has not yet been rototiled */ - -#if 0 -extern void ascii_print(netdissect_options *,u_int); -extern void default_print(netdissect_options *,const u_char *, u_int); -extern char *smb_errstr(netdissect_options *,int, int); -extern const char *nt_errstr(netdissect_options *, uint32_t); -#endif +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 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); +extern void tftp_print(netdissect_options *, const u_char *, u_int); +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 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 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 zmtp1_print(netdissect_options *, const u_char *, u_int); +extern void zmtp1_print_datagram(netdissect_options *, const u_char *, const u_int); -extern u_int ipnet_if_print(netdissect_options *,const struct pcap_pkthdr *, const u_char *); -extern u_int ppi_if_print(netdissect_options *,const struct pcap_pkthdr *, const u_char *); -extern u_int nflog_if_print(netdissect_options *,const struct pcap_pkthdr *, const u_char *); -extern u_int ieee802_15_4_if_print(netdissect_options *,const struct pcap_pkthdr *, const u_char *); -extern u_int pktap_if_print(netdissect_options *,const struct pcap_pkthdr *, const u_char *); -extern u_int ieee802_11_radio_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern u_int ieee802_11_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern u_int ieee802_11_radio_avs_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); -extern u_int prism_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); - -extern void ip6_print(netdissect_options *,const u_char *, u_int); -#ifdef INET6 -extern int frag6_print(netdissect_options *, const u_char *, const u_char *); -extern int rt6_print(netdissect_options *, const u_char *, const u_char *); -extern int hbhopt_print(netdissect_options *, const u_char *); -extern int dstopt_print(netdissect_options *, const u_char *); -extern void ripng_print(netdissect_options *, const u_char *, unsigned int); -extern int mobility_print(netdissect_options *, const u_char *, const u_char *); -extern void dhcp6_print(netdissect_options *, const u_char *, u_int); -extern void ospf6_print(netdissect_options *, const u_char *, u_int); -extern void babel_print(netdissect_options *, const u_char *, u_int); -#endif /*INET6*/ +/* checksum routines */ +extern void init_checksum(void); +extern uint16_t verify_crc10_cksum(uint16_t, const u_char *, int); +extern uint16_t create_osi_cksum(const uint8_t *, int, int); -#if 0 struct cksum_vec { const uint8_t *ptr; int len; }; extern uint16_t in_cksum(const struct cksum_vec *, int); extern uint16_t in_cksum_shouldbe(uint16_t, uint16_t); -#endif -extern int nextproto4_cksum(netdissect_options *ndo, const struct ip *, const uint8_t *, u_int, u_int, u_int); -extern int decode_prefix4(netdissect_options *ndo, const u_char *, u_int, char *, u_int); -#ifdef INET6 -extern int decode_prefix6(netdissect_options *ndo, const u_char *, u_int, char *, u_int); -#endif -extern void esp_print_decodesecret(netdissect_options *ndo); -extern int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo, - int initiator, - u_char spii[8], u_char spir[8], - u_char *buf, u_char *end); +extern int nextproto4_cksum(netdissect_options *, const struct ip *, const uint8_t *, u_int, u_int, u_int); + +/* in print-ip6.c */ +extern int nextproto6_cksum(netdissect_options *, const struct ip6_hdr *, const uint8_t *, u_int, u_int, u_int); + +/* Utilities */ +extern int mask2plen(uint32_t); +extern int mask62plen(const u_char *); + +extern const char *dnname_string(netdissect_options *, u_short); +extern const char *dnnum_string(netdissect_options *, u_short); +extern char *smb_errstr(int, int); +extern const char *nt_errstr(uint32_t); -extern void geonet_print(netdissect_options *ndo,const u_char *eth_hdr,const u_char *geo_pck, u_int len); -extern void calm_fast_print(netdissect_options *ndo,const u_char *eth_hdr,const u_char *calm_pck, u_int len); +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 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], + const u_char *, const u_char *); #endif /* netdissect_h */ diff --git a/contrib/tcpdump/nfs.h b/contrib/tcpdump/nfs.h index a47c005..da7bc50 100644 --- a/contrib/tcpdump/nfs.h +++ b/contrib/tcpdump/nfs.h @@ -35,7 +35,6 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD$ * @(#)nfsproto.h 8.2 (Berkeley) 3/30/95 */ diff --git a/contrib/tcpdump/nfsfh.h b/contrib/tcpdump/nfsfh.h index fbc2355..5cf8fc4 100644 --- a/contrib/tcpdump/nfsfh.h +++ b/contrib/tcpdump/nfsfh.h @@ -37,8 +37,6 @@ * Jeffrey C. Mogul * Digital Equipment Corporation * Western Research Laboratory - * $FreeBSD$ - * $NetBSD: nfsfh.h,v 1.1.1.2 1997/10/03 17:25:13 christos Exp $ */ /* @@ -65,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 *, int, my_fsid *, uint32_t *, const char **, const char **, int); +extern void Parse_fh(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 919e87d..4b44ee1 100644 --- a/contrib/tcpdump/nlpid.c +++ b/contrib/tcpdump/nlpid.c @@ -13,13 +13,12 @@ * Original code by Hannes Gredler (hannes@juniper.net) */ -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include -#include "interface.h" +#include +#include "netdissect.h" #include "nlpid.h" const struct tok nlpid_values[] = { diff --git a/contrib/tcpdump/oui.c b/contrib/tcpdump/oui.c index 2aea5ad..71425de 100644 --- a/contrib/tcpdump/oui.c +++ b/contrib/tcpdump/oui.c @@ -13,13 +13,12 @@ * Original code by Hannes Gredler (hannes@juniper.net) */ -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include -#include "interface.h" +#include +#include "netdissect.h" #include "oui.h" /* FIXME complete OUI list using a script */ @@ -27,6 +26,7 @@ const struct tok oui_values[] = { { OUI_ENCAP_ETHER, "Ethernet" }, { OUI_CISCO, "Cisco" }, + { OUI_IANA, "IANA" }, { OUI_NORTEL, "Nortel Networks SONMP" }, { OUI_CISCO_90, "Cisco bridged" }, { OUI_RFC2684, "Ethernet bridged" }, diff --git a/contrib/tcpdump/oui.h b/contrib/tcpdump/oui.h index 4a983ec..a85f883 100644 --- a/contrib/tcpdump/oui.h +++ b/contrib/tcpdump/oui.h @@ -16,29 +16,30 @@ extern const struct tok oui_values[]; extern const struct tok smi_values[]; -#define OUI_ENCAP_ETHER 0x000000 /* encapsulated Ethernet */ -#define OUI_CISCO 0x00000c /* Cisco protocols */ -#define OUI_NORTEL 0x000081 /* Nortel SONMP */ -#define OUI_CISCO_90 0x0000f8 /* Cisco bridging */ -#define OUI_RFC2684 0x0080c2 /* RFC 2427/2684 bridged Ethernet */ -#define OUI_ATM_FORUM 0x00A03E /* ATM Forum */ -#define OUI_CABLE_BPDU 0x00E02F /* DOCSIS spanning tree BPDU */ -#define OUI_APPLETALK 0x080007 /* Appletalk */ -#define OUI_JUNIPER 0x009069 /* Juniper */ -#define OUI_HP 0x080009 /* Hewlett-Packard */ -#define OUI_IEEE_8021_PRIVATE 0x0080c2 /* IEEE 802.1 Organisation Specific - Annex F */ -#define OUI_IEEE_8023_PRIVATE 0x00120f /* IEEE 802.3 Organisation Specific - Annex G */ -#define OUI_TIA 0x0012bb /* TIA - Telecommunications Industry Association - ANSI/TIA-1057- 2006 */ -#define OUI_DCBX 0x001B21 /* DCBX */ -#define OUI_NICIRA 0x002320 /* Nicira Networks */ -#define OUI_BSN 0x5c16c7 /* Big Switch Networks */ -#define OUI_VELLO 0xb0d2f5 /* Vello Systems */ -#define OUI_HP2 0x002481 /* HP too */ -#define OUI_HPLABS 0x0004ea /* HP-Labs */ -#define OUI_INFOBLOX 0x748771 /* Infoblox Inc */ -#define OUI_ONLAB 0xa42305 /* Open Networking Lab */ -#define OUI_FREESCALE 0x00049f /* Freescale */ -#define OUI_NETRONOME 0x0015ad /* Netronome */ +#define OUI_ENCAP_ETHER 0x000000 /* encapsulated Ethernet */ +#define OUI_CISCO 0x00000c /* Cisco protocols */ +#define OUI_IANA 0x00005E /* IANA */ +#define OUI_NORTEL 0x000081 /* Nortel SONMP */ +#define OUI_CISCO_90 0x0000f8 /* Cisco bridging */ +#define OUI_RFC2684 0x0080c2 /* RFC 2427/2684 bridged Ethernet */ +#define OUI_ATM_FORUM 0x00A03E /* ATM Forum */ +#define OUI_CABLE_BPDU 0x00E02F /* DOCSIS spanning tree BPDU */ +#define OUI_APPLETALK 0x080007 /* Appletalk */ +#define OUI_JUNIPER 0x009069 /* Juniper */ +#define OUI_HP 0x080009 /* Hewlett-Packard */ +#define OUI_IEEE_8021_PRIVATE 0x0080c2 /* IEEE 802.1 Organisation Specific - Annex F */ +#define OUI_IEEE_8023_PRIVATE 0x00120f /* IEEE 802.3 Organisation Specific - Annex G */ +#define OUI_TIA 0x0012bb /* TIA - Telecommunications Industry Association - ANSI/TIA-1057- 2006 */ +#define OUI_DCBX 0x001B21 /* DCBX */ +#define OUI_NICIRA 0x002320 /* Nicira Networks */ +#define OUI_BSN 0x5c16c7 /* Big Switch Networks */ +#define OUI_VELLO 0xb0d2f5 /* Vello Systems */ +#define OUI_HP2 0x002481 /* HP too */ +#define OUI_HPLABS 0x0004ea /* HP-Labs */ +#define OUI_INFOBLOX 0x748771 /* Infoblox Inc */ +#define OUI_ONLAB 0xa42305 /* Open Networking Lab */ +#define OUI_FREESCALE 0x00049f /* Freescale */ +#define OUI_NETRONOME 0x0015ad /* Netronome */ /* * These are SMI Network Management Private Enterprise Codes for diff --git a/contrib/tcpdump/parsenfsfh.c b/contrib/tcpdump/parsenfsfh.c index 909a180..8f48e77 100644 --- a/contrib/tcpdump/parsenfsfh.c +++ b/contrib/tcpdump/parsenfsfh.c @@ -38,21 +38,18 @@ * Jeffrey C. Mogul * Digital Equipment Corporation * Western Research Laboratory - * - * $FreeBSD$ */ -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include #include -#include "interface.h" +#include "netdissect.h" #include "nfsfh.h" /* @@ -105,10 +102,10 @@ ((lsb) + ((e)<<8) + ((d)<<16) + ((c)<<24)) #endif -static int is_UCX(const unsigned char *); +static int is_UCX(const unsigned char *, u_int); void -Parse_fh(register const unsigned char *fh, int len _U_, my_fsid *fsidp, +Parse_fh(register 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) */ @@ -117,138 +114,146 @@ Parse_fh(register const unsigned char *fh, int len _U_, my_fsid *fsidp, register const unsigned char *fhp = fh; uint32_t temp; int fhtype = FHT_UNKNOWN; - int i; + u_int i; - if (ourself) { - /* File handle generated on this host, no need for guessing */ + /* + * Require at least 16 bytes of file handle; it's variable-length + * in NFSv3. "len" is in units of 32-bit words, not bytes. + */ + if (len < 16/4) + fhtype = FHT_UNKNOWN; + else { + if (ourself) { + /* File handle generated on this host, no need for guessing */ #if defined(IRIX40) - fhtype = FHT_IRIX4; + fhtype = FHT_IRIX4; #endif #if defined(IRIX50) - fhtype = FHT_IRIX5; + fhtype = FHT_IRIX5; #endif #if defined(IRIX51) - fhtype = FHT_IRIX5; + fhtype = FHT_IRIX5; #endif #if defined(SUNOS4) - fhtype = FHT_SUNOS4; + fhtype = FHT_SUNOS4; #endif #if defined(SUNOS5) - fhtype = FHT_SUNOS5; + fhtype = FHT_SUNOS5; #endif #if defined(ultrix) - fhtype = FHT_ULTRIX; + fhtype = FHT_ULTRIX; #endif #if defined(__osf__) - fhtype = FHT_DECOSF; + fhtype = FHT_DECOSF; #endif #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) \ || defined(__OpenBSD__) - fhtype = FHT_BSD44; -#endif - } - /* - * This is basically a big decision tree - */ - else if ((fhp[0] == 0) && (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)) { - /* bytes[2,3] == (0,0); must be Auspex */ - /* XXX or could be Ultrix+MASSBUS "hp" disk? */ - fhtype = FHT_AUSPEX; - } - else { - /* - * 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)) { - /* 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)) { - /* looks like a length, not a file system typecode */ - fhtype = FHT_IRIX4; - } - else { - /* by elimination */ - fhtype = FHT_SUNOS4; - } - } - } - } - else { - /* - * bytes[0,1] != (0,0); rules out Auspex, IRIX4, SUNOS4 - * could be IRIX5, DECOSF, UCX, Ultrix, SUNOS5 - * could be AIX, HP-UX - */ - if ((fhp[2] == 0) && (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)) { fhtype = FHT_BSD44; +#endif } - /*XXX we probably only need to test of these two bytes */ - else if ((fhp[21] == 0) && (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) - fhtype = FHT_SUNOS5; - /* XXX what about AIX? */ - } - } - else { /* - * bytes[2,3] != (0,0); rules out Ultrix, could be - * DECOSF, SUNOS5, IRIX5, AIX, HP-UX, or UCX + * This is basically a big decision tree */ - if ((fhp[8] == 12) && (fhp[9] == 0)) { - fhtype = FHT_DECOSF; - } - else if ((fhp[8] == 0) && (fhp[9] == 10)) { - /* could be SUNOS5/IRIX5, AIX, HP-UX */ - if ((fhp[7] == 0) && (fhp[6] == 0) && - (fhp[5] == 0) && (fhp[4] == 0)) { - /* XXX is this always true of HP-UX? */ - fhtype = FHT_HPUX9; - } - else if (fhp[7] == 2) { - /* This would be MNT_NFS on AIX, which is impossible */ - fhtype = FHT_SUNOS5; /* or maybe IRIX5 */ + else if ((fhp[0] == 0) && (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)) { + /* bytes[2,3] == (0,0); must be Auspex */ + /* XXX or could be Ultrix+MASSBUS "hp" disk? */ + fhtype = FHT_AUSPEX; } else { /* - * XXX Could be SUNOS5/IRIX5 or AIX. I don't - * XXX see any way to disambiguate these, so - * XXX I'm going with the more likely guess. - * XXX Sorry, Big Blue. + * bytes[2,3] != (0,0); rules out Auspex, could be + * DECOSF, SUNOS4, or IRIX4 */ - fhtype = FHT_SUNOS5; /* or maybe IRIX5 */ + if ((fhp[4] != 0) && (fhp[5] == 0) && + (fhp[8] == 12) && (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)) { + /* looks like a length, not a file system typecode */ + fhtype = FHT_IRIX4; + } + else { + /* by elimination */ + fhtype = FHT_SUNOS4; + } + } } - } + } else { - if (is_UCX(fhp)) { - fhtype = FHT_VMSUCX; + /* + * bytes[0,1] != (0,0); rules out Auspex, IRIX4, SUNOS4 + * could be IRIX5, DECOSF, UCX, Ultrix, SUNOS5 + * could be AIX, HP-UX + */ + if ((fhp[2] == 0) && (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)) { + 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)) { + fhtype = FHT_ULTRIX; + } + else { + /* Could be SUNOS5/IRIX5, maybe AIX */ + /* XXX no obvious difference between SUNOS5 and IRIX5 */ + if (fhp[9] == 10) + fhtype = FHT_SUNOS5; + /* XXX what about AIX? */ + } } else { - fhtype = FHT_UNKNOWN; + /* + * 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)) { + fhtype = FHT_DECOSF; + } + else if ((fhp[8] == 0) && (fhp[9] == 10)) { + /* could be SUNOS5/IRIX5, AIX, HP-UX */ + if ((fhp[7] == 0) && (fhp[6] == 0) && + (fhp[5] == 0) && (fhp[4] == 0)) { + /* XXX is this always true of HP-UX? */ + fhtype = FHT_HPUX9; + } + else if (fhp[7] == 2) { + /* This would be MNT_NFS on AIX, which is impossible */ + fhtype = FHT_SUNOS5; /* or maybe IRIX5 */ + } + else { + /* + * XXX Could be SUNOS5/IRIX5 or AIX. I don't + * XXX see any way to disambiguate these, so + * XXX I'm going with the more likely guess. + * XXX Sorry, Big Blue. + */ + fhtype = FHT_SUNOS5; /* or maybe IRIX5 */ + } + } + else { + if (is_UCX(fhp, len)) { + fhtype = FHT_VMSUCX; + } + else { + fhtype = FHT_UNKNOWN; + } + } } } - } } /* XXX still needs to handle SUNOS3 */ @@ -363,13 +368,13 @@ Parse_fh(register const unsigned char *fh, int len _U_, my_fsid *fsidp, if (sizeof(*fsidp) > 14) memset((char *)fsidp, 0, sizeof(*fsidp)); /* just use the whole thing */ - memcpy((char *)fsidp, (char *)fh, 14); + memcpy((char *)fsidp, (const char *)fh, 14); } else { uint32_t tempa[4]; /* at least 16 bytes, maybe more */ memset((char *)tempa, 0, sizeof(tempa)); - memcpy((char *)tempa, (char *)fh, 14); /* ensure alignment */ + memcpy((char *)tempa, (const char *)fh, 14); /* ensure alignment */ fsidp->Fsid_dev.Minor = tempa[0] + (tempa[1]<<1); fsidp->Fsid_dev.Major = tempa[2] + (tempa[3]<<1); fsidp->fsid_code = 0; @@ -380,7 +385,7 @@ Parse_fh(register const unsigned char *fh, int len _U_, my_fsid *fsidp, /* Caller must save (and null-terminate?) this value */ if (fsnamep) - *fsnamep = (char *)&(fhp[1]); + *fsnamep = (const char *)&(fhp[1]); if (osnamep) *osnamep = "VMS"; @@ -412,13 +417,14 @@ Parse_fh(register const unsigned char *fh, int len _U_, my_fsid *fsidp, case FHT_UNKNOWN: #ifdef DEBUG /* XXX debugging */ - for (i = 0; i < 32; i++) + for (i = 0; i < len*4; i++) (void)fprintf(stderr, "%x.", fhp[i]); (void)fprintf(stderr, "\n"); #endif /* Save the actual handle, so it can be display with -u */ - for (i = 0; i < 32; i++) + 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]); + fsidp->Opaque_Handle[i*2] = '\0'; /* XXX for now, give "bogus" values to aid debugging */ fsidp->fsid_code = 0; @@ -445,11 +451,18 @@ Parse_fh(register const unsigned char *fh, int len _U_, my_fsid *fsidp, * (3) followed by string of nulls */ static int -is_UCX(const unsigned char *fhp) +is_UCX(const unsigned char *fhp, u_int len) { - register int i; + register u_int i; int seen_null = 0; + /* + * Require at least 28 bytes of file handle; it's variable-length + * in NFSv3. "len" is in units of 32-bit words, not bytes. + */ + if (len < 28/4) + return(0); + for (i = 1; i < 14; i++) { if (ND_ISPRINT(fhp[i])) { if (seen_null) diff --git a/contrib/tcpdump/pcap-missing.h b/contrib/tcpdump/pcap-missing.h index d776810..92706b1 100644 --- a/contrib/tcpdump/pcap-missing.h +++ b/contrib/tcpdump/pcap-missing.h @@ -19,8 +19,8 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#ifndef tcpdump_pcap_missing_h -#define tcpdump_pcap_missing_h +#ifndef netdissect_pcap_missing_h +#define netdissect_pcap_missing_h /* * Declarations of functions that might be missing from libpcap. @@ -46,13 +46,4 @@ extern const char *pcap_datalink_val_to_description(int); extern long pcap_dump_ftell(pcap_dumper_t *); #endif -#endif - - - - - - - - - +#endif /* netdissect_pcap_missing_h */ diff --git a/contrib/tcpdump/ppp.h b/contrib/tcpdump/ppp.h index da4810a..9d53423 100644 --- a/contrib/tcpdump/ppp.h +++ b/contrib/tcpdump/ppp.h @@ -13,8 +13,6 @@ * University. Carnegie Mellon makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. - * - * $FreeBSD$ */ #define PPP_HDRLEN 4 /* length of PPP header */ diff --git a/contrib/tcpdump/print-802_11.c b/contrib/tcpdump/print-802_11.c index 88fbf40..3db98ea 100644 --- a/contrib/tcpdump/print-802_11.c +++ b/contrib/tcpdump/print-802_11.c @@ -20,16 +20,17 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: IEEE 802.11 printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" @@ -45,8 +46,11 @@ #define IEEE802_11_BSSID_LEN 6 #define IEEE802_11_RA_LEN 6 #define IEEE802_11_TA_LEN 6 +#define IEEE802_11_ADDR1_LEN 6 #define IEEE802_11_SEQ_LEN 2 #define IEEE802_11_CTL_LEN 2 +#define IEEE802_11_CARRIED_FC_LEN 2 +#define IEEE802_11_HT_CONTROL_LEN 4 #define IEEE802_11_IV_LEN 3 #define IEEE802_11_KID_LEN 1 @@ -166,15 +170,15 @@ static const struct tok ctrl_str[] = { #define FC_RETRY(fc) ((fc) & 0x0800) #define FC_POWER_MGMT(fc) ((fc) & 0x1000) #define FC_MORE_DATA(fc) ((fc) & 0x2000) -#define FC_WEP(fc) ((fc) & 0x4000) +#define FC_PROTECTED(fc) ((fc) & 0x4000) #define FC_ORDER(fc) ((fc) & 0x8000) struct mgmt_header_t { uint16_t fc; uint16_t duration; - uint8_t da[6]; - uint8_t sa[6]; - uint8_t bssid[6]; + 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; }; @@ -292,85 +296,90 @@ struct mgmt_body_t { struct tim_t tim; }; -struct ctrl_rts_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]; +}; + +#define CTRL_CONTROL_WRAPPER_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ + IEEE802_11_ADDR1_LEN+\ + IEEE802_11_CARRIED_FC_LEN+\ + IEEE802_11_HT_CONTROL_LEN) + +struct ctrl_rts_hdr_t { uint16_t fc; uint16_t duration; - uint8_t ra[6]; - uint8_t ta[6]; - uint8_t fcs[4]; + uint8_t ra[IEEE802_11_RA_LEN]; + uint8_t ta[IEEE802_11_TA_LEN]; }; #define CTRL_RTS_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ IEEE802_11_RA_LEN+IEEE802_11_TA_LEN) -struct ctrl_cts_t { +struct ctrl_cts_hdr_t { uint16_t fc; uint16_t duration; - uint8_t ra[6]; - uint8_t fcs[4]; + uint8_t ra[IEEE802_11_RA_LEN]; }; #define CTRL_CTS_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN) -struct ctrl_ack_t { +struct ctrl_ack_hdr_t { uint16_t fc; uint16_t duration; - uint8_t ra[6]; - uint8_t fcs[4]; + uint8_t ra[IEEE802_11_RA_LEN]; }; #define CTRL_ACK_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN) -struct ctrl_ps_poll_t { +struct ctrl_ps_poll_hdr_t { uint16_t fc; uint16_t aid; - uint8_t bssid[6]; - uint8_t ta[6]; - uint8_t fcs[4]; + uint8_t bssid[IEEE802_11_BSSID_LEN]; + uint8_t ta[IEEE802_11_TA_LEN]; }; #define CTRL_PS_POLL_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_AID_LEN+\ IEEE802_11_BSSID_LEN+IEEE802_11_TA_LEN) -struct ctrl_end_t { +struct ctrl_end_hdr_t { uint16_t fc; uint16_t duration; - uint8_t ra[6]; - uint8_t bssid[6]; - uint8_t fcs[4]; + uint8_t ra[IEEE802_11_RA_LEN]; + uint8_t bssid[IEEE802_11_BSSID_LEN]; }; #define CTRL_END_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ IEEE802_11_RA_LEN+IEEE802_11_BSSID_LEN) -struct ctrl_end_ack_t { +struct ctrl_end_ack_hdr_t { uint16_t fc; uint16_t duration; - uint8_t ra[6]; - uint8_t bssid[6]; - uint8_t fcs[4]; + uint8_t ra[IEEE802_11_RA_LEN]; + uint8_t bssid[IEEE802_11_BSSID_LEN]; }; #define CTRL_END_ACK_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ IEEE802_11_RA_LEN+IEEE802_11_BSSID_LEN) -struct ctrl_ba_t { +struct ctrl_ba_hdr_t { uint16_t fc; uint16_t duration; - uint8_t ra[6]; - uint8_t fcs[4]; + uint8_t ra[IEEE802_11_RA_LEN]; }; #define CTRL_BA_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN) -struct ctrl_bar_t { +struct ctrl_bar_hdr_t { uint16_t fc; uint16_t dur; - uint8_t ra[6]; - uint8_t ta[6]; + uint8_t ra[IEEE802_11_RA_LEN]; + uint8_t ta[IEEE802_11_TA_LEN]; uint16_t ctl; uint16_t seq; - uint8_t fcs[4]; }; #define CTRL_BAR_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ @@ -390,354 +399,50 @@ struct meshcntl_t { #define IV_PAD(iv) (((iv) >> 24) & 0x3F) #define IV_KEYID(iv) (((iv) >> 30) & 0x03) -/* $FreeBSD$ */ -/* NetBSD: ieee802_11_radio.h,v 1.2 2006/02/26 03:04:03 dyoung Exp */ +#define PRINT_SSID(p) \ + if (p.ssid_present) { \ + ND_PRINT((ndo, " (")); \ + fn_print(ndo, p.ssid.ssid, NULL); \ + ND_PRINT((ndo, ")")); \ + } -/*- - * Copyright (c) 2003, 2004 David Young. 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. The name of David Young may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``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 DAVID - * YOUNG 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. - */ +#define PRINT_RATE(_sep, _r, _suf) \ + ND_PRINT((ndo, "%s%2.1f%s", _sep, (.5 * ((_r) & 0x7f)), _suf)) +#define PRINT_RATES(p) \ + if (p.rates_present) { \ + int z; \ + const char *sep = " ["; \ + for (z = 0; z < p.rates.length ; z++) { \ + PRINT_RATE(sep, p.rates.rate[z], \ + (p.rates.rate[z] & 0x80 ? "*" : "")); \ + sep = " "; \ + } \ + if (p.rates.length != 0) \ + ND_PRINT((ndo, " Mbit]")); \ + } -/* A generic radio capture format is desirable. It must be - * rigidly defined (e.g., units for fields should be given), - * and easily extensible. - * - * The following is an extensible radio capture format. It is - * based on a bitmap indicating which fields are present. - * - * I am trying to describe precisely what the application programmer - * should expect in the following, and for that reason I tell the - * units and origin of each measurement (where it applies), or else I - * use sufficiently weaselly language ("is a monotonically nondecreasing - * function of...") that I cannot set false expectations for lawyerly - * readers. - */ +#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" : "")); -/* - * The radio capture header precedes the 802.11 header. - * - * Note well: all radiotap fields are little-endian. - */ -struct ieee80211_radiotap_header { - 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 - * header in bytes, including - * it_version, it_pad, - * it_len, and data fields. - */ - uint32_t it_present; /* A bitmap telling which - * fields are present. Set bit 31 - * (0x80000000) to extend the - * bitmap by another 32 bits. - * Additional extensions are made - * by setting bit 31. - */ -}; +#define MAX_MCS_INDEX 76 -/* Name Data type Units - * ---- --------- ----- - * - * IEEE80211_RADIOTAP_TSFT uint64_t microseconds - * - * Value in microseconds of the MAC's 64-bit 802.11 Time - * Synchronization Function timer when the first bit of the - * MPDU arrived at the MAC. For received frames, only. - * - * IEEE80211_RADIOTAP_CHANNEL 2 x uint16_t MHz, bitmap - * - * Tx/Rx frequency in MHz, followed by flags (see below). - * Note that IEEE80211_RADIOTAP_XCHANNEL must be used to - * represent an HT channel as there is not enough room in - * the flags word. - * - * IEEE80211_RADIOTAP_FHSS uint16_t see below - * - * For frequency-hopping radios, the hop set (first byte) - * and pattern (second byte). - * - * IEEE80211_RADIOTAP_RATE uint8_t 500kb/s or index - * - * 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) - * - * RF signal power at the antenna, decibel difference from - * one milliwatt. - * - * IEEE80211_RADIOTAP_DBM_ANTNOISE int8_t decibels from - * one milliwatt (dBm) - * - * RF noise power at the antenna, decibel difference from one - * milliwatt. - * - * IEEE80211_RADIOTAP_DB_ANTSIGNAL uint8_t decibel (dB) - * - * RF signal power at the antenna, decibel difference from an - * arbitrary, fixed reference. - * - * IEEE80211_RADIOTAP_DB_ANTNOISE uint8_t decibel (dB) - * - * RF noise power at the antenna, decibel difference from an - * arbitrary, fixed reference point. - * - * IEEE80211_RADIOTAP_LOCK_QUALITY uint16_t unitless - * - * Quality of Barker code lock. Unitless. Monotonically - * nondecreasing with "better" lock strength. Called "Signal - * Quality" in datasheets. (Is there a standard way to measure - * this?) - * - * IEEE80211_RADIOTAP_TX_ATTENUATION uint16_t unitless - * - * Transmit power expressed as unitless distance from max - * power set at factory calibration. 0 is max power. - * Monotonically nondecreasing with lower power levels. - * - * IEEE80211_RADIOTAP_DB_TX_ATTENUATION uint16_t decibels (dB) - * - * Transmit power expressed as decibel distance from max power - * 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) - * - * Transmit power expressed as dBm (decibels from a 1 milliwatt - * reference). This is the absolute power level measured at - * the antenna port. - * - * IEEE80211_RADIOTAP_FLAGS uint8_t bitmap - * - * Properties of transmitted and received frames. See flags - * defined below. - * - * IEEE80211_RADIOTAP_ANTENNA uint8_t antenna index - * - * Unitless indication of the Rx/Tx antenna for this packet. - * The first antenna is antenna 0. - * - * IEEE80211_RADIOTAP_RX_FLAGS uint16_t bitmap - * - * 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 - * - * Extended channel specification: flags (see below) followed by - * frequency in MHz, the corresponding IEEE channel number, and - * finally the maximum regulatory transmit power cap in .5 dBm - * units. This property supersedes IEEE80211_RADIOTAP_CHANNEL - * and only one of the two should be present. - * - * IEEE80211_RADIOTAP_MCS 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 - * in IEEE 802.11n. +/* + * Indices are: * - * IEEE80211_RADIOTAP_VENDOR_NAMESPACE - * uint8_t OUI[3] - * uint8_t subspace - * uint16_t length + * the MCS index (0-76); * - * The Vendor Namespace Field contains three sub-fields. The first - * sub-field is 3 bytes long. It contains the vendor's IEEE 802 - * Organizationally Unique Identifier (OUI). The fourth byte is a - * vendor-specific "namespace selector." + * 0 for 20 MHz, 1 for 40 MHz; * + * 0 for a long guard interval, 1 for a short guard interval. */ -enum ieee80211_radiotap_type { - IEEE80211_RADIOTAP_TSFT = 0, - IEEE80211_RADIOTAP_FLAGS = 1, - IEEE80211_RADIOTAP_RATE = 2, - IEEE80211_RADIOTAP_CHANNEL = 3, - IEEE80211_RADIOTAP_FHSS = 4, - IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5, - IEEE80211_RADIOTAP_DBM_ANTNOISE = 6, - IEEE80211_RADIOTAP_LOCK_QUALITY = 7, - IEEE80211_RADIOTAP_TX_ATTENUATION = 8, - IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9, - IEEE80211_RADIOTAP_DBM_TX_POWER = 10, - IEEE80211_RADIOTAP_ANTENNA = 11, - IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12, - IEEE80211_RADIOTAP_DB_ANTNOISE = 13, - IEEE80211_RADIOTAP_RX_FLAGS = 14, - /* NB: gap for netbsd definitions */ - IEEE80211_RADIOTAP_XCHANNEL = 18, - IEEE80211_RADIOTAP_MCS = 19, - IEEE80211_RADIOTAP_NAMESPACE = 29, - IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30, - IEEE80211_RADIOTAP_EXT = 31 -}; - -/* channel attributes */ -#define IEEE80211_CHAN_TURBO 0x00010 /* Turbo channel */ -#define IEEE80211_CHAN_CCK 0x00020 /* CCK channel */ -#define IEEE80211_CHAN_OFDM 0x00040 /* OFDM channel */ -#define IEEE80211_CHAN_2GHZ 0x00080 /* 2 GHz spectrum channel. */ -#define IEEE80211_CHAN_5GHZ 0x00100 /* 5 GHz spectrum channel */ -#define IEEE80211_CHAN_PASSIVE 0x00200 /* Only passive scan allowed */ -#define IEEE80211_CHAN_DYN 0x00400 /* Dynamic CCK-OFDM channel */ -#define IEEE80211_CHAN_GFSK 0x00800 /* GFSK channel (FHSS PHY) */ -#define IEEE80211_CHAN_GSM 0x01000 /* 900 MHz spectrum channel */ -#define IEEE80211_CHAN_STURBO 0x02000 /* 11a static turbo channel only */ -#define IEEE80211_CHAN_HALF 0x04000 /* Half rate channel */ -#define IEEE80211_CHAN_QUARTER 0x08000 /* Quarter rate channel */ -#define IEEE80211_CHAN_HT20 0x10000 /* HT 20 channel */ -#define IEEE80211_CHAN_HT40U 0x20000 /* HT 40 channel w/ ext above */ -#define IEEE80211_CHAN_HT40D 0x40000 /* HT 40 channel w/ ext below */ - -/* Useful combinations of channel characteristics, borrowed from Ethereal */ -#define IEEE80211_CHAN_A \ - (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM) -#define IEEE80211_CHAN_B \ - (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK) -#define IEEE80211_CHAN_G \ - (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN) -#define IEEE80211_CHAN_TA \ - (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO) -#define IEEE80211_CHAN_TG \ - (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN | IEEE80211_CHAN_TURBO) - - -/* For IEEE80211_RADIOTAP_FLAGS */ -#define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received - * during CFP - */ -#define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received - * with short - * preamble - */ -#define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received - * with WEP encryption - */ -#define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received - * with fragmentation - */ -#define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FCS */ -#define IEEE80211_RADIOTAP_F_DATAPAD 0x20 /* frame has padding between - * 802.11 header and payload - * (to 32-bit boundary) - */ -#define IEEE80211_RADIOTAP_F_BADFCS 0x40 /* does not pass FCS check */ - -/* For IEEE80211_RADIOTAP_RX_FLAGS */ -#define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001 /* frame failed crc check */ -#define IEEE80211_RADIOTAP_F_RX_PLCP_CRC 0x0002 /* frame failed PLCP CRC check */ - -/* For IEEE80211_RADIOTAP_MCS known */ -#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN 0x01 -#define IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN 0x02 /* MCS index field */ -#define IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN 0x04 -#define IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN 0x08 -#define IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN 0x10 -#define IEEE80211_RADIOTAP_MCS_STBC_KNOWN 0x20 - -/* For IEEE80211_RADIOTAP_MCS flags */ -#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK 0x03 -#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20 0 -#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_40 1 -#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20L 2 -#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20U 3 -#define IEEE80211_RADIOTAP_MCS_SHORT_GI 0x04 /* short guard interval */ -#define IEEE80211_RADIOTAP_MCS_HT_GREENFIELD 0x08 -#define IEEE80211_RADIOTAP_MCS_FEC_LDPC 0x10 -#define IEEE80211_RADIOTAP_MCS_STBC_MASK 0x60 -#define IEEE80211_RADIOTAP_MCS_STBC_1 1 -#define IEEE80211_RADIOTAP_MCS_STBC_2 2 -#define IEEE80211_RADIOTAP_MCS_STBC_3 3 -#define IEEE80211_RADIOTAP_MCS_STBC_SHIFT 5 - -static const char tstr[] = "[|802.11]"; - -/* Radiotap state */ -/* This is used to save state when parsing/processing parameters */ -struct radiotap_state -{ - uint32_t present; - - uint8_t rate; -}; - -#define PRINT_SSID(p) \ - if (p.ssid_present) { \ - ND_PRINT((ndo, " (")); \ - fn_print(ndo, p.ssid.ssid, NULL); \ - ND_PRINT((ndo, ")")); \ - } - -#define PRINT_RATE(_sep, _r, _suf) \ - ND_PRINT((ndo, "%s%2.1f%s", _sep, (.5 * ((_r) & 0x7f)), _suf)) -#define PRINT_RATES(p) \ - if (p.rates_present) { \ - int z; \ - const char *sep = " ["; \ - for (z = 0; z < p.rates.length ; z++) { \ - PRINT_RATE(sep, p.rates.rate[z], \ - (p.rates.rate[z] & 0x80 ? "*" : "")); \ - sep = " "; \ - } \ - if (p.rates.length != 0) \ - ND_PRINT((ndo, " 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" : "")); - -#define MAX_MCS_INDEX 76 - -/* - * Indices are: - * - * the MCS index (0-76); - * - * 0 for 20 MHz, 1 for 40 MHz; - * - * 0 for a long guard interval, 1 for a short guard interval. - */ -static const float ieee80211_float_htrates[MAX_MCS_INDEX+1][2][2] = { - /* MCS 0 */ - { /* 20 Mhz */ { 6.5, /* SGI */ 7.2, }, - /* 40 Mhz */ { 13.5, /* SGI */ 15.0, }, - }, +static const float ieee80211_float_htrates[MAX_MCS_INDEX+1][2][2] = { + /* MCS 0 */ + { /* 20 Mhz */ { 6.5, /* SGI */ 7.2, }, + /* 40 Mhz */ { 13.5, /* SGI */ 15.0, }, + }, /* MCS 1 */ { /* 20 Mhz */ { 13.0, /* SGI */ 14.4, }, @@ -1283,7 +988,7 @@ wep_print(netdissect_options *ndo, return 0; iv = EXTRACT_LE_32BITS(p); - ND_PRINT((ndo, "Data IV:%3x Pad %x KeyID %x", IV_IV(iv), IV_PAD(iv), + ND_PRINT((ndo, " IV:%3x Pad %x KeyID %x", IV_IV(iv), IV_PAD(iv), IV_KEYID(iv))); return 1; @@ -1801,7 +1506,7 @@ handle_auth(netdissect_options *ndo, static int handle_deauth(netdissect_options *ndo, - const struct mgmt_header_t *pmh, 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; @@ -1821,7 +1526,7 @@ handle_deauth(netdissect_options *ndo, if (ndo->ndo_eflag) { ND_PRINT((ndo, ": %s", reason)); } else { - ND_PRINT((ndo, " (%s): %s", etheraddr_string(ndo, pmh->sa), reason)); + ND_PRINT((ndo, " (%s): %s", etheraddr_string(ndo, src), reason)); } return 1; } @@ -1886,7 +1591,7 @@ handle_deauth(netdissect_options *ndo, static int handle_action(netdissect_options *ndo, - const struct mgmt_header_t *pmh, 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; @@ -1895,7 +1600,7 @@ handle_action(netdissect_options *ndo, if (ndo->ndo_eflag) { ND_PRINT((ndo, ": ")); } else { - ND_PRINT((ndo, " (%s): ", etheraddr_string(ndo, pmh->sa))); + ND_PRINT((ndo, " (%s): ", etheraddr_string(ndo, src))); } switch (p[0]) { case 0: ND_PRINT((ndo, "Spectrum Management Act#%d", p[1])); break; @@ -1926,10 +1631,13 @@ handle_action(netdissect_options *ndo, static int mgmt_body_print(netdissect_options *ndo, - uint16_t fc, const struct mgmt_header_t *pmh, - 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)))); + + /* There may be a problem w/ AP not having this bit set */ + if (FC_PROTECTED(fc)) + return wep_print(ndo, p); switch (FC_SUBTYPE(fc)) { case ST_ASSOC_REQUEST: return handle_assoc_request(ndo, p, length); @@ -1950,17 +1658,11 @@ mgmt_body_print(netdissect_options *ndo, case ST_DISASSOC: return handle_disassoc(ndo, p, length); case ST_AUTH: - if (!ND_TTEST2(*p, 3)) - return 0; - if ((p[0] == 0 ) && (p[1] == 0) && (p[2] == 0)) { - ND_PRINT((ndo, "Authentication (Shared-Key)-3 ")); - return wep_print(ndo, p); - } return handle_auth(ndo, p, length); case ST_DEAUTH: - return handle_deauth(ndo, pmh, p, length); + return handle_deauth(ndo, src, p, length); case ST_ACTION: - return handle_action(ndo, pmh, p, length); + return handle_action(ndo, src, p, length); default: return 1; } @@ -1985,68 +1687,64 @@ ctrl_body_print(netdissect_options *ndo, return 0; if (!ndo->ndo_eflag) ND_PRINT((ndo, " RA:%s TA:%s CTL(%x) SEQ(%u) ", - etheraddr_string(ndo, ((const struct ctrl_bar_t *)p)->ra), - etheraddr_string(ndo, ((const struct ctrl_bar_t *)p)->ta), - EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)), - EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)))); + 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)))); break; case CTRL_BA: if (!ND_TTEST2(*p, CTRL_BA_HDRLEN)) return 0; if (!ndo->ndo_eflag) ND_PRINT((ndo, " RA:%s ", - etheraddr_string(ndo, ((const struct ctrl_ba_t *)p)->ra))); + etheraddr_string(ndo, ((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_t *)p)->aid)))); + EXTRACT_LE_16BITS(&(((const struct ctrl_ps_poll_hdr_t *)p)->aid)))); break; case CTRL_RTS: if (!ND_TTEST2(*p, CTRL_RTS_HDRLEN)) return 0; if (!ndo->ndo_eflag) ND_PRINT((ndo, " TA:%s ", - etheraddr_string(ndo, ((const struct ctrl_rts_t *)p)->ta))); + etheraddr_string(ndo, ((const struct ctrl_rts_hdr_t *)p)->ta))); break; case CTRL_CTS: if (!ND_TTEST2(*p, CTRL_CTS_HDRLEN)) return 0; if (!ndo->ndo_eflag) ND_PRINT((ndo, " RA:%s ", - etheraddr_string(ndo, ((const struct ctrl_cts_t *)p)->ra))); + etheraddr_string(ndo, ((const struct ctrl_cts_hdr_t *)p)->ra))); break; case CTRL_ACK: if (!ND_TTEST2(*p, CTRL_ACK_HDRLEN)) return 0; if (!ndo->ndo_eflag) ND_PRINT((ndo, " RA:%s ", - etheraddr_string(ndo, ((const struct ctrl_ack_t *)p)->ra))); + etheraddr_string(ndo, ((const struct ctrl_ack_hdr_t *)p)->ra))); break; case CTRL_CF_END: if (!ND_TTEST2(*p, CTRL_END_HDRLEN)) return 0; if (!ndo->ndo_eflag) ND_PRINT((ndo, " RA:%s ", - etheraddr_string(ndo, ((const struct ctrl_end_t *)p)->ra))); + etheraddr_string(ndo, ((const struct ctrl_end_hdr_t *)p)->ra))); break; case CTRL_END_ACK: if (!ND_TTEST2(*p, CTRL_END_ACK_HDRLEN)) return 0; if (!ndo->ndo_eflag) ND_PRINT((ndo, " RA:%s ", - etheraddr_string(ndo, ((const struct ctrl_end_ack_t *)p)->ra))); + etheraddr_string(ndo, ((const struct ctrl_end_ack_hdr_t *)p)->ra))); break; } return 1; } /* - * Print Header funcs - */ - -/* * Data Frame - Address field contents * * To Ds | From DS | Addr 1 | Addr 2 | Addr 3 | Addr 4 @@ -2056,10 +1754,63 @@ ctrl_body_print(netdissect_options *ndo, * 1 | 1 | RA | TA | DA | SA */ +/* + * Function to get source and destination MAC addresses for a data frame. + */ +static void +get_data_src_dst_mac(uint16_t fc, const u_char *p, const uint8_t **srcp, + const uint8_t **dstp) +{ +#define ADDR1 (p + 4) +#define ADDR2 (p + 10) +#define ADDR3 (p + 16) +#define ADDR4 (p + 24) + + if (!FC_TO_DS(fc)) { + if (!FC_FROM_DS(fc)) { + /* not To DS and not From DS */ + *srcp = ADDR2; + *dstp = ADDR1; + } else { + /* not To DS and From DS */ + *srcp = ADDR3; + *dstp = ADDR1; + } + } else { + if (!FC_FROM_DS(fc)) { + /* From DS and not To DS */ + *srcp = ADDR2; + *dstp = ADDR3; + } else { + /* To DS and From DS */ + *srcp = ADDR4; + *dstp = ADDR3; + } + } + +#undef ADDR1 +#undef ADDR2 +#undef ADDR3 +#undef ADDR4 +} + +static void +get_mgmt_src_dst_mac(const u_char *p, const uint8_t **srcp, const uint8_t **dstp) +{ + const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p; + + if (srcp != NULL) + *srcp = hp->sa; + if (dstp != NULL) + *dstp = hp->da; +} + +/* + * Print Header funcs + */ + static void -data_header_print(netdissect_options *ndo, - uint16_t fc, const u_char *p, const uint8_t **srcp, - const uint8_t **dstp) +data_header_print(netdissect_options *ndo, uint16_t fc, const u_char *p) { u_int subtype = FC_SUBTYPE(fc); @@ -2086,42 +1837,18 @@ data_header_print(netdissect_options *ndo, #define ADDR4 (p + 24) if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) { - if (srcp != NULL) - *srcp = ADDR2; - if (dstp != NULL) - *dstp = ADDR1; - if (!ndo->ndo_eflag) - return; ND_PRINT((ndo, "DA:%s SA:%s BSSID:%s ", etheraddr_string(ndo, ADDR1), etheraddr_string(ndo, ADDR2), etheraddr_string(ndo, ADDR3))); } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) { - if (srcp != NULL) - *srcp = ADDR3; - if (dstp != NULL) - *dstp = ADDR1; - if (!ndo->ndo_eflag) - return; ND_PRINT((ndo, "DA:%s BSSID:%s SA:%s ", etheraddr_string(ndo, ADDR1), etheraddr_string(ndo, ADDR2), etheraddr_string(ndo, ADDR3))); } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) { - if (srcp != NULL) - *srcp = ADDR2; - if (dstp != NULL) - *dstp = ADDR3; - if (!ndo->ndo_eflag) - return; ND_PRINT((ndo, "BSSID:%s SA:%s DA:%s ", etheraddr_string(ndo, ADDR1), etheraddr_string(ndo, ADDR2), etheraddr_string(ndo, ADDR3))); } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) { - if (srcp != NULL) - *srcp = ADDR4; - if (dstp != NULL) - *dstp = ADDR3; - if (!ndo->ndo_eflag) - return; 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))); @@ -2134,77 +1861,60 @@ data_header_print(netdissect_options *ndo, } static void -mgmt_header_print(netdissect_options *ndo, - const u_char *p, const uint8_t **srcp, const uint8_t **dstp) +mgmt_header_print(netdissect_options *ndo, const u_char *p) { const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p; - if (srcp != NULL) - *srcp = hp->sa; - if (dstp != NULL) - *dstp = hp->da; - if (!ndo->ndo_eflag) - return; - ND_PRINT((ndo, "BSSID:%s DA:%s SA:%s ", etheraddr_string(ndo, (hp)->bssid), etheraddr_string(ndo, (hp)->da), etheraddr_string(ndo, (hp)->sa))); } static void -ctrl_header_print(netdissect_options *ndo, - uint16_t fc, const u_char *p, const uint8_t **srcp, - const uint8_t **dstp) +ctrl_header_print(netdissect_options *ndo, uint16_t fc, const u_char *p) { - if (srcp != NULL) - *srcp = NULL; - if (dstp != NULL) - *dstp = NULL; - if (!ndo->ndo_eflag) - return; - 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_t *)p)->ra), - etheraddr_string(ndo, ((const struct ctrl_bar_t *)p)->ta), - EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)), - EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)))); + 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)))); break; case CTRL_BA: ND_PRINT((ndo, "RA:%s ", - etheraddr_string(ndo, ((const struct ctrl_ba_t *)p)->ra))); + etheraddr_string(ndo, ((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_t *)p)->bssid), - etheraddr_string(ndo, ((const struct ctrl_ps_poll_t *)p)->ta))); + etheraddr_string(ndo, ((const struct ctrl_ps_poll_hdr_t *)p)->bssid), + etheraddr_string(ndo, ((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_t *)p)->ra), - etheraddr_string(ndo, ((const struct ctrl_rts_t *)p)->ta))); + etheraddr_string(ndo, ((const struct ctrl_rts_hdr_t *)p)->ra), + etheraddr_string(ndo, ((const struct ctrl_rts_hdr_t *)p)->ta))); break; case CTRL_CTS: ND_PRINT((ndo, "RA:%s ", - etheraddr_string(ndo, ((const struct ctrl_cts_t *)p)->ra))); + etheraddr_string(ndo, ((const struct ctrl_cts_hdr_t *)p)->ra))); break; case CTRL_ACK: ND_PRINT((ndo, "RA:%s ", - etheraddr_string(ndo, ((const struct ctrl_ack_t *)p)->ra))); + etheraddr_string(ndo, ((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_t *)p)->ra), - etheraddr_string(ndo, ((const struct ctrl_end_t *)p)->bssid))); + etheraddr_string(ndo, ((const struct ctrl_end_hdr_t *)p)->ra), + etheraddr_string(ndo, ((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_t *)p)->ra), - etheraddr_string(ndo, ((const struct ctrl_end_ack_t *)p)->bssid))); + etheraddr_string(ndo, ((const struct ctrl_end_ack_hdr_t *)p)->ra), + etheraddr_string(ndo, ((const struct ctrl_end_ack_hdr_t *)p)->bssid))); break; default: - ND_PRINT((ndo, "(H) Unknown Ctrl Subtype")); + /* We shouldn't get here - we should already have quit */ break; } } @@ -2220,8 +1930,12 @@ extract_header_length(netdissect_options *ndo, return MGMT_HDRLEN; case T_CTRL: switch (FC_SUBTYPE(fc)) { + case CTRL_CONTROL_WRAPPER: + return CTRL_CONTROL_WRAPPER_HDRLEN; case CTRL_BAR: return CTRL_BAR_HDRLEN; + case CTRL_BA: + return CTRL_BA_HDRLEN; case CTRL_PS_POLL: return CTRL_PS_POLL_HDRLEN; case CTRL_RTS: @@ -2235,6 +1949,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))); return 0; } case T_DATA: @@ -2243,7 +1958,7 @@ extract_header_length(netdissect_options *ndo, len += 2; return len; default: - ND_PRINT((ndo, "unknown IEEE802.11 frame type (%d)", FC_TYPE(fc))); + ND_PRINT((ndo, "unknown 802.11 frame type (%d)", FC_TYPE(fc))); return 0; } } @@ -2255,15 +1970,12 @@ extract_mesh_header_length(const u_char *p) } /* - * Print the 802.11 MAC header if eflag is set, and set "*srcp" and "*dstp" - * to point to the source and destination MAC addresses in any case if - * "srcp" and "dstp" aren't null. + * Print the 802.11 MAC header. */ static void ieee_802_11_hdr_print(netdissect_options *ndo, uint16_t fc, const u_char *p, u_int hdrlen, - u_int meshdrlen, const uint8_t **srcp, - const uint8_t **dstp) + u_int meshdrlen) { if (ndo->ndo_vflag) { if (FC_MORE_DATA(fc)) @@ -2276,8 +1988,8 @@ ieee_802_11_hdr_print(netdissect_options *ndo, ND_PRINT((ndo, "Retry ")); if (FC_ORDER(fc)) ND_PRINT((ndo, "Strictly Ordered ")); - if (FC_WEP(fc)) - ND_PRINT((ndo, "WEP Encrypted ")); + if (FC_PROTECTED(fc)) + ND_PRINT((ndo, "Protected ")); if (FC_TYPE(fc) != T_CTRL || FC_SUBTYPE(fc) != CTRL_PS_POLL) ND_PRINT((ndo, "%dus ", EXTRACT_LE_16BITS( @@ -2301,19 +2013,15 @@ ieee_802_11_hdr_print(netdissect_options *ndo, switch (FC_TYPE(fc)) { case T_MGMT: - mgmt_header_print(ndo, p, srcp, dstp); + mgmt_header_print(ndo, p); break; case T_CTRL: - ctrl_header_print(ndo, fc, p, srcp, dstp); + ctrl_header_print(ndo, fc, p); break; case T_DATA: - data_header_print(ndo, fc, p, srcp, dstp); + data_header_print(ndo, fc, p); break; default: - ND_PRINT((ndo, "(header) unknown IEEE802.11 frame type (%d)", - FC_TYPE(fc))); - *srcp = NULL; - *dstp = NULL; break; } } @@ -2322,6 +2030,8 @@ ieee_802_11_hdr_print(netdissect_options *ndo, #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, @@ -2329,8 +2039,8 @@ ieee802_11_print(netdissect_options *ndo, { uint16_t fc; u_int caplen, hdrlen, meshdrlen; - const uint8_t *src, *dst; - u_short extracted_ethertype; + struct lladdr_info src, dst; + int llc_hdrlen; caplen = orig_caplen; /* Remove FCS, if present */ @@ -2353,6 +2063,10 @@ ieee802_11_print(netdissect_options *ndo, fc = EXTRACT_LE_16BITS(p); hdrlen = extract_header_length(ndo, fc); + if (hdrlen == 0) { + /* Unknown frame type or control frame subtype; quit. */ + return (0); + } if (pad) hdrlen = roundup2(hdrlen, 4); if (ndo->ndo_Hflag && FC_TYPE(fc) == T_DATA && @@ -2362,13 +2076,13 @@ ieee802_11_print(netdissect_options *ndo, } else meshdrlen = 0; - if (caplen < hdrlen) { ND_PRINT((ndo, "%s", tstr)); return hdrlen; } - ieee_802_11_hdr_print(ndo, fc, p, hdrlen, meshdrlen, &src, &dst); + if (ndo->ndo_eflag) + ieee_802_11_hdr_print(ndo, fc, p, hdrlen, meshdrlen); /* * Go past the 802.11 header. @@ -2377,10 +2091,12 @@ ieee802_11_print(netdissect_options *ndo, caplen -= hdrlen; p += hdrlen; + src.addr_string = etheraddr_string; + dst.addr_string = etheraddr_string; switch (FC_TYPE(fc)) { case T_MGMT: - if (!mgmt_body_print(ndo, fc, - (const struct mgmt_header_t *)(p - hdrlen), p, length)) { + 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)); return hdrlen; } @@ -2395,30 +2111,29 @@ ieee802_11_print(netdissect_options *ndo, if (DATA_FRAME_IS_NULL(FC_SUBTYPE(fc))) return hdrlen; /* no-data frame */ /* There may be a problem w/ AP not having this bit set */ - if (FC_WEP(fc)) { + if (FC_PROTECTED(fc)) { + ND_PRINT((ndo, "Data")); if (!wep_print(ndo, p)) { ND_PRINT((ndo, "%s", tstr)); return hdrlen; } - } else if (llc_print(ndo, p, length, caplen, dst, src, - &extracted_ethertype) == 0) { - /* - * Some kinds of LLC packet we cannot - * handle intelligently - */ - if (!ndo->ndo_eflag) - ieee_802_11_hdr_print(ndo, fc, p - hdrlen, hdrlen, - meshdrlen, NULL, NULL); - if (extracted_ethertype) - ND_PRINT((ndo, "(LLC %s) ", - etherproto_string( - htons(extracted_ethertype)))); - if (!ndo->ndo_suppress_default_print) - ND_DEFAULTPRINT(p, caplen); + } else { + get_data_src_dst_mac(fc, p - hdrlen, &src.addr, &dst.addr); + llc_hdrlen = llc_print(ndo, p, length, caplen, &src, &dst); + if (llc_hdrlen < 0) { + /* + * Some kinds of LLC packet we cannot + * handle intelligently + */ + if (!ndo->ndo_suppress_default_print) + ND_DEFAULTPRINT(p, caplen); + llc_hdrlen = -llc_hdrlen; + } + hdrlen += llc_hdrlen; } break; default: - ND_PRINT((ndo, "unknown 802.11 frame type (%d)", FC_TYPE(fc))); + /* We shouldn't get here - we should already have quit */ break; } @@ -2438,207 +2153,465 @@ ieee802_11_if_print(netdissect_options *ndo, return ieee802_11_print(ndo, p, h->len, h->caplen, 0, 0); } -#define IEEE80211_CHAN_FHSS \ - (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK) -#define IEEE80211_CHAN_A \ - (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM) -#define IEEE80211_CHAN_B \ - (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK) -#define IEEE80211_CHAN_PUREG \ - (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM) -#define IEEE80211_CHAN_G \ - (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN) - -#define IS_CHAN_FHSS(flags) \ - ((flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS) -#define IS_CHAN_A(flags) \ - ((flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A) -#define IS_CHAN_B(flags) \ - ((flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B) -#define IS_CHAN_PUREG(flags) \ - ((flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG) -#define IS_CHAN_G(flags) \ - ((flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G) -#define IS_CHAN_ANYG(flags) \ - (IS_CHAN_PUREG(flags) || IS_CHAN_G(flags)) - -static void -print_chaninfo(netdissect_options *ndo, - int freq, int flags) -{ - ND_PRINT((ndo, "%u MHz", freq)); - if (IS_CHAN_FHSS(flags)) - ND_PRINT((ndo, " FHSS")); - if (IS_CHAN_A(flags)) { - if (flags & IEEE80211_CHAN_HALF) - ND_PRINT((ndo, " 11a/10Mhz")); - else if (flags & IEEE80211_CHAN_QUARTER) - ND_PRINT((ndo, " 11a/5Mhz")); - else - ND_PRINT((ndo, " 11a")); - } - if (IS_CHAN_ANYG(flags)) { - if (flags & IEEE80211_CHAN_HALF) - ND_PRINT((ndo, " 11g/10Mhz")); - else if (flags & IEEE80211_CHAN_QUARTER) - ND_PRINT((ndo, " 11g/5Mhz")); - else - ND_PRINT((ndo, " 11g")); - } else if (IS_CHAN_B(flags)) - ND_PRINT((ndo, " 11b")); - if (flags & IEEE80211_CHAN_TURBO) - ND_PRINT((ndo, " Turbo")); - if (flags & IEEE80211_CHAN_HT20) - ND_PRINT((ndo, " ht/20")); - else if (flags & IEEE80211_CHAN_HT40D) - ND_PRINT((ndo, " ht/40-")); - else if (flags & IEEE80211_CHAN_HT40U) - ND_PRINT((ndo, " ht/40+")); - ND_PRINT((ndo, " ")); -} - -static int -print_radiotap_field(netdissect_options *ndo, - struct cpack_state *s, uint32_t bit, uint8_t *flags, - struct radiotap_state *state, uint32_t presentflags) -{ - union { - int8_t i8; - uint8_t u8; - int16_t i16; - uint16_t u16; - uint32_t u32; - uint64_t u64; - } u, u2, u3, u4; - int rc; - switch (bit) { - case IEEE80211_RADIOTAP_FLAGS: - rc = cpack_uint8(s, &u.u8); - if (rc != 0) - break; - *flags = u.u8; - break; - case IEEE80211_RADIOTAP_RATE: - rc = cpack_uint8(s, &u.u8); - if (rc != 0) - break; +/* $FreeBSD: stable/11/contrib/tcpdump/print-802_11.c 276788 2015-01-07 19:55:18Z delphij $ */ +/* NetBSD: ieee802_11_radio.h,v 1.2 2006/02/26 03:04:03 dyoung Exp */ - /* Save state rate */ - state->rate = u.u8; - break; - case IEEE80211_RADIOTAP_DB_ANTSIGNAL: - case IEEE80211_RADIOTAP_DB_ANTNOISE: - case IEEE80211_RADIOTAP_ANTENNA: - rc = cpack_uint8(s, &u.u8); - break; - case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: - case IEEE80211_RADIOTAP_DBM_ANTNOISE: - rc = cpack_int8(s, &u.i8); - break; - case IEEE80211_RADIOTAP_CHANNEL: - rc = cpack_uint16(s, &u.u16); - if (rc != 0) - break; - rc = cpack_uint16(s, &u2.u16); - break; - case IEEE80211_RADIOTAP_FHSS: - case IEEE80211_RADIOTAP_LOCK_QUALITY: - case IEEE80211_RADIOTAP_TX_ATTENUATION: - case IEEE80211_RADIOTAP_RX_FLAGS: - rc = cpack_uint16(s, &u.u16); - break; - case IEEE80211_RADIOTAP_DB_TX_ATTENUATION: - rc = cpack_uint8(s, &u.u8); - break; - case IEEE80211_RADIOTAP_DBM_TX_POWER: - rc = cpack_int8(s, &u.i8); - break; - case IEEE80211_RADIOTAP_TSFT: - rc = cpack_uint64(s, &u.u64); - break; - case IEEE80211_RADIOTAP_XCHANNEL: - rc = cpack_uint32(s, &u.u32); - if (rc != 0) - break; - rc = cpack_uint16(s, &u2.u16); - if (rc != 0) - break; - rc = cpack_uint8(s, &u3.u8); - if (rc != 0) - break; - rc = cpack_uint8(s, &u4.u8); - break; - case IEEE80211_RADIOTAP_MCS: - rc = cpack_uint8(s, &u.u8); - if (rc != 0) - break; - rc = cpack_uint8(s, &u2.u8); +/*- + * Copyright (c) 2003, 2004 David Young. 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. The name of David Young may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``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 DAVID + * YOUNG 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. + */ + +/* A generic radio capture format is desirable. It must be + * rigidly defined (e.g., units for fields should be given), + * and easily extensible. + * + * The following is an extensible radio capture format. It is + * based on a bitmap indicating which fields are present. + * + * I am trying to describe precisely what the application programmer + * should expect in the following, and for that reason I tell the + * units and origin of each measurement (where it applies), or else I + * use sufficiently weaselly language ("is a monotonically nondecreasing + * function of...") that I cannot set false expectations for lawyerly + * readers. + */ + +/* + * The radio capture header precedes the 802.11 header. + * + * Note well: all radiotap fields are little-endian. + */ +struct ieee80211_radiotap_header { + 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 + * header in bytes, including + * it_version, it_pad, + * it_len, and data fields. + */ + uint32_t it_present; /* A bitmap telling which + * fields are present. Set bit 31 + * (0x80000000) to extend the + * bitmap by another 32 bits. + * Additional extensions are made + * by setting bit 31. + */ +}; + +/* Name Data type Units + * ---- --------- ----- + * + * IEEE80211_RADIOTAP_TSFT uint64_t microseconds + * + * Value in microseconds of the MAC's 64-bit 802.11 Time + * Synchronization Function timer when the first bit of the + * MPDU arrived at the MAC. For received frames, only. + * + * IEEE80211_RADIOTAP_CHANNEL 2 x uint16_t MHz, bitmap + * + * Tx/Rx frequency in MHz, followed by flags (see below). + * Note that IEEE80211_RADIOTAP_XCHANNEL must be used to + * represent an HT channel as there is not enough room in + * the flags word. + * + * IEEE80211_RADIOTAP_FHSS uint16_t see below + * + * For frequency-hopping radios, the hop set (first byte) + * and pattern (second byte). + * + * IEEE80211_RADIOTAP_RATE uint8_t 500kb/s or index + * + * 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) + * + * RF signal power at the antenna, decibel difference from + * one milliwatt. + * + * IEEE80211_RADIOTAP_DBM_ANTNOISE int8_t decibels from + * one milliwatt (dBm) + * + * RF noise power at the antenna, decibel difference from one + * milliwatt. + * + * IEEE80211_RADIOTAP_DB_ANTSIGNAL uint8_t decibel (dB) + * + * RF signal power at the antenna, decibel difference from an + * arbitrary, fixed reference. + * + * IEEE80211_RADIOTAP_DB_ANTNOISE uint8_t decibel (dB) + * + * RF noise power at the antenna, decibel difference from an + * arbitrary, fixed reference point. + * + * IEEE80211_RADIOTAP_LOCK_QUALITY uint16_t unitless + * + * Quality of Barker code lock. Unitless. Monotonically + * nondecreasing with "better" lock strength. Called "Signal + * Quality" in datasheets. (Is there a standard way to measure + * this?) + * + * IEEE80211_RADIOTAP_TX_ATTENUATION uint16_t unitless + * + * Transmit power expressed as unitless distance from max + * power set at factory calibration. 0 is max power. + * Monotonically nondecreasing with lower power levels. + * + * IEEE80211_RADIOTAP_DB_TX_ATTENUATION uint16_t decibels (dB) + * + * Transmit power expressed as decibel distance from max power + * 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) + * + * Transmit power expressed as dBm (decibels from a 1 milliwatt + * reference). This is the absolute power level measured at + * the antenna port. + * + * IEEE80211_RADIOTAP_FLAGS uint8_t bitmap + * + * Properties of transmitted and received frames. See flags + * defined below. + * + * IEEE80211_RADIOTAP_ANTENNA uint8_t antenna index + * + * Unitless indication of the Rx/Tx antenna for this packet. + * The first antenna is antenna 0. + * + * IEEE80211_RADIOTAP_RX_FLAGS uint16_t bitmap + * + * 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 + * + * Extended channel specification: flags (see below) followed by + * frequency in MHz, the corresponding IEEE channel number, and + * finally the maximum regulatory transmit power cap in .5 dBm + * units. This property supersedes IEEE80211_RADIOTAP_CHANNEL + * and only one of the two should be present. + * + * IEEE80211_RADIOTAP_MCS 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 + * in IEEE 802.11n. + * + * + * IEEE80211_RADIOTAP_AMPDU_STATUS u32, u16, u8, u8 unitless + * + * Contains the AMPDU information for the subframe. + * + * IEEE80211_RADIOTAP_VHT u16, u8, u8, u8[4], u8, u8, u16 + * + * Contains VHT information about this frame. + * + * IEEE80211_RADIOTAP_VENDOR_NAMESPACE + * uint8_t OUI[3] + * 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 + * Organizationally Unique Identifier (OUI). The fourth byte is a + * vendor-specific "namespace selector." + * + */ +enum ieee80211_radiotap_type { + IEEE80211_RADIOTAP_TSFT = 0, + IEEE80211_RADIOTAP_FLAGS = 1, + IEEE80211_RADIOTAP_RATE = 2, + IEEE80211_RADIOTAP_CHANNEL = 3, + IEEE80211_RADIOTAP_FHSS = 4, + IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5, + IEEE80211_RADIOTAP_DBM_ANTNOISE = 6, + IEEE80211_RADIOTAP_LOCK_QUALITY = 7, + IEEE80211_RADIOTAP_TX_ATTENUATION = 8, + IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9, + IEEE80211_RADIOTAP_DBM_TX_POWER = 10, + IEEE80211_RADIOTAP_ANTENNA = 11, + IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12, + IEEE80211_RADIOTAP_DB_ANTNOISE = 13, + IEEE80211_RADIOTAP_RX_FLAGS = 14, + /* NB: gap for netbsd definitions */ + IEEE80211_RADIOTAP_XCHANNEL = 18, + IEEE80211_RADIOTAP_MCS = 19, + IEEE80211_RADIOTAP_AMPDU_STATUS = 20, + IEEE80211_RADIOTAP_VHT = 21, + IEEE80211_RADIOTAP_NAMESPACE = 29, + IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30, + IEEE80211_RADIOTAP_EXT = 31 +}; + +/* channel attributes */ +#define IEEE80211_CHAN_TURBO 0x00010 /* Turbo channel */ +#define IEEE80211_CHAN_CCK 0x00020 /* CCK channel */ +#define IEEE80211_CHAN_OFDM 0x00040 /* OFDM channel */ +#define IEEE80211_CHAN_2GHZ 0x00080 /* 2 GHz spectrum channel. */ +#define IEEE80211_CHAN_5GHZ 0x00100 /* 5 GHz spectrum channel */ +#define IEEE80211_CHAN_PASSIVE 0x00200 /* Only passive scan allowed */ +#define IEEE80211_CHAN_DYN 0x00400 /* Dynamic CCK-OFDM channel */ +#define IEEE80211_CHAN_GFSK 0x00800 /* GFSK channel (FHSS PHY) */ +#define IEEE80211_CHAN_GSM 0x01000 /* 900 MHz spectrum channel */ +#define IEEE80211_CHAN_STURBO 0x02000 /* 11a static turbo channel only */ +#define IEEE80211_CHAN_HALF 0x04000 /* Half rate channel */ +#define IEEE80211_CHAN_QUARTER 0x08000 /* Quarter rate channel */ +#define IEEE80211_CHAN_HT20 0x10000 /* HT 20 channel */ +#define IEEE80211_CHAN_HT40U 0x20000 /* HT 40 channel w/ ext above */ +#define IEEE80211_CHAN_HT40D 0x40000 /* HT 40 channel w/ ext below */ + +/* Useful combinations of channel characteristics, borrowed from Ethereal */ +#define IEEE80211_CHAN_A \ + (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM) +#define IEEE80211_CHAN_B \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK) +#define IEEE80211_CHAN_G \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN) +#define IEEE80211_CHAN_TA \ + (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO) +#define IEEE80211_CHAN_TG \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN | IEEE80211_CHAN_TURBO) + + +/* For IEEE80211_RADIOTAP_FLAGS */ +#define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received + * during CFP + */ +#define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received + * with short + * preamble + */ +#define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received + * with WEP encryption + */ +#define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received + * with fragmentation + */ +#define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FCS */ +#define IEEE80211_RADIOTAP_F_DATAPAD 0x20 /* frame has padding between + * 802.11 header and payload + * (to 32-bit boundary) + */ +#define IEEE80211_RADIOTAP_F_BADFCS 0x40 /* does not pass FCS check */ + +/* For IEEE80211_RADIOTAP_RX_FLAGS */ +#define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001 /* frame failed crc check */ +#define IEEE80211_RADIOTAP_F_RX_PLCP_CRC 0x0002 /* frame failed PLCP CRC check */ + +/* For IEEE80211_RADIOTAP_MCS known */ +#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN 0x01 +#define IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN 0x02 /* MCS index field */ +#define IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN 0x04 +#define IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN 0x08 +#define IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN 0x10 +#define IEEE80211_RADIOTAP_MCS_STBC_KNOWN 0x20 +#define IEEE80211_RADIOTAP_MCS_NESS_KNOWN 0x40 +#define IEEE80211_RADIOTAP_MCS_NESS_BIT_1 0x80 + +/* For IEEE80211_RADIOTAP_MCS flags */ +#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK 0x03 +#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20 0 +#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_40 1 +#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20L 2 +#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20U 3 +#define IEEE80211_RADIOTAP_MCS_SHORT_GI 0x04 /* short guard interval */ +#define IEEE80211_RADIOTAP_MCS_HT_GREENFIELD 0x08 +#define IEEE80211_RADIOTAP_MCS_FEC_LDPC 0x10 +#define IEEE80211_RADIOTAP_MCS_STBC_MASK 0x60 +#define IEEE80211_RADIOTAP_MCS_STBC_1 1 +#define IEEE80211_RADIOTAP_MCS_STBC_2 2 +#define IEEE80211_RADIOTAP_MCS_STBC_3 3 +#define IEEE80211_RADIOTAP_MCS_STBC_SHIFT 5 +#define IEEE80211_RADIOTAP_MCS_NESS_BIT_0 0x80 + +/* For IEEE80211_RADIOTAP_AMPDU_STATUS */ +#define IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN 0x0001 +#define IEEE80211_RADIOTAP_AMPDU_IS_ZEROLEN 0x0002 +#define IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN 0x0004 +#define IEEE80211_RADIOTAP_AMPDU_IS_LAST 0x0008 +#define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR 0x0010 +#define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN 0x0020 + +/* For IEEE80211_RADIOTAP_VHT known */ +#define IEEE80211_RADIOTAP_VHT_STBC_KNOWN 0x0001 +#define IEEE80211_RADIOTAP_VHT_TXOP_PS_NA_KNOWN 0x0002 +#define IEEE80211_RADIOTAP_VHT_GUARD_INTERVAL_KNOWN 0x0004 +#define IEEE80211_RADIOTAP_VHT_SGI_NSYM_DIS_KNOWN 0x0008 +#define IEEE80211_RADIOTAP_VHT_LDPC_EXTRA_OFDM_SYM_KNOWN 0x0010 +#define IEEE80211_RADIOTAP_VHT_BEAMFORMED_KNOWN 0x0020 +#define IEEE80211_RADIOTAP_VHT_BANDWIDTH_KNOWN 0x0040 +#define IEEE80211_RADIOTAP_VHT_GROUP_ID_KNOWN 0x0080 +#define IEEE80211_RADIOTAP_VHT_PARTIAL_AID_KNOWN 0x0100 + +/* For IEEE80211_RADIOTAP_VHT flags */ +#define IEEE80211_RADIOTAP_VHT_STBC 0x01 +#define IEEE80211_RADIOTAP_VHT_TXOP_PS_NA 0x02 +#define IEEE80211_RADIOTAP_VHT_SHORT_GI 0x04 +#define IEEE80211_RADIOTAP_VHT_SGI_NSYM_M10_9 0x08 +#define IEEE80211_RADIOTAP_VHT_LDPC_EXTRA_OFDM_SYM 0x10 +#define IEEE80211_RADIOTAP_VHT_BEAMFORMED 0x20 + +#define IEEE80211_RADIOTAP_VHT_BANDWIDTH_MASK 0x1f + +#define IEEE80211_RADIOTAP_VHT_NSS_MASK 0x0f +#define IEEE80211_RADIOTAP_VHT_MCS_MASK 0xf0 +#define IEEE80211_RADIOTAP_VHT_MCS_SHIFT 4 + +#define IEEE80211_RADIOTAP_CODING_LDPC_USERn 0x01 + +#define IEEE80211_CHAN_FHSS \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK) +#define IEEE80211_CHAN_A \ + (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM) +#define IEEE80211_CHAN_B \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK) +#define IEEE80211_CHAN_PUREG \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM) +#define IEEE80211_CHAN_G \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN) + +#define IS_CHAN_FHSS(flags) \ + ((flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS) +#define IS_CHAN_A(flags) \ + ((flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A) +#define IS_CHAN_B(flags) \ + ((flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B) +#define IS_CHAN_PUREG(flags) \ + ((flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG) +#define IS_CHAN_G(flags) \ + ((flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G) +#define IS_CHAN_ANYG(flags) \ + (IS_CHAN_PUREG(flags) || IS_CHAN_G(flags)) + +static void +print_chaninfo(netdissect_options *ndo, + uint16_t freq, int flags, int presentflags) +{ + ND_PRINT((ndo, "%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")); + } else { + if (IS_CHAN_FHSS(flags)) + ND_PRINT((ndo, " FHSS")); + if (IS_CHAN_A(flags)) { + if (flags & IEEE80211_CHAN_HALF) + ND_PRINT((ndo, " 11a/10Mhz")); + else if (flags & IEEE80211_CHAN_QUARTER) + ND_PRINT((ndo, " 11a/5Mhz")); + else + ND_PRINT((ndo, " 11a")); + } + if (IS_CHAN_ANYG(flags)) { + if (flags & IEEE80211_CHAN_HALF) + ND_PRINT((ndo, " 11g/10Mhz")); + else if (flags & IEEE80211_CHAN_QUARTER) + ND_PRINT((ndo, " 11g/5Mhz")); + else + ND_PRINT((ndo, " 11g")); + } else if (IS_CHAN_B(flags)) + ND_PRINT((ndo, " 11b")); + if (flags & IEEE80211_CHAN_TURBO) + ND_PRINT((ndo, " Turbo")); + } + /* + * These apply to 11n. + */ + if (flags & IEEE80211_CHAN_HT20) + ND_PRINT((ndo, " ht/20")); + else if (flags & IEEE80211_CHAN_HT40D) + ND_PRINT((ndo, " ht/40-")); + else if (flags & IEEE80211_CHAN_HT40U) + ND_PRINT((ndo, " ht/40+")); + ND_PRINT((ndo, " ")); +} + +static int +print_radiotap_field(netdissect_options *ndo, + struct cpack_state *s, uint32_t bit, uint8_t *flagsp, + uint32_t presentflags) +{ + u_int i; + int rc; + + switch (bit) { + + case IEEE80211_RADIOTAP_TSFT: { + uint64_t tsft; + + rc = cpack_uint64(s, &tsft); if (rc != 0) - break; - rc = cpack_uint8(s, &u3.u8); + goto trunc; + ND_PRINT((ndo, "%" PRIu64 "us tsft ", tsft)); break; - case IEEE80211_RADIOTAP_VENDOR_NAMESPACE: { - uint8_t vns[3]; - uint16_t length; - uint8_t subspace; - - if ((cpack_align_and_reserve(s, 2)) == NULL) { - rc = -1; - break; } - rc = cpack_uint8(s, &vns[0]); - if (rc != 0) - break; - rc = cpack_uint8(s, &vns[1]); - if (rc != 0) - break; - rc = cpack_uint8(s, &vns[2]); - if (rc != 0) - break; - rc = cpack_uint8(s, &subspace); - if (rc != 0) - break; - rc = cpack_uint16(s, &length); - if (rc != 0) - break; + case IEEE80211_RADIOTAP_FLAGS: { + uint8_t flagsval; - /* Skip up to length */ - s->c_next += length; + rc = cpack_uint8(s, &flagsval); + if (rc != 0) + goto trunc; + *flagsp = flagsval; + if (flagsval & IEEE80211_RADIOTAP_F_CFP) + ND_PRINT((ndo, "cfp ")); + if (flagsval & IEEE80211_RADIOTAP_F_SHORTPRE) + ND_PRINT((ndo, "short preamble ")); + if (flagsval & IEEE80211_RADIOTAP_F_WEP) + ND_PRINT((ndo, "wep ")); + if (flagsval & IEEE80211_RADIOTAP_F_FRAG) + ND_PRINT((ndo, "fragmented ")); + if (flagsval & IEEE80211_RADIOTAP_F_BADFCS) + ND_PRINT((ndo, "bad-fcs ")); break; - } - default: - /* this bit indicates a field whose - * size we do not know, so we cannot - * proceed. Just print the bit number. - */ - ND_PRINT((ndo, "[bit %u] ", bit)); - return -1; - } - - if (rc != 0) { - ND_PRINT((ndo, "%s", tstr)); - return rc; - } + } - /* Preserve the state present flags */ - state->present = presentflags; + case IEEE80211_RADIOTAP_RATE: { + uint8_t rate; - switch (bit) { - case IEEE80211_RADIOTAP_CHANNEL: - /* - * If CHANNEL and XCHANNEL are both present, skip - * CHANNEL. - */ - if (presentflags & (1 << IEEE80211_RADIOTAP_XCHANNEL)) - break; - print_chaninfo(ndo, u.u16, u2.u16); - break; - case IEEE80211_RADIOTAP_FHSS: - ND_PRINT((ndo, "fhset %d fhpat %d ", u.u16 & 0xff, (u.u16 >> 8) & 0xff)); - break; - case IEEE80211_RADIOTAP_RATE: + rc = cpack_uint8(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 @@ -2660,7 +2633,7 @@ print_radiotap_field(netdissect_options *ndo, * setting. Such rates do exist, e.g. 11n * MCS 7 at 20 MHz with a long guard interval. */ - if (u.u8 >= 0x80 && u.u8 <= 0x8f) { + if (rate >= 0x80 && rate <= 0x8f) { /* * XXX - we don't know the channel width * or guard interval length, so we can't @@ -2677,60 +2650,173 @@ print_radiotap_field(netdissect_options *ndo, * information from Flags, at least on * FreeBSD? */ - ND_PRINT((ndo, "MCS %u ", u.u8 & 0x7f)); + ND_PRINT((ndo, "MCS %u ", rate & 0x7f)); } else - ND_PRINT((ndo, "%2.1f Mb/s ", .5 * u.u8)); + ND_PRINT((ndo, "%2.1f Mb/s ", .5 * rate)); break; - case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: - ND_PRINT((ndo, "%ddB signal ", u.i8)); + } + + case IEEE80211_RADIOTAP_CHANNEL: { + uint16_t frequency; + uint16_t flags; + + rc = cpack_uint16(s, &frequency); + if (rc != 0) + goto trunc; + rc = cpack_uint16(s, &flags); + if (rc != 0) + goto trunc; + /* + * If CHANNEL and XCHANNEL are both present, skip + * CHANNEL. + */ + if (presentflags & (1 << IEEE80211_RADIOTAP_XCHANNEL)) + break; + print_chaninfo(ndo, frequency, flags, presentflags); break; - case IEEE80211_RADIOTAP_DBM_ANTNOISE: - ND_PRINT((ndo, "%ddB noise ", u.i8)); + } + + case IEEE80211_RADIOTAP_FHSS: { + uint8_t hopset; + uint8_t hoppat; + + rc = cpack_uint8(s, &hopset); + if (rc != 0) + goto trunc; + rc = cpack_uint8(s, &hoppat); + if (rc != 0) + goto trunc; + ND_PRINT((ndo, "fhset %d fhpat %d ", hopset, hoppat)); break; - case IEEE80211_RADIOTAP_DB_ANTSIGNAL: - ND_PRINT((ndo, "%ddB signal ", u.u8)); + } + + case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: { + int8_t dbm_antsignal; + + rc = cpack_int8(s, &dbm_antsignal); + if (rc != 0) + goto trunc; + ND_PRINT((ndo, "%ddBm signal ", dbm_antsignal)); break; - case IEEE80211_RADIOTAP_DB_ANTNOISE: - ND_PRINT((ndo, "%ddB noise ", u.u8)); + } + + case IEEE80211_RADIOTAP_DBM_ANTNOISE: { + int8_t dbm_antnoise; + + rc = cpack_int8(s, &dbm_antnoise); + if (rc != 0) + goto trunc; + ND_PRINT((ndo, "%ddBm noise ", dbm_antnoise)); break; - case IEEE80211_RADIOTAP_LOCK_QUALITY: - ND_PRINT((ndo, "%u sq ", u.u16)); + } + + case IEEE80211_RADIOTAP_LOCK_QUALITY: { + uint16_t lock_quality; + + rc = cpack_uint16(s, &lock_quality); + if (rc != 0) + goto trunc; + ND_PRINT((ndo, "%u sq ", lock_quality)); break; - case IEEE80211_RADIOTAP_TX_ATTENUATION: - ND_PRINT((ndo, "%d tx power ", -(int)u.u16)); + } + + case IEEE80211_RADIOTAP_TX_ATTENUATION: { + uint16_t tx_attenuation; + + rc = cpack_uint16(s, &tx_attenuation); + if (rc != 0) + goto trunc; + ND_PRINT((ndo, "%d tx power ", -(int)tx_attenuation)); break; - case IEEE80211_RADIOTAP_DB_TX_ATTENUATION: - ND_PRINT((ndo, "%ddB tx power ", -(int)u.u8)); + } + + case IEEE80211_RADIOTAP_DB_TX_ATTENUATION: { + uint8_t db_tx_attenuation; + + rc = cpack_uint8(s, &db_tx_attenuation); + if (rc != 0) + goto trunc; + ND_PRINT((ndo, "%ddB tx attenuation ", -(int)db_tx_attenuation)); break; - case IEEE80211_RADIOTAP_DBM_TX_POWER: - ND_PRINT((ndo, "%ddBm tx power ", u.i8)); + } + + case IEEE80211_RADIOTAP_DBM_TX_POWER: { + int8_t dbm_tx_power; + + rc = cpack_int8(s, &dbm_tx_power); + if (rc != 0) + goto trunc; + ND_PRINT((ndo, "%ddBm tx power ", dbm_tx_power)); break; - case IEEE80211_RADIOTAP_FLAGS: - if (u.u8 & IEEE80211_RADIOTAP_F_CFP) - ND_PRINT((ndo, "cfp ")); - if (u.u8 & IEEE80211_RADIOTAP_F_SHORTPRE) - ND_PRINT((ndo, "short preamble ")); - if (u.u8 & IEEE80211_RADIOTAP_F_WEP) - ND_PRINT((ndo, "wep ")); - if (u.u8 & IEEE80211_RADIOTAP_F_FRAG) - ND_PRINT((ndo, "fragmented ")); - if (u.u8 & IEEE80211_RADIOTAP_F_BADFCS) - ND_PRINT((ndo, "bad-fcs ")); + } + + case IEEE80211_RADIOTAP_ANTENNA: { + uint8_t antenna; + + rc = cpack_uint8(s, &antenna); + if (rc != 0) + goto trunc; + ND_PRINT((ndo, "antenna %u ", antenna)); break; - case IEEE80211_RADIOTAP_ANTENNA: - ND_PRINT((ndo, "antenna %d ", u.u8)); + } + + case IEEE80211_RADIOTAP_DB_ANTSIGNAL: { + uint8_t db_antsignal; + + rc = cpack_uint8(s, &db_antsignal); + if (rc != 0) + goto trunc; + ND_PRINT((ndo, "%ddB signal ", db_antsignal)); break; - case IEEE80211_RADIOTAP_TSFT: - ND_PRINT((ndo, "%" PRIu64 "us tsft ", u.u64)); + } + + case IEEE80211_RADIOTAP_DB_ANTNOISE: { + uint8_t db_antnoise; + + rc = cpack_uint8(s, &db_antnoise); + if (rc != 0) + goto trunc; + ND_PRINT((ndo, "%ddB noise ", db_antnoise)); break; - case IEEE80211_RADIOTAP_RX_FLAGS: + } + + case IEEE80211_RADIOTAP_RX_FLAGS: { + uint16_t rx_flags; + + rc = cpack_uint16(s, &rx_flags); + if (rc != 0) + goto trunc; /* Do nothing for now */ break; - case IEEE80211_RADIOTAP_XCHANNEL: - print_chaninfo(ndo, u2.u16, u.u32); + } + + case IEEE80211_RADIOTAP_XCHANNEL: { + uint32_t flags; + uint16_t frequency; + uint8_t channel; + uint8_t maxpower; + + rc = cpack_uint32(s, &flags); + if (rc != 0) + goto trunc; + rc = cpack_uint16(s, &frequency); + if (rc != 0) + goto trunc; + rc = cpack_uint8(s, &channel); + if (rc != 0) + goto trunc; + rc = cpack_uint8(s, &maxpower); + if (rc != 0) + goto trunc; + print_chaninfo(ndo, frequency, flags, presentflags); break; + } + case IEEE80211_RADIOTAP_MCS: { - static const char *bandwidth[4] = { + uint8_t known; + uint8_t flags; + uint8_t mcs_index; + static const char *ht_bandwidth[4] = { "20 MHz", "40 MHz", "20 MHz (L)", @@ -2738,15 +2824,24 @@ print_radiotap_field(netdissect_options *ndo, }; float htrate; - if (u.u8 & IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN) { + rc = cpack_uint8(s, &known); + if (rc != 0) + goto trunc; + rc = cpack_uint8(s, &flags); + if (rc != 0) + goto trunc; + rc = cpack_uint8(s, &mcs_index); + if (rc != 0) + goto trunc; + if (known & IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN) { /* * We know the MCS index. */ - if (u3.u8 <= MAX_MCS_INDEX) { + if (mcs_index <= MAX_MCS_INDEX) { /* * And it's in-range. */ - if (u.u8 & (IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN|IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN)) { + if (known & (IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN|IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN)) { /* * And we know both the bandwidth and * the guard interval, so we can look @@ -2754,9 +2849,9 @@ print_radiotap_field(netdissect_options *ndo, */ htrate = ieee80211_float_htrates \ - [u3.u8] \ - [((u2.u8 & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK) == IEEE80211_RADIOTAP_MCS_BANDWIDTH_40 ? 1 : 0)] \ - [((u2.u8 & IEEE80211_RADIOTAP_MCS_SHORT_GI) ? 1 : 0)]; + [mcs_index] \ + [((flags & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK) == IEEE80211_RADIOTAP_MCS_BANDWIDTH_40 ? 1 : 0)] \ + [((flags & IEEE80211_RADIOTAP_MCS_SHORT_GI) ? 1 : 0)]; } else { /* * We don't know both the bandwidth @@ -2776,126 +2871,398 @@ print_radiotap_field(netdissect_options *ndo, * We have the rate. * Print it. */ - ND_PRINT((ndo, "%.1f Mb/s MCS %u ", htrate, u3.u8)); + ND_PRINT((ndo, "%.1f Mb/s MCS %u ", htrate, mcs_index)); } else { /* * We at least have the MCS index. * Print it. */ - ND_PRINT((ndo, "MCS %u ", u3.u8)); + ND_PRINT((ndo, "MCS %u ", mcs_index)); } } - if (u.u8 & IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN) { + if (known & IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN) { ND_PRINT((ndo, "%s ", - bandwidth[u2.u8 & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK])); + ht_bandwidth[flags & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK])); } - if (u.u8 & IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN) { + if (known & IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN) { ND_PRINT((ndo, "%s GI ", - (u2.u8 & IEEE80211_RADIOTAP_MCS_SHORT_GI) ? - "short" : "lon")); + (flags & IEEE80211_RADIOTAP_MCS_SHORT_GI) ? + "short" : "long")); } - if (u.u8 & IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN) { + if (known & IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN) { ND_PRINT((ndo, "%s ", - (u2.u8 & IEEE80211_RADIOTAP_MCS_HT_GREENFIELD) ? + (flags & IEEE80211_RADIOTAP_MCS_HT_GREENFIELD) ? "greenfield" : "mixed")); } - if (u.u8 & IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN) { + if (known & IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN) { ND_PRINT((ndo, "%s FEC ", - (u2.u8 & IEEE80211_RADIOTAP_MCS_FEC_LDPC) ? + (flags & IEEE80211_RADIOTAP_MCS_FEC_LDPC) ? "LDPC" : "BCC")); } - if (u.u8 & IEEE80211_RADIOTAP_MCS_STBC_KNOWN) { + if (known & IEEE80211_RADIOTAP_MCS_STBC_KNOWN) { ND_PRINT((ndo, "RX-STBC%u ", - (u2.u8 & IEEE80211_RADIOTAP_MCS_STBC_MASK) >> IEEE80211_RADIOTAP_MCS_STBC_SHIFT)); + (flags & IEEE80211_RADIOTAP_MCS_STBC_MASK) >> IEEE80211_RADIOTAP_MCS_STBC_SHIFT)); + } + break; + } + + case IEEE80211_RADIOTAP_AMPDU_STATUS: { + uint32_t reference_num; + uint16_t flags; + uint8_t delim_crc; + uint8_t reserved; + + rc = cpack_uint32(s, &reference_num); + if (rc != 0) + goto trunc; + rc = cpack_uint16(s, &flags); + if (rc != 0) + goto trunc; + rc = cpack_uint8(s, &delim_crc); + if (rc != 0) + goto trunc; + rc = cpack_uint8(s, &reserved); + if (rc != 0) + goto trunc; + /* Do nothing for now */ + break; + } + + case IEEE80211_RADIOTAP_VHT: { + uint16_t known; + uint8_t flags; + uint8_t bandwidth; + uint8_t mcs_nss[4]; + uint8_t coding; + uint8_t group_id; + uint16_t partial_aid; + static const char *vht_bandwidth[32] = { + "20 MHz", + "40 MHz", + "20 MHz (L)", + "20 MHz (U)", + "80 MHz", + "80 MHz (L)", + "80 MHz (U)", + "80 MHz (LL)", + "80 MHz (LU)", + "80 MHz (UL)", + "80 MHz (UU)", + "160 MHz", + "160 MHz (L)", + "160 MHz (U)", + "160 MHz (LL)", + "160 MHz (LU)", + "160 MHz (UL)", + "160 MHz (UU)", + "160 MHz (LLL)", + "160 MHz (LLU)", + "160 MHz (LUL)", + "160 MHz (UUU)", + "160 MHz (ULL)", + "160 MHz (ULU)", + "160 MHz (UUL)", + "160 MHz (UUU)", + "unknown (26)", + "unknown (27)", + "unknown (28)", + "unknown (29)", + "unknown (30)", + "unknown (31)" + }; + + rc = cpack_uint16(s, &known); + if (rc != 0) + goto trunc; + rc = cpack_uint8(s, &flags); + if (rc != 0) + goto trunc; + rc = cpack_uint8(s, &bandwidth); + if (rc != 0) + goto trunc; + for (i = 0; i < 4; i++) { + rc = cpack_uint8(s, &mcs_nss[i]); + if (rc != 0) + goto trunc; } + rc = cpack_uint8(s, &coding); + if (rc != 0) + goto trunc; + rc = cpack_uint8(s, &group_id); + if (rc != 0) + goto trunc; + rc = cpack_uint16(s, &partial_aid); + if (rc != 0) + goto trunc; + for (i = 0; i < 4; i++) { + u_int nss, mcs; + nss = mcs_nss[i] & IEEE80211_RADIOTAP_VHT_NSS_MASK; + mcs = (mcs_nss[i] & IEEE80211_RADIOTAP_VHT_MCS_MASK) >> IEEE80211_RADIOTAP_VHT_MCS_SHIFT; + if (nss == 0) + continue; + + ND_PRINT((ndo, "User %u MCS %u ", i, mcs)); + ND_PRINT((ndo, "%s FEC ", + (coding & (IEEE80211_RADIOTAP_CODING_LDPC_USERn << i)) ? + "LDPC" : "BCC")); + } + if (known & IEEE80211_RADIOTAP_VHT_BANDWIDTH_KNOWN) { + ND_PRINT((ndo, "%s ", + vht_bandwidth[bandwidth & IEEE80211_RADIOTAP_VHT_BANDWIDTH_MASK])); + } + if (known & IEEE80211_RADIOTAP_VHT_GUARD_INTERVAL_KNOWN) { + ND_PRINT((ndo, "%s GI ", + (flags & IEEE80211_RADIOTAP_VHT_SHORT_GI) ? + "short" : "long")); + } break; } + + default: + /* this bit indicates a field whose + * size we do not know, so we cannot + * proceed. Just print the bit number. + */ + ND_PRINT((ndo, "[bit %u] ", bit)); + return -1; } + return 0; + +trunc: + ND_PRINT((ndo, "%s", tstr)); + return rc; } -static u_int -ieee802_11_radio_print(netdissect_options *ndo, - const u_char *p, u_int length, u_int caplen) + +static int +print_in_radiotap_namespace(netdissect_options *ndo, + 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))) #define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x))) #define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x))) #define BITNO_2(x) (((x) & 2) ? 1 : 0) + uint32_t present, next_present; + int bitno; + enum ieee80211_radiotap_type bit; + int rc; + + for (present = presentflags; present; present = next_present) { + /* + * Clear the least significant bit that is set. + */ + next_present = present & (present - 1); + + /* + * Get the bit number, within this presence word, + * of the remaining least significant bit that + * is set. + */ + bitno = BITNO_32(present ^ next_present); + + /* + * Stop if this is one of the "same meaning + * in all presence flags" bits. + */ + if (bitno >= IEEE80211_RADIOTAP_NAMESPACE) + break; + + /* + * Get the radiotap bit number of that bit. + */ + bit = (enum ieee80211_radiotap_type)(bit0 + bitno); + + rc = print_radiotap_field(ndo, s, bit, flags, presentflags); + if (rc != 0) + return rc; + } + + return 0; +} + +static u_int +ieee802_11_radio_print(netdissect_options *ndo, + 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 struct cpack_state cpacker; - struct ieee80211_radiotap_header *hdr; - uint32_t present, next_present; - uint32_t presentflags = 0; - uint32_t *presentp, *last_presentp; - enum ieee80211_radiotap_type bit; + const struct ieee80211_radiotap_header *hdr; + uint32_t presentflags; + const uint32_t *presentp, *last_presentp; + int vendor_namespace; + uint8_t vendor_oui[3]; + uint8_t vendor_subnamespace; + uint16_t skip_length; int bit0; u_int len; uint8_t flags; int pad; u_int fcslen; - struct radiotap_state state; if (caplen < sizeof(*hdr)) { ND_PRINT((ndo, "%s", tstr)); return caplen; } - hdr = (struct ieee80211_radiotap_header *)p; + hdr = (const struct ieee80211_radiotap_header *)p; len = EXTRACT_LE_16BITS(&hdr->it_len); + /* + * If we don't have the entire radiotap header, just give up. + */ if (caplen < len) { ND_PRINT((ndo, "%s", tstr)); return caplen; } - cpack_init(&cpacker, (uint8_t *)hdr, len); /* align against header start */ + cpack_init(&cpacker, (const uint8_t *)hdr, len); /* align against header start */ cpack_advance(&cpacker, sizeof(*hdr)); /* includes the 1st bitmap */ for (last_presentp = &hdr->it_present; - IS_EXTENDED(last_presentp) && - (u_char*)(last_presentp + 1) <= p + len; + (const u_char*)(last_presentp + 1) <= p + len && + IS_EXTENDED(last_presentp); last_presentp++) cpack_advance(&cpacker, sizeof(hdr->it_present)); /* more bitmaps */ /* are there more bitmap extensions than bytes in header? */ - if (IS_EXTENDED(last_presentp)) { + if ((const u_char*)(last_presentp + 1) > p + len) { ND_PRINT((ndo, "%s", tstr)); return caplen; } + /* + * Start out at the beginning of the default radiotap namespace. + */ + bit0 = 0; + vendor_namespace = 0; + memset(vendor_oui, 0, 3); + vendor_subnamespace = 0; + skip_length = 0; /* Assume no flags */ flags = 0; /* Assume no Atheros padding between 802.11 header and body */ pad = 0; /* Assume no FCS at end of frame */ fcslen = 0; - for (bit0 = 0, presentp = &hdr->it_present; presentp <= last_presentp; - presentp++, bit0 += 32) { + for (presentp = &hdr->it_present; presentp <= last_presentp; + presentp++) { presentflags = EXTRACT_LE_32BITS(presentp); - /* Clear state. */ - memset(&state, 0, sizeof(state)); + /* + * If this is a vendor namespace, we don't handle it. + */ + if (vendor_namespace) { + /* + * Skip past the stuff we don't understand. + * If we add support for any vendor namespaces, + * it'd be added here; use vendor_oui and + * vendor_subnamespace to interpret the fields. + */ + if (cpack_advance(&cpacker, skip_length) != 0) { + /* + * Ran out of space in the packet. + */ + break; + } + + /* + * We've skipped it all; nothing more to + * skip. + */ + skip_length = 0; + } else { + if (print_in_radiotap_namespace(ndo, &cpacker, + &flags, presentflags, bit0) != 0) { + /* + * Fatal error - can't process anything + * more in the radiotap header. + */ + break; + } + } + + /* + * Handle the namespace switch bits; we've already handled + * the extension bit in all but the last word above. + */ + switch (presentflags & + (BIT(IEEE80211_RADIOTAP_NAMESPACE)|BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE))) { + + case 0: + /* + * We're not changing namespaces. + * advance to the next 32 bits in the current + * namespace. + */ + bit0 += 32; + break; - for (present = EXTRACT_LE_32BITS(presentp); present; - present = next_present) { - /* clear the least significant bit that is set */ - next_present = present & (present - 1); + case BIT(IEEE80211_RADIOTAP_NAMESPACE): + /* + * We're switching to the radiotap namespace. + * Reset the presence-bitmap index to 0, and + * reset the namespace to the default radiotap + * namespace. + */ + bit0 = 0; + vendor_namespace = 0; + memset(vendor_oui, 0, 3); + vendor_subnamespace = 0; + skip_length = 0; + break; - /* extract the least significant bit that is set */ - bit = (enum ieee80211_radiotap_type) - (bit0 + BITNO_32(present ^ next_present)); + case BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE): + /* + * We're switching to a vendor namespace. + * Reset the presence-bitmap index to 0, + * note that we're in a vendor namespace, + * and fetch the fields of the Vendor Namespace + * item. + */ + bit0 = 0; + vendor_namespace = 1; + if ((cpack_align_and_reserve(&cpacker, 2)) == NULL) { + ND_PRINT((ndo, "%s", tstr)); + break; + } + if (cpack_uint8(&cpacker, &vendor_oui[0]) != 0) { + ND_PRINT((ndo, "%s", tstr)); + break; + } + if (cpack_uint8(&cpacker, &vendor_oui[1]) != 0) { + ND_PRINT((ndo, "%s", tstr)); + break; + } + if (cpack_uint8(&cpacker, &vendor_oui[2]) != 0) { + ND_PRINT((ndo, "%s", tstr)); + break; + } + if (cpack_uint8(&cpacker, &vendor_subnamespace) != 0) { + ND_PRINT((ndo, "%s", tstr)); + break; + } + if (cpack_uint16(&cpacker, &skip_length) != 0) { + ND_PRINT((ndo, "%s", tstr)); + break; + } + break; - if (print_radiotap_field(ndo, &cpacker, bit, &flags, &state, presentflags) != 0) - goto out; + default: + /* + * Illegal combination. The behavior in this + * case is undefined by the radiotap spec; we + * just ignore both bits. + */ + break; } } -out: if (flags & IEEE80211_RADIOTAP_F_DATAPAD) pad = 1; /* Atheros padding */ if (flags & IEEE80211_RADIOTAP_F_FCS) diff --git a/contrib/tcpdump/print-802_15_4.c b/contrib/tcpdump/print-802_15_4.c index 26c28ee..6fe6d35 100644 --- a/contrib/tcpdump/print-802_15_4.c +++ b/contrib/tcpdump/print-802_15_4.c @@ -20,14 +20,15 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: IEEE 802.15.4 printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" @@ -112,7 +113,7 @@ ieee802_15_4_if_print(netdissect_options *ndo, if (ndo->ndo_vflag) ND_PRINT((ndo,"seq %02x ", seq)); if (hdrlen == -1) { - ND_PRINT((ndo,"malformed! ")); + ND_PRINT((ndo,"invalid! ")); return caplen; } @@ -139,7 +140,7 @@ ieee802_15_4_if_print(netdissect_options *ndo, case 0x03: panid = EXTRACT_LE_16BITS(p); p += 2; - ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(p))); + ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(ndo, p))); p += 8; break; } @@ -165,7 +166,7 @@ ieee802_15_4_if_print(netdissect_options *ndo, panid = EXTRACT_LE_16BITS(p); p += 2; } - ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(p))); + ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(ndo, p))); p += 8; break; } diff --git a/contrib/tcpdump/print-ah.c b/contrib/tcpdump/print-ah.c index 0badf48..bec6f88 100644 --- a/contrib/tcpdump/print-ah.c +++ b/contrib/tcpdump/print-ah.c @@ -21,40 +21,40 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: IPSEC Authentication Header printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include "ah.h" -#include "interface.h" +#include "netdissect.h" #include "extract.h" int ah_print(netdissect_options *ndo, register const u_char *bp) { register const struct ah *ah; - register const u_char *ep; int sumlen; - uint32_t spi; ah = (const struct ah *)bp; - ep = ndo->ndo_snapend; /* 'ep' points to the end of available data. */ ND_TCHECK(*ah); sumlen = ah->ah_len << 2; - spi = EXTRACT_32BITS(&ah->ah_spi); - ND_PRINT((ndo, "AH(spi=0x%08x", spi)); + ND_PRINT((ndo, "AH(spi=0x%08x", EXTRACT_32BITS(&ah->ah_spi))); 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 (bp + sizeof(struct ah) + sumlen > ep) - ND_PRINT((ndo, "[truncated]")); + if (!ND_TTEST2(*bp, sizeof(struct ah) + sumlen)) { + ND_PRINT((ndo, "[truncated]):")); + return -1; + } ND_PRINT((ndo, "): ")); return sizeof(struct ah) + sumlen; diff --git a/contrib/tcpdump/print-ahcp.c b/contrib/tcpdump/print-ahcp.c index a9ae38a..067b506 100644 --- a/contrib/tcpdump/print-ahcp.c +++ b/contrib/tcpdump/print-ahcp.c @@ -1,8 +1,4 @@ /* - * This module implements decoding of AHCP (Ad Hoc Configuration Protocol) based - * on draft-chroboczek-ahcp-00 and source code of ahcpd-0.53. - * - * * Copyright (c) 2013 The TCPDUMP project * All rights reserved. * @@ -29,19 +25,21 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#define NETDISSECT_REWORKED +/* \summary: Ad Hoc Configuration Protocol (AHCP) printer */ + +/* Based on draft-chroboczek-ahcp-00 and source code of ahcpd-0.53 */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "addrtoname.h" static const char tstr[] = " [|ahcp]"; -static const char cstr[] = "(corrupt)"; #define AHCP_MAGIC_NUMBER 43 #define AHCP_VERSION_1 1 @@ -107,7 +105,7 @@ ahcp_time_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) char buf[BUFSIZE]; if (cp + 4 != ep) - goto corrupt; + goto invalid; ND_TCHECK2(*cp, 4); t = EXTRACT_32BITS(cp); if (NULL == (tm = gmtime(&t))) @@ -118,8 +116,8 @@ ahcp_time_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) ND_PRINT((ndo, ": %s UTC", buf)); return 0; -corrupt: - ND_PRINT((ndo, ": %s", cstr)); +invalid: + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp, ep - cp); return 0; trunc: @@ -131,13 +129,13 @@ static int ahcp_seconds_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) { if (cp + 4 != ep) - goto corrupt; + goto invalid; ND_TCHECK2(*cp, 4); ND_PRINT((ndo, ": %us", EXTRACT_32BITS(cp))); return 0; -corrupt: - ND_PRINT((ndo, ": %s", cstr)); +invalid: + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp, ep - cp); return 0; trunc: @@ -152,20 +150,16 @@ ahcp_ipv6_addresses_print(netdissect_options *ndo, const u_char *cp, const u_cha while (cp < ep) { if (cp + 16 > ep) - goto corrupt; + goto invalid; ND_TCHECK2(*cp, 16); -#ifdef INET6 ND_PRINT((ndo, "%s%s", sep, ip6addr_string(ndo, cp))); -#else - ND_PRINT((ndo, "%s(compiled w/o IPv6)", sep)); -#endif /* INET6 */ cp += 16; sep = ", "; } return 0; -corrupt: - ND_PRINT((ndo, ": %s", cstr)); +invalid: + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp, ep - cp); return 0; trunc: @@ -180,7 +174,7 @@ ahcp_ipv4_addresses_print(netdissect_options *ndo, const u_char *cp, const u_cha while (cp < ep) { if (cp + 4 > ep) - goto corrupt; + goto invalid; ND_TCHECK2(*cp, 4); ND_PRINT((ndo, "%s%s", sep, ipaddr_string(ndo, cp))); cp += 4; @@ -188,8 +182,8 @@ ahcp_ipv4_addresses_print(netdissect_options *ndo, const u_char *cp, const u_cha } return 0; -corrupt: - ND_PRINT((ndo, ": %s", cstr)); +invalid: + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp, ep - cp); return 0; trunc: @@ -204,20 +198,16 @@ ahcp_ipv6_prefixes_print(netdissect_options *ndo, const u_char *cp, const u_char while (cp < ep) { if (cp + 17 > ep) - goto corrupt; + goto invalid; ND_TCHECK2(*cp, 17); -#ifdef INET6 ND_PRINT((ndo, "%s%s/%u", sep, ip6addr_string(ndo, cp), *(cp + 16))); -#else - ND_PRINT((ndo, "%s(compiled w/o IPv6)/%u", sep, *(cp + 16))); -#endif /* INET6 */ cp += 17; sep = ", "; } return 0; -corrupt: - ND_PRINT((ndo, ": %s", cstr)); +invalid: + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp, ep - cp); return 0; trunc: @@ -232,7 +222,7 @@ ahcp_ipv4_prefixes_print(netdissect_options *ndo, const u_char *cp, const u_char while (cp < ep) { if (cp + 5 > ep) - goto corrupt; + goto invalid; ND_TCHECK2(*cp, 5); ND_PRINT((ndo, "%s%s/%u", sep, ipaddr_string(ndo, cp), *(cp + 4))); cp += 5; @@ -240,8 +230,8 @@ ahcp_ipv4_prefixes_print(netdissect_options *ndo, const u_char *cp, const u_char } return 0; -corrupt: - ND_PRINT((ndo, ": %s", cstr)); +invalid: + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp, ep - cp); return 0; trunc: @@ -283,12 +273,12 @@ ahcp1_options_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) continue; /* Length */ if (cp + 1 > ep) - goto corrupt; + goto invalid; ND_TCHECK2(*cp, 1); option_len = *cp; cp += 1; if (cp + option_len > ep) - goto corrupt; + 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) @@ -301,8 +291,8 @@ ahcp1_options_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) } return; -corrupt: - ND_PRINT((ndo, " %s", cstr)); +invalid: + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp, ep - cp); return; trunc: @@ -316,7 +306,7 @@ ahcp1_body_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) uint16_t body_len; if (cp + AHCP1_BODY_MIN_LEN > ep) - goto corrupt; + goto invalid; /* Type */ ND_TCHECK2(*cp, 1); type = *cp; @@ -337,7 +327,7 @@ ahcp1_body_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) ND_PRINT((ndo, ", Length %u", body_len)); } if (cp + body_len > ep) - goto corrupt; + goto invalid; /* Options */ if (ndo->ndo_vflag >= 2) @@ -346,8 +336,8 @@ ahcp1_body_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) ND_TCHECK2(*cp, body_len); return; -corrupt: - ND_PRINT((ndo, " %s", cstr)); +invalid: + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp, ep - cp); return; trunc: @@ -362,11 +352,11 @@ ahcp_print(netdissect_options *ndo, const u_char *cp, const u_int len) ND_PRINT((ndo, "AHCP")); if (len < 2) - goto corrupt; + goto invalid; /* Magic */ ND_TCHECK2(*cp, 1); if (*cp != AHCP_MAGIC_NUMBER) - goto corrupt; + goto invalid; cp += 1; /* Version */ ND_TCHECK2(*cp, 1); @@ -376,7 +366,7 @@ ahcp_print(netdissect_options *ndo, const u_char *cp, const u_int len) case AHCP_VERSION_1: { ND_PRINT((ndo, " Version 1")); if (len < AHCP1_HEADER_FIX_LEN) - goto corrupt; + goto invalid; if (!ndo->ndo_vflag) { ND_TCHECK2(*cp, AHCP1_HEADER_FIX_LEN - 2); cp += AHCP1_HEADER_FIX_LEN - 2; @@ -412,8 +402,8 @@ ahcp_print(netdissect_options *ndo, const u_char *cp, const u_int len) } return; -corrupt: - ND_PRINT((ndo, " %s", cstr)); +invalid: + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp, ep - cp); return; trunc: diff --git a/contrib/tcpdump/print-aodv.c b/contrib/tcpdump/print-aodv.c index ef27eee..6cd0c9e 100644 --- a/contrib/tcpdump/print-aodv.c +++ b/contrib/tcpdump/print-aodv.c @@ -30,16 +30,17 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#define NETDISSECT_REWORKED +/* \summary: Ad hoc On-Demand Distance Vector (AODV) Routing printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" -#include "extract.h" /* must come after interface.h */ +#include "extract.h" struct aodv_rreq { @@ -53,7 +54,6 @@ struct aodv_rreq { uint32_t rreq_oa; /* originator IPv4 address */ uint32_t rreq_os; /* originator sequence number */ }; -#ifdef INET6 struct aodv_rreq6 { uint8_t rreq_type; /* AODV message type (1) */ uint8_t rreq_flags; /* various flags */ @@ -76,7 +76,6 @@ struct aodv_rreq6_draft_01 { struct in6_addr rreq_da; /* destination IPv6 address */ struct in6_addr rreq_oa; /* originator IPv6 address */ }; -#endif #define RREQ_JOIN 0x80 /* join (reserved for multicast */ #define RREQ_REPAIR 0x40 /* repair (reserved for multicast */ @@ -95,7 +94,6 @@ struct aodv_rrep { uint32_t rrep_oa; /* originator IPv4 address */ uint32_t rrep_life; /* lifetime of this route */ }; -#ifdef INET6 struct aodv_rrep6 { uint8_t rrep_type; /* AODV message type (2) */ uint8_t rrep_flags; /* various flags */ @@ -116,7 +114,6 @@ struct aodv_rrep6_draft_01 { struct in6_addr rrep_oa; /* originator IPv6 address */ uint32_t rrep_life; /* lifetime of this route */ }; -#endif #define RREP_REPAIR 0x80 /* repair (reserved for multicast */ #define RREP_ACK 0x40 /* acknowledgement required */ @@ -127,7 +124,6 @@ struct rerr_unreach { uint32_t u_da; /* IPv4 address */ uint32_t u_ds; /* sequence number */ }; -#ifdef INET6 struct rerr_unreach6 { struct in6_addr u_da; /* IPv6 address */ uint32_t u_ds; /* sequence number */ @@ -136,7 +132,6 @@ struct rerr_unreach6_draft_01 { struct in6_addr u_da; /* IPv6 address */ uint32_t u_ds; /* sequence number */ }; -#endif struct aodv_rerr { uint8_t rerr_type; /* AODV message type (3 or 18) */ @@ -275,7 +270,7 @@ aodv_rerr(netdissect_options *ndo, const u_char *dat, u_int length) ND_PRINT((ndo, " rerr %s [items %u] [%u]:", ap->rerr_flags & RERR_NODELETE ? "[D]" : "", ap->rerr_dc, length)); - dp = (struct rerr_unreach *)(dat + sizeof(*ap)); + dp = (const struct rerr_unreach *)(dat + sizeof(*ap)); i = length - sizeof(*ap); for (dc = ap->rerr_dc; dc != 0; dc--) { ND_TCHECK(*dp); @@ -293,13 +288,8 @@ trunc: } static void -#ifdef INET6 aodv_v6_rreq(netdissect_options *ndo, const u_char *dat, u_int length) -#else -aodv_v6_rreq(netdissect_options *ndo, const u_char *dat _U_, u_int length) -#endif { -#ifdef INET6 u_int i; const struct aodv_rreq6 *ap = (const struct aodv_rreq6 *)dat; @@ -326,19 +316,11 @@ aodv_v6_rreq(netdissect_options *ndo, const u_char *dat _U_, u_int length) trunc: ND_PRINT((ndo, " [|rreq")); -#else - ND_PRINT((ndo, " v6 rreq %u", length)); -#endif } static void -#ifdef INET6 aodv_v6_rrep(netdissect_options *ndo, const u_char *dat, u_int length) -#else -aodv_v6_rrep(netdissect_options *ndo, const u_char *dat _U_, u_int length) -#endif { -#ifdef INET6 u_int i; const struct aodv_rrep6 *ap = (const struct aodv_rrep6 *)dat; @@ -362,19 +344,11 @@ aodv_v6_rrep(netdissect_options *ndo, const u_char *dat _U_, u_int length) trunc: ND_PRINT((ndo, " [|rreq")); -#else - ND_PRINT((ndo, " rrep %u", length)); -#endif } static void -#ifdef INET6 aodv_v6_rerr(netdissect_options *ndo, const u_char *dat, u_int length) -#else -aodv_v6_rerr(netdissect_options *ndo, const u_char *dat _U_, u_int length) -#endif { -#ifdef INET6 u_int i, dc; const struct aodv_rerr *ap = (const struct aodv_rerr *)dat; const struct rerr_unreach6 *dp6; @@ -385,7 +359,7 @@ aodv_v6_rerr(netdissect_options *ndo, const u_char *dat _U_, u_int length) ND_PRINT((ndo, " rerr %s [items %u] [%u]:", ap->rerr_flags & RERR_NODELETE ? "[D]" : "", ap->rerr_dc, length)); - dp6 = (struct rerr_unreach6 *)(void *)(ap + 1); + dp6 = (const struct rerr_unreach6 *)(const void *)(ap + 1); i = length - sizeof(*ap); for (dc = ap->rerr_dc; dc != 0; dc--) { ND_TCHECK(*dp6); @@ -400,19 +374,11 @@ aodv_v6_rerr(netdissect_options *ndo, const u_char *dat _U_, u_int length) trunc: ND_PRINT((ndo, "[|rerr]")); -#else - ND_PRINT((ndo, " rerr %u", length)); -#endif } static void -#ifdef INET6 aodv_v6_draft_01_rreq(netdissect_options *ndo, const u_char *dat, u_int length) -#else -aodv_v6_draft_01_rreq(netdissect_options *ndo, const u_char *dat _U_, u_int length) -#endif { -#ifdef INET6 u_int i; const struct aodv_rreq6_draft_01 *ap = (const struct aodv_rreq6_draft_01 *)dat; @@ -439,19 +405,11 @@ aodv_v6_draft_01_rreq(netdissect_options *ndo, const u_char *dat _U_, u_int leng trunc: ND_PRINT((ndo, " [|rreq")); -#else - ND_PRINT((ndo, " rreq %u", length)); -#endif } static void -#ifdef INET6 aodv_v6_draft_01_rrep(netdissect_options *ndo, const u_char *dat, u_int length) -#else -aodv_v6_draft_01_rrep(netdissect_options *ndo, const u_char *dat _U_, u_int length) -#endif { -#ifdef INET6 u_int i; const struct aodv_rrep6_draft_01 *ap = (const struct aodv_rrep6_draft_01 *)dat; @@ -475,19 +433,11 @@ aodv_v6_draft_01_rrep(netdissect_options *ndo, const u_char *dat _U_, u_int leng trunc: ND_PRINT((ndo, " [|rreq")); -#else - ND_PRINT((ndo, " rrep %u", length)); -#endif } static void -#ifdef INET6 aodv_v6_draft_01_rerr(netdissect_options *ndo, const u_char *dat, u_int length) -#else -aodv_v6_draft_01_rerr(netdissect_options *ndo, const u_char *dat _U_, u_int length) -#endif { -#ifdef INET6 u_int i, dc; const struct aodv_rerr *ap = (const struct aodv_rerr *)dat; const struct rerr_unreach6_draft_01 *dp6; @@ -498,7 +448,7 @@ aodv_v6_draft_01_rerr(netdissect_options *ndo, const u_char *dat _U_, u_int leng ND_PRINT((ndo, " rerr %s [items %u] [%u]:", ap->rerr_flags & RERR_NODELETE ? "[D]" : "", ap->rerr_dc, length)); - dp6 = (struct rerr_unreach6_draft_01 *)(void *)(ap + 1); + 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); @@ -513,9 +463,6 @@ aodv_v6_draft_01_rerr(netdissect_options *ndo, const u_char *dat _U_, u_int leng trunc: ND_PRINT((ndo, "[|rerr]")); -#else - ND_PRINT((ndo, " rerr %u", length)); -#endif } void diff --git a/contrib/tcpdump/print-aoe.c b/contrib/tcpdump/print-aoe.c index f8bc1fc..97e93df 100644 --- a/contrib/tcpdump/print-aoe.c +++ b/contrib/tcpdump/print-aoe.c @@ -1,8 +1,4 @@ /* - * This module implements decoding of the ATA over Ethernet (AoE) protocol - * according to the following specification: - * http://support.coraid.com/documents/AoEr11.txt - * * Copyright (c) 2014 The TCPDUMP project * All rights reserved. * @@ -29,20 +25,22 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#define NETDISSECT_REWORKED +/* \summary: ATA over Ethernet (AoE) protocol printer */ + +/* specification: http://brantleycoilecompany.com/AoEr11.pdf */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "addrtoname.h" #include "ether.h" static const char tstr[] = " [|aoe]"; -static const char cstr[] = " (corrupt)"; #define AOE_V1 1 #define ATA_SECTOR_SIZE 512 @@ -148,7 +146,7 @@ aoev1_issue_print(netdissect_options *ndo, const u_char *ep = cp + len; if (len < AOEV1_ISSUE_ARG_LEN) - goto corrupt; + goto invalid; /* AFlags */ ND_TCHECK2(*cp, 1); ND_PRINT((ndo, "\n\tAFlags: [%s]", bittok2str(aoev1_aflag_str, "none", *cp))); @@ -197,8 +195,8 @@ aoev1_issue_print(netdissect_options *ndo, ND_PRINT((ndo, "\n\tData: %u bytes", len - AOEV1_ISSUE_ARG_LEN)); return; -corrupt: - ND_PRINT((ndo, "%s", cstr)); +invalid: + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp, ep - cp); return; trunc: @@ -213,7 +211,7 @@ aoev1_query_print(netdissect_options *ndo, uint16_t cslen; if (len < AOEV1_QUERY_ARG_LEN) - goto corrupt; + goto invalid; /* Buffer Count */ ND_TCHECK2(*cp, 2); ND_PRINT((ndo, "\n\tBuffer Count: %u", EXTRACT_16BITS(cp))); @@ -236,7 +234,7 @@ aoev1_query_print(netdissect_options *ndo, cslen = EXTRACT_16BITS(cp); cp += 2; if (cslen > AOEV1_MAX_CONFSTR_LEN || AOEV1_QUERY_ARG_LEN + cslen > len) - goto corrupt; + goto invalid; /* Config String */ ND_TCHECK2(*cp, cslen); if (cslen) { @@ -246,8 +244,8 @@ aoev1_query_print(netdissect_options *ndo, } return; -corrupt: - ND_PRINT((ndo, "%s", cstr)); +invalid: + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp, ep - cp); return; trunc: @@ -262,7 +260,7 @@ aoev1_mac_print(netdissect_options *ndo, uint8_t dircount, i; if (len < AOEV1_MAC_ARG_LEN) - goto corrupt; + goto invalid; /* Reserved */ ND_TCHECK2(*cp, 1); cp += 1; @@ -280,7 +278,7 @@ aoev1_mac_print(netdissect_options *ndo, cp += 1; ND_PRINT((ndo, ", Dir Count: %u", dircount)); if (AOEV1_MAC_ARG_LEN + dircount * 8 > len) - goto corrupt; + goto invalid; /* directives */ for (i = 0; i < dircount; i++) { /* Reserved */ @@ -297,8 +295,8 @@ aoev1_mac_print(netdissect_options *ndo, } return; -corrupt: - ND_PRINT((ndo, "%s", cstr)); +invalid: + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp, ep - cp); return; trunc: @@ -313,7 +311,7 @@ aoev1_reserve_print(netdissect_options *ndo, uint8_t nmacs, i; if (len < AOEV1_RESERVE_ARG_LEN || (len - AOEV1_RESERVE_ARG_LEN) % ETHER_ADDR_LEN) - goto corrupt; + goto invalid; /* RCmd */ ND_TCHECK2(*cp, 1); ND_PRINT((ndo, "\n\tRCmd: %s", tok2str(aoev1_rcmd_str, "Unknown (0x%02x)", *cp))); @@ -324,7 +322,7 @@ aoev1_reserve_print(netdissect_options *ndo, cp += 1; ND_PRINT((ndo, ", NMacs: %u", nmacs)); if (AOEV1_RESERVE_ARG_LEN + nmacs * ETHER_ADDR_LEN != len) - goto corrupt; + goto invalid; /* addresses */ for (i = 0; i < nmacs; i++) { ND_PRINT((ndo, "\n\tEthernet Address %u: %s", i, etheraddr_string(ndo, cp))); @@ -332,8 +330,8 @@ aoev1_reserve_print(netdissect_options *ndo, } return; -corrupt: - ND_PRINT((ndo, "%s", cstr)); +invalid: + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp, ep - cp); return; trunc: @@ -350,7 +348,7 @@ aoev1_print(netdissect_options *ndo, void (*cmd_decoder)(netdissect_options *, const u_char *, const u_int); if (len < AOEV1_COMMON_HDR_LEN) - goto corrupt; + goto invalid; /* Flags */ flags = *cp & 0x0F; ND_PRINT((ndo, ", Flags: [%s]", bittok2str(aoev1_flag_str, "none", flags))); @@ -390,8 +388,8 @@ aoev1_print(netdissect_options *ndo, cmd_decoder(ndo, cp, len - AOEV1_COMMON_HDR_LEN); return; -corrupt: - ND_PRINT((ndo, "%s", cstr)); +invalid: + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp, ep - cp); return; trunc: @@ -408,7 +406,7 @@ aoe_print(netdissect_options *ndo, ND_PRINT((ndo, "AoE length %u", len)); if (len < 1) - goto corrupt; + goto invalid; /* Ver/Flags */ ND_TCHECK2(*cp, 1); ver = (*cp & 0xF0) >> 4; @@ -422,8 +420,8 @@ aoe_print(netdissect_options *ndo, } return; -corrupt: - ND_PRINT((ndo, "%s", cstr)); +invalid: + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp, ep - cp); return; trunc: diff --git a/contrib/tcpdump/print-ap1394.c b/contrib/tcpdump/print-ap1394.c index 3befe23..79401cb 100644 --- a/contrib/tcpdump/print-ap1394.c +++ b/contrib/tcpdump/print-ap1394.c @@ -19,14 +19,15 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: Apple IP-over-IEEE 1394 printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "addrtoname.h" #include "ethertype.h" @@ -48,6 +49,12 @@ struct firewire_header { */ #define FIREWIRE_HDRLEN 18 +static const char * +fwaddr_string(netdissect_options *ndo, const u_char *addr) +{ + return (linkaddr_string(ndo, addr, LINKADDR_IEEE1394, FIREWIRE_EUI64_LEN)); +} + static inline void ap1394_hdr_print(netdissect_options *ndo, register const u_char *bp, u_int length) { @@ -57,8 +64,8 @@ ap1394_hdr_print(netdissect_options *ndo, register const u_char *bp, u_int lengt fp = (const struct firewire_header *)bp; ND_PRINT((ndo, "%s > %s", - linkaddr_string(ndo, fp->firewire_dhost, LINKADDR_IEEE1394, FIREWIRE_EUI64_LEN), - linkaddr_string(ndo, fp->firewire_shost, LINKADDR_IEEE1394, FIREWIRE_EUI64_LEN))); + fwaddr_string(ndo, fp->firewire_shost), + fwaddr_string(ndo, fp->firewire_dhost))); firewire_type = EXTRACT_16BITS(&fp->firewire_type); if (!ndo->ndo_qflag) { @@ -83,8 +90,9 @@ ap1394_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_ch { u_int length = h->len; u_int caplen = h->caplen; - struct firewire_header *fp; + const struct firewire_header *fp; u_short ether_type; + struct lladdr_info src, dst; if (caplen < FIREWIRE_HDRLEN) { ND_PRINT((ndo, "[|ap1394]")); @@ -96,14 +104,18 @@ ap1394_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_ch length -= FIREWIRE_HDRLEN; caplen -= FIREWIRE_HDRLEN; - fp = (struct firewire_header *)p; + fp = (const struct firewire_header *)p; p += FIREWIRE_HDRLEN; ether_type = EXTRACT_16BITS(&fp->firewire_type); - if (ethertype_print(ndo, ether_type, p, length, caplen) == 0) { + src.addr = fp->firewire_shost; + src.addr_string = fwaddr_string; + dst.addr = fp->firewire_dhost; + dst.addr_string = fwaddr_string; + if (ethertype_print(ndo, ether_type, p, length, caplen, &src, &dst) == 0) { /* ether_type not known, print raw packet */ if (!ndo->ndo_eflag) - ap1394_hdr_print(ndo, (u_char *)fp, length + FIREWIRE_HDRLEN); + ap1394_hdr_print(ndo, (const u_char *)fp, length + FIREWIRE_HDRLEN); if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); diff --git a/contrib/tcpdump/print-arcnet.c b/contrib/tcpdump/print-arcnet.c index 0ffb922..abc19b8 100644 --- a/contrib/tcpdump/print-arcnet.c +++ b/contrib/tcpdump/print-arcnet.c @@ -21,14 +21,15 @@ * From: NetBSD: print-arcnet.c,v 1.2 2000/04/24 13:02:28 itojun Exp */ -#define NETDISSECT_REWORKED +/* \summary: Attached Resource Computer NETwork (ARCNET) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" /* diff --git a/contrib/tcpdump/print-arp.c b/contrib/tcpdump/print-arp.c index 883099b..eff97c4 100644 --- a/contrib/tcpdump/print-arp.c +++ b/contrib/tcpdump/print-arp.c @@ -17,24 +17,23 @@ * 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. - * - * $FreeBSD$ */ -#define NETDISSECT_REWORKED +/* \summary: Address Resolution Protocol (ARP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "ether.h" #include "ethertype.h" -#include "extract.h" /* must come after interface.h */ +#include "extract.h" static const char tstr[] = "[|ARP]"; @@ -178,7 +177,17 @@ struct atmarp_pkthdr { #define ATMTSA(ap) (aar_tsa(ap)) #define ATMTPA(ap) (aar_tpa(ap)) -static u_char ezero[6]; +static int +isnonzero(const u_char *a, size_t len) +{ + while (len > 0) { + if (*a != 0) + return (1); + a++; + len--; + } + return (0); +} static void atmarp_addr_print(netdissect_options *ndo, @@ -359,7 +368,7 @@ arp_print(netdissect_options *ndo, case ARPOP_REQUEST: ND_PRINT((ndo, "who-has %s", ipaddr_string(ndo, TPA(ap)))); - if (memcmp((const char *)ezero, (const char *)THA(ap), HRD_LEN(ap)) != 0) + 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 %s", ipaddr_string(ndo, SPA(ap)))); diff --git a/contrib/tcpdump/print-ascii.c b/contrib/tcpdump/print-ascii.c index 3cefef3..4ef38a1 100644 --- a/contrib/tcpdump/print-ascii.c +++ b/contrib/tcpdump/print-ascii.c @@ -36,15 +36,16 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#define NETDISSECT_REWORKED +/* \summary: ASCII packet dump printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" #define ASCII_LINELENGTH 300 #define HEXDUMP_BYTES_PER_LINE 16 diff --git a/contrib/tcpdump/print-atalk.c b/contrib/tcpdump/print-atalk.c index 7d210be..9d7d69d 100644 --- a/contrib/tcpdump/print-atalk.c +++ b/contrib/tcpdump/print-atalk.c @@ -17,26 +17,23 @@ * 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. - * - * Format and print AppleTalk packets. - * - * $FreeBSD$ */ -#define NETDISSECT_REWORKED +/* \summary: AppleTalk printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "ethertype.h" -#include "extract.h" /* must come after interface.h */ +#include "extract.h" #include "appletalk.h" static const char tstr[] = "[|atalk]"; @@ -80,7 +77,14 @@ u_int ltalk_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { - return (llap_print(ndo, p, h->caplen)); + u_int hdrlen; + + hdrlen = llap_print(ndo, p, h->len); + if (hdrlen == 0) { + /* Cut short by the snapshot length. */ + return (h->caplen); + } + return (hdrlen); } /* @@ -100,6 +104,10 @@ llap_print(netdissect_options *ndo, ND_PRINT((ndo, " [|llap %u]", length)); return (length); } + if (!ND_TTEST2(*bp, sizeof(*lp))) { + ND_PRINT((ndo, " [|llap]")); + return (0); /* cut short by the snapshot length */ + } lp = (const struct LAP *)bp; bp += sizeof(*lp); length -= sizeof(*lp); @@ -111,6 +119,10 @@ llap_print(netdissect_options *ndo, ND_PRINT((ndo, " [|sddp %u]", length)); return (length); } + if (!ND_TTEST2(*bp, ddpSSize)) { + ND_PRINT((ndo, " [|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))); @@ -127,6 +139,10 @@ llap_print(netdissect_options *ndo, ND_PRINT((ndo, " [|ddp %u]", length)); return (length); } + if (!ND_TTEST2(*bp, ddpSize)) { + ND_PRINT((ndo, " [|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), @@ -173,6 +189,10 @@ atalk_print(netdissect_options *ndo, ND_PRINT((ndo, " [|ddp %u]", length)); return; } + if (!ND_TTEST2(*bp, ddpSize)) { + ND_PRINT((ndo, " [|ddp]")); + return; + } dp = (const struct atDDP *)bp; snet = EXTRACT_16BITS(&dp->srcNet); ND_PRINT((ndo, "%s.%s", ataddr_string(ndo, snet, dp->srcNode), @@ -196,6 +216,15 @@ aarp_print(netdissect_options *ndo, ND_PRINT((ndo, "aarp ")); ap = (const struct aarp *)bp; + if (!ND_TTEST(*ap)) { + /* Just bail if we don't have the whole chunk. */ + ND_PRINT((ndo, " [|aarp]")); + return; + } + if (length < sizeof(*ap)) { + ND_PRINT((ndo, " [|aarp %u]", length)); + return; + } if (EXTRACT_16BITS(&ap->htype) == 1 && EXTRACT_16BITS(&ap->ptype) == ETHERTYPE_ATALK && ap->halen == 6 && ap->palen == 4 ) @@ -382,7 +411,7 @@ nbp_print(netdissect_options *ndo, register u_char snode, register u_char skt) { register const struct atNBPtuple *tp = - (const struct atNBPtuple *)((u_char *)np + nbpHeaderSize); + (const struct atNBPtuple *)((const u_char *)np + nbpHeaderSize); int i; const u_char *ep; @@ -569,8 +598,11 @@ ataddr_string(netdissect_options *ndo, tp->nxt; tp = tp->nxt) ; tp->addr = i2; - tp->nxt = newhnamemem(); + tp->nxt = newhnamemem(ndo); tp->name = strdup(nambuf); + if (tp->name == NULL) + (*ndo->ndo_error)(ndo, + "ataddr_string: strdup(nambuf)"); } fclose(fp); } @@ -584,20 +616,25 @@ ataddr_string(netdissect_options *ndo, for (tp2 = &hnametable[i & (HASHNAMESIZE-1)]; tp2->nxt; tp2 = tp2->nxt) if (tp2->addr == i) { tp->addr = (atnet << 8) | athost; - tp->nxt = newhnamemem(); + tp->nxt = newhnamemem(ndo); (void)snprintf(nambuf, sizeof(nambuf), "%s.%d", tp2->name, athost); tp->name = strdup(nambuf); + if (tp->name == NULL) + (*ndo->ndo_error)(ndo, + "ataddr_string: strdup(nambuf)"); return (tp->name); } tp->addr = (atnet << 8) | athost; - tp->nxt = newhnamemem(); + tp->nxt = newhnamemem(ndo); if (athost != 255) (void)snprintf(nambuf, sizeof(nambuf), "%d.%d", atnet, athost); else (void)snprintf(nambuf, sizeof(nambuf), "%d", atnet); tp->name = strdup(nambuf); + if (tp->name == NULL) + (*ndo->ndo_error)(ndo, "ataddr_string: strdup(nambuf)"); return (tp->name); } diff --git a/contrib/tcpdump/print-atm.c b/contrib/tcpdump/print-atm.c index 8f1277b..596e406 100644 --- a/contrib/tcpdump/print-atm.c +++ b/contrib/tcpdump/print-atm.c @@ -17,24 +17,112 @@ * 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. - * - * $FreeBSD$ */ -#define NETDISSECT_REWORKED +/* \summary: Asynchronous Transfer Mode (ATM) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "addrtoname.h" #include "atm.h" -#include "atmuni31.h" #include "llc.h" +/* start of the original atmuni31.h */ + +/* + * Copyright (c) 1997 Yen Yen Lim and North Dakota State University + * 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 Yen Yen Lim and + North Dakota State University + * 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 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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. + */ + +/* Based on UNI3.1 standard by ATM Forum */ + +/* ATM traffic types based on VPI=0 and (the following VCI */ +#define VCI_PPC 0x05 /* Point-to-point signal msg */ +#define VCI_BCC 0x02 /* Broadcast signal msg */ +#define VCI_OAMF4SC 0x03 /* Segment OAM F4 flow cell */ +#define VCI_OAMF4EC 0x04 /* End-to-end OAM F4 flow cell */ +#define VCI_METAC 0x01 /* Meta signal msg */ +#define VCI_ILMIC 0x10 /* ILMI msg */ + +/* Q.2931 signalling messages */ +#define CALL_PROCEED 0x02 /* call proceeding */ +#define CONNECT 0x07 /* connect */ +#define CONNECT_ACK 0x0f /* connect_ack */ +#define SETUP 0x05 /* setup */ +#define RELEASE 0x4d /* release */ +#define RELEASE_DONE 0x5a /* release_done */ +#define RESTART 0x46 /* restart */ +#define RESTART_ACK 0x4e /* restart ack */ +#define STATUS 0x7d /* status */ +#define STATUS_ENQ 0x75 /* status ack */ +#define ADD_PARTY 0x80 /* add party */ +#define ADD_PARTY_ACK 0x81 /* add party ack */ +#define ADD_PARTY_REJ 0x82 /* add party rej */ +#define DROP_PARTY 0x83 /* drop party */ +#define DROP_PARTY_ACK 0x84 /* drop party ack */ + +/* Information Element Parameters in the signalling messages */ +#define CAUSE 0x08 /* cause */ +#define ENDPT_REF 0x54 /* endpoint reference */ +#define AAL_PARA 0x58 /* ATM adaptation layer parameters */ +#define TRAFF_DESCRIP 0x59 /* atm traffic descriptors */ +#define CONNECT_ID 0x5a /* connection identifier */ +#define QOS_PARA 0x5c /* quality of service parameters */ +#define B_HIGHER 0x5d /* broadband higher layer information */ +#define B_BEARER 0x5e /* broadband bearer capability */ +#define B_LOWER 0x5f /* broadband lower information */ +#define CALLING_PARTY 0x6c /* calling party number */ +#define CALLED_PARTY 0x70 /* called party nmber */ + +#define Q2931 0x09 + +/* Q.2931 signalling general messages format */ +#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 */ +#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 + +/* end of the original atmuni31.h */ + static const char tstr[] = "[|atm]"; #define OAM_CRC10_MASK 0x3ff @@ -128,22 +216,20 @@ static const struct tok *oam_functype_values[16] = { /* * Print an RFC 1483 LLC-encapsulated ATM frame. */ -static void +static u_int atm_llc_print(netdissect_options *ndo, const u_char *p, int length, int caplen) { - u_short extracted_ethertype; - - if (!llc_print(ndo, p, length, caplen, NULL, NULL, - &extracted_ethertype)) { - /* ether_type not known, print raw packet */ - if (extracted_ethertype) { - ND_PRINT((ndo, "(LLC %s) ", - etherproto_string(htons(extracted_ethertype)))); - } + int llc_hdrlen; + + llc_hdrlen = llc_print(ndo, p, length, caplen, NULL, NULL); + if (llc_hdrlen < 0) { + /* packet not known, print raw packet */ if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); + llc_hdrlen = -llc_hdrlen; } + return (llc_hdrlen); } /* @@ -231,7 +317,7 @@ atm_if_print(netdissect_options *ndo, caplen -= 20; hdrlen += 20; } - atm_llc_print(ndo, p, length, caplen); + hdrlen += atm_llc_print(ndo, p, length, caplen); return (hdrlen); } @@ -259,24 +345,18 @@ static const struct tok msgtype2str[] = { static void sig_print(netdissect_options *ndo, - const u_char *p, int caplen) + const u_char *p) { uint32_t call_ref; - if (caplen < PROTO_POS) { - ND_PRINT((ndo, "%s", tstr)); - return; - } + ND_TCHECK(p[PROTO_POS]); if (p[PROTO_POS] == Q2931) { /* * protocol:Q.2931 for User to Network Interface * (UNI 3.1) signalling */ ND_PRINT((ndo, "Q.2931")); - if (caplen < MSG_TYPE_POS) { - ND_PRINT((ndo, " %s", tstr)); - return; - } + ND_TCHECK(p[MSG_TYPE_POS]); ND_PRINT((ndo, ":%s ", tok2str(msgtype2str, "msgtype#%d", p[MSG_TYPE_POS]))); @@ -292,6 +372,10 @@ sig_print(netdissect_options *ndo, /* SCCOP with some unknown protocol atop it */ ND_PRINT((ndo, "SSCOP, proto %d ", p[PROTO_POS])); } + return; + +trunc: + ND_PRINT((ndo, " %s", tstr)); } /* @@ -309,7 +393,7 @@ atm_print(netdissect_options *ndo, switch (vci) { case VCI_PPC: - sig_print(ndo, p, caplen); + sig_print(ndo, p); return; case VCI_BCC: @@ -362,7 +446,7 @@ struct oam_fm_ais_rdi_t { uint8_t unused[28]; }; -int +void oam_print (netdissect_options *ndo, const u_char *p, u_int length, u_int hec) { @@ -376,6 +460,7 @@ oam_print (netdissect_options *ndo, } 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; @@ -392,7 +477,7 @@ oam_print (netdissect_options *ndo, clp, length)); if (!ndo->ndo_vflag) { - return 1; + return; } ND_PRINT((ndo, "\n\tcell-type %s (%u)", @@ -411,6 +496,7 @@ oam_print (netdissect_options *ndo, 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", tok2str(oam_fm_loopback_indicator_values, "Unknown", @@ -433,6 +519,7 @@ 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 ")); for (idx = 0; idx < sizeof(oam_ptr.oam_fm_ais_rdi->failure_location); idx++) { @@ -451,6 +538,7 @@ 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) & OAM_CRC10_MASK; cksum_shouldbe = verify_crc10_cksum(0, p, OAM_PAYLOAD_LEN); @@ -459,5 +547,9 @@ oam_print (netdissect_options *ndo, cksum, cksum_shouldbe == 0 ? "" : "in")); - return 1; + return; + +trunc: + ND_PRINT((ndo, "[|oam]")); + return; } diff --git a/contrib/tcpdump/print-babel.c b/contrib/tcpdump/print-babel.c index 75cb32c..f8741d7 100644 --- a/contrib/tcpdump/print-babel.c +++ b/contrib/tcpdump/print-babel.c @@ -26,17 +26,18 @@ * SUCH DAMAGE. */ -#define NETDISSECT_REWORKED +/* \summary: Babel Routing Protocol printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" @@ -53,7 +54,7 @@ babel_print(netdissect_options *ndo, ND_TCHECK2(*cp, 4); if(cp[0] != 42) { - ND_PRINT((ndo, " malformed header")); + ND_PRINT((ndo, " invalid header")); return; } else { ND_PRINT((ndo, " %d", cp[1])); @@ -89,6 +90,9 @@ babel_print(netdissect_options *ndo, #define MESSAGE_MH_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 /* sub-TLVs */ #define MESSAGE_SUB_PAD1 0 @@ -123,11 +127,7 @@ format_prefix(netdissect_options *ndo, const u_char *prefix, unsigned char plen) if(plen >= 96 && memcmp(prefix, v4prefix, 12) == 0) snprintf(buf, 50, "%s/%u", ipaddr_string(ndo, prefix + 12), plen - 96); else -#ifdef INET6 snprintf(buf, 50, "%s/%u", ip6addr_string(ndo, prefix), plen); -#else - snprintf(buf, 50, "IPv6 addresses not supported"); -#endif buf[49] = '\0'; return buf; } @@ -138,11 +138,7 @@ format_address(netdissect_options *ndo, const u_char *prefix) if(memcmp(prefix, v4prefix, 12) == 0) return ipaddr_string(ndo, prefix + 12); else -#ifdef INET6 return ip6addr_string(ndo, prefix); -#else - return "IPv6 addresses not supported"; -#endif } static const char * @@ -284,10 +280,10 @@ subtlvs_print(netdissect_options *ndo, continue; } if(cp == ep) - goto corrupt; + goto invalid; sublen = *cp++; if(cp + sublen > ep) - goto corrupt; + goto invalid; switch(subtype) { case MESSAGE_SUB_PADN: @@ -305,19 +301,20 @@ subtlvs_print(netdissect_options *ndo, ND_PRINT((ndo, "%s%s", sep, tok2str(diversity_str, "%u", *cp++))); sep = "-"; } - if(tlv_type != MESSAGE_UPDATE) + if(tlv_type != MESSAGE_UPDATE && + tlv_type != MESSAGE_UPDATE_SRC_SPECIFIC) ND_PRINT((ndo, " (bogus)")); break; case MESSAGE_SUB_TIMESTAMP: ND_PRINT((ndo, " sub-timestamp")); if(tlv_type == MESSAGE_HELLO) { if(sublen < 4) - goto corrupt; + goto invalid; t1 = EXTRACT_32BITS(cp); ND_PRINT((ndo, " %s", format_timestamp(t1))); } else if(tlv_type == MESSAGE_IHU) { if(sublen < 8) - goto corrupt; + goto invalid; t1 = EXTRACT_32BITS(cp); ND_PRINT((ndo, " %s", format_timestamp(t1))); t2 = EXTRACT_32BITS(cp + 4); @@ -333,12 +330,12 @@ subtlvs_print(netdissect_options *ndo, } /* while */ return; - corrupt: - ND_PRINT((ndo, " (corrupt)")); + invalid: + ND_PRINT((ndo, "%s", istr)); } #define ICHECK(i, l) \ - if ((i) + (l) > bodylen || (i) + (l) > length) goto corrupt; + if ((i) + (l) > bodylen || (i) + (l) > length) goto invalid; static void babel_print_v2(netdissect_options *ndo, @@ -352,7 +349,7 @@ babel_print_v2(netdissect_options *ndo, ND_TCHECK2(*cp, 4); if (length < 4) - goto corrupt; + goto invalid; bodylen = EXTRACT_16BITS(cp + 2); ND_PRINT((ndo, " (%u)", bodylen)); @@ -393,7 +390,7 @@ babel_print_v2(netdissect_options *ndo, ND_PRINT((ndo, " ack-req")); else { ND_PRINT((ndo, "\n\tAcknowledgment Request ")); - if(len < 6) goto corrupt; + if(len < 6) goto invalid; nonce = EXTRACT_16BITS(message + 4); interval = EXTRACT_16BITS(message + 6); ND_PRINT((ndo, "%04x %s", nonce, format_interval(interval))); @@ -407,7 +404,7 @@ babel_print_v2(netdissect_options *ndo, ND_PRINT((ndo, " ack")); else { ND_PRINT((ndo, "\n\tAcknowledgment ")); - if(len < 2) goto corrupt; + if(len < 2) goto invalid; nonce = EXTRACT_16BITS(message + 2); ND_PRINT((ndo, "%04x", nonce)); } @@ -420,7 +417,7 @@ babel_print_v2(netdissect_options *ndo, ND_PRINT((ndo, " hello")); else { ND_PRINT((ndo, "\n\tHello ")); - if(len < 6) goto corrupt; + 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))); @@ -439,7 +436,7 @@ babel_print_v2(netdissect_options *ndo, u_char address[16]; int rc; ND_PRINT((ndo, "\n\tIHU ")); - if(len < 6) goto corrupt; + 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); @@ -459,7 +456,7 @@ babel_print_v2(netdissect_options *ndo, ND_PRINT((ndo, " router-id")); else { ND_PRINT((ndo, "\n\tRouter Id")); - if(len < 10) goto corrupt; + if(len < 10) goto invalid; ND_PRINT((ndo, " %s", format_id(message + 4))); } } @@ -472,9 +469,9 @@ babel_print_v2(netdissect_options *ndo, int rc; u_char nh[16]; ND_PRINT((ndo, "\n\tNext Hop")); - if(len < 2) goto corrupt; + if(len < 2) goto invalid; rc = network_address(message[2], message + 4, len - 2, nh); - if(rc < 0) goto corrupt; + if(rc < 0) goto invalid; ND_PRINT((ndo, " %s", format_address(ndo, nh))); } } @@ -496,13 +493,13 @@ babel_print_v2(netdissect_options *ndo, int rc; u_char prefix[16]; ND_PRINT((ndo, "\n\tUpdate")); - if(len < 10) goto corrupt; + if(len < 10) goto invalid; plen = message[4] + (message[2] == 1 ? 96 : 0); rc = network_prefix(message[2], message[4], message[5], message + 12, message[2] == 1 ? v4_prefix : v6_prefix, len - 10, prefix); - if(rc < 0) goto corrupt; + if(rc < 0) goto invalid; interval = EXTRACT_16BITS(message + 6); seqno = EXTRACT_16BITS(message + 8); metric = EXTRACT_16BITS(message + 10); @@ -532,11 +529,11 @@ babel_print_v2(netdissect_options *ndo, int rc; u_char prefix[16], plen; ND_PRINT((ndo, "\n\tRequest ")); - if(len < 2) goto corrupt; + if(len < 2) goto invalid; plen = message[3] + (message[2] == 1 ? 96 : 0); rc = network_prefix(message[2], message[3], 0, message + 4, NULL, len - 2, prefix); - if(rc < 0) goto corrupt; + if(rc < 0) goto invalid; ND_PRINT((ndo, "for %s", message[2] == 0 ? "any" : format_prefix(ndo, prefix, plen))); } @@ -551,11 +548,11 @@ babel_print_v2(netdissect_options *ndo, u_short seqno; u_char prefix[16], plen; ND_PRINT((ndo, "\n\tMH-Request ")); - if(len < 14) goto corrupt; + if(len < 14) goto invalid; seqno = EXTRACT_16BITS(message + 4); rc = network_prefix(message[2], message[3], 0, message + 16, NULL, len - 14, prefix); - if(rc < 0) goto corrupt; + 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), @@ -568,7 +565,7 @@ babel_print_v2(netdissect_options *ndo, ND_PRINT((ndo, " tspc")); else { ND_PRINT((ndo, "\n\tTS/PC ")); - if(len < 6) goto corrupt; + if(len < 6) goto invalid; ND_PRINT((ndo, "timestamp %u packetcounter %u", EXTRACT_32BITS (message + 4), EXTRACT_16BITS(message + 2))); } @@ -579,13 +576,127 @@ babel_print_v2(netdissect_options *ndo, else { unsigned j; ND_PRINT((ndo, "\n\tHMAC ")); - if(len < 18) goto corrupt; + if(len < 18) goto invalid; ND_PRINT((ndo, "key-id %u digest-%u ", EXTRACT_16BITS(message + 2), len - 2)); for (j = 0; j < len - 2; j++) ND_PRINT((ndo, "%02X", message[4 + j])); } } break; + + case MESSAGE_UPDATE_SRC_SPECIFIC : { + if(!ndo->ndo_vflag) { + ND_PRINT((ndo, " 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")); + 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); + rc = network_prefix(ae, plen, omitted, message + 2 + parsed_len, + ae == 1 ? v4_prefix : v6_prefix, + len - parsed_len, prefix); + if(rc < 0) goto invalid; + if(ae == 1) + plen += 96; + parsed_len += rc; + rc = network_prefix(ae, src_plen, 0, message + 2 + parsed_len, + NULL, len - parsed_len, src_prefix); + if(rc < 0) goto invalid; + if(ae == 1) + 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", + format_prefix(ndo, src_prefix, src_plen), + metric, seqno, format_interval_update(interval))); + /* extra data? */ + if((u_int)parsed_len < len) + subtlvs_print(ndo, message + 2 + parsed_len, + message + 2 + len, type); + } + } + break; + + case MESSAGE_REQUEST_SRC_SPECIFIC : { + if(!ndo->ndo_vflag) + ND_PRINT((ndo, " 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 ")); + if(len < 3) goto invalid; + ae = message[2]; + plen = message[3]; + src_plen = message[4]; + rc = network_prefix(ae, plen, 0, message + 2 + parsed_len, + NULL, len - parsed_len, prefix); + if(rc < 0) goto invalid; + if(ae == 1) + plen += 96; + parsed_len += rc; + rc = network_prefix(ae, src_plen, 0, message + 2 + parsed_len, + NULL, len - parsed_len, src_prefix); + if(rc < 0) goto invalid; + if(ae == 1) + src_plen += 96; + parsed_len += rc; + if(ae == 0) { + ND_PRINT((ndo, "for any")); + } else { + ND_PRINT((ndo, "for (%s, ", format_prefix(ndo, prefix, plen))); + ND_PRINT((ndo, "%s)", format_prefix(ndo, src_prefix, src_plen))); + } + } + } + break; + + case MESSAGE_MH_REQUEST_SRC_SPECIFIC : { + if(!ndo->ndo_vflag) + ND_PRINT((ndo, " 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 ")); + if(len < 14) goto invalid; + ae = message[2]; + plen = message[3]; + seqno = EXTRACT_16BITS(message + 4); + hopc = message[6]; + src_plen = message[7]; + router_id = message + 8; + rc = network_prefix(ae, plen, 0, message + 2 + parsed_len, + NULL, len - parsed_len, prefix); + if(rc < 0) goto invalid; + if(ae == 1) + plen += 96; + parsed_len += rc; + rc = network_prefix(ae, src_plen, 0, message + 2 + parsed_len, + NULL, len - parsed_len, src_prefix); + 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", + format_prefix(ndo, src_prefix, src_plen), + seqno, format_id(router_id))); + } + } + break; + default: if (!ndo->ndo_vflag) ND_PRINT((ndo, " unknown")); @@ -600,7 +711,7 @@ babel_print_v2(netdissect_options *ndo, ND_PRINT((ndo, " %s", tstr)); return; - corrupt: - ND_PRINT((ndo, " (corrupt)")); + invalid: + ND_PRINT((ndo, "%s", istr)); return; } diff --git a/contrib/tcpdump/print-beep.c b/contrib/tcpdump/print-beep.c index 7982feb..ed502b9 100644 --- a/contrib/tcpdump/print-beep.c +++ b/contrib/tcpdump/print-beep.c @@ -2,23 +2,24 @@ * Copyright (C) 2000, Richard Sharpe * * This software may be distributed either under the terms of the - * BSD-style licence that accompanies tcpdump or under the GNU GPL + * BSD-style license that accompanies tcpdump or under the GNU GPL * version 2 or later. * * print-beep.c * */ -#define NETDISSECT_REWORKED +/* \summary: Blocks Extensible Exchange Protocol (BEEP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" /* Check for a string but not go beyond length * Return TRUE on match, FALSE otherwise diff --git a/contrib/tcpdump/print-bfd.c b/contrib/tcpdump/print-bfd.c index f1c2ee8..ad0a406 100644 --- a/contrib/tcpdump/print-bfd.c +++ b/contrib/tcpdump/print-bfd.c @@ -13,14 +13,17 @@ * Original code by Hannes Gredler (hannes@juniper.net) */ -#define NETDISSECT_REWORKED +/* \summary: Bidirectional Forwarding Detection (BFD) printer */ + +/* specification: RFC 5880 (for version 1) and RFC 5881 */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "udp.h" @@ -46,12 +49,12 @@ */ /* - * Control packet, BFDv1, draft-ietf-bfd-base-02.txt + * Control packet, BFDv1, RFC 5880 * * 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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * |Vers | Diag |Sta|P|F|C|A|D|R| Detect Mult | Length | + * |Vers | Diag |Sta|P|F|C|A|D|M| Detect Mult | Length | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | My Discriminator | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -91,20 +94,37 @@ struct bfd_auth_header_t { uint8_t auth_type; uint8_t auth_len; uint8_t auth_data; + uint8_t dummy; /* minimun 4 bytes */ +}; + +enum auth_type { + AUTH_PASSWORD = 1, + AUTH_MD5 = 2, + AUTH_MET_MD5 = 3, + AUTH_SHA1 = 4, + AUTH_MET_SHA1 = 5 }; static const struct tok bfd_v1_authentication_values[] = { - { 0, "Reserved" }, - { 1, "Simple Password" }, - { 2, "Keyed MD5" }, - { 3, "Meticulous Keyed MD5" }, - { 4, "Keyed SHA1" }, - { 5, "Meticulous Keyed SHA1" }, + { AUTH_PASSWORD, "Simple Password" }, + { AUTH_MD5, "Keyed MD5" }, + { AUTH_MET_MD5, "Meticulous Keyed MD5" }, + { AUTH_SHA1, "Keyed SHA1" }, + { AUTH_MET_SHA1, "Meticulous Keyed SHA1" }, { 0, NULL } }; -#define BFD_EXTRACT_VERSION(x) (((x)&0xe0)>>5) -#define BFD_EXTRACT_DIAG(x) ((x)&0x1f) +enum auth_length { + AUTH_PASSWORD_FIELD_MIN_LEN = 4, /* header + password min: 3 + 1 */ + AUTH_PASSWORD_FIELD_MAX_LEN = 19, /* header + password max: 3 + 16 */ + AUTH_MD5_FIELD_LEN = 24, + AUTH_MD5_HASH_LEN = 16, + AUTH_SHA1_FIELD_LEN = 28, + AUTH_SHA1_HASH_LEN = 20 +}; + +#define BFD_EXTRACT_VERSION(x) (((x)&0xe0)>>5) +#define BFD_EXTRACT_DIAG(x) ((x)&0x1f) static const struct tok bfd_port_values[] = { { BFD_CONTROL_PORT, "Control" }, @@ -112,7 +132,6 @@ static const struct tok bfd_port_values[] = { { 0, NULL } }; - static const struct tok bfd_diag_values[] = { { 0, "No Diagnostic" }, { 1, "Control Detection Time Expired" }, @@ -127,14 +146,14 @@ static const struct tok bfd_diag_values[] = { }; static const struct tok bfd_v0_flag_values[] = { - { 0x80, "I Hear You" }, - { 0x40, "Demand" }, - { 0x20, "Poll" }, - { 0x10, "Final" }, - { 0x08, "Reserved" }, - { 0x04, "Reserved" }, - { 0x02, "Reserved" }, - { 0x01, "Reserved" }, + { 0x80, "I Hear You" }, + { 0x40, "Demand" }, + { 0x20, "Poll" }, + { 0x10, "Final" }, + { 0x08, "Reserved" }, + { 0x04, "Reserved" }, + { 0x02, "Reserved" }, + { 0x01, "Reserved" }, { 0, NULL } }; @@ -146,7 +165,7 @@ static const struct tok bfd_v1_flag_values[] = { { 0x08, "Control Plane Independent" }, { BFD_FLAG_AUTH, "Authentication Present" }, { 0x02, "Demand" }, - { 0x01, "Reserved" }, + { 0x01, "Multipoint" }, { 0, NULL } }; @@ -158,12 +177,122 @@ static const struct tok bfd_v1_state_values[] = { { 0, NULL } }; +static int +auth_print(netdissect_options *ndo, register const u_char *pptr) +{ + const struct bfd_auth_header_t *bfd_auth_header; + int i; + + pptr += sizeof (const 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)); + pptr += 2; + ND_PRINT((ndo, "\n\t Auth Key ID: %d", *pptr)); + + switch(bfd_auth_header->auth_type) { + case AUTH_PASSWORD: +/* + * Simple Password Authentication Section Format + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Auth Type | Auth Len | Auth Key ID | Password... | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | ... | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + 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)); + break; + } + pptr++; + ND_PRINT((ndo, ", 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; + break; + case AUTH_MD5: + case AUTH_MET_MD5: +/* + * Keyed MD5 and Meticulous Keyed MD5 Authentication Section Format + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Auth Type | Auth Len | Auth Key ID | Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Sequence Number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Auth Key/Digest... | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | ... | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + if (bfd_auth_header->auth_len != AUTH_MD5_FIELD_LEN) { + ND_PRINT((ndo, "[invalid length %d]", + bfd_auth_header->auth_len)); + break; + } + pptr += 2; + ND_TCHECK2(*pptr, 4); + ND_PRINT((ndo, ", Sequence Number: 0x%08x", EXTRACT_32BITS(pptr))); + pptr += 4; + ND_TCHECK2(*pptr, AUTH_MD5_HASH_LEN); + ND_PRINT((ndo, "\n\t Digest: ")); + for(i = 0; i < AUTH_MD5_HASH_LEN; i++) + ND_PRINT((ndo, "%02x", pptr[i])); + break; + case AUTH_SHA1: + case AUTH_MET_SHA1: +/* + * Keyed SHA1 and Meticulous Keyed SHA1 Authentication Section Format + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Auth Type | Auth Len | Auth Key ID | Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Sequence Number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Auth Key/Hash... | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | ... | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + if (bfd_auth_header->auth_len != AUTH_SHA1_FIELD_LEN) { + ND_PRINT((ndo, "[invalid length %d]", + bfd_auth_header->auth_len)); + break; + } + pptr += 2; + ND_TCHECK2(*pptr, 4); + ND_PRINT((ndo, ", Sequence Number: 0x%08x", EXTRACT_32BITS(pptr))); + pptr += 4; + ND_TCHECK2(*pptr, AUTH_SHA1_HASH_LEN); + ND_PRINT((ndo, "\n\t Hash: ")); + for(i = 0; i < AUTH_SHA1_HASH_LEN; i++) + ND_PRINT((ndo, "%02x", 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) { const struct bfd_header_t *bfd_header; - const struct bfd_auth_header_t *bfd_auth_header; uint8_t version = 0; bfd_header = (const struct bfd_header_t *)pptr; @@ -244,13 +373,8 @@ bfd_print(netdissect_options *ndo, register const u_char *pptr, ND_PRINT((ndo, "\n\t Required min Echo Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_echo_interval)/1000)); if (bfd_header->flags & BFD_FLAG_AUTH) { - pptr += sizeof (const struct bfd_header_t); - bfd_auth_header = (const struct bfd_auth_header_t *)pptr; - ND_TCHECK2(*bfd_auth_header, sizeof(const struct bfd_auth_header_t)); - ND_PRINT((ndo, "\n\t%s (%u) Authentication, length %u present", - tok2str(bfd_v1_authentication_values,"Unknown",bfd_auth_header->auth_type), - bfd_auth_header->auth_type, - bfd_auth_header->auth_len)); + if (auth_print(ndo, pptr)) + goto trunc; } break; diff --git a/contrib/tcpdump/print-bgp.c b/contrib/tcpdump/print-bgp.c index c617c3b..79afeab 100644 --- a/contrib/tcpdump/print-bgp.c +++ b/contrib/tcpdump/print-bgp.c @@ -30,17 +30,18 @@ * complete BGP support. */ -#define NETDISSECT_REWORKED +/* \summary: Border Gateway Protocol (BGP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" #include "af.h" @@ -121,18 +122,25 @@ struct bgp_route_refresh { #define BGPTYPE_ATOMIC_AGGREGATE 6 #define BGPTYPE_AGGREGATOR 7 #define BGPTYPE_COMMUNITIES 8 /* RFC1997 */ -#define BGPTYPE_ORIGINATOR_ID 9 /* RFC1998 */ -#define BGPTYPE_CLUSTER_LIST 10 /* RFC1998 */ -#define BGPTYPE_DPA 11 /* draft-ietf-idr-bgp-dpa */ -#define BGPTYPE_ADVERTISERS 12 /* RFC1863 */ -#define BGPTYPE_RCID_PATH 13 /* RFC1863 */ -#define BGPTYPE_MP_REACH_NLRI 14 /* RFC2283 */ -#define BGPTYPE_MP_UNREACH_NLRI 15 /* RFC2283 */ -#define BGPTYPE_EXTD_COMMUNITIES 16 /* draft-ietf-idr-bgp-ext-communities */ -#define BGPTYPE_AS4_PATH 17 /* RFC4893 */ -#define BGPTYPE_AGGREGATOR4 18 /* RFC4893 */ -#define BGPTYPE_PMSI_TUNNEL 22 /* draft-ietf-l3vpn-2547bis-mcast-bgp-02.txt */ -#define BGPTYPE_ATTR_SET 128 /* draft-marques-ppvpn-ibgp */ +#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 */ @@ -156,6 +164,13 @@ static const struct tok bgp_attr_values[] = { { BGPTYPE_MP_UNREACH_NLRI, "Multi-Protocol Unreach NLRI"}, { BGPTYPE_EXTD_COMMUNITIES, "Extended Community"}, { BGPTYPE_PMSI_TUNNEL, "PMSI Tunnel"}, + { BGPTYPE_TUNNEL_ENCAP, "Tunnel Encapsulation"}, + { BGPTYPE_TRAFFIC_ENG, "Traffic Engineering"}, + { BGPTYPE_IPV6_EXTD_COMMUNITIES, "IPv6 Extended Community"}, + { BGPTYPE_AIGP, "Accumulated IGP Metric"}, + { BGPTYPE_PE_DISTINGUISHER_LABEL, "PE Distinguisher Label"}, + { BGPTYPE_ENTROPY_LABEL, "Entropy Label"}, + { BGPTYPE_LARGE_COMMUNITY, "Large Community"}, { BGPTYPE_ATTR_SET, "Attribute Set"}, { 255, "Reserved for development"}, { 0, NULL} @@ -188,28 +203,37 @@ static const struct tok bgp_as_path_segment_close_values[] = { #define BGP_OPT_AUTH 1 #define BGP_OPT_CAP 2 - static const struct tok bgp_opt_values[] = { { BGP_OPT_AUTH, "Authentication Information"}, { BGP_OPT_CAP, "Capabilities Advertisement"}, { 0, NULL} }; -#define BGP_CAPCODE_MP 1 -#define BGP_CAPCODE_RR 2 -#define BGP_CAPCODE_ORF 3 /* XXX */ -#define BGP_CAPCODE_RESTART 64 /* draft-ietf-idr-restart-05 */ -#define BGP_CAPCODE_AS_NEW 65 /* XXX */ -#define BGP_CAPCODE_DYN_CAP 67 /* XXX */ +#define BGP_CAPCODE_MP 1 /* RFC2858 */ +#define BGP_CAPCODE_RR 2 /* RFC2918 */ +#define BGP_CAPCODE_ORF 3 /* RFC5291 */ +#define BGP_CAPCODE_MR 4 /* RFC3107 */ +#define BGP_CAPCODE_EXT_NH 5 /* RFC5549 */ +#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_RR_CISCO 128 static const struct tok bgp_capcode_values[] = { { BGP_CAPCODE_MP, "Multiprotocol Extensions"}, { BGP_CAPCODE_RR, "Route Refresh"}, { BGP_CAPCODE_ORF, "Cooperative Route Filtering"}, + { BGP_CAPCODE_MR, "Multiple Routes to a Destination"}, + { BGP_CAPCODE_EXT_NH, "Extended Next Hop Encoding"}, { 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_RR_CISCO, "Route Refresh (Cisco)"}, { 0, NULL} }; @@ -279,6 +303,13 @@ static const struct tok bgp_notify_minor_update_values[] = { { 0, NULL} }; +static const struct tok bgp_notify_minor_fsm_values[] = { + { 1, "In OpenSent State"}, + { 2, "In OpenConfirm State"}, + { 3, "In Established State"}, + { 0, NULL } +}; + static const struct tok bgp_notify_minor_cap_values[] = { { 1, "Invalid Action Value" }, { 2, "Invalid Capability Length" }, @@ -318,25 +349,34 @@ static const struct tok bgp_pmsi_flag_values[] = { { 0, NULL} }; +#define BGP_AIGP_TLV 1 + +static const struct tok bgp_aigp_values[] = { + { BGP_AIGP_TLV, "AIGP"}, + { 0, NULL} +}; /* Subsequent address family identifier, RFC2283 section 7 */ #define SAFNUM_RES 0 #define SAFNUM_UNICAST 1 #define SAFNUM_MULTICAST 2 -#define SAFNUM_UNIMULTICAST 3 +#define SAFNUM_UNIMULTICAST 3 /* deprecated now */ /* labeled BGP RFC3107 */ #define SAFNUM_LABUNICAST 4 -/* draft-ietf-l3vpn-2547bis-mcast-bgp-02.txt */ +/* RFC6514 */ #define SAFNUM_MULTICAST_VPN 5 -#define SAFNUM_TUNNEL 64 /* XXX */ -#define SAFNUM_VPLS 65 /* XXX */ -/* draft-nalawade-idr-mdt-safi-03 */ +/* draft-nalawade-kapoor-tunnel-safi */ +#define SAFNUM_TUNNEL 64 +/* RFC4761 */ +#define SAFNUM_VPLS 65 +/* RFC6037 */ #define SAFNUM_MDT 66 -/* Section 4.3.4 of draft-rosen-rfc2547bis-03.txt */ +/* RFC4364 */ #define SAFNUM_VPNUNICAST 128 +/* RFC6513 */ #define SAFNUM_VPNMULTICAST 129 -#define SAFNUM_VPNUNIMULTICAST 130 -/* draft-marques-ppvpn-rt-constrain-01.txt */ +#define SAFNUM_VPNUNIMULTICAST 130 /* deprecated now */ +/* RFC4684 */ #define SAFNUM_RT_ROUTING_INFO 132 #define BGP_VPN_RD_LEN 8 @@ -390,7 +430,6 @@ 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 @@ -454,7 +493,14 @@ static const struct tok bgp_extd_comm_ospf_rtype_values[] = { { 0, NULL }, }; -#define TOKBUFSIZE 128 +/* ADD-PATH Send/Receive field values */ +static const struct tok bgp_add_path_recvsend[] = { + { 1, "Receive" }, + { 2, "Send" }, + { 3, "Both" }, + { 0, NULL }, +}; + static char astostr[20]; /* @@ -503,7 +549,7 @@ decode_prefix4(netdissect_options *ndo, ((u_char *)&addr)[plenbytes - 1] &= ((0xff00 >> (plen % 8)) & 0xff); } - snprintf(buf, buflen, "%s/%d", getname(ndo, (u_char *)&addr), plen); + snprintf(buf, buflen, "%s/%d", ipaddr_string(ndo, &addr), plen); return 1 + plenbytes; trunc: @@ -553,7 +599,7 @@ decode_labeled_prefix4(netdissect_options *ndo, } /* the label may get offsetted by 4 bits so lets shift it right */ snprintf(buf, buflen, "%s/%d, label:%u %s", - getname(ndo, (u_char *)&addr), + ipaddr_string(ndo, &addr), plen, EXTRACT_24BITS(pptr+1)>>4, ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); @@ -586,12 +632,10 @@ bgp_vpn_ip_print(netdissect_options *ndo, ND_TCHECK2(pptr[0], sizeof(struct in_addr)); snprintf(pos, sizeof(addr), "%s", ipaddr_string(ndo, pptr)); break; -#ifdef INET6 case (sizeof(struct in6_addr) << 3): /* 128 */ ND_TCHECK2(pptr[0], sizeof(struct in6_addr)); snprintf(pos, sizeof(addr), "%s", ip6addr_string(ndo, pptr)); break; -#endif default: snprintf(pos, sizeof(addr), "bogus address length %u", addr_length); break; @@ -662,7 +706,6 @@ trunc: return (total_length); } - /* RDs and RTs share the same semantics * we use bgp_vpn_rd_print for * printing route targets inside a NLRI */ @@ -775,7 +818,7 @@ decode_labeled_vpn_prefix4(netdissect_options *ndo, /* 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), - getname(ndo, (u_char *)&addr), + ipaddr_string(ndo, &addr), plen, EXTRACT_24BITS(pptr+1)>>4, ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); @@ -951,21 +994,21 @@ trunc: * the buffer would have overflowed; again, set buflen to 0 in * that case. */ -#define UPDATE_BUF_BUFLEN(buf, buflen, strlen) \ - if (strlen<0) \ +#define UPDATE_BUF_BUFLEN(buf, buflen, stringlen) \ + if (stringlen<0) \ buflen=0; \ - else if ((u_int)strlen>buflen) \ + else if ((u_int)stringlen>buflen) \ buflen=0; \ else { \ - buflen-=strlen; \ - buf+=strlen; \ + buflen-=stringlen; \ + buf+=stringlen; \ } static int decode_labeled_vpn_l2(netdissect_options *ndo, const u_char *pptr, char *buf, u_int buflen) { - int plen,tlen,strlen,tlv_type,tlv_len,ttlv_len; + int plen,tlen,stringlen,tlv_type,tlv_len,ttlv_len; ND_TCHECK2(pptr[0], 2); plen=EXTRACT_16BITS(pptr); @@ -979,12 +1022,11 @@ decode_labeled_vpn_l2(netdissect_options *ndo, /* assume AD-only with RD, BGPNH */ ND_TCHECK2(pptr[0],12); buf[0]='\0'; - strlen=snprintf(buf, buflen, "RD: %s, BGPNH: %s", - bgp_vpn_rd_print(ndo, pptr), - /* need something like getname(ndo, ) here */ - getname(ndo, pptr+8) - ); - UPDATE_BUF_BUFLEN(buf, buflen, strlen); + 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; @@ -994,12 +1036,12 @@ decode_labeled_vpn_l2(netdissect_options *ndo, ND_TCHECK2(pptr[0],15); buf[0]='\0'; - strlen=snprintf(buf, buflen, "RD: %s, CE-ID: %u, Label-Block Offset: %u, Label Base %u", - bgp_vpn_rd_print(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, strlen); + 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; @@ -1016,27 +1058,27 @@ decode_labeled_vpn_l2(netdissect_options *ndo, switch(tlv_type) { case 1: if (buflen!=0) { - strlen=snprintf(buf,buflen, "\n\t\tcircuit status vector (%u) length: %u: 0x", - tlv_type, - tlv_len); - UPDATE_BUF_BUFLEN(buf, buflen, strlen); + 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) { - strlen=snprintf(buf,buflen, "%02x",*pptr++); - UPDATE_BUF_BUFLEN(buf, buflen, strlen); + stringlen=snprintf(buf,buflen, "%02x",*pptr++); + UPDATE_BUF_BUFLEN(buf, buflen, stringlen); } ttlv_len--; } break; default: if (buflen!=0) { - strlen=snprintf(buf,buflen, "\n\t\tunknown TLV #%u, length: %u", - tlv_type, - tlv_len); - UPDATE_BUF_BUFLEN(buf, buflen, strlen); + stringlen=snprintf(buf,buflen, "\n\t\tunknown TLV #%u, length: %u", + tlv_type, + tlv_len); + UPDATE_BUF_BUFLEN(buf, buflen, stringlen); } break; } @@ -1054,7 +1096,6 @@ trunc: return -2; } -#ifdef INET6 int decode_prefix6(netdissect_options *ndo, const u_char *pd, u_int itemlen, char *buf, u_int buflen) @@ -1078,7 +1119,7 @@ decode_prefix6(netdissect_options *ndo, addr.s6_addr[plenbytes - 1] &= ((0xff00 >> (plen % 8)) & 0xff); } - snprintf(buf, buflen, "%s/%d", getname6(ndo, (u_char *)&addr), plen); + snprintf(buf, buflen, "%s/%d", ip6addr_string(ndo, &addr), plen); return 1 + plenbytes; trunc: @@ -1119,7 +1160,7 @@ decode_labeled_prefix6(netdissect_options *ndo, } /* the label may get offsetted by 4 bits so lets shift it right */ snprintf(buf, buflen, "%s/%d, label:%u %s", - getname6(ndo, (u_char *)&addr), + ip6addr_string(ndo, &addr), plen, EXTRACT_24BITS(pptr+1)>>4, ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); @@ -1161,7 +1202,7 @@ decode_labeled_vpn_prefix6(netdissect_options *ndo, /* 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), - getname6(ndo, (u_char *)&addr), + ip6addr_string(ndo, &addr), plen, EXTRACT_24BITS(pptr+1)>>4, ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); @@ -1171,7 +1212,6 @@ decode_labeled_vpn_prefix6(netdissect_options *ndo, trunc: return -2; } -#endif static int decode_clnp_prefix(netdissect_options *ndo, @@ -1194,7 +1234,7 @@ decode_clnp_prefix(netdissect_options *ndo, ((0xff00 >> (plen % 8)) & 0xff); } snprintf(buf, buflen, "%s/%d", - isonsap_string(addr,(plen + 7) / 8), + isonsap_string(ndo, addr,(plen + 7) / 8), plen); return 1 + (plen + 7) / 8; @@ -1231,7 +1271,7 @@ decode_labeled_vpn_clnp_prefix(netdissect_options *ndo, /* 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(addr,(plen + 7) / 8), + isonsap_string(ndo, addr,(plen + 7) / 8), plen, EXTRACT_24BITS(pptr+1)>>4, ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); @@ -1315,7 +1355,6 @@ bgp_attr_print(netdissect_options *ndo, u_int tlen; const u_char *tptr; char buf[MAXHOSTNAMELEN + 100]; - char tokbuf[TOKBUFSIZE]; int as_size; tptr = pptr; @@ -1327,14 +1366,12 @@ bgp_attr_print(netdissect_options *ndo, ND_PRINT((ndo, "invalid len")); else { ND_TCHECK(*tptr); - ND_PRINT((ndo, "%s", tok2strbuf(bgp_origin_values, + ND_PRINT((ndo, "%s", tok2str(bgp_origin_values, "Unknown Origin Typecode", - tptr[0], - tokbuf, sizeof(tokbuf)))); + tptr[0]))); } break; - /* * Process AS4 byte path and AS2 byte path attributes here. */ @@ -1361,9 +1398,8 @@ bgp_attr_print(netdissect_options *ndo, while (tptr < pptr + len) { ND_TCHECK(tptr[0]); - ND_PRINT((ndo, "%s", tok2strbuf(bgp_as_path_segment_open_values, - "?", tptr[0], - tokbuf, sizeof(tokbuf)))); + ND_PRINT((ndo, "%s", tok2str(bgp_as_path_segment_open_values, + "?", tptr[0]))); for (i = 0; i < tptr[1] * as_size; i += as_size) { ND_TCHECK2(tptr[2 + i], as_size); ND_PRINT((ndo, "%s ", @@ -1373,9 +1409,8 @@ bgp_attr_print(netdissect_options *ndo, EXTRACT_32BITS(&tptr[2 + i])))); } ND_TCHECK(tptr[0]); - ND_PRINT((ndo, "%s", tok2strbuf(bgp_as_path_segment_close_values, - "?", tptr[0], - tokbuf, sizeof(tokbuf)))); + ND_PRINT((ndo, "%s", tok2str(bgp_as_path_segment_close_values, + "?", tptr[0]))); ND_TCHECK(tptr[1]); tptr += 2 + tptr[1] * as_size; } @@ -1385,7 +1420,7 @@ bgp_attr_print(netdissect_options *ndo, ND_PRINT((ndo, "invalid len")); else { ND_TCHECK2(tptr[0], 4); - ND_PRINT((ndo, "%s", getname(ndo, tptr))); + ND_PRINT((ndo, "%s", ipaddr_string(ndo, tptr))); } break; case BGPTYPE_MULTI_EXIT_DISC: @@ -1415,11 +1450,11 @@ bgp_attr_print(netdissect_options *ndo, if (len == 6) { ND_PRINT((ndo, " AS #%s, origin %s", as_printf(ndo, astostr, sizeof(astostr), EXTRACT_16BITS(tptr)), - getname(ndo, tptr + 2))); + ipaddr_string(ndo, tptr + 2))); } else { ND_PRINT((ndo, " AS #%s, origin %s", as_printf(ndo, astostr, sizeof(astostr), - EXTRACT_32BITS(tptr)), getname(ndo, tptr + 4))); + EXTRACT_32BITS(tptr)), ipaddr_string(ndo, tptr + 4))); } break; case BGPTYPE_AGGREGATOR4: @@ -1430,7 +1465,7 @@ bgp_attr_print(netdissect_options *ndo, ND_TCHECK2(tptr[0], 8); ND_PRINT((ndo, " AS #%s, origin %s", as_printf(ndo, astostr, sizeof(astostr), EXTRACT_32BITS(tptr)), - getname(ndo, tptr + 4))); + ipaddr_string(ndo, tptr + 4))); break; case BGPTYPE_COMMUNITIES: if (len % 4) { @@ -1468,7 +1503,7 @@ bgp_attr_print(netdissect_options *ndo, break; } ND_TCHECK2(tptr[0], 4); - ND_PRINT((ndo, "%s",getname(ndo, tptr))); + ND_PRINT((ndo, "%s",ipaddr_string(ndo, tptr))); break; case BGPTYPE_CLUSTER_LIST: if (len % 4) { @@ -1478,7 +1513,7 @@ bgp_attr_print(netdissect_options *ndo, while (tlen>0) { ND_TCHECK2(tptr[0], 4); ND_PRINT((ndo, "%s%s", - getname(ndo, tptr), + ipaddr_string(ndo, tptr), (tlen>4) ? ", " : "")); tlen -=4; tptr +=4; @@ -1490,12 +1525,10 @@ bgp_attr_print(netdissect_options *ndo, safi = tptr[2]; ND_PRINT((ndo, "\n\t AFI: %s (%u), %sSAFI: %s (%u)", - tok2strbuf(af_values, "Unknown AFI", af, - tokbuf, sizeof(tokbuf)), + tok2str(af_values, "Unknown AFI", af), af, (safi>128) ? "vendor specific " : "", /* 128 is meanwhile wellknown */ - tok2strbuf(bgp_safi_values, "Unknown SAFI", safi, - tokbuf, sizeof(tokbuf)), + tok2str(bgp_safi_values, "Unknown SAFI", safi), safi)); switch(af<<8 | safi) { @@ -1509,7 +1542,6 @@ bgp_attr_print(netdissect_options *ndo, case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST): case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): case (AFNUM_INET<<8 | SAFNUM_MDT): -#ifdef INET6 case (AFNUM_INET6<<8 | SAFNUM_UNICAST): case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): @@ -1517,7 +1549,6 @@ bgp_attr_print(netdissect_options *ndo, case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST): case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST): case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST): -#endif case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): @@ -1565,7 +1596,7 @@ bgp_attr_print(netdissect_options *ndo, tlen = 0; } else { ND_TCHECK2(tptr[0], sizeof(struct in_addr)); - ND_PRINT((ndo, "%s",getname(ndo, tptr))); + ND_PRINT((ndo, "%s",ipaddr_string(ndo, tptr))); tlen -= sizeof(struct in_addr); tptr += sizeof(struct in_addr); } @@ -1580,12 +1611,11 @@ bgp_attr_print(netdissect_options *ndo, ND_TCHECK2(tptr[0], sizeof(struct in_addr)+BGP_VPN_RD_LEN); ND_PRINT((ndo, "RD: %s, %s", bgp_vpn_rd_print(ndo, tptr), - getname(ndo, tptr+BGP_VPN_RD_LEN))); + 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; -#ifdef INET6 case (AFNUM_INET6<<8 | SAFNUM_UNICAST): case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): @@ -1595,7 +1625,7 @@ bgp_attr_print(netdissect_options *ndo, tlen = 0; } else { ND_TCHECK2(tptr[0], sizeof(struct in6_addr)); - ND_PRINT((ndo, "%s", getname6(ndo, tptr))); + ND_PRINT((ndo, "%s", ip6addr_string(ndo, tptr))); tlen -= sizeof(struct in6_addr); tptr += sizeof(struct in6_addr); } @@ -1610,12 +1640,11 @@ bgp_attr_print(netdissect_options *ndo, ND_TCHECK2(tptr[0], sizeof(struct in6_addr)+BGP_VPN_RD_LEN); ND_PRINT((ndo, "RD: %s, %s", bgp_vpn_rd_print(ndo, tptr), - getname6(ndo, tptr+BGP_VPN_RD_LEN))); + 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; -#endif case (AFNUM_VPLS<<8 | SAFNUM_VPLS): case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): @@ -1625,7 +1654,7 @@ bgp_attr_print(netdissect_options *ndo, tlen = 0; } else { ND_TCHECK2(tptr[0], sizeof(struct in_addr)); - ND_PRINT((ndo, "%s", getname(ndo, tptr))); + ND_PRINT((ndo, "%s", ipaddr_string(ndo, tptr))); tlen -= (sizeof(struct in_addr)); tptr += (sizeof(struct in_addr)); } @@ -1634,7 +1663,7 @@ bgp_attr_print(netdissect_options *ndo, case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): ND_TCHECK2(tptr[0], tlen); - ND_PRINT((ndo, "%s", isonsap_string(tptr, tlen))); + ND_PRINT((ndo, "%s", isonsap_string(ndo, tptr, tlen))); tptr += tlen; tlen = 0; break; @@ -1649,15 +1678,13 @@ bgp_attr_print(netdissect_options *ndo, ND_TCHECK2(tptr[0], tlen); ND_PRINT((ndo, "RD: %s, %s", bgp_vpn_rd_print(ndo, tptr), - isonsap_string(tptr+BGP_VPN_RD_LEN,tlen-BGP_VPN_RD_LEN))); + isonsap_string(ndo, tptr+BGP_VPN_RD_LEN,tlen-BGP_VPN_RD_LEN))); /* rfc986 mapped IPv4 address ? */ if (EXTRACT_32BITS(tptr+BGP_VPN_RD_LEN) == 0x47000601) - ND_PRINT((ndo, " = %s", getname(ndo, tptr+BGP_VPN_RD_LEN+4))); -#ifdef INET6 + ND_PRINT((ndo, " = %s", ipaddr_string(ndo, tptr+BGP_VPN_RD_LEN+4))); /* rfc1888 mapped IPv6 address ? */ else if (EXTRACT_24BITS(tptr+BGP_VPN_RD_LEN) == 0x350000) - ND_PRINT((ndo, " = %s", getname6(ndo, tptr+BGP_VPN_RD_LEN+3))); -#endif + ND_PRINT((ndo, " = %s", ip6addr_string(ndo, tptr+BGP_VPN_RD_LEN+3))); tptr += tlen; tlen = 0; } @@ -1758,7 +1785,6 @@ bgp_attr_print(netdissect_options *ndo, else ND_PRINT((ndo, "\n\t %s", buf)); break; -#ifdef INET6 case (AFNUM_INET6<<8 | SAFNUM_UNICAST): case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): @@ -1794,7 +1820,6 @@ bgp_attr_print(netdissect_options *ndo, else ND_PRINT((ndo, "\n\t %s", buf)); break; -#endif case (AFNUM_VPLS<<8 | SAFNUM_VPLS): case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): @@ -1851,12 +1876,10 @@ bgp_attr_print(netdissect_options *ndo, safi = tptr[2]; ND_PRINT((ndo, "\n\t AFI: %s (%u), %sSAFI: %s (%u)", - tok2strbuf(af_values, "Unknown AFI", af, - tokbuf, sizeof(tokbuf)), + tok2str(af_values, "Unknown AFI", af), af, (safi>128) ? "vendor specific " : "", /* 128 is meanwhile wellknown */ - tok2strbuf(bgp_safi_values, "Unknown SAFI", safi, - tokbuf, sizeof(tokbuf)), + tok2str(bgp_safi_values, "Unknown SAFI", safi), safi)); if (len == BGP_MP_NLRI_MINSIZE) @@ -1901,7 +1924,6 @@ bgp_attr_print(netdissect_options *ndo, else ND_PRINT((ndo, "\n\t %s", buf)); break; -#ifdef INET6 case (AFNUM_INET6<<8 | SAFNUM_UNICAST): case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): @@ -1937,7 +1959,6 @@ bgp_attr_print(netdissect_options *ndo, else ND_PRINT((ndo, "\n\t %s", buf)); break; -#endif case (AFNUM_VPLS<<8 | SAFNUM_VPLS): case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): @@ -2017,9 +2038,9 @@ bgp_attr_print(netdissect_options *ndo, extd_comm=EXTRACT_16BITS(tptr); ND_PRINT((ndo, "\n\t %s (0x%04x), Flags [%s]", - tok2strbuf(bgp_extd_comm_subtype_values, + tok2str(bgp_extd_comm_subtype_values, "unknown extd community typecode", - extd_comm, tokbuf, sizeof(tokbuf)), + extd_comm), extd_comm, bittok2str(bgp_extd_comm_flag_values, "none", extd_comm))); @@ -2031,14 +2052,14 @@ bgp_attr_print(netdissect_options *ndo, ND_PRINT((ndo, ": %u:%u (= %s)", EXTRACT_16BITS(tptr+2), EXTRACT_32BITS(tptr+4), - getname(ndo, 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", - getname(ndo, tptr+2), + ipaddr_string(ndo, tptr+2), EXTRACT_16BITS(tptr+6))); break; case BGP_EXT_COM_RT_2: @@ -2058,25 +2079,23 @@ bgp_attr_print(netdissect_options *ndo, case BGP_EXT_COM_VPN_ORIGIN4: case BGP_EXT_COM_OSPF_RID: case BGP_EXT_COM_OSPF_RID2: - ND_PRINT((ndo, "%s", getname(ndo, tptr+2))); + 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", - getname(ndo, tptr+2), - tok2strbuf(bgp_extd_comm_ospf_rtype_values, + ipaddr_string(ndo, tptr+2), + tok2str(bgp_extd_comm_ospf_rtype_values, "unknown (0x%02x)", - *(tptr+6), - tokbuf, sizeof(tokbuf)), + *(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", - tok2strbuf(l2vpn_encaps_values, + tok2str(l2vpn_encaps_values, "unknown encaps", - *(tptr+2), - tokbuf, sizeof(tokbuf)), + *(tptr+2)), *(tptr+3), EXTRACT_16BITS(tptr+4))); break; @@ -2151,6 +2170,48 @@ bgp_attr_print(netdissect_options *ndo, } break; } + case BGPTYPE_AIGP: + { + uint8_t type; + uint16_t length; + + ND_TCHECK2(tptr[0], 3); + + tlen = len; + + while (tlen >= 3) { + + type = *tptr; + length = EXTRACT_16BITS(tptr+1); + + ND_PRINT((ndo, "\n\t %s TLV (%u), length %u", + tok2str(bgp_aigp_values, "Unknown", type), + type, length)); + + /* + * Check if we can read the TLV data. + */ + ND_TCHECK2(tptr[3], length - 3); + + switch (type) { + + case BGP_AIGP_TLV: + ND_TCHECK2(tptr[3], 8); + ND_PRINT((ndo, ", metric %" PRIu64, + EXTRACT_64BITS(tptr+3))); + break; + + default: + if (ndo->ndo_vflag <= 1) { + print_unknown_data(ndo, tptr+3,"\n\t ", length-3); + } + } + + tptr += length; + tlen -= length; + } + break; + } case BGPTYPE_ATTR_SET: ND_TCHECK2(tptr[0], 4); if (len < 4) @@ -2161,7 +2222,7 @@ bgp_attr_print(netdissect_options *ndo, len -=4; while (len) { - u_int aflags, atype, alenlen, alen; + u_int aflags, alenlen, alen; ND_TCHECK2(tptr[0], 2); if (len < 2) @@ -2179,9 +2240,8 @@ bgp_attr_print(netdissect_options *ndo, len -= alenlen; ND_PRINT((ndo, "\n\t %s (%u), length: %u", - tok2strbuf(bgp_attr_values, - "Unknown Attribute", atype, - tokbuf, sizeof(tokbuf)), + tok2str(bgp_attr_values, + "Unknown Attribute", atype), atype, alen)); @@ -2203,7 +2263,23 @@ bgp_attr_print(netdissect_options *ndo, } 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 */ @@ -2225,8 +2301,6 @@ static void bgp_capabilities_print(netdissect_options *ndo, const u_char *opt, int caps_len) { - char tokbuf[TOKBUFSIZE]; - char tokbuf2[TOKBUFSIZE]; int cap_type, cap_len, tcap_len, cap_offset; int i = 0; @@ -2236,21 +2310,19 @@ bgp_capabilities_print(netdissect_options *ndo, cap_len=opt[i+1]; tcap_len=cap_len; ND_PRINT((ndo, "\n\t %s (%u), length: %u", - tok2strbuf(bgp_capcode_values, "Unknown", - cap_type, tokbuf, sizeof(tokbuf)), + 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: ND_PRINT((ndo, "\n\t\tAFI %s (%u), SAFI %s (%u)", - tok2strbuf(af_values, "Unknown", - EXTRACT_16BITS(opt+i+2), - tokbuf, sizeof(tokbuf)), + tok2str(af_values, "Unknown", + EXTRACT_16BITS(opt+i+2)), EXTRACT_16BITS(opt+i+2), - tok2strbuf(bgp_safi_values, "Unknown", - opt[i+5], - tokbuf, sizeof(tokbuf)), + tok2str(bgp_safi_values, "Unknown", + opt[i+5]), opt[i+5])); break; case BGP_CAPCODE_RESTART: @@ -2261,13 +2333,11 @@ bgp_capabilities_print(netdissect_options *ndo, cap_offset=4; while(tcap_len>=4) { ND_PRINT((ndo, "\n\t\t AFI %s (%u), SAFI %s (%u), Forwarding state preserved: %s", - tok2strbuf(af_values,"Unknown", - EXTRACT_16BITS(opt+i+cap_offset), - tokbuf, sizeof(tokbuf)), + tok2str(af_values,"Unknown", + EXTRACT_16BITS(opt+i+cap_offset)), EXTRACT_16BITS(opt+i+cap_offset), - tok2strbuf(bgp_safi_values,"Unknown", - opt[i+cap_offset+2], - tokbuf2, sizeof(tokbuf2)), + 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; @@ -2288,6 +2358,28 @@ bgp_capabilities_print(netdissect_options *ndo, 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)); @@ -2314,7 +2406,6 @@ bgp_open_print(netdissect_options *ndo, struct bgp_opt bgpopt; const u_char *opt; int i; - char tokbuf[TOKBUFSIZE]; ND_TCHECK2(dat[0], BGP_OPEN_SIZE); memcpy(&bgpo, dat, BGP_OPEN_SIZE); @@ -2323,7 +2414,7 @@ bgp_open_print(netdissect_options *ndo, 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", getname(ndo, (u_char *)&bgpo.bgpo_id))); + 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 */ @@ -2344,9 +2435,8 @@ bgp_open_print(netdissect_options *ndo, } ND_PRINT((ndo, "\n\t Option %s (%u), length: %u", - tok2strbuf(bgp_opt_values,"Unknown", - bgpopt.bgpopt_type, - tokbuf, sizeof(tokbuf)), + tok2str(bgp_opt_values,"Unknown", + bgpopt.bgpopt_type), bgpopt.bgpopt_type, bgpopt.bgpopt_len)); @@ -2380,11 +2470,6 @@ bgp_update_print(netdissect_options *ndo, int withdrawn_routes_len; int len; int i; - char tokbuf[TOKBUFSIZE]; -#ifndef INET6 - char buf[MAXHOSTNAMELEN + 100]; - int wpfx; -#endif ND_TCHECK2(dat[0], BGP_SIZE); if (length < BGP_SIZE) @@ -2409,36 +2494,9 @@ bgp_update_print(netdissect_options *ndo, ND_TCHECK2(p[0], withdrawn_routes_len); if (length < withdrawn_routes_len) goto trunc; -#ifdef INET6 ND_PRINT((ndo, "\n\t Withdrawn routes: %d bytes", withdrawn_routes_len)); p += withdrawn_routes_len; length -= withdrawn_routes_len; -#else - if (withdrawn_routes_len < 2) - goto trunc; - length -= 2; - withdrawn_routes_len -= 2; - - - ND_PRINT((ndo, "\n\t Withdrawn routes:")); - - while(withdrawn_routes_len > 0) { - wpfx = decode_prefix4(ndo, p, withdrawn_routes_len, buf, sizeof(buf)); - if (wpfx == -1) { - ND_PRINT((ndo, "\n\t (illegal prefix length)")); - break; - } else if (wpfx == -2) - goto trunc; - else if (wpfx == -3) - goto trunc; /* bytes left, but not enough */ - else { - ND_PRINT((ndo, "\n\t %s", buf)); - p += wpfx; - length -= wpfx; - withdrawn_routes_len -= wpfx; - } - } -#endif } ND_TCHECK2(p[0], 2); @@ -2481,9 +2539,8 @@ bgp_update_print(netdissect_options *ndo, length -= alenlen; ND_PRINT((ndo, "\n\t %s (%u), length: %u", - tok2strbuf(bgp_attr_values, "Unknown Attribute", - atype, - tokbuf, sizeof(tokbuf)), + tok2str(bgp_attr_values, "Unknown Attribute", + atype), atype, alen)); @@ -2547,8 +2604,6 @@ bgp_notification_print(netdissect_options *ndo, { struct bgp_notification bgpn; const u_char *tptr; - char tokbuf[TOKBUFSIZE]; - char tokbuf2[TOKBUFSIZE]; ND_TCHECK2(dat[0], BGP_NOTIFICATION_SIZE); memcpy(&bgpn, dat, BGP_NOTIFICATION_SIZE); @@ -2558,39 +2613,46 @@ bgp_notification_print(netdissect_options *ndo, return; ND_PRINT((ndo, ", %s (%u)", - tok2strbuf(bgp_notify_major_values, "Unknown Error", - bgpn.bgpn_major, tokbuf, sizeof(tokbuf)), + tok2str(bgp_notify_major_values, "Unknown Error", + bgpn.bgpn_major), bgpn.bgpn_major)); switch (bgpn.bgpn_major) { case BGP_NOTIFY_MAJOR_MSG: ND_PRINT((ndo, ", subcode %s (%u)", - tok2strbuf(bgp_notify_minor_msg_values, "Unknown", - bgpn.bgpn_minor, tokbuf, sizeof(tokbuf)), + 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)", - tok2strbuf(bgp_notify_minor_open_values, "Unknown", - bgpn.bgpn_minor, tokbuf, sizeof(tokbuf)), + 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)", - tok2strbuf(bgp_notify_minor_update_values, "Unknown", - bgpn.bgpn_minor, tokbuf, sizeof(tokbuf)), + 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)", - tok2strbuf(bgp_notify_minor_cap_values, "Unknown", - bgpn.bgpn_minor, tokbuf, sizeof(tokbuf)), + 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)", - tok2strbuf(bgp_notify_minor_cease_values, "Unknown", - bgpn.bgpn_minor, tokbuf, sizeof(tokbuf)), + tok2str(bgp_notify_minor_cease_values, "Unknown", + bgpn.bgpn_minor), bgpn.bgpn_minor)); /* draft-ietf-idr-cease-subcode-02 mentions optionally 7 bytes @@ -2600,11 +2662,10 @@ bgp_notification_print(netdissect_options *ndo, tptr = dat + BGP_NOTIFICATION_SIZE; ND_TCHECK2(*tptr, 7); ND_PRINT((ndo, ", AFI %s (%u), SAFI %s (%u), Max Prefixes: %u", - tok2strbuf(af_values, "Unknown", - EXTRACT_16BITS(tptr), tokbuf, sizeof(tokbuf)), + tok2str(af_values, "Unknown", + EXTRACT_16BITS(tptr)), EXTRACT_16BITS(tptr), - tok2strbuf(bgp_safi_values, "Unknown", *(tptr+2), - tokbuf2, sizeof(tokbuf)), + tok2str(bgp_safi_values, "Unknown", *(tptr+2)), *(tptr+2), EXTRACT_32BITS(tptr+3))); } @@ -2623,8 +2684,6 @@ bgp_route_refresh_print(netdissect_options *ndo, const u_char *pptr, int len) { const struct bgp_route_refresh *bgp_route_refresh_header; - char tokbuf[TOKBUFSIZE]; - char tokbuf2[TOKBUFSIZE]; ND_TCHECK2(pptr[0], BGP_ROUTE_REFRESH_SIZE); @@ -2635,15 +2694,13 @@ bgp_route_refresh_print(netdissect_options *ndo, bgp_route_refresh_header = (const struct bgp_route_refresh *)pptr; ND_PRINT((ndo, "\n\t AFI %s (%u), SAFI %s (%u)", - tok2strbuf(af_values,"Unknown", + tok2str(af_values,"Unknown", /* this stinks but the compiler pads the structure * weird */ - EXTRACT_16BITS(&bgp_route_refresh_header->afi), - tokbuf, sizeof(tokbuf)), + EXTRACT_16BITS(&bgp_route_refresh_header->afi)), EXTRACT_16BITS(&bgp_route_refresh_header->afi), - tok2strbuf(bgp_safi_values,"Unknown", - bgp_route_refresh_header->safi, - tokbuf2, sizeof(tokbuf2)), + tok2str(bgp_safi_values,"Unknown", + bgp_route_refresh_header->safi), bgp_route_refresh_header->safi)); if (ndo->ndo_vflag > 1) { @@ -2661,13 +2718,11 @@ bgp_header_print(netdissect_options *ndo, const u_char *dat, int length) { struct bgp bgp; - char tokbuf[TOKBUFSIZE]; ND_TCHECK2(dat[0], BGP_SIZE); memcpy(&bgp, dat, BGP_SIZE); ND_PRINT((ndo, "\n\t%s Message (%u), length: %u", - tok2strbuf(bgp_msg_values, "Unknown", bgp.bgp_type, - tokbuf, sizeof(tokbuf)), + tok2str(bgp_msg_values, "Unknown", bgp.bgp_type), bgp.bgp_type, length)); @@ -2712,7 +2767,6 @@ bgp_print(netdissect_options *ndo, }; struct bgp bgp; uint16_t hlen; - char tokbuf[TOKBUFSIZE]; ep = dat + length; if (ndo->ndo_snapend < dat + length) @@ -2761,10 +2815,9 @@ bgp_print(netdissect_options *ndo, start = p; } else { ND_PRINT((ndo, "\n[|BGP %s]", - tok2strbuf(bgp_msg_values, + tok2str(bgp_msg_values, "Unknown Message Type", - bgp.bgp_type, - tokbuf, sizeof(tokbuf)))); + bgp.bgp_type))); break; } } diff --git a/contrib/tcpdump/print-bootp.c b/contrib/tcpdump/print-bootp.c index 0cbc121..fe798a0 100644 --- a/contrib/tcpdump/print-bootp.c +++ b/contrib/tcpdump/print-bootp.c @@ -17,22 +17,19 @@ * 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. - * - * Format and print bootp packets. - * - * $FreeBSD$ */ -#define NETDISSECT_REWORKED +/* \summary: BOOTP and IPv4 DHCP printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" @@ -215,8 +212,9 @@ struct bootp { #define TAG_CLIENT_GUID ((uint8_t) 97) #define TAG_LDAP_URL ((uint8_t) 95) #define TAG_6OVER4 ((uint8_t) 96) -#define TAG_PRINTER_NAME ((uint8_t) 100) -#define TAG_MDHCP_SERVER ((uint8_t) 101) +/* 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) @@ -224,6 +222,7 @@ struct bootp { #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) */ #define DHCPDISCOVER 1 @@ -294,6 +293,7 @@ bootp_print(netdissect_options *ndo, 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))); @@ -356,7 +356,8 @@ bootp_print(netdissect_options *ndo, ND_TCHECK2(bp->bp_sname[0], 1); /* check first char only */ if (*bp->bp_sname) { ND_PRINT((ndo, "\n\t sname \"")); - if (fn_print(ndo, bp->bp_sname, ndo->ndo_snapend)) { + if (fn_printztn(ndo, bp->bp_sname, (u_int)sizeof bp->bp_sname, + ndo->ndo_snapend)) { ND_PRINT((ndo, "\"")); ND_PRINT((ndo, "%s", tstr + 1)); return; @@ -366,7 +367,8 @@ bootp_print(netdissect_options *ndo, ND_TCHECK2(bp->bp_file[0], 1); /* check first char only */ if (*bp->bp_file) { ND_PRINT((ndo, "\n\t file \"")); - if (fn_print(ndo, bp->bp_file, ndo->ndo_snapend)) { + if (fn_printztn(ndo, bp->bp_file, (u_int)sizeof bp->bp_file, + ndo->ndo_snapend)) { ND_PRINT((ndo, "\"")); ND_PRINT((ndo, "%s", tstr + 1)); return; @@ -522,13 +524,14 @@ static const struct tok tag2str[] = { { TAG_CLIENT_GUID, "bGUID" }, /* XXX 'b' */ { TAG_LDAP_URL, "aLDAP" }, { TAG_6OVER4, "i6o4" }, - { TAG_PRINTER_NAME, "aPRTR" }, - { TAG_MDHCP_SERVER, "bMDHCP" }, /* XXX 'b' */ + { 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 */ @@ -999,7 +1002,7 @@ rfc1048_print(netdissect_options *ndo, break; } if (len < suboptlen) { - ND_PRINT((ndo, "ERROR: malformed option")); + ND_PRINT((ndo, "ERROR: invalid option")); bp += len; len = 0; break; diff --git a/contrib/tcpdump/print-bt.c b/contrib/tcpdump/print-bt.c index 128daad..b37f8fa 100644 --- a/contrib/tcpdump/print-bt.c +++ b/contrib/tcpdump/print-bt.c @@ -17,14 +17,15 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: Bluetooth printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #if defined(DLT_BLUETOOTH_HCI_H4_WITH_PHDR) && defined(HAVE_PCAP_BLUETOOTH_H) diff --git a/contrib/tcpdump/print-calm-fast.c b/contrib/tcpdump/print-calm-fast.c index 5cc39f4..c9be008 100644 --- a/contrib/tcpdump/print-calm-fast.c +++ b/contrib/tcpdump/print-calm-fast.c @@ -15,14 +15,15 @@ * Original code by Ola Martin Lykkja (ola.lykkja@q-free.com) */ -#define NETDISSECT_REWORKED +/* \summary: Communication access for land mobiles (CALM) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" /* @@ -36,19 +37,33 @@ * to the calm header of the packet. */ void -calm_fast_print(netdissect_options *ndo, const u_char *eth, const u_char *bp, u_int length) +calm_fast_print(netdissect_options *ndo, const u_char *bp, u_int length, const struct lladdr_info *src) { - int srcNwref = bp[0]; - int dstNwref = bp[1]; + int srcNwref; + int dstNwref; + + ND_TCHECK2(*bp, 2); + if (length < 2) + goto trunc; + srcNwref = bp[0]; + dstNwref = bp[1]; length -= 2; bp += 2; - ND_PRINT((ndo, "CALM FAST src:%s; ", etheraddr_string(ndo, eth+6))); + ND_PRINT((ndo, "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)); if (ndo->ndo_vflag) ND_DEFAULTPRINT(bp, length); + return; + +trunc: + ND_PRINT((ndo, "[|calm fast]")); + return; } diff --git a/contrib/tcpdump/print-carp.c b/contrib/tcpdump/print-carp.c index 7b9f28c..c650d18 100644 --- a/contrib/tcpdump/print-carp.c +++ b/contrib/tcpdump/print-carp.c @@ -34,14 +34,15 @@ * */ -#define NETDISSECT_REWORKED +/* \summary: Common Address Redundancy Protocol (CARP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" /* for checksum structure and functions */ +#include "netdissect.h" /* for checksum structure and functions */ #include "extract.h" void diff --git a/contrib/tcpdump/print-cdp.c b/contrib/tcpdump/print-cdp.c index 932f7bc..6f8f356 100644 --- a/contrib/tcpdump/print-cdp.c +++ b/contrib/tcpdump/print-cdp.c @@ -24,18 +24,19 @@ * http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm */ -#define NETDISSECT_REWORKED +/* \summary: Cisco Discovery Protocol (CDP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" -#include "extract.h" /* must come after interface.h */ +#include "extract.h" #include "nlpid.h" static const char tstr[] = "[|cdp]"; @@ -170,9 +171,11 @@ cdp_print(netdissect_options *ndo, ND_PRINT((ndo, "\n\t ")); for (i=0;i endp) @@ -317,7 +318,6 @@ cdp_print_addr(netdissect_options *ndo, ND_PRINT((ndo, "IPv4 (%u) %s", num, ipaddr_string(ndo, p))); p += 4; } -#ifdef INET6 else if (pt == PT_IEEE_802_2 && pl == 8 && memcmp(p, prot_ipv6, 8) == 0 && al == 16) { /* @@ -334,7 +334,6 @@ cdp_print_addr(netdissect_options *ndo, ND_PRINT((ndo, "IPv6 (%u) %s", num, ip6addr_string(ndo, p))); p += al; } -#endif else { /* * Generic case: just print raw data diff --git a/contrib/tcpdump/print-cfm.c b/contrib/tcpdump/print-cfm.c index a85eec0..43ad438 100644 --- a/contrib/tcpdump/print-cfm.c +++ b/contrib/tcpdump/print-cfm.c @@ -12,21 +12,20 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * Support for the IEEE Connectivity Fault Management Protocols as per 802.1ag. - * * Original code by Hannes Gredler (hannes@juniper.net) */ -#define NETDISSECT_REWORKED +/* \summary: IEEE 802.1ag Connectivity Fault Management (CFM) protocols printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "ether.h" #include "addrtoname.h" @@ -65,18 +64,15 @@ static const struct tok cfm_opcode_values[] = { struct cfm_ccm_t { uint8_t sequence[4]; uint8_t ma_epi[2]; - uint8_t md_nameformat; - uint8_t md_namelength; - uint8_t md_name[46]; /* md name and short ma name */ - uint8_t reserved_itu[16]; - uint8_t reserved[6]; + uint8_t names[48]; + uint8_t itu_t_y_1731[16]; }; /* * Timer Bases for the CCM Interval field. * Expressed in units of seconds. */ -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, 0.003333, 0.01, 0.1, 1, 10, 60, 600}; #define CCM_INTERVAL_MIN_MULTIPLIER 3.25 #define CCM_INTERVAL_MAX_MULTIPLIER 3.5 @@ -115,16 +111,13 @@ static const struct tok cfm_ma_nameformat_values[] = { struct cfm_lbm_t { uint8_t transaction_id[4]; - uint8_t reserved[4]; }; struct cfm_ltm_t { uint8_t transaction_id[4]; - uint8_t egress_id[8]; uint8_t ttl; uint8_t original_mac[ETHER_ADDR_LEN]; uint8_t target_mac[ETHER_ADDR_LEN]; - uint8_t reserved[3]; }; static const struct tok cfm_ltm_flag_values[] = { @@ -134,11 +127,8 @@ static const struct tok cfm_ltm_flag_values[] = { struct cfm_ltr_t { uint8_t transaction_id[4]; - uint8_t last_egress_id[8]; - uint8_t next_egress_id[8]; uint8_t ttl; uint8_t replay_action; - uint8_t reserved[6]; }; static const struct tok cfm_ltr_flag_values[] = { @@ -226,10 +216,10 @@ static const struct tok cfm_tlv_senderid_chassisid_values[] = { static int -cfm_mgmt_addr_print(netdissect_options *ndo, - register const u_char *tptr) +cfm_network_addr_print(netdissect_options *ndo, + register const u_char *tptr) { - u_int mgmt_addr_type; + u_int network_addr_type; u_int hexdump = FALSE; /* @@ -237,24 +227,22 @@ cfm_mgmt_addr_print(netdissect_options *ndo, * 802.1ab specifies that this field width * is only once octet */ - mgmt_addr_type = *tptr; - ND_PRINT((ndo, "\n\t Management Address Type %s (%u)", - tok2str(af_values, "Unknown", mgmt_addr_type), - mgmt_addr_type)); + network_addr_type = *tptr; + ND_PRINT((ndo, "\n\t Network Address Type %s (%u)", + tok2str(af_values, "Unknown", network_addr_type), + network_addr_type)); /* * Resolve the passed in Address. */ - switch(mgmt_addr_type) { + switch(network_addr_type) { case AFNUM_INET: ND_PRINT((ndo, ", %s", ipaddr_string(ndo, tptr + 1))); break; -#ifdef INET6 case AFNUM_INET6: ND_PRINT((ndo, ", %s", ip6addr_string(ndo, tptr + 1))); break; -#endif default: hexdump = TRUE; @@ -264,29 +252,19 @@ cfm_mgmt_addr_print(netdissect_options *ndo, return hexdump; } -/* - * The egress-ID string is a 16-Bit string plus a MAC address. - */ -static const char * -cfm_egress_id_string(netdissect_options *ndo, register const u_char *tptr) -{ - static char egress_id_buffer[80]; - - snprintf(egress_id_buffer, sizeof(egress_id_buffer), - "MAC 0x%4x-%s", - EXTRACT_16BITS(tptr), - etheraddr_string(ndo, tptr+2)); - - return egress_id_buffer; -} - void cfm_print(netdissect_options *ndo, register const u_char *pptr, register u_int length) { const struct cfm_common_header_t *cfm_common_header; const struct cfm_tlv_header_t *cfm_tlv_header; - const uint8_t *tptr, *tlv_ptr, *ma_name, *ma_nameformat, *ma_namelength; + const uint8_t *tptr, *tlv_ptr; + const uint8_t *namesp; + u_int names_data_remaining; + uint8_t md_nameformat, md_namelength; + const uint8_t *md_name; + uint8_t ma_nameformat, ma_namelength; + const uint8_t *ma_name; u_int hexdump, tlen, cfm_tlv_len, cfm_tlv_type, ccm_interval; @@ -299,6 +277,8 @@ cfm_print(netdissect_options *ndo, 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); /* @@ -328,9 +308,25 @@ cfm_print(netdissect_options *ndo, tptr += sizeof(const 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)); + return; + } + switch (cfm_common_header->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))); + return; + } + if (tlen < sizeof(*msg_ptr.cfm_ccm)) + goto tooshort; + ND_TCHECK(*msg_ptr.cfm_ccm); ccm_interval = CFM_EXTRACT_CCM_INTERVAL(cfm_common_header->flags); ND_PRINT((ndo, ", Flags [CCM Interval %u%s]", @@ -353,55 +349,89 @@ cfm_print(netdissect_options *ndo, EXTRACT_32BITS(msg_ptr.cfm_ccm->sequence), EXTRACT_16BITS(msg_ptr.cfm_ccm->ma_epi))); + namesp = msg_ptr.cfm_ccm->names; + names_data_remaining = sizeof(msg_ptr.cfm_ccm->names); /* * Resolve the MD fields. */ - ND_PRINT((ndo, "\n\t MD Name Format %s (%u), MD Name length %u", - tok2str(cfm_md_nameformat_values, "Unknown", - msg_ptr.cfm_ccm->md_nameformat), - msg_ptr.cfm_ccm->md_nameformat, - msg_ptr.cfm_ccm->md_namelength)); + md_nameformat = *namesp; + namesp++; + names_data_remaining--; /* We know this is != 0 */ + if (md_nameformat != CFM_CCM_MD_FORMAT_NONE) { + md_namelength = *namesp; + namesp++; + names_data_remaining--; /* We know this is !=0 */ + ND_PRINT((ndo, "\n\t MD Name Format %s (%u), MD Name length %u", + tok2str(cfm_md_nameformat_values, "Unknown", + md_nameformat), + md_nameformat, + md_namelength)); + + /* -2 for the MA short name format and length */ + if (md_namelength > names_data_remaining - 2) { + ND_PRINT((ndo, " (too large, must be <= %u)", names_data_remaining - 2)); + return; + } - if (msg_ptr.cfm_ccm->md_nameformat != CFM_CCM_MD_FORMAT_NONE) { + md_name = namesp; ND_PRINT((ndo, "\n\t MD Name: ")); - switch (msg_ptr.cfm_ccm->md_nameformat) { + switch (md_nameformat) { case CFM_CCM_MD_FORMAT_DNS: case CFM_CCM_MD_FORMAT_CHAR: - safeputs(ndo, msg_ptr.cfm_ccm->md_name, msg_ptr.cfm_ccm->md_namelength); + safeputs(ndo, md_name, md_namelength); break; case CFM_CCM_MD_FORMAT_MAC: - ND_PRINT((ndo, "\n\t MAC %s", etheraddr_string(ndo, - msg_ptr.cfm_ccm->md_name))); + if (md_namelength == 6) { + ND_PRINT((ndo, "\n\t MAC %s", etheraddr_string(ndo, + md_name))); + } else { + ND_PRINT((ndo, "\n\t MAC (length invalid)")); + } break; /* FIXME add printers for those MD formats - hexdump for now */ case CFM_CCM_MA_FORMAT_8021: default: - print_unknown_data(ndo, msg_ptr.cfm_ccm->md_name, "\n\t ", - msg_ptr.cfm_ccm->md_namelength); + print_unknown_data(ndo, md_name, "\n\t ", + md_namelength); } + namesp += md_namelength; + names_data_remaining -= md_namelength; + } else { + ND_PRINT((ndo, "\n\t MD Name Format %s (%u)", + tok2str(cfm_md_nameformat_values, "Unknown", + md_nameformat), + md_nameformat)); } /* * Resolve the MA fields. */ - ma_nameformat = msg_ptr.cfm_ccm->md_name + msg_ptr.cfm_ccm->md_namelength; - ma_namelength = msg_ptr.cfm_ccm->md_name + msg_ptr.cfm_ccm->md_namelength + 1; - ma_name = msg_ptr.cfm_ccm->md_name + msg_ptr.cfm_ccm->md_namelength + 2; - + ma_nameformat = *namesp; + namesp++; + names_data_remaining--; /* We know this is != 0 */ + ma_namelength = *namesp; + namesp++; + names_data_remaining--; /* We know this is != 0 */ ND_PRINT((ndo, "\n\t MA Name-Format %s (%u), MA name length %u", tok2str(cfm_ma_nameformat_values, "Unknown", - *ma_nameformat), - *ma_nameformat, - *ma_namelength)); + ma_nameformat), + ma_nameformat, + ma_namelength)); + if (ma_namelength > names_data_remaining) { + ND_PRINT((ndo, " (too large, must be <= %u)", names_data_remaining)); + return; + } + + ma_name = namesp; ND_PRINT((ndo, "\n\t MA Name: ")); - switch (*ma_nameformat) { + switch (ma_nameformat) { case CFM_CCM_MA_FORMAT_CHAR: - safeputs(ndo, ma_name, *ma_namelength); + safeputs(ndo, ma_name, ma_namelength); break; /* FIXME add printers for those MA formats - hexdump for now */ @@ -410,19 +440,26 @@ cfm_print(netdissect_options *ndo, case CFM_CCM_MA_FORMAT_INT: case CFM_CCM_MA_FORMAT_VPN: default: - print_unknown_data(ndo, ma_name, "\n\t ", *ma_namelength); + print_unknown_data(ndo, ma_name, "\n\t ", ma_namelength); } break; 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))); + return; + } + if (tlen < sizeof(*msg_ptr.cfm_ltm)) + goto tooshort; + ND_TCHECK(*msg_ptr.cfm_ltm); ND_PRINT((ndo, ", Flags [%s]", bittok2str(cfm_ltm_flag_values, "none", cfm_common_header->flags))); - ND_PRINT((ndo, "\n\t Transaction-ID 0x%08x, Egress-ID %s, ttl %u", + ND_PRINT((ndo, "\n\t Transaction-ID 0x%08x, ttl %u", EXTRACT_32BITS(msg_ptr.cfm_ltm->transaction_id), - cfm_egress_id_string(ndo, msg_ptr.cfm_ltm->egress_id), msg_ptr.cfm_ltm->ttl)); ND_PRINT((ndo, "\n\t Original-MAC %s, Target-MAC %s", @@ -432,16 +469,20 @@ cfm_print(netdissect_options *ndo, 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))); + return; + } + if (tlen < sizeof(*msg_ptr.cfm_ltr)) + goto tooshort; + ND_TCHECK(*msg_ptr.cfm_ltr); ND_PRINT((ndo, ", Flags [%s]", bittok2str(cfm_ltr_flag_values, "none", cfm_common_header->flags))); - ND_PRINT((ndo, "\n\t Transaction-ID 0x%08x, Last-Egress-ID %s", + ND_PRINT((ndo, "\n\t Transaction-ID 0x%08x, ttl %u", EXTRACT_32BITS(msg_ptr.cfm_ltr->transaction_id), - cfm_egress_id_string(ndo, msg_ptr.cfm_ltr->last_egress_id))); - - ND_PRINT((ndo, "\n\t Next-Egress-ID %s, ttl %u", - cfm_egress_id_string(ndo, msg_ptr.cfm_ltr->next_egress_id), msg_ptr.cfm_ltr->ttl)); ND_PRINT((ndo, "\n\t Replay-Action %s (%u)", @@ -458,20 +499,11 @@ cfm_print(netdissect_options *ndo, case CFM_OPCODE_LBR: case CFM_OPCODE_LBM: default: - if (tlen > cfm_common_header->first_tlv_offset) { - print_unknown_data(ndo, tptr, "\n\t ", - tlen - cfm_common_header->first_tlv_offset); - } + print_unknown_data(ndo, tptr, "\n\t ", + tlen - cfm_common_header->first_tlv_offset); break; } - /* - * Sanity check for not walking off. - */ - if (tlen <= cfm_common_header->first_tlv_offset) { - return; - } - tptr += cfm_common_header->first_tlv_offset; tlen -= cfm_common_header->first_tlv_offset; @@ -482,55 +514,59 @@ cfm_print(netdissect_options *ndo, ND_TCHECK2(*tptr, 1); cfm_tlv_type=cfm_tlv_header->type; - if (cfm_tlv_type != CFM_TLV_END) { - /* did we capture enough for fully decoding the object header ? */ - ND_TCHECK2(*tptr, sizeof(struct cfm_tlv_header_t)); - cfm_tlv_len=EXTRACT_16BITS(&cfm_tlv_header->length); - } else { - cfm_tlv_len = 0; - } - - ND_PRINT((ndo, "\n\t%s TLV (0x%02x), length %u", + ND_PRINT((ndo, "\n\t%s TLV (0x%02x)", tok2str(cfm_tlv_values, "Unknown", cfm_tlv_type), - cfm_tlv_type, - cfm_tlv_len)); - - /* sanity check for not walking off and infinite loop check. */ - if ((cfm_tlv_type != CFM_TLV_END) && - ((cfm_tlv_len + sizeof(struct cfm_tlv_header_t) > tlen) || - (!cfm_tlv_len))) { - print_unknown_data(ndo, tptr, "\n\t ", tlen); + cfm_tlv_type)); + + if (cfm_tlv_type == CFM_TLV_END) { + /* Length is "Not present if the Type field is 0." */ return; } + /* 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_PRINT((ndo, ", length %u", cfm_tlv_len)); + tptr += sizeof(struct cfm_tlv_header_t); tlen -= sizeof(struct cfm_tlv_header_t); tlv_ptr = tptr; - /* did we capture enough for fully decoding the object ? */ - if (cfm_tlv_type != CFM_TLV_END) { - ND_TCHECK2(*tptr, cfm_tlv_len); - } + /* do we have the full tlv ? */ + if (tlen < cfm_tlv_len) + goto tooshort; + ND_TCHECK2(*tptr, cfm_tlv_len); hexdump = FALSE; switch(cfm_tlv_type) { - case CFM_TLV_END: - /* we are done - bail out */ - return; - case CFM_TLV_PORT_STATUS: + if (cfm_tlv_len < 1) { + ND_PRINT((ndo, " (too short, must be >= 1)")); + return; + } ND_PRINT((ndo, ", Status: %s (%u)", tok2str(cfm_tlv_port_status_values, "Unknown", *tptr), *tptr)); break; case CFM_TLV_INTERFACE_STATUS: + if (cfm_tlv_len < 1) { + ND_PRINT((ndo, " (too short, must be >= 1)")); + return; + } ND_PRINT((ndo, ", Status: %s (%u)", tok2str(cfm_tlv_interface_status_values, "Unknown", *tptr), *tptr)); break; case CFM_TLV_PRIVATE: + if (cfm_tlv_len < 4) { + ND_PRINT((ndo, " (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), @@ -543,20 +579,26 @@ cfm_print(netdissect_options *ndo, u_int chassis_id_type, chassis_id_length; u_int mgmt_addr_length; + if (cfm_tlv_len < 1) { + ND_PRINT((ndo, " (too short, must be >= 1)")); + return; + } + /* - * Check if there is a Chassis-ID. + * Get the Chassis ID length and check it. */ chassis_id_length = *tptr; - if (chassis_id_length > tlen) { - hexdump = TRUE; - break; - } - tptr++; tlen--; + cfm_tlv_len--; if (chassis_id_length) { + if (cfm_tlv_len < 1) { + ND_PRINT((ndo, "\n\t (TLV too short)")); + return; + } chassis_id_type = *tptr; + cfm_tlv_len--; ND_PRINT((ndo, "\n\t Chassis-ID Type %s (%u), Chassis-ID length %u", tok2str(cfm_tlv_senderid_chassisid_values, "Unknown", @@ -564,13 +606,18 @@ cfm_print(netdissect_options *ndo, chassis_id_type, chassis_id_length)); + if (cfm_tlv_len < chassis_id_length) { + ND_PRINT((ndo, "\n\t (TLV too short)")); + return; + } + switch (chassis_id_type) { case CFM_CHASSIS_ID_MAC_ADDRESS: ND_PRINT((ndo, "\n\t MAC %s", etheraddr_string(ndo, tptr + 1))); break; case CFM_CHASSIS_ID_NETWORK_ADDRESS: - hexdump |= cfm_mgmt_addr_print(ndo, tptr); + hexdump |= cfm_network_addr_print(ndo, tptr); break; case CFM_CHASSIS_ID_INTERFACE_NAME: /* fall through */ @@ -585,32 +632,60 @@ cfm_print(netdissect_options *ndo, hexdump = TRUE; break; } - } + cfm_tlv_len -= chassis_id_length; - tptr += chassis_id_length; - tlen -= chassis_id_length; + tptr += 1 + chassis_id_length; + tlen -= 1 + chassis_id_length; + } /* * Check if there is a Management Address. */ - mgmt_addr_length = *tptr; - if (mgmt_addr_length > tlen) { - hexdump = TRUE; - break; + if (cfm_tlv_len == 0) { + /* No, there isn't; we're done. */ + return; } + mgmt_addr_length = *tptr; tptr++; tlen--; - + cfm_tlv_len--; if (mgmt_addr_length) { - hexdump |= cfm_mgmt_addr_print(ndo, tptr); + if (cfm_tlv_len < mgmt_addr_length) { + ND_PRINT((ndo, "\n\t (TLV too short)")); + return; + } + cfm_tlv_len -= mgmt_addr_length; + /* + * XXX - this is an OID; print it as such. + */ + tptr += mgmt_addr_length; + tlen -= mgmt_addr_length; + + if (cfm_tlv_len < 1) { + ND_PRINT((ndo, "\n\t (TLV too short)")); + return; + } + + mgmt_addr_length = *tptr; + tptr++; + tlen--; + cfm_tlv_len--; + if (mgmt_addr_length) { + if (cfm_tlv_len < mgmt_addr_length) { + ND_PRINT((ndo, "\n\t (TLV too short)")); + return; + } + cfm_tlv_len -= mgmt_addr_length; + /* + * XXX - this is a TransportDomain; print it as such. + */ + tptr += mgmt_addr_length; + tlen -= mgmt_addr_length; + } } - - tptr += mgmt_addr_length; - tlen -= mgmt_addr_length; - + break; } - break; /* * FIXME those are the defined TLVs that lack a decoder @@ -632,6 +707,11 @@ cfm_print(netdissect_options *ndo, tlen-=cfm_tlv_len; } return; + +tooshort: + ND_PRINT((ndo, "\n\t\t packet is too short")); + return; + trunc: ND_PRINT((ndo, "\n\t\t packet exceeded snapshot")); } diff --git a/contrib/tcpdump/print-chdlc.c b/contrib/tcpdump/print-chdlc.c index 3951ef7..450d286 100644 --- a/contrib/tcpdump/print-chdlc.c +++ b/contrib/tcpdump/print-chdlc.c @@ -19,14 +19,15 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: Cisco HDLC printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "ethertype.h" #include "extract.h" @@ -96,9 +97,9 @@ chdlc_print(netdissect_options *ndo, register const u_char *p, u_int length) if (*(p+1) == 0x81 || *(p+1) == 0x82 || *(p+1) == 0x83) - isoclns_print(ndo, p + 1, length - 1, length - 1); + isoclns_print(ndo, p + 1, length - 1, ndo->ndo_snapend - p - 1); else - isoclns_print(ndo, p, length, length); + isoclns_print(ndo, p, length, ndo->ndo_snapend - p); break; default: if (!ndo->ndo_eflag) diff --git a/contrib/tcpdump/print-cip.c b/contrib/tcpdump/print-cip.c index 91abe08..a123b69 100644 --- a/contrib/tcpdump/print-cip.c +++ b/contrib/tcpdump/print-cip.c @@ -20,20 +20,19 @@ * */ -#define NETDISSECT_REWORKED +/* \summary: Classical-IP over ATM printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif #include -#include +#include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" -#define RFC1483LLC_LEN 8 - static const unsigned char rfcllc[] = { 0xaa, /* DSAP: non-ISO */ 0xaa, /* SSAP: non-ISO */ @@ -43,12 +42,12 @@ static const unsigned char rfcllc[] = { 0x00 }; static inline void -cip_print(netdissect_options *ndo, int length) +cip_print(netdissect_options *ndo, u_int length) { /* * There is no MAC-layer header, so just print the length. */ - ND_PRINT((ndo, "%d: ", length)); + ND_PRINT((ndo, "%u: ", length)); } /* @@ -62,40 +61,42 @@ cip_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char { u_int caplen = h->caplen; u_int length = h->len; - u_short extracted_ethertype; + size_t cmplen; + int llc_hdrlen; - if (memcmp(rfcllc, p, sizeof(rfcllc))==0 && caplen < RFC1483LLC_LEN) { - ND_PRINT((ndo, "[|cip]")); - return (0); - } + cmplen = sizeof(rfcllc); + if (cmplen > caplen) + cmplen = caplen; + if (cmplen > length) + cmplen = length; if (ndo->ndo_eflag) cip_print(ndo, length); - if (memcmp(rfcllc, p, sizeof(rfcllc)) == 0) { + if (cmplen == 0) { + ND_PRINT((ndo, "[|cip]")); + return 0; + } + if (memcmp(rfcllc, p, cmplen) == 0) { /* * LLC header is present. Try to print it & higher layers. */ - if (llc_print(ndo, p, length, caplen, NULL, NULL, - &extracted_ethertype) == 0) { - /* ether_type not known, print raw packet */ - if (!ndo->ndo_eflag) - cip_print(ndo, length); - if (extracted_ethertype) { - ND_PRINT((ndo, "(LLC %s) ", - etherproto_string(htons(extracted_ethertype)))); - } + llc_hdrlen = llc_print(ndo, p, length, caplen, NULL, NULL); + 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; } } else { /* * LLC header is absent; treat it as just IP. */ + llc_hdrlen = 0; ip_print(ndo, p, length); } - return (0); + return (llc_hdrlen); } diff --git a/contrib/tcpdump/print-cnfp.c b/contrib/tcpdump/print-cnfp.c index d80d7fd..e3e9b6d 100644 --- a/contrib/tcpdump/print-cnfp.c +++ b/contrib/tcpdump/print-cnfp.c @@ -30,6 +30,8 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* \summary: Cisco NetFlow protocol printer */ + /* * Cisco NetFlow protocol * @@ -38,17 +40,16 @@ * http://www.cisco.com/c/en/us/td/docs/net_mgmt/netflow_collection_engine/3-6/user/guide/format.html#wp1005892 */ -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" diff --git a/contrib/tcpdump/print-dccp.c b/contrib/tcpdump/print-dccp.c index 45468b5..6e25264 100644 --- a/contrib/tcpdump/print-dccp.c +++ b/contrib/tcpdump/print-dccp.c @@ -7,23 +7,22 @@ * BSD-style license that accompanies tcpdump or the GNU GPL version 2 */ -#define NETDISSECT_REWORKED +/* \summary: Datagram Congestion Control Protocol (DCCP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" -#include "extract.h" /* must come after interface.h */ +#include "extract.h" #include "ip.h" -#ifdef INET6 #include "ip6.h" -#endif #include "ipproto.h" /* RFC4340: Datagram Congestion Control Protocol (DCCP) */ @@ -201,17 +200,16 @@ static inline u_int dccp_csum_coverage(const struct dccp_hdr* dh, u_int len) static int 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 *)(void *)dh, len, + return nextproto4_cksum(ndo, ip, (const uint8_t *)(const void *)dh, len, dccp_csum_coverage(dh, len), IPPROTO_DCCP); } -#ifdef INET6 -static int dccp6_cksum(const struct ip6_hdr *ip6, const struct dccp_hdr *dh, u_int len) +static int dccp6_cksum(netdissect_options *ndo, const struct ip6_hdr *ip6, + const struct dccp_hdr *dh, u_int len) { - return nextproto6_cksum(ip6, (const uint8_t *)(void *)dh, len, + return nextproto6_cksum(ndo, ip6, (const uint8_t *)(const void *)dh, len, dccp_csum_coverage(dh, len), IPPROTO_DCCP); } -#endif static const char *dccp_reset_code(uint8_t code) { @@ -272,9 +270,7 @@ void dccp_print(netdissect_options *ndo, const u_char *bp, const u_char *data2, { const struct dccp_hdr *dh; const struct ip *ip; -#ifdef INET6 const struct ip6_hdr *ip6; -#endif const u_char *cp; u_short sport, dport; u_int hlen; @@ -283,13 +279,11 @@ void dccp_print(netdissect_options *ndo, const u_char *bp, const u_char *data2, dh = (const struct dccp_hdr *)bp; - ip = (struct ip *)data2; -#ifdef INET6 + ip = (const struct ip *)data2; if (IP_V(ip) == 6) ip6 = (const struct ip6_hdr *)data2; else ip6 = NULL; -#endif /*INET6*/ /* make sure we have enough data to look at the X bit */ cp = (const u_char *)(dh + 1); @@ -316,14 +310,11 @@ void dccp_print(netdissect_options *ndo, const u_char *bp, const u_char *data2, dport = EXTRACT_16BITS(&dh->dccph_dport); hlen = dh->dccph_doff * 4; -#ifdef INET6 if (ip6) { ND_PRINT((ndo, "%s.%d > %s.%d: ", ip6addr_string(ndo, &ip6->ip6_src), sport, ip6addr_string(ndo, &ip6->ip6_dst), dport)); - } else -#endif /*INET6*/ - { + } else { ND_PRINT((ndo, "%s.%d > %s.%d: ", ipaddr_string(ndo, &ip->ip_src), sport, ipaddr_string(ndo, &ip->ip_dst), dport)); @@ -353,10 +344,8 @@ void dccp_print(netdissect_options *ndo, const u_char *bp, const u_char *data2, ND_PRINT((ndo, "cksum 0x%04x ", dccp_sum)); if (IP_V(ip) == 4) sum = dccp_cksum(ndo, ip, dh, len); -#ifdef INET6 else if (IP_V(ip) == 6) - sum = dccp6_cksum(ip6, dh, len); -#endif + sum = dccp6_cksum(ndo, ip6, dh, len); if (sum != 0) ND_PRINT((ndo, "(incorrect -> 0x%04x)",in_cksum_shouldbe(dccp_sum, sum))); else @@ -370,8 +359,8 @@ void dccp_print(netdissect_options *ndo, const u_char *bp, const u_char *data2, dccph_type = DCCPH_TYPE(dh); switch (dccph_type) { case DCCP_PKT_REQUEST: { - struct dccp_hdr_request *dhr = - (struct dccp_hdr_request *)(bp + fixed_hdrlen); + const struct dccp_hdr_request *dhr = + (const struct dccp_hdr_request *)(bp + fixed_hdrlen); fixed_hdrlen += 4; if (len < fixed_hdrlen) { ND_PRINT((ndo, "truncated-%s - %u bytes missing!", @@ -386,8 +375,8 @@ void dccp_print(netdissect_options *ndo, const u_char *bp, const u_char *data2, break; } case DCCP_PKT_RESPONSE: { - struct dccp_hdr_response *dhr = - (struct dccp_hdr_response *)(bp + fixed_hdrlen); + const struct dccp_hdr_response *dhr = + (const struct dccp_hdr_response *)(bp + fixed_hdrlen); fixed_hdrlen += 12; if (len < fixed_hdrlen) { ND_PRINT((ndo, "truncated-%s - %u bytes missing!", @@ -447,8 +436,8 @@ void dccp_print(netdissect_options *ndo, const u_char *bp, const u_char *data2, ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type))); break; case DCCP_PKT_RESET: { - struct dccp_hdr_reset *dhr = - (struct dccp_hdr_reset *)(bp + fixed_hdrlen); + 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!", @@ -498,7 +487,6 @@ void dccp_print(netdissect_options *ndo, const u_char *bp, const u_char *data2, /* process options */ if (hlen > fixed_hdrlen){ - const u_char *cp; u_int optlen; cp = bp + fixed_hdrlen; ND_PRINT((ndo, " <")); diff --git a/contrib/tcpdump/print-decnet.c b/contrib/tcpdump/print-decnet.c index 5414ec2..88aa9e3 100644 --- a/contrib/tcpdump/print-decnet.c +++ b/contrib/tcpdump/print-decnet.c @@ -19,12 +19,13 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: DECnet printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include struct mbuf; struct rtentry; @@ -38,12 +39,12 @@ struct rtentry; #include #include "extract.h" -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" static const char tstr[] = "[|decnet]"; -#ifndef WIN32 +#ifndef _WIN32 typedef uint8_t byte[1]; /* single byte field */ #else /* @@ -51,7 +52,7 @@ typedef uint8_t byte[1]; /* single byte field */ */ typedef unsigned char Byte[1]; /* single byte field */ #define byte Byte -#endif /* WIN32 */ +#endif /* _WIN32 */ typedef uint8_t word[2]; /* 2 byte field */ typedef uint8_t longword[4]; /* 4 bytes field */ @@ -325,7 +326,6 @@ union controlmsg #define COS_NONE 0 /* no flow control */ #define COS_SEGMENT 04 /* segment flow control */ #define COS_MESSAGE 010 /* message flow control */ -#define COS_CRYPTSER 020 /* cryptographic services requested */ #define COS_DEFAULT 1 /* default value for field */ #define COI_MASK 3 /* mask for version field */ @@ -491,9 +491,6 @@ static void print_i_info(netdissect_options *, int); static int print_elist(const char *, u_int); static int print_nsp(netdissect_options *, const u_char *, u_int); static void print_reason(netdissect_options *, int); -#ifdef PRINT_NSPDATA -static void pdata(netdissect_options *, u_char *, u_int); -#endif #ifndef HAVE_NETDNET_DNETDB_H_DNET_HTOA extern char *dnet_htoa(struct dn_naddr *); @@ -586,7 +583,7 @@ decnet_print(netdissect_options *ndo, break; default: ND_PRINT((ndo, "unknown message flags under mask")); - ND_DEFAULTPRINT((u_char *)ap, min(length, caplen)); + ND_DEFAULTPRINT((const u_char *)ap, min(length, caplen)); return; } @@ -617,11 +614,11 @@ print_decnet_ctlmsg(netdissect_options *ndo, u_int caplen) { int mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags); - register union controlmsg *cmp = (union controlmsg *)rhp; + register const union controlmsg *cmp = (const union controlmsg *)rhp; int src, dst, info, blksize, eco, ueco, hello, other, vers; etheraddr srcea, rtea; int priority; - char *rhpx = (char *)rhp; + const char *rhpx = (const char *)rhp; int ret; switch (mflags & RMF_CTLMASK) { @@ -692,7 +689,7 @@ print_decnet_ctlmsg(netdissect_options *ndo, 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, (char *)&(cmp->cm_rhello.rh_src), + 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); @@ -715,13 +712,13 @@ print_decnet_ctlmsg(netdissect_options *ndo, 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, (char *)&(cmp->cm_ehello.eh_src), + 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); /*seed*/ - memcpy((char *)&rtea, (char *)&(cmp->cm_ehello.eh_router), + 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); @@ -736,7 +733,7 @@ print_decnet_ctlmsg(netdissect_options *ndo, default: ND_PRINT((ndo, "unknown control message")); - ND_DEFAULTPRINT((u_char *)rhp, min(length, caplen)); + ND_DEFAULTPRINT((const u_char *)rhp, min(length, caplen)); ret = 1; break; } @@ -855,7 +852,7 @@ static int print_nsp(netdissect_options *ndo, const u_char *nspp, u_int nsplen) { - const struct nsphdr *nsphp = (struct nsphdr *)nspp; + const struct nsphdr *nsphp = (const struct nsphdr *)nspp; int dst, src, flags; if (nsplen < sizeof(struct nsphdr)) @@ -874,11 +871,8 @@ print_nsp(netdissect_options *ndo, case MFS_BOM+MFS_EOM: ND_PRINT((ndo, "data %d>%d ", src, dst)); { - struct seghdr *shp = (struct seghdr *)nspp; + const struct seghdr *shp = (const struct seghdr *)nspp; int ack; -#ifdef PRINT_NSPDATA - u_char *dp; -#endif u_int data_off = sizeof(struct minseghdr); if (nsplen < data_off) @@ -908,23 +902,13 @@ print_nsp(netdissect_options *ndo, } } ND_PRINT((ndo, "seg %d ", ack & SGQ_MASK)); -#ifdef PRINT_NSPDATA - if (nsplen > data_off) { - dp = &(nspp[data_off]); - ND_TCHECK2(*dp, nsplen - data_off); - pdata(ndo, dp, nsplen - data_off); - } -#endif } break; case MFS_ILS+MFS_INT: ND_PRINT((ndo, "intr ")); { - struct seghdr *shp = (struct seghdr *)nspp; + const struct seghdr *shp = (const struct seghdr *)nspp; int ack; -#ifdef PRINT_NSPDATA - u_char *dp; -#endif u_int data_off = sizeof(struct minseghdr); if (nsplen < data_off) @@ -954,21 +938,14 @@ print_nsp(netdissect_options *ndo, } } ND_PRINT((ndo, "seg %d ", ack & SGQ_MASK)); -#ifdef PRINT_NSPDATA - if (nsplen > data_off) { - dp = &(nspp[data_off]); - ND_TCHECK2(*dp, nsplen - data_off); - pdata(ndo, dp, nsplen - data_off); - } -#endif } break; case MFS_ILS: ND_PRINT((ndo, "link-service %d>%d ", src, dst)); { - struct seghdr *shp = (struct seghdr *)nspp; - struct lsmsg *lsmp = - (struct lsmsg *)&(nspp[sizeof(struct seghdr)]); + const struct seghdr *shp = (const struct seghdr *)nspp; + const struct lsmsg *lsmp = + (const struct lsmsg *)&(nspp[sizeof(struct seghdr)]); int ack; int lsflags, fcval; @@ -1032,7 +1009,7 @@ print_nsp(netdissect_options *ndo, case MFS_DACK: ND_PRINT((ndo, "data-ack %d>%d ", src, dst)); { - struct ackmsg *amp = (struct ackmsg *)nspp; + const struct ackmsg *amp = (const struct ackmsg *)nspp; int ack; if (nsplen < sizeof(struct ackmsg)) @@ -1057,7 +1034,7 @@ print_nsp(netdissect_options *ndo, case MFS_IACK: ND_PRINT((ndo, "ils-ack %d>%d ", src, dst)); { - struct ackmsg *amp = (struct ackmsg *)nspp; + const struct ackmsg *amp = (const struct ackmsg *)nspp; int ack; if (nsplen < sizeof(struct ackmsg)) @@ -1098,11 +1075,8 @@ print_nsp(netdissect_options *ndo, ND_PRINT((ndo, "retrans-conn-initiate ")); ND_PRINT((ndo, "%d>%d ", src, dst)); { - struct cimsg *cimp = (struct cimsg *)nspp; + const struct cimsg *cimp = (const struct cimsg *)nspp; int services, info, segsize; -#ifdef PRINT_NSPDATA - u_char *dp; -#endif if (nsplen < sizeof(struct cimsg)) goto trunc; @@ -1120,9 +1094,6 @@ print_nsp(netdissect_options *ndo, case COS_MESSAGE: ND_PRINT((ndo, "msg ")); break; - case COS_CRYPTSER: - ND_PRINT((ndo, "crypt ")); - break; } switch (info & COI_MASK) { case COI_32: @@ -1139,24 +1110,14 @@ print_nsp(netdissect_options *ndo, break; } ND_PRINT((ndo, "segsize %d ", segsize)); -#ifdef PRINT_NSPDATA - if (nsplen > sizeof(struct cimsg)) { - dp = &(nspp[sizeof(struct cimsg)]); - ND_TCHECK2(*dp, nsplen - sizeof(struct cimsg)); - pdata(ndo, dp, nsplen - sizeof(struct cimsg)); - } -#endif } break; case MFS_CC: ND_PRINT((ndo, "conn-confirm %d>%d ", src, dst)); { - struct ccmsg *ccmp = (struct ccmsg *)nspp; + const struct ccmsg *ccmp = (const struct ccmsg *)nspp; int services, info; u_int segsize, optlen; -#ifdef PRINT_NSPDATA - u_char *dp; -#endif if (nsplen < sizeof(struct ccmsg)) goto trunc; @@ -1175,9 +1136,6 @@ print_nsp(netdissect_options *ndo, case COS_MESSAGE: ND_PRINT((ndo, "msg ")); break; - case COS_CRYPTSER: - ND_PRINT((ndo, "crypt ")); - break; } switch (info & COI_MASK) { case COI_32: @@ -1196,25 +1154,15 @@ print_nsp(netdissect_options *ndo, ND_PRINT((ndo, "segsize %d ", segsize)); if (optlen) { ND_PRINT((ndo, "optlen %d ", optlen)); -#ifdef PRINT_NSPDATA - if (optlen > nsplen - sizeof(struct ccmsg)) - goto trunc; - dp = &(nspp[sizeof(struct ccmsg)]); - ND_TCHECK2(*dp, optlen); - pdata(ndo, dp, optlen); -#endif } } break; case MFS_DI: ND_PRINT((ndo, "disconn-initiate %d>%d ", src, dst)); { - struct dimsg *dimp = (struct dimsg *)nspp; + const struct dimsg *dimp = (const struct dimsg *)nspp; int reason; u_int optlen; -#ifdef PRINT_NSPDATA - u_char *dp; -#endif if (nsplen < sizeof(struct dimsg)) goto trunc; @@ -1225,20 +1173,13 @@ print_nsp(netdissect_options *ndo, print_reason(ndo, reason); if (optlen) { ND_PRINT((ndo, "optlen %d ", optlen)); -#ifdef PRINT_NSPDATA - if (optlen > nsplen - sizeof(struct dimsg)) - goto trunc; - dp = &(nspp[sizeof(struct dimsg)]); - ND_TCHECK2(*dp, optlen); - pdata(ndo, dp, optlen); -#endif } } break; case MFS_DC: ND_PRINT((ndo, "disconn-confirm %d>%d ", src, dst)); { - struct dcmsg *dcmp = (struct dcmsg *)nspp; + const struct dcmsg *dcmp = (const struct dcmsg *)nspp; int reason; ND_TCHECK(*dcmp); @@ -1296,7 +1237,7 @@ print_reason(netdissect_options *ndo, } const char * -dnnum_string(u_short dnaddr) +dnnum_string(netdissect_options *ndo, u_short dnaddr) { char *str; size_t siz; @@ -1305,13 +1246,13 @@ dnnum_string(u_short dnaddr) str = (char *)malloc(siz = sizeof("00.0000")); if (str == NULL) - error("dnnum_string: malloc"); + (*ndo->ndo_error)(ndo, "dnnum_string: malloc"); snprintf(str, siz, "%d.%d", area, node); return(str); } const char * -dnname_string(u_short dnaddr) +dnname_string(netdissect_options *ndo, u_short dnaddr) { #ifdef HAVE_DNET_HTOA struct dn_naddr dna; @@ -1323,23 +1264,8 @@ dnname_string(u_short dnaddr) if(dnname != NULL) return (strdup(dnname)); else - return(dnnum_string(dnaddr)); + return(dnnum_string(ndo, dnaddr)); #else - return(dnnum_string(dnaddr)); /* punt */ + return(dnnum_string(ndo, dnaddr)); /* punt */ #endif } - -#ifdef PRINT_NSPDATA -static void -pdata(netdissect_options *ndo, - u_char *dp, u_int maxlen) -{ - char c; - u_int x = maxlen; - - while (x-- > 0) { - c = *dp++; - safeputchar(ndo, c); - } -} -#endif diff --git a/contrib/tcpdump/print-dhcp6.c b/contrib/tcpdump/print-dhcp6.c index 53b96ef..762d918 100644 --- a/contrib/tcpdump/print-dhcp6.c +++ b/contrib/tcpdump/print-dhcp6.c @@ -26,6 +26,9 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ + +/* \summary: IPv6 DHCP printer */ + /* * RFC3315: DHCPv6 * supported DHCPv6 options: @@ -40,17 +43,16 @@ * RFC6334: Dual-Stack Lite option, */ -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" @@ -103,8 +105,8 @@ static const struct tok dh6_msgtype_str[] = { /* DHCP6 base packet format */ struct dhcp6 { union { - uint8_t m; - uint32_t x; + nd_uint8_t m; + nd_uint32_t x; } dh6_msgtypexid; /* options follow */ }; @@ -114,10 +116,10 @@ struct dhcp6 { /* DHCPv6 relay messages */ struct dhcp6_relay { - uint8_t dh6relay_msgtype; - uint8_t dh6relay_hcnt; - uint8_t dh6relay_linkaddr[16]; /* XXX: badly aligned */ - uint8_t dh6relay_peeraddr[16]; + 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]; /* options follow */ }; @@ -192,6 +194,7 @@ struct dhcp6_relay { # define DH6OPT_NTP_SUBOPTION_MC_ADDR 2 # define DH6OPT_NTP_SUBOPTION_SRV_FQDN 3 #define DH6OPT_AFTR_NAME 64 +#define DH6OPT_MUDURL 112 static const struct tok dh6opt_str[] = { { DH6OPT_CLIENTID, "client-ID" }, @@ -242,27 +245,28 @@ static const struct tok dh6opt_str[] = { { DH6OPT_LQ_CLIENT_LINK, "LQ-client-link" }, { DH6OPT_NTP_SERVER, "NTP-server" }, { DH6OPT_AFTR_NAME, "AFTR-Name" }, + { DH6OPT_MUDURL, "MUD-URL" }, { 0, NULL } }; static const struct tok dh6opt_stcode_str[] = { - { DH6OPT_STCODE_SUCCESS, "success" }, - { DH6OPT_STCODE_UNSPECFAIL, "unspec failure" }, - { DH6OPT_STCODE_NOADDRAVAIL, "no addresses" }, - { DH6OPT_STCODE_NOBINDING, "no binding" }, - { DH6OPT_STCODE_NOTONLINK, "not on-link" }, - { DH6OPT_STCODE_USEMULTICAST, "use multicast" }, - { DH6OPT_STCODE_NOPREFIXAVAIL, "no prefixes" }, - { DH6OPT_STCODE_UNKNOWNQUERYTYPE, "unknown query type" }, - { DH6OPT_STCODE_MALFORMEDQUERY, "malformed query" }, - { DH6OPT_STCODE_NOTCONFIGURED, "not configured" }, - { DH6OPT_STCODE_NOTALLOWED, "not allowed" }, + { DH6OPT_STCODE_SUCCESS, "Success" }, /* RFC3315 */ + { DH6OPT_STCODE_UNSPECFAIL, "UnspecFail" }, /* RFC3315 */ + { DH6OPT_STCODE_NOADDRAVAIL, "NoAddrsAvail" }, /* RFC3315 */ + { DH6OPT_STCODE_NOBINDING, "NoBinding" }, /* RFC3315 */ + { DH6OPT_STCODE_NOTONLINK, "NotOnLink" }, /* RFC3315 */ + { DH6OPT_STCODE_USEMULTICAST, "UseMulticast" }, /* RFC3315 */ + { DH6OPT_STCODE_NOPREFIXAVAIL, "NoPrefixAvail" }, /* RFC3633 */ + { DH6OPT_STCODE_UNKNOWNQUERYTYPE, "UnknownQueryType" }, /* RFC5007 */ + { DH6OPT_STCODE_MALFORMEDQUERY, "MalformedQuery" }, /* RFC5007 */ + { DH6OPT_STCODE_NOTCONFIGURED, "NotConfigured" }, /* RFC5007 */ + { DH6OPT_STCODE_NOTALLOWED, "NotAllowed" }, /* RFC5007 */ { 0, NULL } }; struct dhcp6opt { - uint16_t dh6opt_type; - uint16_t dh6opt_len; + nd_uint16_t dh6opt_type; + nd_uint16_t dh6opt_len; /* type-dependent data follows */ }; @@ -293,13 +297,14 @@ dhcp6opt_print(netdissect_options *ndo, while (cp < ep) { if (ep < cp + sizeof(*dh6o)) goto trunc; - dh6o = (struct dhcp6opt *)cp; + dh6o = (const struct dhcp6opt *)cp; ND_TCHECK(*dh6o); optlen = EXTRACT_16BITS(&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); switch (opttype) { case DH6OPT_CLIENTID: case DH6OPT_SERVERID: @@ -308,7 +313,7 @@ dhcp6opt_print(netdissect_options *ndo, ND_PRINT((ndo, " ?)")); break; } - tp = (u_char *)(dh6o + 1); + tp = (const u_char *)(dh6o + 1); switch (EXTRACT_16BITS(tp)) { case 1: if (optlen >= 2 + 6) { @@ -360,7 +365,7 @@ dhcp6opt_print(netdissect_options *ndo, ND_PRINT((ndo, " ?)")); break; } - tp = (u_char *)(dh6o + 1); + 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]), @@ -377,7 +382,7 @@ dhcp6opt_print(netdissect_options *ndo, ND_PRINT((ndo, " ?)")); break; } - tp = (u_char *)(dh6o + 1); + 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])))); @@ -389,7 +394,7 @@ dhcp6opt_print(netdissect_options *ndo, ND_PRINT((ndo, " ?)")); break; } - tp = (u_char *)(dh6o + 1); + tp = (const u_char *)(dh6o + 1); ND_PRINT((ndo, " %d)", *tp)); break; case DH6OPT_ELAPSED_TIME: @@ -397,12 +402,12 @@ dhcp6opt_print(netdissect_options *ndo, ND_PRINT((ndo, " ?)")); break; } - tp = (u_char *)(dh6o + 1); + tp = (const u_char *)(dh6o + 1); ND_PRINT((ndo, " %d)", EXTRACT_16BITS(tp))); break; case DH6OPT_RELAY_MSG: ND_PRINT((ndo, " (")); - tp = (u_char *)(dh6o + 1); + tp = (const u_char *)(dh6o + 1); dhcp6_print(ndo, tp, optlen); ND_PRINT((ndo, ")")); break; @@ -411,7 +416,7 @@ dhcp6opt_print(netdissect_options *ndo, ND_PRINT((ndo, " ?)")); break; } - tp = (u_char *)(dh6o + 1); + tp = (const u_char *)(dh6o + 1); auth_proto = *tp; switch (auth_proto) { case DH6OPT_AUTHPROTO_DELAYED: @@ -506,14 +511,14 @@ dhcp6opt_print(netdissect_options *ndo, * Since we cannot predict the encoding, print hex dump * at most 10 characters. */ - tp = (u_char *)(dh6o + 1); + tp = (const u_char *)(dh6o + 1); ND_PRINT((ndo, " ")); for (i = 0; i < optlen && i < 10; i++) ND_PRINT((ndo, "%02x", tp[i])); ND_PRINT((ndo, "...)")); break; case DH6OPT_RECONF_MSG: - tp = (u_char *)(dh6o + 1); + tp = (const u_char *)(dh6o + 1); switch (*tp) { case DH6_RENEW: ND_PRINT((ndo, " for renew)")); @@ -541,14 +546,14 @@ dhcp6opt_print(netdissect_options *ndo, ND_PRINT((ndo, " ?)")); break; } - tp = (u_char *)(dh6o + 1); + 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, ")")); break; case DH6OPT_SIP_SERVER_D: case DH6OPT_DOMAIN_LIST: - tp = (u_char *)(dh6o + 1); + 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) @@ -561,7 +566,7 @@ dhcp6opt_print(netdissect_options *ndo, ND_PRINT((ndo, " ?)")); break; } - tp = (u_char *)(dh6o + 1); + tp = (const u_char *)(dh6o + 1); ND_PRINT((ndo, " %s)", dhcp6stcode(EXTRACT_16BITS(&tp[0])))); break; case DH6OPT_IA_NA: @@ -570,7 +575,7 @@ dhcp6opt_print(netdissect_options *ndo, ND_PRINT((ndo, " ?)")); break; } - tp = (u_char *)(dh6o + 1); + tp = (const u_char *)(dh6o + 1); ND_PRINT((ndo, " IAID:%u T1:%u T2:%u", EXTRACT_32BITS(&tp[0]), EXTRACT_32BITS(&tp[4]), @@ -586,7 +591,7 @@ dhcp6opt_print(netdissect_options *ndo, ND_PRINT((ndo, " ?)")); break; } - tp = (u_char *)(dh6o + 1); + tp = (const u_char *)(dh6o + 1); ND_PRINT((ndo, " IAID:%u", EXTRACT_32BITS(tp))); if (optlen > 4) { /* there are sub-options */ @@ -599,7 +604,7 @@ dhcp6opt_print(netdissect_options *ndo, ND_PRINT((ndo, " ?)")); break; } - tp = (u_char *)(dh6o + 1); + 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]), @@ -616,7 +621,7 @@ dhcp6opt_print(netdissect_options *ndo, ND_PRINT((ndo, " ?)")); break; } - tp = (u_char *)(dh6o + 1); + tp = (const u_char *)(dh6o + 1); ND_PRINT((ndo, " %d)", EXTRACT_32BITS(tp))); break; case DH6OPT_REMOTE_ID: @@ -624,7 +629,7 @@ dhcp6opt_print(netdissect_options *ndo, ND_PRINT((ndo, " ?)")); break; } - tp = (u_char *)(dh6o + 1); + tp = (const u_char *)(dh6o + 1); ND_PRINT((ndo, " %d ", EXTRACT_32BITS(tp))); /* * Print hex dump first 10 characters. @@ -638,7 +643,7 @@ dhcp6opt_print(netdissect_options *ndo, ND_PRINT((ndo, " ?)")); break; } - tp = (u_char *)(dh6o + 1); + tp = (const u_char *)(dh6o + 1); switch (*tp) { case 1: ND_PRINT((ndo, " by-address")); @@ -658,7 +663,7 @@ dhcp6opt_print(netdissect_options *ndo, ND_PRINT((ndo, ")")); break; case DH6OPT_CLIENT_DATA: - tp = (u_char *)(dh6o + 1); + tp = (const u_char *)(dh6o + 1); if (optlen > 0) { /* there are encapsulated options */ dhcp6opt_print(ndo, tp, tp + optlen); @@ -670,7 +675,7 @@ dhcp6opt_print(netdissect_options *ndo, ND_PRINT((ndo, " ?)")); break; } - tp = (u_char *)(dh6o + 1); + tp = (const u_char *)(dh6o + 1); ND_PRINT((ndo, " %s ", ip6addr_string(ndo, &tp[0]))); /* * Print hex dump first 10 characters. @@ -684,7 +689,7 @@ dhcp6opt_print(netdissect_options *ndo, ND_PRINT((ndo, " ?)")); break; } - tp = (u_char *)(dh6o + 1); + tp = (const u_char *)(dh6o + 1); while (tp < cp + sizeof(*dh6o) + optlen - 4) { subopt_code = EXTRACT_16BITS(tp); tp += 2; @@ -720,14 +725,14 @@ dhcp6opt_print(netdissect_options *ndo, ND_PRINT((ndo, " ?)")); break; } - tp = (u_char *)(dh6o + 1); + tp = (const u_char *)(dh6o + 1); remain_len = optlen; ND_PRINT((ndo, " ")); /* Encoding is described in section 3.1 of RFC 1035 */ while (remain_len && *tp) { label_len = *tp++; if (label_len < remain_len - 1) { - ND_PRINT((ndo, "%.*s", label_len, tp)); + (void)fn_printn(ndo, tp, label_len, NULL); tp += label_len; remain_len -= (label_len + 1); if(*tp) ND_PRINT((ndo, ".")); @@ -738,6 +743,19 @@ dhcp6opt_print(netdissect_options *ndo, } ND_PRINT((ndo, ")")); 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, " ?)")); + break; + } + tp = (const u_char *)(dh6o + 1); + ND_PRINT((ndo, "=")); + (void)fn_printn(ndo, tp, (u_int)optlen, NULL); + ND_PRINT((ndo, ")")); + break; + default: ND_PRINT((ndo, ")")); break; @@ -758,20 +776,20 @@ void dhcp6_print(netdissect_options *ndo, const u_char *cp, u_int length) { - struct dhcp6 *dh6; - struct dhcp6_relay *dh6relay; + const struct dhcp6 *dh6; + const struct dhcp6_relay *dh6relay; const u_char *ep; - u_char *extp; + const u_char *extp; const char *name; ND_PRINT((ndo, "dhcp6")); - ep = (u_char *)ndo->ndo_snapend; + ep = (const u_char *)ndo->ndo_snapend; if (cp + length < ep) ep = cp + length; - dh6 = (struct dhcp6 *)cp; - dh6relay = (struct dhcp6_relay *)cp; + 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); @@ -786,7 +804,7 @@ dhcp6_print(netdissect_options *ndo, 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)); - extp = (u_char *)(dh6 + 1); + extp = (const u_char *)(dh6 + 1); dhcp6opt_print(ndo, extp, ep); } else { /* relay messages */ struct in6_addr addr6; @@ -799,7 +817,7 @@ dhcp6_print(netdissect_options *ndo, memcpy(&addr6, dh6relay->dh6relay_peeraddr, sizeof (addr6)); ND_PRINT((ndo, " peeraddr=%s", ip6addr_string(ndo, &addr6))); - dhcp6opt_print(ndo, (u_char *)(dh6relay + 1), ep); + dhcp6opt_print(ndo, (const u_char *)(dh6relay + 1), ep); } /*(*/ ND_PRINT((ndo, ")")); diff --git a/contrib/tcpdump/print-domain.c b/contrib/tcpdump/print-domain.c index 4e2d378..d0b6996 100644 --- a/contrib/tcpdump/print-domain.c +++ b/contrib/tcpdump/print-domain.c @@ -17,24 +17,24 @@ * 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. - * - * $FreeBSD$ */ -#define NETDISSECT_REWORKED +/* \summary: Domain Name System (DNS) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include "nameser.h" #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" -#include "extract.h" /* must come after interface.h */ +#include "addrtostr.h" +#include "extract.h" static const char *ns_ops[] = { "", " inv_q", " stat", " op3", " notify", " update", " op6", " op7", @@ -397,7 +397,7 @@ ns_rprint(netdissect_options *ndo, } else if (ndo->ndo_vflag > 2) { /* print ttl */ ND_PRINT((ndo, " [")); - relts_print(ndo, EXTRACT_32BITS(cp)); + unsigned_relts_print(ndo, EXTRACT_32BITS(cp)); ND_PRINT((ndo, "]")); cp += 4; } else { @@ -483,17 +483,14 @@ ns_rprint(netdissect_options *ndo, EXTRACT_16BITS(cp), EXTRACT_16BITS(cp + 2))); break; -#ifdef INET6 case T_AAAA: { - struct in6_addr addr; char ntop_buf[INET6_ADDRSTRLEN]; if (!ND_TTEST2(*cp, sizeof(struct in6_addr))) return(NULL); - memcpy(&addr, cp, sizeof(struct in6_addr)); ND_PRINT((ndo, " %s", - inet_ntop(AF_INET6, &addr, ntop_buf, sizeof(ntop_buf)))); + addrtostr6(cp, ntop_buf, sizeof(ntop_buf)))); break; } @@ -517,7 +514,7 @@ ns_rprint(netdissect_options *ndo, memset(&a, 0, sizeof(a)); memcpy(&a.s6_addr[pbyte], cp + 1, sizeof(a) - pbyte); ND_PRINT((ndo, " %u %s", pbit, - inet_ntop(AF_INET6, &a, ntop_buf, sizeof(ntop_buf)))); + addrtostr6(&a, ntop_buf, sizeof(ntop_buf)))); } if (pbit > 0) { ND_PRINT((ndo, " ")); @@ -526,12 +523,11 @@ ns_rprint(netdissect_options *ndo, } break; } -#endif /*INET6*/ case T_OPT: ND_PRINT((ndo, " UDPsize=%u", class)); if (opt_flags & 0x8000) - ND_PRINT((ndo, " OK")); + ND_PRINT((ndo, " DO")); break; case T_UNSPECA: /* One long string */ @@ -668,7 +664,7 @@ ns_print(netdissect_options *ndo, DNS_CD(np) ? "%" : "")); /* any weirdness? */ - b2 = EXTRACT_16BITS(((u_short *)np)+1); + b2 = EXTRACT_16BITS(((const u_short *)np)+1); if (b2 & 0x6cf) ND_PRINT((ndo, " [b2&3=0x%x]", b2)); diff --git a/contrib/tcpdump/print-dtp.c b/contrib/tcpdump/print-dtp.c index 5d84a77..1d8c66a 100644 --- a/contrib/tcpdump/print-dtp.c +++ b/contrib/tcpdump/print-dtp.c @@ -12,22 +12,23 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * Dynamic Trunk Protocol (DTP) - * * Original code by Carles Kishimoto */ -#define NETDISSECT_REWORKED +/* \summary: Dynamic Trunking Protocol (DTP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" +static const char tstr[] = " [|dtp]"; + #define DTP_HEADER_LEN 1 #define DTP_DOMAIN_TLV 0x0001 #define DTP_STATUS_TLV 0x0002 @@ -71,30 +72,36 @@ dtp_print (netdissect_options *ndo, const u_char *pptr, u_int length) while (tptr < (pptr+length)) { ND_TCHECK2(*tptr, 4); - type = EXTRACT_16BITS(tptr); len = EXTRACT_16BITS(tptr+2); - - /* infinite loop check */ - if (type == 0 || len == 0) { + /* 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", tok2str(dtp_tlv_values, "Unknown", type), type, len)); + /* infinite loop check */ + if (len < 4) + goto invalid; + ND_TCHECK2(*tptr, len); + switch (type) { case DTP_DOMAIN_TLV: - ND_PRINT((ndo, ", %s", tptr+4)); + ND_PRINT((ndo, ", ")); + fn_printzp(ndo, tptr+4, len-4, pptr+length); break; case DTP_STATUS_TLV: case DTP_DTP_TYPE_TLV: + if (len < 5) + goto invalid; ND_PRINT((ndo, ", 0x%x", *(tptr+4))); break; case DTP_NEIGHBOR_TLV: + if (len < 10) + goto invalid; ND_PRINT((ndo, ", %s", etheraddr_string(ndo, tptr+4))); break; @@ -106,8 +113,11 @@ dtp_print (netdissect_options *ndo, const u_char *pptr, u_int length) return; + invalid: + ND_PRINT((ndo, "%s", istr)); + return; trunc: - ND_PRINT((ndo, "[|dtp]")); + ND_PRINT((ndo, "%s", tstr)); } /* diff --git a/contrib/tcpdump/print-dvmrp.c b/contrib/tcpdump/print-dvmrp.c index 96a0ee7..60f836e 100644 --- a/contrib/tcpdump/print-dvmrp.c +++ b/contrib/tcpdump/print-dvmrp.c @@ -19,14 +19,15 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: Distance Vector Multicast Routing Protocol printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "addrtoname.h" @@ -337,7 +338,7 @@ print_prune(netdissect_options *ndo, ND_PRINT((ndo, " src %s grp %s", ipaddr_string(ndo, bp), ipaddr_string(ndo, bp + 4))); bp += 8; ND_PRINT((ndo, " timer ")); - relts_print(ndo, EXTRACT_32BITS(bp)); + unsigned_relts_print(ndo, EXTRACT_32BITS(bp)); return (0); trunc: return (-1); diff --git a/contrib/tcpdump/print-eap.c b/contrib/tcpdump/print-eap.c index 0e2c2d3..125e1ee 100644 --- a/contrib/tcpdump/print-eap.c +++ b/contrib/tcpdump/print-eap.c @@ -16,19 +16,17 @@ * 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. - * - * Format and print EAP packets. - * */ -#define NETDISSECT_REWORKED +/* \summary: Extensible Authentication Protocol (EAP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #define EAP_FRAME_TYPE_PACKET 0 @@ -151,7 +149,7 @@ static const struct tok eap_aka_subtype_values[] = { void eap_print(netdissect_options *ndo, register const u_char *cp, - u_int length _U_) + u_int length) { const struct eap_frame_t *eap; const u_char *tptr; diff --git a/contrib/tcpdump/print-egp.c b/contrib/tcpdump/print-egp.c index 9c5c811..8fba9ce 100644 --- a/contrib/tcpdump/print-egp.c +++ b/contrib/tcpdump/print-egp.c @@ -18,14 +18,15 @@ * Initial contribution from Jeff Honig (jch@MITCHELL.CIT.CORNELL.EDU). */ -#define NETDISSECT_REWORKED +/* \summary: Exterior Gateway Protocol (EGP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" @@ -128,7 +129,7 @@ static const char *egp_reasons[] = { static void egpnrprint(netdissect_options *ndo, - register const struct egp_packet *egp) + register const struct egp_packet *egp, u_int length) { register const uint8_t *cp; uint32_t addr; @@ -152,12 +153,15 @@ egpnrprint(netdissect_options *ndo, net = 0; netlen = 0; } - cp = (uint8_t *)(egp + 1); + cp = (const uint8_t *)(egp + 1); + length -= sizeof(*egp); t_gateways = egp->egp_intgw + egp->egp_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); switch (netlen) { @@ -171,8 +175,12 @@ egpnrprint(netdissect_options *ndo, addr = (addr << 8) | *cp++; } addr |= net; + length -= 4 - netlen; + if (length < 1) + goto trunc; ND_TCHECK2(cp[0], 1); distances = *cp++; + length--; ND_PRINT((ndo, " %s %s ", gateways < (int)egp->egp_intgw ? "int" : "ext", ipaddr_string(ndo, &addr))); @@ -180,21 +188,33 @@ egpnrprint(netdissect_options *ndo, comma = ""; ND_PRINT((ndo, "(")); while (--distances >= 0) { + if (length < 2) + goto trunc; ND_TCHECK2(cp[0], 2); ND_PRINT((ndo, "%sd%d:", comma, (int)*cp++)); comma = ", "; networks = *cp++; + length -= 2; while (--networks >= 0) { /* Pickup network number */ + if (length < 1) + goto trunc; ND_TCHECK2(cp[0], 1); addr = (uint32_t)*cp++ << 24; + length--; if (IN_CLASSB(addr)) { + if (length < 1) + goto trunc; ND_TCHECK2(cp[0], 1); addr |= (uint32_t)*cp++ << 16; + 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; + length -= 2; } ND_PRINT((ndo, " %s", ipaddr_string(ndo, &addr))); } @@ -215,8 +235,8 @@ egp_print(netdissect_options *ndo, register int code; register int type; - egp = (struct egp_packet *)bp; - if (!ND_TTEST2(*egp, length)) { + egp = (const struct egp_packet *)bp; + if (length < sizeof(*egp) || !ND_TTEST(*egp)) { ND_PRINT((ndo, "[|egp]")); return; } @@ -333,7 +353,7 @@ egp_print(netdissect_options *ndo, egp->egp_intgw, egp->egp_extgw)); if (ndo->ndo_vflag) - egpnrprint(ndo, egp); + egpnrprint(ndo, egp, length); break; case EGPT_ERROR: diff --git a/contrib/tcpdump/print-eigrp.c b/contrib/tcpdump/print-eigrp.c index cab77ba..7e1ffb7 100644 --- a/contrib/tcpdump/print-eigrp.c +++ b/contrib/tcpdump/print-eigrp.c @@ -14,16 +14,17 @@ * FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: Enhanced Interior Gateway Routing Protocol (EIGRP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "addrtoname.h" diff --git a/contrib/tcpdump/print-enc.c b/contrib/tcpdump/print-enc.c index 7bd8631..d791b3f 100644 --- a/contrib/tcpdump/print-enc.c +++ b/contrib/tcpdump/print-enc.c @@ -21,14 +21,15 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: OpenBSD IPsec encapsulation BPF layer printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" /* From $OpenBSD: if_enc.h,v 1.8 2001/06/25 05:14:00 angelos Exp $ */ @@ -98,7 +99,7 @@ enc_if_print(netdissect_options *ndo, goto out; } - hdr = (struct enchdr *)p; + hdr = (const struct enchdr *)p; flags = hdr->flags; if (flags == 0) ND_PRINT((ndo, "(unprotected): ")); diff --git a/contrib/tcpdump/print-esp.c b/contrib/tcpdump/print-esp.c index 8e267d4..1115f36 100644 --- a/contrib/tcpdump/print-esp.c +++ b/contrib/tcpdump/print-esp.c @@ -21,12 +21,13 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: IPSEC Encapsulating Security Payload (ESP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include #include @@ -43,13 +44,14 @@ #endif #endif +#include "netdissect.h" +#include "strtoaddr.h" +#include "extract.h" + +#include "ascii_strcasecmp.h" + #include "ip.h" -#ifdef INET6 #include "ip6.h" -#endif - -#include "interface.h" -#include "extract.h" /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -98,9 +100,7 @@ struct newesp { #ifdef HAVE_LIBCRYPTO union inaddr_u { struct in_addr in4; -#ifdef INET6 struct in6_addr in6; -#endif }; struct sa_list { struct sa_list *next; @@ -119,6 +119,32 @@ struct sa_list { int secretlen; }; +#ifndef HAVE_EVP_CIPHER_CTX_NEW +/* + * Allocate an EVP_CIPHER_CTX. + * Used if we have an older version of OpenSSL that doesn't provide + * routines to allocate and free them. + */ +static EVP_CIPHER_CTX * +EVP_CIPHER_CTX_new(void) +{ + EVP_CIPHER_CTX *ctx; + + ctx = malloc(sizeof(*ctx)); + if (ctx == NULL) + return (NULL); + memset(ctx, 0, sizeof(*ctx)); + return (ctx); +} + +static void +EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) +{ + EVP_CIPHER_CTX_cleanup(ctx); + free(ctx); +} +#endif + /* * this will adjust ndo_packetp and ndo_snapend to new buffer! */ @@ -126,12 +152,12 @@ USES_APPLE_DEPRECATED_API int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo, int initiator, u_char spii[8], u_char spir[8], - u_char *buf, u_char *end) + const u_char *buf, const u_char *end) { struct sa_list *sa; - u_char *iv; + const u_char *iv; int len; - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX *ctx; /* initiator arg is any non-zero value */ if(initiator) initiator=1; @@ -159,12 +185,14 @@ int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo, if(end <= buf) return 0; - memset(&ctx, 0, sizeof(ctx)); - if (EVP_CipherInit(&ctx, sa->evp, sa->secret, NULL, 0) < 0) + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) + return 0; + if (EVP_CipherInit(ctx, sa->evp, sa->secret, NULL, 0) < 0) (*ndo->ndo_warning)(ndo, "espkey init failed"); - EVP_CipherInit(&ctx, NULL, NULL, iv, 0); - EVP_Cipher(&ctx, buf, buf, len); - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CipherInit(ctx, NULL, NULL, iv, 0); + EVP_Cipher(ctx, __DECONST(u_char *, buf), buf, len); + EVP_CIPHER_CTX_free(ctx); ndo->ndo_packetp = buf; ndo->ndo_snapend = end; @@ -332,8 +360,8 @@ espprint_decode_authalgo(netdissect_options *ndo, } *colon = '\0'; - if(strcasecmp(colon,"sha1") == 0 || - strcasecmp(colon,"md5") == 0) { + if(ascii_strcasecmp(colon,"sha1") == 0 || + ascii_strcasecmp(colon,"md5") == 0) { sa->authlen = 12; } return 1; @@ -427,22 +455,23 @@ static void esp_print_decode_onesecret(netdissect_options *ndo, char *line, } else decode = line; - if (spikey && strcasecmp(spikey, "file") == 0) { + if (spikey && ascii_strcasecmp(spikey, "file") == 0) { /* open file and read it */ FILE *secretfile; char fileline[1024]; - int lineno=0; + int subfile_lineno=0; char *nl; char *filename = line; secretfile = fopen(filename, FOPEN_READ_TXT); if (secretfile == NULL) { - perror(filename); - exit(3); + (*ndo->ndo_error)(ndo, "print_esp: can't open %s: %s\n", + filename, strerror(errno)); + return; } while (fgets(fileline, sizeof(fileline)-1, secretfile) != NULL) { - lineno++; + subfile_lineno++; /* remove newline from the line */ nl = strchr(fileline, '\n'); if (nl) @@ -450,14 +479,14 @@ static void esp_print_decode_onesecret(netdissect_options *ndo, char *line, if (fileline[0] == '#') continue; if (fileline[0] == '\0') continue; - esp_print_decode_onesecret(ndo, fileline, filename, lineno); + esp_print_decode_onesecret(ndo, fileline, filename, subfile_lineno); } fclose(secretfile); return; } - if (spikey && strcasecmp(spikey, "ikev2") == 0) { + if (spikey && ascii_strcasecmp(spikey, "ikev2") == 0) { esp_print_decode_ikeline(ndo, line, file, lineno); return; } @@ -477,17 +506,14 @@ static void esp_print_decode_onesecret(netdissect_options *ndo, char *line, sa1.spi = spino; -#ifdef INET6 - if (inet_pton(AF_INET6, spikey, &sa1.daddr.in6) == 1) { + if (strtoaddr6(spikey, &sa1.daddr.in6) == 1) { sa1.daddr_version = 6; - } else -#endif - if (inet_pton(AF_INET, spikey, &sa1.daddr.in4) == 1) { - sa1.daddr_version = 4; - } else { - (*ndo->ndo_warning)(ndo, "print_esp: can not decode IP# %s\n", spikey); - return; - } + } else if (strtoaddr(spikey, &sa1.daddr.in4) == 1) { + sa1.daddr_version = 4; + } else { + (*ndo->ndo_warning)(ndo, "print_esp: can not decode IP# %s\n", spikey); + return; + } } if (decode) { @@ -506,8 +532,14 @@ static void esp_print_decode_onesecret(netdissect_options *ndo, char *line, USES_APPLE_DEPRECATED_API static void esp_init(netdissect_options *ndo _U_) { - + /* + * 0.9.6 doesn't appear to define OPENSSL_API_COMPAT, so + * we check whether it's undefined or it's less than the + * value for 1.1.0. + */ +#if !defined(OPENSSL_API_COMPAT) || OPENSSL_API_COMPAT < 0x10100000L OpenSSL_add_all_algorithms(); +#endif EVP_add_cipher_alias(SN_des_ede3_cbc, "3des"); } USES_APPLE_RST @@ -564,21 +596,19 @@ esp_print(netdissect_options *ndo, register const struct newesp *esp; register const u_char *ep; #ifdef HAVE_LIBCRYPTO - struct ip *ip; + const struct ip *ip; struct sa_list *sa = NULL; -#ifdef INET6 - struct ip6_hdr *ip6 = NULL; -#endif + const struct ip6_hdr *ip6 = NULL; int advance; int len; u_char *secret; int ivlen = 0; - u_char *ivoff; - u_char *p; - EVP_CIPHER_CTX ctx; + const u_char *ivoff; + const u_char *p; + EVP_CIPHER_CTX *ctx; #endif - esp = (struct newesp *)bp; + esp = (const struct newesp *)bp; #ifdef HAVE_LIBCRYPTO secret = NULL; @@ -593,7 +623,7 @@ esp_print(netdissect_options *ndo, /* 'ep' points to the end of available data. */ ep = ndo->ndo_snapend; - if ((u_char *)(esp + 1) >= ep) { + if ((const u_char *)(esp + 1) >= ep) { ND_PRINT((ndo, "[|ESP]")); goto fail; } @@ -615,11 +645,10 @@ esp_print(netdissect_options *ndo, if (ndo->ndo_sa_list_head == NULL) goto fail; - ip = (struct ip *)bp2; + ip = (const struct ip *)bp2; switch (IP_V(ip)) { -#ifdef INET6 case 6: - ip6 = (struct ip6_hdr *)bp2; + ip6 = (const struct ip6_hdr *)bp2; /* we do not attempt to decrypt jumbograms */ if (!EXTRACT_16BITS(&ip6->ip6_plen)) goto fail; @@ -636,7 +665,6 @@ esp_print(netdissect_options *ndo, } } break; -#endif /*INET6*/ case 4: /* nexthdr & padding are in the last fragment */ if (EXTRACT_16BITS(&ip->ip_off) & IP_MF) @@ -675,21 +703,25 @@ esp_print(netdissect_options *ndo, ep = bp2 + len; } - ivoff = (u_char *)(esp + 1) + 0; + ivoff = (const u_char *)(esp + 1) + 0; ivlen = sa->ivlen; secret = sa->secret; ep = ep - sa->authlen; if (sa->evp) { - memset(&ctx, 0, sizeof(ctx)); - if (EVP_CipherInit(&ctx, sa->evp, secret, NULL, 0) < 0) - (*ndo->ndo_warning)(ndo, "espkey init failed"); - - p = ivoff; - EVP_CipherInit(&ctx, NULL, NULL, p, 0); - EVP_Cipher(&ctx, p + ivlen, p + ivlen, ep - (p + ivlen)); - EVP_CIPHER_CTX_cleanup(&ctx); - advance = ivoff - (u_char *)esp + ivlen; + ctx = EVP_CIPHER_CTX_new(); + if (ctx != NULL) { + if (EVP_CipherInit(ctx, sa->evp, secret, NULL, 0) < 0) + (*ndo->ndo_warning)(ndo, "espkey init failed"); + + p = ivoff; + EVP_CipherInit(ctx, NULL, NULL, p, 0); + EVP_Cipher(ctx, __DECONST(u_char *, p + ivlen), + p + ivlen, ep - (p + ivlen)); + EVP_CIPHER_CTX_free(ctx); + advance = ivoff - (const u_char *)esp + ivlen; + } else + advance = sizeof(struct newesp); } else advance = sizeof(struct newesp); diff --git a/contrib/tcpdump/print-ether.c b/contrib/tcpdump/print-ether.c index b96620f..bbfd7e9 100644 --- a/contrib/tcpdump/print-ether.c +++ b/contrib/tcpdump/print-ether.c @@ -17,18 +17,17 @@ * 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. - * - * $FreeBSD$ */ -#define NETDISSECT_REWORKED +/* \summary: Ethernet printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "addrtoname.h" #include "ethertype.h" @@ -85,6 +84,7 @@ const struct tok ethertype_values[] = { { ETHERTYPE_GEONET, "GeoNet"}, { ETHERTYPE_CALM_FAST, "CALM FAST"}, { ETHERTYPE_AOE, "AoE" }, + { ETHERTYPE_MEDSA, "MEDSA" }, { 0, NULL} }; @@ -93,7 +93,7 @@ ether_hdr_print(netdissect_options *ndo, const u_char *bp, u_int length) { register const struct ether_header *ep; - uint16_t ether_type; + uint16_t length_type; ep = (const struct ether_header *)bp; @@ -101,19 +101,21 @@ ether_hdr_print(netdissect_options *ndo, etheraddr_string(ndo, ESRC(ep)), etheraddr_string(ndo, EDST(ep)))); - ether_type = EXTRACT_16BITS(&ep->ether_type); + length_type = EXTRACT_16BITS(&ep->ether_length_type); if (!ndo->ndo_qflag) { - if (ether_type <= ETHERMTU) - ND_PRINT((ndo, ", 802.3")); - else - ND_PRINT((ndo, ", ethertype %s (0x%04x)", - tok2str(ethertype_values,"Unknown", ether_type), - ether_type)); + 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 (ether_type <= ETHERMTU) - ND_PRINT((ndo, ", 802.3")); - else - ND_PRINT((ndo, ", %s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", ether_type))); + 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((ndo, ", length %u: ", length)); @@ -124,20 +126,28 @@ ether_hdr_print(netdissect_options *ndo, * 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. */ -void +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) { - struct ether_header *ep; + const struct ether_header *ep; u_int orig_length; - u_short ether_type; - u_short extracted_ether_type; + u_short length_type; + u_int hdrlen; + int llc_hdrlen; + struct lladdr_info src, dst; - if (caplen < ETHER_HDRLEN || length < ETHER_HDRLEN) { + if (caplen < ETHER_HDRLEN) { + ND_PRINT((ndo, "[|ether]")); + return (caplen); + } + if (length < ETHER_HDRLEN) { ND_PRINT((ndo, "[|ether]")); - return; + return (length); } if (ndo->ndo_eflag) { @@ -149,55 +159,61 @@ ether_print(netdissect_options *ndo, length -= ETHER_HDRLEN; caplen -= ETHER_HDRLEN; - ep = (struct ether_header *)p; + ep = (const struct ether_header *)p; p += ETHER_HDRLEN; + hdrlen = ETHER_HDRLEN; - ether_type = EXTRACT_16BITS(&ep->ether_type); + src.addr = ESRC(ep); + src.addr_string = etheraddr_string; + dst.addr = EDST(ep); + dst.addr_string = etheraddr_string; + length_type = EXTRACT_16BITS(&ep->ether_length_type); recurse: /* * Is it (gag) an 802.3 encapsulation? */ - if (ether_type <= ETHERMTU) { + if (length_type <= ETHERMTU) { /* Try to print the LLC-layer header & higher layers */ - if (llc_print(ndo, p, length, caplen, ESRC(ep), EDST(ep), - &extracted_ether_type) == 0) { - /* ether_type not known, print raw packet */ - if (!ndo->ndo_eflag) { - if (print_encap_header != NULL) - (*print_encap_header)(ndo, encap_header_arg); - ether_hdr_print(ndo, (u_char *)ep, orig_length); - } - + 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; } - } else if (ether_type == ETHERTYPE_8021Q || - ether_type == ETHERTYPE_8021Q9100 || - ether_type == ETHERTYPE_8021Q9200 || - ether_type == ETHERTYPE_8021QinQ) { + hdrlen += llc_hdrlen; + } else if (length_type == ETHERTYPE_8021Q || + length_type == ETHERTYPE_8021Q9100 || + length_type == ETHERTYPE_8021Q9200 || + length_type == ETHERTYPE_8021QinQ) { /* * Print VLAN information, and then go back and process * the enclosed type field. */ - if (caplen < 4 || length < 4) { + if (caplen < 4) { + ND_PRINT((ndo, "[|vlan]")); + return (hdrlen + caplen); + } + if (length < 4) { ND_PRINT((ndo, "[|vlan]")); - return; + return (hdrlen + length); } if (ndo->ndo_eflag) { - uint16_t tag = EXTRACT_16BITS(p); + uint16_t tag = EXTRACT_16BITS(p); ND_PRINT((ndo, "%s, ", ieee8021q_tci_string(tag))); } - ether_type = EXTRACT_16BITS(p + 2); - if (ndo->ndo_eflag && ether_type > ETHERMTU) - ND_PRINT((ndo, "ethertype %s, ", tok2str(ethertype_values,"0x%04x", ether_type))); + 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))); p += 4; length -= 4; caplen -= 4; + hdrlen += 4; goto recurse; - } else if (ether_type == ETHERTYPE_JUMBO) { + } else if (length_type == ETHERTYPE_JUMBO) { /* * Alteon jumbo frames. * See @@ -208,53 +224,48 @@ recurse: * there's an LLC header and payload. */ /* Try to print the LLC-layer header & higher layers */ - if (llc_print(ndo, p, length, caplen, ESRC(ep), EDST(ep), - &extracted_ether_type) == 0) { - /* ether_type not known, print raw packet */ - if (!ndo->ndo_eflag) { - if (print_encap_header != NULL) - (*print_encap_header)(ndo, encap_header_arg); - ether_hdr_print(ndo, (u_char *)ep, orig_length); - } - + 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; } else { - if (ethertype_print(ndo, ether_type, p, length, caplen) == 0) { - /* ether_type not known, print raw packet */ + 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, (u_char *)ep, orig_length); + ether_hdr_print(ndo, (const u_char *)ep, orig_length); } if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); } } + return (hdrlen); } /* * This is the top level routine of the printer. 'p' points - * to the ether header of the packet, 'h->ts' is the timestamp, - * 'h->len' is the length of the packet off the wire, and 'h->caplen' - * is the number of bytes actually captured. + * to the ether header of the packet, 'h->len' is the length + * of the packet off the wire, and 'h->caplen' is the number + * of bytes actually captured. */ u_int ether_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { - ether_print(ndo, p, h->len, h->caplen, NULL, NULL); - - return (ETHER_HDRLEN); + return (ether_print(ndo, p, h->len, h->caplen, NULL, NULL)); } /* * 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. + * to the ether header of the packet, 'h->len' is the length + * of the packet off the wire, and 'h->caplen' is the number + * of bytes actually captured. * * This is for DLT_NETANALYZER, which has a 4-byte pseudo-header * before the Ethernet header. @@ -272,16 +283,14 @@ netanalyzer_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, } /* Skip the pseudo-header. */ - ether_print(ndo, p + 4, h->len - 4, h->caplen - 4, NULL, NULL); - - return (4 + ETHER_HDRLEN); + return (4 + ether_print(ndo, p + 4, h->len - 4, h->caplen - 4, NULL, NULL)); } /* * 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. + * to the ether header of the packet, 'h->len' is the length + * of the packet off the wire, and 'h->caplen' is the number + * of bytes actually captured. * * This is for DLT_NETANALYZER_TRANSPARENT, which has a 4-byte * pseudo-header, a 7-byte Ethernet preamble, and a 1-byte Ethernet SOF @@ -302,9 +311,7 @@ netanalyzer_transparent_if_print(netdissect_options *ndo, } /* Skip the pseudo-header, preamble, and SOF. */ - ether_print(ndo, p + 12, h->len - 12, h->caplen - 12, NULL, NULL); - - return (12 + ETHER_HDRLEN); + return (12 + ether_print(ndo, p + 12, h->len - 12, h->caplen - 12, NULL, NULL)); } /* @@ -317,7 +324,8 @@ 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) + u_int length, u_int caplen, + const struct lladdr_info *src, const struct lladdr_info *dst) { switch (ether_type) { @@ -331,7 +339,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: @@ -354,7 +362,11 @@ ethertype_print(netdissect_options *ndo, return (1); case ETHERTYPE_ISO: - isoclns_print(ndo, p + 1, length - 1, length - 1); + if (length == 0 || caplen == 0) { + ND_PRINT((ndo, " [|osi]")); + return (1); + } + isoclns_print(ndo, p + 1, length - 1, caplen - 1); return(1); case ETHERTYPE_PPPOED: @@ -369,7 +381,7 @@ ethertype_print(netdissect_options *ndo, return (1); case ETHERTYPE_RRCP: - rrcp_print(ndo, p - 14 , length + 14); + rrcp_print(ndo, p, length, src, dst); return (1); case ETHERTYPE_PPP: @@ -415,17 +427,21 @@ ethertype_print(netdissect_options *ndo, case ETHERTYPE_GEONET_OLD: case ETHERTYPE_GEONET: - geonet_print(ndo, p-14, p, length); + geonet_print(ndo, p, length, src); return (1); case ETHERTYPE_CALM_FAST: - calm_fast_print(ndo, p-14, p, length); + 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); + return (1); + case ETHERTYPE_LAT: case ETHERTYPE_SCA: case ETHERTYPE_MOPRC: diff --git a/contrib/tcpdump/print-fddi.c b/contrib/tcpdump/print-fddi.c index 2b53c45..2780378 100644 --- a/contrib/tcpdump/print-fddi.c +++ b/contrib/tcpdump/print-fddi.c @@ -17,20 +17,19 @@ * 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. - * - * $FreeBSD$ */ -#define NETDISSECT_REWORKED +/* \summary: Fiber Distributed Data Interface (FDDI) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "ether.h" @@ -86,9 +85,9 @@ struct fddi_header { * Some FDDI interfaces use bit-swapped addresses. */ #if defined(ultrix) || defined(__alpha) || defined(__bsdi) || defined(__NetBSD__) || defined(__linux__) -int fddi_bitswap = 0; +static int fddi_bitswap = 0; #else -int fddi_bitswap = 1; +static int fddi_bitswap = 1; #endif /* @@ -261,17 +260,11 @@ fddi_hdr_print(netdissect_options *ndo, srcname = etheraddr_string(ndo, fsrc); dstname = etheraddr_string(ndo, fdst); - if (ndo->ndo_vflag) - ND_PRINT((ndo, "%02x %s %s %d: ", - fddip->fddi_fc, - srcname, dstname, - length)); - else if (ndo->ndo_qflag) - ND_PRINT((ndo, "%s %s %d: ", srcname, dstname, length)); - else { + if (!ndo->ndo_qflag) print_fddi_fc(ndo, fddip->fddi_fc); - ND_PRINT((ndo, "%s %s %d: ", srcname, dstname, length)); - } + ND_PRINT((ndo, "%s > %s, length %u: ", + srcname, dstname, + length)); } static inline void @@ -280,16 +273,17 @@ fddi_smt_print(netdissect_options *ndo, const u_char *p _U_, u_int length _U_) ND_PRINT((ndo, "")); } -void +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; - u_short extracted_ethertype; + struct lladdr_info src, dst; + int llc_hdrlen; if (caplen < FDDI_HDRLEN) { ND_PRINT((ndo, "[|fddi]")); - return; + return (caplen); } /* @@ -300,6 +294,11 @@ fddi_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen) if (ndo->ndo_eflag) fddi_hdr_print(ndo, fddip, length, ESRC(&ehdr), EDST(&ehdr)); + src.addr = ESRC(&ehdr); + src.addr_string = etheraddr_string; + dst.addr = EDST(&ehdr); + dst.addr_string = etheraddr_string; + /* Skip over FDDI MAC header */ length -= FDDI_HDRLEN; p += FDDI_HDRLEN; @@ -308,32 +307,29 @@ fddi_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen) /* Frame Control field determines interpretation of packet */ if ((fddip->fddi_fc & FDDIFC_CLFF) == FDDIFC_LLC_ASYNC) { /* Try to print the LLC-layer header & higher layers */ - if (llc_print(ndo, p, length, caplen, ESRC(&ehdr), EDST(&ehdr), - &extracted_ethertype) == 0) { + llc_hdrlen = llc_print(ndo, p, length, caplen, &src, &dst); + if (llc_hdrlen < 0) { /* * Some kinds of LLC packet we cannot * handle intelligently */ - if (!ndo->ndo_eflag) - fddi_hdr_print(ndo, fddip, length + FDDI_HDRLEN, - ESRC(&ehdr), EDST(&ehdr)); - if (extracted_ethertype) { - ND_PRINT((ndo, "(LLC %s) ", - etherproto_string(htons(extracted_ethertype)))); - } if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); + llc_hdrlen = -llc_hdrlen; } - } else if ((fddip->fddi_fc & FDDIFC_CLFF) == FDDIFC_SMT) + } else if ((fddip->fddi_fc & FDDIFC_CLFF) == FDDIFC_SMT) { fddi_smt_print(ndo, p, caplen); - else { + 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)); if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); + llc_hdrlen = 0; } + return (FDDI_HDRLEN + llc_hdrlen); } /* @@ -345,7 +341,5 @@ fddi_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen) u_int fddi_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, register const u_char *p) { - fddi_print(ndo, p, h->len, h->caplen); - - return (FDDI_HDRLEN); + return (fddi_print(ndo, p, h->len, h->caplen)); } diff --git a/contrib/tcpdump/print-forces.c b/contrib/tcpdump/print-forces.c index 6c02b25..de6c826 100644 --- a/contrib/tcpdump/print-forces.c +++ b/contrib/tcpdump/print-forces.c @@ -14,21 +14,21 @@ * */ -#define NETDISSECT_REWORKED +/* \summary: Forwarding and Control Element Separation (ForCES) Protocol printer */ + +/* specification: RFC 5810 */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" static const char tstr[] = "[|forces]"; -/* - * RFC5810: Forwarding and Control Element Separation (ForCES) Protocol - */ #define ForCES_VERS 1 #define ForCES_HDRL 24 #define ForCES_ALNL 4U @@ -153,17 +153,17 @@ static const struct tok ForCES_TPs[] = { * Structure of forces header, naked of TLVs. */ struct forcesh { - uint8_t fm_vrsvd; /* version and reserved */ + nd_uint8_t fm_vrsvd; /* version and reserved */ #define ForCES_V(forcesh) ((forcesh)->fm_vrsvd >> 4) - uint8_t fm_tom; /* type of message */ - uint16_t fm_len; /* total length * 4 bytes */ + 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)) - uint32_t fm_sid; /* Source ID */ + nd_uint32_t fm_sid; /* Source ID */ #define ForCES_SID(forcesh) EXTRACT_32BITS(&(forcesh)->fm_sid) - uint32_t fm_did; /* Destination ID */ + nd_uint32_t fm_did; /* Destination ID */ #define ForCES_DID(forcesh) EXTRACT_32BITS(&(forcesh)->fm_did) - uint8_t fm_cor[8]; /* correlator */ - uint32_t fm_flags; /* flags */ + 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) @@ -223,7 +223,7 @@ enum { B_OP_REPORT = 1 << (F_OP_REPORT - 1), B_OP_COMMIT = 1 << (F_OP_COMMIT - 1), B_OP_RCOMMIT = 1 << (F_OP_RCOMMIT - 1), - B_OP_RTRCOMP = 1 << (F_OP_RTRCOMP - 1), + B_OP_RTRCOMP = 1 << (F_OP_RTRCOMP - 1) }; struct optlv_h { @@ -243,8 +243,8 @@ static int invoptlv_print(netdissect_options *, register const u_char * pptr, re #define OP_MIN_SIZ 8 struct pathdata_h { - uint16_t pflags; - uint16_t pIDcnt; + nd_uint16_t pflags; + nd_uint16_t pIDcnt; }; #define B_FULLD 0x1 @@ -288,7 +288,7 @@ static inline const struct optlv_h *get_forces_optlv_h(uint16_t opt) #define IND_CHR ' ' #define IND_PREF '\n' #define IND_SUF 0x0 -char ind_buf[IND_SIZE]; +static char ind_buf[IND_SIZE]; static inline char *indent_pr(int indent, int nlpref) { @@ -376,30 +376,30 @@ static inline int ttlv_valid(uint16_t ttlv) } struct forces_ilv { - uint32_t type; - uint32_t length; + nd_uint32_t type; + nd_uint32_t length; }; struct forces_tlv { - uint16_t type; - uint16_t length; + nd_uint16_t type; + nd_uint16_t length; }; #define F_ALN_LEN(len) ( ((len)+ForCES_ALNL-1) & ~(ForCES_ALNL-1) ) -#define GET_TOP_TLV(fhdr) ((struct forces_tlv *)((fhdr) + sizeof (struct forcesh))) +#define 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) ((void*)(((char*)(tlvp)) + 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)), \ - (struct forces_tlv*)(((char*)(tlv)) \ + (const struct forces_tlv*)(((const char*)(tlv)) \ + F_ALN_LEN(EXTRACT_16BITS(&(tlv)->length)))) #define ILV_SET_LEN(len) (F_ALN_LEN(ILV_HDRL) + (len)) #define ILV_ALN_LEN(len) F_ALN_LEN(ILV_SET_LEN(len)) #define ILV_RDAT_LEN(ilv) ((int)(EXTRACT_32BITS(&(ilv)->length)) - ILV_SET_LEN(0)) -#define ILV_DATA(ilvp) ((void*)(((char*)(ilvp)) + ILV_SET_LEN(0))) +#define 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)), \ - (struct forces_ilv *)(((char*)(ilv)) \ + (const struct forces_ilv *)(((const char*)(ilv)) \ + F_ALN_LEN(EXTRACT_32BITS(&(ilv)->length)))) #define INVALID_RLEN 1 #define INVALID_STLN 2 @@ -452,8 +452,8 @@ static int asttlv_print(netdissect_options *, register const u_char * pptr, regi uint16_t op_msk, int indent); struct forces_lfbsh { - uint32_t class; - uint32_t instance; + nd_uint32_t class; + nd_uint32_t instance; }; #define ASSNS_OPS (B_OP_REPORT) @@ -546,9 +546,9 @@ chk_op_type(netdissect_options *ndo, #define F_TABAPPEND 4 struct res_val { - uint8_t result; - uint8_t resv1; - uint16_t resv2; + nd_uint8_t result; + nd_uint8_t resv1; + nd_uint16_t resv2; }; static int prestlv_print(netdissect_options *, register const u_char * pptr, register u_int len, @@ -646,9 +646,9 @@ prestlv_print(netdissect_options *ndo, register const u_char * pptr, register u_int len, uint16_t op_msk _U_, int indent) { - const struct forces_tlv *tlv = (struct forces_tlv *)pptr; - register const u_char *tdp = (u_char *) TLV_DATA(tlv); - struct res_val *r = (struct res_val *)tdp; + const struct forces_tlv *tlv = (const struct forces_tlv *)pptr; + register const u_char *tdp = (const u_char *) TLV_DATA(tlv); + const struct res_val *r = (const struct res_val *)tdp; u_int dlen; /* @@ -684,9 +684,9 @@ fdatatlv_print(netdissect_options *ndo, register const u_char * pptr, register u_int len, uint16_t op_msk _U_, int indent) { - const struct forces_tlv *tlv = (struct forces_tlv *)pptr; + const struct forces_tlv *tlv = (const struct forces_tlv *)pptr; u_int rlen; - register const u_char *tdp = (u_char *) TLV_DATA(tlv); + register const u_char *tdp = (const u_char *) TLV_DATA(tlv); uint16_t type; /* @@ -720,7 +720,7 @@ sdatailv_print(netdissect_options *ndo, uint16_t op_msk _U_, int indent) { u_int rlen; - const struct forces_ilv *ilv = (struct forces_ilv *)pptr; + const struct forces_ilv *ilv = (const struct forces_ilv *)pptr; int invilv; if (len < ILV_HDRL) { @@ -734,7 +734,7 @@ sdatailv_print(netdissect_options *ndo, ND_PRINT((ndo, "Jamal - outstanding length <%d>\n", rlen)); #endif char *ib = indent_pr(indent, 1); - register const u_char *tdp = (u_char *) ILV_DATA(ilv); + register const u_char *tdp = (const u_char *) ILV_DATA(ilv); ND_TCHECK(*ilv); invilv = ilv_valid(ilv, rlen); if (invilv) { @@ -765,9 +765,9 @@ sdatatlv_print(netdissect_options *ndo, register const u_char * pptr, register u_int len, uint16_t op_msk, int indent) { - const struct forces_tlv *tlv = (struct forces_tlv *)pptr; + const struct forces_tlv *tlv = (const struct forces_tlv *)pptr; u_int rlen; - register const u_char *tdp = (u_char *) TLV_DATA(tlv); + register const u_char *tdp = (const u_char *) TLV_DATA(tlv); uint16_t type; /* @@ -794,10 +794,10 @@ pkeyitlv_print(netdissect_options *ndo, register const u_char * pptr, register u_int len, uint16_t op_msk, int indent) { - const struct forces_tlv *tlv = (struct forces_tlv *)pptr; - register const u_char *tdp = (u_char *) TLV_DATA(tlv); + 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 struct forces_tlv *kdtlv = (struct forces_tlv *)dp; + const struct forces_tlv *kdtlv = (const struct forces_tlv *)dp; uint32_t id; char *ib = indent_pr(indent, 0); uint16_t type, tll; @@ -822,7 +822,7 @@ pkeyitlv_print(netdissect_options *ndo, * go past the end of the containing TLV). */ tll = EXTRACT_16BITS(&kdtlv->length); - dp = (u_char *) TLV_DATA(kdtlv); + dp = (const u_char *) TLV_DATA(kdtlv); return fdatatlv_print(ndo, dp, tll, op_msk, indent); trunc: @@ -881,7 +881,7 @@ pdatacnt_print(netdissect_options *ndo, } if (op_msk & B_KEYIN) { - struct forces_tlv *keytlv; + const struct forces_tlv *keytlv; uint16_t tll; if (len < PTH_DESC_SIZE) { @@ -893,7 +893,7 @@ pdatacnt_print(netdissect_options *ndo, /* skip keyid */ pptr += 4; len -= 4; - keytlv = (struct forces_tlv *)pptr; + keytlv = (const struct forces_tlv *)pptr; /* skip header */ pptr += sizeof(struct forces_tlv); len -= sizeof(struct forces_tlv); @@ -916,7 +916,7 @@ pdatacnt_print(netdissect_options *ndo, } if (len) { - const struct forces_tlv *pdtlv = (struct forces_tlv *)pptr; + const struct forces_tlv *pdtlv = (const struct forces_tlv *)pptr; uint16_t type; uint16_t tll; int pad = 0; @@ -992,7 +992,7 @@ pdata_print(netdissect_options *ndo, register const u_char * pptr, register u_int len, uint16_t op_msk, int indent) { - const struct pathdata_h *pdh = (struct pathdata_h *)pptr; + const struct pathdata_h *pdh = (const struct pathdata_h *)pptr; char *ib = indent_pr(indent, 0); u_int minsize = 0; int more_pd = 0; @@ -1056,7 +1056,7 @@ genoptlv_print(netdissect_options *ndo, register const u_char * pptr, register u_int len, uint16_t op_msk, int indent) { - const struct forces_tlv *pdtlv = (struct forces_tlv *)pptr; + const struct forces_tlv *pdtlv = (const struct forces_tlv *)pptr; uint16_t type; int tll; u_int invtlv; @@ -1074,7 +1074,7 @@ genoptlv_print(netdissect_options *ndo, * length is large enough but not too large (it doesn't * go past the end of the containing TLV). */ - register const u_char *dp = (u_char *) TLV_DATA(pdtlv); + register 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", tok2str(ForCES_TLV_err, NULL, invtlv), type, @@ -1102,7 +1102,7 @@ recpdoptlv_print(netdissect_options *ndo, register const u_char * pptr, register u_int len, uint16_t op_msk, int indent) { - const struct forces_tlv *pdtlv = (struct forces_tlv *)pptr; + const struct forces_tlv *pdtlv = (const struct forces_tlv *)pptr; int tll; u_int invtlv; uint16_t type; @@ -1123,7 +1123,7 @@ recpdoptlv_print(netdissect_options *ndo, */ ib = indent_pr(indent, 0); type = EXTRACT_16BITS(&pdtlv->type); - dp = (u_char *) TLV_DATA(pdtlv); + dp = (const u_char *) TLV_DATA(pdtlv); tll = EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL; if (ndo->ndo_vflag >= 3) @@ -1171,7 +1171,7 @@ 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 = (u_char *) TLV_DATA(otlv); + register const u_char *dp = (const u_char *) TLV_DATA(otlv); uint16_t type; int tll; char *ib = indent_pr(indent, 0); @@ -1349,7 +1349,7 @@ print_metailv(netdissect_options *ndo, u_int rlen; char *ib = indent_pr(indent, 0); /* XXX: check header length */ - const struct forces_ilv *ilv = (struct forces_ilv *)pptr; + const struct forces_ilv *ilv = (const struct forces_ilv *)pptr; /* * print_metatlv() has ensured that len (what remains in the @@ -1378,7 +1378,7 @@ print_metatlv(netdissect_options *ndo, u_int dlen; char *ib = indent_pr(indent, 0); u_int rlen; - const struct forces_ilv *ilv = (struct forces_ilv *)pptr; + const struct forces_ilv *ilv = (const struct forces_ilv *)pptr; int invilv; /* @@ -1400,7 +1400,7 @@ print_metatlv(netdissect_options *ndo, * length is large enough but not too large (it doesn't * go past the end of the containing TLV). */ - print_metailv(ndo, (u_char *) ilv, 0, indent + 1); + print_metailv(ndo, (const u_char *) ilv, 0, indent + 1); ilv = GO_NXT_ILV(ilv, rlen); } @@ -1415,7 +1415,7 @@ trunc: static int print_reddata(netdissect_options *ndo, register const u_char * pptr, register u_int len, - uint16_t op_msk _U_, int indent _U_) + uint16_t op_msk _U_, int indent) { u_int dlen; char *ib = indent_pr(indent, 0); @@ -1439,7 +1439,7 @@ redirect_print(netdissect_options *ndo, register const u_char * pptr, register u_int len, uint16_t op_msk _U_, int indent) { - const struct forces_tlv *tlv = (struct forces_tlv *)pptr; + const struct forces_tlv *tlv = (const struct forces_tlv *)pptr; u_int dlen; u_int rlen; u_int invtlv; @@ -1471,10 +1471,10 @@ redirect_print(netdissect_options *ndo, * go past the end of the containing TLV). */ if (EXTRACT_16BITS(&tlv->type) == F_TLV_METD) { - print_metatlv(ndo, (u_char *) TLV_DATA(tlv), + print_metatlv(ndo, (const u_char *) TLV_DATA(tlv), EXTRACT_16BITS(&tlv->length), 0, indent); } else if ((EXTRACT_16BITS(&tlv->type) == F_TLV_REDD)) { - print_reddata(ndo, (u_char *) TLV_DATA(tlv), + print_reddata(ndo, (const u_char *) TLV_DATA(tlv), EXTRACT_16BITS(&tlv->length), 0, indent); } else { ND_PRINT((ndo, "Unknown REDIRECT TLV 0x%x len %d\n", @@ -1541,7 +1541,7 @@ lfbselect_print(netdissect_options *ndo, EXTRACT_32BITS(&lfbs->instance))); } - otlv = (struct forces_tlv *)(lfbs + 1); + otlv = (const struct forces_tlv *)(lfbs + 1); indent += 1; while (rlen != 0) { @@ -1563,7 +1563,7 @@ lfbselect_print(netdissect_options *ndo, 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))); - invoptlv_print(ndo, (u_char *)otlv, rlen, 0, indent); + invoptlv_print(ndo, (const u_char *)otlv, rlen, 0, indent); } otlv = GO_NXT_TLV(otlv, rlen); } @@ -1645,7 +1645,7 @@ forces_type_print(netdissect_options *ndo, EXTRACT_16BITS(&tltlv->length), EXTRACT_16BITS(&tltlv->length) - TLV_HDRL)); - rc = tops->print(ndo, (u_char *) TLV_DATA(tltlv), + rc = tops->print(ndo, (const u_char *) TLV_DATA(tltlv), EXTRACT_16BITS(&tltlv->length), tops->op_msk, 9); if (rc < 0) { return -1; diff --git a/contrib/tcpdump/print-fr.c b/contrib/tcpdump/print-fr.c index b7bec4b..da7ee25 100644 --- a/contrib/tcpdump/print-fr.c +++ b/contrib/tcpdump/print-fr.c @@ -17,21 +17,20 @@ * 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. - * - * $FreeBSD$ */ -#define NETDISSECT_REWORKED +/* \summary: Frame Relay printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "ethertype.h" #include "llc.h" @@ -277,7 +276,8 @@ fr_print(netdissect_options *ndo, if (ethertype_print(ndo, extracted_ethertype, p+addr_len+ETHERTYPE_LEN, length-addr_len-ETHERTYPE_LEN, - length-addr_len-ETHERTYPE_LEN) == 0) + ndo->ndo_snapend-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])); else @@ -329,11 +329,11 @@ fr_print(netdissect_options *ndo, case NLPID_CLNP: case NLPID_ESIS: case NLPID_ISIS: - isoclns_print(ndo, p - 1, length + 1, length + 1); /* OSI printers need the NLPID field */ + isoclns_print(ndo, p - 1, length + 1, ndo->ndo_snapend - p + 1); /* OSI printers need the NLPID field */ break; case NLPID_SNAP: - if (snap_print(ndo, p, length, length, 0) == 0) { + if (snap_print(ndo, p, length, ndo->ndo_snapend - 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, @@ -599,6 +599,10 @@ frf15_print(netdissect_options *ndo, { uint16_t sequence_num, flags; + if (length < 2) + goto trunc; + ND_TCHECK2(*p, 2); + flags = p[0]&MFR_BEC_MASK; sequence_num = (p[0]&0x1e)<<7 | p[1]; @@ -616,7 +620,10 @@ frf15_print(netdissect_options *ndo, * model is end-to-end or interface based wether we want to print * another Q.922 header */ + return; +trunc: + ND_PRINT((ndo, "[|frf.15]")); } /* @@ -684,7 +691,11 @@ static const struct tok fr_q933_msg_values[] = { { 0, NULL } }; -#define MSG_ANSI_LOCKING_SHIFT 0x95 +#define IE_IS_SINGLE_OCTET(iecode) ((iecode) & 0x80) +#define IE_IS_SHIFT(iecode) (((iecode) & 0xF0) == 0x90) +#define IE_SHIFT_IS_NON_LOCKING(iecode) ((iecode) & 0x08) +#define IE_SHIFT_IS_LOCKING(iecode) (!(IE_SHIFT_IS_NON_LOCKING(iecode))) +#define IE_SHIFT_CODESET(iecode) ((iecode) & 0x07) #define FR_LMI_ANSI_REPORT_TYPE_IE 0x01 #define FR_LMI_ANSI_LINK_VERIFY_IE_91 0x19 /* details? */ @@ -695,7 +706,7 @@ static const struct tok fr_q933_msg_values[] = { #define FR_LMI_CCITT_LINK_VERIFY_IE 0x53 #define FR_LMI_CCITT_PVC_STATUS_IE 0x57 -static const struct tok fr_q933_ie_values_codeset5[] = { +static const struct tok fr_q933_ie_values_codeset_0_5[] = { { FR_LMI_ANSI_REPORT_TYPE_IE, "ANSI Report Type" }, { FR_LMI_ANSI_LINK_VERIFY_IE_91, "ANSI Link Verify" }, { FR_LMI_ANSI_LINK_VERIFY_IE, "ANSI Link Verify" }, @@ -717,14 +728,14 @@ static const struct tok fr_lmi_report_type_ie_values[] = { { 0, NULL } }; -/* array of 16 codepages - currently we only support codepage 1,5 */ +/* array of 16 codesets - currently we only support codepage 0 and 5 */ static const struct tok *fr_q933_ie_codesets[] = { + fr_q933_ie_values_codeset_0_5, NULL, - fr_q933_ie_values_codeset5, NULL, NULL, NULL, - fr_q933_ie_values_codeset5, + fr_q933_ie_values_codeset_0_5, NULL, NULL, NULL, @@ -737,20 +748,20 @@ static const struct tok *fr_q933_ie_codesets[] = { NULL }; -static int fr_q933_print_ie_codeset5(netdissect_options *ndo, - const struct ie_tlv_header_t *ie_p, const u_char *p); +static int fr_q933_print_ie_codeset_0_5(netdissect_options *ndo, u_int iecode, + u_int ielength, const u_char *p); -typedef int (*codeset_pr_func_t)(netdissect_options *, - const struct ie_tlv_header_t *ie_p, const u_char *p); +typedef int (*codeset_pr_func_t)(netdissect_options *, u_int iecode, + u_int ielength, const u_char *p); -/* array of 16 codepages - currently we only support codepage 1,5 */ +/* array of 16 codesets - currently we only support codepage 0 and 5 */ static const codeset_pr_func_t fr_q933_print_ie_codeset[] = { + fr_q933_print_ie_codeset_0_5, NULL, - fr_q933_print_ie_codeset5, NULL, NULL, NULL, - fr_q933_print_ie_codeset5, + fr_q933_print_ie_codeset_0_5, NULL, NULL, NULL, @@ -763,121 +774,316 @@ static const codeset_pr_func_t fr_q933_print_ie_codeset[] = { NULL }; +/* + * ITU-T Q.933. + * + * p points to octet 2, the octet containing the length of the + * call reference value, so p[n] is octet n+2 ("octet X" is as + * used in Q.931/Q.933). + * + * XXX - actually used both for Q.931 and Q.933. + */ void q933_print(netdissect_options *ndo, const u_char *p, u_int length) { - const u_char *ptemp = p; - struct ie_tlv_header_t *ie_p; - int olen; - int is_ansi = 0; - u_int codeset; - u_int ie_is_known = 0; - - if (length < 9) { /* shortest: Q.933a LINK VERIFY */ - ND_PRINT((ndo, "[|q.933]")); - return; + u_int olen; + u_int call_ref_length, i; + uint8_t call_ref[15]; /* maximum length - length field is 4 bits */ + u_int msgtype; + u_int iecode; + u_int ielength; + u_int codeset = 0; + u_int is_ansi = 0; + u_int ie_is_known; + u_int non_locking_shift; + u_int unshift_codeset; + + ND_PRINT((ndo, "%s", ndo->ndo_eflag ? "" : "Q.933")); + + if (length == 0 || !ND_TTEST(*p)) { + if (!ndo->ndo_eflag) + ND_PRINT((ndo, ", ")); + ND_PRINT((ndo, "length %u", length)); + goto trunc; } - codeset = p[2]&0x0f; /* extract the codeset */ - - if (p[2] == MSG_ANSI_LOCKING_SHIFT) { - is_ansi = 1; + /* + * Get the length of the call reference value. + */ + olen = length; /* preserve the original length for display */ + call_ref_length = (*p) & 0x0f; + p++; + length--; + + /* + * Get the call reference value. + */ + for (i = 0; i < call_ref_length; i++) { + if (length == 0 || !ND_TTEST(*p)) { + if (!ndo->ndo_eflag) + ND_PRINT((ndo, ", ")); + ND_PRINT((ndo, "length %u", olen)); + goto trunc; + } + call_ref[i] = *p; + p++; + length--; } - ND_PRINT((ndo, "%s", ndo->ndo_eflag ? "" : "Q.933, ")); + /* + * Get the message type. + */ + if (length == 0 || !ND_TTEST(*p)) { + if (!ndo->ndo_eflag) + ND_PRINT((ndo, ", ")); + ND_PRINT((ndo, "length %u", olen)); + goto trunc; + } + msgtype = *p; + p++; + length--; + + /* + * Peek ahead to see if we start with a shift. + */ + non_locking_shift = 0; + unshift_codeset = codeset; + if (length != 0) { + if (!ND_TTEST(*p)) { + if (!ndo->ndo_eflag) + ND_PRINT((ndo, ", ")); + ND_PRINT((ndo, "length %u", olen)); + goto trunc; + } + iecode = *p; + if (IE_IS_SHIFT(iecode)) { + /* + * It's a shift. Skip over it. + */ + p++; + length--; + + /* + * Get the codeset. + */ + codeset = IE_SHIFT_CODESET(iecode); + + /* + * If it's a locking shift to codeset 5, + * mark this as ANSI. (XXX - 5 is actually + * for national variants in general, not + * the US variant in particular, but maybe + * this is more American exceptionalism. :-)) + */ + if (IE_SHIFT_IS_LOCKING(iecode)) { + /* + * It's a locking shift. + */ + if (codeset == 5) { + /* + * It's a locking shift to + * codeset 5, so this is + * T1.617 Annex D. + */ + is_ansi = 1; + } + } else { + /* + * It's a non-locking shift. + * Remember the current codeset, so we + * can revert to it after the next IE. + */ + non_locking_shift = 1; + unshift_codeset = 0; + } + } + } /* printing out header part */ + if (!ndo->ndo_eflag) + ND_PRINT((ndo, ", ")); ND_PRINT((ndo, "%s, codeset %u", is_ansi ? "ANSI" : "CCITT", codeset)); - if (p[0]) { - ND_PRINT((ndo, ", Call Ref: 0x%02x", p[0])); + if (call_ref_length != 0) { + ND_TCHECK(p[0]); + if (call_ref_length > 1 || p[0] != 0) { + /* + * Not a dummy call reference. + */ + ND_PRINT((ndo, ", Call Ref: 0x")); + for (i = 0; i < call_ref_length; i++) + ND_PRINT((ndo, "%02x", call_ref[i])); + } } - if (ndo->ndo_vflag) { - ND_PRINT((ndo, ", %s (0x%02x), length %u", - tok2str(fr_q933_msg_values, - "unknown message", p[1]), - p[1], - length)); - } else { - ND_PRINT((ndo, ", %s", + if (ndo->ndo_vflag) { + ND_PRINT((ndo, ", %s (0x%02x), length %u", + tok2str(fr_q933_msg_values, + "unknown message", msgtype), + msgtype, + olen)); + } else { + ND_PRINT((ndo, ", %s", tok2str(fr_q933_msg_values, - "unknown message 0x%02x", p[1]))); - } - - olen = length; /* preserve the original length for non verbose mode */ - - if (length < (u_int)(2 - is_ansi)) { - ND_PRINT((ndo, "[|q.933]")); - return; + "unknown message 0x%02x", msgtype))); } - length -= 2 + is_ansi; - ptemp += 2 + is_ansi; - - /* Loop through the rest of IE */ - while (length > sizeof(struct ie_tlv_header_t)) { - ie_p = (struct ie_tlv_header_t *)ptemp; - if (length < sizeof(struct ie_tlv_header_t) || - length < sizeof(struct ie_tlv_header_t) + ie_p->ie_len) { - if (ndo->ndo_vflag) { /* not bark if there is just a trailer */ - ND_PRINT((ndo, "\n[|q.933]")); - } else { - ND_PRINT((ndo, ", length %u", olen)); - } - return; - } - - /* lets do the full IE parsing only in verbose mode - * however some IEs (DLCI Status, Link Verify) - * are also interestting in non-verbose mode */ - if (ndo->ndo_vflag) { - ND_PRINT((ndo, "\n\t%s IE (0x%02x), length %u: ", - tok2str(fr_q933_ie_codesets[codeset], - "unknown", ie_p->ie_type), - ie_p->ie_type, - ie_p->ie_len)); - } - - /* sanity check */ - if (ie_p->ie_type == 0 || ie_p->ie_len == 0) { - return; - } - if (fr_q933_print_ie_codeset[codeset] != NULL) { - ie_is_known = fr_q933_print_ie_codeset[codeset](ndo, ie_p, ptemp); + /* Loop through the rest of the IEs */ + while (length != 0) { + /* + * What's the state of any non-locking shifts? + */ + if (non_locking_shift == 1) { + /* + * There's a non-locking shift in effect for + * this IE. Count it, so we reset the codeset + * before the next IE. + */ + non_locking_shift = 2; + } else if (non_locking_shift == 2) { + /* + * Unshift. + */ + codeset = unshift_codeset; + non_locking_shift = 0; } - if (ndo->ndo_vflag >= 1 && !ie_is_known) { - print_unknown_data(ndo, ptemp+2, "\n\t", ie_p->ie_len); + /* + * Get the first octet of the IE. + */ + if (!ND_TTEST(*p)) { + if (!ndo->ndo_vflag) { + ND_PRINT((ndo, ", length %u", olen)); + } + goto trunc; } + iecode = *p; + p++; + length--; - /* do we want to see a hexdump of the IE ? */ - if (ndo->ndo_vflag> 1 && ie_is_known) { - print_unknown_data(ndo, ptemp+2, "\n\t ", ie_p->ie_len); + /* Single-octet IE? */ + if (IE_IS_SINGLE_OCTET(iecode)) { + /* + * Yes. Is it a shift? + */ + if (IE_IS_SHIFT(iecode)) { + /* + * Yes. Is it locking? + */ + if (IE_SHIFT_IS_LOCKING(iecode)) { + /* + * Yes. + */ + non_locking_shift = 0; + } else { + /* + * No. Remember the current + * codeset, so we can revert + * to it after the next IE. + */ + non_locking_shift = 1; + unshift_codeset = codeset; + } + + /* + * Get the codeset. + */ + codeset = IE_SHIFT_CODESET(iecode); + } + } else { + /* + * No. Get the IE length. + */ + if (length == 0 || !ND_TTEST(*p)) { + if (!ndo->ndo_vflag) { + ND_PRINT((ndo, ", length %u", olen)); + } + goto trunc; + } + ielength = *p; + p++; + length--; + + /* lets do the full IE parsing only in verbose mode + * 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: ", + tok2str(fr_q933_ie_codesets[codeset], + "unknown", iecode), + iecode, + ielength)); + } + + /* sanity checks */ + if (iecode == 0 || ielength == 0) { + return; + } + if (length < ielength || !ND_TTEST2(*p, ielength)) { + if (!ndo->ndo_vflag) { + ND_PRINT((ndo, ", length %u", olen)); + } + goto trunc; + } + + ie_is_known = 0; + if (fr_q933_print_ie_codeset[codeset] != NULL) { + ie_is_known = fr_q933_print_ie_codeset[codeset](ndo, iecode, ielength, p); + } + + if (ie_is_known) { + /* + * Known IE; do we want to see a hexdump + * of it? + */ + if (ndo->ndo_vflag > 1) { + /* Yes. */ + print_unknown_data(ndo, p, "\n\t ", ielength); + } + } else { + /* + * Unknown IE; if we're printing verbosely, + * print its content in hex. + */ + if (ndo->ndo_vflag >= 1) { + print_unknown_data(ndo, p, "\n\t", ielength); + } + } + + length -= ielength; + p += ielength; } - - length = length - ie_p->ie_len - 2; - ptemp = ptemp + ie_p->ie_len + 2; } - if (!ndo->ndo_vflag) { - ND_PRINT((ndo, ", length %u", olen)); + if (!ndo->ndo_vflag) { + ND_PRINT((ndo, ", length %u", olen)); } + return; + +trunc: + ND_PRINT((ndo, "[|q.933]")); } static int -fr_q933_print_ie_codeset5(netdissect_options *ndo, - const struct ie_tlv_header_t *ie_p, const u_char *p) +fr_q933_print_ie_codeset_0_5(netdissect_options *ndo, u_int iecode, + u_int ielength, const u_char *p) { u_int dlci; - switch (ie_p->ie_type) { + switch (iecode) { case FR_LMI_ANSI_REPORT_TYPE_IE: /* fall through */ case FR_LMI_CCITT_REPORT_TYPE_IE: + if (ielength < 1) { + if (!ndo->ndo_vflag) { + ND_PRINT((ndo, ", ")); + } + ND_PRINT((ndo, "Invalid REPORT TYPE IE")); + return 1; + } if (ndo->ndo_vflag) { ND_PRINT((ndo, "%s (%u)", - tok2str(fr_lmi_report_type_ie_values,"unknown",p[2]), - p[2])); + tok2str(fr_lmi_report_type_ie_values,"unknown",p[0]), + p[0])); } return 1; @@ -887,7 +1093,11 @@ fr_q933_print_ie_codeset5(netdissect_options *ndo, if (!ndo->ndo_vflag) { ND_PRINT((ndo, ", ")); } - ND_PRINT((ndo, "TX Seq: %3d, RX Seq: %3d", p[2], p[3])); + if (ielength < 2) { + ND_PRINT((ndo, "Invalid LINK VERIFY IE")); + return 1; + } + ND_PRINT((ndo, "TX Seq: %3d, RX Seq: %3d", p[0], p[1])); return 1; case FR_LMI_ANSI_PVC_STATUS_IE: /* fall through */ @@ -896,28 +1106,29 @@ fr_q933_print_ie_codeset5(netdissect_options *ndo, ND_PRINT((ndo, ", ")); } /* now parse the DLCI information element. */ - if ((ie_p->ie_len < 3) || - (p[2] & 0x80) || - ((ie_p->ie_len == 3) && !(p[3] & 0x80)) || - ((ie_p->ie_len == 4) && ((p[3] & 0x80) || !(p[4] & 0x80))) || - ((ie_p->ie_len == 5) && ((p[3] & 0x80) || (p[4] & 0x80) || - !(p[5] & 0x80))) || - (ie_p->ie_len > 5) || - !(p[ie_p->ie_len + 1] & 0x80)) { - ND_PRINT((ndo, "Invalid DLCI IE")); + 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))) || + (ielength > 5) || + !(p[ielength - 1] & 0x80)) { + ND_PRINT((ndo, "Invalid DLCI in PVC STATUS IE")); + return 1; } - dlci = ((p[2] & 0x3F) << 4) | ((p[3] & 0x78) >> 3); - if (ie_p->ie_len == 4) { - dlci = (dlci << 6) | ((p[4] & 0x7E) >> 1); + dlci = ((p[0] & 0x3F) << 4) | ((p[1] & 0x78) >> 3); + if (ielength == 4) { + dlci = (dlci << 6) | ((p[2] & 0x7E) >> 1); } - else if (ie_p->ie_len == 5) { - dlci = (dlci << 13) | (p[4] & 0x7F) | ((p[5] & 0x7E) >> 1); + else if (ielength == 5) { + dlci = (dlci << 13) | (p[2] & 0x7F) | ((p[3] & 0x7E) >> 1); } ND_PRINT((ndo, "DLCI %u: status %s%s", dlci, - p[ie_p->ie_len + 1] & 0x8 ? "New, " : "", - p[ie_p->ie_len + 1] & 0x2 ? "Active" : "Inactive")); + p[ielength - 1] & 0x8 ? "New, " : "", + p[ielength - 1] & 0x2 ? "Active" : "Inactive")); return 1; } diff --git a/contrib/tcpdump/print-frag6.c b/contrib/tcpdump/print-frag6.c index 1290952..db4a98e 100644 --- a/contrib/tcpdump/print-frag6.c +++ b/contrib/tcpdump/print-frag6.c @@ -19,17 +19,16 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: IPv6 fragmentation header printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#ifdef INET6 - -#include +#include #include "ip6.h" -#include "interface.h" +#include "netdissect.h" #include "extract.h" int @@ -68,4 +67,3 @@ trunc: ND_PRINT((ndo, "[|frag]")); return -1; } -#endif /* INET6 */ diff --git a/contrib/tcpdump/print-ftp.c b/contrib/tcpdump/print-ftp.c index 5479042..a1dd607 100644 --- a/contrib/tcpdump/print-ftp.c +++ b/contrib/tcpdump/print-ftp.c @@ -11,16 +11,13 @@ * FOR A PARTICULAR PURPOSE. */ -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header$"; -#endif +/* \summary: File Transfer Protocol (FTP) printer */ #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include #include diff --git a/contrib/tcpdump/print-geneve.c b/contrib/tcpdump/print-geneve.c index 2187ab8..40402ab 100644 --- a/contrib/tcpdump/print-geneve.c +++ b/contrib/tcpdump/print-geneve.c @@ -15,19 +15,20 @@ * FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: Generic Network Virtualization Encapsulation (Geneve) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "ethertype.h" /* - * Geneve header, draft-gross-geneve-02 + * Geneve header, draft-ietf-nvo3-geneve * * 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 @@ -77,12 +78,25 @@ static const struct tok geneve_flag_values[] = { static const char * format_opt_class(uint16_t opt_class) { - if (opt_class <= 0xff) - return "Standard"; - else if (opt_class == 0xffff) - return "Experimental"; - else - return "Unknown"; + switch (opt_class) { + case 0x0100: + return "Linux"; + case 0x0101: + return "Open vSwitch"; + case 0x0102: + return "Open Virtual Networking (OVN)"; + case 0x0103: + return "In-band Network Telemetry (INT)"; + case 0x0104: + return "VMware"; + default: + if (opt_class <= 0x00ff) + return "Standard"; + else if (opt_class >= 0xfff0) + return "Experimental"; + } + + return "Unknown"; } static void @@ -112,14 +126,14 @@ geneve_opts_print(netdissect_options *ndo, const u_char *bp, u_int len) } if (ndo->ndo_vflag > 1 && opt_len > 4) { - uint32_t *print_data = (uint32_t *)(bp + 4); + const uint32_t *data = (const uint32_t *)(bp + 4); int i; ND_PRINT((ndo, " data")); for (i = 4; i < opt_len; i += 4) { - ND_PRINT((ndo, " %08x", EXTRACT_32BITS(print_data))); - print_data++; + ND_PRINT((ndo, " %08x", EXTRACT_32BITS(data))); + data++; } } @@ -132,7 +146,7 @@ void geneve_print(netdissect_options *ndo, const u_char *bp, u_int len) { uint8_t ver_opt; - uint version; + u_int version; uint8_t flags; uint16_t prot; uint32_t vni; @@ -184,7 +198,7 @@ geneve_print(netdissect_options *ndo, const u_char *bp, u_int len) if (len < opts_len) { ND_PRINT((ndo, " truncated-geneve - %u bytes missing", - len - opts_len)); + opts_len - len)); return; } @@ -209,9 +223,9 @@ geneve_print(netdissect_options *ndo, const u_char *bp, u_int len) else ND_PRINT((ndo, "\n\t")); - if (ethertype_print(ndo, prot, bp, len, len) == 0) { + if (ethertype_print(ndo, prot, bp, len, ndo->ndo_snapend - bp, NULL, NULL) == 0) { if (prot == ETHERTYPE_TEB) - ether_print(ndo, bp, len, len, NULL, NULL); + ether_print(ndo, bp, len, ndo->ndo_snapend - bp, NULL, NULL); else ND_PRINT((ndo, "geneve-proto-0x%x", prot)); } diff --git a/contrib/tcpdump/print-geonet.c b/contrib/tcpdump/print-geonet.c index edfb7f2..9da89bf 100644 --- a/contrib/tcpdump/print-geonet.c +++ b/contrib/tcpdump/print-geonet.c @@ -15,14 +15,15 @@ * Original code by Ola Martin Lykkja (ola.lykkja@q-free.com) */ -#define NETDISSECT_REWORKED +/* \summary: ISO CALM FAST and ETSI GeoNetworking printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "addrtoname.h" @@ -85,6 +86,8 @@ print_long_pos_vector(netdissect_options *ndo, { 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)) @@ -102,7 +105,8 @@ print_long_pos_vector(netdissect_options *ndo, * to the geonet header of the packet. */ void -geonet_print(netdissect_options *ndo, const u_char *eth, const u_char *bp, u_int length) +geonet_print(netdissect_options *ndo, const u_char *bp, u_int length, + const struct lladdr_info *src) { int version; int next_hdr; @@ -114,13 +118,16 @@ geonet_print(netdissect_options *ndo, const u_char *eth, const u_char *bp, u_int const char *hdr_type_txt = "Unknown"; int hdr_size = -1; - ND_PRINT((ndo, "GeoNet src:%s; ", etheraddr_string(ndo, eth+6))); + ND_PRINT((ndo, "GeoNet ")); + if (src != NULL) + ND_PRINT((ndo, "src:%s", (src->addr_string)(ndo, src->addr))); + ND_PRINT((ndo, "; ")); /* Process Common Header */ if (length < 36) - goto malformed; - - ND_TCHECK2(*bp, 7); + goto invalid; + + ND_TCHECK2(*bp, 8); version = bp[0] >> 4; next_hdr = bp[0] & 0x0f; hdr_type = bp[1] >> 4; @@ -224,7 +231,7 @@ geonet_print(netdissect_options *ndo, const u_char *eth, const u_char *bp, u_int /* Skip Extended headers */ if (hdr_size >= 0) { if (length < (u_int)hdr_size) - goto malformed; + goto invalid; ND_TCHECK2(*bp, hdr_size); length -= hdr_size; bp += hdr_size; @@ -234,7 +241,7 @@ geonet_print(netdissect_options *ndo, const u_char *eth, const u_char *bp, u_int case 1: case 2: /* BTP A/B */ if (length < 4) - goto malformed; + goto invalid; ND_TCHECK2(*bp, 4); print_btp(ndo, bp); length -= 4; @@ -261,7 +268,7 @@ geonet_print(netdissect_options *ndo, const u_char *eth, const u_char *bp, u_int ND_DEFAULTPRINT(bp, length); return; -malformed: +invalid: ND_PRINT((ndo, " Malformed (small) ")); /* XXX - print the remaining data as hex? */ return; diff --git a/contrib/tcpdump/print-gre.c b/contrib/tcpdump/print-gre.c index 4d7705f..505752a 100644 --- a/contrib/tcpdump/print-gre.c +++ b/contrib/tcpdump/print-gre.c @@ -31,21 +31,23 @@ * POSSIBILITY OF SUCH DAMAGE. */ +/* \summary: Generic Routing Encapsulation (GRE) printer */ + /* - * tcpdump filter for GRE - Generic Routing Encapsulation + * netdissect printer for GRE - Generic Routing Encapsulation * RFC1701 (GRE), RFC1702 (GRE IPv4), and RFC2637 (Enhanced GRE) */ -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" +#include "addrtostr.h" #include "extract.h" #include "ethertype.h" @@ -78,19 +80,18 @@ static const struct tok gre_flag_values[] = { static void gre_print_0(netdissect_options *, const u_char *, u_int); static void gre_print_1(netdissect_options *, const u_char *, u_int); -static void gre_sre_print(netdissect_options *, uint16_t, uint8_t, uint8_t, const u_char *, u_int); -static void gre_sre_ip_print(netdissect_options *, uint8_t, uint8_t, const u_char *, u_int); -static void gre_sre_asn_print(netdissect_options *, uint8_t, uint8_t, const u_char *, u_int); +static int gre_sre_print(netdissect_options *, uint16_t, uint8_t, uint8_t, const u_char *, u_int); +static int gre_sre_ip_print(netdissect_options *, uint8_t, uint8_t, const u_char *, u_int); +static int gre_sre_asn_print(netdissect_options *, uint8_t, uint8_t, const u_char *, u_int); void gre_print(netdissect_options *ndo, const u_char *bp, u_int length) { u_int len = length, vers; - if (len < 2) { - ND_PRINT((ndo, "%s", tstr)); - return; - } + ND_TCHECK2(*bp, 2); + if (len < 2) + goto trunc; vers = EXTRACT_16BITS(bp) & GRE_VERS_MASK; ND_PRINT((ndo, "GREv%u",vers)); @@ -105,6 +106,11 @@ gre_print(netdissect_options *ndo, const u_char *bp, u_int length) ND_PRINT((ndo, " ERROR: unknown-version")); break; } + return; + +trunc: + ND_PRINT((ndo, "%s", tstr)); + return; } static void @@ -121,6 +127,7 @@ gre_print_0(netdissect_options *ndo, const u_char *bp, u_int length) len -= 2; bp += 2; + ND_TCHECK2(*bp, 2); if (len < 2) goto trunc; prot = EXTRACT_16BITS(bp); @@ -128,6 +135,7 @@ gre_print_0(netdissect_options *ndo, const u_char *bp, u_int length) bp += 2; if ((flags & GRE_CP) | (flags & GRE_RP)) { + ND_TCHECK2(*bp, 2); if (len < 2) goto trunc; if (ndo->ndo_vflag) @@ -135,6 +143,7 @@ gre_print_0(netdissect_options *ndo, const u_char *bp, u_int length) bp += 2; len -= 2; + ND_TCHECK2(*bp, 2); if (len < 2) goto trunc; ND_PRINT((ndo, ", off 0x%x", EXTRACT_16BITS(bp))); @@ -143,6 +152,7 @@ gre_print_0(netdissect_options *ndo, const u_char *bp, u_int length) } if (flags & GRE_KP) { + ND_TCHECK2(*bp, 4); if (len < 4) goto trunc; ND_PRINT((ndo, ", key=0x%x", EXTRACT_32BITS(bp))); @@ -151,6 +161,7 @@ gre_print_0(netdissect_options *ndo, const u_char *bp, u_int length) } if (flags & GRE_SP) { + ND_TCHECK2(*bp, 4); if (len < 4) goto trunc; ND_PRINT((ndo, ", seq %u", EXTRACT_32BITS(bp))); @@ -164,6 +175,7 @@ gre_print_0(netdissect_options *ndo, const u_char *bp, u_int length) uint8_t sreoff; uint8_t srelen; + ND_TCHECK2(*bp, 4); if (len < 4) goto trunc; af = EXTRACT_16BITS(bp); @@ -175,7 +187,8 @@ gre_print_0(netdissect_options *ndo, const u_char *bp, u_int length) if (af == 0 && srelen == 0) break; - gre_sre_print(ndo, af, sreoff, srelen, bp, len); + if (!gre_sre_print(ndo, af, sreoff, srelen, bp, len)) + goto trunc; if (len < srelen) goto trunc; @@ -213,10 +226,10 @@ gre_print_0(netdissect_options *ndo, const u_char *bp, u_int length) atalk_print(ndo, bp, len); break; case ETHERTYPE_GRE_ISO: - isoclns_print(ndo, bp, len, len); + isoclns_print(ndo, bp, len, ndo->ndo_snapend - bp); break; case ETHERTYPE_TEB: - ether_print(ndo, bp, len, len, NULL, NULL); + ether_print(ndo, bp, len, ndo->ndo_snapend - bp, NULL, NULL); break; default: ND_PRINT((ndo, "gre-proto-0x%x", prot)); @@ -241,6 +254,7 @@ gre_print_1(netdissect_options *ndo, const u_char *bp, u_int length) ND_PRINT((ndo, ", Flags [%s]", bittok2str(gre_flag_values,"none",flags))); + ND_TCHECK2(*bp, 2); if (len < 2) goto trunc; prot = EXTRACT_16BITS(bp); @@ -251,6 +265,7 @@ gre_print_1(netdissect_options *ndo, const u_char *bp, u_int length) if (flags & GRE_KP) { uint32_t k; + ND_TCHECK2(*bp, 4); if (len < 4) goto trunc; k = EXTRACT_32BITS(bp); @@ -260,6 +275,7 @@ gre_print_1(netdissect_options *ndo, const u_char *bp, u_int length) } if (flags & GRE_SP) { + ND_TCHECK2(*bp, 4); if (len < 4) goto trunc; ND_PRINT((ndo, ", seq %u", EXTRACT_32BITS(bp))); @@ -268,6 +284,7 @@ gre_print_1(netdissect_options *ndo, const u_char *bp, u_int length) } if (flags & GRE_AP) { + ND_TCHECK2(*bp, 4); if (len < 4) goto trunc; ND_PRINT((ndo, ", ack %u", EXTRACT_32BITS(bp))); @@ -307,62 +324,68 @@ trunc: ND_PRINT((ndo, "%s", tstr)); } -static void +static int gre_sre_print(netdissect_options *ndo, uint16_t af, uint8_t sreoff, uint8_t srelen, const u_char *bp, u_int len) { + int ret; + switch (af) { case GRESRE_IP: ND_PRINT((ndo, ", (rtaf=ip")); - gre_sre_ip_print(ndo, sreoff, srelen, bp, len); - ND_PRINT((ndo, ") ")); + ret = gre_sre_ip_print(ndo, sreoff, srelen, bp, len); + ND_PRINT((ndo, ")")); break; case GRESRE_ASN: ND_PRINT((ndo, ", (rtaf=asn")); - gre_sre_asn_print(ndo, sreoff, srelen, bp, len); - ND_PRINT((ndo, ") ")); + ret = gre_sre_asn_print(ndo, sreoff, srelen, bp, len); + ND_PRINT((ndo, ")")); break; default: - ND_PRINT((ndo, ", (rtaf=0x%x) ", af)); + ND_PRINT((ndo, ", (rtaf=0x%x)", af)); + ret = 1; } + return (ret); } -static void +static int gre_sre_ip_print(netdissect_options *ndo, uint8_t sreoff, uint8_t srelen, const u_char *bp, u_int len) { - struct in_addr a; const u_char *up = bp; + char buf[INET_ADDRSTRLEN]; if (sreoff & 3) { ND_PRINT((ndo, ", badoffset=%u", sreoff)); - return; + return (1); } if (srelen & 3) { ND_PRINT((ndo, ", badlength=%u", srelen)); - return; + return (1); } if (sreoff >= srelen) { ND_PRINT((ndo, ", badoff/len=%u/%u", sreoff, srelen)); - return; + return (1); } - for (;;) { - if (len < 4 || srelen == 0) - return; + while (srelen != 0) { + if (!ND_TTEST2(*bp, 4)) + return (0); + if (len < 4) + return (0); - memcpy(&a, bp, sizeof(a)); + addrtostr(bp, buf, sizeof(buf)); ND_PRINT((ndo, " %s%s", - ((bp - up) == sreoff) ? "*" : "", - inet_ntoa(a))); + ((bp - up) == sreoff) ? "*" : "", buf)); bp += 4; len -= 4; srelen -= 4; } + return (1); } -static void +static int gre_sre_asn_print(netdissect_options *ndo, uint8_t sreoff, uint8_t srelen, const u_char *bp, u_int len) { @@ -370,20 +393,22 @@ gre_sre_asn_print(netdissect_options *ndo, uint8_t sreoff, uint8_t srelen, if (sreoff & 1) { ND_PRINT((ndo, ", badoffset=%u", sreoff)); - return; + return (1); } if (srelen & 1) { ND_PRINT((ndo, ", badlength=%u", srelen)); - return; + return (1); } if (sreoff >= srelen) { ND_PRINT((ndo, ", badoff/len=%u/%u", sreoff, srelen)); - return; + return (1); } - for (;;) { - if (len < 2 || srelen == 0) - return; + while (srelen != 0) { + if (!ND_TTEST2(*bp, 2)) + return (0); + if (len < 2) + return (0); ND_PRINT((ndo, " %s%x", ((bp - up) == sreoff) ? "*" : "", @@ -393,4 +418,5 @@ gre_sre_asn_print(netdissect_options *ndo, uint8_t sreoff, uint8_t srelen, len -= 2; srelen -= 2; } + return (1); } diff --git a/contrib/tcpdump/print-hncp.c b/contrib/tcpdump/print-hncp.c new file mode 100644 index 0000000..87ee8bb --- /dev/null +++ b/contrib/tcpdump/print-hncp.c @@ -0,0 +1,855 @@ +/* + * Copyright (c) 2016 Antonin Décimo, Jean-Raphaël Gaglione + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* \summary: Home Networking Control Protocol (HNCP) printer */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "netdissect.h" +#include "addrtoname.h" +#include "extract.h" + +static void +hncp_print_rec(netdissect_options *ndo, + const u_char *cp, u_int length, int indent); + +void +hncp_print(netdissect_options *ndo, + const u_char *cp, u_int length) +{ + ND_PRINT((ndo, "hncp (%d)", length)); + hncp_print_rec(ndo, cp, length, 1); +} + +/* RFC7787 */ +#define DNCP_REQUEST_NETWORK_STATE 1 +#define DNCP_REQUEST_NODE_STATE 2 +#define DNCP_NODE_ENDPOINT 3 +#define DNCP_NETWORK_STATE 4 +#define DNCP_NODE_STATE 5 +#define DNCP_PEER 8 +#define DNCP_KEEP_ALIVE_INTERVAL 9 +#define DNCP_TRUST_VERDICT 10 + +/* RFC7788 */ +#define HNCP_HNCP_VERSION 32 +#define HNCP_EXTERNAL_CONNECTION 33 +#define HNCP_DELEGATED_PREFIX 34 +#define HNCP_PREFIX_POLICY 43 +#define HNCP_DHCPV4_DATA 37 +#define HNCP_DHCPV6_DATA 38 +#define HNCP_ASSIGNED_PREFIX 35 +#define HNCP_NODE_ADDRESS 36 +#define HNCP_DNS_DELEGATED_ZONE 39 +#define HNCP_DOMAIN_NAME 40 +#define HNCP_NODE_NAME 41 +#define HNCP_MANAGED_PSK 42 + +/* See type_mask in hncp_print_rec below */ +#define RANGE_DNCP_RESERVED 0x10000 +#define RANGE_HNCP_UNASSIGNED 0x10001 +#define RANGE_DNCP_PRIVATE_USE 0x10002 +#define RANGE_DNCP_FUTURE_USE 0x10003 + +static const struct tok type_values[] = { + { DNCP_REQUEST_NETWORK_STATE, "Request network state" }, + { DNCP_REQUEST_NODE_STATE, "Request node state" }, + { DNCP_NODE_ENDPOINT, "Node endpoint" }, + { DNCP_NETWORK_STATE, "Network state" }, + { DNCP_NODE_STATE, "Node state" }, + { DNCP_PEER, "Peer" }, + { DNCP_KEEP_ALIVE_INTERVAL, "Keep-alive interval" }, + { DNCP_TRUST_VERDICT, "Trust-Verdict" }, + + { HNCP_HNCP_VERSION, "HNCP-Version" }, + { HNCP_EXTERNAL_CONNECTION, "External-Connection" }, + { HNCP_DELEGATED_PREFIX, "Delegated-Prefix" }, + { HNCP_PREFIX_POLICY, "Prefix-Policy" }, + { HNCP_DHCPV4_DATA, "DHCPv4-Data" }, + { HNCP_DHCPV6_DATA, "DHCPv6-Data" }, + { HNCP_ASSIGNED_PREFIX, "Assigned-Prefix" }, + { HNCP_NODE_ADDRESS, "Node-Address" }, + { HNCP_DNS_DELEGATED_ZONE, "DNS-Delegated-Zone" }, + { HNCP_DOMAIN_NAME, "Domain-Name" }, + { HNCP_NODE_NAME, "Node-Name" }, + { HNCP_MANAGED_PSK, "Managed-PSK" }, + + { RANGE_DNCP_RESERVED, "Reserved" }, + { RANGE_HNCP_UNASSIGNED, "Unassigned" }, + { RANGE_DNCP_PRIVATE_USE, "Private use" }, + { RANGE_DNCP_FUTURE_USE, "Future use" }, + + { 0, NULL} +}; + +#define DH4OPT_DNS_SERVERS 6 /* RFC2132 */ +#define DH4OPT_NTP_SERVERS 42 /* RFC2132 */ +#define DH4OPT_DOMAIN_SEARCH 119 /* RFC3397 */ + +static const struct tok dh4opt_str[] = { + { DH4OPT_DNS_SERVERS, "DNS-server" }, + { DH4OPT_NTP_SERVERS, "NTP-server"}, + { DH4OPT_DOMAIN_SEARCH, "DNS-search" }, + { 0, NULL } +}; + +#define DH6OPT_DNS_SERVERS 23 /* RFC3646 */ +#define DH6OPT_DOMAIN_LIST 24 /* RFC3646 */ +#define DH6OPT_SNTP_SERVERS 31 /* RFC4075 */ + +static const struct tok dh6opt_str[] = { + { DH6OPT_DNS_SERVERS, "DNS-server" }, + { DH6OPT_DOMAIN_LIST, "DNS-search-list" }, + { DH6OPT_SNTP_SERVERS, "SNTP-servers" }, + { 0, NULL } +}; + +/* + * For IPv4-mapped IPv6 addresses, length of the prefix that precedes + * the 4 bytes of IPv4 address at the end of the IPv6 address. + */ +#define IPV4_MAPPED_HEADING_LEN 12 + +/* + * Is an IPv6 address an IPv4-mapped address? + */ +static inline int +is_ipv4_mapped_address(const u_char *addr) +{ + /* The value of the prefix */ + static const u_char ipv4_mapped_heading[IPV4_MAPPED_HEADING_LEN] = + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF }; + + return memcmp(addr, ipv4_mapped_heading, IPV4_MAPPED_HEADING_LEN) == 0; +} + +static const char * +format_nid(const u_char *data) +{ + static char buf[4][11+5]; + static int i = 0; + i = (i + 1) % 4; + snprintf(buf[i], 16, "%02x:%02x:%02x:%02x", + data[0], data[1], data[2], data[3]); + return buf[i]; +} + +static const char * +format_256(const u_char *data) +{ + static char buf[4][64+5]; + static int i = 0; + i = (i + 1) % 4; + snprintf(buf[i], 28, "%016" PRIx64 "%016" PRIx64 "%016" PRIx64 "%016" PRIx64, + EXTRACT_64BITS(data), + EXTRACT_64BITS(data + 8), + EXTRACT_64BITS(data + 16), + EXTRACT_64BITS(data + 24) + ); + return buf[i]; +} + +static const char * +format_interval(const uint32_t n) +{ + static char buf[4][sizeof("0000000.000s")]; + static int i = 0; + i = (i + 1) % 4; + snprintf(buf[i], sizeof(buf[i]), "%u.%03us", n / 1000, n % 1000); + return buf[i]; +} + +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); + else + return ip6addr_string(ndo, cp); +} + +static int +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; + u_int plen; + + plen = prefix[0]-96; + if (32 < plen) + return -1; + max_length -= 1; + + memset(&addr, 0, sizeof(addr)); + 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); + if (plen % 8) { + ((u_char *)&addr)[plenbytes - 1] &= + ((0xff00 >> (plen % 8)) & 0xff); + } + snprintf(buf, sizeof(buf), "%s/%d", ipaddr_string(ndo, &addr), plen); + plenbytes += 1 + IPV4_MAPPED_HEADING_LEN; + } else { + plenbytes = decode_prefix6(ndo, prefix, max_length, buf, sizeof(buf)); + } + + ND_PRINT((ndo, "%s", buf)); + return plenbytes; +} + +static int +print_dns_label(netdissect_options *ndo, + const u_char *cp, u_int max_length, int print) +{ + u_int length = 0; + while (length < max_length) { + u_int lab_length = cp[length++]; + if (lab_length == 0) + return (int)length; + if (length > 1 && print) + safeputchar(ndo, '.'); + if (length+lab_length > max_length) { + if (print) + safeputs(ndo, cp+length, max_length-length); + break; + } + if (print) + safeputs(ndo, cp+length, lab_length); + length += lab_length; + } + if (print) + ND_PRINT((ndo, "[|DNS]")); + return -1; +} + +static int +dhcpv4_print(netdissect_options *ndo, + const u_char *cp, u_int length, int indent) +{ + u_int i, t; + const u_char *tlv, *value; + uint8_t type, optlen; + + i = 0; + while (i < length) { + tlv = cp + i; + type = (uint8_t)tlv[0]; + optlen = (uint8_t)tlv[1]; + value = tlv + 2; + + ND_PRINT((ndo, "\n")); + for (t = indent; t > 0; t--) + ND_PRINT((ndo, "\t")); + + ND_PRINT((ndo, "%s", tok2str(dh4opt_str, "Unknown", type))); + ND_PRINT((ndo," (%u)", optlen + 2 )); + + switch (type) { + case DH4OPT_DNS_SERVERS: + case DH4OPT_NTP_SERVERS: { + if (optlen < 4 || optlen % 4 != 0) { + return -1; + } + for (t = 0; t < optlen; t += 4) + ND_PRINT((ndo, " %s", ipaddr_string(ndo, 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) + return -1; + } + } + break; + } + + i += 2 + optlen; + } + return 0; +} + +static int +dhcpv6_print(netdissect_options *ndo, + const u_char *cp, u_int length, int indent) +{ + u_int i, t; + const u_char *tlv, *value; + uint16_t type, optlen; + + i = 0; + while (i < length) { + tlv = cp + i; + type = EXTRACT_16BITS(tlv); + optlen = EXTRACT_16BITS(tlv + 2); + value = tlv + 4; + + ND_PRINT((ndo, "\n")); + for (t = indent; t > 0; t--) + ND_PRINT((ndo, "\t")); + + ND_PRINT((ndo, "%s", tok2str(dh6opt_str, "Unknown", type))); + ND_PRINT((ndo," (%u)", optlen + 4 )); + + switch (type) { + case DH6OPT_DNS_SERVERS: + case DH6OPT_SNTP_SERVERS: { + if (optlen % 16 != 0) { + ND_PRINT((ndo, " %s", istr)); + return -1; + } + for (t = 0; t < optlen; t += 16) + ND_PRINT((ndo, " %s", ip6addr_string(ndo, 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) + return -1; + } + } + break; + } + + i += 4 + optlen; + } + return 0; +} + +/* Determine in-line mode */ +static int +is_in_line(netdissect_options *ndo, int indent) +{ + return indent - 1 >= ndo->ndo_vflag && ndo->ndo_vflag < 3; +} + +static void +print_type_in_line(netdissect_options *ndo, + uint32_t type, int count, int indent, int *first_one) +{ + if (count > 0) { + if (*first_one) { + *first_one = 0; + if (indent > 1) { + u_int t; + ND_PRINT((ndo, "\n")); + for (t = indent; t > 0; t--) + ND_PRINT((ndo, "\t")); + } else { + ND_PRINT((ndo, " ")); + } + } else { + ND_PRINT((ndo, ", ")); + } + ND_PRINT((ndo, "%s", tok2str(type_values, "Easter Egg", type))); + if (count > 1) + ND_PRINT((ndo, " (x%d)", count)); + } +} + +void +hncp_print_rec(netdissect_options *ndo, + const u_char *cp, u_int length, int indent) +{ + const int in_line = is_in_line(ndo, indent); + int first_one = 1; + + u_int i, t; + + uint32_t last_type_mask = 0xffffffffU; + int last_type_count = -1; + + const u_char *tlv, *value; + uint16_t type, bodylen; + uint32_t type_mask; + + i = 0; + while (i < length) { + tlv = cp + i; + + if (!in_line) { + ND_PRINT((ndo, "\n")); + for (t = indent; t > 0; t--) + ND_PRINT((ndo, "\t")); + } + + ND_TCHECK2(*tlv, 4); + if (i + 4 > length) + goto invalid; + + type = EXTRACT_16BITS(tlv); + bodylen = EXTRACT_16BITS(tlv + 2); + value = tlv + 4; + ND_TCHECK2(*value, bodylen); + if (i + bodylen + 4 > length) + goto invalid; + + type_mask = + (type == 0) ? RANGE_DNCP_RESERVED: + (44 <= type && type <= 511) ? RANGE_HNCP_UNASSIGNED: + (768 <= type && type <= 1023) ? RANGE_DNCP_PRIVATE_USE: + RANGE_DNCP_FUTURE_USE; + if (type == 6 || type == 7) + type_mask = RANGE_DNCP_FUTURE_USE; + + /* defined types */ + { + t = 0; + while (1) { + u_int key = type_values[t++].v; + if (key > 0xffff) + break; + if (key == type) { + type_mask = type; + break; + } + } + } + + if (in_line) { + if (last_type_mask == type_mask) { + last_type_count++; + } else { + print_type_in_line(ndo, last_type_mask, last_type_count, indent, &first_one); + last_type_mask = type_mask; + last_type_count = 1; + } + + goto skip_multiline; + } + + ND_PRINT((ndo,"%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 )); + + switch (type_mask) { + + case DNCP_REQUEST_NETWORK_STATE: { + if (bodylen != 0) + ND_PRINT((ndo, " %s", istr)); + } + break; + + case DNCP_REQUEST_NODE_STATE: { + const char *node_identifier; + if (bodylen != 4) { + ND_PRINT((ndo, " %s", istr)); + break; + } + node_identifier = format_nid(value); + ND_PRINT((ndo, " NID: %s", node_identifier)); + } + break; + + case DNCP_NODE_ENDPOINT: { + const char *node_identifier; + uint32_t endpoint_identifier; + if (bodylen != 8) { + ND_PRINT((ndo, " %s", istr)); + break; + } + node_identifier = format_nid(value); + endpoint_identifier = EXTRACT_32BITS(value + 4); + ND_PRINT((ndo, " NID: %s EPID: %08x", + node_identifier, + endpoint_identifier + )); + } + break; + + case DNCP_NETWORK_STATE: { + uint64_t hash; + if (bodylen != 8) { + ND_PRINT((ndo, " %s", istr)); + break; + } + hash = EXTRACT_64BITS(value); + ND_PRINT((ndo, " hash: %016" PRIx64, hash)); + } + break; + + case DNCP_NODE_STATE: { + const char *node_identifier, *interval; + uint32_t sequence_number; + uint64_t hash; + if (bodylen < 20) { + ND_PRINT((ndo, " %s", istr)); + 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, + sequence_number, + interval, + hash + )); + hncp_print_rec(ndo, value+20, bodylen-20, indent+1); + } + break; + + case DNCP_PEER: { + const char *peer_node_identifier; + uint32_t peer_endpoint_identifier, endpoint_identifier; + if (bodylen != 12) { + ND_PRINT((ndo, " %s", istr)); + 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, + peer_endpoint_identifier, + endpoint_identifier + )); + } + break; + + case DNCP_KEEP_ALIVE_INTERVAL: { + uint32_t endpoint_identifier; + const char *interval; + if (bodylen < 8) { + ND_PRINT((ndo, " %s", istr)); + break; + } + endpoint_identifier = EXTRACT_32BITS(value); + interval = format_interval(EXTRACT_32BITS(value + 4)); + ND_PRINT((ndo, " EPID: %08x Interval: %s", + endpoint_identifier, + interval + )); + } + break; + + case DNCP_TRUST_VERDICT: { + if (bodylen <= 36) { + ND_PRINT((ndo, " %s", istr)); + break; + } + ND_PRINT((ndo, " Verdict: %u Fingerprint: %s Common Name: ", + *value, + format_256(value + 4))); + safeputs(ndo, value + 36, bodylen - 36); + } + break; + + case HNCP_HNCP_VERSION: { + uint16_t capabilities; + uint8_t M, P, H, L; + if (bodylen < 5) { + ND_PRINT((ndo, " %s", istr)); + break; + } + capabilities = EXTRACT_16BITS(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: ", + M, P, H, L + )); + safeputs(ndo, value + 4, bodylen - 4); + } + break; + + case HNCP_EXTERNAL_CONNECTION: { + /* Container TLV */ + hncp_print_rec(ndo, value, bodylen, indent+1); + } + break; + + case HNCP_DELEGATED_PREFIX: { + int l; + if (bodylen < 9 || bodylen < 9 + (value[8] + 7) / 8) { + ND_PRINT((ndo, " %s", istr)); + break; + } + ND_PRINT((ndo, " VLSO: %s PLSO: %s Prefix: ", + format_interval(EXTRACT_32BITS(value)), + format_interval(EXTRACT_32BITS(value + 4)) + )); + l = print_prefix(ndo, value + 8, bodylen - 8); + if (l == -1) { + ND_PRINT((ndo, "(length is invalid)")); + break; + } + if (l < 0) { + /* + * We've already checked that we've captured the + * entire TLV, based on its length, so this will + * either be -1, meaning "the prefix length is + * greater than the longest possible address of + * that type" (i.e., > 32 for IPv4 or > 128 for + * IPv6", or -3, meaning "the prefix runs past + * the end of the TLV". + */ + ND_PRINT((ndo, " %s", istr)); + break; + } + l += 8 + (-l & 3); + + if (bodylen >= l) + hncp_print_rec(ndo, value + l, bodylen - l, indent+1); + } + break; + + case HNCP_PREFIX_POLICY: { + uint8_t policy; + int l; + if (bodylen < 1) { + ND_PRINT((ndo, " %s", istr)); + break; + } + policy = value[0]; + ND_PRINT((ndo, " type: ")); + if (policy == 0) { + if (bodylen != 1) { + ND_PRINT((ndo, " %s", istr)); + break; + } + ND_PRINT((ndo, "Internet connectivity")); + } else if (policy >= 1 && policy <= 128) { + ND_PRINT((ndo, "Dest-Prefix: ")); + l = print_prefix(ndo, value, bodylen); + if (l == -1) { + ND_PRINT((ndo, "(length is invalid)")); + break; + } + if (l < 0) { + /* + * We've already checked that we've captured the + * entire TLV, based on its length, so this will + * either be -1, meaning "the prefix length is + * greater than the longest possible address of + * that type" (i.e., > 32 for IPv4 or > 128 for + * IPv6", or -3, meaning "the prefix runs past + * the end of the TLV". + */ + ND_PRINT((ndo, " %s", istr)); + break; + } + } else if (policy == 129) { + ND_PRINT((ndo, "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); + } else if (policy == 131) { + if (bodylen != 1) { + ND_PRINT((ndo, " %s", istr)); + break; + } + ND_PRINT((ndo, "Restrictive assignment")); + } else if (policy >= 132) { + ND_PRINT((ndo, "Unknown (%u)", policy)); /* Reserved for future additions */ + } + } + break; + + case HNCP_DHCPV4_DATA: { + if (bodylen == 0) { + ND_PRINT((ndo, " %s", istr)); + break; + } + if (dhcpv4_print(ndo, value, bodylen, indent+1) != 0) + goto invalid; + } + break; + + case HNCP_DHCPV6_DATA: { + if (bodylen == 0) { + ND_PRINT((ndo, " %s", istr)); + break; + } + if (dhcpv6_print(ndo, value, bodylen, indent+1) != 0) { + ND_PRINT((ndo, " %s", istr)); + break; + } + } + break; + + case HNCP_ASSIGNED_PREFIX: { + uint8_t prty; + int l; + if (bodylen < 6 || bodylen < 6 + (value[5] + 7) / 8) { + ND_PRINT((ndo, " %s", istr)); + break; + } + prty = (uint8_t)(value[4] & 0xf); + ND_PRINT((ndo, " EPID: %08x Prty: %u", + EXTRACT_32BITS(value), + prty + )); + ND_PRINT((ndo, " Prefix: ")); + if ((l = print_prefix(ndo, value + 5, bodylen - 5)) < 0) { + ND_PRINT((ndo, " %s", istr)); + break; + } + l += 5; + l += -l & 3; + + if (bodylen >= l) + hncp_print_rec(ndo, value + l, bodylen - l, indent+1); + } + break; + + case HNCP_NODE_ADDRESS: { + uint32_t endpoint_identifier; + const char *ip_address; + if (bodylen < 20) { + ND_PRINT((ndo, " %s", istr)); + break; + } + endpoint_identifier = EXTRACT_32BITS(value); + ip_address = format_ip6addr(ndo, value + 4); + ND_PRINT((ndo, " EPID: %08x IP Address: %s", + endpoint_identifier, + ip_address + )); + + hncp_print_rec(ndo, value + 20, bodylen - 20, indent+1); + } + break; + + case HNCP_DNS_DELEGATED_ZONE: { + const char *ip_address; + int len; + if (bodylen < 17) { + ND_PRINT((ndo, " %s", istr)); + break; + } + ip_address = format_ip6addr(ndo, value); + ND_PRINT((ndo, " IP-Address: %s %c%c%c ", + ip_address, + (value[16] & 4) ? 'l' : '-', + (value[16] & 2) ? 'b' : '-', + (value[16] & 1) ? 's' : '-' + )); + len = print_dns_label(ndo, value+17, bodylen-17, 1); + if (len < 0) { + ND_PRINT((ndo, " %s", istr)); + break; + } + len += 17; + len += -len & 3; + if (bodylen >= len) + hncp_print_rec(ndo, value+len, bodylen-len, indent+1); + } + break; + + case HNCP_DOMAIN_NAME: { + if (bodylen == 0) { + ND_PRINT((ndo, " %s", istr)); + break; + } + ND_PRINT((ndo, " Domain: ")); + print_dns_label(ndo, value, bodylen, 1); + } + break; + + case HNCP_NODE_NAME: { + u_int l; + if (bodylen < 17) { + ND_PRINT((ndo, " %s", istr)); + break; + } + l = value[16]; + if (bodylen < 17 + l) { + ND_PRINT((ndo, " %s", istr)); + break; + } + ND_PRINT((ndo, " IP-Address: %s Name: ", + format_ip6addr(ndo, value) + )); + if (l < 64) { + safeputchar(ndo, '"'); + safeputs(ndo, value + 17, l); + safeputchar(ndo, '"'); + } else { + ND_PRINT((ndo, "%s", istr)); + } + l += 17; + l += -l & 3; + if (bodylen >= l) + hncp_print_rec(ndo, value + l, bodylen - l, indent+1); + } + break; + + case HNCP_MANAGED_PSK: { + if (bodylen < 32) { + ND_PRINT((ndo, " %s", istr)); + break; + } + ND_PRINT((ndo, " PSK: %s", format_256(value))); + hncp_print_rec(ndo, value + 32, bodylen - 32, indent+1); + } + break; + + case RANGE_DNCP_RESERVED: + case RANGE_HNCP_UNASSIGNED: + case RANGE_DNCP_PRIVATE_USE: + case RANGE_DNCP_FUTURE_USE: + break; + + } + skip_multiline: + + i += 4 + bodylen + (-bodylen & 3); + } + print_type_in_line(ndo, last_type_mask, last_type_count, indent, &first_one); + + return; + + trunc: + ND_PRINT((ndo, "%s", "[|hncp]")); + return; + + invalid: + ND_PRINT((ndo, "%s", istr)); + return; +} diff --git a/contrib/tcpdump/print-hsrp.c b/contrib/tcpdump/print-hsrp.c index 0e2420f..3514646 100644 --- a/contrib/tcpdump/print-hsrp.c +++ b/contrib/tcpdump/print-hsrp.c @@ -27,16 +27,17 @@ * SUCH DAMAGE. */ +/* \summary: Cisco Hot Standby Router Protocol (HSRP) printer */ + /* Cisco Hot Standby Router Protocol (HSRP). */ -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" /* HSRP op code types. */ @@ -94,7 +95,7 @@ struct hsrp { void hsrp_print(netdissect_options *ndo, register const uint8_t *bp, register u_int len) { - struct hsrp *hp = (struct hsrp *) bp; + const struct hsrp *hp = (const struct hsrp *) bp; ND_TCHECK(hp->hsrp_version); ND_PRINT((ndo, "HSRPv%d", hp->hsrp_version)); @@ -116,9 +117,9 @@ hsrp_print(netdissect_options *ndo, register const uint8_t *bp, register u_int l ND_PRINT((ndo, "addr=%s", ipaddr_string(ndo, &hp->hsrp_virtaddr))); if (ndo->ndo_vflag) { ND_PRINT((ndo, " hellotime=")); - relts_print(ndo, hp->hsrp_hellotime); + unsigned_relts_print(ndo, hp->hsrp_hellotime); ND_PRINT((ndo, " holdtime=")); - relts_print(ndo, hp->hsrp_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), diff --git a/contrib/tcpdump/print-http.c b/contrib/tcpdump/print-http.c index 49df174..0aec758 100644 --- a/contrib/tcpdump/print-http.c +++ b/contrib/tcpdump/print-http.c @@ -11,21 +11,18 @@ * FOR A PARTICULAR PURPOSE. */ -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header$"; -#endif +/* \summary: Hypertext Transfer Protocol (HTTP) printer */ #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include #include -#include "interface.h" +#include "netdissect.h" #include "extract.h" /* diff --git a/contrib/tcpdump/print-icmp.c b/contrib/tcpdump/print-icmp.c index a4d8275..17e7a75 100644 --- a/contrib/tcpdump/print-icmp.c +++ b/contrib/tcpdump/print-icmp.c @@ -17,23 +17,22 @@ * 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. - * - * $FreeBSD$ */ -#define NETDISSECT_REWORKED +/* \summary: Internet Control Message Protocol (ICMP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" -#include "extract.h" /* must come after interface.h */ +#include "extract.h" #include "ip.h" #include "udp.h" @@ -346,9 +345,9 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * char buf[MAXHOSTNAMELEN + 100]; struct cksum_vec vec[1]; - dp = (struct icmp *)bp; - ext_dp = (struct icmp_ext_t *)bp; - ip = (struct ip *)bp2; + 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); @@ -380,7 +379,7 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * ND_TCHECK(dp->icmp_ip.ip_p); oip = &dp->icmp_ip; hlen = IP_HL(oip) * 4; - ouh = (struct udphdr *)(((u_char *)oip) + hlen); + ouh = (const struct udphdr *)(((const u_char *)oip) + hlen); ND_TCHECK(ouh->uh_dport); dport = EXTRACT_16BITS(&ouh->uh_dport); switch (oip->ip_p) { @@ -389,14 +388,14 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * (void)snprintf(buf, sizeof(buf), "%s tcp port %s unreachable", ipaddr_string(ndo, &oip->ip_dst), - tcpport_string(dport)); + tcpport_string(ndo, dport)); break; case IPPROTO_UDP: (void)snprintf(buf, sizeof(buf), "%s udp port %s unreachable", ipaddr_string(ndo, &oip->ip_dst), - udpport_string(dport)); + udpport_string(ndo, dport)); break; default: @@ -411,7 +410,7 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * case ICMP_UNREACH_NEEDFRAG: { register const struct mtu_discovery *mp; - mp = (struct mtu_discovery *)(u_char *)&dp->icmp_void; + mp = (const struct mtu_discovery *)(const u_char *)&dp->icmp_void; mtu = EXTRACT_16BITS(&mp->nexthopmtu); if (mtu) { (void)snprintf(buf, sizeof(buf), @@ -452,7 +451,7 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * (void)snprintf(buf, sizeof(buf), "router advertisement"); cp = buf + strlen(buf); - ihp = (struct ih_rdiscovery *)&dp->icmp_void; + ihp = (const struct ih_rdiscovery *)&dp->icmp_void; ND_TCHECK(*ihp); (void)strncpy(cp, " lifetime ", sizeof(buf) - (cp - buf)); cp = buf + strlen(buf); @@ -482,7 +481,7 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * " [size %d]", size); break; } - idp = (struct id_rdiscovery *)&dp->icmp_data; + idp = (const struct id_rdiscovery *)&dp->icmp_data; while (num-- > 0) { ND_TCHECK(*idp); (void)snprintf(cp, sizeof(buf) - (cp - buf), " {%s %u}", @@ -559,9 +558,9 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * ND_PRINT((ndo, "ICMP %s, length %u", str, plen)); if (ndo->ndo_vflag && !fragmented) { /* don't attempt checksumming if this is a frag */ uint16_t sum, icmp_sum; - struct cksum_vec vec[1]; + if (ND_TTEST2(*bp, plen)) { - vec[0].ptr = (const uint8_t *)(void *)dp; + vec[0].ptr = (const uint8_t *)(const void *)dp; vec[0].len = plen; sum = in_cksum(vec, 1); if (sum != 0) { @@ -580,7 +579,7 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * if (ndo->ndo_vflag >= 1 && ICMP_ERRTYPE(dp->icmp_type)) { bp += 8; ND_PRINT((ndo, "\n\t")); - ip = (struct ip *)bp; + ip = (const struct ip *)bp; ndo->ndo_snaplen = ndo->ndo_snapend - bp; snapend_save = ndo->ndo_snapend; ip_print(ndo, bp, EXTRACT_16BITS(&ip->ip_len)); @@ -601,7 +600,7 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * * however not all implementations set the length field proper. */ if (!ext_dp->icmp_length) { - vec[0].ptr = (const uint8_t *)(void *)&ext_dp->icmp_ext_version_res; + 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)) { return; @@ -621,7 +620,7 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * } hlen = plen - ICMP_EXTD_MINLEN; - vec[0].ptr = (const uint8_t *)(void *)&ext_dp->icmp_ext_version_res; + 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), @@ -629,11 +628,11 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * hlen)); hlen -= 4; /* subtract common header size */ - obj_tptr = (uint8_t *)ext_dp->icmp_ext_data; + obj_tptr = (const uint8_t *)ext_dp->icmp_ext_data; while (hlen > sizeof(struct icmp_mpls_ext_object_header_t)) { - icmp_mpls_ext_object_header = (struct icmp_mpls_ext_object_header_t *)obj_tptr; + 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; diff --git a/contrib/tcpdump/print-icmp6.c b/contrib/tcpdump/print-icmp6.c index 81563e6..7fe639d 100644 --- a/contrib/tcpdump/print-icmp6.c +++ b/contrib/tcpdump/print-icmp6.c @@ -19,20 +19,20 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: IPv6 Internet Control Message Protocol (ICMPv6) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#ifdef INET6 - -#include +#include #include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" +#include "addrtostr.h" #include "extract.h" #include "ip6.h" @@ -284,13 +284,13 @@ struct nd_opt_hdr { /* Neighbor discovery option header */ #define ND_OPT_DNSSL 31 struct nd_opt_prefix_info { /* prefix information */ - uint8_t nd_opt_pi_type; - uint8_t nd_opt_pi_len; - uint8_t nd_opt_pi_prefix_len; - uint8_t nd_opt_pi_flags_reserved; - uint8_t nd_opt_pi_valid_time[4]; - uint8_t nd_opt_pi_preferred_time[4]; - uint8_t nd_opt_pi_reserved2[4]; + 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; }; @@ -622,14 +622,14 @@ print_lladdr(netdissect_options *ndo, const uint8_t *p, size_t l) } } -static int icmp6_cksum(const struct ip6_hdr *ip6, const struct icmp6_hdr *icp, - u_int len) +static int icmp6_cksum(netdissect_options *ndo, const struct ip6_hdr *ip6, + const struct icmp6_hdr *icp, u_int len) { - return nextproto6_cksum(ip6, (const uint8_t *)(void *)icp, len, len, + return nextproto6_cksum(ndo, ip6, (const uint8_t *)(const void *)icp, len, len, IPPROTO_ICMPV6); } -const struct tok rpl_mop_values[] = { +static const struct tok rpl_mop_values[] = { { RPL_DIO_NONSTORING, "nonstoring"}, { RPL_DIO_STORING, "storing"}, { RPL_DIO_NONSTORING_MULTICAST, "nonstoring-multicast"}, @@ -637,7 +637,7 @@ const struct tok rpl_mop_values[] = { { 0, NULL}, }; -const struct tok rpl_subopt_values[] = { +static const struct tok rpl_subopt_values[] = { { RPL_OPT_PAD0, "pad0"}, { RPL_OPT_PADN, "padN"}, { RPL_DIO_METRICS, "metrics"}, @@ -651,23 +651,6 @@ const struct tok rpl_subopt_values[] = { }; static void -rpl_format_dagid(char dagid_str[65], const u_char *dagid) -{ - char *d = dagid_str; - int i; - - for(i=0;i<16;i++) { - if(isprint(dagid[i])) { - *d++ = dagid[i]; - } else { - snprintf(d,5,"0x%02x", dagid[i]); /* 4 + null char */ - d += 4; - } - } - *d++ = '\0'; -} - -static void rpl_dio_printopt(netdissect_options *ndo, const struct rpl_dio_genoption *opt, u_int length) @@ -678,7 +661,7 @@ rpl_dio_printopt(netdissect_options *ndo, ND_TCHECK(opt->rpl_dio_len); while((opt->rpl_dio_type == RPL_OPT_PAD0 && - (u_char *)opt < ndo->ndo_snapend) || + (const u_char *)opt < ndo->ndo_snapend) || ND_TTEST2(*opt,(opt->rpl_dio_len+2))) { unsigned int optlen = opt->rpl_dio_len+2; @@ -687,18 +670,18 @@ rpl_dio_printopt(netdissect_options *ndo, ND_PRINT((ndo, " opt:pad0")); } else { ND_PRINT((ndo, " opt:%s len:%u ", - tok2str(rpl_subopt_values, "%subopt:%u", opt->rpl_dio_type), + 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; hex_print(ndo, " ", - ((uint8_t *)opt) + RPL_DIO_GENOPTION_LEN, /* content of DIO option */ + ((const uint8_t *)opt) + RPL_DIO_GENOPTION_LEN, /* content of DIO option */ paylen); } } - opt = (struct rpl_dio_genoption *)(((char *)opt) + optlen); + opt = (const struct rpl_dio_genoption *)(((const char *)opt) + optlen); length -= optlen; } return; @@ -711,11 +694,11 @@ static void rpl_dio_print(netdissect_options *ndo, const u_char *bp, u_int length) { - const struct nd_rpl_dio *dio = (struct nd_rpl_dio *)bp; - char dagid_str[65]; + const struct nd_rpl_dio *dio = (const struct nd_rpl_dio *)bp; + const char *dagid_str; ND_TCHECK(*dio); - rpl_format_dagid(dagid_str, dio->rpl_dagid); + dagid_str = ip6addr_string (ndo, dio->rpl_dagid); ND_PRINT((ndo, " [dagid:%s,seq:%u,instance:%u,rank:%u,%smop:%s,prf:%u]", dagid_str, @@ -727,7 +710,7 @@ rpl_dio_print(netdissect_options *ndo, RPL_DIO_PRF(dio->rpl_mopprf))); if(ndo->ndo_vflag > 1) { - struct rpl_dio_genoption *opt = (struct rpl_dio_genoption *)&dio[1]; + const struct rpl_dio_genoption *opt = (const struct rpl_dio_genoption *)&dio[1]; rpl_dio_printopt(ndo, opt, length); } return; @@ -740,21 +723,20 @@ static void rpl_dao_print(netdissect_options *ndo, const u_char *bp, u_int length) { - const struct nd_rpl_dao *dao = (struct nd_rpl_dao *)bp; - char dagid_str[65]; + const struct nd_rpl_dao *dao = (const struct nd_rpl_dao *)bp; + const char *dagid_str = ""; ND_TCHECK(*dao); if (length < ND_RPL_DAO_MIN_LEN) goto tooshort; - strcpy(dagid_str,""); 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); if (length < DAGID_LEN) goto tooshort; - rpl_format_dagid(dagid_str, dao->rpl_dagid); + dagid_str = ip6addr_string (ndo, dao->rpl_dagid); bp += DAGID_LEN; length -= DAGID_LEN; } @@ -768,7 +750,7 @@ rpl_dao_print(netdissect_options *ndo, dao->rpl_flags)); if(ndo->ndo_vflag > 1) { - const struct rpl_dio_genoption *opt = (struct rpl_dio_genoption *)bp; + const struct rpl_dio_genoption *opt = (const struct rpl_dio_genoption *)bp; rpl_dio_printopt(ndo, opt, length); } return; @@ -786,21 +768,20 @@ static void rpl_daoack_print(netdissect_options *ndo, const u_char *bp, u_int length) { - const struct nd_rpl_daoack *daoack = (struct nd_rpl_daoack *)bp; - char dagid_str[65]; + const struct nd_rpl_daoack *daoack = (const struct nd_rpl_daoack *)bp; + const char *dagid_str = ""; ND_TCHECK2(*daoack, ND_RPL_DAOACK_MIN_LEN); if (length < ND_RPL_DAOACK_MIN_LEN) goto tooshort; - strcpy(dagid_str,""); bp += ND_RPL_DAOACK_MIN_LEN; length -= ND_RPL_DAOACK_MIN_LEN; if(RPL_DAOACK_D(daoack->rpl_flags)) { - ND_TCHECK2(daoack->rpl_dagid, 16); + ND_TCHECK2(daoack->rpl_dagid, DAGID_LEN); if (length < DAGID_LEN) goto tooshort; - rpl_format_dagid(dagid_str, daoack->rpl_dagid); + dagid_str = ip6addr_string (ndo, daoack->rpl_dagid); bp += DAGID_LEN; length -= DAGID_LEN; } @@ -813,7 +794,7 @@ rpl_daoack_print(netdissect_options *ndo, /* no officially defined options for DAOACK, but print any we find */ if(ndo->ndo_vflag > 1) { - const struct rpl_dio_genoption *opt = (struct rpl_dio_genoption *)bp; + const struct rpl_dio_genoption *opt = (const struct rpl_dio_genoption *)bp; rpl_dio_printopt(ndo, opt, length); } return; @@ -897,9 +878,9 @@ icmp6_print(netdissect_options *ndo, const u_char *ep; u_int prot; - dp = (struct icmp6_hdr *)bp; - ip = (struct ip6_hdr *)bp2; - oip = (struct ip6_hdr *)(dp + 1); + 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; @@ -910,7 +891,7 @@ icmp6_print(netdissect_options *ndo, if (ND_TTEST2(bp[0], length)) { udp_sum = EXTRACT_16BITS(&dp->icmp6_cksum); - sum = icmp6_cksum(ip, dp, length); + sum = icmp6_cksum(ndo, ip, dp, length); if (sum != 0) ND_PRINT((ndo,"[bad icmp6 cksum 0x%04x -> 0x%04x!] ", udp_sum, @@ -949,7 +930,7 @@ icmp6_print(netdissect_options *ndo, ip6addr_string(ndo, &oip->ip6_src))); break; case ICMP6_DST_UNREACH_NOPORT: - if ((ouh = get_upperlayer(ndo, (u_char *)oip, &prot)) + if ((ouh = get_upperlayer(ndo, (const u_char *)oip, &prot)) == NULL) goto trunc; @@ -958,12 +939,12 @@ icmp6_print(netdissect_options *ndo, case IPPROTO_TCP: ND_PRINT((ndo,", %s tcp port %s", ip6addr_string(ndo, &oip->ip6_dst), - tcpport_string(dport))); + tcpport_string(ndo, dport))); break; case IPPROTO_UDP: ND_PRINT((ndo,", %s udp port %s", ip6addr_string(ndo, &oip->ip6_dst), - udpport_string(dport))); + udpport_string(ndo, dport))); break; default: ND_PRINT((ndo,", %s protocol %d port %d unreachable", @@ -1048,9 +1029,9 @@ icmp6_print(netdissect_options *ndo, case ND_ROUTER_ADVERT: #define RTADVLEN 16 if (ndo->ndo_vflag) { - struct nd_router_advert *p; + const struct nd_router_advert *p; - p = (struct nd_router_advert *)dp; + p = (const struct nd_router_advert *)dp; ND_TCHECK(p->nd_ra_retransmit); ND_PRINT((ndo,"\n\thop limit %u, Flags [%s]" \ ", pref %s, router lifetime %us, reachable time %us, retrans time %us", @@ -1067,8 +1048,8 @@ icmp6_print(netdissect_options *ndo, break; case ND_NEIGHBOR_SOLICIT: { - struct nd_neighbor_solicit *p; - p = (struct nd_neighbor_solicit *)dp; + 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))); if (ndo->ndo_vflag) { @@ -1080,9 +1061,9 @@ icmp6_print(netdissect_options *ndo, break; case ND_NEIGHBOR_ADVERT: { - struct nd_neighbor_advert *p; + const struct nd_neighbor_advert *p; - p = (struct nd_neighbor_advert *)dp; + 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))); @@ -1099,12 +1080,12 @@ icmp6_print(netdissect_options *ndo, } break; case ND_REDIRECT: -#define RDR(i) ((struct nd_redirect *)(i)) +#define RDR(i) ((const struct nd_redirect *)(i)) ND_TCHECK(RDR(dp)->nd_rd_dst); - ND_PRINT((ndo,", %s", getname6(ndo, (const u_char *)&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", - getname6(ndo, (const u_char*)&RDR(dp)->nd_rd_target))); + ip6addr_string(ndo, &RDR(dp)->nd_rd_target))); #define REDIRECTLEN 40 if (ndo->ndo_vflag) { icmp6_opt_print(ndo, (const u_char *)dp + REDIRECTLEN, @@ -1133,14 +1114,14 @@ icmp6_print(netdissect_options *ndo, break; case ICMP6_HADISCOV_REPLY: if (ndo->ndo_vflag) { - struct in6_addr *in6; - u_char *cp; + const struct in6_addr *in6; + const u_char *cp; ND_TCHECK(dp->icmp6_data16[0]); ND_PRINT((ndo,", id 0x%04x", EXTRACT_16BITS(&dp->icmp6_data16[0]))); - cp = (u_char *)dp + length; - in6 = (struct in6_addr *)(dp + 1); - for (; (u_char *)in6 < cp; in6++) { + 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))); } @@ -1182,7 +1163,7 @@ static const struct udphdr * get_upperlayer(netdissect_options *ndo, const u_char *bp, u_int *prot) { const u_char *ep; - const struct ip6_hdr *ip6 = (struct ip6_hdr *)bp; + const struct ip6_hdr *ip6 = (const struct ip6_hdr *)bp; const struct udphdr *uh; const struct ip6_hbh *hbh; const struct ip6_frag *fragh; @@ -1205,7 +1186,7 @@ get_upperlayer(netdissect_options *ndo, const u_char *bp, u_int *prot) switch(nh) { case IPPROTO_UDP: case IPPROTO_TCP: - uh = (struct udphdr *)bp; + uh = (const struct udphdr *)bp; if (ND_TTEST(uh->uh_dport)) { *prot = nh; return(uh); @@ -1217,7 +1198,7 @@ get_upperlayer(netdissect_options *ndo, const u_char *bp, u_int *prot) case IPPROTO_HOPOPTS: case IPPROTO_DSTOPTS: case IPPROTO_ROUTING: - hbh = (struct ip6_hbh *)bp; + hbh = (const struct ip6_hbh *)bp; if (!ND_TTEST(hbh->ip6h_len)) return(NULL); nh = hbh->ip6h_nxt; @@ -1225,7 +1206,7 @@ get_upperlayer(netdissect_options *ndo, const u_char *bp, u_int *prot) break; case IPPROTO_FRAGMENT: /* this should be odd, but try anyway */ - fragh = (struct ip6_frag *)bp; + fragh = (const struct ip6_frag *)bp; if (!ND_TTEST(fragh->ip6f_offlg)) return(NULL); /* fragments with non-zero offset are meaningless */ @@ -1236,7 +1217,7 @@ get_upperlayer(netdissect_options *ndo, const u_char *bp, u_int *prot) break; case IPPROTO_AH: - ah = (struct ah *)bp; + ah = (const struct ah *)bp; if (!ND_TTEST(ah->ah_len)) return(NULL); nh = ah->ah_nxt; @@ -1264,18 +1245,19 @@ 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, *in6p; + struct in6_addr in6; + const struct in6_addr *in6p; size_t l; u_int i; -#define ECHECK(var) if ((u_char *)&(var) > ep - sizeof(var)) return +#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; while (cp < ep) { - op = (struct nd_opt_hdr *)cp; + op = (const struct nd_opt_hdr *)cp; ECHECK(op->nd_opt_len); if (resid <= 0) @@ -1301,7 +1283,7 @@ icmp6_opt_print(netdissect_options *ndo, const u_char *bp, int resid) print_lladdr(ndo, cp + 2, l); break; case ND_OPT_PREFIX_INFORMATION: - opp = (struct nd_opt_prefix_info *)op; + 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), @@ -1316,14 +1298,14 @@ icmp6_opt_print(netdissect_options *ndo, const u_char *bp, int resid) /* xxx */ break; case ND_OPT_MTU: - opm = (struct nd_opt_mtu *)op; + 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" : "" )); break; case ND_OPT_RDNSS: - oprd = (struct nd_opt_rdnss *)op; + 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))); @@ -1334,7 +1316,7 @@ icmp6_opt_print(netdissect_options *ndo, const u_char *bp, int resid) } break; case ND_OPT_DNSSL: - opds = (struct nd_opt_dnssl *)op; + opds = (const struct nd_opt_dnssl *)op; ND_PRINT((ndo," lifetime %us, domain(s):", EXTRACT_32BITS(&opds->nd_opt_dnssl_lifetime))); domp = cp + 8; /* domain names, variable-sized, RFC1035-encoded */ @@ -1346,22 +1328,22 @@ icmp6_opt_print(netdissect_options *ndo, const u_char *bp, int resid) } break; case ND_OPT_ADVINTERVAL: - opa = (struct nd_opt_advinterval *)op; + 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))); break; case ND_OPT_HOMEAGENT_INFO: - oph = (struct nd_opt_homeagent_info *)op; + 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))); break; case ND_OPT_ROUTE_INFO: - opri = (struct nd_opt_route_info *)op; + opri = (const struct nd_opt_route_info *)op; ND_TCHECK(opri->nd_opt_rti_lifetime); memset(&in6, 0, sizeof(in6)); - in6p = (struct in6_addr *)(opri + 1); + in6p = (const struct in6_addr *)(opri + 1); switch (op->nd_opt_len) { case 1: break; @@ -1407,13 +1389,13 @@ icmp6_opt_print(netdissect_options *ndo, const u_char *bp, int resid) static void mld6_print(netdissect_options *ndo, const u_char *bp) { - const struct mld6_hdr *mp = (struct mld6_hdr *)bp; + const struct mld6_hdr *mp = (const struct mld6_hdr *)bp; const u_char *ep; /* 'ep' points to the end of available data. */ ep = ndo->ndo_snapend; - if ((u_char *)mp + sizeof(*mp) > ep) + if ((const u_char *)mp + sizeof(*mp) > ep) return; ND_PRINT((ndo,"max resp delay: %d ", EXTRACT_16BITS(&mp->mld6_maxdelay))); @@ -1423,7 +1405,7 @@ mld6_print(netdissect_options *ndo, const u_char *bp) static void mldv2_report_print(netdissect_options *ndo, const u_char *bp, u_int len) { - struct icmp6_hdr *icp = (struct icmp6_hdr *) bp; + const struct icmp6_hdr *icp = (const struct icmp6_hdr *) bp; u_int group, nsrcs, ngroups; u_int i, j; @@ -1481,7 +1463,7 @@ trunc: static void mldv2_query_print(netdissect_options *ndo, const u_char *bp, u_int len) { - struct icmp6_hdr *icp = (struct icmp6_hdr *) bp; + const struct icmp6_hdr *icp = (const struct icmp6_hdr *) bp; u_int mrc; int mrt, qqi; u_int nsrcs; @@ -1591,8 +1573,8 @@ icmp6_nodeinfo_print(netdissect_options *ndo, u_int icmp6len, const u_char *bp, if (ep < bp) return; - dp = (struct icmp6_hdr *)bp; - ni6 = (struct icmp6_nodeinfo *)bp; + dp = (const struct icmp6_hdr *)bp; + ni6 = (const struct icmp6_nodeinfo *)bp; siz = ep - bp; switch (ni6->ni_type) { @@ -1605,7 +1587,7 @@ icmp6_nodeinfo_print(netdissect_options *ndo, u_int icmp6len, const u_char *bp, ND_PRINT((ndo," node information query")); ND_TCHECK2(*dp, sizeof(*ni6)); - ni6 = (struct icmp6_nodeinfo *)dp; + ni6 = (const struct icmp6_nodeinfo *)dp; ND_PRINT((ndo," (")); /*)*/ switch (EXTRACT_16BITS(&ni6->ni_qtype)) { case NI_QTYPE_NOOP: @@ -1669,7 +1651,7 @@ icmp6_nodeinfo_print(netdissect_options *ndo, u_int icmp6len, const u_char *bp, break; } ND_PRINT((ndo,", subject=%s", - getname6(ndo, (const u_char *)(ni6 + 1)))); + ip6addr_string(ndo, ni6 + 1))); break; case ICMP6_NI_SUBJ_FQDN: ND_PRINT((ndo,", subject=DNS name")); @@ -1697,7 +1679,7 @@ icmp6_nodeinfo_print(netdissect_options *ndo, u_int icmp6len, const u_char *bp, break; } ND_PRINT((ndo,", subject=%s", - getname(ndo, (const u_char *)(ni6 + 1)))); + ipaddr_string(ndo, ni6 + 1))); break; default: ND_PRINT((ndo,", unknown subject")); @@ -1716,7 +1698,7 @@ icmp6_nodeinfo_print(netdissect_options *ndo, u_int icmp6len, const u_char *bp, needcomma = 0; - ni6 = (struct icmp6_nodeinfo *)dp; + ni6 = (const struct icmp6_nodeinfo *)dp; ND_PRINT((ndo," node information reply")); ND_PRINT((ndo," (")); /*)*/ switch (ni6->ni_code) { @@ -1784,7 +1766,7 @@ icmp6_nodeinfo_print(netdissect_options *ndo, u_int icmp6len, const u_char *bp, } else dnsname_print(ndo, cp, ep); if ((EXTRACT_16BITS(&ni6->ni_flags) & 0x01) != 0) - ND_PRINT((ndo," [TTL=%u]", *(uint32_t *)(ni6 + 1))); + ND_PRINT((ndo," [TTL=%u]", EXTRACT_32BITS(ni6 + 1))); break; case NI_QTYPE_NODEADDR: if (needcomma) @@ -1794,7 +1776,7 @@ icmp6_nodeinfo_print(netdissect_options *ndo, u_int icmp6len, const u_char *bp, while (i < siz) { if (i + sizeof(struct in6_addr) + sizeof(int32_t) > siz) break; - ND_PRINT((ndo," %s", getname6(ndo, bp + i))); + 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); @@ -1833,14 +1815,14 @@ icmp6_rrenum_print(netdissect_options *ndo, const u_char *bp, const u_char *ep) { const struct icmp6_router_renum *rr6; const char *cp; - struct rr_pco_match *match; - struct rr_pco_use *use; + const struct rr_pco_match *match; + const struct rr_pco_use *use; char hbuf[NI_MAXHOST]; int n; if (ep < bp) return; - rr6 = (struct icmp6_router_renum *)bp; + rr6 = (const struct icmp6_router_renum *)bp; cp = (const char *)(rr6 + 1); ND_TCHECK(rr6->rr_reserved); @@ -1881,7 +1863,7 @@ icmp6_rrenum_print(netdissect_options *ndo, const u_char *bp, const u_char *ep) } if (rr6->rr_code == ICMP6_ROUTER_RENUMBERING_COMMAND) { - match = (struct rr_pco_match *)cp; + match = (const struct rr_pco_match *)cp; cp = (const char *)(match + 1); ND_TCHECK(match->rpm_prefix); @@ -1903,7 +1885,7 @@ icmp6_rrenum_print(netdissect_options *ndo, const u_char *bp, const u_char *ep) ND_PRINT((ndo,",min=%u", match->rpm_minlen)); ND_PRINT((ndo,",max=%u", match->rpm_maxlen)); } - if (inet_ntop(AF_INET6, &match->rpm_prefix, hbuf, sizeof(hbuf))) + if (addrtostr6(&match->rpm_prefix, hbuf, sizeof(hbuf))) ND_PRINT((ndo,",%s/%u", hbuf, match->rpm_matchlen)); else ND_PRINT((ndo,",?/%u", match->rpm_matchlen)); @@ -1915,7 +1897,7 @@ icmp6_rrenum_print(netdissect_options *ndo, const u_char *bp, const u_char *ep) goto trunc; n /= 4; while (n-- > 0) { - use = (struct rr_pco_use *)cp; + use = (const struct rr_pco_use *)cp; cp = (const char *)(use + 1); ND_TCHECK(use->rpu_prefix); @@ -1946,8 +1928,7 @@ icmp6_rrenum_print(netdissect_options *ndo, const u_char *bp, const u_char *ep) ND_PRINT((ndo,"pltime=%u,", EXTRACT_32BITS(&use->rpu_pltime))); } - if (inet_ntop(AF_INET6, &use->rpu_prefix, hbuf, - sizeof(hbuf))) + if (addrtostr6(&use->rpu_prefix, hbuf, sizeof(hbuf))) ND_PRINT((ndo,"%s/%u/%u", hbuf, use->rpu_uselen, use->rpu_keeplen)); else @@ -1964,8 +1945,6 @@ trunc: ND_PRINT((ndo,"[|icmp6]")); } -#endif /* INET6 */ - /* * Local Variables: * c-style: whitesmith diff --git a/contrib/tcpdump/print-igmp.c b/contrib/tcpdump/print-igmp.c index e4808a7..0bb7f97 100644 --- a/contrib/tcpdump/print-igmp.c +++ b/contrib/tcpdump/print-igmp.c @@ -19,16 +19,17 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: Internet Group Management Protocol (IGMP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" -#include "extract.h" /* must come after interface.h */ +#include "extract.h" #ifndef IN_CLASSD #define IN_CLASSD(i) (((int32_t)(i) & 0xf0000000) == 0xe0000000) @@ -204,7 +205,7 @@ print_igmpv3_query(netdissect_options *ndo, register const u_char *bp, register u_int len) { u_int mrc; - int mrt; + u_int mrt; u_int nsrcs; register u_int i; @@ -226,7 +227,7 @@ print_igmpv3_query(netdissect_options *ndo, if (mrt < 600) { ND_PRINT((ndo, "%.1fs", mrt * 0.1)); } else { - relts_print(ndo, mrt / 10); + unsigned_relts_print(ndo, mrt / 10); } ND_PRINT((ndo, "]")); } @@ -327,7 +328,7 @@ igmp_print(netdissect_options *ndo, break; } - if (ndo->ndo_vflag && ND_TTEST2(bp[0], len)) { + if (ndo->ndo_vflag && len >= 4 && ND_TTEST2(bp[0], len)) { /* Check the IGMP checksum */ vec[0].ptr = bp; vec[0].len = len; diff --git a/contrib/tcpdump/print-igrp.c b/contrib/tcpdump/print-igrp.c index fbb3134..b6eaf31 100644 --- a/contrib/tcpdump/print-igrp.c +++ b/contrib/tcpdump/print-igrp.c @@ -21,15 +21,16 @@ * Initial contribution from Francis Dupont (francis.dupont@inria.fr) */ -#define NETDISSECT_REWORKED +/* \summary: Interior Gateway Routing Protocol (IGRP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" -#include "extract.h" /* must come after interface.h */ +#include "netdissect.h" +#include "extract.h" /* Cisco IGRP definitions */ @@ -65,7 +66,7 @@ struct igrprte { #define IGRP_RTE_SIZE 14 /* don't believe sizeof ! */ static void -igrp_entry_print(netdissect_options *ndo, register struct igrprte *igr, +igrp_entry_print(netdissect_options *ndo, register const struct igrprte *igr, register int is_interior, register int is_exterior) { register u_int delay, bandwidth; @@ -103,12 +104,12 @@ static const struct tok op2str[] = { void igrp_print(netdissect_options *ndo, register const u_char *bp, u_int length) { - register struct igrphdr *hdr; - register u_char *cp; + register const struct igrphdr *hdr; + register const u_char *cp; u_int nint, nsys, next; - hdr = (struct igrphdr *)bp; - cp = (u_char *)(hdr + 1); + hdr = (const struct igrphdr *)bp; + cp = (const u_char *)(hdr + 1); ND_PRINT((ndo, "igrp:")); /* Header */ @@ -130,15 +131,15 @@ igrp_print(netdissect_options *ndo, register const u_char *bp, u_int length) while (length >= IGRP_RTE_SIZE) { if (nint > 0) { ND_TCHECK2(*cp, IGRP_RTE_SIZE); - igrp_entry_print(ndo, (struct igrprte *)cp, 1, 0); + igrp_entry_print(ndo, (const struct igrprte *)cp, 1, 0); --nint; } else if (nsys > 0) { ND_TCHECK2(*cp, IGRP_RTE_SIZE); - igrp_entry_print(ndo, (struct igrprte *)cp, 0, 0); + igrp_entry_print(ndo, (const struct igrprte *)cp, 0, 0); --nsys; } else if (next > 0) { ND_TCHECK2(*cp, IGRP_RTE_SIZE); - igrp_entry_print(ndo, (struct igrprte *)cp, 0, 1); + igrp_entry_print(ndo, (const struct igrprte *)cp, 0, 1); --next; } else { ND_PRINT((ndo, " [extra bytes %d]", length)); diff --git a/contrib/tcpdump/print-ip.c b/contrib/tcpdump/print-ip.c index edf0076..6071bb2 100644 --- a/contrib/tcpdump/print-ip.c +++ b/contrib/tcpdump/print-ip.c @@ -17,22 +17,21 @@ * 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. - * - * $FreeBSD$ */ -#define NETDISSECT_REWORKED +/* \summary: IP printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" -#include "extract.h" /* must come after interface.h */ +#include "extract.h" #include "ip.h" #include "ipproto.h" @@ -125,7 +124,7 @@ ip_finddst(netdissect_options *ndo, } } trunc: - UNALIGNED_MEMCPY(&retval, &ip->ip_dst.s_addr, sizeof(uint32_t)); + UNALIGNED_MEMCPY(&retval, &ip->ip_dst, sizeof(uint32_t)); return retval; } @@ -150,9 +149,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.s_addr, sizeof(uint32_t)); + UNALIGNED_MEMCPY(&ph.src, &ip->ip_src, sizeof(uint32_t)); if (IP_HL(ip) == 5) - UNALIGNED_MEMCPY(&ph.dst, &ip->ip_dst.s_addr, sizeof(uint32_t)); + UNALIGNED_MEMCPY(&ph.dst, &ip->ip_dst, sizeof(uint32_t)); else ph.dst = ip_finddst(ndo, ip); @@ -326,12 +325,15 @@ ip_print_demux(netdissect_options *ndo, struct ip_print_demux_state *ipds) { struct protoent *proto; - struct cksum_vec vec[1]; 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) @@ -356,14 +358,14 @@ again: case IPPROTO_IPCOMP: { - int enh; - ipds->advance = ipcomp_print(ndo, ipds->cp, &enh); - if (ipds->advance <= 0) - break; - ipds->cp += ipds->advance; - ipds->len -= ipds->advance; - ipds->nh = enh & 0xff; - goto again; + 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: @@ -457,9 +459,7 @@ again: break; case IPPROTO_PIM: - vec[0].ptr = ipds->cp; - vec[0].len = ipds->len; - pim_print(ndo, ipds->cp, ipds->len, in_cksum(vec, 1)); + pim_print(ndo, ipds->cp, ipds->len, (const u_char *)ipds->ip); break; case IPPROTO_VRRP: @@ -536,13 +536,14 @@ ip_print(netdissect_options *ndo, ipds->ip = (const struct ip *)bp; ND_TCHECK(ipds->ip->ip_vhl); - if (IP_V(ipds->ip) != 4) { /* print version if != 4 */ + 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 ")); else ND_PRINT((ndo, "IP%u ", IP_V(ipds->ip))); + return; } - else if (!ndo->ndo_eflag) + if (!ndo->ndo_eflag) ND_PRINT((ndo, "IP ")); ND_TCHECK(*ipds->ip); @@ -590,17 +591,22 @@ ip_print(netdissect_options *ndo, if (ndo->ndo_vflag) { ND_PRINT((ndo, "(tos 0x%x", (int)ipds->ip->ip_tos)); /* ECN bits */ - if (ipds->ip->ip_tos & 0x03) { - switch (ipds->ip->ip_tos & 0x03) { - case 1: - ND_PRINT((ndo, ",ECT(1)")); - break; - case 2: - ND_PRINT((ndo, ",ECT(0)")); - break; - case 3: - ND_PRINT((ndo, ",CE")); - } + switch (ipds->ip->ip_tos & 0x03) { + + case 0: + break; + + case 1: + ND_PRINT((ndo, ",ECT(1)")); + break; + + case 2: + ND_PRINT((ndo, ",ECT(0)")); + break; + + case 3: + ND_PRINT((ndo, ",CE")); + break; } if (ipds->ip->ip_ttl >= 1) @@ -623,12 +629,12 @@ ip_print(netdissect_options *ndo, if ((hlen - sizeof(struct ip)) > 0) { ND_PRINT((ndo, ", options (")); - ip_optprint(ndo, (u_char *)(ipds->ip + 1), hlen - sizeof(struct ip)); + ip_optprint(ndo, (const u_char *)(ipds->ip + 1), hlen - sizeof(struct ip)); ND_PRINT((ndo, ")")); } - if (!ndo->ndo_Kflag && (u_char *)ipds->ip + hlen <= ndo->ndo_snapend) { - vec[0].ptr = (const uint8_t *)(void *)ipds->ip; + if (!ndo->ndo_Kflag && (const u_char *)ipds->ip + hlen <= ndo->ndo_snapend) { + vec[0].ptr = (const uint8_t *)(const void *)ipds->ip; vec[0].len = hlen; sum = in_cksum(vec, 1); if (sum != 0) { @@ -657,22 +663,24 @@ ip_print(netdissect_options *ndo, } ip_print_demux(ndo, ipds); } else { - /* Ultra quiet now means that all this stuff should be suppressed */ - if (ndo->ndo_qflag > 1) return; + /* + * Ultra quiet now means that all this stuff should be + * suppressed. + */ + if (ndo->ndo_qflag > 1) + return; - /* - * if this isn't the first frag, we're missing the - * next level protocol header. print the ip addr - * and the protocol. - */ - if (ipds->off & 0x1fff) { - ND_PRINT((ndo, "%s > %s:", ipaddr_string(ndo, &ipds->ip->ip_src), - ipaddr_string(ndo, &ipds->ip->ip_dst))); - if (!ndo->ndo_nflag && (proto = getprotobynumber(ipds->ip->ip_p)) != NULL) - ND_PRINT((ndo, " %s", proto->p_name)); - else - ND_PRINT((ndo, " ip-proto-%d", ipds->ip->ip_p)); - } + /* + * 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 && (proto = getprotobynumber(ipds->ip->ip_p)) != NULL) + ND_PRINT((ndo, " %s", proto->p_name)); + else + ND_PRINT((ndo, " ip-proto-%d", ipds->ip->ip_p)); } return; @@ -684,24 +692,28 @@ trunc: void ipN_print(netdissect_options *ndo, register const u_char *bp, register u_int length) { - struct ip hdr; - - if (length < 4) { + if (length < 1) { ND_PRINT((ndo, "truncated-ip %d", length)); return; } - memcpy (&hdr, bp, 4); - switch (IP_V(&hdr)) { - case 4: + + ND_TCHECK(*bp); + switch (*bp & 0xF0) { + case 0x40: ip_print (ndo, bp, length); - return; - case 6: + break; + case 0x60: ip6_print (ndo, bp, length); - return; + break; default: - ND_PRINT((ndo, "unknown ip %d", IP_V(&hdr))); - return; + ND_PRINT((ndo, "unknown ip %d", (*bp & 0xF0) >> 4)); + break; } + return; + +trunc: + ND_PRINT((ndo, "%s", tstr)); + return; } /* diff --git a/contrib/tcpdump/print-ip6.c b/contrib/tcpdump/print-ip6.c index 5318389..9f590f2 100644 --- a/contrib/tcpdump/print-ip6.c +++ b/contrib/tcpdump/print-ip6.c @@ -17,33 +17,151 @@ * 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. - * - * $FreeBSD$ */ -#define NETDISSECT_REWORKED +/* \summary: IPv6 printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" -#ifdef INET6 - #include "ip6.h" #include "ipproto.h" /* + * If routing headers are presend and valid, set dst to the final destination. + * Otherwise, set it to the IPv6 destination. + * + * This is used for UDP and TCP pseudo-header in the checksum + * calculation. + */ +static void +ip6_finddst(netdissect_options *ndo, struct in6_addr *dst, + const struct ip6_hdr *ip6) +{ + const u_char *cp; + int advance; + u_int nh; + const struct in6_addr *dst_addr; + const struct ip6_rthdr *dp; + const struct ip6_rthdr0 *dp0; + const struct in6_addr *addr; + int i, len; + + cp = (const u_char *)ip6; + advance = sizeof(struct ip6_hdr); + nh = ip6->ip6_nxt; + dst_addr = &ip6->ip6_dst; + + while (cp < ndo->ndo_snapend) { + cp += advance; + + switch (nh) { + + case IPPROTO_HOPOPTS: + case IPPROTO_DSTOPTS: + case IPPROTO_MOBILITY_OLD: + case IPPROTO_MOBILITY: + /* + * These have a header length byte, following + * the next header byte, giving the length of + * the header, in units of 8 octets, excluding + * the first 8 octets. + */ + ND_TCHECK2(*cp, 2); + advance = (int)((*(cp + 1) + 1) << 3); + nh = *cp; + break; + + case IPPROTO_FRAGMENT: + /* + * The byte following the next header byte is + * marked as reserved, and the header is always + * the same size. + */ + ND_TCHECK2(*cp, 1); + advance = sizeof(struct ip6_frag); + nh = *cp; + break; + + case IPPROTO_ROUTING: + /* + * OK, we found it. + */ + dp = (const struct ip6_rthdr *)cp; + ND_TCHECK(*dp); + len = dp->ip6r_len; + switch (dp->ip6r_type) { + + case IPV6_RTHDR_TYPE_0: + case IPV6_RTHDR_TYPE_2: /* Mobile IPv6 ID-20 */ + dp0 = (const struct ip6_rthdr0 *)dp; + if (len % 2 == 1) + goto trunc; + len >>= 1; + addr = &dp0->ip6r0_addr[0]; + for (i = 0; i < len; i++) { + if ((const u_char *)(addr + 1) > ndo->ndo_snapend) + goto trunc; + + dst_addr = addr; + addr++; + } + break; + + default: + break; + } + + /* + * Only one routing header to a customer. + */ + goto done; + + case IPPROTO_AH: + case IPPROTO_ESP: + case IPPROTO_IPCOMP: + default: + /* + * AH and ESP are, in the RFCs that describe them, + * described as being "viewed as an end-to-end + * payload" "in the IPv6 context, so that they + * "should appear after hop-by-hop, routing, and + * fragmentation extension headers". We assume + * that's the case, and stop as soon as we see + * one. (We can't handle an ESP header in + * the general case anyway, as its length depends + * on the encryption algorithm.) + * + * IPComp is also "viewed as an end-to-end + * payload" "in the IPv6 context". + * + * All other protocols are assumed to be the final + * protocol. + */ + goto done; + } + } + +done: +trunc: + UNALIGNED_MEMCPY(dst, dst_addr, sizeof(struct in6_addr)); +} + +/* * Compute a V6-style checksum by building a pseudoheader. */ int -nextproto6_cksum(const struct ip6_hdr *ip6, const uint8_t *data, +nextproto6_cksum(netdissect_options *ndo, + const struct ip6_hdr *ip6, const uint8_t *data, u_int len, u_int covlen, u_int next_proto) { struct { @@ -58,7 +176,26 @@ nextproto6_cksum(const struct ip6_hdr *ip6, const uint8_t *data, /* pseudo-header */ memset(&ph, 0, sizeof(ph)); UNALIGNED_MEMCPY(&ph.ph_src, &ip6->ip6_src, sizeof (struct in6_addr)); - UNALIGNED_MEMCPY(&ph.ph_dst, &ip6->ip6_dst, sizeof (struct in6_addr)); + switch (ip6->ip6_nxt) { + + case IPPROTO_HOPOPTS: + case IPPROTO_DSTOPTS: + case IPPROTO_MOBILITY_OLD: + case IPPROTO_MOBILITY: + case IPPROTO_FRAGMENT: + case IPPROTO_ROUTING: + /* + * The next header is either a routing header or a header + * after which there might be a routing header, so scan + * for a routing header. + */ + ip6_finddst(ndo, &ph.ph_dst, ip6); + break; + + default: + UNALIGNED_MEMCPY(&ph.ph_dst, &ip6->ip6_dst, sizeof (struct in6_addr)); + break; + } ph.ph_len = htonl(len); ph.ph_nxt = next_proto; @@ -156,15 +293,19 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length) switch (nh) { case IPPROTO_HOPOPTS: advance = hbhopt_print(ndo, cp); + if (advance < 0) + return; nh = *cp; break; case IPPROTO_DSTOPTS: advance = dstopt_print(ndo, cp); + if (advance < 0) + return; nh = *cp; break; case IPPROTO_FRAGMENT: advance = frag6_print(ndo, cp, (const u_char *)ip6); - if (ndo->ndo_snapend <= cp + advance) + if (advance < 0 || ndo->ndo_snapend <= cp + advance) return; nh = *cp; fragmented = 1; @@ -173,9 +314,7 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length) case IPPROTO_MOBILITY_OLD: case IPPROTO_MOBILITY: /* - * XXX - we don't use "advance"; the current - * "Mobility Support in IPv6" draft - * (draft-ietf-mobileip-ipv6-24) says that + * 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 @@ -218,15 +357,19 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length) } case IPPROTO_IPCOMP: { - int enh; - advance = ipcomp_print(ndo, cp, &enh); - nh = enh & 0xff; + ipcomp_print(ndo, 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. + */ + advance = -1; break; } case IPPROTO_PIM: - pim_print(ndo, cp, len, nextproto6_cksum(ip6, cp, len, len, - IPPROTO_PIM)); + pim_print(ndo, cp, len, (const u_char *)ip6); return; case IPPROTO_OSPF: @@ -267,13 +410,3 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length) trunc: ND_PRINT((ndo, "[|ip6]")); } - -#else /* INET6 */ - -void -ip6_print(netdissect_options *ndo, const u_char *bp _U_, u_int length) -{ - ND_PRINT((ndo, "IP6, length: %u (printing not supported)", length)); -} - -#endif /* INET6 */ diff --git a/contrib/tcpdump/print-ip6opts.c b/contrib/tcpdump/print-ip6opts.c index 14ad42c..4c16d80 100644 --- a/contrib/tcpdump/print-ip6opts.c +++ b/contrib/tcpdump/print-ip6opts.c @@ -27,17 +27,17 @@ * SUCH DAMAGE. */ -#define NETDISSECT_REWORKED +/* \summary: IPv6 header option printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#ifdef INET6 -#include +#include #include "ip6.h" -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" @@ -173,7 +173,7 @@ trunc: int hbhopt_print(netdissect_options *ndo, register const u_char *bp) { - const struct ip6_hbh *dp = (struct ip6_hbh *)bp; + const struct ip6_hbh *dp = (const struct ip6_hbh *)bp; int hbhlen = 0; ND_TCHECK(dp->ip6h_len); @@ -193,7 +193,7 @@ hbhopt_print(netdissect_options *ndo, register const u_char *bp) int dstopt_print(netdissect_options *ndo, register const u_char *bp) { - const struct ip6_dest *dp = (struct ip6_dest *)bp; + const struct ip6_dest *dp = (const struct ip6_dest *)bp; int dstoptlen = 0; ND_TCHECK(dp->ip6d_len); @@ -211,4 +211,3 @@ dstopt_print(netdissect_options *ndo, register const u_char *bp) ND_PRINT((ndo, "[|DSTOPT]")); return(-1); } -#endif /* INET6 */ diff --git a/contrib/tcpdump/print-ipcomp.c b/contrib/tcpdump/print-ipcomp.c index 1ba687e..291caa9 100644 --- a/contrib/tcpdump/print-ipcomp.c +++ b/contrib/tcpdump/print-ipcomp.c @@ -19,12 +19,13 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: IP Payload Compression Protocol (IPComp) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include struct ipcomp { uint8_t comp_nxt; /* Next Header */ @@ -32,52 +33,37 @@ struct ipcomp { uint16_t comp_cpi; /* Compression parameter index */ }; -#if defined(HAVE_LIBZ) && defined(HAVE_ZLIB_H) -#include -#endif - -#include "interface.h" +#include "netdissect.h" #include "extract.h" -int -ipcomp_print(netdissect_options *ndo, register const u_char *bp, int *nhdr _U_) +void +ipcomp_print(netdissect_options *ndo, register const u_char *bp) { register const struct ipcomp *ipcomp; - register const u_char *ep; uint16_t cpi; -#if defined(HAVE_LIBZ) && defined(HAVE_ZLIB_H) - int advance; -#endif - ipcomp = (struct ipcomp *)bp; + ipcomp = (const struct ipcomp *)bp; + ND_TCHECK(*ipcomp); cpi = EXTRACT_16BITS(&ipcomp->comp_cpi); - /* 'ep' points to the end of available data. */ - ep = ndo->ndo_snapend; - - if ((u_char *)(ipcomp + 1) >= ep - sizeof(struct ipcomp)) { - ND_PRINT((ndo, "[|IPCOMP]")); - goto fail; - } ND_PRINT((ndo, "IPComp(cpi=0x%04x)", cpi)); -#if defined(HAVE_LIBZ) && defined(HAVE_ZLIB_H) - if (1) - goto fail; - /* - * We may want to decompress the packet here. Packet buffer - * management is a headache (if we decompress, packet will become - * larger). + * XXX - based on the CPI, we could decompress the packet here. + * Packet buffer management is a headache (if we decompress, + * packet will become larger). + * + * We would decompress the packet and then call a routine that, + * based on ipcomp->comp_nxt, dissects the decompressed data. + * + * Until we do that, however, we just return -1, so that + * the loop that processes "protocol"/"next header" types + * stops - there's nothing more it can do with a compressed + * payload. */ - if (nhdr) - *nhdr = ipcomp->comp_nxt; - advance = sizeof(struct ipcomp); + return; - ND_PRINT((ndo, ": ")); - return advance; - -#endif -fail: - return -1; +trunc: + ND_PRINT((ndo, "[|IPCOMP]")); + return; } diff --git a/contrib/tcpdump/print-ipfc.c b/contrib/tcpdump/print-ipfc.c index 295ac0f..b8a08e9 100644 --- a/contrib/tcpdump/print-ipfc.c +++ b/contrib/tcpdump/print-ipfc.c @@ -19,24 +19,23 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: IP over Fibre Channel printer */ + +/* specification: RFC 2625 */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "ether.h" -/* - * RFC 2625 IP-over-Fibre Channel. - */ - struct ipfc_header { u_char ipfc_dhost[8]; u_char ipfc_shost[8]; @@ -72,21 +71,34 @@ ipfc_hdr_print(netdissect_options *ndo, dstname = etheraddr_string(ndo, ipfcdst); /* - * XXX - show the upper 16 bits? Do so only if "vflag" is set? + * XXX - should we show the upper 16 bits of the addresses? + * Do so only if "vflag" is set? + * Section 3.3 "FC Port and Node Network Addresses" says that + * + * In this specification, both the Source and Destination + * 4-bit NAA identifiers SHALL be set to binary '0001' + * indicating that an IEEE 48-bit MAC address is contained + * in the lower 48 bits of the network address fields. The + * high order 12 bits in the network address fields SHALL + * be set to 0x0000. + * + * so, for captures following this specification, the upper 16 + * bits should be 0x1000, followed by a MAC address. */ - ND_PRINT((ndo, "%s %s %d: ", srcname, dstname, length)); + ND_PRINT((ndo, "%s > %s, length %u: ", srcname, dstname, length)); } -static void +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; - u_short extracted_ethertype; + struct lladdr_info src, dst; + int llc_hdrlen; if (caplen < IPFC_HDRLEN) { ND_PRINT((ndo, "[|ipfc]")); - return; + return (caplen); } /* * Get the network addresses into a canonical form @@ -96,28 +108,28 @@ ipfc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen) if (ndo->ndo_eflag) ipfc_hdr_print(ndo, ipfcp, length, ESRC(&ehdr), EDST(&ehdr)); + src.addr = ESRC(&ehdr); + src.addr_string = etheraddr_string; + dst.addr = EDST(&ehdr); + dst.addr_string = etheraddr_string; + /* Skip over Network_Header */ length -= IPFC_HDRLEN; p += IPFC_HDRLEN; caplen -= IPFC_HDRLEN; /* Try to print the LLC-layer header & higher layers */ - if (llc_print(ndo, p, length, caplen, ESRC(&ehdr), EDST(&ehdr), - &extracted_ethertype) == 0) { + llc_hdrlen = llc_print(ndo, p, length, caplen, &src, &dst); + if (llc_hdrlen < 0) { /* * Some kinds of LLC packet we cannot * handle intelligently */ - if (!ndo->ndo_eflag) - ipfc_hdr_print(ndo, ipfcp, length + IPFC_HDRLEN, - ESRC(&ehdr), EDST(&ehdr)); - if (extracted_ethertype) { - ND_PRINT((ndo, "(LLC %s) ", - etherproto_string(htons(extracted_ethertype)))); - } if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); + llc_hdrlen = -llc_hdrlen; } + return (IPFC_HDRLEN + llc_hdrlen); } /* @@ -129,7 +141,5 @@ ipfc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen) u_int ipfc_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, register const u_char *p) { - ipfc_print(ndo, p, h->len, h->caplen); - - return (IPFC_HDRLEN); + return (ipfc_print(ndo, p, h->len, h->caplen)); } diff --git a/contrib/tcpdump/print-ipnet.c b/contrib/tcpdump/print-ipnet.c index c4ff16a..f71c145 100644 --- a/contrib/tcpdump/print-ipnet.c +++ b/contrib/tcpdump/print-ipnet.c @@ -1,11 +1,12 @@ -#define NETDISSECT_REWORKED +/* \summary: Solaris DLT_IPNET printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" typedef struct ipnet_hdr { uint8_t iph_version; @@ -55,7 +56,7 @@ ipnet_hdr_print(netdissect_options *ndo, const u_char *bp, u_int length) static void ipnet_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen) { - ipnet_hdr_t *hdr; + const ipnet_hdr_t *hdr; if (caplen < sizeof(ipnet_hdr_t)) { ND_PRINT((ndo, "[|ipnet]")); @@ -67,7 +68,7 @@ ipnet_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen length -= sizeof(ipnet_hdr_t); caplen -= sizeof(ipnet_hdr_t); - hdr = (ipnet_hdr_t *)p; + hdr = (const ipnet_hdr_t *)p; p += sizeof(ipnet_hdr_t); switch (hdr->iph_family) { @@ -82,7 +83,7 @@ ipnet_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen default: if (!ndo->ndo_eflag) - ipnet_hdr_print(ndo, (u_char *)hdr, + ipnet_hdr_print(ndo, (const u_char *)hdr, length + sizeof(ipnet_hdr_t)); if (!ndo->ndo_suppress_default_print) diff --git a/contrib/tcpdump/print-ipx.c b/contrib/tcpdump/print-ipx.c index f076d02..d807a66 100644 --- a/contrib/tcpdump/print-ipx.c +++ b/contrib/tcpdump/print-ipx.c @@ -18,22 +18,20 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * Format and print Novell IPX packets. * Contributed by Brad Parker (brad@fcr.com). - * - * $FreeBSD$ */ -#define NETDISSECT_REWORKED +/* \summary: Novell IPX printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" @@ -91,7 +89,7 @@ ipx_print(netdissect_options *ndo, const u_char *p, u_int length) ND_TCHECK(ipx->length); length = EXTRACT_16BITS(&ipx->length); - ipx_decode(ndo, ipx, (u_char *)ipx + ipxSize, length - ipxSize); + ipx_decode(ndo, ipx, p + ipxSize, length - ipxSize); return; trunc: ND_PRINT((ndo, "[|ipx %d]", length)); @@ -119,14 +117,14 @@ ipx_decode(netdissect_options *ndo, const struct ipxHdr *ipx, const u_char *data ND_PRINT((ndo, "ipx-ncp %d", length)); break; case IPX_SKT_SAP: - ipx_sap_print(ndo, (u_short *)datap, length); + ipx_sap_print(ndo, (const u_short *)datap, length); break; case IPX_SKT_RIP: - ipx_rip_print(ndo, (u_short *)datap, length); + ipx_rip_print(ndo, (const u_short *)datap, length); break; case IPX_SKT_NETBIOS: ND_PRINT((ndo, "ipx-netbios %d", length)); -#ifdef TCPDUMP_DO_SMB +#ifdef ENABLE_SMB ipx_netbios_print(ndo, datap, length); #endif break; @@ -135,7 +133,7 @@ ipx_decode(netdissect_options *ndo, const struct ipxHdr *ipx, const u_char *data break; case IPX_SKT_NWLINK_DGM: ND_PRINT((ndo, "ipx-nwlink-dgm %d", length)); -#ifdef TCPDUMP_DO_SMB +#ifdef ENABLE_SMB ipx_netbios_print(ndo, datap, length); #endif break; @@ -167,7 +165,7 @@ ipx_sap_print(netdissect_options *ndo, const u_short *ipx, u_int length) ND_PRINT((ndo, "ipx-sap-nearest-req")); ND_TCHECK(ipx[0]); - ND_PRINT((ndo, " %s", ipxsap_string(htons(EXTRACT_16BITS(&ipx[0]))))); + ND_PRINT((ndo, " %s", ipxsap_string(ndo, htons(EXTRACT_16BITS(&ipx[0]))))); break; case 2: @@ -179,14 +177,14 @@ ipx_sap_print(netdissect_options *ndo, const u_short *ipx, u_int length) for (i = 0; i < 8 && length > 0; i++) { ND_TCHECK(ipx[0]); - ND_PRINT((ndo, " %s '", ipxsap_string(htons(EXTRACT_16BITS(&ipx[0]))))); - if (fn_printzp(ndo, (u_char *)&ipx[1], 48, ndo->ndo_snapend)) { + 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_TCHECK2(ipx[25], 10); ND_PRINT((ndo, "' addr %s", - ipxaddr_string(EXTRACT_32BITS(&ipx[25]), (u_char *)&ipx[27]))); + ipxaddr_string(EXTRACT_32BITS(&ipx[25]), (const u_char *)&ipx[27]))); ipx += 32; length -= 64; } diff --git a/contrib/tcpdump/print-isakmp.c b/contrib/tcpdump/print-isakmp.c index bef0b45..3dfa171 100644 --- a/contrib/tcpdump/print-isakmp.c +++ b/contrib/tcpdump/print-isakmp.c @@ -28,7 +28,8 @@ * */ -#define NETDISSECT_REWORKED +/* \summary: Internet Security Association and Key Management Protocol (ISAKMP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -40,18 +41,16 @@ #undef HAVE_LIBCRYPTO #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" -#include "extract.h" /* must come after interface.h */ +#include "extract.h" #include "ip.h" -#ifdef INET6 #include "ip6.h" -#endif /* refer to RFC 2408 */ @@ -355,7 +354,7 @@ enum ikev2_t_type { IV2_T_PRF = 2, IV2_T_INTEG= 3, IV2_T_DH = 4, - IV2_T_ESN = 5, + IV2_T_ESN = 5 }; /* 3.4. Key Exchange Payload */ @@ -375,7 +374,7 @@ enum ikev2_id_type { ID_IPV6_ADDR=5, ID_DER_ASN1_DN=9, ID_DER_ASN1_GN=10, - ID_KEY_ID=11, + ID_KEY_ID=11 }; struct ikev2_id { struct isakmp_gen h; @@ -439,7 +438,7 @@ struct ikev2_auth { enum ikev2_auth_type { IV2_RSA_SIG = 1, IV2_SHARED = 2, - IV2_DSS_SIG = 3, + IV2_DSS_SIG = 3 }; /* refer to RFC 2409 */ @@ -645,14 +644,12 @@ ikev1_print(netdissect_options *ndo, const u_char *bp2, struct isakmp *base); #define MAXINITIATORS 20 -int ninitiator = 0; +static int ninitiator = 0; union inaddr_u { struct in_addr in4; -#ifdef INET6 struct in6_addr in6; -#endif }; -struct { +static struct { cookie_t initiator; u_int version; union inaddr_u iaddr; @@ -742,7 +739,7 @@ static const char *etypestr[] = { #define ETYPESTR(x) STR_OR_ID(x, etypestr) #define CHECKLEN(p, np) \ - if (ep < (u_char *)(p)) { \ + if (ep < (const u_char *)(p)) { \ ND_PRINT((ndo," [|%s]", NPSTR(np))); \ goto done; \ } @@ -753,7 +750,7 @@ static const char *etypestr[] = { ? npfunc[(x)] : NULL) static int -iszero(u_char *p, size_t l) +iszero(const u_char *p, size_t l) { while (l--) { if (*p++) @@ -781,10 +778,8 @@ static void cookie_record(cookie_t *in, const u_char *bp2) { int i; - struct ip *ip; -#ifdef INET6 - struct ip6_hdr *ip6; -#endif + const struct ip *ip; + const struct ip6_hdr *ip6; i = cookie_find(in); if (0 <= i) { @@ -792,21 +787,19 @@ cookie_record(cookie_t *in, const u_char *bp2) return; } - ip = (struct ip *)bp2; + ip = (const struct ip *)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)); break; -#ifdef INET6 case 6: - ip6 = (struct ip6_hdr *)bp2; + 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)); break; -#endif default: return; } @@ -819,12 +812,10 @@ cookie_record(cookie_t *in, const u_char *bp2) static int cookie_sidecheck(int i, const u_char *bp2, int initiator) { - struct ip *ip; -#ifdef INET6 - struct ip6_hdr *ip6; -#endif + const struct ip *ip; + const struct ip6_hdr *ip6; - ip = (struct ip *)bp2; + ip = (const struct ip *)bp2; switch (IP_V(ip)) { case 4: if (cookiecache[i].version != 4) @@ -837,11 +828,10 @@ cookie_sidecheck(int i, const u_char *bp2, int initiator) return 1; } break; -#ifdef INET6 case 6: if (cookiecache[i].version != 6) return 0; - ip6 = (struct ip6_hdr *)bp2; + ip6 = (const struct ip6_hdr *)bp2; if (initiator) { if (UNALIGNED_MEMCMP(&ip6->ip6_src, &cookiecache[i].iaddr.in6, sizeof(struct in6_addr)) == 0) return 1; @@ -850,7 +840,6 @@ cookie_sidecheck(int i, const u_char *bp2, int initiator) return 1; } break; -#endif /* INET6 */ default: break; } @@ -859,18 +848,18 @@ cookie_sidecheck(int i, const u_char *bp2, int initiator) } static void -hexprint(netdissect_options *ndo, caddr_t loc, size_t len) +hexprint(netdissect_options *ndo, const uint8_t *loc, size_t len) { - u_char *p; + const uint8_t *p; size_t i; - p = (u_char *)loc; + p = loc; for (i = 0; i < len; i++) ND_PRINT((ndo,"%02x", p[i] & 0xff)); } static int -rawprint(netdissect_options *ndo, caddr_t loc, size_t len) +rawprint(netdissect_options *ndo, const uint8_t *loc, size_t len) { ND_TCHECK2(*loc, len); @@ -902,10 +891,10 @@ static int ike_show_somedata(netdissect_options *ndo, } ND_PRINT((ndo," data=(")); - if(!rawprint(ndo, (caddr_t)(cp), len)) goto trunc; + if(!rawprint(ndo, (const uint8_t *)(cp), len)) goto trunc; ND_PRINT((ndo, "...")); if(elen) { - if(!rawprint(ndo, (caddr_t)(end), elen)) goto trunc; + if(!rawprint(ndo, (const uint8_t *)(end), elen)) goto trunc; } ND_PRINT((ndo,")")); return 1; @@ -949,10 +938,10 @@ ikev1_attrmap_print(netdissect_options *ndo, if (map && t < nmap && v < map[t].nvalue && map[t].value[v]) ND_PRINT((ndo,"%s", map[t].value[v])); else - rawprint(ndo, (caddr_t)&p[2], 2); + rawprint(ndo, (const uint8_t *)&p[2], 2); } else { ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&p[2]))); - rawprint(ndo, (caddr_t)&p[4], EXTRACT_16BITS(&p[2])); + rawprint(ndo, (const uint8_t *)&p[4], EXTRACT_16BITS(&p[2])); } ND_PRINT((ndo,")")); return p + totlen; @@ -979,10 +968,10 @@ ikev1_attr_print(netdissect_options *ndo, const u_char *p, const u_char *ep) if (p[0] & 0x80) { ND_PRINT((ndo,"value=")); t = p[2]; - rawprint(ndo, (caddr_t)&p[2], 2); + rawprint(ndo, (const uint8_t *)&p[2], 2); } else { ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&p[2]))); - rawprint(ndo, (caddr_t)&p[4], EXTRACT_16BITS(&p[2])); + rawprint(ndo, (const uint8_t *)&p[4], EXTRACT_16BITS(&p[2])); } ND_PRINT((ndo,")")); return p + totlen; @@ -1003,7 +992,7 @@ ikev1_sa_print(netdissect_options *ndo, u_char tpay _U_, ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_SA))); - p = (struct ikev1_pl_sa *)ext; + p = (const struct ikev1_pl_sa *)ext; ND_TCHECK(*p); UNALIGNED_MEMCPY(&sa, ext, sizeof(sa)); doi = ntohl(sa.doi); @@ -1011,7 +1000,7 @@ ikev1_sa_print(netdissect_options *ndo, u_char tpay _U_, if (doi != 1) { ND_PRINT((ndo," doi=%d", doi)); ND_PRINT((ndo," situation=%u", (uint32_t)ntohl(sa.sit))); - return (u_char *)(p + 1); + return (const u_char *)(p + 1); } ND_PRINT((ndo," doi=ipsec")); @@ -1028,7 +1017,7 @@ ikev1_sa_print(netdissect_options *ndo, u_char tpay _U_, if (sit & 0x04) ND_PRINT((ndo,"%sintegrity", t ? "+" : "")); - np = (u_char *)ext + sizeof(sa); + np = (const u_char *)ext + sizeof(sa); if (sit != 0x01) { ND_TCHECK2(*(ext + 1), sizeof(ident)); UNALIGNED_MEMCPY(&ident, ext + 1, sizeof(ident)); @@ -1036,7 +1025,7 @@ ikev1_sa_print(netdissect_options *ndo, u_char tpay _U_, np += sizeof(ident); } - ext = (struct isakmp_gen *)np; + ext = (const struct isakmp_gen *)np; ND_TCHECK(*ext); cp = ikev1_sub_print(ndo, ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0, @@ -1060,18 +1049,18 @@ ikev1_p_print(netdissect_options *ndo, u_char tpay _U_, ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_P))); - p = (struct ikev1_pl_p *)ext; + 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, (caddr_t)(p + 1), prop.spi_size)) + if (!rawprint(ndo, (const uint8_t *)(p + 1), prop.spi_size)) goto trunc; } - ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size); + ext = (const struct isakmp_gen *)((const u_char *)(p + 1) + prop.spi_size); ND_TCHECK(*ext); cp = ikev1_sub_print(ndo, ISAKMP_NPTYPE_T, ext, ep, phase, doi0, @@ -1227,7 +1216,7 @@ ikev1_t_print(netdissect_options *ndo, u_char tpay _U_, ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_T))); - p = (struct ikev1_pl_t *)ext; + p = (const struct ikev1_pl_t *)ext; ND_TCHECK(*p); UNALIGNED_MEMCPY(&t, ext, sizeof(t)); @@ -1263,8 +1252,8 @@ ikev1_t_print(netdissect_options *ndo, u_char tpay _U_, ND_PRINT((ndo," #%d id=%s ", t.t_no, idstr)); else ND_PRINT((ndo," #%d id=%d ", t.t_no, t.t_id)); - cp = (u_char *)(p + 1); - ep2 = (u_char *)p + item_len; + cp = (const u_char *)(p + 1); + ep2 = (const u_char *)p + item_len; while (cp < ep && cp < ep2) { if (map && nmap) { cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2, @@ -1295,10 +1284,10 @@ ikev1_ke_print(netdissect_options *ndo, u_char tpay _U_, ND_PRINT((ndo," key len=%d", ntohs(e.len) - 4)); if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { ND_PRINT((ndo," ")); - if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) + if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4)) goto trunc; } - return (u_char *)ext + ntohs(e.len); + return (const u_char *)ext + ntohs(e.len); trunc: ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_KE))); return NULL; @@ -1326,11 +1315,11 @@ ikev1_id_print(netdissect_options *ndo, u_char tpay _U_, ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_ID))); - p = (struct ikev1_pl_id *)ext; + p = (const struct ikev1_pl_id *)ext; ND_TCHECK(*p); UNALIGNED_MEMCPY(&id, ext, sizeof(id)); if (sizeof(*p) < item_len) { - data = (u_char *)(p + 1); + data = (const u_char *)(p + 1); len = item_len - sizeof(*p); } else { data = NULL; @@ -1355,27 +1344,27 @@ ikev1_id_print(netdissect_options *ndo, u_char tpay _U_, #endif case 2: { - const struct ipsecdoi_id *p; - struct ipsecdoi_id id; + const struct ipsecdoi_id *doi_p; + struct ipsecdoi_id doi_id; struct protoent *pe; - p = (struct ipsecdoi_id *)ext; - ND_TCHECK(*p); - UNALIGNED_MEMCPY(&id, ext, sizeof(id)); - ND_PRINT((ndo," idtype=%s", STR_OR_ID(id.type, ipsecidtypestr))); + 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))); /* A protocol ID of 0 DOES NOT mean IPPROTO_IP! */ - pe = id.proto_id ? getprotobynumber(id.proto_id) : NULL; + pe = doi_id.proto_id ? getprotobynumber(doi_id.proto_id) : NULL; if (pe) ND_PRINT((ndo," protoid=%s", pe->p_name)); else - ND_PRINT((ndo," protoid=%u", id.proto_id)); - ND_PRINT((ndo," port=%d", ntohs(id.port))); + ND_PRINT((ndo," protoid=%u", doi_id.proto_id)); + ND_PRINT((ndo," port=%d", ntohs(doi_id.port))); if (!len) break; if (data == NULL) goto trunc; ND_TCHECK2(*data, len); - switch (id.type) { + switch (doi_id.type) { case IPSECDOI_ID_IPV4_ADDR: if (len < 4) ND_PRINT((ndo," len=%d [bad: < 4]", len)); @@ -1407,7 +1396,6 @@ ikev1_id_print(netdissect_options *ndo, u_char tpay _U_, len = 0; break; } -#ifdef INET6 case IPSECDOI_ID_IPV6_ADDR: if (len < 16) ND_PRINT((ndo," len=%d [bad: < 16]", len)); @@ -1421,7 +1409,7 @@ ikev1_id_print(netdissect_options *ndo, u_char tpay _U_, if (len < 20) ND_PRINT((ndo," len=%d [bad: < 20]", len)); else { - mask = (u_char *)(data + sizeof(struct in6_addr)); + mask = (const u_char *)(data + sizeof(struct in6_addr)); /*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), @@ -1433,7 +1421,6 @@ ikev1_id_print(netdissect_options *ndo, u_char tpay _U_, len = 0; break; } -#endif /*INET6*/ case IPSECDOI_ID_IPV4_ADDR_RANGE: if (len < 8) ND_PRINT((ndo," len=%d [bad: < 8]", len)); @@ -1444,7 +1431,6 @@ ikev1_id_print(netdissect_options *ndo, u_char tpay _U_, } len = 0; break; -#ifdef INET6 case IPSECDOI_ID_IPV6_ADDR_RANGE: if (len < 32) ND_PRINT((ndo," len=%d [bad: < 32]", len)); @@ -1455,7 +1441,6 @@ ikev1_id_print(netdissect_options *ndo, u_char tpay _U_, } len = 0; break; -#endif /*INET6*/ case IPSECDOI_ID_DER_ASN1_DN: case IPSECDOI_ID_DER_ASN1_GN: case IPSECDOI_ID_KEY_ID: @@ -1468,11 +1453,11 @@ ikev1_id_print(netdissect_options *ndo, u_char tpay _U_, ND_PRINT((ndo," len=%d", len)); if (2 < ndo->ndo_vflag) { ND_PRINT((ndo," ")); - if (!rawprint(ndo, (caddr_t)data, len)) + if (!rawprint(ndo, (const uint8_t *)data, len)) goto trunc; } } - return (u_char *)ext + item_len; + return (const u_char *)ext + item_len; trunc: ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_ID))); return NULL; @@ -1480,7 +1465,7 @@ trunc: static const u_char * ikev1_cert_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 doi0 _U_, uint32_t proto0 _U_, int depth _U_) @@ -1495,17 +1480,17 @@ ikev1_cert_print(netdissect_options *ndo, u_char tpay _U_, ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_CERT))); - p = (struct ikev1_pl_cert *)ext; + 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))); if (2 < ndo->ndo_vflag && 4 < item_len) { ND_PRINT((ndo," ")); - if (!rawprint(ndo, (caddr_t)(ext + 1), item_len - 4)) + if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4)) goto trunc; } - return (u_char *)ext + item_len; + return (const u_char *)ext + item_len; trunc: ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_CERT))); return NULL; @@ -1513,7 +1498,7 @@ trunc: static const u_char * ikev1_cr_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 doi0 _U_, uint32_t proto0 _U_, int depth _U_) { @@ -1527,17 +1512,17 @@ ikev1_cr_print(netdissect_options *ndo, u_char tpay _U_, ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_CR))); - p = (struct ikev1_pl_cert *)ext; + 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))); if (2 < ndo->ndo_vflag && 4 < item_len) { ND_PRINT((ndo," ")); - if (!rawprint(ndo, (caddr_t)(ext + 1), item_len - 4)) + if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4)) goto trunc; } - return (u_char *)ext + item_len; + return (const u_char *)ext + item_len; trunc: ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_CR))); return NULL; @@ -1558,10 +1543,10 @@ ikev1_hash_print(netdissect_options *ndo, u_char tpay _U_, ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { ND_PRINT((ndo," ")); - if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) + if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4)) goto trunc; } - return (u_char *)ext + ntohs(e.len); + return (const u_char *)ext + ntohs(e.len); trunc: ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_HASH))); return NULL; @@ -1582,10 +1567,10 @@ ikev1_sig_print(netdissect_options *ndo, u_char tpay _U_, ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { ND_PRINT((ndo," ")); - if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) + if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4)) goto trunc; } - return (u_char *)ext + ntohs(e.len); + return (const u_char *)ext + ntohs(e.len); trunc: ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_SIG))); return NULL; @@ -1595,7 +1580,7 @@ static const u_char * ikev1_nonce_print(netdissect_options *ndo, u_char tpay _U_, const struct isakmp_gen *ext, u_int item_len _U_, - const u_char *ep _U_, + const u_char *ep, uint32_t phase _U_, uint32_t doi _U_, uint32_t proto _U_, int depth _U_) { @@ -1608,14 +1593,14 @@ ikev1_nonce_print(netdissect_options *ndo, u_char tpay _U_, ND_PRINT((ndo," n len=%d", ntohs(e.len) - 4)); if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { ND_PRINT((ndo," ")); - if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) + if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4)) goto trunc; } else if (1 < ndo->ndo_vflag && 4 < ntohs(e.len)) { ND_PRINT((ndo," ")); - if (!ike_show_somedata(ndo, (u_char *)(caddr_t)(ext + 1), ep)) + if (!ike_show_somedata(ndo, (const u_char *)(const uint8_t *)(ext + 1), ep)) goto trunc; } - return (u_char *)ext + ntohs(e.len); + return (const u_char *)ext + ntohs(e.len); trunc: ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_NONCE))); return NULL; @@ -1627,9 +1612,10 @@ ikev1_n_print(netdissect_options *ndo, u_char tpay _U_, const u_char *ep, uint32_t phase, uint32_t doi0 _U_, uint32_t proto0 _U_, int depth) { - struct ikev1_pl_n *p, n; + const struct ikev1_pl_n *p; + struct ikev1_pl_n n; const u_char *cp; - u_char *ep2; + const u_char *ep2; uint32_t doi; uint32_t proto; static const char *notify_error_str[] = { @@ -1680,7 +1666,7 @@ ikev1_n_print(netdissect_options *ndo, u_char tpay _U_, ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_N))); - p = (struct ikev1_pl_n *)ext; + p = (const struct ikev1_pl_n *)ext; ND_TCHECK(*p); UNALIGNED_MEMCPY(&n, ext, sizeof(n)); doi = ntohl(n.doi); @@ -1698,10 +1684,10 @@ ikev1_n_print(netdissect_options *ndo, u_char tpay _U_, ND_PRINT((ndo," type=%s", numstr(ntohs(n.type)))); if (n.spi_size) { ND_PRINT((ndo," spi=")); - if (!rawprint(ndo, (caddr_t)(p + 1), n.spi_size)) + if (!rawprint(ndo, (const uint8_t *)(p + 1), n.spi_size)) goto trunc; } - return (u_char *)(p + 1) + n.spi_size; + return (const u_char *)(p + 1) + n.spi_size; } ND_PRINT((ndo," doi=ipsec")); @@ -1718,12 +1704,12 @@ ikev1_n_print(netdissect_options *ndo, u_char tpay _U_, ND_PRINT((ndo," type=%s", numstr(ntohs(n.type)))); if (n.spi_size) { ND_PRINT((ndo," spi=")); - if (!rawprint(ndo, (caddr_t)(p + 1), n.spi_size)) + if (!rawprint(ndo, (const uint8_t *)(p + 1), n.spi_size)) goto trunc; } - cp = (u_char *)(p + 1) + n.spi_size; - ep2 = (u_char *)p + item_len; + cp = (const u_char *)(p + 1) + n.spi_size; + ep2 = (const u_char *)p + item_len; if (cp < ep) { ND_PRINT((ndo," orig=(")); @@ -1744,7 +1730,7 @@ ikev1_n_print(netdissect_options *ndo, u_char tpay _U_, break; case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN: if (ikev1_sub_print(ndo, ISAKMP_NPTYPE_SA, - (struct isakmp_gen *)cp, ep, phase, doi, proto, + (const struct isakmp_gen *)cp, ep, phase, doi, proto, depth) == NULL) return NULL; break; @@ -1756,7 +1742,7 @@ ikev1_n_print(netdissect_options *ndo, u_char tpay _U_, } ND_PRINT((ndo,")")); } - return (u_char *)ext + item_len; + return (const u_char *)ext + item_len; trunc: ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_N))); return NULL; @@ -1777,7 +1763,7 @@ ikev1_d_print(netdissect_options *ndo, u_char tpay _U_, ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_D))); - p = (struct ikev1_pl_d *)ext; + p = (const struct ikev1_pl_d *)ext; ND_TCHECK(*p); UNALIGNED_MEMCPY(&d, ext, sizeof(d)); doi = ntohl(d.doi); @@ -1792,11 +1778,11 @@ ikev1_d_print(netdissect_options *ndo, u_char tpay _U_, ND_PRINT((ndo," spilen=%u", d.spi_size)); ND_PRINT((ndo," nspi=%u", ntohs(d.num_spi))); ND_PRINT((ndo," spi=")); - q = (uint8_t *)(p + 1); + q = (const uint8_t *)(p + 1); for (i = 0; i < ntohs(d.num_spi); i++) { if (i != 0) ND_PRINT((ndo,",")); - if (!rawprint(ndo, (caddr_t)q, d.spi_size)) + if (!rawprint(ndo, (const uint8_t *)q, d.spi_size)) goto trunc; q += d.spi_size; } @@ -1822,10 +1808,10 @@ ikev1_vid_print(netdissect_options *ndo, u_char tpay _U_, ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { ND_PRINT((ndo," ")); - if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) + if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4)) goto trunc; } - return (u_char *)ext + ntohs(e.len); + return (const u_char *)ext + ntohs(e.len); trunc: ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_VID))); return NULL; @@ -1856,20 +1842,19 @@ ikev2_gen_print(netdissect_options *ndo, u_char tpay, ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { ND_PRINT((ndo," ")); - if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) + if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4)) goto trunc; } - return (u_char *)ext + ntohs(e.len); + return (const u_char *)ext + ntohs(e.len); trunc: ND_PRINT((ndo," [|%s]", NPSTR(tpay))); return NULL; } static const u_char * -ikev2_t_print(netdissect_options *ndo, u_char tpay _U_, int pcount, +ikev2_t_print(netdissect_options *ndo, int tcount, const struct isakmp_gen *ext, u_int item_len, - const u_char *ep, uint32_t phase _U_, uint32_t doi _U_, - uint32_t proto _U_, int depth _U_) + const u_char *ep) { const struct ikev2_t *p; struct ikev2_t t; @@ -1880,7 +1865,7 @@ ikev2_t_print(netdissect_options *ndo, u_char tpay _U_, int pcount, size_t nmap; const u_char *ep2; - p = (struct ikev2_t *)ext; + 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); @@ -1919,15 +1904,15 @@ ikev2_t_print(netdissect_options *ndo, u_char tpay _U_, int pcount, } if (idstr) - ND_PRINT((ndo," #%u type=%s id=%s ", pcount, + ND_PRINT((ndo," #%u type=%s id=%s ", tcount, STR_OR_ID(t.t_type, ikev2_t_type_map), idstr)); else - ND_PRINT((ndo," #%u type=%s id=%u ", pcount, + ND_PRINT((ndo," #%u type=%s id=%u ", tcount, STR_OR_ID(t.t_type, ikev2_t_type_map), t.t_id)); - cp = (u_char *)(p + 1); - ep2 = (u_char *)p + item_len; + cp = (const u_char *)(p + 1); + ep2 = (const u_char *)p + item_len; while (cp < ep && cp < ep2) { if (map && nmap) { cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2, @@ -1945,34 +1930,97 @@ trunc: static const u_char * ikev2_p_print(netdissect_options *ndo, u_char tpay _U_, int pcount _U_, - const struct isakmp_gen *ext, u_int item_len _U_, - const u_char *ep, uint32_t phase, uint32_t doi0, - uint32_t proto0 _U_, int depth) + const struct isakmp_gen *ext, u_int oprop_length, + const u_char *ep, int depth) { const struct ikev2_p *p; struct ikev2_p prop; + u_int prop_length; const u_char *cp; + int i; + int tcount; + u_char np; + struct isakmp_gen e; + u_int item_len; - p = (struct ikev2_p *)ext; + p = (const struct ikev2_p *)ext; ND_TCHECK(*p); UNALIGNED_MEMCPY(&prop, ext, sizeof(prop)); + ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_P), prop.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, ntohs(prop.h.len))); + prop.num_t, oprop_length)); + cp = (const u_char *)(p + 1); + if (prop.spi_size) { + if (prop_length < prop.spi_size) + goto toolong; ND_PRINT((ndo," spi=")); - if (!rawprint(ndo, (caddr_t)(p + 1), prop.spi_size)) + if (!rawprint(ndo, (const uint8_t *)cp, prop.spi_size)) goto trunc; + cp += prop.spi_size; + prop_length -= prop.spi_size; } - ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size); - ND_TCHECK(*ext); + /* + * Print the transforms. + */ + tcount = 0; + for (np = ISAKMP_NPTYPE_T; np != 0; np = e.np) { + tcount++; + ext = (const struct isakmp_gen *)cp; + if (prop_length < sizeof(*ext)) + goto toolong; + ND_TCHECK(*ext); - cp = ikev2_sub_print(ndo, NULL, ISAKMP_NPTYPE_T, ext, ep, phase, doi0, - prop.prot_id, depth); + UNALIGNED_MEMCPY(&e, ext, sizeof(e)); + + /* + * Since we can't have a payload length of less than 4 bytes, + * we need to bail out here if the generic header is nonsensical + * or truncated, otherwise we could loop forever processing + * zero-length items or otherwise misdissect the packet. + */ + item_len = ntohs(e.len); + if (item_len <= 4) + goto trunc; + + if (prop_length < item_len) + goto toolong; + ND_TCHECK2(*cp, item_len); + depth++; + ND_PRINT((ndo,"\n")); + for (i = 0; i < depth; i++) + ND_PRINT((ndo," ")); + ND_PRINT((ndo,"(")); + if (np == ISAKMP_NPTYPE_T) { + cp = ikev2_t_print(ndo, tcount, ext, item_len, ep); + if (cp == NULL) { + /* error, already reported */ + return NULL; + } + } else { + ND_PRINT((ndo, "%s", NPSTR(np))); + cp += item_len; + } + ND_PRINT((ndo,")")); + depth--; + prop_length -= item_len; + } + return cp; +toolong: + /* + * Skip the rest of the proposal. + */ + cp += prop_length; + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_P))); return cp; trunc: ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_P))); @@ -1982,26 +2030,86 @@ trunc: static const u_char * ikev2_sa_print(netdissect_options *ndo, u_char tpay, const struct isakmp_gen *ext1, - u_int item_len _U_, const u_char *ep _U_, + u_int osa_length, const u_char *ep, uint32_t phase _U_, uint32_t doi _U_, - uint32_t proto _U_, int depth _U_) + uint32_t proto _U_, int depth) { + const struct isakmp_gen *ext; struct isakmp_gen e; - int osa_length, sa_length; + u_int sa_length; + const u_char *cp; + int i; + int pcount; + u_char np; + u_int item_len; ND_TCHECK(*ext1); UNALIGNED_MEMCPY(&e, ext1, sizeof(e)); ikev2_pay_print(ndo, "sa", e.critical); + /* + * ikev2_sub0_print() guarantees that this is >= 4. + */ osa_length= ntohs(e.len); sa_length = osa_length - 4; ND_PRINT((ndo," len=%d", sa_length)); - ikev2_sub_print(ndo, NULL, ISAKMP_NPTYPE_P, - ext1+1, ep, - 0, 0, 0, depth); + /* + * Print the payloads. + */ + cp = (const u_char *)(ext1 + 1); + pcount = 0; + for (np = ISAKMP_NPTYPE_P; np != 0; np = e.np) { + pcount++; + ext = (const struct isakmp_gen *)cp; + if (sa_length < sizeof(*ext)) + goto toolong; + ND_TCHECK(*ext); + + UNALIGNED_MEMCPY(&e, ext, sizeof(e)); + + /* + * Since we can't have a payload length of less than 4 bytes, + * we need to bail out here if the generic header is nonsensical + * or truncated, otherwise we could loop forever processing + * zero-length items or otherwise misdissect the packet. + */ + item_len = ntohs(e.len); + if (item_len <= 4) + goto trunc; + + if (sa_length < item_len) + goto toolong; + ND_TCHECK2(*cp, item_len); - return (u_char *)ext1 + osa_length; + depth++; + ND_PRINT((ndo,"\n")); + for (i = 0; i < depth; i++) + ND_PRINT((ndo," ")); + ND_PRINT((ndo,"(")); + if (np == ISAKMP_NPTYPE_P) { + cp = ikev2_p_print(ndo, np, pcount, ext, item_len, + ep, depth); + if (cp == NULL) { + /* error, already reported */ + return NULL; + } + } else { + ND_PRINT((ndo, "%s", NPSTR(np))); + cp += item_len; + } + ND_PRINT((ndo,")")); + depth--; + sa_length -= item_len; + } + return cp; +toolong: + /* + * Skip the rest of the SA. + */ + cp += sa_length; + ND_PRINT((ndo," [|%s]", NPSTR(tpay))); + return cp; trunc: ND_PRINT((ndo," [|%s]", NPSTR(tpay))); return NULL; @@ -2015,9 +2123,9 @@ ikev2_ke_print(netdissect_options *ndo, u_char tpay, uint32_t proto _U_, int depth _U_) { struct ikev2_ke ke; - struct ikev2_ke *k; + const struct ikev2_ke *k; - k = (struct ikev2_ke *)ext; + k = (const struct ikev2_ke *)ext; ND_TCHECK(*ext); UNALIGNED_MEMCPY(&ke, ext, sizeof(ke)); ikev2_pay_print(ndo, NPSTR(tpay), ke.h.critical); @@ -2027,10 +2135,10 @@ ikev2_ke_print(netdissect_options *ndo, u_char tpay, if (2 < ndo->ndo_vflag && 8 < ntohs(ke.h.len)) { ND_PRINT((ndo," ")); - if (!rawprint(ndo, (caddr_t)(k + 1), ntohs(ke.h.len) - 8)) + if (!rawprint(ndo, (const uint8_t *)(k + 1), ntohs(ke.h.len) - 8)) goto trunc; } - return (u_char *)ext + ntohs(ke.h.len); + return (const u_char *)ext + ntohs(ke.h.len); trunc: ND_PRINT((ndo," [|%s]", NPSTR(tpay))); return NULL; @@ -2046,7 +2154,7 @@ ikev2_ID_print(netdissect_options *ndo, u_char tpay, struct ikev2_id id; int id_len, idtype_len, i; unsigned int dumpascii, dumphex; - unsigned char *typedata; + const unsigned char *typedata; ND_TCHECK(*ext); UNALIGNED_MEMCPY(&id, ext, sizeof(id)); @@ -2057,14 +2165,14 @@ ikev2_ID_print(netdissect_options *ndo, u_char tpay, ND_PRINT((ndo," len=%d", id_len - 4)); if (2 < ndo->ndo_vflag && 4 < id_len) { ND_PRINT((ndo," ")); - if (!rawprint(ndo, (caddr_t)(ext + 1), id_len - 4)) + if (!rawprint(ndo, (const uint8_t *)(ext + 1), id_len - 4)) goto trunc; } idtype_len =id_len - sizeof(struct ikev2_id); dumpascii = 0; dumphex = 0; - typedata = (unsigned char *)(ext)+sizeof(struct ikev2_id); + typedata = (const unsigned char *)(ext)+sizeof(struct ikev2_id); switch(id.type) { case ID_IPV4_ADDR: @@ -2108,11 +2216,11 @@ ikev2_ID_print(netdissect_options *ndo, u_char tpay, } } if(dumphex) { - if (!rawprint(ndo, (caddr_t)typedata, idtype_len)) + if (!rawprint(ndo, (const uint8_t *)typedata, idtype_len)) goto trunc; } - return (u_char *)ext + id_len; + return (const u_char *)ext + id_len; trunc: ND_PRINT((ndo," [|%s]", NPSTR(tpay))); return NULL; @@ -2141,14 +2249,14 @@ ikev2_cr_print(netdissect_options *ndo, u_char tpay, static const u_char * ikev2_auth_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 _U_, const u_char *ep, uint32_t phase _U_, uint32_t doi _U_, uint32_t proto _U_, int depth _U_) { struct ikev2_auth a; const char *v2_auth[]={ "invalid", "rsasig", "shared-secret", "dsssig" }; - u_char *authdata = (u_char*)ext + sizeof(a); + const u_char *authdata = (const u_char*)ext + sizeof(a); unsigned int len; ND_TCHECK(*ext); @@ -2161,14 +2269,14 @@ ikev2_auth_print(netdissect_options *ndo, u_char tpay, if (1 < ndo->ndo_vflag && 4 < len) { ND_PRINT((ndo," authdata=(")); - if (!rawprint(ndo, (caddr_t)authdata, len - sizeof(a))) + if (!rawprint(ndo, (const uint8_t *)authdata, len - sizeof(a))) goto trunc; ND_PRINT((ndo,") ")); } else if(ndo->ndo_vflag && 4 < len) { if(!ike_show_somedata(ndo, authdata, ep)) goto trunc; } - return (u_char *)ext + len; + return (const u_char *)ext + len; trunc: ND_PRINT((ndo," [|%s]", NPSTR(tpay))); return NULL; @@ -2177,7 +2285,7 @@ trunc: 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_, + u_int item_len _U_, const u_char *ep, uint32_t phase _U_, uint32_t doi _U_, uint32_t proto _U_, int depth _U_) { @@ -2190,14 +2298,14 @@ ikev2_nonce_print(netdissect_options *ndo, u_char tpay, 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, (caddr_t)(ext + 1), ntohs(e.len) - 4)) + if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4)) goto trunc; ND_PRINT((ndo,") ")); } else if(ndo->ndo_vflag && 4 < ntohs(e.len)) { if(!ike_show_somedata(ndo, (const u_char *)(ext+1), ep)) goto trunc; } - return (u_char *)ext + ntohs(e.len); + return (const u_char *)ext + ntohs(e.len); trunc: ND_PRINT((ndo," [|%s]", NPSTR(tpay))); return NULL; @@ -2207,17 +2315,18 @@ trunc: static const u_char * ikev2_n_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, uint32_t phase _U_, uint32_t doi _U_, uint32_t proto _U_, int depth _U_) { - struct ikev2_n *p, n; + const struct ikev2_n *p; + struct ikev2_n n; const u_char *cp; u_char showspi, showdata, showsomedata; const char *notify_name; uint32_t type; - p = (struct ikev2_n *)ext; + 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); @@ -2384,11 +2493,11 @@ ikev2_n_print(netdissect_options *ndo, u_char tpay _U_, if (showspi && n.spi_size) { ND_PRINT((ndo," spi=")); - if (!rawprint(ndo, (caddr_t)(p + 1), n.spi_size)) + if (!rawprint(ndo, (const uint8_t *)(p + 1), n.spi_size)) goto trunc; } - cp = (u_char *)(p + 1) + n.spi_size; + cp = (const u_char *)(p + 1) + n.spi_size; if(3 < ndo->ndo_vflag) { showdata = 1; @@ -2396,7 +2505,7 @@ ikev2_n_print(netdissect_options *ndo, u_char tpay _U_, if ((showdata || (showsomedata && ep-cp < 30)) && cp < ep) { ND_PRINT((ndo," data=(")); - if (!rawprint(ndo, (caddr_t)(cp), ep - cp)) + if (!rawprint(ndo, (const uint8_t *)(cp), ep - cp)) goto trunc; ND_PRINT((ndo,")")); @@ -2405,7 +2514,7 @@ ikev2_n_print(netdissect_options *ndo, u_char tpay _U_, if(!ike_show_somedata(ndo, cp, ep)) goto trunc; } - return (u_char *)ext + item_len; + return (const u_char *)ext + item_len; trunc: ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_N))); return NULL; @@ -2446,10 +2555,10 @@ ikev2_vid_print(netdissect_options *ndo, u_char tpay, } if (2 < ndo->ndo_vflag && 4 < len) { ND_PRINT((ndo," ")); - if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) + if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4)) goto trunc; } - return (u_char *)ext + ntohs(e.len); + return (const u_char *)ext + ntohs(e.len); trunc: ND_PRINT((ndo," [|%s]", NPSTR(tpay))); return NULL; @@ -2492,7 +2601,7 @@ ikev2_e_print(netdissect_options *ndo, int depth) { struct isakmp_gen e; - u_char *dat; + const u_char *dat; volatile int dlen; ND_TCHECK(*ext); @@ -2504,11 +2613,11 @@ ikev2_e_print(netdissect_options *ndo, ND_PRINT((ndo," len=%d", dlen)); if (2 < ndo->ndo_vflag && 4 < dlen) { ND_PRINT((ndo," ")); - if (!rawprint(ndo, (caddr_t)(ext + 1), dlen)) + if (!rawprint(ndo, (const uint8_t *)(ext + 1), dlen)) goto trunc; } - dat = (u_char *)(ext+1); + dat = (const u_char *)(ext+1); ND_TCHECK2(*dat, dlen); #ifdef HAVE_LIBCRYPTO @@ -2566,7 +2675,7 @@ ike_sub0_print(netdissect_options *ndo, struct isakmp_gen e; u_int item_len; - cp = (u_char *)ext; + cp = (const u_char *)ext; ND_TCHECK(*ext); UNALIGNED_MEMCPY(&e, ext, sizeof(e)); @@ -2630,7 +2739,7 @@ ikev1_sub_print(netdissect_options *ndo, } np = e.np; - ext = (struct isakmp_gen *)cp; + ext = (const struct isakmp_gen *)cp; } return cp; trunc: @@ -2668,7 +2777,7 @@ ikev1_print(netdissect_options *ndo, i = cookie_find(&base->i_ck); if (i < 0) { - if (iszero((u_char *)&base->r_ck, sizeof(base->r_ck))) { + if (iszero((const u_char *)&base->r_ck, sizeof(base->r_ck))) { /* the first packet */ ND_PRINT((ndo," I")); if (bp2) @@ -2707,7 +2816,7 @@ ikev1_print(netdissect_options *ndo, CHECKLEN(p + 1, base->np); np = base->np; - ext = (struct isakmp_gen *)(p + 1); + ext = (const struct isakmp_gen *)(p + 1); ikev1_sub_print(ndo, np, ext, ep, phase, 0, 0, 0); } @@ -2722,7 +2831,7 @@ done: static const u_char * ikev2_sub0_print(netdissect_options *ndo, struct isakmp *base, - u_char np, int pcount, + u_char np, const struct isakmp_gen *ext, const u_char *ep, uint32_t phase, uint32_t doi, uint32_t proto, int depth) { @@ -2730,7 +2839,7 @@ ikev2_sub0_print(netdissect_options *ndo, struct isakmp *base, struct isakmp_gen e; u_int item_len; - cp = (u_char *)ext; + cp = (const u_char *)ext; ND_TCHECK(*ext); UNALIGNED_MEMCPY(&e, ext, sizeof(e)); @@ -2744,13 +2853,7 @@ ikev2_sub0_print(netdissect_options *ndo, struct isakmp *base, if (item_len <= 4) return NULL; - if(np == ISAKMP_NPTYPE_P) { - cp = ikev2_p_print(ndo, np, pcount, ext, item_len, - ep, phase, doi, proto, depth); - } else if(np == ISAKMP_NPTYPE_T) { - cp = ikev2_t_print(ndo, np, pcount, ext, item_len, - ep, phase, doi, proto, depth); - } else if(np == ISAKMP_NPTYPE_v2E) { + if (np == ISAKMP_NPTYPE_v2E) { cp = ikev2_e_print(ndo, base, np, ext, item_len, ep, phase, doi, proto, depth); } else if (NPFUNC(np)) { @@ -2758,7 +2861,7 @@ ikev2_sub0_print(netdissect_options *ndo, struct isakmp *base, * XXX - what if item_len is too short, or too long, * for this payload type? */ - cp = (*npfunc[np])(ndo, np, /*pcount,*/ ext, item_len, + cp = (*npfunc[np])(ndo, np, ext, item_len, ep, phase, doi, proto, depth); } else { ND_PRINT((ndo,"%s", NPSTR(np))); @@ -2779,13 +2882,10 @@ ikev2_sub_print(netdissect_options *ndo, { const u_char *cp; int i; - int pcount; struct isakmp_gen e; cp = (const u_char *)ext; - pcount = 0; while (np) { - pcount++; ND_TCHECK(*ext); UNALIGNED_MEMCPY(&e, ext, sizeof(e)); @@ -2797,7 +2897,7 @@ ikev2_sub_print(netdissect_options *ndo, for (i = 0; i < depth; i++) ND_PRINT((ndo," ")); ND_PRINT((ndo,"(")); - cp = ikev2_sub0_print(ndo, base, np, pcount, + cp = ikev2_sub0_print(ndo, base, np, ext, ep, phase, doi, proto, depth); ND_PRINT((ndo,")")); depth--; @@ -2808,7 +2908,7 @@ ikev2_sub_print(netdissect_options *ndo, } np = e.np; - ext = (struct isakmp_gen *)cp; + ext = (const struct isakmp_gen *)cp; } return cp; trunc: @@ -2861,7 +2961,7 @@ ikev2_print(netdissect_options *ndo, CHECKLEN(p + 1, base->np) np = base->np; - ext = (struct isakmp_gen *)(p + 1); + ext = (const struct isakmp_gen *)(p + 1); ikev2_sub_print(ndo, base, np, ext, ep, phase, 0, 0, 0); } @@ -2895,7 +2995,7 @@ isakmp_print(netdissect_options *ndo, p = (const struct isakmp *)bp; ep = ndo->ndo_snapend; - if ((struct isakmp *)ep < p + 1) { + if ((const struct isakmp *)ep < p + 1) { ND_PRINT((ndo,"[|isakmp]")); return; } @@ -2914,14 +3014,14 @@ isakmp_print(netdissect_options *ndo, if (ndo->ndo_vflag) { ND_PRINT((ndo," msgid ")); - hexprint(ndo, (caddr_t)&base.msgid, sizeof(base.msgid)); + hexprint(ndo, (const uint8_t *)&base.msgid, sizeof(base.msgid)); } if (1 < ndo->ndo_vflag) { ND_PRINT((ndo," cookie ")); - hexprint(ndo, (caddr_t)&base.i_ck, sizeof(base.i_ck)); + hexprint(ndo, (const uint8_t *)&base.i_ck, sizeof(base.i_ck)); ND_PRINT((ndo,"->")); - hexprint(ndo, (caddr_t)&base.r_ck, sizeof(base.r_ck)); + hexprint(ndo, (const uint8_t *)&base.r_ck, sizeof(base.r_ck)); } ND_PRINT((ndo,":")); diff --git a/contrib/tcpdump/print-isoclns.c b/contrib/tcpdump/print-isoclns.c index c3e7e87..d08085f 100644 --- a/contrib/tcpdump/print-isoclns.c +++ b/contrib/tcpdump/print-isoclns.c @@ -22,20 +22,19 @@ * * Extensively modified by Hannes Gredler (hannes@juniper.net) for more * complete IS-IS & CLNP support. - * - * $FreeBSD$ */ -#define NETDISSECT_REWORKED +/* \summary: ISO CLNS, ESIS, and ISIS printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "ether.h" #include "nlpid.h" @@ -44,6 +43,8 @@ #include "oui.h" #include "signature.h" +static const char tstr[] = " [|isis]"; + /* * IS-IS is defined in ISO 10589. Look there for protocol definitions. */ @@ -105,6 +106,7 @@ static const struct tok isis_pdu_values[] = { #define ISIS_TLV_AUTH 10 /* iso10589, rfc3567 */ #define ISIS_TLV_CHECKSUM 12 /* rfc3358 */ #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 */ @@ -154,6 +156,7 @@ static const struct tok isis_tlv_values[] = { { ISIS_TLV_LSP, "LSP entries"}, { ISIS_TLV_AUTH, "Authentication"}, { ISIS_TLV_CHECKSUM, "Checksum"}, + { ISIS_TLV_POI, "Purge Originator Identifier"}, { ISIS_TLV_LSP_BUFFERSIZE, "LSP Buffersize"}, { ISIS_TLV_EXT_IS_REACH, "Extended IS Reachability"}, { ISIS_TLV_IS_ALIAS_ID, "IS Alias ID"}, @@ -561,8 +564,8 @@ struct isis_tlv_ptp_adj { uint8_t neighbor_extd_local_circuit_id[4]; }; -static void osi_print_cksum(netdissect_options *, const uint8_t *pptr, uint16_t checksum, - u_int checksum_offset, u_int length); +static int osi_print_cksum(netdissect_options *, const uint8_t *pptr, + uint16_t checksum, int checksum_offset, int length); static int clnp_print(netdissect_options *, const uint8_t *, u_int); static void esis_print(netdissect_options *, const uint8_t *, u_int); static int isis_print(netdissect_options *, const uint8_t *, u_int); @@ -666,8 +669,9 @@ struct isis_tlv_lsp { #define ISIS_CSNP_HEADER_SIZE (sizeof(struct isis_csnp_header)) #define ISIS_PSNP_HEADER_SIZE (sizeof(struct isis_psnp_header)) -void isoclns_print(netdissect_options *ndo, - const uint8_t *p, u_int length, u_int caplen) +void +isoclns_print(netdissect_options *ndo, + const uint8_t *p, u_int length, u_int caplen) { if (caplen <= 1) { /* enough bytes on the wire ? */ ND_PRINT((ndo, "|OSI")); @@ -787,6 +791,18 @@ clnp_print(netdissect_options *ndo, return (0); } + if (li > length) { + ND_PRINT((ndo, " 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++)); + return (0); + } + /* FIXME further header sanity checking */ clnp_pdu_type = clnp_header->type & CLNP_PDU_TYPE_MASK; @@ -794,22 +810,46 @@ clnp_print(netdissect_options *ndo, pptr += sizeof(struct clnp_header_t); li -= sizeof(struct clnp_header_t); + + if (li < 1) { + ND_PRINT((ndo, "li < size of fixed part of CLNP header and addresses")); + return (0); + } + ND_TCHECK(*pptr); dest_address_length = *pptr; - dest_address = pptr + 1; + pptr += 1; + li -= 1; + if (li < dest_address_length) { + ND_PRINT((ndo, "li < size of fixed part of CLNP header and addresses")); + return (0); + } + ND_TCHECK2(*pptr, dest_address_length); + dest_address = pptr; + pptr += dest_address_length; + li -= dest_address_length; - pptr += (1 + dest_address_length); - li -= (1 + dest_address_length); + if (li < 1) { + ND_PRINT((ndo, "li < size of fixed part of CLNP header and addresses")); + return (0); + } + ND_TCHECK(*pptr); source_address_length = *pptr; - source_address = pptr +1; - - pptr += (1 + source_address_length); - li -= (1 + source_address_length); + pptr += 1; + li -= 1; + if (li < source_address_length) { + ND_PRINT((ndo, "li < size of fixed part of CLNP header and addresses")); + return (0); + } + ND_TCHECK2(*pptr, source_address_length); + source_address = pptr; + pptr += source_address_length; + li -= source_address_length; if (ndo->ndo_vflag < 1) { ND_PRINT((ndo, "%s%s > %s, %s, length %u", ndo->ndo_eflag ? "" : ", ", - isonsap_string(source_address, source_address_length), - isonsap_string(dest_address, dest_address_length), + isonsap_string(ndo, source_address, source_address_length), + isonsap_string(ndo, dest_address, dest_address_length), tok2str(clnp_pdu_values,"unknown (%u)",clnp_pdu_type), length)); return (1); @@ -825,19 +865,24 @@ clnp_print(netdissect_options *ndo, EXTRACT_16BITS(clnp_header->segment_length), EXTRACT_16BITS(clnp_header->cksum))); - osi_print_cksum(ndo, optr, EXTRACT_16BITS(clnp_header->cksum), 7, - clnp_header->length_indicator); + if (osi_print_cksum(ndo, optr, EXTRACT_16BITS(clnp_header->cksum), 7, + clnp_header->length_indicator) == 0) + goto trunc; ND_PRINT((ndo, "\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", source_address_length, - isonsap_string(source_address, source_address_length), + isonsap_string(ndo, source_address, source_address_length), dest_address_length, - isonsap_string(dest_address, dest_address_length))); + isonsap_string(ndo, 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")); + 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", @@ -853,19 +898,19 @@ clnp_print(netdissect_options *ndo, u_int op, opli; const uint8_t *tptr; - ND_TCHECK2(*pptr, 2); if (li < 2) { ND_PRINT((ndo, ", bad opts/li")); return (0); } + ND_TCHECK2(*pptr, 2); op = *pptr++; opli = *pptr++; li -= 2; - ND_TCHECK2(*pptr, opli); if (opli > li) { ND_PRINT((ndo, ", opt (%d) too long", op)); return (0); } + ND_TCHECK2(*pptr, opli); li -= opli; tptr = pptr; tlen = opli; @@ -875,11 +920,23 @@ clnp_print(netdissect_options *ndo, op, 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() + * checks. + * We do, however, need to check tlen, to make sure we + * don't run past the end of the option. + */ switch (op) { 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")); + 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))); @@ -906,17 +963,25 @@ clnp_print(netdissect_options *ndo, ND_TCHECK2(*source_address, source_address_length); ND_PRINT((ndo, "\n\t NSAP address (length %u): %s", source_address_length, - isonsap_string(source_address, source_address_length))); + isonsap_string(ndo, source_address, source_address_length))); } tlen-=source_address_length+1; } break; case CLNP_OPTION_PRIORITY: + if (tlen < 1) { + ND_PRINT((ndo, ", bad opt len")); + return (0); + } ND_PRINT((ndo, "0x%1x", *tptr&0x0f)); break; case CLNP_OPTION_QOS_MAINTENANCE: + if (tlen < 1) { + ND_PRINT((ndo, ", bad opt len")); + return (0); + } ND_PRINT((ndo, "\n\t Format Code: %s", tok2str(clnp_option_scope_values, "Reserved", *tptr&CLNP_OPTION_SCOPE_MASK))); @@ -928,12 +993,20 @@ clnp_print(netdissect_options *ndo, break; case CLNP_OPTION_SECURITY: + if (tlen < 2) { + ND_PRINT((ndo, ", 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))); break; case CLNP_OPTION_DISCARD_REASON: + if (tlen < 1) { + ND_PRINT((ndo, ", 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)", @@ -1051,12 +1124,12 @@ esis_print(netdissect_options *ndo, } if (li > length) { - ND_PRINT((ndo, " length indicator(%d) > PDU size (%d)!", li, length)); + ND_PRINT((ndo, " length indicator(%u) > PDU size (%u)!", li, length)); return; } if (li < sizeof(struct esis_header_t) + 2) { - ND_PRINT((ndo, " length indicator < min PDU size %d:", li)); + ND_PRINT((ndo, " length indicator %u < min PDU size:", li)); while (pptr < ndo->ndo_snapend) ND_PRINT((ndo, "%02X", *pptr++)); return; @@ -1080,7 +1153,8 @@ esis_print(netdissect_options *ndo, 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))); - osi_print_cksum(ndo, pptr, EXTRACT_16BITS(esis_header->cksum), 7, li); + if (osi_print_cksum(ndo, pptr, EXTRACT_16BITS(esis_header->cksum), 7, li) == 0) + goto trunc; ND_PRINT((ndo, ", holding time: %us, length indicator: %u", EXTRACT_16BITS(esis_header->holdtime), li)); @@ -1112,7 +1186,7 @@ esis_print(netdissect_options *ndo, dst = pptr; pptr += dstl; li -= dstl; - ND_PRINT((ndo, "\n\t %s", isonsap_string(dst, dstl))); + ND_PRINT((ndo, "\n\t %s", isonsap_string(ndo, dst, dstl))); ND_TCHECK(*pptr); if (li < 1) { @@ -1149,7 +1223,7 @@ esis_print(netdissect_options *ndo, if (netal == 0) ND_PRINT((ndo, "\n\t %s", etheraddr_string(ndo, snpa))); else - ND_PRINT((ndo, "\n\t %s", isonsap_string(neta, netal))); + ND_PRINT((ndo, "\n\t %s", isonsap_string(ndo, neta, netal))); break; } @@ -1182,7 +1256,7 @@ esis_print(netdissect_options *ndo, } ND_PRINT((ndo, "\n\t NET (length: %u): %s", source_address_length, - isonsap_string(pptr, source_address_length))); + isonsap_string(ndo, pptr, source_address_length))); pptr += source_address_length; li -= source_address_length; source_address_number--; @@ -1204,7 +1278,7 @@ esis_print(netdissect_options *ndo, ND_PRINT((ndo, ", bad ish/li")); return; } - ND_PRINT((ndo, "\n\t NET (length: %u): %s", source_address_length, isonsap_string(pptr, source_address_length))); + ND_PRINT((ndo, "\n\t NET (length: %u): %s", source_address_length, isonsap_string(ndo, pptr, source_address_length))); pptr += source_address_length; li -= source_address_length; break; @@ -1297,14 +1371,11 @@ isis_print_mcid(netdissect_options *ndo, { int i; + ND_TCHECK(*mcid); ND_PRINT((ndo, "ID: %d, Name: ", mcid->format_id)); - for(i=0; i<32; i++) - { - ND_PRINT((ndo, "%c", mcid->name[i])); - if(mcid->name[i] == '\0') - break; - } + if (fn_printzp(ndo, mcid->name, 32, ndo->ndo_snapend)) + goto trunc; ND_PRINT((ndo, "\n\t Lvl: %d", EXTRACT_16BITS(mcid->revision_lvl))); @@ -1312,6 +1383,9 @@ isis_print_mcid(netdissect_options *ndo, for(i=0;i<16;i++) ND_PRINT((ndo, "%.2x ", mcid->digest[i])); + +trunc: + ND_PRINT((ndo, "%s", tstr)); } static int @@ -1322,7 +1396,7 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo, const struct isis_subtlv_spb_mcid *subtlv_spb_mcid; int i; - while (len > 0) + while (len > 2) { stlv_type = *(tptr++); stlv_len = *(tptr++); @@ -1340,10 +1414,9 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo, { case ISIS_SUBTLV_SPB_MCID: { - if (!ND_TTEST2(*(tptr), ISIS_SUBTLV_SPB_MCID_MIN_LEN)) - goto trunctlv; + ND_TCHECK2(*(tptr), ISIS_SUBTLV_SPB_MCID_MIN_LEN); - subtlv_spb_mcid = (struct isis_subtlv_spb_mcid *)tptr; + subtlv_spb_mcid = (const struct isis_subtlv_spb_mcid *)tptr; ND_PRINT((ndo, "\n\t MCID: ")); isis_print_mcid(ndo, &(subtlv_spb_mcid->mcid)); @@ -1364,8 +1437,7 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo, case ISIS_SUBTLV_SPB_DIGEST: { - if (!ND_TTEST2(*(tptr), ISIS_SUBTLV_SPB_DIGEST_MIN_LEN)) - goto trunctlv; + ND_TCHECK2(*(tptr), ISIS_SUBTLV_SPB_DIGEST_MIN_LEN); ND_PRINT((ndo, "\n\t RES: %d V: %d A: %d D: %d", (*(tptr) >> 5), (((*tptr)>> 4) & 0x01), @@ -1390,13 +1462,11 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo, case ISIS_SUBTLV_SPB_BVID: { - if (!ND_TTEST2(*(tptr), stlv_len)) - goto trunctlv; + ND_TCHECK2(*(tptr), stlv_len); - while (len) + while (len >= ISIS_SUBTLV_SPB_BVID_MIN_LEN) { - if (!ND_TTEST2(*(tptr), ISIS_SUBTLV_SPB_BVID_MIN_LEN)) - goto trunctlv; + ND_TCHECK2(*(tptr), ISIS_SUBTLV_SPB_BVID_MIN_LEN); ND_PRINT((ndo, "\n\t ECT: %08x", EXTRACT_32BITS(tptr))); @@ -1422,8 +1492,9 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo, return 0; - trunctlv: - ND_PRINT((ndo, "\n\t\t packet exceeded snapshot")); + trunc: + ND_PRINT((ndo, "\n\t\t")); + ND_PRINT((ndo, "%s", tstr)); return(1); } @@ -1433,7 +1504,7 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo, { int stlv_type, stlv_len, tmp; - while (len > 0) + while (len > 2) { stlv_type = *(tptr++); stlv_len = *(tptr++); @@ -1450,8 +1521,7 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo, { case ISIS_SUBTLV_SPB_INSTANCE: - if (!ND_TTEST2(*(tptr), ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN)) - goto trunctlv; + ND_TCHECK2(*tptr, ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN); ND_PRINT((ndo, "\n\t CIST Root-ID: %08x", EXTRACT_32BITS(tptr))); tptr = tptr+4; @@ -1476,8 +1546,7 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo, while (tmp) { - if (!ND_TTEST2(*(tptr), ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN)) - goto trunctlv; + ND_TCHECK2(*tptr, ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN); ND_PRINT((ndo, "\n\t U:%d, M:%d, A:%d, RES:%d", *(tptr) >> 7, (*(tptr) >> 6) & 0x01, @@ -1502,8 +1571,7 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo, case ISIS_SUBTLV_SPBM_SI: - if (!ND_TTEST2(*(tptr), 6)) - goto trunctlv; + ND_TCHECK2(*tptr, 8); ND_PRINT((ndo, "\n\t BMAC: %08x", EXTRACT_32BITS(tptr))); tptr = tptr+4; @@ -1517,8 +1585,8 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo, len = len - 8; stlv_len = stlv_len - 8; - while (stlv_len) - { + 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, @@ -1538,8 +1606,9 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo, } return 0; - trunctlv: - ND_PRINT((ndo, "\n\t\t packet exceeded snapshot")); + trunc: + ND_PRINT((ndo, "\n\t\t")); + ND_PRINT((ndo, "%s", tstr)); return(1); } @@ -1662,13 +1731,12 @@ isis_print_ip_reach_subtlv(netdissect_options *ndo, const uint8_t *tptr, int subt, int subl, const char *ident) { - /* first lets see if we know the subTLVs name*/ - ND_PRINT((ndo, "%s%s subTLV #%u, length: %u", - ident, tok2str(isis_ext_ip_reach_subtlv_values, "unknown", subt), - subt, subl)); + /* first lets see if we know the subTLVs name*/ + ND_PRINT((ndo, "%s%s subTLV #%u, length: %u", + ident, tok2str(isis_ext_ip_reach_subtlv_values, "unknown", subt), + subt, subl)); - if (!ND_TTEST2(*tptr,subl)) - goto trunctlv; + ND_TCHECK2(*tptr,subl); switch(subt) { case ISIS_SUBTLV_EXTD_IP_REACH_MGMT_PREFIX_COLOR: /* fall through */ @@ -1697,8 +1765,9 @@ isis_print_ip_reach_subtlv(netdissect_options *ndo, } return(1); -trunctlv: - ND_PRINT((ndo, "%spacket exceeded snapshot", ident)); +trunc: + ND_PRINT((ndo, "%s", ident)); + ND_PRINT((ndo, "%s", tstr)); return(0); } @@ -1723,8 +1792,7 @@ isis_print_is_reach_subtlv(netdissect_options *ndo, ident, tok2str(isis_ext_is_reach_subtlv_values, "unknown", subt), subt, subl)); - if (!ND_TTEST2(*tptr,subl)) - goto trunctlv; + ND_TCHECK2(*tptr, subl); switch(subt) { case ISIS_SUBTLV_EXT_IS_REACH_ADMIN_GROUP: @@ -1769,6 +1837,7 @@ isis_print_is_reach_subtlv(netdissect_options *ndo, tptr++; /* decode BCs until the subTLV ends */ for (te_class = 0; te_class < (subl-1)/4; te_class++) { + ND_TCHECK2(*tptr, 4); bw.i = EXTRACT_32BITS(tptr); ND_PRINT((ndo, "%s Bandwidth constraint CT%u: %.3f Mbps", ident, @@ -1830,11 +1899,13 @@ isis_print_is_reach_subtlv(netdissect_options *ndo, case GMPLS_PSC2: case GMPLS_PSC3: case GMPLS_PSC4: + ND_TCHECK2(*tptr, 6); 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: + ND_TCHECK2(*tptr, 8); 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, @@ -1857,12 +1928,10 @@ isis_print_is_reach_subtlv(netdissect_options *ndo, } return(1); -trunctlv: - ND_PRINT((ndo, "%spacket exceeded snapshot", ident)); +trunc: return(0); } - /* * this is the common IS-REACH decoder it is called * from various EXTD-IS REACH style TLVs (22,24,222) @@ -1901,7 +1970,7 @@ isis_print_ext_is_reach(netdissect_options *ndo, return(0); subtlv_type=*(tptr++); subtlv_len=*(tptr++); - /* prepend the ident string */ + /* 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); @@ -1950,11 +2019,7 @@ isis_print_extd_ip_reach(netdissect_options *ndo, const uint8_t *tptr, const char *ident, uint16_t afi) { char ident_buffer[20]; -#ifdef INET6 uint8_t prefix[sizeof(struct in6_addr)]; /* shared copy buffer for IPv4 and IPv6 prefixes */ -#else - uint8_t prefix[sizeof(struct in_addr)]; /* shared copy buffer for IPv4 prefixes */ -#endif u_int metric, status_byte, bit_length, byte_length, sublen, processed, subtlvtype, subtlvlen; if (!ND_TTEST2(*tptr, 4)) @@ -1975,7 +2040,6 @@ isis_print_extd_ip_reach(netdissect_options *ndo, return (0); } processed++; -#ifdef INET6 } else if (afi == AF_INET6) { if (!ND_TTEST2(*tptr, 1)) /* fetch status & prefix_len byte */ return (0); @@ -1988,7 +2052,6 @@ isis_print_extd_ip_reach(netdissect_options *ndo, return (0); } processed+=2; -#endif } else return (0); /* somebody is fooling us */ @@ -2006,13 +2069,11 @@ isis_print_extd_ip_reach(netdissect_options *ndo, ident, ipaddr_string(ndo, prefix), bit_length)); -#ifdef INET6 - if (afi == AF_INET6) + else if (afi == AF_INET6) ND_PRINT((ndo, "%sIPv6 prefix: %s/%u", ident, ip6addr_string(ndo, prefix), bit_length)); -#endif ND_PRINT((ndo, ", Distribution: %s, Metric: %u", ISIS_MASK_TLV_EXTD_IP_UPDOWN(status_byte) ? "down" : "up", @@ -2020,17 +2081,13 @@ isis_print_extd_ip_reach(netdissect_options *ndo, if (afi == AF_INET && ISIS_MASK_TLV_EXTD_IP_SUBTLV(status_byte)) ND_PRINT((ndo, ", sub-TLVs present")); -#ifdef INET6 - if (afi == AF_INET6) + else if (afi == AF_INET6) ND_PRINT((ndo, ", %s%s", ISIS_MASK_TLV_EXTD_IP6_IE(status_byte) ? "External" : "Internal", ISIS_MASK_TLV_EXTD_IP6_SUBTLV(status_byte) ? ", sub-TLVs present" : "")); -#endif if ((afi == AF_INET && ISIS_MASK_TLV_EXTD_IP_SUBTLV(status_byte)) -#ifdef INET6 || (afi == AF_INET6 && ISIS_MASK_TLV_EXTD_IP6_SUBTLV(status_byte)) -#endif ) { /* assume that one prefix can hold more than one subTLV - therefore the first byte must reflect @@ -2047,7 +2104,7 @@ isis_print_extd_ip_reach(netdissect_options *ndo, return (0); subtlvtype=*(tptr++); subtlvlen=*(tptr++); - /* prepend the ident string */ + /* prepend the indent string */ snprintf(ident_buffer, sizeof(ident_buffer), "%s ",ident); if (!isis_print_ip_reach_subtlv(ndo, tptr, subtlvtype, subtlvlen, ident_buffer)) return(0); @@ -2059,6 +2116,20 @@ isis_print_extd_ip_reach(netdissect_options *ndo, } /* + * Clear checksum and lifetime prior to signature verification. + */ +static void +isis_clear_checksum_lifetime(void *header) +{ + struct isis_lsp_header *header_lsp = (struct isis_lsp_header *) header; + + header_lsp->checksum[0] = 0; + header_lsp->checksum[1] = 0; + header_lsp->remaining_lifetime[0] = 0; + header_lsp->remaining_lifetime[1] = 0; +} + +/* * isis_print * Decode IS-IS packets. Return 0 on error. */ @@ -2071,7 +2142,7 @@ isis_print(netdissect_options *ndo, const struct isis_iih_lan_header *header_iih_lan; const struct isis_iih_ptp_header *header_iih_ptp; - struct isis_lsp_header *header_lsp; + const struct isis_lsp_header *header_lsp; const struct isis_csnp_header *header_csnp; const struct isis_psnp_header *header_psnp; @@ -2096,7 +2167,7 @@ isis_print(netdissect_options *ndo, pptr = p+(ISIS_COMMON_HEADER_SIZE); header_iih_lan = (const struct isis_iih_lan_header *)pptr; header_iih_ptp = (const struct isis_iih_ptp_header *)pptr; - header_lsp = (struct isis_lsp_header *)pptr; + header_lsp = (const struct isis_lsp_header *)pptr; header_csnp = (const struct isis_csnp_header *)pptr; header_psnp = (const struct isis_psnp_header *)pptr; @@ -2174,6 +2245,7 @@ isis_print(netdissect_options *ndo, case ISIS_PDU_L1_LAN_IIH: case ISIS_PDU_L2_LAN_IIH: + ND_TCHECK(*header_iih_lan); 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", @@ -2181,10 +2253,12 @@ isis_print(netdissect_options *ndo, header_iih_lan->priority)); break; case ISIS_PDU_PTP_IIH: + ND_TCHECK(*header_iih_ptp); ND_PRINT((ndo, ", src-id %s", isis_print_id(header_iih_ptp->source_id, SYSTEM_ID_LEN))); break; case ISIS_PDU_L1_LSP: case ISIS_PDU_L2_LSP: + ND_TCHECK(*header_lsp); 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), @@ -2192,10 +2266,12 @@ isis_print(netdissect_options *ndo, break; case ISIS_PDU_L1_CSNP: case ISIS_PDU_L2_CSNP: + ND_TCHECK(*header_csnp); ND_PRINT((ndo, ", src-id %s", isis_print_id(header_csnp->source_id, NODE_ID_LEN))); break; case ISIS_PDU_L1_PSNP: case ISIS_PDU_L2_PSNP: + ND_TCHECK(*header_psnp); ND_PRINT((ndo, ", src-id %s", isis_print_id(header_psnp->source_id, NODE_ID_LEN))); break; @@ -2235,13 +2311,13 @@ isis_print(netdissect_options *ndo, return (0); } + ND_TCHECK(*header_iih_lan); pdu_len=EXTRACT_16BITS(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_TCHECK(*header_iih_lan); 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), @@ -2270,13 +2346,13 @@ isis_print(netdissect_options *ndo, return (0); } + ND_TCHECK(*header_iih_ptp); pdu_len=EXTRACT_16BITS(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_TCHECK(*header_iih_ptp); 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), @@ -2305,31 +2381,23 @@ isis_print(netdissect_options *ndo, return (0); } + ND_TCHECK(*header_lsp); pdu_len=EXTRACT_16BITS(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_TCHECK(*header_lsp); 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))); - - osi_print_cksum(ndo, (uint8_t *)header_lsp->lsp_id, - EXTRACT_16BITS(header_lsp->checksum), 12, length-12); - - /* - * Clear checksum and lifetime prior to signature verification. - */ - header_lsp->checksum[0] = 0; - header_lsp->checksum[1] = 0; - header_lsp->remaining_lifetime[0] = 0; - header_lsp->remaining_lifetime[1] = 0; - + if (osi_print_cksum(ndo, (const uint8_t *)header_lsp->lsp_id, + EXTRACT_16BITS(header_lsp->checksum), + 12, length-12) == 0) + goto trunc; ND_PRINT((ndo, ", PDU length: %u, Flags: [ %s", pdu_len, @@ -2363,13 +2431,13 @@ isis_print(netdissect_options *ndo, return (0); } + ND_TCHECK(*header_csnp); pdu_len=EXTRACT_16BITS(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_TCHECK(*header_csnp); ND_PRINT((ndo, "\n\t source-id: %s, PDU length: %u", isis_print_id(header_csnp->source_id, NODE_ID_LEN), pdu_len)); @@ -2395,13 +2463,13 @@ isis_print(netdissect_options *ndo, return (0); } + ND_TCHECK(*header_psnp); pdu_len=EXTRACT_16BITS(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_TCHECK(*header_psnp); ND_PRINT((ndo, "\n\t source-id: %s, PDU length: %u", isis_print_id(header_psnp->source_id, NODE_ID_LEN), pdu_len)); @@ -2429,11 +2497,7 @@ isis_print(netdissect_options *ndo, return (1); } - if (!ND_TTEST2(*pptr, 2)) { - ND_PRINT((ndo, "\n\t\t packet exceeded snapshot (%ld) bytes", - (long)(pptr - ndo->ndo_snapend))); - return (1); - } + ND_TCHECK2(*pptr, 2); tlv_type = *pptr++; tlv_len = *pptr++; tmp =tlv_len; /* copy temporary len & pointer to packet data */ @@ -2451,32 +2515,29 @@ isis_print(netdissect_options *ndo, tlv_type, tlv_len)); - if (tlv_len == 0) /* something is malformed */ + if (tlv_len == 0) /* something is invalid */ continue; /* now check if we have a decoder otherwise do a hexdump at the end*/ switch (tlv_type) { case ISIS_TLV_AREA_ADDR: - if (!ND_TTEST2(*tptr, 1)) - goto trunctlv; + ND_TCHECK2(*tptr, 1); alen = *tptr++; while (tmp && alen < tmp) { ND_PRINT((ndo, "\n\t Area address (length: %u): %s", alen, - isonsap_string(tptr, alen))); + isonsap_string(ndo, tptr, alen))); tptr += alen; tmp -= alen + 1; if (tmp==0) /* if this is the last area address do not attemt a boundary check */ break; - if (!ND_TTEST2(*tptr, 1)) - goto trunctlv; + ND_TCHECK2(*tptr, 1); alen = *tptr++; } break; case ISIS_TLV_ISNEIGH: while (tmp >= ETHER_ADDR_LEN) { - if (!ND_TTEST2(*tptr, ETHER_ADDR_LEN)) - goto trunctlv; + 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; @@ -2494,8 +2555,7 @@ isis_print(netdissect_options *ndo, tmp --; ND_PRINT((ndo, "\n\t LAN address length %u bytes ", lan_alen)); while (tmp >= lan_alen) { - if (!ND_TTEST2(*tptr, lan_alen)) - goto trunctlv; + 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; @@ -2541,16 +2601,14 @@ isis_print(netdissect_options *ndo, } break; case ISIS_TLV_IS_REACH: - if (!ND_TTEST2(*tptr,1)) /* check if there is one byte left to read out the virtual flag */ - goto trunctlv; + ND_TCHECK2(*tptr,1); /* check if there is one byte left to read out the virtual flag */ ND_PRINT((ndo, "\n\t %s", tok2str(isis_is_reach_virtual_values, "bogus virtual flag 0x%02x", *tptr++))); tlv_is_reach = (const struct isis_tlv_is_reach *)tptr; while (tmp >= sizeof(struct isis_tlv_is_reach)) { - if (!ND_TTEST(*tlv_is_reach)) - goto trunctlv; + ND_TCHECK(*tlv_is_reach); ND_PRINT((ndo, "\n\t IS Neighbor: %s", isis_print_id(tlv_is_reach->neighbor_nodeid, NODE_ID_LEN))); isis_print_metric_block(ndo, &tlv_is_reach->isis_metric_block); @@ -2562,8 +2620,7 @@ isis_print(netdissect_options *ndo, case ISIS_TLV_ESNEIGH: tlv_es_reach = (const struct isis_tlv_es_reach *)tptr; while (tmp >= sizeof(struct isis_tlv_es_reach)) { - if (!ND_TTEST(*tlv_es_reach)) - goto trunctlv; + ND_TCHECK(*tlv_es_reach); ND_PRINT((ndo, "\n\t ES Neighbor: %s", isis_print_id(tlv_es_reach->neighbor_sysid, SYSTEM_ID_LEN))); isis_print_metric_block(ndo, &tlv_es_reach->isis_metric_block); @@ -2606,7 +2663,6 @@ isis_print(netdissect_options *ndo, } break; -#ifdef INET6 case ISIS_TLV_IP6_REACH: while (tmp>0) { ext_ip_len = isis_print_extd_ip_reach(ndo, tptr, "\n\t ", AF_INET6); @@ -2636,8 +2692,7 @@ isis_print(netdissect_options *ndo, case ISIS_TLV_IP6ADDR: while (tmp>=sizeof(struct in6_addr)) { - if (!ND_TTEST2(*tptr, sizeof(struct in6_addr))) - goto trunctlv; + ND_TCHECK2(*tptr, sizeof(struct in6_addr)); ND_PRINT((ndo, "\n\t IPv6 interface address: %s", ip6addr_string(ndo, tptr))); @@ -2646,10 +2701,8 @@ isis_print(netdissect_options *ndo, tmp -= sizeof(struct in6_addr); } break; -#endif case ISIS_TLV_AUTH: - if (!ND_TTEST2(*tptr, 1)) - goto trunctlv; + ND_TCHECK2(*tptr, 1); ND_PRINT((ndo, "\n\t %s: ", tok2str(isis_subtlv_auth_values, @@ -2658,36 +2711,29 @@ isis_print(netdissect_options *ndo, switch (*tptr) { case ISIS_SUBTLV_AUTH_SIMPLE: - for(i=1;indo_snapend)) + goto trunctlv; break; case ISIS_SUBTLV_AUTH_MD5: for(i=1;i=1) { - if (!ND_TTEST2(*tptr, 1)) - goto trunctlv; + ND_TCHECK2(*tptr, 1); ND_PRINT((ndo, "\n\t Adjacency State: %s (%u)", tok2str(isis_ptp_adjancey_values, "unknown", *tptr), *tptr)); tmp--; } if(tmp>sizeof(tlv_ptp_adj->extd_local_circuit_id)) { - if (!ND_TTEST2(tlv_ptp_adj->extd_local_circuit_id, - sizeof(tlv_ptp_adj->extd_local_circuit_id))) - goto trunctlv; + 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(tmp>=SYSTEM_ID_LEN) { - if (!ND_TTEST2(tlv_ptp_adj->neighbor_sysid, SYSTEM_ID_LEN)) - goto trunctlv; + 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(tmp>=sizeof(tlv_ptp_adj->neighbor_extd_local_circuit_id)) { - if (!ND_TTEST2(tlv_ptp_adj->neighbor_extd_local_circuit_id, - sizeof(tlv_ptp_adj->neighbor_extd_local_circuit_id))) - goto trunctlv; + 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))); } @@ -2736,8 +2776,7 @@ isis_print(netdissect_options *ndo, case ISIS_TLV_PROTOCOLS: ND_PRINT((ndo, "\n\t NLPID(s): ")); while (tmp>0) { - if (!ND_TTEST2(*(tptr), 1)) - goto trunctlv; + ND_TCHECK2(*(tptr), 1); ND_PRINT((ndo, "%s (0x%02x)", tok2str(nlpid_values, "unknown", @@ -2752,8 +2791,7 @@ isis_print(netdissect_options *ndo, case ISIS_TLV_MT_PORT_CAP: { - if (!ND_TTEST2(*(tptr), 2)) - goto trunctlv; + ND_TCHECK2(*(tptr), 2); ND_PRINT((ndo, "\n\t RES: %d, MTID(s): %d", (EXTRACT_16BITS (tptr) >> 12), @@ -2770,8 +2808,7 @@ isis_print(netdissect_options *ndo, case ISIS_TLV_MT_CAPABILITY: - if (!ND_TTEST2(*(tptr), 2)) - goto trunctlv; + ND_TCHECK2(*(tptr), 2); ND_PRINT((ndo, "\n\t O: %d, RES: %d, MTID(s): %d", (EXTRACT_16BITS(tptr) >> 15) & 0x01, @@ -2787,15 +2824,13 @@ isis_print(netdissect_options *ndo, break; case ISIS_TLV_TE_ROUTER_ID: - if (!ND_TTEST2(*pptr, sizeof(struct in_addr))) - goto trunctlv; + ND_TCHECK2(*pptr, sizeof(struct in_addr)); ND_PRINT((ndo, "\n\t Traffic Engineering Router ID: %s", ipaddr_string(ndo, pptr))); break; case ISIS_TLV_IPADDR: while (tmp>=sizeof(struct in_addr)) { - if (!ND_TTEST2(*tptr, sizeof(struct in_addr))) - goto trunctlv; + 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); @@ -2804,49 +2839,40 @@ isis_print(netdissect_options *ndo, case ISIS_TLV_HOSTNAME: ND_PRINT((ndo, "\n\t Hostname: ")); - while (tmp>0) { - if (!ND_TTEST2(*tptr, 1)) - goto trunctlv; - ND_PRINT((ndo, "%c", *tptr++)); - tmp--; - } + if (fn_printzp(ndo, tptr, tmp, ndo->ndo_snapend)) + goto trunctlv; break; case ISIS_TLV_SHARED_RISK_GROUP: if (tmp < NODE_ID_LEN) break; - if (!ND_TTEST2(*tptr, NODE_ID_LEN)) - goto trunctlv; + 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); if (tmp < 1) break; - if (!ND_TTEST2(*tptr, 1)) - goto trunctlv; + ND_TCHECK2(*tptr, 1); ND_PRINT((ndo, ", Flags: [%s]", ISIS_MASK_TLV_SHARED_RISK_GROUP(*tptr++) ? "numbered" : "unnumbered")); tmp--; if (tmp < sizeof(struct in_addr)) break; - if (!ND_TTEST2(*tptr, sizeof(struct in_addr))) - goto trunctlv; + 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); if (tmp < sizeof(struct in_addr)) break; - if (!ND_TTEST2(*tptr, sizeof(struct in_addr))) - goto trunctlv; + 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) { - if (!ND_TTEST2(*tptr, 4)) - goto trunctlv; + ND_TCHECK2(*tptr, 4); ND_PRINT((ndo, "\n\t Link-ID: 0x%08x", EXTRACT_32BITS(tptr))); tptr+=4; tmp-=4; @@ -2856,18 +2882,14 @@ isis_print(netdissect_options *ndo, case ISIS_TLV_LSP: tlv_lsp = (const struct isis_tlv_lsp *)tptr; while(tmp>=sizeof(struct isis_tlv_lsp)) { - if (!ND_TTEST((tlv_lsp->lsp_id)[LSP_ID_LEN-1])) - goto trunctlv; + 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))); - if (!ND_TTEST2(tlv_lsp->sequence_number, 4)) - goto trunctlv; + ND_TCHECK2(tlv_lsp->sequence_number, 4); ND_PRINT((ndo, ", seq: 0x%08x", EXTRACT_32BITS(tlv_lsp->sequence_number))); - if (!ND_TTEST2(tlv_lsp->remaining_lifetime, 2)) - goto trunctlv; + ND_TCHECK2(tlv_lsp->remaining_lifetime, 2); ND_PRINT((ndo, ", lifetime: %5ds", EXTRACT_16BITS(tlv_lsp->remaining_lifetime))); - if (!ND_TTEST2(tlv_lsp->checksum, 2)) - goto trunctlv; + ND_TCHECK2(tlv_lsp->checksum, 2); ND_PRINT((ndo, ", chksum: 0x%04x", EXTRACT_16BITS(tlv_lsp->checksum))); tmp-=sizeof(struct isis_tlv_lsp); tlv_lsp++; @@ -2877,15 +2899,30 @@ isis_print(netdissect_options *ndo, case ISIS_TLV_CHECKSUM: if (tmp < ISIS_TLV_CHECKSUM_MINLEN) break; - if (!ND_TTEST2(*tptr, ISIS_TLV_CHECKSUM_MINLEN)) - goto trunctlv; + ND_TCHECK2(*tptr, ISIS_TLV_CHECKSUM_MINLEN); ND_PRINT((ndo, "\n\t checksum: 0x%04x ", EXTRACT_16BITS(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); + if (osi_print_cksum(ndo, optr, EXTRACT_16BITS(tptr), tptr-optr, + length) == 0) + goto trunc; + 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))); + } break; case ISIS_TLV_MT_SUPPORTED: @@ -2901,7 +2938,7 @@ isis_print(netdissect_options *ndo, tptr+=mt_len; tmp-=mt_len; } else { - ND_PRINT((ndo, "\n\t malformed MT-ID")); + ND_PRINT((ndo, "\n\t invalid MT-ID")); break; } } @@ -2911,8 +2948,7 @@ isis_print(netdissect_options *ndo, /* first attempt to decode the flags */ if (tmp < ISIS_TLV_RESTART_SIGNALING_FLAGLEN) break; - if (!ND_TTEST2(*tptr, ISIS_TLV_RESTART_SIGNALING_FLAGLEN)) - goto trunctlv; + ND_TCHECK2(*tptr, ISIS_TLV_RESTART_SIGNALING_FLAGLEN); ND_PRINT((ndo, "\n\t Flags [%s]", bittok2str(isis_restart_flag_values, "none", *tptr))); tptr+=ISIS_TLV_RESTART_SIGNALING_FLAGLEN; @@ -2924,8 +2960,7 @@ isis_print(netdissect_options *ndo, if (tmp < ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN) break; - if (!ND_TTEST2(*tptr, ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN)) - goto trunctlv; + ND_TCHECK2(*tptr, ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN); ND_PRINT((ndo, ", Remaining holding time %us", EXTRACT_16BITS(tptr))); tptr+=ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN; @@ -2933,8 +2968,7 @@ isis_print(netdissect_options *ndo, /* is there an additional sysid field present ?*/ if (tmp == SYSTEM_ID_LEN) { - if (!ND_TTEST2(*tptr, SYSTEM_ID_LEN)) - goto trunctlv; + ND_TCHECK2(*tptr, SYSTEM_ID_LEN); ND_PRINT((ndo, ", for %s", isis_print_id(tptr,SYSTEM_ID_LEN))); } break; @@ -2942,16 +2976,14 @@ isis_print(netdissect_options *ndo, case ISIS_TLV_IDRP_INFO: if (tmp < ISIS_TLV_IDRP_INFO_MINLEN) break; - if (!ND_TTEST2(*tptr, ISIS_TLV_IDRP_INFO_MINLEN)) - goto trunctlv; + ND_TCHECK2(*tptr, ISIS_TLV_IDRP_INFO_MINLEN); ND_PRINT((ndo, "\n\t Inter-Domain Information Type: %s", tok2str(isis_subtlv_idrp_values, "Unknown (0x%02x)", *tptr))); switch (*tptr++) { case ISIS_SUBTLV_IDRP_ASN: - if (!ND_TTEST2(*tptr, 2)) /* fetch AS number */ - goto trunctlv; + ND_TCHECK2(*tptr, 2); /* fetch AS number */ ND_PRINT((ndo, "AS Number: %u", EXTRACT_16BITS(tptr))); break; case ISIS_SUBTLV_IDRP_LOCAL: @@ -2966,15 +2998,13 @@ isis_print(netdissect_options *ndo, case ISIS_TLV_LSP_BUFFERSIZE: if (tmp < ISIS_TLV_LSP_BUFFERSIZE_MINLEN) break; - if (!ND_TTEST2(*tptr, ISIS_TLV_LSP_BUFFERSIZE_MINLEN)) - goto trunctlv; + ND_TCHECK2(*tptr, ISIS_TLV_LSP_BUFFERSIZE_MINLEN); ND_PRINT((ndo, "\n\t LSP Buffersize: %u", EXTRACT_16BITS(tptr))); break; case ISIS_TLV_PART_DIS: while (tmp >= SYSTEM_ID_LEN) { - if (!ND_TTEST2(*tptr, SYSTEM_ID_LEN)) - goto trunctlv; + ND_TCHECK2(*tptr, SYSTEM_ID_LEN); ND_PRINT((ndo, "\n\t %s", isis_print_id(tptr, SYSTEM_ID_LEN))); tptr+=SYSTEM_ID_LEN; tmp-=SYSTEM_ID_LEN; @@ -2984,16 +3014,14 @@ isis_print(netdissect_options *ndo, case ISIS_TLV_PREFIX_NEIGH: if (tmp < sizeof(struct isis_metric_block)) break; - if (!ND_TTEST2(*tptr, sizeof(struct isis_metric_block))) - goto trunctlv; + ND_TCHECK2(*tptr, sizeof(struct isis_metric_block)); ND_PRINT((ndo, "\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); while(tmp>0) { - if (!ND_TTEST2(*tptr, 1)) - goto trunctlv; + ND_TCHECK2(*tptr, 1); prefix_len=*tptr++; /* read out prefix length in semioctets*/ if (prefix_len < 2) { ND_PRINT((ndo, "\n\t\tAddress: prefix length %u < 2", prefix_len)); @@ -3002,10 +3030,9 @@ isis_print(netdissect_options *ndo, tmp--; if (tmp < prefix_len/2) break; - if (!ND_TTEST2(*tptr, prefix_len / 2)) - goto trunctlv; + ND_TCHECK2(*tptr, prefix_len / 2); ND_PRINT((ndo, "\n\t\tAddress: %s/%u", - isonsap_string(tptr, prefix_len / 2), prefix_len * 4)); + isonsap_string(ndo, tptr, prefix_len / 2), prefix_len * 4)); tptr+=prefix_len/2; tmp-=prefix_len/2; } @@ -3014,16 +3041,14 @@ isis_print(netdissect_options *ndo, case ISIS_TLV_IIH_SEQNR: if (tmp < ISIS_TLV_IIH_SEQNR_MINLEN) break; - if (!ND_TTEST2(*tptr, ISIS_TLV_IIH_SEQNR_MINLEN)) /* check if four bytes are on the wire */ - goto trunctlv; + 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))); break; case ISIS_TLV_VENDOR_PRIVATE: if (tmp < ISIS_TLV_VENDOR_PRIVATE_MINLEN) break; - if (!ND_TTEST2(*tptr, ISIS_TLV_VENDOR_PRIVATE_MINLEN)) /* check if enough byte for a full oui */ - goto trunctlv; + 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)", tok2str(oui_values, "Unknown", vendor_id), @@ -3068,18 +3093,18 @@ isis_print(netdissect_options *ndo, return (1); trunc: - ND_PRINT((ndo, "[|isis]")); + ND_PRINT((ndo, "%s", tstr)); return (1); trunctlv: - ND_PRINT((ndo, "\n\t\t packet exceeded snapshot")); + ND_PRINT((ndo, "\n\t\t")); + ND_PRINT((ndo, "%s", tstr)); return(1); } -static void -osi_print_cksum(netdissect_options *ndo, - const uint8_t *pptr, uint16_t checksum, - u_int checksum_offset, u_int length) +static int +osi_print_cksum(netdissect_options *ndo, const uint8_t *pptr, + uint16_t checksum, int checksum_offset, int length) { uint16_t calculated_checksum; @@ -3089,27 +3114,28 @@ osi_print_cksum(netdissect_options *ndo, * or the base pointer is not sane */ if (!checksum - || length > (u_int)ndo->ndo_snaplen - || checksum_offset > (uint)ndo->ndo_snaplen + || length < 0 + || checksum_offset < 0 + || length > ndo->ndo_snaplen + || checksum_offset > ndo->ndo_snaplen || checksum_offset > length) { - ND_PRINT((ndo, "(unverified)")); + ND_PRINT((ndo, " (unverified)")); + return 1; } else { - unsigned char *truncated = "trunc"; #if 0 printf("\nosi_print_cksum: %p %u %u %u\n", pptr, checksum_offset, length, ndo->ndo_snaplen); - ND_TCHECK2(pptr, checksum_offset+length); #endif + ND_TCHECK2(*pptr, length); calculated_checksum = create_osi_cksum(pptr, checksum_offset, length); if (checksum == calculated_checksum) { ND_PRINT((ndo, " (correct)")); } else { - truncated = "incorrect"; -#if 0 - trunc: -#endif - ND_PRINT((ndo, " (%s should be 0x%04x)", truncated, calculated_checksum)); + ND_PRINT((ndo, " (incorrect should be 0x%04x)", calculated_checksum)); } + return 1; } +trunc: + return 0; } /* diff --git a/contrib/tcpdump/print-juniper.c b/contrib/tcpdump/print-juniper.c index e4bb77c..83ac372 100644 --- a/contrib/tcpdump/print-juniper.c +++ b/contrib/tcpdump/print-juniper.c @@ -15,19 +15,22 @@ * Original code by Hannes Gredler (hannes@juniper.net) */ +/* \summary: DLT_JUNIPER_* printers */ + #ifndef lint #else __RCSID("NetBSD: print-juniper.c,v 1.3 2007/07/25 06:31:32 dogcow Exp "); #endif -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include + +#include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" #include "ppp.h" @@ -89,7 +92,7 @@ enum { }; /* 1 byte type and 1-byte length */ -#define JUNIPER_EXT_TLV_OVERHEAD 2 +#define JUNIPER_EXT_TLV_OVERHEAD 2U static const struct tok jnx_ext_tlv_values[] = { { JUNIPER_EXT_TLV_IFD_IDX, "Device Interface Index" }, @@ -514,7 +517,7 @@ juniper_es_print(netdissect_options *ndo, return l2info.header_len; p+=l2info.header_len; - ih = (struct juniper_ipsec_header *)p; + ih = (const struct juniper_ipsec_header *)p; switch (ih->type) { case JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE: @@ -583,7 +586,7 @@ juniper_monitor_print(netdissect_options *ndo, return l2info.header_len; p+=l2info.header_len; - mh = (struct juniper_monitor_header *)p; + mh = (const struct juniper_monitor_header *)p; if (ndo->ndo_eflag) ND_PRINT((ndo, "service-id %u, iif %u, pkt-type %u: ", @@ -617,7 +620,7 @@ juniper_services_print(netdissect_options *ndo, return l2info.header_len; p+=l2info.header_len; - sh = (struct juniper_services_header *)p; + sh = (const struct juniper_services_header *)p; if (ndo->ndo_eflag) ND_PRINT((ndo, "service-id %u flags 0x%02x service-set-id 0x%04x iif %u: ", @@ -743,7 +746,8 @@ juniper_pppoe_atm_print(netdissect_options *ndo, if (ethertype_print(ndo, extracted_ethertype, p+ETHERTYPE_LEN, l2info.length-ETHERTYPE_LEN, - l2info.caplen-ETHERTYPE_LEN) == 0) + 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)); @@ -818,6 +822,7 @@ juniper_mfr_print(netdissect_options *ndo, { struct juniper_l2info_t l2info; + memset(&l2info, 0, sizeof(l2info)); l2info.pictype = DLT_JUNIPER_MFR; if (juniper_parse_header(ndo, p, h, &l2info) == 0) return l2info.header_len; @@ -920,7 +925,7 @@ u_int juniper_atm1_print(netdissect_options *ndo, const struct pcap_pkthdr *h, register const u_char *p) { - uint16_t extracted_ethertype; + int llc_hdrlen; struct juniper_l2info_t l2info; @@ -938,8 +943,8 @@ juniper_atm1_print(netdissect_options *ndo, if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */ EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */ - if (llc_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL, - &extracted_ethertype) != 0) + llc_hdrlen = llc_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL); + if (llc_hdrlen > 0) return l2info.header_len; } @@ -969,7 +974,7 @@ u_int juniper_atm2_print(netdissect_options *ndo, const struct pcap_pkthdr *h, register const u_char *p) { - uint16_t extracted_ethertype; + int llc_hdrlen; struct juniper_l2info_t l2info; @@ -987,8 +992,8 @@ juniper_atm2_print(netdissect_options *ndo, if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */ EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */ - if (llc_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL, - &extracted_ethertype) != 0) + llc_hdrlen = llc_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL); + if (llc_hdrlen > 0) return l2info.header_len; } @@ -1033,10 +1038,8 @@ juniper_ppp_heuristic_guess(netdissect_options *ndo, case PPP_PAP : case PPP_CHAP : case PPP_ML : -#ifdef INET6 case PPP_IPV6 : case PPP_IPV6CP : -#endif ppp_print(ndo, p, length); break; @@ -1200,9 +1203,11 @@ juniper_parse_header(netdissect_options *ndo, tlv_len = *(tptr++); tlv_value = 0; - /* sanity check */ + /* sanity checks */ if (tlv_type == 0 || tlv_len == 0) break; + if (tlv_len+JUNIPER_EXT_TLV_OVERHEAD > jnx_ext_len) + goto trunc; if (ndo->ndo_vflag > 1) ND_PRINT((ndo, "\n\t %s Extension TLV #%u, length %u, value ", diff --git a/contrib/tcpdump/print-krb.c b/contrib/tcpdump/print-krb.c index 2eebfa6..de69054 100644 --- a/contrib/tcpdump/print-krb.c +++ b/contrib/tcpdump/print-krb.c @@ -21,14 +21,15 @@ * Initial contribution from John Hawkinson (jhawk@mit.edu). */ -#define NETDISSECT_REWORKED +/* \summary: Kerberos printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" static const char tstr[] = " [|kerberos]"; @@ -156,7 +157,7 @@ krb4_print(netdissect_options *ndo, #define IS_LENDIAN(kp) (((kp)->type & 0x01) != 0) #define KTOHSP(kp, cp) (IS_LENDIAN(kp) ? EXTRACT_LE_16BITS(cp) : EXTRACT_16BITS(cp)) - kp = (struct krb *)cp; + kp = (const struct krb *)cp; if ((&kp->type) >= ndo->ndo_snapend) { ND_PRINT((ndo, "%s", tstr)); @@ -227,7 +228,7 @@ krb_print(netdissect_options *ndo, { register const struct krb *kp; - kp = (struct krb *)dat; + kp = (const struct krb *)dat; if (dat >= ndo->ndo_snapend) { ND_PRINT((ndo, "%s", tstr)); diff --git a/contrib/tcpdump/print-l2tp.c b/contrib/tcpdump/print-l2tp.c index 346dae9..42ae391 100644 --- a/contrib/tcpdump/print-l2tp.c +++ b/contrib/tcpdump/print-l2tp.c @@ -21,14 +21,15 @@ * L2TP support contributed by Motonori Shindo (mshindo@mshindo.net) */ -#define NETDISSECT_REWORKED +/* \summary: Layer Two Tunneling Protocol (L2TP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #define L2TP_FLAG_TYPE 0x8000 /* Type (0=Data, 1=Control) */ @@ -298,7 +299,7 @@ print_32bits_val(netdissect_options *ndo, const uint32_t *dat) static void l2tp_msgtype_print(netdissect_options *ndo, const u_char *dat) { - uint16_t *ptr = (uint16_t*)dat; + const uint16_t *ptr = (const uint16_t *)dat; ND_PRINT((ndo, "%s", tok2str(l2tp_msgtype2str, "MSGTYPE-#%u", EXTRACT_16BITS(ptr)))); @@ -307,7 +308,7 @@ l2tp_msgtype_print(netdissect_options *ndo, const u_char *dat) static void l2tp_result_code_print(netdissect_options *ndo, const u_char *dat, u_int length) { - uint16_t *ptr = (uint16_t *)dat; + const uint16_t *ptr = (const uint16_t *)dat; ND_PRINT((ndo, "%u", EXTRACT_16BITS(ptr))); ptr++; /* Result Code */ if (length > 2) { /* Error Code (opt) */ @@ -315,7 +316,7 @@ l2tp_result_code_print(netdissect_options *ndo, const u_char *dat, u_int length) } if (length > 4) { /* Error Message (opt) */ ND_PRINT((ndo, " ")); - print_string(ndo, (u_char *)ptr, length - 4); + print_string(ndo, (const u_char *)ptr, length - 4); } } @@ -329,7 +330,7 @@ l2tp_proto_ver_print(netdissect_options *ndo, const uint16_t *dat) static void l2tp_framing_cap_print(netdissect_options *ndo, const u_char *dat) { - uint32_t *ptr = (uint32_t *)dat; + const uint32_t *ptr = (const uint32_t *)dat; if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_CAP_ASYNC_MASK) { ND_PRINT((ndo, "A")); @@ -342,7 +343,7 @@ l2tp_framing_cap_print(netdissect_options *ndo, const u_char *dat) static void l2tp_bearer_cap_print(netdissect_options *ndo, const u_char *dat) { - uint32_t *ptr = (uint32_t *)dat; + const uint32_t *ptr = (const uint32_t *)dat; if (EXTRACT_32BITS(ptr) & L2TP_BEARER_CAP_ANALOG_MASK) { ND_PRINT((ndo, "A")); @@ -355,7 +356,7 @@ l2tp_bearer_cap_print(netdissect_options *ndo, const u_char *dat) static void l2tp_q931_cc_print(netdissect_options *ndo, const u_char *dat, u_int length) { - print_16bits_val(ndo, (uint16_t *)dat); + print_16bits_val(ndo, (const uint16_t *)dat); ND_PRINT((ndo, ", %02x", dat[2])); if (length > 3) { ND_PRINT((ndo, " ")); @@ -366,7 +367,7 @@ l2tp_q931_cc_print(netdissect_options *ndo, const u_char *dat, u_int length) static void l2tp_bearer_type_print(netdissect_options *ndo, const u_char *dat) { - uint32_t *ptr = (uint32_t *)dat; + const uint32_t *ptr = (const uint32_t *)dat; if (EXTRACT_32BITS(ptr) & L2TP_BEARER_TYPE_ANALOG_MASK) { ND_PRINT((ndo, "A")); @@ -379,7 +380,7 @@ l2tp_bearer_type_print(netdissect_options *ndo, const u_char *dat) static void l2tp_framing_type_print(netdissect_options *ndo, const u_char *dat) { - uint32_t *ptr = (uint32_t *)dat; + const uint32_t *ptr = (const uint32_t *)dat; if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_TYPE_ASYNC_MASK) { ND_PRINT((ndo, "A")); @@ -398,7 +399,7 @@ l2tp_packet_proc_delay_print(netdissect_options *ndo) static void l2tp_proxy_auth_type_print(netdissect_options *ndo, const u_char *dat) { - uint16_t *ptr = (uint16_t *)dat; + const uint16_t *ptr = (const uint16_t *)dat; ND_PRINT((ndo, "%s", tok2str(l2tp_authentype2str, "AuthType-#%u", EXTRACT_16BITS(ptr)))); @@ -407,7 +408,7 @@ l2tp_proxy_auth_type_print(netdissect_options *ndo, const u_char *dat) static void l2tp_proxy_auth_id_print(netdissect_options *ndo, const u_char *dat) { - uint16_t *ptr = (uint16_t *)dat; + const uint16_t *ptr = (const uint16_t *)dat; ND_PRINT((ndo, "%u", EXTRACT_16BITS(ptr) & L2TP_PROXY_AUTH_ID_MASK)); } @@ -415,7 +416,7 @@ l2tp_proxy_auth_id_print(netdissect_options *ndo, const u_char *dat) static void l2tp_call_errors_print(netdissect_options *ndo, const u_char *dat) { - uint16_t *ptr = (uint16_t *)dat; + const uint16_t *ptr = (const uint16_t *)dat; uint16_t val_h, val_l; ptr++; /* skip "Reserved" */ @@ -448,7 +449,7 @@ l2tp_call_errors_print(netdissect_options *ndo, const u_char *dat) static void l2tp_accm_print(netdissect_options *ndo, const u_char *dat) { - uint16_t *ptr = (uint16_t *)dat; + const uint16_t *ptr = (const uint16_t *)dat; uint16_t val_h, val_l; ptr++; /* skip "Reserved" */ @@ -465,12 +466,12 @@ l2tp_accm_print(netdissect_options *ndo, const u_char *dat) static void l2tp_ppp_discon_cc_print(netdissect_options *ndo, const u_char *dat, u_int length) { - uint16_t *ptr = (uint16_t *)dat; + const uint16_t *ptr = (const uint16_t *)dat; ND_PRINT((ndo, "%04x, ", EXTRACT_16BITS(ptr))); ptr++; /* Disconnect Code */ ND_PRINT((ndo, "%04x ", EXTRACT_16BITS(ptr))); ptr++; /* Control Protocol Number */ ND_PRINT((ndo, "%s", tok2str(l2tp_cc_direction2str, - "Direction-#%u", *((u_char *)ptr++)))); + "Direction-#%u", *((const u_char *)ptr++)))); if (length > 5) { ND_PRINT((ndo, " ")); @@ -482,7 +483,7 @@ static void l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length) { u_int len; - const uint16_t *ptr = (uint16_t *)dat; + const uint16_t *ptr = (const uint16_t *)dat; uint16_t attr_type; int hidden = FALSE; @@ -523,7 +524,7 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length) ND_PRINT((ndo, "VENDOR%04x:", EXTRACT_16BITS(ptr))); ptr++; ND_PRINT((ndo, "ATTR%04x", EXTRACT_16BITS(ptr))); ptr++; ND_PRINT((ndo, "(")); - print_octets(ndo, (u_char *)ptr, len-6); + print_octets(ndo, (const u_char *)ptr, len-6); ND_PRINT((ndo, ")")); } else { /* IETF-defined Attributes */ @@ -536,22 +537,22 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length) } else { switch (attr_type) { case L2TP_AVP_MSGTYPE: - l2tp_msgtype_print(ndo, (u_char *)ptr); + l2tp_msgtype_print(ndo, (const u_char *)ptr); break; case L2TP_AVP_RESULT_CODE: - l2tp_result_code_print(ndo, (u_char *)ptr, len-6); + l2tp_result_code_print(ndo, (const u_char *)ptr, len-6); break; case L2TP_AVP_PROTO_VER: l2tp_proto_ver_print(ndo, ptr); break; case L2TP_AVP_FRAMING_CAP: - l2tp_framing_cap_print(ndo, (u_char *)ptr); + l2tp_framing_cap_print(ndo, (const u_char *)ptr); break; case L2TP_AVP_BEARER_CAP: - l2tp_bearer_cap_print(ndo, (u_char *)ptr); + l2tp_bearer_cap_print(ndo, (const u_char *)ptr); break; case L2TP_AVP_TIE_BREAKER: - print_octets(ndo, (u_char *)ptr, 8); + print_octets(ndo, (const u_char *)ptr, 8); break; case L2TP_AVP_FIRM_VER: case L2TP_AVP_ASSND_TUN_ID: @@ -566,7 +567,7 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length) case L2TP_AVP_SUB_ADDRESS: case L2TP_AVP_PROXY_AUTH_NAME: case L2TP_AVP_PRIVATE_GRP_ID: - print_string(ndo, (u_char *)ptr, len-6); + print_string(ndo, (const u_char *)ptr, len-6); break; case L2TP_AVP_CHALLENGE: case L2TP_AVP_INI_RECV_LCP: @@ -575,13 +576,13 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length) case L2TP_AVP_PROXY_AUTH_CHAL: case L2TP_AVP_PROXY_AUTH_RESP: case L2TP_AVP_RANDOM_VECTOR: - print_octets(ndo, (u_char *)ptr, len-6); + print_octets(ndo, (const u_char *)ptr, len-6); break; case L2TP_AVP_Q931_CC: - l2tp_q931_cc_print(ndo, (u_char *)ptr, len-6); + l2tp_q931_cc_print(ndo, (const u_char *)ptr, len-6); break; case L2TP_AVP_CHALLENGE_RESP: - print_octets(ndo, (u_char *)ptr, 16); + print_octets(ndo, (const u_char *)ptr, 16); break; case L2TP_AVP_CALL_SER_NUM: case L2TP_AVP_MINIMUM_BPS: @@ -589,33 +590,33 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length) case L2TP_AVP_TX_CONN_SPEED: case L2TP_AVP_PHY_CHANNEL_ID: case L2TP_AVP_RX_CONN_SPEED: - print_32bits_val(ndo, (uint32_t *)ptr); + print_32bits_val(ndo, (const uint32_t *)ptr); break; case L2TP_AVP_BEARER_TYPE: - l2tp_bearer_type_print(ndo, (u_char *)ptr); + l2tp_bearer_type_print(ndo, (const u_char *)ptr); break; case L2TP_AVP_FRAMING_TYPE: - l2tp_framing_type_print(ndo, (u_char *)ptr); + l2tp_framing_type_print(ndo, (const u_char *)ptr); break; case L2TP_AVP_PACKET_PROC_DELAY: l2tp_packet_proc_delay_print(ndo); break; case L2TP_AVP_PROXY_AUTH_TYPE: - l2tp_proxy_auth_type_print(ndo, (u_char *)ptr); + l2tp_proxy_auth_type_print(ndo, (const u_char *)ptr); break; case L2TP_AVP_PROXY_AUTH_ID: - l2tp_proxy_auth_id_print(ndo, (u_char *)ptr); + l2tp_proxy_auth_id_print(ndo, (const u_char *)ptr); break; case L2TP_AVP_CALL_ERRORS: - l2tp_call_errors_print(ndo, (u_char *)ptr); + l2tp_call_errors_print(ndo, (const u_char *)ptr); break; case L2TP_AVP_ACCM: - l2tp_accm_print(ndo, (u_char *)ptr); + l2tp_accm_print(ndo, (const u_char *)ptr); break; case L2TP_AVP_SEQ_REQUIRED: break; /* No Attribute Value */ case L2TP_AVP_PPP_DISCON_CC: - l2tp_ppp_discon_cc_print(ndo, (u_char *)ptr, len-6); + l2tp_ppp_discon_cc_print(ndo, (const u_char *)ptr, len-6); break; default: break; diff --git a/contrib/tcpdump/print-lane.c b/contrib/tcpdump/print-lane.c index c1e0b2e..ba52084 100644 --- a/contrib/tcpdump/print-lane.c +++ b/contrib/tcpdump/print-lane.c @@ -20,14 +20,15 @@ * */ -#define NETDISSECT_REWORKED +/* \summary: ATM LANE printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "ether.h" @@ -82,14 +83,14 @@ lane_hdr_print(netdissect_options *ndo, const u_char *bp) void lane_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen) { - struct lane_controlhdr *lec; + const struct lane_controlhdr *lec; if (caplen < sizeof(struct lane_controlhdr)) { ND_PRINT((ndo, "[|lane]")); return; } - lec = (struct lane_controlhdr *)p; + lec = (const struct lane_controlhdr *)p; if (EXTRACT_16BITS(&lec->lec_header) == 0xff00) { /* * LE Control. diff --git a/contrib/tcpdump/print-ldp.c b/contrib/tcpdump/print-ldp.c index 3f741d1..40c9d8c 100644 --- a/contrib/tcpdump/print-ldp.c +++ b/contrib/tcpdump/print-ldp.c @@ -14,14 +14,15 @@ * and Steinar Haug (sthaug@nethelp.no) */ -#define NETDISSECT_REWORKED +/* \summary: Label Distribution Protocol (LDP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "addrtoname.h" @@ -284,12 +285,10 @@ ldp_tlv_print(netdissect_options *ndo, TLV_TCHECK(4); ND_PRINT((ndo, "\n\t IPv4 Transport Address: %s", ipaddr_string(ndo, tptr))); break; -#ifdef INET6 case LDP_TLV_IPV6_TRANSPORT_ADDR: TLV_TCHECK(16); ND_PRINT((ndo, "\n\t IPv6 Transport Address: %s", ip6addr_string(ndo, tptr))); break; -#endif case LDP_TLV_CONFIG_SEQ_NUMBER: TLV_TCHECK(4); ND_PRINT((ndo, "\n\t Sequence Number: %u", EXTRACT_32BITS(tptr))); @@ -311,7 +310,6 @@ ldp_tlv_print(netdissect_options *ndo, tptr+=sizeof(struct in_addr); } break; -#ifdef INET6 case AFNUM_INET6: while(tlv_tlen >= sizeof(struct in6_addr)) { ND_TCHECK2(*tptr, sizeof(struct in6_addr)); @@ -320,7 +318,6 @@ ldp_tlv_print(netdissect_options *ndo, tptr+=sizeof(struct in6_addr); } break; -#endif default: /* unknown AF */ break; @@ -365,7 +362,6 @@ ldp_tlv_print(netdissect_options *ndo, else ND_PRINT((ndo, ": IPv4 prefix %s", buf)); } -#ifdef INET6 else if (af == AFNUM_INET6) { i=decode_prefix6(ndo, tptr, tlv_tlen, buf, sizeof(buf)); if (i == -2) @@ -377,7 +373,6 @@ ldp_tlv_print(netdissect_options *ndo, else ND_PRINT((ndo, ": IPv6 prefix %s", buf)); } -#endif else ND_PRINT((ndo, ": Address family %u prefix", af)); break; @@ -385,16 +380,20 @@ ldp_tlv_print(netdissect_options *ndo, break; case LDP_FEC_MARTINI_VC: /* + * We assume the type was supposed to be one of the MPLS + * Pseudowire Types. + */ + TLV_TCHECK(7); + vc_info_len = *(tptr+2); + + /* * According to RFC 4908, the VC info Length field can be zero, * in which case not only are there no interface parameters, * there's no VC ID. */ - TLV_TCHECK(7); - vc_info_len = *(tptr+2); - if (vc_info_len == 0) { ND_PRINT((ndo, ": %s, %scontrol word, group-ID %u, VC-info-length: %u", - tok2str(l2vpn_encaps_values, "Unknown", EXTRACT_16BITS(tptr)&0x7fff), + tok2str(mpls_pw_types_values, "Unknown", EXTRACT_16BITS(tptr)&0x7fff), EXTRACT_16BITS(tptr)&0x8000 ? "" : "no ", EXTRACT_32BITS(tptr+3), vc_info_len)); @@ -404,7 +403,7 @@ ldp_tlv_print(netdissect_options *ndo, /* 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(l2vpn_encaps_values, "Unknown", EXTRACT_16BITS(tptr)&0x7fff), + tok2str(mpls_pw_types_values, "Unknown", EXTRACT_16BITS(tptr)&0x7fff), EXTRACT_16BITS(tptr)&0x8000 ? "" : "no ", EXTRACT_32BITS(tptr+3), EXTRACT_32BITS(tptr+7), diff --git a/contrib/tcpdump/print-lisp.c b/contrib/tcpdump/print-lisp.c new file mode 100644 index 0000000..47afe50 --- /dev/null +++ b/contrib/tcpdump/print-lisp.c @@ -0,0 +1,449 @@ +/* + * Copyright (c) 2015 Ritesh Ranjan (r.ranjan789@gmail.com) + * 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. 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 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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: - Locator/Identifier Separation Protocol (LISP) printer */ + +/* + * specification: RFC 6830 + * + * + * The Map-Register message format is: + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |Type=3 |P|S|I|R| Reserved |M| Record Count | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Nonce . . . | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | . . . Nonce | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Key ID | Authentication Data Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ~ Authentication Data ~ + * +-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | Record TTL | + * | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * R | Locator Count | EID mask-len | ACT |A| Reserved | + * e +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * c | Rsvd | Map-Version Number | EID-Prefix-AFI | + * o +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * r | EID-Prefix | + * d +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | /| Priority | Weight | M Priority | M Weight | + * | L +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | o | Unused Flags |L|p|R| Loc-AFI | + * | c +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | \| Locator | + * +-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * + * The Map-Notify message format is: + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |Type=4 |I|R| Reserved | Record Count | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Nonce . . . | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | . . . Nonce | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Key ID | Authentication Data Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ~ Authentication Data ~ + * +-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | Record TTL | + * | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * R | Locator Count | EID mask-len | ACT |A| Reserved | + * e +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * c | Rsvd | Map-Version Number | EID-Prefix-AFI | + * o +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * r | EID-Prefix | + * d +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | /| Priority | Weight | M Priority | M Weight | + * | L +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | o | Unused Flags |L|p|R| Loc-AFI | + * | c +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | \| Locator | + * +-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include "ip.h" +#include "ip6.h" + +#include "extract.h" +#include "addrtoname.h" + +static const char tstr[] = " [|LISP]"; + +#define IPv4_AFI 1 +#define IPv6_AFI 2 +#define TYPE_INDEX 4 +#define LISP_MAP_NOTIFY_IBIT_MASK 8 +#define LISP_MAP_REGISTER_IBIT_MASK 2 + +enum { + LISP_MAP_REQUEST = 1, + LISP_MAP_REPLY, + LISP_MAP_REGISTER, + LISP_MAP_NOTIFY, + LISP_ENCAPSULATED_CONTROL_MESSAGE = 8 +}; + +enum { + LISP_AUTH_NONE, + LISP_AUTH_SHA1, + LISP_AUTH_SHA256 +}; + +static const struct tok lisp_type [] = { + { 0, "LISP-Reserved" }, + { 1, "LISP-Map-Request" }, + { 2, "LISP-Map-Reply" }, + { 3, "LISP-Map-Register" }, + { 4, "LISP-Map-Notify" }, + { 8, "LISP-Encapsulated-Contol-Message" }, + { 0, NULL } +}; + +/* + * P-Bit : Request for Proxy Map-Reply from the MS/MR + * S-Bit : Security Enhancement. ETR is LISP-SEC enabled. draft-ietf-lisp-sec + * I-Bit : 128 bit xTR-ID and 64 bit Site-ID present. + * xTR-ID and Site-ID help in differentiation of xTRs in multi xTR + * and multi Site deployment scenarios. + * R-Bit : Built for a Reencapsulating-Tunnel-Router. Used in Traffic + * Engineering and Service Chaining + */ +static const struct tok map_register_hdr_flag[] = { + { 0x08000000, "P-Proxy-Map-Reply" }, + { 0x04000000, "S-LISP-SEC-Capable" }, + { 0x02000000, "I-xTR-ID-Present" }, + { 0x01000000, "R-Build-For-RTR" }, + { 0x00000100, "M-Want-Map-Notify" }, + { 0, NULL } +}; + +static const struct tok map_notify_hdr_flag[] = { + { 0x08000000, "I-xTR-ID-Present" }, + { 0x04000000, "R-Build-For-RTR" }, + { 0, NULL } +}; + +static const struct tok auth_type[] = { + { LISP_AUTH_NONE, "None" }, + { LISP_AUTH_SHA1, "SHA1" }, + { LISP_AUTH_SHA256, "SHA256" }, + { 0, NULL} +}; + +static const struct tok lisp_eid_action[] = { + { 0, "No-Action" }, + { 1, "Natively-Forward" }, + { 2, "Send-Map-Request" }, + { 3, "Drop" }, + { 0, NULL} +}; + +static const struct tok lisp_loc_flag[] = { + { 0x0004, "Local-Locator" }, + { 0x0002, "RLoc-Probed" }, + { 0x0001, "Reachable" }, + { 0, NULL } +}; + +typedef struct map_register_hdr { + nd_uint8_t type_and_flag; + nd_uint8_t reserved; + nd_uint8_t reserved_and_flag2; + nd_uint8_t record_count; + nd_uint64_t nonce; + nd_uint16_t key_id; + nd_uint16_t auth_data_len; +} lisp_map_register_hdr; + +#define MAP_REGISTER_HDR_LEN sizeof(lisp_map_register_hdr) + +typedef struct map_register_eid { + nd_uint32_t ttl; + nd_uint8_t locator_count; + 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 eid_prefix_afi; +} lisp_map_register_eid; + +#define MAP_REGISTER_EID_LEN sizeof(lisp_map_register_eid) + +typedef struct map_register_loc { + nd_uint8_t priority; + nd_uint8_t weight; + nd_uint8_t m_priority; + nd_uint8_t m_weight; + nd_uint16_t unused_and_flag; + nd_uint16_t locator_afi; +} lisp_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 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) +{ + uint8_t type; + uint8_t mask_len; + uint8_t loc_count; + uint8_t xtr_present; + uint8_t record_count; + uint16_t key_id; + uint16_t eid_afi; + uint16_t loc_afi; + uint16_t map_version; + uint16_t packet_offset; + uint16_t auth_data_len; + uint32_t ttl; + const u_char *packet_iterator; + const u_char *loc_ip_pointer; + const lisp_map_register_hdr *lisp_hdr; + const lisp_map_register_eid *lisp_eid; + const lisp_map_register_loc *lisp_loc; + + /* Check if enough bytes for header are available */ + ND_TCHECK2(*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); + 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); + + /* Extract the number of EID records present */ + auth_data_len = EXTRACT_16BITS(&lisp_hdr->auth_data_len); + packet_iterator = (const u_char *)(lisp_hdr); + packet_offset = MAP_REGISTER_HDR_LEN; + record_count = 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))); + hex_print(ndo, "\n Authentication-Data: ", packet_iterator + + packet_offset, auth_data_len); + } else { + ND_PRINT((ndo, " %u record(s),", record_count)); + } + packet_offset += auth_data_len; + + if (record_count == 0) + goto invalid; + + /* 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")); + 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; + + 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)); + } + + 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)); + 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)); + packet_offset += 16; + break; + default: + /* + * No support for LCAF right now. + */ + return; + break; + } + + ND_PRINT((ndo, " %u locator(s)", loc_count)); + + while (loc_count--) { + ND_TCHECK2(*(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); + + if (ndo->ndo_vflag) + ND_PRINT((ndo, "\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))); + 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))); + packet_offset += 16; + break; + default: + break; + } + if (ndo->ndo_vflag) { + ND_PRINT((ndo, "\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)); + } + } + } + + /* + * Print xTR and Site ID. Handle the fact that the packet could be invalid. + * If the xTR_ID_Present bit is not set, and we still have data to display, + * show it as hex data. + */ + if (xtr_present) { + if (!ND_TTEST2(*(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))); + } 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); + } + } + return; +trunc: + ND_PRINT((ndo, "\n %s", tstr)); + return; +invalid: + ND_PRINT((ndo, "\n %s", istr)); + return; +} + +static inline 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) +{ + uint8_t xtr_present = 0; + + if (type == LISP_MAP_REGISTER) + xtr_present = (lisp_hdr_flags) & LISP_MAP_REGISTER_IBIT_MASK; + else if (type == LISP_MAP_NOTIFY) + xtr_present = (lisp_hdr_flags) & LISP_MAP_NOTIFY_IBIT_MASK; + + return xtr_present; +} + +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); + + if (!ndo->ndo_vflag) { + ND_PRINT((ndo, "%s,", tok2str(lisp_type, "unknown-type-%u", type))); + return; + } else { + ND_PRINT((ndo, "%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)))); + } else if (type == LISP_MAP_NOTIFY) { + ND_PRINT((ndo, " flags [%s],", bittok2str(map_notify_hdr_flag, + "none", EXTRACT_32BITS(lisp_hdr)))); + } + + return; +} + +static void action_flag(netdissect_options *ndo, uint8_t act_auth_inc_res) +{ + uint8_t action; + uint8_t authoritative; + + authoritative = ((act_auth_inc_res >> 4) & 1); + + if (authoritative) + ND_PRINT((ndo, " Authoritative,")); + else + ND_PRINT((ndo, " Non-Authoritative,")); + + action = act_auth_inc_res >> 5; + ND_PRINT((ndo, " %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))); +} + diff --git a/contrib/tcpdump/print-llc.c b/contrib/tcpdump/print-llc.c index 78b8631..6bdf599 100644 --- a/contrib/tcpdump/print-llc.c +++ b/contrib/tcpdump/print-llc.c @@ -20,20 +20,19 @@ * * Code by Matt Thomas, Digital Equipment Corporation * with an awful lot of hacking by Jeffrey Mogul, DECWRL - * - * $FreeBSD$ */ -#define NETDISSECT_REWORKED +/* \summary: IEEE 802.2 LLC printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" -#include "extract.h" /* must come after interface.h */ +#include "extract.h" #include "llc.h" #include "ethertype.h" @@ -140,23 +139,31 @@ static const struct oui_tok oui_to_tok[] = { }; /* - * Returns non-zero IFF it succeeds in printing the header + * If we printed information about the payload, returns the length of the LLC + * header, plus the length of any SNAP header following it. + * + * Otherwise (for example, if the packet has unknown SAPs or has a SNAP + * header with an unknown OUI/PID combination), returns the *negative* + * of that value. */ int llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, - const u_char *esrc, const u_char *edst, u_short *extracted_ethertype) + const struct lladdr_info *src, const struct lladdr_info *dst) { uint8_t dsap_field, dsap, ssap_field, ssap; uint16_t control; + int hdrlen; int is_u; - register int ret; - - *extracted_ethertype = 0; - if (caplen < 3 || length < 3) { + if (caplen < 3) { ND_PRINT((ndo, "[|llc]")); - ND_DEFAULTPRINT((u_char *)p, caplen); - return (1); + ND_DEFAULTPRINT((const u_char *)p, caplen); + return (caplen); + } + if (length < 3) { + ND_PRINT((ndo, "[|llc]")); + ND_DEFAULTPRINT((const u_char *)p, caplen); + return (length); } dsap_field = *p; @@ -174,15 +181,21 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, * U frame. */ is_u = 1; + hdrlen = 3; /* DSAP, SSAP, 1-byte control field */ } else { /* * The control field in I and S frames is * 2 bytes... */ - if (caplen < 4 || length < 4) { + if (caplen < 4) { ND_PRINT((ndo, "[|llc]")); - ND_DEFAULTPRINT((u_char *)p, caplen); - return (1); + ND_DEFAULTPRINT((const u_char *)p, caplen); + return (caplen); + } + if (length < 4) { + ND_PRINT((ndo, "[|llc]")); + ND_DEFAULTPRINT((const u_char *)p, caplen); + return (length); } /* @@ -190,6 +203,7 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, */ control = EXTRACT_LE_16BITS(p + 2); is_u = 0; + hdrlen = 4; /* DSAP, SSAP, 2-byte control field */ } if (ssap_field == LLCSAP_GLOBAL && dsap_field == LLCSAP_GLOBAL) { @@ -212,7 +226,7 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, ND_PRINT((ndo, "IPX 802.3: ")); ipx_print(ndo, p, length); - return (1); + return (0); /* no LLC header */ } dsap = dsap_field & ~LLC_IG; @@ -234,21 +248,47 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, } } + /* + * Skip LLC header. + */ + p += hdrlen; + length -= hdrlen; + caplen -= hdrlen; + + if (ssap == LLCSAP_SNAP && dsap == LLCSAP_SNAP + && control == LLC_UI) { + /* + * XXX - what *is* the right bridge pad value here? + * Does anybody ever bridge one form of LAN traffic + * over a networking type that uses 802.2 LLC? + */ + if (!snap_print(ndo, p, length, caplen, src, dst, 2)) { + /* + * Unknown packet type; tell our caller, by + * returning a negative value, so they + * can print the raw packet. + */ + return (-(hdrlen + 5)); /* include LLC and SNAP header */ + } else + return (hdrlen + 5); /* include LLC and SNAP header */ + } + if (ssap == LLCSAP_8021D && dsap == LLCSAP_8021D && control == LLC_UI) { - stp_print(ndo, p+3, length-3); - return (1); + stp_print(ndo, p, length); + return (hdrlen); } if (ssap == LLCSAP_IP && dsap == LLCSAP_IP && control == LLC_UI) { - if (caplen < 4 || length < 4) { - ND_PRINT((ndo, "[|llc]")); - ND_DEFAULTPRINT((u_char *)p, caplen); - return (1); - } - ip_print(ndo, p+4, length-4); - return (1); + /* + * This is an RFC 948-style IP packet, with + * an 802.3 header and an 802.2 LLC header + * with the source and destination SAPs being + * the IP SAP. + */ + ip_print(ndo, p, length); + return (hdrlen); } if (ssap == LLCSAP_IPX && dsap == LLCSAP_IPX && @@ -257,17 +297,15 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, * This is an Ethernet_802.2 IPX frame, with an 802.3 * header and an 802.2 LLC header with the source and * destination SAPs being the IPX SAP. - * - * Skip DSAP, LSAP, and control field. */ if (ndo->ndo_eflag) ND_PRINT((ndo, "IPX 802.2: ")); - ipx_print(ndo, p+3, length-3); - return (1); + ipx_print(ndo, p, length); + return (hdrlen); } -#ifdef TCPDUMP_DO_SMB +#ifdef ENABLE_SMB if (ssap == LLCSAP_NETBEUI && dsap == LLCSAP_NETBEUI && (!(control & LLC_S_FMT) || control == LLC_U_FMT)) { /* @@ -280,58 +318,35 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, * LLC_S_FMT, set in the first byte of the control field) * and UI frames (whose control field is just 3, LLC_U_FMT). */ - - /* - * Skip the LLC header. - */ - if (is_u) { - p += 3; - length -= 3; - } else { - p += 4; - length -= 4; - } netbeui_print(ndo, control, p, length); - return (1); + return (hdrlen); } #endif if (ssap == LLCSAP_ISONS && dsap == LLCSAP_ISONS && control == LLC_UI) { - isoclns_print(ndo, p + 3, length - 3, caplen - 3); - return (1); - } - - if (ssap == LLCSAP_SNAP && dsap == LLCSAP_SNAP - && control == LLC_UI) { - /* - * XXX - what *is* the right bridge pad value here? - * Does anybody ever bridge one form of LAN traffic - * over a networking type that uses 802.2 LLC? - */ - ret = snap_print(ndo, p+3, length-3, caplen-3, 2); - if (ret) - return (ret); + isoclns_print(ndo, p, length, caplen); + return (hdrlen); } if (!ndo->ndo_eflag) { if (ssap == dsap) { - if (esrc == NULL || edst == NULL) + if (src == NULL || dst == NULL) ND_PRINT((ndo, "%s ", tok2str(llc_values, "Unknown DSAP 0x%02x", dsap))); else ND_PRINT((ndo, "%s > %s %s ", - etheraddr_string(ndo, esrc), - etheraddr_string(ndo, edst), + (src->addr_string)(ndo, src->addr), + (dst->addr_string)(ndo, dst->addr), tok2str(llc_values, "Unknown DSAP 0x%02x", dsap))); } else { - if (esrc == NULL || edst == NULL) + if (src == NULL || dst == NULL) ND_PRINT((ndo, "%s > %s ", tok2str(llc_values, "Unknown SSAP 0x%02x", ssap), tok2str(llc_values, "Unknown DSAP 0x%02x", dsap))); else ND_PRINT((ndo, "%s %s > %s %s ", - etheraddr_string(ndo, esrc), + (src->addr_string)(ndo, src->addr), tok2str(llc_values, "Unknown SSAP 0x%02x", ssap), - etheraddr_string(ndo, edst), + (dst->addr_string)(ndo, dst->addr), tok2str(llc_values, "Unknown DSAP 0x%02x", dsap))); } } @@ -340,13 +355,31 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, ND_PRINT((ndo, "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)); - - p += 3; + length + hdrlen)); if ((control & ~LLC_U_POLL) == LLC_XID) { + if (length == 0) { + /* + * XID with no payload. + * This could, for example, be an SNA + * "short form" XID. + */ + return (hdrlen); + } + if (caplen < 1) { + ND_PRINT((ndo, "[|llc]")); + if (caplen > 0) + ND_DEFAULTPRINT((const u_char *)p, caplen); + return (hdrlen); + } if (*p == LLC_XID_FI) { - ND_PRINT((ndo, ": %02x %02x", p[1], p[2])); + if (caplen < 3 || length < 3) { + ND_PRINT((ndo, "[|llc]")); + if (caplen > 0) + ND_DEFAULTPRINT((const u_char *)p, caplen); + } else + ND_PRINT((ndo, ": %02x %02x", p[1], p[2])); + return (hdrlen); } } } else { @@ -355,20 +388,38 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, 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)); + length + hdrlen)); + return (hdrlen); /* no payload to print */ } else { ND_PRINT((ndo, "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)); + length + hdrlen)); } } - return(1); + return (-hdrlen); +} + +static const struct tok * +oui_to_struct_tok(uint32_t orgcode) +{ + const struct tok *tok = null_values; + const struct oui_tok *otp; + + for (otp = &oui_to_tok[0]; otp->tok != NULL; otp++) { + if (otp->oui == orgcode) { + tok = otp->tok; + break; + } + } + return (tok); } int -snap_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, u_int bridge_pad) +snap_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, + const struct lladdr_info *src, const struct lladdr_info *dst, + u_int bridge_pad) { uint32_t orgcode; register u_short et; @@ -381,21 +432,17 @@ snap_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, et = EXTRACT_16BITS(p + 3); if (ndo->ndo_eflag) { - const struct tok *tok = null_values; - const struct oui_tok *otp; - - for (otp = &oui_to_tok[0]; otp->tok != NULL; otp++) { - if (otp->oui == orgcode) { - tok = otp->tok; - break; - } - } - ND_PRINT((ndo, "oui %s (0x%06x), %s %s (0x%04x): ", + /* + * Somebody's already printed the MAC addresses, if there + * 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: ", tok2str(oui_values, "Unknown", orgcode), orgcode, (orgcode == 0x000000 ? "ethertype" : "pid"), - tok2str(tok, "Unknown", et), - et)); + tok2str(oui_to_struct_tok(orgcode), "Unknown", et), + et, length - 5)); } p += 5; length -= 5; @@ -410,7 +457,7 @@ snap_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, * Cisco hardware; the protocol ID is * an Ethernet protocol type. */ - ret = ethertype_print(ndo, et, p, length, caplen); + ret = ethertype_print(ndo, et, p, length, caplen, src, dst); if (ret) return (ret); break; @@ -425,7 +472,7 @@ snap_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, * but used 0x000000 and an Ethernet * packet type for AARP packets. */ - ret = ethertype_print(ndo, et, p, length, caplen); + ret = ethertype_print(ndo, et, p, length, caplen, src, dst); if (ret) return (ret); } @@ -524,6 +571,33 @@ snap_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, return (1); } } + if (!ndo->ndo_eflag) { + /* + * Nobody printed the link-layer addresses, so print them, if + * we have any. + */ + if (src != NULL && dst != NULL) { + ND_PRINT((ndo, "%s > %s ", + (src->addr_string)(ndo, src->addr), + (dst->addr_string)(ndo, dst->addr))); + } + /* + * Print the SNAP header, but if the OUI is 000000, don't + * bother printing it, and report the PID as being an + * ethertype. + */ + if (orgcode == 0x000000) { + ND_PRINT((ndo, "SNAP, ethertype %s (0x%04x), length %u: ", + tok2str(ethertype_values, "Unknown", et), + et, length)); + } else { + ND_PRINT((ndo, "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)); + } + } return (0); trunc: diff --git a/contrib/tcpdump/print-lldp.c b/contrib/tcpdump/print-lldp.c index ce3c093..730b36f 100644 --- a/contrib/tcpdump/print-lldp.c +++ b/contrib/tcpdump/print-lldp.c @@ -12,23 +12,22 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * support for the IEEE Link Discovery Protocol as per 802.1AB - * * Original code by Hannes Gredler (hannes@juniper.net) * IEEE and TIA extensions by Carles Kishimoto * DCBX extensions by Kaladhar Musunuru */ -#define NETDISSECT_REWORKED +/* \summary: IEEE 802.1ab Link Layer Discovery Protocol (LLDP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "addrtoname.h" #include "af.h" @@ -602,6 +601,14 @@ static const struct tok lldp_evb_mode_values[]={ #define LLDP_PRIVATE_8021_SUBTYPE_EVB_LENGTH 9 #define LLDP_PRIVATE_8021_SUBTYPE_CDCP_MIN_LENGTH 8 +#define LLDP_IANA_SUBTYPE_MUDURL 1 + +static const struct tok lldp_iana_subtype_values[] = { + { LLDP_IANA_SUBTYPE_MUDURL, "MUD-URL" }, + { 0, NULL } +}; + + static void print_ets_priority_assignment_table(netdissect_options *ndo, const u_char *ptr) @@ -915,6 +922,40 @@ lldp_extract_latlon(const u_char *tptr) return latlon; } +/* objects defined in IANA subtype 00 00 5e + * (right now there is only one) + */ + + +static int +lldp_private_iana_print(netdissect_options *ndo, + const u_char *tptr, u_int tlv_len) +{ + int subtype, hexdump = FALSE; + + if (tlv_len < 8) { + return hexdump; + } + subtype = *(tptr+3); + + ND_PRINT((ndo, "\n\t %s Subtype (%u)", + tok2str(lldp_iana_subtype_values, "unknown", 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); + break; + default: + hexdump=TRUE; + } + + return hexdump; +} + + + /* * Print private TIA extensions. */ @@ -1279,15 +1320,15 @@ lldp_network_addr_print(netdissect_options *ndo, const u_char *tptr, u_int len) case AFNUM_INET: if (len < 4) return NULL; + /* This cannot be assigned to ipaddr_string(), which is a macro. */ pfunc = getname; break; -#ifdef INET6 case AFNUM_INET6: if (len < 16) return NULL; + /* This cannot be assigned to ip6addr_string(), which is a macro. */ pfunc = getname6; break; -#endif case AFNUM_802: if (len < 6) return NULL; @@ -1574,6 +1615,9 @@ lldp_print(netdissect_options *ndo, case OUI_IEEE_8023_PRIVATE: hexdump = lldp_private_8023_print(ndo, tptr, tlv_len); break; + case OUI_IANA: + hexdump = lldp_private_iana_print(ndo, tptr, tlv_len); + break; case OUI_TIA: hexdump = lldp_private_tia_print(ndo, tptr, tlv_len); break; diff --git a/contrib/tcpdump/print-lmp.c b/contrib/tcpdump/print-lmp.c index 904dd71..1c7710c 100644 --- a/contrib/tcpdump/print-lmp.c +++ b/contrib/tcpdump/print-lmp.c @@ -10,21 +10,22 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * Support for the Link Management Protocol as per rfc 4204. - * * Original code by Hannes Gredler (hannes@juniper.net) * Support for LMP service discovery extensions (defined by UNI 1.0) added * by Manu Pathak (mapathak@cisco.com), May 2005 */ -#define NETDISSECT_REWORKED +/* \summary: Link Management Protocol (LMP) printer */ + +/* specification: RFC 4204 */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "addrtoname.h" #include "gmpls.h" @@ -459,14 +460,12 @@ lmp_print(netdissect_options *ndo, ipaddr_string(ndo, obj_tptr), EXTRACT_32BITS(obj_tptr))); break; -#ifdef INET6 case LMP_CTYPE_IPV6_LOC: case LMP_CTYPE_IPV6_RMT: ND_PRINT((ndo, "\n\t IPv6 Link ID: %s (0x%08x)", ip6addr_string(ndo, obj_tptr), EXTRACT_32BITS(obj_tptr))); break; -#endif case LMP_CTYPE_UNMD_LOC: case LMP_CTYPE_UNMD_RMT: ND_PRINT((ndo, "\n\t Link ID: %u (0x%08x)", @@ -551,9 +550,7 @@ lmp_print(netdissect_options *ndo, EXTRACT_32BITS(obj_tptr+8))); break; -#ifdef INET6 case LMP_CTYPE_IPV6: -#endif case LMP_CTYPE_UNMD: default: hexdump=TRUE; @@ -620,9 +617,7 @@ lmp_print(netdissect_options *ndo, } break; -#ifdef INET6 case LMP_CTYPE_IPV6: -#endif default: hexdump=TRUE; } @@ -709,9 +704,7 @@ lmp_print(netdissect_options *ndo, offset+=8; } break; -#ifdef INET6 case LMP_CTYPE_IPV6: -#endif default: hexdump=TRUE; } @@ -729,9 +722,7 @@ lmp_print(netdissect_options *ndo, offset+=4; } break; -#ifdef INET6 case LMP_CTYPE_IPV6: -#endif default: hexdump=TRUE; } @@ -851,7 +842,7 @@ lmp_print(netdissect_options *ndo, default: hexdump = TRUE; - }; + } break; diff --git a/contrib/tcpdump/print-loopback.c b/contrib/tcpdump/print-loopback.c index 9a74ae6..10f6931 100644 --- a/contrib/tcpdump/print-loopback.c +++ b/contrib/tcpdump/print-loopback.c @@ -1,9 +1,4 @@ /* - * This module implements decoding of the Loopback Protocol, originally - * defined as the Configuration Testing Protocol. It is based on the following - * specification: - * http://www.mit.edu/people/jhawk/ctp.pdf - * * Copyright (c) 2014 The TCPDUMP project * All rights reserved. * @@ -30,20 +25,25 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#define NETDISSECT_REWORKED +/* \summary: Loopback Protocol printer */ + +/* + * originally defined as the Ethernet Configuration Testing Protocol. + * specification: http://www.mit.edu/people/jhawk/ctp.pdf + */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "ether.h" #include "addrtoname.h" static const char tstr[] = " [|loopback]"; -static const char cstr[] = " (corrupt)"; #define LOOPBACK_REPLY 1 #define LOOPBACK_FWDDATA 2 @@ -61,7 +61,7 @@ loopback_message_print(netdissect_options *ndo, const u_char *cp, const u_int le uint16_t function; if (len < 2) - goto corrupt; + goto invalid; /* function */ ND_TCHECK2(*cp, 2); function = EXTRACT_LE_16BITS(cp); @@ -71,7 +71,7 @@ loopback_message_print(netdissect_options *ndo, const u_char *cp, const u_int le switch (function) { case LOOPBACK_REPLY: if (len < 4) - goto corrupt; + goto invalid; /* receipt number */ ND_TCHECK2(*cp, 2); ND_PRINT((ndo, ", receipt number %u", EXTRACT_LE_16BITS(cp))); @@ -82,7 +82,7 @@ loopback_message_print(netdissect_options *ndo, const u_char *cp, const u_int le break; case LOOPBACK_FWDDATA: if (len < 8) - goto corrupt; + goto invalid; /* forwarding address */ ND_TCHECK2(*cp, ETHER_ADDR_LEN); ND_PRINT((ndo, ", forwarding address %s", etheraddr_string(ndo, cp))); @@ -97,8 +97,8 @@ loopback_message_print(netdissect_options *ndo, const u_char *cp, const u_int le } return; -corrupt: - ND_PRINT((ndo, "%s", cstr)); +invalid: + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp, ep - cp); return; trunc: @@ -113,7 +113,7 @@ loopback_print(netdissect_options *ndo, const u_char *cp, const u_int len) ND_PRINT((ndo, "Loopback")); if (len < 2) - goto corrupt; + goto invalid; /* skipCount */ ND_TCHECK2(*cp, 2); skipCount = EXTRACT_LE_16BITS(cp); @@ -122,12 +122,12 @@ loopback_print(netdissect_options *ndo, const u_char *cp, const u_int len) if (skipCount % 8) ND_PRINT((ndo, " (bogus)")); if (skipCount > len - 2) - goto corrupt; + goto invalid; loopback_message_print(ndo, cp + skipCount, len - 2 - skipCount); return; -corrupt: - ND_PRINT((ndo, "%s", cstr)); +invalid: + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp, ep - cp); return; trunc: diff --git a/contrib/tcpdump/print-lspping.c b/contrib/tcpdump/print-lspping.c index 888adfa..4d260db 100644 --- a/contrib/tcpdump/print-lspping.c +++ b/contrib/tcpdump/print-lspping.c @@ -13,20 +13,23 @@ * Original code by Hannes Gredler (hannes@juniper.net) */ -#define NETDISSECT_REWORKED +/* \summary: MPLS LSP PING printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "addrtoname.h" #include "l2vpn.h" #include "oui.h" +/* RFC 4349 */ + /* * LSPPING common header * @@ -57,7 +60,7 @@ struct lspping_common_header { uint8_t version[2]; - uint8_t reserved[2]; + uint8_t global_flags[2]; uint8_t msg_type; uint8_t reply_mode; uint8_t return_code; @@ -100,6 +103,7 @@ static const struct tok lspping_return_code_values[] = { { 10, "Mapping for this FEC is not the given label at stack depth"}, { 11, "No label entry at stack-depth"}, { 12, "Protocol not associated with interface at FEC stack depth"}, + { 13, "Premature termination of ping due to label stack shrinking to a single label"}, }; @@ -126,9 +130,12 @@ struct lspping_tlv_header { #define LSPPING_TLV_TARGET_FEC_STACK 1 #define LSPPING_TLV_DOWNSTREAM_MAPPING 2 #define LSPPING_TLV_PAD 3 +/* not assigned 4 */ #define LSPPING_TLV_VENDOR_ENTERPRISE 5 #define LSPPING_TLV_VENDOR_ENTERPRISE_LEN 4 +/* not assigned 6 */ #define LSPPING_TLV_INTERFACE_LABEL_STACK 7 +/* not assigned 8 */ #define LSPPING_TLV_ERROR_CODE 9 #define LSPPING_TLV_REPLY_TOS_BYTE 10 #define LSPPING_TLV_BFD_DISCRIMINATOR 15 /* draft-ietf-bfd-mpls-02 */ @@ -148,17 +155,22 @@ static const struct tok lspping_tlv_values[] = { { 0, NULL} }; -#define LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4 1 -#define LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6 2 -#define LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4 3 -#define LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6 4 -#define LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4 6 -#define LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6 7 -#define LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT 8 -#define LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID_OLD 9 -#define LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID 10 -#define LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4 11 -#define LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6 12 +#define LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4 1 +#define LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6 2 +#define LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4 3 +#define LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6 4 +/* not assigned 5 */ +#define LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4 6 +#define LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6 7 +#define LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT 8 +#define LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW_OLD 9 +#define LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW 10 +#define LSPPING_TLV_TARGETFEC_SUBTLV_FEC_129_PW 11 +#define LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4 12 +#define LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6 13 +#define LSPPING_TLV_TARGETFEC_SUBTLV_GENERIC_IPV4 14 +#define LSPPING_TLV_TARGETFEC_SUBTLV_GENERIC_IPV6 15 +#define LSPPING_TLV_TARGETFEC_SUBTLV_NIL_FEC 16 static const struct tok lspping_tlvtargetfec_subtlv_values[] = { { LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4, "LDP IPv4 prefix"}, @@ -169,8 +181,8 @@ static const struct tok lspping_tlvtargetfec_subtlv_values[] = { { LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4, "VPN IPv4 prefix"}, { LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6, "VPN IPv6 prefix"}, { LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT, "L2 VPN endpoint"}, - { LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID_OLD, "L2 circuit ID (old)"}, - { LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID, "L2 circuit ID"}, + { LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW_OLD, "FEC 128 pseudowire (old)"}, + { LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW, "FEC 128 pseudowire"}, { LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4, "BGP labeled IPv4 prefix"}, { LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6, "BGP labeled IPv6 prefix"}, { 0, NULL} @@ -208,44 +220,6 @@ struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t { }; /* - * 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 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Sender identifier | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | IPv4 prefix | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Prefix Length | Must Be Zero | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ -struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t { - uint8_t sender_id [4]; - uint8_t prefix [4]; - uint8_t prefix_len; -}; - -/* - * 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 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Sender identifier | - * | (16 octets) | - * | | - * | | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | IPv6 prefix | - * | (16 octets) | - * | | - * | | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Prefix Length | Must Be Zero | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ -struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t { - uint8_t sender_id [16]; - uint8_t prefix [16]; - uint8_t prefix_len; -}; - -/* * 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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -350,7 +324,7 @@ struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t { * | Route Distinguisher | * | (8 octets) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Sender's CE ID | Receiver's CE ID | + * | Sender's VE ID | Receiver's VE ID | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Encapsulation Type | Must Be Zero | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -358,8 +332,8 @@ struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t { */ struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t { uint8_t rd [8]; - uint8_t sender_ce_id [2]; - uint8_t receiver_ce_id [2]; + uint8_t sender_ve_id [2]; + uint8_t receiver_ve_id [2]; uint8_t encapsulation[2]; }; @@ -368,15 +342,15 @@ struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t { * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Remote PE Address | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | VC ID | + * | PW ID | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Encapsulation Type | Must Be Zero | + * | PW Type | Must Be Zero | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_old_t { +struct lspping_tlv_targetfec_subtlv_fec_128_pw_old { uint8_t remote_pe_address [4]; - uint8_t vc_id [4]; - uint8_t encapsulation[2]; + uint8_t pw_id [4]; + uint8_t pw_type[2]; }; /* @@ -386,16 +360,45 @@ struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_old_t { * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Remote PE Address | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | VC ID | + * | PW ID | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Encapsulation Type | Must Be Zero | + * | PW Type | Must Be Zero | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_t { +struct lspping_tlv_targetfec_subtlv_fec_128_pw { uint8_t sender_pe_address [4]; uint8_t remote_pe_address [4]; - uint8_t vc_id [4]; - uint8_t encapsulation[2]; + uint8_t pw_id [4]; + uint8_t pw_type[2]; +}; + +/* + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | IPv4 prefix | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Prefix Length | Must Be Zero | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ +struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t { + uint8_t prefix [4]; + uint8_t prefix_len; +}; + +/* + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | IPv6 prefix | + * | (16 octets) | + * | | + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Prefix Length | Must Be Zero | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ +struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t { + uint8_t prefix [16]; + uint8_t prefix_len; }; /* @@ -408,7 +411,7 @@ struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_t { * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Downstream Interface Address (4 or 16 octets) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Hash Key Type | Depth Limit | Multipath Length | + * | Multipath Type| Depth Limit | Multipath Length | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * . . * . (Multipath Information) . @@ -423,10 +426,25 @@ struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_t { * | Downstream Label | Protocol | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/* Enough to get the address type */ +struct lspping_tlv_downstream_map_t { + uint8_t mtu [2]; + uint8_t address_type; + uint8_t ds_flags; +}; + struct lspping_tlv_downstream_map_ipv4_t { uint8_t mtu [2]; uint8_t address_type; - uint8_t res; + uint8_t ds_flags; + uint8_t downstream_ip[4]; + uint8_t downstream_interface[4]; +}; + +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]; }; @@ -434,25 +452,35 @@ struct lspping_tlv_downstream_map_ipv4_t { struct lspping_tlv_downstream_map_ipv6_t { uint8_t mtu [2]; uint8_t address_type; - uint8_t res; + uint8_t ds_flags; uint8_t downstream_ip[16]; uint8_t downstream_interface[16]; }; +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]; +}; + struct lspping_tlv_downstream_map_info_t { - uint8_t hash_key_type; + uint8_t multipath_type; uint8_t depth_limit; uint8_t multipath_length [2]; }; -#define LSPPING_AFI_IPV4 1 -#define LSPPING_AFI_UNMB 2 -#define LSPPING_AFI_IPV6 3 +#define LSPPING_AFI_IPV4 1 +#define LSPPING_AFI_IPV4_UNMB 2 +#define LSPPING_AFI_IPV6 3 +#define LSPPING_AFI_IPV6_UNMB 4 static const struct tok lspping_tlv_downstream_addr_values[] = { - { LSPPING_AFI_IPV4, "IPv4"}, - { LSPPING_AFI_IPV6, "IPv6"}, - { LSPPING_AFI_UNMB, "Unnumbered"}, + { LSPPING_AFI_IPV4, "IPv4"}, + { LSPPING_AFI_IPV4_UNMB, "Unnumbered IPv4"}, + { LSPPING_AFI_IPV6, "IPv6"}, + { LSPPING_AFI_IPV6_UNMB, "IPv6"}, { 0, NULL} }; @@ -464,14 +492,17 @@ lspping_print(netdissect_options *ndo, const struct lspping_tlv_header *lspping_tlv_header; const struct lspping_tlv_header *lspping_subtlv_header; const u_char *tptr,*tlv_tptr,*subtlv_tptr; - int tlen,lspping_tlv_len,lspping_tlv_type,tlv_tlen; + u_int tlen,lspping_tlv_len,lspping_tlv_type,tlv_tlen; int tlv_hexdump,subtlv_hexdump; - int lspping_subtlv_len,lspping_subtlv_type; + u_int lspping_subtlv_len,lspping_subtlv_type; struct timeval timestamp; union { + const struct lspping_tlv_downstream_map_t *lspping_tlv_downstream_map; const struct lspping_tlv_downstream_map_ipv4_t *lspping_tlv_downstream_map_ipv4; + const struct lspping_tlv_downstream_map_ipv4_unmb_t *lspping_tlv_downstream_map_ipv4_unmb; const struct lspping_tlv_downstream_map_ipv6_t *lspping_tlv_downstream_map_ipv6; + const struct lspping_tlv_downstream_map_ipv6_unmb_t *lspping_tlv_downstream_map_ipv6_unmb; const struct lspping_tlv_downstream_map_info_t *lspping_tlv_downstream_map_info; } tlv_ptr; @@ -483,14 +514,16 @@ lspping_print(netdissect_options *ndo, const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t *lspping_tlv_targetfec_subtlv_l3vpn_ipv4; const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t *lspping_tlv_targetfec_subtlv_l3vpn_ipv6; const struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t *lspping_tlv_targetfec_subtlv_l2vpn_endpt; - const struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_old_t *lspping_tlv_targetfec_subtlv_l2vpn_vcid_old; - const struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_t *lspping_tlv_targetfec_subtlv_l2vpn_vcid; + const struct lspping_tlv_targetfec_subtlv_fec_128_pw_old *lspping_tlv_targetfec_subtlv_l2vpn_vcid_old; + const struct lspping_tlv_targetfec_subtlv_fec_128_pw *lspping_tlv_targetfec_subtlv_l2vpn_vcid; const struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t *lspping_tlv_targetfec_subtlv_bgp_ipv4; const struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t *lspping_tlv_targetfec_subtlv_bgp_ipv6; } subtlv_ptr; tptr=pptr; lspping_com_header = (const struct lspping_common_header *)pptr; + if (len < sizeof(const struct lspping_common_header)) + goto tooshort; ND_TCHECK(*lspping_com_header); /* @@ -565,7 +598,10 @@ lspping_print(netdissect_options *ndo, tptr+=sizeof(const struct lspping_common_header); tlen-=sizeof(const struct lspping_common_header); - while(tlen>(int)sizeof(struct lspping_tlv_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)); @@ -574,15 +610,6 @@ lspping_print(netdissect_options *ndo, lspping_tlv_type=EXTRACT_16BITS(lspping_tlv_header->type); lspping_tlv_len=EXTRACT_16BITS(lspping_tlv_header->length); - /* some little sanity checking */ - if (lspping_tlv_type == 0 || lspping_tlv_len == 0) - return; - - if(lspping_tlv_len < 4) { - ND_PRINT((ndo, "\n\t ERROR: TLV %u bogus size %u",lspping_tlv_type,lspping_tlv_len)); - return; - } - ND_PRINT((ndo, "\n\t %s TLV (%u), length: %u", tok2str(lspping_tlv_values, "Unknown", @@ -590,19 +617,34 @@ lspping_print(netdissect_options *ndo, lspping_tlv_type, lspping_tlv_len)); + /* some little sanity checking */ + if (lspping_tlv_len == 0) { + tptr+=sizeof(struct lspping_tlv_header); + tlen-=sizeof(struct lspping_tlv_header); + continue; /* no value to dissect */ + } + tlv_tptr=tptr+sizeof(struct lspping_tlv_header); tlv_tlen=lspping_tlv_len; /* header not included -> no adjustment */ + /* Does the TLV go past the end of the packet? */ + if (tlen < lspping_tlv_len+sizeof(struct lspping_tlv_header)) + goto tooshort; /* did we capture enough for fully decoding the tlv ? */ - ND_TCHECK2(*tptr, lspping_tlv_len); + ND_TCHECK2(*tlv_tptr, lspping_tlv_len); tlv_hexdump=FALSE; switch(lspping_tlv_type) { case LSPPING_TLV_TARGET_FEC_STACK: - while(tlv_tlen>(int)sizeof(struct lspping_tlv_header)) { - + 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")); + tlv_hexdump = TRUE; + goto tlv_tooshort; + } /* did we capture enough for fully decoding the subtlv header ? */ - ND_TCHECK2(*tptr, sizeof(struct lspping_tlv_header)); + ND_TCHECK2(*tlv_tptr, sizeof(struct lspping_tlv_header)); subtlv_hexdump=FALSE; lspping_subtlv_header = (const struct lspping_tlv_header *)tlv_tptr; @@ -610,8 +652,15 @@ lspping_print(netdissect_options *ndo, lspping_subtlv_len=EXTRACT_16BITS(lspping_subtlv_header->length); subtlv_tptr=tlv_tptr+sizeof(struct lspping_tlv_header); - if (lspping_subtlv_len == 0) - break; + /* 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")); + tlv_hexdump = TRUE; + goto tlv_tooshort; + } + + /* Did we capture enough for fully decoding the subTLV? */ + ND_TCHECK2(*subtlv_tptr, lspping_subtlv_len); ND_PRINT((ndo, "\n\t %s subTLV (%u), length: %u", tok2str(lspping_tlvtargetfec_subtlv_values, @@ -623,132 +672,185 @@ lspping_print(netdissect_options *ndo, switch(lspping_subtlv_type) { case 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)); + /* Is the subTLV length correct? */ + if (lspping_subtlv_len != 5) { + ND_PRINT((ndo, "\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 = \ + (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)); + } break; -#ifdef INET6 case 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)); + /* Is the subTLV length correct? */ + if (lspping_subtlv_len != 17) { + ND_PRINT((ndo, "\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 = \ + (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)); + } break; -#endif case 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, sender-id %s", - ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix), - subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix_len, - ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->sender_id))); + /* Is the subTLV length correct? */ + if (lspping_subtlv_len != 5) { + ND_PRINT((ndo, "\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 = \ + (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)); + } break; -#ifdef INET6 case 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, sender-id %s", - ip6addr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix), - subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix_len, - ip6addr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->sender_id))); + /* Is the subTLV length correct? */ + if (lspping_subtlv_len != 17) { + ND_PRINT((ndo, "\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 = \ + (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)); + } break; -#endif case 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" \ - "\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))); + /* Is the subTLV length correct? */ + if (lspping_subtlv_len != 20) { + ND_PRINT((ndo, "\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 = \ + (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" \ + "\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))); + } break; -#ifdef INET6 case 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" \ - "\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))); + /* Is the subTLV length correct? */ + if (lspping_subtlv_len != 56) { + ND_PRINT((ndo, "\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 = \ + (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" \ + "\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))); + } break; -#endif case 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", - 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)); + /* Is the subTLV length correct? */ + if (lspping_subtlv_len != 13) { + ND_PRINT((ndo, "\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 = \ + (const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t *)subtlv_tptr; + ND_PRINT((ndo, "\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)); + } break; -#ifdef INET6 case 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", - 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)); + /* Is the subTLV length correct? */ + if (lspping_subtlv_len != 25) { + ND_PRINT((ndo, "\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 = \ + (const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t *)subtlv_tptr; + ND_PRINT((ndo, "\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)); + } break; -#endif case 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 CE-ID: %u, Receiver CE-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_ce_id), - EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->receiver_ce_id), - tok2str(l2vpn_encaps_values, - "unknown", - EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation)), - EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation))); - + /* Is the subTLV length correct? */ + if (lspping_subtlv_len != 14) { + ND_PRINT((ndo, "\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 = \ + (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" \ + "\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), + 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))); + } break; /* the old L2VPN VCID subTLV does not have support for the sender field */ - case LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID_OLD: - subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old = \ - (const struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_old_t *)subtlv_tptr; - ND_PRINT((ndo, "\n\t Remote PE: %s" \ - "\n\t VC-ID: 0x%08x, Encapsulation 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->vc_id), - tok2str(l2vpn_encaps_values, - "unknown", - EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->encapsulation)), - EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->encapsulation))); - + 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")); + subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ + } else { + 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" \ + "\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), + 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))); + } break; - case LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID: - subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid = \ - (const struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_t *)subtlv_tptr; - ND_PRINT((ndo, "\n\t Sender PE: %s, Remote PE: %s" \ - "\n\t VC-ID: 0x%08x, Encapsulation 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->vc_id), - tok2str(l2vpn_encaps_values, - "unknown", - EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->encapsulation)), - EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->encapsulation))); - + 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")); + subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ + } else { + 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" \ + "\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), + 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))); + } break; default: @@ -761,30 +863,58 @@ lspping_print(netdissect_options *ndo, "\n\t ", lspping_subtlv_len); + /* All subTLVs are aligned to four octet boundary */ + if (lspping_subtlv_len % 4) { + 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")); + return; + } + } tlv_tptr+=lspping_subtlv_len; tlv_tlen-=lspping_subtlv_len+sizeof(struct lspping_tlv_header); } break; 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")); + 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)); + + 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 , after we found the address-type - * lets recast the tlv_tptr and move on */ + * 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. */ - tlv_ptr.lspping_tlv_downstream_map_ipv4= \ - (const struct lspping_tlv_downstream_map_ipv4_t *)tlv_tptr; - tlv_ptr.lspping_tlv_downstream_map_ipv6= \ - (const struct lspping_tlv_downstream_map_ipv6_t *)tlv_tptr; ND_PRINT((ndo, "\n\t MTU: %u, Address-Type: %s (%u)", - EXTRACT_16BITS(tlv_ptr.lspping_tlv_downstream_map_ipv4->mtu), + EXTRACT_16BITS(tlv_ptr.lspping_tlv_downstream_map->mtu), tok2str(lspping_tlv_downstream_addr_values, "unknown", - tlv_ptr.lspping_tlv_downstream_map_ipv4->address_type), - tlv_ptr.lspping_tlv_downstream_map_ipv4->address_type)); + tlv_ptr.lspping_tlv_downstream_map->address_type), + tlv_ptr.lspping_tlv_downstream_map->address_type)); - switch(tlv_ptr.lspping_tlv_downstream_map_ipv4->address_type) { + switch(tlv_ptr.lspping_tlv_downstream_map->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")); + 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)); + + 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" \ "\n\t Downstream Interface IP: %s", ipaddr_string(ndo, tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_ip), @@ -792,8 +922,37 @@ lspping_print(netdissect_options *ndo, tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_t); tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_t); break; -#ifdef INET6 - case LSPPING_AFI_IPV6: + 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")); + 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)); + + 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" \ + "\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))); + 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")); + 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)); + + 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" \ "\n\t Downstream Interface IP: %s", ip6addr_string(ndo, tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_ip), @@ -801,14 +960,24 @@ lspping_print(netdissect_options *ndo, tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv6_t); tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv6_t); break; -#endif - case LSPPING_AFI_UNMB: + 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")); + 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)); + + 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" \ "\n\t Downstream Interface Index: 0x%08x", - ipaddr_string(ndo, tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_ip), - EXTRACT_32BITS(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); + 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))); + tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t); + tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t); break; default: @@ -816,37 +985,55 @@ lspping_print(netdissect_options *ndo, break; } + /* 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")); + 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)); + 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 */ - tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_info_t); tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_info_t); /* FIXME print downstream labels */ - tlv_hexdump=TRUE; /* dump the TLV until code complete */ break; case LSPPING_TLV_BFD_DISCRIMINATOR: - tptr += sizeof(struct lspping_tlv_header); - ND_TCHECK2(*tptr, LSPPING_TLV_BFD_DISCRIMINATOR_LEN); - ND_PRINT((ndo, "\n\t BFD Discriminator 0x%08x", EXTRACT_32BITS(tptr))); + if (tlv_tlen < LSPPING_TLV_BFD_DISCRIMINATOR_LEN) { + ND_PRINT((ndo, "\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))); + } break; case LSPPING_TLV_VENDOR_ENTERPRISE: { uint32_t vendor_id; - ND_TCHECK2(*tptr, LSPPING_TLV_VENDOR_ENTERPRISE_LEN); - vendor_id = EXTRACT_32BITS(tlv_tptr); - ND_PRINT((ndo, "\n\t Vendor: %s (0x%04x)", - tok2str(smi_values, "Unknown", vendor_id), - vendor_id)); + if (tlv_tlen < LSPPING_TLV_VENDOR_ENTERPRISE_LEN) { + ND_PRINT((ndo, "\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)", + tok2str(smi_values, "Unknown", vendor_id), + vendor_id)); + } } break; @@ -864,6 +1051,7 @@ lspping_print(netdissect_options *ndo, break; } /* do we want to see an additionally tlv hexdump ? */ + tlv_tooshort: if (ndo->ndo_vflag > 1 || tlv_hexdump==TRUE) print_unknown_data(ndo, tptr+sizeof(struct lspping_tlv_header), "\n\t ", lspping_tlv_len); @@ -872,14 +1060,21 @@ lspping_print(netdissect_options *ndo, /* All TLVs are aligned to four octet boundary */ if (lspping_tlv_len % 4) { lspping_tlv_len += (4 - lspping_tlv_len % 4); + /* Does the TLV, including padding, go past the end of the packet? */ + if (tlen < lspping_tlv_len+sizeof(struct lspping_tlv_header)) + goto tooshort; } tptr+=lspping_tlv_len+sizeof(struct lspping_tlv_header); tlen-=lspping_tlv_len+sizeof(struct lspping_tlv_header); } return; +tooshort: + ND_PRINT((ndo, "\n\t\t packet is too short")); + return; trunc: ND_PRINT((ndo, "\n\t\t packet exceeded snapshot")); + return; } /* * Local Variables: diff --git a/contrib/tcpdump/print-lwapp.c b/contrib/tcpdump/print-lwapp.c index 5b8683f..bab3219 100644 --- a/contrib/tcpdump/print-lwapp.c +++ b/contrib/tcpdump/print-lwapp.c @@ -12,19 +12,20 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * Support for the Light Weight Access Point Protocol as per RFC 5412 - * * Original code by Carles Kishimoto */ -#define NETDISSECT_REWORKED +/* \summary: Light Weight Access Point Protocol (LWAPP) printer */ + +/* specification: RFC 5412 */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "addrtoname.h" diff --git a/contrib/tcpdump/print-lwres.c b/contrib/tcpdump/print-lwres.c index d78c9a9..ae35280 100644 --- a/contrib/tcpdump/print-lwres.c +++ b/contrib/tcpdump/print-lwres.c @@ -27,21 +27,22 @@ * SUCH DAMAGE. */ -#define NETDISSECT_REWORKED +/* \summary: BIND9 Lightweight Resolver protocol printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include "nameser.h" #include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" -#include "extract.h" /* must come after interface.h */ +#include "extract.h" /* BIND9 lib/lwres/include/lwres */ typedef uint32_t lwres_uint32_t; @@ -250,7 +251,7 @@ lwres_printbinlen(netdissect_options *ndo, static int lwres_printaddr(netdissect_options *ndo, - lwres_addr_t *ap) + const lwres_addr_t *ap) { uint16_t l; const char *p; @@ -269,14 +270,12 @@ lwres_printaddr(netdissect_options *ndo, ND_PRINT((ndo, " %s", ipaddr_string(ndo, p))); p += sizeof(struct in_addr); break; -#ifdef INET6 case 2: /* IPv6 */ if (l < 16) return -1; ND_PRINT((ndo, " %s", ip6addr_string(ndo, p))); p += sizeof(struct in6_addr); break; -#endif default: ND_PRINT((ndo, " %u/", EXTRACT_32BITS(&ap->family))); for (i = 0; i < l; i++) @@ -343,9 +342,9 @@ lwres_print(netdissect_options *ndo, /* * queries */ - lwres_gabnrequest_t *gabn; - lwres_gnbarequest_t *gnba; - lwres_grbnrequest_t *grbn; + const lwres_gabnrequest_t *gabn; + const lwres_gnbarequest_t *gnba; + const lwres_grbnrequest_t *grbn; uint32_t l; gabn = NULL; @@ -356,7 +355,7 @@ lwres_print(netdissect_options *ndo, case LWRES_OPCODE_NOOP: break; case LWRES_OPCODE_GETADDRSBYNAME: - gabn = (lwres_gabnrequest_t *)(np + 1); + gabn = (const lwres_gabnrequest_t *)(np + 1); ND_TCHECK(gabn->namelen); /* XXX gabn points to packed struct */ s = (const char *)&gabn->namelen + @@ -390,7 +389,7 @@ lwres_print(netdissect_options *ndo, s += advance; break; case LWRES_OPCODE_GETNAMEBYADDR: - gnba = (lwres_gnbarequest_t *)(np + 1); + gnba = (const lwres_gnbarequest_t *)(np + 1); ND_TCHECK(gnba->addr); /* BIND910: not used */ @@ -408,7 +407,7 @@ lwres_print(netdissect_options *ndo, break; case LWRES_OPCODE_GETRDATABYNAME: /* XXX no trace, not tested */ - grbn = (lwres_grbnrequest_t *)(np + 1); + grbn = (const lwres_grbnrequest_t *)(np + 1); ND_TCHECK(grbn->namelen); /* BIND910: not used */ @@ -442,9 +441,9 @@ lwres_print(netdissect_options *ndo, /* * responses */ - lwres_gabnresponse_t *gabn; - lwres_gnbaresponse_t *gnba; - lwres_grbnresponse_t *grbn; + const lwres_gabnresponse_t *gabn; + const lwres_gnbaresponse_t *gnba; + const lwres_grbnresponse_t *grbn; uint32_t l, na; uint32_t i; @@ -456,7 +455,7 @@ lwres_print(netdissect_options *ndo, case LWRES_OPCODE_NOOP: break; case LWRES_OPCODE_GETADDRSBYNAME: - gabn = (lwres_gabnresponse_t *)(np + 1); + gabn = (const lwres_gabnresponse_t *)(np + 1); ND_TCHECK(gabn->realnamelen); /* XXX gabn points to packed struct */ s = (const char *)&gabn->realnamelen + @@ -489,14 +488,14 @@ lwres_print(netdissect_options *ndo, /* addrs */ na = EXTRACT_16BITS(&gabn->naddrs); for (i = 0; i < na; i++) { - advance = lwres_printaddr(ndo, (lwres_addr_t *)s); + advance = lwres_printaddr(ndo, (const lwres_addr_t *)s); if (advance < 0) goto trunc; s += advance; } break; case LWRES_OPCODE_GETNAMEBYADDR: - gnba = (lwres_gnbaresponse_t *)(np + 1); + gnba = (const lwres_gnbaresponse_t *)(np + 1); ND_TCHECK(gnba->realnamelen); /* XXX gnba points to packed struct */ s = (const char *)&gnba->realnamelen + @@ -527,7 +526,7 @@ lwres_print(netdissect_options *ndo, break; case LWRES_OPCODE_GETRDATABYNAME: /* XXX no trace, not tested */ - grbn = (lwres_grbnresponse_t *)(np + 1); + grbn = (const lwres_grbnresponse_t *)(np + 1); ND_TCHECK(grbn->nsigs); /* BIND910: not used */ @@ -543,7 +542,7 @@ lwres_print(netdissect_options *ndo, EXTRACT_16BITS(&grbn->rdclass)))); } ND_PRINT((ndo, " TTL ")); - relts_print(ndo, EXTRACT_32BITS(&grbn->ttl)); + unsigned_relts_print(ndo, EXTRACT_32BITS(&grbn->ttl)); ND_PRINT((ndo, " %u/%u", EXTRACT_16BITS(&grbn->nrdatas), EXTRACT_16BITS(&grbn->nsigs))); diff --git a/contrib/tcpdump/print-m3ua.c b/contrib/tcpdump/print-m3ua.c index 33f8777..1f974b2 100644 --- a/contrib/tcpdump/print-m3ua.c +++ b/contrib/tcpdump/print-m3ua.c @@ -22,20 +22,20 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#define NETDISSECT_REWORKED +/* \summary: Message Transfer Part 3 (MTP3) User Adaptation Layer (M3UA) printer */ + +/* RFC 4666 */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" static const char tstr[] = " [|m3ua]"; -static const char cstr[] = " (corrupt)"; - -/* RFC 4666 */ #define M3UA_REL_1_0 1 @@ -218,7 +218,7 @@ tag_value_print(netdissect_options *ndo, case M3UA_PARAM_CORR_ID: /* buf and size don't include the header */ if (size < 4) - goto corrupt; + goto invalid; ND_TCHECK2(*buf, size); ND_PRINT((ndo, "0x%08x", EXTRACT_32BITS(buf))); break; @@ -229,8 +229,8 @@ tag_value_print(netdissect_options *ndo, } return; -corrupt: - ND_PRINT((ndo, "%s", cstr)); +invalid: + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*buf, size); return; trunc: @@ -259,7 +259,7 @@ m3ua_tags_print(netdissect_options *ndo, while (p < buf + size) { if (p + sizeof(struct m3ua_param_header) > buf + size) - goto corrupt; + goto invalid; ND_TCHECK2(*p, sizeof(struct m3ua_param_header)); /* Parameter Tag */ hdr_tag = EXTRACT_16BITS(p); @@ -267,7 +267,7 @@ m3ua_tags_print(netdissect_options *ndo, /* Parameter Length */ hdr_len = EXTRACT_16BITS(p + 2); if (hdr_len < sizeof(struct m3ua_param_header)) - goto corrupt; + goto invalid; /* Parameter Value */ align = (p + hdr_len - buf) % 4; align = align ? 4 - align : 0; @@ -277,8 +277,8 @@ m3ua_tags_print(netdissect_options *ndo, } return; -corrupt: - ND_PRINT((ndo, "%s", cstr)); +invalid: + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*buf, size); return; trunc: @@ -305,7 +305,7 @@ m3ua_print(netdissect_options *ndo, /* size includes the header */ if (size < sizeof(struct m3ua_common_header)) - goto corrupt; + goto invalid; ND_TCHECK(*hdr); if (hdr->v != M3UA_REL_1_0) return; @@ -329,8 +329,8 @@ m3ua_print(netdissect_options *ndo, m3ua_tags_print(ndo, buf + sizeof(struct m3ua_common_header), EXTRACT_32BITS(&hdr->len) - sizeof(struct m3ua_common_header)); return; -corrupt: - ND_PRINT((ndo, "%s", cstr)); +invalid: + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*buf, size); return; trunc: diff --git a/contrib/tcpdump/print-medsa.c b/contrib/tcpdump/print-medsa.c new file mode 100644 index 0000000..4895fd9 --- /dev/null +++ b/contrib/tcpdump/print-medsa.c @@ -0,0 +1,196 @@ +/* + * 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 df412ee..6d31648 100644 --- a/contrib/tcpdump/print-mobile.c +++ b/contrib/tcpdump/print-mobile.c @@ -36,16 +36,17 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#define NETDISSECT_REWORKED +/* \summary: IPv4 mobility printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" -#include "extract.h" /* must come after interface.h */ +#include "extract.h" #define MOBILE_SIZE (8) @@ -94,7 +95,7 @@ mobile_print(netdissect_options *ndo, const u_char *bp, u_int length) ND_PRINT((ndo, "> %s ", ipaddr_string(ndo, &mob->odst))); ND_PRINT((ndo, "(oproto=%d)", proto>>8)); } - vec[0].ptr = (const uint8_t *)(void *)mob; + 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)); diff --git a/contrib/tcpdump/print-mobility.c b/contrib/tcpdump/print-mobility.c index b6fa61e..71cc85b 100644 --- a/contrib/tcpdump/print-mobility.c +++ b/contrib/tcpdump/print-mobility.c @@ -27,18 +27,20 @@ * SUCH DAMAGE. */ -#define NETDISSECT_REWORKED +/* \summary: IPv6 mobility printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#ifdef INET6 -#include +#include #include "ip6.h" -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" -#include "extract.h" /* must come after interface.h */ +#include "extract.h" + +static const char tstr[] = "[|MOBILITY]"; /* Mobility header */ struct ip6_mobility { @@ -71,6 +73,18 @@ struct ip6_mobility { #define IP6M_BINDING_ERROR 7 /* Binding Error */ #define IP6M_MAX 7 +static const struct tok ip6m_str[] = { + { IP6M_BINDING_REQUEST, "BRR" }, + { IP6M_HOME_TEST_INIT, "HoTI" }, + { IP6M_CAREOF_TEST_INIT, "CoTI" }, + { IP6M_HOME_TEST, "HoT" }, + { IP6M_CAREOF_TEST, "CoT" }, + { IP6M_BINDING_UPDATE, "BU" }, + { IP6M_BINDING_ACK, "BA" }, + { IP6M_BINDING_ERROR, "BE" }, + { 0, NULL } +}; + static const unsigned ip6m_hdrlen[IP6M_MAX + 1] = { IP6M_MINLEN, /* IP6M_BINDING_REQUEST */ IP6M_MINLEN + 8, /* IP6M_HOME_TEST_INIT */ @@ -82,11 +96,6 @@ static const unsigned ip6m_hdrlen[IP6M_MAX + 1] = { IP6M_MINLEN + 16, /* IP6M_BINDING_ERROR */ }; -/* XXX: unused */ -#define IP6MOPT_BU_MINLEN 10 -#define IP6MOPT_BA_MINLEN 13 -#define IP6MOPT_BR_MINLEN 2 - /* Mobility Header Options */ #define IP6MOPT_MINLEN 2 #define IP6MOPT_PAD1 0x0 /* Pad1 */ @@ -100,7 +109,7 @@ static const unsigned ip6m_hdrlen[IP6M_MAX + 1] = { #define IP6MOPT_AUTH 0x5 /* Binding Authorization Data */ #define IP6MOPT_AUTH_MINLEN 12 -static void +static int mobility_opt_print(netdissect_options *ndo, const u_char *bp, const unsigned len) { @@ -174,10 +183,10 @@ mobility_opt_print(netdissect_options *ndo, break; } } - return; + return 0; trunc: - ND_PRINT((ndo, "[trunc] ")); + return 1; } /* @@ -192,7 +201,7 @@ mobility_print(netdissect_options *ndo, unsigned mhlen, hlen; uint8_t type; - mh = (struct ip6_mobility *)bp; + mh = (const struct ip6_mobility *)bp; /* 'ep' points to the end of available data. */ ep = ndo->ndo_snapend; @@ -223,17 +232,15 @@ mobility_print(netdissect_options *ndo, ND_PRINT((ndo, "(header length %u is too small for type %u)", mhlen, type)); goto trunc; } + ND_PRINT((ndo, "mobility: %s", tok2str(ip6m_str, "type-#%u", type))); switch (type) { case IP6M_BINDING_REQUEST: - ND_PRINT((ndo, "mobility: BRR")); hlen = IP6M_MINLEN; break; case IP6M_HOME_TEST_INIT: case IP6M_CAREOF_TEST_INIT: - ND_PRINT((ndo, "mobility: %soTI", - type == IP6M_HOME_TEST_INIT ? "H" : "C")); hlen = IP6M_MINLEN; - if (ndo->ndo_vflag) { + if (ndo->ndo_vflag) { ND_TCHECK2(*mh, hlen + 8); ND_PRINT((ndo, " %s Init Cookie=%08x:%08x", type == IP6M_HOME_TEST_INIT ? "Home" : "Care-of", @@ -244,12 +251,10 @@ mobility_print(netdissect_options *ndo, break; case IP6M_HOME_TEST: case IP6M_CAREOF_TEST: - ND_PRINT((ndo, "mobility: %soT", - type == IP6M_HOME_TEST ? "H" : "C")); ND_TCHECK(mh->ip6m_data16[0]); ND_PRINT((ndo, " nonce id=0x%x", EXTRACT_16BITS(&mh->ip6m_data16[0]))); hlen = IP6M_MINLEN; - if (ndo->ndo_vflag) { + if (ndo->ndo_vflag) { ND_TCHECK2(*mh, hlen + 8); ND_PRINT((ndo, " %s Init Cookie=%08x:%08x", type == IP6M_HOME_TEST ? "Home" : "Care-of", @@ -257,7 +262,7 @@ mobility_print(netdissect_options *ndo, EXTRACT_32BITS(&bp[hlen + 4]))); } hlen += 8; - if (ndo->ndo_vflag) { + if (ndo->ndo_vflag) { ND_TCHECK2(*mh, hlen + 8); ND_PRINT((ndo, " %s Keygen Token=%08x:%08x", type == IP6M_HOME_TEST ? "Home" : "Care-of", @@ -267,7 +272,6 @@ mobility_print(netdissect_options *ndo, hlen += 8; break; case IP6M_BINDING_UPDATE: - ND_PRINT((ndo, "mobility: BU")); ND_TCHECK(mh->ip6m_data16[0]); ND_PRINT((ndo, " seq#=%u", EXTRACT_16BITS(&mh->ip6m_data16[0]))); hlen = IP6M_MINLEN; @@ -292,7 +296,6 @@ mobility_print(netdissect_options *ndo, hlen += 2; break; case IP6M_BINDING_ACK: - ND_PRINT((ndo, "mobility: BA")); ND_TCHECK(mh->ip6m_data8[0]); ND_PRINT((ndo, " status=%u", mh->ip6m_data8[0])); if (mh->ip6m_data8[1] & 0x80) @@ -308,7 +311,6 @@ mobility_print(netdissect_options *ndo, hlen += 2; break; case IP6M_BINDING_ERROR: - ND_PRINT((ndo, "mobility: BE")); ND_TCHECK(mh->ip6m_data8[0]); ND_PRINT((ndo, " status=%u", mh->ip6m_data8[0])); /* Reserved */ @@ -318,17 +320,17 @@ mobility_print(netdissect_options *ndo, hlen += 16; break; default: - ND_PRINT((ndo, "mobility: type-#%u len=%u", type, mh->ip6m_len)); + ND_PRINT((ndo, " len=%u", mh->ip6m_len)); return(mhlen); break; } - if (ndo->ndo_vflag) - mobility_opt_print(ndo, &bp[hlen], mhlen - hlen); + if (ndo->ndo_vflag) + if (mobility_opt_print(ndo, &bp[hlen], mhlen - hlen)) + goto trunc;; return(mhlen); trunc: - ND_PRINT((ndo, "[|MOBILITY]")); + ND_PRINT((ndo, "%s", tstr)); return(mhlen); } -#endif /* INET6 */ diff --git a/contrib/tcpdump/print-mpcp.c b/contrib/tcpdump/print-mpcp.c index 9da3582..1b9a5d7 100644 --- a/contrib/tcpdump/print-mpcp.c +++ b/contrib/tcpdump/print-mpcp.c @@ -12,19 +12,18 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * support for the IEEE MPCP protocol as per 802.3ah - * * Original code by Hannes Gredler (hannes@juniper.net) */ -#define NETDISSECT_REWORKED +/* \summary: IEEE 802.3ah Multi-Point Control Protocol (MPCP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #define MPCP_TIMESTAMP_LEN 4 diff --git a/contrib/tcpdump/print-mpls.c b/contrib/tcpdump/print-mpls.c index bc34d50..ba42233 100644 --- a/contrib/tcpdump/print-mpls.c +++ b/contrib/tcpdump/print-mpls.c @@ -26,15 +26,16 @@ * SUCH DAMAGE. */ -#define NETDISSECT_REWORKED +/* \summary: Multi-Protocol Label Switching (MPLS) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" -#include "extract.h" /* must come after interface.h */ +#include "netdissect.h" +#include "extract.h" #include "mpls.h" static const char *mpls_labelname[] = { @@ -67,6 +68,10 @@ mpls_print(netdissect_options *ndo, const u_char *bp, u_int length) ND_PRINT((ndo, "MPLS")); 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", (label_stack_depth && ndo->ndo_vflag) ? "\n\t" : " ", @@ -81,6 +86,7 @@ mpls_print(netdissect_options *ndo, const u_char *bp, u_int length) ND_PRINT((ndo, ", ttl %u)", MPLS_TTL(label_entry))); p += sizeof(label_entry); + length -= sizeof(label_entry); } while (!MPLS_STACK(label_entry)); /* @@ -123,6 +129,11 @@ 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: @@ -175,22 +186,22 @@ mpls_print(netdissect_options *ndo, const u_char *bp, u_int length) */ if (pt == PT_UNKNOWN) { if (!ndo->ndo_suppress_default_print) - ND_DEFAULTPRINT(p, length - (p - bp)); + ND_DEFAULTPRINT(p, length); return; } ND_PRINT((ndo, ndo->ndo_vflag ? "\n\t" : " ")); switch (pt) { case PT_IPV4: - ip_print(ndo, p, length - (p - bp)); + ip_print(ndo, p, length); break; case PT_IPV6: - ip6_print(ndo, p, length - (p - bp)); + ip6_print(ndo, p, length); break; case PT_OSI: - isoclns_print(ndo, p, length - (p - bp), length - (p - bp)); + isoclns_print(ndo, p, length, length); break; default: diff --git a/contrib/tcpdump/print-mptcp.c b/contrib/tcpdump/print-mptcp.c index f85f1d2..e757ea4 100644 --- a/contrib/tcpdump/print-mptcp.c +++ b/contrib/tcpdump/print-mptcp.c @@ -32,14 +32,17 @@ * SUCH DAMAGE. */ -#define NETDISSECT_REWORKED +/* \summary: Multipath TCP (MPTCP) printer */ + +/* specification: RFC 6824 */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "addrtoname.h" @@ -173,7 +176,7 @@ static int mp_capable_print(netdissect_options *ndo, const u_char *opt, u_int opt_len, u_char flags) { - struct mp_capable *mpc = (struct mp_capable *) opt; + const struct mp_capable *mpc = (const struct mp_capable *) opt; if (!(opt_len == 12 && flags & TH_SYN) && !(opt_len == 20 && (flags & (TH_SYN | TH_ACK)) == TH_ACK)) @@ -197,7 +200,7 @@ static int mp_join_print(netdissect_options *ndo, const u_char *opt, u_int opt_len, u_char flags) { - struct mp_join *mpj = (struct mp_join *) opt; + const struct mp_join *mpj = (const struct mp_join *) opt; if (!(opt_len == 12 && flags & TH_SYN) && !(opt_len == 16 && (flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) && @@ -233,7 +236,7 @@ mp_join_print(netdissect_options *ndo, return 1; } -static u_int mp_dss_len(struct mp_dss *m, int csum) +static u_int mp_dss_len(const struct mp_dss *m, int csum) { u_int len; @@ -265,7 +268,7 @@ static int mp_dss_print(netdissect_options *ndo, const u_char *opt, u_int opt_len, u_char flags) { - struct mp_dss *mdss = (struct mp_dss *) opt; + const struct mp_dss *mdss = (const struct mp_dss *) opt; if ((opt_len != mp_dss_len(mdss, 1) && opt_len != mp_dss_len(mdss, 0)) || flags & TH_SYN) @@ -310,7 +313,7 @@ static int add_addr_print(netdissect_options *ndo, const u_char *opt, u_int opt_len, u_char flags _U_) { - struct mp_add_addr *add_addr = (struct mp_add_addr *) opt; + 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) && @@ -325,9 +328,7 @@ add_addr_print(netdissect_options *ndo, ND_PRINT((ndo, ":%u", EXTRACT_16BITS(add_addr->u.v4.port))); break; case 6: -#ifdef INET6 ND_PRINT((ndo, " %s", ip6addr_string(ndo, add_addr->u.v6.addr))); -#endif if (opt_len == 22) ND_PRINT((ndo, ":%u", EXTRACT_16BITS(add_addr->u.v6.port))); break; @@ -342,8 +343,8 @@ static int remove_addr_print(netdissect_options *ndo, const u_char *opt, u_int opt_len, u_char flags _U_) { - struct mp_remove_addr *remove_addr = (struct mp_remove_addr *) opt; - uint8_t *addr_id = &remove_addr->addrs_id; + const struct mp_remove_addr *remove_addr = (const struct mp_remove_addr *) opt; + const uint8_t *addr_id = &remove_addr->addrs_id; if (opt_len < 4) return 0; @@ -359,7 +360,7 @@ static int mp_prio_print(netdissect_options *ndo, const u_char *opt, u_int opt_len, u_char flags _U_) { - struct mp_prio *mpp = (struct mp_prio *) opt; + const struct mp_prio *mpp = (const struct mp_prio *) opt; if (opt_len != 3 && opt_len != 4) return 0; @@ -415,13 +416,13 @@ int mptcp_print(netdissect_options *ndo, const u_char *cp, u_int len, u_char flags) { - struct mptcp_option *opt; + const struct mptcp_option *opt; u_int subtype; if (len < 3) return 0; - opt = (struct mptcp_option *) cp; + opt = (const struct mptcp_option *) cp; subtype = min(MPTCP_OPT_SUBTYPE(opt->sub_etc), MPTCP_SUB_FCLOSE + 1); ND_PRINT((ndo, " %s", mptcp_options[subtype].name)); diff --git a/contrib/tcpdump/print-msdp.c b/contrib/tcpdump/print-msdp.c index fb802b5..50bafb0 100644 --- a/contrib/tcpdump/print-msdp.c +++ b/contrib/tcpdump/print-msdp.c @@ -16,14 +16,15 @@ * FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: Multicast Source Discovery Protocol (MSDP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" diff --git a/contrib/tcpdump/print-msnlb.c b/contrib/tcpdump/print-msnlb.c index fcd0006..5264da4 100644 --- a/contrib/tcpdump/print-msnlb.c +++ b/contrib/tcpdump/print-msnlb.c @@ -26,14 +26,15 @@ * SUCH DAMAGE. */ -#define NETDISSECT_REWORKED +/* \summary: MS Network Load Balancing's (NLB) heartbeat printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" @@ -51,7 +52,7 @@ msnlb_print(netdissect_options *ndo, const u_char *bp) { const struct msnlb_heartbeat_pkt *hb; - hb = (struct msnlb_heartbeat_pkt *)bp; + hb = (const struct msnlb_heartbeat_pkt *)bp; ND_TCHECK(*hb); ND_PRINT((ndo, "MS NLB heartbeat, host priority: %u,", diff --git a/contrib/tcpdump/print-nflog.c b/contrib/tcpdump/print-nflog.c index 95da4cb..41cbf78 100644 --- a/contrib/tcpdump/print-nflog.c +++ b/contrib/tcpdump/print-nflog.c @@ -25,23 +25,24 @@ * DAMAGE. */ -#define NETDISSECT_REWORKED +/* \summary: DLT_NFLOG printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #if defined(DLT_NFLOG) && defined(HAVE_PCAP_NFLOG_H) #include static const struct tok nflog_values[] = { { AF_INET, "IPv4" }, -#ifdef INET6 +#ifdef AF_INET6 { AF_INET6, "IPv6" }, -#endif /*INET6*/ +#endif /*AF_INET6*/ { 0, NULL } }; @@ -81,7 +82,7 @@ nflog_if_print(netdissect_options *ndo, return h_size; } - if (!(hdr->nflog_version) == 0) { + if (hdr->nflog_version != 0) { ND_PRINT((ndo, "version %u (unknown)", hdr->nflog_version)); return h_size; } diff --git a/contrib/tcpdump/print-nfs.c b/contrib/tcpdump/print-nfs.c index d08fd95..a71e068 100644 --- a/contrib/tcpdump/print-nfs.c +++ b/contrib/tcpdump/print-nfs.c @@ -17,21 +17,20 @@ * 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. - * - * $FreeBSD$ */ -#define NETDISSECT_REWORKED +/* \summary: Network File System (NFS) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" @@ -39,9 +38,7 @@ #include "nfsfh.h" #include "ip.h" -#ifdef INET6 #include "ip6.h" -#endif #include "rpc_auth.h" #include "rpc_msg.h" @@ -57,7 +54,7 @@ static const uint32_t *parse_post_op_attr(netdissect_options *, const uint32_t * /* * Mapping of old NFS Version 2 RPC numbers to generic numbers. */ -uint32_t nfsv3_procid[NFS_NPROCS] = { +static uint32_t nfsv3_procid[NFS_NPROCS] = { NFSPROC_NULL, NFSPROC_GETATTR, NFSPROC_SETATTR, @@ -205,33 +202,24 @@ static void print_nfsaddr(netdissect_options *ndo, const u_char *bp, const char *s, const char *d) { - struct ip *ip; -#ifdef INET6 - struct ip6_hdr *ip6; + const struct ip *ip; + const struct ip6_hdr *ip6; char srcaddr[INET6_ADDRSTRLEN], dstaddr[INET6_ADDRSTRLEN]; -#else -#ifndef INET_ADDRSTRLEN -#define INET_ADDRSTRLEN 16 -#endif - char srcaddr[INET_ADDRSTRLEN], dstaddr[INET_ADDRSTRLEN]; -#endif srcaddr[0] = dstaddr[0] = '\0'; - switch (IP_V((struct ip *)bp)) { + switch (IP_V((const struct ip *)bp)) { case 4: - ip = (struct ip *)bp; + 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)); break; -#ifdef INET6 case 6: - ip6 = (struct ip6_hdr *)bp; + ip6 = (const struct ip6_hdr *)bp; strlcpy(srcaddr, ip6addr_string(ndo, &ip6->ip6_src), sizeof(srcaddr)); strlcpy(dstaddr, ip6addr_string(ndo, &ip6->ip6_dst), sizeof(dstaddr)); break; -#endif default: strlcpy(srcaddr, "?", sizeof(srcaddr)); strlcpy(dstaddr, "?", sizeof(dstaddr)); @@ -436,7 +424,7 @@ parsereq(netdissect_options *ndo, /* * find the start of the req data (if we captured it) */ - dp = (uint32_t *)&rp->rm_call.cb_cred; + dp = (const uint32_t *)&rp->rm_call.cb_cred; ND_TCHECK(dp[1]); len = EXTRACT_32BITS(&dp[1]); if (len < length) { @@ -498,7 +486,7 @@ parsefn(netdissect_options *ndo, ND_TCHECK2(*dp, ((len + 3) & ~3)); - cp = (u_char *)dp; + 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, "\"")); @@ -665,12 +653,12 @@ nfsreq_print_noaddr(netdissect_options *ndo, break; case NFSPROC_SYMLINK: - if ((dp = parsereq(ndo, rp, length)) != 0 && - (dp = parsefhn(ndo, dp, v3)) != 0) { + if ((dp = parsereq(ndo, rp, length)) != NULL && + (dp = parsefhn(ndo, dp, v3)) != NULL) { ND_PRINT((ndo, " ->")); - if (v3 && (dp = parse_sattr3(ndo, dp, &sa3)) == 0) + if (v3 && (dp = parse_sattr3(ndo, dp, &sa3)) == NULL) break; - if (parsefn(ndo, dp) == 0) + if (parsefn(ndo, dp) == NULL) break; if (v3 && ndo->ndo_vflag) print_sattr3(ndo, &sa3, ndo->ndo_vflag); @@ -679,12 +667,12 @@ nfsreq_print_noaddr(netdissect_options *ndo, break; case NFSPROC_MKNOD: - if ((dp = parsereq(ndo, rp, length)) != 0 && - (dp = parsefhn(ndo, dp, v3)) != 0) { + 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)) == 0) + 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)) { @@ -853,13 +841,8 @@ nfs_printfh(netdissect_options *ndo, struct xid_map_entry { uint32_t xid; /* transaction ID (net order) */ int ipver; /* IP version (4 or 6) */ -#ifdef INET6 struct in6_addr client; /* client IP address (net order) */ struct in6_addr server; /* server IP address (net order) */ -#else - struct in_addr client; /* client IP address (net order) */ - struct in_addr server; /* server IP address (net order) */ -#endif uint32_t proc; /* call proc number (host order) */ uint32_t vers; /* program version (host order) */ }; @@ -872,32 +855,28 @@ struct xid_map_entry { #define XIDMAPSIZE 64 -struct xid_map_entry xid_map[XIDMAPSIZE]; +static struct xid_map_entry xid_map[XIDMAPSIZE]; -int xid_map_next = 0; -int xid_map_hint = 0; +static int xid_map_next = 0; +static int xid_map_hint = 0; static int xid_map_enter(netdissect_options *ndo, const struct sunrpc_msg *rp, const u_char *bp) { - struct ip *ip = NULL; -#ifdef INET6 - struct ip6_hdr *ip6 = NULL; -#endif + const struct ip *ip = NULL; + const struct ip6_hdr *ip6 = NULL; struct xid_map_entry *xmep; if (!ND_TTEST(rp->rm_call.cb_vers)) return (0); - switch (IP_V((struct ip *)bp)) { + switch (IP_V((const struct ip *)bp)) { case 4: - ip = (struct ip *)bp; + ip = (const struct ip *)bp; break; -#ifdef INET6 case 6: - ip6 = (struct ip6_hdr *)bp; + ip6 = (const struct ip6_hdr *)bp; break; -#endif default: return (1); } @@ -913,13 +892,11 @@ xid_map_enter(netdissect_options *ndo, UNALIGNED_MEMCPY(&xmep->client, &ip->ip_src, sizeof(ip->ip_src)); UNALIGNED_MEMCPY(&xmep->server, &ip->ip_dst, sizeof(ip->ip_dst)); } -#ifdef INET6 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)); } -#endif xmep->proc = EXTRACT_32BITS(&rp->rm_call.cb_proc); xmep->vers = EXTRACT_32BITS(&rp->rm_call.cb_vers); return (1); @@ -935,13 +912,12 @@ xid_map_find(const struct sunrpc_msg *rp, const u_char *bp, uint32_t *proc, { int i; struct xid_map_entry *xmep; - uint32_t xid = rp->rm_xid; - struct ip *ip = (struct ip *)bp; -#ifdef INET6 - struct ip6_hdr *ip6 = (struct ip6_hdr *)bp; -#endif + uint32_t xid; + const struct ip *ip = (const struct ip *)bp; + const struct ip6_hdr *ip6 = (const struct ip6_hdr *)bp; int cmp; + UNALIGNED_MEMCPY(&xid, &rp->rm_xid, sizeof(xmep->xid)); /* Start searching from where we last left off */ i = xid_map_hint; do { @@ -958,7 +934,6 @@ xid_map_find(const struct sunrpc_msg *rp, const u_char *bp, uint32_t *proc, cmp = 0; } break; -#ifdef INET6 case 6: if (UNALIGNED_MEMCMP(&ip6->ip6_src, &xmep->server, sizeof(ip6->ip6_src)) != 0 || @@ -967,7 +942,6 @@ xid_map_find(const struct sunrpc_msg *rp, const u_char *bp, uint32_t *proc, cmp = 0; } break; -#endif default: cmp = 0; break; @@ -1041,7 +1015,7 @@ parserep(netdissect_options *ndo, } /* successful return */ ND_TCHECK2(*dp, sizeof(astat)); - return ((uint32_t *) (sizeof(astat) + ((char *)dp))); + return ((const uint32_t *) (sizeof(astat) + ((const char *)dp))); trunc: return (0); } @@ -1086,7 +1060,7 @@ parsefattr(netdissect_options *ndo, if (v3) { ND_TCHECK(fap->fa3_size); ND_PRINT((ndo, " sz %" PRIu64, - EXTRACT_64BITS((uint32_t *)&fap->fa3_size))); + EXTRACT_64BITS((const uint32_t *)&fap->fa3_size))); } else { ND_TCHECK(fap->fa2_size); ND_PRINT((ndo, " sz %d", EXTRACT_32BITS(&fap->fa2_size))); @@ -1101,9 +1075,9 @@ parsefattr(netdissect_options *ndo, EXTRACT_32BITS(&fap->fa3_rdev.specdata1), EXTRACT_32BITS(&fap->fa3_rdev.specdata2))); ND_PRINT((ndo, " fsid %" PRIx64, - EXTRACT_64BITS((uint32_t *)&fap->fa3_fsid))); + EXTRACT_64BITS((const uint32_t *)&fap->fa3_fsid))); ND_PRINT((ndo, " fileid %" PRIx64, - EXTRACT_64BITS((uint32_t *)&fap->fa3_fileid))); + 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))); @@ -1131,7 +1105,7 @@ parsefattr(netdissect_options *ndo, EXTRACT_32BITS(&fap->fa2_ctime.nfsv2_usec))); } } - return ((const uint32_t *)((unsigned char *)dp + + return ((const uint32_t *)((const unsigned char *)dp + (v3 ? NFSX_V3FATTR : NFSX_V2FATTR))); trunc: return (NULL); @@ -1216,14 +1190,14 @@ parsestatfs(netdissect_options *ndo, if (v3) { ND_PRINT((ndo, " tbytes %" PRIu64 " fbytes %" PRIu64 " abytes %" PRIu64, - EXTRACT_64BITS((uint32_t *)&sfsp->sf_tbytes), - EXTRACT_64BITS((uint32_t *)&sfsp->sf_fbytes), - EXTRACT_64BITS((uint32_t *)&sfsp->sf_abytes))); + EXTRACT_64BITS((const uint32_t *)&sfsp->sf_tbytes), + EXTRACT_64BITS((const uint32_t *)&sfsp->sf_fbytes), + EXTRACT_64BITS((const uint32_t *)&sfsp->sf_abytes))); if (ndo->ndo_vflag) { ND_PRINT((ndo, " tfiles %" PRIu64 " ffiles %" PRIu64 " afiles %" PRIu64 " invar %u", - EXTRACT_64BITS((uint32_t *)&sfsp->sf_tfiles), - EXTRACT_64BITS((uint32_t *)&sfsp->sf_ffiles), - EXTRACT_64BITS((uint32_t *)&sfsp->sf_afiles), + 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))); } } else { @@ -1370,7 +1344,7 @@ parsewccres(netdissect_options *ndo, if (!(dp = parsestatus(ndo, dp, &er))) return (0); - return parse_wcc_data(ndo, dp, verbose) != 0; + return parse_wcc_data(ndo, dp, verbose) != NULL; } static const uint32_t * @@ -1401,7 +1375,7 @@ static int parsefsinfo(netdissect_options *ndo, const uint32_t *dp) { - struct nfsv3_fsinfo *sfp; + const struct nfsv3_fsinfo *sfp; int er; if (!(dp = parsestatus(ndo, dp, &er))) @@ -1413,7 +1387,7 @@ parsefsinfo(netdissect_options *ndo, if (er) return (1); - sfp = (struct nfsv3_fsinfo *)dp; + 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), @@ -1425,7 +1399,7 @@ parsefsinfo(netdissect_options *ndo, ND_PRINT((ndo, " rtmult %u wtmult %u maxfsz %" PRIu64, EXTRACT_32BITS(&sfp->fs_rtmult), EXTRACT_32BITS(&sfp->fs_wtmult), - EXTRACT_64BITS((uint32_t *)&sfp->fs_maxfilesize))); + 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))); @@ -1440,7 +1414,7 @@ parsepathconf(netdissect_options *ndo, const uint32_t *dp) { int er; - struct nfsv3_pathconf *spp; + const struct nfsv3_pathconf *spp; if (!(dp = parsestatus(ndo, dp, &er))) return (0); @@ -1451,7 +1425,7 @@ parsepathconf(netdissect_options *ndo, if (er) return (1); - spp = (struct nfsv3_pathconf *)dp; + spp = (const struct nfsv3_pathconf *)dp; ND_TCHECK(*spp); ND_PRINT((ndo, " linkmax %u namemax %u %s %s %s %s", @@ -1602,7 +1576,7 @@ interp_reply(netdissect_options *ndo, if (!(dp = parserep(ndo, rp, length))) break; if (v3) { - if (parsecreateopres(ndo, dp, ndo->ndo_vflag) != 0) + if (parsecreateopres(ndo, dp, ndo->ndo_vflag) != NULL) return; } else { if (parsediropres(ndo, dp) != 0) @@ -1614,10 +1588,10 @@ interp_reply(netdissect_options *ndo, if (!(dp = parserep(ndo, rp, length))) break; if (v3) { - if (parsecreateopres(ndo, dp, ndo->ndo_vflag) != 0) + if (parsecreateopres(ndo, dp, ndo->ndo_vflag) != NULL) return; } else { - if (parsestatus(ndo, dp, &er) != 0) + if (parsestatus(ndo, dp, &er) != NULL) return; } break; @@ -1625,7 +1599,7 @@ interp_reply(netdissect_options *ndo, case NFSPROC_MKNOD: if (!(dp = parserep(ndo, rp, length))) break; - if (parsecreateopres(ndo, dp, ndo->ndo_vflag) != 0) + if (parsecreateopres(ndo, dp, ndo->ndo_vflag) != NULL) return; break; @@ -1637,7 +1611,7 @@ interp_reply(netdissect_options *ndo, if (parsewccres(ndo, dp, ndo->ndo_vflag)) return; } else { - if (parsestatus(ndo, dp, &er) != 0) + if (parsestatus(ndo, dp, &er) != NULL) return; } break; @@ -1658,7 +1632,7 @@ interp_reply(netdissect_options *ndo, } return; } else { - if (parsestatus(ndo, dp, &er) != 0) + if (parsestatus(ndo, dp, &er) != NULL) return; } break; @@ -1679,7 +1653,7 @@ interp_reply(netdissect_options *ndo, return; } } else { - if (parsestatus(ndo, dp, &er) != 0) + if (parsestatus(ndo, dp, &er) != NULL) return; } break; diff --git a/contrib/tcpdump/print-nsh.c b/contrib/tcpdump/print-nsh.c new file mode 100644 index 0000000..abd722d --- /dev/null +++ b/contrib/tcpdump/print-nsh.c @@ -0,0 +1,185 @@ +/* Copyright (c) 2015, bugyo + * 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 OWNER 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: Network Service Header (NSH) printer */ + +/* specification: draft-ietf-sfc-nsh-01 */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "netdissect.h" +#include "extract.h" + +static const char tstr[] = " [|NSH]"; +static const struct tok nsh_flags [] = { + { 0x20, "O" }, + { 0x10, "C" }, + { 0, NULL } +}; + +#define NSH_BASE_HDR_LEN 4 +#define NSH_SERVICE_PATH_HDR_LEN 4 +#define NSH_HDR_WORD_SIZE 4U + +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; + 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_int next_len; + + /* print Base Header and Service Path Header */ + if (len < NSH_BASE_HDR_LEN + NSH_SERVICE_PATH_HDR_LEN) + goto trunc; + + ND_TCHECK2(*bp, NSH_BASE_HDR_LEN + NSH_SERVICE_PATH_HDR_LEN); + + 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, ")); + if (ndo->ndo_vflag > 1) { + ND_PRINT((ndo, "ver %d, ", ver)); + } + ND_PRINT((ndo, "flags [%s], ", bittok2str_nosep(nsh_flags, "none", flags))); + if (ndo->ndo_vflag > 2) { + ND_PRINT((ndo, "length %d, ", length)); + ND_PRINT((ndo, "md type 0x%x, ", md_type)); + } + if (ndo->ndo_vflag > 1) { + ND_PRINT((ndo, "next-protocol 0x%x, ", 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; + + ND_TCHECK2(*bp, length * NSH_HDR_WORD_SIZE); + + /* + * length includes the lengths of the Base and Service Path headers. + * That means it must be at least 2. + */ + if (length < 2) + goto trunc; + + /* + * Print, or skip, the Context Headers. + * (length - 2) is the length of those headers. + */ + if (ndo->ndo_vflag > 2) { + if (md_type == 0x01) { + for (n = 0; n < length - 2; n++) { + ctx = EXTRACT_32BITS(bp); + bp += NSH_HDR_WORD_SIZE; + ND_PRINT((ndo, "\n Context[%02d]: 0x%08x", n, ctx)); + } + } + else if (md_type == 0x02) { + n = 0; + while (n < length - 2) { + tlv_class = EXTRACT_16BITS(bp); + bp += 2; + tlv_type = *bp; + bp += 1; + tlv_len = *bp; + bp += 1; + + ND_PRINT((ndo, "\n TLV Class %d, Type %d, Len %d", + tlv_class, tlv_type, tlv_len)); + + n += 1; + + if (length - 2 < n + tlv_len) { + ND_PRINT((ndo, " ERROR: invalid-tlv-length")); + return; + } + + 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)); + } + n += tlv_len; + } + } + else { + ND_PRINT((ndo, "ERROR: unknown-next-protocol")); + return; + } + } + else { + bp += (length - 2) * NSH_HDR_WORD_SIZE; + } + ND_PRINT((ndo, ndo->ndo_vflag ? "\n " : ": ")); + + /* print Next Protocol */ + next_len = len - length * NSH_HDR_WORD_SIZE; + switch (next_protocol) { + case 0x1: + ip_print(ndo, bp, next_len); + break; + case 0x2: + ip6_print(ndo, bp, next_len); + break; + case 0x3: + ether_print(ndo, bp, next_len, ndo->ndo_snapend - bp, NULL, NULL); + break; + default: + ND_PRINT((ndo, "ERROR: unknown-next-protocol")); + return; + } + + return; + +trunc: + ND_PRINT((ndo, "%s", tstr)); +} + diff --git a/contrib/tcpdump/print-ntp.c b/contrib/tcpdump/print-ntp.c index 8603906..0689264 100644 --- a/contrib/tcpdump/print-ntp.c +++ b/contrib/tcpdump/print-ntp.c @@ -18,25 +18,23 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * Format and print ntp packets. * By Jeffrey Mogul/DECWRL * loosely based on print-bootp.c - * - * $FreeBSD$ */ -#define NETDISSECT_REWORKED +/* \summary: Network Time Protocol (NTP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #ifdef HAVE_STRFTIME #include #endif -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" @@ -209,7 +207,7 @@ ntp_print(netdissect_options *ndo, register const struct ntpdata *bp; int mode, version, leapind; - bp = (struct ntpdata *)cp; + bp = (const struct ntpdata *)cp; ND_TCHECK(bp->status); @@ -263,7 +261,7 @@ ntp_print(netdissect_options *ndo, break; case PRIM_REF: - if (fn_printn(ndo, (u_char *)&(bp->refid), 4, ndo->ndo_snapend)) + if (fn_printn(ndo, (const u_char *)&(bp->refid), 4, ndo->ndo_snapend)) goto trunc; break; @@ -329,12 +327,12 @@ p_sfix(netdissect_options *ndo, { register int i; register int f; - register float ff; + register double ff; i = EXTRACT_16BITS(&sfp->int_part); f = EXTRACT_16BITS(&sfp->fraction); - ff = f / 65536.0; /* shift radix point by 16 bits */ - f = ff * 1000000.0; /* Treat fraction as parts per million */ + 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)); } @@ -347,15 +345,15 @@ p_ntp_time(netdissect_options *ndo, register int32_t i; register uint32_t uf; register uint32_t f; - register float ff; + 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 = ff * 1000000000.0; /* treat fraction as parts per billion */ + 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)); #ifdef HAVE_STRFTIME @@ -384,7 +382,7 @@ p_ntp_delta(netdissect_options *ndo, register uint32_t u, uf; register uint32_t ou, ouf; register uint32_t f; - register float ff; + register double ff; int signbit; u = EXTRACT_32BITS(&lfp->int_part); @@ -422,8 +420,8 @@ p_ntp_delta(netdissect_options *ndo, ff = f; if (ff < 0.0) /* some compilers are buggy */ ff += FMAXINT; - ff = ff / FMAXINT; /* shift radix point by 32 bits */ - f = ff * 1000000000.0; /* treat fraction as parts per billion */ + 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)); } diff --git a/contrib/tcpdump/print-null.c b/contrib/tcpdump/print-null.c index d296089..14df5fd 100644 --- a/contrib/tcpdump/print-null.c +++ b/contrib/tcpdump/print-null.c @@ -17,20 +17,19 @@ * 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. - * - * $FreeBSD$ */ -#define NETDISSECT_REWORKED +/* \summary: BSD loopback device printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" #include "af.h" /* @@ -85,7 +84,7 @@ null_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char return (NULL_HDRLEN); } - memcpy((char *)&family, (char *)p, sizeof(family)); + memcpy((char *)&family, (const char *)p, sizeof(family)); /* * This isn't necessarily in our host byte order; if this is diff --git a/contrib/tcpdump/print-olsr.c b/contrib/tcpdump/print-olsr.c index b90eea1..e095ef7 100644 --- a/contrib/tcpdump/print-olsr.c +++ b/contrib/tcpdump/print-olsr.c @@ -13,20 +13,21 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * Optimized Link State Protocl (OLSR) as per rfc3626 - * * Original code by Hannes Gredler * IPv6 additions by Florian Forster */ -#define NETDISSECT_REWORKED +/* \summary: Optimized Link State Routing Protocol (OLSR) printer */ + +/* specification: RFC 3626 */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" @@ -135,6 +136,26 @@ struct olsr_hna6 { }; +/** gateway HNA flags */ +enum gateway_hna_flags { + GW_HNA_FLAG_LINKSPEED = 1 << 0, + GW_HNA_FLAG_IPV4 = 1 << 1, + GW_HNA_FLAG_IPV4_NAT = 1 << 2, + GW_HNA_FLAG_IPV6 = 1 << 3, + GW_HNA_FLAG_IPV6PREFIX = 1 << 4 +}; + +/** gateway HNA field byte offsets in the netmask field of the HNA */ +enum gateway_hna_fields { + GW_HNA_PAD = 0, + GW_HNA_FLAGS = 1, + GW_HNA_UPLINK = 2, + GW_HNA_DOWNLINK = 3, + GW_HNA_V6PREFIXLEN = 4, + GW_HNA_V6PREFIX = 5 +}; + + #define OLSR_EXTRACT_LINK_TYPE(link_code) (link_code & 0x3) #define OLSR_EXTRACT_NEIGHBOR_TYPE(link_code) (link_code >> 2) @@ -167,6 +188,37 @@ struct olsr_lq_neighbor6 { uint8_t res[2]; }; +#define MAX_SMARTGW_SPEED 320000000 + +/** + * Convert an encoded 1 byte transport value (5 bits mantissa, 3 bits exponent) + * to an uplink/downlink speed value + * + * @param value the encoded 1 byte transport value + * @return the uplink/downlink speed value (in kbit/s) + */ +static uint32_t deserialize_gw_speed(uint8_t value) { + uint32_t speed; + uint32_t exp; + + if (!value) { + return 0; + } + + if (value == UINT8_MAX) { + /* maximum value: also return maximum value */ + return MAX_SMARTGW_SPEED; + } + + speed = (value >> 3) + 1; + exp = value & 7; + + while (exp-- > 0) { + speed *= 10; + } + return speed; +} + /* * macro to convert the 8-bit mantissa/exponent to a double float * taken from olsr.org. @@ -182,16 +234,16 @@ static int olsr_print_lq_neighbor4(netdissect_options *ndo, const u_char *msg_data, u_int hello_len) { - struct olsr_lq_neighbor4 *lq_neighbor; + const struct olsr_lq_neighbor4 *lq_neighbor; while (hello_len >= sizeof(struct olsr_lq_neighbor4)) { - lq_neighbor = (struct olsr_lq_neighbor4 *)msg_data; + lq_neighbor = (const struct olsr_lq_neighbor4 *)msg_data; if (!ND_TTEST(*lq_neighbor)) return (-1); - ND_PRINT((ndo, "\n\t neighbor %s, link-quality %.2lf%%" - ", neighbor-link-quality %.2lf%%", + ND_PRINT((ndo, "\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))); @@ -202,21 +254,20 @@ olsr_print_lq_neighbor4(netdissect_options *ndo, return (0); } -#if INET6 static int olsr_print_lq_neighbor6(netdissect_options *ndo, const u_char *msg_data, u_int hello_len) { - struct olsr_lq_neighbor6 *lq_neighbor; + const struct olsr_lq_neighbor6 *lq_neighbor; while (hello_len >= sizeof(struct olsr_lq_neighbor6)) { - lq_neighbor = (struct olsr_lq_neighbor6 *)msg_data; + lq_neighbor = (const struct olsr_lq_neighbor6 *)msg_data; if (!ND_TTEST(*lq_neighbor)) return (-1); - ND_PRINT((ndo, "\n\t neighbor %s, link-quality %.2lf%%" - ", neighbor-link-quality %.2lf%%", + ND_PRINT((ndo, "\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))); @@ -226,7 +277,6 @@ olsr_print_lq_neighbor6(netdissect_options *ndo, } return (0); } -#endif /* INET6 */ /* * print a neighbor list. @@ -284,7 +334,7 @@ olsr_print(netdissect_options *ndo, ND_TCHECK2(*tptr, sizeof(struct olsr_common)); - ptr.common = (struct olsr_common *)tptr; + ptr.common = (const struct olsr_common *)tptr; length = min(length, EXTRACT_16BITS(ptr.common->packet_len)); ND_PRINT((ndo, "OLSRv%i, seq 0x%04x, length %u", @@ -304,17 +354,16 @@ olsr_print(netdissect_options *ndo, while (tptr < (pptr+length)) { union { - struct olsr_msg4 *v4; - struct olsr_msg6 *v6; + const struct olsr_msg4 *v4; + const struct olsr_msg6 *v6; } msgptr; int msg_len_valid = 0; ND_TCHECK2(*tptr, sizeof(struct olsr_msg4)); -#if INET6 if (is_ipv6) { - msgptr.v6 = (struct olsr_msg6 *) tptr; + msgptr.v6 = (const struct olsr_msg6 *) tptr; msg_type = msgptr.v6->msg_type; msg_len = EXTRACT_16BITS(msgptr.v6->msg_len); if ((msg_len >= sizeof (struct olsr_msg6)) @@ -327,7 +376,7 @@ olsr_print(netdissect_options *ndo, } ND_PRINT((ndo, "\n\t%s Message (%#04x), originator %s, ttl %u, hop %u" - "\n\t vtime %.3lfs, msg-seq 0x%04x, length %u%s", + "\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, @@ -343,9 +392,8 @@ olsr_print(netdissect_options *ndo, msg_data = tptr + sizeof(struct olsr_msg6); } else /* (!is_ipv6) */ -#endif /* INET6 */ { - msgptr.v4 = (struct olsr_msg4 *) tptr; + msgptr.v4 = (const struct olsr_msg4 *) tptr; msg_type = msgptr.v4->msg_type; msg_len = EXTRACT_16BITS(msgptr.v4->msg_len); if ((msg_len >= sizeof (struct olsr_msg4)) @@ -358,7 +406,7 @@ olsr_print(netdissect_options *ndo, } ND_PRINT((ndo, "\n\t%s Message (%#04x), originator %s, ttl %u, hop %u" - "\n\t vtime %.3lfs, msg-seq 0x%04x, length %u%s", + "\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, @@ -381,8 +429,8 @@ olsr_print(netdissect_options *ndo, goto trunc; ND_TCHECK2(*msg_data, sizeof(struct olsr_hello)); - ptr.hello = (struct olsr_hello *)msg_data; - ND_PRINT((ndo, "\n\t hello-time %.3lfs, MPR willingness %u", + 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)); msg_data += sizeof(struct olsr_hello); msg_tlen -= sizeof(struct olsr_hello); @@ -395,7 +443,7 @@ olsr_print(netdissect_options *ndo, */ ND_TCHECK2(*msg_data, sizeof(struct olsr_hello_link)); - ptr.hello_link = (struct olsr_hello_link *)msg_data; + 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); @@ -423,13 +471,10 @@ olsr_print(netdissect_options *ndo, if (olsr_print_neighbor(ndo, msg_data, hello_len) == -1) goto trunc; } else { -#if INET6 if (is_ipv6) { if (olsr_print_lq_neighbor6(ndo, msg_data, hello_len) == -1) goto trunc; - } else -#endif - { + } else { if (olsr_print_lq_neighbor4(ndo, msg_data, hello_len) == -1) goto trunc; } @@ -446,7 +491,7 @@ olsr_print(netdissect_options *ndo, goto trunc; ND_TCHECK2(*msg_data, sizeof(struct olsr_tc)); - ptr.tc = (struct olsr_tc *)msg_data; + ptr.tc = (const struct olsr_tc *)msg_data; ND_PRINT((ndo, "\n\t advertised neighbor seq 0x%04x", EXTRACT_16BITS(ptr.tc->ans_seq))); msg_data += sizeof(struct olsr_tc); @@ -456,13 +501,10 @@ olsr_print(netdissect_options *ndo, if (olsr_print_neighbor(ndo, msg_data, msg_tlen) == -1) goto trunc; } else { -#if INET6 if (is_ipv6) { if (olsr_print_lq_neighbor6(ndo, msg_data, msg_tlen) == -1) goto trunc; - } else -#endif - { + } else { if (olsr_print_lq_neighbor4(ndo, msg_data, msg_tlen) == -1) goto trunc; } @@ -473,21 +515,14 @@ olsr_print(netdissect_options *ndo, { size_t addr_size = sizeof(struct in_addr); -#if INET6 if (is_ipv6) addr_size = sizeof(struct in6_addr); -#endif while (msg_tlen >= addr_size) { ND_TCHECK2(*msg_data, addr_size); -#if INET6 ND_PRINT((ndo, "\n\t interface address %s", is_ipv6 ? ip6addr_string(ndo, msg_data) : ipaddr_string(ndo, msg_data))); -#else - ND_PRINT((ndo, "\n\t interface address %s", - ipaddr_string(ndo, msg_data))); -#endif msg_data += addr_size; msg_tlen -= addr_size; @@ -496,18 +531,19 @@ olsr_print(netdissect_options *ndo, } case OLSR_HNA_MSG: - ND_PRINT((ndo, "\n\t Advertised networks (total %u)", - (unsigned int) (msg_tlen / sizeof(struct olsr_hna6)))); -#if INET6 if (is_ipv6) { int i = 0; + + ND_PRINT((ndo, "\n\t Advertised networks (total %u)", + (unsigned int) (msg_tlen / sizeof(struct olsr_hna6)))); + while (msg_tlen >= sizeof(struct olsr_hna6)) { - struct olsr_hna6 *hna6; + const struct olsr_hna6 *hna6; ND_TCHECK2(*msg_data, sizeof(struct olsr_hna6)); - hna6 = (struct olsr_hna6 *)msg_data; + hna6 = (const struct olsr_hna6 *)msg_data; ND_PRINT((ndo, "\n\t #%i: %s/%u", i, ip6addr_string(ndo, hna6->network), @@ -518,19 +554,57 @@ olsr_print(netdissect_options *ndo, } } else -#endif { int col = 0; + + ND_PRINT((ndo, "\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)); - ptr.hna = (struct olsr_hna4 *)msg_data; + ptr.hna = (const struct olsr_hna4 *)msg_data; /* print 4 prefixes per line */ - ND_PRINT((ndo, "%s%s/%u", - col == 0 ? "\n\t " : ", ", - ipaddr_string(ndo, ptr.hna->network), - mask2plen(EXTRACT_32BITS(ptr.hna->mask)))); + if (!ptr.hna->network[0] && !ptr.hna->network[1] && + !ptr.hna->network[2] && !ptr.hna->network[3] && + !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", + col == 0 ? "\n\t " : ", ", /* indent */ + /* sgw */ + /* LINKSPEED */ + (ptr.hna->mask[GW_HNA_FLAGS] & + GW_HNA_FLAG_LINKSPEED) ? " LINKSPEED" : "", + /* IPV4 */ + (ptr.hna->mask[GW_HNA_FLAGS] & + GW_HNA_FLAG_IPV4) ? " IPV4" : "", + /* IPV4-NAT */ + (ptr.hna->mask[GW_HNA_FLAGS] & + GW_HNA_FLAG_IPV4_NAT) ? " IPV4-NAT" : "", + /* IPV6 */ + (ptr.hna->mask[GW_HNA_FLAGS] & + GW_HNA_FLAG_IPV6) ? " IPV6" : "", + /* IPv6PREFIX */ + (ptr.hna->mask[GW_HNA_FLAGS] & + GW_HNA_FLAG_IPV6PREFIX) ? " IPv6-PREFIX" : "", + /* uplink */ + (ptr.hna->mask[GW_HNA_FLAGS] & + GW_HNA_FLAG_LINKSPEED) ? + deserialize_gw_speed(ptr.hna->mask[GW_HNA_UPLINK]) : 0, + /* downlink */ + (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", + col == 0 ? "\n\t " : ", ", + ipaddr_string(ndo, ptr.hna->network), + mask2plen(EXTRACT_32BITS(ptr.hna->mask)))); + } msg_data += sizeof(struct olsr_hna4); msg_tlen -= sizeof(struct olsr_hna4); @@ -601,12 +675,10 @@ olsr_print(netdissect_options *ndo, ND_TCHECK2(*msg_data, addr_size + name_entry_len + name_entry_padding); -#if INET6 if (is_ipv6) ND_PRINT((ndo, ", address %s, name \"", ip6addr_string(ndo, msg_data))); else -#endif ND_PRINT((ndo, ", address %s, name \"", ipaddr_string(ndo, msg_data))); (void)fn_printn(ndo, msg_data + addr_size, name_entry_len, NULL); diff --git a/contrib/tcpdump/print-openflow-1.0.c b/contrib/tcpdump/print-openflow-1.0.c index a36c32f..ce95843 100644 --- a/contrib/tcpdump/print-openflow-1.0.c +++ b/contrib/tcpdump/print-openflow-1.0.c @@ -14,7 +14,7 @@ * * 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 malformed or truncated. This way it is possible + * 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. * @@ -56,14 +56,15 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#define NETDISSECT_REWORKED +/* \summary: OpenFlow protocol version 1.0 printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "addrtoname.h" #include "ether.h" @@ -73,7 +74,6 @@ #include "openflow.h" static const char tstr[] = " [|openflow]"; -static const char cstr[] = " (corrupt)"; #define OFPT_HELLO 0x00 #define OFPT_ERROR 0x01 @@ -760,7 +760,7 @@ of10_bsn_message_print(netdissect_options *ndo, uint32_t subtype; if (len < 4) - goto corrupt; + goto invalid; /* subtype */ ND_TCHECK2(*cp, 4); subtype = EXTRACT_32BITS(cp); @@ -781,7 +781,7 @@ of10_bsn_message_print(netdissect_options *ndo, * */ if (len != 12) - goto corrupt; + goto invalid; /* index */ ND_TCHECK2(*cp, 1); ND_PRINT((ndo, ", index %u", *cp)); @@ -805,7 +805,7 @@ of10_bsn_message_print(netdissect_options *ndo, * */ if (len != 12) - goto corrupt; + goto invalid; /* index */ ND_TCHECK2(*cp, 1); ND_PRINT((ndo, ", index %u", *cp)); @@ -832,7 +832,7 @@ of10_bsn_message_print(netdissect_options *ndo, * */ if (len != 8) - goto corrupt; + goto invalid; /* report_mirror_ports */ ND_TCHECK2(*cp, 1); ND_PRINT((ndo, ", report_mirror_ports %s", tok2str(bsn_onoff_str, "bogus (%u)", *cp))); @@ -855,7 +855,7 @@ of10_bsn_message_print(netdissect_options *ndo, * */ if (len != 4) - goto corrupt; + goto invalid; break; case BSN_VIRTUAL_PORT_REMOVE_REQUEST: /* @@ -869,7 +869,7 @@ of10_bsn_message_print(netdissect_options *ndo, * */ if (len != 8) - goto corrupt; + goto invalid; /* vport_no */ ND_TCHECK2(*cp, 4); ND_PRINT((ndo, ", vport_no %u", EXTRACT_32BITS(cp))); @@ -889,7 +889,7 @@ of10_bsn_message_print(netdissect_options *ndo, * */ if (len < 8) - goto corrupt; + goto invalid; /* service */ ND_TCHECK2(*cp, 4); ND_PRINT((ndo, ", service %u", EXTRACT_32BITS(cp))); @@ -936,7 +936,7 @@ of10_bsn_message_print(netdissect_options *ndo, * */ if (len != 8) - goto corrupt; + goto invalid; /* status */ ND_TCHECK2(*cp, 4); ND_PRINT((ndo, ", status 0x%08x", EXTRACT_32BITS(cp))); @@ -948,8 +948,8 @@ of10_bsn_message_print(netdissect_options *ndo, } return cp; -corrupt: /* skip the undersized data */ - ND_PRINT((ndo, "%s", cstr)); +invalid: /* skip the undersized data */ + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp0, len); return cp0 + len; trunc: @@ -965,7 +965,7 @@ of10_bsn_actions_print(netdissect_options *ndo, uint32_t subtype, vlan_tag; if (len < 4) - goto corrupt; + goto invalid; /* subtype */ ND_TCHECK2(*cp, 4); subtype = EXTRACT_32BITS(cp); @@ -988,7 +988,7 @@ of10_bsn_actions_print(netdissect_options *ndo, * */ if (len != 16) - goto corrupt; + goto invalid; /* dest_port */ ND_TCHECK2(*cp, 4); ND_PRINT((ndo, ", dest_port %u", EXTRACT_32BITS(cp))); @@ -1022,8 +1022,8 @@ of10_bsn_actions_print(netdissect_options *ndo, return cp; -corrupt: - ND_PRINT((ndo, "%s", cstr)); +invalid: + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp0, len); return cp0 + len; trunc: @@ -1039,7 +1039,7 @@ of10_vendor_action_print(netdissect_options *ndo, const u_char *(*decoder)(netdissect_options *, const u_char *, const u_char *, const u_int); if (len < 4) - goto corrupt; + goto invalid; /* vendor */ ND_TCHECK2(*cp, 4); vendor = EXTRACT_32BITS(cp); @@ -1051,8 +1051,8 @@ of10_vendor_action_print(netdissect_options *ndo, of10_data_print; return decoder(ndo, cp, ep, len - 4); -corrupt: /* skip the undersized data */ - ND_PRINT((ndo, "%s", cstr)); +invalid: /* skip the undersized data */ + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp, len); return cp + len; trunc: @@ -1068,7 +1068,7 @@ of10_vendor_message_print(netdissect_options *ndo, const u_char *(*decoder)(netdissect_options *, const u_char *, const u_char *, u_int); if (len < 4) - goto corrupt; + goto invalid; /* vendor */ ND_TCHECK2(*cp, 4); vendor = EXTRACT_32BITS(cp); @@ -1080,8 +1080,8 @@ of10_vendor_message_print(netdissect_options *ndo, of10_data_print; return decoder(ndo, cp, ep, len - 4); -corrupt: /* skip the undersized data */ - ND_PRINT((ndo, "%s", cstr)); +invalid: /* skip the undersized data */ + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp, len); return cp + len; trunc: @@ -1097,7 +1097,7 @@ of10_vendor_data_print(netdissect_options *ndo, uint32_t vendor; if (len < 4) - goto corrupt; + goto invalid; /* vendor */ ND_TCHECK2(*cp, 4); vendor = EXTRACT_32BITS(cp); @@ -1106,8 +1106,8 @@ of10_vendor_data_print(netdissect_options *ndo, /* data */ return of10_data_print(ndo, cp, ep, len - 4); -corrupt: /* skip the undersized data */ - ND_PRINT((ndo, "%s", cstr)); +invalid: /* skip the undersized data */ + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp, len); return cp + len; trunc: @@ -1147,7 +1147,7 @@ of10_phy_ports_print(netdissect_options *ndo, while (len) { if (len < OF_PHY_PORT_LEN) - goto corrupt; + goto invalid; /* port_no */ ND_TCHECK2(*cp, 2); ND_PRINT((ndo, "\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); @@ -1203,8 +1203,8 @@ next_port: } /* while */ return cp; -corrupt: /* skip the undersized trailing data */ - ND_PRINT((ndo, "%s", cstr)); +invalid: /* skip the undersized trailing data */ + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp0, len0); return cp0 + len0; trunc: @@ -1225,7 +1225,7 @@ of10_queue_props_print(netdissect_options *ndo, u_char plen_bogus = 0, skip = 0; if (len < OF_QUEUE_PROP_HEADER_LEN) - goto corrupt; + goto invalid; /* property */ ND_TCHECK2(*cp, 2); property = EXTRACT_16BITS(cp); @@ -1237,7 +1237,7 @@ of10_queue_props_print(netdissect_options *ndo, cp += 2; ND_PRINT((ndo, ", len %u", plen)); if (plen < OF_QUEUE_PROP_HEADER_LEN || plen > len) - goto corrupt; + goto invalid; /* pad */ ND_TCHECK2(*cp, 4); cp += 4; @@ -1279,8 +1279,8 @@ next_property: } /* while */ return cp; -corrupt: /* skip the rest of queue properties */ - ND_PRINT((ndo, "%s", cstr)); +invalid: /* skip the rest of queue properties */ + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp0, len0); return cp0 + len0; trunc: @@ -1299,7 +1299,7 @@ of10_queues_print(netdissect_options *ndo, while (len) { if (len < OF_PACKET_QUEUE_LEN) - goto corrupt; + goto invalid; /* queue_id */ ND_TCHECK2(*cp, 4); ND_PRINT((ndo, "\n\t queue_id %u", EXTRACT_32BITS(cp))); @@ -1310,7 +1310,7 @@ of10_queues_print(netdissect_options *ndo, cp += 2; ND_PRINT((ndo, ", len %u", desclen)); if (desclen < OF_PACKET_QUEUE_LEN || desclen > len) - goto corrupt; + goto invalid; /* pad */ ND_TCHECK2(*cp, 2); cp += 2; @@ -1327,8 +1327,8 @@ next_queue: } /* while */ return cp; -corrupt: /* skip the rest of queues */ - ND_PRINT((ndo, "%s", cstr)); +invalid: /* skip the rest of queues */ + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp0, len0); return cp0 + len0; trunc: @@ -1454,7 +1454,7 @@ of10_actions_print(netdissect_options *ndo, u_char alen_bogus = 0, skip = 0; if (len < OF_ACTION_HEADER_LEN) - goto corrupt; + goto invalid; /* type */ ND_TCHECK2(*cp, 2); type = EXTRACT_16BITS(cp); @@ -1467,7 +1467,7 @@ of10_actions_print(netdissect_options *ndo, ND_PRINT((ndo, ", len %u", alen)); /* On action size underrun/overrun skip the rest of the action list. */ if (alen < OF_ACTION_HEADER_LEN || alen > len) - goto corrupt; + 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. */ switch (type) { @@ -1598,8 +1598,8 @@ next_action: } /* while */ return cp; -corrupt: /* skip the rest of actions */ - ND_PRINT((ndo, "%s", cstr)); +invalid: /* skip the rest of actions */ + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp0, len0); return cp0 + len0; trunc: @@ -1766,12 +1766,12 @@ of10_stats_request_print(netdissect_options *ndo, case OFPST_DESC: case OFPST_TABLE: if (len) - goto corrupt; + goto invalid; return cp; case OFPST_FLOW: case OFPST_AGGREGATE: if (len != OF_FLOW_STATS_REQUEST_LEN) - goto corrupt; + goto invalid; /* match */ if (ep == (cp = of10_match_print(ndo, "\n\t ", cp, ep))) return ep; /* end of snapshot */ @@ -1788,7 +1788,7 @@ of10_stats_request_print(netdissect_options *ndo, return cp + 2; case OFPST_PORT: if (len != OF_PORT_STATS_REQUEST_LEN) - goto corrupt; + goto invalid; /* port_no */ ND_TCHECK2(*cp, 2); ND_PRINT((ndo, "\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); @@ -1798,7 +1798,7 @@ of10_stats_request_print(netdissect_options *ndo, return cp + 6; case OFPST_QUEUE: if (len != OF_QUEUE_STATS_REQUEST_LEN) - goto corrupt; + goto invalid; /* port_no */ ND_TCHECK2(*cp, 2); ND_PRINT((ndo, "\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); @@ -1815,8 +1815,8 @@ of10_stats_request_print(netdissect_options *ndo, } return cp; -corrupt: /* skip the message body */ - ND_PRINT((ndo, "%s", cstr)); +invalid: /* skip the message body */ + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp0, len0); return cp0 + len0; trunc: @@ -1830,7 +1830,7 @@ of10_desc_stats_reply_print(netdissect_options *ndo, const u_char *cp, const u_char *ep, const u_int len) { if (len != OF_DESC_STATS_LEN) - goto corrupt; + goto invalid; /* mfr_desc */ ND_TCHECK2(*cp, DESC_STR_LEN); ND_PRINT((ndo, "\n\t mfr_desc '")); @@ -1862,8 +1862,8 @@ of10_desc_stats_reply_print(netdissect_options *ndo, ND_PRINT((ndo, "'")); return cp + DESC_STR_LEN; -corrupt: /* skip the message body */ - ND_PRINT((ndo, "%s", cstr)); +invalid: /* skip the message body */ + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp, len); return cp + len; trunc: @@ -1882,13 +1882,13 @@ of10_flow_stats_reply_print(netdissect_options *ndo, while (len) { if (len < OF_FLOW_STATS_LEN) - goto corrupt; + 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) - goto corrupt; + goto invalid; cp += 2; /* table_id */ ND_TCHECK2(*cp, 1); @@ -1943,8 +1943,8 @@ of10_flow_stats_reply_print(netdissect_options *ndo, } /* while */ return cp; -corrupt: /* skip the rest of flow statistics entries */ - ND_PRINT((ndo, "%s", cstr)); +invalid: /* skip the rest of flow statistics entries */ + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp0, len0); return cp0 + len0; trunc: @@ -1959,7 +1959,7 @@ of10_aggregate_stats_reply_print(netdissect_options *ndo, const u_int len) { if (len != OF_AGGREGATE_STATS_REPLY_LEN) - goto corrupt; + goto invalid; /* packet_count */ ND_TCHECK2(*cp, 8); ND_PRINT((ndo, "\n\t packet_count %" PRIu64, EXTRACT_64BITS(cp))); @@ -1976,8 +1976,8 @@ of10_aggregate_stats_reply_print(netdissect_options *ndo, ND_TCHECK2(*cp, 4); return cp + 4; -corrupt: /* skip the message body */ - ND_PRINT((ndo, "%s", cstr)); +invalid: /* skip the message body */ + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp, len); return cp + len; trunc: @@ -1995,7 +1995,7 @@ of10_table_stats_reply_print(netdissect_options *ndo, while (len) { if (len < OF_TABLE_STATS_LEN) - goto corrupt; + goto invalid; /* table_id */ ND_TCHECK2(*cp, 1); ND_PRINT((ndo, "\n\t table_id %s", tok2str(tableid_str, "%u", *cp))); @@ -2035,8 +2035,8 @@ of10_table_stats_reply_print(netdissect_options *ndo, } /* while */ return cp; -corrupt: /* skip the undersized trailing data */ - ND_PRINT((ndo, "%s", cstr)); +invalid: /* skip the undersized trailing data */ + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp0, len0); return cp0 + len0; trunc: @@ -2054,7 +2054,7 @@ of10_port_stats_reply_print(netdissect_options *ndo, while (len) { if (len < OF_PORT_STATS_LEN) - goto corrupt; + goto invalid; /* port_no */ ND_TCHECK2(*cp, 2); ND_PRINT((ndo, "\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); @@ -2120,8 +2120,8 @@ next_port: } /* while */ return cp; -corrupt: /* skip the undersized trailing data */ - ND_PRINT((ndo, "%s", cstr)); +invalid: /* skip the undersized trailing data */ + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp0, len0); return cp0 + len0; trunc: @@ -2139,7 +2139,7 @@ of10_queue_stats_reply_print(netdissect_options *ndo, while (len) { if (len < OF_QUEUE_STATS_LEN) - goto corrupt; + goto invalid; /* port_no */ ND_TCHECK2(*cp, 2); ND_PRINT((ndo, "\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); @@ -2168,8 +2168,8 @@ of10_queue_stats_reply_print(netdissect_options *ndo, } /* while */ return cp; -corrupt: /* skip the undersized trailing data */ - ND_PRINT((ndo, "%s", cstr)); +invalid: /* skip the undersized trailing data */ + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp0, len0); return cp0 + len0; trunc: @@ -2239,15 +2239,15 @@ of10_packet_out_print(netdissect_options *ndo, actions_len = EXTRACT_16BITS(cp); cp += 2; if (actions_len > len - OF_PACKET_OUT_LEN) - goto corrupt; + goto invalid; /* actions */ if (ep == (cp = of10_actions_print(ndo, "\n\t ", cp, ep, actions_len))) return ep; /* end of snapshot */ /* data */ return of10_packet_data_print(ndo, cp, ep, len - OF_PACKET_OUT_LEN - actions_len); -corrupt: /* skip the rest of the message body */ - ND_PRINT((ndo, "%s", cstr)); +invalid: /* skip the rest of the message body */ + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp0, len0); return cp0 + len0; trunc: @@ -2387,7 +2387,7 @@ of10_header_body_print(netdissect_options *ndo, * 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 - * corrupt, proceed to the next message. */ + * invalid, proceed to the next message. */ /* [OF10] Section 5.1 */ ND_PRINT((ndo, "\n\tversion 1.0, type %s, length %u, xid 0x%08x", @@ -2399,14 +2399,14 @@ of10_header_body_print(netdissect_options *ndo, case OFPT_BARRIER_REQUEST: /* [OF10] Section 5.3.7 */ case OFPT_BARRIER_REPLY: /* ibid */ if (len != OF_HEADER_LEN) - goto corrupt; + 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 corrupt; + goto invalid; if (ndo->ndo_vflag < 1) goto next_message; /* flags */ @@ -2419,13 +2419,13 @@ of10_header_body_print(netdissect_options *ndo, return cp + 2; case OFPT_PORT_MOD: if (len != OF_PORT_MOD_LEN) - goto corrupt; + 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 corrupt; + goto invalid; if (ndo->ndo_vflag < 1) goto next_message; /* port */ @@ -2437,13 +2437,13 @@ of10_header_body_print(netdissect_options *ndo, return cp + 2; case OFPT_FLOW_REMOVED: if (len != OF_FLOW_REMOVED_LEN) - goto corrupt; + 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 corrupt; + goto invalid; if (ndo->ndo_vflag < 1) goto next_message; /* reason */ @@ -2459,7 +2459,7 @@ of10_header_body_print(netdissect_options *ndo, /* OpenFlow header, fixed-size message body and n * fixed-size data units. */ case OFPT_FEATURES_REPLY: if (len < OF_SWITCH_FEATURES_LEN) - goto corrupt; + goto invalid; if (ndo->ndo_vflag < 1) goto next_message; return of10_features_reply_print(ndo, cp, ep, len); @@ -2475,21 +2475,21 @@ of10_header_body_print(netdissect_options *ndo, /* OpenFlow header, fixed-size message body and variable-size data. */ case OFPT_ERROR: if (len < OF_ERROR_MSG_LEN) - goto corrupt; + 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 corrupt; + 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 corrupt; + goto invalid; if (ndo->ndo_vflag < 1) goto next_message; return of10_packet_in_print(ndo, cp, ep, len); @@ -2499,7 +2499,7 @@ of10_header_body_print(netdissect_options *ndo, /* c. OpenFlow header, fixed-size message body and variable-size data. */ case OFPT_STATS_REQUEST: if (len < OF_STATS_REQUEST_LEN) - goto corrupt; + goto invalid; if (ndo->ndo_vflag < 1) goto next_message; return of10_stats_request_print(ndo, cp, ep, len); @@ -2510,7 +2510,7 @@ of10_header_body_print(netdissect_options *ndo, /* d. OpenFlow header, fixed-size message body and variable-size data. */ case OFPT_STATS_REPLY: if (len < OF_STATS_REPLY_LEN) - goto corrupt; + goto invalid; if (ndo->ndo_vflag < 1) goto next_message; return of10_stats_reply_print(ndo, cp, ep, len); @@ -2518,7 +2518,7 @@ of10_header_body_print(netdissect_options *ndo, /* OpenFlow header and n * variable-size data units and variable-size data. */ case OFPT_PACKET_OUT: if (len < OF_PACKET_OUT_LEN) - goto corrupt; + goto invalid; if (ndo->ndo_vflag < 1) goto next_message; return of10_packet_out_print(ndo, cp, ep, len); @@ -2526,7 +2526,7 @@ of10_header_body_print(netdissect_options *ndo, /* OpenFlow header, fixed-size message body and n * variable-size data units. */ case OFPT_FLOW_MOD: if (len < OF_FLOW_MOD_LEN) - goto corrupt; + goto invalid; if (ndo->ndo_vflag < 1) goto next_message; return of10_flow_mod_print(ndo, cp, ep, len); @@ -2534,7 +2534,7 @@ of10_header_body_print(netdissect_options *ndo, /* 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 corrupt; + goto invalid; if (ndo->ndo_vflag < 1) goto next_message; /* port */ @@ -2549,8 +2549,8 @@ of10_header_body_print(netdissect_options *ndo, } /* switch (type) */ goto next_message; -corrupt: /* skip the message body */ - ND_PRINT((ndo, "%s", cstr)); +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; diff --git a/contrib/tcpdump/print-openflow.c b/contrib/tcpdump/print-openflow.c index 8825ae3..043adc2 100644 --- a/contrib/tcpdump/print-openflow.c +++ b/contrib/tcpdump/print-openflow.c @@ -30,20 +30,20 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#define NETDISSECT_REWORKED +/* \summary: version-independent OpenFlow printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "openflow.h" #include "oui.h" static const char tstr[] = " [|openflow]"; -static const char cstr[] = " (corrupt)"; #define OF_VER_1_0 0x01 @@ -83,7 +83,7 @@ of_header_body_print(netdissect_options *ndo, const u_char *cp, const u_char *ep uint32_t xid; if (ep < cp + OF_HEADER_LEN) - goto corrupt; + goto invalid; /* version */ ND_TCHECK2(*cp, 1); version = *cp; @@ -107,7 +107,7 @@ of_header_body_print(netdissect_options *ndo, const u_char *cp, const u_char *ep * segment. */ if (length < OF_HEADER_LEN) { of_header_print(ndo, version, type, length, xid); - goto corrupt; + goto invalid; } /* Decode known protocol versions further without printing the header (the * type decoding is version-specific. */ @@ -120,8 +120,8 @@ of_header_body_print(netdissect_options *ndo, const u_char *cp, const u_char *ep return cp + length - OF_HEADER_LEN; /* done with current message */ } -corrupt: /* fail current packet */ - ND_PRINT((ndo, "%s", cstr)); +invalid: /* fail current packet */ + ND_PRINT((ndo, "%s", istr)); ND_TCHECK2(*cp, ep - cp); return ep; trunc: diff --git a/contrib/tcpdump/print-ospf.c b/contrib/tcpdump/print-ospf.c index 3583417..db4231b 100644 --- a/contrib/tcpdump/print-ospf.c +++ b/contrib/tcpdump/print-ospf.c @@ -21,14 +21,15 @@ * OSPF support contributed by Jeffrey Honig (jch@mitchell.cit.cornell.edu) */ -#define NETDISSECT_REWORKED +/* \summary: Open Shortest Path First (OSPF) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" #include "gmpls.h" @@ -314,6 +315,10 @@ ospf_print_te_lsa(netdissect_options *ndo, tptr+=4; tlv_length-=4; + /* Infinite loop protection */ + if (subtlv_type == 0 || subtlv_length == 0) + goto invalid; + ND_PRINT((ndo, "\n\t %s subTLV (%u), length: %u", tok2str(lsa_opaque_te_link_tlv_subtlv_values,"unknown",subtlv_type), subtlv_type, @@ -322,10 +327,18 @@ ospf_print_te_lsa(netdissect_options *ndo, ND_TCHECK2(*tptr, subtlv_length); switch(subtlv_type) { case LS_OPAQUE_TE_LINK_SUBTLV_ADMIN_GROUP: + if (subtlv_length != 4) { + ND_PRINT((ndo, " != 4")); + goto invalid; + } ND_PRINT((ndo, ", 0x%08x", EXTRACT_32BITS(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")); + goto invalid; + } ND_PRINT((ndo, ", %s (0x%08x)", ipaddr_string(ndo, tptr), EXTRACT_32BITS(tptr))); @@ -336,14 +349,26 @@ ospf_print_te_lsa(netdissect_options *ndo, 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")); + goto invalid; + } ND_PRINT((ndo, ", %s", ipaddr_string(ndo, 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")); + goto invalid; + } bw.i = EXTRACT_32BITS(tptr); ND_PRINT((ndo, ", %.3f Mbps", bw.f * 8 / 1000000)); break; case LS_OPAQUE_TE_LINK_SUBTLV_UNRES_BW: + if (subtlv_length != 32) { + ND_PRINT((ndo, " != 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", @@ -352,9 +377,22 @@ ospf_print_te_lsa(netdissect_options *ndo, } break; case LS_OPAQUE_TE_LINK_SUBTLV_BW_CONSTRAINTS: + if (subtlv_length < 4) { + ND_PRINT((ndo, " < 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)); + if (subtlv_length % 4 != 0) { + ND_PRINT((ndo, "\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)); + 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); @@ -364,14 +402,27 @@ ospf_print_te_lsa(netdissect_options *ndo, } break; case LS_OPAQUE_TE_LINK_SUBTLV_TE_METRIC: + if (subtlv_length != 4) { + ND_PRINT((ndo, " != 4")); + goto invalid; + } ND_PRINT((ndo, ", Metric %u", EXTRACT_32BITS(tptr))); break; case LS_OPAQUE_TE_LINK_SUBTLV_LINK_PROTECTION_TYPE: - ND_PRINT((ndo, ", %s, Priority %u", - bittok2str(gmpls_link_prot_values, "none", *tptr), - *(tptr + 1))); + /* Protection Cap (1 octet) + Reserved ((3 octets) */ + if (subtlv_length != 4) { + ND_PRINT((ndo, " != 4")); + goto invalid; + } + ND_PRINT((ndo, ", %s", + bittok2str(gmpls_link_prot_values, "none", *tptr))); break; case LS_OPAQUE_TE_LINK_SUBTLV_INTF_SW_CAP_DESCR: + if (subtlv_length < 36) { + ND_PRINT((ndo, " < 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:", @@ -384,12 +435,20 @@ ospf_print_te_lsa(netdissect_options *ndo, } break; case LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE: + if (subtlv_length != 1) { + ND_PRINT((ndo, " != 1")); + goto invalid; + } ND_PRINT((ndo, ", %s (%u)", tok2str(lsa_opaque_te_tlv_link_type_sub_tlv_values,"unknown",*tptr), *tptr)); break; case LS_OPAQUE_TE_LINK_SUBTLV_SHARED_RISK_GROUP: + if (subtlv_length % 4 != 0) { + ND_PRINT((ndo, " != N x 4")); + goto invalid; + } count_srlg = subtlv_length / 4; if (count_srlg != 0) ND_PRINT((ndo, "\n\t\t Shared risk group: ")); @@ -445,6 +504,9 @@ ospf_print_te_lsa(netdissect_options *ndo, return 0; trunc: return -1; +invalid: + ND_PRINT((ndo, "%s", istr)); + return -1; } static int @@ -506,16 +568,16 @@ trunc: /* draft-ietf-ospf-mt-09 */ static const struct tok ospf_topology_values[] = { - { 0, "default " }, - { 1, "multicast " }, - { 2, "management " }, + { 0, "default" }, + { 1, "multicast" }, + { 2, "management" }, { 0, NULL } }; /* * Print all the per-topology metrics. */ -static void +static int ospf_print_tos_metrics(netdissect_options *ndo, const union un_tos *tos) { @@ -528,9 +590,10 @@ ospf_print_tos_metrics(netdissect_options *ndo, /* * All but the first metric contain a valid topology id. */ - while (toscount) { - ND_PRINT((ndo, "\n\t\ttopology %s(%u), metric %u", - tok2str(ospf_topology_values, "", + while (toscount > 0) { + ND_TCHECK(*tos); + ND_PRINT((ndo, "\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))); @@ -538,6 +601,9 @@ ospf_print_tos_metrics(netdissect_options *ndo, tos++; toscount--; } + return 0; +trunc: + return 1; } /* @@ -559,11 +625,11 @@ ospf_print_lsa(netdissect_options *ndo, register int ls_length; const uint8_t *tptr; - tptr = (uint8_t *)lsap->lsa_un.un_unknown; /* squelch compiler warnings */ + 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); - ls_end = (uint8_t *)lsap + ls_length; + ls_end = (const uint8_t *)lsap + ls_length; ls_length -= sizeof(struct lsa_hdr); switch (lsap->ls_hdr.ls_type) { @@ -611,9 +677,10 @@ ospf_print_lsa(netdissect_options *ndo, return (ls_end); } - ospf_print_tos_metrics(ndo, &rlp->un_tos); + if (ospf_print_tos_metrics(ndo, &rlp->un_tos)) + goto trunc; - rlp = (struct rlalink *)((u_char *)(rlp + 1) + + rlp = (const struct rlalink *)((const u_char *)(rlp + 1) + ((rlp->un_tos.link.link_tos_count) * sizeof(union un_tos))); } break; @@ -623,7 +690,7 @@ ospf_print_lsa(netdissect_options *ndo, ND_PRINT((ndo, "\n\t Mask %s\n\t Connected Routers:", ipaddr_string(ndo, &lsap->lsa_un.un_nla.nla_mask))); ap = lsap->lsa_un.un_nla.nla_router; - while ((u_char *)ap < ls_end) { + while ((const u_char *)ap < ls_end) { ND_TCHECK(*ap); ND_PRINT((ndo, "\n\t %s", ipaddr_string(ndo, ap))); ++ap; @@ -636,14 +703,14 @@ ospf_print_lsa(netdissect_options *ndo, 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 ((u_char *)lp < ls_end) { + while ((const u_char *)lp < ls_end) { register uint32_t ul; ND_TCHECK(*lp); ul = EXTRACT_32BITS(lp); topology = (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS; - ND_PRINT((ndo, "\n\t\ttopology %s(%u) metric %d", - tok2str(ospf_topology_values, "", topology), + ND_PRINT((ndo, "\n\t\ttopology %s (%u) metric %d", + tok2str(ospf_topology_values, "Unknown", topology), topology, ul & SLA_MASK_METRIC)); ++lp; @@ -653,14 +720,14 @@ ospf_print_lsa(netdissect_options *ndo, case LS_TYPE_SUM_ABR: ND_TCHECK(lsap->lsa_un.un_sla.sla_tosmetric); lp = lsap->lsa_un.un_sla.sla_tosmetric; - while ((u_char *)lp < ls_end) { + while ((const u_char *)lp < ls_end) { register uint32_t ul; ND_TCHECK(*lp); ul = EXTRACT_32BITS(lp); topology = (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS; - ND_PRINT((ndo, "\n\t\ttopology %s(%u) metric %d", - tok2str(ospf_topology_values, "", topology), + ND_PRINT((ndo, "\n\t\ttopology %s (%u) metric %d", + tok2str(ospf_topology_values, "Unknown", topology), topology, ul & SLA_MASK_METRIC)); ++lp; @@ -675,14 +742,14 @@ ospf_print_lsa(netdissect_options *ndo, ND_TCHECK(lsap->lsa_un.un_sla.sla_tosmetric); almp = lsap->lsa_un.un_asla.asla_metric; - while ((u_char *)almp < ls_end) { + while ((const u_char *)almp < ls_end) { register uint32_t ul; ND_TCHECK(almp->asla_tosmetric); ul = EXTRACT_32BITS(&almp->asla_tosmetric); topology = ((ul & ASLA_MASK_TOS) >> ASLA_SHIFT_TOS); - ND_PRINT((ndo, "\n\t\ttopology %s(%u), type %d, metric", - tok2str(ospf_topology_values, "", topology), + ND_PRINT((ndo, "\n\t\ttopology %s (%u), type %d, metric", + tok2str(ospf_topology_values, "Unknown", topology), topology, (ul & ASLA_FLAG_EXTERNAL) ? 2 : 1)); if ((ul & ASLA_MASK_METRIC) == 0xffffff) @@ -705,7 +772,7 @@ ospf_print_lsa(netdissect_options *ndo, case LS_TYPE_GROUP: /* Multicast extensions as of 23 July 1991 */ mcp = lsap->lsa_un.un_mcla; - while ((u_char *)mcp < ls_end) { + while ((const u_char *)mcp < ls_end) { ND_TCHECK(mcp->mcla_vid); switch (EXTRACT_32BITS(&mcp->mcla_vtype)) { @@ -734,7 +801,7 @@ ospf_print_lsa(netdissect_options *ndo, switch (*(&lsap->ls_hdr.un_lsa_id.opaque_field.opaque_type)) { case LS_OPAQUE_TYPE_RI: - tptr = (uint8_t *)(&lsap->lsa_un.un_ri_tlv.type); + tptr = (const uint8_t *)(&lsap->lsa_un.un_ri_tlv.type); while (ls_length != 0) { ND_TCHECK2(*tptr, 4); @@ -782,14 +849,14 @@ ospf_print_lsa(netdissect_options *ndo, break; case LS_OPAQUE_TYPE_GRACE: - if (ospf_print_grace_lsa(ndo, (uint8_t *)(&lsap->lsa_un.un_grace_tlv.type), + if (ospf_print_grace_lsa(ndo, (const uint8_t *)(&lsap->lsa_un.un_grace_tlv.type), ls_length) == -1) { return(ls_end); } break; case LS_OPAQUE_TYPE_TE: - if (ospf_print_te_lsa(ndo, (uint8_t *)(&lsap->lsa_un.un_te_lsa_tlv.type), + if (ospf_print_te_lsa(ndo, (const uint8_t *)(&lsap->lsa_un.un_te_lsa_tlv.type), ls_length) == -1) { return(ls_end); } @@ -797,7 +864,7 @@ ospf_print_lsa(netdissect_options *ndo, default: if (ndo->ndo_vflag <= 1) { - if (!print_unknown_data(ndo, (uint8_t *)lsap->lsa_un.un_unknown, + if (!print_unknown_data(ndo, (const uint8_t *)lsap->lsa_un.un_unknown, "\n\t ", ls_length)) return(ls_end); } @@ -807,7 +874,7 @@ ospf_print_lsa(netdissect_options *ndo, /* do we want to see an additionally hexdump ? */ if (ndo->ndo_vflag> 1) - if (!print_unknown_data(ndo, (uint8_t *)lsap->lsa_un.un_unknown, + if (!print_unknown_data(ndo, (const uint8_t *)lsap->lsa_un.un_unknown, "\n\t ", ls_length)) { return(ls_end); } @@ -845,8 +912,8 @@ ospf_decode_lls(netdissect_options *ndo, /* dig deeper if LLS data is available; see RFC4813 */ length2 = EXTRACT_16BITS(&op->ospf_len); - dptr = (u_char *)op + length2; - dataend = (u_char *)op + length; + 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]; @@ -929,6 +996,7 @@ ospf_decode_v2(netdissect_options *ndo, break; 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))); @@ -950,9 +1018,9 @@ ospf_decode_v2(netdissect_options *ndo, ipaddr_string(ndo, &op->ospf_hello.hello_bdr))); ap = op->ospf_hello.hello_neighbor; - if ((u_char *)ap < dataend) + if ((const u_char *)ap < dataend) ND_PRINT((ndo, "\n\t Neighbor List:")); - while ((u_char *)ap < dataend) { + while ((const u_char *)ap < dataend) { ND_TCHECK(*ap); ND_PRINT((ndo, "\n\t %s", ipaddr_string(ndo, ap))); ++ap; @@ -975,14 +1043,14 @@ ospf_decode_v2(netdissect_options *ndo, /* Print all the LS adv's */ lshp = op->ospf_db.db_lshdr; - while (((u_char *)lshp < dataend) && ospf_print_lshdr(ndo, lshp) != -1) { + while (((const u_char *)lshp < dataend) && ospf_print_lshdr(ndo, lshp) != -1) { ++lshp; } break; case OSPF_TYPE_LS_REQ: lsrp = op->ospf_lsr; - while ((u_char *)lsrp < dataend) { + while ((const u_char *)lsrp < dataend) { ND_TCHECK(*lsrp); ND_PRINT((ndo, "\n\t Advertising Router: %s, %s LSA (%u)", @@ -1047,7 +1115,7 @@ ospf_print(netdissect_options *ndo, register const u_char *dataend; register const char *cp; - op = (struct ospfhdr *)bp; + op = (const struct ospfhdr *)bp; /* XXX Before we do anything else, strip off the MD5 trailer */ ND_TCHECK(op->ospf_authtype); diff --git a/contrib/tcpdump/print-ospf6.c b/contrib/tcpdump/print-ospf6.c index 49210bc..e8a9dc6 100644 --- a/contrib/tcpdump/print-ospf6.c +++ b/contrib/tcpdump/print-ospf6.c @@ -21,16 +21,17 @@ * OSPF support contributed by Jeffrey Honig (jch@mitchell.cit.cornell.edu) */ -#define NETDISSECT_REWORKED +/* \summary: IPv6 Open Shortest Path First (OSPFv3) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" @@ -386,7 +387,7 @@ static int ospf6_print_lshdr(netdissect_options *ndo, register const struct lsa6_hdr *lshp, const u_char *dataend) { - if ((u_char *)(lshp + 1) > dataend) + if ((const u_char *)(lshp + 1) > dataend) goto trunc; ND_TCHECK(lshp->ls_type); ND_TCHECK(lshp->ls_seq); @@ -408,7 +409,7 @@ static int ospf6_print_lsaprefix(netdissect_options *ndo, const uint8_t *tptr, u_int lsa_length) { - const struct lsa6_prefix *lsapp = (struct lsa6_prefix *)tptr; + const struct lsa6_prefix *lsapp = (const struct lsa6_prefix *)tptr; u_int wordlen; struct in6_addr prefix; @@ -480,10 +481,10 @@ ospf6_print_lsa(netdissect_options *ndo, * If it does, find the length of what follows the * header. */ - if (length < sizeof(struct lsa6_hdr) || (u_char *)lsap + length > dataend) + if (length < sizeof(struct lsa6_hdr) || (const u_char *)lsap + length > dataend) return (1); lsa_length = length - sizeof(struct lsa6_hdr); - tptr = (uint8_t *)lsap+sizeof(struct lsa6_hdr); + tptr = (const uint8_t *)lsap+sizeof(struct lsa6_hdr); switch (EXTRACT_16BITS(&lsap->ls_hdr.ls_type)) { case LS_TYPE_ROUTER | LS_SCOPE_AREA: @@ -569,7 +570,7 @@ ospf6_print_lsa(netdissect_options *ndo, ND_PRINT((ndo, ", metric %u", EXTRACT_32BITS(&lsap->lsa_un.un_inter_ap.inter_ap_metric) & SLA_MASK_METRIC)); - tptr = (uint8_t *)lsap->lsa_un.un_inter_ap.inter_ap_prefix; + 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) @@ -591,8 +592,8 @@ ospf6_print_lsa(netdissect_options *ndo, EXTRACT_32BITS(&lsap->lsa_un.un_asla.asla_metric) & ASLA_MASK_METRIC)); - tptr = (uint8_t *)lsap->lsa_un.un_asla.asla_prefix; - lsapp = (struct lsa6_prefix *)tptr; + 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; @@ -600,9 +601,9 @@ ospf6_print_lsa(netdissect_options *ndo, tptr += bytelen; if ((flags32 & ASLA_FLAG_FWDADDR) != 0) { - struct in6_addr *fwdaddr6; + const struct in6_addr *fwdaddr6; - fwdaddr6 = (struct in6_addr *)tptr; + fwdaddr6 = (const struct in6_addr *)tptr; if (lsa_length < sizeof (*fwdaddr6)) return (1); lsa_length -= sizeof (*fwdaddr6); @@ -616,9 +617,9 @@ ospf6_print_lsa(netdissect_options *ndo, if (lsa_length < sizeof (uint32_t)) return (1); lsa_length -= sizeof (uint32_t); - ND_TCHECK(*(uint32_t *)tptr); + ND_TCHECK(*(const uint32_t *)tptr); ND_PRINT((ndo, " tag %s", - ipaddr_string(ndo, (uint32_t *)tptr))); + ipaddr_string(ndo, (const uint32_t *)tptr))); tptr += sizeof(uint32_t); } @@ -626,9 +627,9 @@ ospf6_print_lsa(netdissect_options *ndo, if (lsa_length < sizeof (uint32_t)) return (1); lsa_length -= sizeof (uint32_t); - ND_TCHECK(*(uint32_t *)tptr); + ND_TCHECK(*(const uint32_t *)tptr); ND_PRINT((ndo, " RefLSID: %s", - ipaddr_string(ndo, (uint32_t *)tptr))); + ipaddr_string(ndo, (const uint32_t *)tptr))); tptr += sizeof(uint32_t); } break; @@ -653,7 +654,7 @@ ospf6_print_lsa(netdissect_options *ndo, ip6addr_string(ndo, &llsap->llsa_lladdr), prefixes)); - tptr = (uint8_t *)llsap->llsa_prefix; + tptr = (const uint8_t *)llsap->llsa_prefix; while (prefixes > 0) { bytelen = ospf6_print_lsaprefix(ndo, tptr, lsa_length); if (bytelen < 0) @@ -681,7 +682,7 @@ ospf6_print_lsa(netdissect_options *ndo, prefixes = EXTRACT_16BITS(&lsap->lsa_un.un_intra_ap.intra_ap_nprefix); ND_PRINT((ndo, "\n\t Prefixes %d:", prefixes)); - tptr = (uint8_t *)lsap->lsa_un.un_intra_ap.intra_ap_prefix; + tptr = (const uint8_t *)lsap->lsa_un.un_intra_ap.intra_ap_prefix; while (prefixes > 0) { bytelen = ospf6_print_lsaprefix(ndo, tptr, lsa_length); if (bytelen < 0) @@ -732,7 +733,7 @@ ospf6_decode_v3(netdissect_options *ndo, switch (op->ospf6_type) { case OSPF_TYPE_HELLO: { - register const struct hello6 *hellop = (const struct hello6 *)((uint8_t *)op + OSPF6HDR_LEN); + register const struct hello6 *hellop = (const struct hello6 *)((const uint8_t *)op + OSPF6HDR_LEN); ND_PRINT((ndo, "\n\tOptions [%s]", bittok2str(ospf6_option_values, "none", @@ -756,7 +757,7 @@ ospf6_decode_v3(netdissect_options *ndo, if (ndo->ndo_vflag > 1) { ND_PRINT((ndo, "\n\t Neighbor List:")); ap = hellop->hello_neighbor; - while ((u_char *)ap < dataend) { + while ((const u_char *)ap < dataend) { ND_TCHECK(*ap); ND_PRINT((ndo, "\n\t %s", ipaddr_string(ndo, ap))); ++ap; @@ -766,7 +767,7 @@ ospf6_decode_v3(netdissect_options *ndo, } case OSPF_TYPE_DD: { - register const struct dd6 *ddp = (const struct dd6 *)((uint8_t *)op + OSPF6HDR_LEN); + register const struct dd6 *ddp = (const struct dd6 *)((const uint8_t *)op + OSPF6HDR_LEN); ND_TCHECK(ddp->db_options); ND_PRINT((ndo, "\n\tOptions [%s]", @@ -783,7 +784,7 @@ ospf6_decode_v3(netdissect_options *ndo, if (ndo->ndo_vflag > 1) { /* Print all the LS adv's */ lshp = ddp->db_lshdr; - while ((u_char *)lshp < dataend) { + while ((const u_char *)lshp < dataend) { if (ospf6_print_lshdr(ndo, lshp++, dataend)) goto trunc; } @@ -793,8 +794,8 @@ ospf6_decode_v3(netdissect_options *ndo, case OSPF_TYPE_LS_REQ: if (ndo->ndo_vflag > 1) { - lsrp = (const struct lsr6 *)((uint8_t *)op + OSPF6HDR_LEN); - while ((u_char *)lsrp < dataend) { + 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))); @@ -807,15 +808,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 *)((uint8_t *)op + OSPF6HDR_LEN); + register const struct lsu6 *lsup = (const struct lsu6 *)((const uint8_t *)op + OSPF6HDR_LEN); ND_TCHECK(lsup->lsu_count); i = EXTRACT_32BITS(&lsup->lsu_count); lsap = lsup->lsu_lsa; - while ((u_char *)lsap < dataend && i--) { + while ((const u_char *)lsap < dataend && i--) { if (ospf6_print_lsa(ndo, lsap, dataend)) goto trunc; - lsap = (struct lsa6 *)((u_char *)lsap + + lsap = (const struct lsa6 *)((const u_char *)lsap + EXTRACT_16BITS(&lsap->ls_hdr.ls_length)); } } @@ -823,8 +824,8 @@ ospf6_decode_v3(netdissect_options *ndo, case OSPF_TYPE_LS_ACK: if (ndo->ndo_vflag > 1) { - lshp = (const struct lsa6_hdr *)((uint8_t *)op + OSPF6HDR_LEN); - while ((u_char *)lshp < dataend) { + lshp = (const struct lsa6_hdr *)((const uint8_t *)op + OSPF6HDR_LEN); + while ((const u_char *)lshp < dataend) { if (ospf6_print_lshdr(ndo, lshp++, dataend)) goto trunc; } @@ -931,11 +932,11 @@ ospf6_decode_v3_trailer(netdissect_options *ndo, int lls_dd = 0; if (op->ospf6_type == OSPF_TYPE_HELLO) { - const struct hello6 *hellop = (const struct hello6 *)((uint8_t *)op + OSPF6HDR_LEN); + const struct hello6 *hellop = (const struct hello6 *)((const uint8_t *)op + OSPF6HDR_LEN); if (EXTRACT_32BITS(&hellop->hello_options) & OSPF6_OPTION_L) lls_hello = 1; } else if (op->ospf6_type == OSPF_TYPE_DD) { - const struct dd6 *ddp = (const struct dd6 *)((uint8_t *)op + OSPF6HDR_LEN); + const struct dd6 *ddp = (const struct dd6 *)((const uint8_t *)op + OSPF6HDR_LEN); if (EXTRACT_32BITS(&ddp->db_options) & OSPF6_OPTION_L) lls_dd = 1; } @@ -956,7 +957,7 @@ ospf6_print(netdissect_options *ndo, register const char *cp; uint16_t datalen; - op = (struct ospf6hdr *)bp; + 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 */ diff --git a/contrib/tcpdump/print-otv.c b/contrib/tcpdump/print-otv.c index 53a79de..5a82752 100644 --- a/contrib/tcpdump/print-otv.c +++ b/contrib/tcpdump/print-otv.c @@ -13,14 +13,17 @@ * Original code by Francesco Fondelli (francesco dot fondelli, gmail dot com) */ -#define NETDISSECT_REWORKED +/* \summary: Overlay Transport Virtualization (OTV) printer */ + +/* specification: draft-hasmit-otv-04 */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" /* @@ -39,27 +42,31 @@ void otv_print(netdissect_options *ndo, const u_char *bp, u_int len) { uint8_t flags; - uint32_t overlay_id; - uint32_t instance_id; - if (len < 8) { - ND_PRINT((ndo, "[|OTV]")); - return; - } + ND_PRINT((ndo, "OTV, ")); + if (len < 8) + goto trunc; + ND_TCHECK(*bp); flags = *bp; + ND_PRINT((ndo, "flags [%s] (0x%02x), ", flags & 0x08 ? "I" : ".", flags)); bp += 1; - overlay_id = EXTRACT_24BITS(bp); + ND_TCHECK2(*bp, 3); + ND_PRINT((ndo, "overlay %u, ", EXTRACT_24BITS(bp))); bp += 3; - instance_id = EXTRACT_24BITS(bp); - bp += 4; + ND_TCHECK2(*bp, 3); + ND_PRINT((ndo, "instance %u\n", EXTRACT_24BITS(bp))); + bp += 3; - ND_PRINT((ndo, "OTV, ")); - ND_PRINT((ndo, "flags [%s] (0x%02x), ", flags & 0x08 ? "I" : ".", flags)); - ND_PRINT((ndo, "overlay %u, ", overlay_id)); - ND_PRINT((ndo, "instance %u\n", instance_id)); + /* Reserved */ + ND_TCHECK(*bp); + bp += 1; + + ether_print(ndo, bp, len - 8, ndo->ndo_snapend - bp, NULL, NULL); + return; - ether_print(ndo, bp, len - 8, len - 8, NULL, NULL); +trunc: + ND_PRINT((ndo, " [|OTV]")); } diff --git a/contrib/tcpdump/print-pflog.c b/contrib/tcpdump/print-pflog.c index 72ae276..265efd3 100644 --- a/contrib/tcpdump/print-pflog.c +++ b/contrib/tcpdump/print-pflog.c @@ -19,7 +19,8 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: OpenBSD packet filter log file printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -33,9 +34,9 @@ #include #include -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" static const char tstr[] = "[|pflog]"; @@ -120,7 +121,7 @@ pflog_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, } #define MIN_PFLOG_HDRLEN 45 - hdr = (struct pfloghdr *)p; + hdr = (const struct pfloghdr *)p; if (hdr->length < MIN_PFLOG_HDRLEN) { ND_PRINT((ndo, "[pflog: invalid header length!]")); return (hdr->length); /* XXX: not really */ @@ -133,7 +134,6 @@ pflog_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, } /* print what we know */ - hdr = (struct pfloghdr *)p; ND_TCHECK(*hdr); if (ndo->ndo_eflag) pflog_print(ndo, hdr); diff --git a/contrib/tcpdump/print-pfsync.c b/contrib/tcpdump/print-pfsync.c index eb9aed8..6291333 100644 --- a/contrib/tcpdump/print-pfsync.c +++ b/contrib/tcpdump/print-pfsync.c @@ -33,17 +33,20 @@ #include "config.h" #endif -#include - +#ifndef HAVE_NET_PFVAR_H +#error "No pf headers available" +#endif #include #include -#include /* XXX */ +#include #include #define TCPSTATES #include +#include #include +#include "netdissect.h" #include "interface.h" #include "addrtoname.h" @@ -178,7 +181,7 @@ pfsync_print(netdissect_options *ndo, struct pfsync_header *hdr, break; } - if (vflag) + if (ndo->ndo_vflag) actions[subh->action].print(ndo, bp); bp += alen; @@ -234,7 +237,7 @@ pfsync_print_upd_c(netdissect_options *ndo, const void *bp) ND_PRINT((ndo, "\n\tid: %016jx creatorid: %08x", (uintmax_t)be64toh(u->id), ntohl(u->creatorid))); - if (vflag > 2) { + if (ndo->ndo_vflag > 2) { ND_PRINT((ndo, "\n\tTCP? :")); print_src_dst(ndo, &u->src, &u->dst, IPPROTO_TCP); } @@ -343,7 +346,7 @@ print_src_dst(netdissect_options *ndo, const struct pfsync_state_peer *src, else ND_PRINT((ndo, " ", src->state, dst->state)); - if (vflag > 1) { + if (ndo->ndo_vflag > 1) { ND_PRINT((ndo, "\n\t")); print_seq(ndo, src); if (src->wscale && dst->wscale) @@ -417,7 +420,7 @@ print_state(netdissect_options *ndo, struct pfsync_state *s) print_src_dst(ndo, src, dst, s->proto); - if (vflag > 1) { + if (ndo->ndo_vflag > 1) { uint64_t packets[2]; uint64_t bytes[2]; uint32_t creation = ntohl(s->creation); @@ -446,7 +449,7 @@ print_state(netdissect_options *ndo, struct pfsync_state *s) if (s->rule != ntohl(-1)) ND_PRINT((ndo, ", rule %u", ntohl(s->rule))); } - if (vflag > 1) { + if (ndo->ndo_vflag > 1) { uint64_t id; bcopy(&s->id, &id, sizeof(uint64_t)); diff --git a/contrib/tcpdump/print-pgm.c b/contrib/tcpdump/print-pgm.c index 6a83425..6d5c01c 100644 --- a/contrib/tcpdump/print-pgm.c +++ b/contrib/tcpdump/print-pgm.c @@ -13,21 +13,21 @@ * Original code by Andy Heffernan (ahh@juniper.net) */ -#define NETDISSECT_REWORKED +/* \summary: Pragmatic General Multicast (PGM) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "addrtoname.h" +#include "addrtostr.h" #include "ip.h" -#ifdef INET6 #include "ip6.h" -#endif #include "ipproto.h" #include "af.h" @@ -151,42 +151,26 @@ pgm_print(netdissect_options *ndo, register const struct ip *ip; register char ch; uint16_t sport, dport; - int addr_size; - const void *nla; - int nla_af; -#ifdef INET6 + u_int nla_afnum; char nla_buf[INET6_ADDRSTRLEN]; register const struct ip6_hdr *ip6; -#else - char nla_buf[INET_ADDRSTRLEN]; -#endif uint8_t opt_type, opt_len; uint32_t seq, opts_len, len, offset; - pgm = (struct pgm_header *)bp; - ip = (struct ip *)bp2; -#ifdef INET6 + pgm = (const struct pgm_header *)bp; + ip = (const struct ip *)bp2; if (IP_V(ip) == 6) - ip6 = (struct ip6_hdr *)bp2; + ip6 = (const struct ip6_hdr *)bp2; else ip6 = NULL; -#else /* INET6 */ - if (IP_V(ip) == 6) { - ND_PRINT((ndo, "Can't handle IPv6")); - return; - } -#endif /* INET6 */ ch = '\0'; if (!ND_TTEST(pgm->pgm_dport)) { -#ifdef INET6 if (ip6) { ND_PRINT((ndo, "%s > %s: [|pgm]", ip6addr_string(ndo, &ip6->ip6_src), ip6addr_string(ndo, &ip6->ip6_dst))); return; - } else -#endif /* INET6 */ - { + } else { ND_PRINT((ndo, "%s > %s: [|pgm]", ipaddr_string(ndo, &ip->ip_src), ipaddr_string(ndo, &ip->ip_dst))); @@ -197,30 +181,27 @@ pgm_print(netdissect_options *ndo, sport = EXTRACT_16BITS(&pgm->pgm_sport); dport = EXTRACT_16BITS(&pgm->pgm_dport); -#ifdef INET6 if (ip6) { if (ip6->ip6_nxt == IPPROTO_PGM) { ND_PRINT((ndo, "%s.%s > %s.%s: ", ip6addr_string(ndo, &ip6->ip6_src), - tcpport_string(sport), + tcpport_string(ndo, sport), ip6addr_string(ndo, &ip6->ip6_dst), - tcpport_string(dport))); + tcpport_string(ndo, dport))); } else { ND_PRINT((ndo, "%s > %s: ", - tcpport_string(sport), tcpport_string(dport))); + tcpport_string(ndo, sport), tcpport_string(ndo, dport))); } - } else -#endif /*INET6*/ - { + } else { if (ip->ip_p == IPPROTO_PGM) { ND_PRINT((ndo, "%s.%s > %s.%s: ", ipaddr_string(ndo, &ip->ip_src), - tcpport_string(sport), + tcpport_string(ndo, sport), ipaddr_string(ndo, &ip->ip_dst), - tcpport_string(dport))); + tcpport_string(ndo, dport))); } else { ND_PRINT((ndo, "%s > %s: ", - tcpport_string(sport), tcpport_string(dport))); + tcpport_string(ndo, sport), tcpport_string(ndo, dport))); } } @@ -240,32 +221,28 @@ pgm_print(netdissect_options *ndo, pgm->pgm_gsid[5])); switch (pgm->pgm_type) { case PGM_SPM: { - struct pgm_spm *spm; + const struct pgm_spm *spm; - spm = (struct pgm_spm *)(pgm + 1); + spm = (const struct pgm_spm *)(pgm + 1); ND_TCHECK(*spm); + bp = (const u_char *) (spm + 1); switch (EXTRACT_16BITS(&spm->pgms_nla_afi)) { case AFNUM_INET: - addr_size = sizeof(struct in_addr); - nla_af = AF_INET; + ND_TCHECK2(*bp, sizeof(struct in_addr)); + addrtostr(bp, nla_buf, sizeof(nla_buf)); + bp += sizeof(struct in_addr); break; -#ifdef INET6 case AFNUM_INET6: - addr_size = sizeof(struct in6_addr); - nla_af = AF_INET6; + ND_TCHECK2(*bp, sizeof(struct in6_addr)); + addrtostr6(bp, nla_buf, sizeof(nla_buf)); + bp += sizeof(struct in6_addr); break; -#endif default: goto trunc; break; } - bp = (u_char *) (spm + 1); - ND_TCHECK2(*bp, addr_size); - nla = bp; - bp += addr_size; - inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf)); ND_PRINT((ndo, "SPM seq %u trail %u lead %u nla %s", EXTRACT_32BITS(&spm->pgms_seq), EXTRACT_32BITS(&spm->pgms_trailseq), @@ -275,44 +252,39 @@ pgm_print(netdissect_options *ndo, } case PGM_POLL: { - struct pgm_poll *poll; + const struct pgm_poll *poll_msg; - poll = (struct pgm_poll *)(pgm + 1); - ND_TCHECK(*poll); + poll_msg = (const struct pgm_poll *)(pgm + 1); + ND_TCHECK(*poll_msg); ND_PRINT((ndo, "POLL seq %u round %u", - EXTRACT_32BITS(&poll->pgmp_seq), - EXTRACT_16BITS(&poll->pgmp_round))); - bp = (u_char *) (poll + 1); + EXTRACT_32BITS(&poll_msg->pgmp_seq), + EXTRACT_16BITS(&poll_msg->pgmp_round))); + bp = (const u_char *) (poll_msg + 1); break; } case PGM_POLR: { - struct pgm_polr *polr; + const struct pgm_polr *polr; uint32_t ivl, rnd, mask; - polr = (struct pgm_polr *)(pgm + 1); + polr = (const struct pgm_polr *)(pgm + 1); ND_TCHECK(*polr); + bp = (const u_char *) (polr + 1); switch (EXTRACT_16BITS(&polr->pgmp_nla_afi)) { case AFNUM_INET: - addr_size = sizeof(struct in_addr); - nla_af = AF_INET; + ND_TCHECK2(*bp, sizeof(struct in_addr)); + addrtostr(bp, nla_buf, sizeof(nla_buf)); + bp += sizeof(struct in_addr); break; -#ifdef INET6 case AFNUM_INET6: - addr_size = sizeof(struct in6_addr); - nla_af = AF_INET6; + ND_TCHECK2(*bp, sizeof(struct in6_addr)); + addrtostr6(bp, nla_buf, sizeof(nla_buf)); + bp += sizeof(struct in6_addr); break; -#endif default: goto trunc; break; } - bp = (u_char *) (polr + 1); - ND_TCHECK2(*bp, addr_size); - nla = bp; - bp += addr_size; - - inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf)); ND_TCHECK2(*bp, sizeof(uint32_t)); ivl = EXTRACT_32BITS(bp); @@ -332,43 +304,38 @@ pgm_print(netdissect_options *ndo, break; } case PGM_ODATA: { - struct pgm_data *odata; + const struct pgm_data *odata; - odata = (struct pgm_data *)(pgm + 1); + 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))); - bp = (u_char *) (odata + 1); + bp = (const u_char *) (odata + 1); break; } case PGM_RDATA: { - struct pgm_data *rdata; + const struct pgm_data *rdata; - rdata = (struct pgm_data *)(pgm + 1); + 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))); - bp = (u_char *) (rdata + 1); + bp = (const u_char *) (rdata + 1); break; } case PGM_NAK: case PGM_NULLNAK: case PGM_NCF: { - struct pgm_nak *nak; - const void *source, *group; - int source_af, group_af; -#ifdef INET6 + const struct pgm_nak *nak; char source_buf[INET6_ADDRSTRLEN], group_buf[INET6_ADDRSTRLEN]; -#else - char source_buf[INET_ADDRSTRLEN], group_buf[INET_ADDRSTRLEN]; -#endif - nak = (struct pgm_nak *)(pgm + 1); + nak = (const struct pgm_nak *)(pgm + 1); ND_TCHECK(*nak); + bp = (const u_char *) (nak + 1); /* * Skip past the source, saving info along the way @@ -376,53 +343,44 @@ pgm_print(netdissect_options *ndo, */ switch (EXTRACT_16BITS(&nak->pgmn_source_afi)) { case AFNUM_INET: - addr_size = sizeof(struct in_addr); - source_af = AF_INET; + ND_TCHECK2(*bp, sizeof(struct in_addr)); + addrtostr(bp, source_buf, sizeof(source_buf)); + bp += sizeof(struct in_addr); break; -#ifdef INET6 case AFNUM_INET6: - addr_size = sizeof(struct in6_addr); - source_af = AF_INET6; + ND_TCHECK2(*bp, sizeof(struct in6_addr)); + addrtostr6(bp, source_buf, sizeof(source_buf)); + bp += sizeof(struct in6_addr); break; -#endif default: goto trunc; break; } - bp = (u_char *) (nak + 1); - ND_TCHECK2(*bp, addr_size); - source = bp; - bp += addr_size; /* * Skip past the group, saving info along the way * and stopping if we don't have enough. */ + bp += (2 * sizeof(uint16_t)); switch (EXTRACT_16BITS(bp)) { case AFNUM_INET: - addr_size = sizeof(struct in_addr); - group_af = AF_INET; + ND_TCHECK2(*bp, sizeof(struct in_addr)); + addrtostr(bp, group_buf, sizeof(group_buf)); + bp += sizeof(struct in_addr); break; -#ifdef INET6 case AFNUM_INET6: - addr_size = sizeof(struct in6_addr); - group_af = AF_INET6; + ND_TCHECK2(*bp, sizeof(struct in6_addr)); + addrtostr6(bp, group_buf, sizeof(group_buf)); + bp += sizeof(struct in6_addr); break; -#endif default: goto trunc; break; } - bp += (2 * sizeof(uint16_t)); - ND_TCHECK2(*bp, addr_size); - group = bp; - bp += addr_size; /* * Options decoding can go here. */ - inet_ntop(source_af, source, source_buf, sizeof(source_buf)); - inet_ntop(group_af, group, group_buf, sizeof(group_buf)); switch (pgm->pgm_type) { case PGM_NAK: ND_PRINT((ndo, "NAK ")); @@ -442,13 +400,13 @@ pgm_print(netdissect_options *ndo, } case PGM_ACK: { - struct pgm_ack *ack; + const struct pgm_ack *ack; - ack = (struct pgm_ack *)(pgm + 1); + ack = (const struct pgm_ack *)(pgm + 1); ND_TCHECK(*ack); ND_PRINT((ndo, "ACK seq %u", EXTRACT_32BITS(&ack->pgma_rx_max_seq))); - bp = (u_char *) (ack + 1); + bp = (const u_char *) (ack + 1); break; } @@ -601,33 +559,35 @@ pgm_print(netdissect_options *ndo, case PGM_OPT_REDIRECT: bp += 2; - switch (EXTRACT_16BITS(bp)) { + nla_afnum = EXTRACT_16BITS(bp); + bp += (2 * sizeof(uint16_t)); + switch (nla_afnum) { case AFNUM_INET: - addr_size = sizeof(struct in_addr); - nla_af = AF_INET; + if (opt_len != 4 + sizeof(struct in_addr)) { + ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u != 4 + address size]", opt_len)); + return; + } + ND_TCHECK2(*bp, sizeof(struct in_addr)); + addrtostr(bp, nla_buf, sizeof(nla_buf)); + bp += sizeof(struct in_addr); + opts_len -= 4 + sizeof(struct in_addr); break; -#ifdef INET6 case AFNUM_INET6: - addr_size = sizeof(struct in6_addr); - nla_af = AF_INET6; + if (opt_len != 4 + sizeof(struct in6_addr)) { + ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u != 4 + address size]", opt_len)); + return; + } + ND_TCHECK2(*bp, sizeof(struct in6_addr)); + addrtostr6(bp, nla_buf, sizeof(nla_buf)); + bp += sizeof(struct in6_addr); + opts_len -= 4 + sizeof(struct in6_addr); break; -#endif default: goto trunc; break; } - bp += (2 * sizeof(uint16_t)); - if (opt_len != 4 + addr_size) { - ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u != 4 + address size]", opt_len)); - return; - } - ND_TCHECK2(*bp, addr_size); - nla = bp; - bp += addr_size; - inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf)); - ND_PRINT((ndo, " REDIRECT %s", (char *)nla)); - opts_len -= 4 + addr_size; + ND_PRINT((ndo, " REDIRECT %s", nla_buf)); break; case PGM_OPT_PARITY_PRM: @@ -732,66 +692,70 @@ pgm_print(netdissect_options *ndo, bp += 2; offset = EXTRACT_32BITS(bp); bp += sizeof(uint32_t); - switch (EXTRACT_16BITS(bp)) { + nla_afnum = EXTRACT_16BITS(bp); + bp += (2 * sizeof(uint16_t)); + switch (nla_afnum) { case AFNUM_INET: - addr_size = sizeof(struct in_addr); - nla_af = AF_INET; + if (opt_len != 12 + sizeof(struct in_addr)) { + ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len)); + return; + } + ND_TCHECK2(*bp, sizeof(struct in_addr)); + addrtostr(bp, nla_buf, sizeof(nla_buf)); + bp += sizeof(struct in_addr); + opts_len -= 12 + sizeof(struct in_addr); break; -#ifdef INET6 case AFNUM_INET6: - addr_size = sizeof(struct in6_addr); - nla_af = AF_INET6; + if (opt_len != 12 + sizeof(struct in6_addr)) { + ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len)); + return; + } + ND_TCHECK2(*bp, sizeof(struct in6_addr)); + addrtostr6(bp, nla_buf, sizeof(nla_buf)); + bp += sizeof(struct in6_addr); + opts_len -= 12 + sizeof(struct in6_addr); break; -#endif default: goto trunc; break; } - bp += (2 * sizeof(uint16_t)); - if (opt_len != 12 + addr_size) { - ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len)); - return; - } - ND_TCHECK2(*bp, addr_size); - nla = bp; - bp += addr_size; - inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf)); - ND_PRINT((ndo, " PGMCC DATA %u %s", offset, (char*)nla)); - opts_len -= 16; + ND_PRINT((ndo, " PGMCC DATA %u %s", offset, nla_buf)); break; case PGM_OPT_PGMCC_FEEDBACK: bp += 2; offset = EXTRACT_32BITS(bp); bp += sizeof(uint32_t); - switch (EXTRACT_16BITS(bp)) { + nla_afnum = EXTRACT_16BITS(bp); + bp += (2 * sizeof(uint16_t)); + switch (nla_afnum) { case AFNUM_INET: - addr_size = sizeof(struct in_addr); - nla_af = AF_INET; + if (opt_len != 12 + sizeof(struct in_addr)) { + ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len)); + return; + } + ND_TCHECK2(*bp, sizeof(struct in_addr)); + addrtostr(bp, nla_buf, sizeof(nla_buf)); + bp += sizeof(struct in_addr); + opts_len -= 12 + sizeof(struct in_addr); break; -#ifdef INET6 case AFNUM_INET6: - addr_size = sizeof(struct in6_addr); - nla_af = AF_INET6; + if (opt_len != 12 + sizeof(struct in6_addr)) { + ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len)); + return; + } + ND_TCHECK2(*bp, sizeof(struct in6_addr)); + addrtostr6(bp, nla_buf, sizeof(nla_buf)); + bp += sizeof(struct in6_addr); + opts_len -= 12 + sizeof(struct in6_addr); break; -#endif default: goto trunc; break; } - bp += (2 * sizeof(uint16_t)); - if (opt_len != 12 + addr_size) { - ND_PRINT((ndo, "[Bad OPT_PGMCC_FEEDBACK option, length %u != 12 + address size]", opt_len)); - return; - } - ND_TCHECK2(*bp, addr_size); - nla = bp; - bp += addr_size; - inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf)); - ND_PRINT((ndo, " PGMCC FEEDBACK %u %s", offset, (char*)nla)); - opts_len -= 16; + ND_PRINT((ndo, " PGMCC FEEDBACK %u %s", offset, nla_buf)); break; default: diff --git a/contrib/tcpdump/print-pim.c b/contrib/tcpdump/print-pim.c index 6738e37..2552595 100644 --- a/contrib/tcpdump/print-pim.c +++ b/contrib/tcpdump/print-pim.c @@ -17,22 +17,23 @@ * 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. - * - * $FreeBSD$ */ -#define NETDISSECT_REWORKED +/* \summary: Protocol Independent Multicast (PIM) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" #include "ip.h" +#include "ip6.h" +#include "ipproto.h" #define PIMV1_TYPE_QUERY 0 #define PIMV1_TYPE_REGISTER 1 @@ -136,7 +137,7 @@ struct pim { u_short pim_cksum; /* IP style check sum */ }; -static void pimv2_print(netdissect_options *, register const u_char *bp, register u_int len, u_int cksum); +static void pimv2_print(netdissect_options *, register const u_char *bp, register u_int len, const u_char *); static void pimv1_join_prune_print(netdissect_options *ndo, @@ -154,7 +155,7 @@ pimv1_join_prune_print(netdissect_options *ndo, hold = EXTRACT_16BITS(&bp[6]); if (hold != 180) { ND_PRINT((ndo, "Hold ")); - relts_print(ndo, hold); + unsigned_relts_print(ndo, hold); } ND_PRINT((ndo, "%s (%s/%d, %s", njoin ? "Join" : "Prune", ipaddr_string(ndo, &bp[26]), bp[25] & 0x3f, @@ -176,7 +177,7 @@ pimv1_join_prune_print(netdissect_options *ndo, if (ndo->ndo_vflag > 1) ND_PRINT((ndo, "\n")); ND_PRINT((ndo, " Hold time: ")); - relts_print(ndo, EXTRACT_16BITS(&bp[6])); + unsigned_relts_print(ndo, EXTRACT_16BITS(&bp[6])); if (ndo->ndo_vflag < 2) return; bp += 8; @@ -261,7 +262,7 @@ pimv1_print(netdissect_options *ndo, if (ndo->ndo_vflag) { ND_TCHECK2(bp[10],2); ND_PRINT((ndo, " (Hold-time ")); - relts_print(ndo, EXTRACT_16BITS(&bp[10])); + unsigned_relts_print(ndo, EXTRACT_16BITS(&bp[10])); ND_PRINT((ndo, ")")); } break; @@ -283,7 +284,7 @@ pimv1_print(netdissect_options *ndo, 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]))); - relts_print(ndo, EXTRACT_16BITS(&bp[22])); + unsigned_relts_print(ndo, EXTRACT_16BITS(&bp[22])); } break; case PIMV1_TYPE_ASSERT: @@ -350,7 +351,7 @@ cisco_autorp_print(netdissect_options *ndo, ND_PRINT((ndo, " Hold ")); hold = EXTRACT_16BITS(&bp[2]); if (hold) - relts_print(ndo, EXTRACT_16BITS(&bp[2])); + unsigned_relts_print(ndo, EXTRACT_16BITS(&bp[2])); else ND_PRINT((ndo, "FOREVER")); @@ -417,10 +418,10 @@ trunc: void pim_print(netdissect_options *ndo, - register const u_char *bp, register u_int len, u_int cksum) + register const u_char *bp, register u_int len, const u_char *bp2) { register const u_char *ep; - register struct pim *pim = (struct pim *)bp; + register const struct pim *pim = (const struct pim *)bp; ep = (const u_char *)ndo->ndo_snapend; if (bp >= ep) @@ -442,7 +443,7 @@ pim_print(netdissect_options *ndo, PIM_VER(pim->pim_typever), len, tok2str(pimv2_type_values,"Unknown Type",PIM_TYPE(pim->pim_typever)))); - pimv2_print(ndo, bp, len, cksum); + pimv2_print(ndo, bp, len, bp2); } break; default: @@ -536,12 +537,10 @@ pimv2_addr_print(netdissect_options *ndo, af = AF_INET; len = sizeof(struct in_addr); break; -#ifdef INET6 case 2: af = AF_INET6; len = sizeof(struct in6_addr); break; -#endif default: return -1; } @@ -553,11 +552,9 @@ pimv2_addr_print(netdissect_options *ndo, case sizeof(struct in_addr): af = AF_INET; break; -#ifdef INET6 case sizeof(struct in6_addr): af = AF_INET6; break; -#endif default: return -1; break; @@ -574,12 +571,10 @@ pimv2_addr_print(netdissect_options *ndo, if (!silent) ND_PRINT((ndo, "%s", ipaddr_string(ndo, bp))); } -#ifdef INET6 else if (af == AF_INET6) { if (!silent) ND_PRINT((ndo, "%s", ip6addr_string(ndo, bp))); } -#endif return hdrlen + len; case pimv2_group: case pimv2_source: @@ -591,7 +586,6 @@ pimv2_addr_print(netdissect_options *ndo, ND_PRINT((ndo, "/%u", bp[1])); } } -#ifdef INET6 else if (af == AF_INET6) { if (!silent) { ND_PRINT((ndo, "%s", ip6addr_string(ndo, bp + 2))); @@ -599,7 +593,6 @@ pimv2_addr_print(netdissect_options *ndo, ND_PRINT((ndo, "/%u", bp[1])); } } -#endif if (bp[0] && !silent) { if (at == pimv2_group) { ND_PRINT((ndo, "(0x%02x)", bp[0])); @@ -622,13 +615,50 @@ trunc: return -1; } +enum checksum_status { + CORRECT, + INCORRECT, + UNVERIFIED +}; + +static enum checksum_status +pimv2_check_checksum(netdissect_options *ndo, const u_char *bp, + const u_char *bp2, u_int len) +{ + const struct ip *ip; + u_int cksum; + + if (!ND_TTEST2(bp[0], len)) { + /* We don't have all the data. */ + return (UNVERIFIED); + } + ip = (const struct ip *)bp2; + if (IP_V(ip) == 4) { + struct cksum_vec vec[1]; + + vec[0].ptr = bp; + vec[0].len = len; + cksum = in_cksum(vec, 1); + return (cksum ? INCORRECT : CORRECT); + } else if (IP_V(ip) == 6) { + const struct ip6_hdr *ip6; + + ip6 = (const struct ip6_hdr *)bp2; + cksum = nextproto6_cksum(ndo, ip6, bp, len, len, IPPROTO_PIM); + return (cksum ? INCORRECT : CORRECT); + } else { + return (UNVERIFIED); + } +} + static void pimv2_print(netdissect_options *ndo, - register const u_char *bp, register u_int len, u_int cksum) + register const u_char *bp, register u_int len, const u_char *bp2) { register const u_char *ep; - register struct pim *pim = (struct pim *)bp; + register const struct pim *pim = (const struct pim *)bp; int advance; + enum checksum_status cksum_status; ep = (const u_char *)ndo->ndo_snapend; if (bp >= ep) @@ -644,7 +674,41 @@ pimv2_print(netdissect_options *ndo, if (EXTRACT_16BITS(&pim->pim_cksum) == 0) { ND_PRINT((ndo, "(unverified)")); } else { - ND_PRINT((ndo, "(%scorrect)", ND_TTEST2(bp[0], len) && cksum ? "in" : "" )); + if (PIM_TYPE(pim->pim_typever) == PIMV2_TYPE_REGISTER) { + /* + * The checksum only covers the packet header, + * not the encapsulated packet. + */ + cksum_status = pimv2_check_checksum(ndo, bp, bp2, 8); + if (cksum_status == INCORRECT) { + /* + * To quote RFC 4601, "For interoperability + * reasons, a message carrying a checksum + * calculated over the entire PIM Register + * message should also be accepted." + */ + cksum_status = pimv2_check_checksum(ndo, bp, bp2, len); + } + } else { + /* + * The checksum covers the entire packet. + */ + cksum_status = pimv2_check_checksum(ndo, bp, bp2, len); + } + switch (cksum_status) { + + case CORRECT: + ND_PRINT((ndo, "(correct)")); + break; + + case INCORRECT: + ND_PRINT((ndo, "(incorrect)")); + break; + + case UNVERIFIED: + ND_PRINT((ndo, "(unverified)")); + break; + } } switch (PIM_TYPE(pim->pim_typever)) { @@ -665,7 +729,7 @@ pimv2_print(netdissect_options *ndo, switch (otype) { case PIMV2_HELLO_OPTION_HOLDTIME: - relts_print(ndo, EXTRACT_16BITS(bp)); + unsigned_relts_print(ndo, EXTRACT_16BITS(bp)); break; case PIMV2_HELLO_OPTION_LANPRUNEDELAY: @@ -706,7 +770,7 @@ pimv2_print(netdissect_options *ndo, ND_PRINT((ndo, "v%d", *bp)); if (*(bp+1) != 0) { ND_PRINT((ndo, ", interval ")); - relts_print(ndo, *(bp+1)); + unsigned_relts_print(ndo, *(bp+1)); } if (EXTRACT_16BITS(bp+2) != 0) { ND_PRINT((ndo, " ?0x%04x?", EXTRACT_16BITS(bp+2))); @@ -721,8 +785,6 @@ pimv2_print(netdissect_options *ndo, if (ndo->ndo_vflag > 1) { const u_char *ptr = bp; while (ptr < (bp+olen)) { - int advance; - ND_PRINT((ndo, "\n\t ")); advance = pimv2_addr_print(ndo, ptr, pimv2_unicast, 0); if (advance < 0) { @@ -748,7 +810,7 @@ pimv2_print(netdissect_options *ndo, case PIMV2_TYPE_REGISTER: { - struct ip *ip; + const struct ip *ip; ND_TCHECK2(*(bp + 4), PIMV2_REGISTER_FLAG_LEN); @@ -759,7 +821,7 @@ pimv2_print(netdissect_options *ndo, bp += 8; len -= 8; /* encapsulated multicast packet */ - ip = (struct ip *)bp; + ip = (const struct ip *)bp; switch (IP_V(ip)) { case 0: /* Null header */ ND_PRINT((ndo, "IP-Null-header %s > %s", @@ -870,7 +932,7 @@ pimv2_print(netdissect_options *ndo, if (holdtime == 0xffff) ND_PRINT((ndo, "infinite")); else - relts_print(ndo, holdtime); + unsigned_relts_print(ndo, holdtime); } bp += 4; len -= 4; for (i = 0; i < ngroup; i++) { @@ -974,7 +1036,7 @@ pimv2_print(netdissect_options *ndo, goto bs_done; } ND_PRINT((ndo, ",holdtime=")); - relts_print(ndo, EXTRACT_16BITS(bp)); + unsigned_relts_print(ndo, EXTRACT_16BITS(bp)); if (bp + 2 >= ep) { ND_PRINT((ndo, "...)")); goto bs_done; @@ -1026,7 +1088,7 @@ pimv2_print(netdissect_options *ndo, ND_PRINT((ndo, " prio=%d", bp[1])); if (bp + 3 >= ep) break; ND_PRINT((ndo, " holdtime=")); - relts_print(ndo, EXTRACT_16BITS(&bp[2])); + unsigned_relts_print(ndo, EXTRACT_16BITS(&bp[2])); bp += 4; /* Encoded-Unicast-RP-Address */ @@ -1072,7 +1134,7 @@ pimv2_print(netdissect_options *ndo, bp += advance; ND_TCHECK2(bp[0], 2); ND_PRINT((ndo, " TUNR ")); - relts_print(ndo, EXTRACT_16BITS(bp)); + unsigned_relts_print(ndo, EXTRACT_16BITS(bp)); break; diff --git a/contrib/tcpdump/print-pktap.c b/contrib/tcpdump/print-pktap.c index 46a187d..7144f3c 100644 --- a/contrib/tcpdump/print-pktap.c +++ b/contrib/tcpdump/print-pktap.c @@ -19,14 +19,15 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: Apple's DLT_PKTAP printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #ifdef DLT_PKTAP @@ -71,16 +72,18 @@ pktap_header_print(netdissect_options *ndo, const u_char *bp, u_int length) { const pktap_header_t *hdr; uint32_t dlt, hdrlen; + const char *dltname; hdr = (const pktap_header_t *)bp; dlt = EXTRACT_LE_32BITS(&hdr->pkt_dlt); hdrlen = EXTRACT_LE_32BITS(&hdr->pkt_len); + dltname = pcap_datalink_val_to_name(dlt); if (!ndo->ndo_qflag) { - ND_PRINT((ndo,", DLT %s (%d) len %d", - pcap_datalink_val_to_name(dlt), dlt, hdrlen)); + ND_PRINT((ndo,"DLT %s (%d) len %d", + (dltname != NULL ? dltname : "UNKNOWN"), dlt, hdrlen)); } else { - ND_PRINT((ndo,", %s", pcap_datalink_val_to_name(dlt))); + ND_PRINT((ndo,"%s", (dltname != NULL ? dltname : "UNKNOWN"))); } ND_PRINT((ndo, ", length %u: ", length)); @@ -99,15 +102,14 @@ pktap_if_print(netdissect_options *ndo, uint32_t dlt, hdrlen, rectype; u_int caplen = h->caplen; u_int length = h->len; - if_ndo_printer ndo_printer; - if_printer printer; - pktap_header_t *hdr; + if_printer printer; + const pktap_header_t *hdr; if (caplen < sizeof(pktap_header_t) || length < sizeof(pktap_header_t)) { ND_PRINT((ndo, "[|pktap]")); return (0); } - hdr = (pktap_header_t *)p; + hdr = (const pktap_header_t *)p; dlt = EXTRACT_LE_32BITS(&hdr->pkt_dlt); hdrlen = EXTRACT_LE_32BITS(&hdr->pkt_len); if (hdrlen < sizeof(pktap_header_t)) { @@ -142,12 +144,10 @@ pktap_if_print(netdissect_options *ndo, case PKT_REC_PACKET: if ((printer = lookup_printer(dlt)) != NULL) { - printer(h, p); - } else if ((ndo_printer = lookup_ndo_printer(dlt)) != NULL) { - ndo_printer(ndo, h, p); + hdrlen += printer(ndo, h, p); } else { if (!ndo->ndo_eflag) - pktap_header_print(ndo, (u_char *)hdr, + pktap_header_print(ndo, (const u_char *)hdr, length + hdrlen); if (!ndo->ndo_suppress_default_print) diff --git a/contrib/tcpdump/print-ppi.c b/contrib/tcpdump/print-ppi.c index b403536..72cd1b8 100644 --- a/contrib/tcpdump/print-ppi.c +++ b/contrib/tcpdump/print-ppi.c @@ -1,14 +1,16 @@ /* * Oracle */ -#define NETDISSECT_REWORKED + +/* \summary: Oracle DLT_PPI printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" typedef struct ppi_header { @@ -28,49 +30,56 @@ ppi_header_print(netdissect_options *ndo, const u_char *bp, u_int length) const ppi_header_t *hdr; uint16_t len; uint32_t dlt; + const char *dltname; hdr = (const ppi_header_t *)bp; len = EXTRACT_LE_16BITS(&hdr->ppi_len); dlt = EXTRACT_LE_32BITS(&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, - pcap_datalink_val_to_name(dlt), dlt, + (dltname != NULL ? dltname : "UNKNOWN"), dlt, len)); } else { - ND_PRINT((ndo, "%s", pcap_datalink_val_to_name(dlt))); + ND_PRINT((ndo, "%s", (dltname != NULL ? dltname : "UNKNOWN"))); } ND_PRINT((ndo, ", length %u: ", length)); } -static void +static u_int ppi_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { - if_ndo_printer ndo_printer; - if_printer printer; - ppi_header_t *hdr; + if_printer printer; + const ppi_header_t *hdr; u_int caplen = h->caplen; u_int length = h->len; uint16_t len; uint32_t dlt; + uint32_t hdrlen; + struct pcap_pkthdr nhdr; if (caplen < sizeof(ppi_header_t)) { ND_PRINT((ndo, "[|ppi]")); - return; + return (caplen); } - hdr = (ppi_header_t *)p; + hdr = (const ppi_header_t *)p; len = EXTRACT_LE_16BITS(&hdr->ppi_len); - if (len < sizeof(ppi_header_t)) { + if (caplen < len) { + /* + * If we don't have the entire PPI header, don't + * bother. + */ ND_PRINT((ndo, "[|ppi]")); - return; + return (caplen); } - if (caplen < len) { + if (len < sizeof(ppi_header_t)) { ND_PRINT((ndo, "[|ppi]")); - return; + return (len); } dlt = EXTRACT_LE_32BITS(&hdr->ppi_dlt); @@ -82,16 +91,19 @@ ppi_print(netdissect_options *ndo, p += len; if ((printer = lookup_printer(dlt)) != NULL) { - printer(h, p); - } else if ((ndo_printer = lookup_ndo_printer(dlt)) != NULL) { - ndo_printer(ndo, h, p); + nhdr = *h; + nhdr.caplen = caplen; + nhdr.len = length; + hdrlen = printer(ndo, &nhdr, p); } else { if (!ndo->ndo_eflag) - ppi_header_print(ndo, (u_char *)hdr, length + len); + ppi_header_print(ndo, (const u_char *)hdr, length + len); if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); + hdrlen = 0; } + return (len + hdrlen); } /* @@ -104,9 +116,7 @@ u_int ppi_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { - ppi_print(ndo, h, p); - - return (sizeof(ppi_header_t)); + return (ppi_print(ndo, h, p)); } /* diff --git a/contrib/tcpdump/print-ppp.c b/contrib/tcpdump/print-ppp.c index 7e4870d..ee8239c 100644 --- a/contrib/tcpdump/print-ppp.c +++ b/contrib/tcpdump/print-ppp.c @@ -20,10 +20,10 @@ * * Extensively modified by Motonori Shindo (mshindo@mshindo.net) for more * complete PPP support. - * - * $FreeBSD$ */ +/* \summary: Point to Point Protocol (PPP) printer */ + /* * TODO: * o resolve XXX as much as possible @@ -31,12 +31,11 @@ * o BAP support */ -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #ifdef __bsdi__ #include @@ -45,7 +44,7 @@ #include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "addrtoname.h" #include "ppp.h" @@ -945,6 +944,9 @@ handle_pap(netdissect_options *ndo, switch (code) { case PAP_AREQ: + /* A valid Authenticate-Request is 6 or more octets long. */ + if (len < 6) + goto trunc; if (length - (p - p0) < 1) return; ND_TCHECK(*p); @@ -973,6 +975,13 @@ handle_pap(netdissect_options *ndo, break; case PAP_AACK: case PAP_ANAK: + /* Although some implementations ignore truncation at + * this point and at least one generates a truncated + * packet, RFC 1334 section 2.2.2 clearly states that + * both AACK and ANAK are at least 5 bytes long. + */ + if (len < 5) + goto trunc; if (length - (p - p0) < 1) return; ND_TCHECK(*p); @@ -1672,6 +1681,11 @@ ppp_hdlc_if_print(netdissect_options *ndo, return (chdlc_if_print(ndo, h, p)); default: + if (caplen < 4) { + ND_PRINT((ndo, "[|ppp]")); + return (caplen); + } + if (ndo->ndo_eflag) ND_PRINT((ndo, "%02x %02x %d ", p[0], p[1], length)); p += 2; diff --git a/contrib/tcpdump/print-pppoe.c b/contrib/tcpdump/print-pppoe.c index 1624c5e..23d9a23 100644 --- a/contrib/tcpdump/print-pppoe.c +++ b/contrib/tcpdump/print-pppoe.c @@ -21,15 +21,16 @@ * Original code by Greg Stark */ -#define NETDISSECT_REWORKED +/* \summary: PPP-over-Ethernet (PPPoE) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" -#include "extract.h" /* must come after interface.h */ +#include "netdissect.h" +#include "extract.h" /* Codes */ enum { @@ -147,7 +148,7 @@ pppoe_print(netdissect_options *ndo, register const u_char *bp, u_int length) /* p points to tag_value */ if (tag_len) { - unsigned isascii = 0, isgarbage = 0; + unsigned ascii_count = 0, garbage_count = 0; const u_char *v; char tag_str[MAXTAGPRINT]; unsigned tag_str_len = 0; @@ -157,14 +158,14 @@ pppoe_print(netdissect_options *ndo, register const u_char *bp, u_int length) for (v = p; v < p + tag_len && tag_str_len < MAXTAGPRINT-1; v++) if (*v >= 32 && *v < 127) { tag_str[tag_str_len++] = *v; - isascii++; + ascii_count++; } else { tag_str[tag_str_len++] = '.'; - isgarbage++; + garbage_count++; } tag_str[tag_str_len] = 0; - if (isascii > isgarbage) { + if (ascii_count > garbage_count) { ND_PRINT((ndo, " [%s \"%*.*s\"]", tok2str(pppoetag2str, "TAG-0x%x", tag_type), (int)tag_str_len, diff --git a/contrib/tcpdump/print-pptp.c b/contrib/tcpdump/print-pptp.c index c77868d..a4d713d 100644 --- a/contrib/tcpdump/print-pptp.c +++ b/contrib/tcpdump/print-pptp.c @@ -21,14 +21,15 @@ * PPTP support contributed by Motonori Shindo (mshindo@mshindo.net) */ -#define NETDISSECT_REWORKED +/* \summary: Point-to-Point Tunnelling Protocol (PPTP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" static const char tstr[] = " [|pptp]"; @@ -518,7 +519,7 @@ static void pptp_sccrq_print(netdissect_options *ndo, const u_char *dat) { - struct pptp_msg_sccrq *ptr = (struct pptp_msg_sccrq *)dat; + 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); @@ -546,7 +547,7 @@ static void pptp_sccrp_print(netdissect_options *ndo, const u_char *dat) { - struct pptp_msg_sccrp *ptr = (struct pptp_msg_sccrp *)dat; + 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); @@ -577,7 +578,7 @@ static void pptp_stopccrq_print(netdissect_options *ndo, const u_char *dat) { - struct pptp_msg_stopccrq *ptr = (struct pptp_msg_stopccrq *)dat; + const struct pptp_msg_stopccrq *ptr = (const struct pptp_msg_stopccrq *)dat; ND_TCHECK(ptr->reason); ND_PRINT((ndo, " REASON(%u", ptr->reason)); @@ -611,7 +612,7 @@ static void pptp_stopccrp_print(netdissect_options *ndo, const u_char *dat) { - struct pptp_msg_stopccrp *ptr = (struct pptp_msg_stopccrp *)dat; + 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); @@ -629,7 +630,7 @@ static void pptp_echorq_print(netdissect_options *ndo, const u_char *dat) { - struct pptp_msg_echorq *ptr = (struct pptp_msg_echorq *)dat; + const struct pptp_msg_echorq *ptr = (const struct pptp_msg_echorq *)dat; ND_TCHECK(ptr->id); pptp_id_print(ndo, &ptr->id); @@ -644,7 +645,7 @@ static void pptp_echorp_print(netdissect_options *ndo, const u_char *dat) { - struct pptp_msg_echorp *ptr = (struct pptp_msg_echorp *)dat; + const struct pptp_msg_echorp *ptr = (const struct pptp_msg_echorp *)dat; ND_TCHECK(ptr->id); pptp_id_print(ndo, &ptr->id); @@ -664,7 +665,7 @@ static void pptp_ocrq_print(netdissect_options *ndo, const u_char *dat) { - struct pptp_msg_ocrq *ptr = (struct pptp_msg_ocrq *)dat; + 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); @@ -700,7 +701,7 @@ static void pptp_ocrp_print(netdissect_options *ndo, const u_char *dat) { - struct pptp_msg_ocrp *ptr = (struct pptp_msg_ocrp *)dat; + 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); @@ -731,7 +732,7 @@ static void pptp_icrq_print(netdissect_options *ndo, const u_char *dat) { - struct pptp_msg_icrq *ptr = (struct pptp_msg_icrq *)dat; + 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); @@ -762,7 +763,7 @@ static void pptp_icrp_print(netdissect_options *ndo, const u_char *dat) { - struct pptp_msg_icrp *ptr = (struct pptp_msg_icrp *)dat; + 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); @@ -788,7 +789,7 @@ static void pptp_iccn_print(netdissect_options *ndo, const u_char *dat) { - struct pptp_msg_iccn *ptr = (struct pptp_msg_iccn *)dat; + 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); @@ -812,7 +813,7 @@ static void pptp_ccrq_print(netdissect_options *ndo, const u_char *dat) { - struct pptp_msg_ccrq *ptr = (struct pptp_msg_ccrq *)dat; + 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); @@ -828,7 +829,7 @@ static void pptp_cdn_print(netdissect_options *ndo, const u_char *dat) { - struct pptp_msg_cdn *ptr = (struct pptp_msg_cdn *)dat; + 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); @@ -852,7 +853,7 @@ static void pptp_wen_print(netdissect_options *ndo, const u_char *dat) { - struct pptp_msg_wen *ptr = (struct pptp_msg_wen *)dat; + 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); @@ -880,7 +881,7 @@ static void pptp_sli_print(netdissect_options *ndo, const u_char *dat) { - struct pptp_msg_sli *ptr = (struct pptp_msg_sli *)dat; + 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); @@ -906,7 +907,7 @@ pptp_print(netdissect_options *ndo, ND_PRINT((ndo, ": pptp")); - hdr = (struct pptp_hdr *)dat; + hdr = (const struct pptp_hdr *)dat; ND_TCHECK(hdr->length); if (ndo->ndo_vflag) { diff --git a/contrib/tcpdump/print-radius.c b/contrib/tcpdump/print-radius.c index 5cf8ad2..eb48de5 100644 --- a/contrib/tcpdump/print-radius.c +++ b/contrib/tcpdump/print-radius.c @@ -19,6 +19,9 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ + +/* \summary: Radius protocol printer */ + /* * Radius printer routines as specified on: * @@ -37,6 +40,10 @@ * RFC 2869: * "RADIUS Extensions" * + * RFC 3580: + * "IEEE 802.1X Remote Authentication Dial In User Service (RADIUS)" + * "Usage Guidelines" + * * RFC 4675: * "RADIUS Attributes for Virtual LAN and Priority Support" * @@ -48,16 +55,15 @@ * TODO: Among other things to print ok MacIntosh and Vendor values */ -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" #include "oui.h" @@ -162,12 +168,12 @@ static const struct tok rfc4675_tagged[] = { }; -static void print_attr_string(netdissect_options *, register u_char *, u_int, u_short ); -static void print_attr_num(netdissect_options *, register u_char *, u_int, u_short ); -static void print_vendor_attr(netdissect_options *, register u_char *, u_int, u_short ); -static void print_attr_address(netdissect_options *, register u_char *, u_int, u_short); -static void print_attr_time(netdissect_options *, register u_char *, u_int, u_short); -static void print_attr_strange(netdissect_options *, register u_char *, u_int, u_short); +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 */ @@ -331,6 +337,7 @@ static const char *tunnel_type[]={ NULL, "GRE", "DVS", "IP-in-IP Tunneling", + "VLAN", }; /* Tunnel-Medium-Type Attribute standard values */ @@ -365,11 +372,12 @@ static const char *prompt[]={ "No Echo", }; -struct attrtype { const char *name; /* Attribute name */ +static 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 u_char *, u_int, u_short); + void (*print_func)(netdissect_options *, register const u_char *, u_int, u_short); } attr_type[]= { { NULL, NULL, 0, 0, NULL }, @@ -478,7 +486,7 @@ struct attrtype { const char *name; /* Attribute name */ /*****************************/ static void print_attr_string(netdissect_options *ndo, - register u_char *data, u_int length, u_short attr_code) + register const u_char *data, u_int length, u_short attr_code) { register u_int i; @@ -533,7 +541,7 @@ print_attr_string(netdissect_options *ndo, } for (i=0; *data && i < length ; i++, data++) - ND_PRINT((ndo, "%c", (*data < 32 || *data > 128) ? '.' : *data)); + ND_PRINT((ndo, "%c", (*data < 32 || *data > 126) ? '.' : *data)); return; @@ -546,7 +554,7 @@ print_attr_string(netdissect_options *ndo, */ static void print_vendor_attr(netdissect_options *ndo, - register u_char *data, u_int length, u_short attr_code _U_) + register const u_char *data, u_int length, u_short attr_code _U_) { u_int idx; u_int vendor_id; @@ -593,7 +601,7 @@ print_vendor_attr(netdissect_options *ndo, vendor_type, vendor_length)); for (idx = 0; idx < vendor_length ; idx++, data++) - ND_PRINT((ndo, "%c", (*data < 32 || *data > 128) ? '.' : *data)); + ND_PRINT((ndo, "%c", (*data < 32 || *data > 126) ? '.' : *data)); length-=vendor_length; } return; @@ -611,7 +619,7 @@ print_vendor_attr(netdissect_options *ndo, /******************************/ static void print_attr_num(netdissect_options *ndo, - register u_char *data, u_int length, u_short attr_code) + register const u_char *data, u_int length, u_short attr_code) { uint32_t timeout; @@ -734,7 +742,7 @@ print_attr_num(netdissect_options *ndo, /*****************************/ static void print_attr_address(netdissect_options *ndo, - register u_char *data, u_int length, u_short attr_code) + register const u_char *data, u_int length, u_short attr_code) { if (length != 4) { @@ -778,7 +786,7 @@ print_attr_address(netdissect_options *ndo, /*************************************/ static void print_attr_time(netdissect_options *ndo, - register u_char *data, u_int length, u_short attr_code _U_) + register const u_char *data, u_int length, u_short attr_code _U_) { time_t attr_time; char string[26]; @@ -811,7 +819,7 @@ print_attr_time(netdissect_options *ndo, /***********************************/ static void print_attr_strange(netdissect_options *ndo, - register u_char *data, u_int length, u_short attr_code) + register const u_char *data, u_int length, u_short attr_code) { u_short len_data; @@ -884,7 +892,7 @@ static void radius_attrs_print(netdissect_options *ndo, register const u_char *attr, u_int length) { - register const struct radius_attr *rad_attr = (struct radius_attr *)attr; + register const struct radius_attr *rad_attr = (const struct radius_attr *)attr; const char *attr_string; while (length > 0) @@ -924,16 +932,16 @@ radius_attrs_print(netdissect_options *ndo, { if ( attr_type[rad_attr->type].print_func ) (*attr_type[rad_attr->type].print_func)( - ndo, ((u_char *)(rad_attr+1)), + ndo, ((const u_char *)(rad_attr+1)), rad_attr->len - 2, rad_attr->type); } } /* do we also want to see a hex dump ? */ if (ndo->ndo_vflag> 1) - print_unknown_data(ndo, (u_char *)rad_attr+2, "\n\t ", (rad_attr->len)-2); + print_unknown_data(ndo, (const u_char *)rad_attr+2, "\n\t ", (rad_attr->len)-2); length-=(rad_attr->len); - rad_attr = (struct radius_attr *)( ((char *)(rad_attr))+rad_attr->len); + rad_attr = (const struct radius_attr *)( ((const char *)(rad_attr))+rad_attr->len); } return; @@ -949,7 +957,7 @@ radius_print(netdissect_options *ndo, u_int len, auth_idx; ND_TCHECK2(*dat, MIN_RADIUS_LEN); - rad = (struct radius_hdr *)dat; + rad = (const struct radius_hdr *)dat; len = EXTRACT_16BITS(&rad->len); if (len < MIN_RADIUS_LEN) diff --git a/contrib/tcpdump/print-raw.c b/contrib/tcpdump/print-raw.c index d20387c..463aa41 100644 --- a/contrib/tcpdump/print-raw.c +++ b/contrib/tcpdump/print-raw.c @@ -19,14 +19,15 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: Raw IP printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" /* * The DLT_RAW packet has no header. It contains a raw IP packet. diff --git a/contrib/tcpdump/print-resp.c b/contrib/tcpdump/print-resp.c new file mode 100644 index 0000000..9d71e21 --- /dev/null +++ b/contrib/tcpdump/print-resp.c @@ -0,0 +1,538 @@ +/* + * Copyright (c) 2015 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. + * + * Initial contribution by Andrew Darqui (andrew.darqui@gmail.com). + */ + +/* \summary: REdis Serialization Protocol (RESP) printer */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#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 + */ + +#define RESP_SIMPLE_STRING '+' +#define RESP_ERROR '-' +#define RESP_INTEGER ':' +#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 LCHECK2(_tot_len, _len) \ + { \ + if (_tot_len < _len) \ + goto trunc; \ + } + +#define LCHECK(_tot_len) LCHECK2(_tot_len, 1) + +/* + * FIND_CRLF: + * Attempts to move our 'ptr' forward until a \r\n is found, + * while also making sure we don't exceed the buffer '_len' + * or go past the end of the captured data. + * If we exceed or go past the end of the captured data, + * jump to trunc. + */ +#define FIND_CRLF(_ptr, _len) \ + for (;;) { \ + LCHECK2(_len, 2); \ + ND_TCHECK2(*_ptr, 2); \ + if (*_ptr == '\r' && *(_ptr+1) == '\n') \ + break; \ + _ptr++; \ + _len--; \ + } + +/* + * CONSUME_CRLF + * Consume a CRLF that we've just found. + */ +#define CONSUME_CRLF(_ptr, _len) \ + _ptr += 2; \ + _len -= 2; + +/* + * FIND_CR_OR_LF + * Attempts to move our '_ptr' forward until a \r or \n is found, + * while also making sure we don't exceed the buffer '_len' + * or go past the end of the captured data. + * If we exceed or go past the end of the captured data, + * jump to trunc. + */ +#define FIND_CR_OR_LF(_ptr, _len) \ + for (;;) { \ + LCHECK(_len); \ + ND_TCHECK(*_ptr); \ + if (*_ptr == '\r' || *_ptr == '\n') \ + break; \ + _ptr++; \ + _len--; \ + } + +/* + * CONSUME_CR_OR_LF + * Consume all consecutive \r and \n bytes. + * If we exceed '_len' or go past the end of the captured data, + * jump to trunc. + */ +#define CONSUME_CR_OR_LF(_ptr, _len) \ + { \ + int _found_cr_or_lf = 0; \ + for (;;) { \ + /* \ + * Have we hit the end of data? \ + */ \ + if (_len == 0 || !ND_TTEST(*_ptr)) { \ + /* \ + * Yes. Have we seen a \r \ + * or \n? \ + */ \ + if (_found_cr_or_lf) { \ + /* \ + * Yes. Just stop. \ + */ \ + break; \ + } \ + /* \ + * No. We ran out of packet. \ + */ \ + goto trunc; \ + } \ + if (*_ptr != '\r' && *_ptr != '\n') \ + break; \ + _found_cr_or_lf = 1; \ + _ptr++; \ + _len--; \ + } \ + } + +/* + * SKIP_OPCODE + * Skip over the opcode character. + * The opcode has already been fetched, so we know it's there, and don't + * need to do any checks. + */ +#define SKIP_OPCODE(_ptr, _tot_len) \ + _ptr++; \ + _tot_len--; + +/* + * GET_LENGTH + * Get a bulk string or array length. + */ +#define GET_LENGTH(_ndo, _tot_len, _ptr, _len) \ + { \ + const u_char *_endp; \ + _len = resp_get_length(_ndo, _ptr, _tot_len, &_endp); \ + _tot_len -= (_endp - _ptr); \ + _ptr = _endp; \ + } + +/* + * TEST_RET_LEN + * If ret_len is < 0, jump to the trunc tag which returns (-1) + * and 'bubbles up' to printing tstr. Otherwise, return ret_len. + */ +#define TEST_RET_LEN(rl) \ + if (rl < 0) { goto trunc; } else { return rl; } + +/* + * TEST_RET_LEN_NORETURN + * If ret_len is < 0, jump to the trunc tag which returns (-1) + * and 'bubbles up' to printing tstr. Otherwise, continue onward. + */ +#define TEST_RET_LEN_NORETURN(rl) \ + if (rl < 0) { goto trunc; } + +/* + * RESP_PRINT_SEGMENT + * Prints a segment in the form of: ' ""\n" + * 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)) \ + goto trunc; \ + fn_print_char(_ndo, '"'); + +void +resp_print(netdissect_options *ndo, const u_char *bp, u_int length) +{ + int ret_len = 0, length_cur = length; + + if(!bp || length <= 0) + return; + + ND_PRINT((ndo, ": RESP")); + while (length_cur > 0) { + /* + * This block supports redis pipelining. + * For example, multiple operations can be pipelined within the same string: + * "*2\r\n\$4\r\nINCR\r\n\$1\r\nz\r\n*2\r\n\$4\r\nINCR\r\n\$1\r\nz\r\n*2\r\n\$4\r\nINCR\r\n\$1\r\nz\r\n" + * or + * "PING\r\nPING\r\nPING\r\n" + * In order to handle this case, we must try and parse 'bp' until + * 'length' bytes have been processed or we reach a trunc condition. + */ + ret_len = resp_parse(ndo, bp, length_cur); + TEST_RET_LEN_NORETURN(ret_len); + bp += ret_len; + length_cur -= ret_len; + } + + return; + +trunc: + ND_PRINT((ndo, "%s", tstr)); +} + +static int +resp_parse(netdissect_options *ndo, register const u_char *bp, int length) +{ + u_char op; + int ret_len; + + LCHECK2(length, 1); + ND_TCHECK(*bp); + op = *bp; + + /* bp now points to the op, so these routines must skip it */ + switch(op) { + case RESP_SIMPLE_STRING: ret_len = resp_print_simple_string(ndo, bp, length); break; + case RESP_INTEGER: ret_len = resp_print_integer(ndo, bp, length); break; + case RESP_ERROR: ret_len = resp_print_error(ndo, bp, length); break; + case RESP_BULK_STRING: ret_len = resp_print_bulk_string(ndo, bp, length); break; + case RESP_ARRAY: ret_len = resp_print_bulk_array(ndo, bp, length); break; + default: ret_len = resp_print_inline(ndo, bp, length); break; + } + + /* + * This gives up with a "truncated" indicator for all errors, + * including invalid packet errors; that's what we want, as + * we have to give up on further parsing in that case. + */ + TEST_RET_LEN(ret_len); + +trunc: + return (-1); +} + +static int +resp_print_simple_string(netdissect_options *ndo, register 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) { + return resp_print_string_error_integer(ndo, bp, length); +} + +static int +resp_print_error(netdissect_options *ndo, register 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) { + int length_cur = length, len, ret_len; + const u_char *bp_ptr; + + /* bp points to the op; skip it */ + SKIP_OPCODE(bp, length_cur); + bp_ptr = bp; + + /* + * bp now prints past the (+-;) opcode, so it's pointing to the first + * character of the string (which could be numeric). + * +OK\r\n + * -ERR ...\r\n + * :02912309\r\n + * + * Find the \r\n with FIND_CRLF(). + */ + FIND_CRLF(bp_ptr, length_cur); + + /* + * bp_ptr points to the \r\n, so bp_ptr - bp is the length of text + * preceding the \r\n. That includes the opcode, so don't print + * that. + */ + len = (bp_ptr - bp); + RESP_PRINT_SEGMENT(ndo, bp, len); + ret_len = 1 /**/ + len /**/ + 2 /**/; + + TEST_RET_LEN(ret_len); + +trunc: + return (-1); +} + +static int +resp_print_bulk_string(netdissect_options *ndo, register const u_char *bp, int length) { + int length_cur = length, string_len; + + /* bp points to the op; skip it */ + SKIP_OPCODE(bp, length_cur); + + /* \r\n */ + GET_LENGTH(ndo, length_cur, bp, string_len); + + if (string_len >= 0) { + /* Byte string of length string_len, starting at bp */ + if (string_len == 0) + resp_print_empty(ndo); + else { + LCHECK2(length_cur, string_len); + ND_TCHECK2(*bp, string_len); + RESP_PRINT_SEGMENT(ndo, bp, string_len); + bp += string_len; + length_cur -= string_len; + } + + /* + * Find the \r\n at the end of the string and skip past it. + * XXX - report an error if the \r\n isn't immediately after + * the item? + */ + FIND_CRLF(bp, length_cur); + CONSUME_CRLF(bp, length_cur); + } else { + /* null, truncated, or invalid for some reason */ + switch(string_len) { + case (-1): resp_print_null(ndo); break; + case (-2): goto trunc; + case (-3): resp_print_length_too_large(ndo); break; + case (-4): resp_print_length_negative(ndo); break; + default: resp_print_invalid(ndo); break; + } + } + + return (length - length_cur); + +trunc: + return (-1); +} + +static int +resp_print_bulk_array(netdissect_options *ndo, register const u_char *bp, int length) { + u_int length_cur = length; + int array_len, i, ret_len; + + /* bp points to the op; skip it */ + SKIP_OPCODE(bp, length_cur); + + /* \r\n */ + GET_LENGTH(ndo, length_cur, bp, array_len); + + if (array_len > 0) { + /* non empty array */ + for (i = 0; i < array_len; i++) { + ret_len = resp_parse(ndo, bp, length_cur); + + TEST_RET_LEN_NORETURN(ret_len); + + bp += ret_len; + length_cur -= ret_len; + } + } else { + /* empty, null, truncated, or invalid */ + switch(array_len) { + case 0: resp_print_empty(ndo); break; + case (-1): resp_print_null(ndo); break; + case (-2): goto trunc; + case (-3): resp_print_length_too_large(ndo); break; + case (-4): resp_print_length_negative(ndo); break; + default: resp_print_invalid(ndo); break; + } + } + + return (length - length_cur); + +trunc: + return (-1); +} + +static int +resp_print_inline(netdissect_options *ndo, register const u_char *bp, int length) { + int length_cur = length; + int len; + const u_char *bp_ptr; + + /* + * Inline commands are simply 'strings' followed by \r or \n or both. + * Redis will do its best to split/parse these strings. + * This feature of redis is implemented to support the ability of + * command parsing from telnet/nc sessions etc. + * + * <\r||\n||\r\n...> + */ + + /* + * Skip forward past any leading \r, \n, or \r\n. + */ + CONSUME_CR_OR_LF(bp, length_cur); + bp_ptr = bp; + + /* + * Scan forward looking for \r or \n. + */ + FIND_CR_OR_LF(bp_ptr, length_cur); + + /* + * 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. + */ + len = (bp_ptr - bp); + RESP_PRINT_SEGMENT(ndo, bp, len); + + /* + * Skip forward past the \r, \n, or \r\n. + */ + CONSUME_CR_OR_LF(bp_ptr, length_cur); + + /* + * Return the number of bytes we processed. + */ + return (length - length_cur); + +trunc: + return (-1); +} + +static int +resp_get_length(netdissect_options *ndo, register const u_char *bp, int len, const u_char **endp) +{ + int result; + u_char c; + int saw_digit; + int neg; + int too_large; + + if (len == 0) + goto trunc; + ND_TCHECK(*bp); + too_large = 0; + neg = 0; + if (*bp == '-') { + neg = 1; + bp++; + len--; + } + result = 0; + saw_digit = 0; + + for (;;) { + if (len == 0) + goto trunc; + ND_TCHECK(*bp); + c = *bp; + if (!(c >= '0' && c <= '9')) { + if (!saw_digit) + goto invalid; + break; + } + c -= '0'; + if (result > (INT_MAX / 10)) { + /* This will overflow an int when we multiply it by 10. */ + too_large = 1; + } else { + result *= 10; + if (result == INT_MAX && c > (INT_MAX % 10)) { + /* This will overflow an int when we add c */ + too_large = 1; + } else + result += c; + } + bp++; + len--; + saw_digit = 1; + } + if (!saw_digit) + goto invalid; + + /* + * OK, the next thing should be \r\n. + */ + if (len == 0) + goto trunc; + ND_TCHECK(*bp); + if (*bp != '\r') + goto invalid; + bp++; + len--; + if (len == 0) + goto trunc; + ND_TCHECK(*bp); + if (*bp != '\n') + goto invalid; + bp++; + len--; + *endp = bp; + if (neg) { + /* -1 means "null", anything else is invalid */ + if (too_large || result != 1) + return (-4); + result = -1; + } + return (too_large ? -3 : result); + +trunc: + return (-2); + +invalid: + return (-5); +} diff --git a/contrib/tcpdump/print-rip.c b/contrib/tcpdump/print-rip.c index c1b036e..cf661d0 100644 --- a/contrib/tcpdump/print-rip.c +++ b/contrib/tcpdump/print-rip.c @@ -19,18 +19,19 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: Routing Information Protocol (RIP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" -#include "extract.h" /* must come after interface.h */ +#include "extract.h" #include "af.h" @@ -102,14 +103,14 @@ rip_entry_print_v1(netdissect_options *ndo, family = EXTRACT_16BITS(&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, (uint8_t *)&ni->rip_family, "\n\t ", RIP_ROUTELEN); + print_unknown_data(ndo, (const uint8_t *)&ni->rip_family, "\n\t ", RIP_ROUTELEN); return; } if (EXTRACT_16BITS(&ni->rip_tag) || EXTRACT_32BITS(&ni->rip_dest_mask) || EXTRACT_32BITS(&ni->rip_router)) { /* MBZ fields not zero */ - print_unknown_data(ndo, (uint8_t *)&ni->rip_family, "\n\t ", RIP_ROUTELEN); + print_unknown_data(ndo, (const uint8_t *)&ni->rip_family, "\n\t ", RIP_ROUTELEN); return; } if (family == 0) { @@ -133,31 +134,31 @@ rip_entry_print_v2(netdissect_options *ndo, if (family == 0xFFFF) { /* variable-sized authentication structures */ uint16_t auth_type = EXTRACT_16BITS(&ni->rip_tag); if (auth_type == 2) { - register u_char *p = (u_char *)&ni->rip_dest; + 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 : '.')); } else if (auth_type == 3) { ND_PRINT((ndo, "\n\t Auth header:")); - ND_PRINT((ndo, " Packet Len %u,", EXTRACT_16BITS((uint8_t *)ni + 4))); - ND_PRINT((ndo, " Key-ID %u,", *((uint8_t *)ni + 6))); - ND_PRINT((ndo, " Auth Data Len %u,", *((uint8_t *)ni + 7))); + 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))); } else if (auth_type == 1) { ND_PRINT((ndo, "\n\t Auth trailer:")); - print_unknown_data(ndo, (uint8_t *)&ni->rip_dest, "\n\t ", remaining); + print_unknown_data(ndo, (const uint8_t *)&ni->rip_dest, "\n\t ", remaining); return 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, (uint8_t *)&ni->rip_dest, "\n\t ", remaining); + print_unknown_data(ndo, (const uint8_t *)&ni->rip_dest, "\n\t ", remaining); } } 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, (uint8_t *)&ni->rip_tag, "\n\t ", RIP_ROUTELEN-2); + print_unknown_data(ndo, (const uint8_t *)&ni->rip_tag, "\n\t ", RIP_ROUTELEN-2); } 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), @@ -194,7 +195,7 @@ rip_print(netdissect_options *ndo, } i -= sizeof(*rp); - rp = (struct rip *)dat; + rp = (const struct rip *)dat; ND_PRINT((ndo, "%sRIPv%u", (ndo->ndo_vflag >= 1) ? "\n\t" : "", @@ -213,7 +214,7 @@ rip_print(netdissect_options *ndo, * * so perhaps we should just dump the packet, in hex. */ - print_unknown_data(ndo, (uint8_t *)&rp->rip_cmd, "\n\t", length); + 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*/ @@ -231,7 +232,7 @@ rip_print(netdissect_options *ndo, case RIPCMD_RESPONSE: j = length / sizeof(*ni); ND_PRINT((ndo, ", routes: %u%s", j, rp->rip_vers == 2 ? " or less" : "")); - ni = (struct rip_netinfo *)(rp + 1); + ni = (const struct rip_netinfo *)(rp + 1); for (; i >= sizeof(*ni); ++ni) { if (rp->rip_vers == 1) { @@ -256,14 +257,14 @@ rip_print(netdissect_options *ndo, /* fall through */ default: if (ndo->ndo_vflag <= 1) { - if(!print_unknown_data(ndo, (uint8_t *)rp, "\n\t", length)) + 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, (uint8_t *)rp, "\n\t", length)) + if(!print_unknown_data(ndo, (const uint8_t *)rp, "\n\t", length)) return; } } diff --git a/contrib/tcpdump/print-ripng.c b/contrib/tcpdump/print-ripng.c index 4bc900d..25e9bbc 100644 --- a/contrib/tcpdump/print-ripng.c +++ b/contrib/tcpdump/print-ripng.c @@ -19,16 +19,15 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: IPv6 Routing Information Protocol (RIPng) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#ifdef INET6 - -#include +#include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" @@ -109,7 +108,7 @@ rip6_entry_print(netdissect_options *ndo, register const struct netinfo6 *ni, in void ripng_print(netdissect_options *ndo, const u_char *dat, unsigned int length) { - register const struct rip6 *rp = (struct rip6 *)dat; + register const struct rip6 *rp = (const struct rip6 *)dat; register const struct netinfo6 *ni; register u_int amt; register u_int i; @@ -173,4 +172,3 @@ ripng_print(netdissect_options *ndo, const u_char *dat, unsigned int length) if (rp->rip6_vers != RIP6_VERSION) ND_PRINT((ndo, " [vers %d]", rp->rip6_vers)); } -#endif /* INET6 */ diff --git a/contrib/tcpdump/print-rpki-rtr.c b/contrib/tcpdump/print-rpki-rtr.c index 34e2057..77e29c7 100644 --- a/contrib/tcpdump/print-rpki-rtr.c +++ b/contrib/tcpdump/print-rpki-rtr.c @@ -12,24 +12,27 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * support for the The RPKI/Router Protocol as RFC6810 - * * Original code by Hannes Gredler (hannes@juniper.net) */ -#define NETDISSECT_REWORKED +/* \summary: Resource Public Key Infrastructure (RPKI) to Router Protocol printer */ + +/* specification: RFC 6810 */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "addrtoname.h" +static const char tstr[] = "[|RPKI-RTR]"; + /* * RPKI/Router PDU header * @@ -168,14 +171,14 @@ indent_string (u_int indent) /* * Print a single PDU. */ -static void +static int rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent) { const rpki_rtr_pdu *pdu_header; u_int pdu_type, pdu_len, hexdump; const u_char *msg; - pdu_header = (rpki_rtr_pdu *)tptr; + pdu_header = (const rpki_rtr_pdu *)tptr; pdu_type = pdu_header->pdu_type; pdu_len = EXTRACT_32BITS(pdu_header->length); ND_TCHECK2(*tptr, pdu_len); @@ -221,9 +224,9 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent) case RPKI_RTR_IPV4_PREFIX_PDU: { - rpki_rtr_pdu_ipv4_prefix *pdu; + const rpki_rtr_pdu_ipv4_prefix *pdu; - pdu = (rpki_rtr_pdu_ipv4_prefix *)tptr; + pdu = (const rpki_rtr_pdu_ipv4_prefix *)tptr; ND_PRINT((ndo, "%sIPv4 Prefix %s/%u-%u, origin-as %u, flags 0x%02x", indent_string(indent+2), ipaddr_string(ndo, pdu->prefix), @@ -232,12 +235,11 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent) } break; -#ifdef INET6 case RPKI_RTR_IPV6_PREFIX_PDU: { - rpki_rtr_pdu_ipv6_prefix *pdu; + const rpki_rtr_pdu_ipv6_prefix *pdu; - pdu = (rpki_rtr_pdu_ipv6_prefix *)tptr; + pdu = (const rpki_rtr_pdu_ipv6_prefix *)tptr; ND_PRINT((ndo, "%sIPv6 Prefix %s/%u-%u, origin-as %u, flags 0x%02x", indent_string(indent+2), ip6addr_string(ndo, pdu->prefix), @@ -245,14 +247,13 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent) EXTRACT_32BITS(pdu->as), pdu->flags)); } break; -#endif case RPKI_RTR_ERROR_REPORT_PDU: { - rpki_rtr_pdu_error_report *pdu; + const rpki_rtr_pdu_error_report *pdu; u_int encapsulated_pdu_length, text_length, tlen, error_code; - pdu = (rpki_rtr_pdu_error_report *)tptr; + pdu = (const rpki_rtr_pdu_error_report *)tptr; encapsulated_pdu_length = EXTRACT_32BITS(pdu->encapsulated_pdu_length); ND_TCHECK2(*tptr, encapsulated_pdu_length); tlen = pdu_len; @@ -272,7 +273,8 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent) if (encapsulated_pdu_length && (encapsulated_pdu_length <= tlen)) { ND_PRINT((ndo, "%s-----encapsulated PDU-----", indent_string(indent+4))); - rpki_rtr_pdu_print(ndo, tptr, indent+2); + if (rpki_rtr_pdu_print(ndo, tptr, indent+2)) + goto trunc; } tptr += encapsulated_pdu_length; @@ -290,7 +292,8 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent) ND_TCHECK2(*tptr, text_length); if (text_length && (text_length <= tlen )) { ND_PRINT((ndo, "%sError text: ", indent_string(indent+2))); - fn_printn(ndo, tptr, text_length, ndo->ndo_snapend); + if (fn_printn(ndo, tptr, text_length, ndo->ndo_snapend)) + goto trunc; } } break; @@ -307,11 +310,10 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent) if (ndo->ndo_vflag > 1 || (ndo->ndo_vflag && hexdump)) { print_unknown_data(ndo,tptr,"\n\t ", pdu_len); } - return; + return 0; - trunc: - ND_PRINT((ndo, "|trunc")); - return; +trunc: + return 1; } void @@ -333,7 +335,7 @@ rpki_rtr_print(netdissect_options *ndo, register const u_char *pptr, register u_ ND_TCHECK2(*tptr, sizeof(rpki_rtr_pdu)); - pdu_header = (rpki_rtr_pdu *)tptr; + pdu_header = (const rpki_rtr_pdu *)tptr; pdu_type = pdu_header->pdu_type; pdu_len = EXTRACT_32BITS(pdu_header->length); ND_TCHECK2(*tptr, pdu_len); @@ -350,14 +352,15 @@ rpki_rtr_print(netdissect_options *ndo, register const u_char *pptr, register u_ /* * Print the PDU. */ - rpki_rtr_pdu_print(ndo, tptr, 8); + if (rpki_rtr_pdu_print(ndo, tptr, 8)) + goto trunc; tlen -= pdu_len; tptr += pdu_len; } return; - trunc: - ND_PRINT((ndo, "\n\t[|RPKI-RTR]")); +trunc: + ND_PRINT((ndo, "\n\t%s", tstr)); } /* diff --git a/contrib/tcpdump/print-rrcp.c b/contrib/tcpdump/print-rrcp.c index 2370d9c..936b3ea 100644 --- a/contrib/tcpdump/print-rrcp.c +++ b/contrib/tcpdump/print-rrcp.c @@ -21,14 +21,15 @@ * and Realtek Echo Protocol (RRCP-REP) packets. */ -#define NETDISSECT_REWORKED +/* \summary: Realtek Remote Control Protocol (RRCP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" #include "ether.h" @@ -72,56 +73,54 @@ static const struct tok opcode_values[] = { void rrcp_print(netdissect_options *ndo, register const u_char *cp, - u_int length _U_) + u_int length _U_, + const struct lladdr_info *src, + const struct lladdr_info *dst) { - const u_char *rrcp; uint8_t rrcp_proto; uint8_t rrcp_opcode; - register const struct ether_header *ep; - char proto_str[16]; - char opcode_str[32]; - - ep = (const struct ether_header *)cp; - rrcp = cp + ETHER_HDRLEN; - ND_TCHECK(*(rrcp + RRCP_PROTO_OFFSET)); - rrcp_proto = *(rrcp + RRCP_PROTO_OFFSET); - ND_TCHECK(*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)); - rrcp_opcode = (*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_OPCODE_MASK; - ND_PRINT((ndo, "%s > %s, %s %s", - etheraddr_string(ndo, ESRC(ep)), - etheraddr_string(ndo, EDST(ep)), - tok2strbuf(proto_values,"RRCP-0x%02x",rrcp_proto,proto_str,sizeof(proto_str)), - ((*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY) ? "reply" : "query")); + 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; + if (src != NULL && dst != NULL) { + ND_PRINT((ndo, "%s > %s, ", + (src->addr_string)(ndo, src->addr), + (dst->addr_string)(ndo, dst->addr))); + } + ND_PRINT((ndo, "%s %s", + tok2str(proto_values,"RRCP-0x%02x",rrcp_proto), + ((*(cp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY) ? "reply" : "query")); if (rrcp_proto==1){ ND_PRINT((ndo, ": %s", - tok2strbuf(opcode_values,"unknown opcode (0x%02x)",rrcp_opcode,opcode_str,sizeof(opcode_str)))); + tok2str(opcode_values,"unknown opcode (0x%02x)",rrcp_opcode))); } if (rrcp_opcode==1 || rrcp_opcode==2){ - ND_TCHECK2(*(rrcp + RRCP_REG_ADDR_OFFSET), 6); + ND_TCHECK2(*(cp + RRCP_REG_ADDR_OFFSET), 6); ND_PRINT((ndo, " addr=0x%04x, data=0x%08x", - EXTRACT_LE_16BITS(rrcp + RRCP_REG_ADDR_OFFSET), - EXTRACT_LE_32BITS(rrcp + RRCP_REG_DATA_OFFSET))); + EXTRACT_LE_16BITS(cp + RRCP_REG_ADDR_OFFSET), + EXTRACT_LE_32BITS(cp + RRCP_REG_DATA_OFFSET))); } if (rrcp_proto==1){ - ND_TCHECK2(*(rrcp + RRCP_AUTHKEY_OFFSET), 2); + ND_TCHECK2(*(cp + RRCP_AUTHKEY_OFFSET), 2); ND_PRINT((ndo, ", auth=0x%04x", - EXTRACT_16BITS(rrcp + RRCP_AUTHKEY_OFFSET))); + EXTRACT_16BITS(cp + RRCP_AUTHKEY_OFFSET))); } if (rrcp_proto==1 && rrcp_opcode==0 && - ((*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY)){ - ND_TCHECK2(*(rrcp + RRCP_VENDOR_ID_OFFSET), 4); + ((*(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 ", - *(rrcp + RRCP_DOWNLINK_PORT_OFFSET), - *(rrcp + RRCP_UPLINK_PORT_OFFSET), - etheraddr_string(ndo, rrcp + RRCP_UPLINK_MAC_OFFSET), - EXTRACT_32BITS(rrcp + RRCP_VENDOR_ID_OFFSET), - EXTRACT_16BITS(rrcp + RRCP_CHIP_ID_OFFSET))); + *(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))); }else if (rrcp_opcode==1 || rrcp_opcode==2 || rrcp_proto==2){ - ND_TCHECK2(*(rrcp + RRCP_COOKIE2_OFFSET), 4); + ND_TCHECK2(*(cp + RRCP_COOKIE2_OFFSET), 4); ND_PRINT((ndo, ", cookie=0x%08x%08x ", - EXTRACT_32BITS(rrcp + RRCP_COOKIE2_OFFSET), - EXTRACT_32BITS(rrcp + RRCP_COOKIE1_OFFSET))); + EXTRACT_32BITS(cp + RRCP_COOKIE2_OFFSET), + EXTRACT_32BITS(cp + RRCP_COOKIE1_OFFSET))); } return; diff --git a/contrib/tcpdump/print-rsvp.c b/contrib/tcpdump/print-rsvp.c index 263ef3d..be3dfa3 100644 --- a/contrib/tcpdump/print-rsvp.c +++ b/contrib/tcpdump/print-rsvp.c @@ -15,14 +15,15 @@ * Original code by Hannes Gredler (hannes@juniper.net) */ -#define NETDISSECT_REWORKED +/* \summary: Resource ReSerVation Protocol (RSVP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "addrtoname.h" #include "ethertype.h" @@ -30,6 +31,8 @@ #include "af.h" #include "signature.h" +static const char tstr[] = " [|rsvp]"; + /* * RFC 2205 common header * @@ -82,7 +85,7 @@ struct rsvp_object_header { #define RSVP_MSGTYPE_PATHTEAR 5 #define RSVP_MSGTYPE_RESVTEAR 6 #define RSVP_MSGTYPE_RESVCONF 7 -#define RSVP_MSGTYPE_AGGREGATE 12 +#define RSVP_MSGTYPE_BUNDLE 12 #define RSVP_MSGTYPE_ACK 13 #define RSVP_MSGTYPE_HELLO_OLD 14 /* ancient Hellos */ #define RSVP_MSGTYPE_SREFRESH 15 @@ -96,7 +99,7 @@ static const struct tok rsvp_msg_type_values[] = { { RSVP_MSGTYPE_PATHTEAR, "PathTear" }, { RSVP_MSGTYPE_RESVTEAR, "ResvTear" }, { RSVP_MSGTYPE_RESVCONF, "ResvConf" }, - { RSVP_MSGTYPE_AGGREGATE, "Aggregate" }, + { RSVP_MSGTYPE_BUNDLE, "Bundle" }, { RSVP_MSGTYPE_ACK, "Acknowledgement" }, { RSVP_MSGTYPE_HELLO_OLD, "Hello (Old)" }, { RSVP_MSGTYPE_SREFRESH, "Refresh" }, @@ -497,6 +500,7 @@ rsvp_intserv_print(netdissect_options *ndo, if (obj_tlen < 4) return 0; parameter_id = *(tptr); + ND_TCHECK2(*(tptr + 2), 2); parameter_length = EXTRACT_16BITS(tptr+2)<<2; /* convert wordcount to bytecount */ ND_PRINT((ndo, "\n\t Parameter ID: %s (%u), length: %u, Flags: [0x%02x]", @@ -517,8 +521,10 @@ rsvp_intserv_print(netdissect_options *ndo, * | IS hop cnt (32-bit unsigned integer) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ - if (parameter_length == 4) + if (parameter_length == 4) { + ND_TCHECK2(*(tptr + 4), 4); ND_PRINT((ndo, "\n\t\tIS hop count: %u", EXTRACT_32BITS(tptr + 4))); + } break; case 6: @@ -530,6 +536,7 @@ 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)); } @@ -544,6 +551,7 @@ 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")); @@ -561,8 +569,10 @@ rsvp_intserv_print(netdissect_options *ndo, * | Composed MTU (32-bit unsigned integer) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ - if (parameter_length == 4) + if (parameter_length == 4) { + ND_TCHECK2(*(tptr + 4), 4); ND_PRINT((ndo, "\n\t\tComposed MTU: %u bytes", EXTRACT_32BITS(tptr + 4))); + } break; case 127: /* @@ -582,6 +592,7 @@ 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); @@ -605,6 +616,7 @@ 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))); @@ -615,8 +627,10 @@ rsvp_intserv_print(netdissect_options *ndo, case 134: case 135: case 136: - if (parameter_length == 4) + if (parameter_length == 4) { + ND_TCHECK2(*(tptr + 4), 4); ND_PRINT((ndo, "\n\t\tValue: %u", EXTRACT_32BITS(tptr + 4))); + } break; default: @@ -624,20 +638,29 @@ rsvp_intserv_print(netdissect_options *ndo, print_unknown_data(ndo, tptr + 4, "\n\t\t", parameter_length); } return (parameter_length+4); /* header length 4 bytes */ + +trunc: + ND_PRINT((ndo, "%s", tstr)); + return 0; +} + +/* + * Clear checksum prior to signature verification. + */ +static void +rsvp_clear_checksum(void *header) +{ + struct rsvp_common_header *rsvp_com_header = (struct rsvp_common_header *) header; + + rsvp_com_header->checksum[0] = 0; + rsvp_com_header->checksum[1] = 0; } static int rsvp_obj_print(netdissect_options *ndo, - const u_char *pptr -#ifndef HAVE_LIBCRYPTO -_U_ -#endif -, u_int plen -#ifndef HAVE_LIBCRYPTO -_U_ -#endif -, const u_char *tptr, - const char *ident, u_int tlen) + const u_char *pptr, u_int plen, const u_char *tptr, + const char *ident, u_int tlen, + const struct rsvp_common_header *rsvp_com_header) { const struct rsvp_object_header *rsvp_obj_header; const u_char *obj_tptr; @@ -723,7 +746,6 @@ _U_ obj_tlen-=8; obj_tptr+=8; break; -#ifdef INET6 case RSVP_CTYPE_IPV6: if (obj_tlen < 20) return -1; @@ -762,7 +784,6 @@ _U_ obj_tlen-=26; obj_tptr+=26; break; -#endif case RSVP_CTYPE_13: /* IPv4 p2mp LSP Tunnel */ if (obj_tlen < 12) return -1; @@ -802,7 +823,6 @@ _U_ obj_tlen-=sizeof(struct in_addr); obj_tptr+=sizeof(struct in_addr); break; -#ifdef INET6 case RSVP_CTYPE_IPV6: if (obj_tlen < sizeof(struct in6_addr)) return -1; @@ -812,7 +832,6 @@ _U_ obj_tlen-=sizeof(struct in6_addr); obj_tptr+=sizeof(struct in6_addr); break; -#endif default: hexdump=TRUE; } @@ -829,7 +848,6 @@ _U_ obj_tlen-=sizeof(struct in_addr); obj_tptr+=sizeof(struct in_addr); break; -#ifdef INET6 case RSVP_CTYPE_IPV6: if (obj_tlen < sizeof(struct in6_addr)) return-1; @@ -839,7 +857,6 @@ _U_ obj_tlen-=sizeof(struct in6_addr); obj_tptr+=sizeof(struct in6_addr); break; -#endif default: hexdump=TRUE; } @@ -914,7 +931,6 @@ _U_ obj_tlen-=8; obj_tptr+=8; break; -#ifdef INET6 case RSVP_CTYPE_IPV6: if (obj_tlen < 20) return-1; @@ -939,7 +955,6 @@ _U_ obj_tlen-=40; obj_tptr+=40; break; -#endif case RSVP_CTYPE_TUNNEL_IPV4: if (obj_tlen < 8) return-1; @@ -1051,20 +1066,37 @@ _U_ switch(rsvp_obj_ctype) { case RSVP_CTYPE_IPV4: 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, tok2str(rsvp_obj_xro_values, "Unknown %u", RSVP_OBJ_XRO_MASK_SUBOBJ(*obj_tptr)), - *(obj_tptr + 1))); + length)); - if (*(obj_tptr+1) == 0) { /* prevent infinite loops */ + if (length == 0) { /* prevent infinite loops */ ND_PRINT((ndo, "%s ERROR: zero length ERO subtype", ident)); break; } switch(RSVP_OBJ_XRO_MASK_SUBOBJ(*obj_tptr)) { + u_char prefix_length; + case RSVP_OBJ_XRO_IPV4: + if (length != 8) { + ND_PRINT((ndo, " ERROR: length != 8")); + goto invalid; + } + ND_TCHECK2(*obj_tptr, 8); + prefix_length = *(obj_tptr+6); + if (prefix_length != 32) { + ND_PRINT((ndo, " 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), @@ -1074,6 +1106,11 @@ _U_ *(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")); + goto invalid; + } + ND_TCHECK2(*obj_tptr, 8); ND_PRINT((ndo, ", Flags: [%s] (%#x), Class-Type: %s (%u), %u", bittok2str(rsvp_obj_rro_label_flag_values, "none", @@ -1179,6 +1216,9 @@ _U_ tok2str(af_values, "Unknown", af), af, subobj_len)); + if(subobj_len == 0) + goto invalid; + switch(subobj_type) { case RSVP_GEN_UNI_SUBOBJ_SOURCE_TNA_ADDRESS: case RSVP_GEN_UNI_SUBOBJ_DESTINATION_TNA_ADDRESS: @@ -1190,14 +1230,12 @@ _U_ ND_PRINT((ndo, "%s UNI IPv4 TNA address: %s", ident, ipaddr_string(ndo, obj_tptr + 4))); break; -#ifdef INET6 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))); break; -#endif case AFNUM_NSAP: if (subobj_len) { /* unless we have a TLV parser lets just hexdump */ @@ -1271,7 +1309,6 @@ _U_ if (obj_tlen) hexdump=TRUE; /* unless we have a TLV parser lets just hexdump */ break; -#ifdef INET6 case RSVP_CTYPE_4: /* fall through - FIXME add TLV parser */ case RSVP_CTYPE_IPV6: if (obj_tlen < 20) @@ -1284,7 +1321,6 @@ _U_ obj_tptr+=20; hexdump=TRUE; /* unless we have a TLV parser lets just hexdump */ break; -#endif default: hexdump=TRUE; } @@ -1360,7 +1396,6 @@ _U_ obj_tlen-=8; obj_tptr+=8; break; -#ifdef INET6 case RSVP_CTYPE_IPV6: if (obj_tlen < 20) return-1; @@ -1405,7 +1440,6 @@ _U_ obj_tlen-=40; obj_tptr+=40; break; -#endif case RSVP_CTYPE_TUNNEL_IPV4: if (obj_tlen < 8) return-1; @@ -1547,7 +1581,6 @@ _U_ obj_tlen-=8; obj_tptr+=8; break; -#ifdef INET6 case RSVP_CTYPE_4: /* fall through - FIXME add TLV parser */ case RSVP_CTYPE_IPV6: if (obj_tlen < 20) @@ -1574,7 +1607,6 @@ _U_ obj_tlen-=20; obj_tptr+=20; break; -#endif default: hexdump=TRUE; } @@ -1664,12 +1696,10 @@ _U_ EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest+8), EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest + 12))); -#ifdef HAVE_LIBCRYPTO - sigcheck = signature_verify(ndo, pptr, plen, (unsigned char *)obj_ptr.\ - rsvp_obj_integrity->digest); -#else - sigcheck = CANT_CHECK_SIGNATURE; -#endif + 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))); obj_tlen+=sizeof(struct rsvp_obj_integrity_t); @@ -1750,7 +1780,6 @@ _U_ obj_tlen-=4; obj_tptr+=4; break; -#ifdef INET6 case RSVP_CTYPE_IPV6: if (obj_tlen < 16) return-1; @@ -1760,7 +1789,6 @@ _U_ obj_tlen-=16; obj_tptr+=16; break; -#endif default: hexdump=TRUE; } @@ -1788,8 +1816,12 @@ _U_ tlen-=rsvp_obj_len; } return 0; +invalid: + ND_PRINT((ndo, "%s", istr)); + return -1; trunc: - ND_PRINT((ndo, "\n\t\t packet exceeded snapshot")); + ND_PRINT((ndo, "\n\t\t")); + ND_PRINT((ndo, "%s", tstr)); return -1; } @@ -1797,13 +1829,13 @@ void rsvp_print(netdissect_options *ndo, register const u_char *pptr, register u_int len) { - struct rsvp_common_header *rsvp_com_header; - const u_char *tptr,*subtptr; - u_short plen, tlen, subtlen; + const struct rsvp_common_header *rsvp_com_header; + const u_char *tptr; + u_short plen, tlen; tptr=pptr; - rsvp_com_header = (struct rsvp_common_header *)pptr; + rsvp_com_header = (const struct rsvp_common_header *)pptr; ND_TCHECK(*rsvp_com_header); /* @@ -1837,12 +1869,6 @@ rsvp_print(netdissect_options *ndo, rsvp_com_header->ttl, EXTRACT_16BITS(rsvp_com_header->checksum))); - /* - * Clear checksum prior to signature verification. - */ - rsvp_com_header->checksum[0] = 0; - rsvp_com_header->checksum[1] = 0; - if (tlen < sizeof(const struct rsvp_common_header)) { ND_PRINT((ndo, "ERROR: common header too short %u < %lu", tlen, (unsigned long)sizeof(const struct rsvp_common_header))); @@ -1854,10 +1880,19 @@ rsvp_print(netdissect_options *ndo, switch(rsvp_com_header->msg_type) { - case RSVP_MSGTYPE_AGGREGATE: + case RSVP_MSGTYPE_BUNDLE: + /* + * Process each submessage in the bundle message. + * Bundle messages may not contain bundle submessages, so we don't + * need to handle bundle submessages specially. + */ while(tlen > 0) { - subtptr=tptr; - rsvp_com_header = (struct rsvp_common_header *)subtptr; + const u_char *subpptr=tptr, *subtptr; + u_short subplen, subtlen; + + subtptr=subpptr; + + rsvp_com_header = (const struct rsvp_common_header *)subpptr; ND_TCHECK(*rsvp_com_header); /* @@ -1868,7 +1903,8 @@ rsvp_print(netdissect_options *ndo, RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags))); return; } - subtlen=EXTRACT_16BITS(rsvp_com_header->length); + + subplen = subtlen = EXTRACT_16BITS(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), @@ -1879,12 +1915,6 @@ rsvp_print(netdissect_options *ndo, rsvp_com_header->ttl, EXTRACT_16BITS(rsvp_com_header->checksum))); - /* - * Clear checksum prior to signature verification. - */ - rsvp_com_header->checksum[0] = 0; - rsvp_com_header->checksum[1] = 0; - if (subtlen < sizeof(const struct rsvp_common_header)) { ND_PRINT((ndo, "ERROR: common header too short %u < %lu", subtlen, (unsigned long)sizeof(const struct rsvp_common_header))); @@ -1900,7 +1930,10 @@ rsvp_print(netdissect_options *ndo, subtptr+=sizeof(const struct rsvp_common_header); subtlen-=sizeof(const struct rsvp_common_header); - if (rsvp_obj_print(ndo, pptr, plen, subtptr, "\n\t ", subtlen) == -1) + /* + * Print all objects in the submessage. + */ + if (rsvp_obj_print(ndo, subpptr, subplen, subtptr, "\n\t ", subtlen, rsvp_com_header) == -1) return; tptr+=subtlen+sizeof(const struct rsvp_common_header); @@ -1920,7 +1953,10 @@ rsvp_print(netdissect_options *ndo, case RSVP_MSGTYPE_HELLO: case RSVP_MSGTYPE_ACK: case RSVP_MSGTYPE_SREFRESH: - if (rsvp_obj_print(ndo, pptr, plen, tptr, "\n\t ", tlen) == -1) + /* + * Print all objects in the message. + */ + if (rsvp_obj_print(ndo, pptr, plen, tptr, "\n\t ", tlen, rsvp_com_header) == -1) return; break; @@ -1931,5 +1967,6 @@ rsvp_print(netdissect_options *ndo, return; trunc: - ND_PRINT((ndo, "\n\t\t packet exceeded snapshot")); + ND_PRINT((ndo, "\n\t\t")); + ND_PRINT((ndo, "%s", tstr)); } diff --git a/contrib/tcpdump/print-rt6.c b/contrib/tcpdump/print-rt6.c index 3d5f9e3..35dbed9 100644 --- a/contrib/tcpdump/print-rt6.c +++ b/contrib/tcpdump/print-rt6.c @@ -19,20 +19,19 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: IPv6 routing header printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#ifdef INET6 - -#include +#include #include #include "ip6.h" -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" @@ -44,9 +43,8 @@ rt6_print(netdissect_options *ndo, register const u_char *bp, const u_char *bp2 register const u_char *ep; int i, len; register const struct in6_addr *addr; - const struct in6_addr *last_addr = NULL; - dp = (struct ip6_rthdr *)bp; + dp = (const struct ip6_rthdr *)bp; len = dp->ip6r_len; /* 'ep' points to the end of available data. */ @@ -59,15 +57,9 @@ rt6_print(netdissect_options *ndo, register const u_char *bp, const u_char *bp2 ND_PRINT((ndo, ", segleft=%d", dp->ip6r_segleft)); switch (dp->ip6r_type) { -#ifndef IPV6_RTHDR_TYPE_0 -#define IPV6_RTHDR_TYPE_0 0 -#endif -#ifndef IPV6_RTHDR_TYPE_2 -#define IPV6_RTHDR_TYPE_2 2 -#endif case IPV6_RTHDR_TYPE_0: case IPV6_RTHDR_TYPE_2: /* Mobile IPv6 ID-20 */ - dp0 = (struct ip6_rthdr0 *)dp; + dp0 = (const struct ip6_rthdr0 *)dp; ND_TCHECK(dp0->ip6r0_reserved); if (dp0->ip6r0_reserved || ndo->ndo_vflag) { @@ -80,21 +72,12 @@ rt6_print(netdissect_options *ndo, register const u_char *bp, const u_char *bp2 len >>= 1; addr = &dp0->ip6r0_addr[0]; for (i = 0; i < len; i++) { - if ((u_char *)(addr + 1) > ep) + if ((const u_char *)(addr + 1) > ep) goto trunc; ND_PRINT((ndo, ", [%d]%s", i, ip6addr_string(ndo, addr))); - last_addr = addr; addr++; } - /* - * the destination address used in the pseudo-header is that of the final - * destination : the last address of the routing header - */ - if (last_addr != NULL) { - struct ip6_hdr *ip6 = (struct ip6_hdr *)bp2; - UNALIGNED_MEMCPY(&ip6->ip6_dst, last_addr, sizeof (struct in6_addr)); - } /*(*/ ND_PRINT((ndo, ") ")); return((dp0->ip6r0_len + 1) << 3); @@ -108,4 +91,3 @@ rt6_print(netdissect_options *ndo, register const u_char *bp, const u_char *bp2 ND_PRINT((ndo, "[|srcrt]")); return -1; } -#endif /* INET6 */ diff --git a/contrib/tcpdump/print-rtsp.c b/contrib/tcpdump/print-rtsp.c index d721b8d..54cc930 100644 --- a/contrib/tcpdump/print-rtsp.c +++ b/contrib/tcpdump/print-rtsp.c @@ -11,21 +11,18 @@ * FOR A PARTICULAR PURPOSE. */ -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header$"; -#endif +/* \summary: Real Time Streaming Protocol (RTSP) printer */ #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include #include -#include "interface.h" +#include "netdissect.h" #include "extract.h" static const char *rtspcmds[] = { diff --git a/contrib/tcpdump/print-rx.c b/contrib/tcpdump/print-rx.c index 8a9babb..ea3a5e6 100644 --- a/contrib/tcpdump/print-rx.c +++ b/contrib/tcpdump/print-rx.c @@ -20,6 +20,9 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ + +/* \summary: AFS RX printer */ + /* * This code unmangles RX packets. RX is the mutant form of RPC that AFS * uses to communicate between clients and servers. @@ -32,7 +35,6 @@ * Ken Hornstein */ -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -40,9 +42,9 @@ #include #include #include -#include +#include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" @@ -522,9 +524,9 @@ static int is_ubik(uint32_t); void rx_print(netdissect_options *ndo, register const u_char *bp, int length, int sport, int dport, - u_char *bp2) + const u_char *bp2) { - register struct rx_header *rxh; + register const struct rx_header *rxh; int i; int32_t opcode; @@ -533,7 +535,7 @@ rx_print(netdissect_options *ndo, return; } - rxh = (struct rx_header *) bp; + rxh = (const struct rx_header *) bp; ND_PRINT((ndo, " rx %s", tok2str(rx_types, "type %d", rxh->type))); @@ -689,8 +691,8 @@ rx_cache_insert(netdissect_options *ndo, rx_cache_next = 0; rxent->callnum = rxh->callNumber; - rxent->client = ip->ip_src; - rxent->server = ip->ip_dst; + UNALIGNED_MEMCPY(&rxent->client, &ip->ip_src, sizeof(uint32_t)); + UNALIGNED_MEMCPY(&rxent->server, &ip->ip_dst, sizeof(uint32_t)); rxent->dport = dport; rxent->serviceId = rxh->serviceId; rxent->opcode = EXTRACT_32BITS(bp + sizeof(struct rx_header)); @@ -709,8 +711,11 @@ rx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport, { int i; struct rx_cache_entry *rxent; - uint32_t clip = ip->ip_dst.s_addr; - uint32_t sip = ip->ip_src.s_addr; + uint32_t clip; + uint32_t sip; + + UNALIGNED_MEMCPY(&clip, &ip->ip_dst, sizeof(uint32_t)); + UNALIGNED_MEMCPY(&sip, &ip->ip_src, sizeof(uint32_t)); /* Start the search where we last left off */ @@ -752,63 +757,63 @@ rx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport, ND_PRINT((ndo, " fid %d/%d/%d", (int) n1, (int) n2, (int) n3)); \ } -#define STROUT(MAX) { unsigned int i; \ +#define STROUT(MAX) { unsigned int _i; \ ND_TCHECK2(bp[0], sizeof(int32_t)); \ - i = EXTRACT_32BITS(bp); \ - if (i > (MAX)) \ + _i = EXTRACT_32BITS(bp); \ + if (_i > (MAX)) \ goto trunc; \ bp += sizeof(int32_t); \ ND_PRINT((ndo, " \"")); \ - if (fn_printn(ndo, bp, i, ndo->ndo_snapend)) \ + if (fn_printn(ndo, bp, _i, ndo->ndo_snapend)) \ goto trunc; \ ND_PRINT((ndo, "\"")); \ - bp += ((i + sizeof(int32_t) - 1) / sizeof(int32_t)) * sizeof(int32_t); \ + bp += ((_i + sizeof(int32_t) - 1) / sizeof(int32_t)) * sizeof(int32_t); \ } -#define INTOUT() { int i; \ +#define INTOUT() { int _i; \ ND_TCHECK2(bp[0], sizeof(int32_t)); \ - i = (int) EXTRACT_32BITS(bp); \ + _i = (int) EXTRACT_32BITS(bp); \ bp += sizeof(int32_t); \ - ND_PRINT((ndo, " %d", i)); \ + ND_PRINT((ndo, " %d", _i)); \ } -#define UINTOUT() { unsigned long i; \ +#define UINTOUT() { unsigned long _i; \ ND_TCHECK2(bp[0], sizeof(int32_t)); \ - i = EXTRACT_32BITS(bp); \ + _i = EXTRACT_32BITS(bp); \ bp += sizeof(int32_t); \ - ND_PRINT((ndo, " %lu", i)); \ + ND_PRINT((ndo, " %lu", _i)); \ } -#define UINT64OUT() { uint64_t i; \ +#define UINT64OUT() { uint64_t _i; \ ND_TCHECK2(bp[0], sizeof(uint64_t)); \ - i = EXTRACT_64BITS(bp); \ + _i = EXTRACT_64BITS(bp); \ bp += sizeof(uint64_t); \ - ND_PRINT((ndo, " %" PRIu64, i)); \ + ND_PRINT((ndo, " %" PRIu64, _i)); \ } -#define DATEOUT() { time_t t; struct tm *tm; char str[256]; \ +#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) EXTRACT_32BITS(bp); \ bp += sizeof(int32_t); \ - tm = localtime(&t); \ - strftime(str, 256, "%Y/%m/%d %T", tm); \ + tm = localtime(&_t); \ + strftime(str, 256, "%Y/%m/%d %H:%M:%S", tm); \ ND_PRINT((ndo, " %s", str)); \ } -#define STOREATTROUT() { unsigned long mask, i; \ +#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)); \ + _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)); \ /* undocumented in 3.3 docu */ \ if (mask & 1024) ND_PRINT((ndo, " fsync")); \ } @@ -822,7 +827,7 @@ rx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport, ND_PRINT((ndo, " %d.%d", epoch, counter)); \ } -#define AFSUUIDOUT() {uint32_t temp; int i; \ +#define AFSUUIDOUT() {uint32_t temp; int _i; \ ND_TCHECK2(bp[0], 11*sizeof(uint32_t)); \ temp = EXTRACT_32BITS(bp); \ bp += sizeof(uint32_t); \ @@ -833,7 +838,7 @@ rx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport, temp = EXTRACT_32BITS(bp); \ bp += sizeof(uint32_t); \ ND_PRINT((ndo, "%04x", temp)); \ - for (i = 0; i < 8; i++) { \ + for (_i = 0; _i < 8; _i++) { \ temp = EXTRACT_32BITS(bp); \ bp += sizeof(uint32_t); \ ND_PRINT((ndo, "%02x", (unsigned char) temp)); \ @@ -951,7 +956,7 @@ fs_print(netdissect_options *ndo, bp += sizeof(int32_t); ND_TCHECK2(bp[0], i); i = min(AFSOPAQUEMAX, i); - strncpy(a, (char *) bp, i); + strncpy(a, (const char *) bp, i); a[i] = '\0'; acl_print(ndo, (u_char *) a, sizeof(a), (u_char *) a + i); break; @@ -1054,12 +1059,12 @@ fs_reply_print(netdissect_options *ndo, register const u_char *bp, int length, int32_t opcode) { unsigned long i; - struct rx_header *rxh; + const struct rx_header *rxh; if (length <= (int)sizeof(struct rx_header)) return; - rxh = (struct rx_header *) bp; + rxh = (const struct rx_header *) bp; /* * Print out the afs call we're invoking. The table used here was @@ -1084,7 +1089,7 @@ fs_reply_print(netdissect_options *ndo, bp += sizeof(int32_t); ND_TCHECK2(bp[0], i); i = min(AFSOPAQUEMAX, i); - strncpy(a, (char *) bp, i); + strncpy(a, (const char *) bp, i); a[i] = '\0'; acl_print(ndo, (u_char *) a, sizeof(a), (u_char *) a + i); break; @@ -1105,8 +1110,6 @@ fs_reply_print(netdissect_options *ndo, ; } } else if (rxh->type == RX_PACKET_TYPE_ABORT) { - int i; - /* * Otherwise, just print out the return code */ @@ -1299,12 +1302,12 @@ static void cb_reply_print(netdissect_options *ndo, register const u_char *bp, int length, int32_t opcode) { - struct rx_header *rxh; + const struct rx_header *rxh; if (length <= (int)sizeof(struct rx_header)) return; - rxh = (struct rx_header *) bp; + rxh = (const struct rx_header *) bp; /* * Print out the afs call we're invoking. The table used here was @@ -1493,13 +1496,13 @@ static void prot_reply_print(netdissect_options *ndo, register const u_char *bp, int length, int32_t opcode) { - struct rx_header *rxh; + const struct rx_header *rxh; unsigned long i; if (length < (int)sizeof(struct rx_header)) return; - rxh = (struct rx_header *) bp; + rxh = (const struct rx_header *) bp; /* * Print out the afs call we're invoking. The table used here was @@ -1700,13 +1703,13 @@ static void vldb_reply_print(netdissect_options *ndo, register const u_char *bp, int length, int32_t opcode) { - struct rx_header *rxh; + const struct rx_header *rxh; unsigned long i; if (length < (int)sizeof(struct rx_header)) return; - rxh = (struct rx_header *) bp; + rxh = (const struct rx_header *) bp; /* * Print out the afs call we're invoking. The table used here was @@ -1752,7 +1755,7 @@ vldb_reply_print(netdissect_options *ndo, ND_TCHECK2(bp[0], sizeof(int32_t)); if (i < nservers) ND_PRINT((ndo, " %s", - intoa(((struct in_addr *) bp)->s_addr))); + intoa(((const struct in_addr *) bp)->s_addr))); bp += sizeof(int32_t); } ND_PRINT((ndo, " partitions")); @@ -1799,7 +1802,7 @@ vldb_reply_print(netdissect_options *ndo, ND_TCHECK2(bp[0], sizeof(int32_t)); if (i < nservers) ND_PRINT((ndo, " %s", - intoa(((struct in_addr *) bp)->s_addr))); + intoa(((const struct in_addr *) bp)->s_addr))); bp += sizeof(int32_t); } ND_PRINT((ndo, " partitions")); @@ -1921,7 +1924,7 @@ kauth_print(netdissect_options *ndo, bp += sizeof(struct rx_header) + 4; switch (kauth_op) { - case 1: /* Authenticate old */; + case 1: /* Authenticate old */ case 21: /* Authenticate */ case 22: /* Authenticate-V2 */ case 2: /* Change PW */ @@ -1982,12 +1985,12 @@ static void kauth_reply_print(netdissect_options *ndo, register const u_char *bp, int length, int32_t opcode) { - struct rx_header *rxh; + const struct rx_header *rxh; if (length <= (int)sizeof(struct rx_header)) return; - rxh = (struct rx_header *) bp; + rxh = (const struct rx_header *) bp; /* * Print out the afs call we're invoking. The table used here was @@ -2236,12 +2239,12 @@ static void vol_reply_print(netdissect_options *ndo, register const u_char *bp, int length, int32_t opcode) { - struct rx_header *rxh; + const struct rx_header *rxh; if (length <= (int)sizeof(struct rx_header)) return; - rxh = (struct rx_header *) bp; + rxh = (const struct rx_header *) bp; /* * Print out the afs call we're invoking. The table used here was @@ -2463,12 +2466,12 @@ static void bos_reply_print(netdissect_options *ndo, register const u_char *bp, int length, int32_t opcode) { - struct rx_header *rxh; + const struct rx_header *rxh; if (length <= (int)sizeof(struct rx_header)) return; - rxh = (struct rx_header *) bp; + rxh = (const struct rx_header *) bp; /* * Print out the afs call we're invoking. The table used here was @@ -2632,12 +2635,12 @@ static void ubik_reply_print(netdissect_options *ndo, register const u_char *bp, int length, int32_t opcode) { - struct rx_header *rxh; + const struct rx_header *rxh; if (length < (int)sizeof(struct rx_header)) return; - rxh = (struct rx_header *) bp; + rxh = (const struct rx_header *) bp; /* * Print out the ubik call we're invoking. This table was gleaned @@ -2696,7 +2699,7 @@ static void rx_ack_print(netdissect_options *ndo, register const u_char *bp, int length) { - struct rx_ackPacket *rxa; + const struct rx_ackPacket *rxa; int i, start, last; uint32_t firstPacket; @@ -2715,7 +2718,7 @@ rx_ack_print(netdissect_options *ndo, ND_TCHECK2(bp[0], sizeof(struct rx_ackPacket) - RX_MAXACKS); - rxa = (struct rx_ackPacket *) bp; + rxa = (const struct rx_ackPacket *) bp; bp += (sizeof(struct rx_ackPacket) - RX_MAXACKS); /* diff --git a/contrib/tcpdump/print-sctp.c b/contrib/tcpdump/print-sctp.c index 4b595f2..f625dce 100644 --- a/contrib/tcpdump/print-sctp.c +++ b/contrib/tcpdump/print-sctp.c @@ -33,20 +33,19 @@ * SUCH DAMAGE. */ -#define NETDISSECT_REWORKED +/* \summary: Stream Control Transmission Protocol (SCTP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" -#include "extract.h" /* must come after interface.h */ +#include "extract.h" #include "ip.h" -#ifdef INET6 #include "ip6.h" -#endif /* Definitions from: * @@ -496,48 +495,35 @@ void sctp_print(netdissect_options *ndo, const u_char *bp2, /* beginning of enclosing */ u_int sctpPacketLength) /* ip packet */ { + u_int sctpPacketLengthRemaining; const struct sctpHeader *sctpPktHdr; const struct ip *ip; -#ifdef INET6 const struct ip6_hdr *ip6; -#endif - const void *endPacketPtr; u_short sourcePort, destPort; int chunkCount; const struct sctpChunkDesc *chunkDescPtr; - const void *nextChunk; const char *sep; int isforces = 0; - - sctpPktHdr = (const struct sctpHeader*) bp; - endPacketPtr = (const u_char*)sctpPktHdr+sctpPacketLength; - - if( (u_long) endPacketPtr > (u_long) ndo->ndo_snapend) - endPacketPtr = (const void *) ndo->ndo_snapend; - ip = (struct ip *)bp2; -#ifdef INET6 - if (IP_V(ip) == 6) - ip6 = (const struct ip6_hdr *)bp2; - else - ip6 = NULL; -#endif /*INET6*/ - ND_TCHECK(*sctpPktHdr); - if (sctpPacketLength < sizeof(struct sctpHeader)) { ND_PRINT((ndo, "truncated-sctp - %ld bytes missing!", - (long)sctpPacketLength-sizeof(struct sctpHeader))); + (long)(sizeof(struct sctpHeader) - sctpPacketLength))); return; } - - /* sctpPacketLength -= sizeof(struct sctpHeader); packet length */ - /* is now only as long as the payload */ + sctpPktHdr = (const struct sctpHeader*) bp; + ND_TCHECK(*sctpPktHdr); + sctpPacketLengthRemaining = sctpPacketLength; sourcePort = EXTRACT_16BITS(&sctpPktHdr->source); destPort = EXTRACT_16BITS(&sctpPktHdr->destination); -#ifdef INET6 + ip = (const struct ip *)bp2; + if (IP_V(ip) == 6) + ip6 = (const struct ip6_hdr *)bp2; + else + ip6 = NULL; + if (ip6) { ND_PRINT((ndo, "%s.%d > %s.%d: sctp", ip6addr_string(ndo, &ip6->ip6_src), @@ -545,7 +531,6 @@ void sctp_print(netdissect_options *ndo, ip6addr_string(ndo, &ip6->ip6_dst), destPort)); } else -#endif /*INET6*/ { ND_PRINT((ndo, "%s.%d > %s.%d: sctp", ipaddr_string(ndo, &ip->ip_src), @@ -563,40 +548,48 @@ void sctp_print(netdissect_options *ndo, isforces = 1; } + bp += sizeof(struct sctpHeader); + sctpPacketLengthRemaining -= sizeof(struct sctpHeader); + if (ndo->ndo_vflag >= 2) sep = "\n\t"; else sep = " ("; /* cycle through all chunks, printing information on each one */ - for (chunkCount = 0, - chunkDescPtr = (const struct sctpChunkDesc *) - ((const u_char*) sctpPktHdr + sizeof(struct sctpHeader)); - chunkDescPtr != NULL && - ( (const void *) - ((const u_char *) chunkDescPtr + sizeof(struct sctpChunkDesc)) - <= endPacketPtr); - - chunkDescPtr = (const struct sctpChunkDesc *) nextChunk, chunkCount++) + for (chunkCount = 0, chunkDescPtr = (const struct sctpChunkDesc *)bp; + sctpPacketLengthRemaining != 0; + chunkCount++) { - uint16_t chunkLength; - const u_char *chunkEnd; + uint16_t chunkLength, chunkLengthRemaining; uint16_t align; + 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_TCHECK(*chunkDescPtr); chunkLength = EXTRACT_16BITS(&chunkDescPtr->chunkLength); if (chunkLength < sizeof(*chunkDescPtr)) { - ND_PRINT((ndo, "%s%d) [Bad chunk length %u]", sep, chunkCount+1, chunkLength)); + ND_PRINT((ndo, "%s%d) [Bad chunk length %u, < size of chunk descriptor]", sep, chunkCount+1, chunkLength)); break; } + chunkLengthRemaining = chunkLength; - ND_TCHECK2(*((uint8_t *)chunkDescPtr), chunkLength); - chunkEnd = ((const u_char*)chunkDescPtr + chunkLength); - - align=chunkLength % 4; + align = chunkLength % 4; if (align != 0) align = 4 - align; - nextChunk = (const void *) (chunkEnd + align); + if (sctpPacketLengthRemaining < align) { + ND_PRINT((ndo, "%s%d) [Bad chunk length %u, > remaining data in packet]", sep, chunkCount+1, chunkLength)); + break; + } + + ND_TCHECK2(*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", @@ -607,7 +600,6 @@ void sctp_print(netdissect_options *ndo, { const struct sctpDataPart *dataHdrPtr; uint32_t ppid; - const u_char *payloadPtr; u_int payload_size; if ((chunkDescPtr->chunkFlg & SCTP_DATA_UNORDERED) @@ -632,7 +624,11 @@ void sctp_print(netdissect_options *ndo, == SCTP_DATA_LAST_FRAG) ) ND_PRINT((ndo, " ")); - dataHdrPtr=(const struct sctpDataPart*)(chunkDescPtr+1); + if (chunkLengthRemaining < sizeof(*dataHdrPtr)) { + ND_PRINT((ndo, "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))); @@ -647,70 +643,92 @@ void sctp_print(netdissect_options *ndo, (ppid == SCTP_PPID_FORCES_LP); } - payloadPtr = (const u_char *) (dataHdrPtr + 1); - if (EXTRACT_16BITS(&chunkDescPtr->chunkLength) < - sizeof(struct sctpDataPart) + sizeof(struct sctpChunkDesc) + 1) { - ND_PRINT((ndo, "bogus chunk length %u]", EXTRACT_16BITS(&chunkDescPtr->chunkLength))); + bp += sizeof(*dataHdrPtr); + sctpPacketLengthRemaining -= sizeof(*dataHdrPtr); + chunkLengthRemaining -= sizeof(*dataHdrPtr); + payload_size = chunkLengthRemaining; + if (payload_size == 0) { + ND_PRINT((ndo, "bogus chunk length %u]", chunkLength)); return; } - payload_size = EXTRACT_16BITS(&chunkDescPtr->chunkLength) - - (sizeof(struct sctpDataPart) + sizeof(struct sctpChunkDesc)); - if (isforces) { - forces_print(ndo, payloadPtr, payload_size); + forces_print(ndo, bp, payload_size); } else if (ndo->ndo_vflag >= 2) { /* if verbose output is specified */ /* at the command line */ switch (ppid) { case SCTP_PPID_M3UA : - m3ua_print(ndo, payloadPtr, payload_size); + m3ua_print(ndo, bp, payload_size); break; default: ND_PRINT((ndo, "[Payload")); if (!ndo->ndo_suppress_default_print) { ND_PRINT((ndo, ":")); - ND_DEFAULTPRINT(payloadPtr, payload_size); + ND_DEFAULTPRINT(bp, payload_size); } ND_PRINT((ndo, "]")); break; } } + bp += payload_size; + sctpPacketLengthRemaining -= payload_size; + chunkLengthRemaining -= payload_size; break; } case SCTP_INITIATION : { const struct sctpInitiation *init; - init=(const struct sctpInitiation*)(chunkDescPtr+1); + if (chunkLengthRemaining < sizeof(*init)) { + ND_PRINT((ndo, "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); -#if(0) /* ALC you can add code for optional params here */ - if( (init+1) < chunkEnd ) +#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.")); #endif + bp += chunkLengthRemaining; + sctpPacketLengthRemaining -= chunkLengthRemaining; + chunkLengthRemaining = 0; break; } case SCTP_INITIATION_ACK : { const struct sctpInitiation *init; - init=(const struct sctpInitiation*)(chunkDescPtr+1); + if (chunkLengthRemaining < sizeof(*init)) { + ND_PRINT((ndo, "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); -#if(0) /* ALC you can add code for optional params here */ - if( (init+1) < chunkEnd ) +#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.")); #endif + bp += chunkLengthRemaining; + sctpPacketLengthRemaining -= chunkLengthRemaining; + chunkLengthRemaining = 0; break; } case SCTP_SELECTIVE_ACK: @@ -720,38 +738,77 @@ void sctp_print(netdissect_options *ndo, int fragNo, tsnNo; const u_char *dupTSN; - sack=(const struct sctpSelectiveAck*)(chunkDescPtr+1); + if (chunkLengthRemaining < sizeof(*sack)) { + ND_PRINT((ndo, "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); + sctpPacketLengthRemaining -= sizeof(*sack); + chunkLengthRemaining -= sizeof(*sack); /* print gaps */ - for (frag = ( (const struct sctpSelectiveFrag *) - ((const struct sctpSelectiveAck *) sack+1)), - fragNo=0; - (const void *)frag < nextChunk && fragNo < EXTRACT_16BITS(&sack->numberOfdesc); - frag++, fragNo++) + for (fragNo=0; + chunkLengthRemaining != 0 && fragNo < EXTRACT_16BITS(&sack->numberOfdesc); + bp += sizeof(*frag), sctpPacketLengthRemaining -= sizeof(*frag), chunkLengthRemaining -= sizeof(*frag), fragNo++) { + if (chunkLengthRemaining < sizeof(*frag)) { + ND_PRINT((ndo, "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] ", fragNo+1, EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentStart), EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentEnd))); - + } /* print duplicate TSNs */ - for (dupTSN = (const u_char *)frag, tsnNo=0; - (const void *) dupTSN < nextChunk && tsnNonumDupTsns); - dupTSN += 4, tsnNo++) + for (tsnNo=0; + chunkLengthRemaining != 0 && tsnNonumDupTsns); + bp += 4, sctpPacketLengthRemaining -= 4, chunkLengthRemaining -= 4, tsnNo++) { + if (chunkLengthRemaining < 4) { + ND_PRINT((ndo, "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))); - + EXTRACT_32BITS(dupTSN))); + } + break; + } + default : + { + bp += chunkLengthRemaining; + sctpPacketLengthRemaining -= chunkLengthRemaining; + chunkLengthRemaining = 0; break; } } - if (ndo->ndo_vflag < 2) - sep = ", ("; + /* + * Any extra stuff at the end of the chunk? + * XXX - report this? + */ + bp += chunkLengthRemaining; + sctpPacketLengthRemaining -= chunkLengthRemaining; + + if (ndo->ndo_vflag < 2) + sep = ", ("; + + if (align != 0) { + /* + * Fail if the alignment padding isn't in the captured data. + * Otherwise, skip it. + */ + ND_TCHECK2(*bp, align); + bp += align; + sctpPacketLengthRemaining -= align; + } } return; diff --git a/contrib/tcpdump/print-sflow.c b/contrib/tcpdump/print-sflow.c index 24112f4..37a41b5 100644 --- a/contrib/tcpdump/print-sflow.c +++ b/contrib/tcpdump/print-sflow.c @@ -12,21 +12,22 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * The SFLOW protocol as per http://www.sflow.org/developers/specifications.php - * * Original code by Carles Kishimoto * * Expansion and refactoring by Rick Jones */ -#define NETDISSECT_REWORKED +/* \summary: sFlow protocol printer */ + +/* specification: http://www.sflow.org/developers/specifications.php */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "addrtoname.h" @@ -304,8 +305,8 @@ print_sflow_counter_generic(netdissect_options *ndo, if (len < sizeof(struct sflow_generic_counter_t)) 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), @@ -339,6 +340,9 @@ print_sflow_counter_generic(netdissect_options *ndo, EXTRACT_32BITS(sflow_gen_counter->ifpromiscmode))); return 0; + +trunc: + return 1; } static int @@ -351,6 +355,7 @@ 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), @@ -369,6 +374,9 @@ print_sflow_counter_ethernet(netdissect_options *ndo, EXTRACT_32BITS(sflow_eth_counter->symbol_errors))); return 0; + +trunc: + return 1; } static int @@ -388,6 +396,7 @@ 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))); @@ -412,6 +421,9 @@ print_sflow_counter_basevg(netdissect_options *ndo, EXTRACT_64BITS(sflow_100basevg_counter->hc_out_highpriority_octets))); return 0; + +trunc: + return 1; } static int @@ -424,6 +436,7 @@ 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 ", unicast_pkt %u, multicast_pkt %u, broadcast_pkt %u, discards %u", EXTRACT_32BITS(sflow_vlan_counter->vlan_id), @@ -434,6 +447,9 @@ print_sflow_counter_vlan(netdissect_options *ndo, EXTRACT_32BITS(sflow_vlan_counter->discards))); return 0; + +trunc: + return 1; } struct sflow_processor_counter_t { @@ -454,6 +470,7 @@ 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 ", total_mem %" PRIu64, EXTRACT_32BITS(sflow_processor_counter->five_sec_util), @@ -463,6 +480,9 @@ print_sflow_counter_processor(netdissect_options *ndo, EXTRACT_64BITS(sflow_processor_counter->free_memory))); return 0; + +trunc: + return 1; } static int @@ -486,6 +506,7 @@ 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); counter_type = enterprise & 0x0FFF; @@ -541,6 +562,9 @@ sflow_print_counter_records(netdissect_options *ndo, } return 0; + +trunc: + return 1; } static int @@ -553,11 +577,11 @@ sflow_print_counter_sample(netdissect_options *ndo, 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); @@ -574,6 +598,8 @@ sflow_print_counter_sample(netdissect_options *ndo, len - sizeof(struct sflow_counter_sample_t), nrecords); +trunc: + return 1; } static int @@ -588,6 +614,7 @@ 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); @@ -601,6 +628,8 @@ sflow_print_expanded_counter_sample(netdissect_options *ndo, len - sizeof(struct sflow_expanded_counter_sample_t), nrecords); +trunc: + return 1; } static int @@ -613,6 +642,7 @@ 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), @@ -624,6 +654,9 @@ print_sflow_raw_packet(netdissect_options *ndo, assuming of course there is wnough data present to do so... */ return 0; + +trunc: + return 1; } static int @@ -636,12 +669,16 @@ 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))); return 0; + +trunc: + return 1; } static int @@ -654,6 +691,7 @@ 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), @@ -661,6 +699,9 @@ print_sflow_extended_switch_data(netdissect_options *ndo, EXTRACT_32BITS(sflow_extended_sw_data->dst_pri))); return 0; + +trunc: + return 1; } static int @@ -685,6 +726,7 @@ 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. */ @@ -747,6 +789,9 @@ sflow_print_flow_records(netdissect_options *ndo, } return 0; + +trunc: + return 1; } static int @@ -762,7 +807,8 @@ sflow_print_flow_sample(netdissect_options *ndo, if (len < sizeof(struct sflow_flow_sample_t)) return 1; - sflow_flow_sample = (struct sflow_flow_sample_t *)pointer; + 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); @@ -784,6 +830,8 @@ sflow_print_flow_sample(netdissect_options *ndo, len - sizeof(struct sflow_flow_sample_t), nrecords); +trunc: + return 1; } static int @@ -797,6 +845,7 @@ 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); @@ -813,6 +862,8 @@ sflow_print_expanded_flow_sample(netdissect_options *ndo, len - sizeof(struct sflow_expanded_flow_sample_t), nrecords); +trunc: + return 1; } void @@ -827,7 +878,6 @@ sflow_print(netdissect_options *ndo, uint32_t sflow_sample_type, sflow_sample_len; uint32_t nsamples; - tptr = pptr; tlen = len; sflow_datagram = (const struct sflow_datagram_t *)pptr; diff --git a/contrib/tcpdump/print-sip.c b/contrib/tcpdump/print-sip.c index d0fd349..8e308ed 100644 --- a/contrib/tcpdump/print-sip.c +++ b/contrib/tcpdump/print-sip.c @@ -15,14 +15,15 @@ * Guy Harris. */ -#define NETDISSECT_REWORKED +/* \summary: Session Initiation Protocol (SIP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" static const char *sipcmds[] = { diff --git a/contrib/tcpdump/print-sl.c b/contrib/tcpdump/print-sl.c index 8d9eadc..3fd7e89 100644 --- a/contrib/tcpdump/print-sl.c +++ b/contrib/tcpdump/print-sl.c @@ -17,19 +17,18 @@ * 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. - * - * $FreeBSD$ */ -#define NETDISSECT_REWORKED +/* \summary: Compressed Serial Line Internet Protocol printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" -#include "extract.h" /* must come after interface.h */ +#include "netdissect.h" +#include "extract.h" #include "ip.h" #include "tcp.h" @@ -69,19 +68,25 @@ sl_if_print(netdissect_options *ndo, return (caplen); } + caplen -= SLIP_HDRLEN; length -= SLIP_HDRLEN; - ip = (struct ip *)(p + SLIP_HDRLEN); + ip = (const struct ip *)(p + SLIP_HDRLEN); if (ndo->ndo_eflag) sliplink_print(ndo, p, ip, length); + if (caplen < 1 || length < 1) { + ND_PRINT((ndo, "%s", tstr)); + return (caplen + SLIP_HDRLEN); + } + switch (IP_V(ip)) { case 4: - ip_print(ndo, (u_char *)ip, length); + ip_print(ndo, (const u_char *)ip, length); break; case 6: - ip6_print(ndo, (u_char *)ip, length); + ip6_print(ndo, (const u_char *)ip, length); break; default: ND_PRINT((ndo, "ip v%d", IP_V(ip))); @@ -105,14 +110,14 @@ sl_bsdos_if_print(netdissect_options *ndo, length -= SLIP_HDRLEN; - ip = (struct ip *)(p + SLIP_HDRLEN); + ip = (const struct ip *)(p + SLIP_HDRLEN); #ifdef notdef if (ndo->ndo_eflag) sliplink_print(ndo, p, ip, length); #endif - ip_print(ndo, (u_char *)ip, length); + ip_print(ndo, (const u_char *)ip, length); return (SLIP_HDRLEN); } @@ -149,9 +154,9 @@ 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 = ((struct ip *)&p[SLX_CHDR])->ip_p; + lastconn = ((const struct ip *)&p[SLX_CHDR])->ip_p; hlen = IP_HL(ip); - hlen += TH_OFF((struct tcphdr *)&((int *)ip)[hlen]); + hlen += TH_OFF((const struct tcphdr *)&((const int *)ip)[hlen]); lastlen[dir][lastconn] = length - (hlen << 2); ND_PRINT((ndo, "utcp %d: ", lastconn)); break; @@ -244,7 +249,7 @@ compressed_sl_print(netdissect_options *ndo, * 'length - hlen' is the amount of data in the packet. */ hlen = IP_HL(ip); - hlen += TH_OFF((struct tcphdr *)&((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))); } diff --git a/contrib/tcpdump/print-sll.c b/contrib/tcpdump/print-sll.c index 1f5f600..6148569 100644 --- a/contrib/tcpdump/print-sll.c +++ b/contrib/tcpdump/print-sll.c @@ -19,14 +19,15 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: Linux cooked sockets capture printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "ethertype.h" #include "extract.h" @@ -198,7 +199,8 @@ sll_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char u_int length = h->len; register const struct sll_header *sllp; u_short ether_type; - u_short extracted_ethertype; + int llc_hdrlen; + u_int hdrlen; if (caplen < SLL_HDR_LEN) { /* @@ -221,6 +223,7 @@ sll_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char length -= SLL_HDR_LEN; caplen -= SLL_HDR_LEN; p += SLL_HDR_LEN; + hdrlen = SLL_HDR_LEN; ether_type = EXTRACT_16BITS(&sllp->sll_protocol); @@ -247,23 +250,17 @@ recurse: * 802.2. * Try to print the LLC-layer header & higher layers. */ - if (llc_print(ndo, p, length, caplen, NULL, NULL, - &extracted_ethertype) == 0) + llc_hdrlen = llc_print(ndo, p, length, caplen, NULL, NULL); + if (llc_hdrlen < 0) goto unknown; /* unknown LLC type */ + hdrlen += llc_hdrlen; break; default: - extracted_ethertype = 0; /*FALLTHROUGH*/ unknown: - /* ether_type not known, print raw packet */ - if (!ndo->ndo_eflag) - sll_print(ndo, sllp, length + SLL_HDR_LEN); - if (extracted_ethertype) { - ND_PRINT((ndo, "(LLC %s) ", - etherproto_string(htons(extracted_ethertype)))); - } + /* packet type not known, print raw packet */ if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); break; @@ -273,9 +270,13 @@ recurse: * Print VLAN information, and then go back and process * the enclosed type field. */ - if (caplen < 4 || length < 4) { + if (caplen < 4) { + ND_PRINT((ndo, "[|vlan]")); + return (hdrlen + caplen); + } + if (length < 4) { ND_PRINT((ndo, "[|vlan]")); - return (SLL_HDR_LEN); + return (hdrlen + length); } if (ndo->ndo_eflag) { uint16_t tag = EXTRACT_16BITS(p); @@ -293,9 +294,10 @@ recurse: p += 4; length -= 4; caplen -= 4; + hdrlen += 4; goto recurse; } else { - if (ethertype_print(ndo, ether_type, p, length, caplen) == 0) { + if (ethertype_print(ndo, ether_type, p, length, caplen, NULL, NULL) == 0) { /* ether_type not known, print raw packet */ if (!ndo->ndo_eflag) sll_print(ndo, sllp, length + SLL_HDR_LEN); @@ -304,5 +306,5 @@ recurse: } } - return (SLL_HDR_LEN); + return (hdrlen); } diff --git a/contrib/tcpdump/print-slow.c b/contrib/tcpdump/print-slow.c index 2db3581..92d4a7b 100644 --- a/contrib/tcpdump/print-slow.c +++ b/contrib/tcpdump/print-slow.c @@ -18,24 +18,20 @@ * Original code by Hannes Gredler (hannes@juniper.net) */ -#define NETDISSECT_REWORKED +/* \summary: IEEE "slow protocols" (802.3ad/802.3ah) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "addrtoname.h" #include "ether.h" #include "oui.h" -struct slow_common_header_t { - uint8_t proto_subtype; - uint8_t version; -}; - #define SLOW_PROTO_LACP 1 #define SLOW_PROTO_MARKER 2 #define SLOW_PROTO_OAM 3 @@ -185,21 +181,21 @@ struct tlv_header_t { uint8_t length; }; -#define LACP_TLV_TERMINATOR 0x00 -#define LACP_TLV_ACTOR_INFO 0x01 -#define LACP_TLV_PARTNER_INFO 0x02 -#define LACP_TLV_COLLECTOR_INFO 0x03 +#define LACP_MARKER_TLV_TERMINATOR 0x00 /* same code for LACP and Marker */ + +#define LACP_TLV_ACTOR_INFO 0x01 +#define LACP_TLV_PARTNER_INFO 0x02 +#define LACP_TLV_COLLECTOR_INFO 0x03 -#define MARKER_TLV_TERMINATOR 0x00 -#define MARKER_TLV_MARKER_INFO 0x01 +#define MARKER_TLV_MARKER_INFO 0x01 static const struct tok slow_tlv_values[] = { - { (SLOW_PROTO_LACP << 8) + LACP_TLV_TERMINATOR, "Terminator"}, + { (SLOW_PROTO_LACP << 8) + LACP_MARKER_TLV_TERMINATOR, "Terminator"}, { (SLOW_PROTO_LACP << 8) + LACP_TLV_ACTOR_INFO, "Actor Information"}, { (SLOW_PROTO_LACP << 8) + LACP_TLV_PARTNER_INFO, "Partner Information"}, { (SLOW_PROTO_LACP << 8) + LACP_TLV_COLLECTOR_INFO, "Collector Information"}, - { (SLOW_PROTO_MARKER << 8) + MARKER_TLV_TERMINATOR, "Terminator"}, + { (SLOW_PROTO_MARKER << 8) + LACP_MARKER_TLV_TERMINATOR, "Terminator"}, { (SLOW_PROTO_MARKER << 8) + MARKER_TLV_MARKER_INFO, "Marker Information"}, { 0, NULL} }; @@ -242,35 +238,42 @@ struct lacp_marker_tlv_terminator_t { uint8_t pad[50]; }; -static void slow_marker_lacp_print(netdissect_options *, register const u_char *, register u_int); +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); -const struct slow_common_header_t *slow_com_header; - void slow_print(netdissect_options *ndo, register const u_char *pptr, register u_int len) { int print_version; + u_int subtype; - slow_com_header = (const struct slow_common_header_t *)pptr; - ND_TCHECK(*slow_com_header); + if (len < 1) + goto tooshort; + ND_TCHECK(*pptr); + subtype = *pptr; /* * Sanity checking of the header. */ - switch (slow_com_header->proto_subtype) { + switch (subtype) { case SLOW_PROTO_LACP: - if (slow_com_header->version != LACP_VERSION) { - ND_PRINT((ndo, "LACP version %u packet not supported",slow_com_header->version)); + 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))); return; } print_version = 1; break; case SLOW_PROTO_MARKER: - if (slow_com_header->version != MARKER_VERSION) { - ND_PRINT((ndo, "MARKER version %u packet not supported",slow_com_header->version)); + 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))); return; } print_version = 1; @@ -286,15 +289,15 @@ slow_print(netdissect_options *ndo, break; } - if (print_version) { + if (print_version == 1) { ND_PRINT((ndo, "%sv%u, length %u", - tok2str(slow_proto_values, "unknown (%u)",slow_com_header->proto_subtype), - slow_com_header->version, + tok2str(slow_proto_values, "unknown (%u)", subtype), + *(pptr+1), len)); } else { /* some slow protos don't have a version number in the header */ ND_PRINT((ndo, "%s, length %u", - tok2str(slow_proto_values, "unknown (%u)",slow_com_header->proto_subtype), + tok2str(slow_proto_values, "unknown (%u)", subtype), len)); } @@ -307,32 +310,45 @@ slow_print(netdissect_options *ndo, if (!ndo->ndo_vflag) return; - switch (slow_com_header->proto_subtype) { + switch (subtype) { default: /* should not happen */ break; case SLOW_PROTO_OAM: - /* skip proto_subtype */ - slow_oam_print(ndo, pptr+1, len-1); + /* skip subtype */ + len -= 1; + pptr += 1; + slow_oam_print(ndo, pptr, len); break; case SLOW_PROTO_LACP: /* LACP and MARKER share the same semantics */ case SLOW_PROTO_MARKER: - /* skip slow_common_header */ - len -= sizeof(const struct slow_common_header_t); - pptr += sizeof(const struct slow_common_header_t); - slow_marker_lacp_print(ndo, pptr, len); + /* skip subtype and version */ + len -= 2; + pptr += 2; + slow_marker_lacp_print(ndo, pptr, len, subtype); break; } return; +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: - ND_PRINT((ndo, "\n\t\t packet exceeded snapshot")); + if (!ndo->ndo_vflag) + ND_PRINT((ndo, " (packet exceeded snapshot)")); + else + ND_PRINT((ndo, "\n\t\t packet exceeded snapshot")); } static void slow_marker_lacp_print(netdissect_options *ndo, - register const u_char *tptr, register u_int tlen) + register const u_char *tptr, register u_int tlen, + u_int proto_subtype) { const struct tlv_header_t *tlv_header; const u_char *tlv_tptr; @@ -346,6 +362,9 @@ slow_marker_lacp_print(netdissect_options *ndo, } tlv_ptr; while(tlen>0) { + /* is the packet big enough to include the tlv header ? */ + 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; @@ -354,30 +373,46 @@ slow_marker_lacp_print(netdissect_options *ndo, ND_PRINT((ndo, "\n\t%s TLV (0x%02x), length %u", tok2str(slow_tlv_values, "Unknown", - (slow_com_header->proto_subtype << 8) + tlv_header->type), + (proto_subtype << 8) + tlv_header->type), tlv_header->type, tlv_len)); - if ((tlv_len < sizeof(struct tlv_header_t) || - tlv_len > tlen) && - tlv_header->type != LACP_TLV_TERMINATOR && - tlv_header->type != MARKER_TLV_TERMINATOR) { - ND_PRINT((ndo, "\n\t-----trailing data-----")); - print_unknown_data(ndo, tptr+sizeof(struct tlv_header_t), "\n\t ", tlen); + if (tlv_header->type == LACP_MARKER_TLV_TERMINATOR) { + /* + * This TLV has a length of zero, and means there are no + * more TLVs to process. + */ return; } - tlv_tptr=tptr+sizeof(struct tlv_header_t); - tlv_tlen=tlv_len-sizeof(struct tlv_header_t); + /* 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))); + return; + } + /* is the packet big enough to include the tlv ? */ + if (tlen < tlv_len) + goto tooshort; /* did we capture enough for fully decoding the tlv ? */ ND_TCHECK2(*tptr, tlv_len); - switch((slow_com_header->proto_subtype << 8) + tlv_header->type) { + tlv_tptr=tptr+sizeof(struct tlv_header_t); + tlv_tlen=tlv_len-sizeof(struct tlv_header_t); + + switch((proto_subtype << 8) + tlv_header->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)))); + 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" \ @@ -394,6 +429,13 @@ slow_marker_lacp_print(netdissect_options *ndo, 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)))); + 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", @@ -402,6 +444,13 @@ slow_marker_lacp_print(netdissect_options *ndo, 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)))); + 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", @@ -411,29 +460,13 @@ slow_marker_lacp_print(netdissect_options *ndo, break; - /* those two TLVs have the same structure -> fall through */ - case ((SLOW_PROTO_LACP << 8) + LACP_TLV_TERMINATOR): - case ((SLOW_PROTO_MARKER << 8) + LACP_TLV_TERMINATOR): - tlv_ptr.lacp_marker_tlv_terminator = (const struct lacp_marker_tlv_terminator_t *)tlv_tptr; - if (tlv_len == 0) { - tlv_len = sizeof(tlv_ptr.lacp_marker_tlv_terminator->pad) + - sizeof(struct tlv_header_t); - /* tell the user that we modified the length field */ - if (ndo->ndo_vflag>1) - ND_PRINT((ndo, " (=%u)", tlv_len)); - /* we have messed around with the length field - now we need to check - * again if there are enough bytes on the wire for the hexdump */ - ND_TCHECK2(tlv_ptr.lacp_marker_tlv_terminator->pad[0], - sizeof(tlv_ptr.lacp_marker_tlv_terminator->pad)); - } - - break; - default: if (ndo->ndo_vflag <= 1) print_unknown_data(ndo, tlv_tptr, "\n\t ", tlv_tlen); break; } + + badlength: /* do we want to see an additional hexdump ? */ if (ndo->ndo_vflag > 1) { print_unknown_data(ndo, tptr+sizeof(struct tlv_header_t), "\n\t ", @@ -444,6 +477,11 @@ slow_marker_lacp_print(netdissect_options *ndo, tlen-=tlv_len; } return; + +tooshort: + ND_PRINT((ndo, "\n\t\t packet is too short")); + return; + trunc: ND_PRINT((ndo, "\n\t\t packet exceeded snapshot")); } @@ -477,7 +515,10 @@ slow_oam_print(netdissect_options *ndo, const struct slow_oam_loopbackctrl_t *slow_oam_loopbackctrl; } tlv; - ptr.slow_oam_common_header = (struct slow_oam_common_header_t *)tptr; + 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); tptr += sizeof(struct slow_oam_common_header_t); tlen -= sizeof(struct slow_oam_common_header_t); @@ -491,20 +532,36 @@ slow_oam_print(netdissect_options *ndo, 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)); - hexdump = FALSE; - switch (ptr.slow_oam_tlv_header->type) { - case SLOW_OAM_INFO_TYPE_END_OF_TLV: - if (ptr.slow_oam_tlv_header->length != 0) { - ND_PRINT((ndo, "\n\t ERROR: illegal length - should be 0")); - } + if (ptr.slow_oam_tlv_header->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)". + */ + return; + } + + /* 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))); return; + } + + if (tlen < ptr.slow_oam_tlv_header->length) + goto tooshort; + ND_TCHECK2(*tptr, ptr.slow_oam_tlv_header->length); + hexdump = FALSE; + switch (ptr.slow_oam_tlv_header->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; @@ -513,7 +570,8 @@ slow_oam_print(netdissect_options *ndo, 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))); - return; + hexdump = TRUE; + goto badlength_code_info; } ND_PRINT((ndo, "\n\t OAM-Version %u, Revision %u", @@ -546,11 +604,7 @@ slow_oam_print(netdissect_options *ndo, break; } - /* infinite loop check */ - if (!ptr.slow_oam_tlv_header->length) { - return; - } - + badlength_code_info: /* do we also want to see a hex dump ? */ if (ndo->ndo_vflag > 1 || hexdump==TRUE) { print_unknown_data(ndo, tptr, "\n\t ", @@ -563,22 +617,47 @@ slow_oam_print(netdissect_options *ndo, break; case SLOW_OAM_CODE_EVENT_NOTIF: + /* Sequence number */ + if (tlen < 2) + goto tooshort; + ND_TCHECK2(*tptr, 2); + ND_PRINT((ndo, "\n\t Sequence Number %u", EXTRACT_16BITS(tptr))); + tlen -= 2; + tptr += 2; + + /* TLVs */ 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 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)); - hexdump = FALSE; - switch (ptr.slow_oam_tlv_header->type) { - case SLOW_OAM_LINK_EVENT_END_OF_TLV: - if (ptr.slow_oam_tlv_header->length != 0) { - ND_PRINT((ndo, "\n\t ERROR: illegal length - should be 0")); - } + if (ptr.slow_oam_tlv_header->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)". + */ return; + } + + /* 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))); + return; + } + if (tlen < ptr.slow_oam_tlv_header->length) + goto tooshort; + ND_TCHECK2(*tptr, ptr.slow_oam_tlv_header->length); + + hexdump = FALSE; + switch (ptr.slow_oam_tlv_header->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: @@ -589,7 +668,8 @@ slow_oam_print(netdissect_options *ndo, 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))); - return; + hexdump = TRUE; + goto badlength_event_notif; } ND_PRINT((ndo, "\n\t Timestamp %u ms, Errored Window %" PRIu64 @@ -614,11 +694,7 @@ slow_oam_print(netdissect_options *ndo, break; } - /* infinite loop check */ - if (!ptr.slow_oam_tlv_header->length) { - return; - } - + badlength_event_notif: /* do we also want to see a hex dump ? */ if (ndo->ndo_vflag > 1 || hexdump==TRUE) { print_unknown_data(ndo, tptr, "\n\t ", @@ -632,13 +708,16 @@ slow_oam_print(netdissect_options *ndo, case SLOW_OAM_CODE_LOOPBACK_CTRL: 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)", tok2str(slow_oam_loopbackctrl_cmd_values, "Unknown", tlv.slow_oam_loopbackctrl->command), tlv.slow_oam_loopbackctrl->command)); - tptr ++; - tlen --; + tptr ++; + tlen --; break; /* @@ -655,4 +734,11 @@ slow_oam_print(netdissect_options *ndo, break; } return; + +tooshort: + ND_PRINT((ndo, "\n\t\t packet is too short")); + return; + +trunc: + ND_PRINT((ndo, "\n\t\t packet exceeded snapshot")); } diff --git a/contrib/tcpdump/print-smb.c b/contrib/tcpdump/print-smb.c index f5be9ff..723b9a0 100644 --- a/contrib/tcpdump/print-smb.c +++ b/contrib/tcpdump/print-smb.c @@ -6,16 +6,17 @@ * or later */ -#define NETDISSECT_REWORKED +/* \summary: SMB/CIFS printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "smb.h" @@ -100,7 +101,7 @@ trans2_findfirst(netdissect_options *ndo, smb_fdata(ndo, param, fmt, param + pcnt, unicodestr); if (dcnt) { ND_PRINT((ndo, "data:\n")); - print_data(ndo, data, dcnt); + smb_print_data(ndo, data, dcnt); } } @@ -135,7 +136,7 @@ trans2_qfsinfo(netdissect_options *ndo, } if (dcnt) { ND_PRINT((ndo, "data:\n")); - print_data(ndo, data, dcnt); + smb_print_data(ndo, data, dcnt); } return; trunc: @@ -416,7 +417,7 @@ print_negprot(netdissect_options *ndo, smb_fdata(ndo, words + 1, f1, min(words + 1 + wct * 2, maxbuf), unicodestr); else - print_data(ndo, words + 1, min(wct * 2, PTR_DIFF(maxbuf, words + 1))); + smb_print_data(ndo, words + 1, min(wct * 2, PTR_DIFF(maxbuf, words + 1))); ND_TCHECK2(*data, 2); bcc = EXTRACT_LE_16BITS(data); @@ -426,7 +427,7 @@ print_negprot(netdissect_options *ndo, smb_fdata(ndo, data + 2, f2, min(data + 2 + EXTRACT_LE_16BITS(data), maxbuf), unicodestr); else - print_data(ndo, data + 2, min(EXTRACT_LE_16BITS(data), PTR_DIFF(maxbuf, data + 2))); + smb_print_data(ndo, data + 2, min(EXTRACT_LE_16BITS(data), PTR_DIFF(maxbuf, data + 2))); } return; trunc: @@ -460,7 +461,7 @@ print_sesssetup(netdissect_options *ndo, smb_fdata(ndo, words + 1, f1, min(words + 1 + wct * 2, maxbuf), unicodestr); else - print_data(ndo, words + 1, min(wct * 2, PTR_DIFF(maxbuf, words + 1))); + smb_print_data(ndo, words + 1, min(wct * 2, PTR_DIFF(maxbuf, words + 1))); ND_TCHECK2(*data, 2); bcc = EXTRACT_LE_16BITS(data); @@ -470,7 +471,7 @@ print_sesssetup(netdissect_options *ndo, smb_fdata(ndo, data + 2, f2, min(data + 2 + EXTRACT_LE_16BITS(data), maxbuf), unicodestr); else - print_data(ndo, data + 2, min(EXTRACT_LE_16BITS(data), PTR_DIFF(maxbuf, data + 2))); + smb_print_data(ndo, data + 2, min(EXTRACT_LE_16BITS(data), PTR_DIFF(maxbuf, data + 2))); } return; trunc: @@ -510,7 +511,7 @@ print_lockingandx(netdissect_options *ndo, smb_fdata(ndo, data + 2, f2, min(data + 2 + EXTRACT_LE_16BITS(data), maxbuf), unicodestr); else - print_data(ndo, data + 2, min(EXTRACT_LE_16BITS(data), PTR_DIFF(maxbuf, data + 2))); + smb_print_data(ndo, data + 2, min(EXTRACT_LE_16BITS(data), PTR_DIFF(maxbuf, data + 2))); } return; trunc: @@ -805,9 +806,6 @@ print_smb(netdissect_options *ndo, ND_TCHECK(buf[9]); request = (buf[9] & 0x80) ? 0 : 1; - flags2 = EXTRACT_LE_16BITS(&buf[10]); - unicodestr = flags2 & 0x8000; - nterrcodes = flags2 & 0x4000; startbuf = buf; command = buf[4]; @@ -822,6 +820,11 @@ print_smb(netdissect_options *ndo, if (ndo->ndo_vflag < 2) return; + ND_TCHECK_16BITS(&buf[10]); + flags2 = EXTRACT_LE_16BITS(&buf[10]); + unicodestr = flags2 & 0x8000; + nterrcodes = flags2 & 0x4000; + /* print out the header */ smb_fdata(ndo, buf, fmt_smbheader, buf + 33, unicodestr); @@ -883,7 +886,7 @@ print_smb(netdissect_options *ndo, } else { if (bcc > 0) { ND_PRINT((ndo, "smb_buf[]=\n")); - print_data(ndo, data + 2, min(bcc, PTR_DIFF(maxbuf, data + 2))); + smb_print_data(ndo, data + 2, min(bcc, PTR_DIFF(maxbuf, data + 2))); } } } @@ -1164,10 +1167,12 @@ nbt_udp137_print(netdissect_options *ndo, 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); if (p == NULL) goto out; + ND_TCHECK_16BITS(p); rdlen = EXTRACT_16BITS(p); ND_PRINT((ndo, "ResourceLength=%d\nResourceData=\n", rdlen)); p += 2; @@ -1209,7 +1214,7 @@ nbt_udp137_print(netdissect_options *ndo, p += 2; } } else { - print_data(ndo, p, min(rdlen, length - (p - data))); + smb_print_data(ndo, p, min(rdlen, length - (p - data))); p += rdlen; } } @@ -1309,7 +1314,7 @@ out: /* print netbeui frames */ -struct nbf_strings { +static struct nbf_strings { const char *name; const char *nonverbose; const char *verbose; diff --git a/contrib/tcpdump/print-smtp.c b/contrib/tcpdump/print-smtp.c index fe0bbc2..0cdcf1d 100644 --- a/contrib/tcpdump/print-smtp.c +++ b/contrib/tcpdump/print-smtp.c @@ -11,11 +11,13 @@ * FOR A PARTICULAR PURPOSE. */ +/* \summary: Simple Mail Transfer Protocol (SMTP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include #include diff --git a/contrib/tcpdump/print-snmp.c b/contrib/tcpdump/print-snmp.c index f550158..1b096dc 100644 --- a/contrib/tcpdump/print-snmp.c +++ b/contrib/tcpdump/print-snmp.c @@ -56,12 +56,13 @@ # @(#)snmp.awk.x 1.1 (LANL) 1/15/90 */ -#define NETDISSECT_REWORKED +/* \summary: Simple Network Management Protocol (SNMP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include #include @@ -70,7 +71,7 @@ #include #endif -#include "interface.h" +#include "netdissect.h" #undef OPAQUE /* defined in */ @@ -253,7 +254,7 @@ static const char *Form[] = { * A structure for the OID tree for the compiled-in MIB. * This is stored as a general-order tree. */ -struct obj { +static struct obj { const char *desc; /* name of object */ u_char oid; /* sub-id following parent */ u_char type; /* object type (unused) */ @@ -275,28 +276,46 @@ struct obj { * Currently, this includes the prefixes for the Internet MIB, the * private enterprises tree, and the experimental tree. */ +#define OID_FIRST_OCTET(x, y) (((x)*40) + (y)) /* X.690 8.19.4 */ + +#ifndef NO_ABREV_MIB +static const uint8_t mib_oid[] = { OID_FIRST_OCTET(1, 3), 6, 1, 2, 1 }; +#endif +#ifndef NO_ABREV_ENTER +static const uint8_t enterprises_oid[] = { OID_FIRST_OCTET(1, 3), 6, 1, 4, 1 }; +#endif +#ifndef NO_ABREV_EXPERI +static const uint8_t experimental_oid[] = { OID_FIRST_OCTET(1, 3), 6, 1, 3 }; +#endif +#ifndef NO_ABBREV_SNMPMODS +static const uint8_t snmpModules_oid[] = { OID_FIRST_OCTET(1, 3), 6, 1, 6, 3 }; +#endif + +#define OBJ_ABBREV_ENTRY(prefix, obj) \ + { prefix, &_ ## obj ## _obj, obj ## _oid, sizeof (obj ## _oid) } static const struct obj_abrev { const char *prefix; /* prefix for this abrev */ struct obj *node; /* pointer into object table */ - const char *oid; /* ASN.1 encoded OID */ + const uint8_t *oid; /* ASN.1 encoded OID */ + size_t oid_len; /* length of OID */ } obj_abrev_list[] = { #ifndef NO_ABREV_MIB /* .iso.org.dod.internet.mgmt.mib */ - { "", &_mib_obj, "\53\6\1\2\1" }, + OBJ_ABBREV_ENTRY("", mib), #endif #ifndef NO_ABREV_ENTER /* .iso.org.dod.internet.private.enterprises */ - { "E:", &_enterprises_obj, "\53\6\1\4\1" }, + OBJ_ABBREV_ENTRY("E:", enterprises), #endif #ifndef NO_ABREV_EXPERI /* .iso.org.dod.internet.experimental */ - { "X:", &_experimental_obj, "\53\6\1\3" }, + OBJ_ABBREV_ENTRY("X:", experimental), #endif #ifndef NO_ABBREV_SNMPMODS /* .iso.org.dod.internet.snmpV2.snmpModules */ - { "S:", &_snmpModules_obj, "\53\6\1\6\3" }, + OBJ_ABBREV_ENTRY("S:", snmpModules), #endif - { 0,0,0 } + { 0,0,0,0 } }; /* @@ -325,14 +344,11 @@ static const struct obj_abrev { struct be { uint32_t asnlen; union { - caddr_t raw; + const uint8_t *raw; int32_t integer; uint32_t uns; const u_char *str; - struct { - uint32_t high; - uint32_t low; - } uns64; + uint64_t uns64; } data; u_short id; u_char form, class; /* tag info */ @@ -446,13 +462,18 @@ asn1_parse(netdissect_options *ndo, * bit set. XXX - this doesn't handle a value * that won't fit in 32 bits. */ - for (id = 0; *p & ASN_BIT8; len--, hdr++, p++) { + id = 0; + ND_TCHECK(*p); + while (*p & ASN_BIT8) { if (len < 1) { ND_PRINT((ndo, "[Xtagfield?]")); return -1; } - ND_TCHECK(*p); id = (id << 7) | (*p & ~ASN_BIT8); + len--; + hdr++; + p++; + ND_TCHECK(*p); } if (len < 1) { ND_PRINT((ndo, "[Xtagfield?]")); @@ -498,6 +519,7 @@ asn1_parse(netdissect_options *ndo, ND_PRINT((ndo, "[id?%c/%s/%d]", *Form[form], Class[class].name, id)); return -1; } + ND_TCHECK2(*p, elem->asnlen); switch (form) { case PRIMITIVE: @@ -514,7 +536,10 @@ asn1_parse(netdissect_options *ndo, elem->type = BE_INT; data = 0; - ND_TCHECK2(*p, elem->asnlen); + if (elem->asnlen == 0) { + ND_PRINT((ndo, "[asnlen=0]")); + return -1; + } if (*p & ASN_BIT8) /* negative */ data = -1; for (i = elem->asnlen; i-- > 0; p++) @@ -525,7 +550,7 @@ asn1_parse(netdissect_options *ndo, case OBJECTID: elem->type = BE_OID; - elem->data.raw = (caddr_t)p; + elem->data.raw = (const uint8_t *)p; break; case ASN_NULL: @@ -535,7 +560,7 @@ asn1_parse(netdissect_options *ndo, default: elem->type = BE_OCTET; - elem->data.raw = (caddr_t)p; + elem->data.raw = (const uint8_t *)p; ND_PRINT((ndo, "[P/U/%s]", Class[class].Id[id])); break; } @@ -545,14 +570,13 @@ asn1_parse(netdissect_options *ndo, switch (id) { case IPADDR: elem->type = BE_INETADDR; - elem->data.raw = (caddr_t)p; + elem->data.raw = (const uint8_t *)p; break; case COUNTER: case GAUGE: case TIMETICKS: { register uint32_t data; - ND_TCHECK2(*p, elem->asnlen); elem->type = BE_UNS; data = 0; for (i = elem->asnlen; i-- > 0; p++) @@ -562,23 +586,18 @@ asn1_parse(netdissect_options *ndo, } case COUNTER64: { - register uint32_t high, low; - ND_TCHECK2(*p, elem->asnlen); + register uint64_t data64; elem->type = BE_UNS64; - high = 0, low = 0; - for (i = elem->asnlen; i-- > 0; p++) { - high = (high << 8) | - ((low & 0xFF000000) >> 24); - low = (low << 8) | *p; - } - elem->data.uns64.high = high; - elem->data.uns64.low = low; + data64 = 0; + for (i = elem->asnlen; i-- > 0; p++) + data64 = (data64 << 8) + *p; + elem->data.uns64 = data64; break; } default: elem->type = BE_OCTET; - elem->data.raw = (caddr_t)p; + elem->data.raw = (const uint8_t *)p; ND_PRINT((ndo, "[P/A/%s]", Class[class].Id[id])); break; @@ -606,9 +625,8 @@ asn1_parse(netdissect_options *ndo, default: ND_PRINT((ndo, "[P/%s/%s]", Class[class].name, Class[class].Id[id])); - ND_TCHECK2(*p, elem->asnlen); elem->type = BE_OCTET; - elem->data.raw = (caddr_t)p; + elem->data.raw = (const uint8_t *)p; break; } break; @@ -619,12 +637,12 @@ asn1_parse(netdissect_options *ndo, switch (id) { case SEQUENCE: elem->type = BE_SEQ; - elem->data.raw = (caddr_t)p; + elem->data.raw = (const uint8_t *)p; break; default: elem->type = BE_OCTET; - elem->data.raw = (caddr_t)p; + elem->data.raw = (const uint8_t *)p; ND_PRINT((ndo, "C/U/%s", Class[class].Id[id])); break; } @@ -632,12 +650,12 @@ asn1_parse(netdissect_options *ndo, case CONTEXT: elem->type = BE_PDU; - elem->data.raw = (caddr_t)p; + elem->data.raw = (const uint8_t *)p; break; default: elem->type = BE_OCTET; - elem->data.raw = (caddr_t)p; + elem->data.raw = (const uint8_t *)p; ND_PRINT((ndo, "C/%s/%s", Class[class].name, Class[class].Id[id])); break; } @@ -652,6 +670,56 @@ trunc: return -1; } +static int +asn1_print_octets(netdissect_options *ndo, struct be *elem) +{ + const u_char *p = (const u_char *)elem->data.raw; + uint32_t asnlen = elem->asnlen; + uint32_t i; + + ND_TCHECK2(*p, asnlen); + for (i = asnlen; i-- > 0; p++) + ND_PRINT((ndo, "_%.2x", *p)); + return 0; + +trunc: + ND_PRINT((ndo, "%s", tstr)); + return -1; +} + +static int +asn1_print_string(netdissect_options *ndo, struct be *elem) +{ + register 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); + p = elem->data.str; + if (printable) { + ND_PRINT((ndo, "\"")); + if (fn_printn(ndo, p, asnlen, ndo->ndo_snapend)) { + ND_PRINT((ndo, "\"")); + goto trunc; + } + ND_PRINT((ndo, "\"")); + } else { + for (i = asnlen; i-- > 0; p++) { + ND_PRINT((ndo, first ? "%.2x" : "_%.2x", *p)); + first = 0; + } + } + return 0; + +trunc: + ND_PRINT((ndo, "%s", tstr)); + return -1; +} + /* * Display the ASN.1 object represented by the BE object. * This used to be an integral part of asn1_parse() before the intermediate @@ -661,33 +729,36 @@ static int asn1_print(netdissect_options *ndo, struct be *elem) { - u_char *p = (u_char *)elem->data.raw; + const u_char *p; uint32_t asnlen = elem->asnlen; uint32_t i; switch (elem->type) { case BE_OCTET: - ND_TCHECK2(*p, asnlen); - for (i = asnlen; i-- > 0; p++) - ND_PRINT((ndo, "_%.2x", *p)); + if (asn1_print_octets(ndo, elem) == -1) + return -1; break; case BE_NULL: break; case BE_OID: { - int o = 0, first = -1, i = asnlen; + int o = 0, first = -1; - if (!ndo->ndo_sflag && !ndo->ndo_nflag && asnlen > 2) { + p = (const u_char *)elem->data.raw; + i = asnlen; + if (!ndo->ndo_nflag && asnlen > 2) { const struct obj_abrev *a = &obj_abrev_list[0]; - size_t a_len = strlen(a->oid); for (; a->node; a++) { - ND_TCHECK2(*p, a_len); - if (memcmp(a->oid, (char *)p, a_len) == 0) { + if (i < a->oid_len) + continue; + if (!ND_TTEST2(*p, a->oid_len)) + continue; + if (memcmp(a->oid, p, a->oid_len) == 0) { objp = a->node->child; - i -= strlen(a->oid); - p += strlen(a->oid); + i -= a->oid_len; + p += a->oid_len; ND_PRINT((ndo, "%s", a->prefix)); first = 1; break; @@ -695,14 +766,15 @@ asn1_print(netdissect_options *ndo, } } - for (; !ndo->ndo_sflag && i-- > 0; p++) { + for (; i-- > 0; p++) { ND_TCHECK(*p); o = (o << ASN_SHIFT7) + (*p & ~ASN_BIT8); if (*p & ASN_LONGLEN) continue; /* - * first subitem encodes two items with 1st*OIDMUX+2nd + * first subitem encodes two items with + * 1st*OIDMUX+2nd * (see X.690:1997 clause 8.19 for the details) */ if (first < 0) { @@ -731,69 +803,14 @@ asn1_print(netdissect_options *ndo, ND_PRINT((ndo, "%u", elem->data.uns)); break; - case BE_UNS64: { /* idea borrowed from by Marshall Rose */ - double d; - int j, carry; - char *cpf, *cpl, last[6], first[30]; - if (elem->data.uns64.high == 0) { - ND_PRINT((ndo, "%u", elem->data.uns64.low)); - break; - } - d = elem->data.uns64.high * 4294967296.0; /* 2^32 */ - if (elem->data.uns64.high <= 0x1fffff) { - d += elem->data.uns64.low; -#if 0 /*is looks illegal, but what is the intention?*/ - ND_PRINT((ndo, "%.f", d)); -#else - ND_PRINT((ndo, "%f", d)); -#endif - break; - } - d += (elem->data.uns64.low & 0xfffff000); -#if 0 /*is looks illegal, but what is the intention?*/ - snprintf(first, sizeof(first), "%.f", d); -#else - snprintf(first, sizeof(first), "%f", d); -#endif - snprintf(last, sizeof(last), "%5.5d", - elem->data.uns64.low & 0xfff); - for (carry = 0, cpf = first+strlen(first)-1, cpl = last+4; - cpl >= last; - cpf--, cpl--) { - j = carry + (*cpf - '0') + (*cpl - '0'); - if (j > 9) { - j -= 10; - carry = 1; - } else { - carry = 0; - } - *cpf = j + '0'; - } - ND_PRINT((ndo, "%s", first)); + case BE_UNS64: + ND_PRINT((ndo, "%" PRIu64, elem->data.uns64)); break; - } - case BE_STR: { - register int printable = 1, first = 1; - const u_char *p = elem->data.str; - ND_TCHECK2(*p, asnlen); - for (i = asnlen; printable && i-- > 0; p++) - printable = ND_ISPRINT(*p); - p = elem->data.str; - if (printable) { - ND_PRINT((ndo, "\"")); - if (fn_printn(ndo, p, asnlen, ndo->ndo_snapend)) { - ND_PRINT((ndo, "\"")); - goto trunc; - } - ND_PRINT((ndo, "\"")); - } else - for (i = asnlen; i-- > 0; p++) { - ND_PRINT((ndo, first ? "%.2x" : "_%.2x", *p)); - first = 0; - } + case BE_STR: + if (asn1_print_string(ndo, elem) == -1) + return -1; break; - } case BE_SEQ: ND_PRINT((ndo, "Seq(%u)", elem->asnlen)); @@ -802,6 +819,7 @@ asn1_print(netdissect_options *ndo, case BE_INETADDR: if (asnlen != ASNLEN_INETADDR) ND_PRINT((ndo, "[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)); @@ -895,12 +913,12 @@ smi_decode_oid(netdissect_options *ndo, struct be *elem, unsigned int *oid, unsigned int oidsize, unsigned int *oidlen) { - u_char *p = (u_char *)elem->data.raw; + const u_char *p = (const u_char *)elem->data.raw; uint32_t asnlen = elem->asnlen; int o = 0, first = -1, i = asnlen; unsigned int firstval; - for (*oidlen = 0; ndo->ndo_sflag && i-- > 0; p++) { + for (*oidlen = 0; i-- > 0; p++) { ND_TCHECK(*p); o = (o << ASN_SHIFT7) + (*p & ~ASN_BIT8); if (*p & ASN_LONGLEN) @@ -911,7 +929,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; @@ -1029,6 +1047,10 @@ smi_print_variable(netdissect_options *ndo, SmiNode *smiNode = NULL; unsigned int i; + if (!nd_smi_module_loaded) { + *status = asn1_print(ndo, elem); + return NULL; + } *status = smi_decode_oid(ndo, elem, oid, sizeof(oid) / sizeof(unsigned int), &oidlen); if (*status < 0) @@ -1053,7 +1075,7 @@ smi_print_variable(netdissect_options *ndo, static int smi_print_value(netdissect_options *ndo, - SmiNode *smiNode, u_char pduid, struct be *elem) + SmiNode *smiNode, u_short pduid, struct be *elem) { unsigned int i, oid[128], oidlen; SmiType *smiType; @@ -1114,22 +1136,24 @@ smi_print_value(netdissect_options *ndo, if (smiType->basetype == SMI_BASETYPE_BITS) { /* print bit labels */ } else { - smi_decode_oid(ndo, elem, oid, - sizeof(oid)/sizeof(unsigned int), - &oidlen); - smiNode = smiGetNodeByOID(oidlen, oid); - if (smiNode) { - if (ndo->ndo_vflag) { - ND_PRINT((ndo, "%s::", smiGetNodeModule(smiNode)->name)); - } - ND_PRINT((ndo, "%s", smiNode->name)); - if (smiNode->oidlen < oidlen) { - for (i = smiNode->oidlen; - i < oidlen; i++) { - ND_PRINT((ndo, ".%u", oid[i])); + if (nd_smi_module_loaded && + smi_decode_oid(ndo, elem, oid, + sizeof(oid)/sizeof(unsigned int), + &oidlen) == 0) { + smiNode = smiGetNodeByOID(oidlen, oid); + if (smiNode) { + if (ndo->ndo_vflag) { + ND_PRINT((ndo, "%s::", smiGetNodeModule(smiNode)->name)); + } + ND_PRINT((ndo, "%s", smiNode->name)); + if (smiNode->oidlen < oidlen) { + for (i = smiNode->oidlen; + i < oidlen; i++) { + ND_PRINT((ndo, ".%u", oid[i])); + } } + done++; } - done++; } } break; @@ -1196,7 +1220,7 @@ smi_print_value(netdissect_options *ndo, */ static void varbind_print(netdissect_options *ndo, - u_char pduid, const u_char *np, u_int length) + u_short pduid, const u_char *np, u_int length) { struct be elem; int count = 0, ind; @@ -1217,7 +1241,7 @@ varbind_print(netdissect_options *ndo, ND_PRINT((ndo, "[%d extra after SEQ of varbind]", length - count)); /* descend */ length = elem.asnlen; - np = (u_char *)elem.data.raw; + np = (const u_char *)elem.data.raw; for (ind = 1; length > 0; ind++) { const u_char *vbend; @@ -1237,7 +1261,7 @@ varbind_print(netdissect_options *ndo, vblength = length - count; /* descend */ length = elem.asnlen; - np = (u_char *)elem.data.raw; + np = (const u_char *)elem.data.raw; /* objName (OID) */ if ((count = asn1_parse(ndo, np, length, &elem)) < 0) @@ -1296,7 +1320,7 @@ snmppdu_print(netdissect_options *ndo, u_short pduid, const u_char *np, u_int length) { struct be elem; - int count = 0, error; + int count = 0, error_status; /* reqId (Integer) */ if ((count = asn1_parse(ndo, np, length, &elem)) < 0) @@ -1319,7 +1343,7 @@ snmppdu_print(netdissect_options *ndo, asn1_print(ndo, &elem); return; } - error = 0; + error_status = 0; if ((pduid == GETREQ || pduid == GETNEXTREQ || pduid == SETREQ || pduid == INFORMREQ || pduid == V2TRAP || pduid == REPORT) && elem.data.integer != 0) { @@ -1331,7 +1355,7 @@ snmppdu_print(netdissect_options *ndo, } else if (elem.data.integer != 0) { char errbuf[20]; ND_PRINT((ndo, " %s", DECODE_ErrorStatus(elem.data.integer))); - error = elem.data.integer; + error_status = elem.data.integer; } length -= count; np += count; @@ -1351,15 +1375,12 @@ snmppdu_print(netdissect_options *ndo, else if (pduid == GETBULKREQ) ND_PRINT((ndo, " M=%d", elem.data.integer)); else if (elem.data.integer != 0) { - if (!error) + if (!error_status) ND_PRINT((ndo, "[errorIndex(%d) w/o errorStatus]", elem.data.integer)); - else { + else ND_PRINT((ndo, "@%d", elem.data.integer)); - error = elem.data.integer; - } - } else if (error) { + } else if (error_status) { ND_PRINT((ndo, "[errorIndex==0]")); - error = 0; } length -= count; np += count; @@ -1486,7 +1507,7 @@ pdu_print(netdissect_options *ndo, ND_PRINT((ndo, " ")); /* descend into PDU */ length = pdu.asnlen; - np = (u_char *)pdu.data.raw; + np = (const u_char *)pdu.data.raw; if (version == SNMP_VERSION_1 && (pdu.id == GETBULKREQ || pdu.id == INFORMREQ || @@ -1529,7 +1550,7 @@ scopedpdu_print(netdissect_options *ndo, const u_char *np, u_int length, int version) { struct be elem; - int i, count = 0; + int count = 0; /* Sequence */ if ((count = asn1_parse(ndo, np, length, &elem)) < 0) @@ -1540,7 +1561,7 @@ scopedpdu_print(netdissect_options *ndo, return; } length = elem.asnlen; - np = (u_char *)elem.data.raw; + np = (const u_char *)elem.data.raw; /* contextEngineID (OCTET STRING) */ if ((count = asn1_parse(ndo, np, length, &elem)) < 0) @@ -1553,10 +1574,9 @@ scopedpdu_print(netdissect_options *ndo, length -= count; np += count; - ND_PRINT((ndo, "E= ")); - for (i = 0; i < (int)elem.asnlen; i++) { - ND_PRINT((ndo, "0x%02X", elem.data.str[i])); - } + ND_PRINT((ndo, "E=")); + if (asn1_print_octets(ndo, &elem) == -1) + return; ND_PRINT((ndo, " ")); /* contextName (OCTET STRING) */ @@ -1570,7 +1590,10 @@ scopedpdu_print(netdissect_options *ndo, length -= count; np += count; - ND_PRINT((ndo, "C=%.*s ", (int)elem.asnlen, elem.data.str)); + ND_PRINT((ndo, "C=")); + if (asn1_print_string(ndo, &elem) == -1) + return; + ND_PRINT((ndo, " ")); pdu_print(ndo, np, length, version); } @@ -1595,10 +1618,14 @@ community_print(netdissect_options *ndo, } /* default community */ if (!(elem.asnlen == sizeof(DEF_COMMUNITY) - 1 && - strncmp((char *)elem.data.str, DEF_COMMUNITY, - sizeof(DEF_COMMUNITY) - 1) == 0)) + strncmp((const char *)elem.data.str, DEF_COMMUNITY, + sizeof(DEF_COMMUNITY) - 1) == 0)) { /* ! "public" */ - ND_PRINT((ndo, "C=%.*s ", (int)elem.asnlen, elem.data.str)); + ND_PRINT((ndo, "C=")); + if (asn1_print_string(ndo, &elem) == -1) + return; + ND_PRINT((ndo, " ")); + } length -= count; np += count; @@ -1624,7 +1651,7 @@ usm_print(netdissect_options *ndo, return; } length = elem.asnlen; - np = (u_char *)elem.data.raw; + np = (const u_char *)elem.data.raw; /* msgAuthoritativeEngineID (OCTET STRING) */ if ((count = asn1_parse(ndo, np, length, &elem)) < 0) @@ -1674,7 +1701,10 @@ usm_print(netdissect_options *ndo, length -= count; np += count; - ND_PRINT((ndo, "U=%.*s ", (int)elem.asnlen, elem.data.str)); + ND_PRINT((ndo, "U=")); + if (asn1_print_string(ndo, &elem) == -1) + return; + ND_PRINT((ndo, " ")); /* msgAuthenticationParameters (OCTET STRING) */ if ((count = asn1_parse(ndo, np, length, &elem)) < 0) @@ -1725,7 +1755,7 @@ v3msg_print(netdissect_options *ndo, return; } length = elem.asnlen; - np = (u_char *)elem.data.raw; + np = (const u_char *)elem.data.raw; if (ndo->ndo_vflag) { ND_PRINT((ndo, "{ ")); @@ -1864,7 +1894,7 @@ snmp_print(netdissect_options *ndo, ND_PRINT((ndo, "[%d extra after iSEQ]", length - count)); /* descend */ length = elem.asnlen; - np = (u_char *)elem.data.raw; + np = (const u_char *)elem.data.raw; /* Version (INTEGER) */ if ((count = asn1_parse(ndo, np, length, &elem)) < 0) @@ -1883,7 +1913,7 @@ snmp_print(netdissect_options *ndo, ND_PRINT((ndo, "{ %s ", SnmpVersion[elem.data.integer])); break; default: - ND_PRINT((ndo, "[version = %d]", elem.data.integer)); + ND_PRINT((ndo, "SNMP [version = %d]", elem.data.integer)); return; } version = elem.data.integer; diff --git a/contrib/tcpdump/print-stp.c b/contrib/tcpdump/print-stp.c index 93bb600..2f5c917 100644 --- a/contrib/tcpdump/print-stp.c +++ b/contrib/tcpdump/print-stp.c @@ -5,20 +5,20 @@ * BSD-style license that accompanies tcpdump or the GNU General * Public License * - * Format and print IEEE 802.1d spanning tree protocol packets. * Contributed by Lennert Buytenhek */ -#define NETDISSECT_REWORKED +/* \summary: IEEE 802.1d Spanning Tree Protocol (STP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #define RSTP_EXTRACT_PORT_ROLE(x) (((x)&0x0C)>>2) @@ -84,6 +84,8 @@ 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) { @@ -96,22 +98,25 @@ stp_print_bridge_id(const u_char *p) return bridge_id_str; } -static void +static int 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))); + 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)); /* in non-verbose mode just print the bridge-id */ if (!ndo->ndo_vflag) { - return; + return 1; } + ND_TCHECK(stp_bpdu->forward_delay); ND_PRINT((ndo, "\n\tmessage-age %.2fs, max-age %.2fs" ", hello-time %.2fs, forwarding-delay %.2fs", (float)EXTRACT_16BITS(&stp_bpdu->message_age) / STP_TIME_BASE, @@ -129,6 +134,10 @@ stp_print_config_bpdu(netdissect_options *ndo, const struct stp_bpdu_ *stp_bpdu, tok2str(rstp_obj_port_role_values, "Unknown", RSTP_EXTRACT_PORT_ROLE(stp_bpdu->flags)))); } + return 1; + +trunc: + return 0; } /* @@ -226,8 +235,7 @@ stp_print_config_bpdu(netdissect_options *ndo, const struct stp_bpdu_ *stp_bpdu, #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 void +static int stp_print_mstp_bpdu(netdissect_options *ndo, const struct stp_bpdu_ *stp_bpdu, u_int length) { @@ -245,22 +253,26 @@ stp_print_mstp_bpdu(netdissect_options *ndo, const struct stp_bpdu_ *stp_bpdu, * in non-verbose mode just print the flags. */ if (!ndo->ndo_vflag) { - return; + return 1; } ND_PRINT((ndo, "\n\tport-role %s, ", tok2str(rstp_obj_port_role_values, "Unknown", RSTP_EXTRACT_PORT_ROLE(stp_bpdu->flags)))); - ND_PRINT((ndo, "CIST root-id %s, CIST ext-pathcost %u ", + 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_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((ndo, "CIST port-id %04x, ", EXTRACT_16BITS(&stp_bpdu->port_id))); + ND_TCHECK(stp_bpdu->port_id); + ND_PRINT((ndo, "CIST port-id %04x,", EXTRACT_16BITS(&stp_bpdu->port_id))); + ND_TCHECK(stp_bpdu->forward_delay); ND_PRINT((ndo, "\n\tmessage-age %.2fs, max-age %.2fs" ", hello-time %.2fs, forwarding-delay %.2fs", (float)EXTRACT_16BITS(&stp_bpdu->message_age) / STP_TIME_BASE, @@ -268,30 +280,40 @@ stp_print_mstp_bpdu(netdissect_options *ndo, const struct stp_bpdu_ *stp_bpdu, (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_PRINT((ndo, "MCID Name %s, rev %u, " + 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," "\n\t\tdigest %08x%08x%08x%08x, ", - ptr + MST_BPDU_CONFIG_NAME_OFFSET, 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), + 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))); - ND_PRINT((ndo, "CIST int-root-pathcost %u, ", + 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_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_TCHECK(ptr[MST_BPDU_CIST_REMAIN_HOPS_OFFSET]); ND_PRINT((ndo, "CIST remaining-hops %d", 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); 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 = msti & 0x0FFF; @@ -314,9 +336,13 @@ stp_print_mstp_bpdu(netdissect_options *ndo, const struct stp_bpdu_ *stp_bpdu, offset += MST_BPDU_MSTI_LENGTH; } } + return 1; + +trunc: + return 0; } -static void +static int stp_print_spb_bpdu(netdissect_options *ndo, const struct stp_bpdu_ *stp_bpdu, u_int offset) { @@ -326,13 +352,18 @@ 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; + return 1; } ptr = (const u_char *)stp_bpdu; - ND_PRINT((ndo, "\n\tv4len %d AUXMCID Name %s, Rev %u, \n\t\tdigest %08x%08x%08x%08x", - EXTRACT_16BITS (ptr + offset), - ptr + offset + SPB_BPDU_CONFIG_NAME_OFFSET, + 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), @@ -340,8 +371,8 @@ stp_print_spb_bpdu(netdissect_options *ndo, const struct stp_bpdu_ *stp_bpdu, 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, " + "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, @@ -353,10 +384,14 @@ stp_print_spb_bpdu(netdissect_options *ndo, const struct stp_bpdu_ *stp_bpdu, 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)); + 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; } /* @@ -369,17 +404,19 @@ stp_print(netdissect_options *ndo, const u_char *p, u_int length) u_int mstp_len; u_int spb_len; - stp_bpdu = (struct stp_bpdu_*)p; + stp_bpdu = (const struct stp_bpdu_*)p; /* Minimum STP Frame size. */ if (length < 4) goto trunc; + ND_TCHECK(stp_bpdu->protocol_id); if (EXTRACT_16BITS(&stp_bpdu->protocol_id)) { ND_PRINT((ndo, "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))); @@ -393,6 +430,7 @@ 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))); @@ -401,7 +439,8 @@ stp_print(netdissect_options *ndo, const u_char *p, u_int length) if (length < sizeof(struct stp_bpdu_) - 1) { goto trunc; } - stp_print_config_bpdu(ndo, stp_bpdu, length); + if (!stp_print_config_bpdu(ndo, stp_bpdu, length)) + goto trunc; break; case STP_BPDU_TYPE_RSTP: @@ -409,25 +448,29 @@ stp_print(netdissect_options *ndo, const u_char *p, u_int length) if (length < sizeof(struct stp_bpdu_)) { goto trunc; } - stp_print_config_bpdu(ndo, stp_bpdu, length); + 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) { if (length < STP_BPDU_MSTP_MIN_LEN) { goto trunc; } + ND_TCHECK(stp_bpdu->v1_length); if (stp_bpdu->v1_length != 0) { /* FIX ME: Emit a message here ? */ goto trunc; } /* Validate v3 length */ + ND_TCHECK_16BITS(p + MST_BPDU_VER3_LEN_OFFSET); mstp_len = EXTRACT_16BITS(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; } - stp_print_mstp_bpdu(ndo, stp_bpdu, length); + if (!stp_print_mstp_bpdu(ndo, stp_bpdu, length)) + goto trunc; if (stp_bpdu->protocol_version == STP_PROTO_SPB) { @@ -438,7 +481,8 @@ stp_print(netdissect_options *ndo, const u_char *p, u_int length) spb_len < SPB_BPDU_MIN_LEN) { goto trunc; } - stp_print_spb_bpdu(ndo, stp_bpdu, (sizeof(struct stp_bpdu_) + mstp_len)); + if (!stp_print_spb_bpdu(ndo, stp_bpdu, (sizeof(struct stp_bpdu_) + mstp_len))) + goto trunc; } } break; @@ -452,7 +496,7 @@ stp_print(netdissect_options *ndo, const u_char *p, u_int length) } return; - trunc: +trunc: ND_PRINT((ndo, "[|stp %d]", length)); } diff --git a/contrib/tcpdump/print-sunatm.c b/contrib/tcpdump/print-sunatm.c index fc03d42..a587e50 100644 --- a/contrib/tcpdump/print-sunatm.c +++ b/contrib/tcpdump/print-sunatm.c @@ -30,17 +30,18 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#define NETDISSECT_REWORKED +/* \summary: SunATM DLPI capture printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include struct mbuf; struct rtentry; -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "atm.h" diff --git a/contrib/tcpdump/print-sunrpc.c b/contrib/tcpdump/print-sunrpc.c index 6d98282..2c7f6c7 100644 --- a/contrib/tcpdump/print-sunrpc.c +++ b/contrib/tcpdump/print-sunrpc.c @@ -17,11 +17,10 @@ * 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. - * - * $FreeBSD$ */ -#define NETDISSECT_REWORKED +/* \summary: Sun Remote Procedure Call printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -41,7 +40,7 @@ */ #undef _XOPEN_SOURCE_EXTENDED -#include +#include #if defined(HAVE_GETRPCBYNUMBER) && defined(HAVE_RPC_RPC_H) #include @@ -53,14 +52,12 @@ #include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" #include "ip.h" -#ifdef INET6 #include "ip6.h" -#endif #include "rpc_auth.h" #include "rpc_msg.h" @@ -95,7 +92,7 @@ * * from: @(#)pmap_prot.h 1.14 88/02/08 SMI * from: @(#)pmap_prot.h 2.1 88/07/29 4.0 RPCSRC - * $FreeBSD$ + * $FreeBSD: stable/11/contrib/tcpdump/print-sunrpc.c 276788 2015-01-07 19:55:18Z delphij $ */ /* @@ -173,13 +170,11 @@ sunrpcrequest_print(netdissect_options *ndo, register const u_char *bp, { register const struct sunrpc_msg *rp; register const struct ip *ip; -#ifdef INET6 register const struct ip6_hdr *ip6; -#endif uint32_t x; char srcid[20], dstid[20]; /*fits 32bit*/ - rp = (struct sunrpc_msg *)bp; + rp = (const struct sunrpc_msg *)bp; if (!ndo->ndo_nflag) { snprintf(srcid, sizeof(srcid), "0x%x", @@ -191,21 +186,19 @@ sunrpcrequest_print(netdissect_options *ndo, register const u_char *bp, snprintf(dstid, sizeof(dstid), "0x%x", SUNRPC_PMAPPORT); } - switch (IP_V((struct ip *)bp2)) { + switch (IP_V((const struct ip *)bp2)) { case 4: - ip = (struct ip *)bp2; + 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)); break; -#ifdef INET6 case 6: - ip6 = (struct ip6_hdr *)bp2; + 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)); break; -#endif default: ND_PRINT((ndo, "%s.%s > %s.%s: %d", "?", srcid, "?", dstid, length)); break; diff --git a/contrib/tcpdump/print-symantec.c b/contrib/tcpdump/print-symantec.c index dcff2a6..9e9f8f3 100644 --- a/contrib/tcpdump/print-symantec.c +++ b/contrib/tcpdump/print-symantec.c @@ -19,14 +19,15 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: Symantec Enterprise Firewall printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "ethertype.h" @@ -75,7 +76,7 @@ symantec_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_ { u_int length = h->len; u_int caplen = h->caplen; - struct symantec_header *sp; + const struct symantec_header *sp; u_short ether_type; if (caplen < sizeof (struct symantec_header)) { @@ -88,7 +89,7 @@ symantec_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_ length -= sizeof (struct symantec_header); caplen -= sizeof (struct symantec_header); - sp = (struct symantec_header *)p; + sp = (const struct symantec_header *)p; p += sizeof (struct symantec_header); ether_type = EXTRACT_16BITS(&sp->ether_type); @@ -96,14 +97,14 @@ symantec_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_ if (ether_type <= ETHERMTU) { /* ether_type not known, print raw packet */ if (!ndo->ndo_eflag) - symantec_hdr_print(ndo, (u_char *)sp, length + sizeof (struct symantec_header)); + symantec_hdr_print(ndo, (const u_char *)sp, length + sizeof (struct symantec_header)); if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); - } else if (ethertype_print(ndo, ether_type, p, length, caplen) == 0) { + } else if (ethertype_print(ndo, ether_type, p, length, caplen, NULL, NULL) == 0) { /* ether_type not known, print raw packet */ if (!ndo->ndo_eflag) - symantec_hdr_print(ndo, (u_char *)sp, length + sizeof (struct symantec_header)); + symantec_hdr_print(ndo, (const u_char *)sp, length + sizeof (struct symantec_header)); if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); diff --git a/contrib/tcpdump/print-syslog.c b/contrib/tcpdump/print-syslog.c index 5e3cd4f..ff86676 100644 --- a/contrib/tcpdump/print-syslog.c +++ b/contrib/tcpdump/print-syslog.c @@ -14,14 +14,15 @@ * FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: Syslog protocol printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" static const char tstr[] = "[|syslog]"; diff --git a/contrib/tcpdump/print-tcp.c b/contrib/tcpdump/print-tcp.c index a5c7047..e0d0531 100644 --- a/contrib/tcpdump/print-tcp.c +++ b/contrib/tcpdump/print-tcp.c @@ -23,40 +23,37 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ +/* \summary: TCP printer */ + #ifndef lint #else __RCSID("$NetBSD: print-tcp.c,v 1.8 2007/07/24 11:53:48 drochner Exp $"); #endif -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" #include "tcp.h" #include "ip.h" -#ifdef INET6 #include "ip6.h" -#endif #include "ipproto.h" #include "rpc_auth.h" #include "rpc_msg.h" -#include "nameser.h" - #ifdef HAVE_LIBCRYPTO #include -#include +#include "signature.h" static int tcp_verify_signature(netdissect_options *ndo, const struct ip *ip, const struct tcphdr *tp, @@ -64,6 +61,8 @@ static int tcp_verify_signature(netdissect_options *ndo, #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, + u_int datalen, int exp); #define MAX_RST_DATA_LEN 30 @@ -81,7 +80,6 @@ struct tcp_seq_hash { tcp_seq ack; }; -#ifdef INET6 struct tha6 { struct in6_addr src; struct in6_addr dst; @@ -94,7 +92,6 @@ struct tcp_seq_hash6 { tcp_seq seq; tcp_seq ack; }; -#endif #define TSEQ_HASHSIZE 919 @@ -102,9 +99,7 @@ struct tcp_seq_hash6 { #define ZEROLENOPT(o) ((o) == TCPOPT_EOL || (o) == TCPOPT_NOP) static struct tcp_seq_hash tcp_seq_hash4[TSEQ_HASHSIZE]; -#ifdef INET6 static struct tcp_seq_hash6 tcp_seq_hash6[TSEQ_HASHSIZE]; -#endif static const struct tok tcp_flag_values[] = { { TH_FIN, "F" }, @@ -132,9 +127,11 @@ static const struct tok tcp_option_values[] = { { TCPOPT_CCNEW, "ccnew" }, { TCPOPT_CCECHO, "" }, { TCPOPT_SIGNATURE, "md5" }, - { TCPOPT_AUTH, "enhanced auth" }, + { TCPOPT_SCPS, "scps" }, { TCPOPT_UTO, "uto" }, + { TCPOPT_TCPAO, "tcp-ao" }, { TCPOPT_MPTCP, "mptcp" }, + { TCPOPT_FASTOPEN, "tfo" }, { TCPOPT_EXPERIMENT2, "exp" }, { 0, NULL } }; @@ -149,6 +146,16 @@ tcp_cksum(netdissect_options *ndo, IPPROTO_TCP); } +static int +tcp6_cksum(netdissect_options *ndo, + register const struct ip6_hdr *ip6, + register const struct tcphdr *tp, + register u_int len) +{ + 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, @@ -164,18 +171,14 @@ tcp_print(netdissect_options *ndo, u_int utoval; uint16_t magic; register int rev; -#ifdef INET6 register const struct ip6_hdr *ip6; -#endif - tp = (struct tcphdr *)bp; - ip = (struct ip *)bp2; -#ifdef INET6 + tp = (const struct tcphdr *)bp; + ip = (const struct ip *)bp2; if (IP_V(ip) == 6) - ip6 = (struct ip6_hdr *)bp2; + ip6 = (const struct ip6_hdr *)bp2; else ip6 = NULL; -#endif /*INET6*/ ch = '\0'; if (!ND_TTEST(tp->th_dport)) { ND_PRINT((ndo, "%s > %s: [|tcp]", @@ -187,43 +190,40 @@ tcp_print(netdissect_options *ndo, sport = EXTRACT_16BITS(&tp->th_sport); dport = EXTRACT_16BITS(&tp->th_dport); - hlen = TH_OFF(tp) * 4; - -#ifdef INET6 if (ip6) { if (ip6->ip6_nxt == IPPROTO_TCP) { ND_PRINT((ndo, "%s.%s > %s.%s: ", ip6addr_string(ndo, &ip6->ip6_src), - tcpport_string(sport), + tcpport_string(ndo, sport), ip6addr_string(ndo, &ip6->ip6_dst), - tcpport_string(dport))); + tcpport_string(ndo, dport))); } else { ND_PRINT((ndo, "%s > %s: ", - tcpport_string(sport), tcpport_string(dport))); + tcpport_string(ndo, sport), tcpport_string(ndo, dport))); } - } else -#endif /*INET6*/ - { + } else { if (ip->ip_p == IPPROTO_TCP) { ND_PRINT((ndo, "%s.%s > %s.%s: ", ipaddr_string(ndo, &ip->ip_src), - tcpport_string(sport), + tcpport_string(ndo, sport), ipaddr_string(ndo, &ip->ip_dst), - tcpport_string(dport))); + tcpport_string(ndo, dport))); } else { ND_PRINT((ndo, "%s > %s: ", - tcpport_string(sport), tcpport_string(dport))); + tcpport_string(ndo, sport), tcpport_string(ndo, dport))); } } + ND_TCHECK(*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))); return; } - ND_TCHECK(*tp); - seq = EXTRACT_32BITS(&tp->th_seq); ack = EXTRACT_32BITS(&tp->th_ack); win = EXTRACT_16BITS(&tp->th_win); @@ -249,11 +249,10 @@ tcp_print(netdissect_options *ndo, * both directions). */ rev = 0; -#ifdef INET6 if (ip6) { register struct tcp_seq_hash6 *th; struct tcp_seq_hash6 *tcp_seq_hash; - const void *src, *dst; + const struct in6_addr *src, *dst; struct tha6 tha; tcp_seq_hash = tcp_seq_hash6; @@ -287,7 +286,8 @@ tcp_print(netdissect_options *ndo, th->nxt = (struct tcp_seq_hash6 *) calloc(1, sizeof(*th)); if (th->nxt == NULL) - error("tcp_print: calloc"); + (*ndo->ndo_error)(ndo, + "tcp_print: calloc"); } th->addr = tha; if (rev) @@ -304,30 +304,24 @@ tcp_print(netdissect_options *ndo, thseq = th->seq; thack = th->ack; } else { -#else /*INET6*/ - { -#endif /*INET6*/ register struct tcp_seq_hash *th; struct tcp_seq_hash *tcp_seq_hash; - const void *src, *dst; struct tha tha; tcp_seq_hash = tcp_seq_hash4; - src = &ip->ip_src; - dst = &ip->ip_dst; if (sport > dport) rev = 1; else if (sport == dport) { - if (UNALIGNED_MEMCMP(src, 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, dst, sizeof ip->ip_dst); - UNALIGNED_MEMCPY(&tha.dst, 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 = dport << 16 | sport; } else { - UNALIGNED_MEMCPY(&tha.dst, dst, sizeof ip->ip_dst); - UNALIGNED_MEMCPY(&tha.src, 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 = sport << 16 | dport; } @@ -343,7 +337,8 @@ tcp_print(netdissect_options *ndo, th->nxt = (struct tcp_seq_hash *) calloc(1, sizeof(*th)); if (th->nxt == NULL) - error("tcp_print: calloc"); + (*ndo->ndo_error)(ndo, + "tcp_print: calloc"); } th->addr = tha; if (rev) @@ -386,12 +381,9 @@ tcp_print(netdissect_options *ndo, else ND_PRINT((ndo, " (correct)")); } - } -#ifdef INET6 - else if (IP_V(ip) == 6 && ip6->ip6_plen) { + } else if (IP_V(ip) == 6 && ip6->ip6_plen) { if (ND_TTEST2(tp->th_sport, length)) { - sum = nextproto6_cksum(ip6, (const uint8_t *)tp, - length, length, IPPROTO_TCP); + sum = tcp6_cksum(ndo, ip6, tp, length); tcp_sum = EXTRACT_16BITS(&tp->th_sum); ND_PRINT((ndo, ", cksum 0x%04x", tcp_sum)); @@ -403,7 +395,6 @@ tcp_print(netdissect_options *ndo, } } -#endif } length -= hlen; @@ -474,7 +465,7 @@ tcp_print(netdissect_options *ndo, case TCPOPT_SACK: datalen = len - 2; if (datalen % 8 != 0) { - ND_PRINT((ndo, "malformed sack")); + ND_PRINT((ndo, " invalid sack")); } else { uint32_t s, e; @@ -522,6 +513,7 @@ tcp_print(netdissect_options *ndo, case TCPOPT_SIGNATURE: datalen = TCP_SIGLEN; LENCHECK(datalen); + ND_PRINT((ndo, " ")); #ifdef HAVE_LIBCRYPTO switch (tcp_verify_signature(ndo, ip, tp, bp + TH_OFF(tp) * 4, length, cp)) { @@ -546,15 +538,35 @@ tcp_print(netdissect_options *ndo, #endif break; - case TCPOPT_AUTH: - ND_PRINT((ndo, "keyid %d", *cp++)); - datalen = len - 3; - for (i = 0; i < datalen; ++i) { - LENCHECK(i); - ND_PRINT((ndo, "%02x", cp[i])); - } + case TCPOPT_SCPS: + datalen = 2; + LENCHECK(datalen); + ND_PRINT((ndo, " cap %02x id %u", cp[0], cp[1])); break; + case TCPOPT_TCPAO: + datalen = len - 2; + /* RFC 5925 Section 2.2: + * "The Length value MUST be greater than or equal to 4." + * (This includes the Kind and Length fields already processed + * at this point.) + */ + if (datalen < 2) { + ND_PRINT((ndo, " invalid")); + } else { + LENCHECK(1); + ND_PRINT((ndo, " keyid %u", cp[0])); + LENCHECK(2); + ND_PRINT((ndo, " rnextkeyid %u", cp[1])); + if (datalen > 2) { + ND_PRINT((ndo, " mac 0x")); + for (i = 2; i < datalen; i++) { + LENCHECK(i + 1); + ND_PRINT((ndo, "%02x", cp[i])); + } + } + } + break; case TCPOPT_EOL: case TCPOPT_NOP: @@ -569,7 +581,7 @@ tcp_print(netdissect_options *ndo, datalen = 2; LENCHECK(datalen); utoval = EXTRACT_16BITS(cp); - ND_PRINT((ndo, "0x%x", utoval)); + ND_PRINT((ndo, " 0x%x", utoval)); if (utoval & 0x0001) utoval = (utoval >> 1) * 60; else @@ -584,6 +596,13 @@ tcp_print(netdissect_options *ndo, goto bad; break; + case TCPOPT_FASTOPEN: + datalen = len - 2; + LENCHECK(datalen); + ND_PRINT((ndo, " ")); + print_tcp_fastopen_option(ndo, cp, datalen, FALSE); + break; + case TCPOPT_EXPERIMENT2: datalen = len - 2; LENCHECK(datalen); @@ -595,21 +614,8 @@ tcp_print(netdissect_options *ndo, switch(magic) { - case 0xf989: - /* TCP Fast Open: RFC 7413 */ - if (datalen == 2) { - /* Fast Open Cookie Request */ - ND_PRINT((ndo, "tfo cookiereq")); - } else { - /* Fast Open Cookie */ - if (datalen % 2 != 0 || datalen < 6 || datalen > 18) { - ND_PRINT((ndo, "tfo malformed")); - } else { - ND_PRINT((ndo, "tfo cookie ")); - for (i = 2; i < datalen; ++i) - ND_PRINT((ndo, "%02x", cp[i])); - } - } + case 0xf989: /* TCP Fast Open RFC 7413 */ + print_tcp_fastopen_option(ndo, cp + 2, datalen - 2, TRUE); break; default: @@ -624,7 +630,7 @@ tcp_print(netdissect_options *ndo, if (datalen) ND_PRINT((ndo, " 0x")); for (i = 0; i < datalen; ++i) { - LENCHECK(i); + LENCHECK(i + 1); ND_PRINT((ndo, "%02x", cp[i])); } break; @@ -669,58 +675,59 @@ tcp_print(netdissect_options *ndo, case PT_ZMTP1: zmtp1_print(ndo, bp, length); break; + case PT_RESP: + resp_print(ndo, bp, length); + break; } return; } - if (sport == TELNET_PORT || dport == TELNET_PORT) { + if (IS_SRC_OR_DST_PORT(TELNET_PORT)) { telnet_print(ndo, bp, length); - } else if (sport == SMTP_PORT || dport == SMTP_PORT) { + } else if (IS_SRC_OR_DST_PORT(SMTP_PORT)) { ND_PRINT((ndo, ": ")); smtp_print(ndo, bp, length); - } else if (sport == BGP_PORT || dport == BGP_PORT) + } else if (IS_SRC_OR_DST_PORT(BGP_PORT)) bgp_print(ndo, bp, length); - else if (sport == PPTP_PORT || dport == PPTP_PORT) + else if (IS_SRC_OR_DST_PORT(PPTP_PORT)) pptp_print(ndo, bp); -#ifdef TCPDUMP_DO_SMB - else if (sport == NETBIOS_SSN_PORT || dport == NETBIOS_SSN_PORT) + else if (IS_SRC_OR_DST_PORT(REDIS_PORT)) + resp_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 (sport == SMB_PORT || dport == SMB_PORT) + else if (IS_SRC_OR_DST_PORT(SMB_PORT)) smb_tcp_print(ndo, bp, length); #endif - else if (sport == BEEP_PORT || dport == BEEP_PORT) + else if (IS_SRC_OR_DST_PORT(BEEP_PORT)) beep_print(ndo, bp, length); - else if (sport == OPENFLOW_PORT_OLD || dport == OPENFLOW_PORT_OLD || - sport == OPENFLOW_PORT_IANA || dport == OPENFLOW_PORT_IANA) + 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 (sport == FTP_PORT || dport == FTP_PORT) { + else if (IS_SRC_OR_DST_PORT(FTP_PORT)) { ND_PRINT((ndo, ": ")); ftp_print(ndo, bp, length); - } else if (sport == HTTP_PORT || dport == HTTP_PORT || - sport == HTTP_PORT_ALT || dport == HTTP_PORT_ALT) { + } else if (IS_SRC_OR_DST_PORT(HTTP_PORT) || IS_SRC_OR_DST_PORT(HTTP_PORT_ALT)) { ND_PRINT((ndo, ": ")); http_print(ndo, bp, length); - } else if (sport == RTSP_PORT || dport == RTSP_PORT || - sport == RTSP_PORT_ALT || dport == RTSP_PORT_ALT) { + } else if (IS_SRC_OR_DST_PORT(RTSP_PORT) || IS_SRC_OR_DST_PORT(RTSP_PORT_ALT)) { ND_PRINT((ndo, ": ")); rtsp_print(ndo, bp, length); } else if (length > 2 && - (sport == NAMESERVER_PORT || dport == NAMESERVER_PORT || - sport == MULTICASTDNS_PORT || dport == MULTICASTDNS_PORT)) { + (IS_SRC_OR_DST_PORT(NAMESERVER_PORT))) { /* * 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 (sport == MSDP_PORT || dport == MSDP_PORT) { + } else if (IS_SRC_OR_DST_PORT(MSDP_PORT)) { msdp_print(ndo, bp, length); - } else if (sport == RPKI_RTR_PORT || dport == RPKI_RTR_PORT) { + } else if (IS_SRC_OR_DST_PORT(RPKI_RTR_PORT)) { rpki_rtr_print(ndo, bp, length); } - else if (length > 0 && (sport == LDP_PORT || dport == LDP_PORT)) { + else if (length > 0 && (IS_SRC_OR_DST_PORT(LDP_PORT))) { ldp_print(ndo, bp, length); } - else if ((sport == NFS_PORT || dport == NFS_PORT) && + else if ((IS_SRC_OR_DST_PORT(NFS_PORT)) && length >= 4 && ND_TTEST2(*bp, 4)) { /* * If data present, header length valid, and NFS port used, @@ -729,23 +736,23 @@ tcp_print(netdissect_options *ndo, * to NFS print routines. */ uint32_t fraglen; - register struct sunrpc_msg *rp; + register const struct sunrpc_msg *rp; enum sunrpc_msg_type direction; fraglen = EXTRACT_32BITS(bp) & 0x7FFFFFFF; if (fraglen > (length) - 4) fraglen = (length) - 4; - rp = (struct sunrpc_msg *)(bp + 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 (dport == NFS_PORT && direction == SUNRPC_CALL) { ND_PRINT((ndo, ": NFS request xid %u ", EXTRACT_32BITS(&rp->rm_xid))); - nfsreq_print_noaddr(ndo, (u_char *)rp, fraglen, (u_char *)ip); + nfsreq_print_noaddr(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, (u_char *)rp, fraglen, (u_char *)ip); + nfsreply_print_noaddr(ndo, (const u_char *)rp, fraglen, (const u_char *)ip); return; } } @@ -790,13 +797,37 @@ print_tcp_rst_data(netdissect_options *ndo, ND_PRINT((ndo, "+")); /* indicate we truncate */ } ND_PRINT((ndo, " ")); - while (length-- && sp <= ndo->ndo_snapend) { + while (length-- && sp < ndo->ndo_snapend) { c = *sp++; safeputchar(ndo, c); } ND_PRINT((ndo, "]")); } +static void +print_tcp_fastopen_option(netdissect_options *ndo, register const u_char *cp, + u_int datalen, int exp) +{ + u_int i; + + if (exp) + ND_PRINT((ndo, "tfo")); + + if (datalen == 0) { + /* Fast Open Cookie Request */ + ND_PRINT((ndo, " cookiereq")); + } else { + /* Fast Open Cookie */ + if (datalen % 2 != 0 || datalen < 4 || datalen > 16) { + ND_PRINT((ndo, " invalid")); + } else { + ND_PRINT((ndo, " cookie ")); + for (i = 0; i < datalen; ++i) + ND_PRINT((ndo, "%02x", cp[i])); + } + } +} + #ifdef HAVE_LIBCRYPTO USES_APPLE_DEPRECATED_API static int @@ -809,11 +840,9 @@ tcp_verify_signature(netdissect_options *ndo, char zero_proto = 0; MD5_CTX ctx; uint16_t savecsum, tlen; -#ifdef INET6 - struct ip6_hdr *ip6; + const struct ip6_hdr *ip6; uint32_t len32; uint8_t nxt; -#endif if (data + length > ndo->ndo_snapend) { ND_PRINT((ndo, "snaplen too short, ")); @@ -832,33 +861,27 @@ tcp_verify_signature(netdissect_options *ndo, * Step 1: Update MD5 hash with IP pseudo-header. */ if (IP_V(ip) == 4) { - MD5_Update(&ctx, (char *)&ip->ip_src, sizeof(ip->ip_src)); - MD5_Update(&ctx, (char *)&ip->ip_dst, sizeof(ip->ip_dst)); - MD5_Update(&ctx, (char *)&zero_proto, sizeof(zero_proto)); - MD5_Update(&ctx, (char *)&ip->ip_p, sizeof(ip->ip_p)); + MD5_Update(&ctx, (const char *)&ip->ip_src, sizeof(ip->ip_src)); + 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 = htons(tlen); - MD5_Update(&ctx, (char *)&tlen, sizeof(tlen)); -#ifdef INET6 + MD5_Update(&ctx, (const char *)&tlen, sizeof(tlen)); } else if (IP_V(ip) == 6) { - ip6 = (struct ip6_hdr *)ip; - MD5_Update(&ctx, (char *)&ip6->ip6_src, sizeof(ip6->ip6_src)); - MD5_Update(&ctx, (char *)&ip6->ip6_dst, sizeof(ip6->ip6_dst)); + 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)); - MD5_Update(&ctx, (char *)&len32, sizeof(len32)); + MD5_Update(&ctx, (const char *)&len32, sizeof(len32)); nxt = 0; - MD5_Update(&ctx, (char *)&nxt, sizeof(nxt)); - MD5_Update(&ctx, (char *)&nxt, sizeof(nxt)); - MD5_Update(&ctx, (char *)&nxt, sizeof(nxt)); + MD5_Update(&ctx, (const char *)&nxt, sizeof(nxt)); + MD5_Update(&ctx, (const char *)&nxt, sizeof(nxt)); + MD5_Update(&ctx, (const char *)&nxt, sizeof(nxt)); nxt = IPPROTO_TCP; - MD5_Update(&ctx, (char *)&nxt, sizeof(nxt)); -#endif + MD5_Update(&ctx, (const char *)&nxt, sizeof(nxt)); } else { -#ifdef INET6 ND_PRINT((ndo, "IP version not 4 or 6, ")); -#else - ND_PRINT((ndo, "IP version not 4, ")); -#endif return (CANT_CHECK_SIGNATURE); } @@ -868,7 +891,7 @@ tcp_verify_signature(netdissect_options *ndo, */ savecsum = tp1.th_sum; tp1.th_sum = 0; - MD5_Update(&ctx, (char *)&tp1, sizeof(struct tcphdr)); + MD5_Update(&ctx, (const char *)&tp1, sizeof(struct tcphdr)); tp1.th_sum = savecsum; /* * Step 3: Update MD5 hash with TCP segment data, if present. diff --git a/contrib/tcpdump/print-telnet.c b/contrib/tcpdump/print-telnet.c index fa59b1f..a664034 100644 --- a/contrib/tcpdump/print-telnet.c +++ b/contrib/tcpdump/print-telnet.c @@ -45,16 +45,19 @@ * are preserved in all copies. */ -#define NETDISSECT_REWORKED +/* \summary: Telnet option printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" + +static const char tstr[] = " [|telnet]"; #define TELCMDS #define TELOPTS @@ -88,7 +91,7 @@ #define SYNCH 242 /* for telfunc calls */ #ifdef TELCMDS -const char *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, @@ -149,7 +152,7 @@ extern char *telcmds[]; #define NTELOPTS (1+TELOPT_NEW_ENVIRON) #ifdef TELOPTS -const char *telopts[NTELOPTS+1] = { +static const char *telopts[NTELOPTS+1] = { "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME", "STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP", "NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS", @@ -434,6 +437,7 @@ telnet_parse(netdissect_options *ndo, const u_char *sp, u_int length, int print) /* IAC SB .... IAC SE */ p = sp; while (length > (u_int)(p + 1 - sp)) { + ND_TCHECK2(*p, 2); if (p[0] == IAC && p[1] == SE) break; p++; @@ -494,7 +498,7 @@ done: return sp - osp; trunc: - ND_PRINT((ndo, "[|telnet]")); + ND_PRINT((ndo, "%s", tstr)); pktend: return -1; #undef FETCH @@ -509,6 +513,7 @@ telnet_print(netdissect_options *ndo, const u_char *sp, u_int length) osp = sp; + ND_TCHECK(*sp); while (length > 0 && *sp == IAC) { /* * Parse the Telnet command without printing it, @@ -537,6 +542,7 @@ telnet_print(netdissect_options *ndo, const u_char *sp, u_int length) sp += l; length -= l; + ND_TCHECK(*sp); } if (!first) { if (ndo->ndo_Xflag && 2 < ndo->ndo_vflag) @@ -544,4 +550,7 @@ telnet_print(netdissect_options *ndo, const u_char *sp, u_int length) else ND_PRINT((ndo, "]")); } + return; +trunc: + ND_PRINT((ndo, "%s", tstr)); } diff --git a/contrib/tcpdump/print-tftp.c b/contrib/tcpdump/print-tftp.c index 9b88e74..69bc601 100644 --- a/contrib/tcpdump/print-tftp.c +++ b/contrib/tcpdump/print-tftp.c @@ -17,20 +17,19 @@ * 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. - * - * Format and print trivial file transfer protocol packets. */ -#define NETDISSECT_REWORKED +/* \summary: Trivial File Transfer Protocol (TFTP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" #include "extract.h" /* @@ -110,7 +109,8 @@ tftp_print(netdissect_options *ndo, register const struct tftphdr *tp; register const char *cp; register const u_char *p; - register int opcode, i; + register int opcode; + u_int ui; tp = (const struct tftphdr *)bp; @@ -118,9 +118,12 @@ tftp_print(netdissect_options *ndo, ND_PRINT((ndo, " %d", length)); /* Print tftp request type */ + if (length < 2) + goto trunc; ND_TCHECK(tp->th_opcode); opcode = EXTRACT_16BITS(&tp->th_opcode); cp = tok2str(op2str, "tftp-#%d", opcode); + length -= 2; ND_PRINT((ndo, " %s", cp)); /* Bail if bogus opcode */ if (*cp == 't') @@ -130,46 +133,80 @@ tftp_print(netdissect_options *ndo, case RRQ: case WRQ: - case OACK: - p = (u_char *)tp->th_stuff; + p = (const u_char *)tp->th_stuff; + if (length == 0) + goto trunc; + ND_PRINT((ndo, " ")); + /* Print filename */ + ND_PRINT((ndo, "\"")); + ui = fn_printztn(ndo, p, length, ndo->ndo_snapend); + ND_PRINT((ndo, "\"")); + if (ui == 0) + goto trunc; + p += ui; + length -= ui; + + /* Print the mode - RRQ and WRQ only */ + if (length == 0) + goto trunc; /* no mode */ ND_PRINT((ndo, " ")); - /* Print filename or first option */ - if (opcode != OACK) - ND_PRINT((ndo, "\"")); - i = fn_print(ndo, p, ndo->ndo_snapend); - if (opcode != OACK) - ND_PRINT((ndo, "\"")); - - /* Print the mode (RRQ and WRQ only) and any options */ - while ((p = (const u_char *)strchr((const char *)p, '\0')) != NULL) { - if (length <= (u_int)(p - (const u_char *)&tp->th_block)) - break; - p++; - if (*p != '\0') { + ui = fn_printztn(ndo, p, length, ndo->ndo_snapend); + if (ui == 0) + goto trunc; + p += ui; + length -= ui; + + /* Print options, if any */ + while (length != 0) { + ND_TCHECK(*p); + if (*p != '\0') ND_PRINT((ndo, " ")); - fn_print(ndo, p, ndo->ndo_snapend); - } + ui = fn_printztn(ndo, p, length, ndo->ndo_snapend); + if (ui == 0) + goto trunc; + p += ui; + length -= ui; } + break; - if (i) - goto trunc; + case OACK: + p = (const u_char *)tp->th_stuff; + /* Print options */ + while (length != 0) { + ND_TCHECK(*p); + if (*p != '\0') + ND_PRINT((ndo, " ")); + ui = fn_printztn(ndo, p, length, ndo->ndo_snapend); + if (ui == 0) + goto trunc; + p += ui; + length -= ui; + } break; case ACK: case DATA: + if (length < 2) + goto trunc; /* no block number */ ND_TCHECK(tp->th_block); ND_PRINT((ndo, " block %d", EXTRACT_16BITS(&tp->th_block))); break; case TFTP_ERROR: /* Print error code string */ + if (length < 2) + goto trunc; /* no error code */ ND_TCHECK(tp->th_code); - ND_PRINT((ndo, " %s \"", tok2str(err2str, "tftp-err-#%d \"", + ND_PRINT((ndo, " %s", tok2str(err2str, "tftp-err-#%d \"", EXTRACT_16BITS(&tp->th_code)))); + length -= 2; /* Print error message string */ - i = fn_print(ndo, (const u_char *)tp->th_data, ndo->ndo_snapend); + if (length == 0) + goto trunc; /* no error message */ + ND_PRINT((ndo, " \"")); + ui = fn_printztn(ndo, (const u_char *)tp->th_data, length, ndo->ndo_snapend); ND_PRINT((ndo, "\"")); - if (i) + if (ui == 0) goto trunc; break; diff --git a/contrib/tcpdump/print-timed.c b/contrib/tcpdump/print-timed.c index 5830bc7..6aa7a82 100644 --- a/contrib/tcpdump/print-timed.c +++ b/contrib/tcpdump/print-timed.c @@ -19,18 +19,21 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: BSD time daemon protocol printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" /* * Time Synchronization Protocol + * + * http://docs.freebsd.org/44doc/smm/12.timed/paper.pdf */ struct tsp_timeval { @@ -95,7 +98,7 @@ void timed_print(netdissect_options *ndo, register const u_char *bp) { - struct tsp *tsp = (struct tsp *)bp; + const struct tsp *tsp = (const struct tsp *)bp; long sec, usec; ND_TCHECK(tsp->tsp_type); @@ -124,7 +127,7 @@ timed_print(netdissect_options *ndo, usec = EXTRACT_32BITS(&tsp->tsp_time.tv_usec); /* XXX The comparison below is always false? */ if (usec < 0) - /* corrupt, skip the rest of the packet */ + /* invalid, skip the rest of the packet */ return; ND_PRINT((ndo, " time ")); if (sec < 0 && usec != 0) { @@ -138,7 +141,7 @@ timed_print(netdissect_options *ndo, } ND_TCHECK(tsp->tsp_name); ND_PRINT((ndo, " name ")); - if (fn_print(ndo, (u_char *)tsp->tsp_name, (u_char *)tsp->tsp_name + sizeof(tsp->tsp_name))) + if (fn_print(ndo, (const u_char *)tsp->tsp_name, (const u_char *)tsp->tsp_name + sizeof(tsp->tsp_name))) goto trunc; return; diff --git a/contrib/tcpdump/print-tipc.c b/contrib/tcpdump/print-tipc.c index b883fba..4d8848f 100644 --- a/contrib/tcpdump/print-tipc.c +++ b/contrib/tcpdump/print-tipc.c @@ -19,27 +19,27 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: Transparent Inter-Process Communication (TIPC) protocol printer */ + +/* + * specification: + * http://tipc.sourceforge.net/doc/draft-spec-tipc-07.html + * http://tipc.sourceforge.net/doc/tipc_message_formats.html + */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "ether.h" #include "ethertype.h" -#include "extract.h" /* must come after interface.h */ +#include "extract.h" static const char tstr[] = "[|TIPC]"; -/* - * Transparent Inter-Process Communication (TIPC) protocol. - * - * http://tipc.sourceforge.net/doc/draft-spec-tipc-07.html - * http://tipc.sourceforge.net/doc/tipc_message_formats.html - */ - #define TIPC_USER_LOW_IMPORTANCE 0 #define TIPC_USER_MEDIUM_IMPORTANCE 1 #define TIPC_USER_HIGH_IMPORTANCE 2 @@ -342,7 +342,7 @@ tipc_print(netdissect_options *ndo, const u_char *bp, u_int length _U_, uint32_t w0; u_int user; - ap = (struct tipc_pkthdr *)bp; + ap = (const struct tipc_pkthdr *)bp; ND_TCHECK(ap->w0); w0 = EXTRACT_32BITS(&ap->w0); user = TIPC_USER(w0); @@ -355,11 +355,11 @@ tipc_print(netdissect_options *ndo, const u_char *bp, u_int length _U_, case TIPC_USER_CRITICAL_IMPORTANCE: case TIPC_USER_NAME_DISTRIBUTOR: case TIPC_USER_CONN_MANAGER: - print_payload(ndo, (struct payload_tipc_pkthdr *)bp); + print_payload(ndo, (const struct payload_tipc_pkthdr *)bp); break; case TIPC_USER_LINK_CONFIG: - print_link_conf(ndo, (struct link_conf_tipc_pkthdr *)bp); + print_link_conf(ndo, (const struct link_conf_tipc_pkthdr *)bp); break; case TIPC_USER_BCAST_PROTOCOL: @@ -367,7 +367,7 @@ tipc_print(netdissect_options *ndo, const u_char *bp, u_int length _U_, case TIPC_USER_LINK_PROTOCOL: case TIPC_USER_CHANGEOVER_PROTOCOL: case TIPC_USER_MSG_FRAGMENTER: - print_internal(ndo, (struct internal_tipc_pkthdr *)bp); + print_internal(ndo, (const struct internal_tipc_pkthdr *)bp); break; } diff --git a/contrib/tcpdump/print-token.c b/contrib/tcpdump/print-token.c index af4780c..faffd4b 100644 --- a/contrib/tcpdump/print-token.c +++ b/contrib/tcpdump/print-token.c @@ -22,20 +22,19 @@ * * Further tweaked to more closely resemble print-fddi.c * Guy Harris - * - * $FreeBSD$ */ -#define NETDISSECT_REWORKED +/* \summary: Token Ring printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "addrtoname.h" #include "ether.h" @@ -115,14 +114,13 @@ token_hdr_print(netdissect_options *ndo, srcname = etheraddr_string(ndo, fsrc); dstname = etheraddr_string(ndo, fdst); - if (ndo->ndo_vflag) - ND_PRINT((ndo, "%02x %02x %s %s %d: ", + if (!ndo->ndo_qflag) + ND_PRINT((ndo, "%02x %02x ", trp->token_ac, - trp->token_fc, - srcname, dstname, - length)); - else - ND_PRINT((ndo, "%s %s %d: ", srcname, dstname, length)); + trp->token_fc)); + ND_PRINT((ndo, "%s > %s, length %u: ", + srcname, dstname, + length)); } static const char *broadcast_indicator[] = { @@ -151,8 +149,9 @@ u_int token_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen) { const struct token_header *trp; - u_short extracted_ethertype; + int llc_hdrlen; struct ether_header ehdr; + struct lladdr_info src, dst; u_int route_len = 0, hdr_len = TOKEN_HDRLEN; int seg; @@ -205,6 +204,11 @@ token_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen token_hdr_print(ndo, trp, length, ESRC(&ehdr), EDST(&ehdr)); } + src.addr = ESRC(&ehdr); + src.addr_string = etheraddr_string; + dst.addr = EDST(&ehdr); + dst.addr_string = etheraddr_string; + /* Skip over token ring MAC header and routing information */ length -= hdr_len; p += hdr_len; @@ -213,20 +217,14 @@ token_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen /* Frame Control field determines interpretation of packet */ if (FRAME_TYPE(trp) == TOKEN_FC_LLC) { /* Try to print the LLC-layer header & higher layers */ - if (llc_print(ndo, p, length, caplen, ESRC(&ehdr), EDST(&ehdr), - &extracted_ethertype) == 0) { - /* ether_type not known, print raw packet */ - if (!ndo->ndo_eflag) - token_hdr_print(ndo, trp, - length + TOKEN_HDRLEN + route_len, - ESRC(&ehdr), EDST(&ehdr)); - if (extracted_ethertype) { - ND_PRINT((ndo, "(LLC %s) ", - etherproto_string(htons(extracted_ethertype)))); - } + 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; } + hdr_len += llc_hdrlen; } else { /* Some kinds of TR packet we cannot handle intelligently */ /* XXX - dissect MAC packets if frame type is 0 */ diff --git a/contrib/tcpdump/print-udld.c b/contrib/tcpdump/print-udld.c index 15e2bf6..02921d0 100644 --- a/contrib/tcpdump/print-udld.c +++ b/contrib/tcpdump/print-udld.c @@ -12,22 +12,24 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * UNIDIRECTIONAL LINK DETECTION (UDLD) as per - * http://www.ietf.org/internet-drafts/draft-foschiano-udld-02.txt - * * Original code by Carles Kishimoto */ -#define NETDISSECT_REWORKED +/* \summary: Cisco UniDirectional Link Detection (UDLD) protocol printer */ + +/* specification: RFC 5171 */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" +static const char tstr[] = " [|udld]"; + #define UDLD_HEADER_LEN 4 #define UDLD_DEVICE_ID_TLV 0x0001 #define UDLD_PORT_ID_TLV 0x0002 @@ -63,9 +65,10 @@ static const struct tok udld_flags_values[] = { }; /* + * UDLD's Protocol Data Unit format: * - * 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 + * 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 | Opcode | Flags | Checksum | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -73,6 +76,18 @@ static const struct tok udld_flags_values[] = { * | ... | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * + * TLV format: + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | TYPE | LENGTH | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | VALUE | + * | ... | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * LENGTH: Length in bytes of the Type, Length, and Value fields. */ #define UDLD_EXTRACT_VERSION(x) (((x)&0xe0)>>5) @@ -115,35 +130,48 @@ udld_print (netdissect_options *ndo, const u_char *pptr, u_int length) while (tptr < (pptr+length)) { ND_TCHECK2(*tptr, 4); - type = EXTRACT_16BITS(tptr); len = EXTRACT_16BITS(tptr+2); - len -= 4; - tptr += 4; - - /* infinite loop check */ - if (type == 0 || len == 0) { - return; - } ND_PRINT((ndo, "\n\t%s (0x%04x) TLV, length %u", tok2str(udld_tlv_values, "Unknown", type), type, len)); + if (type == 0) + goto invalid; + + /* infinite loop check */ + if (len <= 4) + goto invalid; + + len -= 4; + tptr += 4; + + ND_TCHECK2(*tptr, len); + switch (type) { case UDLD_DEVICE_ID_TLV: case UDLD_PORT_ID_TLV: - case UDLD_ECHO_TLV: case UDLD_DEVICE_NAME_TLV: - ND_PRINT((ndo, ", %s", tptr)); + ND_PRINT((ndo, ", ")); + fn_printzp(ndo, tptr, len, NULL); + break; + + case UDLD_ECHO_TLV: + ND_PRINT((ndo, ", ")); + (void)fn_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))); break; case UDLD_SEQ_NUMBER_TLV: + if (len != 4) + goto invalid; ND_PRINT((ndo, ", %u", EXTRACT_32BITS(tptr))); break; @@ -155,8 +183,11 @@ udld_print (netdissect_options *ndo, const u_char *pptr, u_int length) return; - trunc: - ND_PRINT((ndo, "[|udld]")); +invalid: + ND_PRINT((ndo, "%s", istr)); + return; +trunc: + ND_PRINT((ndo, "%s", tstr)); } /* diff --git a/contrib/tcpdump/print-udp.c b/contrib/tcpdump/print-udp.c index c9e6058..5a74ff2 100644 --- a/contrib/tcpdump/print-udp.c +++ b/contrib/tcpdump/print-udp.c @@ -17,18 +17,17 @@ * 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. - * - * $FreeBSD$ */ -#define NETDISSECT_REWORKED +/* \summary: UDP printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" #include "appletalk.h" @@ -36,16 +35,18 @@ #include "udp.h" #include "ip.h" -#ifdef INET6 #include "ip6.h" -#endif #include "ipproto.h" #include "rpc_auth.h" #include "rpc_msg.h" -#include "nameser.h" #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) */ @@ -99,16 +100,25 @@ static void vat_print(netdissect_options *ndo, const void *hdr, register const struct udphdr *up) { /* vat/vt audio */ - u_int ts = *(uint16_t *)hdr; + u_int ts; + + ND_TCHECK_16BITS((const u_int *)hdr); + ts = EXTRACT_16BITS(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)); } else { /* probably vat */ - uint32_t i0 = EXTRACT_32BITS(&((u_int *)hdr)[0]); - uint32_t i1 = EXTRACT_32BITS(&((u_int *)hdr)[1]); + 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), i0 & 0xffff, @@ -119,6 +129,9 @@ vat_print(netdissect_options *ndo, const void *hdr, register const struct udphdr if (i0 & 0x3f000000) ND_PRINT((ndo, " s%d", (i0 >> 24) & 0x3f)); } + +trunc: + ND_PRINT((ndo, "%s", vat_tstr)); } static void @@ -126,26 +139,30 @@ rtp_print(netdissect_options *ndo, const void *hdr, u_int len, register const struct udphdr *up) { /* rtp v1 or v2 */ - u_int *ip = (u_int *)hdr; - u_int hasopt, hasext, contype, hasmarker; - uint32_t i0 = EXTRACT_32BITS(&((u_int *)hdr)[0]); - uint32_t i1 = EXTRACT_32BITS(&((u_int *)hdr)[1]); - u_int dlen = EXTRACT_16BITS(&up->uh_ulen) - sizeof(*up) - 8; + const u_int *ip = (const u_int *)hdr; + u_int hasopt, hasext, contype, hasmarker, dlen; + 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; ip += 2; len >>= 2; len -= 2; hasopt = 0; hasext = 0; if ((i0 >> 30) == 1) { - /* rtp v1 */ + /* rtp v1 - draft-ietf-avt-rtp-04 */ hasopt = i0 & 0x800000; contype = (i0 >> 16) & 0x3f; hasmarker = i0 & 0x400000; ptype = "rtpv1"; } else { - /* rtp v2 */ + /* rtp v2 - RFC 3550 */ hasext = i0 & 0x10000000; contype = (i0 >> 16) & 0x7f; hasmarker = i0 & 0x800000; @@ -163,11 +180,13 @@ rtp_print(netdissect_options *ndo, const void *hdr, u_int len, i0 & 0xffff, i1)); if (ndo->ndo_vflag) { - ND_PRINT((ndo, " %u", EXTRACT_32BITS(&((u_int *)hdr)[2]))); + ND_TCHECK_32BITS(&((const u_int *)hdr)[2]); + ND_PRINT((ndo, " %u", EXTRACT_32BITS(&((const u_int *)hdr)[2]))); if (hasopt) { u_int i2, optlen; do { - i2 = ip[0]; + ND_TCHECK_32BITS(ip); + i2 = EXTRACT_32BITS(ip); optlen = (i2 >> 16) & 0xff; if (optlen == 0 || optlen > len) { ND_PRINT((ndo, " !opt")); @@ -179,7 +198,8 @@ rtp_print(netdissect_options *ndo, const void *hdr, u_int len, } if (hasext) { u_int i2, extlen; - i2 = ip[0]; + ND_TCHECK_32BITS(ip); + i2 = EXTRACT_32BITS(ip); extlen = (i2 & 0xffff) + 1; if (extlen > len) { ND_PRINT((ndo, " !ext")); @@ -187,53 +207,55 @@ rtp_print(netdissect_options *ndo, const void *hdr, u_int len, } ip += extlen; } + ND_TCHECK_32BITS(ip); if (contype == 0x1f) /*XXX H.261 */ - ND_PRINT((ndo, " 0x%04x", ip[0] >> 16)); + ND_PRINT((ndo, " 0x%04x", EXTRACT_32BITS(ip) >> 16)); } + +trunc: + ND_PRINT((ndo, "%s", rtp_tstr)); } static const u_char * rtcp_print(netdissect_options *ndo, const u_char *hdr, const u_char *ep) { /* rtp v2 control (rtcp) */ - struct rtcp_rr *rr = 0; - struct rtcp_sr *sr; - struct rtcphdr *rh = (struct rtcphdr *)hdr; + const struct rtcp_rr *rr = 0; + const struct rtcp_sr *sr; + const struct rtcphdr *rh = (const struct rtcphdr *)hdr; u_int len; uint16_t flags; int cnt; double ts, dts; - if ((u_char *)(rh + 1) > ep) { - ND_PRINT((ndo, " [|rtcp]")); - return (ep); - } + 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); cnt = (flags >> 8) & 0x1f; switch (flags & 0xff) { case RTCP_PT_SR: - sr = (struct rtcp_sr *)(rh + 1); + sr = (const struct rtcp_sr *)(rh + 1); ND_PRINT((ndo, " sr")); if (len != cnt * sizeof(*rr) + sizeof(*sr) + sizeof(*rh)) ND_PRINT((ndo, " [%d]", len)); if (ndo->ndo_vflag) ND_PRINT((ndo, " %u", EXTRACT_32BITS(&rh->rh_ssrc))); - if ((u_char *)(sr + 1) > ep) { - ND_PRINT((ndo, " [|rtcp]")); - return (ep); - } + 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))); - rr = (struct rtcp_rr *)(sr + 1); + rr = (const struct rtcp_rr *)(sr + 1); break; case RTCP_PT_RR: ND_PRINT((ndo, " rr")); if (len != cnt * sizeof(*rr) + sizeof(*rh)) ND_PRINT((ndo, " [%d]", len)); - rr = (struct rtcp_rr *)(rh + 1); + rr = (const struct rtcp_rr *)(rh + 1); if (ndo->ndo_vflag) ND_PRINT((ndo, " %u", EXTRACT_32BITS(&rh->rh_ssrc))); break; @@ -257,10 +279,9 @@ rtcp_print(netdissect_options *ndo, const u_char *hdr, const u_char *ep) if (cnt > 1) ND_PRINT((ndo, " c%d", cnt)); while (--cnt >= 0) { - if ((u_char *)(rr + 1) > ep) { - ND_PRINT((ndo, " [|rtcp]")); - return (ep); - } + if ((const u_char *)(rr + 1) > ep) + goto trunc; + ND_TCHECK(*rr); if (ndo->ndo_vflag) ND_PRINT((ndo, " %u", EXTRACT_32BITS(&rr->rr_srcid))); ts = (double)(EXTRACT_32BITS(&rr->rr_lsr)) / 65536.; @@ -271,29 +292,30 @@ rtcp_print(netdissect_options *ndo, const u_char *hdr, const u_char *ep) EXTRACT_32BITS(&rr->rr_dv), ts, dts)); } return (hdr + len); + +trunc: + ND_PRINT((ndo, "%s", rtcp_tstr)); + return ep; } static int udp_cksum(netdissect_options *ndo, register const struct ip *ip, register const struct udphdr *up, register u_int len) { - return nextproto4_cksum(ndo, ip, (const uint8_t *)(void *)up, len, len, + return nextproto4_cksum(ndo, ip, (const uint8_t *)(const void *)up, len, len, IPPROTO_UDP); } -#ifdef INET6 -static int udp6_cksum(const struct ip6_hdr *ip6, const struct udphdr *up, - u_int len) +static int udp6_cksum(netdissect_options *ndo, const struct ip6_hdr *ip6, + const struct udphdr *up, u_int len) { - return nextproto6_cksum(ip6, (const uint8_t *)(void *)up, len, len, - IPPROTO_UDP); + return nextproto6_cksum(ndo, ip6, (const uint8_t *)(const void *)up, len, len, + IPPROTO_UDP); } -#endif static void udpipaddr_print(netdissect_options *ndo, const struct ip *ip, int sport, int dport) { -#ifdef INET6 const struct ip6_hdr *ip6; if (IP_V(ip) == 6) @@ -310,20 +332,18 @@ udpipaddr_print(netdissect_options *ndo, const struct ip *ip, int sport, int dpo } else { ND_PRINT((ndo, "%s.%s > %s.%s: ", ip6addr_string(ndo, &ip6->ip6_src), - udpport_string(sport), + udpport_string(ndo, sport), ip6addr_string(ndo, &ip6->ip6_dst), - udpport_string(dport))); + udpport_string(ndo, dport))); } } else { if (sport != -1) { ND_PRINT((ndo, "%s > %s: ", - udpport_string(sport), - udpport_string(dport))); + udpport_string(ndo, sport), + udpport_string(ndo, dport))); } } - } else -#endif /*INET6*/ - { + } else { if (ip->ip_p == IPPROTO_UDP) { if (sport == -1) { ND_PRINT((ndo, "%s > %s: ", @@ -332,15 +352,15 @@ udpipaddr_print(netdissect_options *ndo, const struct ip *ip, int sport, int dpo } else { ND_PRINT((ndo, "%s.%s > %s.%s: ", ipaddr_string(ndo, &ip->ip_src), - udpport_string(sport), + udpport_string(ndo, sport), ipaddr_string(ndo, &ip->ip_dst), - udpport_string(dport))); + udpport_string(ndo, dport))); } } else { if (sport != -1) { ND_PRINT((ndo, "%s > %s: ", - udpport_string(sport), - udpport_string(dport))); + udpport_string(ndo, sport), + udpport_string(ndo, dport))); } } } @@ -355,24 +375,19 @@ udp_print(netdissect_options *ndo, register const u_char *bp, u_int length, register const u_char *cp; register const u_char *ep = bp + length; uint16_t sport, dport, ulen; -#ifdef INET6 register const struct ip6_hdr *ip6; -#endif if (ep > ndo->ndo_snapend) ep = ndo->ndo_snapend; - up = (struct udphdr *)bp; - ip = (struct ip *)bp2; -#ifdef INET6 + up = (const struct udphdr *)bp; + ip = (const struct ip *)bp2; if (IP_V(ip) == 6) - ip6 = (struct ip6_hdr *)bp2; + ip6 = (const struct ip6_hdr *)bp2; else ip6 = NULL; -#endif /*INET6*/ if (!ND_TTEST(up->uh_dport)) { udpipaddr_print(ndo, ip, -1, -1); - ND_PRINT((ndo, "[|udp]")); - return; + goto trunc; } sport = EXTRACT_16BITS(&up->uh_sport); @@ -383,6 +398,10 @@ udp_print(netdissect_options *ndo, register const u_char *bp, u_int length, ND_PRINT((ndo, "truncated-udp %d", length)); return; } + if (!ND_TTEST(up->uh_ulen)) { + udpipaddr_print(ndo, ip, sport, dport); + goto trunc; + } ulen = EXTRACT_16BITS(&up->uh_ulen); if (ulen < sizeof(struct udphdr)) { udpipaddr_print(ndo, ip, sport, dport); @@ -394,43 +413,42 @@ udp_print(netdissect_options *ndo, register const u_char *bp, u_int length, if (ulen < length) length = ulen; - cp = (u_char *)(up + 1); + cp = (const u_char *)(up + 1); if (cp > ndo->ndo_snapend) { udpipaddr_print(ndo, ip, sport, dport); - ND_PRINT((ndo, "[|udp]")); - return; + goto trunc; } if (ndo->ndo_packettype) { - register struct sunrpc_msg *rp; + register 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, (void *)(up + 1), up); + vat_print(ndo, (const void *)(up + 1), up); break; case PT_WB: udpipaddr_print(ndo, ip, sport, dport); - wb_print(ndo, (void *)(up + 1), length); + wb_print(ndo, (const void *)(up + 1), length); break; case PT_RPC: - rp = (struct sunrpc_msg *)(up + 1); + rp = (const struct sunrpc_msg *)(up + 1); direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction); if (direction == SUNRPC_CALL) - sunrpcrequest_print(ndo, (u_char *)rp, length, - (u_char *)ip); + sunrpcrequest_print(ndo, (const u_char *)rp, length, + (const u_char *)ip); else - nfsreply_print(ndo, (u_char *)rp, length, - (u_char *)ip); /*XXX*/ + nfsreply_print(ndo, (const u_char *)rp, length, + (const u_char *)ip); /*XXX*/ break; case PT_RTP: udpipaddr_print(ndo, ip, sport, dport); - rtp_print(ndo, (void *)(up + 1), length, up); + rtp_print(ndo, (const void *)(up + 1), length, up); break; case PT_RTCP: @@ -457,11 +475,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, -#ifdef INET6 ip6 != NULL); -#else - 0); -#endif break; case PT_RADIUS: @@ -489,39 +503,31 @@ udp_print(netdissect_options *ndo, register const u_char *bp, u_int length, udpipaddr_print(ndo, ip, sport, dport); if (!ndo->ndo_qflag) { - register struct sunrpc_msg *rp; + register const struct sunrpc_msg *rp; enum sunrpc_msg_type direction; - rp = (struct sunrpc_msg *)(up + 1); + rp = (const struct sunrpc_msg *)(up + 1); if (ND_TTEST(rp->rm_direction)) { direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&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, (u_char *)rp, length, - (u_char *)ip); + nfsreq_print_noaddr(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, (u_char *)rp, length, - (u_char *)ip); + nfsreply_print_noaddr(ndo, (const u_char *)rp, length, + (const u_char *)ip); return; } #ifdef notdef if (dport == SUNRPC_PORT && direction == SUNRPC_CALL) { - sunrpcrequest_print((u_char *)rp, length, (u_char *)ip); + sunrpcrequest_print((const u_char *)rp, length, (const u_char *)ip); return; } #endif } - if (ND_TTEST(((struct LAP *)cp)->type) && - ((struct LAP *)cp)->type == lapDDP && - (atalk_port(sport) || atalk_port(dport))) { - if (ndo->ndo_vflag) - ND_PRINT((ndo, "kip ")); - llap_print(ndo, cp, length); - return; - } } if (ndo->ndo_vflag && !ndo->ndo_Kflag && !fragmented) { @@ -547,11 +553,10 @@ udp_print(netdissect_options *ndo, register const u_char *bp, u_int length, ND_PRINT((ndo, "[udp sum ok] ")); } } -#ifdef INET6 else if (IP_V(ip) == 6 && ip6->ip6_plen) { /* for IPv6, UDP checksum is mandatory */ if (ND_TTEST2(cp[0], length)) { - sum = udp6_cksum(ip6, up, length + sizeof(struct udphdr)); + sum = udp6_cksum(ndo, ip6, up, length + sizeof(struct udphdr)); udp_sum = EXTRACT_16BITS(&up->uh_sum); if (sum != 0) { @@ -562,55 +567,49 @@ udp_print(netdissect_options *ndo, register const u_char *bp, u_int length, ND_PRINT((ndo, "[udp sum ok] ")); } } -#endif } if (!ndo->ndo_qflag) { -#define ISPORT(p) (dport == (p) || sport == (p)) - if (ISPORT(NAMESERVER_PORT)) + if (IS_SRC_OR_DST_PORT(NAMESERVER_PORT)) ns_print(ndo, (const u_char *)(up + 1), length, 0); - else if (ISPORT(MULTICASTDNS_PORT)) + else if (IS_SRC_OR_DST_PORT(MULTICASTDNS_PORT)) ns_print(ndo, (const u_char *)(up + 1), length, 1); - else if (ISPORT(TIMED_PORT)) + else if (IS_SRC_OR_DST_PORT(TIMED_PORT)) timed_print(ndo, (const u_char *)(up + 1)); - else if (ISPORT(TFTP_PORT)) + else if (IS_SRC_OR_DST_PORT(TFTP_PORT)) tftp_print(ndo, (const u_char *)(up + 1), length); - else if (ISPORT(BOOTPC_PORT) || ISPORT(BOOTPS_PORT)) + 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); - else if (ISPORT(RIP_PORT)) + else if (IS_SRC_OR_DST_PORT(RIP_PORT)) rip_print(ndo, (const u_char *)(up + 1), length); - else if (ISPORT(AODV_PORT)) + else if (IS_SRC_OR_DST_PORT(AODV_PORT)) aodv_print(ndo, (const u_char *)(up + 1), length, -#ifdef INET6 ip6 != NULL); -#else - 0); -#endif - else if (ISPORT(ISAKMP_PORT)) + else if (IS_SRC_OR_DST_PORT(ISAKMP_PORT)) isakmp_print(ndo, (const u_char *)(up + 1), length, bp2); - else if (ISPORT(ISAKMP_PORT_NATT)) + 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 (ISPORT(ISAKMP_PORT_USER1) || ISPORT(ISAKMP_PORT_USER2)) + 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 (ISPORT(SNMP_PORT) || ISPORT(SNMPTRAP_PORT)) + 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); - else if (ISPORT(NTP_PORT)) + else if (IS_SRC_OR_DST_PORT(NTP_PORT)) ntp_print(ndo, (const u_char *)(up + 1), length); - else if (ISPORT(KERBEROS_PORT) || ISPORT(KERBEROS_SEC_PORT)) + else if (IS_SRC_OR_DST_PORT(KERBEROS_PORT) || IS_SRC_OR_DST_PORT(KERBEROS_SEC_PORT)) krb_print(ndo, (const void *)(up + 1)); - else if (ISPORT(L2TP_PORT)) + else if (IS_SRC_OR_DST_PORT(L2TP_PORT)) l2tp_print(ndo, (const u_char *)(up + 1), length); -#ifdef TCPDUMP_DO_SMB - else if (ISPORT(NETBIOS_NS_PORT)) +#ifdef ENABLE_SMB + else if (IS_SRC_OR_DST_PORT(NETBIOS_NS_PORT)) nbt_udp137_print(ndo, (const u_char *)(up + 1), length); - else if (ISPORT(NETBIOS_DGRAM_PORT)) + else if (IS_SRC_OR_DST_PORT(NETBIOS_DGRAM_PORT)) nbt_udp138_print(ndo, (const u_char *)(up + 1), length); #endif else if (dport == VAT_PORT) vat_print(ndo, (const void *)(up + 1), up); - else if (ISPORT(ZEPHYR_SRV_PORT) || ISPORT(ZEPHYR_CLT_PORT)) + 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); /* * Since there are 10 possible ports to check, I think @@ -619,78 +618,84 @@ udp_print(netdissect_options *ndo, register const u_char *bp, u_int length, 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, - (u_char *) ip); -#ifdef INET6 - else if (ISPORT(RIPNG_PORT)) + (const u_char *) ip); + else if (IS_SRC_OR_DST_PORT(RIPNG_PORT)) ripng_print(ndo, (const u_char *)(up + 1), length); - else if (ISPORT(DHCP6_SERV_PORT) || ISPORT(DHCP6_CLI_PORT)) + 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); - else if (ISPORT(AHCP_PORT)) + else if (IS_SRC_OR_DST_PORT(AHCP_PORT)) ahcp_print(ndo, (const u_char *)(up + 1), length); - else if (ISPORT(BABEL_PORT) || ISPORT(BABEL_PORT_OLD)) + 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); -#endif /*INET6*/ + else if (IS_SRC_OR_DST_PORT(HNCP_PORT)) + hncp_print(ndo, (const u_char *)(up + 1), length); /* * Kludge in test for whiteboard packets. */ else if (dport == WB_PORT) wb_print(ndo, (const void *)(up + 1), length); - else if (ISPORT(CISCO_AUTORP_PORT)) + else if (IS_SRC_OR_DST_PORT(CISCO_AUTORP_PORT)) cisco_autorp_print(ndo, (const void *)(up + 1), length); - else if (ISPORT(RADIUS_PORT) || - ISPORT(RADIUS_NEW_PORT) || - ISPORT(RADIUS_ACCOUNTING_PORT) || - ISPORT(RADIUS_NEW_ACCOUNTING_PORT) || - ISPORT(RADIUS_COA_PORT) ) + 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); else if (dport == HSRP_PORT) hsrp_print(ndo, (const u_char *)(up + 1), length); - else if (ISPORT(LWRES_PORT)) + else if (IS_SRC_OR_DST_PORT(LWRES_PORT)) lwres_print(ndo, (const u_char *)(up + 1), length); - else if (ISPORT(LDP_PORT)) + else if (IS_SRC_OR_DST_PORT(LDP_PORT)) ldp_print(ndo, (const u_char *)(up + 1), length); - else if (ISPORT(OLSR_PORT)) + else if (IS_SRC_OR_DST_PORT(OLSR_PORT)) olsr_print(ndo, (const u_char *)(up + 1), length, -#if INET6 (IP_V(ip) == 6) ? 1 : 0); -#else - 0); -#endif - else if (ISPORT(MPLS_LSP_PING_PORT)) + else if (IS_SRC_OR_DST_PORT(MPLS_LSP_PING_PORT)) lspping_print(ndo, (const u_char *)(up + 1), length); else if (dport == BFD_CONTROL_PORT || dport == BFD_ECHO_PORT ) bfd_print(ndo, (const u_char *)(up+1), length, dport); - else if (ISPORT(LMP_PORT)) + else if (IS_SRC_OR_DST_PORT(LMP_PORT)) lmp_print(ndo, (const u_char *)(up + 1), length); - else if (ISPORT(VQP_PORT)) + else if (IS_SRC_OR_DST_PORT(VQP_PORT)) vqp_print(ndo, (const u_char *)(up + 1), length); - else if (ISPORT(SFLOW_PORT)) + 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 (ISPORT(LWAPP_DATA_PORT)) + else if (IS_SRC_OR_DST_PORT(LWAPP_DATA_PORT)) lwapp_data_print(ndo, (const u_char *)(up + 1), length); - else if (ISPORT(SIP_PORT)) + else if (IS_SRC_OR_DST_PORT(SIP_PORT)) sip_print(ndo, (const u_char *)(up + 1), length); - else if (ISPORT(SYSLOG_PORT)) + else if (IS_SRC_OR_DST_PORT(SYSLOG_PORT)) syslog_print(ndo, (const u_char *)(up + 1), length); - else if (ISPORT(OTV_PORT)) + else if (IS_SRC_OR_DST_PORT(OTV_PORT)) otv_print(ndo, (const u_char *)(up + 1), length); - else if (ISPORT(VXLAN_PORT)) + else if (IS_SRC_OR_DST_PORT(VXLAN_PORT)) vxlan_print(ndo, (const u_char *)(up + 1), length); - else if (ISPORT(GENEVE_PORT)) + else if (IS_SRC_OR_DST_PORT(GENEVE_PORT)) geneve_print(ndo, (const u_char *)(up + 1), length); - else { + else if (IS_SRC_OR_DST_PORT(LISP_CONTROL_PORT)) + lisp_print(ndo, (const u_char *)(up + 1), 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))) { + if (ndo->ndo_vflag) + ND_PRINT((ndo, "kip ")); + llap_print(ndo, cp, length); + } else { if (ulen > length) ND_PRINT((ndo, "UDP, bad length %u > %u", ulen, length)); else ND_PRINT((ndo, "UDP, length %u", ulen)); } -#undef ISPORT } else { if (ulen > length) ND_PRINT((ndo, "UDP, bad length %u > %u", @@ -698,6 +703,10 @@ udp_print(netdissect_options *ndo, register const u_char *bp, u_int length, else ND_PRINT((ndo, "UDP, length %u", ulen)); } + return; + +trunc: + ND_PRINT((ndo, "%s", udp_tstr)); } @@ -707,4 +716,3 @@ udp_print(netdissect_options *ndo, register const u_char *bp, u_int length, * c-basic-offset: 8 * End: */ - diff --git a/contrib/tcpdump/print-usb.c b/contrib/tcpdump/print-usb.c index 75f78fc..04eb4ef 100644 --- a/contrib/tcpdump/print-usb.c +++ b/contrib/tcpdump/print-usb.c @@ -19,14 +19,15 @@ * */ -#define NETDISSECT_REWORKED +/* \summary: USB printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #if defined(HAVE_PCAP_USB_H) && defined(DLT_USB_LINUX) diff --git a/contrib/tcpdump/print-vjc.c b/contrib/tcpdump/print-vjc.c index 24f8a12..3287b9b 100644 --- a/contrib/tcpdump/print-vjc.c +++ b/contrib/tcpdump/print-vjc.c @@ -19,14 +19,17 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: PPP Van Jacobson compression printer */ + +/* specification: RFC 1144 */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "slcompress.h" #include "ppp.h" @@ -71,6 +74,13 @@ * We therefore leave "proto" - which is the PPP protocol type - in place, * *not* marked as unused, for now, so that GCC warnings about the * 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 + * 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_) @@ -96,7 +106,7 @@ vjc_print(netdissect_options *ndo, register const char *bp, u_short proto _U_) if (bp[1]) ND_PRINT((ndo, " ")); ND_PRINT((ndo, "C=0x%02x ", bp[2])); - ND_PRINT((ndo, "sum=0x%04x ", *(u_short *)&bp[3])); + ND_PRINT((ndo, "sum=0x%04x ", *(const u_short *)&bp[3])); return -1; case TYPE_ERROR: if (ndo->ndo_eflag) diff --git a/contrib/tcpdump/print-vqp.c b/contrib/tcpdump/print-vqp.c index ce3572a..44a2193 100644 --- a/contrib/tcpdump/print-vqp.c +++ b/contrib/tcpdump/print-vqp.c @@ -12,19 +12,18 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * support for the Cisco prop. VQP Protocol - * * Original code by Carles Kishimoto */ -#define NETDISSECT_REWORKED +/* \summary: Cisco VLAN Query Protocol (VQP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "addrtoname.h" diff --git a/contrib/tcpdump/print-vrrp.c b/contrib/tcpdump/print-vrrp.c index f739d1e..d8ba426 100644 --- a/contrib/tcpdump/print-vrrp.c +++ b/contrib/tcpdump/print-vrrp.c @@ -23,14 +23,15 @@ * FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: Virtual Router Redundancy Protocol (VRRP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "addrtoname.h" @@ -147,7 +148,7 @@ vrrp_print(netdissect_options *ndo, } if (version == 3 && ND_TTEST2(bp[0], len)) { - uint16_t cksum = nextproto4_cksum(ndo, (struct ip *)bp2, bp, + uint16_t cksum = nextproto4_cksum(ndo, (const struct ip *)bp2, bp, len, len, IPPROTO_VRRP); if (cksum) ND_PRINT((ndo, ", (bad vrrp cksum %x)", diff --git a/contrib/tcpdump/print-vtp.c b/contrib/tcpdump/print-vtp.c index 9fe86e3..285beb9 100644 --- a/contrib/tcpdump/print-vtp.c +++ b/contrib/tcpdump/print-vtp.c @@ -12,8 +12,6 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * VLAN TRUNKING PROTOCOL (VTP) - * * Reference documentation: * http://www.cisco.com/en/US/tech/tk389/tk689/technologies_tech_note09186a0080094c52.shtml * http://www.cisco.com/warp/public/473/21.html @@ -22,14 +20,15 @@ * Original code ode by Carles Kishimoto */ -#define NETDISSECT_REWORKED +/* \summary: Cisco VLAN Trunking Protocol (VTP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" @@ -121,7 +120,7 @@ void vtp_print (netdissect_options *ndo, const u_char *pptr, u_int length) { - int type, len, tlv_len, tlv_value; + int type, len, tlv_len, tlv_value, mgmtd_len; const u_char *tptr; const struct vtp_vlan_ *vtp_vlan; @@ -136,7 +135,7 @@ vtp_print (netdissect_options *ndo, ND_PRINT((ndo, "VTPv%u, Message %s (0x%02x), length %u", *tptr, tok2str(vtp_message_type_values,"Unknown message type", type), - *(tptr+1), + type, length)); /* In non-verbose mode, just print version and message type */ @@ -145,9 +144,15 @@ vtp_print (netdissect_options *ndo, } /* verbose mode print all fields */ - ND_PRINT((ndo, "\n\tDomain name: %s, %s: %u", - (tptr+4), - tok2str(vtp_header_values,"Unknown",*(tptr+1)), + 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; + } + fn_printzp(ndo, tptr + 4, mgmtd_len, NULL); + ND_PRINT((ndo, ", %s: %u", + tok2str(vtp_header_values, "Unknown", type), *(tptr+2))); tptr += VTP_HEADER_LEN; @@ -161,9 +166,9 @@ vtp_print (netdissect_options *ndo, * * 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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Version | Code | Followers | MmgtD Len | + * | Version | Code | Followers | MgmtD Len | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Management Domain Name | + * | Management Domain Name (zero-padded to 32 bytes) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Configuration revision number | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -176,15 +181,18 @@ 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))); 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))); 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), @@ -200,9 +208,9 @@ vtp_print (netdissect_options *ndo, * * 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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Version | Code | Seq number | MmgtD Len | + * | Version | Code | Seq number | MgmtD Len | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Management Domain Name | + * | Management Domain Name (zero-padded to 32 bytes) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Configuration revision number | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -241,14 +249,15 @@ vtp_print (netdissect_options *ndo, ND_TCHECK2(*tptr, len); - vtp_vlan = (struct vtp_vlan_*)tptr; - ND_PRINT((ndo, "\n\tVLAN info status %s, type %s, VLAN-id %u, MTU %u, SAID 0x%08x, Name %s", + vtp_vlan = (const struct vtp_vlan_*)tptr; + 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), - (tptr + VTP_VLAN_INFO_OFFSET))); + EXTRACT_32BITS(&vtp_vlan->index))); + fn_printzp(ndo, tptr + VTP_VLAN_INFO_OFFSET, vtp_vlan->name_len, NULL); /* * Vlan names are aligned to 32-bit boundaries. @@ -338,15 +347,16 @@ vtp_print (netdissect_options *ndo, * * 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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Version | Code | Reserved | MmgtD Len | + * | Version | Code | Reserved | MgmtD Len | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Management Domain Name | + * | Management Domain Name (zero-padded to 32 bytes) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Start value | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * */ + ND_TCHECK2(*tptr, 4); ND_PRINT((ndo, "\n\tStart value: %u", EXTRACT_32BITS(tptr))); break; diff --git a/contrib/tcpdump/print-vxlan-gpe.c b/contrib/tcpdump/print-vxlan-gpe.c new file mode 100644 index 0000000..6d170de --- /dev/null +++ b/contrib/tcpdump/print-vxlan-gpe.c @@ -0,0 +1,113 @@ +/* Copyright (c) 2015, bugyo + * 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 OWNER 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: Generic Protocol Extension for VXLAN (VXLAN GPE) printer */ + +/* specification: draft-ietf-nvo3-vxlan-gpe-01 */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "netdissect.h" +#include "extract.h" + +static const char tstr[] = " [|VXLAN-GPE]"; +static const struct tok vxlan_gpe_flags [] = { + { 0x08, "I" }, + { 0x04, "P" }, + { 0x01, "O" }, + { 0, NULL } +}; + +#define VXLAN_GPE_HDR_LEN 8 + +/* + * VXLAN GPE header, draft-ietf-nvo3-vxlan-gpe-01 + * Generic Protocol Extension for VXLAN + * + * 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|R|Ver|I|P|R|O| Reserved |Next Protocol | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | VXLAN Network Identifier (VNI) | Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +void +vxlan_gpe_print(netdissect_options *ndo, const u_char *bp, u_int len) +{ + uint8_t flags; + uint8_t next_protocol; + uint32_t vni; + + if (len < VXLAN_GPE_HDR_LEN) + goto trunc; + + ND_TCHECK2(*bp, VXLAN_GPE_HDR_LEN); + + flags = *bp; + bp += 3; + + next_protocol = *bp; + bp += 1; + + vni = EXTRACT_24BITS(bp); + bp += 4; + + 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 " : ": ")); + + switch (next_protocol) { + case 0x1: + ip_print(ndo, bp, len - 8); + break; + case 0x2: + ip6_print(ndo, bp, len - 8); + break; + case 0x3: + ether_print(ndo, bp, len - 8, ndo->ndo_snapend - bp, NULL, NULL); + break; + case 0x4: + nsh_print(ndo, bp, len - 8); + break; + case 0x5: + mpls_print(ndo, bp, len - 8); + break; + default: + ND_PRINT((ndo, "ERROR: unknown-next-protocol")); + return; + } + + return; + +trunc: + ND_PRINT((ndo, "%s", tstr)); +} + diff --git a/contrib/tcpdump/print-vxlan.c b/contrib/tcpdump/print-vxlan.c index c4de68d..0c2a82e 100644 --- a/contrib/tcpdump/print-vxlan.c +++ b/contrib/tcpdump/print-vxlan.c @@ -13,16 +13,23 @@ * Original code by Francesco Fondelli (francesco dot fondelli, gmail dot com) */ -#define NETDISSECT_REWORKED +/* \summary: Virtual eXtensible Local Area Network (VXLAN) printer */ + +/* specification: RFC 7348 */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" +static const char tstr[] = " [|VXLAN]"; + +#define VXLAN_HDR_LEN 8 + /* * VXLAN header, RFC7348 * Virtual eXtensible Local Area Network (VXLAN): A Framework @@ -43,10 +50,10 @@ vxlan_print(netdissect_options *ndo, const u_char *bp, u_int len) uint8_t flags; uint32_t vni; - if (len < 8) { - ND_PRINT((ndo, "[|VXLAN]")); - return; - } + if (len < VXLAN_HDR_LEN) + goto trunc; + + ND_TCHECK2(*bp, VXLAN_HDR_LEN); flags = *bp; bp += 4; @@ -58,5 +65,10 @@ vxlan_print(netdissect_options *ndo, const u_char *bp, u_int len) ND_PRINT((ndo, "flags [%s] (0x%02x), ", flags & 0x08 ? "I" : ".", flags)); ND_PRINT((ndo, "vni %u\n", vni)); - ether_print(ndo, bp, len - 8, len - 8, NULL, NULL); + ether_print(ndo, bp, len - VXLAN_HDR_LEN, ndo->ndo_snapend - bp, NULL, NULL); + + return; + +trunc: + ND_PRINT((ndo, "%s", tstr)); } diff --git a/contrib/tcpdump/print-wb.c b/contrib/tcpdump/print-wb.c index e10d532..88857d9 100644 --- a/contrib/tcpdump/print-wb.c +++ b/contrib/tcpdump/print-wb.c @@ -19,14 +19,15 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: White Board printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" @@ -48,8 +49,8 @@ static const char tstr[] = "[|wb]"; #define DOP_ALIGN 4 #define DOP_ROUNDUP(x) ((((int)(x)) + (DOP_ALIGN - 1)) & ~(DOP_ALIGN - 1)) #define DOP_NEXT(d)\ - ((struct dophdr *)((u_char *)(d) + \ - DOP_ROUNDUP(EXTRACT_16BITS(&(d)->dh_len) + sizeof(*(d))))) + ((const struct dophdr *)((const u_char *)(d) + \ + DOP_ROUNDUP(EXTRACT_16BITS(&(d)->dh_len) + sizeof(*(d))))) /* * Format of the whiteboard packet header. @@ -200,11 +201,11 @@ wb_id(netdissect_options *ndo, nid = EXTRACT_16BITS(&id->pi_ps.nid); len -= sizeof(*io) * nid; - io = (struct id_off *)(id + 1); - cp = (char *)(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, (u_char *)cp, (u_char *)cp + len); + fn_print(ndo, (const u_char *)cp, (const u_char *)cp + len); ND_PRINT((ndo, "\"")); } @@ -275,16 +276,16 @@ wb_prep(netdissect_options *ndo, EXTRACT_32BITS(&ps->slot), ipaddr_string(ndo, &ps->page.p_sid), EXTRACT_32BITS(&ps->page.p_uid))); - io = (struct id_off *)(ps + 1); + 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))); c = ','; } ND_PRINT((ndo, ">")); - ps = (struct pgstate *)io; + ps = (const struct pgstate *)io; } - return ((u_char *)ps <= ep? 0 : -1); + return ((const u_char *)ps <= ep? 0 : -1); } @@ -416,32 +417,32 @@ wb_print(netdissect_options *ndo, return; case PT_ID: - if (wb_id(ndo, (struct pkt_id *)(ph + 1), len) >= 0) + if (wb_id(ndo, (const struct pkt_id *)(ph + 1), len) >= 0) return; break; case PT_RREQ: - if (wb_rreq(ndo, (struct pkt_rreq *)(ph + 1), len) >= 0) + if (wb_rreq(ndo, (const struct pkt_rreq *)(ph + 1), len) >= 0) return; break; case PT_RREP: - if (wb_rrep(ndo, (struct pkt_rrep *)(ph + 1), len) >= 0) + if (wb_rrep(ndo, (const struct pkt_rrep *)(ph + 1), len) >= 0) return; break; case PT_DRAWOP: - if (wb_drawop(ndo, (struct pkt_dop *)(ph + 1), len) >= 0) + if (wb_drawop(ndo, (const struct pkt_dop *)(ph + 1), len) >= 0) return; break; case PT_PREQ: - if (wb_preq(ndo, (struct pkt_preq *)(ph + 1), len) >= 0) + if (wb_preq(ndo, (const struct pkt_preq *)(ph + 1), len) >= 0) return; break; case PT_PREP: - if (wb_prep(ndo, (struct pkt_prep *)(ph + 1), len) >= 0) + if (wb_prep(ndo, (const struct pkt_prep *)(ph + 1), len) >= 0) return; break; diff --git a/contrib/tcpdump/print-zephyr.c b/contrib/tcpdump/print-zephyr.c index 8132c49..38b0cd0 100644 --- a/contrib/tcpdump/print-zephyr.c +++ b/contrib/tcpdump/print-zephyr.c @@ -20,37 +20,38 @@ * PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: Zephyr printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include #include #include -#include "interface.h" +#include "netdissect.h" struct z_packet { - char *version; + const char *version; int numfields; int kind; - char *uid; + const char *uid; int port; int auth; int authlen; - char *authdata; - char *class; - char *inst; - char *opcode; - char *sender; + const char *authdata; + const char *class; + const char *inst; + const char *opcode; + const char *sender; const char *recipient; - char *format; + const char *format; int cksum; int multi; - char *multi_uid; + const char *multi_uid; /* Other fields follow here.. */ }; @@ -80,30 +81,30 @@ static const struct tok z_types[] = { static char z_buf[256]; -static char * -parse_field(netdissect_options *ndo, char **pptr, int *len) +static const char * +parse_field(netdissect_options *ndo, const char **pptr, int *len) { - char *s; + const char *s; if (*len <= 0 || !pptr || !*pptr) return NULL; - if (*pptr > (char *) ndo->ndo_snapend) + if (*pptr > (const char *) ndo->ndo_snapend) return NULL; s = *pptr; - while (*pptr <= (char *) ndo->ndo_snapend && *len >= 0 && **pptr) { + while (*pptr <= (const char *) ndo->ndo_snapend && *len >= 0 && **pptr) { (*pptr)++; (*len)--; } (*pptr)++; (*len)--; - if (*len < 0 || *pptr > (char *) ndo->ndo_snapend) + if (*len < 0 || *pptr > (const char *) ndo->ndo_snapend) return NULL; return s; } static const char * -z_triple(char *class, char *inst, const char *recipient) +z_triple(const char *class, const char *inst, const char *recipient) { if (!*recipient) recipient = "*"; @@ -113,15 +114,17 @@ z_triple(char *class, char *inst, const char *recipient) } static const char * -str_to_lower(char *string) +str_to_lower(const char *string) { + char *zb_string; + strncpy(z_buf, string, sizeof(z_buf)); z_buf[sizeof(z_buf)-1] = '\0'; - string = z_buf; - while (*string) { - *string = tolower((unsigned char)(*string)); - string++; + zb_string = z_buf; + while (*zb_string) { + *zb_string = tolower((unsigned char)(*zb_string)); + zb_string++; } return z_buf; @@ -131,9 +134,9 @@ void zephyr_print(netdissect_options *ndo, const u_char *cp, int length) { struct z_packet z; - char *parse = (char *) cp; + const char *parse = (const char *) cp; int parselen = length; - char *s; + const char *s; int lose = 0; /* squelch compiler warnings */ @@ -193,7 +196,7 @@ zephyr_print(netdissect_options *ndo, const u_char *cp, int length) ND_PRINT((ndo, " %s", tok2str(z_types, "type %d", z.kind))); if (z.kind == Z_PACKET_SERVACK) { /* Initialization to silence warnings */ - char *ackdata = NULL; + const char *ackdata = NULL; PARSE_FIELD_STR(ackdata); if (!lose && strcmp(ackdata, "SENT")) ND_PRINT((ndo, "/%s", str_to_lower(ackdata))); @@ -226,7 +229,7 @@ zephyr_print(netdissect_options *ndo, const u_char *cp, int length) "-nodefs")); if (z.kind != Z_PACKET_SERVACK) { /* Initialization to silence warnings */ - char *c = NULL, *i = NULL, *r = NULL; + const char *c = NULL, *i = NULL, *r = NULL; PARSE_FIELD_STR(c); PARSE_FIELD_STR(i); PARSE_FIELD_STR(r); diff --git a/contrib/tcpdump/print-zeromq.c b/contrib/tcpdump/print-zeromq.c index ba22c96..a23d98a 100644 --- a/contrib/tcpdump/print-zeromq.c +++ b/contrib/tcpdump/print-zeromq.c @@ -1,7 +1,4 @@ /* - * This file implements decoding of ZeroMQ network protocol(s). - * - * * Copyright (c) 2013 The TCPDUMP project * All rights reserved. * @@ -28,14 +25,15 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#define NETDISSECT_REWORKED +/* \summary: ZeroMQ Message Transport Protocol (ZMTP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" static const char tstr[] = " [|zmtp1]"; @@ -87,22 +85,18 @@ zmtp1_print_frame(netdissect_options *ndo, const u_char *cp, const u_char *ep) if (cp[0] != 0xFF) { header_len = 1; /* length */ body_len_declared = cp[0]; - if (body_len_declared == 0) - return cp + header_len; /* skip to next frame */ - ND_PRINT((ndo, " frame flags+body (8-bit) length %u", cp[0])); - ND_TCHECK2(*cp, header_len + 1); /* length, flags */ - flags = cp[1]; + ND_PRINT((ndo, " 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); - if (body_len_declared == 0) - return cp + header_len; /* skip to next frame */ ND_PRINT((ndo, " %" PRIu64, body_len_declared)); - ND_TCHECK2(*cp, header_len + 1); /* 0xFF, length, flags */ - flags = cp[9]; } + 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]; body_len_captured = ep - cp - header_len; if (body_len_declared > body_len_captured) @@ -131,8 +125,15 @@ zmtp1_print_frame(netdissect_options *ndo, const u_char *cp, const u_char *ep) } } - ND_TCHECK2(*cp, header_len + body_len_declared); /* Next frame within the buffer ? */ - return cp + header_len + body_len_declared; + /* + * Do not advance cp by the sum of header_len and body_len_declared + * before each offset has successfully passed ND_TCHECK2() 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 ? */ + return cp + body_len_declared; trunc: ND_PRINT((ndo, "%s", tstr)); diff --git a/contrib/tcpdump/print.c b/contrib/tcpdump/print.c new file mode 100644 index 0000000..41ca9ca --- /dev/null +++ b/contrib/tcpdump/print.c @@ -0,0 +1,484 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000 + * 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. + * + * Support for splitting captures into multiple files with a maximum + * file size: + * + * Copyright (c) 2001 + * Seth Webster + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include + +#include "netdissect.h" +#include "addrtoname.h" +#include "print.h" + +struct printer { + if_printer f; + int type; +}; + +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 }, +#endif +#ifdef DLT_IPV6 + { raw_if_print, DLT_IPV6 }, +#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 }, +#endif +#ifdef DLT_C_HDLC + { chdlc_if_print, DLT_C_HDLC }, +#endif +#ifdef DLT_HDLC + { chdlc_if_print, DLT_HDLC }, +#endif +#ifdef DLT_PPP_ETHER + { pppoe_if_print, DLT_PPP_ETHER }, +#endif +#if defined(DLT_PFLOG) && defined(HAVE_NET_IF_PFLOG_H) + { pflog_if_print, DLT_PFLOG }, +#endif + { token_if_print, DLT_IEEE802 }, + { fddi_if_print, DLT_FDDI }, +#ifdef DLT_LINUX_SLL + { sll_if_print, DLT_LINUX_SLL }, +#endif +#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 }, +#endif + { atm_if_print, DLT_ATM_RFC1483 }, +#ifdef DLT_SUNATM + { sunatm_if_print, DLT_SUNATM }, +#endif +#ifdef DLT_ENC + { enc_if_print, DLT_ENC }, +#endif + { sl_if_print, DLT_SLIP }, +#ifdef DLT_SLIP_BSDOS + { sl_bsdos_if_print, DLT_SLIP_BSDOS }, +#endif +#ifdef DLT_LTALK + { ltalk_if_print, DLT_LTALK }, +#endif +#ifdef DLT_JUNIPER_ATM1 + { juniper_atm1_print, DLT_JUNIPER_ATM1 }, +#endif +#ifdef DLT_JUNIPER_ATM2 + { juniper_atm2_print, DLT_JUNIPER_ATM2 }, +#endif +#ifdef DLT_JUNIPER_MFR + { juniper_mfr_print, DLT_JUNIPER_MFR }, +#endif +#ifdef DLT_JUNIPER_MLFR + { juniper_mlfr_print, DLT_JUNIPER_MLFR }, +#endif +#ifdef DLT_JUNIPER_MLPPP + { juniper_mlppp_print, DLT_JUNIPER_MLPPP }, +#endif +#ifdef DLT_JUNIPER_PPPOE + { juniper_pppoe_print, DLT_JUNIPER_PPPOE }, +#endif +#ifdef DLT_JUNIPER_PPPOE_ATM + { juniper_pppoe_atm_print, DLT_JUNIPER_PPPOE_ATM }, +#endif +#ifdef DLT_JUNIPER_GGSN + { juniper_ggsn_print, DLT_JUNIPER_GGSN }, +#endif +#ifdef DLT_JUNIPER_ES + { juniper_es_print, DLT_JUNIPER_ES }, +#endif +#ifdef DLT_JUNIPER_MONITOR + { juniper_monitor_print, DLT_JUNIPER_MONITOR }, +#endif +#ifdef DLT_JUNIPER_SERVICES + { juniper_services_print, DLT_JUNIPER_SERVICES }, +#endif +#ifdef DLT_JUNIPER_ETHER + { juniper_ether_print, DLT_JUNIPER_ETHER }, +#endif +#ifdef DLT_JUNIPER_PPP + { juniper_ppp_print, DLT_JUNIPER_PPP }, +#endif +#ifdef DLT_JUNIPER_FRELAY + { juniper_frelay_print, DLT_JUNIPER_FRELAY }, +#endif +#ifdef DLT_JUNIPER_CHDLC + { juniper_chdlc_print, DLT_JUNIPER_CHDLC }, +#endif +#ifdef DLT_PKTAP + { pktap_if_print, DLT_PKTAP }, +#endif +#ifdef DLT_IEEE802_11_RADIO + { ieee802_11_radio_if_print, DLT_IEEE802_11_RADIO }, +#endif +#ifdef DLT_IEEE802_11 + { ieee802_11_if_print, DLT_IEEE802_11}, +#endif +#ifdef DLT_IEEE802_11_RADIO_AVS + { ieee802_11_radio_avs_if_print, DLT_IEEE802_11_RADIO_AVS }, +#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 }, +#endif +#ifdef DLT_PPP_BSDOS + { ppp_bsdos_if_print, DLT_PPP_BSDOS }, +#endif +#ifdef DLT_PPP_SERIAL + { ppp_hdlc_if_print, DLT_PPP_SERIAL }, +#endif + { NULL, 0 }, +}; + +static void ndo_default_print(netdissect_options *ndo, const u_char *bp, + u_int length); + +static void ndo_error(netdissect_options *ndo, const char *fmt, ...) + __attribute__((noreturn)) +#ifdef __ATTRIBUTE___FORMAT_OK + __attribute__((format (printf, 2, 3))) +#endif /* __ATTRIBUTE___FORMAT_OK */ + ; +static void ndo_warning(netdissect_options *ndo, const char *fmt, ...) +#ifdef __ATTRIBUTE___FORMAT_OK + __attribute__((format (printf, 2, 3))) +#endif /* __ATTRIBUTE___FORMAT_OK */ + ; + +static int ndo_printf(netdissect_options *ndo, const char *fmt, ...) +#ifdef __ATTRIBUTE___FORMAT_OK + __attribute ((format (printf, 2, 3))) +#endif /* __ATTRIBUTE___FORMAT_OK */ + ; + +void +init_print(netdissect_options *ndo, uint32_t localnet, uint32_t mask, + uint32_t timezone_offset) +{ + + thiszone = timezone_offset; + init_addrtoname(ndo, localnet, mask); + init_checksum(); +} + +if_printer +lookup_printer(int type) +{ + const struct printer *p; + + for (p = printers; p->f; ++p) + if (type == p->type) + return p->f; + +#if defined(DLT_USER2) && defined(DLT_PKTAP) + /* + * Apple incorrectly chose to use DLT_USER2 for their PKTAP + * header. + * + * We map DLT_PKTAP, whether it's DLT_USER2 as it is on Darwin- + * based OSes or the same value as LINKTYPE_PKTAP as it is on + * other OSes, to LINKTYPE_PKTAP, so files written with + * this version of libpcap for a DLT_PKTAP capture have a link- + * layer header type of LINKTYPE_PKTAP. + * + * However, files written on OS X Mavericks for a DLT_PKTAP + * capture have a link-layer header type of LINKTYPE_USER2. + * If we don't have a printer for DLT_USER2, and type is + * DLT_USER2, we look up the printer for DLT_PKTAP and use + * that. + */ + if (type == DLT_USER2) { + for (p = printers; p->f; ++p) + if (DLT_PKTAP == p->type) + return p->f; + } +#endif + + return NULL; + /* NOTREACHED */ +} + +int +has_printer(int type) +{ + return (lookup_printer(type) != NULL); +} + +if_printer +get_if_printer(netdissect_options *ndo, 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); + } + return printer; +} + +void +pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h, + const u_char *sp, u_int packets_captured) +{ + u_int hdrlen; + + if(ndo->ndo_packet_number) + ND_PRINT((ndo, "%5u ", packets_captured)); + + ts_print(ndo, &h->ts); + + /* + * Some printers want to 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); + + /* + * Restore the original snapend, as a printer might have + * changed it. + */ + ndo->ndo_snapend = sp + h->caplen; + if (ndo->ndo_Xflag) { + /* + * Print the raw packet data in hex and ASCII. + */ + if (ndo->ndo_Xflag > 1) { + /* + * Include the link-layer header. + */ + hex_and_ascii_print(ndo, "\n\t", sp, h->caplen); + } else { + /* + * Don't include the link-layer header - and if + * we have nothing past the link-layer header, + * print nothing. + */ + if (h->caplen > hdrlen) + hex_and_ascii_print(ndo, "\n\t", sp + hdrlen, + h->caplen - hdrlen); + } + } else if (ndo->ndo_xflag) { + /* + * Print the raw packet data in hex. + */ + if (ndo->ndo_xflag > 1) { + /* + * Include the link-layer header. + */ + hex_print(ndo, "\n\t", sp, h->caplen); + } else { + /* + * Don't include the link-layer header - and if + * we have nothing past the link-layer header, + * print nothing. + */ + if (h->caplen > hdrlen) + hex_print(ndo, "\n\t", sp + hdrlen, + h->caplen - hdrlen); + } + } else if (ndo->ndo_Aflag) { + /* + * Print the raw packet data in ASCII. + */ + if (ndo->ndo_Aflag > 1) { + /* + * Include the link-layer header. + */ + ascii_print(ndo, sp, h->caplen); + } else { + /* + * Don't include the link-layer header - and if + * we have nothing past the link-layer header, + * print nothing. + */ + if (h->caplen > hdrlen) + ascii_print(ndo, sp + hdrlen, h->caplen - hdrlen); + } + } + + ND_PRINT((ndo, "\n")); +} + +/* + * By default, print the specified data out in hex and ASCII. + */ +static void +ndo_default_print(netdissect_options *ndo, const u_char *bp, u_int length) +{ + hex_and_ascii_print(ndo, "\n\t", bp, length); /* pass on lf and indentation string */ +} + +/* VARARGS */ +static void +ndo_error(netdissect_options *ndo, const char *fmt, ...) +{ + va_list ap; + + if(ndo->program_name) + (void)fprintf(stderr, "%s: ", ndo->program_name); + va_start(ap, fmt); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + if (*fmt) { + fmt += strlen(fmt); + if (fmt[-1] != '\n') + (void)fputc('\n', stderr); + } + nd_cleanup(); + exit(1); + /* NOTREACHED */ +} + +/* VARARGS */ +static void +ndo_warning(netdissect_options *ndo, const char *fmt, ...) +{ + va_list ap; + + if(ndo->program_name) + (void)fprintf(stderr, "%s: ", ndo->program_name); + (void)fprintf(stderr, "WARNING: "); + va_start(ap, fmt); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + if (*fmt) { + fmt += strlen(fmt); + if (fmt[-1] != '\n') + (void)fputc('\n', stderr); + } +} + +static int +ndo_printf(netdissect_options *ndo, const char *fmt, ...) +{ + va_list args; + int ret; + + va_start(args, fmt); + ret = vfprintf(stdout, fmt, args); + va_end(args); + + if (ret < 0) + ndo_error(ndo, "Unable to write output: %s", pcap_strerror(errno)); + return (ret); +} + +void +ndo_set_function_pointers(netdissect_options *ndo) +{ + ndo->ndo_default_print=ndo_default_print; + ndo->ndo_printf=ndo_printf; + 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 new file mode 100644 index 0000000..9632694 --- /dev/null +++ b/contrib/tcpdump/print.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000 + * 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. + * + * Support for splitting captures into multiple files with a maximum + * file size: + * + * Copyright (c) 2001 + * Seth Webster + */ + +#ifndef print_h +#define print_h + +void init_print(netdissect_options *ndo, uint32_t localnet, uint32_t mask, + uint32_t timezone_offset); + +int has_printer(int type); + +if_printer get_if_printer(netdissect_options *ndo, int type); + +void pretty_print_packet(netdissect_options *ndo, + const struct pcap_pkthdr *h, const u_char *sp, + u_int packets_captured); + +void ndo_set_function_pointers(netdissect_options *ndo); + +#endif /* print_h */ diff --git a/contrib/tcpdump/rpc_auth.h b/contrib/tcpdump/rpc_auth.h index 6dabb49..2069090 100644 --- a/contrib/tcpdump/rpc_auth.h +++ b/contrib/tcpdump/rpc_auth.h @@ -28,8 +28,7 @@ * * from: @(#)auth.h 1.17 88/02/08 SMI * from: @(#)auth.h 2.3 88/08/07 4.0 RPCSRC - * $FreeBSD$ - * FreeBSD: src/include/rpc/auth.h,v 1.14.2.1 1999/08/29 14:39:02 peter Exp + * $FreeBSD: stable/11/contrib/tcpdump/rpc_auth.h 276788 2015-01-07 19:55:18Z delphij $ */ /* diff --git a/contrib/tcpdump/rpc_msg.h b/contrib/tcpdump/rpc_msg.h index 35a191c..d906563 100644 --- a/contrib/tcpdump/rpc_msg.h +++ b/contrib/tcpdump/rpc_msg.h @@ -28,8 +28,7 @@ * * from: @(#)rpc_msg.h 1.7 86/07/16 SMI * from: @(#)rpc_msg.h 2.1 88/07/29 4.0 RPCSRC - * $FreeBSD$ - * FreeBSD: src/include/rpc/rpc_msg.h,v 1.11.2.1 1999/08/29 14:39:07 peter Exp + * $FreeBSD: stable/11/contrib/tcpdump/rpc_msg.h 276788 2015-01-07 19:55:18Z delphij $ */ /* diff --git a/contrib/tcpdump/rpl.h b/contrib/tcpdump/rpl.h index c48784b..5ad074b 100644 --- a/contrib/tcpdump/rpl.h +++ b/contrib/tcpdump/rpl.h @@ -22,7 +22,7 @@ enum ND_RPL_CODE { ND_RPL_SEC_DAG_IO = 0x81, ND_RPL_SEC_DAG = 0x82, ND_RPL_SEC_DAG_ACK= 0x83, - ND_RPL_SEC_CONSIST= 0x84, + ND_RPL_SEC_CONSIST= 0x8A }; enum ND_RPL_DIO_FLAGS { @@ -31,7 +31,7 @@ enum ND_RPL_DIO_FLAGS { ND_RPL_DIO_DASUPPORT= 0x20, ND_RPL_DIO_RES4 = 0x10, ND_RPL_DIO_RES3 = 0x08, - ND_RPL_DIO_PRF_MASK = 0x07, /* 3-bit preference */ + ND_RPL_DIO_PRF_MASK = 0x07 /* 3-bit preference */ }; #define DAGID_LEN 16 @@ -81,7 +81,7 @@ enum RPL_DIO_MOP { RPL_DIO_NONSTORING= 0x0, RPL_DIO_STORING = 0x1, RPL_DIO_NONSTORING_MULTICAST = 0x2, - RPL_DIO_STORING_MULTICAST = 0x3, + RPL_DIO_STORING_MULTICAST = 0x3 }; enum RPL_SUBOPT { @@ -93,7 +93,7 @@ enum RPL_SUBOPT { RPL_DAO_RPLTARGET = 5, RPL_DAO_TRANSITINFO = 6, RPL_DIO_DESTPREFIX = 8, - RPL_DAO_RPLTARGET_DESC=9, + RPL_DAO_RPLTARGET_DESC=9 }; struct rpl_dio_genoption { diff --git a/contrib/tcpdump/setsignal.c b/contrib/tcpdump/setsignal.c index 1bcc032..4d93ceb 100644 --- a/contrib/tcpdump/setsignal.c +++ b/contrib/tcpdump/setsignal.c @@ -23,7 +23,7 @@ #include "config.h" #endif -#include +#include #include #ifdef HAVE_SIGACTION diff --git a/contrib/tcpdump/signature.c b/contrib/tcpdump/signature.c index 324035f..1af798a 100644 --- a/contrib/tcpdump/signature.c +++ b/contrib/tcpdump/signature.c @@ -15,16 +15,16 @@ * Original code by Hannes Gredler (hannes@juniper.net) */ -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include +#include -#include "interface.h" +#include "netdissect.h" #include "signature.h" #ifdef HAVE_LIBCRYPTO @@ -34,6 +34,7 @@ const struct tok signature_check_values[] = { { SIGNATURE_VALID, "valid"}, { SIGNATURE_INVALID, "invalid"}, + { CANT_ALLOCATE_COPY, "can't allocate memory"}, { CANT_CHECK_SIGNATURE, "unchecked"}, { 0, NULL } }; @@ -108,39 +109,86 @@ signature_compute_hmac_md5(const uint8_t *text, int text_len, unsigned char *key MD5_Final(digest, &context); /* finish up 2nd pass */ } USES_APPLE_RST -#endif -#ifdef HAVE_LIBCRYPTO /* * Verify a cryptographic signature of the packet. * Currently only MD5 is supported. */ int -signature_verify(netdissect_options *ndo, - const u_char *pptr, u_int plen, u_char *sig_ptr) +signature_verify(netdissect_options *ndo, const u_char *pptr, u_int plen, + const u_char *sig_ptr, void (*clear_rtn)(void *), + const void *clear_arg) { - uint8_t rcvsig[16]; + uint8_t *packet_copy, *sig_copy; uint8_t sig[16]; unsigned int i; + if (!ndo->ndo_sigsecret) { + return (CANT_CHECK_SIGNATURE); + } + /* - * Save the signature before clearing it. + * Do we have all the packet data to be checked? */ - memcpy(rcvsig, sig_ptr, sizeof(rcvsig)); - memset(sig_ptr, 0, sizeof(rcvsig)); + if (!ND_TTEST2(pptr, plen)) { + /* No. */ + return (CANT_CHECK_SIGNATURE); + } - if (!ndo->ndo_sigsecret) { + /* + * Do we have the entire signature to check? + */ + if (!ND_TTEST2(sig_ptr, sizeof(sig))) { + /* No. */ return (CANT_CHECK_SIGNATURE); } + if (sig_ptr + sizeof(sig) > pptr + plen) { + /* No. */ + return (CANT_CHECK_SIGNATURE); + } + + /* + * Make a copy of the packet, so we don't overwrite the original. + */ + packet_copy = malloc(plen); + if (packet_copy == NULL) { + return (CANT_ALLOCATE_COPY); + } + + memcpy(packet_copy, pptr, plen); - signature_compute_hmac_md5(pptr, plen, (unsigned char *)ndo->ndo_sigsecret, + /* + * Clear the signature in the copy. + */ + sig_copy = packet_copy + (sig_ptr - pptr); + memset(sig_copy, 0, sizeof(sig)); + + /* + * Clear anything else that needs to be cleared in the copy. + * Our caller is assumed to have vetted the clear_arg pointer. + */ + (*clear_rtn)((void *)(packet_copy + ((const uint8_t *)clear_arg - pptr))); + + /* + * Compute the signature. + */ + signature_compute_hmac_md5(packet_copy, plen, + (unsigned char *)ndo->ndo_sigsecret, strlen(ndo->ndo_sigsecret), sig); - if (memcmp(rcvsig, sig, sizeof(sig)) == 0) { - return (SIGNATURE_VALID); + /* + * Free the copy. + */ + free(packet_copy); + /* + * Does the computed signature match the signature in the packet? + */ + if (memcmp(sig_ptr, sig, sizeof(sig)) == 0) { + /* Yes. */ + return (SIGNATURE_VALID); } else { - + /* No - print the computed signature. */ for (i = 0; i < sizeof(sig); ++i) { ND_PRINT((ndo, "%02x", sig[i])); } @@ -148,6 +196,14 @@ signature_verify(netdissect_options *ndo, return (SIGNATURE_INVALID); } } +#else +int +signature_verify(netdissect_options *ndo _U_, const u_char *pptr _U_, + u_int plen _U_, const u_char *sig_ptr _U_, + void (*clear_rtn)(void *) _U_, const void *clear_arg _U_) +{ + return (CANT_CHECK_SIGNATURE); +} #endif /* diff --git a/contrib/tcpdump/signature.h b/contrib/tcpdump/signature.h index a052df8..239ee3e 100644 --- a/contrib/tcpdump/signature.h +++ b/contrib/tcpdump/signature.h @@ -21,7 +21,9 @@ /* signature checking result codes */ #define SIGNATURE_VALID 0 #define SIGNATURE_INVALID 1 -#define CANT_CHECK_SIGNATURE 2 +#define CANT_ALLOCATE_COPY 2 +#define CANT_CHECK_SIGNATURE 3 extern const struct tok signature_check_values[]; -extern int signature_verify(netdissect_options *, const u_char *, u_int, u_char *); +extern int signature_verify(netdissect_options *, const u_char *, u_int, + const u_char *, void (*)(void *), const void *); diff --git a/contrib/tcpdump/smb.h b/contrib/tcpdump/smb.h index 88eaa06..b521617 100644 --- a/contrib/tcpdump/smb.h +++ b/contrib/tcpdump/smb.h @@ -116,7 +116,7 @@ #define TRANSACT2_FINDNOTIFYNEXT 12 #define TRANSACT2_MKDIR 13 -#define PTR_DIFF(p1, p2) ((size_t)(((char *)(p1)) - (char *)(p2))) +#define PTR_DIFF(p1, p2) ((size_t)(((const char *)(p1)) - (const char *)(p2))) /* some protos */ const u_char *smb_fdata(netdissect_options *, const u_char *, const char *, const u_char *, int); diff --git a/contrib/tcpdump/smbutil.c b/contrib/tcpdump/smbutil.c index 1c1742c..b38d73a 100644 --- a/contrib/tcpdump/smbutil.c +++ b/contrib/tcpdump/smbutil.c @@ -6,18 +6,17 @@ * or later */ -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include #include #include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "smb.h" @@ -272,8 +271,7 @@ name_type_str(int name_type) } void -print_data(netdissect_options *ndo, - const unsigned char *buf, int len) +smb_print_data(netdissect_options *ndo, const unsigned char *buf, int len) { int i = 0; @@ -861,7 +859,7 @@ smb_fdata(netdissect_options *ndo, if (!depth && buf < maxbuf) { size_t len = PTR_DIFF(maxbuf, buf); ND_PRINT((ndo, "Data: (%lu bytes)\n", (unsigned long)len)); - print_data(ndo, buf, len); + smb_print_data(ndo, buf, len); return(buf + len); } return(buf); diff --git a/contrib/tcpdump/strcasecmp.c b/contrib/tcpdump/strcasecmp.c deleted file mode 100644 index 7ee4e38..0000000 --- a/contrib/tcpdump/strcasecmp.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 1987 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that this notice is preserved and that due credit is given - * to the University of California at Berkeley. The name of the University - * may not be used to endorse or promote products derived from this - * software without specific written prior permission. This software - * is provided ``as is'' without express or implied warranty. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "interface.h" - -/* - * This array is designed for mapping upper and lower case letter - * together for a case independent comparison. The mappings are - * based upon ascii character sequences. - */ -static const u_char charmap[] = { - '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', - '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', - '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', - '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', - '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', - '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', - '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', - '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', - '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', - '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', - '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', - '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', - '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', - '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', - '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', - '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177', - '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207', - '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217', - '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227', - '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237', - '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247', - '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257', - '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267', - '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277', - '\300', '\341', '\342', '\343', '\344', '\345', '\346', '\347', - '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', - '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', - '\370', '\371', '\372', '\333', '\334', '\335', '\336', '\337', - '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347', - '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', - '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', - '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377', -}; - -int -strcasecmp(s1, s2) - const char *s1, *s2; -{ - register const u_char *cm = charmap, - *us1 = (u_char *)s1, - *us2 = (u_char *)s2; - - while (cm[*us1] == cm[*us2++]) - if (*us1++ == '\0') - return(0); - return(cm[*us1] - cm[*--us2]); -} - -int -strncasecmp(s1, s2, n) - const char *s1, *s2; - register int n; -{ - register const u_char *cm = charmap, - *us1 = (u_char *)s1, - *us2 = (u_char *)s2; - - while (--n >= 0 && cm[*us1] == cm[*us2++]) - if (*us1++ == '\0') - return(0); - return(n < 0 ? 0 : cm[*us1] - cm[*--us2]); -} diff --git a/contrib/tcpdump/strtoaddr.c b/contrib/tcpdump/strtoaddr.c new file mode 100644 index 0000000..81a041f --- /dev/null +++ b/contrib/tcpdump/strtoaddr.c @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1996,1999 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include "strtoaddr.h" + +#ifndef NS_INADDRSZ +#define NS_INADDRSZ 4 /* IPv4 T_A */ +#endif + +#ifndef NS_IN6ADDRSZ +#define NS_IN6ADDRSZ 16 /* IPv6 T_AAAA */ +#endif + +#ifndef NS_INT16SZ +#define NS_INT16SZ 2 /* #/bytes of data in a uint16_t */ +#endif + +/*% + * WARNING: Don't even consider trying to compile this on a system where + * 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. + * return: + * 1 if `src' is a valid input, else 0. + * notice: + * does not touch `dst' unless it's returning 1. + * author: + * Paul Vixie, 1996. + */ +int +strtoaddr(const char *src, void *dst) +{ + uint32_t val; + u_int digit; + ptrdiff_t n; + unsigned char c; + u_int parts[4]; + u_int *pp = parts; + + c = *src; + for (;;) { + /* + * Collect number up to ``.''. + * Values are specified as for C: + * 0x=hex, 0=octal, isdigit=decimal. + */ + if (!isdigit(c)) + return (0); + val = 0; + if (c == '0') { + c = *++src; + if (c == 'x' || c == 'X') + return (0); + else if (isdigit(c) && c != '9') + return (0); + } + for (;;) { + if (isdigit(c)) { + digit = c - '0'; + if (digit >= 10) + break; + val = (val * 10) + digit; + c = *++src; + } else + break; + } + if (c == '.') { + /* + * Internet format: + * a.b.c.d + * a.b.c (with c treated as 16 bits) + * a.b (with b treated as 24 bits) + * a (with a treated as 32 bits) + */ + if (pp >= parts + 3) + return (0); + *pp++ = val; + c = *++src; + } else + break; + } + /* + * Check for trailing characters. + */ + if (c != '\0' && !isspace(c)) + return (0); + /* + * Find the number of parts specified. + * It must be 4; we only support dotted quads, we don't + * support shorthand. + */ + n = pp - parts + 1; + if (n != 4) + return (0); + /* + * parts[0-2] were set to the first 3 parts of the address; + * val was set to the 4th part. + * + * Check if any part is bigger than 255. + */ + if ((parts[0] | parts[1] | parts[2] | val) > 0xff) + return (0); + /* + * Add the other three parts to val. + */ + val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); + if (dst) { + val = htonl(val); + memcpy(dst, &val, NS_INADDRSZ); + } + return (1); +} + +/* int + * strtoaddr6(src, dst) + * convert presentation level IPv6 address to network order binary form. + * return: + * 1 if `src' is a valid [RFC1884 2.2] address, else 0. + * notice: + * (1) does not touch `dst' unless it's returning 1. + * (2) :: in a full address is silently ignored. + * credit: + * inspired by Mark Andrews. + * author: + * Paul Vixie, 1996. + */ +int +strtoaddr6(const char *src, void *dst) +{ + static const char xdigits_l[] = "0123456789abcdef", + xdigits_u[] = "0123456789ABCDEF"; + u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; + const char *xdigits, *curtok; + int ch, seen_xdigits; + u_int val; + + memset((tp = tmp), '\0', NS_IN6ADDRSZ); + endp = tp + NS_IN6ADDRSZ; + colonp = NULL; + /* Leading :: requires some special handling. */ + if (*src == ':') + if (*++src != ':') + return (0); + curtok = src; + seen_xdigits = 0; + val = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) + pch = strchr((xdigits = xdigits_u), ch); + if (pch != NULL) { + val <<= 4; + val |= (int)(pch - xdigits); + if (++seen_xdigits > 4) + return (0); + continue; + } + if (ch == ':') { + curtok = src; + if (!seen_xdigits) { + if (colonp) + return (0); + colonp = tp; + continue; + } else if (*src == '\0') + return (0); + if (tp + NS_INT16SZ > endp) + return (0); + *tp++ = (u_char) (val >> 8) & 0xff; + *tp++ = (u_char) val & 0xff; + seen_xdigits = 0; + val = 0; + continue; + } + if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && + strtoaddr(curtok, tp) > 0) { + tp += NS_INADDRSZ; + seen_xdigits = 0; + break; /*%< '\\0' was seen by strtoaddr(). */ + } + return (0); + } + if (seen_xdigits) { + if (tp + NS_INT16SZ > endp) + return (0); + *tp++ = (u_char) (val >> 8) & 0xff; + *tp++ = (u_char) val & 0xff; + } + if (colonp != NULL) { + /* + * Since some memmove()'s erroneously fail to handle + * overlapping regions, we'll do the shift by hand. + */ + const ptrdiff_t n = tp - colonp; + int i; + + if (tp == endp) + return (0); + for (i = 1; i <= n; i++) { + endp[- i] = colonp[n - i]; + colonp[n - i] = 0; + } + tp = endp; + } + if (tp != endp) + return (0); + memcpy(dst, tmp, NS_IN6ADDRSZ); + return (1); +} diff --git a/contrib/tcpdump/strtoaddr.h b/contrib/tcpdump/strtoaddr.h new file mode 100644 index 0000000..8bd22c7 --- /dev/null +++ b/contrib/tcpdump/strtoaddr.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1996,1999 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* Text string to address translation routines. */ + +int strtoaddr(const char *src, void *dst); +int strtoaddr6(const char *src, void *dst); + + diff --git a/contrib/tcpdump/tcp.h b/contrib/tcpdump/tcp.h index c18d138..912b5e8 100644 --- a/contrib/tcpdump/tcp.h +++ b/contrib/tcpdump/tcp.h @@ -81,56 +81,80 @@ struct tcphdr { #define TCPOPT_SIGNATURE 19 /* Keyed MD5 (rfc2385) */ #define TCPOLEN_SIGNATURE 18 #define TCP_SIGLEN 16 /* length of an option 19 digest */ -#define TCPOPT_AUTH 20 /* Enhanced AUTH option */ +#define TCPOPT_SCPS 20 /* SCPS-TP (CCSDS 714.0-B-2) */ #define TCPOPT_UTO 28 /* tcp user timeout (rfc5482) */ #define TCPOLEN_UTO 4 +#define TCPOPT_TCPAO 29 /* TCP authentication option (rfc5925) */ #define TCPOPT_MPTCP 30 /* MPTCP options */ +#define TCPOPT_FASTOPEN 34 /* TCP Fast Open (rfc7413) */ #define TCPOPT_EXPERIMENT2 254 /* experimental headers (rfc4727) */ #define TCPOPT_TSTAMP_HDR \ (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP) +#ifndef FTP_PORT +#define FTP_PORT 21 +#endif +#ifndef SSH_PORT +#define SSH_PORT 22 +#endif #ifndef TELNET_PORT -#define TELNET_PORT 23 +#define TELNET_PORT 23 #endif #ifndef SMTP_PORT #define SMTP_PORT 25 #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 #ifndef BGP_PORT -#define BGP_PORT 179 +#define BGP_PORT 179 #endif -#define NETBIOS_SSN_PORT 139 -#ifndef OPENFLOW_PORT_OLD -#define OPENFLOW_PORT_OLD 6633 +#ifndef RPKI_RTR_PORT +#define RPKI_RTR_PORT 323 #endif -#ifndef OPENFLOW_PORT_IANA -#define OPENFLOW_PORT_IANA 6653 +#ifndef SMB_PORT +#define SMB_PORT 445 +#endif +#ifndef RTSP_PORT +#define RTSP_PORT 554 +#endif +#ifndef MSDP_PORT +#define MSDP_PORT 639 +#endif +#ifndef LDP_PORT +#define LDP_PORT 646 #endif #ifndef PPTP_PORT -#define PPTP_PORT 1723 +#define PPTP_PORT 1723 #endif -#define BEEP_PORT 10288 #ifndef NFS_PORT -#define NFS_PORT 2049 +#define NFS_PORT 2049 #endif -#define MSDP_PORT 639 -#define RPKI_RTR_PORT 323 -#define LDP_PORT 646 -#ifndef SMB_PORT -#define SMB_PORT 445 +#ifndef OPENFLOW_PORT_OLD +#define OPENFLOW_PORT_OLD 6633 #endif -#ifndef HTTP_PORT -#define HTTP_PORT 80 +#ifndef OPENFLOW_PORT_IANA +#define OPENFLOW_PORT_IANA 6653 #endif #ifndef HTTP_PORT_ALT #define HTTP_PORT_ALT 8080 #endif -#ifndef RTSP_PORT -#define RTSP_PORT 554 -#endif #ifndef RTSP_PORT_ALT #define RTSP_PORT_ALT 8554 #endif -#ifndef FTP_PORT -#define FTP_PORT 21 +#ifndef BEEP_PORT +#define BEEP_PORT 10288 +#endif +#ifndef REDIS_PORT +#define REDIS_PORT 6379 #endif diff --git a/contrib/tcpdump/tcpdump-stdinc.h b/contrib/tcpdump/tcpdump-stdinc.h deleted file mode 100644 index 32f8fc9..0000000 --- a/contrib/tcpdump/tcpdump-stdinc.h +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright (c) 2002 - 2003 - * NetGroup, Politecnico di Torino (Italy) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Politecnico di Torino 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 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 - * OWNER 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. - */ - -/* - * Include the appropriate OS header files on Windows and various flavors - * of UNIX, include various non-OS header files on Windows, and define - * various items as needed, to isolate most of tcpdump's platform - * differences to this one file. - */ - -#ifndef tcpdump_stdinc_h -#define tcpdump_stdinc_h - -#include - -#ifdef WIN32 - -#include -#include -#include -#include -#include "bittypes.h" /* in wpcap's Win32/include */ -#include -#include -#include -#include -#include -#include /* in wpcap's Win32/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 - -#ifndef PRIx64 -#define PRIx64 "llx" -#endif - -#endif /* _MSC_EXTENSIONS */ - -#ifdef _MSC_VER -#define stat _stat -#define open _open -#define fstat _fstat -#define read _read -#define close _close -#define O_RDONLY _O_RDONLY -#endif /* _MSC_VER */ - -/* Protos for missing/x.c functions (ideally - * should be used, but it clashes with ). - */ -extern const char *inet_ntop (int, const void *, char *, size_t); -extern int inet_pton (int, const char *, void *); -extern int inet_aton (const char *cp, struct in_addr *addr); - -/* - * With MSVC, for C, __inline is used to make a function an inline. - */ -#ifdef _MSC_VER -#define inline __inline -#endif - -#ifndef INET6_ADDRSTRLEN -#define INET6_ADDRSTRLEN 46 -#endif - -/* It is in MSVC's , but not defined in MingW+Watcom. - */ -#ifndef EAFNOSUPPORT -#define EAFNOSUPPORT WSAEAFNOSUPPORT -#endif - -#ifndef caddr_t -typedef char* caddr_t; -#endif /* caddr_t */ - -#define MAXHOSTNAMELEN 64 -#define NI_MAXHOST 1025 -#define snprintf _snprintf -#define vsnprintf _vsnprintf -#define RETSIGTYPE void - -#else /* WIN32 */ - -#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 */ - -#ifndef HAVE___ATTRIBUTE__ -#define __attribute__(x) -#endif - -/* - * Used to declare a structure unaligned, so that the C compiler, - * if necessary, generates code that doesn't assume alignment. - * This is required because there is no guarantee that the packet - * data we get from libpcap/WinPcap is properly aligned. - * - * This assumes that, for all compilers that support __attribute__: - * - * 1) they support __attribute__((packed)); - * - * 2) for all instruction set architectures requiring strict - * alignment, declaring a structure with that attribute - * causes the compiler to generate code that handles - * misaligned 2-byte, 4-byte, and 8-byte integral - * quantities. - * - * It does not (yet) handle compilers where you can get the compiler - * to generate code of that sort by some other means. - * - * This is required in order to, for example, keep the compiler from - * generating, for - * - * if (bp->bp_htype == 1 && bp->bp_hlen == 6 && bp->bp_op == BOOTPREQUEST) { - * - * in print-bootp.c, code that loads the first 4-byte word of a - * "struct bootp", masking out the bp_hops field, and comparing the result - * against 0x01010600. - * - * Note: this also requires that padding be put into the structure, - * at least for compilers where it's implemented as __attribute__((packed)). - */ -#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 - -#if defined(WIN32) || defined(MSDOS) - #define FOPEN_READ_TXT "rt" - #define FOPEN_READ_BIN "rb" - #define FOPEN_WRITE_TXT "wt" - #define FOPEN_WRITE_BIN "wb" -#else - #define FOPEN_READ_TXT "r" - #define FOPEN_READ_BIN FOPEN_READ_TXT - #define FOPEN_WRITE_TXT "w" - #define FOPEN_WRITE_BIN FOPEN_WRITE_TXT -#endif - -#if defined(__GNUC__) && defined(__i386__) && !defined(__APPLE__) && !defined(__ntohl) - #undef ntohl - #undef ntohs - #undef htonl - #undef htons - - static __inline__ unsigned long __ntohl (unsigned long x); - static __inline__ unsigned short __ntohs (unsigned short x); - - #define ntohl(x) __ntohl(x) - #define ntohs(x) __ntohs(x) - #define htonl(x) __ntohl(x) - #define htons(x) __ntohs(x) - - static __inline__ unsigned long __ntohl (unsigned long x) - { - __asm__ ("xchgb %b0, %h0\n\t" /* swap lower bytes */ - "rorl $16, %0\n\t" /* swap words */ - "xchgb %b0, %h0" /* swap higher bytes */ - : "=q" (x) : "0" (x)); - return (x); - } - - static __inline__ unsigned short __ntohs (unsigned short x) - { - __asm__ ("xchgb %b0, %h0" /* swap bytes */ - : "=q" (x) : "0" (x)); - return (x); - } -#endif - -#ifndef INET_ADDRSTRLEN -#define INET_ADDRSTRLEN 16 -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -/* - * The Apple deprecation workaround macros below were adopted from the - * FreeRADIUS server code under permission of Alan DeKok and Arran Cudbard-Bell. - */ - -#define XSTRINGIFY(x) #x - -/* - * Macros for controlling warnings in GCC >= 4.2 and clang >= 2.8 - */ -#define DIAG_JOINSTR(x,y) XSTRINGIFY(x ## y) -#define DIAG_DO_PRAGMA(x) _Pragma (#x) - -#if 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)) -# define DIAG_ON(x) DIAG_PRAGMA(pop) -# else -# 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 - -/* - * For dealing with APIs which are only deprecated in OSX (like the OpenSSL API) - */ -#ifdef __APPLE__ -# define USES_APPLE_DEPRECATED_API DIAG_OFF(deprecated-declarations) -# define USES_APPLE_RST DIAG_ON(deprecated-declarations) -#else -# define USES_APPLE_DEPRECATED_API -# define USES_APPLE_RST -#endif - -/* - * end of Apple deprecation workaround macros - */ - -#ifndef min -#define min(a,b) ((a)>(b)?(b):(a)) -#endif -#ifndef max -#define max(a,b) ((b)>(a)?(b):(a)) -#endif - -#endif /* tcpdump_stdinc_h */ diff --git a/contrib/tcpdump/tcpdump.1.in b/contrib/tcpdump/tcpdump.1.in index f9522cb..f04a579 100644 --- a/contrib/tcpdump/tcpdump.1.in +++ b/contrib/tcpdump/tcpdump.1.in @@ -20,14 +20,14 @@ .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. .\" -.TH TCPDUMP 1 "11 July 2014" +.TH TCPDUMP 1 "17 September 2015" .SH NAME tcpdump \- dump traffic on a network .SH SYNOPSIS .na .B tcpdump [ -.B \-AbdDefhHIJKlLnNOpqRStuUvxX# +.B \-AbdDefhHIJKlLnNOpqStuUvxX# ] [ .B \-B .I buffer_size @@ -400,7 +400,7 @@ If the flag is supported, an interface number as printed by that flag can be used as the .I interface -argument. +argument, if no interface on the system has that number as a name. .TP .B \-I .PD 0 @@ -593,12 +593,6 @@ Quick (quiet?) output. Print less protocol information so output lines are shorter. .TP -.B \-R -Assume ESP/AH packets to be based on old specification (RFC1825 to RFC1829). -If specified, \fItcpdump\fP will not print replay prevention field. -Since there is no protocol version field in ESP/AH specification, -\fItcpdump\fP cannot deduce the version of ESP/AH protocol. -.TP .BI \-r " file" Read packets from \fIfile\fR (which was created with the .B \-w @@ -618,7 +612,7 @@ Print absolute, rather than relative, TCP sequence numbers. .BI \-\-snapshot\-length= snaplen .PD Snarf \fIsnaplen\fP bytes of data from each packet rather than the -default of 65535 bytes. +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. @@ -630,7 +624,7 @@ lost. You should limit \fIsnaplen\fP to the smallest number that will capture the protocol information you're interested in. Setting -\fIsnaplen\fP to 0 sets it to the default of 65535, +\fIsnaplen\fP to 0 sets it to the default of 262144, for backwards compatibility with recent older versions of .IR tcpdump . .TP @@ -644,6 +638,7 @@ Currently known types are \fBlmp\fR (Link Management Protocol), \fBpgm\fR (Pragmatic General Multicast), \fBpgm_zmtp1\fR (ZMTP/1.0 inside PGM/EPGM), +\fBresp\fR (REdis Serialization Protocol), \fBradius\fR (RADIUS), \fBrpc\fR (Remote Procedure Call), \fBrtp\fR (Real-Time Applications protocol), @@ -1882,11 +1877,15 @@ is the current clock time in the form .fi .RE and is as accurate as the kernel's clock. -The timestamp reflects the time the kernel first saw the packet. -No attempt -is made to account for the time lag between when the -Ethernet interface removed the packet from the wire and when the kernel -serviced the `new packet' interrupt. +The timestamp reflects the time the kernel applied a time stamp to the packet. +No attempt is made to account for the time lag between when the network +interface finished receiving the packet from the network and when the +kernel applied a time stamp to the packet; that time lag could include a +delay between the time when the network interface finished receiving a +packet from the network and the time when an interrupt was delivered to +the kernel to get it to read the packet and a delay between the time +when the kernel serviced the `new packet' interrupt and the time when it +applied a time stamp to the packet. .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@) diff --git a/contrib/tcpdump/tcpdump.c b/contrib/tcpdump/tcpdump.c index 2bec0b8..202dce2 100644 --- a/contrib/tcpdump/tcpdump.c +++ b/contrib/tcpdump/tcpdump.c @@ -31,10 +31,8 @@ static const char copyright[] _U_ = The Regents of the University of California. All rights reserved.\n"; #endif -/* $FreeBSD$ */ - /* - * tcpdump - monitor tcp/ip traffic on an ethernet. + * tcpdump - dump traffic on a network * * First written in 1987 by Van Jacobson, Lawrence Berkeley Laboratory. * Mercilessly hacked and occasionally improved since then via the @@ -56,18 +54,12 @@ The Regents of the University of California. All rights reserved.\n"; #endif #endif -#include +#include -#ifdef WIN32 -#include "w32_fzs.h" -extern int strcasecmp (const char *__s1, const char *__s2); -extern int SIZE_BUF; -#define off_t long -#define uint UINT -#endif /* WIN32 */ +#include -#ifdef USE_LIBSMI -#include +#ifdef HAVE_FCNTL_H +#include #endif #ifdef HAVE_LIBCRYPTO @@ -83,32 +75,31 @@ extern int SIZE_BUF; * to compile if has already been included; including the headers * in the opposite order works fine. */ -#ifdef __FreeBSD__ +#ifdef HAVE_CAPSICUM #include #include +#include +#include +#include #include -#endif /* __FreeBSD__ */ #ifdef HAVE_CASPER #include #include -#include -#include -#include -#include -#include #endif /* HAVE_CASPER */ +#endif /* HAVE_CAPSICUM */ #include #include #include +#include #include #include #include -#ifndef WIN32 +#ifndef _WIN32 #include #include #include #include -#endif /* WIN32 */ +#endif /* _WIN32 */ /* capabilities convenience library */ /* If a code depends on HAVE_LIBCAP_NG, it depends also on HAVE_CAP_NG_H. @@ -130,6 +121,9 @@ extern int SIZE_BUF; #include "setsignal.h" #include "gmt2local.h" #include "pcap-missing.h" +#include "ascii_strcasecmp.h" + +#include "print.h" #ifndef PATH_MAX #define PATH_MAX 1024 @@ -141,19 +135,41 @@ extern int SIZE_BUF; #define SIGNAL_REQ_INFO SIGUSR1 #endif -netdissect_options Gndo; -netdissect_options *gndo = &Gndo; - +static int Bflag; /* buffer size */ +static int Cflag; /* rotate dump files after this many bytes */ +static int Cflag_count; /* Keep track of which file number we're writing */ static int Dflag; /* list available devices and exit */ -static int dflag; /* print filter code */ +/* + * This is exported because, in some versions of libpcap, if libpcap + * is built with optimizer debugging code (which is *NOT* the default + * configuration!), the library *imports*(!) a variable named dflag, + * under the expectation that tcpdump is exporting it, to govern + * how much debugging information to print when optimizing + * the generated BPF code. + * + * This is a horrible hack; newer versions of libpcap don't import + * dflag but, instead, *if* built with optimizer debugging code, + * *export* a routine to set that flag. + */ +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 */ +static time_t Gflag_time; /* The last time_t the dump file was rotated. */ 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 */ +static int pflag; /* don't go promiscuous */ #ifdef HAVE_PCAP_SETDIRECTION -int Qflag = -1; /* restrict captured packet by send/receive direction */ +static int Qflag = -1; /* restrict captured packet by send/receive direction */ #endif +static int Uflag; /* "unbuffered" output of dump files */ +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 immediate_mode; static int infodelay; static int infoprint; @@ -164,31 +180,33 @@ char *program_name; cap_channel_t *capdns; #endif -int32_t thiszone; /* seconds offset from gmt to local time */ - /* Forwards */ +static void error(const char *, ...) + __attribute__((noreturn)) +#ifdef __ATTRIBUTE___FORMAT_OK + __attribute__((format (printf, 1, 2))) +#endif /* __ATTRIBUTE___FORMAT_OK */ + ; +static void warning(const char *, ...) +#ifdef __ATTRIBUTE___FORMAT_OK + __attribute__((format (printf, 1, 2))) +#endif /* __ATTRIBUTE___FORMAT_OK */ + ; +static void exit_tcpdump(int) __attribute__((noreturn)); static RETSIGTYPE cleanup(int); static RETSIGTYPE child_cleanup(int); static void print_version(void); static void print_usage(void); -static void show_dlts_and_exit(const char *device, pcap_t *pd) __attribute__((noreturn)); +static void show_tstamp_types_and_exit(pcap_t *, const char *device) __attribute__((noreturn)); +static void show_dlts_and_exit(pcap_t *, const char *device) __attribute__((noreturn)); +#ifdef HAVE_PCAP_FINDALLDEVS +static void show_devices_and_exit (void) __attribute__((noreturn)); +#endif static void print_packet(u_char *, const struct pcap_pkthdr *, const u_char *); -static void ndo_default_print(netdissect_options *, const u_char *, u_int); static void dump_packet_and_trunc(u_char *, const struct pcap_pkthdr *, const u_char *); static void dump_packet(u_char *, const struct pcap_pkthdr *, const u_char *); static void droproot(const char *, const char *); -static void ndo_error(netdissect_options *ndo, const char *fmt, ...) - __attribute__((noreturn)) -#ifdef __ATTRIBUTE___FORMAT_OK - __attribute__((format (printf, 2, 3))) -#endif /* __ATTRIBUTE___FORMAT_OK */ - ; -static void ndo_warning(netdissect_options *ndo, const char *fmt, ...) -#ifdef __ATTRIBUTE___FORMAT_OK - __attribute__((format (printf, 2, 3))) -#endif /* __ATTRIBUTE___FORMAT_OK */ - ; #ifdef SIGNAL_REQ_INFO RETSIGTYPE requestinfo(int); @@ -205,202 +223,7 @@ RETSIGTYPE requestinfo(int); static void info(int); static u_int packets_captured; -struct printer { - if_printer f; - int type; -}; - - -struct ndo_printer { - if_ndo_printer f; - int type; -}; - - -static const struct printer printers[] = { - { NULL, 0 }, -}; - -static const struct ndo_printer ndo_printers[] = { - { ether_if_print, DLT_EN10MB }, -#ifdef DLT_IPNET - { ipnet_if_print, DLT_IPNET }, -#endif -#ifdef DLT_IEEE802_15_4 - { ieee802_15_4_if_print, DLT_IEEE802_15_4 }, -#endif -#ifdef DLT_IEEE802_15_4_NOFCS - { ieee802_15_4_if_print, DLT_IEEE802_15_4_NOFCS }, -#endif -#ifdef DLT_PPI - { ppi_if_print, DLT_PPI }, -#endif -#ifdef DLT_NETANALYZER - { netanalyzer_if_print, DLT_NETANALYZER }, -#endif -#ifdef DLT_NETANALYZER_TRANSPARENT - { netanalyzer_transparent_if_print, DLT_NETANALYZER_TRANSPARENT }, -#endif -#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 }, -#endif -#ifdef DLT_IPV6 - { raw_if_print, DLT_IPV6 }, -#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 }, -#endif -#ifdef DLT_C_HDLC - { chdlc_if_print, DLT_C_HDLC }, -#endif -#ifdef DLT_HDLC - { chdlc_if_print, DLT_HDLC }, -#endif -#ifdef DLT_PPP_ETHER - { pppoe_if_print, DLT_PPP_ETHER }, -#endif -#if defined(DLT_PFLOG) && defined(HAVE_NET_PFVAR_H) - { pflog_if_print, DLT_PFLOG }, -#endif - { token_if_print, DLT_IEEE802 }, - { fddi_if_print, DLT_FDDI }, -#ifdef DLT_LINUX_SLL - { sll_if_print, DLT_LINUX_SLL }, -#endif -#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 }, -#endif - { atm_if_print, DLT_ATM_RFC1483 }, -#ifdef DLT_SUNATM - { sunatm_if_print, DLT_SUNATM }, -#endif -#ifdef DLT_ENC - { enc_if_print, DLT_ENC }, -#endif - { sl_if_print, DLT_SLIP }, -#ifdef DLT_SLIP_BSDOS - { sl_bsdos_if_print, DLT_SLIP_BSDOS }, -#endif -#ifdef DLT_LTALK - { ltalk_if_print, DLT_LTALK }, -#endif -#ifdef DLT_JUNIPER_ATM1 - { juniper_atm1_print, DLT_JUNIPER_ATM1 }, -#endif -#ifdef DLT_JUNIPER_ATM2 - { juniper_atm2_print, DLT_JUNIPER_ATM2 }, -#endif -#ifdef DLT_JUNIPER_MFR - { juniper_mfr_print, DLT_JUNIPER_MFR }, -#endif -#ifdef DLT_JUNIPER_MLFR - { juniper_mlfr_print, DLT_JUNIPER_MLFR }, -#endif -#ifdef DLT_JUNIPER_MLPPP - { juniper_mlppp_print, DLT_JUNIPER_MLPPP }, -#endif -#ifdef DLT_JUNIPER_PPPOE - { juniper_pppoe_print, DLT_JUNIPER_PPPOE }, -#endif -#ifdef DLT_JUNIPER_PPPOE_ATM - { juniper_pppoe_atm_print, DLT_JUNIPER_PPPOE_ATM }, -#endif -#ifdef DLT_JUNIPER_GGSN - { juniper_ggsn_print, DLT_JUNIPER_GGSN }, -#endif -#ifdef DLT_JUNIPER_ES - { juniper_es_print, DLT_JUNIPER_ES }, -#endif -#ifdef DLT_JUNIPER_MONITOR - { juniper_monitor_print, DLT_JUNIPER_MONITOR }, -#endif -#ifdef DLT_JUNIPER_SERVICES - { juniper_services_print, DLT_JUNIPER_SERVICES }, -#endif -#ifdef DLT_JUNIPER_ETHER - { juniper_ether_print, DLT_JUNIPER_ETHER }, -#endif -#ifdef DLT_JUNIPER_PPP - { juniper_ppp_print, DLT_JUNIPER_PPP }, -#endif -#ifdef DLT_JUNIPER_FRELAY - { juniper_frelay_print, DLT_JUNIPER_FRELAY }, -#endif -#ifdef DLT_JUNIPER_CHDLC - { juniper_chdlc_print, DLT_JUNIPER_CHDLC }, -#endif -#ifdef DLT_PKTAP - { pktap_if_print, DLT_PKTAP }, -#endif -#ifdef DLT_IEEE802_11_RADIO - { ieee802_11_radio_if_print, DLT_IEEE802_11_RADIO }, -#endif -#ifdef DLT_IEEE802_11 - { ieee802_11_if_print, DLT_IEEE802_11}, -#endif -#ifdef DLT_IEEE802_11_RADIO_AVS - { ieee802_11_radio_avs_if_print, DLT_IEEE802_11_RADIO_AVS }, -#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 }, -#endif -#ifdef DLT_PPP_BSDOS - { ppp_bsdos_if_print, DLT_PPP_BSDOS }, -#endif -#ifdef DLT_PPP_SERIAL - { ppp_hdlc_if_print, DLT_PPP_SERIAL }, -#endif - { NULL, 0 }, -}; - +#ifdef HAVE_PCAP_FINDALLDEVS static const struct tok status_flags[] = { #ifdef PCAP_IF_UP { PCAP_IF_UP, "Up" }, @@ -411,57 +234,8 @@ static const struct tok status_flags[] = { { PCAP_IF_LOOPBACK, "Loopback" }, { 0, NULL } }; - -if_printer -lookup_printer(int type) -{ - const struct printer *p; - - for (p = printers; p->f; ++p) - if (type == p->type) - return p->f; - - return NULL; - /* NOTREACHED */ -} - -if_ndo_printer -lookup_ndo_printer(int type) -{ - const struct ndo_printer *p; - - for (p = ndo_printers; p->f; ++p) - if (type == p->type) - return p->f; - -#if defined(DLT_USER2) && defined(DLT_PKTAP) - /* - * Apple incorrectly chose to use DLT_USER2 for their PKTAP - * header. - * - * We map DLT_PKTAP, whether it's DLT_USER2 as it is on Darwin- - * based OSes or the same value as LINKTYPE_PKTAP as it is on - * other OSes, to LINKTYPE_PKTAP, so files written with - * this version of libpcap for a DLT_PKTAP capture have a link- - * layer header type of LINKTYPE_PKTAP. - * - * However, files written on OS X Mavericks for a DLT_PKTAP - * capture have a link-layer header type of LINKTYPE_USER2. - * If we don't have a printer for DLT_USER2, and type is - * DLT_USER2, we look up the printer for DLT_PKTAP and use - * that. - */ - if (type == DLT_USER2) { - for (p = ndo_printers; p->f; ++p) - if (DLT_PKTAP == p->type) - return p->f; - } #endif - return NULL; - /* NOTREACHED */ -} - static pcap_t *pd; static int supports_monitor_mode; @@ -470,42 +244,127 @@ extern int optind; extern int opterr; extern char *optarg; -struct print_info { - netdissect_options *ndo; - union { - if_printer printer; - if_ndo_printer ndo_printer; - } p; - int ndo_type; -}; - struct dump_info { char *WFileName; char *CurrentFileName; pcap_t *pd; pcap_dumper_t *p; -#ifdef __FreeBSD__ +#ifdef HAVE_CAPSICUM int dirfd; #endif }; +#if defined(HAVE_PCAP_SET_PARSER_DEBUG) +/* + * We have pcap_set_parser_debug() in libpcap; declare it (it's not declared + * by any libpcap header, because it's a special hack, only available if + * libpcap was configured to include it, and only intended for use by + * libpcap developers trying to debug the parser for filter expressions). + */ +#ifdef _WIN32 +__declspec(dllimport) +#else /* _WIN32 */ +extern +#endif /* _WIN32 */ +void pcap_set_parser_debug(int); +#elif defined(HAVE_PCAP_DEBUG) || defined(HAVE_YYDEBUG) +/* + * We don't have pcap_set_parser_debug() in libpcap, but we do have + * pcap_debug or yydebug. Make a local version of pcap_set_parser_debug() + * to set the flag, and define HAVE_PCAP_SET_PARSER_DEBUG. + */ +static void +pcap_set_parser_debug(int value) +{ +#ifdef HAVE_PCAP_DEBUG + extern int pcap_debug; + + pcap_debug = value; +#else /* HAVE_PCAP_DEBUG */ + extern int yydebug; + + yydebug = value; +#endif /* HAVE_PCAP_DEBUG */ +} + +#define HAVE_PCAP_SET_PARSER_DEBUG +#endif + +#if defined(HAVE_PCAP_SET_OPTIMIZER_DEBUG) +/* + * We have pcap_set_optimizer_debug() in libpcap; declare it (it's not declared + * by any libpcap header, because it's a special hack, only available if + * libpcap was configured to include it, and only intended for use by + * libpcap developers trying to debug the optimizer for filter expressions). + */ +#ifdef _WIN32 +__declspec(dllimport) +#else /* _WIN32 */ +extern +#endif /* _WIN32 */ +void pcap_set_optimizer_debug(int); +#endif + +/* VARARGS */ +static void +error(const char *fmt, ...) +{ + va_list ap; + + (void)fprintf(stderr, "%s: ", program_name); + va_start(ap, fmt); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + if (*fmt) { + fmt += strlen(fmt); + if (fmt[-1] != '\n') + (void)fputc('\n', stderr); + } + exit_tcpdump(1); + /* NOTREACHED */ +} + +/* VARARGS */ +static void +warning(const char *fmt, ...) +{ + va_list ap; + + (void)fprintf(stderr, "%s: WARNING: ", program_name); + va_start(ap, fmt); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + if (*fmt) { + fmt += strlen(fmt); + if (fmt[-1] != '\n') + (void)fputc('\n', stderr); + } +} + +static void +exit_tcpdump(int status) +{ + nd_cleanup(); + exit(status); +} + #ifdef HAVE_PCAP_SET_TSTAMP_TYPE static void -show_tstamp_types_and_exit(const char *device, pcap_t *pd) +show_tstamp_types_and_exit(pcap_t *pc, const char *device) { int n_tstamp_types; int *tstamp_types = 0; const char *tstamp_type_name; int i; - n_tstamp_types = pcap_list_tstamp_types(pd, &tstamp_types); + n_tstamp_types = pcap_list_tstamp_types(pc, &tstamp_types); if (n_tstamp_types < 0) - error("%s", pcap_geterr(pd)); + error("%s", pcap_geterr(pc)); if (n_tstamp_types == 0) { fprintf(stderr, "Time stamp type cannot be set for %s\n", device); - exit(0); + exit_tcpdump(0); } fprintf(stderr, "Time stamp types for %s (use option -j to set):\n", device); @@ -519,20 +378,20 @@ show_tstamp_types_and_exit(const char *device, pcap_t *pd) } } pcap_free_tstamp_types(tstamp_types); - exit(0); + exit_tcpdump(0); } #endif static void -show_dlts_and_exit(const char *device, pcap_t *pd) +show_dlts_and_exit(pcap_t *pc, const char *device) { - int n_dlts; + int n_dlts, i; int *dlts = 0; const char *dlt_name; - n_dlts = pcap_list_datalinks(pd, &dlts); + n_dlts = pcap_list_datalinks(pc, &dlts); if (n_dlts < 0) - error("%s", pcap_geterr(pd)); + error("%s", pcap_geterr(pc)); else if (n_dlts == 0 || !dlts) error("No data link types."); @@ -552,52 +411,49 @@ show_dlts_and_exit(const char *device, pcap_t *pd) (void) fprintf(stderr, "Data link types for %s (use option -y to set):\n", device); - while (--n_dlts >= 0) { - dlt_name = pcap_datalink_val_to_name(dlts[n_dlts]); + for (i = 0; i < n_dlts; i++) { + dlt_name = pcap_datalink_val_to_name(dlts[i]); if (dlt_name != NULL) { (void) fprintf(stderr, " %s (%s)", dlt_name, - pcap_datalink_val_to_description(dlts[n_dlts])); + pcap_datalink_val_to_description(dlts[i])); /* * OK, does tcpdump handle that type? */ - if (lookup_printer(dlts[n_dlts]) == NULL - && lookup_ndo_printer(dlts[n_dlts]) == NULL) + if (!has_printer(dlts[i])) (void) fprintf(stderr, " (printing not supported)"); fprintf(stderr, "\n"); } else { (void) fprintf(stderr, " DLT %d (printing not supported)\n", - dlts[n_dlts]); + dlts[i]); } } #ifdef HAVE_PCAP_FREE_DATALINKS pcap_free_datalinks(dlts); #endif - exit(0); + exit_tcpdump(0); } #ifdef HAVE_PCAP_FINDALLDEVS static void show_devices_and_exit (void) { - pcap_if_t *devpointer; + pcap_if_t *dev, *devlist; char ebuf[PCAP_ERRBUF_SIZE]; int i; - if (pcap_findalldevs(&devpointer, ebuf) < 0) + if (pcap_findalldevs(&devlist, ebuf) < 0) error("%s", ebuf); - else { - for (i = 0; devpointer != NULL; i++) { - printf("%d.%s", i+1, devpointer->name); - if (devpointer->description != NULL) - printf(" (%s)", devpointer->description); - if (devpointer->flags != 0) - printf(" [%s]", bittok2str(status_flags, "none", devpointer->flags)); - printf("\n"); - devpointer = devpointer->next; - } + 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(" [%s]", bittok2str(status_flags, "none", dev->flags)); + printf("\n"); } - exit(0); + pcap_freealldevs(devlist); + exit_tcpdump(0); } #endif /* HAVE_PCAP_FINDALLDEVS */ @@ -612,7 +468,7 @@ show_devices_and_exit (void) * OS X 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 tospecify that packet comments in pcap-ng files + * OS X tcpdump uses -k to specify that packet comments in pcap-ng files * should be printed; * * OpenBSD tcpdump uses -o to indicate that OS fingerprinting should be done @@ -635,13 +491,13 @@ show_devices_and_exit (void) * Set up flags that might or might not be supported depending on the * version of libpcap we're using. */ -#if defined(HAVE_PCAP_CREATE) || defined(WIN32) +#if defined(HAVE_PCAP_CREATE) || defined(_WIN32) #define B_FLAG "B:" #define B_FLAG_USAGE " [ -B size ]" -#else /* defined(HAVE_PCAP_CREATE) || defined(WIN32) */ +#else /* defined(HAVE_PCAP_CREATE) || defined(_WIN32) */ #define B_FLAG #define B_FLAG_USAGE -#endif /* defined(HAVE_PCAP_CREATE) || defined(WIN32) */ +#endif /* defined(HAVE_PCAP_CREATE) || defined(_WIN32) */ #ifdef HAVE_PCAP_CREATE #define I_FLAG "I" @@ -677,7 +533,7 @@ show_devices_and_exit (void) #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:Rs:StT:u" U_FLAG "vV:w:W:xXy:Yz:Z:#" +#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:#" /* * Long options. @@ -704,7 +560,7 @@ show_devices_and_exit (void) #define OPTION_IMMEDIATE_MODE 130 static const struct option longopts[] = { -#if defined(HAVE_PCAP_CREATE) || defined(WIN32) +#if defined(HAVE_PCAP_CREATE) || defined(_WIN32) { "buffer-size", required_argument, NULL, 'B' }, #endif { "list-interfaces", no_argument, NULL, 'D' }, @@ -736,7 +592,7 @@ static const struct option longopts[] = { #ifdef HAVE_PCAP_SET_IMMEDIATE_MODE { "immediate-mode", no_argument, NULL, OPTION_IMMEDIATE_MODE }, #endif -#if defined(HAVE_PCAP_DEBUG) || defined(HAVE_YYDEBUG) +#ifdef HAVE_PCAP_SET_PARSER_DEBUG { "debug-filter-parser", no_argument, NULL, 'Y' }, #endif { "relinquish-privileges", required_argument, NULL, 'Z' }, @@ -745,7 +601,7 @@ static const struct option longopts[] = { { NULL, 0, NULL, 0 } }; -#ifndef WIN32 +#ifndef _WIN32 /* Drop root privileges and chroot if necessary */ static void droproot(const char *username, const char *chroot_dir) @@ -753,36 +609,38 @@ droproot(const char *username, const char *chroot_dir) struct passwd *pw = NULL; if (chroot_dir && !username) { - fprintf(stderr, "tcpdump: Chroot without dropping root is insecure\n"); - exit(1); + fprintf(stderr, "%s: Chroot without dropping root is insecure\n", + program_name); + exit_tcpdump(1); } pw = getpwnam(username); if (pw) { if (chroot_dir) { if (chroot(chroot_dir) != 0 || chdir ("/") != 0) { - fprintf(stderr, "tcpdump: Couldn't chroot/chdir to '%.64s': %s\n", - chroot_dir, pcap_strerror(errno)); - exit(1); + fprintf(stderr, "%s: Couldn't chroot/chdir to '%.64s': %s\n", + program_name, chroot_dir, pcap_strerror(errno)); + exit_tcpdump(1); } } #ifdef HAVE_LIBCAP_NG - int ret = capng_change_id(pw->pw_uid, pw->pw_gid, CAPNG_NO_FLAG); - if (ret < 0) { - fprintf(stderr, "error : ret %d\n", ret); - } - else { - fprintf(stderr, "dropped privs to %s\n", username); + { + int ret = capng_change_id(pw->pw_uid, pw->pw_gid, CAPNG_NO_FLAG); + if (ret < 0) { + fprintf(stderr, "error : ret %d\n", ret); + } else { + fprintf(stderr, "dropped privs to %s\n", username); + } } #else if (initgroups(pw->pw_name, pw->pw_gid) != 0 || setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) { - fprintf(stderr, "tcpdump: Couldn't change to '%.32s' uid=%lu gid=%lu: %s\n", - username, - (unsigned long)pw->pw_uid, - (unsigned long)pw->pw_gid, - pcap_strerror(errno)); - exit(1); + fprintf(stderr, "%s: Couldn't change to '%.32s' uid=%lu gid=%lu: %s\n", + program_name, 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); @@ -790,23 +648,24 @@ droproot(const char *username, const char *chroot_dir) #endif /* HAVE_LIBCAP_NG */ } else { - fprintf(stderr, "tcpdump: Couldn't find user '%.32s'\n", - username); - exit(1); + fprintf(stderr, "%s: Couldn't find user '%.32s'\n", + program_name, username); + exit_tcpdump(1); } #ifdef HAVE_LIBCAP_NG - /* We don't need CAP_SETUID and CAP_SETGID any more. */ + /* We don't need CAP_SETUID, CAP_SETGID and CAP_SYS_CHROOT any more. */ capng_updatev( CAPNG_DROP, CAPNG_EFFECTIVE | CAPNG_PERMITTED, CAP_SETUID, CAP_SETGID, + CAP_SYS_CHROOT, -1); capng_apply(CAPNG_SELECT_BOTH); #endif /* HAVE_LIBCAP_NG */ } -#endif /* WIN32 */ +#endif /* _WIN32 */ static int getWflagChars(int x) @@ -856,43 +715,6 @@ MakeFilename(char *buffer, char *orig_name, int cnt, int max_chars) free(filename); } -static int tcpdump_printf(netdissect_options *ndo _U_, - const char *fmt, ...) -{ - - va_list args; - int ret; - - va_start(args, fmt); - ret=vfprintf(stdout, fmt, args); - va_end(args); - - return ret; -} - -static struct print_info -get_print_info(int type) -{ - struct print_info printinfo; - - printinfo.ndo_type = 1; - printinfo.ndo = gndo; - printinfo.p.ndo_printer = lookup_ndo_printer(type); - if (printinfo.p.ndo_printer == NULL) { - printinfo.p.printer = lookup_printer(type); - printinfo.ndo_type = 0; - if (printinfo.p.printer == NULL) { - gndo->ndo_dltname = pcap_datalink_val_to_name(type); - if (gndo->ndo_dltname != NULL) - error("packet printing is not supported for link type %s: use -w", - gndo->ndo_dltname); - else - error("packet printing is not supported for link type %d: use -w", type); - } - } - return (printinfo); -} - static char * get_next_file(FILE *VFile, char *ptr) { @@ -967,7 +789,7 @@ tstamp_precision_to_string(int precision) } #endif -#ifdef __FreeBSD__ +#ifdef HAVE_CAPSICUM /* * Ensure that, on a dump file's descriptor, we have all the rights * necessary to make the standard I/O library work with an fdopen()ed @@ -1031,28 +853,327 @@ set_dumper_capsicum_rights(pcap_dumper_t *p) if (cap_rights_limit(fd, &rights) < 0 && errno != ENOSYS) { error("unable to limit dump descriptor"); } - if (cap_fcntls_limit(fd, CAP_FCNTL_GETFL) < 0 && errno != ENOSYS) { - error("unable to limit dump descriptor fcntls"); + if (cap_fcntls_limit(fd, CAP_FCNTL_GETFL) < 0 && errno != ENOSYS) { + error("unable to limit dump descriptor fcntls"); + } +} +#endif + +/* + * Copy arg vector into a new buffer, concatenating arguments with spaces. + */ +static char * +copy_argv(register char **argv) +{ + register char **p; + register u_int len = 0; + char *buf; + char *src, *dst; + + p = argv; + if (*p == NULL) + return 0; + + while (*p) + len += strlen(*p++) + 1; + + buf = (char *)malloc(len); + if (buf == NULL) + error("copy_argv: malloc"); + + p = argv; + dst = buf; + while ((src = *p++) != NULL) { + while ((*dst++ = *src++) != '\0') + ; + dst[-1] = ' '; + } + dst[-1] = '\0'; + + return buf; +} + +/* + * On Windows, we need to open the file in binary mode, so that + * we get all the bytes specified by the size we get from "fstat()". + * On UNIX, that's not necessary. O_BINARY is defined on Windows; + * we define it as 0 if it's not defined, so it does nothing. + */ +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +static char * +read_infile(char *fname) +{ + register int i, fd, cc; + register char *cp; + struct stat 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) + error("can't stat %s: %s", fname, pcap_strerror(errno)); + + cp = malloc((u_int)buf.st_size + 1); + if (cp == NULL) + error("malloc(%d) for %s: %s", (u_int)buf.st_size + 1, + fname, pcap_strerror(errno)); + cc = read(fd, cp, (u_int)buf.st_size); + 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); + + close(fd); + /* replace "# comment" with spaces */ + for (i = 0; i < cc; i++) { + if (cp[i] == '#') + while (i < cc && cp[i] != '\n') + cp[i++] = ' '; + } + cp[cc] = '\0'; + return (cp); +} + +#ifdef HAVE_PCAP_FINDALLDEVS +static long +parse_interface_number(const char *device) +{ + long devnum; + char *end; + + devnum = strtol(device, &end, 10); + if (device != end && *end == '\0') { + /* + * It's all-numeric, but is it a valid number? + */ + if (devnum <= 0) { + /* + * No, it's not an ordinal. + */ + error("Invalid adapter index"); + } + return (devnum); + } else { + /* + * It's not all-numeric; return -1, so our caller + * knows that. + */ + return (-1); + } +} + +static char * +find_interface_by_number(long devnum) +{ + pcap_if_t *dev, *devlist; + long i; + char ebuf[PCAP_ERRBUF_SIZE]; + char *device; + + if (pcap_findalldevs(&devlist, ebuf) < 0) + error("%s", ebuf); + /* + * Look for the devnum-th entry in the list of devices (1-based). + */ + for (i = 0, dev = devlist; i < devnum-1 && dev != NULL; + i++, dev = dev->next) + ; + if (dev == NULL) + error("Invalid adapter index"); + device = strdup(dev->name); + pcap_freealldevs(devlist); + return (device); +} +#endif + +static pcap_t * +open_interface(const char *device, netdissect_options *ndo, char *ebuf) +{ + pcap_t *pc; +#ifdef HAVE_PCAP_CREATE + int status; + char *cp; +#endif + +#ifdef HAVE_PCAP_CREATE + pc = pcap_create(device, ebuf); + if (pc == NULL) { + /* + * If this failed with "No such device", 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) + return (NULL); + error("%s", ebuf); + } +#ifdef HAVE_PCAP_SET_TSTAMP_TYPE + if (Jflag) + show_tstamp_types_and_exit(pc, device); +#endif +#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION + 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)); +#endif + +#ifdef HAVE_PCAP_SET_IMMEDIATE_MODE + if (immediate_mode) { + status = pcap_set_immediate_mode(pc, 1); + if (status != 0) + error("%s: Can't set immediate mode: %s", + device, + pcap_statustostr(status)); + } +#endif + /* + * Is this an interface that supports monitor mode? + */ + if (pcap_can_set_rfmon(pc) == 1) + 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)); + status = pcap_set_promisc(pc, !pflag); + if (status != 0) + error("%s: Can't set promiscuous mode: %s", + device, pcap_statustostr(status)); + if (Iflag) { + status = pcap_set_rfmon(pc, 1); + if (status != 0) + error("%s: Can't set monitor mode: %s", + device, pcap_statustostr(status)); + } + status = pcap_set_timeout(pc, 1000); + if (status != 0) + error("%s: pcap_set_timeout failed: %s", + device, pcap_statustostr(status)); + if (Bflag != 0) { + status = pcap_set_buffer_size(pc, Bflag); + if (status != 0) + error("%s: Can't set buffer size: %s", + device, pcap_statustostr(status)); + } +#ifdef HAVE_PCAP_SET_TSTAMP_TYPE + if (jflag != -1) { + status = pcap_set_tstamp_type(pc, jflag); + if (status < 0) + error("%s: Can't set time stamp type: %s", + device, pcap_statustostr(status)); } -} #endif + status = pcap_activate(pc); + if (status < 0) { + /* + * pcap_activate() failed. + */ + cp = pcap_geterr(pc); + if (status == PCAP_ERROR) + error("%s", cp); + else if (status == PCAP_ERROR_NO_SUCH_DEVICE) { + /* + * Return an error for our caller to handle. + */ + pcap_close(pc); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s\n(%s)", + device, pcap_statustostr(status), cp); + 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. */ + 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)); + } else if (status > 0) { + /* + * pcap_activate() succeeded, but it's warning us + * of a problem it had. + */ + cp = pcap_geterr(pc); + if (status == PCAP_WARNING) + warning("%s", cp); + else if (status == PCAP_WARNING_PROMISC_NOTSUP && + *cp != '\0') + warning("%s: %s\n(%s)", device, + pcap_statustostr(status), cp); + else + warning("%s: %s", device, + pcap_statustostr(status)); + } +#ifdef HAVE_PCAP_SETDIRECTION + if (Qflag != -1) { + status = pcap_setdirection(pc, Qflag); + if (status != 0) + error("%s: pcap_setdirection() failed: %s", + device, pcap_geterr(pc)); + } +#endif /* HAVE_PCAP_SETDIRECTION */ +#else /* HAVE_PCAP_CREATE */ + *ebuf = '\0'; + pc = pcap_open_live(device, ndo->ndo_snaplen, !pflag, 1000, ebuf); + if (pc == NULL) { + /* + * If this failed with "No such device", 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) + return (NULL); + error("%s", ebuf); + } + if (*ebuf) + warning("%s", ebuf); +#endif /* HAVE_PCAP_CREATE */ + + return (pc); +} 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; pcap_handler callback; - int type; int dlt; - int new_dlt; const char *dlt_name; struct bpf_program fcode; -#ifndef WIN32 +#ifndef _WIN32 RETSIGTYPE (*oldhandler)(int); #endif - struct print_info printinfo; struct dump_info dumpinfo; u_char *pcap_userdata; char ebuf[PCAP_ERRBUF_SIZE]; @@ -1062,30 +1183,31 @@ main(int argc, char **argv) char *ret = NULL; char *end; #ifdef HAVE_PCAP_FINDALLDEVS - pcap_if_t *devpointer; - int devnum; + pcap_if_t *devlist; + long devnum; #endif int status; FILE *VFile; -#ifdef __FreeBSD__ +#ifdef HAVE_CAPSICUM cap_rights_t rights; -#endif /* !__FreeBSD__ */ int cansandbox; +#endif /* HAVE_CAPSICUM */ + int Oflag = 1; /* run filter code optimizer */ + int yflag_dlt = -1; + const char *yflag_dlt_name = NULL; + + netdissect_options Ndo; + netdissect_options *ndo = &Ndo; + + /* + * Initialize the netdissect code. + */ + if (nd_init(ebuf, sizeof ebuf) == -1) + error("%s", ebuf); -#ifdef WIN32 - if(wsockinit() != 0) return 1; -#endif /* WIN32 */ - - jflag=-1; /* not set */ - gndo->ndo_Oflag=1; - gndo->ndo_Rflag=1; - gndo->ndo_dlt=-1; - gndo->ndo_default_print=ndo_default_print; - gndo->ndo_printf=tcpdump_printf; - gndo->ndo_error=ndo_error; - gndo->ndo_warning=ndo_warning; - gndo->ndo_snaplen = DEFAULT_SNAPLEN; - gndo->ndo_immediate = 0; + memset(ndo, 0, sizeof(*ndo)); + ndo_set_function_pointers(ndo); + ndo->ndo_snaplen = DEFAULT_SNAPLEN; cnt = -1; device = NULL; @@ -1096,9 +1218,14 @@ main(int argc, char **argv) WFileName = NULL; dlt = -1; if ((cp = strrchr(argv[0], '/')) != NULL) - program_name = cp + 1; + ndo->program_name = program_name = cp + 1; else - program_name = argv[0]; + ndo->program_name = program_name = argv[0]; + +#ifdef _WIN32 + if (pcap_wsockinit() != 0) + error("Attempting to initialize Winsock failed"); +#endif /* _WIN32 */ /* * On platforms where the CPU doesn't support unaligned loads, @@ -1110,10 +1237,6 @@ main(int argc, char **argv) if (abort_on_misalignment(ebuf, sizeof(ebuf)) < 0) error("%s", ebuf); -#ifdef USE_LIBSMI - smiInit("tcpdump"); -#endif - while ( (op = getopt_long(argc, argv, SHORTOPTS, longopts, NULL)) != -1) switch (op) { @@ -1123,20 +1246,20 @@ main(int argc, char **argv) break; case 'A': - ++Aflag; + ++ndo->ndo_Aflag; break; case 'b': - ++bflag; + ++ndo->ndo_bflag; break; -#if defined(HAVE_PCAP_CREATE) || defined(WIN32) +#if defined(HAVE_PCAP_CREATE) || defined(_WIN32) case 'B': Bflag = atoi(optarg)*1024; if (Bflag <= 0) error("invalid packet buffer size %s", optarg); break; -#endif /* defined(HAVE_PCAP_CREATE) || defined(WIN32) */ +#endif /* defined(HAVE_PCAP_CREATE) || defined(_WIN32) */ case 'c': cnt = atoi(optarg); @@ -1146,7 +1269,7 @@ main(int argc, char **argv) case 'C': Cflag = atoi(optarg) * 1000000; - if (Cflag < 0) + if (Cflag <= 0) error("invalid file size %s", optarg); break; @@ -1163,18 +1286,18 @@ main(int argc, char **argv) break; case 'e': - ++eflag; + ++ndo->ndo_eflag; break; case 'E': #ifndef HAVE_LIBCRYPTO warning("crypto code not compiled in"); #endif - gndo->ndo_espsecret = optarg; + ndo->ndo_espsecret = optarg; break; case 'f': - ++fflag; + ++ndo->ndo_fflag; break; case 'F': @@ -1198,52 +1321,14 @@ main(int argc, char **argv) case 'h': print_usage(); - exit(0); + exit_tcpdump(0); break; case 'H': - ++Hflag; + ++ndo->ndo_Hflag; break; case 'i': - if (optarg[0] == '0' && optarg[1] == 0) - error("Invalid adapter index"); - -#ifdef HAVE_PCAP_FINDALLDEVS - /* - * If the argument is a number, treat it as - * an index into the list of adapters, as - * printed by "tcpdump -D". - * - * This should be OK on UNIX systems, as interfaces - * shouldn't have names that begin with digits. - * It can be useful on Windows, where more than - * one interface can have the same name. - */ - devnum = strtol(optarg, &end, 10); - if (optarg != end && *end == '\0') { - if (devnum < 0) - error("Invalid adapter index"); - - if (pcap_findalldevs(&devpointer, ebuf) < 0) - error("%s", ebuf); - else { - /* - * Look for the devnum-th entry - * in the list of devices - * (1-based). - */ - for (i = 0; - i < devnum-1 && devpointer != NULL; - i++, devpointer = devpointer->next) - ; - if (devpointer == NULL) - error("Invalid adapter index"); - } - device = devpointer->name; - break; - } -#endif /* HAVE_PCAP_FINDALLDEVS */ device = optarg; break; @@ -1266,41 +1351,39 @@ main(int argc, char **argv) #endif case 'l': -#ifdef WIN32 +#ifdef _WIN32 /* * _IOLBF is the same as _IOFBF in Microsoft's C * libraries; the only alternative they offer * is _IONBF. * * XXX - this should really be checking for MSVC++, - * not WIN32, if, for example, MinGW has its own + * not _WIN32, if, for example, MinGW has its own * C library that is more UNIX-compatible. */ setvbuf(stdout, NULL, _IONBF, 0); -#else /* WIN32 */ +#else /* _WIN32 */ #ifdef HAVE_SETLINEBUF setlinebuf(stdout); #else setvbuf(stdout, NULL, _IOLBF, 0); #endif -#endif /* WIN32 */ +#endif /* _WIN32 */ break; case 'K': - ++Kflag; + ++ndo->ndo_Kflag; break; case 'm': -#ifdef USE_LIBSMI - if (smiLoadModule(optarg) == 0) { - error("could not load MIB module %s", optarg); + if (nd_have_smi_support()) { + if (nd_load_smi_module(optarg, ebuf, sizeof ebuf) == -1) + error("%s", ebuf); + } else { + (void)fprintf(stderr, "%s: ignoring option `-m %s' ", + program_name, optarg); + (void)fprintf(stderr, "(no libsmi support)\n"); } - sflag = 1; -#else - (void)fprintf(stderr, "%s: ignoring option `-m %s' ", - program_name, optarg); - (void)fprintf(stderr, "(no libsmi support)\n"); -#endif break; case 'M': @@ -1308,15 +1391,15 @@ main(int argc, char **argv) #ifndef HAVE_LIBCRYPTO warning("crypto code not compiled in"); #endif - sigsecret = optarg; + ndo->ndo_sigsecret = optarg; break; case 'n': - ++nflag; + ++ndo->ndo_nflag; break; case 'N': - ++Nflag; + ++ndo->ndo_Nflag; break; case 'O': @@ -1328,17 +1411,17 @@ main(int argc, char **argv) break; case 'q': - ++qflag; - ++suppress_default_print; + ++ndo->ndo_qflag; + ++ndo->ndo_suppress_default_print; break; #ifdef HAVE_PCAP_SETDIRECTION case 'Q': - if (strcasecmp(optarg, "in") == 0) + if (ascii_strcasecmp(optarg, "in") == 0) Qflag = PCAP_D_IN; - else if (strcasecmp(optarg, "out") == 0) + else if (ascii_strcasecmp(optarg, "out") == 0) Qflag = PCAP_D_OUT; - else if (strcasecmp(optarg, "inout") == 0) + else if (ascii_strcasecmp(optarg, "inout") == 0) Qflag = PCAP_D_INOUT; else error("unknown capture direction `%s'", optarg); @@ -1349,66 +1432,64 @@ main(int argc, char **argv) RFileName = optarg; break; - case 'R': - Rflag = 0; - break; - case 's': - snaplen = strtol(optarg, &end, 0); + ndo->ndo_snaplen = strtol(optarg, &end, 0); if (optarg == end || *end != '\0' - || snaplen < 0 || snaplen > MAXIMUM_SNAPLEN) + || ndo->ndo_snaplen < 0 || ndo->ndo_snaplen > MAXIMUM_SNAPLEN) error("invalid snaplen %s", optarg); - else if (snaplen == 0) - snaplen = MAXIMUM_SNAPLEN; + else if (ndo->ndo_snaplen == 0) + ndo->ndo_snaplen = MAXIMUM_SNAPLEN; break; case 'S': - ++Sflag; + ++ndo->ndo_Sflag; break; case 't': - ++tflag; + ++ndo->ndo_tflag; break; case 'T': - if (strcasecmp(optarg, "vat") == 0) - packettype = PT_VAT; - else if (strcasecmp(optarg, "wb") == 0) - packettype = PT_WB; - else if (strcasecmp(optarg, "rpc") == 0) - packettype = PT_RPC; - else if (strcasecmp(optarg, "rtp") == 0) - packettype = PT_RTP; - else if (strcasecmp(optarg, "rtcp") == 0) - packettype = PT_RTCP; - else if (strcasecmp(optarg, "snmp") == 0) - packettype = PT_SNMP; - else if (strcasecmp(optarg, "cnfp") == 0) - packettype = PT_CNFP; - else if (strcasecmp(optarg, "tftp") == 0) - packettype = PT_TFTP; - else if (strcasecmp(optarg, "aodv") == 0) - packettype = PT_AODV; - else if (strcasecmp(optarg, "carp") == 0) - packettype = PT_CARP; - else if (strcasecmp(optarg, "radius") == 0) - packettype = PT_RADIUS; - else if (strcasecmp(optarg, "zmtp1") == 0) - packettype = PT_ZMTP1; - else if (strcasecmp(optarg, "vxlan") == 0) - packettype = PT_VXLAN; - else if (strcasecmp(optarg, "pgm") == 0) - packettype = PT_PGM; - else if (strcasecmp(optarg, "pgm_zmtp1") == 0) - packettype = PT_PGM_ZMTP1; - else if (strcasecmp(optarg, "lmp") == 0) - packettype = PT_LMP; + if (ascii_strcasecmp(optarg, "vat") == 0) + ndo->ndo_packettype = PT_VAT; + else if (ascii_strcasecmp(optarg, "wb") == 0) + ndo->ndo_packettype = PT_WB; + else if (ascii_strcasecmp(optarg, "rpc") == 0) + ndo->ndo_packettype = PT_RPC; + else if (ascii_strcasecmp(optarg, "rtp") == 0) + ndo->ndo_packettype = PT_RTP; + else if (ascii_strcasecmp(optarg, "rtcp") == 0) + ndo->ndo_packettype = PT_RTCP; + else if (ascii_strcasecmp(optarg, "snmp") == 0) + ndo->ndo_packettype = PT_SNMP; + else if (ascii_strcasecmp(optarg, "cnfp") == 0) + ndo->ndo_packettype = PT_CNFP; + else if (ascii_strcasecmp(optarg, "tftp") == 0) + ndo->ndo_packettype = PT_TFTP; + else if (ascii_strcasecmp(optarg, "aodv") == 0) + ndo->ndo_packettype = PT_AODV; + else if (ascii_strcasecmp(optarg, "carp") == 0) + ndo->ndo_packettype = PT_CARP; + else if (ascii_strcasecmp(optarg, "radius") == 0) + ndo->ndo_packettype = PT_RADIUS; + else if (ascii_strcasecmp(optarg, "zmtp1") == 0) + ndo->ndo_packettype = PT_ZMTP1; + else if (ascii_strcasecmp(optarg, "vxlan") == 0) + ndo->ndo_packettype = PT_VXLAN; + else if (ascii_strcasecmp(optarg, "pgm") == 0) + ndo->ndo_packettype = PT_PGM; + else if (ascii_strcasecmp(optarg, "pgm_zmtp1") == 0) + ndo->ndo_packettype = PT_PGM_ZMTP1; + else if (ascii_strcasecmp(optarg, "lmp") == 0) + ndo->ndo_packettype = PT_LMP; + else if (ascii_strcasecmp(optarg, "resp") == 0) + ndo->ndo_packettype = PT_RESP; else error("unknown packet type `%s'", optarg); break; case 'u': - ++uflag; + ++ndo->ndo_uflag; break; #ifdef HAVE_PCAP_DUMP_FLUSH @@ -1418,7 +1499,7 @@ main(int argc, char **argv) #endif case 'v': - ++vflag; + ++ndo->ndo_vflag; break; case 'V': @@ -1431,77 +1512,71 @@ main(int argc, char **argv) case 'W': Wflag = atoi(optarg); - if (Wflag < 0) + if (Wflag <= 0) error("invalid number of output files %s", optarg); WflagChars = getWflagChars(Wflag); break; case 'x': - ++xflag; - ++suppress_default_print; + ++ndo->ndo_xflag; + ++ndo->ndo_suppress_default_print; break; case 'X': - ++Xflag; - ++suppress_default_print; + ++ndo->ndo_Xflag; + ++ndo->ndo_suppress_default_print; break; case 'y': - gndo->ndo_dltname = optarg; - gndo->ndo_dlt = - pcap_datalink_name_to_val(gndo->ndo_dltname); - if (gndo->ndo_dlt < 0) - error("invalid data link type %s", gndo->ndo_dltname); + yflag_dlt_name = optarg; + yflag_dlt = + pcap_datalink_name_to_val(yflag_dlt_name); + if (yflag_dlt < 0) + error("invalid data link type %s", yflag_dlt_name); break; -#if defined(HAVE_PCAP_DEBUG) || defined(HAVE_YYDEBUG) +#ifdef HAVE_PCAP_SET_PARSER_DEBUG case 'Y': { /* Undocumented flag */ -#ifdef HAVE_PCAP_DEBUG - extern int pcap_debug; - pcap_debug = 1; -#else - extern int yydebug; - yydebug = 1; -#endif + pcap_set_parser_debug(1); } break; #endif case 'z': - zflag = strdup(optarg); + zflag = optarg; break; case 'Z': - username = strdup(optarg); + username = optarg; break; case '#': - gndo->ndo_packet_number = 1; + ndo->ndo_packet_number = 1; break; case OPTION_VERSION: print_version(); - exit(0); + exit_tcpdump(0); break; #ifdef HAVE_PCAP_SET_TSTAMP_PRECISION case OPTION_TSTAMP_PRECISION: - gndo->ndo_tstamp_precision = tstamp_precision_from_string(optarg); - if (gndo->ndo_tstamp_precision < 0) + ndo->ndo_tstamp_precision = tstamp_precision_from_string(optarg); + if (ndo->ndo_tstamp_precision < 0) error("unsupported time stamp precision"); break; #endif #ifdef HAVE_PCAP_SET_IMMEDIATE_MODE case OPTION_IMMEDIATE_MODE: - gndo->ndo_immediate = 1; + immediate_mode = 1; break; #endif default: print_usage(); - exit(1); + exit_tcpdump(1); /* NOTREACHED */ } @@ -1510,11 +1585,11 @@ main(int argc, char **argv) show_devices_and_exit(); #endif - switch (tflag) { + switch (ndo->ndo_tflag) { case 0: /* Default */ case 4: /* Default + Date*/ - thiszone = gmt2local(0); + timezone_offset = gmt2local(0); break; case 1: /* No time stamp */ @@ -1528,7 +1603,7 @@ main(int argc, char **argv) break; } - if (fflag != 0 && (VFileName != NULL || RFileName != NULL)) + if (ndo->ndo_fflag != 0 && (VFileName != NULL || RFileName != NULL)) error("-f can not be used with -V or -r"); if (VFileName != NULL && RFileName != NULL) @@ -1542,7 +1617,7 @@ main(int argc, char **argv) * probably expecting to see packets pop up immediately. */ if (WFileName == NULL && isatty(1)) - gndo->ndo_immediate = 1; + immediate_mode = 1; #endif #ifdef WITH_CHROOT @@ -1573,7 +1648,7 @@ main(int argc, char **argv) * In either case, we're reading a savefile, not doing * a live capture. */ -#ifndef WIN32 +#ifndef _WIN32 /* * We don't need network access, so relinquish any set-UID * or set-GID privileges we have (if any). @@ -1585,7 +1660,7 @@ main(int argc, char **argv) */ if (setgid(getgid()) != 0 || setuid(getuid()) != 0 ) fprintf(stderr, "Warning: setgid/setuid failed !\n"); -#endif /* WIN32 */ +#endif /* _WIN32 */ if (VFileName != NULL) { if (VFileName[0] == '-' && VFileName[1] == '\0') VFile = stdin; @@ -1593,7 +1668,7 @@ main(int argc, char **argv) VFile = fopen(VFileName, "r"); if (VFile == NULL) - error("Unable to open file: %s\n", strerror(errno)); + error("Unable to open file: %s\n", pcap_strerror(errno)); ret = get_next_file(VFile, VFileLine); if (!ret) @@ -1603,14 +1678,14 @@ main(int argc, char **argv) #ifdef HAVE_PCAP_SET_TSTAMP_PRECISION pd = pcap_open_offline_with_tstamp_precision(RFileName, - gndo->ndo_tstamp_precision, ebuf); + ndo->ndo_tstamp_precision, ebuf); #else pd = pcap_open_offline(RFileName, ebuf); #endif if (pd == NULL) error("%s", ebuf); -#ifdef HAVE_CASPER +#ifdef HAVE_CAPSICUM cap_rights_init(&rights, CAP_READ); if (cap_rights_limit(fileno(pcap_file(pd)), &rights) < 0 && errno != ENOSYS) { @@ -1633,178 +1708,91 @@ main(int argc, char **argv) * We're doing a live capture. */ if (device == NULL) { + /* + * No interface was specified. Pick one. + */ +#ifdef HAVE_PCAP_FINDALLDEVS + /* + * 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); + } +#else /* HAVE_PCAP_FINDALLDEVS */ + /* + * Use whatever interface pcap_lookupdev() + * chooses. + */ device = pcap_lookupdev(ebuf); +#endif if (device == NULL) error("%s", ebuf); } -#ifdef WIN32 - /* - * Print a message to the standard error on Windows. - * XXX - why do it here, with a different message? - */ - if(strlen(device) == 1) /* we assume that an ASCII string is always longer than 1 char */ - { /* a Unicode string has a \0 as second byte (so strlen() is 1) */ - fprintf(stderr, "%s: listening on %ws\n", program_name, device); - } - else - { - fprintf(stderr, "%s: listening on %s\n", program_name, device); - } - - fflush(stderr); -#endif /* WIN32 */ -#ifdef HAVE_PCAP_CREATE - pd = pcap_create(device, ebuf); - if (pd == NULL) - error("%s", ebuf); -#ifdef HAVE_PCAP_SET_TSTAMP_TYPE - if (Jflag) - show_tstamp_types_and_exit(device, pd); -#endif -#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION - status = pcap_set_tstamp_precision(pd, gndo->ndo_tstamp_precision); - if (status != 0) - error("%s: Can't set %ssecond time stamp precision: %s", - device, - tstamp_precision_to_string(gndo->ndo_tstamp_precision), - pcap_statustostr(status)); -#endif -#ifdef HAVE_PCAP_SET_IMMEDIATE_MODE - if (gndo->ndo_immediate) { - status = pcap_set_immediate_mode(pd, 1); - if (status != 0) - error("%s: Can't set immediate mode: %s", - device, - pcap_statustostr(status)); - } -#endif /* - * Is this an interface that supports monitor mode? + * Try to open the interface with the specified name. */ - if (pcap_can_set_rfmon(pd) == 1) - supports_monitor_mode = 1; - else - supports_monitor_mode = 0; - status = pcap_set_snaplen(pd, snaplen); - if (status != 0) - error("%s: Can't set snapshot length: %s", - device, pcap_statustostr(status)); - status = pcap_set_promisc(pd, !pflag); - if (status != 0) - error("%s: Can't set promiscuous mode: %s", - device, pcap_statustostr(status)); - if (Iflag) { - status = pcap_set_rfmon(pd, 1); - if (status != 0) - error("%s: Can't set monitor mode: %s", - device, pcap_statustostr(status)); - } - status = pcap_set_timeout(pd, 1000); - if (status != 0) - error("%s: pcap_set_timeout failed: %s", - device, pcap_statustostr(status)); - if (Bflag != 0) { - status = pcap_set_buffer_size(pd, Bflag); - if (status != 0) - error("%s: Can't set buffer size: %s", - device, pcap_statustostr(status)); - } -#ifdef HAVE_PCAP_SET_TSTAMP_TYPE - if (jflag != -1) { - status = pcap_set_tstamp_type(pd, jflag); - if (status < 0) - error("%s: Can't set time stamp type: %s", - device, pcap_statustostr(status)); - } -#endif - status = pcap_activate(pd); - if (status < 0) { + pd = open_interface(device, ndo, ebuf); + if (pd == NULL) { /* - * pcap_activate() failed. + * That failed. If we can get a list of + * interfaces, and the interface name + * is purely numeric, try to use it as + * a 1-based index in the list of + * interfaces. */ - cp = pcap_geterr(pd); - if (status == PCAP_ERROR) - error("%s", cp); - else if ((status == PCAP_ERROR_NO_SUCH_DEVICE || - 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. */ - 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\nand use %s as the tcpdump " - "interface", device, newdev, parent, - newdev); +#ifdef HAVE_PCAP_FINDALLDEVS + devnum = parse_interface_number(device); + if (devnum == -1) { + /* + * It's not a number; just report + * the open error and fail. + */ + error("%s", ebuf); } -#endif - else - error("%s: %s", device, - pcap_statustostr(status)); - } else if (status > 0) { + /* - * pcap_activate() succeeded, but it's warning us - * of a problem it had. + * OK, it's a number; try to find the + * interface with that index, and try + * to open it. + * + * find_interface_by_number() exits if it + * couldn't be found. + */ + device = find_interface_by_number(devnum); + pd = open_interface(device, ndo, ebuf); + if (pd == NULL) + error("%s", ebuf); +#else /* HAVE_PCAP_FINDALLDEVS */ + /* + * We can't get a list of interfaces; just + * fail. */ - cp = pcap_geterr(pd); - if (status == PCAP_WARNING) - warning("%s", cp); - else if (status == PCAP_WARNING_PROMISC_NOTSUP && - *cp != '\0') - warning("%s: %s\n(%s)", device, - pcap_statustostr(status), cp); - else - warning("%s: %s", device, - pcap_statustostr(status)); - } -#ifdef HAVE_PCAP_SETDIRECTION - if (Qflag != -1) { - status = pcap_setdirection(pd, Qflag); - if (status != 0) - error("%s: pcap_setdirection() failed: %s", - device, pcap_geterr(pd)); - } -#endif /* HAVE_PCAP_SETDIRECTION */ -#else - *ebuf = '\0'; - pd = pcap_open_live(device, snaplen, !pflag, 1000, ebuf); - if (pd == NULL) error("%s", ebuf); - else if (*ebuf) - warning("%s", ebuf); -#endif /* HAVE_PCAP_CREATE */ +#endif /* HAVE_PCAP_FINDALLDEVS */ + } + /* * Let user own process after socket has been opened. */ -#ifndef WIN32 +#ifndef _WIN32 if (setgid(getgid()) != 0 || setuid(getuid()) != 0) fprintf(stderr, "Warning: setgid/setuid failed !\n"); -#endif /* WIN32 */ -#if !defined(HAVE_PCAP_CREATE) && defined(WIN32) +#endif /* _WIN32 */ +#if !defined(HAVE_PCAP_CREATE) && defined(_WIN32) if(Bflag != 0) if(pcap_setbuff(pd, Bflag)==-1){ error("%s", pcap_geterr(pd)); } -#endif /* !defined(HAVE_PCAP_CREATE) && defined(WIN32) */ +#endif /* !defined(HAVE_PCAP_CREATE) && defined(_WIN32) */ if (Lflag) - show_dlts_and_exit(device, pd); - if (gndo->ndo_dlt >= 0) { + show_dlts_and_exit(pd, device); + if (yflag_dlt >= 0) { #ifdef HAVE_PCAP_SET_DATALINK - if (pcap_set_datalink(pd, gndo->ndo_dlt) < 0) + if (pcap_set_datalink(pd, yflag_dlt) < 0) error("%s", pcap_geterr(pd)); #else /* @@ -1812,21 +1800,21 @@ main(int argc, char **argv) * data link type, so we only let them * set it to what it already is. */ - if (gndo->ndo_dlt != pcap_datalink(pd)) { + if (yflag_dlt != pcap_datalink(pd)) { error("%s is not one of the DLTs supported by this device\n", - gndo->ndo_dltname); + yflag_dlt_name); } #endif (void)fprintf(stderr, "%s: data link type %s\n", - program_name, gndo->ndo_dltname); + program_name, yflag_dlt_name); (void)fflush(stderr); } i = pcap_snapshot(pd); - if (snaplen < i) { - warning("snaplen raised from %d to %d", snaplen, i); - snaplen = i; + if (ndo->ndo_snaplen < i) { + warning("snaplen raised from %d to %d", ndo->ndo_snaplen, i); + ndo->ndo_snaplen = i; } - if(fflag != 0) { + if(ndo->ndo_fflag != 0) { if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) { warning("foreign (-f) flag used but: %s", ebuf); } @@ -1838,38 +1826,41 @@ main(int argc, char **argv) else cmdbuf = copy_argv(&argv[optind]); +#ifdef HAVE_PCAP_SET_OPTIMIZER_DEBUG + pcap_set_optimizer_debug(dflag); +#endif if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0) error("%s", pcap_geterr(pd)); if (dflag) { bpf_dump(&fcode, dflag); pcap_close(pd); free(cmdbuf); - exit(0); + pcap_freecode(&fcode); + exit_tcpdump(0); } #ifdef HAVE_CASPER - if (!nflag) + if (!ndo->ndo_nflag) capdns = capdns_setup(); #endif /* HAVE_CASPER */ - init_addrtoname(gndo, localnet, netmask); - init_checksum(); + init_print(ndo, localnet, netmask, timezone_offset); -#ifndef WIN32 +#ifndef _WIN32 (void)setsignal(SIGPIPE, cleanup); (void)setsignal(SIGTERM, cleanup); (void)setsignal(SIGINT, cleanup); -#endif /* WIN32 */ +#endif /* _WIN32 */ #if defined(HAVE_FORK) || defined(HAVE_VFORK) (void)setsignal(SIGCHLD, child_cleanup); #endif /* Cooperate with nohup(1) */ -#ifndef WIN32 +#ifndef _WIN32 if ((oldhandler = setsignal(SIGHUP, cleanup)) != SIG_DFL) (void)setsignal(SIGHUP, oldhandler); -#endif /* WIN32 */ +#endif /* _WIN32 */ -#ifndef WIN32 +#ifndef _WIN32 /* * If a user name was specified with "-Z", attempt to switch to * that user's UID. This would probably be used with sudo, @@ -1900,6 +1891,13 @@ main(int argc, char **argv) CAP_SETGID, -1); } + if (chroot_dir) { + capng_update( + CAPNG_ADD, + CAPNG_PERMITTED | CAPNG_EFFECTIVE, + CAP_SYS_CHROOT + ); + } if (WFileName) { capng_update( @@ -1914,13 +1912,13 @@ main(int argc, char **argv) droproot(username, chroot_dir); } -#endif /* WIN32 */ +#endif /* _WIN32 */ if (pcap_setfilter(pd, &fcode) < 0) error("%s", pcap_geterr(pd)); -#ifdef HAVE_CASPER +#ifdef HAVE_CAPSICUM if (RFileName == NULL && VFileName == NULL) { - static const unsigned long cmds[] = { BIOCGSTATS }; + static const unsigned long cmds[] = { BIOCGSTATS, BIOCROTZBUF }; /* * The various libpcap devices use a combination of @@ -1968,12 +1966,16 @@ main(int argc, char **argv) #endif /* HAVE_LIBCAP_NG */ if (p == NULL) error("%s", pcap_geterr(pd)); -#ifdef __FreeBSD__ +#ifdef HAVE_CAPSICUM set_dumper_capsicum_rights(p); #endif if (Cflag != 0 || Gflag != 0) { -#ifdef __FreeBSD__ +#ifdef HAVE_CAPSICUM dumpinfo.WFileName = strdup(basename(WFileName)); + if (dumpinfo.WFileName == NULL) { + error("Unable to allocate memory for file %s", + WFileName); + } dumpinfo.dirfd = open(dirname(WFileName), O_DIRECTORY | O_RDONLY); if (dumpinfo.dirfd < 0) { @@ -1990,7 +1992,7 @@ main(int argc, char **argv) errno != ENOSYS) { error("unable to limit dump descriptor fcntls"); } -#else /* !__FreeBSD__ */ +#else /* !HAVE_CAPSICUM */ dumpinfo.WFileName = WFileName; #endif callback = dump_packet_and_trunc; @@ -2006,10 +2008,10 @@ main(int argc, char **argv) pcap_dump_flush(p); #endif } else { - type = pcap_datalink(pd); - printinfo = get_print_info(type); + dlt = pcap_datalink(pd); + ndo->ndo_if_printer = get_if_printer(ndo, dlt); callback = print_packet; - pcap_userdata = (u_char *)&printinfo; + pcap_userdata = (u_char *)ndo; } #ifdef SIGNAL_REQ_INFO @@ -2021,10 +2023,10 @@ main(int argc, char **argv) (void)setsignal(SIGNAL_REQ_INFO, requestinfo); #endif - if (vflag > 0 && WFileName) { + if (ndo->ndo_vflag > 0 && WFileName) { /* * When capturing to a file, "-v" means tcpdump should, - * every 10 secodns, "v"erbosely report the number of + * every 10 seconds, "v"erbosely report the number of * packets captured. */ #ifdef USE_WIN32_MM_TIMER @@ -2037,14 +2039,13 @@ main(int argc, char **argv) #endif } -#ifndef WIN32 if (RFileName == NULL) { /* * Live capture (if -V was specified, we set RFileName * to a file from the -V file). Print a message to * the standard error on UN*X. */ - if (!vflag && !WFileName) { + if (!ndo->ndo_vflag && !WFileName) { (void)fprintf(stderr, "%s: verbose output suppressed, use -v or -vv for full protocol decode\n", program_name); @@ -2054,26 +2055,25 @@ main(int argc, char **argv) dlt_name = pcap_datalink_val_to_name(dlt); if (dlt_name == NULL) { (void)fprintf(stderr, "listening on %s, link-type %u, capture size %u bytes\n", - device, dlt, snaplen); + device, dlt, ndo->ndo_snaplen); } 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), snaplen); + pcap_datalink_val_to_description(dlt), ndo->ndo_snaplen); } (void)fflush(stderr); } -#endif /* WIN32 */ -#ifdef __FreeBSD__ +#ifdef HAVE_CAPSICUM cansandbox = (VFileName == NULL && zflag == NULL); #ifdef HAVE_CASPER - cansandbox = (cansandbox && (nflag || capdns != NULL)); + cansandbox = (cansandbox && (ndo->ndo_nflag || capdns != NULL)); #else - cansandbox = (cansandbox && nflag); -#endif + cansandbox = (cansandbox && ndo->ndo_nflag); +#endif /* HAVE_CASPER */ if (cansandbox && cap_enter() < 0 && errno != ENOSYS) error("unable to enter the capability mode"); -#endif /* __FreeBSD__ */ +#endif /* HAVE_CAPSICUM */ do { status = pcap_loop(pd, cnt, callback, pcap_userdata); @@ -2118,11 +2118,13 @@ main(int argc, char **argv) if (VFileName != NULL) { ret = get_next_file(VFile, VFileLine); if (ret) { + int new_dlt; + RFileName = VFileLine; pd = pcap_open_offline(RFileName, ebuf); if (pd == NULL) error("%s", ebuf); -#ifdef HAVE_CASPER +#ifdef HAVE_CAPSICUM cap_rights_init(&rights, CAP_READ); if (cap_rights_limit(fileno(pcap_file(pd)), &rights) < 0 && errno != ENOSYS) { @@ -2130,30 +2132,67 @@ main(int argc, char **argv) } #endif new_dlt = pcap_datalink(pd); - if (WFileName && new_dlt != dlt) - error("%s: new dlt does not match original", RFileName); - printinfo = get_print_info(new_dlt); - dlt_name = pcap_datalink_val_to_name(new_dlt); + if (new_dlt != dlt) { + /* + * The new file has a different + * link-layer header type from the + * previous one. + */ + if (WFileName != NULL) { + /* + * We're writing raw packets + * that match the filter to + * a pcap file. pcap files + * don't support multiple + * different link-layer + * header types, so we fail + * here. + */ + error("%s: new dlt does not match original", RFileName); + } + + /* + * We're printing the decoded packets; + * switch to the new DLT. + * + * To do that, we need to change + * the printer, change the DLT name, + * and recompile the filter with + * the new DLT. + */ + dlt = new_dlt; + ndo->ndo_if_printer = get_if_printer(ndo, dlt); + if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0) + error("%s", pcap_geterr(pd)); + } + + /* + * Set the filter on the new file. + */ + if (pcap_setfilter(pd, &fcode) < 0) + error("%s", pcap_geterr(pd)); + + /* + * Report the new file. + */ + dlt_name = pcap_datalink_val_to_name(dlt); if (dlt_name == NULL) { fprintf(stderr, "reading from file %s, link-type %u\n", - RFileName, new_dlt); + RFileName, dlt); } else { fprintf(stderr, "reading from file %s, link-type %s (%s)\n", - RFileName, dlt_name, - pcap_datalink_val_to_description(new_dlt)); + RFileName, dlt_name, + pcap_datalink_val_to_description(dlt)); } - if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0) - error("%s", pcap_geterr(pd)); - if (pcap_setfilter(pd, &fcode) < 0) - error("%s", pcap_geterr(pd)); } } } while (ret != NULL); free(cmdbuf); - exit(status == -1 ? 1 : 0); + pcap_freecode(&fcode); + exit_tcpdump(status == -1 ? 1 : 0); } /* make a clean exit on interrupts */ @@ -2193,7 +2232,7 @@ cleanup(int signo _U_) (void)fflush(stdout); info(1); } - exit(0); + exit_tcpdump(0); #endif } @@ -2212,14 +2251,14 @@ child_cleanup(int signo _U_) static void info(register int verbose) { - struct pcap_stat stat; + struct pcap_stat stats; /* * Older versions of libpcap didn't set ps_ifdrop on some * platforms; initialize it to 0 to handle that. */ - stat.ps_ifdrop = 0; - if (pcap_stats(pd, &stat) < 0) { + stats.ps_ifdrop = 0; + if (pcap_stats(pd, &stats) < 0) { (void)fprintf(stderr, "pcap_stats: %s\n", pcap_geterr(pd)); infoprint = 0; return; @@ -2234,38 +2273,52 @@ info(register int verbose) fputs(", ", stderr); else putc('\n', stderr); - (void)fprintf(stderr, "%u packet%s received by filter", stat.ps_recv, - PLURAL_SUFFIX(stat.ps_recv)); + (void)fprintf(stderr, "%u packet%s received by filter", stats.ps_recv, + PLURAL_SUFFIX(stats.ps_recv)); if (!verbose) fputs(", ", stderr); else putc('\n', stderr); - (void)fprintf(stderr, "%u packet%s dropped by kernel", stat.ps_drop, - PLURAL_SUFFIX(stat.ps_drop)); - if (stat.ps_ifdrop != 0) { + (void)fprintf(stderr, "%u packet%s dropped by kernel", stats.ps_drop, + PLURAL_SUFFIX(stats.ps_drop)); + if (stats.ps_ifdrop != 0) { if (!verbose) fputs(", ", stderr); else putc('\n', stderr); (void)fprintf(stderr, "%u packet%s dropped by interface\n", - stat.ps_ifdrop, PLURAL_SUFFIX(stat.ps_ifdrop)); + stats.ps_ifdrop, PLURAL_SUFFIX(stats.ps_ifdrop)); } else putc('\n', stderr); infoprint = 0; } #if defined(HAVE_FORK) || defined(HAVE_VFORK) +#ifdef HAVE_FORK +#define fork_subprocess() fork() +#else +#define fork_subprocess() vfork() +#endif static void compress_savefile(const char *filename) { -# ifdef HAVE_FORK - if (fork()) -# else - if (vfork()) -# endif + pid_t child; + + child = fork_subprocess(); + if (child == -1) { + fprintf(stderr, + "compress_savefile: fork failed: %s\n", + pcap_strerror(errno)); + return; + } + if (child != 0) { + /* Parent process. */ return; + } + /* - * Set to lowest priority so that this doesn't disturb the capture + * Child process. + * Set to lowest priority so that this doesn't disturb the capture. */ #ifdef NZERO setpriority(PRIO_PROCESS, 0, NZERO - 1); @@ -2274,15 +2327,15 @@ compress_savefile(const char *filename) #endif if (execlp(zflag, zflag, filename, (char *)NULL) == -1) fprintf(stderr, - "compress_savefile:execlp(%s, %s): %s\n", + "compress_savefile: execlp(%s, %s) failed: %s\n", zflag, filename, - strerror(errno)); -# ifdef HAVE_FORK + pcap_strerror(errno)); +#ifdef HAVE_FORK exit(1); -# else +#else _exit(1); -# endif +#endif } #else /* HAVE_FORK && HAVE_VFORK */ static void @@ -2325,7 +2378,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s /* If the time is greater than the specified window, rotate */ if (t - Gflag_time >= Gflag) { -#ifdef __FreeBSD__ +#ifdef HAVE_CAPSICUM FILE *fp; int fd; #endif @@ -2352,7 +2405,8 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s if (Cflag == 0 && Wflag > 0 && Gflag_count >= Wflag) { (void)fprintf(stderr, "Maximum file limit reached: %d\n", Wflag); - exit(0); + info(1); + exit_tcpdump(0); /* NOTREACHED */ } if (dump_info->CurrentFileName != NULL) @@ -2383,7 +2437,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE); capng_apply(CAPNG_SELECT_BOTH); #endif /* HAVE_LIBCAP_NG */ -#ifdef __FreeBSD__ +#ifdef HAVE_CAPSICUM fd = openat(dump_info->dirfd, dump_info->CurrentFileName, O_CREAT | O_WRONLY | O_TRUNC, 0644); @@ -2397,7 +2451,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s dump_info->CurrentFileName); } dump_info->p = pcap_dump_fopen(dump_info->pd, fp); -#else /* !__FreeBSD__ */ +#else /* !HAVE_CAPSICUM */ dump_info->p = pcap_dump_open(dump_info->pd, dump_info->CurrentFileName); #endif #ifdef HAVE_LIBCAP_NG @@ -2406,7 +2460,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s #endif /* HAVE_LIBCAP_NG */ if (dump_info->p == NULL) error("%s", pcap_geterr(pd)); -#ifdef __FreeBSD__ +#ifdef HAVE_CAPSICUM set_dumper_capsicum_rights(dump_info->p); #endif } @@ -2423,7 +2477,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s if (size == -1) error("ftell fails on output file"); if (size > Cflag) { -#ifdef __FreeBSD__ +#ifdef HAVE_CAPSICUM FILE *fp; int fd; #endif @@ -2455,7 +2509,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE); capng_apply(CAPNG_SELECT_BOTH); #endif /* HAVE_LIBCAP_NG */ -#ifdef __FreeBSD__ +#ifdef HAVE_CAPSICUM fd = openat(dump_info->dirfd, dump_info->CurrentFileName, O_CREAT | O_WRONLY | O_TRUNC, 0644); if (fd < 0) { @@ -2468,7 +2522,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s dump_info->CurrentFileName); } dump_info->p = pcap_dump_fopen(dump_info->pd, fp); -#else /* !__FreeBSD__ */ +#else /* !HAVE_CAPSICUM */ dump_info->p = pcap_dump_open(dump_info->pd, dump_info->CurrentFileName); #endif #ifdef HAVE_LIBCAP_NG @@ -2477,7 +2531,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s #endif /* HAVE_LIBCAP_NG */ if (dump_info->p == NULL) error("%s", pcap_geterr(pd)); -#ifdef __FreeBSD__ +#ifdef HAVE_CAPSICUM set_dumper_capsicum_rights(dump_info->p); #endif } @@ -2515,107 +2569,18 @@ dump_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) static void print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) { - struct print_info *print_info; - u_int hdrlen; - netdissect_options *ndo; - ++packets_captured; ++infodelay; - print_info = (struct print_info *)user; - ndo = print_info->ndo; - - if(ndo->ndo_packet_number) - ND_PRINT((ndo, "%5u ", packets_captured)); - - ts_print(ndo, &h->ts); - - /* - * Some printers want to 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; - - if(print_info->ndo_type) { - hdrlen = (*print_info->p.ndo_printer)(print_info->ndo, h, sp); - } else { - hdrlen = (*print_info->p.printer)(h, sp); - } - - /* - * Restore the original snapend, as a printer might have - * changed it. - */ - ndo->ndo_snapend = sp + h->caplen; - if (ndo->ndo_Xflag) { - /* - * Print the raw packet data in hex and ASCII. - */ - if (ndo->ndo_Xflag > 1) { - /* - * Include the link-layer header. - */ - hex_and_ascii_print(ndo, "\n\t", sp, h->caplen); - } else { - /* - * Don't include the link-layer header - and if - * we have nothing past the link-layer header, - * print nothing. - */ - if (h->caplen > hdrlen) - hex_and_ascii_print(ndo, "\n\t", sp + hdrlen, - h->caplen - hdrlen); - } - } else if (ndo->ndo_xflag) { - /* - * Print the raw packet data in hex. - */ - if (ndo->ndo_xflag > 1) { - /* - * Include the link-layer header. - */ - hex_print(ndo, "\n\t", sp, h->caplen); - } else { - /* - * Don't include the link-layer header - and if - * we have nothing past the link-layer header, - * print nothing. - */ - if (h->caplen > hdrlen) - hex_print(ndo, "\n\t", sp + hdrlen, - h->caplen - hdrlen); - } - } else if (ndo->ndo_Aflag) { - /* - * Print the raw packet data in ASCII. - */ - if (ndo->ndo_Aflag > 1) { - /* - * Include the link-layer header. - */ - ascii_print(ndo, sp, h->caplen); - } else { - /* - * Don't include the link-layer header - and if - * we have nothing past the link-layer header, - * print nothing. - */ - if (h->caplen > hdrlen) - ascii_print(ndo, sp + hdrlen, h->caplen - hdrlen); - } - } - - putchar('\n'); + pretty_print_packet((netdissect_options *)user, h, sp, packets_captured); --infodelay; if (infoprint) info(0); } -#ifdef WIN32 +#ifdef _WIN32 /* * XXX - there should really be libpcap calls to get the version * number as a string (the string would be generated from #defines @@ -2642,21 +2607,6 @@ print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) char Wpcap_version[]="3.1"; #endif -/* - * By default, print the specified data out in hex and ASCII. - */ -static void -ndo_default_print(netdissect_options *ndo, const u_char *bp, u_int length) -{ - hex_and_ascii_print(ndo, "\n\t", bp, length); /* pass on lf and indentation string */ -} - -void -default_print(const u_char *bp, u_int length) -{ - ndo_default_print(gndo, bp, length); -} - #ifdef SIGNAL_REQ_INFO RETSIGTYPE requestinfo(int signo _U_) { @@ -2674,17 +2624,13 @@ RETSIGTYPE requestinfo(int signo _U_) void CALLBACK verbose_stats_dump (UINT timer_id _U_, UINT msg _U_, DWORD_PTR arg _U_, DWORD_PTR dw1 _U_, DWORD_PTR dw2 _U_) { - struct pcap_stat stat; - - if (infodelay == 0 && pcap_stats(pd, &stat) >= 0) + if (infodelay == 0) fprintf(stderr, "Got %u\r", packets_captured); } #elif defined(HAVE_ALARM) static void verbose_stats_dump(int sig _U_) { - struct pcap_stat stat; - - if (infodelay == 0 && pcap_stats(pd, &stat) >= 0) + if (infodelay == 0) fprintf(stderr, "Got %u\r", packets_captured); alarm(1); } @@ -2696,37 +2642,38 @@ print_version(void) { extern char version[]; #ifndef HAVE_PCAP_LIB_VERSION -#if defined(WIN32) || defined(HAVE_PCAP_VERSION) +#if defined(_WIN32) || defined(HAVE_PCAP_VERSION) extern char pcap_version[]; -#else /* defined(WIN32) || defined(HAVE_PCAP_VERSION) */ +#else /* defined(_WIN32) || defined(HAVE_PCAP_VERSION) */ static char pcap_version[] = "unknown"; -#endif /* defined(WIN32) || defined(HAVE_PCAP_VERSION) */ +#endif /* defined(_WIN32) || defined(HAVE_PCAP_VERSION) */ #endif /* HAVE_PCAP_LIB_VERSION */ + const char *smi_version_string; #ifdef HAVE_PCAP_LIB_VERSION -#ifdef WIN32 +#ifdef _WIN32 (void)fprintf(stderr, "%s version %s, based on tcpdump version %s\n", program_name, WDversion, version); -#else /* WIN32 */ +#else /* _WIN32 */ (void)fprintf(stderr, "%s version %s\n", program_name, version); -#endif /* WIN32 */ +#endif /* _WIN32 */ (void)fprintf(stderr, "%s\n",pcap_lib_version()); #else /* HAVE_PCAP_LIB_VERSION */ -#ifdef WIN32 +#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 */ +#else /* _WIN32 */ (void)fprintf(stderr, "%s version %s\n", program_name, version); (void)fprintf(stderr, "libpcap version %s\n", pcap_version); -#endif /* WIN32 */ +#endif /* _WIN32 */ #endif /* HAVE_PCAP_LIB_VERSION */ #if defined(HAVE_LIBCRYPTO) && defined(SSLEAY_VERSION) (void)fprintf (stderr, "%s\n", SSLeay_version(SSLEAY_VERSION)); #endif -#ifdef USE_LIBSMI - (void)fprintf (stderr, "SMI-library: %s\n", smi_version_string); -#endif + smi_version_string = nd_smi_version_string(); + if (smi_version_string != NULL) + (void)fprintf (stderr, "SMI-library: %s\n", smi_version_string); } USES_APPLE_RST @@ -2735,7 +2682,7 @@ print_usage(void) { print_version(); (void)fprintf(stderr, -"Usage: %s [-aAbd" D_FLAG "efhH" I_FLAG J_FLAG "KlLnNOpqRStu" U_FLAG "vxX#]" B_FLAG_USAGE " [ -c count ]\n", program_name); +"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, "\t\t[ -C file_size ] [ -E algo:secret ] [ -F file ] [ -G seconds ]\n"); (void)fprintf(stderr, @@ -2756,48 +2703,10 @@ print_usage(void) #endif (void)fprintf(stderr, "[ -T type ] [ --version ] [ -V file ]\n"); (void)fprintf(stderr, -"\t\t[ -w file ] [ -W filecount ] [ -y datalinktype ] [ -z command ]\n"); +"\t\t[ -w file ] [ -W filecount ] [ -y datalinktype ] [ -z postrotate-command ]\n"); (void)fprintf(stderr, "\t\t[ -Z user ] [ expression ]\n"); } - - - -/* VARARGS */ -static void -ndo_error(netdissect_options *ndo _U_, const char *fmt, ...) -{ - va_list ap; - - (void)fprintf(stderr, "%s: ", program_name); - va_start(ap, fmt); - (void)vfprintf(stderr, fmt, ap); - va_end(ap); - if (*fmt) { - fmt += strlen(fmt); - if (fmt[-1] != '\n') - (void)fputc('\n', stderr); - } - exit(1); - /* NOTREACHED */ -} - -/* VARARGS */ -static void -ndo_warning(netdissect_options *ndo _U_, const char *fmt, ...) -{ - va_list ap; - - (void)fprintf(stderr, "%s: WARNING: ", program_name); - va_start(ap, fmt); - (void)vfprintf(stderr, fmt, ap); - va_end(ap); - if (*fmt) { - fmt += strlen(fmt); - if (fmt[-1] != '\n') - (void)fputc('\n', stderr); - } -} /* * Local Variables: * c-style: whitesmith diff --git a/contrib/tcpdump/timeval-operations.h b/contrib/tcpdump/timeval-operations.h new file mode 100644 index 0000000..4f4e85c --- /dev/null +++ b/contrib/tcpdump/timeval-operations.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2015 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. + */ + +#ifndef netdissect_timeval_operations_h +#define netdissect_timeval_operations_h + +/* Operations on timevals. */ + +#ifndef _MICRO_PER_SEC +#define _MICRO_PER_SEC 1000000 +#endif + +#ifndef _NANO_PER_SEC +#define _NANO_PER_SEC 1000000000 +#endif + +#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) \ + (((tvp)->tv_sec == (uvp)->tv_sec) ? \ + ((tvp)->tv_usec cmp (uvp)->tv_usec) : \ + ((tvp)->tv_sec cmp (uvp)->tv_sec)) + +#define netdissect_timevaladd(tvp, uvp, vvp, nano_prec) \ + do { \ + (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) { \ + (vvp)->tv_sec++; \ + (vvp)->tv_usec -= _NANO_PER_SEC; \ + } \ + } else { \ + if ((vvp)->tv_usec >= _MICRO_PER_SEC) { \ + (vvp)->tv_sec++; \ + (vvp)->tv_usec -= _MICRO_PER_SEC; \ + } \ + } \ + } while (0) + +#define netdissect_timevalsub(tvp, uvp, vvp, nano_prec) \ + do { \ + (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ + (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); \ + } \ + } while (0) + +#endif /* netdissect_timeval_operations_h */ diff --git a/contrib/tcpdump/udp.h b/contrib/tcpdump/udp.h index 743ddfa..409cc59 100644 --- a/contrib/tcpdump/udp.h +++ b/contrib/tcpdump/udp.h @@ -44,60 +44,273 @@ struct udphdr { uint16_t uh_sum; /* udp checksum */ }; -#define BOOTPS_PORT 67 /* RFC951 */ -#define BOOTPC_PORT 68 /* RFC951 */ -#define TFTP_PORT 69 /*XXX*/ -#define KERBEROS_PORT 88 /*XXX*/ -#define SUNRPC_PORT 111 /*XXX*/ -#define SNMP_PORT 161 /*XXX*/ -#define NTP_PORT 123 /*XXX*/ -#define SNMPTRAP_PORT 162 /*XXX*/ -#define ISAKMP_PORT 500 /*XXX*/ -#define SYSLOG_PORT 514 /* rfc3164 */ -#define TIMED_PORT 525 /*XXX*/ -#define RIP_PORT 520 /*XXX*/ -#define LDP_PORT 646 -#define AODV_PORT 654 /*XXX*/ -#define OLSR_PORT 698 /* rfc3626 */ -#define KERBEROS_SEC_PORT 750 /*XXX*/ -#define L2TP_PORT 1701 /*XXX*/ -#define SIP_PORT 5060 -#define ISAKMP_PORT_NATT 4500 /* rfc3948 */ -#define ISAKMP_PORT_USER1 7500 /*XXX - nonstandard*/ -#define ISAKMP_PORT_USER2 8500 /*XXX - nonstandard*/ -#define RX_PORT_LOW 7000 /*XXX*/ -#define RX_PORT_HIGH 7009 /*XXX*/ -#define NETBIOS_NS_PORT 137 -#define NETBIOS_DGRAM_PORT 138 -#define CISCO_AUTORP_PORT 496 /*XXX*/ -#define RADIUS_PORT 1645 -#define RADIUS_NEW_PORT 1812 -#define RADIUS_ACCOUNTING_PORT 1646 -#define RADIUS_NEW_ACCOUNTING_PORT 1813 -#define RADIUS_COA_PORT 3799 -#define HSRP_PORT 1985 /*XXX*/ -#define LMP_PORT 701 /* rfc4204 */ -#define LWRES_PORT 921 -#define VQP_PORT 1589 -#define ZEPHYR_SRV_PORT 2103 -#define ZEPHYR_CLT_PORT 2104 -#define VAT_PORT 3456 -#define MPLS_LSP_PING_PORT 3503 /* draft-ietf-mpls-lsp-ping-02.txt */ -#define BFD_CONTROL_PORT 3784 /* draft-katz-ward-bfd-v4v6-1hop-00.txt */ -#define BFD_ECHO_PORT 3785 /* draft-katz-ward-bfd-v4v6-1hop-00.txt */ -#define WB_PORT 4567 -#define SFLOW_PORT 6343 /* http://www.sflow.org/developers/specifications.php */ -#define LWAPP_DATA_PORT 12222 /* RFC 5412 */ -#define LWAPP_CONTROL_PORT 12223 /* RFC 5412 */ -#define OTV_PORT 8472 /* draft-hasmit-otv-04 */ -#define VXLAN_PORT 4789 /* RFC 7348 */ -#define GENEVE_PORT 6081 /* draft-gross-geneve-02 */ - -#ifdef INET6 -#define RIPNG_PORT 521 /* RFC 2080 */ -#define DHCP6_SERV_PORT 546 /*XXX*/ -#define DHCP6_CLI_PORT 547 /*XXX*/ -#define AHCP_PORT 5359 /* draft-chroboczek-ahcp-00 */ -#define BABEL_PORT 6696 /* RFC 6126 errata */ -#define BABEL_PORT_OLD 6697 /* RFC 6126 */ +#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 +#ifndef BOOTPC_PORT +#define BOOTPC_PORT 68 /* RFC951 */ +#endif +#ifndef TFTP_PORT +#define TFTP_PORT 69 /*XXX*/ +#endif +#ifndef KERBEROS_PORT +#define KERBEROS_PORT 88 /*XXX*/ +#endif +#ifndef SUNRPC_PORT +#define SUNRPC_PORT 111 /*XXX*/ +#endif +#ifndef NTP_PORT +#define NTP_PORT 123 /*XXX*/ +#endif +#ifndef NETBIOS_NS_PORT +#define NETBIOS_NS_PORT 137 /* RFC 1001, RFC 1002 */ +#endif +#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*/ +#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 */ +#endif +#ifndef CISCO_AUTORP_PORT +#define CISCO_AUTORP_PORT 496 /*XXX*/ +#endif +#ifndef ISAKMP_PORT +#define ISAKMP_PORT 500 /*XXX*/ +#endif +#ifndef SYSLOG_PORT +#define SYSLOG_PORT 514 /* rfc3164 */ +#endif +#ifndef RIP_PORT +#define RIP_PORT 520 /*XXX*/ +#endif +#ifndef RIPNG_PORT +#define RIPNG_PORT 521 /* RFC 2080 */ +#endif +#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 +#ifndef OLSR_PORT +#define OLSR_PORT 698 /* rfc3626 */ +#endif +#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 +#ifndef RADIUS_PORT +#define RADIUS_PORT 1645 /*XXX*/ +#endif +#ifndef RADIUS_ACCOUNTING_PORT +#define RADIUS_ACCOUNTING_PORT 1646 +#endif +#ifndef RADIUS_CISCO_COA_PORT +#define RADIUS_CISCO_COA_PORT 1700 +#endif +#ifndef L2TP_PORT +#define L2TP_PORT 1701 /*XXX*/ +#endif +#ifndef RADIUS_NEW_PORT +#define RADIUS_NEW_PORT 1812 /*XXX*/ +#endif +#ifndef RADIUS_NEW_ACCOUNTING_PORT +#define RADIUS_NEW_ACCOUNTING_PORT 1813 +#endif +#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*/ +#endif +#ifndef BFD_CONTROL_PORT +#define BFD_CONTROL_PORT 3784 /* RFC 5881 */ +#endif +#ifndef BFD_ECHO_PORT +#define BFD_ECHO_PORT 3785 /* RFC 5881 */ +#endif +#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 +#ifndef ISAKMP_PORT_NATT +#define ISAKMP_PORT_NATT 4500 /* rfc3948 */ +#endif +#ifndef WB_PORT +#define WB_PORT 4567 +#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 +#ifndef MULTICASTDNS_PORT +#define MULTICASTDNS_PORT 5353 /* RFC 6762 */ +#endif +#ifndef AHCP_PORT +#define AHCP_PORT 5359 /* draft-chroboczek-ahcp-00 */ +#endif +#ifndef GENEVE_PORT +#define GENEVE_PORT 6081 /* draft-gross-geneve-02 */ +#endif +#ifndef SFLOW_PORT +#define SFLOW_PORT 6343 /* http://www.sflow.org/developers/specifications.php */ +#endif +#ifndef BABEL_PORT +#define BABEL_PORT 6696 /* RFC 6126 errata */ +#endif +#ifndef BABEL_PORT_OLD +#define BABEL_PORT_OLD 6697 /* RFC 6126 */ +#endif +#ifndef RX_PORT_LOW +#define RX_PORT_LOW 7000 /*XXX*/ +#endif +#ifndef RX_PORT_HIGH +#define RX_PORT_HIGH 7009 /*XXX*/ +#endif +#ifndef ISAKMP_PORT_USER1 +#define ISAKMP_PORT_USER1 7500 /*XXX - nonstandard*/ +#endif +#ifndef HNCP_PORT +#define HNCP_PORT 8231 /* RFC 7788 */ +#endif +#ifndef OTV_PORT +#define OTV_PORT 8472 /* draft-hasmit-otv-04 */ +#endif +#ifndef ISAKMP_PORT_USER2 +#define ISAKMP_PORT_USER2 8500 /*XXX - nonstandard*/ +#endif +#ifndef LWAPP_DATA_PORT +#define LWAPP_DATA_PORT 12222 /* RFC 5412 */ +#endif +#ifndef LWAPP_CONTROL_PORT +#define LWAPP_CONTROL_PORT 12223 /* RFC 5412 */ #endif diff --git a/contrib/tcpdump/util-print.c b/contrib/tcpdump/util-print.c new file mode 100644 index 0000000..5db042a --- /dev/null +++ b/contrib/tcpdump/util-print.c @@ -0,0 +1,938 @@ +/* + * 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. + */ + +/* + * txtproto_print() derived from original code by Hannes Gredler + * (hannes@juniper.net): + * + * 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 "config.h" +#endif + +#include + +#include + +#ifdef HAVE_FCNTL_H +#include +#endif +#include +#include +#include +#include +#include + +#include "netdissect.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 + +/* + * Print out a character, filtering out the non-printable ones + */ +void +fn_print_char(netdissect_options *ndo, u_char c) +{ + 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)); +} + +/* + * 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. + */ +int +fn_print(netdissect_options *ndo, + register const u_char *s, register const u_char *ep) +{ + 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); +} + +/* + * Print out a null-terminated filename (or other ascii string) from + * a fixed-length buffer. + * If ep is NULL, assume no truncation check is needed. + * Return the number of bytes of string processed, including the + * terminating null, if not truncated. 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) +{ + register u_int bytes; + register u_char c; + + bytes = 0; + for (;;) { + if (n == 0 || (ep != NULL && s >= ep)) { + /* + * Truncated. This includes "no null before we + * got to the end of the fixed-length buffer". + * + * XXX - BOOTP says "null-terminated", which + * means the maximum length of the string, in + * bytes, is 1 less than the size of the buffer, + * as there must always be a terminating null. + */ + bytes = 0; + break; + } + + c = *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)); + } + return(bytes); +} + +/* + * Print out a counted 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, whichever is first. + */ +int +fn_printn(netdissect_options *ndo, + register const u_char *s, register u_int n, register const u_char *ep) +{ + register 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)); + } + 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. + */ +int +fn_printzp(netdissect_options *ndo, + register const u_char *s, register u_int n, + register const u_char *ep) +{ + register int ret; + register u_char c; + + ret = 1; /* assume truncated */ + while (n > 0 && (ep == NULL || s < ep)) { + n--; + 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 (n == 0) ? 0 : ret; +} + +/* + * Format the timestamp + */ +static char * +ts_format(netdissect_options *ndo +#ifndef HAVE_PCAP_SET_TSTAMP_PRECISION +_U_ +#endif +, int sec, int usec, char *buf) +{ + const char *format; + +#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION + switch (ndo->ndo_tstamp_precision) { + + case PCAP_TSTAMP_PRECISION_MICRO: + format = "%02d:%02d:%02d.%06u"; + break; + + case PCAP_TSTAMP_PRECISION_NANO: + format = "%02d:%02d:%02d.%09u"; + break; + + default: + format = "%02d:%02d:%02d.{unknown}"; + break; + } +#else + format = "%02d:%02d:%02d.%06u"; +#endif + + snprintf(buf, TS_BUF_SIZE, format, + sec / 3600, (sec % 3600) / 60, sec % 60, usec); + + return buf; +} + +/* + * Format the timestamp - Unix timeval style + */ +static char * +ts_unix_format(netdissect_options *ndo +#ifndef HAVE_PCAP_SET_TSTAMP_PRECISION +_U_ +#endif +, int sec, int usec, char *buf) +{ + const char *format; + +#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION + switch (ndo->ndo_tstamp_precision) { + + case PCAP_TSTAMP_PRECISION_MICRO: + format = "%u.%06u"; + break; + + case PCAP_TSTAMP_PRECISION_NANO: + format = "%u.%09u"; + break; + + default: + format = "%u.{unknown}"; + break; + } +#else + format = "%u.%06u"; +#endif + + snprintf(buf, TS_BUF_SIZE, format, + (unsigned)sec, (unsigned)usec); + + return buf; +} + +/* + * Print the timestamp + */ +void +ts_print(netdissect_options *ndo, + register 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; + int nano_prec; + + 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))); + 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))); + break; + + case 3: /* Microseconds/nanoseconds since previous packet */ + case 5: /* Microseconds/nanoseconds since first packet */ +#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION + switch (ndo->ndo_tstamp_precision) { + case PCAP_TSTAMP_PRECISION_MICRO: + nano_prec = 0; + break; + case PCAP_TSTAMP_PRECISION_NANO: + nano_prec = 1; + break; + default: + nano_prec = 0; + break; + } +#else + nano_prec = 0; +#endif + if (!(netdissect_timevalisset(&tv_ref))) + tv_ref = *tvp; /* set timestamp for first packet */ + + negative_offset = netdissect_timevalcmp(tvp, &tv_ref, <); + if (negative_offset) + netdissect_timevalsub(&tv_ref, tvp, &tv_result, nano_prec); + 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))); + + 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))); + break; + } +} + +/* + * Print an unsigned relative number of seconds (e.g. hold time, prune timer) + * in the form 5m1s. This does no truncation, so 32230861 seconds + * is represented as 1y1w1d1h1m1s. + */ +void +unsigned_relts_print(netdissect_options *ndo, + uint32_t secs) +{ + static const char *lengths[] = {"y", "w", "d", "h", "m", "s"}; + static const u_int seconds[] = {31536000, 604800, 86400, 3600, 60, 1}; + const char **l = lengths; + const u_int *s = seconds; + + if (secs == 0) { + ND_PRINT((ndo, "0s")); + return; + } + while (secs > 0) { + if (secs >= *s) { + ND_PRINT((ndo, "%d%s", secs / *s, *l)); + secs -= (secs / *s) * *s; + } + s++; + l++; + } +} + +/* + * Print a signed relative number of seconds (e.g. hold time, prune timer) + * in the form 5m1s. This does no truncation, so 32230861 seconds + * is represented as 1y1w1d1h1m1s. + */ +void +signed_relts_print(netdissect_options *ndo, + int32_t secs) +{ + if (secs < 0) { + ND_PRINT((ndo, "-")); + if (secs == INT32_MIN) { + /* + * -2^31; you can't fit its absolute value into + * a 32-bit signed integer. + * + * Just directly pass said absolute value to + * unsigned_relts_print() directly. + * + * (XXX - does ISO C guarantee that -(-2^n), + * when calculated and cast to an n-bit unsigned + * integer type, will have the value 2^n?) + */ + unsigned_relts_print(ndo, 2147483648U); + } else { + /* + * We now know -secs will fit into an int32_t; + * negate it and pass that to unsigned_relts_print(). + */ + unsigned_relts_print(ndo, -secs); + } + return; + } + unsigned_relts_print(ndo, secs); +} + +/* + * this is a generic routine for printing unknown data; + * we pass on the linefeed plus indentation string to + * get a proper output - returns 0 on error + */ + +int +print_unknown_data(netdissect_options *ndo, const u_char *cp,const char *ident,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)); + return(0); + } + hex_print(ndo, ident,cp,len); + return(1); /* everything is ok */ +} + +/* + * 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) +{ + if (lp != NULL) { + while (lp->s != NULL) { + if (lp->v == v) + return (lp->s); + ++lp; + } + } + if (fmt == NULL) + fmt = "#%d"; + + (void)snprintf(buf, bufsize, fmt, v); + return (const char *)buf; +} + +/* + * Convert a token value to a string; use "fmt" if not found. + */ +const char * +tok2str(register const struct tok *lp, register const char *fmt, + register u_int v) +{ + static char buf[4][TOKBUFSIZE]; + static int idx = 0; + char *ret; + + ret = buf[idx]; + idx = (idx+1) & 3; + return tok2strbuf(lp, fmt, v, ret, sizeof(buf[0])); +} + +/* + * Convert a bit token value to a string; use "fmt" if not found. + * this is useful for parsing bitfields, the output strings are seperated + * if the s field is positive. + */ +static char * +bittok2str_internal(register const struct tok *lp, register const char *fmt, + register u_int v, const char *sep) +{ + static char buf[256]; /* our stringbuffer */ + int buflen=0; + 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 */ + buflen+=snprintf(buf+buflen, sizeof(buf)-buflen, "%s%s", + sepstr, lp->s); + sepstr = sep; + break; + } + rotbit=rotbit<<1; /* no match - lets shift and try again */ + } + lp++; + } + + if (buflen == 0) + /* bummer - lets print the "unknown" message as advised in the fmt string if we got one */ + (void)snprintf(buf, sizeof(buf), fmt == NULL ? "#%08x" : fmt, v); + return (buf); +} + +/* + * 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. + */ +char * +bittok2str_nosep(register const struct tok *lp, register const char *fmt, + register 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. + */ +char * +bittok2str(register const struct tok *lp, register const char *fmt, + register u_int v) +{ + return (bittok2str_internal(lp, fmt, v, ", ")); +} + +/* + * Convert a value to a string using an array; the macro + * tok2strary() in is the public interface to + * this function and ensures that the second argument is + * correct for bounds-checking. + */ +const char * +tok2strary_internal(register const char **lp, int n, register const char *fmt, + register int v) +{ + static char buf[TOKBUFSIZE]; + + if (v >= 0 && v < n && lp[v] != NULL) + return lp[v]; + if (fmt == NULL) + fmt = "#%d"; + (void)snprintf(buf, sizeof(buf), fmt, v); + return (buf); +} + +/* + * Convert a 32-bit netmask to prefixlen if possible + * the function returns the prefix-len; if plen == -1 + * then conversion was not possible; + */ + +int +mask2plen(uint32_t mask) +{ + uint32_t bitmasks[33] = { + 0x00000000, + 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, + 0xf8000000, 0xfc000000, 0xfe000000, 0xff000000, + 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000, + 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000, + 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000, + 0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00, + 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0, + 0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff + }; + int prefix_len = 32; + + /* let's see if we can transform the mask into a prefixlen */ + while (prefix_len >= 0) { + if (bitmasks[prefix_len] == mask) + break; + prefix_len--; + } + return (prefix_len); +} + +int +mask62plen(const u_char *mask) +{ + u_char bitmasks[9] = { + 0x00, + 0x80, 0xc0, 0xe0, 0xf0, + 0xf8, 0xfc, 0xfe, 0xff + }; + int byte; + int cidr_len = 0; + + for (byte = 0; byte < 16; byte++) { + u_int bits; + + for (bits = 0; bits < (sizeof (bitmasks) / sizeof (bitmasks[0])); bits++) { + if (mask[byte] == bitmasks[bits]) { + cidr_len += bits; + break; + } + } + + if (mask[byte] != 0xff) + break; + } + return (cidr_len); +} + +/* + * Routine to print out information for text-based protocols such as FTP, + * HTTP, SMTP, RTSP, SIP, .... + */ +#define MAX_TOKEN 128 + +/* + * Fetch a token from a packet, starting at the specified index, + * and return the length of the token. + * + * Returns 0 on error; yes, this is indistinguishable from an empty + * token, but an "empty token" isn't a valid token - it just means + * either a space character at the beginning of the line (this + * includes a blank line) or no more tokens remaining on the line. + */ +static int +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; + + for (; idx < len; idx++) { + if (!ND_TTEST(*(pptr + idx))) { + /* ran past end of captured data */ + return (0); + } + if (!isascii(*(pptr + idx))) { + /* not an ASCII character */ + return (0); + } + if (isspace(*(pptr + idx))) { + /* end of token */ + break; + } + if (!isprint(*(pptr + idx))) { + /* not part of a command token or response code */ + return (0); + } + if (toklen + 2 > tbuflen) { + /* no room for this character and terminating '\0' */ + return (0); + } + tbuf[toklen] = *(pptr + idx); + toklen++; + } + if (toklen == 0) { + /* no token */ + return (0); + } + tbuf[toklen] = '\0'; + + /* + * Skip past any white space after the token, until we see + * an end-of-line (CR or LF). + */ + for (; idx < len; idx++) { + if (!ND_TTEST(*(pptr + idx))) { + /* ran past end of captured data */ + break; + } + if (*(pptr + idx) == '\r' || *(pptr + idx) == '\n') { + /* end of line */ + break; + } + if (!isascii(*(pptr + idx)) || !isprint(*(pptr + idx))) { + /* not a printable ASCII character */ + break; + } + if (!isspace(*(pptr + idx))) { + /* beginning of next token */ + break; + } + } + return (idx); +} + +/* + * Scan a buffer looking for a line ending - LF or CR-LF. + * Return the index of the character after the line ending or 0 if + * we encounter a non-ASCII or non-printable character or don't find + * 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) +{ + u_int startidx; + u_int linelen; + + startidx = idx; + while (idx < len) { + ND_TCHECK(*(pptr+idx)); + if (*(pptr+idx) == '\n') { + /* + * LF without CR; end of line. + * Skip the LF and print the line, with the + * exception of the LF. + */ + linelen = idx - startidx; + idx++; + goto print; + } else if (*(pptr+idx) == '\r') { + /* CR - any LF? */ + if ((idx+1) >= len) { + /* not in this packet */ + return (0); + } + ND_TCHECK(*(pptr+idx+1)); + if (*(pptr+idx+1) == '\n') { + /* + * CR-LF; end of line. + * Skip the CR-LF and print the line, with + * the exception of the CR-LF. + */ + linelen = idx - startidx; + idx += 2; + goto print; + } + + /* + * CR followed by something else; treat this + * as if it were binary data, and don't print + * it. + */ + return (0); + } else if (!isascii(*(pptr+idx)) || + (!isprint(*(pptr+idx)) && *(pptr+idx) != '\t')) { + /* + * Not a printable ASCII character and not a tab; + * treat this as if it were binary data, and + * don't print it. + */ + return (0); + } + idx++; + } + + /* + * 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)); + return (0); + +print: + ND_PRINT((ndo, "%s%.*s", prefix, (int)linelen, pptr + startidx)); + return (idx); +} + +void +txtproto_print(netdissect_options *ndo, const u_char *pptr, u_int len, + const char *protoname, 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; + + if (cmds != NULL) { + /* + * This protocol has more than just request and + * response lines; see whether this looks like a + * request or response. + */ + idx = fetch_token(ndo, pptr, 0, len, token, sizeof(token)); + if (idx != 0) { + /* Is this a valid request name? */ + while ((cmd = *cmds++) != NULL) { + if (ascii_strcasecmp((const char *)token, cmd) == 0) { + /* Yes. */ + is_reqresp = 1; + break; + } + } + + /* + * No - is this a valid response code (3 digits)? + * + * Is this token the response code, or is the next + * token the response code? + */ + if (flags & RESP_CODE_SECOND_TOKEN) { + /* + * Next token - get it. + */ + idx = fetch_token(ndo, pptr, idx, len, token, + sizeof(token)); + } + if (idx != 0) { + if (isdigit(token[0]) && isdigit(token[1]) && + isdigit(token[2]) && token[3] == '\0') { + /* Yes. */ + is_reqresp = 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. + */ + is_reqresp = 1; + } + + /* Capitalize the protocol name */ + for (pnp = protoname; *pnp != '\0'; pnp++) + ND_PRINT((ndo, "%c", toupper((u_char)*pnp))); + + if (is_reqresp) { + /* + * In non-verbose mode, just print the protocol, followed + * by the first line as the request or response info. + * + * In verbose mode, print lines as text until we run out + * of characters or see something that's not a + * printable-ASCII line. + */ + if (ndo->ndo_vflag) { + /* + * We're going to print all the text lines in the + * request or response; just print the length + * on the first line of the output. + */ + ND_PRINT((ndo, ", length: %u", len)); + for (idx = 0; + idx < len && (eol = print_txt_line(ndo, protoname, "\n\t", pptr, idx, len)) != 0; + idx = eol) + ; + } else { + /* + * Just print the first text line. + */ + print_txt_line(ndo, protoname, ": ", pptr, 0, len); + } + } +} + +void +safeputs(netdissect_options *ndo, + const u_char *s, const u_int maxlen) +{ + u_int idx = 0; + + while (*s && idx < maxlen) { + 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 +/* + * 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. + */ +void +unaligned_memcpy(void *p, const void *q, size_t l) +{ + memcpy(p, q, l); +} + +/* As with memcpy(), so with memcmp(). */ +int +unaligned_memcmp(const void *p, const void *q, size_t l) +{ + return (memcmp(p, q, l)); +} +#endif + diff --git a/contrib/tcpdump/util.c b/contrib/tcpdump/util.c deleted file mode 100644 index b37f3d8..0000000 --- a/contrib/tcpdump/util.c +++ /dev/null @@ -1,890 +0,0 @@ -/* - * 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. - */ - -/* - * txtproto_print() derived from original code by Hannes Gredler - * (hannes@juniper.net): - * - * 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. - */ - -#define NETDISSECT_REWORKED -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include - -#ifdef HAVE_FCNTL_H -#include -#endif -#include -#include -#include -#include - -#include "interface.h" - -/* - * Print out a null-terminated filename (or other ascii string). - * If ep is NULL, assume no truncation check is needed. - * Return true if truncated. - */ -int -fn_print(netdissect_options *ndo, - register const u_char *s, register const u_char *ep) -{ - 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); -} - -/* - * Print out a counted filename (or other ascii string). - * If ep is NULL, assume no truncation check is needed. - * Return true if truncated. - */ -int -fn_printn(netdissect_options *ndo, - register const u_char *s, register u_int n, register const u_char *ep) -{ - register 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)); - } - 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. - */ -int -fn_printzp(netdissect_options *ndo, - register const u_char *s, register u_int n, - register const u_char *ep) -{ - register int ret; - register u_char c; - - ret = 1; /* assume truncated */ - while (n > 0 && (ep == NULL || s < ep)) { - n--; - 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 (n == 0) ? 0 : ret; -} - -/* - * Format the timestamp - */ -static char * -ts_format(netdissect_options *ndo -#ifndef HAVE_PCAP_SET_TSTAMP_PRECISION -_U_ -#endif -, int sec, int usec) -{ - static char buf[sizeof("00:00:00.000000000")]; - const char *format; - -#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION - switch (ndo->ndo_tstamp_precision) { - - case PCAP_TSTAMP_PRECISION_MICRO: - format = "%02d:%02d:%02d.%06u"; - break; - - case PCAP_TSTAMP_PRECISION_NANO: - format = "%02d:%02d:%02d.%09u"; - break; - - default: - format = "%02d:%02d:%02d.{unknown precision}"; - break; - } -#else - format = "%02d:%02d:%02d.%06u"; -#endif - - snprintf(buf, sizeof(buf), format, - sec / 3600, (sec % 3600) / 60, sec % 60, usec); - - return buf; -} - -/* - * Print the timestamp - */ -void -ts_print(netdissect_options *ndo, - register const struct timeval *tvp) -{ - register int s; - struct tm *tm; - time_t Time; - static unsigned b_sec; - static unsigned b_usec; - int d_usec; - int d_sec; - - switch (ndo->ndo_tflag) { - - case 0: /* Default */ - s = (tvp->tv_sec + thiszone) % 86400; - ND_PRINT((ndo, "%s ", ts_format(ndo, s, tvp->tv_usec))); - break; - - case 1: /* No time stamp */ - break; - - case 2: /* Unix timeval style */ - ND_PRINT((ndo, "%u.%06u ", - (unsigned)tvp->tv_sec, - (unsigned)tvp->tv_usec)); - break; - - case 3: /* Microseconds since previous packet */ - case 5: /* Microseconds since first packet */ - if (b_sec == 0) { - /* init timestamp for first packet */ - b_usec = tvp->tv_usec; - b_sec = tvp->tv_sec; - } - - d_usec = tvp->tv_usec - b_usec; - d_sec = tvp->tv_sec - b_sec; - - while (d_usec < 0) { - d_usec += 1000000; - d_sec--; - } - - ND_PRINT((ndo, "%s ", ts_format(ndo, d_sec, d_usec))); - - if (ndo->ndo_tflag == 3) { /* set timestamp for last packet */ - b_sec = tvp->tv_sec; - b_usec = tvp->tv_usec; - } - 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))); - break; - } -} - -/* - * Print a relative number of seconds (e.g. hold time, prune timer) - * in the form 5m1s. This does no truncation, so 32230861 seconds - * is represented as 1y1w1d1h1m1s. - */ -void -relts_print(netdissect_options *ndo, - int secs) -{ - static const char *lengths[] = {"y", "w", "d", "h", "m", "s"}; - static const int seconds[] = {31536000, 604800, 86400, 3600, 60, 1}; - const char **l = lengths; - const int *s = seconds; - - if (secs == 0) { - ND_PRINT((ndo, "0s")); - return; - } - if (secs < 0) { - ND_PRINT((ndo, "-")); - secs = -secs; - } - while (secs > 0) { - if (secs >= *s) { - ND_PRINT((ndo, "%d%s", secs / *s, *l)); - secs -= (secs / *s) * *s; - } - s++; - l++; - } -} - -/* - * this is a generic routine for printing unknown data; - * we pass on the linefeed plus indentation string to - * get a proper output - returns 0 on error - */ - -int -print_unknown_data(netdissect_options *ndo, const u_char *cp,const char *ident,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)); - return(0); - } - hex_print(ndo, ident,cp,len); - return(1); /* everything is ok */ -} - -/* - * 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) -{ - if (lp != NULL) { - while (lp->s != NULL) { - if (lp->v == v) - return (lp->s); - ++lp; - } - } - if (fmt == NULL) - fmt = "#%d"; - - (void)snprintf(buf, bufsize, fmt, v); - return (const char *)buf; -} - -/* - * Convert a token value to a string; use "fmt" if not found. - */ -const char * -tok2str(register const struct tok *lp, register const char *fmt, - register u_int v) -{ - static char buf[4][128]; - static int idx = 0; - char *ret; - - ret = buf[idx]; - idx = (idx+1) & 3; - return tok2strbuf(lp, fmt, v, ret, sizeof(buf[0])); -} - -/* - * Convert a bit token value to a string; use "fmt" if not found. - * this is useful for parsing bitfields, the output strings are seperated - * if the s field is positive. - */ -static char * -bittok2str_internal(register const struct tok *lp, register const char *fmt, - register u_int v, const char *sep) -{ - static char buf[256]; /* our stringbuffer */ - int buflen=0; - 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 */ - buflen+=snprintf(buf+buflen, sizeof(buf)-buflen, "%s%s", - sepstr, lp->s); - sepstr = sep; - break; - } - rotbit=rotbit<<1; /* no match - lets shift and try again */ - } - lp++; - } - - if (buflen == 0) - /* bummer - lets print the "unknown" message as advised in the fmt string if we got one */ - (void)snprintf(buf, sizeof(buf), fmt == NULL ? "#%08x" : fmt, v); - return (buf); -} - -/* - * 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. - */ -char * -bittok2str_nosep(register const struct tok *lp, register const char *fmt, - register 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. - */ -char * -bittok2str(register const struct tok *lp, register const char *fmt, - register u_int v) -{ - return (bittok2str_internal(lp, fmt, v, ", ")); -} - -/* - * Convert a value to a string using an array; the macro - * tok2strary() in is the public interface to - * this function and ensures that the second argument is - * correct for bounds-checking. - */ -const char * -tok2strary_internal(register const char **lp, int n, register const char *fmt, - register int v) -{ - static char buf[128]; - - if (v >= 0 && v < n && lp[v] != NULL) - return lp[v]; - if (fmt == NULL) - fmt = "#%d"; - (void)snprintf(buf, sizeof(buf), fmt, v); - return (buf); -} - -/* - * Convert a 32-bit netmask to prefixlen if possible - * the function returns the prefix-len; if plen == -1 - * then conversion was not possible; - */ - -int -mask2plen(uint32_t mask) -{ - uint32_t bitmasks[33] = { - 0x00000000, - 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, - 0xf8000000, 0xfc000000, 0xfe000000, 0xff000000, - 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000, - 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000, - 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000, - 0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00, - 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0, - 0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff - }; - int prefix_len = 32; - - /* let's see if we can transform the mask into a prefixlen */ - while (prefix_len >= 0) { - if (bitmasks[prefix_len] == mask) - break; - prefix_len--; - } - return (prefix_len); -} - -#ifdef INET6 -int -mask62plen(const u_char *mask) -{ - u_char bitmasks[9] = { - 0x00, - 0x80, 0xc0, 0xe0, 0xf0, - 0xf8, 0xfc, 0xfe, 0xff - }; - int byte; - int cidr_len = 0; - - for (byte = 0; byte < 16; byte++) { - u_int bits; - - for (bits = 0; bits < (sizeof (bitmasks) / sizeof (bitmasks[0])); bits++) { - if (mask[byte] == bitmasks[bits]) { - cidr_len += bits; - break; - } - } - - if (mask[byte] != 0xff) - break; - } - return (cidr_len); -} -#endif /* INET6 */ - -/* - * Routine to print out information for text-based protocols such as FTP, - * HTTP, SMTP, RTSP, SIP, .... - */ -#define MAX_TOKEN 128 - -/* - * Fetch a token from a packet, starting at the specified index, - * and return the length of the token. - * - * Returns 0 on error; yes, this is indistinguishable from an empty - * token, but an "empty token" isn't a valid token - it just means - * either a space character at the beginning of the line (this - * includes a blank line) or no more tokens remaining on the line. - */ -static int -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; - - for (; idx < len; idx++) { - if (!ND_TTEST(*(pptr + idx))) { - /* ran past end of captured data */ - return (0); - } - if (!isascii(*(pptr + idx))) { - /* not an ASCII character */ - return (0); - } - if (isspace(*(pptr + idx))) { - /* end of token */ - break; - } - if (!isprint(*(pptr + idx))) { - /* not part of a command token or response code */ - return (0); - } - if (toklen + 2 > tbuflen) { - /* no room for this character and terminating '\0' */ - return (0); - } - tbuf[toklen] = *(pptr + idx); - toklen++; - } - if (toklen == 0) { - /* no token */ - return (0); - } - tbuf[toklen] = '\0'; - - /* - * Skip past any white space after the token, until we see - * an end-of-line (CR or LF). - */ - for (; idx < len; idx++) { - if (!ND_TTEST(*(pptr + idx))) { - /* ran past end of captured data */ - break; - } - if (*(pptr + idx) == '\r' || *(pptr + idx) == '\n') { - /* end of line */ - break; - } - if (!isascii(*(pptr + idx)) || !isprint(*(pptr + idx))) { - /* not a printable ASCII character */ - break; - } - if (!isspace(*(pptr + idx))) { - /* beginning of next token */ - break; - } - } - return (idx); -} - -/* - * Scan a buffer looking for a line ending - LF or CR-LF. - * Return the index of the character after the line ending or 0 if - * we encounter a non-ASCII or non-printable character or don't find - * 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) -{ - u_int startidx; - u_int linelen; - - startidx = idx; - while (idx < len) { - ND_TCHECK(*(pptr+idx)); - if (*(pptr+idx) == '\n') { - /* - * LF without CR; end of line. - * Skip the LF and print the line, with the - * exception of the LF. - */ - linelen = idx - startidx; - idx++; - goto print; - } else if (*(pptr+idx) == '\r') { - /* CR - any LF? */ - if ((idx+1) >= len) { - /* not in this packet */ - return (0); - } - ND_TCHECK(*(pptr+idx+1)); - if (*(pptr+idx+1) == '\n') { - /* - * CR-LF; end of line. - * Skip the CR-LF and print the line, with - * the exception of the CR-LF. - */ - linelen = idx - startidx; - idx += 2; - goto print; - } - - /* - * CR followed by something else; treat this - * as if it were binary data, and don't print - * it. - */ - return (0); - } else if (!isascii(*(pptr+idx)) || - (!isprint(*(pptr+idx)) && *(pptr+idx) != '\t')) { - /* - * Not a printable ASCII character and not a tab; - * treat this as if it were binary data, and - * don't print it. - */ - return (0); - } - idx++; - } - - /* - * 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)); - return (0); - -print: - ND_PRINT((ndo, "%s%.*s", prefix, (int)linelen, pptr + startidx)); - return (idx); -} - -void -txtproto_print(netdissect_options *ndo, const u_char *pptr, u_int len, - const char *protoname, 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; - - if (cmds != NULL) { - /* - * This protocol has more than just request and - * response lines; see whether this looks like a - * request or response. - */ - idx = fetch_token(ndo, pptr, 0, len, token, sizeof(token)); - if (idx != 0) { - /* Is this a valid request name? */ - while ((cmd = *cmds++) != NULL) { - if (strcasecmp((const char *)token, cmd) == 0) { - /* Yes. */ - is_reqresp = 1; - break; - } - } - - /* - * No - is this a valid response code (3 digits)? - * - * Is this token the response code, or is the next - * token the response code? - */ - if (flags & RESP_CODE_SECOND_TOKEN) { - /* - * Next token - get it. - */ - idx = fetch_token(ndo, pptr, idx, len, token, - sizeof(token)); - } - if (idx != 0) { - if (isdigit(token[0]) && isdigit(token[1]) && - isdigit(token[2]) && token[3] == '\0') { - /* Yes. */ - is_reqresp = 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. - */ - is_reqresp = 1; - } - - /* Capitalize the protocol name */ - for (pnp = protoname; *pnp != '\0'; pnp++) - ND_PRINT((ndo, "%c", toupper(*pnp))); - - if (is_reqresp) { - /* - * In non-verbose mode, just print the protocol, followed - * by the first line as the request or response info. - * - * In verbose mode, print lines as text until we run out - * of characters or see something that's not a - * printable-ASCII line. - */ - if (ndo->ndo_vflag) { - /* - * We're going to print all the text lines in the - * request or response; just print the length - * on the first line of the output. - */ - ND_PRINT((ndo, ", length: %u", len)); - for (idx = 0; - idx < len && (eol = print_txt_line(ndo, protoname, "\n\t", pptr, idx, len)) != 0; - idx = eol) - ; - } else { - /* - * Just print the first text line. - */ - print_txt_line(ndo, protoname, ": ", pptr, 0, len); - } - } -} - -/* VARARGS */ -void -error(const char *fmt, ...) -{ - va_list ap; - - (void)fprintf(stderr, "%s: ", program_name); - va_start(ap, fmt); - (void)vfprintf(stderr, fmt, ap); - va_end(ap); - if (*fmt) { - fmt += strlen(fmt); - if (fmt[-1] != '\n') - (void)fputc('\n', stderr); - } - exit(1); - /* NOTREACHED */ -} - -/* VARARGS */ -void -warning(const char *fmt, ...) -{ - va_list ap; - - (void)fprintf(stderr, "%s: WARNING: ", program_name); - va_start(ap, fmt); - (void)vfprintf(stderr, fmt, ap); - va_end(ap); - if (*fmt) { - fmt += strlen(fmt); - if (fmt[-1] != '\n') - (void)fputc('\n', stderr); - } -} - -/* - * Copy arg vector into a new buffer, concatenating arguments with spaces. - */ -char * -copy_argv(register char **argv) -{ - register char **p; - register u_int len = 0; - char *buf; - char *src, *dst; - - p = argv; - if (*p == 0) - return 0; - - while (*p) - len += strlen(*p++) + 1; - - buf = (char *)malloc(len); - if (buf == NULL) - error("copy_argv: malloc"); - - p = argv; - dst = buf; - while ((src = *p++) != NULL) { - while ((*dst++ = *src++) != '\0') - ; - dst[-1] = ' '; - } - dst[-1] = '\0'; - - return buf; -} - -/* - * On Windows, we need to open the file in binary mode, so that - * we get all the bytes specified by the size we get from "fstat()". - * On UNIX, that's not necessary. O_BINARY is defined on Windows; - * we define it as 0 if it's not defined, so it does nothing. - */ -#ifndef O_BINARY -#define O_BINARY 0 -#endif - -char * -read_infile(char *fname) -{ - register int i, fd, cc; - register char *cp; - struct stat 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) - error("can't stat %s: %s", fname, pcap_strerror(errno)); - - cp = malloc((u_int)buf.st_size + 1); - if (cp == NULL) - error("malloc(%d) for %s: %s", (u_int)buf.st_size + 1, - fname, pcap_strerror(errno)); - cc = read(fd, cp, (u_int)buf.st_size); - 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); - - close(fd); - /* replace "# comment" with spaces */ - for (i = 0; i < cc; i++) { - if (cp[i] == '#') - while (i < cc && cp[i] != '\n') - cp[i++] = ' '; - } - cp[cc] = '\0'; - return (cp); -} - -void -safeputs(netdissect_options *ndo, - const u_char *s, const u_int maxlen) -{ - u_int idx = 0; - - while (*s && idx < maxlen) { - 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 -/* - * 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. - */ -void -unaligned_memcpy(void *p, const void *q, size_t l) -{ - memcpy(p, q, l); -} - -/* As with memcpy(), so with memcmp(). */ -int -unaligned_memcmp(const void *p, const void *q, size_t l) -{ - return (memcmp(p, q, l)); -} -#endif diff --git a/contrib/tcpdump/vfprintf.c b/contrib/tcpdump/vfprintf.c index 6f3e15f..ae28bcf 100644 --- a/contrib/tcpdump/vfprintf.c +++ b/contrib/tcpdump/vfprintf.c @@ -30,7 +30,7 @@ #include #include -#include "interface.h" +#include "netdissect.h" /* * Stock 4.3 doesn't have vfprintf. -- cgit v1.1