release-request-323db86e-b638-4d24-8eb1-d2e3bf4a9d1a-for-git_oc-mr1-release-4017779 snap-temp-L47900000064949209

Change-Id: Ib9904f214285e747abcdcdd49ba5f31c5cabb630
diff --git a/.gitignore b/.gitignore
index 1939ca6..a9f9359 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,8 +2,8 @@
 *.rej
 Makefile
 *~
+*.a
 *.o
-config.h
 config.log
 config.cache
 config.status
@@ -14,6 +14,5 @@
 tcpdump
 tcpdump.1
 tcpdump-*.tar.gz
-version.c
 failure-outputs.txt
 autom4te.cache/
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index fcad877..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-language: c
-
-env:
-  - BUILD_LIBPCAP=true
-
-before_script:
-  - sudo apt-get install libssl-dev libssl0.9.8 libssl1.0.0
-  - if [ $BUILD_LIBPCAP == "true" ]; then ( cd ../ && git clone git://github.com/the-tcpdump-group/libpcap.git && cd libpcap && ./configure && make ); else sudo apt-get install libpcap-dev; fi
-
-script:
-  - ./configure
-  - make
-  - make check
diff --git a/Android.mk b/Android.mk
index becd082..1e5e3b2 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,164 +1,181 @@
 LOCAL_PATH:= $(call my-dir)
 
-tcpdump_src_files := \
-  addrtoname.c \
-  af.c \
-  bpf_dump.c \
-  checksum.c \
-  cpack.c \
-  gmpls.c \
-  gmt2local.c \
-  in_cksum.c \
-  ipproto.c \
-  l2vpn.c \
-  machdep.c \
-  nlpid.c \
-  oui.c \
-  parsenfsfh.c \
-  print-802_11.c \
-  print-802_15_4.c \
-  print-ah.c \
-  print-ahcp.c \
-  print-aodv.c \
-  print-aoe.c \
-  print-ap1394.c \
-  print-arcnet.c \
-  print-arp.c \
-  print-ascii.c \
-  print-atalk.c \
-  print-atm.c \
-  print-babel.c \
-  print-beep.c \
-  print-bfd.c \
-  print-bgp.c \
-  print-bootp.c \
-  print-bt.c \
-  print-calm-fast.c \
-  print-carp.c \
-  print-cdp.c \
-  print-cfm.c \
-  print-chdlc.c \
-  print-cip.c \
-  print-cnfp.c \
-  print-dccp.c \
-  print-decnet.c \
-  print-dhcp6.c \
-  print-domain.c \
-  print-dtp.c \
-  print-dvmrp.c \
-  print-eap.c \
-  print-egp.c \
-  print-eigrp.c \
-  print-enc.c \
-  print-esp.c \
-  print-ether.c \
-  print-fddi.c \
-  print-forces.c \
-  print-frag6.c \
-  print-fr.c \
-  print-ftp.c \
-  print-geneve.c \
-  print-geonet.c \
-  print-gre.c \
-  print-hsrp.c \
-  print-http.c \
-  print-icmp6.c \
-  print-icmp.c \
-  print-igmp.c \
-  print-igrp.c \
-  print-ip6.c \
-  print-ip6opts.c \
-  print-ip.c \
-  print-ipcomp.c \
-  print-ipfc.c \
-  print-ipnet.c \
-  print-ipx.c \
-  print-isakmp.c \
-  print-isoclns.c \
-  print-juniper.c \
-  print-krb.c \
-  print-l2tp.c \
-  print-lane.c \
-  print-ldp.c \
-  print-llc.c \
-  print-lldp.c \
-  print-lmp.c \
-  print-loopback.c \
-  print-lspping.c \
-  print-lwapp.c \
-  print-lwres.c \
-  print-m3ua.c \
-  print-mobile.c \
-  print-mobility.c \
-  print-mpcp.c \
-  print-mpls.c \
-  print-mptcp.c \
-  print-msdp.c \
-  print-msnlb.c \
-  print-nflog.c \
-  print-nfs.c \
-  print-ntp.c \
-  print-null.c \
-  print-olsr.c \
-  print-openflow-1.0.c \
-  print-openflow.c \
-  print-ospf6.c \
-  print-ospf.c \
-  print-otv.c \
-  print-pgm.c \
-  print-pim.c \
-  print-pktap.c \
-  print-ppi.c \
-  print-ppp.c \
-  print-pppoe.c \
-  print-pptp.c \
-  print-radius.c \
-  print-raw.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 \
-  print-sflow.c \
-  print-sip.c \
-  print-sl.c \
-  print-sll.c \
-  print-slow.c \
-  print-smb.c \
-  print-smtp.c \
-  print-snmp.c \
-  print-stp.c \
-  print-sunatm.c \
-  print-sunrpc.c \
-  print-symantec.c \
-  print-syslog.c \
-  print-tcp.c \
-  print-telnet.c \
-  print-tftp.c \
-  print-timed.c \
-  print-tipc.c \
-  print-token.c \
-  print-udld.c \
-  print-udp.c \
-  print-usb.c \
-  print-vjc.c \
-  print-vqp.c \
-  print-vrrp.c \
-  print-vtp.c \
-  print-vxlan.c \
-  print-wb.c \
-  print-zephyr.c \
-  print-zeromq.c \
-  setsignal.c \
-  signature.c \
-  smbutil.c \
-  tcpdump.c \
-  util.c \
-  version.c \
+# Based on the tcpdump Makefile...
+
+# CSRC
+tcpdump_src_files := setsignal.c tcpdump.c
+
+# LIBNETDISSECT_SRC
+tcpdump_src_files += \
+        addrtoname.c \
+        addrtostr.c \
+        af.c \
+        ascii_strcasecmp.c \
+        checksum.c \
+        cpack.c \
+        gmpls.c \
+        gmt2local.c \
+        in_cksum.c \
+        ipproto.c \
+        l2vpn.c \
+        machdep.c \
+        nlpid.c \
+        oui.c \
+        parsenfsfh.c \
+        print.c \
+        print-802_11.c \
+        print-802_15_4.c \
+        print-ah.c \
+        print-ahcp.c \
+        print-aodv.c \
+        print-aoe.c \
+        print-ap1394.c \
+        print-arcnet.c \
+        print-arp.c \
+        print-ascii.c \
+        print-atalk.c \
+        print-atm.c \
+        print-babel.c \
+        print-beep.c \
+        print-bfd.c \
+        print-bgp.c \
+        print-bootp.c \
+        print-bt.c \
+        print-calm-fast.c \
+        print-carp.c \
+        print-cdp.c \
+        print-cfm.c \
+        print-chdlc.c \
+        print-cip.c \
+        print-cnfp.c \
+        print-dccp.c \
+        print-decnet.c \
+        print-dhcp6.c \
+        print-domain.c \
+        print-dtp.c \
+        print-dvmrp.c \
+        print-eap.c \
+        print-egp.c \
+        print-eigrp.c \
+        print-enc.c \
+        print-esp.c \
+        print-ether.c \
+        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 \
+        print-ipx.c \
+        print-isakmp.c \
+        print-isoclns.c \
+        print-juniper.c \
+        print-krb.c \
+        print-l2tp.c \
+        print-lane.c \
+        print-ldp.c \
+        print-lisp.c \
+        print-llc.c \
+        print-lldp.c \
+        print-lmp.c \
+        print-loopback.c \
+        print-lspping.c \
+        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 \
+        print-msdp.c \
+        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 \
+        print-pktap.c \
+        print-ppi.c \
+        print-ppp.c \
+        print-pppoe.c \
+        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 \
+        print-sflow.c \
+        print-sip.c \
+        print-sl.c \
+        print-sll.c \
+        print-slow.c \
+        print-smtp.c \
+        print-snmp.c \
+        print-stp.c \
+        print-sunatm.c \
+        print-sunrpc.c \
+        print-symantec.c \
+        print-syslog.c \
+        print-tcp.c \
+        print-telnet.c \
+        print-tftp.c \
+        print-timed.c \
+        print-tipc.c \
+        print-token.c \
+        print-udld.c \
+        print-udp.c \
+        print-usb.c \
+        print-vjc.c \
+        print-vqp.c \
+        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 \
+        strtoaddr.c \
+        util-print.c \
+
+# LOCALSRC
+tcpdump_src_files += print-smb.c smbutil.c
+
+# GENSRC
+tcpdump_src_files += version.c
 
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES := $(tcpdump_src_files)
@@ -168,6 +185,8 @@
 LOCAL_CFLAGS += -Werror
 # http://b/33566695
 LOCAL_CFLAGS += -Wno-address-of-packed-member
+LOCAL_CFLAGS += -Wno-sign-compare
+LOCAL_CFLAGS += -Wno-incompatible-pointer-types-discards-qualifiers
 LOCAL_SHARED_LIBRARIES += libssl libcrypto libpcap
 LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
 LOCAL_MODULE_TAGS := debug
diff --git a/CHANGES b/CHANGES
index 38769f2..7c4be17 100644
--- a/CHANGES
+++ b/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 @@
 
 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/CONTRIBUTING b/CONTRIBUTING
new file mode 100644
index 0000000..5d3b46e
--- /dev/null
+++ b/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/<username>/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/CREDITS b/CREDITS
index a21311a..5242967 100644
--- a/CREDITS
+++ b/CREDITS
@@ -20,11 +20,13 @@
     Andrea Bittau                 <a dot bittau at cs dot ucl dot ac dot uk>
     Andrew Brown                  <atatat at atatdot dot net>
     Andrew Church                 <andrew at users dot sourceforge dot net>
+    Andrew Darqui                 <andrew dot darqui at gmail dot com>
     Andrew Hintz                  <adhintz at users dot sourceforge dot net>
     Andrew Nording                <andrew at nording dot ru>
     Andrew Tridgell               <tridge at linuxcare dot com>
     Andy Heffernan                <ahh at juniper dot net>
     Anton Bernal                  <anton at juniper dot net>
+    Antonin Décimo                <antonin dot decimo at gmail dot com>
     Arkadiusz Miskiewicz          <misiek at pld dot org dot pl>
     Armando L. Caro Jr.           <acaro at mail dot eecis dot udel dot edu>
     Arnaldo Carvalho de Melo      <acme at ghostprotocols dot net>
@@ -33,6 +35,7 @@
     Ben Byer                      <bushing at sourceforge dot net>
     Ben Smithurst                 <ben at scientia dot demon dot co dot uk>
     Bert Vermeulen                <bert at biot dot com>
+    Bill Parker                   <wp02855 at gmail dot com>
     Bjoern A. Zeeb                <bzeeb at Zabbadoz dot NeT>
     Bram                          <tcpdump at mail dot wizbit dot be>
     Brent L. Bates                <blbates at vigyan dot com>
@@ -95,6 +98,7 @@
     Jason R. Thorpe               <thorpej at netbsd dot org>
     Jefferson Ogata               <jogata at nodc dot noaa dot gov>
     Jeffrey Hutzelman             <jhutz at cmu dot edu>
+    Jean-Raphaël Gaglione         <jr dot gaglione at yahoo dot fr>
     Jesper Peterson               <jesper at endace dot com>
     Jesse Gross                   <jesse at nicira dot com>
     Jim Hutchins                  <jim at ca dot sandia dot gov>
@@ -119,7 +123,7 @@
     Larry Lile                    <lile at stdio dot com>
     Lennert Buytenhek             <buytenh at gnu dot org>
     Loganaden Velvindron          <logan at elandsys dot com>
-    Longinus00                    <Longinus00 at gmail dot com>
+    Daniel Lee                    <Longinus00 at gmail dot com>
     Loris Degioanni               <loris at netgroup-serv dot polito dot it>
     Love Hörnquist-Åstrand        <lha at stacken dot kth dot se>
     Lucas C. Villa Real           <lucasvr at us dot ibm dot com>
@@ -134,6 +138,7 @@
     Markus Schöpflin              <schoepflin at sourceforge dot net>
     Marshall Rose                 <mrose at dbc dot mtview dot ca dot us>
     Martin Husemann               <martin at netbsd dot org>
+    Matthieu Boutier              <boutier at pps dot univ-paris-diderot dot fr>
     Max Laier                     <max at love2party dot net>
     Michael A. Meffie III         <meffie at sourceforge dot net>
     Michael Madore                <mmadore at turbolinux dot com>
diff --git a/INSTALL.txt b/INSTALL.txt
index dcb52b8..f91d004 100644
--- a/INSTALL.txt
+++ b/INSTALL.txt
@@ -49,9 +49,10 @@
 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 @@
 		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 @@
 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/Makefile.in b/Makefile.in
index a0dc559..c18d5ed 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -74,7 +74,9 @@
 
 LIBNETDISSECT_SRC=\
 	addrtoname.c \
+	addrtostr.c \
 	af.c \
+	ascii_strcasecmp.c \
 	checksum.c \
 	cpack.c \
 	gmpls.c \
@@ -86,6 +88,7 @@
 	nlpid.c \
 	oui.c \
 	parsenfsfh.c \
+	print.c \
 	print-802_11.c \
 	print-802_15_4.c \
 	print-ah.c \
@@ -98,6 +101,7 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 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 @@
 	oui.h \
 	pcap-missing.h \
 	ppp.h \
+	print.h \
 	rpc_auth.h \
 	rpc_msg.h \
 	rpl.h \
@@ -271,14 +293,15 @@
 	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 @@
 
 EXTRA_DIST = \
 	CHANGES \
+	CONTRIBUTING \
 	CREDITS \
 	INSTALL.txt \
 	LICENSE \
 	Makefile.in \
 	Makefile-devel-adds \
+	PLATFORMS \
+	README \
 	README.md \
 	Readme.Win32 \
 	VERSION \
@@ -314,14 +340,9 @@
 	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 @@
 	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`
 
@@ -369,16 +382,8 @@
 	$(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 @@
 check: tcpdump
 	(cd tests && ./TESTrun.sh)
 
+extags: $(TAGFILES)
+	ctags $(TAGFILES)
+
 tags: $(TAGFILES)
 	ctags -wtd $(TAGFILES)
 
diff --git a/PLATFORMS b/PLATFORMS
new file mode 100644
index 0000000..ec85e59
--- /dev/null
+++ b/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/README b/README
new file mode 120000
index 0000000..42061c0
--- /dev/null
+++ b/README
@@ -0,0 +1 @@
+README.md
\ No newline at end of file
diff --git a/README.version b/README.version
index 4c5f0c1..1e3229b 100644
--- a/README.version
+++ b/README.version
@@ -1,3 +1,3 @@
-URL: http://www.tcpdump.org/release/tcpdump-4.7.4.tar.gz
-Version: 4.7.4
+URL: http://www.tcpdump.org/release/tcpdump-4.9.0.tar.gz
+Version: 4.9.0
 BugComponent: 119452
diff --git a/VERSION b/VERSION
index b48b2de..6ed7776 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-4.7.4
+4.9.0
diff --git a/aclocal.m4 b/aclocal.m4
index 285000d..ea0f624 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -219,6 +219,36 @@
 ])
 
 dnl
+dnl Check whether, if you pass an unknown warning option to the
+dnl compiler, it fails or just prints a warning message and succeeds.
+dnl Set ac_lbl_unknown_warning_option_error to the appropriate flag
+dnl to force an error if it would otherwise just print a warning message
+dnl and succeed.
+dnl
+AC_DEFUN(AC_LBL_CHECK_UNKNOWN_WARNING_OPTION_ERROR,
+    [
+	AC_MSG_CHECKING([whether the compiler fails when given an unknown warning option])
+	save_CFLAGS="$CFLAGS"
+	CFLAGS="$CFLAGS -Wxyzzy-this-will-never-succeed-xyzzy"
+	AC_TRY_COMPILE(
+	    [],
+	    [return 0],
+	    [
+		AC_MSG_RESULT([no])
+		#
+		# 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"
+	    ],
+	    [
+		AC_MSG_RESULT([yes])
+	    ])
+	CFLAGS="$save_CFLAGS"
+    ])
+
+dnl
 dnl Check whether the compiler option specified as the second argument
 dnl is supported by the compiler and, if so, add it to the macro
 dnl specified as the first argument
@@ -227,7 +257,18 @@
     [
 	AC_MSG_CHECKING([whether the compiler supports the $2 option])
 	save_CFLAGS="$CFLAGS"
-	CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors $2"
+	if expr "x$2" : "x-W.*" >/dev/null
+	then
+	    CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error $2"
+	elif expr "x$2" : "x-f.*" >/dev/null
+	then
+	    CFLAGS="$CFLAGS -Werror $2"
+	elif expr "x$2" : "x-m.*" >/dev/null
+	then
+	    CFLAGS="$CFLAGS -Werror $2"
+	else
+	    CFLAGS="$CFLAGS $2"
+	fi
 	AC_TRY_COMPILE(
 	    [],
 	    [return 0],
@@ -942,11 +983,18 @@
 	    # Skip all the warning option stuff on some compilers.
 	    #
 	    if test "$ac_lbl_cc_dont_try_gcc_dashW" != yes; then
+		    AC_LBL_CHECK_UNKNOWN_WARNING_OPTION_ERROR()
 		    AC_LBL_CHECK_COMPILER_OPT($1, -Wall)
 		    AC_LBL_CHECK_COMPILER_OPT($1, -Wmissing-prototypes)
 		    AC_LBL_CHECK_COMPILER_OPT($1, -Wstrict-prototypes)
 		    AC_LBL_CHECK_COMPILER_OPT($1, -Wwrite-strings)
 		    AC_LBL_CHECK_COMPILER_OPT($1, -Wpointer-arith)
+		    AC_LBL_CHECK_COMPILER_OPT($1, -Wcast-qual)
+		    AC_LBL_CHECK_COMPILER_OPT($1, -Wshadow)
+		    AC_LBL_CHECK_COMPILER_OPT($1, -Wdeclaration-after-statement)
+		    AC_LBL_CHECK_COMPILER_OPT($1, -Wpedantic)
+		    AC_LBL_CHECK_COMPILER_OPT($1, -Wold-style-definition)
+		    AC_LBL_CHECK_COMPILER_OPT($1, -Wused-but-marked-unused)
 		    AC_LBL_CHECK_COMPILER_OPT($1, -W)
 	    fi
 	    AC_LBL_CHECK_DEPENDENCY_GENERATION_OPT()
@@ -1114,131 +1162,6 @@
 dnl SUCH DAMAGE.
 
 dnl
-dnl Checks to see if AF_INET6 is defined
-AC_DEFUN(AC_CHECK_AF_INET6, [
-	AC_MSG_CHECKING(for AF_INET6)
-	AC_CACHE_VAL($1,
-	AC_TRY_COMPILE([
-#		include <sys/types.h>
-#		include <sys/socket.h>],
-		[int a = AF_INET6],
-		$1=yes,
-		$1=no))
-	AC_MSG_RESULT($$1)
-		if test $$1 = yes ; then
-			AC_DEFINE(HAVE_AF_INET6)
-	fi
-])
-
-dnl
-dnl Checks to see if the sockaddr struct has the 4.4 BSD sa_len member
-dnl borrowed from LBL libpcap
-AC_DEFUN(AC_CHECK_SA_LEN, [
-	AC_MSG_CHECKING(if sockaddr struct has sa_len member)
-	AC_CACHE_VAL($1,
-	AC_TRY_COMPILE([
-#		include <sys/types.h>
-#		include <sys/socket.h>],
-		[u_int i = sizeof(((struct sockaddr *)0)->sa_len)],
-		$1=yes,
-		$1=no))
-	AC_MSG_RESULT($$1)
-		if test $$1 = yes ; then
-			AC_DEFINE(HAVE_SOCKADDR_SA_LEN)
-	fi
-])
-
-dnl
-dnl Checks for addrinfo structure
-AC_DEFUN(AC_STRUCT_ADDRINFO, [
-	AC_MSG_CHECKING(for addrinfo)
-	AC_CACHE_VAL($1,
-	AC_TRY_COMPILE([
-#		include <netdb.h>],
-		[struct addrinfo a],
-		$1=yes,
-		$1=no))
-	AC_MSG_RESULT($$1)
-	if test $$1 = yes; then
-		AC_DEFINE(HAVE_ADDRINFO, 1,
-		    [define if you have the addrinfo function])
-	else
-		AC_DEFINE(NEED_ADDRINFO_H, 1,
-		    [define if you need to include missing/addrinfo.h])
-	fi
-])
-
-dnl
-dnl Checks for NI_MAXSERV
-AC_DEFUN(AC_NI_MAXSERV, [
-	AC_MSG_CHECKING(for NI_MAXSERV)
-	AC_CACHE_VAL($1,
-	AC_EGREP_CPP(yes, [#include <netdb.h>
-#ifdef NI_MAXSERV
-yes
-#endif],
-		$1=yes,
-		$1=no))
-	AC_MSG_RESULT($$1)
-	if test $$1 != yes; then
-		AC_DEFINE(NEED_ADDRINFO_H)
-	fi
-])
-
-dnl
-dnl Checks for NI_NAMEREQD
-AC_DEFUN(AC_NI_NAMEREQD, [
-	AC_MSG_CHECKING(for NI_NAMEREQD)
-	AC_CACHE_VAL($1,
-	AC_EGREP_CPP(yes, [#include <netdb.h>
-#ifdef NI_NOFQDN
-yes
-#endif],
-		$1=yes,
-		$1=no))
-	AC_MSG_RESULT($$1)
-	if test $$1 != yes; then
-		AC_DEFINE(NEED_ADDRINFO_H)
-	fi
-])
-
-dnl
-dnl Checks for sockaddr_storage structure
-AC_DEFUN(AC_STRUCT_SA_STORAGE, [
-	AC_MSG_CHECKING(for sockaddr_storage)
-	AC_CACHE_VAL($1,
-	AC_TRY_COMPILE([
-#		include <sys/types.h>
-#		include <sys/socket.h>],
-		[struct sockaddr_storage s],
-		$1=yes,
-		$1=no))
-	AC_MSG_RESULT($$1)
-	if test $$1 = yes; then
-		AC_DEFINE(HAVE_SOCKADDR_STORAGE, 1,
-		    [define if you have struct sockaddr_storage])
-	fi
-])
-
-dnl
-dnl check for h_errno
-AC_DEFUN(AC_VAR_H_ERRNO, [
-	AC_MSG_CHECKING(for h_errno)
-	AC_CACHE_VAL(ac_cv_var_h_errno,
-	AC_TRY_COMPILE([
-#		include <sys/types.h>
-#		include <netdb.h>],
-		[int foo = h_errno;],
-		ac_cv_var_h_errno=yes,
-		ac_cv_var_h_errno=no))
-	AC_MSG_RESULT($ac_cv_var_h_errno)
-	if test "$ac_cv_var_h_errno" = "yes"; then
-		AC_DEFINE(HAVE_H_ERRNO, 1,
-		    [define if you have the h_errno variable])
-	fi
-])
-
-dnl
 dnl Test for __attribute__
 dnl
 
diff --git a/addrtoname.c b/addrtoname.c
index d0437fe..6975b71 100644
--- a/addrtoname.c
+++ b/addrtoname.c
@@ -22,12 +22,11 @@
  *  and address to string conversion routines
  */
 
-#define NETDISSECT_REWORKED
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #ifdef USE_ETHER_NTOHOST
 #ifdef HAVE_NETINET_IF_ETHER_H
@@ -58,8 +57,10 @@
 #include <string.h>
 #include <stdlib.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
+#include "addrtostr.h"
+#include "ethertype.h"
 #include "llc.h"
 #include "setsignal.h"
 #include "extract.h"
@@ -72,7 +73,7 @@
 /*
  * 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
@@ -90,7 +91,7 @@
 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
@@ -128,9 +129,8 @@
 	}
 }
 #define gethostbyaddr win32_gethostbyaddr
-#endif /* INET6 & WIN32 */
+#endif /* _WIN32 */
 
-#ifdef INET6
 struct h6namemem {
 	struct in6_addr addr;
 	char *name;
@@ -138,7 +138,6 @@
 };
 
 static struct h6namemem h6nametable[HASHNAMESIZE];
-#endif /* INET6 */
 
 struct enamemem {
 	u_short e_addr0;
@@ -205,7 +204,7 @@
  *
  * 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
@@ -223,7 +222,7 @@
 {
 	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)];
@@ -232,7 +231,7 @@
 			return (p->name);
 	}
 	p->addr = addr;
-	p->nxt = newhnamemem();
+	p->nxt = newhnamemem(ndo);
 
 	/*
 	 * Print names unless:
@@ -248,6 +247,9 @@
 			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, '.');
@@ -258,10 +260,11 @@
 		}
 	}
 	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.
@@ -277,7 +280,7 @@
 			uint16_t d;
 		} addra;
 	} addr;
-	static struct h6namemem *p;		/* static for longjmp() */
+	struct h6namemem *p;
 	register const char *cp;
 	char ntop_buf[INET6_ADDRSTRLEN];
 
@@ -288,7 +291,7 @@
 			return (p->name);
 	}
 	p->addr = addr.addr;
-	p->nxt = newh6namemem();
+	p->nxt = newh6namemem(ndo);
 
 	/*
 	 * Do not print names if -n was given.
@@ -299,6 +302,9 @@
 			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, '.');
@@ -308,11 +314,12 @@
 			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";
 
@@ -320,7 +327,7 @@
 /* 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;
@@ -342,7 +349,7 @@
 	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;
 }
@@ -353,7 +360,8 @@
  */
 
 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;
@@ -385,12 +393,12 @@
 
 	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;
 }
@@ -398,14 +406,15 @@
 /* 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];
@@ -418,22 +427,23 @@
 		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;
 }
@@ -441,7 +451,7 @@
 /* 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;
@@ -461,7 +471,7 @@
 	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;
 }
@@ -475,21 +485,18 @@
 	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);
 		}
 	}
@@ -510,11 +517,13 @@
 	} 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;
@@ -522,7 +531,7 @@
 	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);
 
@@ -537,12 +546,15 @@
 	*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;
@@ -557,13 +569,13 @@
 	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) {
@@ -576,7 +588,7 @@
 }
 
 const char *
-etherproto_string(u_short port)
+etherproto_string(netdissect_options *ndo, u_short port)
 {
 	register char *cp;
 	register struct hnamemem *tp;
@@ -588,7 +600,7 @@
 			return (tp->name);
 
 	tp->addr = i;
-	tp->nxt = newhnamemem();
+	tp->nxt = newhnamemem(ndo);
 
 	cp = buf;
 	NTOHS(port);
@@ -598,18 +610,20 @@
 	*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;
 
@@ -625,12 +639,15 @@
 	}
 	*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;
@@ -639,13 +656,13 @@
 	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];
@@ -660,7 +677,7 @@
 }
 
 const char *
-tcpport_string(u_short port)
+tcpport_string(netdissect_options *ndo, u_short port)
 {
 	register struct hnamemem *tp;
 	register uint32_t i = port;
@@ -671,15 +688,17 @@
 			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;
@@ -690,15 +709,17 @@
 			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;
@@ -710,7 +731,7 @@
 			return (tp->name);
 
 	tp->addr = i;
-	tp->nxt = newhnamemem();
+	tp->nxt = newhnamemem(ndo);
 
 	cp = buf;
 	NTOHS(port);
@@ -720,6 +741,8 @@
 	*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);
 }
 
@@ -748,25 +771,44 @@
 			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;
@@ -778,7 +820,7 @@
 			table = table->nxt;
 		table->name = eproto_db[i].s;
 		table->addr = htons(eproto_db[i].p);
-		table->nxt = newhnamemem();
+		table->nxt = newhnamemem(ndo);
 	}
 }
 
@@ -799,7 +841,7 @@
  * types.
  */
 static void
-init_protoidarray(void)
+init_protoidarray(netdissect_options *ndo)
 {
 	register int i;
 	register struct protoidmem *tp;
@@ -813,12 +855,15 @@
 		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;
@@ -850,7 +895,7 @@
  * 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;
@@ -864,8 +909,11 @@
 	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);
 	}
@@ -873,7 +921,7 @@
 
 	/* 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;
@@ -881,14 +929,12 @@
 #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
@@ -1114,7 +1160,7 @@
 };
 
 static void
-init_ipxsaparray(void)
+init_ipxsaparray(netdissect_options *ndo)
 {
 	register int i;
 	register struct hnamemem *table;
@@ -1126,7 +1172,7 @@
 			table = table->nxt;
 		table->name = ipxsap_db[i].s;
 		table->addr = htons(ipxsap_db[i].v);
-		table->nxt = newhnamemem();
+		table->nxt = newhnamemem(ndo);
 	}
 }
 
@@ -1149,11 +1195,11 @@
 		 */
 		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 *
@@ -1161,24 +1207,24 @@
 {
 	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;
@@ -1188,17 +1234,16 @@
 		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;
@@ -1208,13 +1253,12 @@
 		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/addrtoname.h b/addrtoname.h
index b07d8b2..72e5ef1 100644
--- a/addrtoname.h
+++ b/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 @@
 
 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/missing/inet_ntop.c b/addrtostr.c
similarity index 77%
rename from missing/inet_ntop.c
rename to addrtostr.c
index 8c6f7eb..9287562 100644
--- a/missing/inet_ntop.c
+++ b/addrtostr.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
@@ -17,7 +17,7 @@
  * 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.
+ *      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
@@ -40,9 +40,11 @@
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
+#include "addrtostr.h"
 
 #include <stdio.h>
+#include <string.h>
 
 /*
  *
@@ -56,13 +58,12 @@
 #define INT16SZ     2    /* word size */
 #endif
 
-static const char *
-inet_ntop_v4 (const void *src, char *dst, size_t size)
+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;
-    struct in_addr *addr = (struct in_addr *)src;
-    u_long a = ntohl(addr->s_addr);
     const char *orig_dst = dst;
 
     if (size < INET_ADDRSTRLEN) {
@@ -70,7 +71,7 @@
 	return NULL;
     }
     for (i = 0; i < 4; ++i) {
-	int n = (a >> (24 - i * 8)) & 0xFF;
+    	int n = *srcaddr++;
 	int non_zerop = 0;
 
 	if (non_zerop || n / 100 > 0) {
@@ -91,12 +92,11 @@
     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)
+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
@@ -105,14 +105,16 @@
    * 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;
+  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;
+  u_int  i;
 
   /* Preprocess:
    *  Copy the input (bytewise) array into a wordwise array.
@@ -120,7 +122,7 @@
    */
   memset (words, 0, sizeof(words));
   for (i = 0; i < IN6ADDRSZ; i++)
-      words[i/2] |= (src[i] << ((1 - (i % 2)) << 3));
+      words[i/2] |= (srcaddr[i] << ((1 - (i % 2)) << 3));
 
   best.len = 0;
   best.base = -1;
@@ -148,7 +150,17 @@
 
   /* Format the result.
    */
-  tp = tmp;
+  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?
@@ -156,61 +168,47 @@
     if (best.base != -1 && i >= best.base && i < (best.base + best.len))
     {
       if (i == best.base)
-         *tp++ = ':';
+      	 APPEND_CHAR(':');
       continue;
     }
 
     /* Are we following an initial run of 0x00s or any real hex?
      */
     if (i != 0)
-       *tp++ = ':';
+       APPEND_CHAR(':');
 
     /* 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)))
+      if (!addrtostr(srcaddr+12, dp, space_left))
       {
         errno = ENOSPC;
         return (NULL);
       }
-      tp += strlen(tp);
+      added_space = strlen(dp);
+      dp += added_space;
+      space_left -= added_space;
       break;
     }
-    tp += sprintf (tp, "%lx", words[i]);
+    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))
-     *tp++ = ':';
-  *tp++ = '\0';
+     APPEND_CHAR(':');
+  APPEND_CHAR('\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;
-    }
+  return (dst);
 }
diff --git a/missing/inet_pton.c b/addrtostr.h
similarity index 85%
rename from missing/inet_pton.c
rename to addrtostr.h
index 3466f42..2b95a16 100644
--- a/missing/inet_pton.c
+++ b/addrtostr.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999 Kungliga Tekniska H�gskolan
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
@@ -17,7 +17,7 @@
  * 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.
+ *      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
@@ -36,14 +36,7 @@
  * SUCH DAMAGE.
  */
 
-#include <tcpdump-stdinc.h>
+/* Address to printable string translation routines. */
 
-int
-inet_pton(int af, const char *src, void *dst)
-{
-    if (af != AF_INET) {
-	errno = EAFNOSUPPORT;
-	return -1;
-    }
-    return inet_aton (src, dst);
-}
+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/af.c b/af.c
index bea6d97..539ede5 100644
--- a/af.c
+++ b/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 <tcpdump-stdinc.h>
-#include "interface.h"
+#include <netdissect-stdinc.h>
+#include "netdissect.h"
 #include "af.h"
 
 const struct tok af_values[] = {
diff --git a/af.h b/af.h
index bbe1a16..1bde577 100644
--- a/af.h
+++ b/af.h
@@ -50,6 +50,6 @@
 #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/ascii_strcasecmp.c b/ascii_strcasecmp.c
new file mode 100644
index 0000000..b8decf1
--- /dev/null
+++ b/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/ascii_strcasecmp.h b/ascii_strcasecmp.h
new file mode 100644
index 0000000..7f8ddb9
--- /dev/null
+++ b/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 <mcr@tcpdump.org>
+ *      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 <stddef.h>
+
+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/atmuni31.h b/atmuni31.h
deleted file mode 100644
index 0f85430..0000000
--- a/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/bpf_dump.c b/bpf_dump.c
index 2ef8528..9bad38d 100644
--- a/bpf_dump.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <stdio.h>
 
-#include "interface.h"
+#include "netdissect.h"
 
 void
 bpf_dump(const struct bpf_program *p, int option)
diff --git a/checksum.c b/checksum.c
index d8263c7..0829fbe 100644
--- a/checksum.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
 
-#include "interface.h"
+#include "netdissect.h"
 
 /*
  * CRC-10 table generated using the following Python snippet:
@@ -146,17 +145,17 @@
     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/config.h b/config.h
index 5a5d8ce..d7eb01f 100644
--- a/config.h
+++ b/config.h
@@ -1,8 +1,8 @@
 /* config.h.  Generated from config.h.in by configure.  */
 /* config.h.in.  Generated from configure.in by autoheader.  */
 
-/* define if you have the addrinfo function */
-#define HAVE_ADDRINFO 1
+/* define if you want to build the possibly-buggy SMB printer */
+#define ENABLE_SMB 1
 
 /* Define to 1 if you have the `alarm' function. */
 #define HAVE_ALARM 1
@@ -10,9 +10,24 @@
 /* Define to 1 if you have the `bpf_dump' function. */
 #define HAVE_BPF_DUMP 1
 
+/* capsicum support available */
+/* #undef HAVE_CAPSICUM */
+
+/* Define to 1 if you have the `cap_enter' function. */
+/* #undef HAVE_CAP_ENTER */
+
+/* Define to 1 if you have the `cap_ioctls_limit' function. */
+/* #undef HAVE_CAP_IOCTLS_LIMIT */
+
+/* Define to 1 if you have the <cap-ng.h> header file. */
+/* #undef HAVE_CAP_NG_H */
+
+/* Define to 1 if you have the `cap_rights_limit' function. */
+/* #undef HAVE_CAP_RIGHTS_LIMIT */
+
 /* Define to 1 if you have the declaration of `ether_ntohost', and to 0 if you
    don't. */
-/* #undef HAVE_DECL_ETHER_NTOHOST */
+#define HAVE_DECL_ETHER_NTOHOST 0
 
 /* define if you have the dnet_htoa function */
 /* #undef HAVE_DNET_HTOA */
@@ -20,33 +35,33 @@
 /* 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. */
+#define HAVE_EVP_CIPHER_CTX_NEW 1
+
 /* Define to 1 if you have the <fcntl.h> header file. */
 #define HAVE_FCNTL_H 1
 
 /* Define to 1 if you have the `fork' function. */
 #define HAVE_FORK 1
 
-/* Define to 1 if you have the `getnameinfo' function. */
-#define HAVE_GETNAMEINFO 1
+/* Define to 1 if you have the `getopt_long' function. */
+#define HAVE_GETOPT_LONG 1
 
 /* define if you have getrpcbynumber() */
-/* #undef HAVE_GETRPCBYNUMBER */
-
-/* define if you have the h_errno variable */
-#define HAVE_H_ERRNO 1
+#define HAVE_GETRPCBYNUMBER 1
 
 /* Define to 1 if you have the <inttypes.h> header file. */
 #define HAVE_INTTYPES_H 1
 
+/* Define to 1 if you have the `cap-ng' library (-lcap-ng). */
+/* #undef HAVE_LIBCAP_NG */
+
 /* Define to 1 if you have the `crypto' library (-lcrypto). */
 #define HAVE_LIBCRYPTO 1
 
 /* Define to 1 if you have the `rpc' library (-lrpc). */
 /* #undef HAVE_LIBRPC */
 
-/* Define to 1 if you have the `smi' library (-lsmi). */
-/* #undef HAVE_LIBSMI */
-
 /* Define to 1 if you have the <memory.h> header file. */
 #define HAVE_MEMORY_H 1
 
@@ -62,12 +77,21 @@
 /* Define to 1 if you have the <netinet/if_ether.h> header file. */
 #define HAVE_NETINET_IF_ETHER_H 1
 
+/* Define to 1 if you have the <net/if_pflog.h> header file. */
+/* #undef HAVE_NET_IF_PFLOG_H */
+
 /* Define to 1 if you have the <net/pfvar.h> header file. */
 /* #undef HAVE_NET_PFVAR_H */
 
+/* Define to 1 if you have the `openat' function. */
+#define HAVE_OPENAT 1
+
 /* Define to 1 if you have the <openssl/evp.h> header file. */
 #define HAVE_OPENSSL_EVP_H 1
 
+/* define if the OS provides AF_INET6 and struct in6_addr */
+#define HAVE_OS_IPV6_SUPPORT 1
+
 /* if there's an os_proto.h for this platform, to use additional prototypes */
 /* #undef HAVE_OS_PROTO_H */
 
@@ -98,6 +122,9 @@
 /* Define to 1 if you have the `pcap_findalldevs' function. */
 #define HAVE_PCAP_FINDALLDEVS 1
 
+/* Define to 1 if you have the `pcap_free_datalinks' function. */
+#define HAVE_PCAP_FREE_DATALINKS 1
+
 /* Define to 1 if the system has the type `pcap_if_t'. */
 #define HAVE_PCAP_IF_T 1
 
@@ -113,9 +140,21 @@
 /* Define to 1 if you have the `pcap_setdirection' function. */
 #define HAVE_PCAP_SETDIRECTION 1
 
-/* define if libpcap has pcap_set_datalink() */
+/* Define to 1 if you have the `pcap_set_datalink' function. */
 #define HAVE_PCAP_SET_DATALINK 1
 
+/* Define to 1 if you have the `pcap_set_immediate_mode' function. */
+#define HAVE_PCAP_SET_IMMEDIATE_MODE 1
+
+/* 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. */
+#define HAVE_PCAP_SET_TSTAMP_PRECISION 1
+
 /* Define to 1 if you have the `pcap_set_tstamp_type' function. */
 #define HAVE_PCAP_SET_TSTAMP_TYPE 1
 
@@ -132,7 +171,7 @@
 /* #undef HAVE_RPC_RPCENT_H */
 
 /* Define to 1 if you have the <rpc/rpc.h> header file. */
-#define HAVE_RPC_RPC_H 1
+/* #undef HAVE_RPC_RPC_H */
 
 /* Define to 1 if you have the `setlinebuf' function. */
 #define HAVE_SETLINEBUF 1
@@ -143,27 +182,18 @@
 /* Define to 1 if you have the `sigset' function. */
 /* #undef HAVE_SIGSET */
 
-/* Define to 1 if you have the <smi.h> header file. */
-/* #undef HAVE_SMI_H */
-
 /* Define to 1 if you have the `snprintf' function. */
 #define HAVE_SNPRINTF 1
 
 /* if struct sockaddr has the sa_len member */
 /* #undef HAVE_SOCKADDR_SA_LEN */
 
-/* define if you have struct sockaddr_storage */
-#define HAVE_SOCKADDR_STORAGE 1
-
 /* Define to 1 if you have the <stdint.h> header file. */
 #define HAVE_STDINT_H 1
 
 /* Define to 1 if you have the <stdlib.h> header file. */
 #define HAVE_STDLIB_H 1
 
-/* Define to 1 if you have the `strcasecmp' function. */
-#define HAVE_STRCASECMP 1
-
 /* Define to 1 if you have the `strdup' function. */
 #define HAVE_STRDUP 1
 
@@ -188,15 +218,15 @@
 /* Define to 1 if the system has the type `struct ether_addr'. */
 /* #undef HAVE_STRUCT_ETHER_ADDR */
 
-/* Define to 1 if you have the <sys/bitypes.h> header file. */
-/* #undef HAVE_SYS_BITYPES_H */
-
 /* Define to 1 if you have the <sys/stat.h> header file. */
 #define HAVE_SYS_STAT_H 1
 
 /* Define to 1 if you have the <sys/types.h> header file. */
 #define HAVE_SYS_TYPES_H 1
 
+/* Define to 1 if the system has the type `uintptr_t'. */
+#define HAVE_UINTPTR_T 1
+
 /* Define to 1 if you have the <unistd.h> header file. */
 #define HAVE_UNISTD_H 1
 
@@ -215,18 +245,9 @@
 /* define if your compiler has __attribute__ */
 #define HAVE___ATTRIBUTE__ 1
 
-/* Define if you enable IPv6 support */
-#define INET6 1
-
 /* if unaligned access fails */
 /* #undef LBL_ALIGN */
 
-/* Define if you enable support for libsmi */
-/* #undef LIBSMI */
-
-/* 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 */
 
@@ -272,15 +293,15 @@
 /* Define to 1 if you have the ANSI C header files. */
 #define STDC_HEADERS 1
 
-/* define if you want to build the possibly-buggy SMB printer */
-#define TCPDUMP_DO_SMB 1
-
 /* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
 #define TIME_WITH_SYS_TIME 1
 
 /* define if you have ether_ntohost() and it works */
 /* #undef USE_ETHER_NTOHOST */
 
+/* Define if you enable support for libsmi */
+/* #undef USE_LIBSMI */
+
 /* define if should chroot when dropping privileges */
 /* #undef WITH_CHROOT */
 
@@ -341,16 +362,16 @@
    a type exists and the standard includes do not define it. */
 /* #undef int8_t */
 
-/* Define to `unsigned short' if u_int16_t not defined. */
+/* Define to `uint16_t' if u_int16_t not defined. */
 /* #undef u_int16_t */
 
-/* Define to `unsigned int' if u_int32_t not defined. */
+/* Define to `uint32_t' if u_int32_t not defined. */
 /* #undef u_int32_t */
 
-/* Define to `unsigned long long' if u_int64_t not defined. */
+/* Define to `uint64_t' if u_int64_t not defined. */
 /* #undef u_int64_t */
 
-/* Define to `unsigned char' if u_int8_t not defined. */
+/* Define to `uint8_t' if u_int8_t not defined. */
 /* #undef u_int8_t */
 
 /* Define to the type of an unsigned integer type of width exactly 16 bits if
@@ -368,3 +389,7 @@
 /* Define to the type of an unsigned integer type of width exactly 8 bits if
    such a type exists and the standard includes do not define it. */
 /* #undef uint8_t */
+
+/* Define to the type of an unsigned integer type wide enough to hold a
+   pointer, if such a type exists, and if the system does not define it. */
+/* #undef uintptr_t */
diff --git a/config.h.in b/config.h.in
index 914289a..27ba4b1 100644
--- a/config.h.in
+++ b/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
@@ -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 <fcntl.h> 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 <inttypes.h> header file. */
 #undef HAVE_INTTYPES_H
 
@@ -79,6 +76,9 @@
 /* Define to 1 if you have the <netinet/if_ether.h> header file. */
 #undef HAVE_NETINET_IF_ETHER_H
 
+/* Define to 1 if you have the <net/if_pflog.h> header file. */
+#undef HAVE_NET_IF_PFLOG_H
+
 /* Define to 1 if you have the <net/pfvar.h> header file. */
 #undef HAVE_NET_PFVAR_H
 
@@ -88,6 +88,9 @@
 /* Define to 1 if you have the <openssl/evp.h> 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 <stdlib.h> 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 <sys/time.h> and <time.h>. */
 #undef TIME_WITH_SYS_TIME
 
diff --git a/configure b/configure
index 43b3068..03c69c5 100755
--- a/configure
+++ b/configure
@@ -704,7 +704,6 @@
 with_user
 with_chroot
 with_sandbox_capsicum
-enable_ipv6
 with_system_libpcap
 with_crypto
 with_cap_ng
@@ -1332,8 +1331,6 @@
   --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 @@
   --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 @@
 	{ $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 @@
 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 <sys/types.h>
+	#include <sys/socket.h>
+	#include <net/if.h>
+	#include <net/pfvar.h>
+"
+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 "$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"
 	;;
@@ -4576,9 +4603,9 @@
 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 @@
 
 
 
-{ $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 <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
@@ -4882,21 +4898,23 @@
 
 _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 @@
 _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 @@
   ipv6type=$i;
 				ipv6lib=inet6;
 				ipv6libdir=/usr/local/v6/lib;
-				ipv6trylibc=yes;
-				CFLAGS="-DINET6 $CFLAGS"
+				ipv6trylibc=yes
 fi
 rm -f conftest*
 
@@ -4952,8 +4968,7 @@
 _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 @@
 				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 @@
   $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 @@
   $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 @@
 	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 <netdb.h> #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 <sys/types.h>
-#include <netdb.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-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 @@
 
 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 <netdb.h>
-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 <netdb.h>
-#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 <netdb.h>
-#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 @@
 
 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 @@
 
 
 
-
                 LBL_LIBS="$LIBS"
     pfopen=/usr/examples/packetfilter/pfopen.c
     if test -f $pfopen ; then
@@ -6163,114 +5819,6 @@
 # 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.
-#
-{ $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 <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-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 <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-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 <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-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.
@@ -6488,44 +6036,6 @@
 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 <sys/types.h>
-#		include <sys/socket.h>
-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 "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 @@
 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 @@
 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 @@
 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 @@
 
 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 @@
 
 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 @@
 	    #
 	    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 @@
 	{ $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 @@
 	{ $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 @@
 	{ $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 @@
 	{ $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 @@
 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 @@
 
     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 <sys/types.h>
-#		include <netdb.h>
-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 @@
   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 @@
 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 @@
 
 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 @@
 
 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/configure.in b/configure.in
index a629559..a78a126 100644
--- a/configure.in
+++ b/configure.in
@@ -37,7 +37,13 @@
 #include <sys/socket.h>
 #include <net/if.h>])
 if test "$ac_cv_header_net_pfvar_h" = yes; then
-	LOCALSRC="print-pflog.c $LOCALSRC"
+	AC_CHECK_HEADERS(net/if_pflog.h, , , [#include <sys/types.h>
+	#include <sys/socket.h>
+	#include <net/if.h>
+	#include <net/pfvar.h>])
+	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 <sys/types.h>
 #include <sys/socket.h>])
@@ -169,7 +175,7 @@
 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"
 	;;
@@ -229,32 +235,24 @@
 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 <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
@@ -267,17 +265,19 @@
 #else
 #error "AF_INET6 not defined"
 #endif
-        ]])
+	]])
     ],
-[ 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(yes)
+	AC_DEFINE(HAVE_OS_IPV6_SUPPORT, 1,
+	    [define if the OS provides AF_INET6 and struct in6_addr])
+	ipv6=yes
+    ],
+    [
+	AC_MSG_RESULT(no)
+	ipv6=no
+    ]
+)
 
 ipv6type=unknown
 ipv6lib=none
@@ -294,8 +294,7 @@
 #ifdef IPV6_INRIA_VERSION
 yes
 #endif],
-				[ipv6type=$i;
-				CFLAGS="-DINET6 $CFLAGS"])
+				[ipv6type=$i])
 			;;
 		kame)
 			dnl http://www.kame.net/
@@ -307,8 +306,7 @@
 				[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 @@
 #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 @@
 				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 @@
 #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 @@
 #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 @@
 	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 <netdb.h> #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 <sys/types.h>
-#include <netdb.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-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 @@
 	    [define if you have a dnet_htoa declaration in <netdnet/dnetdb.h>])
 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 @@
 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 <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>], [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 <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>], [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 <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>], [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 @@
 # 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 @@
 	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)
+#
+# Check for special debugging functions
+#
+AC_CHECK_FUNCS(pcap_set_parser_debug)
+if test "$ac_cv_func_pcap_set_parser_debug" = "no" ; then
 	#
-	# OK, what about "yydebug"?
-	#
-	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 @@
 #
 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_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/cpack.c b/cpack.c
index 16bfd15..e37d813 100644
--- a/cpack.c
+++ b/cpack.c
@@ -27,20 +27,19 @@
  * OF SUCH DAMAGE.
  */
 
-#define NETDISSECT_REWORKED
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
 #include <stdlib.h>
 #include <string.h>
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #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 @@
  * 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 @@
 }
 
 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 @@
 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 @@
 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 @@
 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/cpack.h b/cpack.h
index a7eb6d6..3072e0c 100644
--- a/cpack.h
+++ b/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/ether.h b/ether.h
index 58b92de..6491678 100644
--- a/ether.h
+++ b/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/ethertype.h b/ethertype.h
index 8039917..2aa53a0 100644
--- a/ethertype.h
+++ b/ethertype.h
@@ -196,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/extract.h b/extract.h
index cb62ebd..23623c2 100644
--- a/extract.h
+++ b/extract.h
@@ -103,7 +103,7 @@
 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 @@
 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 @@
 	            ((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/gmpls.c b/gmpls.c
index c9fd9bb..23515e9 100644
--- a/gmpls.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "gmpls.h"
 
 /* rfc3471 */
diff --git a/gmt2local.c b/gmt2local.c
index 6958f66..d6cd93b 100644
--- a/gmt2local.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <stdio.h>
 
diff --git a/in_cksum.c b/in_cksum.c
index 171728a..e9bed22 100644
--- a/in_cksum.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 
 /*
  * Checksum routine for Internet Protocol family headers (Portable Version).
@@ -74,7 +73,7 @@
 	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 @@
 			 */
 			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/interface.h b/interface.h
index 59c1eef..46d338b 100644
--- a/interface.h
+++ b/interface.h
@@ -65,165 +65,15 @@
 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 <pcap.h>
 
-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/ip.h b/ip.h
index 72c8972..8179061 100644
--- a/ip.h
+++ b/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 @@
  * 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 @@
 #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/ip6.h b/ip6.h
index 1ad9149..2ea1d0a 100644
--- a/ip6.h
+++ b/ip6.h
@@ -172,7 +172,11 @@
 	/* 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 @@
 #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/ipproto.c b/ipproto.c
index e44b748..bcf2ced 100644
--- a/ipproto.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "ipproto.h"
 
 const struct tok ipproto_values[] = {
diff --git a/l2vpn.c b/l2vpn.c
index 54037aa..3f3639f 100644
--- a/l2vpn.c
+++ b/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 <tcpdump-stdinc.h>
-#include "interface.h"
+#include <netdissect-stdinc.h>
+#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/l2vpn.h b/l2vpn.h
index 151228f..d93abf1 100644
--- a/l2vpn.h
+++ b/l2vpn.h
@@ -14,3 +14,4 @@
  */
 
 extern const struct tok l2vpn_encaps_values[];
+extern const struct tok mpls_pw_types_values[];
diff --git a/lbl/os-solaris2.h b/lbl/os-solaris2.h
index 9f94da9..aedba4e 100644
--- a/lbl/os-solaris2.h
+++ b/lbl/os-solaris2.h
@@ -25,4 +25,3 @@
 #endif
 char    *strerror(int);
 int	snprintf(char *, size_t, const char *, ...);
-int	strcasecmp(const char *, const char *);
diff --git a/lbl/os-sunos4.h b/lbl/os-sunos4.h
index b735857..0e63270 100644
--- a/lbl/os-sunos4.h
+++ b/lbl/os-sunos4.h
@@ -166,12 +166,10 @@
 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/lbl/os-ultrix4.h b/lbl/os-ultrix4.h
index fa1f770..891def2 100644
--- a/lbl/os-ultrix4.h
+++ b/lbl/os-ultrix4.h
@@ -34,4 +34,3 @@
 int	pfopen(char *, int);
 int	setlinebuf(FILE *);
 int	socket(int, int, int);
-int	strcasecmp(const char *, const char *);
diff --git a/machdep.c b/machdep.c
index 7b259ae..1f08616 100644
--- a/machdep.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #ifndef HAVE___ATTRIBUTE__
 #define __attribute__(x)
diff --git a/machdep.h b/machdep.h
index d1c7d4b..ba8ed38 100644
--- a/machdep.h
+++ b/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/mib.h b/mib.h
index 92c6c2c..6c8e63c 100644
--- a/mib.h
+++ b/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/missing/addrinfo.h b/missing/addrinfo.h
deleted file mode 100644
index bf4bbf6..0000000
--- a/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/missing/datalinks.c b/missing/datalinks.c
index e7d526b..4a7d6fe 100644
--- a/missing/datalinks.c
+++ b/missing/datalinks.c
@@ -35,7 +35,7 @@
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <pcap.h>
 #include <stdlib.h>
diff --git a/missing/dlnames.c b/missing/dlnames.c
index a10cd39..16bfcf7 100644
--- a/missing/dlnames.c
+++ b/missing/dlnames.c
@@ -35,12 +35,13 @@
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <pcap.h>
 #include <string.h>
 
 #include "pcap-missing.h"
+#include "ascii_strcasecmp.h"
 
 struct dlt_choice {
 	const char *name;
@@ -137,7 +138,7 @@
 	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/missing/getnameinfo.c b/missing/getnameinfo.c
deleted file mode 100644
index 63aba73..0000000
--- a/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 <config.h>
-#endif
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <arpa/nameser.h>
-#include <netdb.h>
-#include <resolv.h>
-#include <string.h>
-#include <stddef.h>
-#include <errno.h>
-
-#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/missing/inet_aton.c b/missing/inet_aton.c
deleted file mode 100644
index e85ad5f..0000000
--- a/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 <tcpdump-stdinc.h>
-
-/* 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/missing/snprintf.c b/missing/snprintf.c
index 21d235d..921b74c 100644
--- a/missing/snprintf.c
+++ b/missing/snprintf.c
@@ -42,7 +42,7 @@
 #include <ctype.h>
 #include <sys/types.h>
 
-#include <interface.h>
+#include "netdissect.h"
 
 enum format_flags {
     minus_flag     =  1,
diff --git a/missing/strdup.c b/missing/strdup.c
index 9fca752..9cbf35a 100644
--- a/missing/strdup.c
+++ b/missing/strdup.c
@@ -35,7 +35,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "interface.h"
+#include "netdissect.h"
 
 char *
 strdup(str)
diff --git a/missing/strlcat.c b/missing/strlcat.c
index 34f1af2..4054935 100644
--- a/missing/strlcat.c
+++ b/missing/strlcat.c
@@ -28,15 +28,15 @@
  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H 
+#ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <string.h>
 
-#include "interface.h"
+#include "netdissect.h"
 
 /*
  * Appends src to string dst of size siz (unlike strncat, siz is the
diff --git a/missing/strlcpy.c b/missing/strlcpy.c
index b0671eb..24dcca6 100644
--- a/missing/strlcpy.c
+++ b/missing/strlcpy.c
@@ -28,15 +28,15 @@
  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H 
+#ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <string.h>
 
-#include "interface.h"
+#include "netdissect.h"
 
 /*
  * Copy src to string dst of size siz.  At most siz-1 characters
diff --git a/missing/strsep.c b/missing/strsep.c
index a1e6b30..2c17275 100644
--- a/missing/strsep.c
+++ b/missing/strsep.c
@@ -31,15 +31,15 @@
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H 
+#ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <string.h>
 
-#include "interface.h"
+#include "netdissect.h"
 
 /*
  * Get next token from string *stringp, where tokens are possibly-empty
diff --git a/nameser.h b/nameser.h
index 11e71ef..e075f09 100644
--- a/nameser.h
+++ b/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/tcpdump-stdinc.h b/netdissect-stdinc.h
similarity index 83%
rename from tcpdump-stdinc.h
rename to netdissect-stdinc.h
index 32f8fc9..c7070f0 100644
--- a/tcpdump-stdinc.h
+++ b/netdissect-stdinc.h
@@ -32,28 +32,30 @@
 /*
  * 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
+ * various items as needed, to isolate most of netdissect's platform
  * differences to this one file.
  */
 
-#ifndef tcpdump_stdinc_h
-#define tcpdump_stdinc_h
+#ifndef netdissect_stdinc_h
+#define netdissect_stdinc_h
 
 #include <errno.h>
 
-#ifdef WIN32
+#ifdef _WIN32
+
+/*
+ * Includes and definitions for Windows.
+ */
 
 #include <stdint.h>
 #include <stdio.h>
 #include <winsock2.h>
 #include <ws2tcpip.h>
-#include "bittypes.h"   /* in wpcap's Win32/include */
 #include <ctype.h>
 #include <time.h>
 #include <io.h>
 #include <fcntl.h>
 #include <sys/types.h>
-#include <net/netdb.h>  /* in wpcap's Win32/include */
 
 #ifndef uint8_t
 #define uint8_t		unsigned char
@@ -133,6 +135,17 @@
 
 #endif /* _MSC_EXTENSIONS */
 
+/*
+ * Suppress definition of intN_t in bittypes.h, as included by <pcap/pcap.h>
+ * 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
@@ -142,13 +155,6 @@
 #define O_RDONLY _O_RDONLY
 #endif  /* _MSC_VER */
 
-/* Protos for missing/x.c functions (ideally <missing/addrinfo.h>
- * should be used, but it clashes with <ws2tcpip.h>).
- */
-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.
  */
@@ -156,6 +162,10 @@
 #define inline __inline
 #endif
 
+#ifdef AF_INET6
+#define HAVE_OS_IPV6_SUPPORT
+#endif
+
 #ifndef INET6_ADDRSTRLEN
 #define INET6_ADDRSTRLEN 46
 #endif
@@ -171,12 +181,15 @@
 #endif /* caddr_t */
 
 #define MAXHOSTNAMELEN	64
-#define	NI_MAXHOST	1025
 #define snprintf _snprintf
 #define vsnprintf _vsnprintf
 #define RETSIGTYPE void
 
-#else /* WIN32 */
+#else /* _WIN32 */
+
+/*
+ * Includes and definitions for various flavors of UN*X.
+ */
 
 #include <ctype.h>
 #include <unistd.h>
@@ -198,7 +211,7 @@
 
 #include <arpa/inet.h>
 
-#endif /* WIN32 */
+#endif /* _WIN32 */
 
 #ifndef HAVE___ATTRIBUTE__
 #define __attribute__(x)
@@ -241,7 +254,10 @@
 #define UNALIGNED	__attribute__((packed))
 #endif
 
-#if defined(WIN32) || defined(MSDOS)
+/*
+ * 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"
@@ -253,6 +269,16 @@
   #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
@@ -284,6 +310,32 @@
   }
 #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
@@ -349,4 +401,4 @@
 #define max(a,b) ((b)>(a)?(b):(a))
 #endif
 
-#endif /* tcpdump_stdinc_h */
+#endif /* netdissect_stdinc_h */
diff --git a/netdissect.c b/netdissect.c
new file mode 100644
index 0000000..0215c83
--- /dev/null
+++ b/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 <mcr@tcpdump.org>
+ *      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 <netdissect-stdinc.h>
+#include "netdissect.h"
+#include <string.h>
+#include <stdio.h>
+
+#ifdef USE_LIBSMI
+#include <smi.h>
+#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/netdissect.h b/netdissect.h
index d507f58..ac916c2 100644
--- a/netdissect.h
+++ b/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 <stdarg.h>
+#include <pcap.h>
 
 #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 @@
      __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 @@
 	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 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 @@
   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 @@
 #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 @@
 #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.
@@ -270,8 +302,16 @@
  *
  *	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) \
-  ((l) >= 0 && \
+  (IS_NOT_NEGATIVE(l) && \
 	((uintptr_t)ndo->ndo_snapend - (l) <= (uintptr_t)ndo->ndo_snapend && \
          (uintptr_t)&(var) <= (uintptr_t)ndo->ndo_snapend - (l)))
 
@@ -288,9 +328,12 @@
 #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 *);
 
@@ -302,11 +345,6 @@
 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
@@ -349,284 +387,277 @@
 #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
+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_printer lookup_printer(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;
+
+/*
+ * 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;
+};
 
 /* The printer routines. */
 
-#include <pcap.h>
-
-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 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);
-
-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);
-
-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);
-
+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 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 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 cnfp_print(netdissect_options *, const u_char *);
-extern void dvmrp_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 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 bgp_print(netdissect_options *, const u_char *, int);
-extern void olsr_print(netdissect_options *, const u_char *, u_int, 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 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 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 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 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 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 void rtsp_print(netdissect_options *, const u_char *, u_int);
-extern void smtp_print(netdissect_options *, const u_char *, u_int);
-extern void geneve_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 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 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 babel_print(netdissect_options *, const u_char *, u_int);
-#endif /*INET6*/
+extern void ospf_print(netdissect_options *, const u_char *, u_int, const u_char *);
+extern int ospf_print_grace_lsa(netdissect_options *, const uint8_t *, u_int);
+extern int ospf_print_te_lsa(netdissect_options *, const uint8_t *, u_int);
+extern void otv_print(netdissect_options *, const u_char *, u_int);
+extern void pgm_print(netdissect_options *, const u_char *, u_int, const u_char *);
+extern void pim_print(netdissect_options *, const u_char *, u_int, const u_char *);
+extern void pimv1_print(netdissect_options *, const u_char *, u_int);
+extern u_int ppp_print(netdissect_options *, register const u_char *, u_int);
+extern u_int 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 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 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);
 
-#if 0
+/* 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);
+
 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,
+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 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],
-					     u_char *buf, u_char *end);
-
-
-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);
+					     const u_char *, const u_char *);
 
 #endif  /* netdissect_h */
diff --git a/nfsfh.h b/nfsfh.h
index cfd073b..5cf8fc4 100644
--- a/nfsfh.h
+++ b/nfsfh.h
@@ -63,4 +63,4 @@
 #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/nlpid.c b/nlpid.c
index 919e87d..4b44ee1 100644
--- a/nlpid.c
+++ b/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 <tcpdump-stdinc.h>
-#include "interface.h"
+#include <netdissect-stdinc.h>
+#include "netdissect.h"
 #include "nlpid.h"
 
 const struct tok nlpid_values[] = {
diff --git a/oui.c b/oui.c
index 2aea5ad..71425de 100644
--- a/oui.c
+++ b/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 <tcpdump-stdinc.h>
-#include "interface.h"
+#include <netdissect-stdinc.h>
+#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/oui.h b/oui.h
index 4a983ec..a85f883 100644
--- a/oui.h
+++ b/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/parsenfsfh.c b/parsenfsfh.c
index 826ca94..8f48e77 100644
--- a/parsenfsfh.c
+++ b/parsenfsfh.c
@@ -40,17 +40,16 @@
  * Western Research Laboratory
  */
 
-#define NETDISSECT_REWORKED
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <stdio.h>
 #include <string.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "nfsfh.h"
 
 /*
@@ -103,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) */
@@ -115,138 +114,146 @@
 	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 */
-		    }
-	        }
-		else {
-		    if (is_UCX(fhp)) {
-			fhtype = FHT_VMSUCX;
-		    }
-		    else {
-			fhtype = FHT_UNKNOWN;
+			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;
+			}
+			/*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 {
+			/*
+			 * 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 */
@@ -361,13 +368,13 @@
 		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;
@@ -378,7 +385,7 @@
 
 	    /* Caller must save (and null-terminate?) this value */
 	    if (fsnamep)
-		*fsnamep = (char *)&(fhp[1]);
+		*fsnamep = (const char *)&(fhp[1]);
 
 	    if (osnamep)
 		*osnamep = "VMS";
@@ -410,13 +417,14 @@
 	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;
@@ -443,11 +451,18 @@
  *	(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/pcap-missing.h b/pcap-missing.h
index d776810..92706b1 100644
--- a/pcap-missing.h
+++ b/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 long pcap_dump_ftell(pcap_dumper_t *);
 #endif
 
-#endif
-
-
-
-
-
-
-
-
-
+#endif /* netdissect_pcap_missing_h */
diff --git a/print-802_11.c b/print-802_11.c
index 697e2c9..1bbe47a 100644
--- a/print-802_11.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <string.h>
 
-#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 @@
 #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 tim_t	tim;
 };
 
-struct ctrl_rts_t {
+struct ctrl_control_wrapper_hdr_t {
 	uint16_t	fc;
 	uint16_t	duration;
-	uint8_t		ra[6];
-	uint8_t		ta[6];
-	uint8_t		fcs[4];
+	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[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,310 +399,6 @@
 #define	IV_PAD(iv)	(((iv) >> 24) & 0x3F)
 #define	IV_KEYID(iv)	(((iv) >> 30) & 0x03)
 
-/* $FreeBSD: src/sys/net80211/ieee80211_radiotap.h,v 1.5 2005/01/22 20:12:05 sam Exp $ */
-/* NetBSD: ieee802_11_radio.h,v 1.2 2006/02/26 03:04:03 dyoung Exp  */
-
-/*-
- * 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_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_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, " (")); \
@@ -1283,7 +988,7 @@
 		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 @@
 
 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 @@
 	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 @@
 
 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 @@
 	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 @@
 
 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 @@
 	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 @@
 			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 @@
  *    1    |  1      |  RA    | TA     | DA     | SA
  */
 
+/*
+ * Function to get source and destination MAC addresses for a data frame.
+ */
 static void
-data_header_print(netdissect_options *ndo,
-                  uint16_t fc, const u_char *p, const uint8_t **srcp,
-                  const uint8_t **dstp)
+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)
 {
 	u_int subtype = FC_SUBTYPE(fc);
 
@@ -2086,42 +1837,18 @@
 #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 @@
 }
 
 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 @@
 		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 @@
 		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 @@
 			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 @@
 }
 
 /*
- * 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 @@
 			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 @@
 
 	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 @@
 #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 @@
 {
 	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 @@
 
 	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 @@
 	} 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 @@
 	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 @@
 		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,6 +2153,349 @@
 	return ieee802_11_print(ndo, p, h->len, h->caplen, 0, 0);
 }
 
+
+/* $FreeBSD: src/sys/net80211/ieee80211_radiotap.h,v 1.5 2005/01/22 20:12:05 sam Exp $ */
+/* NetBSD: ieee802_11_radio.h,v 1.2 2006/02/26 03:04:03 dyoung Exp  */
+
+/*-
+ * 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 \
@@ -2464,30 +2522,41 @@
 
 static void
 print_chaninfo(netdissect_options *ndo,
-               int freq, int flags)
+               uint16_t freq, int flags, int presentflags)
 {
 	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 (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"));
 	}
-	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)
@@ -2499,146 +2568,50 @@
 
 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)
+                     struct cpack_state *s, uint32_t bit, uint8_t *flagsp,
+                     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;
+	u_int i;
 	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;
 
-		/* 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);
-		if (rc != 0)
-			break;
-		rc = cpack_uint8(s, &u3.u8);
-		break;
-	case IEEE80211_RADIOTAP_VENDOR_NAMESPACE: {
-		uint8_t vns[3];
-		uint16_t length;
-		uint8_t subspace;
+	case IEEE80211_RADIOTAP_TSFT: {
+		uint64_t tsft;
 
-		if ((cpack_align_and_reserve(s, 2)) == NULL) {
-			rc = -1;
-			break;
+		rc = cpack_uint64(s, &tsft);
+		if (rc != 0)
+			goto trunc;
+		ND_PRINT((ndo, "%" PRIu64 "us tsft ", tsft));
+		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;
-	}
+	case IEEE80211_RADIOTAP_RATE: {
+		uint8_t rate;
 
-	/* Preserve the state present flags */
-	state->present = presentflags;
-
-	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 @@
 		 * 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 @@
 			 * 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 @@
 		};
 		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 @@
 					 */
 					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,42 +2871,216 @@
 				 * 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 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;
 }
 
@@ -2819,83 +3088,181 @@
 ieee802_11_radio_print(netdissect_options *ndo,
                        const u_char *p, u_int length, u_int caplen)
 {
-#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)
 #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;
+			}
 
-		for (present = EXTRACT_LE_32BITS(presentp); present;
-		     present = next_present) {
-			/* clear the least significant bit that is set */
-			next_present = present & (present - 1);
+			/*
+			 * 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;
+			}
+		}
 
-			/* extract the least significant bit that is set */
-			bit = (enum ieee80211_radiotap_type)
-			    (bit0 + BITNO_32(present ^ next_present));
+		/*
+		 * 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))) {
 
-			if (print_radiotap_field(ndo, &cpacker, bit, &flags, &state, presentflags) != 0)
-				goto out;
+		case 0:
+			/*
+			 * We're not changing namespaces.
+			 * advance to the next 32 bits in the current
+			 * namespace.
+			 */
+			bit0 += 32;
+			break;
+
+		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;
+
+		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;
+
+		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/print-802_15_4.c b/print-802_15_4.c
index 26c28ee..6fe6d35 100644
--- a/print-802_15_4.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 
 #include "extract.h"
@@ -112,7 +113,7 @@
 	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 @@
 		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 @@
 				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/print-ah.c b/print-ah.c
index 0badf48..bec6f88 100644
--- a/print-ah.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #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/print-ahcp.c b/print-ahcp.c
index a9ae38a..067b506 100644
--- a/print-ahcp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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 @@
 	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 @@
 		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 @@
 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 @@
 
 	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 @@
 
 	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 @@
 	}
 	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 @@
 
 	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 @@
 
 	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 @@
 	}
 	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 @@
 			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 @@
 	}
 	return;
 
-corrupt:
-	ND_PRINT((ndo, " %s", cstr));
+invalid:
+	ND_PRINT((ndo, "%s", istr));
 	ND_TCHECK2(*cp, ep - cp);
 	return;
 trunc:
@@ -316,7 +306,7 @@
 	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 @@
 		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 @@
 		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 @@
 
 	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 @@
 		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 @@
 	}
 	return;
 
-corrupt:
-	ND_PRINT((ndo, " %s", cstr));
+invalid:
+	ND_PRINT((ndo, "%s", istr));
 	ND_TCHECK2(*cp, ep - cp);
 	return;
 trunc:
diff --git a/print-aodv.c b/print-aodv.c
index ef27eee..6cd0c9e 100644
--- a/print-aodv.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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 @@
 	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 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 @@
 	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 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 @@
 	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 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 @@
 	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 @@
 }
 
 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 @@
 
 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 @@
 
 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 @@
 	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 @@
 
 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 @@
 
 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 @@
 
 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 @@
 	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 @@
 
 trunc:
 	ND_PRINT((ndo, "[|rerr]"));
-#else
-	ND_PRINT((ndo, " rerr %u", length));
-#endif
 }
 
 void
diff --git a/print-aoe.c b/print-aoe.c
index f8bc1fc..97e93df 100644
--- a/print-aoe.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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 @@
 	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 @@
 		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 @@
 	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 @@
 	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 @@
 	}
 	return;
 
-corrupt:
-	ND_PRINT((ndo, "%s", cstr));
+invalid:
+	ND_PRINT((ndo, "%s", istr));
 	ND_TCHECK2(*cp, ep - cp);
 	return;
 trunc:
@@ -262,7 +260,7 @@
 	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 @@
 	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 @@
 	}
 	return;
 
-corrupt:
-	ND_PRINT((ndo, "%s", cstr));
+invalid:
+	ND_PRINT((ndo, "%s", istr));
 	ND_TCHECK2(*cp, ep - cp);
 	return;
 trunc:
@@ -313,7 +311,7 @@
 	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 @@
 	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 @@
 	}
 	return;
 
-corrupt:
-	ND_PRINT((ndo, "%s", cstr));
+invalid:
+	ND_PRINT((ndo, "%s", istr));
 	ND_TCHECK2(*cp, ep - cp);
 	return;
 trunc:
@@ -350,7 +348,7 @@
 	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 @@
 		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 @@
 	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 @@
 	}
 	return;
 
-corrupt:
-	ND_PRINT((ndo, "%s", cstr));
+invalid:
+	ND_PRINT((ndo, "%s", istr));
 	ND_TCHECK2(*cp, ep - cp);
 	return;
 trunc:
diff --git a/print-ap1394.c b/print-ap1394.c
index 3befe23..79401cb 100644
--- a/print-ap1394.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 #include "addrtoname.h"
 #include "ethertype.h"
@@ -48,6 +49,12 @@
  */
 #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 @@
 	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 @@
 {
 	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 @@
 
 	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/print-arcnet.c b/print-arcnet.c
index 0ffb922..abc19b8 100644
--- a/print-arcnet.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 
 /*
diff --git a/print-arp.c b/print-arp.c
index 76f39fe..eff97c4 100644
--- a/print-arp.c
+++ b/print-arp.c
@@ -19,20 +19,21 @@
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: Address Resolution Protocol (ARP) printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <string.h>
 
-#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]";
 
@@ -176,7 +177,17 @@
 #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,
@@ -357,7 +368,7 @@
 
 	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/print-ascii.c b/print-ascii.c
index 3cefef3..4ef38a1 100644
--- a/print-ascii.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 #include <stdio.h>
 
-#include "interface.h"
+#include "netdissect.h"
 
 #define ASCII_LINELENGTH 300
 #define HEXDUMP_BYTES_PER_LINE 16
diff --git a/print-atalk.c b/print-atalk.c
index 6140549..9d7d69d 100644
--- a/print-atalk.c
+++ b/print-atalk.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.
- *
- * Format and print AppleTalk packets.
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: AppleTalk printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <stdio.h>
 #include <string.h>
 
-#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]";
@@ -78,7 +77,14 @@
 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);
 }
 
 /*
@@ -98,6 +104,10 @@
 		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);
@@ -109,6 +119,10 @@
 			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)));
@@ -125,6 +139,10 @@
 			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),
@@ -171,6 +189,10 @@
 		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),
@@ -194,6 +216,15 @@
 
 	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 )
@@ -380,7 +411,7 @@
           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;
 
@@ -567,8 +598,11 @@
 			     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);
 	}
@@ -582,20 +616,25 @@
 	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/print-atm.c b/print-atm.c
index 8faf715..596e406 100644
--- a/print-atm.c
+++ b/print-atm.c
@@ -19,20 +19,110 @@
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: Asynchronous Transfer Mode (ATM) printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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
@@ -126,22 +216,20 @@
 /*
  * 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;
+	int llc_hdrlen;
 
-	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))));
-		}
+	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);
 }
 
 /*
@@ -229,7 +317,7 @@
 		caplen -= 20;
 		hdrlen += 20;
 	}
-	atm_llc_print(ndo, p, length, caplen);
+	hdrlen += atm_llc_print(ndo, p, length, caplen);
 	return (hdrlen);
 }
 
@@ -257,24 +345,18 @@
 
 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])));
 
@@ -290,6 +372,10 @@
 		/* SCCOP with some unknown protocol atop it */
 		ND_PRINT((ndo, "SSCOP, proto %d ", p[PROTO_POS]));
 	}
+	return;
+
+trunc:
+	ND_PRINT((ndo, " %s", tstr));
 }
 
 /*
@@ -307,7 +393,7 @@
 		switch (vci) {
 
 		case VCI_PPC:
-			sig_print(ndo, p, caplen);
+			sig_print(ndo, p);
 			return;
 
 		case VCI_BCC:
@@ -360,7 +446,7 @@
     uint8_t unused[28];
 };
 
-int
+void
 oam_print (netdissect_options *ndo,
            const u_char *p, u_int length, u_int hec)
 {
@@ -374,6 +460,7 @@
     } 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;
@@ -390,7 +477,7 @@
            clp, length));
 
     if (!ndo->ndo_vflag) {
-        return 1;
+        return;
     }
 
     ND_PRINT((ndo, "\n\tcell-type %s (%u)",
@@ -409,6 +496,7 @@
     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",
@@ -431,6 +519,7 @@
     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++) {
@@ -449,6 +538,7 @@
     }
 
     /* 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);
@@ -457,5 +547,9 @@
            cksum,
            cksum_shouldbe == 0 ? "" : "in"));
 
-    return 1;
+    return;
+
+trunc:
+    ND_PRINT((ndo, "[|oam]"));
+    return;
 }
diff --git a/print-babel.c b/print-babel.c
index 75cb32c..f8741d7 100644
--- a/print-babel.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <stdio.h>
 #include <string.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 #include "extract.h"
 
@@ -53,7 +54,7 @@
     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 @@
 #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 @@
     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 @@
     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 @@
             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 @@
                 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 @@
     } /* 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 @@
 
     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 @@
                 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 @@
                 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 @@
                 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 @@
                 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 @@
                 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 @@
                 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 @@
                 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 @@
                 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 @@
                 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 @@
                 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 @@
             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 @@
     ND_PRINT((ndo, " %s", tstr));
     return;
 
- corrupt:
-    ND_PRINT((ndo, " (corrupt)"));
+ invalid:
+    ND_PRINT((ndo, "%s", istr));
     return;
 }
diff --git a/print-beep.c b/print-beep.c
index 7982feb..ed502b9 100644
--- a/print-beep.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <string.h>
 
-#include "interface.h"
+#include "netdissect.h"
 
 /* Check for a string but not go beyond length
  * Return TRUE on match, FALSE otherwise
diff --git a/print-bfd.c b/print-bfd.c
index f1c2ee8..ad0a406 100644
--- a/print-bfd.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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 @@
     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 @@
     { 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_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 @@
     { 0x08, "Control Plane Independent" },
     { BFD_FLAG_AUTH, "Authentication Present" },
     { 0x02, "Demand" },
-    { 0x01, "Reserved" },
+    { 0x01, "Multipoint" },
     { 0, NULL }
 };
 
@@ -158,12 +177,122 @@
     { 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 @@
             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/print-bgp.c b/print-bgp.c
index c617c3b..79afeab 100644
--- a/print-bgp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <stdio.h>
 #include <string.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 #include "extract.h"
 #include "af.h"
@@ -121,18 +122,25 @@
 #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 @@
     { 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 @@
 #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 @@
     { 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 @@
     { 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 @@
 #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 @@
   { 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 @@
 		((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 @@
 	}
         /* 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 @@
         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 @@
     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 @@
         /* 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 @@
  * 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 @@
 	    /* 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 @@
 
 	    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 @@
 		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 @@
         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 @@
 		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 @@
 	}
         /* 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 @@
         /* 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 @@
 trunc:
 	return -2;
 }
-#endif
 
 static int
 decode_clnp_prefix(netdissect_options *ndo,
@@ -1194,7 +1234,7 @@
 			((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 @@
         /* 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 @@
 	u_int tlen;
 	const u_char *tptr;
 	char buf[MAXHOSTNAMELEN + 100];
-	char tokbuf[TOKBUFSIZE];
         int  as_size;
 
         tptr = pptr;
@@ -1327,14 +1366,12 @@
 			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 @@
 
 		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 @@
 				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 @@
 			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 @@
                 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 @@
 		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 @@
 			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 @@
                 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 @@
 		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 @@
                 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 @@
                 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 @@
                                 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 @@
                                 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 @@
                                 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 @@
                                 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 @@
                                 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 @@
                         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 @@
                                 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 @@
                         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 @@
                         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 @@
 		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 @@
                         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 @@
                         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 @@
                     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 @@
                         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 @@
                     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 @@
                 }
                 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 @@
                 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 @@
                     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 @@
 		}
                 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 @@
 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 @@
                 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 @@
                     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 @@
                             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 @@
 	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 @@
 	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 @@
 		}
 
 		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 @@
 	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 @@
 		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 @@
 			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 @@
 {
 	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 @@
             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 @@
 		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 @@
                         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_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 @@
                  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 @@
 	};
 	struct bgp bgp;
 	uint16_t hlen;
-	char tokbuf[TOKBUFSIZE];
 
 	ep = dat + length;
 	if (ndo->ndo_snapend < dat + length)
@@ -2761,10 +2815,9 @@
 			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/print-bootp.c b/print-bootp.c
index fe0a070..fe798a0 100644
--- a/print-bootp.c
+++ b/print-bootp.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 bootp packets.
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: BOOTP and IPv4 DHCP printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <string.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 #include "extract.h"
 
@@ -213,8 +212,9 @@
 #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)
@@ -222,6 +222,7 @@
 #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
@@ -292,6 +293,7 @@
 	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)));
@@ -354,7 +356,8 @@
 	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;
@@ -364,7 +367,8 @@
 	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;
@@ -520,13 +524,14 @@
 	{ 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 */
@@ -997,7 +1002,7 @@
 						break;
 					}
 					if (len < suboptlen) {
-						ND_PRINT((ndo, "ERROR: malformed option"));
+						ND_PRINT((ndo, "ERROR: invalid option"));
 						bp += len;
 						len = 0;
 						break;
diff --git a/print-bt.c b/print-bt.c
index 128daad..b37f8fa 100644
--- a/print-bt.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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/print-calm-fast.c b/print-calm-fast.c
index 5cc39f4..c9be008 100644
--- a/print-calm-fast.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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/print-carp.c b/print-carp.c
index 7b9f28c..c650d18 100644
--- a/print-carp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h" /* for checksum structure and functions */
+#include "netdissect.h" /* for checksum structure and functions */
 #include "extract.h"
 
 void
diff --git a/print-cdp.c b/print-cdp.c
index 932f7bc..6f8f356 100644
--- a/print-cdp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <string.h>
 
-#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 @@
 			ND_PRINT((ndo, "\n\t  "));
 			for (i=0;i<len;i++) {
 			    j = *(tptr+i);
-			    ND_PRINT((ndo, "%c", j));
-			    if (j == 0x0a) /* lets rework the version string to get a nice indentation */
-				ND_PRINT((ndo, "\t  "));
+			    if (j == '\n') /* lets rework the version string to
+					      get a nice indentation */
+				ND_PRINT((ndo, "\n\t  "));
+			    else
+				fn_print_char(ndo, j);
 			}
 			break;
 		    case 0x06: /* Platform */
@@ -278,11 +281,9 @@
 {
 	int pt, pl, al, num;
 	const u_char *endp = p + l;
-#ifdef INET6
 	static const u_char prot_ipv6[] = {
 		0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x86, 0xdd
 	};
-#endif
 
 	ND_TCHECK2(*p, 4);
 	if (p + 4 > endp)
@@ -317,7 +318,6 @@
 			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 @@
 			ND_PRINT((ndo, "IPv6 (%u) %s", num, ip6addr_string(ndo, p)));
 			p += al;
 		}
-#endif
 		else {
 			/*
 			 * Generic case: just print raw data
diff --git a/print-cfm.c b/print-cfm.c
index a85eec0..43ad438 100644
--- a/print-cfm.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <stdio.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 #include "ether.h"
 #include "addrtoname.h"
@@ -65,18 +64,15 @@
 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 @@
 
 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 @@
 
 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 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 @@
      * 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 @@
     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 @@
 
     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 @@
     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 @@
                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));
 
-        if (msg_ptr.cfm_ccm->md_nameformat != CFM_CCM_MD_FORMAT_NONE) {
+            /* -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;
+            }
+
+            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 @@
         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 @@
 
     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 @@
     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 @@
         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));
+               cfm_tlv_type));
 
-        /* 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);
+        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 @@
             u_int chassis_id_type, chassis_id_length;
             u_int mgmt_addr_length;
 
-            /*
-             * Check if there is a Chassis-ID.
-             */
-            chassis_id_length = *tptr;
-            if (chassis_id_length > tlen) {
-                hexdump = TRUE;
-                break;
+            if (cfm_tlv_len < 1) {
+                ND_PRINT((ndo, " (too short, must be >= 1)"));
+                return;
             }
 
+            /*
+             * Get the Chassis ID length and check it.
+             */
+            chassis_id_length = *tptr;
             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 @@
                        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 @@
                     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 @@
         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/print-chdlc.c b/print-chdlc.c
index 3951ef7..450d286 100644
--- a/print-chdlc.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 #include "ethertype.h"
 #include "extract.h"
@@ -96,9 +97,9 @@
                 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/print-cip.c b/print-cip.c
index 91abe08..a123b69 100644
--- a/print-cip.c
+++ b/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 <string.h>
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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 @@
 	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 @@
 {
 	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/print-cnfp.c b/print-cnfp.c
index d80d7fd..e3e9b6d 100644
--- a/print-cnfp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <stdio.h>
 #include <string.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 #include "extract.h"
 
diff --git a/print-dccp.c b/print-dccp.c
index 45468b5..6e25264 100644
--- a/print-dccp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <stdio.h>
 #include <string.h>
 
-#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 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 @@
 {
 	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 @@
 
 	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 @@
 	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 @@
 		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 @@
 	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 @@
 		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 @@
 		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 @@
 
 	/* process options */
 	if (hlen > fixed_hdrlen){
-		const u_char *cp;
 		u_int optlen;
 		cp = bp + fixed_hdrlen;
 		ND_PRINT((ndo, " <"));
diff --git a/print-decnet.c b/print-decnet.c
index 5414ec2..88aa9e3 100644
--- a/print-decnet.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 struct mbuf;
 struct rtentry;
@@ -38,12 +39,12 @@
 #include <string.h>
 
 #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 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 @@
 #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 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 @@
 	    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 @@
                     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 @@
 	    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 @@
 	    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 @@
 
 	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 @@
 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 @@
 	    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 @@
 			}
 		    }
 		    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 @@
 			}
 		    }
 		    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 @@
 	    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 @@
 	    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 @@
 		    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 @@
 		    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 @@
 			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 @@
 		    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 @@
 		    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_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 @@
 }
 
 const char *
-dnnum_string(u_short dnaddr)
+dnnum_string(netdissect_options *ndo, u_short dnaddr)
 {
 	char *str;
 	size_t siz;
@@ -1305,13 +1246,13 @@
 
 	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 @@
 	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/print-dhcp6.c b/print-dhcp6.c
index 53b96ef..762d918 100644
--- a/print-dhcp6.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <stdio.h>
 #include <string.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 #include "extract.h"
 
@@ -103,8 +105,8 @@
 /* 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 @@
 
 /* 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 @@
 #  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 @@
 	{ 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 @@
 	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 @@
 				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 @@
 				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 @@
 				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 @@
 				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 @@
 				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 @@
 				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 @@
 			 * 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 @@
 				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 @@
 				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 @@
 				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 @@
 				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 @@
 				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 @@
 				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 @@
 				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 @@
 				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 @@
 			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 @@
 				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 @@
 				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 @@
 				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 @@
 			}
 			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 @@
 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 @@
 	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 @@
 		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/print-domain.c b/print-domain.c
index 8805007..d0b6996 100644
--- a/print-domain.c
+++ b/print-domain.c
@@ -19,20 +19,22 @@
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: Domain Name System (DNS) printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include "nameser.h"
 
 #include <string.h>
 
-#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",
@@ -395,7 +397,7 @@
 	} 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 {
@@ -481,17 +483,14 @@
 			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;
 	    }
@@ -515,7 +514,7 @@
 			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, " "));
@@ -524,12 +523,11 @@
 		}
 		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 */
@@ -666,7 +664,7 @@
 		    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/print-dtp.c b/print-dtp.c
index 5d84a77..1d8c66a 100644
--- a/print-dtp.c
+++ b/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 <carles.kishimoto@gmail.com>
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: Dynamic Trunking Protocol (DTP) printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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 @@
     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 @@
 
     return;
 
+ invalid:
+    ND_PRINT((ndo, "%s", istr));
+    return;
  trunc:
-    ND_PRINT((ndo, "[|dtp]"));
+    ND_PRINT((ndo, "%s", tstr));
 }
 
 /*
diff --git a/print-dvmrp.c b/print-dvmrp.c
index 96a0ee7..60f836e 100644
--- a/print-dvmrp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 #include "addrtoname.h"
 
@@ -337,7 +338,7 @@
 	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/print-eap.c b/print-eap.c
index 0e2c2d3..125e1ee 100644
--- a/print-eap.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 
 #define	EAP_FRAME_TYPE_PACKET		0
@@ -151,7 +149,7 @@
 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/print-egp.c b/print-egp.c
index 9c5c811..8fba9ce 100644
--- a/print-egp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 #include "extract.h"
 
@@ -128,7 +129,7 @@
 
 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 @@
 		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 @@
 			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 @@
 		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 @@
 	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->egp_intgw,
 		       egp->egp_extgw));
 		if (ndo->ndo_vflag)
-			egpnrprint(ndo, egp);
+			egpnrprint(ndo, egp, length);
 		break;
 
 	case EGPT_ERROR:
diff --git a/print-eigrp.c b/print-eigrp.c
index cab77ba..7e1ffb7 100644
--- a/print-eigrp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <string.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 #include "addrtoname.h"
 
diff --git a/print-enc.c b/print-enc.c
index 7bd8631..d791b3f 100644
--- a/print-enc.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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 @@
 		goto out;
 	}
 
-	hdr = (struct enchdr *)p;
+	hdr = (const struct enchdr *)p;
 	flags = hdr->flags;
 	if (flags == 0)
 		ND_PRINT((ndo, "(unprotected): "));
diff --git a/print-esp.c b/print-esp.c
index 8e267d4..375075a 100644
--- a/print-esp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <string.h>
 #include <stdlib.h>
@@ -43,14 +44,15 @@
 #endif
 #endif
 
-#include "ip.h"
-#ifdef INET6
-#include "ip6.h"
-#endif
-
-#include "interface.h"
+#include "netdissect.h"
+#include "strtoaddr.h"
 #include "extract.h"
 
+#include "ascii_strcasecmp.h"
+
+#include "ip.h"
+#include "ip6.h"
+
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  * All rights reserved.
@@ -98,9 +100,7 @@
 #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 @@
 	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 @@
 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 @@
 
 	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, buf, buf, len);
+	EVP_CIPHER_CTX_free(ctx);
 
 	ndo->ndo_packetp = buf;
 	ndo->ndo_snapend = end;
@@ -332,8 +360,8 @@
 	}
 	*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 @@
 	} 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 @@
 			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 @@
 
 		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 @@
 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 @@
 	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 @@
 	/* '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 @@
 	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 @@
 			}
 		}
 		break;
-#endif /*INET6*/
 	case 4:
 		/* nexthdr & padding are in the last fragment */
 		if (EXTRACT_16BITS(&ip->ip_off) & IP_MF)
@@ -675,21 +703,24 @@
 		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");
+		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, p + ivlen, p + ivlen, ep - (p + ivlen));
-		EVP_CIPHER_CTX_cleanup(&ctx);
-		advance = ivoff - (u_char *)esp + ivlen;
+			p = ivoff;
+			EVP_CipherInit(ctx, NULL, NULL, p, 0);
+			EVP_Cipher(ctx, 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/print-ether.c b/print-ether.c
index e57d993..bbfd7e9 100644
--- a/print-ether.c
+++ b/print-ether.c
@@ -19,14 +19,15 @@
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: Ethernet printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 #include "addrtoname.h"
 #include "ethertype.h"
@@ -83,6 +84,7 @@
     { ETHERTYPE_GEONET,         "GeoNet"},
     { ETHERTYPE_CALM_FAST,      "CALM FAST"},
     { ETHERTYPE_AOE,            "AoE" },
+    { ETHERTYPE_MEDSA,          "MEDSA" },
     { 0, NULL}
 };
 
@@ -91,7 +93,7 @@
                 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;
 
@@ -99,19 +101,21 @@
 		     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));
@@ -122,20 +126,28 @@
  * 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;
+		return (caplen);
+	}
+	if (length < ETHER_HDRLEN) {
+		ND_PRINT((ndo, "[|ether]"));
+		return (length);
 	}
 
 	if (ndo->ndo_eflag) {
@@ -147,55 +159,61 @@
 
 	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;
+			return (hdrlen + caplen);
+		}
+		if (length < 4) {
+			ND_PRINT((ndo, "[|vlan]"));
+			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
@@ -206,53 +224,48 @@
 		 * 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.
@@ -270,16 +283,14 @@
 	}
 
 	/* 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
@@ -300,9 +311,7 @@
 	}
 
 	/* 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));
 }
 
 /*
@@ -315,7 +324,8 @@
 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) {
 
@@ -329,7 +339,7 @@
 
 	case ETHERTYPE_ARP:
 	case ETHERTYPE_REVARP:
-  	        arp_print(ndo, p, length, caplen);
+	        arp_print(ndo, p, length, caplen);
 		return (1);
 
 	case ETHERTYPE_DN:
@@ -352,7 +362,11 @@
 		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:
@@ -367,7 +381,7 @@
 		return (1);
 
 	case ETHERTYPE_RRCP:
-	        rrcp_print(ndo, p - 14 , length + 14);
+	        rrcp_print(ndo, p, length, src, dst);
 		return (1);
 
 	case ETHERTYPE_PPP:
@@ -413,17 +427,21 @@
 
         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/print-fddi.c b/print-fddi.c
index ad760c8..2780378 100644
--- a/print-fddi.c
+++ b/print-fddi.c
@@ -19,16 +19,17 @@
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: Fiber Distributed Data Interface (FDDI) printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <string.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 #include "ether.h"
 
@@ -84,9 +85,9 @@
  * 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
 
 /*
@@ -259,17 +260,11 @@
 	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
@@ -278,16 +273,17 @@
 	ND_PRINT((ndo, "<SMT printer not yet implemented>"));
 }
 
-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);
 	}
 
 	/*
@@ -298,6 +294,11 @@
 	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;
@@ -306,32 +307,29 @@
 	/* 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);
 }
 
 /*
@@ -343,7 +341,5 @@
 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/print-forces.c b/print-forces.c
index 6c02b25..de6c826 100644
--- a/print-forces.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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 @@
  * 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 @@
 	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 @@
 
 #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 @@
 #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 @@
 }
 
 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 @@
 			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 @@
 #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 @@
               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 @@
                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 @@
                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 @@
 		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 @@
                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 @@
                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 @@
 	 * 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 @@
 		}
 
 		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 @@
 			/* 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 @@
 	}
 
 	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 @@
             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 @@
                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 @@
 		 * 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 @@
                  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 @@
 		 */
 		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 @@
            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 @@
 	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 @@
 	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 @@
 		 * 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 @@
 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 @@
                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 @@
 		 * 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 @@
 		       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 @@
 			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 @@
 			       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/print-fr.c b/print-fr.c
index 0832522..da7ee25 100644
--- a/print-fr.c
+++ b/print-fr.c
@@ -19,17 +19,18 @@
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: Frame Relay printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <stdio.h>
 #include <string.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 #include "ethertype.h"
 #include "llc.h"
@@ -275,7 +276,8 @@
                         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
@@ -327,11 +329,11 @@
 	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,
@@ -597,6 +599,10 @@
 {
     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];
 
@@ -614,7 +620,10 @@
  * model is end-to-end or interface based wether we want to print
  * another Q.922 header
  */
+    return;
 
+trunc:
+    ND_PRINT((ndo, "[|frf.15]"));
 }
 
 /*
@@ -682,7 +691,11 @@
     { 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? */
@@ -693,7 +706,7 @@
 #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" },
@@ -715,14 +728,14 @@
     { 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[] = {
-    NULL,
-    fr_q933_ie_values_codeset5,
+    fr_q933_ie_values_codeset_0_5,
     NULL,
     NULL,
     NULL,
-    fr_q933_ie_values_codeset5,
+    NULL,
+    fr_q933_ie_values_codeset_0_5,
     NULL,
     NULL,
     NULL,
@@ -735,20 +748,20 @@
     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[] = {
-    NULL,
-    fr_q933_print_ie_codeset5,
+    fr_q933_print_ie_codeset_0_5,
     NULL,
     NULL,
     NULL,
-    fr_q933_print_ie_codeset5,
+    NULL,
+    fr_q933_print_ie_codeset_0_5,
     NULL,
     NULL,
     NULL,
@@ -761,121 +774,316 @@
     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;
+	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;
 
-	if (length < 9) {	/* shortest: Q.933a LINK VERIFY */
-		ND_PRINT((ndo, "[|q.933]"));
-		return;
+	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 */
+	/*
+	 * Get the length of the call reference value.
+	 */
+	olen = length; /* preserve the original length for display */
+	call_ref_length = (*p) & 0x0f;
+	p++;
+	length--;
 
-	if (p[2] == MSG_ANSI_LOCKING_SHIFT) {
-	        is_ansi = 1;
+	/*
+	 * 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",
+	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", p[1]),
-		       p[1],
-		       length));
-        } else {
-                ND_PRINT((ndo, ", %s",
-		       tok2str(fr_q933_msg_values,
-			       "unknown message 0x%02x", p[1])));
+			       "unknown message 0x%02x", msgtype)));
 	}
 
-        olen = length; /* preserve the original length for non verbose mode */
+	/* 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 (length < (u_int)(2 - is_ansi)) {
-		ND_PRINT((ndo, "[|q.933]"));
-		return;
+		/*
+		 * 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--;
+
+		/* 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 -= 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);
-		}
-
-                if (ndo->ndo_vflag >= 1 && !ie_is_known) {
-                    print_unknown_data(ndo, ptemp+2, "\n\t", ie_p->ie_len);
-		}
-
-                /* 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);
-		}
-
-		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;
 
@@ -885,7 +1093,11 @@
             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 */
@@ -894,28 +1106,29 @@
                 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/print-frag6.c b/print-frag6.c
index 1290952..db4a98e 100644
--- a/print-frag6.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include "ip6.h"
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 
 int
@@ -68,4 +67,3 @@
 	ND_PRINT((ndo, "[|frag]"));
 	return -1;
 }
-#endif /* INET6 */
diff --git a/print-ftp.c b/print-ftp.c
index 5479042..a1dd607 100644
--- a/print-ftp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/print-geneve.c b/print-geneve.c
index 2187ab8..40402ab 100644
--- a/print-geneve.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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 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 @@
         }
 
         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 @@
 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 @@
 
     if (len < opts_len) {
         ND_PRINT((ndo, " truncated-geneve - %u bytes missing",
-                  len - opts_len));
+                  opts_len - len));
         return;
     }
 
@@ -209,9 +223,9 @@
     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/print-geonet.c b/print-geonet.c
index edfb7f2..9da89bf 100644
--- a/print-geonet.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 #include "addrtoname.h"
 
@@ -85,6 +86,8 @@
 {
 	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 @@
  * 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 @@
 	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 @@
 	/* 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 @@
 			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 @@
 		ND_DEFAULTPRINT(bp, length);
 	return;
 
-malformed:
+invalid:
 	ND_PRINT((ndo, " Malformed (small) "));
 	/* XXX - print the remaining data as hex? */
 	return;
diff --git a/print-gre.c b/print-gre.c
index 4d7705f..505752a 100644
--- a/print-gre.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <string.h>
 
-#include "interface.h"
+#include "netdissect.h"
+#include "addrtostr.h"
 #include "extract.h"
 #include "ethertype.h"
 
@@ -78,19 +80,18 @@
 
 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 @@
             ND_PRINT((ndo, " ERROR: unknown-version"));
             break;
         }
+        return;
+
+trunc:
+	ND_PRINT((ndo, "%s", tstr));
+	return;
 }
 
 static void
@@ -121,6 +127,7 @@
 	len -= 2;
 	bp += 2;
 
+	ND_TCHECK2(*bp, 2);
 	if (len < 2)
 		goto trunc;
 	prot = EXTRACT_16BITS(bp);
@@ -128,6 +135,7 @@
 	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 @@
 		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 @@
 	}
 
 	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 @@
 	}
 
 	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 @@
 			uint8_t sreoff;
 			uint8_t srelen;
 
+			ND_TCHECK2(*bp, 4);
 			if (len < 4)
 				goto trunc;
 			af = EXTRACT_16BITS(bp);
@@ -175,7 +187,8 @@
 			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 @@
 		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 @@
             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 @@
 	if (flags & GRE_KP) {
 		uint32_t k;
 
+		ND_TCHECK2(*bp, 4);
 		if (len < 4)
 			goto trunc;
 		k = EXTRACT_32BITS(bp);
@@ -260,6 +275,7 @@
 	}
 
 	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 @@
 	}
 
 	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 @@
 	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 @@
 
 	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 @@
 		len -= 2;
 		srelen -= 2;
 	}
+	return (1);
 }
diff --git a/print-hncp.c b/print-hncp.c
new file mode 100644
index 0000000..87ee8bb
--- /dev/null
+++ b/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 <netdissect-stdinc.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#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/print-hsrp.c b/print-hsrp.c
index 0e2420f..3514646 100644
--- a/print-hsrp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 
 /* HSRP op code types. */
@@ -94,7 +95,7 @@
 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 @@
 	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/print-http.c b/print-http.c
index 49df174..0aec758 100644
--- a/print-http.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 
 /*
diff --git a/print-icmp.c b/print-icmp.c
index 59eb007..17e7a75 100644
--- a/print-icmp.c
+++ b/print-icmp.c
@@ -19,19 +19,20 @@
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: Internet Control Message Protocol (ICMP) printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <stdio.h>
 #include <string.h>
 
-#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"
@@ -344,9 +345,9 @@
 	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);
@@ -378,7 +379,7 @@
 			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) {
@@ -387,14 +388,14 @@
 				(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:
@@ -409,7 +410,7 @@
 		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),
@@ -450,7 +451,7 @@
 		(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);
@@ -480,7 +481,7 @@
 			    " [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}",
@@ -557,9 +558,9 @@
 	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) {
@@ -578,7 +579,7 @@
 	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));
@@ -599,7 +600,7 @@
              * 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;
@@ -619,7 +620,7 @@
             }
 
             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),
@@ -627,11 +628,11 @@
                    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/print-icmp6.c b/print-icmp6.c
index 81563e6..7fe639d 100644
--- a/print-icmp6.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <stdio.h>
 #include <string.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
+#include "addrtostr.h"
 #include "extract.h"
 
 #include "ip6.h"
@@ -284,13 +284,13 @@
 #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 @@
 	}
 }
 
-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 @@
         { 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 @@
 };
 
 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 @@
         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 @@
                         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 @@
 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_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 @@
 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 = "<elided>";
 
         ND_TCHECK(*dao);
         if (length < ND_RPL_DAO_MIN_LEN)
         	goto tooshort;
 
-        strcpy(dagid_str,"<elided>");
         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 @@
                   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 @@
 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 = "<elided>";
 
         ND_TCHECK2(*daoack, ND_RPL_DAOACK_MIN_LEN);
         if (length < ND_RPL_DAOACK_MIN_LEN)
         	goto tooshort;
 
-        strcpy(dagid_str,"<elided>");
         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 @@
 
         /* 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 @@
 	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 @@
 
 		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 @@
                                   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 @@
 			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 @@
 	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 @@
 		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 @@
 		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 @@
 	    }
 		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 @@
                 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 @@
 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 @@
 		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 @@
 		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 @@
 			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 @@
 			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 @@
 	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 @@
 			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 @@
 			/* 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 @@
 			}
 			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 @@
 			}
 			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 @@
 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 @@
 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 @@
 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 @@
 
 	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 @@
 		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 @@
 				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 @@
 				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 @@
 
 		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 @@
 			} 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 @@
 			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 @@
 {
 	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 @@
 	}
 
 	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 @@
 			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 @@
 			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 @@
 					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 @@
 	ND_PRINT((ndo,"[|icmp6]"));
 }
 
-#endif /* INET6 */
-
 /*
  * Local Variables:
  * c-style: whitesmith
diff --git a/print-igmp.c b/print-igmp.c
index e4808a7..0bb7f97 100644
--- a/print-igmp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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 @@
                    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 @@
         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 @@
         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/print-igrp.c b/print-igrp.c
index fbb3134..b6eaf31 100644
--- a/print-igrp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
-#include "extract.h"			/* must come after interface.h */
+#include "netdissect.h"
+#include "extract.h"
 
 /* Cisco IGRP definitions */
 
@@ -65,7 +66,7 @@
 #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 @@
 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 @@
 	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/print-ip.c b/print-ip.c
index ceea536..bb1554f 100644
--- a/print-ip.c
+++ b/print-ip.c
@@ -19,18 +19,19 @@
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: IP printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <string.h>
 
-#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"
@@ -123,7 +124,7 @@
 		}
 	}
 trunc:
-	UNALIGNED_MEMCPY(&retval, &ip->ip_dst.s_addr, sizeof(uint32_t));
+	UNALIGNED_MEMCPY(&retval, &ip->ip_dst, sizeof(uint32_t));
 	return retval;
 }
 
@@ -148,9 +149,9 @@
 	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);
 
@@ -324,12 +325,15 @@
 	       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)
@@ -354,14 +358,14 @@
 
 	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:
@@ -455,9 +459,7 @@
 		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:
@@ -528,13 +530,14 @@
 
 	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);
@@ -582,17 +585,22 @@
         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)
@@ -615,12 +623,12 @@
 
             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) {
@@ -649,22 +657,24 @@
 		}
 		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;
 
@@ -676,24 +686,28 @@
 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/print-ip6.c b/print-ip6.c
index dd6b7f5..9f590f2 100644
--- a/print-ip6.c
+++ b/print-ip6.c
@@ -19,29 +19,149 @@
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: IPv6 printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <string.h>
 
-#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 {
@@ -56,7 +176,26 @@
         /* 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;
 
@@ -154,15 +293,19 @@
 		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;
@@ -171,9 +314,7 @@
 		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
@@ -216,15 +357,19 @@
 		    }
 		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:
@@ -265,13 +410,3 @@
 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/print-ip6opts.c b/print-ip6opts.c
index 14ad42c..4c16d80 100644
--- a/print-ip6opts.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include "ip6.h"
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 #include "extract.h"
 
@@ -173,7 +173,7 @@
 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 @@
 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 @@
     ND_PRINT((ndo, "[|DSTOPT]"));
     return(-1);
 }
-#endif /* INET6 */
diff --git a/print-ipcomp.c b/print-ipcomp.c
index 1ba687e..291caa9 100644
--- a/print-ipcomp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 struct ipcomp {
 	uint8_t comp_nxt;	/* Next Header */
@@ -32,52 +33,37 @@
 	uint16_t comp_cpi;	/* Compression parameter index */
 };
 
-#if defined(HAVE_LIBZ) && defined(HAVE_ZLIB_H)
-#include <zlib.h>
-#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/print-ipfc.c b/print-ipfc.c
index 295ac0f..b8a08e9 100644
--- a/print-ipfc.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <string.h>
 
-#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 @@
 	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 @@
 	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 @@
 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/print-ipnet.c b/print-ipnet.c
index c4ff16a..f71c145 100644
--- a/print-ipnet.c
+++ b/print-ipnet.c
@@ -1,11 +1,12 @@
-#define NETDISSECT_REWORKED
+/* \summary: Solaris DLT_IPNET printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 
 typedef struct ipnet_hdr {
 	uint8_t		iph_version;
@@ -55,7 +56,7 @@
 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 @@
 
 	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 @@
 
 	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/print-ipx.c b/print-ipx.c
index 93f5d59..d807a66 100644
--- a/print-ipx.c
+++ b/print-ipx.c
@@ -18,20 +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).
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: Novell IPX printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <stdio.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 #include "extract.h"
 
@@ -89,7 +89,7 @@
 	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));
@@ -117,14 +117,14 @@
 	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;
@@ -133,7 +133,7 @@
 	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;
@@ -165,7 +165,7 @@
 	    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:
@@ -177,14 +177,14 @@
 
 	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/print-isakmp.c b/print-isakmp.c
index bef0b45..3dfa171 100644
--- a/print-isakmp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <string.h>
 
-#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 @@
 	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 @@
 	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 @@
 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 @@
 	    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 @@
 #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 @@
 		? 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 @@
 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 @@
 		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 @@
 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 @@
 				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 @@
 				return 1;
 		}
 		break;
-#endif /* INET6 */
 	default:
 		break;
 	}
@@ -859,18 +848,18 @@
 }
 
 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 @@
 	}
 
 	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 @@
 		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 @@
 	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 @@
 
 	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 @@
 	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 @@
 	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 @@
 		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 @@
 
 	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 @@
 
 	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 @@
 		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 @@
 	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 @@
 
 	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 @@
 #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 @@
 			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 @@
 			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 @@
 			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 @@
 			}
 			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 @@
 			}
 			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 @@
 		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 @@
 
 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 @@
 
 	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 @@
 
 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 @@
 
 	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 @@
 	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 @@
 	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 @@
 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 @@
 	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 @@
 	      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 @@
 
 	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 @@
 			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 @@
 		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 @@
 			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 @@
 		}
 		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 @@
 
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	}
 
 	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 @@
 
 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 @@
 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);
 
-	return (u_char *)ext1 + osa_length;
+		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);
+
+		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 @@
 		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 @@
 
 	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 @@
 	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 @@
 	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 @@
 		}
 	}
 	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 @@
 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 @@
 
 	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 @@
 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 @@
 	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 @@
 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 @@
 
 	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 @@
 
 	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 @@
 		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 @@
 	}
 	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 @@
 	      int depth)
 {
 	struct isakmp_gen e;
-	u_char *dat;
+	const u_char *dat;
 	volatile int dlen;
 
 	ND_TCHECK(*ext);
@@ -2504,11 +2613,11 @@
 	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 @@
 	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 @@
 		}
 
 		np = e.np;
-		ext = (struct isakmp_gen *)cp;
+		ext = (const struct isakmp_gen *)cp;
 	}
 	return cp;
 trunc:
@@ -2668,7 +2777,7 @@
 
 	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 @@
 
 		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 @@
 
 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 @@
 	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 @@
 	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 @@
 		 * 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 @@
 {
 	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 @@
 		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 @@
 		}
 
 		np = e.np;
-		ext = (struct isakmp_gen *)cp;
+		ext = (const struct isakmp_gen *)cp;
 	}
 	return cp;
 trunc:
@@ -2861,7 +2961,7 @@
 		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 @@
 	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 @@
 
 	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/print-isoclns.c b/print-isoclns.c
index 4536f65..d08085f 100644
--- a/print-isoclns.c
+++ b/print-isoclns.c
@@ -24,16 +24,17 @@
  * complete IS-IS & CLNP support.
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: ISO CLNS, ESIS, and ISIS printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <string.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 #include "ether.h"
 #include "nlpid.h"
@@ -42,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.
  */
@@ -103,6 +106,7 @@
 #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 */
@@ -152,6 +156,7 @@
     { 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"},
@@ -559,7 +564,7 @@
     uint8_t neighbor_extd_local_circuit_id[4];
 };
 
-static void osi_print_cksum(netdissect_options *, const uint8_t *pptr,
+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);
@@ -664,8 +669,9 @@
 #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"));
@@ -785,6 +791,18 @@
             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;
@@ -792,22 +810,46 @@
 
         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);
@@ -823,19 +865,24 @@
                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",
@@ -851,19 +898,19 @@
             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;
@@ -873,11 +920,23 @@
                    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)));
@@ -904,17 +963,25 @@
                                     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)));
 
@@ -926,12 +993,20 @@
                     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)",
@@ -1049,12 +1124,12 @@
         }
 
 	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;
@@ -1078,7 +1153,8 @@
         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));
@@ -1110,7 +1186,7 @@
 		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) {
@@ -1147,7 +1223,7 @@
 		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;
 	}
 
@@ -1180,7 +1256,7 @@
             	}
                 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--;
@@ -1202,7 +1278,7 @@
                 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;
@@ -1295,14 +1371,11 @@
 {
   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)));
 
@@ -1310,6 +1383,9 @@
 
   for(i=0;i<16;i++)
     ND_PRINT((ndo, "%.2x ", mcid->digest[i]));
+
+trunc:
+  ND_PRINT((ndo, "%s", tstr));
 }
 
 static int
@@ -1320,7 +1396,7 @@
   const struct isis_subtlv_spb_mcid *subtlv_spb_mcid;
   int i;
 
-  while (len > 0)
+  while (len > 2)
   {
     stlv_type = *(tptr++);
     stlv_len  = *(tptr++);
@@ -1338,10 +1414,9 @@
     {
       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));
@@ -1362,8 +1437,7 @@
 
       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),
@@ -1388,13 +1462,11 @@
 
       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)));
@@ -1420,8 +1492,9 @@
 
   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);
 }
 
@@ -1431,7 +1504,7 @@
 {
   int stlv_type, stlv_len, tmp;
 
-  while (len > 0)
+  while (len > 2)
   {
     stlv_type = *(tptr++);
     stlv_len  = *(tptr++);
@@ -1448,8 +1521,7 @@
     {
       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;
@@ -1474,8 +1546,7 @@
 
           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,
@@ -1500,8 +1571,7 @@
 
       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;
@@ -1515,8 +1585,8 @@
           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,
@@ -1536,8 +1606,9 @@
   }
   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);
 }
 
@@ -1660,13 +1731,12 @@
                            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 */
@@ -1695,8 +1765,9 @@
     }
     return(1);
 
-trunctlv:
-    ND_PRINT((ndo, "%spacket exceeded snapshot", ident));
+trunc:
+    ND_PRINT((ndo, "%s", ident));
+    ND_PRINT((ndo, "%s", tstr));
     return(0);
 }
 
@@ -1721,8 +1792,7 @@
 	          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:
@@ -1767,6 +1837,7 @@
             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,
@@ -1828,11 +1899,13 @@
               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,
@@ -1855,12 +1928,10 @@
         }
         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)
@@ -1899,7 +1970,7 @@
                 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);
@@ -1948,11 +2019,7 @@
                          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))
@@ -1973,7 +2040,6 @@
             return (0);
         }
         processed++;
-#ifdef INET6
     } else if (afi == AF_INET6) {
         if (!ND_TTEST2(*tptr, 1)) /* fetch status & prefix_len byte */
             return (0);
@@ -1986,7 +2052,6 @@
             return (0);
         }
         processed+=2;
-#endif
     } else
         return (0); /* somebody is fooling us */
 
@@ -2004,13 +2069,11 @@
                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",
@@ -2018,17 +2081,13 @@
 
     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
@@ -2045,7 +2104,7 @@
                 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);
@@ -2057,6 +2116,20 @@
 }
 
 /*
+ * 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.
  */
@@ -2069,7 +2142,7 @@
 
     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;
 
@@ -2094,7 +2167,7 @@
     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;
 
@@ -2172,6 +2245,7 @@
 
 	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",
@@ -2179,10 +2253,12 @@
                    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),
@@ -2190,10 +2266,12 @@
 	    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;
 
@@ -2233,13 +2311,13 @@
 	    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),
@@ -2268,13 +2346,13 @@
 	    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),
@@ -2303,31 +2381,23 @@
 	    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,
@@ -2361,13 +2431,13 @@
 	    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));
@@ -2393,13 +2463,13 @@
 	    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));
@@ -2427,11 +2497,7 @@
             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 */
@@ -2449,32 +2515,29 @@
                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;
@@ -2492,8 +2555,7 @@
             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;
@@ -2539,16 +2601,14 @@
             }
             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);
@@ -2560,8 +2620,7 @@
         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);
@@ -2604,7 +2663,6 @@
 	    }
 	    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);
@@ -2634,8 +2692,7 @@
 
 	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)));
@@ -2644,10 +2701,8 @@
 		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,
@@ -2656,36 +2711,29 @@
 
 	    switch (*tptr) {
 	    case ISIS_SUBTLV_AUTH_SIMPLE:
-		for(i=1;i<tlv_len;i++) {
-		    if (!ND_TTEST2(*(tptr + i), 1))
-			goto trunctlv;
-		    ND_PRINT((ndo, "%c", *(tptr + i)));
-		}
+		if (fn_printzp(ndo, tptr + 1, tlv_len - 1, ndo->ndo_snapend))
+		    goto trunctlv;
 		break;
 	    case ISIS_SUBTLV_AUTH_MD5:
 		for(i=1;i<tlv_len;i++) {
-		    if (!ND_TTEST2(*(tptr + i), 1))
-			goto trunctlv;
+		    ND_TCHECK2(*(tptr + i), 1);
 		    ND_PRINT((ndo, "%02x", *(tptr + i)));
 		}
 		if (tlv_len != ISIS_SUBTLV_AUTH_MD5_LEN+1)
-                    ND_PRINT((ndo, ", (malformed subTLV) "));
+                    ND_PRINT((ndo, ", (invalid subTLV) "));
 
-#ifdef HAVE_LIBCRYPTO
-                sigcheck = signature_verify(ndo, optr, length,
-                                            (unsigned char *)tptr + 1);
-#else
-                sigcheck = CANT_CHECK_SIGNATURE;
-#endif
+                sigcheck = signature_verify(ndo, optr, length, tptr + 1,
+                                            isis_clear_checksum_lifetime,
+                                            header_lsp);
                 ND_PRINT((ndo, " (%s)", tok2str(signature_check_values, "Unknown", sigcheck)));
 
 		break;
             case ISIS_SUBTLV_AUTH_GENERIC:
+		ND_TCHECK2(*(tptr + 1), 2);
                 key_id = EXTRACT_16BITS((tptr+1));
                 ND_PRINT((ndo, "%u, password: ", key_id));
                 for(i=1 + sizeof(uint16_t);i<tlv_len;i++) {
-                    if (!ND_TTEST2(*(tptr + i), 1))
-                        goto trunctlv;
+                    ND_TCHECK2(*(tptr + i), 1);
                     ND_PRINT((ndo, "%02x", *(tptr + i)));
                 }
                 break;
@@ -2700,32 +2748,26 @@
 	case ISIS_TLV_PTP_ADJ:
 	    tlv_ptp_adj = (const struct isis_tlv_ptp_adj *)tptr;
 	    if(tmp>=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)));
 	    }
@@ -2734,8 +2776,7 @@
 	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",
@@ -2750,8 +2791,7 @@
 
     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),
@@ -2768,8 +2808,7 @@
 
     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,
@@ -2785,15 +2824,13 @@
       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);
@@ -2802,49 +2839,40 @@
 
 	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;
@@ -2854,18 +2882,14 @@
 	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++;
@@ -2875,15 +2899,30 @@
 	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:
@@ -2899,7 +2938,7 @@
                     tptr+=mt_len;
                     tmp-=mt_len;
 		} else {
-		    ND_PRINT((ndo, "\n\t      malformed MT-ID"));
+		    ND_PRINT((ndo, "\n\t      invalid MT-ID"));
 		    break;
 		}
 	    }
@@ -2909,8 +2948,7 @@
             /* 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;
@@ -2922,8 +2960,7 @@
 
             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;
@@ -2931,8 +2968,7 @@
 
             /* 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;
@@ -2940,16 +2976,14 @@
         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:
@@ -2964,15 +2998,13 @@
         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;
@@ -2982,16 +3014,14 @@
         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));
@@ -3000,10 +3030,9 @@
                 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;
             }
@@ -3012,16 +3041,14 @@
         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),
@@ -3066,15 +3093,16 @@
     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
+static int
 osi_print_cksum(netdissect_options *ndo, const uint8_t *pptr,
 	        uint16_t checksum, int checksum_offset, int length)
 {
@@ -3092,23 +3120,22 @@
             || checksum_offset > ndo->ndo_snaplen
             || checksum_offset > length) {
                 ND_PRINT((ndo, " (unverified)"));
+                return 1;
         } else {
-                const 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/print-juniper.c b/print-juniper.c
index e4bb77c..83ac372 100644
--- a/print-juniper.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include <string.h>
+
+#include "netdissect.h"
 #include "addrtoname.h"
 #include "extract.h"
 #include "ppp.h"
@@ -89,7 +92,7 @@
 };
 
 /* 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 @@
             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 @@
             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 @@
             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 @@
         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 @@
 {
         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 @@
 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 @@
         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 @@
 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 @@
         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 @@
     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 @@
             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/print-krb.c b/print-krb.c
index 2eebfa6..de69054 100644
--- a/print-krb.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 
 static const char tstr[] = " [|kerberos]";
@@ -156,7 +157,7 @@
 #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 @@
 {
 	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/print-l2tp.c b/print-l2tp.c
index 346dae9..42ae391 100644
--- a/print-l2tp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 
 #define L2TP_FLAG_TYPE		0x8000	/* Type (0=Data, 1=Control) */
@@ -298,7 +299,7 @@
 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 @@
 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 @@
 	}
 	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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 	        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 @@
 		} 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 @@
 			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 @@
 			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 @@
 			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/print-lane.c b/print-lane.c
index c1e0b2e..ba52084 100644
--- a/print-lane.c
+++ b/print-lane.c
@@ -20,14 +20,15 @@
  *
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: ATM LANE printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 #include "ether.h"
 
@@ -82,14 +83,14 @@
 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/print-ldp.c b/print-ldp.c
index 3f741d1..40c9d8c 100644
--- a/print-ldp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 #include "addrtoname.h"
 
@@ -284,12 +285,10 @@
         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 @@
 		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 @@
 		tptr+=sizeof(struct in6_addr);
 	    }
             break;
-#endif
         default:
             /* unknown AF */
             break;
@@ -365,7 +362,6 @@
 		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 @@
 		else
 		    ND_PRINT((ndo, ": IPv6 prefix %s", buf));
 	    }
-#endif
 	    else
 		ND_PRINT((ndo, ": Address family %u prefix", af));
 	    break;
@@ -385,16 +380,20 @@
 	    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 @@
             /* 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/print-lisp.c b/print-lisp.c
new file mode 100644
index 0000000..47afe50
--- /dev/null
+++ b/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 <netdissect-stdinc.h>
+#include <netdissect.h>
+#include <string.h>
+#include <stdlib.h>
+
+#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/print-llc.c b/print-llc.c
index e8a3314..6bdf599 100644
--- a/print-llc.c
+++ b/print-llc.c
@@ -22,16 +22,17 @@
  *	with an awful lot of hacking by Jeffrey Mogul, DECWRL
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: IEEE 802.2 LLC printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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"
@@ -138,23 +139,31 @@
 };
 
 /*
- * 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;
@@ -172,15 +181,21 @@
 		 * 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);
 		}
 
 		/*
@@ -188,6 +203,7 @@
 		 */
 		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) {
@@ -210,7 +226,7 @@
 		ND_PRINT((ndo, "IPX 802.3: "));
 
             ipx_print(ndo, p, length);
-            return (1);
+            return (0);		/* no LLC header */
 	}
 
 	dsap = dsap_field & ~LLC_IG;
@@ -232,21 +248,47 @@
 		}
 	}
 
+	/*
+	 * 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 &&
@@ -255,17 +297,15 @@
 		 * 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)) {
 		/*
@@ -278,58 +318,35 @@
 		 * 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)));
 		}
 	}
@@ -338,13 +355,31 @@
 		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 {
@@ -353,20 +388,38 @@
 				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;
@@ -379,21 +432,17 @@
 	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;
@@ -408,7 +457,7 @@
 		 * 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;
@@ -423,7 +472,7 @@
 			 * 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);
 		}
@@ -522,6 +571,33 @@
 			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/print-lldp.c b/print-lldp.c
index ce3c093..730b36f 100644
--- a/print-lldp.c
+++ b/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 <carles.kishimoto@gmail.com>
  * DCBX extensions by Kaladhar Musunuru <kaladharm@sourceforge.net>
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: IEEE 802.1ab Link Layer Discovery Protocol (LLDP) printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <stdio.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 #include "addrtoname.h"
 #include "af.h"
@@ -602,6 +601,14 @@
 #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 @@
     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 @@
     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 @@
                 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/print-lmp.c b/print-lmp.c
index 904dd71..1c7710c 100644
--- a/print-lmp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 #include "addrtoname.h"
 #include "gmpls.h"
@@ -459,14 +460,12 @@
                        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 @@
                        EXTRACT_32BITS(obj_tptr+8)));
 		break;
 
-#ifdef INET6
 	    case LMP_CTYPE_IPV6:
-#endif
 	    case LMP_CTYPE_UNMD:
             default:
                 hexdump=TRUE;
@@ -620,9 +617,7 @@
 		}
 
 		break;
-#ifdef INET6
 	    case LMP_CTYPE_IPV6:
-#endif
             default:
                 hexdump=TRUE;
             }
@@ -709,9 +704,7 @@
 			offset+=8;
 		}
                 break;
-#ifdef INET6
 	    case LMP_CTYPE_IPV6:
-#endif
             default:
                 hexdump=TRUE;
             }
@@ -729,9 +722,7 @@
 			offset+=4;
 		}
                 break;
-#ifdef INET6
 	    case LMP_CTYPE_IPV6:
-#endif
 	    default:
                 hexdump=TRUE;
             }
@@ -851,7 +842,7 @@
 
 	    default:
 		hexdump = TRUE;
-	    };
+	    }
 
 	break;
 
diff --git a/print-loopback.c b/print-loopback.c
index 9a74ae6..10f6931 100644
--- a/print-loopback.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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 @@
 	uint16_t function;
 
 	if (len < 2)
-		goto corrupt;
+		goto invalid;
 	/* function */
 	ND_TCHECK2(*cp, 2);
 	function = EXTRACT_LE_16BITS(cp);
@@ -71,7 +71,7 @@
 	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 @@
 			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 @@
 	}
 	return;
 
-corrupt:
-	ND_PRINT((ndo, "%s", cstr));
+invalid:
+	ND_PRINT((ndo, "%s", istr));
 	ND_TCHECK2(*cp, ep - cp);
 	return;
 trunc:
@@ -113,7 +113,7 @@
 
 	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 @@
 	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/print-lspping.c b/print-lspping.c
index 888adfa..4d260db 100644
--- a/print-lspping.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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 @@
     { 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 @@
 #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 @@
     { 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 @@
     { 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 @@
 };
 
 /*
- * 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 @@
  * |                      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_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 @@
  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  * |                      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 @@
  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  * |                      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 @@
  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  * |         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 @@
  * |               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_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 @@
     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 @@
         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 @@
     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_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_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_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 @@
                 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 @@
                                        "\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:
-            /* 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 */
+            /* 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_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;
+            tlv_ptr.lspping_tlv_downstream_map= \
+                (const struct lspping_tlv_downstream_map_t *)tlv_tptr;
+
+            /* that strange thing with the downstream map TLV is that until now
+             * we do not know if its IPv4 or IPv6 or is unnumbered; after
+             * we find the address-type, we recast the tlv_tptr and move on. */
+
             ND_PRINT((ndo, "\n\t    MTU: %u, Address-Type: %s (%u)",
-                   EXTRACT_16BITS(tlv_ptr.lspping_tlv_downstream_map_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 @@
                 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 @@
                 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 @@
                 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 @@
             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 @@
         /* 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/print-lwapp.c b/print-lwapp.c
index 5b8683f..bab3219 100644
--- a/print-lwapp.c
+++ b/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 <carles.kishimoto@gmail.com>
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: Light Weight Access Point Protocol (LWAPP) printer */
+
+/* specification: RFC 5412 */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 #include "addrtoname.h"
 
diff --git a/print-lwres.c b/print-lwres.c
index d78c9a9..ae35280 100644
--- a/print-lwres.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include "nameser.h"
 
 #include <stdio.h>
 #include <string.h>
 
-#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 @@
 
 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 @@
 		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 @@
 		/*
 		 * 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 @@
 		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 @@
 			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 @@
 			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 @@
 		/*
 		 * 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 @@
 		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 @@
 			/* 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 @@
 			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 @@
 				    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/print-m3ua.c b/print-m3ua.c
index 33f8777..1f974b2 100644
--- a/print-m3ua.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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 @@
   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 @@
   }
   return;
 
-corrupt:
-  ND_PRINT((ndo, "%s", cstr));
+invalid:
+  ND_PRINT((ndo, "%s", istr));
   ND_TCHECK2(*buf, size);
   return;
 trunc:
@@ -259,7 +259,7 @@
 
   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 @@
     /* 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 @@
   }
   return;
 
-corrupt:
-  ND_PRINT((ndo, "%s", cstr));
+invalid:
+  ND_PRINT((ndo, "%s", istr));
   ND_TCHECK2(*buf, size);
   return;
 trunc:
@@ -305,7 +305,7 @@
 
   /* 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_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/print-medsa.c b/print-medsa.c
new file mode 100644
index 0000000..4895fd9
--- /dev/null
+++ b/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 <netdissect-stdinc.h>
+
+#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/print-mobile.c b/print-mobile.c
index df412ee..6d31648 100644
--- a/print-mobile.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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 @@
 		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/print-mobility.c b/print-mobility.c
index b6fa61e..71cc85b 100644
--- a/print-mobility.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #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 @@
 #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 @@
 	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 @@
 #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 @@
 			break;
 		}
 	}
-	return;
+	return 0;
 
 trunc:
-	ND_PRINT((ndo, "[trunc] "));
+	return 1;
 }
 
 /*
@@ -192,7 +201,7 @@
 	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 @@
 		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 @@
 		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 @@
 			       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 @@
 		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 @@
 		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 @@
 		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 @@
 		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/print-mpcp.c b/print-mpcp.c
index 9da3582..1b9a5d7 100644
--- a/print-mpcp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 
 #define MPCP_TIMESTAMP_LEN        4
diff --git a/print-mpls.c b/print-mpls.c
index bc34d50..ba42233 100644
--- a/print-mpls.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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 @@
 	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 @@
 		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 @@
 		 * 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 @@
 	 */
 	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/print-mptcp.c b/print-mptcp.c
index f85f1d2..e757ea4 100644
--- a/print-mptcp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 #include "addrtoname.h"
 
@@ -173,7 +176,7 @@
 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 @@
 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 @@
         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 @@
 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 @@
 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 @@
                         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 @@
 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 @@
 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 @@
 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/print-msdp.c b/print-msdp.c
index fb802b5..50bafb0 100644
--- a/print-msdp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 #include "extract.h"
 
diff --git a/print-msnlb.c b/print-msnlb.c
index fcd0006..5264da4 100644
--- a/print-msnlb.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 #include "extract.h"
 
@@ -51,7 +52,7 @@
 {
 	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/print-nflog.c b/print-nflog.c
index 4234022..41cbf78 100644
--- a/print-nflog.c
+++ b/print-nflog.c
@@ -25,23 +25,24 @@
  * DAMAGE.
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: DLT_NFLOG printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 
 #if defined(DLT_NFLOG) && defined(HAVE_PCAP_NFLOG_H)
 #include <pcap/nflog.h>
 
 static const struct tok nflog_values[] = {
 	{ AF_INET,		"IPv4" },
-#ifdef INET6
+#ifdef AF_INET6
 	{ AF_INET6,		"IPv6" },
-#endif /*INET6*/
+#endif /*AF_INET6*/
 	{ 0,			NULL }
 };
 
diff --git a/print-nfs.c b/print-nfs.c
index dd2f7f1..a71e068 100644
--- a/print-nfs.c
+++ b/print-nfs.c
@@ -19,17 +19,18 @@
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: Network File System (NFS) printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <stdio.h>
 #include <string.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 #include "extract.h"
 
@@ -37,9 +38,7 @@
 #include "nfsfh.h"
 
 #include "ip.h"
-#ifdef INET6
 #include "ip6.h"
-#endif
 #include "rpc_auth.h"
 #include "rpc_msg.h"
 
@@ -55,7 +54,7 @@
 /*
  * 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,
@@ -203,33 +202,24 @@
 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));
@@ -434,7 +424,7 @@
 	/*
 	 * 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) {
@@ -496,7 +486,7 @@
 
 	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, "\""));
@@ -663,12 +653,12 @@
 		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);
@@ -677,12 +667,12 @@
 		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)) {
@@ -851,13 +841,8 @@
 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) */
 };
@@ -870,32 +855,28 @@
 
 #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);
 	}
@@ -911,13 +892,11 @@
 		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);
@@ -933,13 +912,12 @@
 {
 	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 {
@@ -956,7 +934,6 @@
 				cmp = 0;
 			}
 			break;
-#ifdef INET6
 		case 6:
 			if (UNALIGNED_MEMCMP(&ip6->ip6_src, &xmep->server,
 				   sizeof(ip6->ip6_src)) != 0 ||
@@ -965,7 +942,6 @@
 				cmp = 0;
 			}
 			break;
-#endif
 		default:
 			cmp = 0;
 			break;
@@ -1039,7 +1015,7 @@
 	}
 	/* 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);
 }
@@ -1084,7 +1060,7 @@
 		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)));
@@ -1099,9 +1075,9 @@
 			       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)));
@@ -1129,7 +1105,7 @@
 			       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);
@@ -1214,14 +1190,14 @@
 
 	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 {
@@ -1368,7 +1344,7 @@
 
 	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 *
@@ -1399,7 +1375,7 @@
 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)))
@@ -1411,7 +1387,7 @@
 	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),
@@ -1423,7 +1399,7 @@
 		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)));
@@ -1438,7 +1414,7 @@
               const uint32_t *dp)
 {
 	int er;
-	struct nfsv3_pathconf *spp;
+	const struct nfsv3_pathconf *spp;
 
 	if (!(dp = parsestatus(ndo, dp, &er)))
 		return (0);
@@ -1449,7 +1425,7 @@
 	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",
@@ -1600,7 +1576,7 @@
 		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)
@@ -1612,10 +1588,10 @@
 		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;
@@ -1623,7 +1599,7 @@
 	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;
 
@@ -1635,7 +1611,7 @@
 			if (parsewccres(ndo, dp, ndo->ndo_vflag))
 				return;
 		} else {
-			if (parsestatus(ndo, dp, &er) != 0)
+			if (parsestatus(ndo, dp, &er) != NULL)
 				return;
 		}
 		break;
@@ -1656,7 +1632,7 @@
 			}
 			return;
 		} else {
-			if (parsestatus(ndo, dp, &er) != 0)
+			if (parsestatus(ndo, dp, &er) != NULL)
 				return;
 		}
 		break;
@@ -1677,7 +1653,7 @@
 				return;
 			}
 		} else {
-			if (parsestatus(ndo, dp, &er) != 0)
+			if (parsestatus(ndo, dp, &er) != NULL)
 				return;
 		}
 		break;
diff --git a/print-nsh.c b/print-nsh.c
new file mode 100644
index 0000000..abd722d
--- /dev/null
+++ b/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 <netdissect-stdinc.h>
+
+#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/print-ntp.c b/print-ntp.c
index e83d47a..0689264 100644
--- a/print-ntp.c
+++ b/print-ntp.c
@@ -18,23 +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
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: Network Time Protocol (NTP) printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #ifdef HAVE_STRFTIME
 #include <time.h>
 #endif
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 #include "extract.h"
 
@@ -207,7 +207,7 @@
 	register const struct ntpdata *bp;
 	int mode, version, leapind;
 
-	bp = (struct ntpdata *)cp;
+	bp = (const struct ntpdata *)cp;
 
 	ND_TCHECK(bp->status);
 
@@ -261,7 +261,7 @@
 		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;
 
@@ -327,12 +327,12 @@
 {
 	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));
 }
 
@@ -345,15 +345,15 @@
 	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
@@ -382,7 +382,7 @@
 	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);
@@ -420,8 +420,8 @@
 	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/print-null.c b/print-null.c
index 166f777..14df5fd 100644
--- a/print-null.c
+++ b/print-null.c
@@ -19,16 +19,17 @@
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: BSD loopback device printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <string.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "af.h"
 
 /*
@@ -83,7 +84,7 @@
 		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/print-olsr.c b/print-olsr.c
index b90eea1..e095ef7 100644
--- a/print-olsr.c
+++ b/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 <hannes@juniper.net>
  * IPv6 additions by Florian Forster <octo at verplant.org>
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: Optimized Link State Routing Protocol (OLSR) printer */
+
+/* specification: RFC 3626 */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 #include "extract.h"
 
@@ -135,6 +136,26 @@
 };
 
 
+/** 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 @@
     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 @@
 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 @@
     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 @@
     }
     return (0);
 }
-#endif /* INET6 */
 
 /*
  * print a neighbor list.
@@ -284,7 +334,7 @@
 
     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 @@
     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 @@
             }
 
             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 @@
             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 @@
             }
 
             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 @@
                 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 @@
                  */
                 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 @@
                     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 @@
                 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 @@
                 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 @@
         {
             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 @@
         }
 
         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 @@
                 }
             }
             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 @@
 
                 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/print-openflow-1.0.c b/print-openflow-1.0.c
index a36c32f..ce95843 100644
--- a/print-openflow-1.0.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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 @@
 	uint32_t subtype;
 
 	if (len < 4)
-		goto corrupt;
+		goto invalid;
 	/* subtype */
 	ND_TCHECK2(*cp, 4);
 	subtype = EXTRACT_32BITS(cp);
@@ -781,7 +781,7 @@
 		 *
 		 */
 		if (len != 12)
-			goto corrupt;
+			goto invalid;
 		/* index */
 		ND_TCHECK2(*cp, 1);
 		ND_PRINT((ndo, ", index %u", *cp));
@@ -805,7 +805,7 @@
 		 *
 		 */
 		if (len != 12)
-			goto corrupt;
+			goto invalid;
 		/* index */
 		ND_TCHECK2(*cp, 1);
 		ND_PRINT((ndo, ", index %u", *cp));
@@ -832,7 +832,7 @@
 		 *
 		 */
 		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 @@
 		 *
 		 */
 		if (len != 4)
-			goto corrupt;
+			goto invalid;
 		break;
 	case BSN_VIRTUAL_PORT_REMOVE_REQUEST:
 		/*
@@ -869,7 +869,7 @@
 		 *
 		 */
 		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 @@
 		 *
 		 */
 		if (len < 8)
-			goto corrupt;
+			goto invalid;
 		/* service */
 		ND_TCHECK2(*cp, 4);
 		ND_PRINT((ndo, ", service %u", EXTRACT_32BITS(cp)));
@@ -936,7 +936,7 @@
 		 *
 		 */
 		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 @@
 	}
 	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 @@
 	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 @@
 		 *
 		 */
 		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 @@
 
 	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 @@
 	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_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 @@
 	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_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 @@
 	uint32_t vendor;
 
 	if (len < 4)
-		goto corrupt;
+		goto invalid;
 	/* vendor */
 	ND_TCHECK2(*cp, 4);
 	vendor = EXTRACT_32BITS(cp);
@@ -1106,8 +1106,8 @@
 	/* 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 @@
 
 	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 @@
 	} /* 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 @@
 		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 @@
 		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 @@
 	} /* 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 @@
 
 	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 @@
 		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 @@
 	} /* 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 @@
 		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 @@
 		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 @@
 	} /* 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 @@
 	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 @@
 		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 @@
 		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 @@
 	}
 	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 @@
                             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 @@
 	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 @@
 
 	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 @@
 	} /* 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 @@
                                  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 @@
 	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 @@
 
 	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 @@
 	} /* 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 @@
 
 	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 @@
 	} /* 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 @@
 
 	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 @@
 	} /* 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 @@
 	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 @@
 	 * 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 @@
 	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 @@
 		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 @@
 		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 @@
 	/* 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 @@
 	/* 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 @@
 	/* 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 @@
 	/* 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 @@
 	/* 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 @@
 	/* 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 @@
 	/* 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 @@
 	} /* 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/print-openflow.c b/print-openflow.c
index 8825ae3..043adc2 100644
--- a/print-openflow.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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 @@
 	uint32_t xid;
 
 	if (ep < cp + OF_HEADER_LEN)
-		goto corrupt;
+		goto invalid;
 	/* version */
 	ND_TCHECK2(*cp, 1);
 	version = *cp;
@@ -107,7 +107,7 @@
 	 * 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 @@
 		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/print-ospf.c b/print-ospf.c
index 3583417..db4231b 100644
--- a/print-ospf.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 #include "extract.h"
 #include "gmpls.h"
@@ -314,6 +315,10 @@
                 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 @@
                 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 @@
                     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 @@
                     }
                     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 @@
                     }
                     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 @@
                     }
                     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 @@
     return 0;
 trunc:
     return -1;
+invalid:
+    ND_PRINT((ndo, "%s", istr));
+    return -1;
 }
 
 static int
@@ -506,16 +568,16 @@
 
 /* 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 @@
     /*
      * 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 @@
         tos++;
         toscount--;
     }
+    return 0;
+trunc:
+    return 1;
 }
 
 /*
@@ -559,11 +625,11 @@
 	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 @@
 				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 @@
 		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 @@
 		    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 @@
 	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 @@
 
 		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 @@
 	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 @@
 
 	    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 @@
                 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 @@
 
             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 @@
 
         /* 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 @@
 
     /* 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 @@
 		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 @@
 			          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 @@
 
 		/* 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 @@
 	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/print-ospf6.c b/print-ospf6.c
index 49210bc..e8a9dc6 100644
--- a/print-ospf6.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <string.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 #include "extract.h"
 
@@ -386,7 +387,7 @@
 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 @@
 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 @@
 	 * 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 @@
 		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 @@
 		       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 @@
 		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 @@
 			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 @@
 			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 @@
                        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 @@
                 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 @@
 	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 @@
 		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 @@
 	}
 
 	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 @@
 		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 @@
 
 	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 @@
 
 	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 @@
 
 	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 @@
 	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 @@
 	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/print-otv.c b/print-otv.c
index 53a79de..5a82752 100644
--- a/print-otv.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 
 /*
@@ -39,27 +42,31 @@
 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;
-    }
-
-    flags = *bp;
-    bp += 1;
-
-    overlay_id = EXTRACT_24BITS(bp);
-    bp += 3;
-
-    instance_id = EXTRACT_24BITS(bp);
-    bp += 4;
 
     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));
+    if (len < 8)
+        goto trunc;
 
-    ether_print(ndo, bp, len - 8, len - 8, NULL, NULL);
+    ND_TCHECK(*bp);
+    flags = *bp;
+    ND_PRINT((ndo, "flags [%s] (0x%02x), ", flags & 0x08 ? "I" : ".", flags));
+    bp += 1;
+
+    ND_TCHECK2(*bp, 3);
+    ND_PRINT((ndo, "overlay %u, ", EXTRACT_24BITS(bp)));
+    bp += 3;
+
+    ND_TCHECK2(*bp, 3);
+    ND_PRINT((ndo, "instance %u\n", EXTRACT_24BITS(bp)));
+    bp += 3;
+
+    /* Reserved */
+    ND_TCHECK(*bp);
+    bp += 1;
+
+    ether_print(ndo, bp, len - 8, ndo->ndo_snapend - bp, NULL, NULL);
+    return;
+
+trunc:
+    ND_PRINT((ndo, " [|OTV]"));
 }
diff --git a/print-pflog.c b/print-pflog.c
index 72ae276..265efd3 100644
--- a/print-pflog.c
+++ b/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 <net/pfvar.h>
 #include <net/if_pflog.h>
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 
 static const char tstr[] = "[|pflog]";
@@ -120,7 +121,7 @@
 	}
 
 #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 @@
 	}
 
 	/* print what we know */
-	hdr = (struct pfloghdr *)p;
 	ND_TCHECK(*hdr);
 	if (ndo->ndo_eflag)
 		pflog_print(ndo, hdr);
diff --git a/print-pgm.c b/print-pgm.c
index 6a83425..6d5c01c 100644
--- a/print-pgm.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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 @@
 	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 @@
 	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->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 @@
 	}
 
 	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 @@
 	    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 @@
 	     */
 	    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 @@
 	}
 
 	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 @@
 
 		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 @@
 		    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/print-pim.c b/print-pim.c
index 15f4c51..2552595 100644
--- a/print-pim.c
+++ b/print-pim.c
@@ -19,18 +19,21 @@
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: Protocol Independent Multicast (PIM) printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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
@@ -134,7 +137,7 @@
 	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,
@@ -152,7 +155,7 @@
 		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,
@@ -174,7 +177,7 @@
 	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;
@@ -259,7 +262,7 @@
 		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;
@@ -281,7 +284,7 @@
 			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:
@@ -348,7 +351,7 @@
 	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"));
 
@@ -415,10 +418,10 @@
 
 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)
@@ -440,7 +443,7 @@
 			          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:
@@ -534,12 +537,10 @@
 			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;
 		}
@@ -551,11 +552,9 @@
 		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;
@@ -572,12 +571,10 @@
 			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:
@@ -589,7 +586,6 @@
 					ND_PRINT((ndo, "/%u", bp[1]));
 			}
 		}
-#ifdef INET6
 		else if (af == AF_INET6) {
 			if (!silent) {
 				ND_PRINT((ndo, "%s", ip6addr_string(ndo, bp + 2)));
@@ -597,7 +593,6 @@
 					ND_PRINT((ndo, "/%u", bp[1]));
 			}
 		}
-#endif
 		if (bp[0] && !silent) {
 			if (at == pimv2_group) {
 				ND_PRINT((ndo, "(0x%02x)", bp[0]));
@@ -620,13 +615,50 @@
 	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)
@@ -642,7 +674,41 @@
 	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)) {
@@ -663,7 +729,7 @@
 
 			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:
@@ -704,7 +770,7 @@
 				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)));
@@ -719,8 +785,6 @@
 				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) {
@@ -746,7 +810,7 @@
 
 	case PIMV2_TYPE_REGISTER:
 	{
-		struct ip *ip;
+		const struct ip *ip;
 
 		ND_TCHECK2(*(bp + 4), PIMV2_REGISTER_FLAG_LEN);
 
@@ -757,7 +821,7 @@
 
 		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",
@@ -868,7 +932,7 @@
 			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++) {
@@ -972,7 +1036,7 @@
 					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;
@@ -1024,7 +1088,7 @@
 		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 */
@@ -1070,7 +1134,7 @@
 		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/print-pktap.c b/print-pktap.c
index 46a187d..7144f3c 100644
--- a/print-pktap.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 
 #ifdef DLT_PKTAP
@@ -71,16 +72,18 @@
 {
 	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 @@
 	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 @@
 
 	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/print-ppi.c b/print-ppi.c
index b403536..72cd1b8 100644
--- a/print-ppi.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 
 typedef struct ppi_header {
@@ -28,49 +30,56 @@
 	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 (caplen < len) {
+		/*
+		 * If we don't have the entire PPI header, don't
+		 * bother.
+		 */
+		ND_PRINT((ndo, "[|ppi]"));
+		return (caplen);
+	}
 	if (len < sizeof(ppi_header_t)) {
 		ND_PRINT((ndo, "[|ppi]"));
-		return;
-	}
-	if (caplen < len) {
-		ND_PRINT((ndo, "[|ppi]"));
-		return;
+		return (len);
 	}
 	dlt = EXTRACT_LE_32BITS(&hdr->ppi_dlt);
 
@@ -82,16 +91,19 @@
 	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 @@
 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/print-ppp.c b/print-ppp.c
index edc03c0..ee8239c 100644
--- a/print-ppp.c
+++ b/print-ppp.c
@@ -22,6 +22,8 @@
  * complete PPP support.
  */
 
+/* \summary: Point to Point Protocol (PPP) printer */
+
 /*
  * TODO:
  * o resolve XXX as much as possible
@@ -29,12 +31,11 @@
  * o BAP support
  */
 
-#define NETDISSECT_REWORKED
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #ifdef __bsdi__
 #include <net/slcompress.h>
@@ -43,7 +44,7 @@
 
 #include <stdlib.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 #include "addrtoname.h"
 #include "ppp.h"
@@ -943,6 +944,9 @@
 
 	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);
@@ -971,6 +975,13 @@
 		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);
@@ -1670,6 +1681,11 @@
 		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/print-pppoe.c b/print-pppoe.c
index 1624c5e..23d9a23 100644
--- a/print-pppoe.c
+++ b/print-pppoe.c
@@ -21,15 +21,16 @@
  * Original code by Greg Stark <gsstark@mit.edu>
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: PPP-over-Ethernet (PPPoE) printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
-#include "extract.h"			/* must come after interface.h */
+#include "netdissect.h"
+#include "extract.h"
 
 /* Codes */
 enum {
@@ -147,7 +148,7 @@
 			/* 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 @@
 				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/print-pptp.c b/print-pptp.c
index c77868d..a4d713d 100644
--- a/print-pptp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 
 static const char tstr[] = " [|pptp]";
@@ -518,7 +519,7 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 
 	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/print-radius.c b/print-radius.c
index 5cf8ad2..eb48de5 100644
--- a/print-radius.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <string.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 #include "extract.h"
 #include "oui.h"
@@ -162,12 +168,12 @@
 };
 
 
-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 @@
                                    "GRE",
                                    "DVS",
                                    "IP-in-IP Tunneling",
+                                   "VLAN",
                                  };
 
 /* Tunnel-Medium-Type Attribute standard values */
@@ -365,11 +372,12 @@
                             };
 
 
-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 @@
 /*****************************/
 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 @@
    }
 
    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 @@
  */
 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 @@
                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 @@
 /******************************/
 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 @@
 /*****************************/
 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 @@
 /*************************************/
 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 @@
 /***********************************/
 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 @@
 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 @@
          {
              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 @@
    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/print-raw.c b/print-raw.c
index d20387c..463aa41 100644
--- a/print-raw.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 
 /*
  * The DLT_RAW packet has no header. It contains a raw IP packet.
diff --git a/print-resp.c b/print-resp.c
new file mode 100644
index 0000000..9d71e21
--- /dev/null
+++ b/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 <netdissect-stdinc.h>
+#include "netdissect.h"
+#include <limits.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#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: ' "<stuff>"\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 /*<opcode>*/ + len /*<string>*/ + 2 /*<CRLF>*/;
+
+    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);
+
+    /* <length>\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);
+
+    /* <array_length>\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.
+     *
+     * <string><\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/print-rip.c b/print-rip.c
index c1b036e..cf661d0 100644
--- a/print-rip.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <stdio.h>
 
-#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 @@
 	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 @@
 	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 @@
 	}
 	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 @@
 		 *
 		 * 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 @@
 		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 @@
                     /* 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/print-ripng.c b/print-ripng.c
index 4bc900d..25e9bbc 100644
--- a/print-ripng.c
+++ b/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 <netdissect-stdinc.h>
 
-#include <tcpdump-stdinc.h>
-
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 #include "extract.h"
 
@@ -109,7 +108,7 @@
 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 @@
 	if (rp->rip6_vers != RIP6_VERSION)
 		ND_PRINT((ndo, " [vers %d]", rp->rip6_vers));
 }
-#endif /* INET6 */
diff --git a/print-rpki-rtr.c b/print-rpki-rtr.c
index 34e2057..77e29c7 100644
--- a/print-rpki-rtr.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <string.h>
 
-#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 @@
 /*
  * 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 @@
 
     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 @@
 	}
 	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 @@
 		   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 @@
 	    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 @@
 	    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 @@
     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 @@
 
         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 @@
 	/*
 	 * 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/print-rrcp.c b/print-rrcp.c
index 2370d9c..936b3ea 100644
--- a/print-rrcp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 #include "extract.h"
 #include "ether.h"
@@ -72,56 +73,54 @@
 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/print-rsvp.c b/print-rsvp.c
index 263ef3d..be3dfa3 100644
--- a/print-rsvp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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 @@
 #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 @@
     { 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 @@
     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 @@
         * |        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 @@
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         */
         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 @@
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         */
         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 @@
         * |      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 @@
         */
 
         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 @@
         */
 
         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 @@
     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 @@
             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 @@
                 obj_tlen-=8;
                 obj_tptr+=8;
                 break;
-#ifdef INET6
             case RSVP_CTYPE_IPV6:
                 if (obj_tlen < 20)
                     return -1;
@@ -762,7 +784,6 @@
                 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 @@
                 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 @@
                 obj_tlen-=sizeof(struct in6_addr);
                 obj_tptr+=sizeof(struct in6_addr);
                 break;
-#endif
             default:
                 hexdump=TRUE;
             }
@@ -829,7 +848,6 @@
                 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 @@
                 obj_tlen-=sizeof(struct in6_addr);
                 obj_tptr+=sizeof(struct in6_addr);
                 break;
-#endif
             default:
                 hexdump=TRUE;
             }
@@ -914,7 +931,6 @@
                 obj_tlen-=8;
                 obj_tptr+=8;
                 break;
-#ifdef INET6
             case RSVP_CTYPE_IPV6:
                 if (obj_tlen < 20)
                     return-1;
@@ -939,7 +955,6 @@
                 obj_tlen-=40;
                 obj_tptr+=40;
                 break;
-#endif
             case RSVP_CTYPE_TUNNEL_IPV4:
                 if (obj_tlen < 8)
                     return-1;
@@ -1051,20 +1066,37 @@
             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 @@
                                    *(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 @@
                            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 @@
                             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 @@
                 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 @@
                 obj_tptr+=20;
                 hexdump=TRUE; /* unless we have a TLV parser lets just hexdump */
                 break;
-#endif
             default:
                 hexdump=TRUE;
             }
@@ -1360,7 +1396,6 @@
                 obj_tlen-=8;
                 obj_tptr+=8;
                 break;
-#ifdef INET6
             case RSVP_CTYPE_IPV6:
                 if (obj_tlen < 20)
                     return-1;
@@ -1405,7 +1440,6 @@
                 obj_tlen-=40;
                 obj_tptr+=40;
                 break;
-#endif
             case RSVP_CTYPE_TUNNEL_IPV4:
                 if (obj_tlen < 8)
                     return-1;
@@ -1547,7 +1581,6 @@
                 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 @@
                 obj_tlen-=20;
                 obj_tptr+=20;
                 break;
-#endif
             default:
                 hexdump=TRUE;
             }
@@ -1664,12 +1696,10 @@
                        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 @@
                 obj_tlen-=4;
                 obj_tptr+=4;
                 break;
-#ifdef INET6
             case RSVP_CTYPE_IPV6:
                 if (obj_tlen < 16)
                     return-1;
@@ -1760,7 +1789,6 @@
                 obj_tlen-=16;
                 obj_tptr+=16;
                 break;
-#endif
             default:
                 hexdump=TRUE;
             }
@@ -1788,8 +1816,12 @@
         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 @@
 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_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 @@
 
     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_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_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 @@
             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 @@
     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 @@
 
     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/print-rt6.c b/print-rt6.c
index 3d5f9e3..35dbed9 100644
--- a/print-rt6.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <string.h>
 
 #include "ip6.h"
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 #include "extract.h"
 
@@ -44,9 +43,8 @@
 	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 @@
 	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 @@
 		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 @@
 	ND_PRINT((ndo, "[|srcrt]"));
 	return -1;
 }
-#endif /* INET6 */
diff --git a/print-rtsp.c b/print-rtsp.c
index d721b8d..54cc930 100644
--- a/print-rtsp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 
 static const char *rtspcmds[] = {
diff --git a/print-rx.c b/print-rx.c
index 8a9babb..ea3a5e6 100644
--- a/print-rx.c
+++ b/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 <kenh@cmf.nrl.navy.mil>
  */
 
-#define NETDISSECT_REWORKED
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -40,9 +42,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 #include "extract.h"
 
@@ -522,9 +524,9 @@
 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 @@
 		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_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 @@
 {
 	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 @@
 			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 @@
 			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 @@
 			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 @@
 			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 @@
                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 @@
 			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 @@
 			;
 		}
 	} else if (rxh->type == RX_PACKET_TYPE_ABORT) {
-		int i;
-
 		/*
 		 * Otherwise, just print out the return code
 		 */
@@ -1299,12 +1302,12 @@
 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 @@
 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 @@
 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 @@
 				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 @@
 				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 @@
 	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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 
 	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/print-sctp.c b/print-sctp.c
index 4b595f2..f625dce 100644
--- a/print-sctp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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 @@
                 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 @@
       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 @@
          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 @@
 	  {
 	    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 @@
 		 == 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 @@
 		    (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 @@
 	    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 && tsnNo<EXTRACT_16BITS(&sack->numDupTsns);
-		 dupTSN += 4, tsnNo++)
+	    for (tsnNo=0;
+		 chunkLengthRemaining != 0 && tsnNo<EXTRACT_16BITS(&sack->numDupTsns);
+		 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/print-sflow.c b/print-sflow.c
index 24112f4..37a41b5 100644
--- a/print-sflow.c
+++ b/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 <carles.kishimoto@gmail.com>
  *
  * Expansion and refactoring by Rick Jones <rick.jones2@hp.com>
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: sFlow protocol printer */
+
+/* specification: http://www.sflow.org/developers/specifications.php */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 #include "addrtoname.h"
 
@@ -304,8 +305,8 @@
     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 @@
 	   EXTRACT_32BITS(sflow_gen_counter->ifpromiscmode)));
 
     return 0;
+
+trunc:
+    return 1;
 }
 
 static int
@@ -351,6 +355,7 @@
 	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 @@
 	   EXTRACT_32BITS(sflow_eth_counter->symbol_errors)));
 
     return 0;
+
+trunc:
+    return 1;
 }
 
 static int
@@ -388,6 +396,7 @@
 	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 @@
 	   EXTRACT_64BITS(sflow_100basevg_counter->hc_out_highpriority_octets)));
 
     return 0;
+
+trunc:
+    return 1;
 }
 
 static int
@@ -424,6 +436,7 @@
 	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 @@
 	   EXTRACT_32BITS(sflow_vlan_counter->discards)));
 
     return 0;
+
+trunc:
+    return 1;
 }
 
 struct sflow_processor_counter_t {
@@ -454,6 +470,7 @@
 	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 @@
 	   EXTRACT_64BITS(sflow_processor_counter->free_memory)));
 
     return 0;
+
+trunc:
+    return 1;
 }
 
 static int
@@ -486,6 +506,7 @@
 	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 @@
     }
 
     return 0;
+
+trunc:
+    return 1;
 }
 
 static int
@@ -553,11 +577,11 @@
     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 @@
 				       len - sizeof(struct sflow_counter_sample_t),
 				       nrecords);
 
+trunc:
+    return 1;
 }
 
 static int
@@ -588,6 +614,7 @@
 	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 @@
 				       len - sizeof(struct sflow_expanded_counter_sample_t),
 				       nrecords);
 
+trunc:
+    return 1;
 }
 
 static int
@@ -613,6 +642,7 @@
 	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 @@
        assuming of course there is wnough data present to do so... */
 
     return 0;
+
+trunc:
+    return 1;
 }
 
 static int
@@ -636,12 +669,16 @@
 	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 @@
 	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 @@
 	   EXTRACT_32BITS(sflow_extended_sw_data->dst_pri)));
 
     return 0;
+
+trunc:
+    return 1;
 }
 
 static int
@@ -685,6 +726,7 @@
 	    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 @@
     }
 
     return 0;
+
+trunc:
+    return 1;
 }
 
 static int
@@ -762,7 +807,8 @@
     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 @@
 				    len - sizeof(struct sflow_flow_sample_t),
 				    nrecords);
 
+trunc:
+    return 1;
 }
 
 static int
@@ -797,6 +845,7 @@
 	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 @@
 				    len - sizeof(struct sflow_expanded_flow_sample_t),
 				    nrecords);
 
+trunc:
+    return 1;
 }
 
 void
@@ -827,7 +878,6 @@
     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/print-sip.c b/print-sip.c
index d0fd349..8e308ed 100644
--- a/print-sip.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 
 static const char *sipcmds[] = {
diff --git a/print-sl.c b/print-sl.c
index bd410ce..3fd7e89 100644
--- a/print-sl.c
+++ b/print-sl.c
@@ -19,15 +19,16 @@
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: Compressed Serial Line Internet Protocol printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
-#include "extract.h"			/* must come after interface.h */
+#include "netdissect.h"
+#include "extract.h"
 
 #include "ip.h"
 #include "tcp.h"
@@ -67,19 +68,25 @@
 		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)));
@@ -103,14 +110,14 @@
 
 	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);
 }
@@ -147,9 +154,9 @@
 		 * 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;
@@ -242,7 +249,7 @@
 	 * '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/print-sll.c b/print-sll.c
index 1f5f600..6148569 100644
--- a/print-sll.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 #include "ethertype.h"
 #include "extract.h"
@@ -198,7 +199,8 @@
 	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 @@
 	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 @@
 			 * 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 @@
 		 * 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 (SLL_HDR_LEN);
+			return (hdrlen + caplen);
+		}
+		if (length < 4) {
+			ND_PRINT((ndo, "[|vlan]"));
+			return (hdrlen + length);
 		}
 	        if (ndo->ndo_eflag) {
 	        	uint16_t tag = EXTRACT_16BITS(p);
@@ -293,9 +294,10 @@
 		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 @@
 		}
 	}
 
-	return (SLL_HDR_LEN);
+	return (hdrlen);
 }
diff --git a/print-slow.c b/print-slow.c
index 2db3581..92d4a7b 100644
--- a/print-slow.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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 @@
     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 MARKER_TLV_TERMINATOR   0x00
-#define MARKER_TLV_MARKER_INFO  0x01
+#define LACP_TLV_ACTOR_INFO            0x01
+#define LACP_TLV_PARTNER_INFO          0x02
+#define LACP_TLV_COLLECTOR_INFO        0x03
+
+#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 @@
     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 @@
         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 @@
     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 @@
     } 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 @@
         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;
         }
 
+        /* 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);
+
         tlv_tptr=tptr+sizeof(struct tlv_header_t);
         tlv_tlen=tlv_len-sizeof(struct tlv_header_t);
 
-        /* did we capture enough for fully decoding the tlv ? */
-        ND_TCHECK2(*tptr, tlv_len);
-
-        switch((slow_com_header->proto_subtype << 8) + tlv_header->type) {
+        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 @@
             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 @@
             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 @@
 
             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 @@
         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 @@
         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 @@
     case SLOW_OAM_CODE_INFO:
         while (tlen > 0) {
             ptr.slow_oam_tlv_header = (const struct slow_oam_tlv_header_t *)tptr;
+            if (tlen < sizeof(*ptr.slow_oam_tlv_header))
+                goto tooshort;
+            ND_TCHECK(*ptr.slow_oam_tlv_header);
             ND_PRINT((ndo, "\n\t  %s Information Type (%u), length %u",
                    tok2str(slow_oam_info_type_values, "Reserved",
                            ptr.slow_oam_tlv_header->type),
                    ptr.slow_oam_tlv_header->type,
                    ptr.slow_oam_tlv_header->length));
 
+            if (ptr.slow_oam_tlv_header->type == SLOW_OAM_INFO_TYPE_END_OF_TLV) {
+                /*
+                 * 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_END_OF_TLV:
-                if (ptr.slow_oam_tlv_header->length != 0) {
-                    ND_PRINT((ndo, "\n\t    ERROR: illegal length - should be 0"));
-                }
-                return;
-
             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 @@
                     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 @@
                 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 @@
         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));
 
+            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_END_OF_TLV:
-                if (ptr.slow_oam_tlv_header->length != 0) {
-                    ND_PRINT((ndo, "\n\t    ERROR: illegal length - should be 0"));
-                }
-                return;
-
             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 @@
                     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 @@
                 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 @@
 
     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 @@
         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/print-smb.c b/print-smb.c
index f5be9ff..723b9a0 100644
--- a/print-smb.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <string.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 #include "smb.h"
 
@@ -100,7 +101,7 @@
     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 @@
     }
     if (dcnt) {
 	ND_PRINT((ndo, "data:\n"));
-	print_data(ndo, data, dcnt);
+	smb_print_data(ndo, data, dcnt);
     }
     return;
 trunc:
@@ -416,7 +417,7 @@
 	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 @@
 	    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 @@
 	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 @@
 	    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 @@
 	    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 @@
 
     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 @@
     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 @@
 	    } 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 @@
 	    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 @@
 			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 @@
 /*
    print netbeui frames
 */
-struct nbf_strings {
+static struct nbf_strings {
 	const char	*name;
 	const char	*nonverbose;
 	const char	*verbose;
diff --git a/print-smtp.c b/print-smtp.c
index fe0bbc2..0cdcf1d 100644
--- a/print-smtp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/print-snmp.c b/print-snmp.c
index f550158..1b096dc 100644
--- a/print-snmp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <stdio.h>
 #include <string.h>
@@ -70,7 +71,7 @@
 #include <smi.h>
 #endif
 
-#include "interface.h"
+#include "netdissect.h"
 
 #undef OPAQUE  /* defined in <wingdi.h> */
 
@@ -253,7 +254,7 @@
  * 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 @@
  * 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 @@
 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 @@
 		 * 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 @@
 		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 @@
 				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 @@
 
 			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 @@
 
 			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 @@
 			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 @@
 			}
 
 			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 @@
 
 		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 @@
 			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 @@
 
 		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 @@
 	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 @@
 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 @@
 			}
 		}
 
-		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 @@
 		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 @@
 	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 @@
                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 @@
 		 * (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 @@
 	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 @@
 
 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 @@
 	        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 @@
  */
 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 @@
 		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 @@
 		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 @@
               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 @@
 		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 @@
 	} 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 @@
 	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 @@
 	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 @@
                 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 @@
 		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 @@
 	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 @@
 	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 @@
 	}
 	/* 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 @@
 		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 @@
 	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 @@
 		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 @@
 		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 @@
 			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/print-stp.c b/print-stp.c
index 93bb600..2f5c917 100644
--- a/print-stp.c
+++ b/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 <buytenh@gnu.org>
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: IEEE 802.1d Spanning Tree Protocol (STP) printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <stdio.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 
 #define	RSTP_EXTRACT_PORT_ROLE(x) (((x)&0x0C)>>2)
@@ -84,6 +84,8 @@
     { 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 @@
     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 @@
                tok2str(rstp_obj_port_role_values, "Unknown",
                        RSTP_EXTRACT_PORT_ROLE(stp_bpdu->flags))));
     }
+    return 1;
+
+trunc:
+    return 0;
 }
 
 /*
@@ -226,8 +235,7 @@
 #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 @@
      * 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 @@
            (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 @@
             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 @@
      * 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 @@
             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 @@
             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 @@
     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 @@
         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 @@
         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 @@
             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 @@
                   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 @@
     }
 
     return;
- trunc:
+trunc:
     ND_PRINT((ndo, "[|stp %d]", length));
 }
 
diff --git a/print-sunatm.c b/print-sunatm.c
index fc03d42..a587e50 100644
--- a/print-sunatm.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 struct mbuf;
 struct rtentry;
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 
 #include "atm.h"
diff --git a/print-sunrpc.c b/print-sunrpc.c
index bc7138d..d2366c7 100644
--- a/print-sunrpc.c
+++ b/print-sunrpc.c
@@ -19,7 +19,8 @@
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: Sun Remote Procedure Call printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -39,7 +40,7 @@
  */
 #undef _XOPEN_SOURCE_EXTENDED
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #if defined(HAVE_GETRPCBYNUMBER) && defined(HAVE_RPC_RPC_H)
 #include <rpc/rpc.h>
@@ -51,14 +52,12 @@
 #include <stdio.h>
 #include <string.h>
 
-#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"
@@ -171,13 +170,11 @@
 {
 	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",
@@ -189,21 +186,19 @@
 		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/print-symantec.c b/print-symantec.c
index dcff2a6..9e9f8f3 100644
--- a/print-symantec.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 #include "ethertype.h"
 
@@ -75,7 +76,7 @@
 {
 	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 @@
 
 	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 @@
 	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/print-syslog.c b/print-syslog.c
index 5e3cd4f..ff86676 100644
--- a/print-syslog.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 
 static const char tstr[] = "[|syslog]";
diff --git a/print-tcp.c b/print-tcp.c
index bc200e2..e0d0531 100644
--- a/print-tcp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <stdlib.h>
 #include <string.h>
 
-#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 <openssl/md5.h>
-#include <signature.h>
+#include "signature.h"
 
 static int tcp_verify_signature(netdissect_options *ndo,
                                 const struct ip *ip, const struct tcphdr *tp,
@@ -64,6 +61,8 @@
 #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 @@
         tcp_seq ack;
 };
 
-#ifdef INET6
 struct tha6 {
         struct in6_addr src;
         struct in6_addr dst;
@@ -94,7 +92,6 @@
         tcp_seq seq;
         tcp_seq ack;
 };
-#endif
 
 #define TSEQ_HASHSIZE 919
 
@@ -102,9 +99,7 @@
 #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 @@
         { 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 @@
 				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 @@
         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 @@
         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,7 +249,6 @@
                  * both directions).
                  */
                 rev = 0;
-#ifdef INET6
                 if (ip6) {
                         register struct tcp_seq_hash6 *th;
                         struct tcp_seq_hash6 *tcp_seq_hash;
@@ -287,7 +286,8 @@
                                         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 @@
                         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 struct in_addr *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 @@
                                         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 @@
                                 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 @@
 
                         }
                 }
-#endif
         }
 
         length -= hlen;
@@ -474,7 +465,7 @@
                         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 @@
                         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 @@
 #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 @@
                                 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 @@
                                         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 @@
 
                                 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 @@
                                 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 @@
                 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 @@
                  * 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 @@
                 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 @@
         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 @@
          * 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 @@
          */
         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/print-telnet.c b/print-telnet.c
index fa59b1f..a664034 100644
--- a/print-telnet.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <stdio.h>
 
-#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 @@
 
 #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 @@
 		/* 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 @@
 	return sp - osp;
 
 trunc:
-	ND_PRINT((ndo, "[|telnet]"));
+	ND_PRINT((ndo, "%s", tstr));
 pktend:
 	return -1;
 #undef FETCH
@@ -509,6 +513,7 @@
 
 	osp = sp;
 
+	ND_TCHECK(*sp);
 	while (length > 0 && *sp == IAC) {
 		/*
 		 * Parse the Telnet command without printing it,
@@ -537,6 +542,7 @@
 
 		sp += l;
 		length -= l;
+		ND_TCHECK(*sp);
 	}
 	if (!first) {
 		if (ndo->ndo_Xflag && 2 < ndo->ndo_vflag)
@@ -544,4 +550,7 @@
 		else
 			ND_PRINT((ndo, "]"));
 	}
+	return;
+trunc:
+	ND_PRINT((ndo, "%s", tstr));
 }
diff --git a/print-tftp.c b/print-tftp.c
index 9b88e74..69bc601 100644
--- a/print-tftp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <string.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 
 /*
@@ -110,7 +109,8 @@
 	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 @@
 	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 @@
 
 	case RRQ:
 	case WRQ:
-	case OACK:
-		p = (u_char *)tp->th_stuff;
-		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') {
-				ND_PRINT((ndo, " "));
-				fn_print(ndo, p, ndo->ndo_snapend);
-			}
-		}
-
-		if (i)
+		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, " "));
+		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, " "));
+			ui = fn_printztn(ndo, p, length, ndo->ndo_snapend);
+			if (ui == 0)
+				goto trunc;
+			p += ui;
+			length -= ui;
+		}
+		break;
+
+	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/print-timed.c b/print-timed.c
index 5830bc7..6aa7a82 100644
--- a/print-timed.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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 @@
 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 @@
 		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 @@
 	}
 	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/print-tipc.c b/print-tipc.c
index b883fba..4d8848f 100644
--- a/print-tipc.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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 @@
 	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 @@
 		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 @@
 		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/print-token.c b/print-token.c
index b88bcf7..faffd4b 100644
--- a/print-token.c
+++ b/print-token.c
@@ -24,16 +24,17 @@
  *	Guy Harris <guy@alum.mit.edu>
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: Token Ring printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <string.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 #include "addrtoname.h"
 #include "ether.h"
@@ -113,14 +114,13 @@
 	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[] = {
@@ -149,8 +149,9 @@
 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;
 
@@ -203,6 +204,11 @@
 			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;
@@ -211,20 +217,14 @@
 	/* 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/print-udld.c b/print-udld.c
index 15e2bf6..02921d0 100644
--- a/print-udld.c
+++ b/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 <carles.kishimoto@gmail.com>
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: Cisco UniDirectional Link Detection (UDLD) protocol printer */
+
+/* specification: RFC 5171 */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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 @@
 };
 
 /*
+ * 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 @@
  * |                              ...                              |
  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  *
+ * 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 @@
     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 @@
 
     return;
 
- trunc:
-    ND_PRINT((ndo, "[|udld]"));
+invalid:
+    ND_PRINT((ndo, "%s", istr));
+    return;
+trunc:
+    ND_PRINT((ndo, "%s", tstr));
 }
 
 /*
diff --git a/print-udp.c b/print-udp.c
index c3edf6e..5a74ff2 100644
--- a/print-udp.c
+++ b/print-udp.c
@@ -19,14 +19,15 @@
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: UDP printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 #include "extract.h"
 #include "appletalk.h"
@@ -34,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) */
@@ -97,16 +100,25 @@
 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,
@@ -117,6 +129,9 @@
 		if (i0 & 0x3f000000)
 			ND_PRINT((ndo, " s%d", (i0 >> 24) & 0x3f));
 	}
+
+trunc:
+	ND_PRINT((ndo, "%s", vat_tstr));
 }
 
 static void
@@ -124,26 +139,30 @@
           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;
@@ -161,11 +180,13 @@
 		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"));
@@ -177,7 +198,8 @@
 		}
 		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"));
@@ -185,53 +207,55 @@
 			}
 			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;
@@ -255,10 +279,9 @@
 	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.;
@@ -269,29 +292,30 @@
 		    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)
@@ -308,20 +332,18 @@
 			} 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: ",
@@ -330,15 +352,15 @@
 			} 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)));
 			}
 		}
 	}
@@ -353,24 +375,19 @@
 	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);
@@ -381,6 +398,10 @@
 		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);
@@ -392,43 +413,42 @@
 	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:
@@ -455,11 +475,7 @@
 		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:
@@ -487,39 +503,31 @@
 
 	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) {
@@ -545,11 +553,10 @@
 					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) {
@@ -560,55 +567,49 @@
 					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
@@ -617,78 +618,84 @@
 		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",
@@ -696,6 +703,10 @@
 		else
 			ND_PRINT((ndo, "UDP, length %u", ulen));
 	}
+	return;
+
+trunc:
+	ND_PRINT((ndo, "%s", udp_tstr));
 }
 
 
@@ -705,4 +716,3 @@
  * c-basic-offset: 8
  * End:
  */
-
diff --git a/print-usb.c b/print-usb.c
index 75f78fc..04eb4ef 100644
--- a/print-usb.c
+++ b/print-usb.c
@@ -19,14 +19,15 @@
  *
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: USB printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 
 
 #if defined(HAVE_PCAP_USB_H) && defined(DLT_USB_LINUX)
diff --git a/print-vjc.c b/print-vjc.c
index 24f8a12..3287b9b 100644
--- a/print-vjc.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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 @@
 		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/print-vqp.c b/print-vqp.c
index ce3572a..44a2193 100644
--- a/print-vqp.c
+++ b/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 <Carles.Kishimoto@bsc.es>
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: Cisco VLAN Query Protocol (VQP) printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 #include "addrtoname.h"
 
diff --git a/print-vrrp.c b/print-vrrp.c
index f739d1e..d8ba426 100644
--- a/print-vrrp.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 #include "addrtoname.h"
 
@@ -147,7 +148,7 @@
 		}
 
 		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/print-vtp.c b/print-vtp.c
index 9fe86e3..285beb9 100644
--- a/print-vtp.c
+++ b/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 <carles.kishimoto@gmail.com>
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: Cisco VLAN Trunking Protocol (VTP) printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 #include "extract.h"
 
@@ -121,7 +120,7 @@
 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 @@
     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 @@
     }
 
     /* 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 @@
 	 *
 	 *  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 @@
 	 *
 	 */
 
+	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 @@
 	 *
 	 *  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 @@
 
 	    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 @@
 	 *
 	 *  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/print-vxlan-gpe.c b/print-vxlan-gpe.c
new file mode 100644
index 0000000..6d170de
--- /dev/null
+++ b/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 <netdissect-stdinc.h>
+
+#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/print-vxlan.c b/print-vxlan.c
index c4de68d..0c2a82e 100644
--- a/print-vxlan.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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 @@
     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 @@
     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/print-wb.c b/print-wb.c
index e10d532..88857d9 100644
--- a/print-wb.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "addrtoname.h"
 #include "extract.h"
 
@@ -48,8 +49,8 @@
 #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 @@
 
 	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 @@
 		    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 @@
 		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/print-zephyr.c b/print-zephyr.c
index 8132c49..38b0cd0 100644
--- a/print-zephyr.c
+++ b/print-zephyr.c
@@ -20,37 +20,38 @@
  * PURPOSE.
  */
 
-#define NETDISSECT_REWORKED
+/* \summary: Zephyr printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 
-#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 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 @@
 }
 
 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 @@
 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 @@
     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 @@
 								   "-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/print-zeromq.c b/print-zeromq.c
index ba22c96..a23d98a 100644
--- a/print-zeromq.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 
 static const char tstr[] = " [|zmtp1]";
@@ -87,22 +85,18 @@
 	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 @@
 		}
 	}
 
-	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/print.c b/print.c
new file mode 100644
index 0000000..41ca9ca
--- /dev/null
+++ b/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 <swebster@sst.ll.mit.edu>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <netdissect-stdinc.h>
+
+#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/print.h b/print.h
new file mode 100644
index 0000000..9632694
--- /dev/null
+++ b/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 <swebster@sst.ll.mit.edu>
+ */
+
+#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/rpl.h b/rpl.h
index c48784b..5ad074b 100644
--- a/rpl.h
+++ b/rpl.h
@@ -22,7 +22,7 @@
     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 @@
         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 @@
     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 @@
         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/setsignal.c b/setsignal.c
index 1bcc032..4d93ceb 100644
--- a/setsignal.c
+++ b/setsignal.c
@@ -23,7 +23,7 @@
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <signal.h>
 #ifdef HAVE_SIGACTION
diff --git a/signature.c b/signature.c
index 324035f..1af798a 100644
--- a/signature.c
+++ b/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 <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <string.h>
+#include <stdlib.h>
 
-#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 @@
     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;
 
-    /*
-     * Save the signature before clearing it.
-     */
-    memcpy(rcvsig, sig_ptr, sizeof(rcvsig));
-    memset(sig_ptr, 0, sizeof(rcvsig));
-
     if (!ndo->ndo_sigsecret) {
         return (CANT_CHECK_SIGNATURE);
     }
 
-    signature_compute_hmac_md5(pptr, plen, (unsigned char *)ndo->ndo_sigsecret,
+    /*
+     * Do we have all the packet data to be checked?
+     */
+    if (!ND_TTEST2(pptr, plen)) {
+        /* No. */
+        return (CANT_CHECK_SIGNATURE);
+    }
+
+    /*
+     * 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);
+
+    /*
+     * 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) {
+    /*
+     * 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 @@
         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/signature.h b/signature.h
index a052df8..239ee3e 100644
--- a/signature.h
+++ b/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/smb.h b/smb.h
index 88eaa06..b521617 100644
--- a/smb.h
+++ b/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/smbutil.c b/smbutil.c
index 1c1742c..b38d73a 100644
--- a/smbutil.c
+++ b/smbutil.c
@@ -6,18 +6,17 @@
  * or later
  */
 
-#define NETDISSECT_REWORKED
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "extract.h"
 #include "smb.h"
 
@@ -272,8 +271,7 @@
 }
 
 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 @@
     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/strcasecmp.c b/strcasecmp.c
deleted file mode 100644
index 7ee4e38..0000000
--- a/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 <tcpdump-stdinc.h>
-
-#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/strtoaddr.c b/strtoaddr.c
new file mode 100644
index 0000000..81a041f
--- /dev/null
+++ b/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 <netdissect-stdinc.h>
+#include <stddef.h>
+#include <string.h>
+
+#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/strtoaddr.h b/strtoaddr.h
new file mode 100644
index 0000000..8bd22c7
--- /dev/null
+++ b/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/tcp.h b/tcp.h
index c18d138..912b5e8 100644
--- a/tcp.h
+++ b/tcp.h
@@ -81,56 +81,80 @@
 #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 BGP_PORT
-#define BGP_PORT                179
-#endif
-#define NETBIOS_SSN_PORT        139
-#ifndef OPENFLOW_PORT_OLD
-#define OPENFLOW_PORT_OLD       6633
-#endif
-#ifndef OPENFLOW_PORT_IANA
-#define OPENFLOW_PORT_IANA      6653
-#endif
-#ifndef PPTP_PORT
-#define PPTP_PORT	        1723
-#endif
-#define BEEP_PORT               10288
-#ifndef NFS_PORT
-#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 NAMESERVER_PORT
+#define NAMESERVER_PORT		53
 #endif
 #ifndef HTTP_PORT
 #define HTTP_PORT		80
 #endif
-#ifndef HTTP_PORT_ALT
-#define HTTP_PORT_ALT		8080
+#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
+#endif
+#ifndef RPKI_RTR_PORT
+#define RPKI_RTR_PORT		323
+#endif
+#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
+#endif
+#ifndef NFS_PORT
+#define NFS_PORT		2049
+#endif
+#ifndef OPENFLOW_PORT_OLD
+#define OPENFLOW_PORT_OLD	6633
+#endif
+#ifndef OPENFLOW_PORT_IANA
+#define OPENFLOW_PORT_IANA	6653
+#endif
+#ifndef HTTP_PORT_ALT
+#define HTTP_PORT_ALT		8080
+#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/tcpdump.1.in b/tcpdump.1.in
index f9522cb..f04a579 100644
--- a/tcpdump.1.in
+++ b/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 @@
 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 @@
 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 @@
 .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 @@
 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 @@
 \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 @@
 .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/tcpdump.c b/tcpdump.c
index 2b71d27..73bf138 100644
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -32,7 +32,7 @@
 #endif
 
 /*
- * 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
@@ -54,18 +54,12 @@
 #endif
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
-#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 <sys/stat.h>
 
-#ifdef USE_LIBSMI
-#include <smi.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
 #endif
 
 #ifdef HAVE_LIBCRYPTO
@@ -85,21 +79,21 @@
 #include <sys/capability.h>
 #include <sys/ioccom.h>
 #include <net/bpf.h>
-#include <fcntl.h>
 #include <libgen.h>
 #endif	/* HAVE_CAPSICUM */
 #include <pcap.h>
 #include <signal.h>
 #include <stdio.h>
+#include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
 #include <limits.h>
-#ifndef WIN32
+#ifndef _WIN32
 #include <sys/wait.h>
 #include <sys/resource.h>
 #include <pwd.h>
 #include <grp.h>
-#endif /* WIN32 */
+#endif /* _WIN32 */
 
 /* capabilities convenience library */
 /* If a code depends on HAVE_LIBCAP_NG, it depends also on HAVE_CAP_NG_H.
@@ -121,6 +115,9 @@
 #include "setsignal.h"
 #include "gmt2local.h"
 #include "pcap-missing.h"
+#include "ascii_strcasecmp.h"
+
+#include "print.h"
 
 #ifndef PATH_MAX
 #define PATH_MAX 1024
@@ -132,50 +129,74 @@
 #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;
 
 char *program_name;
 
-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);
@@ -192,202 +213,7 @@
 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"       },
@@ -398,57 +224,8 @@
 	{ 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;
@@ -457,15 +234,6 @@
 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;
@@ -476,23 +244,117 @@
 #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);
@@ -506,20 +368,20 @@
 		}
 	}
 	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.");
 
@@ -539,52 +401,49 @@
 		(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 */
 
@@ -599,7 +458,7 @@
  * 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
@@ -622,13 +481,13 @@
  * 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"
@@ -664,7 +523,7 @@
 #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.
@@ -691,7 +550,7 @@
 #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' },
@@ -723,7 +582,7 @@
 #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' },
@@ -732,7 +591,7 @@
 	{ 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)
@@ -740,36 +599,38 @@
 	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);
@@ -777,23 +638,24 @@
 #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)
@@ -843,43 +705,6 @@
         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)
 {
@@ -995,22 +820,301 @@
 }
 #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);
+		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];
@@ -1020,8 +1124,8 @@
 	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;
@@ -1029,21 +1133,22 @@
 	cap_rights_t rights;
 	int cansandbox;
 #endif	/* HAVE_CAPSICUM */
+	int Oflag = 1;			/* run filter code optimizer */
+	int yflag_dlt = -1;
+	const char *yflag_dlt_name = NULL;
 
-#ifdef WIN32
-	if(wsockinit() != 0) return 1;
-#endif /* WIN32 */
+	netdissect_options Ndo;
+	netdissect_options *ndo = &Ndo;
 
-	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;
+	/*
+	 * Initialize the netdissect code.
+	 */
+	if (nd_init(ebuf, sizeof ebuf) == -1)
+		error("%s", ebuf);
+
+	memset(ndo, 0, sizeof(*ndo));
+	ndo_set_function_pointers(ndo);
+	ndo->ndo_snaplen = DEFAULT_SNAPLEN;
 
 	cnt = -1;
 	device = NULL;
@@ -1054,9 +1159,14 @@
 	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,
@@ -1068,10 +1178,6 @@
 	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) {
@@ -1081,20 +1187,20 @@
 			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);
@@ -1104,7 +1210,7 @@
 
 		case 'C':
 			Cflag = atoi(optarg) * 1000000;
-			if (Cflag < 0)
+			if (Cflag <= 0)
 				error("invalid file size %s", optarg);
 			break;
 
@@ -1121,18 +1227,18 @@
 			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':
@@ -1156,52 +1262,14 @@
 
 		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;
 
@@ -1224,41 +1292,39 @@
 #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':
@@ -1266,15 +1332,15 @@
 #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':
@@ -1286,17 +1352,17 @@
 			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);
@@ -1307,66 +1373,64 @@
 			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
@@ -1376,7 +1440,7 @@
 #endif
 
 		case 'v':
-			++vflag;
+			++ndo->ndo_vflag;
 			break;
 
 		case 'V':
@@ -1389,77 +1453,71 @@
 
 		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 */
 		}
 
@@ -1468,11 +1526,11 @@
 		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 */
@@ -1486,7 +1544,7 @@
 		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)
@@ -1500,7 +1558,7 @@
 	 * probably expecting to see packets pop up immediately.
 	 */
 	if (WFileName == NULL && isatty(1))
-		gndo->ndo_immediate = 1;
+		immediate_mode = 1;
 #endif
 
 #ifdef WITH_CHROOT
@@ -1531,7 +1589,7 @@
 		 * 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).
@@ -1543,7 +1601,7 @@
 		 */
 		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;
@@ -1551,7 +1609,7 @@
 				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)
@@ -1561,7 +1619,7 @@
 
 #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
@@ -1591,157 +1649,91 @@
 		 * 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?
+		 * Try to open the interface with the specified name.
 		 */
-		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);
+		pd = open_interface(device, ndo, ebuf);
+		if (pd == NULL) {
+			/*
+			 * 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.
+			 */
+#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);
+			}
+
+			/*
+			 * 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.
+			 */
+			error("%s", ebuf);
+#endif /* HAVE_PCAP_FINDALLDEVS */
 		}
 
-		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?
-		 */
-		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) {
-			/*
-			 * pcap_activate() failed.
-			 */
-			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);
-			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(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 */
 		/*
 		 * 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
 			/*
@@ -1749,21 +1741,21 @@
 			 * 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);
                         }
@@ -1775,32 +1767,35 @@
 	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);
 	}
-	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,
@@ -1831,6 +1826,13 @@
 				CAP_SETGID,
 				-1);
 		}
+		if (chroot_dir) {
+			capng_update(
+				CAPNG_ADD,
+				CAPNG_PERMITTED | CAPNG_EFFECTIVE,
+				CAP_SYS_CHROOT
+				);
+		}
 
 		if (WFileName) {
 			capng_update(
@@ -1845,13 +1847,13 @@
 			droproot(username, chroot_dir);
 
 	}
-#endif /* WIN32 */
+#endif /* _WIN32 */
 
 	if (pcap_setfilter(pd, &fcode) < 0)
 		error("%s", pcap_geterr(pd));
 #ifdef HAVE_CAPSICUM
 	if (RFileName == NULL && VFileName == NULL) {
-		static const unsigned long cmds[] = { BIOCGSTATS };
+		static const unsigned long cmds[] = { BIOCGSTATS, BIOCROTZBUF };
 
 		cap_rights_init(&rights, CAP_IOCTL, CAP_READ);
 		if (cap_rights_limit(pcap_fileno(pd), &rights) < 0 &&
@@ -1900,6 +1902,10 @@
 		if (Cflag != 0 || Gflag != 0) {
 #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) {
@@ -1932,10 +1938,10 @@
 			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
@@ -1947,10 +1953,10 @@
 		(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
@@ -1963,14 +1969,13 @@
 #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);
@@ -1980,22 +1985,19 @@
 		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 HAVE_CAPSICUM
-	cansandbox = (nflag && VFileName == NULL && zflag == NULL);
+	cansandbox = (ndo->ndo_nflag && VFileName == NULL && zflag == NULL);
 	if (cansandbox && cap_enter() < 0 && errno != ENOSYS)
 		error("unable to enter the capability mode");
-	if (cap_sandboxed())
-		fprintf(stderr, "capability mode sandbox enabled\n");
 #endif	/* HAVE_CAPSICUM */
 
 	do {
@@ -2041,6 +2043,8 @@
 		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)
@@ -2053,30 +2057,67 @@
 				}
 #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 */
@@ -2116,7 +2157,7 @@
 		(void)fflush(stdout);
 		info(1);
 	}
-	exit(0);
+	exit_tcpdump(0);
 #endif
 }
 
@@ -2135,14 +2176,14 @@
 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;
@@ -2157,38 +2198,52 @@
 		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);
@@ -2197,15 +2252,15 @@
 #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
@@ -2275,7 +2330,8 @@
 			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)
@@ -2438,107 +2494,18 @@
 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
@@ -2565,21 +2532,6 @@
 	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_)
 {
@@ -2597,17 +2549,13 @@
 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);
 }
@@ -2619,37 +2567,38 @@
 {
 	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
 
@@ -2658,7 +2607,7 @@
 {
 	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,
@@ -2679,48 +2628,10 @@
 #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/tests/OLSRv1_HNA_sgw_1.out b/tests/OLSRv1_HNA_sgw_1.out
new file mode 100644
index 0000000..0f41cdc
--- /dev/null
+++ b/tests/OLSRv1_HNA_sgw_1.out
@@ -0,0 +1,13 @@
+IP (tos 0x10, ttl 1, id 25245, offset 0, flags [DF], proto UDP (17), length 100)
+    172.29.175.220.698 > 255.255.255.255.698: OLSRv4, seq 0xce93, length 72
+	HNA Message (0x04), originator 172.31.175.220, ttl 255, hop 0
+	  vtime 288.000s, msg-seq 0x6ce5, length 28
+	  Advertised networks (total 2)
+	    Smart-Gateway: LINKSPEED IPV4 IPV4-NAT 10000/10000, 10.175.220.0/24
+	Hello-LQ Message (0xc9), originator 172.31.175.220, ttl 1, hop 0
+	  vtime 3.000s, msg-seq 0x6ce6, length 40
+	  hello-time 1.000s, MPR willingness 3
+	    link-type Symmetric, neighbor-type Symmetric, len 12
+	      neighbor 172.29.175.221, link-quality 0.00%, neighbor-link-quality 0.00%
+	    link-type Unspecified, neighbor-type Symmetric, len 12
+	      neighbor 172.31.175.221, link-quality 0.00%, neighbor-link-quality 0.00%
diff --git a/tests/OLSRv1_HNA_sgw_1.pcap b/tests/OLSRv1_HNA_sgw_1.pcap
new file mode 100644
index 0000000..f975d8f
--- /dev/null
+++ b/tests/OLSRv1_HNA_sgw_1.pcap
Binary files differ
diff --git a/tests/RADIUS-port1700.pcap b/tests/RADIUS-port1700.pcap
new file mode 100644
index 0000000..aa7b24e
--- /dev/null
+++ b/tests/RADIUS-port1700.pcap
Binary files differ
diff --git a/tests/TESTLIST b/tests/TESTLIST
index 35963c6..ba29da4 100644
--- a/tests/TESTLIST
+++ b/tests/TESTLIST
@@ -1,3 +1,5 @@
+# The Option -n is useless in TESTLIST. It is already set in TESTonce.
+
 # Various flags applied to a TCP session.
 #
 # We cannot rely on, for example, "print-x.out" and
@@ -20,12 +22,14 @@
 bgp_vpn_attrset bgp_vpn_attrset.pcap bgp_vpn_attrset.out -t -v
 mpbgp-linklocal-nexthop mpbgp-linklocal-nexthop.pcap mpbgp-linklocal-nexthop.out -t -v
 bgp_infloop-v		bgp-infinite-loop.pcap		bgp_infloop-v.out	-t -v
+bgp-aigp	bgp-aigp.pcap	bgp-aigp.out	-t -v
+bgp-large-community bgp-large-community.pcap bgp-large-community.out -t -v
 
 # EAP tests
 eapon1 eapon1.pcap eapon1.out -t
 
 # ESP tests
-esp0 02-sunrise-sunset-esp.pcap esp0.out -t -n
+esp0 02-sunrise-sunset-esp.pcap esp0.out -t
 # more ESP tests in crypto.sh
 
 # ISAKMP tests
@@ -42,6 +46,14 @@
 # MPLS tests
 mpls-ldp-hello	mpls-ldp-hello.pcap	mpls-ldp-hello.out -t -v
 ldp_infloop	ldp-infinite-loop.pcap	ldp_infloop.out -t
+lspping-fec-ldp    lspping-fec-ldp.pcap lspping-fec-ldp.out -t
+lspping-fec-ldp-v  lspping-fec-ldp.pcap lspping-fec-ldp-v.out -t -v
+lspping-fec-ldp-vv lspping-fec-ldp.pcap lspping-fec-ldp-vv.out -t -vv
+lspping-fec-rsvp    lspping-fec-rsvp.pcap lspping-fec-rsvp.out -t
+lspping-fec-rsvp-v  lspping-fec-rsvp.pcap lspping-fec-rsvp-v.out -t -v
+lspping-fec-rsvp-vv lspping-fec-rsvp.pcap lspping-fec-rsvp-vv.out -t -vv
+mpls-traceroute   mpls-traceroute.pcap mpls-traceroute.out -t
+mpls-traceroute-v mpls-traceroute.pcap mpls-traceroute-v.out -t -v
 
 # OSPF tests
 ospf-gmpls	ospf-gmpls.pcap				ospf-gmpls.out		-t -v
@@ -50,12 +62,16 @@
 ospf3_bc-vv	OSPFv3_broadcast_adjacency.pcap		ospf3_bc-vv.out		-t -v -v
 ospf3_mp-vv	OSPFv3_multipoint_adjacencies.pcap	ospf3_mp-vv.out		-t -v -v
 ospf3_nbma-vv	OSPFv3_NBMA_adjacencies.pcap		ospf3_nbma-vv.out	-t -v -v
+# fuzzed pcap
+ospf2-seg-fault-1-v  ospf2-seg-fault-1.pcap  ospf2-seg-fault-1-v.out  -t -v
 
 # IKEv2 tests
 ikev2four	ikev2four.pcap		ikev2four.out	-t -v
 ikev2fourv	ikev2four.pcap		ikev2fourv.out	-t -v -v -v
 ikev2fourv4	ikev2four.pcap		ikev2fourv4.out	-t -v -v -v -v
 # ikev2pI2 test in crypto.sh
+ikev2pI2-segfault	ikev2pI2-segfault.pcap	ikev2pI2-segfault.out	-t
+ikev2pI2-segfault-v	ikev2pI2-segfault.pcap	ikev2pI2-segfault-v.out	-t -v
 
 # IETF ROLL RPL packets
 dio02           rpl-19-pickdag.pcap         rpl-19-pickdag.out  -t -v -v
@@ -96,6 +112,9 @@
 pppoes          pppoes.pcap            pppoes.out      -t
 pppoes_id       pppoes.pcap            pppoes_id.out   -t pppoes 0x3b
 
+# PPP tests
+truncated_aack  truncated-aack.pcap    trunc_aack.out  -t
+
 # IGMP tests
 igmpv1		IGMP_V1.pcap		igmpv1.out		-t
 igmpv2		IGMP_V2.pcap		igmpv2.out		-t
@@ -112,6 +131,7 @@
 
 # SPB BPDUv4 tests
 spb_bpduv4      spb_bpduv4.pcap       spb_bpduv4.out -t
+spb_bpduv4-v	spb_bpduv4.pcap       spb_bpduv4-v.out -t -v
 
 # DCB Tests
 dcb_ets         dcb_ets.pcap          dcb_ets.out   -t -vv
@@ -139,6 +159,7 @@
 dhcpv6-ntp-server	dhcpv6-ntp-server.pcap	dhcpv6-ntp-server.out	-t -v
 dhcpv6-sip-server-d	dhcpv6-sip-server-d.pcap	dhcpv6-sip-server-d.out -t -v
 dhcpv6-domain-list	dhcpv6-domain-list.pcap	dhcpv6-domain-list.out	-t -v
+dhcpv6-mud	dhcpv6-mud.pcap		dhcpv6-mud.out -t -vv
 
 # ZeroMQ/PGM tests
 # ZMTP/1.0 over TCP
@@ -151,6 +172,8 @@
 pgm_zmtp1v	pgm_zmtp1.pcap		pgm_zmtp1v.out	-t -v -T pgm_zmtp1
 # ZMTP/1.0 inside UDP-encapsulated PGM
 epgm_zmtp1v	epgm_zmtp1.pcap		epgm_zmtp1v.out	-t -v -T pgm_zmtp1
+# fuzzed pcap
+zmtp1-inf-loop-1 zmtp1-inf-loop-1.pcap zmtp1-inf-loop-1.out -t -T zmtp1
 
 # MS NLB tests
 msnlb		msnlb.pcap		msnlb.out	-t
@@ -161,6 +184,8 @@
 mptcp-fclose	mptcp-fclose.pcap	mptcp-fclose.out	-t
 # TFO tests
 tfo		tfo-5c1fa7f9ae91.pcap	tfo.out		-t
+# SCPS
+scps_invalid	scps_invalid.pcap	scps_invalid.out	-t
 
 # IEEE 802.11 tests
 802.11_exthdr	ieee802.11_exthdr.pcap	ieee802.11_exthdr.out	-t -v
@@ -174,7 +199,7 @@
 of10_7050sx_bsn-vv	of10_7050sx_bsn.pcap		of10_7050sx_bsn-vv.out	-t -vv
 
 # GeoNetworking and CALM FAST tests
-geonet-calm-fast	geonet_and_calm_fast.pcap	geonet_and_calm_fast.out	-t -vv -n
+geonet-calm-fast	geonet_and_calm_fast.pcap	geonet_and_calm_fast.out	-t -vv
 
 # M3UA tests
 m3ua isup.pcap isup.out -t
@@ -185,8 +210,11 @@
 # syslog test case
 syslog-v	syslog_udp.pcap		syslog-v.out		-t -v
 
+# DNSSEC from https://bugzilla.redhat.com/show_bug.cgi?id=205842, -vv exposes EDNS DO
+dnssec-vv	dnssec.pcap		dnssec-vv.out		-t -vv
+
 #IPv6 tests
-ipv6-bad-version.pcap	ipv6-bad-version.pcap 	ipv6-bad-version.out	-t
+ipv6-bad-version	ipv6-bad-version.pcap 	ipv6-bad-version.out	-t
 ipv6-routing-header	ipv6-routing-header.pcap	ipv6-routing-header.out -t -v
 
 # Loopback/CTP test case
@@ -217,9 +245,22 @@
 
 # IS-IS tests
 isis_infloop-v	isis-infinite-loop.pcap		isis_infloop-v.out	-t -v
+isis_poi-v      isis_poi.pcap                   isis_poi.out            -t -v
+isis_poi2-v     isis_poi2.pcap                  isis_poi2.out           -t -v
+isis_1		ISIS_external_lsp.pcap		isis_1.out	-t
+isis_1-v	ISIS_external_lsp.pcap		isis_1-v.out	-t -v
+isis_2-v	ISIS_level1_adjacency.pcap	isis_2-v.out	-t -v
+isis_3-v	ISIS_level2_adjacency.pcap	isis_3-v.out	-t -v
+isis_4-v	ISIS_p2p_adjacency.pcap		isis_4-v.out	-t -v
+# fuzzed pcap
+# isis-seg-fault-1-v is now conditionally handled by isis-seg-fault-1-v.sh
+isis-seg-fault-2-v isis-seg-fault-2.pcap isis-seg-fault-2-v.out -t -v
+isis-seg-fault-3-v isis-seg-fault-3.pcap isis-seg-fault-3-v.out -t -v
 
 # RSVP tests
 rsvp_infloop-v	rsvp-infinite-loop.pcap		rsvp_infloop-v.out	-t -v
+# fuzzed pcap
+rsvp-inf-loop-2-v rsvp-inf-loop-2.pcap rsvp-inf-loop-2-v.out -t -v
 
 # HDLC tests
 hdlc1	chdlc-slarp.pcap	hdlc1.out	-t
@@ -234,6 +275,7 @@
 radius-v	RADIUS.pcap	radius-v.out	-t -v
 radius-rfc4675	RADIUS-RFC4675.pcap	radius-rfc4675-v.out	-t -v
 radius-rfc5176	RADIUS-RFC5176.pcap	radius-rfc5176-v.out	-t -v
+radius-port1700	RADIUS-port1700.pcap	radius-port1700-v.out	-t -v
 
 # link-level protocols
 dtp-v		DTP.pcap		dtp-v.out		-t -v
@@ -241,6 +283,10 @@
 lldp_cdp-ev	LLDP_and_CDP.pcap	lldp_cdp-ev.out		-t -e -v
 cdp-v		3560_CDP.pcap		cdp-v.out		-t -v
 udld-v		UDLD.pcap		udld-v.out		-t -v
+lldp_mud-v	lldp_mudurl.pcap	lldp_mudurl-v.out	-t -e -v
+lldp_mud-vv	lldp_mudurl.pcap	lldp_mudurl-vv.out	-t -e -vv
+# fuzzed pcap
+udld-inf-loop-1-v  udld-inf-loop-1.pcap  udld-inf-loop-1-v.out  -t -v
 
 # EIGRP tests
 eigrp1-v	EIGRP_adjacency.pcap	eigrp1-v.out	-t -v
@@ -248,13 +294,6 @@
 eigrp3-v	EIGRP_subnet_down.pcap	eigrp3-v.out	-t -v
 eigrp4-v	EIGRP_subnet_up.pcap	eigrp4-v.out	-t -v
 
-# IS-IS tests
-isis_1		ISIS_external_lsp.pcap		isis_1.out	-t
-isis_1-v	ISIS_external_lsp.pcap		isis_1-v.out	-t -v
-isis_2-v	ISIS_level1_adjacency.pcap	isis_2-v.out	-t -v
-isis_3-v	ISIS_level2_adjacency.pcap	isis_3-v.out	-t -v
-isis_4-v	ISIS_p2p_adjacency.pcap		isis_4-v.out	-t -v
-
 # ATA-over-Ethernet tests
 aoe_1		AoE_Linux.pcap		aoe_1.out	-t
 aoe_1-v		AoE_Linux.pcap		aoe_1-v.out	-t -v
@@ -267,25 +306,140 @@
 # DHCP tests
 dhcp-rfc3004	dhcp-rfc3004.pcap	dhcp-rfc3004-v.out	-t -v
 dhcp-rfc5859	dhcp-rfc5859.pcap	dhcp-rfc5859-v.out	-t -v
+dhcp-mud	dhcp-mud.pcap		dhcp-mud.out	-t -vv
+
+# MEDSA tests
+medsa		medsa.pcap		medsa.out	-t
+medsa-e		medsa.pcap		medsa-e.out	-t -e
+
+# VXLAN tests
+vxlan  vxlan.pcap  vxlan.out  -# -t -e
+
+# CVEs 2014 malformed packets from Steffen Bauch
+cve-2014-8767-OLSR cve-2014-8767-OLSR.pcap cve-2014-8767-OLSR.out -t -v
+cve-2014-8768-Geonet cve-2014-8768-Geonet.pcap cve-2014-8768-Geonet.out -t -v
+cve-2014-8769-AODV cve-2014-8769-AODV.pcap cve-2014-8769-AODV.out -t -v
 
 # bad packets from Kevin Day
-# cve-2015-2155 -- futz testing on FORCES printer
+# cve-2015-2155 -- fuzz testing on FORCES printer
 kday1           kday1.pcap              kday1.out       -t -v
-# cve-2015-2153 -- futz testing on TCP printer
+# cve-2015-2153 -- fuzz testing on TCP printer
 kday2           kday2.pcap              kday2.out       -t -v
-# cve-2015-2153 -- futz testing on TCP printer
+# cve-2015-2153 -- fuzz testing on TCP printer
 kday3           kday3.pcap              kday3.out       -t -v
-# cve-2015-2153 -- futz testing on TCP printer
+# cve-2015-2153 -- fuzz testing on TCP printer
 kday4           kday4.pcap              kday4.out       -t -v
-# cve-2015-2153 -- futz testing on TCP printer
+# cve-2015-2153 -- fuzz testing on TCP printer
 kday5           kday5.pcap              kday5.out       -t -v
 # cve-2015-2154 -- ethernet printer
 kday6           kday6.pcap              kday6.out       -t -v
-# cve-2015-2153 -- futz testing on TCP printer
+# cve-2015-2153 -- fuzz testing on TCP printer
 kday7           kday7.pcap              kday7.out       -t -v
-# cve-2015-2153 -- futz testing on TCP printer
+# cve-2015-2153 -- fuzz testing on TCP printer
 kday8           kday8.pcap              kday8.out       -t -v
 
 # bad packets from reversex86.
 cve2015-0261_01    cve2015-0261-ipv6.pcap       cve2015-0261-ipv6.out -t -v
 cve2015-0261_02    cve2015-0261-crash.pcap      cve2015-0261-crash.out -t -v
+
+# OLSRv1 tests
+olsrv1_1	OLSRv1_HNA_sgw_1.pcap		OLSRv1_HNA_sgw_1.out	-t -v
+
+# tests with unaligned data, to make sure they work on SPARC
+unaligned-nfs-1	unaligned-nfs-1.pcap	unaligned-nfs-1.out	-t -v
+
+# LISP tests
+lisp_eid_notify		lisp_eid_notify.pcap	lisp_eid_notify.out	-t -v
+lisp_eid_register	lisp_eid_register.pcap	lisp_eid_register.out	-t -v
+lisp_ipv6_eid		lisp_ipv6.pcap		lisp_ipv6.out		-t -v
+
+# pcap invalid versions (first: version = 1.4 ; second: version = 2.5)
+pcap-invalid-version-1 pcap-invalid-version-1.pcap pcap-invalid-version-1.out -t
+pcap-invalid-version-2 pcap-invalid-version-2.pcap pcap-invalid-version-2.out -t
+
+# pcap-ng invalid version (first: version = 0.1 ; second: version = 1.1)
+pcap-ng-invalid-vers-1 pcap-ng-invalid-vers-1.pcap pcap-ng-invalid-vers-1.out -t
+pcap-ng-invalid-vers-2 pcap-ng-invalid-vers-2.pcap pcap-ng-invalid-vers-2.out -t
+
+# NSH over VxLAN-GPE
+nsh-over-vxlan-gpe     nsh-over-vxlan-gpe.pcap nsh-over-vxlan-gpe.out     -t
+nsh-over-vxlan-gpe-v   nsh-over-vxlan-gpe.pcap nsh-over-vxlan-gpe-v.out   -t -v
+nsh-over-vxlan-gpe-vv  nsh-over-vxlan-gpe.pcap nsh-over-vxlan-gpe-vv.out  -t -vv
+nsh-over-vxlan-gpe-vvv nsh-over-vxlan-gpe.pcap nsh-over-vxlan-gpe-vvv.out -t -vvv
+
+# RESP tests
+resp_1 resp_1_benchmark.pcap resp_1.out -t
+resp_2 resp_2_inline.pcap    resp_2.out -t
+resp_3 resp_3_malicious.pcap resp_3.out -t
+
+# HNCP tests
+hncp hncp.pcap hncp.out -vvv -t
+
+# BFD tests with authentication fields
+bfd-raw-auth-simple bfd-raw-auth-simple.pcap bfd-raw-auth-simple.out -t
+bfd-raw-auth-simple-v bfd-raw-auth-simple.pcap bfd-raw-auth-simple-v.out -t -v
+bfd-raw-auth-md5 bfd-raw-auth-md5.pcap bfd-raw-auth-md5.out -t
+bfd-raw-auth-md5-v bfd-raw-auth-md5.pcap bfd-raw-auth-md5-v.out -t -v
+bfd-raw-auth-sha1 bfd-raw-auth-sha1.pcap bfd-raw-auth-sha1.out -t
+bfd-raw-auth-sha1-v bfd-raw-auth-sha1.pcap bfd-raw-auth-sha1-v.out -t -v
+
+# bad packets from Hanno Böck
+heap-overflow-1	heap-overflow-1.pcap		heap-overflow-1.out	-t -v -n
+heap-overflow-2	heap-overflow-2.pcap		heap-overflow-2.out	-t -v -n
+heapoverflow-atalk_print	heapoverflow-atalk_print.pcap	heapoverflow-atalk_print.out	-t -v -n
+heapoverflow-EXTRACT_16BITS	heapoverflow-EXTRACT_16BITS.pcap	heapoverflow-EXTRACT_16BITS.out	-t -v -n
+heapoverflow-ppp_hdlc_if_print	heapoverflow-ppp_hdlc_if_print.pcap	heapoverflow-ppp_hdlc_if_print.out	-t -v -n
+heapoverflow-q933_printq	heapoverflow-q933_printq.pcap	heapoverflow-q933_printq.out	-t -v -n
+heapoverflow-sl_if_print	heapoverflow-sl_if_print.pcap	heapoverflow-sl_if_print.out	-t -v -n
+heapoverflow-ip_print_demux	heapoverflow-ip_print_demux.pcap	heapoverflow-ip_print_demux.out	-t -v -n
+heapoverflow-in_checksum	heapoverflow-in_checksum.pcap	heapoverflow-in_checksum.out	-t -v -n
+heapoverflow-tcp_print	heapoverflow-tcp_print.pcap	heapoverflow-tcp_print.out	-t -v -n
+gre-heapoverflow-1	gre-heapoverflow-1.pcap	gre-heapoverflow-1.out	-t -v -n
+gre-heapoverflow-2	gre-heapoverflow-2.pcap	gre-heapoverflow-2.out	-t -v -n
+calm-fast-mac-lookup-heapoverflow	calm-fast-mac-lookup-heapoverflow.pcap	calm-fast-mac-lookup-heapoverflow.out	-t -v -n
+geonet-mac-lookup-heapoverflow	geonet-mac-lookup-heapoverflow.pcap	geonet-mac-lookup-heapoverflow.out	-t -v -n
+radiotap-heapoverflow	radiotap-heapoverflow.pcap	radiotap-heapoverflow.out -t -v -n
+isoclns-heapoverflow	isoclns-heapoverflow.pcap	isoclns-heapoverflow.out	-t -v -n
+tcp-auth-heapoverflow	tcp-auth-heapoverflow.pcap	tcp-auth-heapoverflow.out	-t -v -n
+frf15-heapoverflow	frf15-heapoverflow.pcap	frf15-heapoverflow.out	-t -v -n
+atm-oam-heapoverflow	atm-oam-heapoverflow.pcap	atm-oam-heapoverflow.out	-t -v -n
+tcp_header_heapoverflow	tcp_header_heapoverflow.pcap	tcp_header_heapoverflow.out	-t -v -n
+ipcomp-heapoverflow	ipcomp-heapoverflow.pcap	ipcomp-heapoverflow.out	-t -v -n
+llc-xid-heapoverflow	llc-xid-heapoverflow.pcap	llc-xid-heapoverflow.out	-t -v -n
+udp-length-heapoverflow	udp-length-heapoverflow.pcap	udp-length-heapoverflow.out	-t -v -n
+aarp-heapoverflow-1	aarp-heapoverflow-1.pcap	aarp-heapoverflow-1.out	-t -v -n
+aarp-heapoverflow-2	aarp-heapoverflow-2.pcap	aarp-heapoverflow-2.out	-t -v -n
+mpls-label-heapoverflow	mpls-label-heapoverflow.pcap	mpls-label-heapoverflow.out	-t -v -n
+bad-ipv4-version-pgm-heapoverflow	bad-ipv4-version-pgm-heapoverflow.pcap	bad-ipv4-version-pgm-heapoverflow.out	-t -v -n
+stp-heapoverflow-1	stp-heapoverflow-1.pcap	stp-heapoverflow-1.out	-t -v -n
+stp-heapoverflow-2	stp-heapoverflow-2.pcap	stp-heapoverflow-2.out	-t -v -n
+stp-heapoverflow-3	stp-heapoverflow-3.pcap	stp-heapoverflow-3.out	-t -v -n
+stp-heapoverflow-4	stp-heapoverflow-4.pcap	stp-heapoverflow-4.out	-t -v -n
+stp-heapoverflow-5	stp-heapoverflow-5.pcap	stp-heapoverflow-5.out	-t -v -n
+arp-too-long-tha	arp-too-long-tha.pcap	arp-too-long-tha.out	-t -v -n
+juniper_header-heapoverflow	juniper_header-heapoverflow.pcap	juniper_header-heapoverflow.out	-t -v -n
+tftp-heapoverflow	tftp-heapoverflow.pcap	tftp-heapoverflow.out	-t -v -n
+relts-0x80000000	relts-0x80000000.pcap	relts-0x80000000.out	-t -v -n
+
+# bad packets from Brian Carpenter
+ipv6hdr-heapoverflow	ipv6hdr-heapoverflow.pcap	ipv6hdr-heapoverflow.out	-t
+ipv6hdr-heapoverflow-v	ipv6hdr-heapoverflow.pcap	ipv6hdr-heapoverflow-v.out	-t -v
+otv-heapoverflow-1	otv-heapoverflow-1.pcap		otv-heapoverflow-1.out		-t -c10
+otv-heapoverflow-2	otv-heapoverflow-2.pcap		otv-heapoverflow-2.out		-t -c10
+q933-heapoverflow-2	q933-heapoverflow-2.pcap	q933-heapoverflow-2.out		-t
+atm-heapoverflow	atm-heapoverflow.pcap		atm-heapoverflow.out		-t -c1 -e
+
+# bad packets from Kamil Frankowicz
+snmp-heapoverflow-1	snmp-heapoverflow-1.pcap	snmp-heapoverflow-1.out		-t
+snmp-heapoverflow-2	snmp-heapoverflow-2.pcap	snmp-heapoverflow-2.out		-t
+isoclns-heapoverflow-2	isoclns-heapoverflow-2.pcap	isoclns-heapoverflow-2.out	-t -e -c1
+isoclns-heapoverflow-3	isoclns-heapoverflow-3.pcap	isoclns-heapoverflow-3.out	-t -e -c1
+
+# RTP tests
+# fuzzed pcap
+rtp-seg-fault-1  rtp-seg-fault-1.pcap  rtp-seg-fault-1.out  -t -v -T rtp
+rtp-seg-fault-2  rtp-seg-fault-2.pcap  rtp-seg-fault-2.out  -t -v -T rtp
+
+# NFS tests
+# fuzzed pcap
+nfs-seg-fault-1  nfs-seg-fault-1.pcap  nfs-seg-fault-1.out  -t
diff --git a/tests/TESTonce b/tests/TESTonce
index 30ffccd..78ad075 100755
--- a/tests/TESTonce
+++ b/tests/TESTonce
@@ -36,11 +36,11 @@
 }
 
 if($r == 0) {
-  printf "    %-30s: passed\n", $name;
+  printf "    %-35s: passed\n", $name;
   unlink "DIFF/$output.diff";
   exit 0;
 }
-printf "    %-30s: TEST FAILED", $name;
+printf "    %-35s: TEST FAILED", $name;
 open FOUT, '>>failure-outputs.txt';
 printf FOUT "Failed test: $name\n\n";
 close FOUT;
@@ -56,6 +56,8 @@
 # this is not working right, $r == 0x8b00 when there is a core dump.
 # clearly, we need some platform specific perl magic to take this apart, so look for "core"
 # too.
+# In particular, on Solaris 10 SPARC an alignment problem results in SIGILL,
+# a core dump and $r set to 0x00008a00 ($? == 138 in the shell).
 if($r & 127 || -f "core") {
     my $with = ($r & 128) ? 'with' : 'without';
     if(-f "core") {
diff --git a/tests/aarp-heapoverflow-1.out b/tests/aarp-heapoverflow-1.out
new file mode 100644
index 0000000..a562223
--- /dev/null
+++ b/tests/aarp-heapoverflow-1.out
@@ -0,0 +1 @@
+aarp  [|aarp]
diff --git a/tests/aarp-heapoverflow-1.pcap b/tests/aarp-heapoverflow-1.pcap
new file mode 100644
index 0000000..7ea3f22
--- /dev/null
+++ b/tests/aarp-heapoverflow-1.pcap
Binary files differ
diff --git a/tests/aarp-heapoverflow-2.out b/tests/aarp-heapoverflow-2.out
new file mode 100644
index 0000000..a562223
--- /dev/null
+++ b/tests/aarp-heapoverflow-2.out
@@ -0,0 +1 @@
+aarp  [|aarp]
diff --git a/tests/aarp-heapoverflow-2.pcap b/tests/aarp-heapoverflow-2.pcap
new file mode 100644
index 0000000..8fbbc85
--- /dev/null
+++ b/tests/aarp-heapoverflow-2.pcap
Binary files differ
diff --git a/tests/arp-too-long-tha.out b/tests/arp-too-long-tha.out
new file mode 100644
index 0000000..c70ad83
--- /dev/null
+++ b/tests/arp-too-long-tha.out
@@ -0,0 +1 @@
+ARP, Unknown Hardware (12336) (len 14), IPv4 (len 4), Request who-has 48.48.48.48 (30:30:30:30:30:30:30:30:30:30:30:30:30:30) tell 48.48.48.48, length 808464414
diff --git a/tests/arp-too-long-tha.pcap b/tests/arp-too-long-tha.pcap
new file mode 100644
index 0000000..f773974
--- /dev/null
+++ b/tests/arp-too-long-tha.pcap
Binary files differ
diff --git a/tests/atm-heapoverflow.out b/tests/atm-heapoverflow.out
new file mode 100644
index 0000000..c9b12fd
--- /dev/null
+++ b/tests/atm-heapoverflow.out
@@ -0,0 +1 @@
+Rx: VPI:0 VCI:5  [|atm]
diff --git a/tests/atm-heapoverflow.pcap b/tests/atm-heapoverflow.pcap
new file mode 100644
index 0000000..6918f3e
--- /dev/null
+++ b/tests/atm-heapoverflow.pcap
Binary files differ
diff --git a/tests/atm-oam-heapoverflow.out b/tests/atm-oam-heapoverflow.out
new file mode 100644
index 0000000..cdcb8ce
--- /dev/null
+++ b/tests/atm-oam-heapoverflow.out
@@ -0,0 +1 @@
+[|oam]
diff --git a/tests/atm-oam-heapoverflow.pcap b/tests/atm-oam-heapoverflow.pcap
new file mode 100644
index 0000000..0bbb4d1
--- /dev/null
+++ b/tests/atm-oam-heapoverflow.pcap
Binary files differ
diff --git a/tests/bad-ipv4-version-pgm-heapoverflow.out b/tests/bad-ipv4-version-pgm-heapoverflow.out
new file mode 100644
index 0000000..7655a51
--- /dev/null
+++ b/tests/bad-ipv4-version-pgm-heapoverflow.out
@@ -0,0 +1 @@
+IP6, wrong link-layer encapsulation 
diff --git a/tests/bad-ipv4-version-pgm-heapoverflow.pcap b/tests/bad-ipv4-version-pgm-heapoverflow.pcap
new file mode 100644
index 0000000..c65c4e6
--- /dev/null
+++ b/tests/bad-ipv4-version-pgm-heapoverflow.pcap
Binary files differ
diff --git a/tests/bfd-raw-auth-md5-v.out b/tests/bfd-raw-auth-md5-v.out
new file mode 100644
index 0000000..e6766ff
--- /dev/null
+++ b/tests/bfd-raw-auth-md5-v.out
@@ -0,0 +1,341 @@
+IP (tos 0x0, ttl 10, id 1, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 2, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 3, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 4, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 5, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 6, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 7, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 8, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 9, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 10, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 11, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 12, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 13, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 14, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 15, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 16, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 17, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 18, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 19, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 20, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 21, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 22, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 23, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 24, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 25, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 26, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 27, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 28, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 29, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 30, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
+IP (tos 0x0, ttl 10, id 31, offset 0, flags [none], proto UDP (17), length 76)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 48
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 48
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Keyed MD5 (2), length: 24
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Digest: 01020304050607080910111213141516
diff --git a/tests/bfd-raw-auth-md5.out b/tests/bfd-raw-auth-md5.out
new file mode 100644
index 0000000..aee3165
--- /dev/null
+++ b/tests/bfd-raw-auth-md5.out
@@ -0,0 +1,31 @@
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 48
diff --git a/tests/bfd-raw-auth-md5.pcap b/tests/bfd-raw-auth-md5.pcap
new file mode 100644
index 0000000..9de6d4a
--- /dev/null
+++ b/tests/bfd-raw-auth-md5.pcap
Binary files differ
diff --git a/tests/bfd-raw-auth-sha1-v.out b/tests/bfd-raw-auth-sha1-v.out
new file mode 100644
index 0000000..82b4553
--- /dev/null
+++ b/tests/bfd-raw-auth-sha1-v.out
@@ -0,0 +1,275 @@
+IP (tos 0x0, ttl 10, id 0, offset 0, flags [none], proto UDP (17), length 80)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 52
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 52
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Meticulous Keyed SHA1 (5), length: 28
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Hash: 010203040506070809101112131415161718191a
+IP (tos 0x0, ttl 10, id 1, offset 0, flags [none], proto UDP (17), length 80)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 52
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 52
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Meticulous Keyed SHA1 (5), length: 28
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Hash: 010203040506070809101112131415161718191a
+IP (tos 0x0, ttl 10, id 2, offset 0, flags [none], proto UDP (17), length 80)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 52
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 52
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Meticulous Keyed SHA1 (5), length: 28
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Hash: 010203040506070809101112131415161718191a
+IP (tos 0x0, ttl 10, id 3, offset 0, flags [none], proto UDP (17), length 80)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 52
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 52
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Meticulous Keyed SHA1 (5), length: 28
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Hash: 010203040506070809101112131415161718191a
+IP (tos 0x0, ttl 10, id 4, offset 0, flags [none], proto UDP (17), length 80)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 52
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 52
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Meticulous Keyed SHA1 (5), length: 28
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Hash: 010203040506070809101112131415161718191a
+IP (tos 0x0, ttl 10, id 5, offset 0, flags [none], proto UDP (17), length 80)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 52
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 52
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Meticulous Keyed SHA1 (5), length: 28
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Hash: 010203040506070809101112131415161718191a
+IP (tos 0x0, ttl 10, id 6, offset 0, flags [none], proto UDP (17), length 80)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 52
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 52
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Meticulous Keyed SHA1 (5), length: 28
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Hash: 010203040506070809101112131415161718191a
+IP (tos 0x0, ttl 10, id 7, offset 0, flags [none], proto UDP (17), length 80)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 52
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 52
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Meticulous Keyed SHA1 (5), length: 28
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Hash: 010203040506070809101112131415161718191a
+IP (tos 0x0, ttl 10, id 8, offset 0, flags [none], proto UDP (17), length 80)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 52
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 52
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Meticulous Keyed SHA1 (5), length: 28
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Hash: 010203040506070809101112131415161718191a
+IP (tos 0x0, ttl 10, id 9, offset 0, flags [none], proto UDP (17), length 80)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 52
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 52
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Meticulous Keyed SHA1 (5), length: 28
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Hash: 010203040506070809101112131415161718191a
+IP (tos 0x0, ttl 10, id 10, offset 0, flags [none], proto UDP (17), length 80)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 52
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 52
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Meticulous Keyed SHA1 (5), length: 28
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Hash: 010203040506070809101112131415161718191a
+IP (tos 0x0, ttl 10, id 11, offset 0, flags [none], proto UDP (17), length 80)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 52
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 52
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Meticulous Keyed SHA1 (5), length: 28
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Hash: 010203040506070809101112131415161718191a
+IP (tos 0x0, ttl 10, id 12, offset 0, flags [none], proto UDP (17), length 80)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 52
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 52
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Meticulous Keyed SHA1 (5), length: 28
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Hash: 010203040506070809101112131415161718191a
+IP (tos 0x0, ttl 10, id 13, offset 0, flags [none], proto UDP (17), length 80)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 52
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 52
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Meticulous Keyed SHA1 (5), length: 28
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Hash: 010203040506070809101112131415161718191a
+IP (tos 0x0, ttl 10, id 14, offset 0, flags [none], proto UDP (17), length 80)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 52
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 52
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Meticulous Keyed SHA1 (5), length: 28
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Hash: 010203040506070809101112131415161718191a
+IP (tos 0x0, ttl 10, id 15, offset 0, flags [none], proto UDP (17), length 80)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 52
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 52
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Meticulous Keyed SHA1 (5), length: 28
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Hash: 010203040506070809101112131415161718191a
+IP (tos 0x0, ttl 10, id 16, offset 0, flags [none], proto UDP (17), length 80)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 52
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 52
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Meticulous Keyed SHA1 (5), length: 28
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Hash: 010203040506070809101112131415161718191a
+IP (tos 0x0, ttl 10, id 17, offset 0, flags [none], proto UDP (17), length 80)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 52
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 52
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Meticulous Keyed SHA1 (5), length: 28
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Hash: 010203040506070809101112131415161718191a
+IP (tos 0x0, ttl 10, id 18, offset 0, flags [none], proto UDP (17), length 80)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 52
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 52
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Meticulous Keyed SHA1 (5), length: 28
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Hash: 010203040506070809101112131415161718191a
+IP (tos 0x0, ttl 10, id 19, offset 0, flags [none], proto UDP (17), length 80)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 52
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 52
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Meticulous Keyed SHA1 (5), length: 28
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Hash: 010203040506070809101112131415161718191a
+IP (tos 0x0, ttl 10, id 20, offset 0, flags [none], proto UDP (17), length 80)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 52
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 52
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Meticulous Keyed SHA1 (5), length: 28
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Hash: 010203040506070809101112131415161718191a
+IP (tos 0x0, ttl 10, id 21, offset 0, flags [none], proto UDP (17), length 80)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 52
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 52
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Meticulous Keyed SHA1 (5), length: 28
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Hash: 010203040506070809101112131415161718191a
+IP (tos 0x0, ttl 10, id 22, offset 0, flags [none], proto UDP (17), length 80)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 52
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 52
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Meticulous Keyed SHA1 (5), length: 28
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Hash: 010203040506070809101112131415161718191a
+IP (tos 0x0, ttl 10, id 23, offset 0, flags [none], proto UDP (17), length 80)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 52
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 52
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Meticulous Keyed SHA1 (5), length: 28
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Hash: 010203040506070809101112131415161718191a
+IP (tos 0x0, ttl 10, id 24, offset 0, flags [none], proto UDP (17), length 80)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 52
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 52
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Meticulous Keyed SHA1 (5), length: 28
+	  Auth Key ID: 2, Sequence Number: 0x00000005
+	  Hash: 010203040506070809101112131415161718191a
diff --git a/tests/bfd-raw-auth-sha1.out b/tests/bfd-raw-auth-sha1.out
new file mode 100644
index 0000000..6a5ed8a
--- /dev/null
+++ b/tests/bfd-raw-auth-sha1.out
@@ -0,0 +1,25 @@
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 52
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 52
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 52
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 52
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 52
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 52
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 52
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 52
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 52
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 52
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 52
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 52
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 52
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 52
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 52
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 52
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 52
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 52
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 52
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 52
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 52
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 52
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 52
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 52
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 52
diff --git a/tests/bfd-raw-auth-sha1.pcap b/tests/bfd-raw-auth-sha1.pcap
new file mode 100644
index 0000000..8fafb60
--- /dev/null
+++ b/tests/bfd-raw-auth-sha1.pcap
Binary files differ
diff --git a/tests/bfd-raw-auth-simple-v.out b/tests/bfd-raw-auth-simple-v.out
new file mode 100644
index 0000000..7276f06
--- /dev/null
+++ b/tests/bfd-raw-auth-simple-v.out
@@ -0,0 +1,150 @@
+IP (tos 0x0, ttl 10, id 0, offset 0, flags [none], proto UDP (17), length 61)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 33
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 33
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Simple Password (1), length: 9
+	  Auth Key ID: 2, Password: secret
+IP (tos 0x0, ttl 10, id 1, offset 0, flags [none], proto UDP (17), length 61)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 33
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 33
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Simple Password (1), length: 9
+	  Auth Key ID: 2, Password: secret
+IP (tos 0x0, ttl 10, id 2, offset 0, flags [none], proto UDP (17), length 61)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 33
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 33
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Simple Password (1), length: 9
+	  Auth Key ID: 2, Password: secret
+IP (tos 0x0, ttl 10, id 3, offset 0, flags [none], proto UDP (17), length 61)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 33
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 33
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Simple Password (1), length: 9
+	  Auth Key ID: 2, Password: secret
+IP (tos 0x0, ttl 10, id 4, offset 0, flags [none], proto UDP (17), length 61)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 33
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 33
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Simple Password (1), length: 9
+	  Auth Key ID: 2, Password: secret
+IP (tos 0x0, ttl 10, id 5, offset 0, flags [none], proto UDP (17), length 61)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 33
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 33
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Simple Password (1), length: 9
+	  Auth Key ID: 2, Password: secret
+IP (tos 0x0, ttl 10, id 6, offset 0, flags [none], proto UDP (17), length 61)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 33
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 33
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Simple Password (1), length: 9
+	  Auth Key ID: 2, Password: secret
+IP (tos 0x0, ttl 10, id 7, offset 0, flags [none], proto UDP (17), length 61)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 33
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 33
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Simple Password (1), length: 9
+	  Auth Key ID: 2, Password: secret
+IP (tos 0x0, ttl 10, id 8, offset 0, flags [none], proto UDP (17), length 61)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 33
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 33
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Simple Password (1), length: 9
+	  Auth Key ID: 2, Password: secret
+IP (tos 0x0, ttl 10, id 9, offset 0, flags [none], proto UDP (17), length 61)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 33
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 33
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Simple Password (1), length: 9
+	  Auth Key ID: 2, Password: secret
+IP (tos 0x0, ttl 10, id 10, offset 0, flags [none], proto UDP (17), length 61)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 33
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 33
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Simple Password (1), length: 9
+	  Auth Key ID: 2, Password: secret
+IP (tos 0x0, ttl 10, id 11, offset 0, flags [none], proto UDP (17), length 61)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 33
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 33
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Simple Password (1), length: 9
+	  Auth Key ID: 2, Password: secret
+IP (tos 0x0, ttl 10, id 12, offset 0, flags [none], proto UDP (17), length 61)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 33
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 33
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Simple Password (1), length: 9
+	  Auth Key ID: 2, Password: secret
+IP (tos 0x0, ttl 10, id 13, offset 0, flags [none], proto UDP (17), length 61)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 33
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 33
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Simple Password (1), length: 9
+	  Auth Key ID: 2, Password: secret
+IP (tos 0x0, ttl 10, id 14, offset 0, flags [none], proto UDP (17), length 61)
+    192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, length: 33
+	Control, State Down, Flags: [Authentication Present], Diagnostic: No Diagnostic (0x00)
+	Detection Timer Multiplier: 5 (5000 ms Detection time), BFD Length: 33
+	My Discriminator: 0x00000001, Your Discriminator: 0x00000000
+	  Desired min Tx Interval:    1000 ms
+	  Required min Rx Interval:   1000 ms
+	  Required min Echo Interval:    0 ms
+	Authentication: Simple Password (1), length: 9
+	  Auth Key ID: 2, Password: secret
diff --git a/tests/bfd-raw-auth-simple.out b/tests/bfd-raw-auth-simple.out
new file mode 100644
index 0000000..40b4f37
--- /dev/null
+++ b/tests/bfd-raw-auth-simple.out
@@ -0,0 +1,15 @@
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 33
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 33
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 33
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 33
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 33
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 33
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 33
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 33
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 33
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 33
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 33
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 33
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 33
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 33
+IP 192.85.1.2.1024 > 192.0.0.1.3784: BFDv1, Control, State Down, Flags: [Authentication Present], length: 33
diff --git a/tests/bfd-raw-auth-simple.pcap b/tests/bfd-raw-auth-simple.pcap
new file mode 100644
index 0000000..48cf3ac
--- /dev/null
+++ b/tests/bfd-raw-auth-simple.pcap
Binary files differ
diff --git a/tests/bgp-aigp.out b/tests/bgp-aigp.out
new file mode 100644
index 0000000..3fd6678
--- /dev/null
+++ b/tests/bgp-aigp.out
@@ -0,0 +1,20 @@
+IP (tos 0xc0, ttl 64, id 35063, offset 0, flags [none], proto TCP (6), length 182)
+    172.16.20.5.59631 > 172.16.20.3.179: Flags [P.], cksum 0xe112 (correct), seq 3923783171:3923783301, ack 3341773693, win 16384, options [nop,nop,TS val 32734022 ecr 32695671], length 130: BGP
+	Update Message (2), length: 100
+	  Origin (1), length: 1, Flags [T]: Incomplete
+	  AS Path (2), length: 0, Flags [T]: empty
+	  Multi Exit Discriminator (4), length: 4, Flags [O]: 0
+	  Local Preference (5), length: 4, Flags [T]: 100
+	  Community (8), length: 4, Flags [OT]: 65000:11201
+	  Originator ID (9), length: 4, Flags [O]: 172.16.21.4
+	  Cluster List (10), length: 4, Flags [O]: 172.16.20.5
+	  Accumulated IGP Metric (26), length: 11, Flags [O]: 
+	    AIGP TLV (1), length 11, metric 2000
+	  Multi-Protocol Reach NLRI (14), length: 17, Flags [OE]: 
+	    AFI: IPv4 (1), SAFI: labeled Unicast (4)
+	    nexthop: 172.16.20.5, nh-length: 4, no SNPA
+	      172.16.21.4/32, label:300096 (bottom)
+	Update Message (2), length: 30
+	  Multi-Protocol Unreach NLRI (15), length: 3, Flags [OE]: 
+	    AFI: IPv4 (1), SAFI: labeled Unicast (4)
+	      End-of-Rib Marker (empty NLRI)
diff --git a/tests/bgp-aigp.pcap b/tests/bgp-aigp.pcap
new file mode 100644
index 0000000..1e55e19
--- /dev/null
+++ b/tests/bgp-aigp.pcap
Binary files differ
diff --git a/tests/bgp-large-community.out b/tests/bgp-large-community.out
new file mode 100644
index 0000000..39dcd40
--- /dev/null
+++ b/tests/bgp-large-community.out
@@ -0,0 +1,42 @@
+IP (tos 0x0, ttl 64, id 14630, offset 0, flags [DF], proto TCP (6), length 427)
+    192.0.2.2.46605 > 192.0.2.3.179: Flags [P.], cksum 0x232f (correct), seq 1293104091:1293104466, ack 4093754554, win 457, options [nop,nop,TS val 68367 ecr 68367], length 375: BGP
+	Update Message (2), length: 75
+	  Origin (1), length: 1, Flags [T]: IGP
+	  AS Path (2), length: 6, Flags [T]: 65536 
+	  Next Hop (3), length: 4, Flags [T]: 192.0.2.2
+	  Large Community (32), length: 24, Flags [OT]: 
+	    65535:1:1, 4294967295:4294967295:4294967295
+	  Updated routes:
+	    203.0.113.16/32
+	Update Message (2), length: 75
+	  Origin (1), length: 1, Flags [T]: IGP
+	  AS Path (2), length: 6, Flags [T]: 65536 
+	  Next Hop (3), length: 4, Flags [T]: 192.0.2.2
+	  Large Community (32), length: 24, Flags [OT]: 
+	    65536:1:1, 65536:1:2
+	  Updated routes:
+	    203.0.113.12/32
+	Update Message (2), length: 63
+	  Origin (1), length: 1, Flags [T]: IGP
+	  AS Path (2), length: 6, Flags [T]: 65536 
+	  Next Hop (3), length: 4, Flags [T]: 192.0.2.2
+	  Large Community (32), length: 12, Flags [OT]: 
+	    65536:1:1
+	  Updated routes:
+	    203.0.113.11/32
+	Update Message (2), length: 75
+	  Origin (1), length: 1, Flags [T]: IGP
+	  AS Path (2), length: 6, Flags [T]: 65536 
+	  Next Hop (3), length: 4, Flags [T]: 192.0.2.2
+	  Large Community (32), length: 24, Flags [OT]: 
+	    65536:0:1, 65536:1:0
+	  Updated routes:
+	    203.0.113.15/32
+	Update Message (2), length: 87
+	  Origin (1), length: 1, Flags [T]: IGP
+	  AS Path (2), length: 6, Flags [T]: 65536 
+	  Next Hop (3), length: 4, Flags [T]: 192.0.2.2
+	  Large Community (32), length: 36, Flags [OT]: 
+	    65536:1:1, 65536:1:2, 65536:1:3
+	  Updated routes:
+	    203.0.113.13/32
diff --git a/tests/bgp-large-community.pcap b/tests/bgp-large-community.pcap
new file mode 100644
index 0000000..7b5118d
--- /dev/null
+++ b/tests/bgp-large-community.pcap
Binary files differ
diff --git a/tests/calm-fast-mac-lookup-heapoverflow.out b/tests/calm-fast-mac-lookup-heapoverflow.out
new file mode 100644
index 0000000..a6e6f41
--- /dev/null
+++ b/tests/calm-fast-mac-lookup-heapoverflow.out
@@ -0,0 +1,5 @@
+Q.922, invalid address
+CALM FAST; SrcNwref:48; DstNwref:48; 
+	0x0000:  3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
+	0x0010:  3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
+	0x0020:  3030 3030 3030 3030 3030                 0000000000
diff --git a/tests/calm-fast-mac-lookup-heapoverflow.pcap b/tests/calm-fast-mac-lookup-heapoverflow.pcap
new file mode 100644
index 0000000..64ca581
--- /dev/null
+++ b/tests/calm-fast-mac-lookup-heapoverflow.pcap
Binary files differ
diff --git a/tests/crypto.sh b/tests/crypto.sh
index bd41921..f20e239 100755
--- a/tests/crypto.sh
+++ b/tests/crypto.sh
@@ -10,7 +10,7 @@
 	# Reading the secret(s) from a file does not work with Capsicum.
 	if grep '^#define HAVE_CAPSICUM 1$' ../config.h >/dev/null
 	then
-		FORMAT='    %-30s: TEST SKIPPED (compiled w/Capsicum)\n'
+		FORMAT='    %-35s: TEST SKIPPED (compiled w/Capsicum)\n'
 		printf "$FORMAT" esp4
 		printf "$FORMAT" esp5
 		printf "$FORMAT" espudp1
@@ -24,7 +24,7 @@
 		./TESTonce isakmp4 isakmp4500.pcap isakmp4.out '-t -E "file esp-secrets.txt"'
 	fi
 else
-	FORMAT='    %-30s: TEST SKIPPED (compiled w/o OpenSSL)\n'
+	FORMAT='    %-35s: TEST SKIPPED (compiled w/o OpenSSL)\n'
 	printf "$FORMAT" esp1
 	printf "$FORMAT" esp2
 	printf "$FORMAT" esp3
diff --git a/tests/cve-2014-8767-OLSR.out b/tests/cve-2014-8767-OLSR.out
new file mode 100644
index 0000000..edfb067
--- /dev/null
+++ b/tests/cve-2014-8767-OLSR.out
@@ -0,0 +1,4 @@
+IP (tos 0x15,ECT(1), ttl 77, id 62335, offset 0, flags [DF], proto UDP (17), length 61, bad cksum 30c6 (->22af)!)
+    10.1.1.104.698 > 10.2.2.2.514: OLSRv4, seq 0x0202, length 33
+	TC Message (0x02), originator 2.2.2.2, ttl 2, hop 2
+	  vtime 0.070s, msg-seq 0x0202, length 2 (invalid)
diff --git a/tests/cve-2014-8767-OLSR.pcap b/tests/cve-2014-8767-OLSR.pcap
new file mode 100644
index 0000000..67036ed
--- /dev/null
+++ b/tests/cve-2014-8767-OLSR.pcap
Binary files differ
diff --git a/tests/cve-2014-8768-Geonet.out b/tests/cve-2014-8768-Geonet.out
new file mode 100644
index 0000000..4b7182d
--- /dev/null
+++ b/tests/cve-2014-8768-Geonet.out
@@ -0,0 +1 @@
+GeoNet src:07:07:07:07:07:07; v:12 NH:6-Unknown HT:5-1-TopoScopeBcast-MH HopLim:7 Payload:1799 GN_ADDR:ef:06:07:35:97:00:24:8c lat:4521984 lon:1039368000 Malformed (small) 
diff --git a/tests/cve-2014-8768-Geonet.pcap b/tests/cve-2014-8768-Geonet.pcap
new file mode 100644
index 0000000..345ed24
--- /dev/null
+++ b/tests/cve-2014-8768-Geonet.pcap
Binary files differ
diff --git a/tests/cve-2014-8769-AODV.out b/tests/cve-2014-8769-AODV.out
new file mode 100644
index 0000000..0bb70b4
--- /dev/null
+++ b/tests/cve-2014-8769-AODV.out
@@ -0,0 +1,2 @@
+IP truncated-ip - 58880 bytes missing! (tos 0x0, ttl 64, id 62335, offset 0, flags [DF], proto UDP (17), length 58941, bad cksum 30c6 (->49c3)!)
+    10.1.1.104.654 > 10.2.2.2.3328:  aodv rerr  [items 0] [19192]:
diff --git a/tests/cve-2014-8769-AODV.pcap b/tests/cve-2014-8769-AODV.pcap
new file mode 100644
index 0000000..3cd1569
--- /dev/null
+++ b/tests/cve-2014-8769-AODV.pcap
Binary files differ
diff --git a/tests/cve2015-0261-crash.pcap b/tests/cve2015-0261-crash.pcap
index c876c1f..01cd381 100644
--- a/tests/cve2015-0261-crash.pcap
+++ b/tests/cve2015-0261-crash.pcap
Binary files differ
diff --git a/tests/cve2015-0261-ipv6.out b/tests/cve2015-0261-ipv6.out
index 4674ada..3658c19 100644
--- a/tests/cve2015-0261-ipv6.out
+++ b/tests/cve2015-0261-ipv6.out
@@ -1,3 +1,3 @@
-IP6 truncated-ip6 - 26325 bytes missing!(class 0x76, flowlabel 0x76767, hlim 103, next-header Mobility (135) payload length: 26470) 6767:6767:6767:6767:6767:6767:6767:6767 > 6767:6767:6767:6767:6767:6767:6767:6705: mobility: BU seq#=26471 HL lifetime=105884(type-0x67: len=103)[trunc] 
+IP6 truncated-ip6 - 26325 bytes missing!(class 0x76, flowlabel 0x76767, hlim 103, next-header Mobility (135) payload length: 26470) 6767:6767:6767:6767:6767:6767:6767:6767 > 6767:6767:6767:6767:6767:6767:6767:6705: mobility: BU seq#=26471 HL lifetime=105884(type-0x67: len=103)[|MOBILITY]
 IP6 truncated-ip6 - 26325 bytes missing!(class 0x76, flowlabel 0x76767, hlim 103, next-header Mobility (135) payload length: 26470) 6767:6767:6767:6767:6767:6767:6767:6767 > 6767:6767:4f67:6767:6767:6767:6767:6767: (header length 8 is too small for type 6)[|MOBILITY]
 EXIT CODE 00000100
diff --git a/tests/dhcp-mud.out b/tests/dhcp-mud.out
new file mode 100644
index 0000000..f492746
--- /dev/null
+++ b/tests/dhcp-mud.out
@@ -0,0 +1,36 @@
+IP (tos 0x0, ttl 255, id 9459, offset 0, flags [none], proto UDP (17), length 422)
+    62.12.173.121.67 > 62.12.173.114.67: [udp sum ok] BOOTP/DHCP, Request from b8:27:eb:b8:53:c8, length 394, hops 1, xid 0x68c4847, Flags [none] (0x0000)
+	  Client-IP 62.12.173.123
+	  Gateway-IP 62.12.173.121
+	  Client-Ethernet-Address b8:27:eb:b8:53:c8
+	  Vendor-rfc1048 Extensions
+	    Magic Cookie 0x63825363
+	    DHCP-Message Option 53, length 1: Request
+	    Client-ID Option 61, length 7: ether b8:27:eb:b8:53:c8
+	    MSZ Option 57, length 2: 1472
+	    MUD-URL Option 161, length 54: "https://mudctl.example.com/.well-known/mud/v1/rasbp101"
+	    Vendor-Class Option 60, length 45: "dhcpcd-6.11.5:Linux-4.1.18-v7+:armv7l:BCM2709"
+	    Hostname Option 12, length 11: "raspberrypi"
+	    T145 Option 145, length 1: 1
+	    Parameter-Request Option 55, length 16: 
+	      Subnet-Mask, Classless-Static-Route, Static-Route, Default-Gateway
+	      Domain-Name-Server, Hostname, Domain-Name, BR
+	      NTP, Lease-Time, Server-ID, RN
+	      RB, POSIX-TZ, TZ-Name, Option 119
+IP (tos 0x0, ttl 64, id 10305, offset 0, flags [DF], proto UDP (17), length 338)
+    62.12.173.114.67 > 62.12.173.121.67: [udp sum ok] BOOTP/DHCP, Reply, length 310, hops 1, xid 0x68c4847, Flags [none] (0x0000)
+	  Client-IP 62.12.173.123
+	  Your-IP 62.12.173.123
+	  Server-IP 62.12.173.114
+	  Gateway-IP 62.12.173.121
+	  Client-Ethernet-Address b8:27:eb:b8:53:c8
+	  Vendor-rfc1048 Extensions
+	    Magic Cookie 0x63825363
+	    DHCP-Message Option 53, length 1: ACK
+	    Server-ID Option 54, length 4: 62.12.173.114
+	    Lease-Time Option 51, length 4: 600
+	    Subnet-Mask Option 1, length 4: 255.255.255.248
+	    Default-Gateway Option 3, length 4: 62.12.173.121
+	    Domain-Name-Server Option 6, length 4: 62.12.173.114
+	    Domain-Name Option 15, length 19: "ofcourseimright.com"
+	    TZ-Name Option 101, length 13: "Europe/Berlin"
diff --git a/tests/dhcp-mud.pcap b/tests/dhcp-mud.pcap
new file mode 100644
index 0000000..717f019
--- /dev/null
+++ b/tests/dhcp-mud.pcap
Binary files differ
diff --git a/tests/dhcpv6-mud.out b/tests/dhcpv6-mud.out
new file mode 100644
index 0000000..c447dad
--- /dev/null
+++ b/tests/dhcpv6-mud.out
@@ -0,0 +1,5 @@
+IP6 (class 0xe0, hlim 255, next-header UDP (17) payload length: 252) 2001:8a8:1006:4:223:ebff:fe10:2c29.547 > 2001:8a8:1006:4:223:54ff:fec2:5702.547: [udp sum ok] dhcp6 relay-fwd (linkaddr=2001:8a8:1006:3:225:84ff:fedb:2380 peeraddr=fe80::ba27:ebff:feb8:53c8 (relay-message (dhcp6 solicit (xid=78244b (client-ID hwaddr/time type 1 time 509769483 b827ebb853c8) (elapsed-time 0) (vendor-class) (rapid-commit) (IA_NA IAID:3954725832 T1:0 T2:0) (Client-FQDN) (MUD-URL=https://mudctl.example.com/.well-known/mud/v1/rasbp101) (reconfigure-accept) (option-request DNS-server DNS-search-list SNTP-servers Client-FQDN opt_82 opt_83))) (interface-ID 00000008...))
+IP6 (class 0xe0, hlim 255, next-header UDP (17) payload length: 252) 2001:8a8:1006:4:223:ebff:fe10:2c29.547 > 2001:8a8:1006:4:223:54ff:fec2:5702.547: [udp sum ok] dhcp6 relay-fwd (linkaddr=2001:8a8:1006:3:225:84ff:fedb:2380 peeraddr=fe80::ba27:ebff:feb8:53c8 (relay-message (dhcp6 solicit (xid=78244b (client-ID hwaddr/time type 1 time 509769483 b827ebb853c8) (elapsed-time 96) (vendor-class) (rapid-commit) (IA_NA IAID:3954725832 T1:0 T2:0) (Client-FQDN) (MUD-URL=https://mudctl.example.com/.well-known/mud/v1/rasbp101) (reconfigure-accept) (option-request DNS-server DNS-search-list SNTP-servers Client-FQDN opt_82 opt_83))) (interface-ID 00000008...))
+IP6 (class 0xe0, hlim 255, next-header UDP (17) payload length: 252) 2001:8a8:1006:4:223:ebff:fe10:2c29.547 > 2001:8a8:1006:4:223:54ff:fec2:5702.547: [udp sum ok] dhcp6 relay-fwd (linkaddr=2001:8a8:1006:3:225:84ff:fedb:2380 peeraddr=fe80::ba27:ebff:feb8:53c8 (relay-message (dhcp6 solicit (xid=78244b (client-ID hwaddr/time type 1 time 509769483 b827ebb853c8) (elapsed-time 287) (vendor-class) (rapid-commit) (IA_NA IAID:3954725832 T1:0 T2:0) (Client-FQDN) (MUD-URL=https://mudctl.example.com/.well-known/mud/v1/rasbp101) (reconfigure-accept) (option-request DNS-server DNS-search-list SNTP-servers Client-FQDN opt_82 opt_83))) (interface-ID 00000008...))
+IP6 (class 0xe0, hlim 255, next-header UDP (17) payload length: 252) 2001:8a8:1006:4:223:ebff:fe10:2c29.547 > 2001:8a8:1006:4:223:54ff:fec2:5702.547: [udp sum ok] dhcp6 relay-fwd (linkaddr=2001:8a8:1006:3:225:84ff:fedb:2380 peeraddr=fe80::ba27:ebff:feb8:53c8 (relay-message (dhcp6 solicit (xid=78244b (client-ID hwaddr/time type 1 time 509769483 b827ebb853c8) (elapsed-time 677) (vendor-class) (rapid-commit) (IA_NA IAID:3954725832 T1:0 T2:0) (Client-FQDN) (MUD-URL=https://mudctl.example.com/.well-known/mud/v1/rasbp101) (reconfigure-accept) (option-request DNS-server DNS-search-list SNTP-servers Client-FQDN opt_82 opt_83))) (interface-ID 00000008...))
+IP6 (class 0xe0, hlim 255, next-header UDP (17) payload length: 252) 2001:8a8:1006:4:223:ebff:fe10:2c29.547 > 2001:8a8:1006:4:223:54ff:fec2:5702.547: [udp sum ok] dhcp6 relay-fwd (linkaddr=2001:8a8:1006:3:225:84ff:fedb:2380 peeraddr=fe80::ba27:ebff:feb8:53c8 (relay-message (dhcp6 solicit (xid=78244b (client-ID hwaddr/time type 1 time 509769483 b827ebb853c8) (elapsed-time 1421) (vendor-class) (rapid-commit) (IA_NA IAID:3954725832 T1:0 T2:0) (Client-FQDN) (MUD-URL=https://mudctl.example.com/.well-known/mud/v1/rasbp101) (reconfigure-accept) (option-request DNS-server DNS-search-list SNTP-servers Client-FQDN opt_82 opt_83))) (interface-ID 00000008...))
diff --git a/tests/dhcpv6-mud.pcap b/tests/dhcpv6-mud.pcap
new file mode 100644
index 0000000..baa0154
--- /dev/null
+++ b/tests/dhcpv6-mud.pcap
Binary files differ
diff --git a/tests/dnssec-vv.out b/tests/dnssec-vv.out
new file mode 100644
index 0000000..a75135b
--- /dev/null
+++ b/tests/dnssec-vv.out
@@ -0,0 +1,12 @@
+IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 74)
+    127.0.0.1.43144 > 127.0.0.1.53: [bad udp cksum 0xfe49 -> 0xb5ef!] 20972+ [1au] SSHFP? monadic.cynic.net. ar: . OPT UDPsize=4096 DO (46)
+IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 3040)
+    127.0.0.1.53 > 127.0.0.1.43144: [bad udp cksum 0x09e0 -> 0x4239!] 20972$ q: SSHFP? monadic.cynic.net. 3/6/13 monadic.cynic.net. SSHFP, monadic.cynic.net. RRSIG, monadic.cynic.net. RRSIG ns: cynic.net. NS ns1.cynic.net., cynic.net. NS ns4.cynic.net., cynic.net. NS ns2.cynic.net., cynic.net. NS ns3.cynic.net., cynic.net. RRSIG, cynic.net. RRSIG ar: ns1.cynic.net. A 125.100.126.205, ns2.cynic.net. A 199.175.137.213, ns3.cynic.net. A 203.141.153.22, ns4.cynic.net. A 122.103.238.186, ns1.cynic.net. RRSIG, ns1.cynic.net. RRSIG, ns2.cynic.net. RRSIG, ns2.cynic.net. RRSIG, ns3.cynic.net. RRSIG, ns3.cynic.net. RRSIG, ns4.cynic.net. RRSIG, ns4.cynic.net. RRSIG, . OPT UDPsize=4096 DO (3012)
+IP (tos 0x0, ttl 64, id 22838, offset 0, flags [DF], proto UDP (17), length 74)
+    127.0.0.1.32972 > 127.0.0.1.53: [bad udp cksum 0xfe49 -> 0x28d8!] 48576+ [1au] A? monadic.cynic.net. ar: . OPT UDPsize=1024 (46)
+IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 226)
+    127.0.0.1.53 > 127.0.0.1.32972: [bad udp cksum 0xfee1 -> 0x60dd!] 48576 q: A? monadic.cynic.net. 1/4/5 monadic.cynic.net. A 125.100.126.202 ns: cynic.net. NS ns4.cynic.net., cynic.net. NS ns2.cynic.net., cynic.net. NS ns3.cynic.net., cynic.net. NS ns1.cynic.net. ar: ns1.cynic.net. A 125.100.126.205, ns2.cynic.net. A 199.175.137.213, ns3.cynic.net. A 203.141.153.22, ns4.cynic.net. A 122.103.238.186, . OPT UDPsize=4096 (198)
+IP (tos 0x0, ttl 64, id 22904, offset 0, flags [DF], proto UDP (17), length 74)
+    127.0.0.1.36069 > 127.0.0.1.53: [bad udp cksum 0xfe49 -> 0xf266!] 49432+ [1au] SSHFP? monadic.cynic.net. ar: . OPT UDPsize=0 (46)
+IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 244)
+    127.0.0.1.53 > 127.0.0.1.36069: [bad udp cksum 0xfef3 -> 0x1227!] 49432 q: SSHFP? monadic.cynic.net. 1/4/5 monadic.cynic.net. SSHFP ns: cynic.net. NS ns4.cynic.net., cynic.net. NS ns1.cynic.net., cynic.net. NS ns3.cynic.net., cynic.net. NS ns2.cynic.net. ar: ns1.cynic.net. A 125.100.126.205, ns2.cynic.net. A 199.175.137.213, ns3.cynic.net. A 203.141.153.22, ns4.cynic.net. A 122.103.238.186, . OPT UDPsize=4096 (216)
diff --git a/tests/dnssec.pcap b/tests/dnssec.pcap
new file mode 100644
index 0000000..b191480
--- /dev/null
+++ b/tests/dnssec.pcap
Binary files differ
diff --git a/tests/dtp-v.out b/tests/dtp-v.out
index 1d73418..4eb566b 100644
--- a/tests/dtp-v.out
+++ b/tests/dtp-v.out
@@ -3,28 +3,53 @@
 	Status TLV (0x0002) TLV, length 5, 0x4
 	DTP type TLV (0x0003) TLV, length 5, 0x40
 	Neighbor TLV (0x0004) TLV, length 10, 00:19:06:ea:b8:85
-00:19:06:ea:b8:85 > 01:00:0c:00:00:00 SNAP Unnumbered, ui, Flags [Command], length 76
+00:19:06:ea:b8:85 > 01:00:0c:00:00:00 SNAP, oui Cisco (0x00000c), pid Unknown (0x0003), length 68: 
+	0x0000:  aaaa 0300 000c 0003 0000 0000 0100 0ccc  ................
+	0x0010:  cccc 0019 06ea b885 0025 aaaa 0300 000c  .........%......
+	0x0020:  2004 0100 0100 084c 6162 0000 0200 0504  .......Lab......
+	0x0030:  0003 0005 4000 0400 0a00 1906 eab8 8500  ....@...........
+	0x0040:  0000 0000 0000 0000 f7a7 fe42            ...........B
 DTPv1, length 38
 	Domain TLV (0x0001) TLV, length 8, Lab
 	Status TLV (0x0002) TLV, length 5, 0x4
 	DTP type TLV (0x0003) TLV, length 5, 0x40
 	Neighbor TLV (0x0004) TLV, length 10, 00:19:06:ea:b8:85
-00:19:06:ea:b8:85 > 01:00:0c:00:00:00 SNAP Unnumbered, ui, Flags [Command], length 76
+00:19:06:ea:b8:85 > 01:00:0c:00:00:00 SNAP, oui Cisco (0x00000c), pid Unknown (0x0003), length 68: 
+	0x0000:  aaaa 0300 000c 0003 0000 0000 0100 0ccc  ................
+	0x0010:  cccc 0019 06ea b885 0025 aaaa 0300 000c  .........%......
+	0x0020:  2004 0100 0100 084c 6162 0000 0200 0504  .......Lab......
+	0x0030:  0003 0005 4000 0400 0a00 1906 eab8 8500  ....@...........
+	0x0040:  0000 0000 0000 0000 f7a7 fe42            ...........B
 DTPv1, length 38
 	Domain TLV (0x0001) TLV, length 8, Lab
 	Status TLV (0x0002) TLV, length 5, 0x4
 	DTP type TLV (0x0003) TLV, length 5, 0x40
 	Neighbor TLV (0x0004) TLV, length 10, 00:19:06:ea:b8:85
-00:19:06:ea:b8:85 > 01:00:0c:00:00:00 SNAP Unnumbered, ui, Flags [Command], length 76
+00:19:06:ea:b8:85 > 01:00:0c:00:00:00 SNAP, oui Cisco (0x00000c), pid Unknown (0x0003), length 68: 
+	0x0000:  aaaa 0300 000c 0003 0000 0000 0100 0ccc  ................
+	0x0010:  cccc 0019 06ea b885 0025 aaaa 0300 000c  .........%......
+	0x0020:  2004 0100 0100 084c 6162 0000 0200 0504  .......Lab......
+	0x0030:  0003 0005 4000 0400 0a00 1906 eab8 8500  ....@...........
+	0x0040:  0000 0000 0000 0000 f7a7 fe42            ...........B
 DTPv1, length 38
 	Domain TLV (0x0001) TLV, length 8, Lab
 	Status TLV (0x0002) TLV, length 5, 0x4
 	DTP type TLV (0x0003) TLV, length 5, 0x40
 	Neighbor TLV (0x0004) TLV, length 10, 00:19:06:ea:b8:85
-00:19:06:ea:b8:85 > 01:00:0c:00:00:00 SNAP Unnumbered, ui, Flags [Command], length 76
+00:19:06:ea:b8:85 > 01:00:0c:00:00:00 SNAP, oui Cisco (0x00000c), pid Unknown (0x0003), length 68: 
+	0x0000:  aaaa 0300 000c 0003 0000 0000 0100 0ccc  ................
+	0x0010:  cccc 0019 06ea b885 0025 aaaa 0300 000c  .........%......
+	0x0020:  2004 0100 0100 084c 6162 0000 0200 0504  .......Lab......
+	0x0030:  0003 0005 4000 0400 0a00 1906 eab8 8514  ....@...........
+	0x0040:  0002 000f 0000 0000 7232 1da6            ........r2..
 DTPv1, length 38
 	Domain TLV (0x0001) TLV, length 8, Lab
 	Status TLV (0x0002) TLV, length 5, 0x4
 	DTP type TLV (0x0003) TLV, length 5, 0x40
 	Neighbor TLV (0x0004) TLV, length 10, 00:19:06:ea:b8:85
-00:19:06:ea:b8:85 > 01:00:0c:00:00:00 SNAP Unnumbered, ui, Flags [Command], length 76
+00:19:06:ea:b8:85 > 01:00:0c:00:00:00 SNAP, oui Cisco (0x00000c), pid Unknown (0x0003), length 68: 
+	0x0000:  aaaa 0300 000c 0003 0000 0000 0100 0ccc  ................
+	0x0010:  cccc 0019 06ea b885 0025 aaaa 0300 000c  .........%......
+	0x0020:  2004 0100 0100 084c 6162 0000 0200 0504  .......Lab......
+	0x0030:  0003 0005 4000 0400 0a00 1906 eab8 8514  ....@...........
+	0x0040:  0002 000f 0000 0000 7232 1da6            ........r2..
diff --git a/tests/evb.out b/tests/evb.out
index db8888c..d5d71e8 100644
--- a/tests/evb.out
+++ b/tests/evb.out
@@ -1,23 +1,23 @@
 STP 802.1s, Rapid STP, CIST Flags [Learn, Forward], length 102
-	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0 
-	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003, 
+	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0
+	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003,
 	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
-	v3len 64, MCID Name Default, rev 0, 
-		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0, 
+	v3len 64, MCID Name Default, rev 0,
+		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0,
 	CIST bridge-id 8000.08:00:27:0d:f1:3c, CIST remaining-hops 20
 STP 802.1s, Rapid STP, CIST Flags [Learn, Forward], length 102
-	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0 
-	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003, 
+	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0
+	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003,
 	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
-	v3len 64, MCID Name Default, rev 0, 
-		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0, 
+	v3len 64, MCID Name Default, rev 0,
+		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0,
 	CIST bridge-id 8000.08:00:27:0d:f1:3c, CIST remaining-hops 20
 STP 802.1s, Rapid STP, CIST Flags [Learn, Forward], length 102
-	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0 
-	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003, 
+	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0
+	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003,
 	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
-	v3len 64, MCID Name Default, rev 0, 
-		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0, 
+	v3len 64, MCID Name Default, rev 0,
+		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0,
 	CIST bridge-id 8000.08:00:27:0d:f1:3c, CIST remaining-hops 20
 LLDP, length 103
 	Chassis ID TLV (1), length 7
@@ -61,86 +61,86 @@
 	  0x0000:  0080 c20e 0000 00a7 0010 01
 	End TLV (0), length 0
 STP 802.1s, Rapid STP, CIST Flags [Learn, Forward], length 102
-	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0 
-	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003, 
+	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0
+	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003,
 	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
-	v3len 64, MCID Name Default, rev 0, 
-		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0, 
+	v3len 64, MCID Name Default, rev 0,
+		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0,
 	CIST bridge-id 8000.08:00:27:0d:f1:3c, CIST remaining-hops 20
 STP 802.1s, Rapid STP, CIST Flags [Learn, Forward], length 102
-	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0 
-	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003, 
+	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0
+	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003,
 	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
-	v3len 64, MCID Name Default, rev 0, 
-		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0, 
+	v3len 64, MCID Name Default, rev 0,
+		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0,
 	CIST bridge-id 8000.08:00:27:0d:f1:3c, CIST remaining-hops 20
 STP 802.1s, Rapid STP, CIST Flags [Learn, Forward], length 102
-	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0 
-	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003, 
+	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0
+	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003,
 	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
-	v3len 64, MCID Name Default, rev 0, 
-		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0, 
+	v3len 64, MCID Name Default, rev 0,
+		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0,
 	CIST bridge-id 8000.08:00:27:0d:f1:3c, CIST remaining-hops 20
 STP 802.1s, Rapid STP, CIST Flags [Learn, Forward], length 102
-	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0 
-	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003, 
+	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0
+	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003,
 	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
-	v3len 64, MCID Name Default, rev 0, 
-		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0, 
+	v3len 64, MCID Name Default, rev 0,
+		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0,
 	CIST bridge-id 8000.08:00:27:0d:f1:3c, CIST remaining-hops 20
 STP 802.1s, Rapid STP, CIST Flags [Learn, Forward], length 102
-	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0 
-	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003, 
+	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0
+	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003,
 	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
-	v3len 64, MCID Name Default, rev 0, 
-		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0, 
+	v3len 64, MCID Name Default, rev 0,
+		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0,
 	CIST bridge-id 8000.08:00:27:0d:f1:3c, CIST remaining-hops 20
 STP 802.1s, Rapid STP, CIST Flags [Learn, Forward], length 102
-	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0 
-	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003, 
+	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0
+	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003,
 	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
-	v3len 64, MCID Name Default, rev 0, 
-		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0, 
+	v3len 64, MCID Name Default, rev 0,
+		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0,
 	CIST bridge-id 8000.08:00:27:0d:f1:3c, CIST remaining-hops 20
 STP 802.1s, Rapid STP, CIST Flags [Learn, Forward], length 102
-	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0 
-	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003, 
+	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0
+	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003,
 	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
-	v3len 64, MCID Name Default, rev 0, 
-		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0, 
+	v3len 64, MCID Name Default, rev 0,
+		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0,
 	CIST bridge-id 8000.08:00:27:0d:f1:3c, CIST remaining-hops 20
 STP 802.1s, Rapid STP, CIST Flags [Learn, Forward], length 102
-	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0 
-	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003, 
+	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0
+	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003,
 	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
-	v3len 64, MCID Name Default, rev 0, 
-		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0, 
+	v3len 64, MCID Name Default, rev 0,
+		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0,
 	CIST bridge-id 8000.08:00:27:0d:f1:3c, CIST remaining-hops 20
 STP 802.1s, Rapid STP, CIST Flags [Learn, Forward], length 102
-	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0 
-	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003, 
+	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0
+	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003,
 	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
-	v3len 64, MCID Name Default, rev 0, 
-		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0, 
+	v3len 64, MCID Name Default, rev 0,
+		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0,
 	CIST bridge-id 8000.08:00:27:0d:f1:3c, CIST remaining-hops 20
 STP 802.1s, Rapid STP, CIST Flags [Learn, Forward], length 102
-	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0 
-	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003, 
+	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0
+	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003,
 	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
-	v3len 64, MCID Name Default, rev 0, 
-		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0, 
+	v3len 64, MCID Name Default, rev 0,
+		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0,
 	CIST bridge-id 8000.08:00:27:0d:f1:3c, CIST remaining-hops 20
 STP 802.1s, Rapid STP, CIST Flags [Learn, Forward], length 102
-	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0 
-	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003, 
+	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0
+	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003,
 	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
-	v3len 64, MCID Name Default, rev 0, 
-		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0, 
+	v3len 64, MCID Name Default, rev 0,
+		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0,
 	CIST bridge-id 8000.08:00:27:0d:f1:3c, CIST remaining-hops 20
 STP 802.1s, Rapid STP, CIST Flags [Learn, Forward], length 102
-	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0 
-	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003, 
+	port-role Designated, CIST root-id 8000.08:00:27:0d:f1:3c, CIST ext-pathcost 0
+	CIST regional-root-id 8000.08:00:27:0d:f1:3c, CIST port-id 8003,
 	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
-	v3len 64, MCID Name Default, rev 0, 
-		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0, 
+	v3len 64, MCID Name Default, rev 0,
+		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0,
 	CIST bridge-id 8000.08:00:27:0d:f1:3c, CIST remaining-hops 20
diff --git a/tests/frf15-heapoverflow.out b/tests/frf15-heapoverflow.out
new file mode 100644
index 0000000..a44d1fc
--- /dev/null
+++ b/tests/frf15-heapoverflow.out
@@ -0,0 +1 @@
+UI 30! [|frf.15]
diff --git a/tests/frf15-heapoverflow.pcap b/tests/frf15-heapoverflow.pcap
new file mode 100644
index 0000000..5898e7b
--- /dev/null
+++ b/tests/frf15-heapoverflow.pcap
Binary files differ
diff --git a/tests/geonet-mac-lookup-heapoverflow.out b/tests/geonet-mac-lookup-heapoverflow.out
new file mode 100644
index 0000000..7d49dd0
--- /dev/null
+++ b/tests/geonet-mac-lookup-heapoverflow.out
@@ -0,0 +1 @@
+GeoNet src:30:30:30:30:30:30; v:3 NH:0-Any HT:3-0-GeoAnycastCircle HopLim:48 Payload:12336 [|geonet]
diff --git a/tests/geonet-mac-lookup-heapoverflow.pcap b/tests/geonet-mac-lookup-heapoverflow.pcap
new file mode 100644
index 0000000..2a42bca
--- /dev/null
+++ b/tests/geonet-mac-lookup-heapoverflow.pcap
Binary files differ
diff --git a/tests/gre-heapoverflow-1.out b/tests/gre-heapoverflow-1.out
new file mode 100644
index 0000000..322c329
--- /dev/null
+++ b/tests/gre-heapoverflow-1.out
@@ -0,0 +1,8 @@
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
+	0x0010:  3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
+	0x0020:  3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
+	0x0030:  3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
+	0x0040:  3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
+	0x0050:  3030 3030                                0000
+IP0 
diff --git a/tests/gre-heapoverflow-1.pcap b/tests/gre-heapoverflow-1.pcap
new file mode 100644
index 0000000..f814815
--- /dev/null
+++ b/tests/gre-heapoverflow-1.pcap
Binary files differ
diff --git a/tests/gre-heapoverflow-2.out b/tests/gre-heapoverflow-2.out
new file mode 100644
index 0000000..f1ab2cc
--- /dev/null
+++ b/tests/gre-heapoverflow-2.out
@@ -0,0 +1,6 @@
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
+	0x0010:  3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
+	0x0020:  3030                                     00
+IP (tos 0x30, ttl 48, id 12336, offset 0, flags [none], proto GRE (47), length 12336, bad cksum 3030 (->697f)!)
+    48.48.48.48 > 48.48.48.48: GREv0, Flags [checksum present, routing present], sum 0x3030, off 0x3030, (rtaf=0x3030)[|gre]
diff --git a/tests/gre-heapoverflow-2.pcap b/tests/gre-heapoverflow-2.pcap
new file mode 100644
index 0000000..1722d8d
--- /dev/null
+++ b/tests/gre-heapoverflow-2.pcap
Binary files differ
diff --git a/tests/heap-overflow-1.out b/tests/heap-overflow-1.out
new file mode 100644
index 0000000..4d2862d
--- /dev/null
+++ b/tests/heap-overflow-1.out
@@ -0,0 +1 @@
+unknown ip 3
diff --git a/tests/heap-overflow-1.pcap b/tests/heap-overflow-1.pcap
new file mode 100644
index 0000000..f1519b8
--- /dev/null
+++ b/tests/heap-overflow-1.pcap
Binary files differ
diff --git a/tests/heap-overflow-2.out b/tests/heap-overflow-2.out
new file mode 100644
index 0000000..1e7e21b
--- /dev/null
+++ b/tests/heap-overflow-2.out
@@ -0,0 +1 @@
+IP3 
diff --git a/tests/heap-overflow-2.pcap b/tests/heap-overflow-2.pcap
new file mode 100644
index 0000000..838c5f5
--- /dev/null
+++ b/tests/heap-overflow-2.pcap
Binary files differ
diff --git a/tests/heapoverflow-EXTRACT_16BITS.out b/tests/heapoverflow-EXTRACT_16BITS.out
new file mode 100644
index 0000000..0ddc641
--- /dev/null
+++ b/tests/heapoverflow-EXTRACT_16BITS.out
@@ -0,0 +1 @@
+et1 AT  [|ddp]
diff --git a/tests/heapoverflow-EXTRACT_16BITS.pcap b/tests/heapoverflow-EXTRACT_16BITS.pcap
new file mode 100644
index 0000000..491c2d0
--- /dev/null
+++ b/tests/heapoverflow-EXTRACT_16BITS.pcap
Binary files differ
diff --git a/tests/heapoverflow-atalk_print.out b/tests/heapoverflow-atalk_print.out
new file mode 100644
index 0000000..0ddc641
--- /dev/null
+++ b/tests/heapoverflow-atalk_print.out
@@ -0,0 +1 @@
+et1 AT  [|ddp]
diff --git a/tests/heapoverflow-atalk_print.pcap b/tests/heapoverflow-atalk_print.pcap
new file mode 100644
index 0000000..83f04fd
--- /dev/null
+++ b/tests/heapoverflow-atalk_print.pcap
Binary files differ
diff --git a/tests/heapoverflow-in_checksum.out b/tests/heapoverflow-in_checksum.out
new file mode 100644
index 0000000..fffc692
--- /dev/null
+++ b/tests/heapoverflow-in_checksum.out
@@ -0,0 +1,3 @@
+IP (tos 0x30, ttl 48, id 12336, offset 0, flags [DF], proto PIM (103), length 12336, bad cksum 3030 (->2947)!)
+    48.48.48.48 > 48.48.48.48: PIMv2, length 12316
+	Hello, RFC2117-encoding, cksum 0x3030 (unverified)[|pim]
diff --git a/tests/heapoverflow-in_checksum.pcap b/tests/heapoverflow-in_checksum.pcap
new file mode 100644
index 0000000..82a5500
--- /dev/null
+++ b/tests/heapoverflow-in_checksum.pcap
Binary files differ
diff --git a/tests/heapoverflow-ip_print_demux.out b/tests/heapoverflow-ip_print_demux.out
new file mode 100644
index 0000000..54bd137
--- /dev/null
+++ b/tests/heapoverflow-ip_print_demux.out
@@ -0,0 +1,6 @@
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
+	0x0010:  3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
+	0x0020:  3030                                     00
+IP (tos 0x30, ttl 48, id 12336, offset 0, flags [none], proto AH (51), length 12336, bad cksum 3030 (->697b)!)
+    48.48.48.48 > 48.48.48.48: AH(spi=0x30303030,sumlen=192,seq=0x30303030[truncated]):
diff --git a/tests/heapoverflow-ip_print_demux.pcap b/tests/heapoverflow-ip_print_demux.pcap
new file mode 100644
index 0000000..8dec30b
--- /dev/null
+++ b/tests/heapoverflow-ip_print_demux.pcap
Binary files differ
diff --git a/tests/heapoverflow-ppp_hdlc_if_print.out b/tests/heapoverflow-ppp_hdlc_if_print.out
new file mode 100644
index 0000000..39cef42
--- /dev/null
+++ b/tests/heapoverflow-ppp_hdlc_if_print.out
@@ -0,0 +1 @@
+[|ppp]
diff --git a/tests/heapoverflow-ppp_hdlc_if_print.pcap b/tests/heapoverflow-ppp_hdlc_if_print.pcap
new file mode 100644
index 0000000..356adf3
--- /dev/null
+++ b/tests/heapoverflow-ppp_hdlc_if_print.pcap
Binary files differ
diff --git a/tests/heapoverflow-q933_printq.out b/tests/heapoverflow-q933_printq.out
new file mode 100644
index 0000000..ebc5605
--- /dev/null
+++ b/tests/heapoverflow-q933_printq.out
@@ -0,0 +1,2 @@
+Q.933, CCITT, codeset 0, unknown message (0x30), length 808464430
+	unknown IE (0x30), length 48: [|q.933]
diff --git a/tests/heapoverflow-q933_printq.pcap b/tests/heapoverflow-q933_printq.pcap
new file mode 100644
index 0000000..56d1b12
--- /dev/null
+++ b/tests/heapoverflow-q933_printq.pcap
Binary files differ
diff --git a/tests/heapoverflow-sl_if_print.out b/tests/heapoverflow-sl_if_print.out
new file mode 100644
index 0000000..4ddcf52
--- /dev/null
+++ b/tests/heapoverflow-sl_if_print.out
@@ -0,0 +1 @@
+[|slip]
diff --git a/tests/heapoverflow-sl_if_print.pcap b/tests/heapoverflow-sl_if_print.pcap
new file mode 100644
index 0000000..492a00b
--- /dev/null
+++ b/tests/heapoverflow-sl_if_print.pcap
Binary files differ
diff --git a/tests/heapoverflow-tcp_print.out b/tests/heapoverflow-tcp_print.out
new file mode 100644
index 0000000..9d31674
--- /dev/null
+++ b/tests/heapoverflow-tcp_print.out
@@ -0,0 +1,2 @@
+IP (tos 0x30, ttl 48, id 12336, offset 0, flags [DF], proto TCP (6), length 12336, bad cksum 3030 (->29a8)!)
+    48.48.48.48.12336 > 48.48.48.48.12336: Flags [.U], seq 808464432:808476688, ack 808464432, win 12336, urg 12336, options [unknown-48 0x3030303030303030[|tcp]
diff --git a/tests/heapoverflow-tcp_print.pcap b/tests/heapoverflow-tcp_print.pcap
new file mode 100644
index 0000000..44c171f
--- /dev/null
+++ b/tests/heapoverflow-tcp_print.pcap
Binary files differ
diff --git a/tests/hncp.out b/tests/hncp.out
new file mode 100644
index 0000000..4c3880b
--- /dev/null
+++ b/tests/hncp.out
@@ -0,0 +1,53 @@
+IP6 (hlim 1, next-header UDP (17) payload length: 32) fe80::218:f3ff:fea9:914e.8231 > ff02::11.8231: [udp sum ok] hncp (24)
+	Node endpoint (12) NID: 31:da:78:d2 EPID: 03000000
+	Network state (12) hash: 2ae5f77255200bcc
+IP6 (hlim 64, next-header UDP (17) payload length: 12) fe80::21e:64ff:fe23:4d34.8231 > fe80::218:f3ff:fea9:914e.8231: [udp sum ok] hncp (4)
+	Request network state (4)
+IP6 (hlim 64, next-header UDP (17) payload length: 80) fe80::218:f3ff:fea9:914e.8231 > fe80::21e:64ff:fe23:4d34.8231: [udp sum ok] hncp (72)
+	Node endpoint (12) NID: 31:da:78:d2 EPID: 03000000
+	Network state (12) hash: 2ae5f77255200bcc
+	Node state (24) NID: 31:da:78:d2 seqno: 19 160.088s hash: 800088c8e0714638
+	Node state (24) NID: 61:69:ed:63 seqno: 12 969.681s hash: 011fffa1da966148
+IP6 (hlim 64, next-header UDP (17) payload length: 16) fe80::21e:64ff:fe23:4d34.8231 > fe80::218:f3ff:fea9:914e.8231: [udp sum ok] hncp (8)
+	Request node state (8) NID: 31:da:78:d2
+IP6 (hlim 64, next-header UDP (17) payload length: 16) fe80::21e:64ff:fe23:4d34.8231 > fe80::218:f3ff:fea9:914e.8231: [udp sum ok] hncp (8)
+	Request node state (8) NID: 61:69:ed:63
+IP6 (hlim 64, next-header UDP (17) payload length: 332) fe80::218:f3ff:fea9:914e.8231 > fe80::21e:64ff:fe23:4d34.8231: [udp sum ok] hncp (324)
+	Node endpoint (12) NID: 31:da:78:d2 EPID: 03000000
+	Node state (312) NID: 31:da:78:d2 seqno: 19 160.105s hash: 800088c8e0714638
+		Peer (16) Peer-NID: 61:69:ed:63 Peer-EPID: 01000000 Local-EPID: 01000000
+		HNCP-Version (22) M: 0 P: 4 H: 4 L: 4 User-agent: hnetd/cac971d
+		External-Connection (52)
+			Delegated-Prefix (36) VLSO: 0.599s PLSO: 0.299s Prefix: 10.0.0.0/8
+				Prefix-Policy (5) type: Internet connectivity
+			DHCPv4-Data (10)
+				DNS-server (6) 192.168.1.254
+		Assigned-Prefix (18) EPID: 03000000 Prty: 2 Prefix: fd1f:f88c:e207:dbbc::/64
+		Assigned-Prefix (25) EPID: 01000000 Prty: 2 Prefix: 10.0.99.0/24
+		Assigned-Prefix (25) EPID: 03000000 Prty: 2 Prefix: 10.0.101.0/24
+		Node-Address (24) EPID: 01000000 IP Address: 10.0.99.2
+		Node-Address (24) EPID: 01000000 IP Address: fd1f:f88c:e207::2
+		Node-Address (24) EPID: 03000000 IP Address: 10.0.101.27
+		Node-Address (24) EPID: 03000000 IP Address: fd1f:f88c:e207:dbbc::1b
+		Node-Name (23) IP-Address: 10.0.101.27 Name: "r1"
+IP6 (hlim 64, next-header UDP (17) payload length: 564) fe80::218:f3ff:fea9:914e.8231 > fe80::21e:64ff:fe23:4d34.8231: [udp sum ok] hncp (556)
+	Node endpoint (12) NID: 31:da:78:d2 EPID: 03000000
+	Node state (544) NID: 61:69:ed:63 seqno: 12 969.699s hash: 011fffa1da966148
+		Peer (16) Peer-NID: 31:da:78:d2 Peer-EPID: 01000000 Local-EPID: 01000000
+		HNCP-Version (22) M: 0 P: 4 H: 4 L: 4 User-agent: hnetd/cac971d
+		External-Connection (23)
+			Delegated-Prefix (19) VLSO: 0.599s PLSO: 0.299s Prefix: fd1f:f88c:e207::/48
+		Assigned-Prefix (18) EPID: 01000000 Prty: 2 Prefix: fd1f:f88c:e207::/64
+		Assigned-Prefix (18) EPID: 03000000 Prty: 2 Prefix: fd1f:f88c:e207:17::/64
+		Assigned-Prefix (25) EPID: 03000000 Prty: 2 Prefix: 10.0.116.0/24
+		Node-Address (24) EPID: 01000000 IP Address: 10.0.99.41
+		Node-Address (24) EPID: 01000000 IP Address: fd1f:f88c:e207::69
+		Node-Address (24) EPID: 03000000 IP Address: 10.0.116.44
+		Node-Address (24) EPID: 03000000 IP Address: fd1f:f88c:e207:17::6c
+		DNS-Delegated-Zone (33) IP-Address: fd1f:f88c:e207::69 lb- lan.r.home
+		DNS-Delegated-Zone (35) IP-Address: fd1f:f88c:e207:17::6c lb- wlan0.r.home
+		DNS-Delegated-Zone (44) IP-Address: fd1f:f88c:e207:17::6c --- 116.0.10.in-addr.arpa
+		DNS-Delegated-Zone (63) IP-Address: fd1f:f88c:e207::69 --- 0.0.0.0.7.0.2.e.c.8.8.f.f.1.d.f.ip6.arpa
+		DNS-Delegated-Zone (63) IP-Address: fd1f:f88c:e207:17::6c --- 7.1.0.0.7.0.2.e.c.8.8.f.f.1.d.f.ip6.arpa
+		Node-Name (22) IP-Address: 10.0.116.44 Name: "r"
+		Node-Name (22) IP-Address: fd1f:f88c:e207:17::6c Name: "r"
diff --git a/tests/hncp.pcap b/tests/hncp.pcap
new file mode 100644
index 0000000..16d7047
--- /dev/null
+++ b/tests/hncp.pcap
Binary files differ
diff --git a/tests/ieee802.11_exthdr.out b/tests/ieee802.11_exthdr.out
index dd1689d..7b217e5 100644
--- a/tests/ieee802.11_exthdr.out
+++ b/tests/ieee802.11_exthdr.out
@@ -1,26 +1,26 @@
-10016360us tsft 1.0 Mb/s 2412 MHz 11b -22dB signal -86dB noise antenna 1 [bit 31] 0us Probe Request (omus) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
-10018922us tsft 1.0 Mb/s 2412 MHz 11b -19dB signal -86dB noise antenna 0 [bit 31] 0us Acknowledgment RA:90:a4:de:c0:46:0a 
-10017245us tsft 1.0 Mb/s -86dB noise 27dBm tx power [bit 15] 314us Probe Response (omus) [1.0* 2.0* 5.5* 11.0* 6.0 9.0 12.0 18.0 Mbit] CH: 1
-10085301us tsft 1.0 Mb/s 2412 MHz 11b -19dB signal -86dB noise antenna 1 [bit 31] 0us Probe Request (omus) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
-10087718us tsft 1.0 Mb/s 2412 MHz 11b -18dB signal -86dB noise antenna 0 [bit 31] 0us Acknowledgment RA:90:a4:de:c0:46:0a 
-10086042us tsft 1.0 Mb/s -86dB noise 27dBm tx power [bit 15] 314us Probe Response (omus) [1.0* 2.0* 5.5* 11.0* 6.0 9.0 12.0 18.0 Mbit] CH: 1
-10284358us tsft 1.0 Mb/s 2412 MHz 11b -61dB signal -86dB noise antenna 1 [bit 31] 0us Probe Request (omus) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
-10288217us tsft 1.0 Mb/s 2412 MHz 11b -46dB signal -86dB noise antenna 0 [bit 31] 0us Acknowledgment RA:90:a4:de:c0:46:0a 
-10286542us tsft 1.0 Mb/s -86dB noise 27dBm tx power [bit 15] 314us Probe Response (omus) [1.0* 2.0* 5.5* 11.0* 6.0 9.0 12.0 18.0 Mbit] CH: 1
-10351366us tsft 1.0 Mb/s 2412 MHz 11b -70dB signal -86dB noise antenna 1 [bit 31] 0us Probe Request (omus) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
-10353769us tsft 1.0 Mb/s 2412 MHz 11b -57dB signal -86dB noise antenna 0 [bit 31] 0us Acknowledgment RA:90:a4:de:c0:46:0a 
-10352092us tsft 1.0 Mb/s -86dB noise 27dBm tx power [bit 15] 314us Probe Response (omus) [1.0* 2.0* 5.5* 11.0* 6.0 9.0 12.0 18.0 Mbit] CH: 1
-10418368us tsft 1.0 Mb/s 2412 MHz 11b -67dB signal -86dB noise antenna 1 [bit 31] 0us Probe Request (omus) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
-10420929us tsft 1.0 Mb/s 2412 MHz 11b -73dB signal -86dB noise antenna 0 [bit 31] 0us Acknowledgment RA:90:a4:de:c0:46:0a 
-10419253us tsft 1.0 Mb/s -86dB noise 27dBm tx power [bit 15] 314us Probe Response (omus) [1.0* 2.0* 5.5* 11.0* 6.0 9.0 12.0 18.0 Mbit] CH: 1
-10485371us tsft 1.0 Mb/s 2412 MHz 11b -72dB signal -86dB noise antenna 1 [bit 31] 0us Probe Request (omus) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
-10489278us tsft 1.0 Mb/s 2412 MHz 11b -74dB signal -86dB noise antenna 0 [bit 31] 0us Acknowledgment RA:90:a4:de:c0:46:0a 
-10487602us tsft 1.0 Mb/s -86dB noise 27dBm tx power [bit 15] 314us Probe Response (omus) [1.0* 2.0* 5.5* 11.0* 6.0 9.0 12.0 18.0 Mbit] CH: 1
-13338508us tsft 1.0 Mb/s 2412 MHz 11b -14dB signal -86dB noise antenna 1 [bit 31] 314us Authentication (Open System)-1: Successful
-13340215us tsft 1.0 Mb/s 2412 MHz 11b -17dB signal -86dB noise antenna 0 [bit 31] 0us Acknowledgment RA:90:a4:de:c0:46:0a 
-13339435us tsft 1.0 Mb/s -86dB noise 27dBm tx power [bit 15] 314us Authentication (Open System)-2: 
-13341999us tsft 1.0 Mb/s 2412 MHz 11b -18dB signal -86dB noise antenna 1 [bit 31] 314us Assoc Request (omus) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
-13346458us tsft 1.0 Mb/s 2412 MHz 11b -18dB signal -86dB noise antenna 0 [bit 31] 0us Acknowledgment RA:90:a4:de:c0:46:0a 
-13344925us tsft 1.0 Mb/s -86dB noise 27dBm tx power [bit 15] 314us Assoc Response AID(1) :: Successful
-13355433us tsft 2412 MHz 11g -22dB signal -86dB noise antenna 1 19.5 Mb/s MCS 2 20 MHz lon GI [bit 31] 48us 
-13454791us tsft 2412 MHz 11g -21dB signal -86dB noise antenna 1 52.0 Mb/s MCS 11 20 MHz lon GI [bit 31] Pwr Mgmt 44us 
+10016360us tsft 1.0 Mb/s 2412 MHz 11b -22dBm signal -86dBm noise antenna 1 [bit 32] Probe Request (omus) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
+10018922us tsft 1.0 Mb/s 2412 MHz 11b -19dBm signal -86dBm noise antenna 0 [bit 32] Acknowledgment RA:90:a4:de:c0:46:0a 
+10017245us tsft 1.0 Mb/s -86dBm noise 27dBm tx power [bit 15] Probe Response (omus) [1.0* 2.0* 5.5* 11.0* 6.0 9.0 12.0 18.0 Mbit] CH: 1
+10085301us tsft 1.0 Mb/s 2412 MHz 11b -19dBm signal -86dBm noise antenna 1 [bit 32] Probe Request (omus) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
+10087718us tsft 1.0 Mb/s 2412 MHz 11b -18dBm signal -86dBm noise antenna 0 [bit 32] Acknowledgment RA:90:a4:de:c0:46:0a 
+10086042us tsft 1.0 Mb/s -86dBm noise 27dBm tx power [bit 15] Probe Response (omus) [1.0* 2.0* 5.5* 11.0* 6.0 9.0 12.0 18.0 Mbit] CH: 1
+10284358us tsft 1.0 Mb/s 2412 MHz 11b -61dBm signal -86dBm noise antenna 1 [bit 32] Probe Request (omus) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
+10288217us tsft 1.0 Mb/s 2412 MHz 11b -46dBm signal -86dBm noise antenna 0 [bit 32] Acknowledgment RA:90:a4:de:c0:46:0a 
+10286542us tsft 1.0 Mb/s -86dBm noise 27dBm tx power [bit 15] Probe Response (omus) [1.0* 2.0* 5.5* 11.0* 6.0 9.0 12.0 18.0 Mbit] CH: 1
+10351366us tsft 1.0 Mb/s 2412 MHz 11b -70dBm signal -86dBm noise antenna 1 [bit 32] Probe Request (omus) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
+10353769us tsft 1.0 Mb/s 2412 MHz 11b -57dBm signal -86dBm noise antenna 0 [bit 32] Acknowledgment RA:90:a4:de:c0:46:0a 
+10352092us tsft 1.0 Mb/s -86dBm noise 27dBm tx power [bit 15] Probe Response (omus) [1.0* 2.0* 5.5* 11.0* 6.0 9.0 12.0 18.0 Mbit] CH: 1
+10418368us tsft 1.0 Mb/s 2412 MHz 11b -67dBm signal -86dBm noise antenna 1 [bit 32] Probe Request (omus) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
+10420929us tsft 1.0 Mb/s 2412 MHz 11b -73dBm signal -86dBm noise antenna 0 [bit 32] Acknowledgment RA:90:a4:de:c0:46:0a 
+10419253us tsft 1.0 Mb/s -86dBm noise 27dBm tx power [bit 15] Probe Response (omus) [1.0* 2.0* 5.5* 11.0* 6.0 9.0 12.0 18.0 Mbit] CH: 1
+10485371us tsft 1.0 Mb/s 2412 MHz 11b -72dBm signal -86dBm noise antenna 1 [bit 32] Probe Request (omus) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
+10489278us tsft 1.0 Mb/s 2412 MHz 11b -74dBm signal -86dBm noise antenna 0 [bit 32] Acknowledgment RA:90:a4:de:c0:46:0a 
+10487602us tsft 1.0 Mb/s -86dBm noise 27dBm tx power [bit 15] Probe Response (omus) [1.0* 2.0* 5.5* 11.0* 6.0 9.0 12.0 18.0 Mbit] CH: 1
+13338508us tsft 1.0 Mb/s 2412 MHz 11b -14dBm signal -86dBm noise antenna 1 [bit 32] Authentication (Open System)-1: Successful
+13340215us tsft 1.0 Mb/s 2412 MHz 11b -17dBm signal -86dBm noise antenna 0 [bit 32] Acknowledgment RA:90:a4:de:c0:46:0a 
+13339435us tsft 1.0 Mb/s -86dBm noise 27dBm tx power [bit 15] Authentication (Open System)-2: 
+13341999us tsft 1.0 Mb/s 2412 MHz 11b -18dBm signal -86dBm noise antenna 1 [bit 32] Assoc Request (omus) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
+13346458us tsft 1.0 Mb/s 2412 MHz 11b -18dBm signal -86dBm noise antenna 0 [bit 32] Acknowledgment RA:90:a4:de:c0:46:0a 
+13344925us tsft 1.0 Mb/s -86dBm noise 27dBm tx power [bit 15] Assoc Response AID(1) :: Successful
+13355433us tsft 2412 MHz 11n -22dBm signal -86dBm noise antenna 1 19.5 Mb/s MCS 2 20 MHz long GI [bit 32] 
+13454791us tsft 2412 MHz 11n -21dBm signal -86dBm noise antenna 1 52.0 Mb/s MCS 11 20 MHz long GI [bit 32] 
diff --git a/tests/ieee802.11_rx-stbc.out b/tests/ieee802.11_rx-stbc.out
index 9f483b9..8369b62 100644
--- a/tests/ieee802.11_rx-stbc.out
+++ b/tests/ieee802.11_rx-stbc.out
@@ -1,3 +1,3 @@
-7268us tsft 2462 MHz 11g -51dB signal antenna 1 150.0 Mb/s MCS 7 40 MHz short GI RX-STBC1 CF +QoS Data IV: 11 Pad 20 KeyID 0
-119738173us tsft 2462 MHz 11g -46dB signal antenna 1 135.0 Mb/s MCS 7 40 MHz lon GI RX-STBC2 CF +QoS Data IV:  1 Pad 20 KeyID 0
-470382336us tsft 2462 MHz 11g -45dB signal antenna 1 150.0 Mb/s MCS 7 40 MHz short GI RX-STBC3 CF +QoS Data IV:  5 Pad 20 KeyID 0
+7268us tsft 2462 MHz 11n -51dBm signal antenna 1 150.0 Mb/s MCS 7 40 MHz short GI RX-STBC1 Data IV: 11 Pad 20 KeyID 0
+119738173us tsft 2462 MHz 11n -46dBm signal antenna 1 135.0 Mb/s MCS 7 40 MHz long GI RX-STBC2 Data IV:  1 Pad 20 KeyID 0
+470382336us tsft 2462 MHz 11n -45dBm signal antenna 1 150.0 Mb/s MCS 7 40 MHz short GI RX-STBC3 Data IV:  5 Pad 20 KeyID 0
diff --git a/tests/ikev2pI2-segfault-v.out b/tests/ikev2pI2-segfault-v.out
new file mode 100644
index 0000000..a690ef9
--- /dev/null
+++ b/tests/ikev2pI2-segfault-v.out
@@ -0,0 +1,8 @@
+IP (tos 0x0, ttl 64, id 0, offset 0, flags [none], proto UDP (17), length 536, bad cksum 0 (->f48e)!)
+    192.1.2.45.500 > 192.1.2.23.500: isakmp 2.0 msgid 00000000: parent_sa ikev2_init[I]:
+    (sa[C]: len=240
+        (p: #1 protoid=isakmp transform=4 len=40
+            (t: #1 type=encr id=#26380 )
+            (t: #2 type=integ id=hmac-sha )
+            (t: #3 type=prf id=hmac-sha )
+            (v2e)) [|v2sa]) [|v2ke]
diff --git a/tests/ikev2pI2-segfault.out b/tests/ikev2pI2-segfault.out
new file mode 100644
index 0000000..c7f0281
--- /dev/null
+++ b/tests/ikev2pI2-segfault.out
@@ -0,0 +1 @@
+IP 192.1.2.45.500 > 192.1.2.23.500: isakmp: parent_sa ikev2_init[I]
diff --git a/tests/ikev2pI2-segfault.pcap b/tests/ikev2pI2-segfault.pcap
new file mode 100644
index 0000000..43a7e28
--- /dev/null
+++ b/tests/ikev2pI2-segfault.pcap
Binary files differ
diff --git a/tests/ipcomp-heapoverflow.out b/tests/ipcomp-heapoverflow.out
new file mode 100644
index 0000000..c158cdf
--- /dev/null
+++ b/tests/ipcomp-heapoverflow.out
@@ -0,0 +1,2 @@
+IP (tos 0x30, ttl 48, id 12336, offset 0, flags [none], proto Compressed IP (108), length 12336, bad cksum 3030 (->6942)!)
+    48.48.48.48 > 48.48.48.48: [|IPCOMP]
diff --git a/tests/ipcomp-heapoverflow.pcap b/tests/ipcomp-heapoverflow.pcap
new file mode 100644
index 0000000..8f3cb30
--- /dev/null
+++ b/tests/ipcomp-heapoverflow.pcap
Binary files differ
diff --git a/tests/ipv6hdr-heapoverflow-v.out b/tests/ipv6hdr-heapoverflow-v.out
new file mode 100644
index 0000000..4e3730a
--- /dev/null
+++ b/tests/ipv6hdr-heapoverflow-v.out
@@ -0,0 +1 @@
+IP6 (class 0x33, flowlabel 0x03030, hlim 48, next-header Options (0) payload length: 12336) 3030:3030:3030:3030:3030:3030:3030:3030 > 3030:3030:3030:3030:3030:3030:3030:3030: HBH [trunc] [|HBH]
diff --git a/tests/ipv6hdr-heapoverflow.out b/tests/ipv6hdr-heapoverflow.out
new file mode 100644
index 0000000..f9bc97e
--- /dev/null
+++ b/tests/ipv6hdr-heapoverflow.out
@@ -0,0 +1 @@
+IP6 3030:3030:3030:3030:3030:3030:3030:3030 > 3030:3030:3030:3030:3030:3030:3030:3030: HBH [|HBH]
diff --git a/tests/ipv6hdr-heapoverflow.pcap b/tests/ipv6hdr-heapoverflow.pcap
new file mode 100644
index 0000000..19d28d6
--- /dev/null
+++ b/tests/ipv6hdr-heapoverflow.pcap
Binary files differ
diff --git a/tests/isis-seg-fault-1-v.out b/tests/isis-seg-fault-1-v.out
new file mode 100644
index 0000000..a1b4cdb
--- /dev/null
+++ b/tests/isis-seg-fault-1-v.out
@@ -0,0 +1,301 @@
+IS-IS, length 1497
+	L2 Lan IIH, hlen: 27, v: 1, pdu-v: 1, sys-id-len: 6 (0), max-area: 3 (0)
+	  source-id: 4444.0444.4444,  holding time: 10s, Flags: [Level 2 only]
+	  lan-id:    6344.4444.4444.01, Priority: 64, PDU length: 1497
+	    Protocols supported TLV #129, length: 1
+	      NLPID(s): IPv4 (0xcc)
+	    Area address(es) TLV #1, length: 4
+	      Area address (length: 3): 49.0014
+	    unknown TLV #80, length: 4
+		0x0000:  0a00 0002
+	    Restart Signaling TLV #211, length: 3
+	      Flags [none], Remaining holding time 0s
+	    IS Neighbor(s) TLV #6, length: 6
+	      SNPA: c202.2998.0051
+	    Padding TLV #8, length: 255
+	    IS Alias ID TLV #24, length: 255
+	      IS Neighbor: f500.0000.0000.00, no sub-TLVs present
+	      IS Neighbor: 0000.0000.0000.00, no sub-TLVs present
+	      IS Neighbor: 0000.0000.0000.00, no sub-TLVs present
+	      IS Neighbor: 0000.0000.0000.00, no sub-TLVs present
+	      IS Neighbor: 0000.0000.0000.00, no sub-TLVs present
+	      IS Neighbor: 0000.0000.0000.00, no sub-TLVs present
+	      IS Neighbor: 0000.0000.0000.00, no sub-TLVs present
+	      IS Neighbor: 0000.0000.0000.00, no sub-TLVs present
+	      IS Neighbor: 0000.0000.0000.00, sub-TLVs present (37)
+	        unknown subTLV #0, length: 0
+	        unknown subTLV #0, length: 0
+	        unknown subTLV #0, length: 0
+	        unknown subTLV #0, length: 0
+	        Bandwidth Constraints subTLV #22, length: 0
+	        Bandwidth Constraints Model ID: Russian dolls (0)
+	          Bandwidth constraint CT0: 0.000 Mbps
+	          Bandwidth constraint CT1: 0.000 Mbps
+	          Bandwidth constraint CT2: 0.000 Mbps
+	          Bandwidth constraint CT3: 0.000 Mbps
+	          Bandwidth constraint CT4: 0.000 Mbps
+	          Bandwidth constraint CT5: 0.000 Mbps
+	          Bandwidth constraint CT6: -0.000 Mbps
+	          Bandwidth constraint CT7: 0.000 Mbps
+	          Bandwidth constraint CT8: 0.000 Mbps
+	          Bandwidth constraint CT9: 0.000 Mbps
+	          Bandwidth constraint CT10: 0.000 Mbps
+	          Bandwidth constraint CT11: 0.000 Mbps
+	          Bandwidth constraint CT12: 0.000 Mbps
+	          Bandwidth constraint CT13: 0.000 Mbps
+	          Bandwidth constraint CT14: -1267650597027719304708096.000 Mbps
+	          Bandwidth constraint CT15: 0.000 Mbps
+	          Bandwidth constraint CT16: 0.000 Mbps
+	          Bandwidth constraint CT17: 0.000 Mbps
+	          Bandwidth constraint CT18: 0.000 Mbps
+	          Bandwidth constraint CT19: 0.000 Mbps
+	          Bandwidth constraint CT20: 0.000 Mbps
+	          Bandwidth constraint CT21: 0.000 Mbps
+	          Bandwidth constraint CT22: 0.000 Mbps
+	          Bandwidth constraint CT23: 0.000 Mbps
+	          Bandwidth constraint CT24: 0.000 Mbps
+	          Bandwidth constraint CT25: 0.000 Mbps
+	          Bandwidth constraint CT26: 0.000 Mbps
+	          Bandwidth constraint CT27: 0.000 Mbps
+	          Bandwidth constraint CT28: 0.000 Mbps
+	          Bandwidth constraint CT29: 0.000 Mbps
+	          Bandwidth constraint CT30: 0.000 Mbps
+	          Bandwidth constraint CT31: 0.000 Mbps
+	          Bandwidth constraint CT32: 0.000 Mbps
+	          Bandwidth constraint CT33: 0.000 Mbps
+	          Bandwidth constraint CT34: 0.000 Mbps
+	          Bandwidth constraint CT35: 0.000 Mbps
+	          Bandwidth constraint CT36: 0.000 Mbps
+	          Bandwidth constraint CT37: 0.000 Mbps
+	          Bandwidth constraint CT38: 16.777 Mbps
+	          Bandwidth constraint CT39: 0.000 Mbps
+	          Bandwidth constraint CT40: 0.000 Mbps
+	          Bandwidth constraint CT41: 0.000 Mbps
+	          Bandwidth constraint CT42: 0.000 Mbps
+	          Bandwidth constraint CT43: 0.000 Mbps
+	          Bandwidth constraint CT44: 0.000 Mbps
+	          Bandwidth constraint CT45: 0.000 Mbps
+	          Bandwidth constraint CT46: 0.000 Mbps
+	          Bandwidth constraint CT47: 0.000 Mbps
+	          Bandwidth constraint CT48: 0.000 Mbps
+	          Bandwidth constraint CT49: 0.000 Mbps
+	          Bandwidth constraint CT50: 0.000 Mbps
+	          Bandwidth constraint CT51: 0.000 Mbps
+	          Bandwidth constraint CT52: 0.000 Mbps
+	          Bandwidth constraint CT53: 0.000 Mbps
+	          Bandwidth constraint CT54: 0.000 Mbps
+	          Bandwidth constraint CT55: 0.000 Mbps
+	          Bandwidth constraint CT56: 0.000 Mbps
+	          Bandwidth constraint CT57: 0.000 Mbps
+	          Bandwidth constraint CT58: 0.000 Mbps
+	          Bandwidth constraint CT59: 0.000 Mbps
+	          Bandwidth constraint CT60: 0.000 Mbps
+	          Bandwidth constraint CT61: 0.000 Mbps
+	          Bandwidth constraint CT62: 0.000 Mbps
+	          Bandwidth constraint CT63: 0.000 Mbps
+	          Bandwidth constraint CT64: 0.000 Mbps
+	          Bandwidth constraint CT65: 0.000 Mbps
+	          Bandwidth constraint CT66: 0.000 Mbps
+	          Bandwidth constraint CT67: 0.000 Mbps
+	          Bandwidth constraint CT68: 0.000 Mbps
+	          Bandwidth constraint CT69: 0.000 Mbps
+	          Bandwidth constraint CT70: 0.000 Mbps
+	          Bandwidth constraint CT71: 0.000 Mbps
+	          Bandwidth constraint CT72: 0.000 Mbps
+	          Bandwidth constraint CT73: 0.000 Mbps
+	          Bandwidth constraint CT74: 0.000 Mbps
+	          Bandwidth constraint CT75: 0.000 Mbps
+	          Bandwidth constraint CT76: 0.000 Mbps
+	          Bandwidth constraint CT77: 0.000 Mbps
+	          Bandwidth constraint CT78: 0.000 Mbps
+	          Bandwidth constraint CT79: 0.000 Mbps
+	          Bandwidth constraint CT80: 0.000 Mbps
+	          Bandwidth constraint CT81: 0.000 Mbps
+	          Bandwidth constraint CT82: 0.000 Mbps
+	          Bandwidth constraint CT83: 0.000 Mbps
+	          Bandwidth constraint CT84: 0.000 Mbps
+	          Bandwidth constraint CT85: 0.000 Mbps
+	          Bandwidth constraint CT86: 0.000 Mbps
+	          Bandwidth constraint CT87: 0.000 Mbps
+	          Bandwidth constraint CT88: 0.000 Mbps
+	          Bandwidth constraint CT89: 0.000 Mbps
+	          Bandwidth constraint CT90: 0.000 Mbps
+	          Bandwidth constraint CT91: 0.000 Mbps
+	          Bandwidth constraint CT92: 0.000 Mbps
+	          Bandwidth constraint CT93: 0.000 Mbps
+	          Bandwidth constraint CT94: 0.000 Mbps
+	          Bandwidth constraint CT95: 0.000 Mbps
+	          Bandwidth constraint CT96: 0.000 Mbps
+	          Bandwidth constraint CT97: 0.000 Mbps
+	          Bandwidth constraint CT98: 0.000 Mbps
+	          Bandwidth constraint CT99: 0.000 Mbps
+	          Bandwidth constraint CT100: 0.000 Mbps
+	          Bandwidth constraint CT101: 0.000 Mbps
+	          Bandwidth constraint CT102: 0.000 Mbps
+	          Bandwidth constraint CT103: 0.000 Mbps
+	          Bandwidth constraint CT104: 0.000 Mbps
+	          Bandwidth constraint CT105: 0.000 Mbps
+	          Bandwidth constraint CT106: 0.000 Mbps
+	          Bandwidth constraint CT107: 0.000 Mbps
+	          Bandwidth constraint CT108: 0.000 Mbps
+	          Bandwidth constraint CT109: 0.000 Mbps
+	          Bandwidth constraint CT110: 334903128525925002608918921216.000 Mbps
+	          Bandwidth constraint CT111: 0.000 Mbps
+	          Bandwidth constraint CT112: 0.000 Mbps
+	          Bandwidth constraint CT113: 0.000 Mbps
+	          Bandwidth constraint CT114: 0.000 Mbps
+	          Bandwidth constraint CT115: 0.000 Mbps
+	          Bandwidth constraint CT116: 0.000 Mbps
+	          Bandwidth constraint CT117: 0.000 Mbps
+	          Bandwidth constraint CT118: 0.000 Mbps
+	          Bandwidth constraint CT119: 0.000 Mbps
+	          Bandwidth constraint CT120: 0.000 Mbps
+	          Bandwidth constraint CT121: 0.000 Mbps
+	          Bandwidth constraint CT122: 0.000 Mbps
+	          Bandwidth constraint CT123: 0.000 Mbps
+	          Bandwidth constraint CT124: 0.000 Mbps
+	          Bandwidth constraint CT125: 0.000 Mbps
+	          Bandwidth constraint CT126: 0.000 Mbps
+	          Bandwidth constraint CT127: 0.000 Mbps
+	          Bandwidth constraint CT128: 0.000 Mbps
+	          Bandwidth constraint CT129: 0.000 Mbps
+	          Bandwidth constraint CT130: 0.000 Mbps
+	          Bandwidth constraint CT131: 0.000 Mbps
+	          Bandwidth constraint CT132: 0.000 Mbps
+	          Bandwidth constraint CT133: 0.000 Mbps
+	          Bandwidth constraint CT134: 0.000 Mbps
+	          Bandwidth constraint CT135: 0.000 Mbps
+	          Bandwidth constraint CT136: 0.000 Mbps
+	          Bandwidth constraint CT137: -4.194 Mbps
+	          Bandwidth constraint CT138: 0.000 Mbps
+	          Bandwidth constraint CT139: 0.000 Mbps
+	          Bandwidth constraint CT140: 0.000 Mbps
+	          Bandwidth constraint CT141: 0.000 Mbps
+	          Bandwidth constraint CT142: 0.000 Mbps
+	          Bandwidth constraint CT143: 0.000 Mbps
+	          Bandwidth constraint CT144: 0.000 Mbps
+	          Bandwidth constraint CT145: 0.000 Mbps
+	          Bandwidth constraint CT146: 0.000 Mbps
+	          Bandwidth constraint CT147: 0.000 Mbps
+	          Bandwidth constraint CT148: 0.000 Mbps
+	          Bandwidth constraint CT149: 0.000 Mbps
+	          Bandwidth constraint CT150: 0.000 Mbps
+	          Bandwidth constraint CT151: 0.000 Mbps
+	          Bandwidth constraint CT152: 0.000 Mbps
+	          Bandwidth constraint CT153: 0.000 Mbps
+	          Bandwidth constraint CT154: 16.777 Mbps
+	          Bandwidth constraint CT155: 0.000 Mbps
+	          Bandwidth constraint CT156: 0.000 Mbps
+	          Bandwidth constraint CT157: 0.000 Mbps
+	          Bandwidth constraint CT158: 0.000 Mbps
+	          Bandwidth constraint CT159: 0.000 Mbps
+	          Bandwidth constraint CT160: 0.000 Mbps
+	          Bandwidth constraint CT161: 0.000 Mbps
+	          Bandwidth constraint CT162: 0.000 Mbps
+	          Bandwidth constraint CT163: 0.000 Mbps
+	          Bandwidth constraint CT164: 0.000 Mbps
+	          Bandwidth constraint CT165: 0.000 Mbps
+	          Bandwidth constraint CT166: 0.000 Mbps
+	          Bandwidth constraint CT167: 0.000 Mbps
+	          Bandwidth constraint CT168: 0.000 Mbps
+	          Bandwidth constraint CT169: 0.000 Mbps
+	          Bandwidth constraint CT170: 0.000 Mbps
+	          Bandwidth constraint CT171: 0.000 Mbps
+	          Bandwidth constraint CT172: 0.000 Mbps
+	          Bandwidth constraint CT173: 0.000 Mbps
+	          Bandwidth constraint CT174: 0.000 Mbps
+	          Bandwidth constraint CT175: 0.000 Mbps
+	          Bandwidth constraint CT176: 0.000 Mbps
+	          Bandwidth constraint CT177: 0.000 Mbps
+	          Bandwidth constraint CT178: 0.000 Mbps
+	          Bandwidth constraint CT179: 1099511.625 Mbps
+	          Bandwidth constraint CT180: 0.000 Mbps
+	          Bandwidth constraint CT181: 0.000 Mbps
+	          Bandwidth constraint CT182: 0.000 Mbps
+	          Bandwidth constraint CT183: 0.000 Mbps
+	          Bandwidth constraint CT184: 0.000 Mbps
+	          Bandwidth constraint CT185: 0.000 Mbps
+	          Bandwidth constraint CT186: 0.000 Mbps
+	          Bandwidth constraint CT187: 0.000 Mbps
+	          Bandwidth constraint CT188: 0.000 Mbps
+	          Bandwidth constraint CT189: 0.000 Mbps
+	          Bandwidth constraint CT190: 0.000 Mbps
+	          Bandwidth constraint CT191: 0.000 Mbps
+	          Bandwidth constraint CT192: 0.000 Mbps
+	          Bandwidth constraint CT193: 0.000 Mbps
+	          Bandwidth constraint CT194: 0.000 Mbps
+	          Bandwidth constraint CT195: 0.000 Mbps
+	          Bandwidth constraint CT196: 0.000 Mbps
+	          Bandwidth constraint CT197: 0.000 Mbps
+	          Bandwidth constraint CT198: 0.000 Mbps
+	          Bandwidth constraint CT199: 0.000 Mbps
+	          Bandwidth constraint CT200: 0.000 Mbps
+	          Bandwidth constraint CT201: 0.000 Mbps
+	          Bandwidth constraint CT202: 0.000 Mbps
+	          Bandwidth constraint CT203: 0.000 Mbps
+	          Bandwidth constraint CT204: 0.000 Mbps
+	          Bandwidth constraint CT205: 0.000 Mbps
+	          Bandwidth constraint CT206: 0.000 Mbps
+	          Bandwidth constraint CT207: 0.000 Mbps
+	          Bandwidth constraint CT208: 0.000 Mbps
+	          Bandwidth constraint CT209: 0.000 Mbps
+	          Bandwidth constraint CT210: 0.000 Mbps
+	          Bandwidth constraint CT211: 0.000 Mbps
+	          Bandwidth constraint CT212: 0.000 Mbps
+	          Bandwidth constraint CT213: 0.000 Mbps
+	          Bandwidth constraint CT214: 0.000 Mbps
+	          Bandwidth constraint CT215: 0.000 Mbps
+	          Bandwidth constraint CT216: 0.000 Mbps
+	          Bandwidth constraint CT217: 0.000 Mbps
+	          Bandwidth constraint CT218: 0.000 Mbps
+	          Bandwidth constraint CT219: 0.000 Mbps
+	          Bandwidth constraint CT220: 0.000 Mbps
+	          Bandwidth constraint CT221: 0.000 Mbps
+	          Bandwidth constraint CT222: 0.000 Mbps
+	          Bandwidth constraint CT223: 0.000 Mbps
+	          Bandwidth constraint CT224: 0.000 Mbps
+	          Bandwidth constraint CT225: 0.000 Mbps
+	          Bandwidth constraint CT226: 0.000 Mbps
+	          Bandwidth constraint CT227: 0.000 Mbps
+	          Bandwidth constraint CT228: 0.000 Mbps
+	          Bandwidth constraint CT229: 0.000 Mbps
+	          Bandwidth constraint CT230: -0.000 Mbps
+	          Bandwidth constraint CT231: 0.000 Mbps
+	          Bandwidth constraint CT232: 0.000 Mbps
+	          Bandwidth constraint CT233: 0.000 Mbps
+	          Bandwidth constraint CT234: 0.000 Mbps
+	          Bandwidth constraint CT235: 0.000 Mbps
+	          Bandwidth constraint CT236: 0.000 Mbps
+	          Bandwidth constraint CT237: 0.000 Mbps
+	          Bandwidth constraint CT238: 0.000 Mbps
+	          Bandwidth constraint CT239: 0.000 Mbps
+	          Bandwidth constraint CT240: 0.000 Mbps
+	          Bandwidth constraint CT241: 0.000 Mbps
+	          Bandwidth constraint CT242: 0.000 Mbps
+	          Bandwidth constraint CT243: 0.000 Mbps
+	          Bandwidth constraint CT244: 0.000 Mbps
+	          Bandwidth constraint CT245: 0.000 Mbps
+	          Bandwidth constraint CT246: 0.000 Mbps
+	          Bandwidth constraint CT247: 0.000 Mbps
+	          Bandwidth constraint CT248: 0.000 Mbps
+	          Bandwidth constraint CT249: 0.000 Mbps
+	          Bandwidth constraint CT250: 0.000 Mbps
+	          Bandwidth constraint CT251: 0.000 Mbps
+	          Bandwidth constraint CT252: 0.000 Mbps
+	          Bandwidth constraint CT253: 0.000 Mbps
+	          Bandwidth constraint CT254: 0.000 Mbps
+	          Bandwidth constraint CT255: 0.000 Mbps
+	          Bandwidth constraint CT256: 0.000 Mbps
+	          Bandwidth constraint CT257: 0.000 Mbps
+	          Bandwidth constraint CT258: 0.000 Mbps
+	          Bandwidth constraint CT259: 0.000 Mbps
+	          Bandwidth constraint CT260: 0.000 Mbps
+	          Bandwidth constraint CT261: 0.000 Mbps
+	          Bandwidth constraint CT262: 0.000 Mbps
+	          Bandwidth constraint CT263: 0.000 Mbps
+	          Bandwidth constraint CT264: 0.000 Mbps
+	          Bandwidth constraint CT265: 0.000 Mbps
+	          Bandwidth constraint CT266: 0.000 Mbps
+	          Bandwidth constraint CT267: 0.000 Mbps
+	          Bandwidth constraint CT268: 0.000 Mbps
+		 [|isis]
diff --git a/tests/isis-seg-fault-1-v.sh b/tests/isis-seg-fault-1-v.sh
new file mode 100755
index 0000000..2e9b6ec
--- /dev/null
+++ b/tests/isis-seg-fault-1-v.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+# This "verbose" ISIS protocol test involves a float calculation that
+# may produce a slightly different result if the compiler is not GCC.
+# Test only with GCC (similar to GitHub issue #333).
+
+test_name=isis-seg-fault-1-v
+
+if [ ! -f ../Makefile ]
+then
+	printf '    %-35s: TEST SKIPPED (no Makefile)\n' $test_name
+elif grep '^CC = .*gcc' ../Makefile >/dev/null
+then
+  ./TESTonce $test_name isis-seg-fault-1.pcap isis-seg-fault-1-v.out '-t -v'
+else
+	printf '    %-35s: TEST SKIPPED (compiler is not GCC)\n' $test_name
+fi
diff --git a/tests/isis-seg-fault-1.pcap b/tests/isis-seg-fault-1.pcap
new file mode 100644
index 0000000..e19d082
--- /dev/null
+++ b/tests/isis-seg-fault-1.pcap
Binary files differ
diff --git a/tests/isis-seg-fault-2-v.out b/tests/isis-seg-fault-2-v.out
new file mode 100644
index 0000000..f395a8b
--- /dev/null
+++ b/tests/isis-seg-fault-2-v.out
@@ -0,0 +1,222 @@
+IS-IS, length 1497
+	L1 Lan IIH, hlen: 27, v: 1, pdu-v: 1, sys-id-len: 6 (0), max-area: 3 (0)
+	  source-id: 3333.3333.3333,  holding time: 10s, Flags: [unknown circuit type 0x21]
+	  lan-id:    3333.5a33.3333.02, Priority: 64, PDU length: 1497
+	    Multi-Topology Capability TLV #144, length: 1
+	      O: 1, RES: 4, MTID(s): 3073
+	      unknown subTLV #4, length: 3
+	      unknown subTLV #73, length: 0
+	      unknown subTLV #10, length: 132
+	      unknown subTLV #4, length: 10
+	      unknown subTLV #0, length: 10
+	      unknown subTLV #0, length: 55
+	      SPBM Service Identifier and Unicast Address subTLV #3, length: 0
+	        BMAC: 00000606c201, RES: 2, VID: 2456
+	      unknown subTLV #204, length: 83
+	      unknown subTLV #8, length: 191
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #82, length: 0
+	      unknown subTLV #0, length: 86
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #37, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 37
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 108
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #37, length: 0
+	      unknown subTLV #48, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #37, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #172, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #76, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 90
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 90
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #37, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 107
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 37
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #2, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #37, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 92
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #113, length: 90
+	      unknown subTLV #0, length: 230
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #79, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #234, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #64, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #37, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #37, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #2, length: 0
+	      unknown subTLV #0, length: 0
+	      unknown subTLV #0, length: 0
+	    Area address(es) TLV #1, length: 4
+	      Area address (length: 3): 49.000a
+	    IPv4 Interface address(es) TLV #132, length: 4
+	      IPv4 interface address: 10.0.10.0
+	    unknown TLV #55, length: 3
+		0x0000:  0000 00
+	    IS Neighbor(s) TLV #6, length: 6
+	      SNPA: c201.2998.cc53
+	    Padding TLV #8, length: 191
+	    unknown TLV #0, length: 0
+	    unknown TLV #0, length: 0
+	    unknown TLV #0, length: 0
+	    unknown TLV #0, length: 0
+	    unknown TLV #0, length: 0
+	    unknown TLV #0, length: 37
+		0x0000:  0000 0000 0000 0025 0000 0000 0000 0000
+		0x0010:  0000 0002 0000 0000 0000 0000 0000 0000
+		0x0020:  0000 7300 1e
+	    unknown TLV #0, length: 0
+	    unknown TLV #0, length: 170
+		0x0000:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0010:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0020:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0030:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0040:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0050:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0060:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0070:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0080:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0090:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x00a0:  aaaa aaaa aaaa aaaa aaaa
+	    unknown TLV #170, length: 170
+		0x0000:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0010:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0020:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0030:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0040:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0050:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0060:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0070:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0080:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0090:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x00a0:  aaaa aaaa aaaa aaaa aaaa
+	    unknown TLV #170, length: 170
+		0x0000:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0010:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0020:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0030:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0040:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0050:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0060:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0070:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0080:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0090:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x00a0:  aaaa aaaa aaaa aaaa aaaa
+	    unknown TLV #170, length: 170
+		0x0000:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0010:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0020:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0030:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0040:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0050:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0060:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0070:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0080:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0090:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x00a0:  aaaa aaaa aaaa aaaa aaaa
+	    unknown TLV #170, length: 170
+		0x0000:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0010:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0020:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0030:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0040:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0050:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0060:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0070:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0080:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0090:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x00a0:  aaaa aaaa aaaa aaaa aaaa
+	    unknown TLV #170, length: 170
+		0x0000:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0010:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0020:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0030:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0040:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0050:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0060:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0070:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0080:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x0090:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
+		0x00a0:  aaaa aaaa aaaa aaaa aaaa
+	      164 straggler bytes
diff --git a/tests/isis-seg-fault-2.pcap b/tests/isis-seg-fault-2.pcap
new file mode 100644
index 0000000..66a646d
--- /dev/null
+++ b/tests/isis-seg-fault-2.pcap
Binary files differ
diff --git a/tests/isis-seg-fault-3-v.out b/tests/isis-seg-fault-3-v.out
new file mode 100644
index 0000000..d161093
--- /dev/null
+++ b/tests/isis-seg-fault-3-v.out
@@ -0,0 +1,4 @@
+IS-IS, length 131146
+	L2 LSP, hlen: 27, v: 1, pdu-v: 1, sys-id-len: 6 (0), max-area: 3 (0)
+	  lsp-id: 1111.1111.1111.00-00, seq: 0x00000007, lifetime:  1200s
+	  chksum: 0x378e [|isis]
diff --git a/tests/isis-seg-fault-3.pcap b/tests/isis-seg-fault-3.pcap
new file mode 100644
index 0000000..17f685f
--- /dev/null
+++ b/tests/isis-seg-fault-3.pcap
Binary files differ
diff --git a/tests/isis_poi.out b/tests/isis_poi.out
new file mode 100644
index 0000000..129734b
--- /dev/null
+++ b/tests/isis_poi.out
@@ -0,0 +1,8 @@
+IS-IS, length 43
+	L2 LSP, hlen: 27, v: 1, pdu-v: 1, sys-id-len: 6 (0), max-area: 3 (0)
+	  lsp-id: 1280.9201.9098.00-00, seq: 0x000001e2, lifetime:     0s
+	  chksum: 0x0000 (unverified), PDU length: 43, Flags: [ L2 IS ]
+	    Purge Originator Identifier TLV #13, length: 7
+	      Purge Originator System-ID: 1280.9202.0074
+	    Hostname TLV #137, length: 5
+	      Hostname: P2_re
diff --git a/tests/isis_poi.pcap b/tests/isis_poi.pcap
new file mode 100644
index 0000000..fdd433c
--- /dev/null
+++ b/tests/isis_poi.pcap
Binary files differ
diff --git a/tests/isis_poi2.out b/tests/isis_poi2.out
new file mode 100644
index 0000000..10eecca
--- /dev/null
+++ b/tests/isis_poi2.out
@@ -0,0 +1,9 @@
+IS-IS, length 49
+	L2 LSP, hlen: 27, v: 1, pdu-v: 1, sys-id-len: 6 (0), max-area: 3 (0)
+	  lsp-id: 1280.9201.7082.00-00, seq: 0x0000023f, lifetime:     0s
+	  chksum: 0x0000 (unverified), PDU length: 49, Flags: [ L2 IS ]
+	    Purge Originator Identifier TLV #13, length: 13
+	      Purge Originator System-ID: 1280.9202.7092
+	      Received from System-ID: 1280.9202.0074
+	    Hostname TLV #137, length: 5
+	      Hostname: P1_re
diff --git a/tests/isis_poi2.pcap b/tests/isis_poi2.pcap
new file mode 100644
index 0000000..8174524
--- /dev/null
+++ b/tests/isis_poi2.pcap
Binary files differ
diff --git a/tests/isoclns-heapoverflow-2.out b/tests/isoclns-heapoverflow-2.out
new file mode 100644
index 0000000..6bdfd01
--- /dev/null
+++ b/tests/isoclns-heapoverflow-2.out
@@ -0,0 +1 @@
+fe:fe:fe:fe:fe:fe > 30:30:da:fe:fe:fe, ethertype OSI (0xfefe), length 808464432: OSI NLPID CLNP (0x81): [|clnp]
diff --git a/tests/isoclns-heapoverflow-2.pcap b/tests/isoclns-heapoverflow-2.pcap
new file mode 100644
index 0000000..c86570b
--- /dev/null
+++ b/tests/isoclns-heapoverflow-2.pcap
Binary files differ
diff --git a/tests/isoclns-heapoverflow-3.out b/tests/isoclns-heapoverflow-3.out
new file mode 100644
index 0000000..74d2a22
--- /dev/null
+++ b/tests/isoclns-heapoverflow-3.out
@@ -0,0 +1 @@
+fe:fe:fe:fe:fe:fe > 30:30:da:fe:fe:fe, ethertype OSI (0xfefe), length 808464432: OSI NLPID CLNP (0x81): 00 > e8.3030, Echo Request, length 808464417
diff --git a/tests/isoclns-heapoverflow-3.pcap b/tests/isoclns-heapoverflow-3.pcap
new file mode 100644
index 0000000..1425bdb
--- /dev/null
+++ b/tests/isoclns-heapoverflow-3.pcap
Binary files differ
diff --git a/tests/isoclns-heapoverflow.out b/tests/isoclns-heapoverflow.out
new file mode 100644
index 0000000..c2cfdfb
--- /dev/null
+++ b/tests/isoclns-heapoverflow.out
@@ -0,0 +1 @@
+|OSI
diff --git a/tests/isoclns-heapoverflow.pcap b/tests/isoclns-heapoverflow.pcap
new file mode 100644
index 0000000..f724db0
--- /dev/null
+++ b/tests/isoclns-heapoverflow.pcap
Binary files differ
diff --git a/tests/juniper_header-heapoverflow.out b/tests/juniper_header-heapoverflow.out
new file mode 100644
index 0000000..b13cfbe
--- /dev/null
+++ b/tests/juniper_header-heapoverflow.out
@@ -0,0 +1 @@
+[|juniper_hdr], length 808464432
diff --git a/tests/juniper_header-heapoverflow.pcap b/tests/juniper_header-heapoverflow.pcap
new file mode 100644
index 0000000..ea88636
--- /dev/null
+++ b/tests/juniper_header-heapoverflow.pcap
Binary files differ
diff --git a/tests/kday1.out b/tests/kday1.out
index eaaacaa..9cb884d 100644
--- a/tests/kday1.out
+++ b/tests/kday1.out
@@ -1,15 +1,2 @@
-IP6, wrong link-layer encapsulation (tos 0x10, ttl 192, id 63177, offset 0, flags [DF], proto SCTP (132), length 168, options (security [bad length 110]), bad cksum a291 (->9204)!)
-    c084:a291:b8aa:42aa:3e38:9ac7:826e:b930.33943 > 8497:1a30:7cd4:d4d4:d4d4:d428:13:68.6704: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 1934917887] [SID: 256] [SSEQ 15360] [PPID 0x3c00] 
-	ForCES Config 
-	ForCES Version 14 len 88B flags 0x0a040604 
-	SrcID 0xff000200(AllMulticast) DstID 0xb59cbe(FE) Correlator 0x30480805f4010800
-		Messy oper TLV header, type (0x600)
-		excess of -240 Bytes 
-	[0x0000:  e803 0016 ff00 0200 00b5 9cbe 3048 0805
-	[0x0010:  f401 0800 0a04 0604 0010 003c 0000 3ce8
-	[0x0020:  0300 3c00 000e 0016 0604 0010 003c 0000
-	[0x0030:  0000 ff00 ffff a69c be30 4808 0600 0108
-	[0x0040:  0006 0400 0184 b59c be30 84b5 0010 0000
-	[0x0050:  cc05 367e 0003 0000
-	][|sctp]
+IP6, wrong link-layer encapsulation 
 EXIT CODE 00000100
diff --git a/tests/kday2.out b/tests/kday2.out
index 770fc3b..fa13572 100644
--- a/tests/kday2.out
+++ b/tests/kday2.out
@@ -9,12 +9,7 @@
 	  0x0060:  0000 0000 0000 3200 0000 0000 00aa 6873
 	Port status TLV (0x02), length 26, Status: Unknown (0)
 	Unknown TLV (0x37), length 4101
-	  0x0000:  3710 05ff ff05 cc09 3493 0000 0000 8000
-	  0x0010:  0000 0000 0032 0000 0000 0000 aa68 7354
-	  0x0020:  d706 0b00 3c00 0000 3c00 0000 0080 0000
-	  0x0030:  fffd 4d5f d9bd c709 30ac 8176 b36d cc11
-	  0x0040:  3abf 1291 f106 4ede 61f4 6297 afc4 39a4
-	  0x0050:  0db9 7a
+		 packet is too short
 IP (tos 0x10, ttl 62, id 64806, offset 0, flags [DF], proto TCP (6), length 52)
     204.9.51.132.50079 > 204.9.54.80.22: Flags [.], cksum 0x8611 (incorrect -> 0xa678), ack 1819218606, win 4094, options [nop,nop,TS val 941371775 ecr 4294967242], length 0
 IP (tos 0x10, ttl 62, id 62920, offset 0, flags [DF], proto TCP (6), length 52, bad cksum 4504 (->451a)!)
@@ -29,6 +24,6 @@
 	  0x0020:  b36d cc11 3abf 1291 f106 4ede 61f4 6297
 	  0x0030:  afc4 39a4 0db9 7aa5 6873 33e8
 	RPKI-RTRv65, Error Report PDU (10), length: 21
-	  Error code: Unknown (66), Encapsulated PDU length: 37|trunc
+	  Error code: Unknown (66), Encapsulated PDU length: 37
 	[|RPKI-RTR]
 EXIT CODE 00000100
diff --git a/tests/kday3.out b/tests/kday3.out
index f6fd728..95909e0 100644
--- a/tests/kday3.out
+++ b/tests/kday3.out
@@ -1,7 +1,6 @@
 IP (tos 0x10, ttl 64, id 63177, offset 0, flags [DF], proto TCP (6), length 168)
     204.9.54.80.22 > 204.9.51.132.50079: Flags [P.], cksum 0x0282 (incorrect -> 0x3217), seq 1819218606:1819218722, ack 1238485076, win 1039, options [nop,nop,TS val 1340592078 ecr 941371882], length 116
-IP6, wrong link-layer encapsulation (tos 0x10, ttl 62, id 64806, offset 0, flags [DF], proto TCP (6), length 52, options (unknown 195 [bad length 159]), bad cksum 3da6 (->45ca)!)
-    27759 > 4782:  tcp 24 [bad hdr length 0 - too short, < 20]
+IP6, wrong link-layer encapsulation 
 IP (tos 0x10, ttl 62, id 62920, offset 0, flags [DF], proto TCP (6), length 52, bad cksum 4504 (->451a)!)
     204.9.51.132.50079 > 204.243.53.80.22: Flags [.], cksum 0x858b (incorrect -> 0x85a1), ack 1819218722, win 4092, options [nop,nop,TS val 941371913 ecr 1340592084], length 0
 IP (tos 0x0, ttl 64, id 63178, offset 0, flags [DF], proto TCP (6), length 52, bad cksum 3e8c (->438c)!)
@@ -13,10 +12,7 @@
 	  0x0010:  f857 ee68 4dfd 4d5f d9bd c709 30ac 8176
 	  0x0020:  b36d cc11 3abf 1291 f106 4ede 61f4 6297
 	  0x0030:  afc4 39a4 0db9 7aa5 6873 33e8
-	RPKI-RTRv65, Error Report PDU (10), length: 66|trunc
-	RPKI-RTRv115, Error Report PDU (10), length: 66
-	  Error code: Unknown (66), Encapsulated PDU length: 12
-	    -----encapsulated PDU-----|trunc|trunc
+	RPKI-RTRv65, Error Report PDU (10), length: 66
 	[|RPKI-RTR]
 IP (tos 0x10, ttl 62, id 64806, offset 0, flags [DF], proto TCP (6), length 52)
     204.9.51.132.50079 > 204.9.54.80.22: Flags [.], cksum 0x8611 (incorrect -> 0xa678), ack 0, win 4094, options [nop,nop,TS val 941371775 ecr 4294967242], length 0
@@ -33,9 +29,6 @@
 	  0x0030:  afc4 39a4 0db9 7aa5 6873 33e8
 	RPKI-RTRv65, Error Report PDU (10), length: 66
 	  Error code: Unknown (66), Encapsulated PDU length: 37
-	    -----encapsulated PDU-----|trunc|trunc
-	RPKI-RTRv9, Unknown PDU (51), length: 32
-	  0x0000:  0933 84cc 0000 0020 9f00 1649 d1c8 546c
-	  0x0010:  ff13 1980 100f fc85 8b00 0055 0000 0101
+	    -----encapsulated PDU-----
 	[|RPKI-RTR]
 EXIT CODE 00000100
diff --git a/tests/kday4.out b/tests/kday4.out
index 95b29cc..ccdebfc 100644
--- a/tests/kday4.out
+++ b/tests/kday4.out
@@ -3,6 +3,10 @@
 IP (tos 0x10, ttl 62, id 64806, offset 0, flags [DF], proto TCP (6), length 52, bad cksum 3da6 (->35a6)!)
     212.9.51.132.50079 > 204.9.54.80.22: Flags [.], cksum 0x8611 (incorrect -> 0x4811), ack 1819218606, win 17918, options [nop,nop,TS val 941371903 ecr 1340592074], length 0
 84:b5:9c:be:30:48 Unknown SSAP 0x10 > 0c:c4:7a:08:e9:12 Unknown DSAP 0x44 Information, send seq 0, rcv seq 26, Flags [Command], length 52
+	0x0000:  4510 0034 f5c8 4000 3e06 4504 cc09 3384  E..4..@.>.E...3.
+	0x0010:  cc09 3650 c39f 0016 49d1 c854 6c6f 1322  ..6P....I..Tlo."
+	0x0020:  8010 0ffc 858b 0000 0101 080a 381c 3209  ............8.2.
+	0x0030:  4fe7 cfd4                                O...
 IP (tos 0x0, ttl 64, id 63178, offset 0, flags [DF], proto TCP (6), length 52)
     204.9.54.80.55936 > 204.9.55.10.443: Flags [.], cksum 0x0594 (incorrect -> 0x725a), ack 3589495407, win 1040, options [nop,nop,TS val 647770294 ecr 2364779354], length 0
 IP (tos 0x0, ttl 64, id 36752, offset 0, flags [DF], proto TCP (6), length 399, bad cksum a46b (->a474)!)
@@ -14,10 +18,7 @@
 	  0x0030:  afc4 39a4 0db9 7aa5 6873 33e8
 	RPKI-RTRv65, Error Report PDU (10), length: 66
 	  Error code: Unknown (66), Encapsulated PDU length: 37
-	    -----encapsulated PDU-----|trunc|trunc
-	RPKI-RTRv115, Error Report PDU (10), length: 66
-	  Error code: Unknown (66), Encapsulated PDU length: 12
-	    -----encapsulated PDU-----|trunc|trunc
+	    -----encapsulated PDU-----
 	[|RPKI-RTR]
 IP (tos 0x10, ttl 62, id 64806, offset 0, flags [DF], proto TCP (6), length 52)
     204.9.51.132.50079 > 204.9.54.80.22: Flags [.], cksum 0x8611 (incorrect -> 0xa678), ack 1819218606, win 4094, options [nop,nop,TS val 941371775 ecr 4294967242], length 0
@@ -34,10 +35,7 @@
 	  0x0030:  afc4 39a4 0db9 7aa5 6873 33e8
 	RPKI-RTRv65, Error Report PDU (10), length: 66
 	  Error code: Unknown (66), Encapsulated PDU length: 37
-	    -----encapsulated PDU-----|trunc|trunc
-	RPKI-RTRv115, Error Report PDU (10), length: 66
-	  Error code: Unknown (66), Encapsulated PDU length: 12
-	    -----encapsulated PDU-----|trunc|trunc
+	    -----encapsulated PDU-----
 	[|RPKI-RTR]
 IP truncated-ip - 768 bytes missing! (tos 0x10, ttl 62, id 64806, offset 0, flags [DF], proto TCP (6), length 820, bad cksum 3da6 (->3aa6)!)
     204.9.51.132.50079 > 204.9.54.80.22: Flags [.], seq 0:768, ack 1, win 4094, options [nop,nop,TS val 941371775 ecr 4294967242], length 768
@@ -55,6 +53,6 @@
 	RPKI-RTRv65, Error Report PDU (10), length: 66
 	  Error code: Unknown (66), Encapsulated PDU length: 100
 	  Error text: ^@^@^@M-^?M-^?^_^[pM-xWM-nhMM-}M_M-YM-=M-G^I0M-,M-^AvM-3mM-L^Q:M-?^RM-^QM-q^FNM-^aM-tbM-^WM-/M-D9M-$^MM-9zM-%hs3M-hA^J^@B^@^@^@B^@^@^@%M-Dz^HM-i^RM-^DM-5M-^\M->0H^H^@E^P^@4M-}&@^@>^F
-	RPKI-RTRv115, Error Report PDU (10), length: 66|trunc
+	RPKI-RTRv115, Error Report PDU (10), length: 66
 	[|RPKI-RTR]
 EXIT CODE 00000100
diff --git a/tests/kday5.out b/tests/kday5.out
index 7aeae72..4a8ed7c 100644
--- a/tests/kday5.out
+++ b/tests/kday5.out
@@ -9,12 +9,7 @@
 	  0x0060:  0000 0000 0000 3200 0000 0000 00aa 6873
 	Port status TLV (0x02), length 26, Status: Unknown (0)
 	Unknown TLV (0x37), length 4101
-	  0x0000:  3710 05ff ff05 cc09 3493 0000 0000 8000
-	  0x0010:  0000 0000 0032 0000 0000 0000 aa68 7354
-	  0x0020:  d706 0b00 3c00 0000 3c00 0000 0080 0000
-	  0x0030:  fffd 4d5f d9bd c709 30ac 8176 b36d cc11
-	  0x0040:  3abf 1291 f106 4ede 61f4 6297 afc4 39a4
-	  0x0050:  0db9 7a
+		 packet is too short
 IP (tos 0x10, ttl 62, id 64806, offset 0, flags [DF], proto TCP (6), length 52)
     204.9.51.132.50079 > 204.9.54.80.22: Flags [.], cksum 0x8611 (incorrect -> 0xa678), ack 1819218606, win 4094, options [nop,nop,TS val 941371775 ecr 4294967242], length 0
 IP (tos 0x10, ttl 62, id 62920, offset 0, flags [DF], proto TCP (6), length 52, bad cksum 4504 (->451a)!)
diff --git a/tests/kday6.out b/tests/kday6.out
index 3eba7e6..8c49293 100644
--- a/tests/kday6.out
+++ b/tests/kday6.out
@@ -1,7 +1,7 @@
 FRF.16 Frag, seq 693, Flags [Begin], UI e8! IS-IS, length 301989913
 	L1 LSP, hlen: 27, v: 1, pdu-v: 1, sys-id-len: 6 (0), max-area: 131 (131)
 	  lsp-id: 8383.8383.834f.00-60, seq: 0x06418fcc, lifetime: 33667s
-	  chksum: 0x0900(unverified), PDU length: 33667, Flags: [ Overload bit set, expense ATT bit set, L1 IS ]
+	  chksum: 0x0900 (unverified), PDU length: 33667, Flags: [ Overload bit set, expense ATT bit set, L1 IS ]
 	    Multi-Topology Capability TLV #144, length: 137
 	      O: 0, RES: 4, MTID(s): 3945
 	      unknown subTLV #8, length: 233
@@ -362,19 +362,8 @@
 	    Partition DIS TLV #4, length: 4
 	    Partition DIS TLV #4, length: 4
 	    Partition DIS TLV #4, length: 5
-	    unknown TLV #13, length: 178
-		0x0000:  c4e4 f9cb 0ce2 cd2e 175a 0bf3 b492 01fa
-		0x0010:  0e0e 0e0e 0e0e 0e0e 0e0e 0e0e 0e0e 0e0e
-		0x0020:  0e0e 0e0e 0e0e 0e0e 0e0e 0e0e 0e0e 0e0e
-		0x0030:  3a3a 3a3a 3a3a 3a3a 3a3a 3a3a 3a3a 3a3a
-		0x0040:  3a3a 3a0e 0e0e 0e0e 0e0e 0e0e 0e0e 0e28
-		0x0050:  0e0e 0e0e 0e0e 0e0e 0e0e 0e0e 0e0e 0e0e
-		0x0060:  0e0e 0e0e 0e0e 0e0e 0e0e 0e0e 0e0e 0e0e
-		0x0070:  0e0e 0e0e 0e0e 0e0e 0e0e 0e0e 0e0e 0e0e
-		0x0080:  0e0e 0e0e 0e0e 0e0e 0e0e 0e0e 0e0e 0e0e
-		0x0090:  0e0e 0e0e 0e0e 0e0e 0e0e 0e0e 0e0e 0e0e
-		0x00a0:  0e0e 0e0e 0e0e 0e0e 0e0e 0e0e 0e0e 0e0e
-		0x00b0:  0e0e
+	    Purge Originator Identifier TLV #13, length: 178
+	      Purge Originator System-ID: e4f9.cb0c.e2cd
 	    LSP Buffersize TLV #14, length: 14
 	      LSP Buffersize: 3598
 	    LSP Buffersize TLV #14, length: 14
@@ -455,6 +444,5 @@
 	      LSP Buffersize: 3598
 	    unknown TLV #58, length: 58
 		0x0000:  3a3a 3a3a 3a3a 3a3a 3a3a 3a3a 3a3a 3a3a
-		0x0010:  3a3a 3a
-		 packet exceeded snapshot (39) bytes
+		0x0010:  3a3a 3a [|isis]
 EXIT CODE 00000100
diff --git a/tests/kday7.out b/tests/kday7.out
index 94e8b65..75e24ca 100644
--- a/tests/kday7.out
+++ b/tests/kday7.out
@@ -3,6 +3,10 @@
 IP (tos 0x10, ttl 62, id 64806, offset 0, flags [DF], proto TCP (6), length 52, bad cksum 3da6 (->35a6)!)
     212.9.51.132.50079 > 204.9.54.80.22: Flags [.], cksum 0x8611 (incorrect -> 0x4811), ack 1819218606, win 17918, options [nop,nop,TS val 941371903 ecr 1340592074], length 0
 84:b5:9c:be:30:48 Unknown SSAP 0x10 > 0c:c4:7a:08:e9:12 Unknown DSAP 0x44 Information, send seq 0, rcv seq 26, Flags [Command], length 52
+	0x0000:  4510 0034 f5c8 4000 3e06 4504 cc09 3384  E..4..@.>.E...3.
+	0x0010:  cc09 3650 c39f 0016 49d1 c854 6c6f 1322  ..6P....I..Tlo."
+	0x0020:  8010 0ffc 858b 0000 0101 080a 381c 3209  ............8.2.
+	0x0030:  4fe7 cfd4                                O...
 IP (tos 0x0, ttl 64, id 63178, offset 0, flags [DF], proto TCP (6), length 52)
     204.9.54.80.55936 > 204.9.55.10.443: Flags [.], cksum 0x0594 (incorrect -> 0x725a), ack 3589495407, win 1040, options [nop,nop,TS val 647770294 ecr 2364779354], length 0
 IP (tos 0x0, ttl 64, id 36752, offset 0, flags [DF], proto TCP (6), length 399, bad cksum a46b (->a474)!)
@@ -14,10 +18,7 @@
 	  0x0030:  afc4 39a4 0db9 7aa5 6873 33e8
 	RPKI-RTRv65, Error Report PDU (10), length: 66
 	  Error code: Unknown (66), Encapsulated PDU length: 37
-	    -----encapsulated PDU-----|trunc|trunc
-	RPKI-RTRv115, Error Report PDU (10), length: 66
-	  Error code: Unknown (66), Encapsulated PDU length: 12
-	    -----encapsulated PDU-----|trunc|trunc
+	    -----encapsulated PDU-----
 	[|RPKI-RTR]
 IP (tos 0x10, ttl 62, id 64806, offset 0, flags [DF], proto TCP (6), length 52)
     204.9.51.132.50079 > 204.9.54.80.22: Flags [.], cksum 0x8611 (incorrect -> 0xa678), ack 1819218606, win 4094, options [nop,nop,TS val 941371775 ecr 4294967242], length 0
@@ -34,10 +35,7 @@
 	  0x0030:  afc4 39a4 0db9 7aa5 6873 33e8
 	RPKI-RTRv65, Error Report PDU (10), length: 66
 	  Error code: Unknown (66), Encapsulated PDU length: 37
-	    -----encapsulated PDU-----|trunc|trunc
-	RPKI-RTRv115, Error Report PDU (10), length: 66
-	  Error code: Unknown (66), Encapsulated PDU length: 12
-	    -----encapsulated PDU-----|trunc|trunc
+	    -----encapsulated PDU-----
 	[|RPKI-RTR]
 IP truncated-ip - 768 bytes missing! (tos 0x10, ttl 62, id 64806, offset 0, flags [DF], proto TCP (6), length 820, bad cksum 3da6 (->3aa6)!)
     204.9.51.132.50079 > 204.9.54.80.22: Flags [.], seq 0:768, ack 1, win 4094, options [nop,nop,TS val 941371775 ecr 4294967242], length 768
@@ -53,7 +51,6 @@
 	  0x0020:  b36d cc11 3abf 1291 f106 4ede 61f4 6297
 	  0x0030:  afc4 39a4 0db9 7aa5 6873 33e8
 	RPKI-RTRv65, Error Report PDU (10), length: 66
-	  Error code: Unknown (66), Encapsulated PDU length: 100|trunc
-	RPKI-RTRv115, Error Report PDU (10), length: 66|trunc
+	  Error code: Unknown (66), Encapsulated PDU length: 100
 	[|RPKI-RTR]
 EXIT CODE 00000100
diff --git a/tests/kday8.out b/tests/kday8.out
index 2d84b72..4dfb91c 100644
--- a/tests/kday8.out
+++ b/tests/kday8.out
@@ -9,12 +9,7 @@
 	  0x0060:  fffa 0000 0000 3200 0000 0000 00aa 6873
 	Port status TLV (0x02), length 26, Status: Unknown (0)
 	Unknown TLV (0x37), length 4101
-	  0x0000:  3710 05ff ff05 cc09 3493 0000 0000 80ff
-	  0x0010:  fa00 0000 0032 0000 0000 0000 aa68 7354
-	  0x0020:  d706 0b00 3c00 0000 3c00 0000 0080 0000
-	  0x0030:  fffd 4d5f d9bd c709 30ac 8176 b36d cc11
-	  0x0040:  3abf 1291 f106 4ede 61f4 6297 afc4 39a4
-	  0x0050:  0db9 7a
+		 packet is too short
 IP (tos 0x10, ttl 62, id 64806, offset 0, flags [DF], proto TCP (6), length 52)
     204.9.51.132.50079 > 204.9.54.80.22: Flags [.], cksum 0x8611 (incorrect -> 0xa678), ack 1819218606, win 4094, options [nop,nop,TS val 941371775 ecr 4294967242], length 0
 IP (tos 0x10, ttl 62, id 62920, offset 0, flags [DF], proto TCP (6), length 52, bad cksum 4504 (->451a)!)
@@ -29,6 +24,6 @@
 	  0x0020:  b36d cc11 3abf 1291 f106 4ede 61f4 6297
 	  0x0030:  afc4 39a4 0db9 7aa5 6873 33e8
 	RPKI-RTRv65, Error Report PDU (10), length: 66
-	  Error code: Unknown (66), Encapsulated PDU length: 80|trunc
+	  Error code: Unknown (66), Encapsulated PDU length: 80
 	[|RPKI-RTR]
 EXIT CODE 00000100
diff --git a/tests/lisp_eid_notify.out b/tests/lisp_eid_notify.out
new file mode 100644
index 0000000..43c5246
--- /dev/null
+++ b/tests/lisp_eid_notify.out
@@ -0,0 +1,63 @@
+IP (tos 0x0, ttl 64, id 1, offset 0, flags [none], proto UDP (17), length 160)
+    192.168.0.105.4342 > 127.0.0.1.4342: LISP-Map-Notify, flags [none],
+    3 record(s), Authentication SHA1,
+    Authentication-Data: 0x0000:  4bbb 9614 a67a 8604 0407 7995 4537 1906
+    Authentication-Data: 0x0010:  836c d1d6
+      Record TTL 1440, Authoritative, No-Action, Map Version: 0, EID 10.30.1.100/32, 1 locator(s)
+        LOC 20.20.8.253
+          Priority/Weight 1/100, Multicast Priority/Weight 1/100, flags [none],
+      Record TTL 1440, Authoritative, No-Action, Map Version: 0, EID 10.30.1.96/32, 2 locator(s)
+        LOC 20.20.8.251
+          Priority/Weight 1/100, Multicast Priority/Weight 1/100, flags [none],
+        LOC 20.20.8.252
+          Priority/Weight 1/100, Multicast Priority/Weight 1/100, flags [none],
+      Record TTL 1440, Authoritative, No-Action, Map Version: 0, EID 10.30.1.80/32, 1 locator(s)
+        LOC 20.20.8.239
+          Priority/Weight 1/100, Multicast Priority/Weight 1/100, flags [none],
+IP (tos 0x0, ttl 64, id 1, offset 0, flags [none], proto UDP (17), length 156)
+    192.168.0.105.4342 > 127.0.0.1.4342: LISP-Map-Notify, flags [I-xTR-ID-Present],
+    2 record(s), Authentication SHA1,
+    Authentication-Data: 0x0000:  4bbb 9614 a67a 8604 0407 7995 4537 1906
+    Authentication-Data: 0x0010:  836c d1d6
+      Record TTL 1440, Authoritative, No-Action, Map Version: 0, EID 10.30.1.100/32, 1 locator(s)
+        LOC 20.20.8.253
+          Priority/Weight 1/100, Multicast Priority/Weight 1/100, flags [none],
+      Record TTL 1440, Authoritative, No-Action, Map Version: 0, EID 10.30.1.96/32, 2 locator(s)
+        LOC 20.20.8.251
+          Priority/Weight 1/100, Multicast Priority/Weight 1/100, flags [none],
+        LOC 20.20.8.252
+          Priority/Weight 1/100, Multicast Priority/Weight 1/100, flags [none],
+    xTR-ID: 0x0000:  9787 ad75 3caf 58a7 13fa 6920 e6d2 7a8f
+    SITE-ID: 0
+IP (tos 0x0, ttl 64, id 1, offset 0, flags [none], proto UDP (17), length 160)
+    192.168.0.105.4342 > 127.0.0.1.4342: LISP-Map-Notify, flags [I-xTR-ID-Present],
+    3 record(s), Authentication SHA1,
+    Authentication-Data: 0x0000:  4bbb 9614 a67a 8604 0407 7995 4537 1906
+    Authentication-Data: 0x0010:  836c d1d6
+      Record TTL 1440, Authoritative, No-Action, Map Version: 0, EID 10.30.1.100/32, 1 locator(s)
+        LOC 20.20.8.253
+          Priority/Weight 1/100, Multicast Priority/Weight 1/100, flags [none],
+      Record TTL 1440, Authoritative, No-Action, Map Version: 0, EID 10.30.1.96/32, 2 locator(s)
+        LOC 20.20.8.251
+          Priority/Weight 1/100, Multicast Priority/Weight 1/100, flags [none],
+        LOC 20.20.8.252
+          Priority/Weight 1/100, Multicast Priority/Weight 1/100, flags [none],
+      Record TTL 1440, Authoritative, No-Action, Map Version: 0, EID 10.30.1.80/32, 1 locator(s)
+        LOC 20.20.8.239
+          Priority/Weight 1/100, Multicast Priority/Weight 1/100, flags [none],
+    (invalid)
+IP (tos 0x0, ttl 64, id 1, offset 0, flags [none], proto UDP (17), length 156)
+    192.168.0.105.4342 > 127.0.0.1.4342: LISP-Map-Notify, flags [none],
+    2 record(s), Authentication SHA1,
+    Authentication-Data: 0x0000:  4bbb 9614 a67a 8604 0407 7995 4537 1906
+    Authentication-Data: 0x0010:  836c d1d6
+      Record TTL 1440, Authoritative, No-Action, Map Version: 0, EID 10.30.1.100/32, 1 locator(s)
+        LOC 20.20.8.253
+          Priority/Weight 1/100, Multicast Priority/Weight 1/100, flags [none],
+      Record TTL 1440, Authoritative, No-Action, Map Version: 0, EID 10.30.1.96/32, 2 locator(s)
+        LOC 20.20.8.251
+          Priority/Weight 1/100, Multicast Priority/Weight 1/100, flags [none],
+        LOC 20.20.8.252
+          Priority/Weight 1/100, Multicast Priority/Weight 1/100, flags [none],
+    Data: 0x0000:  9787 ad75 3caf 58a7 13fa 6920 e6d2 7a8f
+    Data: 0x0010:  0000 0000 0000 0000
diff --git a/tests/lisp_eid_notify.pcap b/tests/lisp_eid_notify.pcap
new file mode 100644
index 0000000..1f83378
--- /dev/null
+++ b/tests/lisp_eid_notify.pcap
Binary files differ
diff --git a/tests/lisp_eid_register.out b/tests/lisp_eid_register.out
new file mode 100644
index 0000000..7687b65
--- /dev/null
+++ b/tests/lisp_eid_register.out
@@ -0,0 +1,28 @@
+IP (tos 0x0, ttl 64, id 1, offset 0, flags [none], proto UDP (17), length 144)
+    192.168.0.105.4342 > 127.0.0.1.4342: LISP-Map-Register, flags [I-xTR-ID-Present, M-Want-Map-Notify],
+    2 record(s), Authentication SHA1,
+    Authentication-Data: 0x0000:  4bbb 9614 a67a 8604 0407 7995 4537 1906
+    Authentication-Data: 0x0010:  836c d1d6
+      Record TTL 1440, Authoritative, No-Action, Map Version: 0, EID 10.30.1.100/32, 1 locator(s)
+        LOC 20.20.8.253
+          Priority/Weight 1/100, Multicast Priority/Weight 1/100, flags [none],
+      Record TTL 1440, Authoritative, No-Action, Map Version: 0, EID 10.30.1.96/32, 1 locator(s)
+        LOC 20.20.8.252
+          Priority/Weight 1/100, Multicast Priority/Weight 1/100, flags [none],
+    xTR-ID: 0x0000:  9787 ad75 3caf 58a7 13fa 6920 e6d2 7a8f
+    SITE-ID: 0
+IP (tos 0x0, ttl 64, id 1, offset 0, flags [none], proto UDP (17), length 156)
+    192.168.0.105.4342 > 127.0.0.1.4342: LISP-Map-Register, flags [I-xTR-ID-Present, M-Want-Map-Notify],
+    2 record(s), Authentication SHA1,
+    Authentication-Data: 0x0000:  4bbb 9614 a67a 8604 0407 7995 4537 1906
+    Authentication-Data: 0x0010:  836c d1d6
+      Record TTL 1440, Authoritative, No-Action, Map Version: 0, EID 10.30.1.100/32, 1 locator(s)
+        LOC 20.20.8.253
+          Priority/Weight 1/100, Multicast Priority/Weight 1/100, flags [none],
+      Record TTL 1440, Authoritative, No-Action, Map Version: 0, EID 10.30.1.96/32, 2 locator(s)
+        LOC 20.20.8.251
+          Priority/Weight 1/100, Multicast Priority/Weight 1/100, flags [none],
+        LOC 20.20.8.252
+          Priority/Weight 1/100, Multicast Priority/Weight 1/100, flags [none],
+    xTR-ID: 0x0000:  9787 ad75 3caf 58a7 13fa 6920 e6d2 7a8f
+    SITE-ID: 0
diff --git a/tests/lisp_eid_register.pcap b/tests/lisp_eid_register.pcap
new file mode 100644
index 0000000..a6d71ef
--- /dev/null
+++ b/tests/lisp_eid_register.pcap
Binary files differ
diff --git a/tests/lisp_ipv6.out b/tests/lisp_ipv6.out
new file mode 100644
index 0000000..39e84c3
--- /dev/null
+++ b/tests/lisp_ipv6.out
@@ -0,0 +1,24 @@
+IP (tos 0x0, ttl 64, id 1, offset 0, flags [none], proto UDP (17), length 168)
+    192.168.0.105.4342 > 127.0.0.1.4342: LISP-Map-Register, flags [I-xTR-ID-Present, M-Want-Map-Notify],
+    2 record(s), Authentication SHA1,
+    Authentication-Data: 0x0000:  4bbb 9614 a67a 8604 0407 7995 4537 1906
+    Authentication-Data: 0x0010:  836c d1d6
+      Record TTL 1440, Authoritative, No-Action, Map Version: 0, EID 2001:db8:85a3::8a2e:370:7334/80, 1 locator(s)
+        LOC 20.20.8.253
+          Priority/Weight 1/100, Multicast Priority/Weight 1/100, flags [none],
+      Record TTL 1440, Authoritative, No-Action, Map Version: 0, EID 2001:db8:95a3::8a2e:370:7334/80, 1 locator(s)
+        LOC 20.20.8.251
+          Priority/Weight 1/100, Multicast Priority/Weight 1/100, flags [none],
+    xTR-ID: 0x0000:  9787 ad75 3caf 58a7 13fa 6920 e6d2 7a8f
+    SITE-ID: 0
+IP (tos 0x0, ttl 64, id 1, offset 0, flags [none], proto UDP (17), length 144)
+    192.168.0.105.4342 > 127.0.0.1.4342: LISP-Map-Notify, flags [none],
+    2 record(s), Authentication SHA1,
+    Authentication-Data: 0x0000:  4bbb 9614 a67a 8604 0407 7995 4537 1906
+    Authentication-Data: 0x0010:  836c d1d6
+      Record TTL 1440, Authoritative, No-Action, Map Version: 0, EID 2001:db8:85a3::8a2e:370:7334/80, 1 locator(s)
+        LOC 20.20.8.253
+          Priority/Weight 1/100, Multicast Priority/Weight 1/100, flags [none],
+      Record TTL 1440, Authoritative, No-Action, Map Version: 0, EID 2001:db8:95a3::8a2e:370:7334/80, 1 locator(s)
+        LOC 20.20.8.251
+          Priority/Weight 1/100, Multicast Priority/Weight 1/100, flags [none],
diff --git a/tests/lisp_ipv6.pcap b/tests/lisp_ipv6.pcap
new file mode 100644
index 0000000..b878efd
--- /dev/null
+++ b/tests/lisp_ipv6.pcap
Binary files differ
diff --git a/tests/llc-xid-heapoverflow.out b/tests/llc-xid-heapoverflow.out
new file mode 100644
index 0000000..4fcad70
--- /dev/null
+++ b/tests/llc-xid-heapoverflow.out
@@ -0,0 +1 @@
+Unknown DSAP 0x30 Unnumbered, xid, Flags [Poll], length 808464412[|llc]
diff --git a/tests/llc-xid-heapoverflow.pcap b/tests/llc-xid-heapoverflow.pcap
new file mode 100644
index 0000000..6a5f1a4
--- /dev/null
+++ b/tests/llc-xid-heapoverflow.pcap
Binary files differ
diff --git a/tests/lldp_cdp-ev.out b/tests/lldp_cdp-ev.out
index d9fc647..0029a75 100644
--- a/tests/lldp_cdp-ev.out
+++ b/tests/lldp_cdp-ev.out
@@ -1,4 +1,4 @@
-00:18:ba:98:68:8f > 01:00:0c:cc:cc:cc, 802.3, length 388: LLC, dsap SNAP (0xaa) Individual, ssap SNAP (0xaa) Command, ctrl 0x03: oui Cisco (0x00000c), pid CDP (0x2000): CDPv2, ttl: 180s, checksum: 0x0bea (unverified), length 366
+00:18:ba:98:68:8f > 01:00:0c:cc:cc:cc, 802.3, length 374: LLC, dsap SNAP (0xaa) Individual, ssap SNAP (0xaa) Command, ctrl 0x03: oui Cisco (0x00000c), pid CDP (0x2000), length 366: CDPv2, ttl: 180s, checksum: 0x0bea (unverified), length 366
 	Device-ID (0x01), value length: 2 bytes: 'S1'
 	Version String (0x05), value length: 190 bytes: 
 	  Cisco IOS Software, C3560 Software (C3560-ADVIPSERVICESK9-M), Version 12.2(44)SE, RELEASE SOFTWARE (fc1)
@@ -17,7 +17,7 @@
 	Management Addresses (0x16), value length: 13 bytes: IPv4 (1) 0.0.0.0
 	unknown field type (0x1a), value length: 12 bytes: 
 	  0x0000:  0000 0001 0000 0000 ffff ffff
-00:19:2f:a7:b2:8d > 01:00:0c:cc:cc:cc, 802.3, length 392: LLC, dsap SNAP (0xaa) Individual, ssap SNAP (0xaa) Command, ctrl 0x03: oui Cisco (0x00000c), pid CDP (0x2000): CDPv2, ttl: 180s, checksum: 0x971d (unverified), length 370
+00:19:2f:a7:b2:8d > 01:00:0c:cc:cc:cc, 802.3, length 378: LLC, dsap SNAP (0xaa) Individual, ssap SNAP (0xaa) Command, ctrl 0x03: oui Cisco (0x00000c), pid CDP (0x2000), length 370: CDPv2, ttl: 180s, checksum: 0x971d (unverified), length 370
 	Device-ID (0x01), value length: 2 bytes: 'S2'
 	Version String (0x05), value length: 190 bytes: 
 	  Cisco IOS Software, C3560 Software (C3560-ADVIPSERVICESK9-M), Version 12.2(44)SE, RELEASE SOFTWARE (fc1)
@@ -124,7 +124,7 @@
 	    PMD autoneg capability [Sym PAUSE for fdx, Asym and Sym PAUSE for fdx, 1000BASE-{X LX SX CX} fdx, 1000BASE-T hdx] (0x0036)
 	    MAU type 100BASETX fdx (0x0010)
 	End TLV (0), length 0
-00:18:ba:98:68:8f > 01:00:0c:cc:cc:cc, 802.3, length 388: LLC, dsap SNAP (0xaa) Individual, ssap SNAP (0xaa) Command, ctrl 0x03: oui Cisco (0x00000c), pid CDP (0x2000): CDPv2, ttl: 180s, checksum: 0x0be9 (unverified), length 366
+00:18:ba:98:68:8f > 01:00:0c:cc:cc:cc, 802.3, length 374: LLC, dsap SNAP (0xaa) Individual, ssap SNAP (0xaa) Command, ctrl 0x03: oui Cisco (0x00000c), pid CDP (0x2000), length 366: CDPv2, ttl: 180s, checksum: 0x0be9 (unverified), length 366
 	Device-ID (0x01), value length: 2 bytes: 'S1'
 	Version String (0x05), value length: 190 bytes: 
 	  Cisco IOS Software, C3560 Software (C3560-ADVIPSERVICESK9-M), Version 12.2(44)SE, RELEASE SOFTWARE (fc1)
@@ -143,7 +143,7 @@
 	Management Addresses (0x16), value length: 13 bytes: IPv4 (1) 0.0.0.0
 	unknown field type (0x1a), value length: 12 bytes: 
 	  0x0000:  0000 0001 0000 0000 ffff ffff
-00:19:2f:a7:b2:8d > 01:00:0c:cc:cc:cc, 802.3, length 392: LLC, dsap SNAP (0xaa) Individual, ssap SNAP (0xaa) Command, ctrl 0x03: oui Cisco (0x00000c), pid CDP (0x2000): CDPv2, ttl: 180s, checksum: 0x971c (unverified), length 370
+00:19:2f:a7:b2:8d > 01:00:0c:cc:cc:cc, 802.3, length 378: LLC, dsap SNAP (0xaa) Individual, ssap SNAP (0xaa) Command, ctrl 0x03: oui Cisco (0x00000c), pid CDP (0x2000), length 370: CDPv2, ttl: 180s, checksum: 0x971c (unverified), length 370
 	Device-ID (0x01), value length: 2 bytes: 'S2'
 	Version String (0x05), value length: 190 bytes: 
 	  Cisco IOS Software, C3560 Software (C3560-ADVIPSERVICESK9-M), Version 12.2(44)SE, RELEASE SOFTWARE (fc1)
diff --git a/tests/lldp_mudurl-v.out b/tests/lldp_mudurl-v.out
new file mode 100644
index 0000000..57ac6ff
--- /dev/null
+++ b/tests/lldp_mudurl-v.out
@@ -0,0 +1,62 @@
+00:23:54:c2:57:02 > 01:80:c2:00:00:0e, ethertype LLDP (0x88cc), length 302: LLDP, length 288
+	Chassis ID TLV (1), length 7
+	  Subtype MAC address (4): 00:23:54:c2:57:02
+	Port ID TLV (2), length 7
+	  Subtype MAC address (3): 00:23:54:c2:57:02
+	Time to Live TLV (3), length 2: TTL 120s
+	System Name TLV (5), length 28: upstairs.ofcourseimright.com
+	System Description TLV (6), length 92
+	  Ubuntu 14.04.5 LTS Linux 3.13.0-106-generic #153-Ubuntu SMP Tue Dec 6 15:45:13 UTC 2016 i686
+	System Capabilities TLV (7), length 4
+	  System  Capabilities [Bridge, WLAN AP, Router, Station Only] (0x009c)
+	  Enabled Capabilities [WLAN AP] (0x0008)
+	Management Address TLV (8), length 12
+	  Management Address length 5, AFI IPv4 (1): 62.12.173.114
+	  Interface Index Interface Numbering (2): 2
+	Management Address TLV (8), length 24
+	  Management Address length 17, AFI IPv6 (2): 2001:8a8:1006:4:223:54ff:fec2:5702
+	  Interface Index Interface Numbering (2): 2
+	Port Description TLV (4), length 4: eth0
+	Organization specific TLV (127), length 9: OUI IEEE 802.3 Private (0x00120f)
+	  Link aggregation Subtype (3)
+	    aggregation status [supported], aggregation port ID 0
+	Organization specific TLV (127), length 9: OUI IEEE 802.3 Private (0x00120f)
+	  MAC/PHY configuration/status Subtype (1)
+	    autonegotiation [supported, enabled] (0x03)
+	    PMD autoneg capability [10BASE-T hdx, 10BASE-T fdx, 100BASE-TX hdx, 100BASE-TX fdx, Pause for fdx links, Asym PAUSE for fdx, 1000BASE-T hdx, 1000BASE-T fdx] (0xecc3)
+	    MAU type 100BASETX fdx (0x0010)
+	Organization specific TLV (127), length 64: OUI IANA (0x00005e)
+	  MUD-URL Subtype (1)
+	  MUD-URL=https://imright.mud.example.com/.well-known/mud/v1/vomitv2.0
+	End TLV (0), length 0
+00:23:54:c2:57:02 > 01:80:c2:00:00:0e, ethertype LLDP (0x88cc), length 302: LLDP, length 288
+	Chassis ID TLV (1), length 7
+	  Subtype MAC address (4): 00:23:54:c2:57:02
+	Port ID TLV (2), length 7
+	  Subtype MAC address (3): 00:23:54:c2:57:02
+	Time to Live TLV (3), length 2: TTL 120s
+	System Name TLV (5), length 28: upstairs.ofcourseimright.com
+	System Description TLV (6), length 92
+	  Ubuntu 14.04.5 LTS Linux 3.13.0-106-generic #153-Ubuntu SMP Tue Dec 6 15:45:13 UTC 2016 i686
+	System Capabilities TLV (7), length 4
+	  System  Capabilities [Bridge, WLAN AP, Router, Station Only] (0x009c)
+	  Enabled Capabilities [WLAN AP] (0x0008)
+	Management Address TLV (8), length 12
+	  Management Address length 5, AFI IPv4 (1): 62.12.173.114
+	  Interface Index Interface Numbering (2): 2
+	Management Address TLV (8), length 24
+	  Management Address length 17, AFI IPv6 (2): 2001:8a8:1006:4:223:54ff:fec2:5702
+	  Interface Index Interface Numbering (2): 2
+	Port Description TLV (4), length 4: eth0
+	Organization specific TLV (127), length 9: OUI IEEE 802.3 Private (0x00120f)
+	  Link aggregation Subtype (3)
+	    aggregation status [supported], aggregation port ID 0
+	Organization specific TLV (127), length 9: OUI IEEE 802.3 Private (0x00120f)
+	  MAC/PHY configuration/status Subtype (1)
+	    autonegotiation [supported, enabled] (0x03)
+	    PMD autoneg capability [10BASE-T hdx, 10BASE-T fdx, 100BASE-TX hdx, 100BASE-TX fdx, Pause for fdx links, Asym PAUSE for fdx, 1000BASE-T hdx, 1000BASE-T fdx] (0xecc3)
+	    MAU type 100BASETX fdx (0x0010)
+	Organization specific TLV (127), length 64: OUI IANA (0x00005e)
+	  MUD-URL Subtype (1)
+	  MUD-URL=https://imright.mud.example.com/.well-known/mud/v1/vomitv2.0
+	End TLV (0), length 0
diff --git a/tests/lldp_mudurl-vv.out b/tests/lldp_mudurl-vv.out
new file mode 100644
index 0000000..5564898
--- /dev/null
+++ b/tests/lldp_mudurl-vv.out
@@ -0,0 +1,106 @@
+00:23:54:c2:57:02 > 01:80:c2:00:00:0e, ethertype LLDP (0x88cc), length 302: LLDP, length 288
+	Chassis ID TLV (1), length 7
+	  Subtype MAC address (4): 00:23:54:c2:57:02
+	  0x0000:  0400 2354 c257 02
+	Port ID TLV (2), length 7
+	  Subtype MAC address (3): 00:23:54:c2:57:02
+	  0x0000:  0300 2354 c257 02
+	Time to Live TLV (3), length 2: TTL 120s
+	  0x0000:  0078
+	System Name TLV (5), length 28: upstairs.ofcourseimright.com
+	  0x0000:  7570 7374 6169 7273 2e6f 6663 6f75 7273
+	  0x0010:  6569 6d72 6967 6874 2e63 6f6d
+	System Description TLV (6), length 92
+	  Ubuntu 14.04.5 LTS Linux 3.13.0-106-generic #153-Ubuntu SMP Tue Dec 6 15:45:13 UTC 2016 i686
+	  0x0000:  5562 756e 7475 2031 342e 3034 2e35 204c
+	  0x0010:  5453 204c 696e 7578 2033 2e31 332e 302d
+	  0x0020:  3130 362d 6765 6e65 7269 6320 2331 3533
+	  0x0030:  2d55 6275 6e74 7520 534d 5020 5475 6520
+	  0x0040:  4465 6320 3620 3135 3a34 353a 3133 2055
+	  0x0050:  5443 2032 3031 3620 6936 3836
+	System Capabilities TLV (7), length 4
+	  System  Capabilities [Bridge, WLAN AP, Router, Station Only] (0x009c)
+	  Enabled Capabilities [WLAN AP] (0x0008)
+	  0x0000:  009c 0008
+	Management Address TLV (8), length 12
+	  Management Address length 5, AFI IPv4 (1): 62.12.173.114
+	  Interface Index Interface Numbering (2): 2
+	  0x0000:  0501 3e0c ad72 0200 0000 0200
+	Management Address TLV (8), length 24
+	  Management Address length 17, AFI IPv6 (2): 2001:8a8:1006:4:223:54ff:fec2:5702
+	  Interface Index Interface Numbering (2): 2
+	  0x0000:  1102 2001 08a8 1006 0004 0223 54ff fec2
+	  0x0010:  5702 0200 0000 0200
+	Port Description TLV (4), length 4: eth0
+	  0x0000:  6574 6830
+	Organization specific TLV (127), length 9: OUI IEEE 802.3 Private (0x00120f)
+	  Link aggregation Subtype (3)
+	    aggregation status [supported], aggregation port ID 0
+	  0x0000:  0012 0f03 0100 0000 00
+	Organization specific TLV (127), length 9: OUI IEEE 802.3 Private (0x00120f)
+	  MAC/PHY configuration/status Subtype (1)
+	    autonegotiation [supported, enabled] (0x03)
+	    PMD autoneg capability [10BASE-T hdx, 10BASE-T fdx, 100BASE-TX hdx, 100BASE-TX fdx, Pause for fdx links, Asym PAUSE for fdx, 1000BASE-T hdx, 1000BASE-T fdx] (0xecc3)
+	    MAU type 100BASETX fdx (0x0010)
+	  0x0000:  0012 0f01 03ec c300 10
+	Organization specific TLV (127), length 64: OUI IANA (0x00005e)
+	  MUD-URL Subtype (1)
+	  MUD-URL=https://imright.mud.example.com/.well-known/mud/v1/vomitv2.0
+	  0x0000:  0000 5e01 6874 7470 733a 2f2f 696d 7269
+	  0x0010:  6768 742e 6d75 642e 6578 616d 706c 652e
+	  0x0020:  636f 6d2f 2e77 656c 6c2d 6b6e 6f77 6e2f
+	  0x0030:  6d75 642f 7631 2f76 6f6d 6974 7632 2e30
+	End TLV (0), length 0
+00:23:54:c2:57:02 > 01:80:c2:00:00:0e, ethertype LLDP (0x88cc), length 302: LLDP, length 288
+	Chassis ID TLV (1), length 7
+	  Subtype MAC address (4): 00:23:54:c2:57:02
+	  0x0000:  0400 2354 c257 02
+	Port ID TLV (2), length 7
+	  Subtype MAC address (3): 00:23:54:c2:57:02
+	  0x0000:  0300 2354 c257 02
+	Time to Live TLV (3), length 2: TTL 120s
+	  0x0000:  0078
+	System Name TLV (5), length 28: upstairs.ofcourseimright.com
+	  0x0000:  7570 7374 6169 7273 2e6f 6663 6f75 7273
+	  0x0010:  6569 6d72 6967 6874 2e63 6f6d
+	System Description TLV (6), length 92
+	  Ubuntu 14.04.5 LTS Linux 3.13.0-106-generic #153-Ubuntu SMP Tue Dec 6 15:45:13 UTC 2016 i686
+	  0x0000:  5562 756e 7475 2031 342e 3034 2e35 204c
+	  0x0010:  5453 204c 696e 7578 2033 2e31 332e 302d
+	  0x0020:  3130 362d 6765 6e65 7269 6320 2331 3533
+	  0x0030:  2d55 6275 6e74 7520 534d 5020 5475 6520
+	  0x0040:  4465 6320 3620 3135 3a34 353a 3133 2055
+	  0x0050:  5443 2032 3031 3620 6936 3836
+	System Capabilities TLV (7), length 4
+	  System  Capabilities [Bridge, WLAN AP, Router, Station Only] (0x009c)
+	  Enabled Capabilities [WLAN AP] (0x0008)
+	  0x0000:  009c 0008
+	Management Address TLV (8), length 12
+	  Management Address length 5, AFI IPv4 (1): 62.12.173.114
+	  Interface Index Interface Numbering (2): 2
+	  0x0000:  0501 3e0c ad72 0200 0000 0200
+	Management Address TLV (8), length 24
+	  Management Address length 17, AFI IPv6 (2): 2001:8a8:1006:4:223:54ff:fec2:5702
+	  Interface Index Interface Numbering (2): 2
+	  0x0000:  1102 2001 08a8 1006 0004 0223 54ff fec2
+	  0x0010:  5702 0200 0000 0200
+	Port Description TLV (4), length 4: eth0
+	  0x0000:  6574 6830
+	Organization specific TLV (127), length 9: OUI IEEE 802.3 Private (0x00120f)
+	  Link aggregation Subtype (3)
+	    aggregation status [supported], aggregation port ID 0
+	  0x0000:  0012 0f03 0100 0000 00
+	Organization specific TLV (127), length 9: OUI IEEE 802.3 Private (0x00120f)
+	  MAC/PHY configuration/status Subtype (1)
+	    autonegotiation [supported, enabled] (0x03)
+	    PMD autoneg capability [10BASE-T hdx, 10BASE-T fdx, 100BASE-TX hdx, 100BASE-TX fdx, Pause for fdx links, Asym PAUSE for fdx, 1000BASE-T hdx, 1000BASE-T fdx] (0xecc3)
+	    MAU type 100BASETX fdx (0x0010)
+	  0x0000:  0012 0f01 03ec c300 10
+	Organization specific TLV (127), length 64: OUI IANA (0x00005e)
+	  MUD-URL Subtype (1)
+	  MUD-URL=https://imright.mud.example.com/.well-known/mud/v1/vomitv2.0
+	  0x0000:  0000 5e01 6874 7470 733a 2f2f 696d 7269
+	  0x0010:  6768 742e 6d75 642e 6578 616d 706c 652e
+	  0x0020:  636f 6d2f 2e77 656c 6c2d 6b6e 6f77 6e2f
+	  0x0030:  6d75 642f 7631 2f76 6f6d 6974 7632 2e30
+	End TLV (0), length 0
diff --git a/tests/lldp_mudurl.pcap b/tests/lldp_mudurl.pcap
new file mode 100644
index 0000000..49d83a3
--- /dev/null
+++ b/tests/lldp_mudurl.pcap
Binary files differ
diff --git a/tests/lmp-v.sh b/tests/lmp-v.sh
index 138a0cd..1c286bf 100755
--- a/tests/lmp-v.sh
+++ b/tests/lmp-v.sh
@@ -10,10 +10,10 @@
 # that won't return an error when the file does not exist. Work around.
 if [ ! -f ../Makefile ]
 then
-	printf '    %-30s: TEST SKIPPED (no Makefile)\n' 'lmp-v'
+	printf '    %-35s: TEST SKIPPED (no Makefile)\n' 'lmp-v'
 elif grep '^CC = .*gcc' ../Makefile >/dev/null
 then
   ./TESTonce lmp-v lmp.pcap lmp-v.out '-t -T lmp -v'
 else
-	printf '    %-30s: TEST SKIPPED (compiler is not GCC)\n' 'lmp-v'
+	printf '    %-35s: TEST SKIPPED (compiler is not GCC)\n' 'lmp-v'
 fi
diff --git a/tests/lspping-fec-ldp-v.out b/tests/lspping-fec-ldp-v.out
new file mode 100644
index 0000000..e4a886b
--- /dev/null
+++ b/tests/lspping-fec-ldp-v.out
@@ -0,0 +1,111 @@
+MPLS (label 100656, exp 6, [S], ttl 64)
+	IP (tos 0xc0, ttl 64, id 40719, offset 0, flags [none], proto TCP (6), length 71)
+    12.4.4.4.4100 > 12.8.8.8.179: Flags [P.], cksum 0xfd1b (correct), seq 1860641958:1860641977, ack 2969468967, win 16384, options [nop,nop,TS val 84784152 ecr 84770238], length 19: BGP
+	Keepalive Message (4), length: 19
+MPLS (label 100688, exp 7, [S], ttl 255)
+	IP (tos 0x0, ttl 64, id 40723, offset 0, flags [none], proto UDP (17), length 76)
+    12.4.4.4.4786 > 127.0.0.1.3503: 
+	LSP-PINGv1, msg-type: MPLS Echo Request (1), length: 48
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: No return code or return code contained in the Error Code TLV (0)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 1
+	  Sender Timestamp: Receiver Timestamp: no timestamp
+	  Target FEC Stack TLV (1), length: 12
+	    LDP IPv4 prefix subTLV (1), length: 5
+	      12.1.1.1/32
+IP (tos 0xc0, ttl 62, id 50878, offset 0, flags [none], proto UDP (17), length 60)
+    10.20.0.1.3503 > 12.4.4.4.4786: 
+	LSP-PINGv1, msg-type: MPLS Echo Reply (2), length: 32
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: Replying router is an egress for the FEC at stack depth 0 (3)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 1
+	  Sender Timestamp: Receiver Timestamp: 
+MPLS (label 100704, exp 6, [S], ttl 64)
+	IP (tos 0xc0, ttl 64, id 40725, offset 0, flags [none], proto TCP (6), length 71)
+    12.4.4.4.2006 > 12.1.1.1.179: Flags [P.], cksum 0x6c0d (correct), seq 399708866:399708885, ack 708613212, win 16384, options [nop,nop,TS val 84784455 ecr 130411], length 19: BGP
+	Keepalive Message (4), length: 19
+MPLS (label 100704, exp 6, [S], ttl 64)
+	IP (tos 0xc0, ttl 64, id 40726, offset 0, flags [none], proto TCP (6), length 52)
+    12.4.4.4.2006 > 12.1.1.1.179: Flags [.], cksum 0x6451 (correct), ack 20, win 16384, options [nop,nop,TS val 84784465 ecr 133413], length 0
+MPLS (label 100688, exp 7, [S], ttl 255)
+	IP (tos 0x0, ttl 64, id 40727, offset 0, flags [none], proto UDP (17), length 76)
+    12.4.4.4.4786 > 127.0.0.1.3503: 
+	LSP-PINGv1, msg-type: MPLS Echo Request (1), length: 48
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: No return code or return code contained in the Error Code TLV (0)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 2
+	  Sender Timestamp: Receiver Timestamp: no timestamp
+	  Target FEC Stack TLV (1), length: 12
+	    LDP IPv4 prefix subTLV (1), length: 5
+	      12.1.1.1/32
+IP (tos 0xc0, ttl 62, id 50880, offset 0, flags [none], proto UDP (17), length 60)
+    10.20.0.1.3503 > 12.4.4.4.4786: 
+	LSP-PINGv1, msg-type: MPLS Echo Reply (2), length: 32
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: Replying router is an egress for the FEC at stack depth 0 (3)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 2
+	  Sender Timestamp: Receiver Timestamp: 
+MPLS (label 100688, exp 7, [S], ttl 255)
+	IP (tos 0x0, ttl 64, id 40729, offset 0, flags [none], proto UDP (17), length 76)
+    12.4.4.4.4786 > 127.0.0.1.3503: 
+	LSP-PINGv1, msg-type: MPLS Echo Request (1), length: 48
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: No return code or return code contained in the Error Code TLV (0)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 3
+	  Sender Timestamp: Receiver Timestamp: no timestamp
+	  Target FEC Stack TLV (1), length: 12
+	    LDP IPv4 prefix subTLV (1), length: 5
+	      12.1.1.1/32
+IP (tos 0xc0, ttl 62, id 50882, offset 0, flags [none], proto UDP (17), length 60)
+    10.20.0.1.3503 > 12.4.4.4.4786: 
+	LSP-PINGv1, msg-type: MPLS Echo Reply (2), length: 32
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: Replying router is an egress for the FEC at stack depth 0 (3)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 3
+	  Sender Timestamp: Receiver Timestamp: 
+MPLS (label 100688, exp 7, [S], ttl 255)
+	IP (tos 0x0, ttl 64, id 40731, offset 0, flags [none], proto UDP (17), length 76)
+    12.4.4.4.4786 > 127.0.0.1.3503: 
+	LSP-PINGv1, msg-type: MPLS Echo Request (1), length: 48
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: No return code or return code contained in the Error Code TLV (0)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 4
+	  Sender Timestamp: Receiver Timestamp: no timestamp
+	  Target FEC Stack TLV (1), length: 12
+	    LDP IPv4 prefix subTLV (1), length: 5
+	      12.1.1.1/32
+IP (tos 0xc0, ttl 62, id 50883, offset 0, flags [none], proto UDP (17), length 60)
+    10.20.0.1.3503 > 12.4.4.4.4786: 
+	LSP-PINGv1, msg-type: MPLS Echo Reply (2), length: 32
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: Replying router is an egress for the FEC at stack depth 0 (3)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 4
+	  Sender Timestamp: Receiver Timestamp: 
+MPLS (label 100688, exp 7, [S], ttl 255)
+	IP (tos 0x0, ttl 64, id 40733, offset 0, flags [none], proto UDP (17), length 76)
+    12.4.4.4.4786 > 127.0.0.1.3503: 
+	LSP-PINGv1, msg-type: MPLS Echo Request (1), length: 48
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: No return code or return code contained in the Error Code TLV (0)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 5
+	  Sender Timestamp: Receiver Timestamp: no timestamp
+	  Target FEC Stack TLV (1), length: 12
+	    LDP IPv4 prefix subTLV (1), length: 5
+	      12.1.1.1/32
+IP (tos 0xc0, ttl 62, id 50886, offset 0, flags [none], proto UDP (17), length 60)
+    10.20.0.1.3503 > 12.4.4.4.4786: 
+	LSP-PINGv1, msg-type: MPLS Echo Reply (2), length: 32
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: Replying router is an egress for the FEC at stack depth 0 (3)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 5
+	  Sender Timestamp: Receiver Timestamp: 
diff --git a/tests/lspping-fec-ldp-vv.out b/tests/lspping-fec-ldp-vv.out
new file mode 100644
index 0000000..af0d1f6
--- /dev/null
+++ b/tests/lspping-fec-ldp-vv.out
@@ -0,0 +1,121 @@
+MPLS (label 100656, exp 6, [S], ttl 64)
+	IP (tos 0xc0, ttl 64, id 40719, offset 0, flags [none], proto TCP (6), length 71)
+    12.4.4.4.4100 > 12.8.8.8.179: Flags [P.], cksum 0xfd1b (correct), seq 1860641958:1860641977, ack 2969468967, win 16384, options [nop,nop,TS val 84784152 ecr 84770238], length 19: BGP
+	Keepalive Message (4), length: 19
+MPLS (label 100688, exp 7, [S], ttl 255)
+	IP (tos 0x0, ttl 64, id 40723, offset 0, flags [none], proto UDP (17), length 76)
+    12.4.4.4.4786 > 127.0.0.1.3503: [udp sum ok] 
+	LSP-PINGv1, msg-type: MPLS Echo Request (1), length: 48
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: No return code or return code contained in the Error Code TLV (0)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 1
+	  Sender Timestamp: Receiver Timestamp: no timestamp
+	  Target FEC Stack TLV (1), length: 12
+	    LDP IPv4 prefix subTLV (1), length: 5
+	      12.1.1.1/32
+	      0x0000:  0c01 0101 20
+	    0x0000:  0001 0005 0c01 0101 2000 0000
+IP (tos 0xc0, ttl 62, id 50878, offset 0, flags [none], proto UDP (17), length 60)
+    10.20.0.1.3503 > 12.4.4.4.4786: [udp sum ok] 
+	LSP-PINGv1, msg-type: MPLS Echo Reply (2), length: 32
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: Replying router is an egress for the FEC at stack depth 0 (3)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 1
+	  Sender Timestamp: Receiver Timestamp: 
+MPLS (label 100704, exp 6, [S], ttl 64)
+	IP (tos 0xc0, ttl 64, id 40725, offset 0, flags [none], proto TCP (6), length 71)
+    12.4.4.4.2006 > 12.1.1.1.179: Flags [P.], cksum 0x6c0d (correct), seq 399708866:399708885, ack 708613212, win 16384, options [nop,nop,TS val 84784455 ecr 130411], length 19: BGP
+	Keepalive Message (4), length: 19
+MPLS (label 100704, exp 6, [S], ttl 64)
+	IP (tos 0xc0, ttl 64, id 40726, offset 0, flags [none], proto TCP (6), length 52)
+    12.4.4.4.2006 > 12.1.1.1.179: Flags [.], cksum 0x6451 (correct), seq 19, ack 20, win 16384, options [nop,nop,TS val 84784465 ecr 133413], length 0
+MPLS (label 100688, exp 7, [S], ttl 255)
+	IP (tos 0x0, ttl 64, id 40727, offset 0, flags [none], proto UDP (17), length 76)
+    12.4.4.4.4786 > 127.0.0.1.3503: [udp sum ok] 
+	LSP-PINGv1, msg-type: MPLS Echo Request (1), length: 48
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: No return code or return code contained in the Error Code TLV (0)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 2
+	  Sender Timestamp: Receiver Timestamp: no timestamp
+	  Target FEC Stack TLV (1), length: 12
+	    LDP IPv4 prefix subTLV (1), length: 5
+	      12.1.1.1/32
+	      0x0000:  0c01 0101 20
+	    0x0000:  0001 0005 0c01 0101 2000 0000
+IP (tos 0xc0, ttl 62, id 50880, offset 0, flags [none], proto UDP (17), length 60)
+    10.20.0.1.3503 > 12.4.4.4.4786: [udp sum ok] 
+	LSP-PINGv1, msg-type: MPLS Echo Reply (2), length: 32
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: Replying router is an egress for the FEC at stack depth 0 (3)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 2
+	  Sender Timestamp: Receiver Timestamp: 
+MPLS (label 100688, exp 7, [S], ttl 255)
+	IP (tos 0x0, ttl 64, id 40729, offset 0, flags [none], proto UDP (17), length 76)
+    12.4.4.4.4786 > 127.0.0.1.3503: [udp sum ok] 
+	LSP-PINGv1, msg-type: MPLS Echo Request (1), length: 48
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: No return code or return code contained in the Error Code TLV (0)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 3
+	  Sender Timestamp: Receiver Timestamp: no timestamp
+	  Target FEC Stack TLV (1), length: 12
+	    LDP IPv4 prefix subTLV (1), length: 5
+	      12.1.1.1/32
+	      0x0000:  0c01 0101 20
+	    0x0000:  0001 0005 0c01 0101 2000 0000
+IP (tos 0xc0, ttl 62, id 50882, offset 0, flags [none], proto UDP (17), length 60)
+    10.20.0.1.3503 > 12.4.4.4.4786: [udp sum ok] 
+	LSP-PINGv1, msg-type: MPLS Echo Reply (2), length: 32
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: Replying router is an egress for the FEC at stack depth 0 (3)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 3
+	  Sender Timestamp: Receiver Timestamp: 
+MPLS (label 100688, exp 7, [S], ttl 255)
+	IP (tos 0x0, ttl 64, id 40731, offset 0, flags [none], proto UDP (17), length 76)
+    12.4.4.4.4786 > 127.0.0.1.3503: [udp sum ok] 
+	LSP-PINGv1, msg-type: MPLS Echo Request (1), length: 48
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: No return code or return code contained in the Error Code TLV (0)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 4
+	  Sender Timestamp: Receiver Timestamp: no timestamp
+	  Target FEC Stack TLV (1), length: 12
+	    LDP IPv4 prefix subTLV (1), length: 5
+	      12.1.1.1/32
+	      0x0000:  0c01 0101 20
+	    0x0000:  0001 0005 0c01 0101 2000 0000
+IP (tos 0xc0, ttl 62, id 50883, offset 0, flags [none], proto UDP (17), length 60)
+    10.20.0.1.3503 > 12.4.4.4.4786: [udp sum ok] 
+	LSP-PINGv1, msg-type: MPLS Echo Reply (2), length: 32
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: Replying router is an egress for the FEC at stack depth 0 (3)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 4
+	  Sender Timestamp: Receiver Timestamp: 
+MPLS (label 100688, exp 7, [S], ttl 255)
+	IP (tos 0x0, ttl 64, id 40733, offset 0, flags [none], proto UDP (17), length 76)
+    12.4.4.4.4786 > 127.0.0.1.3503: [udp sum ok] 
+	LSP-PINGv1, msg-type: MPLS Echo Request (1), length: 48
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: No return code or return code contained in the Error Code TLV (0)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 5
+	  Sender Timestamp: Receiver Timestamp: no timestamp
+	  Target FEC Stack TLV (1), length: 12
+	    LDP IPv4 prefix subTLV (1), length: 5
+	      12.1.1.1/32
+	      0x0000:  0c01 0101 20
+	    0x0000:  0001 0005 0c01 0101 2000 0000
+IP (tos 0xc0, ttl 62, id 50886, offset 0, flags [none], proto UDP (17), length 60)
+    10.20.0.1.3503 > 12.4.4.4.4786: [udp sum ok] 
+	LSP-PINGv1, msg-type: MPLS Echo Reply (2), length: 32
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: Replying router is an egress for the FEC at stack depth 0 (3)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 5
+	  Sender Timestamp: Receiver Timestamp: 
diff --git a/tests/lspping-fec-ldp.out b/tests/lspping-fec-ldp.out
new file mode 100644
index 0000000..2df8b4c
--- /dev/null
+++ b/tests/lspping-fec-ldp.out
@@ -0,0 +1,13 @@
+MPLS (label 100656, exp 6, [S], ttl 64) IP 12.4.4.4.4100 > 12.8.8.8.179: Flags [P.], seq 1860641958:1860641977, ack 2969468967, win 16384, options [nop,nop,TS val 84784152 ecr 84770238], length 19: BGP
+MPLS (label 100688, exp 7, [S], ttl 255) IP 12.4.4.4.4786 > 127.0.0.1.3503: LSP-PINGv1, MPLS Echo Request, seq 1, length: 48
+IP 10.20.0.1.3503 > 12.4.4.4.4786: LSP-PINGv1, MPLS Echo Reply, seq 1, length: 32
+MPLS (label 100704, exp 6, [S], ttl 64) IP 12.4.4.4.2006 > 12.1.1.1.179: Flags [P.], seq 399708866:399708885, ack 708613212, win 16384, options [nop,nop,TS val 84784455 ecr 130411], length 19: BGP
+MPLS (label 100704, exp 6, [S], ttl 64) IP 12.4.4.4.2006 > 12.1.1.1.179: Flags [.], ack 20, win 16384, options [nop,nop,TS val 84784465 ecr 133413], length 0
+MPLS (label 100688, exp 7, [S], ttl 255) IP 12.4.4.4.4786 > 127.0.0.1.3503: LSP-PINGv1, MPLS Echo Request, seq 2, length: 48
+IP 10.20.0.1.3503 > 12.4.4.4.4786: LSP-PINGv1, MPLS Echo Reply, seq 2, length: 32
+MPLS (label 100688, exp 7, [S], ttl 255) IP 12.4.4.4.4786 > 127.0.0.1.3503: LSP-PINGv1, MPLS Echo Request, seq 3, length: 48
+IP 10.20.0.1.3503 > 12.4.4.4.4786: LSP-PINGv1, MPLS Echo Reply, seq 3, length: 32
+MPLS (label 100688, exp 7, [S], ttl 255) IP 12.4.4.4.4786 > 127.0.0.1.3503: LSP-PINGv1, MPLS Echo Request, seq 4, length: 48
+IP 10.20.0.1.3503 > 12.4.4.4.4786: LSP-PINGv1, MPLS Echo Reply, seq 4, length: 32
+MPLS (label 100688, exp 7, [S], ttl 255) IP 12.4.4.4.4786 > 127.0.0.1.3503: LSP-PINGv1, MPLS Echo Request, seq 5, length: 48
+IP 10.20.0.1.3503 > 12.4.4.4.4786: LSP-PINGv1, MPLS Echo Reply, seq 5, length: 32
diff --git a/tests/lspping-fec-rsvp-v.out b/tests/lspping-fec-rsvp-v.out
new file mode 100644
index 0000000..f79043e
--- /dev/null
+++ b/tests/lspping-fec-rsvp-v.out
@@ -0,0 +1,105 @@
+MPLS (label 100704, exp 7, [S], ttl 255)
+	IP (tos 0x0, ttl 64, id 40269, offset 0, flags [none], proto UDP (17), length 88)
+    12.4.4.4.4529 > 127.0.0.1.3503: 
+	LSP-PINGv1, msg-type: MPLS Echo Request (1), length: 60
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: No return code or return code contained in the Error Code TLV (0)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 1
+	  Sender Timestamp: Receiver Timestamp: no timestamp
+	  Target FEC Stack TLV (1), length: 24
+	    RSVP IPv4 Session Query subTLV (3), length: 20
+	      tunnel end-point 12.1.1.1, tunnel sender 12.4.4.4, lsp-id 0x0010
+	      tunnel-id 0x5372, extended tunnel-id 12.4.4.4
+IP (tos 0xc0, ttl 62, id 50634, offset 0, flags [none], proto UDP (17), length 60)
+    10.20.0.1.3503 > 12.4.4.4.4529: 
+	LSP-PINGv1, msg-type: MPLS Echo Reply (2), length: 32
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: Replying router is an egress for the FEC at stack depth 0 (3)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 1
+	  Sender Timestamp: Receiver Timestamp: 
+MPLS (label 100704, exp 7, [S], ttl 255)
+	IP (tos 0x0, ttl 64, id 40271, offset 0, flags [none], proto UDP (17), length 88)
+    12.4.4.4.4529 > 127.0.0.1.3503: 
+	LSP-PINGv1, msg-type: MPLS Echo Request (1), length: 60
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: No return code or return code contained in the Error Code TLV (0)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 2
+	  Sender Timestamp: Receiver Timestamp: no timestamp
+	  Target FEC Stack TLV (1), length: 24
+	    RSVP IPv4 Session Query subTLV (3), length: 20
+	      tunnel end-point 12.1.1.1, tunnel sender 12.4.4.4, lsp-id 0x0010
+	      tunnel-id 0x5372, extended tunnel-id 12.4.4.4
+IP (tos 0xc0, ttl 62, id 50635, offset 0, flags [none], proto UDP (17), length 60)
+    10.20.0.1.3503 > 12.4.4.4.4529: 
+	LSP-PINGv1, msg-type: MPLS Echo Reply (2), length: 32
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: Replying router is an egress for the FEC at stack depth 0 (3)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 2
+	  Sender Timestamp: Receiver Timestamp: 
+MPLS (label 100704, exp 7, [S], ttl 255)
+	IP (tos 0x0, ttl 64, id 40273, offset 0, flags [none], proto UDP (17), length 88)
+    12.4.4.4.4529 > 127.0.0.1.3503: 
+	LSP-PINGv1, msg-type: MPLS Echo Request (1), length: 60
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: No return code or return code contained in the Error Code TLV (0)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 3
+	  Sender Timestamp: Receiver Timestamp: no timestamp
+	  Target FEC Stack TLV (1), length: 24
+	    RSVP IPv4 Session Query subTLV (3), length: 20
+	      tunnel end-point 12.1.1.1, tunnel sender 12.4.4.4, lsp-id 0x0010
+	      tunnel-id 0x5372, extended tunnel-id 12.4.4.4
+IP (tos 0xc0, ttl 62, id 50637, offset 0, flags [none], proto UDP (17), length 60)
+    10.20.0.1.3503 > 12.4.4.4.4529: 
+	LSP-PINGv1, msg-type: MPLS Echo Reply (2), length: 32
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: Replying router is an egress for the FEC at stack depth 0 (3)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 3
+	  Sender Timestamp: Receiver Timestamp: 
+MPLS (label 100704, exp 7, [S], ttl 255)
+	IP (tos 0x0, ttl 64, id 40275, offset 0, flags [none], proto UDP (17), length 88)
+    12.4.4.4.4529 > 127.0.0.1.3503: 
+	LSP-PINGv1, msg-type: MPLS Echo Request (1), length: 60
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: No return code or return code contained in the Error Code TLV (0)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 4
+	  Sender Timestamp: Receiver Timestamp: no timestamp
+	  Target FEC Stack TLV (1), length: 24
+	    RSVP IPv4 Session Query subTLV (3), length: 20
+	      tunnel end-point 12.1.1.1, tunnel sender 12.4.4.4, lsp-id 0x0010
+	      tunnel-id 0x5372, extended tunnel-id 12.4.4.4
+IP (tos 0xc0, ttl 62, id 50638, offset 0, flags [none], proto UDP (17), length 60)
+    10.20.0.1.3503 > 12.4.4.4.4529: 
+	LSP-PINGv1, msg-type: MPLS Echo Reply (2), length: 32
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: Replying router is an egress for the FEC at stack depth 0 (3)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 4
+	  Sender Timestamp: Receiver Timestamp: 
+MPLS (label 100704, exp 7, [S], ttl 255)
+	IP (tos 0x0, ttl 64, id 40278, offset 0, flags [none], proto UDP (17), length 88)
+    12.4.4.4.4529 > 127.0.0.1.3503: 
+	LSP-PINGv1, msg-type: MPLS Echo Request (1), length: 60
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: No return code or return code contained in the Error Code TLV (0)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 5
+	  Sender Timestamp: Receiver Timestamp: no timestamp
+	  Target FEC Stack TLV (1), length: 24
+	    RSVP IPv4 Session Query subTLV (3), length: 20
+	      tunnel end-point 12.1.1.1, tunnel sender 12.4.4.4, lsp-id 0x0010
+	      tunnel-id 0x5372, extended tunnel-id 12.4.4.4
+IP (tos 0xc0, ttl 62, id 50641, offset 0, flags [none], proto UDP (17), length 60)
+    10.20.0.1.3503 > 12.4.4.4.4529: 
+	LSP-PINGv1, msg-type: MPLS Echo Reply (2), length: 32
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: Replying router is an egress for the FEC at stack depth 0 (3)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 5
+	  Sender Timestamp: Receiver Timestamp: 
diff --git a/tests/lspping-fec-rsvp-vv.out b/tests/lspping-fec-rsvp-vv.out
new file mode 100644
index 0000000..391dc5a
--- /dev/null
+++ b/tests/lspping-fec-rsvp-vv.out
@@ -0,0 +1,125 @@
+MPLS (label 100704, exp 7, [S], ttl 255)
+	IP (tos 0x0, ttl 64, id 40269, offset 0, flags [none], proto UDP (17), length 88)
+    12.4.4.4.4529 > 127.0.0.1.3503: [udp sum ok] 
+	LSP-PINGv1, msg-type: MPLS Echo Request (1), length: 60
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: No return code or return code contained in the Error Code TLV (0)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 1
+	  Sender Timestamp: Receiver Timestamp: no timestamp
+	  Target FEC Stack TLV (1), length: 24
+	    RSVP IPv4 Session Query subTLV (3), length: 20
+	      tunnel end-point 12.1.1.1, tunnel sender 12.4.4.4, lsp-id 0x0010
+	      tunnel-id 0x5372, extended tunnel-id 12.4.4.4
+	      0x0000:  0c01 0101 0000 5372 0c04 0404 0c04 0404
+	      0x0010:  0000 0010
+	    0x0000:  0003 0014 0c01 0101 0000 5372 0c04 0404
+	    0x0010:  0c04 0404 0000 0010
+IP (tos 0xc0, ttl 62, id 50634, offset 0, flags [none], proto UDP (17), length 60)
+    10.20.0.1.3503 > 12.4.4.4.4529: [udp sum ok] 
+	LSP-PINGv1, msg-type: MPLS Echo Reply (2), length: 32
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: Replying router is an egress for the FEC at stack depth 0 (3)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 1
+	  Sender Timestamp: Receiver Timestamp: 
+MPLS (label 100704, exp 7, [S], ttl 255)
+	IP (tos 0x0, ttl 64, id 40271, offset 0, flags [none], proto UDP (17), length 88)
+    12.4.4.4.4529 > 127.0.0.1.3503: [udp sum ok] 
+	LSP-PINGv1, msg-type: MPLS Echo Request (1), length: 60
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: No return code or return code contained in the Error Code TLV (0)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 2
+	  Sender Timestamp: Receiver Timestamp: no timestamp
+	  Target FEC Stack TLV (1), length: 24
+	    RSVP IPv4 Session Query subTLV (3), length: 20
+	      tunnel end-point 12.1.1.1, tunnel sender 12.4.4.4, lsp-id 0x0010
+	      tunnel-id 0x5372, extended tunnel-id 12.4.4.4
+	      0x0000:  0c01 0101 0000 5372 0c04 0404 0c04 0404
+	      0x0010:  0000 0010
+	    0x0000:  0003 0014 0c01 0101 0000 5372 0c04 0404
+	    0x0010:  0c04 0404 0000 0010
+IP (tos 0xc0, ttl 62, id 50635, offset 0, flags [none], proto UDP (17), length 60)
+    10.20.0.1.3503 > 12.4.4.4.4529: [udp sum ok] 
+	LSP-PINGv1, msg-type: MPLS Echo Reply (2), length: 32
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: Replying router is an egress for the FEC at stack depth 0 (3)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 2
+	  Sender Timestamp: Receiver Timestamp: 
+MPLS (label 100704, exp 7, [S], ttl 255)
+	IP (tos 0x0, ttl 64, id 40273, offset 0, flags [none], proto UDP (17), length 88)
+    12.4.4.4.4529 > 127.0.0.1.3503: [udp sum ok] 
+	LSP-PINGv1, msg-type: MPLS Echo Request (1), length: 60
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: No return code or return code contained in the Error Code TLV (0)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 3
+	  Sender Timestamp: Receiver Timestamp: no timestamp
+	  Target FEC Stack TLV (1), length: 24
+	    RSVP IPv4 Session Query subTLV (3), length: 20
+	      tunnel end-point 12.1.1.1, tunnel sender 12.4.4.4, lsp-id 0x0010
+	      tunnel-id 0x5372, extended tunnel-id 12.4.4.4
+	      0x0000:  0c01 0101 0000 5372 0c04 0404 0c04 0404
+	      0x0010:  0000 0010
+	    0x0000:  0003 0014 0c01 0101 0000 5372 0c04 0404
+	    0x0010:  0c04 0404 0000 0010
+IP (tos 0xc0, ttl 62, id 50637, offset 0, flags [none], proto UDP (17), length 60)
+    10.20.0.1.3503 > 12.4.4.4.4529: [udp sum ok] 
+	LSP-PINGv1, msg-type: MPLS Echo Reply (2), length: 32
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: Replying router is an egress for the FEC at stack depth 0 (3)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 3
+	  Sender Timestamp: Receiver Timestamp: 
+MPLS (label 100704, exp 7, [S], ttl 255)
+	IP (tos 0x0, ttl 64, id 40275, offset 0, flags [none], proto UDP (17), length 88)
+    12.4.4.4.4529 > 127.0.0.1.3503: [udp sum ok] 
+	LSP-PINGv1, msg-type: MPLS Echo Request (1), length: 60
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: No return code or return code contained in the Error Code TLV (0)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 4
+	  Sender Timestamp: Receiver Timestamp: no timestamp
+	  Target FEC Stack TLV (1), length: 24
+	    RSVP IPv4 Session Query subTLV (3), length: 20
+	      tunnel end-point 12.1.1.1, tunnel sender 12.4.4.4, lsp-id 0x0010
+	      tunnel-id 0x5372, extended tunnel-id 12.4.4.4
+	      0x0000:  0c01 0101 0000 5372 0c04 0404 0c04 0404
+	      0x0010:  0000 0010
+	    0x0000:  0003 0014 0c01 0101 0000 5372 0c04 0404
+	    0x0010:  0c04 0404 0000 0010
+IP (tos 0xc0, ttl 62, id 50638, offset 0, flags [none], proto UDP (17), length 60)
+    10.20.0.1.3503 > 12.4.4.4.4529: [udp sum ok] 
+	LSP-PINGv1, msg-type: MPLS Echo Reply (2), length: 32
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: Replying router is an egress for the FEC at stack depth 0 (3)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 4
+	  Sender Timestamp: Receiver Timestamp: 
+MPLS (label 100704, exp 7, [S], ttl 255)
+	IP (tos 0x0, ttl 64, id 40278, offset 0, flags [none], proto UDP (17), length 88)
+    12.4.4.4.4529 > 127.0.0.1.3503: [udp sum ok] 
+	LSP-PINGv1, msg-type: MPLS Echo Request (1), length: 60
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: No return code or return code contained in the Error Code TLV (0)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 5
+	  Sender Timestamp: Receiver Timestamp: no timestamp
+	  Target FEC Stack TLV (1), length: 24
+	    RSVP IPv4 Session Query subTLV (3), length: 20
+	      tunnel end-point 12.1.1.1, tunnel sender 12.4.4.4, lsp-id 0x0010
+	      tunnel-id 0x5372, extended tunnel-id 12.4.4.4
+	      0x0000:  0c01 0101 0000 5372 0c04 0404 0c04 0404
+	      0x0010:  0000 0010
+	    0x0000:  0003 0014 0c01 0101 0000 5372 0c04 0404
+	    0x0010:  0c04 0404 0000 0010
+IP (tos 0xc0, ttl 62, id 50641, offset 0, flags [none], proto UDP (17), length 60)
+    10.20.0.1.3503 > 12.4.4.4.4529: [udp sum ok] 
+	LSP-PINGv1, msg-type: MPLS Echo Reply (2), length: 32
+	  reply-mode: Reply via an IPv4/IPv6 UDP packet (2)
+	  Return Code: Replying router is an egress for the FEC at stack depth 0 (3)
+	  Return Subcode: (0)
+	  Sender Handle: 0x00000000, Sequence: 5
+	  Sender Timestamp: Receiver Timestamp: 
diff --git a/tests/lspping-fec-rsvp.out b/tests/lspping-fec-rsvp.out
new file mode 100644
index 0000000..7013fae
--- /dev/null
+++ b/tests/lspping-fec-rsvp.out
@@ -0,0 +1,10 @@
+MPLS (label 100704, exp 7, [S], ttl 255) IP 12.4.4.4.4529 > 127.0.0.1.3503: LSP-PINGv1, MPLS Echo Request, seq 1, length: 60
+IP 10.20.0.1.3503 > 12.4.4.4.4529: LSP-PINGv1, MPLS Echo Reply, seq 1, length: 32
+MPLS (label 100704, exp 7, [S], ttl 255) IP 12.4.4.4.4529 > 127.0.0.1.3503: LSP-PINGv1, MPLS Echo Request, seq 2, length: 60
+IP 10.20.0.1.3503 > 12.4.4.4.4529: LSP-PINGv1, MPLS Echo Reply, seq 2, length: 32
+MPLS (label 100704, exp 7, [S], ttl 255) IP 12.4.4.4.4529 > 127.0.0.1.3503: LSP-PINGv1, MPLS Echo Request, seq 3, length: 60
+IP 10.20.0.1.3503 > 12.4.4.4.4529: LSP-PINGv1, MPLS Echo Reply, seq 3, length: 32
+MPLS (label 100704, exp 7, [S], ttl 255) IP 12.4.4.4.4529 > 127.0.0.1.3503: LSP-PINGv1, MPLS Echo Request, seq 4, length: 60
+IP 10.20.0.1.3503 > 12.4.4.4.4529: LSP-PINGv1, MPLS Echo Reply, seq 4, length: 32
+MPLS (label 100704, exp 7, [S], ttl 255) IP 12.4.4.4.4529 > 127.0.0.1.3503: LSP-PINGv1, MPLS Echo Request, seq 5, length: 60
+IP 10.20.0.1.3503 > 12.4.4.4.4529: LSP-PINGv1, MPLS Echo Reply, seq 5, length: 32
diff --git a/tests/medsa-e.out b/tests/medsa-e.out
new file mode 100644
index 0000000..265be0d
--- /dev/null
+++ b/tests/medsa-e.out
@@ -0,0 +1,20 @@
+26:a1:fb:92:da:73 > 01:80:c2:00:00:00, ethertype MEDSA (0xdada), length 68: To_CPU, untagged, dev.port:vlan 0.2:0, BDPU, pri 7: LLC, dsap STP (0x42) Individual, ssap STP (0x42) Command, ctrl 0x03: STP 802.1d, Config, Flags [none], bridge-id 8000.26:a1:fb:92:da:73.8001, length 43
+94:10:3e:80:bc:f3 > 00:22:02:00:18:44, ethertype MEDSA (0xdada), length 98: From_CPU, untagged, dev.port:vlan 0.3:0, pri 0: ethertype IPv4 (0x0800) 10.0.0.12.59483 > 198.110.48.12.123: NTPv4, Client, length 48
+00:22:02:00:18:44 > 94:10:3e:80:bc:f3, ethertype MEDSA (0xdada), length 98: Forward, untagged, dev.port:vlan 0.3:0, pri 0: ethertype IPv4 (0x0800) 198.110.48.12.123 > 10.0.0.12.59483: NTPv4, Server, length 48
+26:a1:fb:92:da:73 > 01:80:c2:00:00:00, ethertype MEDSA (0xdada), length 68: To_CPU, untagged, dev.port:vlan 0.2:0, BDPU, pri 7: LLC, dsap STP (0x42) Individual, ssap STP (0x42) Command, ctrl 0x03: STP 802.1d, Config, Flags [none], bridge-id 8000.26:a1:fb:92:da:73.8001, length 43
+26:a1:fb:92:da:73 > 01:80:c2:00:00:00, ethertype MEDSA (0xdada), length 68: To_CPU, untagged, dev.port:vlan 0.2:0, BDPU, pri 7: LLC, dsap STP (0x42) Individual, ssap STP (0x42) Command, ctrl 0x03: STP 802.1d, Config, Flags [none], bridge-id 8000.26:a1:fb:92:da:73.8001, length 43
+94:10:3e:80:bc:f3 > 00:22:02:00:18:44, ethertype MEDSA (0xdada), length 98: From_CPU, untagged, dev.port:vlan 0.3:0, pri 0: ethertype IPv4 (0x0800) 10.0.0.12.59809 > 66.228.42.59.123: NTPv4, Client, length 48
+94:10:3e:80:bc:f3 > 00:22:02:00:18:44, ethertype MEDSA (0xdada), length 98: From_CPU, untagged, dev.port:vlan 0.3:0, pri 0: ethertype IPv4 (0x0800) 10.0.0.12.58880 > 199.102.46.76.123: NTPv4, Client, length 48
+00:22:02:00:18:44 > 94:10:3e:80:bc:f3, ethertype MEDSA (0xdada), length 98: Forward, untagged, dev.port:vlan 0.3:0, pri 0: ethertype IPv4 (0x0800) 199.102.46.76.123 > 10.0.0.12.58880: NTPv4, Server, length 48
+00:22:02:00:18:44 > 94:10:3e:80:bc:f3, ethertype MEDSA (0xdada), length 98: Forward, untagged, dev.port:vlan 0.3:0, pri 0: ethertype IPv4 (0x0800) 66.228.42.59.123 > 10.0.0.12.59809: NTPv4, Server, length 48
+26:a1:fb:92:da:73 > 01:80:c2:00:00:00, ethertype MEDSA (0xdada), length 68: To_CPU, untagged, dev.port:vlan 0.2:0, BDPU, pri 7: LLC, dsap STP (0x42) Individual, ssap STP (0x42) Command, ctrl 0x03: STP 802.1d, Config, Flags [none], bridge-id 8000.26:a1:fb:92:da:73.8001, length 43
+94:10:3e:80:bc:f3 > 00:22:02:00:18:44, ethertype MEDSA (0xdada), length 98: From_CPU, untagged, dev.port:vlan 0.3:0, pri 0: ethertype IPv4 (0x0800) 10.0.0.12.41068 > 208.97.140.69.123: NTPv4, Client, length 48
+00:22:02:00:18:44 > 94:10:3e:80:bc:f3, ethertype MEDSA (0xdada), length 98: Forward, untagged, dev.port:vlan 0.3:0, pri 0: ethertype IPv4 (0x0800) 208.97.140.69.123 > 10.0.0.12.41068: NTPv4, Server, length 48
+26:a1:fb:92:da:73 > 01:80:c2:00:00:00, ethertype MEDSA (0xdada), length 68: To_CPU, untagged, dev.port:vlan 0.2:0, BDPU, pri 7: LLC, dsap STP (0x42) Individual, ssap STP (0x42) Command, ctrl 0x03: STP 802.1d, Config, Flags [none], bridge-id 8000.26:a1:fb:92:da:73.8001, length 43
+26:a1:fb:92:da:73 > 01:80:c2:00:00:00, ethertype MEDSA (0xdada), length 68: To_CPU, untagged, dev.port:vlan 0.2:0, BDPU, pri 7: LLC, dsap STP (0x42) Individual, ssap STP (0x42) Command, ctrl 0x03: STP 802.1d, Config, Flags [none], bridge-id 8000.26:a1:fb:92:da:73.8001, length 43
+94:10:3e:80:bc:f3 > 00:22:02:00:18:44, ethertype MEDSA (0xdada), length 350: From_CPU, untagged, dev.port:vlan 0.3:0, pri 0: ethertype IPv4 (0x0800) 10.0.0.12.68 > 10.0.0.1.67: BOOTP/DHCP, Request from 94:10:3e:80:bc:f3, length 300
+00:22:02:00:18:44 > 94:10:3e:80:bc:f3, ethertype MEDSA (0xdada), length 350: Forward, untagged, dev.port:vlan 0.3:0, pri 0: ethertype IPv4 (0x0800) 10.0.0.1.67 > 10.0.0.12.68: BOOTP/DHCP, Reply, length 300
+26:a1:fb:92:da:73 > 01:80:c2:00:00:00, ethertype MEDSA (0xdada), length 68: To_CPU, untagged, dev.port:vlan 0.2:0, BDPU, pri 7: LLC, dsap STP (0x42) Individual, ssap STP (0x42) Command, ctrl 0x03: STP 802.1d, Config, Flags [none], bridge-id 8000.26:a1:fb:92:da:73.8001, length 43
+26:a1:fb:92:da:73 > 01:80:c2:00:00:00, ethertype MEDSA (0xdada), length 68: To_CPU, untagged, dev.port:vlan 0.2:0, BDPU, pri 7: LLC, dsap STP (0x42) Individual, ssap STP (0x42) Command, ctrl 0x03: STP 802.1d, Config, Flags [none], bridge-id 8000.26:a1:fb:92:da:73.8001, length 43
+94:10:3e:80:bc:f3 > 00:22:02:00:18:44, ethertype MEDSA (0xdada), length 98: From_CPU, untagged, dev.port:vlan 0.3:0, pri 0: ethertype IPv4 (0x0800) 10.0.0.12.45651 > 171.66.97.126.123: NTPv4, Client, length 48
+00:22:02:00:18:44 > 94:10:3e:80:bc:f3, ethertype MEDSA (0xdada), length 98: Forward, untagged, dev.port:vlan 0.3:0, pri 0: ethertype IPv4 (0x0800) 171.66.97.126.123 > 10.0.0.12.45651: NTPv4, Server, length 48
diff --git a/tests/medsa.out b/tests/medsa.out
new file mode 100644
index 0000000..c81ce48
--- /dev/null
+++ b/tests/medsa.out
@@ -0,0 +1,20 @@
+MEDSA 0.2:0: STP 802.1d, Config, Flags [none], bridge-id 8000.26:a1:fb:92:da:73.8001, length 43
+MEDSA 0.3:0: IP 10.0.0.12.59483 > 198.110.48.12.123: NTPv4, Client, length 48
+MEDSA 0.3:0: IP 198.110.48.12.123 > 10.0.0.12.59483: NTPv4, Server, length 48
+MEDSA 0.2:0: STP 802.1d, Config, Flags [none], bridge-id 8000.26:a1:fb:92:da:73.8001, length 43
+MEDSA 0.2:0: STP 802.1d, Config, Flags [none], bridge-id 8000.26:a1:fb:92:da:73.8001, length 43
+MEDSA 0.3:0: IP 10.0.0.12.59809 > 66.228.42.59.123: NTPv4, Client, length 48
+MEDSA 0.3:0: IP 10.0.0.12.58880 > 199.102.46.76.123: NTPv4, Client, length 48
+MEDSA 0.3:0: IP 199.102.46.76.123 > 10.0.0.12.58880: NTPv4, Server, length 48
+MEDSA 0.3:0: IP 66.228.42.59.123 > 10.0.0.12.59809: NTPv4, Server, length 48
+MEDSA 0.2:0: STP 802.1d, Config, Flags [none], bridge-id 8000.26:a1:fb:92:da:73.8001, length 43
+MEDSA 0.3:0: IP 10.0.0.12.41068 > 208.97.140.69.123: NTPv4, Client, length 48
+MEDSA 0.3:0: IP 208.97.140.69.123 > 10.0.0.12.41068: NTPv4, Server, length 48
+MEDSA 0.2:0: STP 802.1d, Config, Flags [none], bridge-id 8000.26:a1:fb:92:da:73.8001, length 43
+MEDSA 0.2:0: STP 802.1d, Config, Flags [none], bridge-id 8000.26:a1:fb:92:da:73.8001, length 43
+MEDSA 0.3:0: IP 10.0.0.12.68 > 10.0.0.1.67: BOOTP/DHCP, Request from 94:10:3e:80:bc:f3, length 300
+MEDSA 0.3:0: IP 10.0.0.1.67 > 10.0.0.12.68: BOOTP/DHCP, Reply, length 300
+MEDSA 0.2:0: STP 802.1d, Config, Flags [none], bridge-id 8000.26:a1:fb:92:da:73.8001, length 43
+MEDSA 0.2:0: STP 802.1d, Config, Flags [none], bridge-id 8000.26:a1:fb:92:da:73.8001, length 43
+MEDSA 0.3:0: IP 10.0.0.12.45651 > 171.66.97.126.123: NTPv4, Client, length 48
+MEDSA 0.3:0: IP 171.66.97.126.123 > 10.0.0.12.45651: NTPv4, Server, length 48
diff --git a/tests/medsa.pcap b/tests/medsa.pcap
new file mode 100644
index 0000000..ab20710
--- /dev/null
+++ b/tests/medsa.pcap
Binary files differ
diff --git a/tests/mpls-label-heapoverflow.out b/tests/mpls-label-heapoverflow.out
new file mode 100644
index 0000000..1419cac
--- /dev/null
+++ b/tests/mpls-label-heapoverflow.out
@@ -0,0 +1,2 @@
+MPLS (label 197379, exp 0, ttl 48)
+	(label 197387, exp 5, [S], ttl 48)[|MPLS]
diff --git a/tests/mpls-label-heapoverflow.pcap b/tests/mpls-label-heapoverflow.pcap
new file mode 100644
index 0000000..9a63b45
--- /dev/null
+++ b/tests/mpls-label-heapoverflow.pcap
Binary files differ
diff --git a/tests/mpls-traceroute-v.out b/tests/mpls-traceroute-v.out
new file mode 100644
index 0000000..b70c2e3
--- /dev/null
+++ b/tests/mpls-traceroute-v.out
@@ -0,0 +1,81 @@
+MPLS (label 100704, exp 0, [S], ttl 1)
+	IP (tos 0x0, ttl 1, id 42316, offset 0, flags [none], proto UDP (17), length 40)
+    12.4.4.4.42315 > 12.1.1.1.33435: UDP, length 12
+IP (tos 0x0, ttl 255, id 5014, offset 0, flags [DF], proto ICMP (1), length 168)
+    10.5.0.1 > 12.4.4.4: ICMP time exceeded in-transit, length 148
+	IP (tos 0x0, ttl 1, id 42316, offset 0, flags [none], proto UDP (17), length 40)
+    12.4.4.4.42315 > 12.1.1.1.33435: UDP, length 12
+	MPLS extension v2, checksum 0xc55f (correct), length 12
+	  MPLS Stack Entry Object (1), Class-Type: 1, length 8
+	    label 100704, exp 0, [S], ttl 1
+MPLS (label 100704, exp 0, [S], ttl 1)
+	IP (tos 0x0, ttl 1, id 42317, offset 0, flags [none], proto UDP (17), length 40)
+    12.4.4.4.42315 > 12.1.1.1.33436: UDP, length 12
+IP (tos 0x0, ttl 255, id 5015, offset 0, flags [DF], proto ICMP (1), length 168)
+    10.5.0.1 > 12.4.4.4: ICMP time exceeded in-transit, length 148
+	IP (tos 0x0, ttl 1, id 42317, offset 0, flags [none], proto UDP (17), length 40)
+    12.4.4.4.42315 > 12.1.1.1.33436: UDP, length 12
+	MPLS extension v2, checksum 0xc55f (correct), length 12
+	  MPLS Stack Entry Object (1), Class-Type: 1, length 8
+	    label 100704, exp 0, [S], ttl 1
+MPLS (label 100704, exp 0, [S], ttl 1)
+	IP (tos 0x0, ttl 1, id 42318, offset 0, flags [none], proto UDP (17), length 40)
+    12.4.4.4.42315 > 12.1.1.1.33437: UDP, length 12
+IP (tos 0x0, ttl 255, id 5016, offset 0, flags [DF], proto ICMP (1), length 168)
+    10.5.0.1 > 12.4.4.4: ICMP time exceeded in-transit, length 148
+	IP (tos 0x0, ttl 1, id 42318, offset 0, flags [none], proto UDP (17), length 40)
+    12.4.4.4.42315 > 12.1.1.1.33437: UDP, length 12
+	MPLS extension v2, checksum 0xc55f (correct), length 12
+	  MPLS Stack Entry Object (1), Class-Type: 1, length 8
+	    label 100704, exp 0, [S], ttl 1
+MPLS (label 100704, exp 0, [S], ttl 2)
+	IP (tos 0x0, ttl 2, id 42319, offset 0, flags [none], proto UDP (17), length 40)
+    12.4.4.4.42315 > 12.1.1.1.33438: UDP, length 12
+IP (tos 0x0, ttl 254, id 59166, offset 0, flags [DF], proto ICMP (1), length 168)
+    10.4.0.2 > 12.4.4.4: ICMP time exceeded in-transit, length 148
+	IP (tos 0x0, ttl 1, id 42319, offset 0, flags [none], proto UDP (17), length 40)
+    12.4.4.4.42315 > 12.1.1.1.33438: UDP, length 12
+	MPLS extension v2, checksum 0xc4e4 (correct), length 12
+	  MPLS Stack Entry Object (1), Class-Type: 1, length 8
+	    label 102672, exp 0, [S], ttl 1
+MPLS (label 100704, exp 0, [S], ttl 2)
+	IP (tos 0x0, ttl 2, id 42320, offset 0, flags [none], proto UDP (17), length 40)
+    12.4.4.4.42315 > 12.1.1.1.33439: UDP, length 12
+IP (tos 0x0, ttl 254, id 59167, offset 0, flags [DF], proto ICMP (1), length 168)
+    10.4.0.2 > 12.4.4.4: ICMP time exceeded in-transit, length 148
+	IP (tos 0x0, ttl 1, id 42320, offset 0, flags [none], proto UDP (17), length 40)
+    12.4.4.4.42315 > 12.1.1.1.33439: UDP, length 12
+	MPLS extension v2, checksum 0xc4e4 (correct), length 12
+	  MPLS Stack Entry Object (1), Class-Type: 1, length 8
+	    label 102672, exp 0, [S], ttl 1
+MPLS (label 100704, exp 0, [S], ttl 2)
+	IP (tos 0x0, ttl 2, id 42321, offset 0, flags [none], proto UDP (17), length 40)
+    12.4.4.4.42315 > 12.1.1.1.33440: UDP, length 12
+IP (tos 0x0, ttl 254, id 59168, offset 0, flags [DF], proto ICMP (1), length 168)
+    10.4.0.2 > 12.4.4.4: ICMP time exceeded in-transit, length 148
+	IP (tos 0x0, ttl 1, id 42321, offset 0, flags [none], proto UDP (17), length 40)
+    12.4.4.4.42315 > 12.1.1.1.33440: UDP, length 12
+	MPLS extension v2, checksum 0xc4e4 (correct), length 12
+	  MPLS Stack Entry Object (1), Class-Type: 1, length 8
+	    label 102672, exp 0, [S], ttl 1
+MPLS (label 100704, exp 0, [S], ttl 3)
+	IP (tos 0x0, ttl 3, id 42322, offset 0, flags [none], proto UDP (17), length 40)
+    12.4.4.4.42315 > 12.1.1.1.33441: UDP, length 12
+IP (tos 0x0, ttl 253, id 50599, offset 0, flags [DF], proto ICMP (1), length 56)
+    12.1.1.1 > 12.4.4.4: ICMP 12.1.1.1 udp port 33441 unreachable, length 36
+	IP (tos 0x0, ttl 1, id 42322, offset 0, flags [none], proto UDP (17), length 40)
+    12.4.4.4.42315 > 12.1.1.1.33441: UDP, length 12
+MPLS (label 100704, exp 0, [S], ttl 3)
+	IP (tos 0x0, ttl 3, id 42323, offset 0, flags [none], proto UDP (17), length 40)
+    12.4.4.4.42315 > 12.1.1.1.33442: UDP, length 12
+IP (tos 0x0, ttl 253, id 50600, offset 0, flags [DF], proto ICMP (1), length 56)
+    12.1.1.1 > 12.4.4.4: ICMP 12.1.1.1 udp port 33442 unreachable, length 36
+	IP (tos 0x0, ttl 1, id 42323, offset 0, flags [none], proto UDP (17), length 40)
+    12.4.4.4.42315 > 12.1.1.1.33442: UDP, length 12
+MPLS (label 100704, exp 0, [S], ttl 3)
+	IP (tos 0x0, ttl 3, id 42324, offset 0, flags [none], proto UDP (17), length 40)
+    12.4.4.4.42315 > 12.1.1.1.33443: UDP, length 12
+IP (tos 0x0, ttl 253, id 50601, offset 0, flags [DF], proto ICMP (1), length 56)
+    12.1.1.1 > 12.4.4.4: ICMP 12.1.1.1 udp port 33443 unreachable, length 36
+	IP (tos 0x0, ttl 1, id 42324, offset 0, flags [none], proto UDP (17), length 40)
+    12.4.4.4.42315 > 12.1.1.1.33443: UDP, length 12
diff --git a/tests/mpls-traceroute.out b/tests/mpls-traceroute.out
new file mode 100644
index 0000000..fe8c116
--- /dev/null
+++ b/tests/mpls-traceroute.out
@@ -0,0 +1,18 @@
+MPLS (label 100704, exp 0, [S], ttl 1) IP 12.4.4.4.42315 > 12.1.1.1.33435: UDP, length 12
+IP 10.5.0.1 > 12.4.4.4: ICMP time exceeded in-transit, length 148
+MPLS (label 100704, exp 0, [S], ttl 1) IP 12.4.4.4.42315 > 12.1.1.1.33436: UDP, length 12
+IP 10.5.0.1 > 12.4.4.4: ICMP time exceeded in-transit, length 148
+MPLS (label 100704, exp 0, [S], ttl 1) IP 12.4.4.4.42315 > 12.1.1.1.33437: UDP, length 12
+IP 10.5.0.1 > 12.4.4.4: ICMP time exceeded in-transit, length 148
+MPLS (label 100704, exp 0, [S], ttl 2) IP 12.4.4.4.42315 > 12.1.1.1.33438: UDP, length 12
+IP 10.4.0.2 > 12.4.4.4: ICMP time exceeded in-transit, length 148
+MPLS (label 100704, exp 0, [S], ttl 2) IP 12.4.4.4.42315 > 12.1.1.1.33439: UDP, length 12
+IP 10.4.0.2 > 12.4.4.4: ICMP time exceeded in-transit, length 148
+MPLS (label 100704, exp 0, [S], ttl 2) IP 12.4.4.4.42315 > 12.1.1.1.33440: UDP, length 12
+IP 10.4.0.2 > 12.4.4.4: ICMP time exceeded in-transit, length 148
+MPLS (label 100704, exp 0, [S], ttl 3) IP 12.4.4.4.42315 > 12.1.1.1.33441: UDP, length 12
+IP 12.1.1.1 > 12.4.4.4: ICMP 12.1.1.1 udp port 33441 unreachable, length 36
+MPLS (label 100704, exp 0, [S], ttl 3) IP 12.4.4.4.42315 > 12.1.1.1.33442: UDP, length 12
+IP 12.1.1.1 > 12.4.4.4: ICMP 12.1.1.1 udp port 33442 unreachable, length 36
+MPLS (label 100704, exp 0, [S], ttl 3) IP 12.4.4.4.42315 > 12.1.1.1.33443: UDP, length 12
+IP 12.1.1.1 > 12.4.4.4: ICMP 12.1.1.1 udp port 33443 unreachable, length 36
diff --git a/tests/mstp-v.out b/tests/mstp-v.out
index 16127b5..998ebfa 100644
--- a/tests/mstp-v.out
+++ b/tests/mstp-v.out
@@ -1,9 +1,9 @@
 STP 802.1s, Rapid STP, CIST Flags [Learn, Forward], length 134
-	port-role Root, CIST root-id 0000.00:1f:27:b4:7d:80, CIST ext-pathcost 200000 
-	CIST regional-root-id 8000.00:16:46:b5:8c:80, CIST port-id 8012, 
+	port-role Root, CIST root-id 0000.00:1f:27:b4:7d:80, CIST ext-pathcost 200000
+	CIST regional-root-id 8000.00:16:46:b5:8c:80, CIST port-id 8012,
 	message-age 1.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
-	v3len 96, MCID Name Brewery, rev 0, 
-		digest 9357ebb7a8d74dd5fef4f2bab50531aa, CIST int-root-pathcost 200000, 
+	v3len 96, MCID Name Brewery, rev 0,
+		digest 9357ebb7a8d74dd5fef4f2bab50531aa, CIST int-root-pathcost 200000,
 	CIST bridge-id 8000.00:1e:f7:05:a8:80, CIST remaining-hops 20
 	MSTI 1, Flags [Learn, Forward, Agreement, Topology change ACK], port-role Designated
 		MSTI regional-root-id 6001.00:1e:f7:05:a8:80, pathcost 0
@@ -12,11 +12,11 @@
 		MSTI regional-root-id 8002.00:16:46:b5:8c:80, pathcost 200000
 		MSTI bridge-prio 8, port-prio 8, hops 20
 STP 802.1s, Rapid STP, CIST Flags [Learn, Forward, Agreement], length 134
-	port-role Designated, CIST root-id 0000.00:1f:27:b4:7d:80, CIST ext-pathcost 200000 
-	CIST regional-root-id 8000.00:16:46:b5:8c:80, CIST port-id 800f, 
+	port-role Designated, CIST root-id 0000.00:1f:27:b4:7d:80, CIST ext-pathcost 200000
+	CIST regional-root-id 8000.00:16:46:b5:8c:80, CIST port-id 800f,
 	message-age 1.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
-	v3len 96, MCID Name Brewery, rev 0, 
-		digest 9357ebb7a8d74dd5fef4f2bab50531aa, CIST int-root-pathcost 0, 
+	v3len 96, MCID Name Brewery, rev 0,
+		digest 9357ebb7a8d74dd5fef4f2bab50531aa, CIST int-root-pathcost 0,
 	CIST bridge-id 8000.00:16:46:b5:8c:80, CIST remaining-hops 20
 	MSTI 1, Flags [Learn, Forward, Agreement, Topology change ACK], port-role Root
 		MSTI regional-root-id 6001.00:1e:f7:05:a8:80, pathcost 200000
@@ -25,11 +25,11 @@
 		MSTI regional-root-id 8002.00:16:46:b5:8c:80, pathcost 0
 		MSTI bridge-prio 8, port-prio 8, hops 20
 STP 802.1s, Rapid STP, CIST Flags [Learn, Forward], length 134
-	port-role Root, CIST root-id 0000.00:1f:27:b4:7d:80, CIST ext-pathcost 200000 
-	CIST regional-root-id 8000.00:16:46:b5:8c:80, CIST port-id 8012, 
+	port-role Root, CIST root-id 0000.00:1f:27:b4:7d:80, CIST ext-pathcost 200000
+	CIST regional-root-id 8000.00:16:46:b5:8c:80, CIST port-id 8012,
 	message-age 1.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
-	v3len 96, MCID Name Brewery, rev 0, 
-		digest 9357ebb7a8d74dd5fef4f2bab50531aa, CIST int-root-pathcost 200000, 
+	v3len 96, MCID Name Brewery, rev 0,
+		digest 9357ebb7a8d74dd5fef4f2bab50531aa, CIST int-root-pathcost 200000,
 	CIST bridge-id 8000.00:1e:f7:05:a8:80, CIST remaining-hops 20
 	MSTI 1, Flags [Learn, Forward, Agreement, Topology change ACK], port-role Designated
 		MSTI regional-root-id 6001.00:1e:f7:05:a8:80, pathcost 0
@@ -38,11 +38,11 @@
 		MSTI regional-root-id 8002.00:16:46:b5:8c:80, pathcost 200000
 		MSTI bridge-prio 8, port-prio 8, hops 20
 STP 802.1s, Rapid STP, CIST Flags [Learn, Forward, Agreement], length 134
-	port-role Designated, CIST root-id 0000.00:1f:27:b4:7d:80, CIST ext-pathcost 200000 
-	CIST regional-root-id 8000.00:16:46:b5:8c:80, CIST port-id 800f, 
+	port-role Designated, CIST root-id 0000.00:1f:27:b4:7d:80, CIST ext-pathcost 200000
+	CIST regional-root-id 8000.00:16:46:b5:8c:80, CIST port-id 800f,
 	message-age 1.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
-	v3len 96, MCID Name Brewery, rev 0, 
-		digest 9357ebb7a8d74dd5fef4f2bab50531aa, CIST int-root-pathcost 0, 
+	v3len 96, MCID Name Brewery, rev 0,
+		digest 9357ebb7a8d74dd5fef4f2bab50531aa, CIST int-root-pathcost 0,
 	CIST bridge-id 8000.00:16:46:b5:8c:80, CIST remaining-hops 20
 	MSTI 1, Flags [Learn, Forward, Agreement, Topology change ACK], port-role Root
 		MSTI regional-root-id 6001.00:1e:f7:05:a8:80, pathcost 200000
@@ -51,11 +51,11 @@
 		MSTI regional-root-id 8002.00:16:46:b5:8c:80, pathcost 0
 		MSTI bridge-prio 8, port-prio 8, hops 20
 STP 802.1s, Rapid STP, CIST Flags [Learn, Forward], length 134
-	port-role Root, CIST root-id 0000.00:1f:27:b4:7d:80, CIST ext-pathcost 200000 
-	CIST regional-root-id 8000.00:16:46:b5:8c:80, CIST port-id 8012, 
+	port-role Root, CIST root-id 0000.00:1f:27:b4:7d:80, CIST ext-pathcost 200000
+	CIST regional-root-id 8000.00:16:46:b5:8c:80, CIST port-id 8012,
 	message-age 1.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
-	v3len 96, MCID Name Brewery, rev 0, 
-		digest 9357ebb7a8d74dd5fef4f2bab50531aa, CIST int-root-pathcost 200000, 
+	v3len 96, MCID Name Brewery, rev 0,
+		digest 9357ebb7a8d74dd5fef4f2bab50531aa, CIST int-root-pathcost 200000,
 	CIST bridge-id 8000.00:1e:f7:05:a8:80, CIST remaining-hops 20
 	MSTI 1, Flags [Learn, Forward, Agreement, Topology change ACK], port-role Designated
 		MSTI regional-root-id 6001.00:1e:f7:05:a8:80, pathcost 0
@@ -64,11 +64,11 @@
 		MSTI regional-root-id 8002.00:16:46:b5:8c:80, pathcost 200000
 		MSTI bridge-prio 8, port-prio 8, hops 20
 STP 802.1s, Rapid STP, CIST Flags [Learn, Forward, Agreement], length 134
-	port-role Designated, CIST root-id 0000.00:1f:27:b4:7d:80, CIST ext-pathcost 200000 
-	CIST regional-root-id 8000.00:16:46:b5:8c:80, CIST port-id 800f, 
+	port-role Designated, CIST root-id 0000.00:1f:27:b4:7d:80, CIST ext-pathcost 200000
+	CIST regional-root-id 8000.00:16:46:b5:8c:80, CIST port-id 800f,
 	message-age 1.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
-	v3len 96, MCID Name Brewery, rev 0, 
-		digest 9357ebb7a8d74dd5fef4f2bab50531aa, CIST int-root-pathcost 0, 
+	v3len 96, MCID Name Brewery, rev 0,
+		digest 9357ebb7a8d74dd5fef4f2bab50531aa, CIST int-root-pathcost 0,
 	CIST bridge-id 8000.00:16:46:b5:8c:80, CIST remaining-hops 20
 	MSTI 1, Flags [Learn, Forward, Agreement, Topology change ACK], port-role Root
 		MSTI regional-root-id 6001.00:1e:f7:05:a8:80, pathcost 200000
@@ -77,11 +77,11 @@
 		MSTI regional-root-id 8002.00:16:46:b5:8c:80, pathcost 0
 		MSTI bridge-prio 8, port-prio 8, hops 20
 STP 802.1s, Rapid STP, CIST Flags [Learn, Forward], length 134
-	port-role Root, CIST root-id 0000.00:1f:27:b4:7d:80, CIST ext-pathcost 200000 
-	CIST regional-root-id 8000.00:16:46:b5:8c:80, CIST port-id 8012, 
+	port-role Root, CIST root-id 0000.00:1f:27:b4:7d:80, CIST ext-pathcost 200000
+	CIST regional-root-id 8000.00:16:46:b5:8c:80, CIST port-id 8012,
 	message-age 1.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
-	v3len 96, MCID Name Brewery, rev 0, 
-		digest 9357ebb7a8d74dd5fef4f2bab50531aa, CIST int-root-pathcost 200000, 
+	v3len 96, MCID Name Brewery, rev 0,
+		digest 9357ebb7a8d74dd5fef4f2bab50531aa, CIST int-root-pathcost 200000,
 	CIST bridge-id 8000.00:1e:f7:05:a8:80, CIST remaining-hops 20
 	MSTI 1, Flags [Learn, Forward, Agreement, Topology change ACK], port-role Designated
 		MSTI regional-root-id 6001.00:1e:f7:05:a8:80, pathcost 0
@@ -90,11 +90,11 @@
 		MSTI regional-root-id 8002.00:16:46:b5:8c:80, pathcost 200000
 		MSTI bridge-prio 8, port-prio 8, hops 20
 STP 802.1s, Rapid STP, CIST Flags [Learn, Forward, Agreement], length 134
-	port-role Designated, CIST root-id 0000.00:1f:27:b4:7d:80, CIST ext-pathcost 200000 
-	CIST regional-root-id 8000.00:16:46:b5:8c:80, CIST port-id 800f, 
+	port-role Designated, CIST root-id 0000.00:1f:27:b4:7d:80, CIST ext-pathcost 200000
+	CIST regional-root-id 8000.00:16:46:b5:8c:80, CIST port-id 800f,
 	message-age 1.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
-	v3len 96, MCID Name Brewery, rev 0, 
-		digest 9357ebb7a8d74dd5fef4f2bab50531aa, CIST int-root-pathcost 0, 
+	v3len 96, MCID Name Brewery, rev 0,
+		digest 9357ebb7a8d74dd5fef4f2bab50531aa, CIST int-root-pathcost 0,
 	CIST bridge-id 8000.00:16:46:b5:8c:80, CIST remaining-hops 20
 	MSTI 1, Flags [Learn, Forward, Agreement, Topology change ACK], port-role Root
 		MSTI regional-root-id 6001.00:1e:f7:05:a8:80, pathcost 200000
@@ -103,11 +103,11 @@
 		MSTI regional-root-id 8002.00:16:46:b5:8c:80, pathcost 0
 		MSTI bridge-prio 8, port-prio 8, hops 20
 STP 802.1s, Rapid STP, CIST Flags [Learn, Forward], length 134
-	port-role Root, CIST root-id 0000.00:1f:27:b4:7d:80, CIST ext-pathcost 200000 
-	CIST regional-root-id 8000.00:16:46:b5:8c:80, CIST port-id 8012, 
+	port-role Root, CIST root-id 0000.00:1f:27:b4:7d:80, CIST ext-pathcost 200000
+	CIST regional-root-id 8000.00:16:46:b5:8c:80, CIST port-id 8012,
 	message-age 1.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
-	v3len 96, MCID Name Brewery, rev 0, 
-		digest 9357ebb7a8d74dd5fef4f2bab50531aa, CIST int-root-pathcost 200000, 
+	v3len 96, MCID Name Brewery, rev 0,
+		digest 9357ebb7a8d74dd5fef4f2bab50531aa, CIST int-root-pathcost 200000,
 	CIST bridge-id 8000.00:1e:f7:05:a8:80, CIST remaining-hops 20
 	MSTI 1, Flags [Learn, Forward, Agreement, Topology change ACK], port-role Designated
 		MSTI regional-root-id 6001.00:1e:f7:05:a8:80, pathcost 0
@@ -116,11 +116,11 @@
 		MSTI regional-root-id 8002.00:16:46:b5:8c:80, pathcost 200000
 		MSTI bridge-prio 8, port-prio 8, hops 20
 STP 802.1s, Rapid STP, CIST Flags [Learn, Forward, Agreement], length 134
-	port-role Designated, CIST root-id 0000.00:1f:27:b4:7d:80, CIST ext-pathcost 200000 
-	CIST regional-root-id 8000.00:16:46:b5:8c:80, CIST port-id 800f, 
+	port-role Designated, CIST root-id 0000.00:1f:27:b4:7d:80, CIST ext-pathcost 200000
+	CIST regional-root-id 8000.00:16:46:b5:8c:80, CIST port-id 800f,
 	message-age 1.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
-	v3len 96, MCID Name Brewery, rev 0, 
-		digest 9357ebb7a8d74dd5fef4f2bab50531aa, CIST int-root-pathcost 0, 
+	v3len 96, MCID Name Brewery, rev 0,
+		digest 9357ebb7a8d74dd5fef4f2bab50531aa, CIST int-root-pathcost 0,
 	CIST bridge-id 8000.00:16:46:b5:8c:80, CIST remaining-hops 20
 	MSTI 1, Flags [Learn, Forward, Agreement, Topology change ACK], port-role Root
 		MSTI regional-root-id 6001.00:1e:f7:05:a8:80, pathcost 200000
diff --git a/tests/nflog-e.sh b/tests/nflog-e.sh
index 00ac4fd..46b99ee 100755
--- a/tests/nflog-e.sh
+++ b/tests/nflog-e.sh
@@ -6,5 +6,5 @@
 then
   ./TESTonce nflog-e nflog.pcap nflog-e.out '-t -e'
 else
-	printf '    %-30s: TEST SKIPPED (compiled w/o NFLOG)\n' 'nflog-e'
+	printf '    %-35s: TEST SKIPPED (compiled w/o NFLOG)\n' 'nflog-e'
 fi
diff --git a/tests/nfs-seg-fault-1.out b/tests/nfs-seg-fault-1.out
new file mode 100644
index 0000000..8ffc80a
--- /dev/null
+++ b/tests/nfs-seg-fault-1.out
@@ -0,0 +1 @@
+IP 10.131.101.60.923 > 10.131.101.118.2049: Flags [.], seq 1192508771:1192516731, ack 3532274502, win 3819, length 7960: NFS request xid 1260897737 7956 write fh Unknown/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 2863311530 (2863311530) bytes @ 12297829382473034410
diff --git a/tests/nfs-seg-fault-1.pcap b/tests/nfs-seg-fault-1.pcap
new file mode 100644
index 0000000..5c2d8ee
--- /dev/null
+++ b/tests/nfs-seg-fault-1.pcap
Binary files differ
diff --git a/tests/nsh-over-vxlan-gpe-v.out b/tests/nsh-over-vxlan-gpe-v.out
new file mode 100644
index 0000000..f8db332
--- /dev/null
+++ b/tests/nsh-over-vxlan-gpe-v.out
@@ -0,0 +1,5 @@
+IP (tos 0x0, ttl 64, id 16419, offset 0, flags [DF], proto UDP (17), length 92)
+    127.0.0.1.4790 > 127.0.0.1.4790: VXLAN-GPE, flags [IP], vni 16777215
+    NSH, flags [OC], service-path-id 0xffffff, service-index 0xff
+    IP (tos 0x0, ttl 255, id 54321, offset 0, flags [none], proto UDP (17), length 32)
+    192.168.0.1.10000 > 192.168.0.2.20000: UDP, length 4
diff --git a/tests/nsh-over-vxlan-gpe-vv.out b/tests/nsh-over-vxlan-gpe-vv.out
new file mode 100644
index 0000000..5233701
--- /dev/null
+++ b/tests/nsh-over-vxlan-gpe-vv.out
@@ -0,0 +1,5 @@
+IP (tos 0x0, ttl 64, id 16419, offset 0, flags [DF], proto UDP (17), length 92)
+    127.0.0.1.4790 > 127.0.0.1.4790: [udp sum ok] VXLAN-GPE, flags [IP], vni 16777215
+    NSH, ver 0, flags [OC], next-protocol 0x1, service-path-id 0xffffff, service-index 0xff
+    IP (tos 0x0, ttl 255, id 54321, offset 0, flags [none], proto UDP (17), length 32)
+    192.168.0.1.10000 > 192.168.0.2.20000: [udp sum ok] UDP, length 4
diff --git a/tests/nsh-over-vxlan-gpe-vvv.out b/tests/nsh-over-vxlan-gpe-vvv.out
new file mode 100644
index 0000000..f8af283
--- /dev/null
+++ b/tests/nsh-over-vxlan-gpe-vvv.out
@@ -0,0 +1,9 @@
+IP (tos 0x0, ttl 64, id 16419, offset 0, flags [DF], proto UDP (17), length 92)
+    127.0.0.1.4790 > 127.0.0.1.4790: [udp sum ok] VXLAN-GPE, flags [IP], vni 16777215
+    NSH, ver 0, flags [OC], length 6, md type 0x2, next-protocol 0x1, service-path-id 0xffffff, service-index 0xff
+        TLV Class 1, Type 2, Len 1
+            Value[00]: 0x12345678
+        TLV Class 2, Type 3, Len 1
+            Value[00]: 0x12345678
+    IP (tos 0x0, ttl 255, id 54321, offset 0, flags [none], proto UDP (17), length 32)
+    192.168.0.1.10000 > 192.168.0.2.20000: [udp sum ok] UDP, length 4
diff --git a/tests/nsh-over-vxlan-gpe.out b/tests/nsh-over-vxlan-gpe.out
new file mode 100644
index 0000000..3348a42
--- /dev/null
+++ b/tests/nsh-over-vxlan-gpe.out
@@ -0,0 +1 @@
+IP 127.0.0.1.4790 > 127.0.0.1.4790: VXLAN-GPE, flags [IP], vni 16777215: NSH, flags [OC], service-path-id 0xffffff, service-index 0xff: IP 192.168.0.1.10000 > 192.168.0.2.20000: UDP, length 4
diff --git a/tests/nsh-over-vxlan-gpe.pcap b/tests/nsh-over-vxlan-gpe.pcap
new file mode 100644
index 0000000..0cc3b67
--- /dev/null
+++ b/tests/nsh-over-vxlan-gpe.pcap
Binary files differ
diff --git a/tests/of10_p3295-vv.out b/tests/of10_p3295-vv.out
index 7d1a691..1e9f5d5 100644
--- a/tests/of10_p3295-vv.out
+++ b/tests/of10_p3295-vv.out
@@ -497,7 +497,7 @@
 	 match nw_proto 1 [|openflow]
 IP (tos 0x0, ttl 64, id 784, offset 0, flags [DF], proto TCP (6), length 740)
     10.0.0.20.6633 > 10.0.0.50.35256: Flags [P.], cksum 0x171c (incorrect -> 0xdfee), seq 1549:2237, ack 2585, win 154, options [nop,nop,TS val 220958532 ecr 194889014], length 688: OpenFlow
-	version unknown (0x00), type 0x00, length 0, xid 0x0003000d (corrupt)
+	version unknown (0x00), type 0x00, length 0, xid 0x0003000d (invalid)
 IP (tos 0x0, ttl 64, id 55503, offset 0, flags [DF], proto TCP (6), length 52)
     10.0.0.50.35256 > 10.0.0.20.6633: Flags [.], cksum 0x9386 (correct), seq 2585, ack 1549, win 273, options [nop,nop,TS val 194889016 ecr 220958532], length 0
 IP (tos 0x0, ttl 64, id 55504, offset 0, flags [DF], proto TCP (6), length 52)
@@ -770,7 +770,7 @@
     10.0.0.20.6633 > 10.0.0.50.35256: Flags [.], cksum 0x146c (incorrect -> 0x733a), seq 2237, ack 9953, win 248, options [nop,nop,TS val 220958722 ecr 194889063], length 0
 IP (tos 0x0, ttl 64, id 55532, offset 0, flags [DF], proto TCP (6), length 2680)
     10.0.0.50.35256 > 10.0.0.20.6633: Flags [P.], cksum 0x1eb0 (incorrect -> 0x561b), seq 9953:12581, ack 2237, win 364, options [nop,nop,TS val 194889063 ecr 220958721], length 2628: OpenFlow
-	version unknown (0x00), type 0x00, length 0, xid 0x00000000 (corrupt)
+	version unknown (0x00), type 0x00, length 0, xid 0x00000000 (invalid)
 IP (tos 0x0, ttl 64, id 796, offset 0, flags [DF], proto TCP (6), length 52)
     10.0.0.20.6633 > 10.0.0.50.35256: Flags [.], cksum 0x146c (incorrect -> 0x68cd), seq 2237, ack 12581, win 289, options [nop,nop,TS val 220958722 ecr 194889063], length 0
 IP (tos 0x0, ttl 64, id 55534, offset 0, flags [DF], proto TCP (6), length 64)
diff --git a/tests/of10_s4810-vvvv.out b/tests/of10_s4810-vvvv.out
index dabc2f2..fd0e3b1 100644
--- a/tests/of10_s4810-vvvv.out
+++ b/tests/of10_s4810-vvvv.out
@@ -377,7 +377,7 @@
 	 match dl_dst 00:11:22:33:00:15 [|openflow]
 IP (tos 0x0, ttl 64, id 53104, offset 0, flags [DF], proto TCP (6), length 180)
     10.0.0.20.6633 > 10.0.0.81.56068: Flags [P.], cksum 0x150b (incorrect -> 0x8ec7), seq 4241:4369, ack 677, win 139, options [nop,nop,TS val 47836527 ecr 1], length 128: OpenFlow
-	version unknown (0x00), type 0x00, length 0, xid 0x00000000 (corrupt)
+	version unknown (0x00), type 0x00, length 0, xid 0x00000000 (invalid)
 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 52)
     10.0.0.81.56068 > 10.0.0.20.6633: Flags [.], cksum 0xfaa7 (correct), seq 677, ack 2873, win 952, options [nop,nop,TS val 1 ecr 47836527], length 0
 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 52)
@@ -858,7 +858,7 @@
 	  duration_sec 0, duration_nsec 0, priority 65535, idle_timeout 0, hard_timeout 0, cookie 0x0000000000000025, packet_count 0 [|openflow]
 IP (tos 0x0, ttl 64, id 53582, offset 0, flags [DF], proto TCP (6), length 1040)
     10.0.0.81.56068 > 10.0.0.20.6633: Flags [P.], cksum 0x395e (correct), seq 8113:9101, ack 4545, win 1035, options [nop,nop,TS val 2 ecr 47837000], length 988: OpenFlow
-	version unknown (0x00), type 0x00, length 0, xid 0x00000000 (corrupt)
+	version unknown (0x00), type 0x00, length 0, xid 0x00000000 (invalid)
 IP (tos 0x0, ttl 64, id 53111, offset 0, flags [DF], proto TCP (6), length 52)
     10.0.0.20.6633 > 10.0.0.81.56068: Flags [.], cksum 0x148b (incorrect -> 0xd387), seq 4641, ack 9101, win 302, options [nop,nop,TS val 47837000 ecr 2], length 0
 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 52)
@@ -886,11 +886,11 @@
 	 buffer_id NONE, total_len 119, in_port 1, reason ACTION
 	 data (119 octets), frame decoding below
 STP 802.1s, Rapid STP, CIST Flags [Proposal, Learn, Forward, Agreement], length 102
-	port-role Designated, CIST root-id 8000.08:9e:01:62:d5:f4, CIST ext-pathcost 0 
-	CIST regional-root-id 8000.08:9e:01:62:d5:f4, CIST port-id 8034, 
+	port-role Designated, CIST root-id 8000.08:9e:01:62:d5:f4, CIST ext-pathcost 0
+	CIST regional-root-id 8000.08:9e:01:62:d5:f4, CIST port-id 8034,
 	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
-	v3len 64, MCID Name pica8, rev 0, 
-		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0, 
+	v3len 64, MCID Name pica8, rev 0,
+		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0,
 	CIST bridge-id 8000.08:9e:01:62:d5:f4, CIST remaining-hops 20
 IP (tos 0x0, ttl 64, id 53605, offset 0, flags [DF], proto TCP (6), length 168)
     10.0.0.81.56068 > 10.0.0.20.6633: Flags [P.], cksum 0x4a03 (correct), seq 10350:10466, ack 4641, win 1035, options [nop,nop,TS val 3 ecr 47837000], length 116: OpenFlow
@@ -1236,6 +1236,10 @@
 	 action type OUTPUT, len 8, port 1
 	 data (60 octets), frame decoding below
 67:68:00:00:00:00 > 61:62:63:64:65:66 Null Information, send seq 0, rcv seq 0, Flags [Command], length 46
+	0x0000:  0000 0000 0000 0000 0000 0000 0000 0000  ................
+	0x0010:  0000 0000 0000 0000 0000 0000 0000 0000  ................
+	0x0020:  0000 0000 0000 0000 0000 0000 0000 0112  ................
+	0x0030:  0008 0000 0045                           .....E
 	version 1.0, type BARRIER_REQUEST, length 8, xid 0x00000045
 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
     10.0.0.81.56068 > 10.0.0.20.6633: Flags [P.], cksum 0xb6f1 (correct), seq 14734:14742, ack 4821, win 1035, options [nop,nop,TS val 3 ecr 47837403], length 8: OpenFlow
@@ -1315,11 +1319,11 @@
 	 buffer_id NONE, total_len 119, in_port 1, reason NO_MATCH
 	 data (119 octets), frame decoding below
 STP 802.1s, Rapid STP, CIST Flags [Proposal, Learn, Forward, Agreement], length 102
-	port-role Designated, CIST root-id 8000.08:9e:01:62:d5:f4, CIST ext-pathcost 0 
-	CIST regional-root-id 8000.08:9e:01:62:d5:f4, CIST port-id 8034, 
+	port-role Designated, CIST root-id 8000.08:9e:01:62:d5:f4, CIST ext-pathcost 0
+	CIST regional-root-id 8000.08:9e:01:62:d5:f4, CIST port-id 8034,
 	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
-	v3len 64, MCID Name pica8, rev 0, 
-		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0, 
+	v3len 64, MCID Name pica8, rev 0,
+		digest ac36177f50283cd4b83821d8ab26de62, CIST int-root-pathcost 0,
 	CIST bridge-id 8000.08:9e:01:62:d5:f4, CIST remaining-hops 20
 IP (tos 0x0, ttl 64, id 53128, offset 0, flags [DF], proto TCP (6), length 52)
     10.0.0.20.6633 > 10.0.0.81.56068: Flags [.], cksum 0x148b (incorrect -> 0xb3e0), seq 4857, ack 14903, win 331, options [nop,nop,TS val 47839052 ecr 6], length 0
diff --git a/tests/ospf2-seg-fault-1-v.out b/tests/ospf2-seg-fault-1-v.out
new file mode 100644
index 0000000..7b06bb1
--- /dev/null
+++ b/tests/ospf2-seg-fault-1-v.out
@@ -0,0 +1,9 @@
+IP (tos 0xc0, ttl 1, id 4106, offset 0, flags [none], proto OSPF (89), length 172)
+    40.35.1.2 > 224.0.0.5: OSPFv2, LS-Update, length 152
+	Router-ID 10.255.245.35, Backbone Area, Authentication Type: none (0), 1 LSA
+	  LSA #1
+	  Advertising Router 10.255.245.37, seq 0x80000002, age 9s, length 104
+	    Area Local Opaque LSA (10), Opaque-Type Traffic Engineering LSA (1), Opaque-ID 9
+	    Options: [External]
+	    Link TLV (2), length: 100
+	      Bandwidth Constraints subTLV (17), length: 1 < 4 (invalid)
diff --git a/tests/ospf2-seg-fault-1.pcap b/tests/ospf2-seg-fault-1.pcap
new file mode 100644
index 0000000..269c6df
--- /dev/null
+++ b/tests/ospf2-seg-fault-1.pcap
Binary files differ
diff --git a/tests/otv-heapoverflow-1.out b/tests/otv-heapoverflow-1.out
new file mode 100644
index 0000000..4bef9dd
--- /dev/null
+++ b/tests/otv-heapoverflow-1.out
@@ -0,0 +1,10 @@
+IP 192.168.0.134.47808 > 192.168.0.24.47808: UDP, length 6
+IP 192.168.0.134.47808 > 192.168.0.24.47808: UDP, length 12
+IP 192.168.0.24.47808 > 192.168.0.134.47808: UDP, length 6
+IP 192.168.0.24.47808 > 192.168.0.255.47808: UDP, length 18
+IP 192.168.0.105.47808 > 192.168.0.255.47808: UDP, length 25
+IP 192.168.0.24.47808 > 192.168.0.134.47808: UDP, length 31
+IP 192.168.0.18.47808 > 192.168.0.255.47808: UDP, length 24
+IP 192.168.0.24.40896 > 192.168.0.134.47808: UDP, length 30
+IP 192.168.0.24.47808 > 192.168.0.255.47808: UDP, length 20
+IP 192.168.0.9.37123 > 97.34.1.224.8472: OTV, flags [I] (0x9d), overlay 12124160,  [|OTV]
diff --git a/tests/otv-heapoverflow-1.pcap b/tests/otv-heapoverflow-1.pcap
new file mode 100644
index 0000000..c5e16bf
--- /dev/null
+++ b/tests/otv-heapoverflow-1.pcap
Binary files differ
diff --git a/tests/otv-heapoverflow-2.out b/tests/otv-heapoverflow-2.out
new file mode 100644
index 0000000..7ea809f
--- /dev/null
+++ b/tests/otv-heapoverflow-2.out
@@ -0,0 +1,11 @@
+IP 192.168.0.134.47808 > 192.168.0.24.47808: UDP, length 6
+IP 192.168.0.134.47808 > 192.168.0.24.47808: UDP, length 12
+IP 192.168.0.24.47808 > 192.168.0.134.47808: UDP, length 6
+IP 192.168.0.24.47808 > 192.168.0.255.47808: UDP, length 18
+IP 192.168.0.105.47808 > 192.168.0.255.47808: UDP, length 25
+IP 192.168.0.24.47808 > 192.168.0.134.47808: UDP, length 31
+IP 192.168.0.18.47808 > 192.168.0.255.47808: UDP, length 24
+IP 192.168.0.24.40896 > 192.168.0.134.47808: UDP, length 30
+IP 192.168.0.24.47808 > 192.168.0.255.47808: UDP, length 20
+IP 192.168.0.9.37123 > 97.34.1.224.8472: OTV, flags [I] (0x9d), overlay 12124160, instance 4587520
+[|ether]
diff --git a/tests/otv-heapoverflow-2.pcap b/tests/otv-heapoverflow-2.pcap
new file mode 100644
index 0000000..69d6e78
--- /dev/null
+++ b/tests/otv-heapoverflow-2.pcap
Binary files differ
diff --git a/tests/pcap-invalid-version-1.out b/tests/pcap-invalid-version-1.out
new file mode 100644
index 0000000..5edcdda
--- /dev/null
+++ b/tests/pcap-invalid-version-1.out
@@ -0,0 +1 @@
+EXIT CODE 00000100
diff --git a/tests/pcap-invalid-version-1.pcap b/tests/pcap-invalid-version-1.pcap
new file mode 100644
index 0000000..9dd0429
--- /dev/null
+++ b/tests/pcap-invalid-version-1.pcap
Binary files differ
diff --git a/tests/pcap-invalid-version-2.out b/tests/pcap-invalid-version-2.out
new file mode 100644
index 0000000..5edcdda
--- /dev/null
+++ b/tests/pcap-invalid-version-2.out
@@ -0,0 +1 @@
+EXIT CODE 00000100
diff --git a/tests/pcap-invalid-version-2.pcap b/tests/pcap-invalid-version-2.pcap
new file mode 100644
index 0000000..4217d1e
--- /dev/null
+++ b/tests/pcap-invalid-version-2.pcap
Binary files differ
diff --git a/tests/pcap-ng-invalid-vers-1.out b/tests/pcap-ng-invalid-vers-1.out
new file mode 100644
index 0000000..5edcdda
--- /dev/null
+++ b/tests/pcap-ng-invalid-vers-1.out
@@ -0,0 +1 @@
+EXIT CODE 00000100
diff --git a/tests/pcap-ng-invalid-vers-1.pcap b/tests/pcap-ng-invalid-vers-1.pcap
new file mode 100644
index 0000000..7bbb7ab
--- /dev/null
+++ b/tests/pcap-ng-invalid-vers-1.pcap
Binary files differ
diff --git a/tests/pcap-ng-invalid-vers-2.out b/tests/pcap-ng-invalid-vers-2.out
new file mode 100644
index 0000000..5edcdda
--- /dev/null
+++ b/tests/pcap-ng-invalid-vers-2.out
@@ -0,0 +1 @@
+EXIT CODE 00000100
diff --git a/tests/pcap-ng-invalid-vers-2.pcap b/tests/pcap-ng-invalid-vers-2.pcap
new file mode 100644
index 0000000..77595f4
--- /dev/null
+++ b/tests/pcap-ng-invalid-vers-2.pcap
Binary files differ
diff --git a/tests/q933-heapoverflow-2.out b/tests/q933-heapoverflow-2.out
new file mode 100644
index 0000000..1a40c73
--- /dev/null
+++ b/tests/q933-heapoverflow-2.out
@@ -0,0 +1,24 @@
+Q.922, invalid address
+UI 00! Q.922, hdr-len 4, DLCI 5769024, Flags [none], NLPID unknown (0x11), length 41: 
+	0x0000:  886b 68                                  .kh
+Q.922, invalid address
+UI 00! Q.922, hdr-len 4, DLCI 5769024, Flags [none], NLPID unknown (0x14), length 160: 
+	0x0000:  a530 b0                                  .0.
+Q.922, invalid address
+UI 00! Q.922, hdr-len 4, DLCI 5801792, Flags [none], NLPID unknown (0x11), length 179: 
+	0x0000:  886b 68                                  .kh
+Q.922, invalid address
+UI 00! Q.922, hdr-len 4, DLCI 5769024, Flags [none], NLPID unknown (0x14), length 30: 
+	0x0000:  a530 b0                                  .0.
+Q.922, invalid address
+UI 00! Q.922, hdr-len 4, DLCI 1856, Flags [none], NLPID unknown (0x11), length 85: 
+	0x0000:  886b 68                                  .kh
+Q.922, invalid address
+Q.922, invalid address
+UI 00! Q.922, hdr-len 4, DLCI 526144, Flags [none], NLPID unknown (0x14), length 46: 
+	0x0000:  a530 b0                                  .0.
+Q.922, invalid address
+UI 2c! Pad! Q.922, hdr-len 2, DLCI 288, Flags [none], NLPID NULL (0x00), length 24: 
+	0x0000:  1188 6b68                                ..kh
+Q.922, invalid address
+UI 2c! Pad! Q.933, CCITT, codeset 0[|q.933]
diff --git a/tests/q933-heapoverflow-2.pcap b/tests/q933-heapoverflow-2.pcap
new file mode 100644
index 0000000..c38c7b6
--- /dev/null
+++ b/tests/q933-heapoverflow-2.pcap
Binary files differ
diff --git a/tests/radiotap-heapoverflow.out b/tests/radiotap-heapoverflow.out
new file mode 100644
index 0000000..a81d184
--- /dev/null
+++ b/tests/radiotap-heapoverflow.out
@@ -0,0 +1 @@
+[|802.11]
diff --git a/tests/radiotap-heapoverflow.pcap b/tests/radiotap-heapoverflow.pcap
new file mode 100644
index 0000000..82c6e19
--- /dev/null
+++ b/tests/radiotap-heapoverflow.pcap
Binary files differ
diff --git a/tests/radius-port1700-v.out b/tests/radius-port1700-v.out
new file mode 100644
index 0000000..389c763
--- /dev/null
+++ b/tests/radius-port1700-v.out
@@ -0,0 +1,4 @@
+IP (tos 0x0, ttl 64, id 44978, offset 0, flags [none], proto UDP (17), length 53)
+    127.0.0.1.42172 > 127.0.0.1.1700: RADIUS, length: 25
+	CoA-Request (43), id: 0xa6, Authenticator: 7fbf02c6662b5990838a5e6e331b3ff0
+	  User-Name Attribute (1), length: 5, Value: bob
diff --git a/tests/radius-rfc4675-v.out b/tests/radius-rfc4675-v.out
index ff0e96f..c1cea56 100644
--- a/tests/radius-rfc4675-v.out
+++ b/tests/radius-rfc4675-v.out
@@ -5,7 +5,7 @@
 	  User-Password Attribute (2), length: 18, Value: 
 	  NAS-IP-Address Attribute (4), length: 6, Value: 127.0.0.1
 	  NAS-Port Attribute (5), length: 6, Value: 1
-	  Message-Authenticator Attribute (80), length: 18, Value: .....b..7-...b.
+	  Message-Authenticator Attribute (80), length: 18, Value: .....b..7-....b.
 IP (tos 0x0, ttl 64, id 20821, offset 0, flags [none], proto UDP (17), length 81)
     127.0.0.1.1812 > 127.0.0.1.53334: RADIUS, length: 53
 	Access-Accept (2), id: 0x46, Authenticator: 766a0314eaf4b95f1ec271ae19cb3bdc
diff --git a/tests/relts-0x80000000.out b/tests/relts-0x80000000.out
new file mode 100644
index 0000000..195404a
--- /dev/null
+++ b/tests/relts-0x80000000.out
@@ -0,0 +1,2 @@
+IP (tos 0x30, ttl 48, id 12336, offset 0, flags [none], proto IGMP (2), length 12336, bad cksum 3030 (->69ac)!)
+    48.48.48.48 > 48.48.48.48: igmp dvmrp Prune src 48.48.48.48 grp 48.48.48.48 timer 68y5w3h14m8s
diff --git a/tests/relts-0x80000000.pcap b/tests/relts-0x80000000.pcap
new file mode 100644
index 0000000..eb825fb
--- /dev/null
+++ b/tests/relts-0x80000000.pcap
Binary files differ
diff --git a/tests/resp_1.out b/tests/resp_1.out
new file mode 100644
index 0000000..88c9140
--- /dev/null
+++ b/tests/resp_1.out
@@ -0,0 +1,150 @@
+IP 127.0.0.1.35901 > 127.0.0.1.6379: Flags [S], seq 1159918511, win 43690, options [mss 65495,sackOK,TS val 2004405846 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35901: Flags [S.], seq 1309831771, ack 1159918512, win 43690, options [mss 65495,sackOK,TS val 2004405846 ecr 2004405846,nop,wscale 7], length 0
+IP 127.0.0.1.35901 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 0
+IP 127.0.0.1.35901 > 127.0.0.1.6379: Flags [P.], seq 1:7, ack 1, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 6: RESP "PING"
+IP 127.0.0.1.6379 > 127.0.0.1.35901: Flags [.], ack 7, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35901: Flags [P.], seq 1:8, ack 7, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 7: RESP "PONG"
+IP 127.0.0.1.35901 > 127.0.0.1.6379: Flags [.], ack 8, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 0
+IP 127.0.0.1.35901 > 127.0.0.1.6379: Flags [F.], seq 7, ack 8, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35901: Flags [F.], seq 8, ack 8, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 0
+IP 127.0.0.1.35901 > 127.0.0.1.6379: Flags [.], ack 9, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 0
+IP 127.0.0.1.35902 > 127.0.0.1.6379: Flags [S], seq 3880036895, win 43690, options [mss 65495,sackOK,TS val 2004405846 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35902: Flags [S.], seq 95825237, ack 3880036896, win 43690, options [mss 65495,sackOK,TS val 2004405846 ecr 2004405846,nop,wscale 7], length 0
+IP 127.0.0.1.35902 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 0
+IP 127.0.0.1.35902 > 127.0.0.1.6379: Flags [P.], seq 1:15, ack 1, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 14: RESP "PING"
+IP 127.0.0.1.6379 > 127.0.0.1.35902: Flags [.], ack 15, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35902: Flags [P.], seq 1:8, ack 15, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 7: RESP "PONG"
+IP 127.0.0.1.35902 > 127.0.0.1.6379: Flags [.], ack 8, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 0
+IP 127.0.0.1.35902 > 127.0.0.1.6379: Flags [F.], seq 15, ack 8, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35902: Flags [F.], seq 8, ack 16, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 0
+IP 127.0.0.1.35902 > 127.0.0.1.6379: Flags [.], ack 9, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 0
+IP 127.0.0.1.35903 > 127.0.0.1.6379: Flags [S], seq 3040658582, win 43690, options [mss 65495,sackOK,TS val 2004405846 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35903: Flags [S.], seq 2458684268, ack 3040658583, win 43690, options [mss 65495,sackOK,TS val 2004405846 ecr 2004405846,nop,wscale 7], length 0
+IP 127.0.0.1.35903 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 0
+IP 127.0.0.1.35903 > 127.0.0.1.6379: Flags [P.], seq 1:46, ack 1, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 45: RESP "SET" "key:000000000943" "xxx"
+IP 127.0.0.1.6379 > 127.0.0.1.35903: Flags [.], ack 46, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35903: Flags [P.], seq 1:6, ack 46, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 5: RESP "OK"
+IP 127.0.0.1.35903 > 127.0.0.1.6379: Flags [.], ack 6, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 0
+IP 127.0.0.1.35903 > 127.0.0.1.6379: Flags [F.], seq 46, ack 6, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35903: Flags [F.], seq 6, ack 47, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 0
+IP 127.0.0.1.35903 > 127.0.0.1.6379: Flags [.], ack 7, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 0
+IP 127.0.0.1.35904 > 127.0.0.1.6379: Flags [S], seq 2555867980, win 43690, options [mss 65495,sackOK,TS val 2004405846 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35904: Flags [S.], seq 4291997072, ack 2555867981, win 43690, options [mss 65495,sackOK,TS val 2004405846 ecr 2004405846,nop,wscale 7], length 0
+IP 127.0.0.1.35904 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 0
+IP 127.0.0.1.35904 > 127.0.0.1.6379: Flags [P.], seq 1:37, ack 1, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 36: RESP "GET" "key:000000000199"
+IP 127.0.0.1.6379 > 127.0.0.1.35904: Flags [.], ack 37, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35904: Flags [P.], seq 1:10, ack 37, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 9: RESP "xxx"
+IP 127.0.0.1.35904 > 127.0.0.1.6379: Flags [.], ack 10, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 0
+IP 127.0.0.1.35904 > 127.0.0.1.6379: Flags [F.], seq 37, ack 10, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35904: Flags [F.], seq 10, ack 38, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 0
+IP 127.0.0.1.35904 > 127.0.0.1.6379: Flags [.], ack 11, win 342, options [nop,nop,TS val 2004405846 ecr 2004405846], length 0
+IP 127.0.0.1.35905 > 127.0.0.1.6379: Flags [S], seq 2342248419, win 43690, options [mss 65495,sackOK,TS val 2004405846 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35905: Flags [S.], seq 2490886259, ack 2342248420, win 43690, options [mss 65495,sackOK,TS val 2004405847 ecr 2004405846,nop,wscale 7], length 0
+IP 127.0.0.1.35905 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35905 > 127.0.0.1.6379: Flags [P.], seq 1:42, ack 1, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 41: RESP "INCR" "counter:000000000293"
+IP 127.0.0.1.6379 > 127.0.0.1.35905: Flags [.], ack 42, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35905: Flags [P.], seq 1:5, ack 42, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 4: RESP "3"
+IP 127.0.0.1.35905 > 127.0.0.1.6379: Flags [.], ack 5, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35905 > 127.0.0.1.6379: Flags [F.], seq 42, ack 5, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35905: Flags [F.], seq 5, ack 43, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35905 > 127.0.0.1.6379: Flags [.], ack 6, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35906 > 127.0.0.1.6379: Flags [S], seq 131158412, win 43690, options [mss 65495,sackOK,TS val 2004405847 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35906: Flags [S.], seq 49781958, ack 131158413, win 43690, options [mss 65495,sackOK,TS val 2004405847 ecr 2004405847,nop,wscale 7], length 0
+IP 127.0.0.1.35906 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35906 > 127.0.0.1.6379: Flags [P.], seq 1:37, ack 1, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 36: RESP "LPUSH" "mylist" "xxx"
+IP 127.0.0.1.6379 > 127.0.0.1.35906: Flags [.], ack 37, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35906: Flags [P.], seq 1:9, ack 37, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 8: RESP "47158"
+IP 127.0.0.1.35906 > 127.0.0.1.6379: Flags [.], ack 9, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35906 > 127.0.0.1.6379: Flags [F.], seq 37, ack 9, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35906: Flags [F.], seq 9, ack 38, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35906 > 127.0.0.1.6379: Flags [.], ack 10, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35907 > 127.0.0.1.6379: Flags [S], seq 1454742392, win 43690, options [mss 65495,sackOK,TS val 2004405847 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35907: Flags [S.], seq 4166501195, ack 1454742393, win 43690, options [mss 65495,sackOK,TS val 2004405847 ecr 2004405847,nop,wscale 7], length 0
+IP 127.0.0.1.35907 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35907 > 127.0.0.1.6379: Flags [P.], seq 1:27, ack 1, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 26: RESP "LPOP" "mylist"
+IP 127.0.0.1.6379 > 127.0.0.1.35907: Flags [.], ack 27, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35907: Flags [P.], seq 1:10, ack 27, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 9: RESP "xxx"
+IP 127.0.0.1.35907 > 127.0.0.1.6379: Flags [.], ack 10, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35907 > 127.0.0.1.6379: Flags [F.], seq 27, ack 10, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35907: Flags [F.], seq 10, ack 28, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35907 > 127.0.0.1.6379: Flags [.], ack 11, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35908 > 127.0.0.1.6379: Flags [S], seq 545589487, win 43690, options [mss 65495,sackOK,TS val 2004405847 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35908: Flags [S.], seq 2823817844, ack 545589488, win 43690, options [mss 65495,sackOK,TS val 2004405847 ecr 2004405847,nop,wscale 7], length 0
+IP 127.0.0.1.35908 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35908 > 127.0.0.1.6379: Flags [P.], seq 1:53, ack 1, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 52: RESP "SADD" "myset" "element:000000000063"
+IP 127.0.0.1.6379 > 127.0.0.1.35908: Flags [.], ack 53, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35908: Flags [P.], seq 1:5, ack 53, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 4: RESP "1"
+IP 127.0.0.1.35908 > 127.0.0.1.6379: Flags [.], ack 5, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35908 > 127.0.0.1.6379: Flags [F.], seq 53, ack 5, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35908: Flags [F.], seq 5, ack 54, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35908 > 127.0.0.1.6379: Flags [.], ack 6, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35909 > 127.0.0.1.6379: Flags [S], seq 296698850, win 43690, options [mss 65495,sackOK,TS val 2004405847 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35909: Flags [S.], seq 3970806453, ack 296698851, win 43690, options [mss 65495,sackOK,TS val 2004405847 ecr 2004405847,nop,wscale 7], length 0
+IP 127.0.0.1.35909 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35909 > 127.0.0.1.6379: Flags [P.], seq 1:26, ack 1, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 25: RESP "SPOP" "myset"
+IP 127.0.0.1.6379 > 127.0.0.1.35909: Flags [.], ack 26, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35909: Flags [P.], seq 1:28, ack 26, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 27: RESP "element:000000000063"
+IP 127.0.0.1.35909 > 127.0.0.1.6379: Flags [.], ack 28, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35909 > 127.0.0.1.6379: Flags [F.], seq 26, ack 28, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35909: Flags [F.], seq 28, ack 27, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35909 > 127.0.0.1.6379: Flags [.], ack 29, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35910 > 127.0.0.1.6379: Flags [S], seq 2082555059, win 43690, options [mss 65495,sackOK,TS val 2004405847 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35910: Flags [S.], seq 1762470779, ack 2082555060, win 43690, options [mss 65495,sackOK,TS val 2004405847 ecr 2004405847,nop,wscale 7], length 0
+IP 127.0.0.1.35910 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35910 > 127.0.0.1.6379: Flags [P.], seq 1:37, ack 1, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 36: RESP "LPUSH" "mylist" "xxx"
+IP 127.0.0.1.6379 > 127.0.0.1.35910: Flags [.], ack 37, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35910: Flags [P.], seq 1:9, ack 37, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 8: RESP "47158"
+IP 127.0.0.1.35910 > 127.0.0.1.6379: Flags [.], ack 9, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35910 > 127.0.0.1.6379: Flags [F.], seq 37, ack 9, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35910: Flags [F.], seq 9, ack 38, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35910 > 127.0.0.1.6379: Flags [.], ack 10, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35911 > 127.0.0.1.6379: Flags [S], seq 823555559, win 43690, options [mss 65495,sackOK,TS val 2004405847 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35911: Flags [S.], seq 1343119127, ack 823555560, win 43690, options [mss 65495,sackOK,TS val 2004405847 ecr 2004405847,nop,wscale 7], length 0
+IP 127.0.0.1.35911 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35911 > 127.0.0.1.6379: Flags [P.], seq 1:44, ack 1, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 43: RESP "LRANGE" "mylist" "0" "99"
+IP 127.0.0.1.6379 > 127.0.0.1.35911: Flags [.], ack 44, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35911: Flags [P.], seq 1:907, ack 44, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 906: RESP "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx"
+IP 127.0.0.1.35911 > 127.0.0.1.6379: Flags [.], ack 907, win 356, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35911 > 127.0.0.1.6379: Flags [F.], seq 44, ack 907, win 356, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35911: Flags [F.], seq 907, ack 45, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35911 > 127.0.0.1.6379: Flags [.], ack 908, win 356, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35912 > 127.0.0.1.6379: Flags [S], seq 2379661641, win 43690, options [mss 65495,sackOK,TS val 2004405847 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35912: Flags [S.], seq 1832740480, ack 2379661642, win 43690, options [mss 65495,sackOK,TS val 2004405847 ecr 2004405847,nop,wscale 7], length 0
+IP 127.0.0.1.35912 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35912 > 127.0.0.1.6379: Flags [P.], seq 1:45, ack 1, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 44: RESP "LRANGE" "mylist" "0" "299"
+IP 127.0.0.1.6379 > 127.0.0.1.35912: Flags [.], ack 45, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35912: Flags [P.], seq 1:2707, ack 45, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 2706: RESP "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx"
+IP 127.0.0.1.35912 > 127.0.0.1.6379: Flags [.], ack 2707, win 1365, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35912 > 127.0.0.1.6379: Flags [F.], seq 45, ack 2707, win 1365, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35912: Flags [F.], seq 2707, ack 46, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35912 > 127.0.0.1.6379: Flags [.], ack 2708, win 1365, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35913 > 127.0.0.1.6379: Flags [S], seq 1669304377, win 43690, options [mss 65495,sackOK,TS val 2004405847 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35913: Flags [S.], seq 1910612537, ack 1669304378, win 43690, options [mss 65495,sackOK,TS val 2004405847 ecr 2004405847,nop,wscale 7], length 0
+IP 127.0.0.1.35913 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 2004405847 ecr 2004405847], length 0
+IP 127.0.0.1.35913 > 127.0.0.1.6379: Flags [P.], seq 1:45, ack 1, win 342, options [nop,nop,TS val 2004405848 ecr 2004405847], length 44: RESP "LRANGE" "mylist" "0" "449"
+IP 127.0.0.1.6379 > 127.0.0.1.35913: Flags [.], ack 45, win 342, options [nop,nop,TS val 2004405848 ecr 2004405848], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35913: Flags [P.], seq 1:4057, ack 45, win 342, options [nop,nop,TS val 2004405848 ecr 2004405848], length 4056: RESP "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx"
+IP 127.0.0.1.35913 > 127.0.0.1.6379: Flags [.], ack 4057, win 1365, options [nop,nop,TS val 2004405848 ecr 2004405848], length 0
+IP 127.0.0.1.35913 > 127.0.0.1.6379: Flags [F.], seq 45, ack 4057, win 1365, options [nop,nop,TS val 2004405848 ecr 2004405848], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35913: Flags [F.], seq 4057, ack 46, win 342, options [nop,nop,TS val 2004405848 ecr 2004405848], length 0
+IP 127.0.0.1.35913 > 127.0.0.1.6379: Flags [.], ack 4058, win 1365, options [nop,nop,TS val 2004405848 ecr 2004405848], length 0
+IP 127.0.0.1.35914 > 127.0.0.1.6379: Flags [S], seq 1695153288, win 43690, options [mss 65495,sackOK,TS val 2004405848 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35914: Flags [S.], seq 488402032, ack 1695153289, win 43690, options [mss 65495,sackOK,TS val 2004405848 ecr 2004405848,nop,wscale 7], length 0
+IP 127.0.0.1.35914 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 2004405848 ecr 2004405848], length 0
+IP 127.0.0.1.35914 > 127.0.0.1.6379: Flags [P.], seq 1:45, ack 1, win 342, options [nop,nop,TS val 2004405848 ecr 2004405848], length 44: RESP "LRANGE" "mylist" "0" "599"
+IP 127.0.0.1.6379 > 127.0.0.1.35914: Flags [.], ack 45, win 342, options [nop,nop,TS val 2004405848 ecr 2004405848], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35914: Flags [P.], seq 1:5407, ack 45, win 342, options [nop,nop,TS val 2004405848 ecr 2004405848], length 5406: RESP "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx" "xxx"
+IP 127.0.0.1.35914 > 127.0.0.1.6379: Flags [.], ack 5407, win 1365, options [nop,nop,TS val 2004405848 ecr 2004405848], length 0
+IP 127.0.0.1.35914 > 127.0.0.1.6379: Flags [F.], seq 45, ack 5407, win 1365, options [nop,nop,TS val 2004405848 ecr 2004405848], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35914: Flags [F.], seq 5407, ack 46, win 342, options [nop,nop,TS val 2004405848 ecr 2004405848], length 0
+IP 127.0.0.1.35914 > 127.0.0.1.6379: Flags [.], ack 5408, win 1365, options [nop,nop,TS val 2004405848 ecr 2004405848], length 0
+IP 127.0.0.1.35915 > 127.0.0.1.6379: Flags [S], seq 3952529642, win 43690, options [mss 65495,sackOK,TS val 2004405848 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35915: Flags [S.], seq 2079771045, ack 3952529643, win 43690, options [mss 65495,sackOK,TS val 2004405848 ecr 2004405848,nop,wscale 7], length 0
+IP 127.0.0.1.35915 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 2004405848 ecr 2004405848], length 0
+IP 127.0.0.1.35915 > 127.0.0.1.6379: Flags [P.], seq 1:336, ack 1, win 342, options [nop,nop,TS val 2004405848 ecr 2004405848], length 335: RESP "MSET" "key:000000000525" "xxx" "key:000000000050" "xxx" "key:000000000416" "xxx" "key:000000000263" "xxx" "key:000000000941" "xxx" "key:000000000148" "xxx" "key:000000000739" "xxx" "key:000000000571" "xxx" "key:000000000974" "xxx" "key:000000000495" "xxx"
+IP 127.0.0.1.6379 > 127.0.0.1.35915: Flags [.], ack 336, win 350, options [nop,nop,TS val 2004405848 ecr 2004405848], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35915: Flags [P.], seq 1:6, ack 336, win 350, options [nop,nop,TS val 2004405848 ecr 2004405848], length 5: RESP "OK"
+IP 127.0.0.1.35915 > 127.0.0.1.6379: Flags [.], ack 6, win 342, options [nop,nop,TS val 2004405848 ecr 2004405848], length 0
+IP 127.0.0.1.35915 > 127.0.0.1.6379: Flags [F.], seq 336, ack 6, win 342, options [nop,nop,TS val 2004405848 ecr 2004405848], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35915: Flags [F.], seq 6, ack 337, win 350, options [nop,nop,TS val 2004405848 ecr 2004405848], length 0
+IP 127.0.0.1.35915 > 127.0.0.1.6379: Flags [.], ack 7, win 342, options [nop,nop,TS val 2004405848 ecr 2004405848], length 0
diff --git a/tests/resp_1_benchmark.pcap b/tests/resp_1_benchmark.pcap
new file mode 100644
index 0000000..b746f1c
--- /dev/null
+++ b/tests/resp_1_benchmark.pcap
Binary files differ
diff --git a/tests/resp_2.out b/tests/resp_2.out
new file mode 100644
index 0000000..37333d7
--- /dev/null
+++ b/tests/resp_2.out
@@ -0,0 +1,14 @@
+IP 127.0.0.1.35934 > 127.0.0.1.6379: Flags [S], seq 270581733, win 43690, options [mss 65495,sackOK,TS val 2004413385 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35934: Flags [S.], seq 3524975383, ack 270581734, win 43690, options [mss 65495,sackOK,TS val 2004413385 ecr 2004413385,nop,wscale 7], length 0
+IP 127.0.0.1.35934 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 2004413385 ecr 2004413385], length 0
+IP 127.0.0.1.35934 > 127.0.0.1.6379: Flags [P.], seq 1:13, ack 1, win 342, options [nop,nop,TS val 2004413683 ecr 2004413385], length 12: RESP "set test 1"
+IP 127.0.0.1.6379 > 127.0.0.1.35934: Flags [.], ack 13, win 342, options [nop,nop,TS val 2004413683 ecr 2004413683], length 0
+IP 127.0.0.1.35934 > 127.0.0.1.6379: Flags [P.], seq 13:157, ack 1, win 342, options [nop,nop,TS val 2004413683 ecr 2004413683], length 144: RESP "incr test" "set test2 redis" "get test2" "lpush test3 r" "lpush test3 e" "lpush test3 d" "lpush test3 i" "lpush test3 s" "lrange test3 0 -1" "del test4"
+IP 127.0.0.1.6379 > 127.0.0.1.35934: Flags [.], ack 157, win 350, options [nop,nop,TS val 2004413683 ecr 2004413683], length 0
+IP 127.0.0.1.35934 > 127.0.0.1.6379: Flags [P.], seq 157:168, ack 1, win 342, options [nop,nop,TS val 2004413683 ecr 2004413683], length 11: RESP "get test4"
+IP 127.0.0.1.6379 > 127.0.0.1.35934: Flags [.], ack 168, win 350, options [nop,nop,TS val 2004413683 ecr 2004413683], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35934: Flags [P.], seq 1:1289, ack 168, win 350, options [nop,nop,TS val 2004413683 ecr 2004413683], length 1288: RESP "OK" "2" "OK" "redis" "170" "171" "172" "173" "174" "s" "i" "d" "e" "r" "s" "i" "d" "e" "r" "s" "i" "d" "e" "r" "s" "i" "d" "e" "r" "s" "i" "d" "e" "r" "s" "i" "d" "e" "r" "s" "i" "d" "e" "r" "s" "i" "d" "e" "r" "s" "i" "d" "e" "r" "s" "i" "d" "e" "r" "s" "i" "d" "e" "r" "s" "i" "d" "e" "r" "s" "i" "d" "e" "r" "s" "i" "d" "e" "r" "s" "i" "d" "e" "r" "s" "i" "d" "e" "r" "s" "i" "d" "e" "r" "s" "i" "d" "e" "r" "s" "i" "d" "e" "r" "s" "i" "d" "e" "r" "i" "r" "s" "i" "d" "e" "r" "s" "i" "d" "e" "r" "s" "i" "d" "e" "r" "s" "i" "d" "e" "r" "s" "i" "d" "e" "r" "s" "i" "d" "e" "r" "s" "i" "d" "e" "r" "d" "r" "s" "i" "d" "e" "r" "s" "i" "d" "e" "r" "s" "i" "d" "e" "r" "s" "i" "d" "e" "r" "s" "i" "d" "e" "r" "i" "s" "i" "e" "r" "s" "i" "d" "e" "r" "0" null
+IP 127.0.0.1.35934 > 127.0.0.1.6379: Flags [.], ack 1289, win 1365, options [nop,nop,TS val 2004413683 ecr 2004413683], length 0
+IP 127.0.0.1.35934 > 127.0.0.1.6379: Flags [F.], seq 168, ack 1289, win 1365, options [nop,nop,TS val 2004413984 ecr 2004413683], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.35934: Flags [F.], seq 1289, ack 169, win 350, options [nop,nop,TS val 2004413984 ecr 2004413984], length 0
+IP 127.0.0.1.35934 > 127.0.0.1.6379: Flags [.], ack 1290, win 1365, options [nop,nop,TS val 2004413984 ecr 2004413984], length 0
diff --git a/tests/resp_2_inline.pcap b/tests/resp_2_inline.pcap
new file mode 100644
index 0000000..e22b5f2
--- /dev/null
+++ b/tests/resp_2_inline.pcap
Binary files differ
diff --git a/tests/resp_3.out b/tests/resp_3.out
new file mode 100644
index 0000000..1852f4e
--- /dev/null
+++ b/tests/resp_3.out
@@ -0,0 +1,163 @@
+IP 127.0.0.1.52759 > 127.0.0.1.6379: Flags [F.], seq 2169831382, ack 489972337, win 342, options [nop,nop,TS val 1132418034 ecr 1132417734], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52759: Flags [F.], seq 1, ack 1, win 342, options [nop,nop,TS val 1132418034 ecr 1132418034], length 0
+IP 127.0.0.1.52759 > 127.0.0.1.6379: Flags [.], ack 2, win 342, options [nop,nop,TS val 1132418034 ecr 1132418034], length 0
+IP 127.0.0.1.52760 > 127.0.0.1.6379: Flags [S], seq 264055152, win 43690, options [mss 65495,sackOK,TS val 1132418037 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52760: Flags [S.], seq 4227148888, ack 264055153, win 43690, options [mss 65495,sackOK,TS val 1132418037 ecr 1132418037,nop,wscale 7], length 0
+IP 127.0.0.1.52760 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 1132418037 ecr 1132418037], length 0
+IP 127.0.0.1.52760 > 127.0.0.1.6379: Flags [P.], seq 1:7, ack 1, win 342, options [nop,nop,TS val 1132418037 ecr 1132418037], length 6: RESP empty
+IP 127.0.0.1.6379 > 127.0.0.1.52760: Flags [.], ack 7, win 342, options [nop,nop,TS val 1132418037 ecr 1132418037], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52760: Flags [P.], seq 1:28, ack 7, win 342, options [nop,nop,TS val 1132418037 ecr 1132418037], length 27: RESP "ERR unknown command '$0'"
+IP 127.0.0.1.52760 > 127.0.0.1.6379: Flags [.], ack 28, win 342, options [nop,nop,TS val 1132418037 ecr 1132418037], length 0
+IP 127.0.0.1.52760 > 127.0.0.1.6379: Flags [F.], seq 7, ack 28, win 342, options [nop,nop,TS val 1132418337 ecr 1132418037], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52760: Flags [F.], seq 28, ack 8, win 342, options [nop,nop,TS val 1132418337 ecr 1132418337], length 0
+IP 127.0.0.1.52760 > 127.0.0.1.6379: Flags [.], ack 29, win 342, options [nop,nop,TS val 1132418337 ecr 1132418337], length 0
+IP 127.0.0.1.52763 > 127.0.0.1.6379: Flags [S], seq 4029577365, win 43690, options [mss 65495,sackOK,TS val 1132418340 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52763: Flags [S.], seq 365322185, ack 4029577366, win 43690, options [mss 65495,sackOK,TS val 1132418340 ecr 1132418340,nop,wscale 7], length 0
+IP 127.0.0.1.52763 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 1132418340 ecr 1132418340], length 0
+IP 127.0.0.1.52763 > 127.0.0.1.6379: Flags [P.], seq 1:4, ack 1, win 342, options [nop,nop,TS val 1132418340 ecr 1132418340], length 3: RESP ""
+IP 127.0.0.1.6379 > 127.0.0.1.52763: Flags [.], ack 4, win 342, options [nop,nop,TS val 1132418340 ecr 1132418340], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52763: Flags [P.], seq 1:27, ack 4, win 342, options [nop,nop,TS val 1132418340 ecr 1132418340], length 26: RESP "ERR unknown command '+'"
+IP 127.0.0.1.52763 > 127.0.0.1.6379: Flags [.], ack 27, win 342, options [nop,nop,TS val 1132418340 ecr 1132418340], length 0
+IP 127.0.0.1.52763 > 127.0.0.1.6379: Flags [F.], seq 4, ack 27, win 342, options [nop,nop,TS val 1132418640 ecr 1132418340], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52763: Flags [F.], seq 27, ack 5, win 342, options [nop,nop,TS val 1132418640 ecr 1132418640], length 0
+IP 127.0.0.1.52763 > 127.0.0.1.6379: Flags [.], ack 28, win 342, options [nop,nop,TS val 1132418640 ecr 1132418640], length 0
+IP 127.0.0.1.52764 > 127.0.0.1.6379: Flags [S], seq 3994485171, win 43690, options [mss 65495,sackOK,TS val 1132418642 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52764: Flags [S.], seq 3089553256, ack 3994485172, win 43690, options [mss 65495,sackOK,TS val 1132418642 ecr 1132418642,nop,wscale 7], length 0
+IP 127.0.0.1.52764 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 1132418642 ecr 1132418642], length 0
+IP 127.0.0.1.52764 > 127.0.0.1.6379: Flags [P.], seq 1:4, ack 1, win 342, options [nop,nop,TS val 1132418642 ecr 1132418642], length 3: RESP ""
+IP 127.0.0.1.6379 > 127.0.0.1.52764: Flags [.], ack 4, win 342, options [nop,nop,TS val 1132418642 ecr 1132418642], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52764: Flags [P.], seq 1:27, ack 4, win 342, options [nop,nop,TS val 1132418642 ecr 1132418642], length 26: RESP "ERR unknown command '-'"
+IP 127.0.0.1.52764 > 127.0.0.1.6379: Flags [.], ack 27, win 342, options [nop,nop,TS val 1132418642 ecr 1132418642], length 0
+IP 127.0.0.1.52764 > 127.0.0.1.6379: Flags [F.], seq 4, ack 27, win 342, options [nop,nop,TS val 1132418942 ecr 1132418642], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52764: Flags [F.], seq 27, ack 5, win 342, options [nop,nop,TS val 1132418942 ecr 1132418942], length 0
+IP 127.0.0.1.52764 > 127.0.0.1.6379: Flags [.], ack 28, win 342, options [nop,nop,TS val 1132418942 ecr 1132418942], length 0
+IP 127.0.0.1.52765 > 127.0.0.1.6379: Flags [S], seq 3235592213, win 43690, options [mss 65495,sackOK,TS val 1132418944 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52765: Flags [S.], seq 1213611847, ack 3235592214, win 43690, options [mss 65495,sackOK,TS val 1132418944 ecr 1132418944,nop,wscale 7], length 0
+IP 127.0.0.1.52765 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 1132418944 ecr 1132418944], length 0
+IP 127.0.0.1.52765 > 127.0.0.1.6379: Flags [P.], seq 1:4, ack 1, win 342, options [nop,nop,TS val 1132418944 ecr 1132418944], length 3: RESP ""
+IP 127.0.0.1.6379 > 127.0.0.1.52765: Flags [.], ack 4, win 342, options [nop,nop,TS val 1132418944 ecr 1132418944], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52765: Flags [P.], seq 1:27, ack 4, win 342, options [nop,nop,TS val 1132418945 ecr 1132418944], length 26: RESP "ERR unknown command ':'"
+IP 127.0.0.1.52765 > 127.0.0.1.6379: Flags [.], ack 27, win 342, options [nop,nop,TS val 1132418945 ecr 1132418945], length 0
+IP 127.0.0.1.52765 > 127.0.0.1.6379: Flags [F.], seq 4, ack 27, win 342, options [nop,nop,TS val 1132419244 ecr 1132418945], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52765: Flags [F.], seq 27, ack 5, win 342, options [nop,nop,TS val 1132419244 ecr 1132419244], length 0
+IP 127.0.0.1.52765 > 127.0.0.1.6379: Flags [.], ack 28, win 342, options [nop,nop,TS val 1132419244 ecr 1132419244], length 0
+IP 127.0.0.1.52766 > 127.0.0.1.6379: Flags [S], seq 1161779316, win 43690, options [mss 65495,sackOK,TS val 1132419247 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52766: Flags [S.], seq 1206331179, ack 1161779317, win 43690, options [mss 65495,sackOK,TS val 1132419247 ecr 1132419247,nop,wscale 7], length 0
+IP 127.0.0.1.52766 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 1132419247 ecr 1132419247], length 0
+IP 127.0.0.1.52766 > 127.0.0.1.6379: Flags [P.], seq 1:89, ack 1, win 342, options [nop,nop,TS val 1132419247 ecr 1132419247], length 88: RESP "0392049029024920492304923049032940329402394092304932049230492034932094032940234902340"
+IP 127.0.0.1.6379 > 127.0.0.1.52766: Flags [.], ack 89, win 342, options [nop,nop,TS val 1132419247 ecr 1132419247], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52766: Flags [P.], seq 1:112, ack 89, win 342, options [nop,nop,TS val 1132419247 ecr 1132419247], length 111: RESP "ERR unknown command ':0392049029024920492304923049032940329402394092304932049230492034932094032940234902340'"
+IP 127.0.0.1.52766 > 127.0.0.1.6379: Flags [.], ack 112, win 342, options [nop,nop,TS val 1132419247 ecr 1132419247], length 0
+IP 127.0.0.1.52766 > 127.0.0.1.6379: Flags [F.], seq 89, ack 112, win 342, options [nop,nop,TS val 1132419547 ecr 1132419247], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52766: Flags [F.], seq 112, ack 90, win 342, options [nop,nop,TS val 1132419547 ecr 1132419547], length 0
+IP 127.0.0.1.52766 > 127.0.0.1.6379: Flags [.], ack 113, win 342, options [nop,nop,TS val 1132419547 ecr 1132419547], length 0
+IP 127.0.0.1.52767 > 127.0.0.1.6379: Flags [S], seq 3453687710, win 43690, options [mss 65495,sackOK,TS val 1132419549 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52767: Flags [S.], seq 4076862539, ack 3453687711, win 43690, options [mss 65495,sackOK,TS val 1132419549 ecr 1132419549,nop,wscale 7], length 0
+IP 127.0.0.1.52767 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 1132419549 ecr 1132419549], length 0
+IP 127.0.0.1.52767 > 127.0.0.1.6379: Flags [P.], seq 1:39, ack 1, win 342, options [nop,nop,TS val 1132419549 ecr 1132419549], length 38: RESP length too large
+IP 127.0.0.1.6379 > 127.0.0.1.52767: Flags [.], ack 39, win 342, options [nop,nop,TS val 1132419549 ecr 1132419549], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52767: Flags [P.], seq 1:48, ack 39, win 342, options [nop,nop,TS val 1132419549 ecr 1132419549], length 47: RESP "ERR Protocol error: invalid multibulk length"
+IP 127.0.0.1.52767 > 127.0.0.1.6379: Flags [.], ack 48, win 342, options [nop,nop,TS val 1132419549 ecr 1132419549], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52767: Flags [F.], seq 48, ack 39, win 342, options [nop,nop,TS val 1132419549 ecr 1132419549], length 0
+IP 127.0.0.1.52767 > 127.0.0.1.6379: Flags [F.], seq 39, ack 49, win 342, options [nop,nop,TS val 1132419549 ecr 1132419549], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52767: Flags [.], ack 40, win 342, options [nop,nop,TS val 1132419549 ecr 1132419549], length 0
+IP 127.0.0.1.52768 > 127.0.0.1.6379: Flags [S], seq 3109305893, win 43690, options [mss 65495,sackOK,TS val 1132419852 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52768: Flags [S.], seq 4202059680, ack 3109305894, win 43690, options [mss 65495,sackOK,TS val 1132419852 ecr 1132419852,nop,wscale 7], length 0
+IP 127.0.0.1.52768 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 1132419852 ecr 1132419852], length 0
+IP 127.0.0.1.52768 > 127.0.0.1.6379: Flags [P.], seq 1:7, ack 1, win 342, options [nop,nop,TS val 1132419852 ecr 1132419852], length 6: RESP length negative and not -1
+IP 127.0.0.1.6379 > 127.0.0.1.52768: Flags [.], ack 7, win 342, options [nop,nop,TS val 1132419852 ecr 1132419852], length 0
+IP 127.0.0.1.52768 > 127.0.0.1.6379: Flags [F.], seq 7, ack 1, win 342, options [nop,nop,TS val 1132420152 ecr 1132419852], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52768: Flags [F.], seq 1, ack 8, win 342, options [nop,nop,TS val 1132420152 ecr 1132420152], length 0
+IP 127.0.0.1.52768 > 127.0.0.1.6379: Flags [.], ack 2, win 342, options [nop,nop,TS val 1132420152 ecr 1132420152], length 0
+IP 127.0.0.1.52769 > 127.0.0.1.6379: Flags [S], seq 4072438166, win 43690, options [mss 65495,sackOK,TS val 1132420154 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52769: Flags [S.], seq 156730490, ack 4072438167, win 43690, options [mss 65495,sackOK,TS val 1132420154 ecr 1132420154,nop,wscale 7], length 0
+IP 127.0.0.1.52769 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 1132420154 ecr 1132420154], length 0
+IP 127.0.0.1.52769 > 127.0.0.1.6379: Flags [P.], seq 1:11, ack 1, win 342, options [nop,nop,TS val 1132420154 ecr 1132420154], length 10: RESP length negative and not -1 "hi"
+IP 127.0.0.1.6379 > 127.0.0.1.52769: Flags [.], ack 11, win 342, options [nop,nop,TS val 1132420154 ecr 1132420154], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52769: Flags [P.], seq 1:57, ack 11, win 342, options [nop,nop,TS val 1132420154 ecr 1132420154], length 56: RESP "ERR unknown command '$-20'" "ERR unknown command 'hi'"
+IP 127.0.0.1.52769 > 127.0.0.1.6379: Flags [.], ack 57, win 342, options [nop,nop,TS val 1132420154 ecr 1132420154], length 0
+IP 127.0.0.1.52769 > 127.0.0.1.6379: Flags [F.], seq 11, ack 57, win 342, options [nop,nop,TS val 1132420454 ecr 1132420154], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52769: Flags [F.], seq 57, ack 12, win 342, options [nop,nop,TS val 1132420454 ecr 1132420454], length 0
+IP 127.0.0.1.52769 > 127.0.0.1.6379: Flags [.], ack 58, win 342, options [nop,nop,TS val 1132420454 ecr 1132420454], length 0
+IP 127.0.0.1.52770 > 127.0.0.1.6379: Flags [S], seq 374549345, win 43690, options [mss 65495,sackOK,TS val 1132420457 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52770: Flags [S.], seq 1146630634, ack 374549346, win 43690, options [mss 65495,sackOK,TS val 1132420457 ecr 1132420457,nop,wscale 7], length 0
+IP 127.0.0.1.52770 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 1132420457 ecr 1132420457], length 0
+IP 127.0.0.1.52770 > 127.0.0.1.6379: Flags [P.], seq 1:7, ack 1, win 342, options [nop,nop,TS val 1132420457 ecr 1132420457], length 6: RESP [|RESP]
+IP 127.0.0.1.6379 > 127.0.0.1.52770: Flags [.], ack 7, win 342, options [nop,nop,TS val 1132420457 ecr 1132420457], length 0
+IP 127.0.0.1.52770 > 127.0.0.1.6379: Flags [F.], seq 7, ack 1, win 342, options [nop,nop,TS val 1132420757 ecr 1132420457], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52770: Flags [F.], seq 1, ack 8, win 342, options [nop,nop,TS val 1132420757 ecr 1132420757], length 0
+IP 127.0.0.1.52770 > 127.0.0.1.6379: Flags [.], ack 2, win 342, options [nop,nop,TS val 1132420757 ecr 1132420757], length 0
+IP 127.0.0.1.52771 > 127.0.0.1.6379: Flags [S], seq 2541241523, win 43690, options [mss 65495,sackOK,TS val 1132420760 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52771: Flags [S.], seq 3482468888, ack 2541241524, win 43690, options [mss 65495,sackOK,TS val 1132420760 ecr 1132420760,nop,wscale 7], length 0
+IP 127.0.0.1.52771 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 1132420760 ecr 1132420760], length 0
+IP 127.0.0.1.52771 > 127.0.0.1.6379: Flags [P.], seq 1:7, ack 1, win 342, options [nop,nop,TS val 1132420760 ecr 1132420760], length 6: RESP [|RESP]
+IP 127.0.0.1.6379 > 127.0.0.1.52771: Flags [.], ack 7, win 342, options [nop,nop,TS val 1132420760 ecr 1132420760], length 0
+IP 127.0.0.1.52771 > 127.0.0.1.6379: Flags [F.], seq 7, ack 1, win 342, options [nop,nop,TS val 1132421059 ecr 1132420760], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52771: Flags [F.], seq 1, ack 8, win 342, options [nop,nop,TS val 1132421059 ecr 1132421059], length 0
+IP 127.0.0.1.52771 > 127.0.0.1.6379: Flags [.], ack 2, win 342, options [nop,nop,TS val 1132421059 ecr 1132421059], length 0
+IP 127.0.0.1.52772 > 127.0.0.1.6379: Flags [S], seq 3376019145, win 43690, options [mss 65495,sackOK,TS val 1132421060 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52772: Flags [S.], seq 2449011991, ack 3376019146, win 43690, options [mss 65495,sackOK,TS val 1132421060 ecr 1132421060,nop,wscale 7], length 0
+IP 127.0.0.1.52772 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 1132421060 ecr 1132421060], length 0
+IP 127.0.0.1.52772 > 127.0.0.1.6379: Flags [P.], seq 1:7, ack 1, win 342, options [nop,nop,TS val 1132421060 ecr 1132421060], length 6: RESP [|RESP]
+IP 127.0.0.1.6379 > 127.0.0.1.52772: Flags [.], ack 7, win 342, options [nop,nop,TS val 1132421060 ecr 1132421060], length 0
+IP 127.0.0.1.52772 > 127.0.0.1.6379: Flags [F.], seq 7, ack 1, win 342, options [nop,nop,TS val 1132421360 ecr 1132421060], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52772: Flags [F.], seq 1, ack 8, win 342, options [nop,nop,TS val 1132421360 ecr 1132421360], length 0
+IP 127.0.0.1.52772 > 127.0.0.1.6379: Flags [.], ack 2, win 342, options [nop,nop,TS val 1132421360 ecr 1132421360], length 0
+IP 127.0.0.1.52773 > 127.0.0.1.6379: Flags [S], seq 3567970909, win 43690, options [mss 65495,sackOK,TS val 1132421363 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52773: Flags [S.], seq 3366370739, ack 3567970910, win 43690, options [mss 65495,sackOK,TS val 1132421363 ecr 1132421363,nop,wscale 7], length 0
+IP 127.0.0.1.52773 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 1132421363 ecr 1132421363], length 0
+IP 127.0.0.1.52773 > 127.0.0.1.6379: Flags [P.], seq 1:6, ack 1, win 342, options [nop,nop,TS val 1132421363 ecr 1132421363], length 5: RESP null
+IP 127.0.0.1.6379 > 127.0.0.1.52773: Flags [.], ack 6, win 342, options [nop,nop,TS val 1132421363 ecr 1132421363], length 0
+IP 127.0.0.1.52773 > 127.0.0.1.6379: Flags [F.], seq 6, ack 1, win 342, options [nop,nop,TS val 1132421663 ecr 1132421363], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52773: Flags [F.], seq 1, ack 7, win 342, options [nop,nop,TS val 1132421663 ecr 1132421663], length 0
+IP 127.0.0.1.52773 > 127.0.0.1.6379: Flags [.], ack 2, win 342, options [nop,nop,TS val 1132421663 ecr 1132421663], length 0
+IP 127.0.0.1.52775 > 127.0.0.1.6379: Flags [S], seq 3374943379, win 43690, options [mss 65495,sackOK,TS val 1132421665 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52775: Flags [S.], seq 363870070, ack 3374943380, win 43690, options [mss 65495,sackOK,TS val 1132421665 ecr 1132421665,nop,wscale 7], length 0
+IP 127.0.0.1.52775 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 1132421665 ecr 1132421665], length 0
+IP 127.0.0.1.52775 > 127.0.0.1.6379: Flags [P.], seq 1:6, ack 1, win 342, options [nop,nop,TS val 1132421665 ecr 1132421665], length 5: RESP null
+IP 127.0.0.1.6379 > 127.0.0.1.52775: Flags [.], ack 6, win 342, options [nop,nop,TS val 1132421665 ecr 1132421665], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52775: Flags [P.], seq 1:29, ack 6, win 342, options [nop,nop,TS val 1132421665 ecr 1132421665], length 28: RESP "ERR unknown command '$-1'"
+IP 127.0.0.1.52775 > 127.0.0.1.6379: Flags [.], ack 29, win 342, options [nop,nop,TS val 1132421665 ecr 1132421665], length 0
+IP 127.0.0.1.52775 > 127.0.0.1.6379: Flags [F.], seq 6, ack 29, win 342, options [nop,nop,TS val 1132421965 ecr 1132421665], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52775: Flags [F.], seq 29, ack 7, win 342, options [nop,nop,TS val 1132421965 ecr 1132421965], length 0
+IP 127.0.0.1.52775 > 127.0.0.1.6379: Flags [.], ack 30, win 342, options [nop,nop,TS val 1132421965 ecr 1132421965], length 0
+IP 127.0.0.1.52776 > 127.0.0.1.6379: Flags [S], seq 2780863902, win 43690, options [mss 65495,sackOK,TS val 1132421969 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52776: Flags [S.], seq 2789065616, ack 2780863903, win 43690, options [mss 65495,sackOK,TS val 1132421969 ecr 1132421969,nop,wscale 7], length 0
+IP 127.0.0.1.52776 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 1132421969 ecr 1132421969], length 0
+IP 127.0.0.1.52776 > 127.0.0.1.6379: Flags [P.], seq 1:64, ack 1, win 342, options [nop,nop,TS val 1132421969 ecr 1132421969], length 63: RESP "INCR" "z" "INCR" "z" "INCR" "z"
+IP 127.0.0.1.6379 > 127.0.0.1.52776: Flags [.], ack 64, win 342, options [nop,nop,TS val 1132421969 ecr 1132421969], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52776: Flags [P.], seq 1:16, ack 64, win 342, options [nop,nop,TS val 1132421969 ecr 1132421969], length 15: RESP "69" "70" "71"
+IP 127.0.0.1.52776 > 127.0.0.1.6379: Flags [.], ack 16, win 342, options [nop,nop,TS val 1132421969 ecr 1132421969], length 0
+IP 127.0.0.1.52776 > 127.0.0.1.6379: Flags [F.], seq 64, ack 16, win 342, options [nop,nop,TS val 1132422270 ecr 1132421969], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52776: Flags [F.], seq 16, ack 65, win 342, options [nop,nop,TS val 1132422270 ecr 1132422270], length 0
+IP 127.0.0.1.52776 > 127.0.0.1.6379: Flags [.], ack 17, win 342, options [nop,nop,TS val 1132422270 ecr 1132422270], length 0
+IP 127.0.0.1.52777 > 127.0.0.1.6379: Flags [S], seq 357339476, win 43690, options [mss 65495,sackOK,TS val 1132422271 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52777: Flags [S.], seq 3123925211, ack 357339477, win 43690, options [mss 65495,sackOK,TS val 1132422271 ecr 1132422271,nop,wscale 7], length 0
+IP 127.0.0.1.52777 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 1132422271 ecr 1132422271], length 0
+IP 127.0.0.1.52777 > 127.0.0.1.6379: Flags [P.], seq 1:21, ack 1, win 342, options [nop,nop,TS val 1132422271 ecr 1132422271], length 20: RESP "PING" "PING" "PING"
+IP 127.0.0.1.6379 > 127.0.0.1.52777: Flags [.], ack 21, win 342, options [nop,nop,TS val 1132422271 ecr 1132422271], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52777: Flags [P.], seq 1:22, ack 21, win 342, options [nop,nop,TS val 1132422271 ecr 1132422271], length 21: RESP "PONG" "PONG" "PONG"
+IP 127.0.0.1.52777 > 127.0.0.1.6379: Flags [.], ack 22, win 342, options [nop,nop,TS val 1132422271 ecr 1132422271], length 0
+IP 127.0.0.1.52777 > 127.0.0.1.6379: Flags [F.], seq 21, ack 22, win 342, options [nop,nop,TS val 1132422571 ecr 1132422271], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52777: Flags [F.], seq 22, ack 22, win 342, options [nop,nop,TS val 1132422571 ecr 1132422571], length 0
+IP 127.0.0.1.52777 > 127.0.0.1.6379: Flags [.], ack 23, win 342, options [nop,nop,TS val 1132422571 ecr 1132422571], length 0
+IP 127.0.0.1.52778 > 127.0.0.1.6379: Flags [S], seq 2069568772, win 43690, options [mss 65495,sackOK,TS val 1132422573 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52778: Flags [S.], seq 1085796497, ack 2069568773, win 43690, options [mss 65495,sackOK,TS val 1132422573 ecr 1132422573,nop,wscale 7], length 0
+IP 127.0.0.1.52778 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 1132422573 ecr 1132422573], length 0
+IP 127.0.0.1.52778 > 127.0.0.1.6379: Flags [P.], seq 1:21, ack 1, win 342, options [nop,nop,TS val 1132422573 ecr 1132422573], length 20: RESP "PING" "PING" "PING"
+IP 127.0.0.1.6379 > 127.0.0.1.52778: Flags [.], ack 21, win 342, options [nop,nop,TS val 1132422573 ecr 1132422573], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52778: Flags [P.], seq 1:22, ack 21, win 342, options [nop,nop,TS val 1132422573 ecr 1132422573], length 21: RESP "PONG" "PONG" "PONG"
+IP 127.0.0.1.52778 > 127.0.0.1.6379: Flags [.], ack 22, win 342, options [nop,nop,TS val 1132422573 ecr 1132422573], length 0
+IP 127.0.0.1.52778 > 127.0.0.1.6379: Flags [F.], seq 21, ack 22, win 342, options [nop,nop,TS val 1132422873 ecr 1132422573], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52778: Flags [F.], seq 22, ack 22, win 342, options [nop,nop,TS val 1132422873 ecr 1132422873], length 0
+IP 127.0.0.1.52778 > 127.0.0.1.6379: Flags [.], ack 23, win 342, options [nop,nop,TS val 1132422873 ecr 1132422873], length 0
+IP 127.0.0.1.52779 > 127.0.0.1.6379: Flags [S], seq 1578479120, win 43690, options [mss 65495,sackOK,TS val 1132422875 ecr 0,nop,wscale 7], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52779: Flags [S.], seq 2529957046, ack 1578479121, win 43690, options [mss 65495,sackOK,TS val 1132422875 ecr 1132422875,nop,wscale 7], length 0
+IP 127.0.0.1.52779 > 127.0.0.1.6379: Flags [.], ack 1, win 342, options [nop,nop,TS val 1132422875 ecr 1132422875], length 0
+IP 127.0.0.1.52779 > 127.0.0.1.6379: Flags [P.], seq 1:24, ack 1, win 342, options [nop,nop,TS val 1132422875 ecr 1132422875], length 23: RESP "PING" "PING" "PING"
+IP 127.0.0.1.6379 > 127.0.0.1.52779: Flags [.], ack 24, win 342, options [nop,nop,TS val 1132422875 ecr 1132422875], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52779: Flags [P.], seq 1:22, ack 24, win 342, options [nop,nop,TS val 1132422875 ecr 1132422875], length 21: RESP "PONG" "PONG" "PONG"
+IP 127.0.0.1.52779 > 127.0.0.1.6379: Flags [.], ack 22, win 342, options [nop,nop,TS val 1132422875 ecr 1132422875], length 0
+IP 127.0.0.1.52779 > 127.0.0.1.6379: Flags [F.], seq 24, ack 22, win 342, options [nop,nop,TS val 1132423175 ecr 1132422875], length 0
+IP 127.0.0.1.6379 > 127.0.0.1.52779: Flags [F.], seq 22, ack 25, win 342, options [nop,nop,TS val 1132423175 ecr 1132423175], length 0
+IP 127.0.0.1.52779 > 127.0.0.1.6379: Flags [.], ack 23, win 342, options [nop,nop,TS val 1132423175 ecr 1132423175], length 0
diff --git a/tests/resp_3_malicious.pcap b/tests/resp_3_malicious.pcap
new file mode 100644
index 0000000..02cd53f
--- /dev/null
+++ b/tests/resp_3_malicious.pcap
Binary files differ
diff --git a/tests/rpl-14-daovvv.out b/tests/rpl-14-daovvv.out
index 7869e6b..7e4b8a5 100644
--- a/tests/rpl-14-daovvv.out
+++ b/tests/rpl-14-daovvv.out
@@ -1 +1 @@
-IP6 (hlim 64, next-header ICMPv6 (58) payload length: 24) fe80::216:3eff:fe11:3424 > ff02::1: [icmp6 sum ok] ICMP6, RPL, (CLR)Destination Advertisement Object [dagid:pandora is fun0x0al,seq:1,instance:1,Dagid,40]
+IP6 (hlim 64, next-header ICMPv6 (58) payload length: 24) fe80::216:3eff:fe11:3424 > ff02::1: [icmp6 sum ok] ICMP6, RPL, (CLR)Destination Advertisement Object [dagid:7061:6e64:6f72:6120:6973:2066:756e:a6c,seq:1,instance:1,Dagid,40]
diff --git a/tests/rpl-19-pickdag.out b/tests/rpl-19-pickdag.out
index 2460ada..d3c41ee 100644
--- a/tests/rpl-19-pickdag.out
+++ b/tests/rpl-19-pickdag.out
@@ -1 +1 @@
-IP6 (hlim 64, next-header ICMPv6 (58) payload length: 56) fe80::216:3eff:fe11:3424 > fe80::216:3eff:fe11:3424: [icmp6 sum ok] ICMP6, RPL, (CLR)Destination Advertisement Object [dagid:T10x000x000x000x000x000x000x000x000x000x000x000x000x000x00,seq:10,instance:42,Dagid,40] opt:rpltarget len:25  opt:pad0 opt:pad0 opt:pad0 opt:pad0 opt:pad0 opt:pad0 opt:pad0
+IP6 (hlim 64, next-header ICMPv6 (58) payload length: 56) fe80::216:3eff:fe11:3424 > fe80::216:3eff:fe11:3424: [icmp6 sum ok] ICMP6, RPL, (CLR)Destination Advertisement Object [dagid:5431::,seq:10,instance:42,Dagid,40] opt:rpltarget len:25  opt:pad0 opt:pad0 opt:pad0 opt:pad0 opt:pad0 opt:pad0 opt:pad0
diff --git a/tests/rpl-19-pickdagvvv.out b/tests/rpl-19-pickdagvvv.out
index bd93453..deee033 100644
--- a/tests/rpl-19-pickdagvvv.out
+++ b/tests/rpl-19-pickdagvvv.out
@@ -1 +1 @@
-IP6 (hlim 64, next-header ICMPv6 (58) payload length: 56) fe80::216:3eff:fe11:3424 > fe80::216:3eff:fe11:3424: [icmp6 sum ok] ICMP6, RPL, (CLR)Destination Advertisement Object [dagid:T10x000x000x000x000x000x000x000x000x000x000x000x000x000x00,seq:10,instance:42,Dagid,40] opt:rpltarget len:25  0x0000:  0080 2001 0db8 0001 0000 0216 3eff fe11 0x0010:  3424 0000 0000 00 opt:pad0 opt:pad0 opt:pad0 opt:pad0 opt:pad0 opt:pad0 opt:pad0
+IP6 (hlim 64, next-header ICMPv6 (58) payload length: 56) fe80::216:3eff:fe11:3424 > fe80::216:3eff:fe11:3424: [icmp6 sum ok] ICMP6, RPL, (CLR)Destination Advertisement Object [dagid:5431::,seq:10,instance:42,Dagid,40] opt:rpltarget len:25  0x0000:  0080 2001 0db8 0001 0000 0216 3eff fe11 0x0010:  3424 0000 0000 00 opt:pad0 opt:pad0 opt:pad0 opt:pad0 opt:pad0 opt:pad0 opt:pad0
diff --git a/tests/rpl-26-senddaovv.out b/tests/rpl-26-senddaovv.out
index 6d11c81..1b642bb 100644
--- a/tests/rpl-26-senddaovv.out
+++ b/tests/rpl-26-senddaovv.out
@@ -1 +1 @@
-IP6 (hlim 64, next-header ICMPv6 (58) payload length: 24) fe80::216:3eff:fe11:3424 > ff02::1: [icmp6 sum ok] ICMP6, RPL, (CLR)Destination Advertisement Object Ack [dagid:thisismydicedag2,seq:11,instance:43,status:0]
+IP6 (hlim 64, next-header ICMPv6 (58) payload length: 24) fe80::216:3eff:fe11:3424 > ff02::1: [icmp6 sum ok] ICMP6, RPL, (CLR)Destination Advertisement Object Ack [dagid:7468:6973:6973:6d79:6469:6365:6461:6732,seq:11,instance:43,status:0]
diff --git a/tests/rsvp-inf-loop-2-v.out b/tests/rsvp-inf-loop-2-v.out
new file mode 100644
index 0000000..03696fb
--- /dev/null
+++ b/tests/rsvp-inf-loop-2-v.out
@@ -0,0 +1,12 @@
+IP (tos 0x0, ttl 254, id 0, offset 0, flags [none], proto RSVP (46), length 268, options (RA))
+    10.31.0.1 > 10.33.0.1: 
+	RSVPv1 Path Message (1), Flags: [none], length: 244, ttl: 254, checksum: 0x0ca3
+	  Session Object (1) Flags: [reject if unknown], Class-Type: Tunnel IPv4 (7), length: 16
+	    IPv4 Tunnel EndPoint: 10.33.0.1, Tunnel ID: 0x0004, Extended Tunnel ID: 10.31.0.1
+	  RSVP Hop Object (3) Flags: [reject if unknown], Class-Type: IPv4 (1), length: 12
+	    Previous/Next Interface: 10.1.2.1, Logical Interface Handle: 0x98006700
+	  Time Values Object (5) Flags: [reject if unknown], Class-Type: 1 (1), length: 8
+	    Refresh Period: 30000ms
+	  ERO Object (20) Flags: [reject if unknown], Class-Type: IPv4 (1), length: 36
+	    Subobject Type: IPv4 prefix, length 8, Strict, 10.1.2.2/32, Flags: [none]
+	    Subobject Type: IPv4 prefix, length 8 ERROR: Prefix length 70 != 32 (invalid)
diff --git a/tests/rsvp-inf-loop-2.pcap b/tests/rsvp-inf-loop-2.pcap
new file mode 100644
index 0000000..e2caa2a
--- /dev/null
+++ b/tests/rsvp-inf-loop-2.pcap
Binary files differ
diff --git a/tests/rtp-seg-fault-1.out b/tests/rtp-seg-fault-1.out
new file mode 100644
index 0000000..d18ab8c
--- /dev/null
+++ b/tests/rtp-seg-fault-1.out
@@ -0,0 +1,2 @@
+IP (tos 0x0, ttl 255, id 158, offset 0, flags [DF], proto UDP (17), length 37, bad cksum d7e0 (->9cf8)!)
+    208.21.2.184.1512 > 10.1.1.99.53: udp/rtp 57323 c31 +* 4652 3815804996 [|rtp]
diff --git a/tests/rtp-seg-fault-1.pcap b/tests/rtp-seg-fault-1.pcap
new file mode 100644
index 0000000..5a0510c
--- /dev/null
+++ b/tests/rtp-seg-fault-1.pcap
Binary files differ
diff --git a/tests/rtp-seg-fault-2.out b/tests/rtp-seg-fault-2.out
new file mode 100644
index 0000000..1c504da
--- /dev/null
+++ b/tests/rtp-seg-fault-2.out
@@ -0,0 +1,2 @@
+IP (tos 0x0, ttl 252, id 8264, offset 0, flags [none], proto UDP (17), length 100, bad cksum f803 (->c00f)!)
+    208.21.2.184.1512 > 10.1.1.99.514: udp/rtp -12 c31 + 31926 3881022529 455123981 [|rtp]
diff --git a/tests/rtp-seg-fault-2.pcap b/tests/rtp-seg-fault-2.pcap
new file mode 100644
index 0000000..77fefbf
--- /dev/null
+++ b/tests/rtp-seg-fault-2.pcap
Binary files differ
diff --git a/tests/scps_invalid.out b/tests/scps_invalid.out
new file mode 100644
index 0000000..31e8384
--- /dev/null
+++ b/tests/scps_invalid.out
@@ -0,0 +1,2 @@
+IP 182.181.202.230.52750 > 83.253.102.83.63764: Flags [S], seq 3757264999, win 8192, options [mss 1452,nop,wscale 2,nop,nop,scps[bad opt]>
+IP 182.181.158.21.53052 > 83.253.102.83.30122: Flags [S], seq 2824624414, win 8192, options [mss 1452,nop,wscale 2,nop,nop,scps[bad opt]>
diff --git a/tests/scps_invalid.pcap b/tests/scps_invalid.pcap
new file mode 100644
index 0000000..e420bae
--- /dev/null
+++ b/tests/scps_invalid.pcap
Binary files differ
diff --git a/tests/snmp-heapoverflow-1.out b/tests/snmp-heapoverflow-1.out
new file mode 100644
index 0000000..b885607
--- /dev/null
+++ b/tests/snmp-heapoverflow-1.out
@@ -0,0 +1,21 @@
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
+	0x0010:  3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
+	0x0020:  3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
+	0x0030:  3030                                     00
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
+	0x0010:  3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
+	0x0020:  3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
+	0x0030:  3030                                     00
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
+	0x0010:  3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
+	0x0020:  3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
+	0x0030:  3030                                     00
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
+	0x0010:  3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
+	0x0020:  3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
+	0x0030:  3030                                     00
+IP 48.48.48.48.12336 > 48.48.48.48.161:  [|snmp]
diff --git a/tests/snmp-heapoverflow-1.pcap b/tests/snmp-heapoverflow-1.pcap
new file mode 100644
index 0000000..83e5759
--- /dev/null
+++ b/tests/snmp-heapoverflow-1.pcap
Binary files differ
diff --git a/tests/snmp-heapoverflow-2.out b/tests/snmp-heapoverflow-2.out
new file mode 100644
index 0000000..9878915
--- /dev/null
+++ b/tests/snmp-heapoverflow-2.out
@@ -0,0 +1 @@
+IP 48.48.48.48.12336 > 48.48.48.48.162:  [|snmp]
diff --git a/tests/snmp-heapoverflow-2.pcap b/tests/snmp-heapoverflow-2.pcap
new file mode 100644
index 0000000..19fd248
--- /dev/null
+++ b/tests/snmp-heapoverflow-2.pcap
Binary files differ
diff --git a/tests/spb_bpduv4-v.out b/tests/spb_bpduv4-v.out
new file mode 100644
index 0000000..019b249
--- /dev/null
+++ b/tests/spb_bpduv4-v.out
@@ -0,0 +1,400 @@
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+	port-role Designated, CIST root-id 8000.52:54:00:45:5f:15, CIST ext-pathcost 0
+	CIST regional-root-id 8000.52:54:00:45:5f:15, CIST port-id 8003,
+	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
+	v3len 80, MCID Name IEEE802.1 SPB Default, rev 0,
+		digest 67d768dfa948eb5e9fd54077e80975a2, CIST int-root-pathcost 0,
+	CIST bridge-id 8000.52:54:00:45:5f:15, CIST remaining-hops 20
+	MSTI 10, Flags [Learn, Forward], port-role Designated
+		MSTI regional-root-id 800a.52:54:00:45:5f:15, pathcost 0
+		MSTI bridge-prio 8, port-prio 8, hops 20
+	v4len 85, AUXMCID Name IEEE802.1 SPB Default, Rev 0,
+		digest c8bd946a00815f86ace612b9f8616283
+	Agreement num 0, Discarded Agreement num 0, Agreement valid-flag 0,
+	Restricted role-flag: 0, Format id 0 cap 0, Convention id 2 cap 32,
+	Edge count 32, Agreement digest 0000000e918994fa9ca00398d9138a3e54000000
+
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+	port-role Designated, CIST root-id 8000.52:54:00:45:5f:15, CIST ext-pathcost 0
+	CIST regional-root-id 8000.52:54:00:45:5f:15, CIST port-id 8003,
+	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
+	v3len 80, MCID Name IEEE802.1 SPB Default, rev 0,
+		digest 67d768dfa948eb5e9fd54077e80975a2, CIST int-root-pathcost 0,
+	CIST bridge-id 8000.52:54:00:45:5f:15, CIST remaining-hops 20
+	MSTI 10, Flags [Learn, Forward], port-role Designated
+		MSTI regional-root-id 800a.52:54:00:45:5f:15, pathcost 0
+		MSTI bridge-prio 8, port-prio 8, hops 20
+	v4len 85, AUXMCID Name IEEE802.1 SPB Default, Rev 0,
+		digest c8bd946a00815f86ace612b9f8616283
+	Agreement num 0, Discarded Agreement num 0, Agreement valid-flag 0,
+	Restricted role-flag: 0, Format id 0 cap 0, Convention id 2 cap 32,
+	Edge count 32, Agreement digest 0000000e918994fa9ca00398d9138a3e54000000
+
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+	port-role Designated, CIST root-id 8000.52:54:00:45:5f:15, CIST ext-pathcost 0
+	CIST regional-root-id 8000.52:54:00:45:5f:15, CIST port-id 8003,
+	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
+	v3len 80, MCID Name IEEE802.1 SPB Default, rev 0,
+		digest 67d768dfa948eb5e9fd54077e80975a2, CIST int-root-pathcost 0,
+	CIST bridge-id 8000.52:54:00:45:5f:15, CIST remaining-hops 20
+	MSTI 10, Flags [Learn, Forward], port-role Designated
+		MSTI regional-root-id 800a.52:54:00:45:5f:15, pathcost 0
+		MSTI bridge-prio 8, port-prio 8, hops 20
+	v4len 85, AUXMCID Name IEEE802.1 SPB Default, Rev 0,
+		digest c8bd946a00815f86ace612b9f8616283
+	Agreement num 0, Discarded Agreement num 0, Agreement valid-flag 0,
+	Restricted role-flag: 0, Format id 0 cap 0, Convention id 2 cap 32,
+	Edge count 32, Agreement digest 0000000e918994fa9ca00398d9138a3e54000000
+
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+	port-role Designated, CIST root-id 8000.52:54:00:45:5f:15, CIST ext-pathcost 0
+	CIST regional-root-id 8000.52:54:00:45:5f:15, CIST port-id 8003,
+	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
+	v3len 80, MCID Name IEEE802.1 SPB Default, rev 0,
+		digest 67d768dfa948eb5e9fd54077e80975a2, CIST int-root-pathcost 0,
+	CIST bridge-id 8000.52:54:00:45:5f:15, CIST remaining-hops 20
+	MSTI 10, Flags [Learn, Forward], port-role Designated
+		MSTI regional-root-id 800a.52:54:00:45:5f:15, pathcost 0
+		MSTI bridge-prio 8, port-prio 8, hops 20
+	v4len 85, AUXMCID Name IEEE802.1 SPB Default, Rev 0,
+		digest c8bd946a00815f86ace612b9f8616283
+	Agreement num 0, Discarded Agreement num 0, Agreement valid-flag 0,
+	Restricted role-flag: 0, Format id 0 cap 0, Convention id 2 cap 32,
+	Edge count 32, Agreement digest 0000000e918994fa9ca00398d9138a3e54000000
+
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+	port-role Designated, CIST root-id 8000.52:54:00:45:5f:15, CIST ext-pathcost 0
+	CIST regional-root-id 8000.52:54:00:45:5f:15, CIST port-id 8003,
+	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
+	v3len 80, MCID Name IEEE802.1 SPB Default, rev 0,
+		digest 67d768dfa948eb5e9fd54077e80975a2, CIST int-root-pathcost 0,
+	CIST bridge-id 8000.52:54:00:45:5f:15, CIST remaining-hops 20
+	MSTI 10, Flags [Learn, Forward], port-role Designated
+		MSTI regional-root-id 800a.52:54:00:45:5f:15, pathcost 0
+		MSTI bridge-prio 8, port-prio 8, hops 20
+	v4len 85, AUXMCID Name IEEE802.1 SPB Default, Rev 0,
+		digest c8bd946a00815f86ace612b9f8616283
+	Agreement num 0, Discarded Agreement num 0, Agreement valid-flag 0,
+	Restricted role-flag: 0, Format id 0 cap 0, Convention id 2 cap 32,
+	Edge count 32, Agreement digest 0000000e918994fa9ca00398d9138a3e54000000
+
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+	port-role Designated, CIST root-id 8000.52:54:00:45:5f:15, CIST ext-pathcost 0
+	CIST regional-root-id 8000.52:54:00:45:5f:15, CIST port-id 8003,
+	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
+	v3len 80, MCID Name IEEE802.1 SPB Default, rev 0,
+		digest 67d768dfa948eb5e9fd54077e80975a2, CIST int-root-pathcost 0,
+	CIST bridge-id 8000.52:54:00:45:5f:15, CIST remaining-hops 20
+	MSTI 10, Flags [Learn, Forward], port-role Designated
+		MSTI regional-root-id 800a.52:54:00:45:5f:15, pathcost 0
+		MSTI bridge-prio 8, port-prio 8, hops 20
+	v4len 85, AUXMCID Name IEEE802.1 SPB Default, Rev 0,
+		digest c8bd946a00815f86ace612b9f8616283
+	Agreement num 0, Discarded Agreement num 0, Agreement valid-flag 0,
+	Restricted role-flag: 0, Format id 0 cap 0, Convention id 2 cap 32,
+	Edge count 32, Agreement digest 0000000e918994fa9ca00398d9138a3e54000000
+
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+	port-role Designated, CIST root-id 8000.52:54:00:45:5f:15, CIST ext-pathcost 0
+	CIST regional-root-id 8000.52:54:00:45:5f:15, CIST port-id 8003,
+	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
+	v3len 80, MCID Name IEEE802.1 SPB Default, rev 0,
+		digest 67d768dfa948eb5e9fd54077e80975a2, CIST int-root-pathcost 0,
+	CIST bridge-id 8000.52:54:00:45:5f:15, CIST remaining-hops 20
+	MSTI 10, Flags [Learn, Forward], port-role Designated
+		MSTI regional-root-id 800a.52:54:00:45:5f:15, pathcost 0
+		MSTI bridge-prio 8, port-prio 8, hops 20
+	v4len 85, AUXMCID Name IEEE802.1 SPB Default, Rev 0,
+		digest c8bd946a00815f86ace612b9f8616283
+	Agreement num 0, Discarded Agreement num 0, Agreement valid-flag 0,
+	Restricted role-flag: 0, Format id 0 cap 0, Convention id 2 cap 32,
+	Edge count 32, Agreement digest 0000000e918994fa9ca00398d9138a3e54000000
+
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+	port-role Designated, CIST root-id 8000.52:54:00:45:5f:15, CIST ext-pathcost 0
+	CIST regional-root-id 8000.52:54:00:45:5f:15, CIST port-id 8003,
+	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
+	v3len 80, MCID Name IEEE802.1 SPB Default, rev 0,
+		digest 67d768dfa948eb5e9fd54077e80975a2, CIST int-root-pathcost 0,
+	CIST bridge-id 8000.52:54:00:45:5f:15, CIST remaining-hops 20
+	MSTI 10, Flags [Learn, Forward], port-role Designated
+		MSTI regional-root-id 800a.52:54:00:45:5f:15, pathcost 0
+		MSTI bridge-prio 8, port-prio 8, hops 20
+	v4len 85, AUXMCID Name IEEE802.1 SPB Default, Rev 0,
+		digest c8bd946a00815f86ace612b9f8616283
+	Agreement num 0, Discarded Agreement num 0, Agreement valid-flag 0,
+	Restricted role-flag: 0, Format id 0 cap 0, Convention id 2 cap 32,
+	Edge count 32, Agreement digest 0000000e918994fa9ca00398d9138a3e54000000
+
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+	port-role Designated, CIST root-id 8000.52:54:00:45:5f:15, CIST ext-pathcost 0
+	CIST regional-root-id 8000.52:54:00:45:5f:15, CIST port-id 8003,
+	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
+	v3len 80, MCID Name IEEE802.1 SPB Default, rev 0,
+		digest 67d768dfa948eb5e9fd54077e80975a2, CIST int-root-pathcost 0,
+	CIST bridge-id 8000.52:54:00:45:5f:15, CIST remaining-hops 20
+	MSTI 10, Flags [Learn, Forward], port-role Designated
+		MSTI regional-root-id 800a.52:54:00:45:5f:15, pathcost 0
+		MSTI bridge-prio 8, port-prio 8, hops 20
+	v4len 85, AUXMCID Name IEEE802.1 SPB Default, Rev 0,
+		digest c8bd946a00815f86ace612b9f8616283
+	Agreement num 0, Discarded Agreement num 0, Agreement valid-flag 0,
+	Restricted role-flag: 0, Format id 0 cap 0, Convention id 2 cap 32,
+	Edge count 32, Agreement digest 0000000e918994fa9ca00398d9138a3e54000000
+
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+	port-role Designated, CIST root-id 8000.52:54:00:45:5f:15, CIST ext-pathcost 0
+	CIST regional-root-id 8000.52:54:00:45:5f:15, CIST port-id 8003,
+	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
+	v3len 80, MCID Name IEEE802.1 SPB Default, rev 0,
+		digest 67d768dfa948eb5e9fd54077e80975a2, CIST int-root-pathcost 0,
+	CIST bridge-id 8000.52:54:00:45:5f:15, CIST remaining-hops 20
+	MSTI 10, Flags [Learn, Forward], port-role Designated
+		MSTI regional-root-id 800a.52:54:00:45:5f:15, pathcost 0
+		MSTI bridge-prio 8, port-prio 8, hops 20
+	v4len 85, AUXMCID Name IEEE802.1 SPB Default, Rev 0,
+		digest c8bd946a00815f86ace612b9f8616283
+	Agreement num 0, Discarded Agreement num 0, Agreement valid-flag 0,
+	Restricted role-flag: 0, Format id 0 cap 0, Convention id 2 cap 32,
+	Edge count 32, Agreement digest 0000000e918994fa9ca00398d9138a3e54000000
+
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+	port-role Designated, CIST root-id 8000.52:54:00:45:5f:15, CIST ext-pathcost 0
+	CIST regional-root-id 8000.52:54:00:45:5f:15, CIST port-id 8003,
+	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
+	v3len 80, MCID Name IEEE802.1 SPB Default, rev 0,
+		digest 67d768dfa948eb5e9fd54077e80975a2, CIST int-root-pathcost 0,
+	CIST bridge-id 8000.52:54:00:45:5f:15, CIST remaining-hops 20
+	MSTI 10, Flags [Learn, Forward], port-role Designated
+		MSTI regional-root-id 800a.52:54:00:45:5f:15, pathcost 0
+		MSTI bridge-prio 8, port-prio 8, hops 20
+	v4len 85, AUXMCID Name IEEE802.1 SPB Default, Rev 0,
+		digest c8bd946a00815f86ace612b9f8616283
+	Agreement num 0, Discarded Agreement num 0, Agreement valid-flag 0,
+	Restricted role-flag: 0, Format id 0 cap 0, Convention id 2 cap 32,
+	Edge count 32, Agreement digest 0000000e918994fa9ca00398d9138a3e54000000
+
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+	port-role Designated, CIST root-id 8000.52:54:00:45:5f:15, CIST ext-pathcost 0
+	CIST regional-root-id 8000.52:54:00:45:5f:15, CIST port-id 8003,
+	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
+	v3len 80, MCID Name IEEE802.1 SPB Default, rev 0,
+		digest 67d768dfa948eb5e9fd54077e80975a2, CIST int-root-pathcost 0,
+	CIST bridge-id 8000.52:54:00:45:5f:15, CIST remaining-hops 20
+	MSTI 10, Flags [Learn, Forward], port-role Designated
+		MSTI regional-root-id 800a.52:54:00:45:5f:15, pathcost 0
+		MSTI bridge-prio 8, port-prio 8, hops 20
+	v4len 85, AUXMCID Name IEEE802.1 SPB Default, Rev 0,
+		digest c8bd946a00815f86ace612b9f8616283
+	Agreement num 0, Discarded Agreement num 0, Agreement valid-flag 0,
+	Restricted role-flag: 0, Format id 0 cap 0, Convention id 2 cap 32,
+	Edge count 32, Agreement digest 0000000e918994fa9ca00398d9138a3e54000000
+
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+	port-role Designated, CIST root-id 8000.52:54:00:45:5f:15, CIST ext-pathcost 0
+	CIST regional-root-id 8000.52:54:00:45:5f:15, CIST port-id 8003,
+	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
+	v3len 80, MCID Name IEEE802.1 SPB Default, rev 0,
+		digest 67d768dfa948eb5e9fd54077e80975a2, CIST int-root-pathcost 0,
+	CIST bridge-id 8000.52:54:00:45:5f:15, CIST remaining-hops 20
+	MSTI 10, Flags [Learn, Forward], port-role Designated
+		MSTI regional-root-id 800a.52:54:00:45:5f:15, pathcost 0
+		MSTI bridge-prio 8, port-prio 8, hops 20
+	v4len 85, AUXMCID Name IEEE802.1 SPB Default, Rev 0,
+		digest c8bd946a00815f86ace612b9f8616283
+	Agreement num 0, Discarded Agreement num 0, Agreement valid-flag 0,
+	Restricted role-flag: 0, Format id 0 cap 0, Convention id 2 cap 32,
+	Edge count 32, Agreement digest 0000000e918994fa9ca00398d9138a3e54000000
+
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+	port-role Designated, CIST root-id 8000.52:54:00:45:5f:15, CIST ext-pathcost 0
+	CIST regional-root-id 8000.52:54:00:45:5f:15, CIST port-id 8003,
+	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
+	v3len 80, MCID Name IEEE802.1 SPB Default, rev 0,
+		digest 67d768dfa948eb5e9fd54077e80975a2, CIST int-root-pathcost 0,
+	CIST bridge-id 8000.52:54:00:45:5f:15, CIST remaining-hops 20
+	MSTI 10, Flags [Learn, Forward], port-role Designated
+		MSTI regional-root-id 800a.52:54:00:45:5f:15, pathcost 0
+		MSTI bridge-prio 8, port-prio 8, hops 20
+	v4len 85, AUXMCID Name IEEE802.1 SPB Default, Rev 0,
+		digest c8bd946a00815f86ace612b9f8616283
+	Agreement num 0, Discarded Agreement num 0, Agreement valid-flag 0,
+	Restricted role-flag: 0, Format id 0 cap 0, Convention id 2 cap 32,
+	Edge count 32, Agreement digest 0000000e918994fa9ca00398d9138a3e54000000
+
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+	port-role Designated, CIST root-id 8000.52:54:00:45:5f:15, CIST ext-pathcost 0
+	CIST regional-root-id 8000.52:54:00:45:5f:15, CIST port-id 8003,
+	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
+	v3len 80, MCID Name IEEE802.1 SPB Default, rev 0,
+		digest 67d768dfa948eb5e9fd54077e80975a2, CIST int-root-pathcost 0,
+	CIST bridge-id 8000.52:54:00:45:5f:15, CIST remaining-hops 20
+	MSTI 10, Flags [Learn, Forward], port-role Designated
+		MSTI regional-root-id 800a.52:54:00:45:5f:15, pathcost 0
+		MSTI bridge-prio 8, port-prio 8, hops 20
+	v4len 85, AUXMCID Name IEEE802.1 SPB Default, Rev 0,
+		digest c8bd946a00815f86ace612b9f8616283
+	Agreement num 0, Discarded Agreement num 0, Agreement valid-flag 0,
+	Restricted role-flag: 0, Format id 0 cap 0, Convention id 2 cap 32,
+	Edge count 32, Agreement digest 0000000e918994fa9ca00398d9138a3e54000000
+
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+	port-role Designated, CIST root-id 8000.52:54:00:45:5f:15, CIST ext-pathcost 0
+	CIST regional-root-id 8000.52:54:00:45:5f:15, CIST port-id 8003,
+	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
+	v3len 80, MCID Name IEEE802.1 SPB Default, rev 0,
+		digest 67d768dfa948eb5e9fd54077e80975a2, CIST int-root-pathcost 0,
+	CIST bridge-id 8000.52:54:00:45:5f:15, CIST remaining-hops 20
+	MSTI 10, Flags [Learn, Forward], port-role Designated
+		MSTI regional-root-id 800a.52:54:00:45:5f:15, pathcost 0
+		MSTI bridge-prio 8, port-prio 8, hops 20
+	v4len 85, AUXMCID Name IEEE802.1 SPB Default, Rev 0,
+		digest c8bd946a00815f86ace612b9f8616283
+	Agreement num 0, Discarded Agreement num 0, Agreement valid-flag 0,
+	Restricted role-flag: 0, Format id 0 cap 0, Convention id 2 cap 32,
+	Edge count 32, Agreement digest 0000000e918994fa9ca00398d9138a3e54000000
+
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+	port-role Designated, CIST root-id 8000.52:54:00:45:5f:15, CIST ext-pathcost 0
+	CIST regional-root-id 8000.52:54:00:45:5f:15, CIST port-id 8003,
+	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
+	v3len 80, MCID Name IEEE802.1 SPB Default, rev 0,
+		digest 67d768dfa948eb5e9fd54077e80975a2, CIST int-root-pathcost 0,
+	CIST bridge-id 8000.52:54:00:45:5f:15, CIST remaining-hops 20
+	MSTI 10, Flags [Learn, Forward], port-role Designated
+		MSTI regional-root-id 800a.52:54:00:45:5f:15, pathcost 0
+		MSTI bridge-prio 8, port-prio 8, hops 20
+	v4len 85, AUXMCID Name IEEE802.1 SPB Default, Rev 0,
+		digest c8bd946a00815f86ace612b9f8616283
+	Agreement num 0, Discarded Agreement num 0, Agreement valid-flag 0,
+	Restricted role-flag: 0, Format id 0 cap 0, Convention id 2 cap 32,
+	Edge count 32, Agreement digest 0000000e918994fa9ca00398d9138a3e54000000
+
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+	port-role Designated, CIST root-id 8000.52:54:00:45:5f:15, CIST ext-pathcost 0
+	CIST regional-root-id 8000.52:54:00:45:5f:15, CIST port-id 8003,
+	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
+	v3len 80, MCID Name IEEE802.1 SPB Default, rev 0,
+		digest 67d768dfa948eb5e9fd54077e80975a2, CIST int-root-pathcost 0,
+	CIST bridge-id 8000.52:54:00:45:5f:15, CIST remaining-hops 20
+	MSTI 10, Flags [Learn, Forward], port-role Designated
+		MSTI regional-root-id 800a.52:54:00:45:5f:15, pathcost 0
+		MSTI bridge-prio 8, port-prio 8, hops 20
+	v4len 85, AUXMCID Name IEEE802.1 SPB Default, Rev 0,
+		digest c8bd946a00815f86ace612b9f8616283
+	Agreement num 0, Discarded Agreement num 0, Agreement valid-flag 0,
+	Restricted role-flag: 0, Format id 0 cap 0, Convention id 2 cap 32,
+	Edge count 32, Agreement digest 0000000e918994fa9ca00398d9138a3e54000000
+
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+	port-role Designated, CIST root-id 8000.52:54:00:45:5f:15, CIST ext-pathcost 0
+	CIST regional-root-id 8000.52:54:00:45:5f:15, CIST port-id 8003,
+	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
+	v3len 80, MCID Name IEEE802.1 SPB Default, rev 0,
+		digest 67d768dfa948eb5e9fd54077e80975a2, CIST int-root-pathcost 0,
+	CIST bridge-id 8000.52:54:00:45:5f:15, CIST remaining-hops 20
+	MSTI 10, Flags [Learn, Forward], port-role Designated
+		MSTI regional-root-id 800a.52:54:00:45:5f:15, pathcost 0
+		MSTI bridge-prio 8, port-prio 8, hops 20
+	v4len 85, AUXMCID Name IEEE802.1 SPB Default, Rev 0,
+		digest c8bd946a00815f86ace612b9f8616283
+	Agreement num 0, Discarded Agreement num 0, Agreement valid-flag 0,
+	Restricted role-flag: 0, Format id 0 cap 0, Convention id 2 cap 32,
+	Edge count 32, Agreement digest 0000000e918994fa9ca00398d9138a3e54000000
+
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+	port-role Designated, CIST root-id 8000.52:54:00:45:5f:15, CIST ext-pathcost 0
+	CIST regional-root-id 8000.52:54:00:45:5f:15, CIST port-id 8003,
+	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
+	v3len 80, MCID Name IEEE802.1 SPB Default, rev 0,
+		digest 67d768dfa948eb5e9fd54077e80975a2, CIST int-root-pathcost 0,
+	CIST bridge-id 8000.52:54:00:45:5f:15, CIST remaining-hops 20
+	MSTI 10, Flags [Learn, Forward], port-role Designated
+		MSTI regional-root-id 800a.52:54:00:45:5f:15, pathcost 0
+		MSTI bridge-prio 8, port-prio 8, hops 20
+	v4len 85, AUXMCID Name IEEE802.1 SPB Default, Rev 0,
+		digest c8bd946a00815f86ace612b9f8616283
+	Agreement num 0, Discarded Agreement num 0, Agreement valid-flag 0,
+	Restricted role-flag: 0, Format id 0 cap 0, Convention id 2 cap 32,
+	Edge count 32, Agreement digest 0000000e918994fa9ca00398d9138a3e54000000
+
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+	port-role Designated, CIST root-id 8000.52:54:00:45:5f:15, CIST ext-pathcost 0
+	CIST regional-root-id 8000.52:54:00:45:5f:15, CIST port-id 8003,
+	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
+	v3len 80, MCID Name IEEE802.1 SPB Default, rev 0,
+		digest 67d768dfa948eb5e9fd54077e80975a2, CIST int-root-pathcost 0,
+	CIST bridge-id 8000.52:54:00:45:5f:15, CIST remaining-hops 20
+	MSTI 10, Flags [Learn, Forward], port-role Designated
+		MSTI regional-root-id 800a.52:54:00:45:5f:15, pathcost 0
+		MSTI bridge-prio 8, port-prio 8, hops 20
+	v4len 85, AUXMCID Name IEEE802.1 SPB Default, Rev 0,
+		digest c8bd946a00815f86ace612b9f8616283
+	Agreement num 0, Discarded Agreement num 0, Agreement valid-flag 0,
+	Restricted role-flag: 0, Format id 0 cap 0, Convention id 2 cap 32,
+	Edge count 32, Agreement digest 0000000e918994fa9ca00398d9138a3e54000000
+
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+	port-role Designated, CIST root-id 8000.52:54:00:45:5f:15, CIST ext-pathcost 0
+	CIST regional-root-id 8000.52:54:00:45:5f:15, CIST port-id 8003,
+	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
+	v3len 80, MCID Name IEEE802.1 SPB Default, rev 0,
+		digest 67d768dfa948eb5e9fd54077e80975a2, CIST int-root-pathcost 0,
+	CIST bridge-id 8000.52:54:00:45:5f:15, CIST remaining-hops 20
+	MSTI 10, Flags [Learn, Forward], port-role Designated
+		MSTI regional-root-id 800a.52:54:00:45:5f:15, pathcost 0
+		MSTI bridge-prio 8, port-prio 8, hops 20
+	v4len 85, AUXMCID Name IEEE802.1 SPB Default, Rev 0,
+		digest c8bd946a00815f86ace612b9f8616283
+	Agreement num 0, Discarded Agreement num 0, Agreement valid-flag 0,
+	Restricted role-flag: 0, Format id 0 cap 0, Convention id 2 cap 32,
+	Edge count 32, Agreement digest 0000000e918994fa9ca00398d9138a3e54000000
+
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+	port-role Designated, CIST root-id 8000.52:54:00:45:5f:15, CIST ext-pathcost 0
+	CIST regional-root-id 8000.52:54:00:45:5f:15, CIST port-id 8003,
+	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
+	v3len 80, MCID Name IEEE802.1 SPB Default, rev 0,
+		digest 67d768dfa948eb5e9fd54077e80975a2, CIST int-root-pathcost 0,
+	CIST bridge-id 8000.52:54:00:45:5f:15, CIST remaining-hops 20
+	MSTI 10, Flags [Learn, Forward], port-role Designated
+		MSTI regional-root-id 800a.52:54:00:45:5f:15, pathcost 0
+		MSTI bridge-prio 8, port-prio 8, hops 20
+	v4len 85, AUXMCID Name IEEE802.1 SPB Default, Rev 0,
+		digest c8bd946a00815f86ace612b9f8616283
+	Agreement num 0, Discarded Agreement num 0, Agreement valid-flag 0,
+	Restricted role-flag: 0, Format id 0 cap 0, Convention id 2 cap 32,
+	Edge count 32, Agreement digest 0000000e918994fa9ca00398d9138a3e54000000
+
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+	port-role Designated, CIST root-id 8000.52:54:00:45:5f:15, CIST ext-pathcost 0
+	CIST regional-root-id 8000.52:54:00:45:5f:15, CIST port-id 8003,
+	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
+	v3len 80, MCID Name IEEE802.1 SPB Default, rev 0,
+		digest 67d768dfa948eb5e9fd54077e80975a2, CIST int-root-pathcost 0,
+	CIST bridge-id 8000.52:54:00:45:5f:15, CIST remaining-hops 20
+	MSTI 10, Flags [Learn, Forward], port-role Designated
+		MSTI regional-root-id 800a.52:54:00:45:5f:15, pathcost 0
+		MSTI bridge-prio 8, port-prio 8, hops 20
+	v4len 85, AUXMCID Name IEEE802.1 SPB Default, Rev 0,
+		digest c8bd946a00815f86ace612b9f8616283
+	Agreement num 0, Discarded Agreement num 0, Agreement valid-flag 0,
+	Restricted role-flag: 0, Format id 0 cap 0, Convention id 2 cap 32,
+	Edge count 32, Agreement digest 0000000e918994fa9ca00398d9138a3e54000000
+
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+	port-role Designated, CIST root-id 8000.52:54:00:45:5f:15, CIST ext-pathcost 0
+	CIST regional-root-id 8000.52:54:00:45:5f:15, CIST port-id 8003,
+	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
+	v3len 80, MCID Name IEEE802.1 SPB Default, rev 0,
+		digest 67d768dfa948eb5e9fd54077e80975a2, CIST int-root-pathcost 0,
+	CIST bridge-id 8000.52:54:00:45:5f:15, CIST remaining-hops 20
+	MSTI 10, Flags [Learn, Forward], port-role Designated
+		MSTI regional-root-id 800a.52:54:00:45:5f:15, pathcost 0
+		MSTI bridge-prio 8, port-prio 8, hops 20
+	v4len 85, AUXMCID Name IEEE802.1 SPB Default, Rev 0,
+		digest c8bd946a00815f86ace612b9f8616283
+	Agreement num 0, Discarded Agreement num 0, Agreement valid-flag 0,
+	Restricted role-flag: 0, Format id 0 cap 0, Convention id 2 cap 32,
+	Edge count 32, Agreement digest 0000000e918994fa9ca00398d9138a3e54000000
+
diff --git a/tests/stp-heapoverflow-1.out b/tests/stp-heapoverflow-1.out
new file mode 100644
index 0000000..f4cc053
--- /dev/null
+++ b/tests/stp-heapoverflow-1.out
@@ -0,0 +1,27 @@
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 30                             00000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 30                             00000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 30                             00000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 30                             00000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 30                             00000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 30                             00000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 30                             00000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 30                             00000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 30                             00000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 30                             00000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 30                             00000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 30                             00000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 30                             00000
+[|stp 808464415]
diff --git a/tests/stp-heapoverflow-1.pcap b/tests/stp-heapoverflow-1.pcap
new file mode 100644
index 0000000..21fcce9
--- /dev/null
+++ b/tests/stp-heapoverflow-1.pcap
Binary files differ
diff --git a/tests/stp-heapoverflow-2.out b/tests/stp-heapoverflow-2.out
new file mode 100644
index 0000000..17dc5ef
--- /dev/null
+++ b/tests/stp-heapoverflow-2.out
@@ -0,0 +1,27 @@
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030                           000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030                           000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030                           000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030                           000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030                           000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030                           000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030                           000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030                           000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030                           000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030                           000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030                           000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030                           000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030                           000000
+STP 802.1d[|stp 808464415]
diff --git a/tests/stp-heapoverflow-2.pcap b/tests/stp-heapoverflow-2.pcap
new file mode 100644
index 0000000..83b572f
--- /dev/null
+++ b/tests/stp-heapoverflow-2.pcap
Binary files differ
diff --git a/tests/stp-heapoverflow-3.out b/tests/stp-heapoverflow-3.out
new file mode 100644
index 0000000..273a0df
--- /dev/null
+++ b/tests/stp-heapoverflow-3.out
@@ -0,0 +1,27 @@
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 30                                  000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 30                                  000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 30                                  000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 30                                  000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 30                                  000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 30                                  000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 30                                  000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 30                                  000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 30                                  000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 30                                  000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 30                                  000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 30                                  000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 30                                  000
+[|stp 808464415]
diff --git a/tests/stp-heapoverflow-3.pcap b/tests/stp-heapoverflow-3.pcap
new file mode 100644
index 0000000..3f33b0d
--- /dev/null
+++ b/tests/stp-heapoverflow-3.pcap
Binary files differ
diff --git a/tests/stp-heapoverflow-4.out b/tests/stp-heapoverflow-4.out
new file mode 100644
index 0000000..f2c3258
--- /dev/null
+++ b/tests/stp-heapoverflow-4.out
@@ -0,0 +1,27 @@
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030 3030                      00000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030 3030                      00000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030 3030                      00000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030 3030                      00000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030 3030                      00000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030 3030                      00000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030 3030                      00000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030 3030                      00000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030 3030                      00000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030 3030                      00000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030 3030                      00000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030 3030                      00000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030 3030                      00000000
+STP 802.1d, Config, Flags [Learn, Forward][|stp 808464415]
diff --git a/tests/stp-heapoverflow-4.pcap b/tests/stp-heapoverflow-4.pcap
new file mode 100644
index 0000000..76d2959
--- /dev/null
+++ b/tests/stp-heapoverflow-4.pcap
Binary files differ
diff --git a/tests/stp-heapoverflow-5.out b/tests/stp-heapoverflow-5.out
new file mode 100644
index 0000000..17dc5ef
--- /dev/null
+++ b/tests/stp-heapoverflow-5.out
@@ -0,0 +1,27 @@
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030                           000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030                           000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030                           000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030                           000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030                           000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030                           000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030                           000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030                           000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030                           000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030                           000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030                           000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030                           000000
+30:30:30:30:30:30 > 30:30:30:30:30:30, ethertype Unknown (0x3030), length 808464432: 
+	0x0000:  3030 3030 3030                           000000
+STP 802.1d[|stp 808464415]
diff --git a/tests/stp-heapoverflow-5.pcap b/tests/stp-heapoverflow-5.pcap
new file mode 100644
index 0000000..83b572f
--- /dev/null
+++ b/tests/stp-heapoverflow-5.pcap
Binary files differ
diff --git a/tests/tcp-auth-heapoverflow.out b/tests/tcp-auth-heapoverflow.out
new file mode 100644
index 0000000..b7ff7f7
--- /dev/null
+++ b/tests/tcp-auth-heapoverflow.out
@@ -0,0 +1,2 @@
+IP (tos 0x30, ttl 48, id 12336, offset 0, flags [DF], proto TCP (6), length 12336, bad cksum 3030 (->29a8)!)
+    48.48.48.48.12336 > 48.48.48.48.12336: Flags [.U], seq 808464432:808476696, ack 808464432, win 12336, urg 12336, options [tcp-ao keyid 48 rnextkeyid 48 mac 0x303030303030[|tcp]
diff --git a/tests/tcp-auth-heapoverflow.pcap b/tests/tcp-auth-heapoverflow.pcap
new file mode 100644
index 0000000..a9f823d
--- /dev/null
+++ b/tests/tcp-auth-heapoverflow.pcap
Binary files differ
diff --git a/tests/tcp_header_heapoverflow.out b/tests/tcp_header_heapoverflow.out
new file mode 100644
index 0000000..0f830ab
--- /dev/null
+++ b/tests/tcp_header_heapoverflow.out
@@ -0,0 +1,2 @@
+IP (tos 0x30, ttl 48, id 12336, offset 0, flags [none], proto TCP (6), length 12336, bad cksum 3030 (->69a8)!)
+    48.48.48.48.12336 > 48.48.48.48.12336: [|tcp]
diff --git a/tests/tcp_header_heapoverflow.pcap b/tests/tcp_header_heapoverflow.pcap
new file mode 100644
index 0000000..3d6b7c7
--- /dev/null
+++ b/tests/tcp_header_heapoverflow.pcap
Binary files differ
diff --git a/tests/tftp-heapoverflow.out b/tests/tftp-heapoverflow.out
new file mode 100644
index 0000000..0d68d45
--- /dev/null
+++ b/tests/tftp-heapoverflow.out
@@ -0,0 +1,2 @@
+IP (tos 0x30, ttl 48, id 12336, offset 0, flags [DF], proto UDP (17), length 12336, bad cksum 3030 (->299d)!)
+    48.48.48.48.69 > 48.48.48.48.12336:  12308 RRQ "00" [|tftp]
diff --git a/tests/tftp-heapoverflow.pcap b/tests/tftp-heapoverflow.pcap
new file mode 100644
index 0000000..c8800f6
--- /dev/null
+++ b/tests/tftp-heapoverflow.pcap
Binary files differ
diff --git a/tests/trunc_aack.out b/tests/trunc_aack.out
new file mode 100644
index 0000000..4b652c0
--- /dev/null
+++ b/tests/trunc_aack.out
@@ -0,0 +1 @@
+PAP, Auth-ACK (0x02), id 1[|pap]
diff --git a/tests/truncated-aack.pcap b/tests/truncated-aack.pcap
new file mode 100644
index 0000000..f90b9e9
--- /dev/null
+++ b/tests/truncated-aack.pcap
Binary files differ
diff --git a/tests/udld-inf-loop-1-v.out b/tests/udld-inf-loop-1-v.out
new file mode 100644
index 0000000..daeabbd
--- /dev/null
+++ b/tests/udld-inf-loop-1-v.out
@@ -0,0 +1,9 @@
+UDLDv1, Code Probe message (1), Flags [RT, RSY] (0x01), length 80
+	Checksum 0x3956 (unverified)
+	Device-ID TLV (0x0001) TLV, length 15, FOC1031Z7JG
+	Port-ID TLV (0x0002) TLV, length 9, Gi0/1
+	Echo TLV (0x0003) TLV, length 28, ^@^@^@^A^@^KFOC1025X4W3^@^EFa0/1
+	Message Interval TLV (0x0004) TLV, length 5, 15s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S1
+	Sequence Number TLV (0x0007) TLV, length 0 (invalid)
diff --git a/tests/udld-inf-loop-1.pcap b/tests/udld-inf-loop-1.pcap
new file mode 100644
index 0000000..652935c
--- /dev/null
+++ b/tests/udld-inf-loop-1.pcap
Binary files differ
diff --git a/tests/udld-v.out b/tests/udld-v.out
index cb55b8a..d4361f4 100644
--- a/tests/udld-v.out
+++ b/tests/udld-v.out
@@ -1,261 +1,261 @@
 UDLDv1, Code Probe message (1), Flags [RT, RSY] (0x03), length 60
 	Checksum 0x6d85 (unverified)
-	Device-ID TLV (0x0001) TLV, length 11, FOC1031Z7JG
-	Port-ID TLV (0x0002) TLV, length 5, Gi0/1
-	Echo TLV (0x0003) TLV, length 4, 
-	Message Interval TLV (0x0004) TLV, length 1, 7s
-	Timeout Interval TLV (0x0005) TLV, length 1, 5s
-	Device Name TLV (0x0006) TLV, length 2, S1
-	Sequence Number TLV (0x0007) TLV, length 4, 1
+	Device-ID TLV (0x0001) TLV, length 15, FOC1031Z7JG
+	Port-ID TLV (0x0002) TLV, length 9, Gi0/1
+	Echo TLV (0x0003) TLV, length 8, ^@^@^@^@
+	Message Interval TLV (0x0004) TLV, length 5, 7s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S1
+	Sequence Number TLV (0x0007) TLV, length 8, 1
 UDLDv1, Code Echo message (2), Flags [RT] (0x00), length 80
 	Checksum 0x805d (unverified)
-	Device-ID TLV (0x0001) TLV, length 11, FOC1025X4W3
-	Port-ID TLV (0x0002) TLV, length 5, Fa0/1
-	Echo TLV (0x0003) TLV, length 24, 
-	Message Interval TLV (0x0004) TLV, length 1, 7s
-	Timeout Interval TLV (0x0005) TLV, length 1, 5s
-	Device Name TLV (0x0006) TLV, length 2, S2
-	Sequence Number TLV (0x0007) TLV, length 4, 1
+	Device-ID TLV (0x0001) TLV, length 15, FOC1025X4W3
+	Port-ID TLV (0x0002) TLV, length 9, Fa0/1
+	Echo TLV (0x0003) TLV, length 28, ^@^@^@^A^@^KFOC1031Z7JG^@^EGi0/1
+	Message Interval TLV (0x0004) TLV, length 5, 7s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S2
+	Sequence Number TLV (0x0007) TLV, length 8, 1
 UDLDv1, Code Echo message (2), Flags [RT] (0x00), length 80
 	Checksum 0x805e (unverified)
-	Device-ID TLV (0x0001) TLV, length 11, FOC1031Z7JG
-	Port-ID TLV (0x0002) TLV, length 5, Gi0/1
-	Echo TLV (0x0003) TLV, length 24, 
-	Message Interval TLV (0x0004) TLV, length 1, 7s
-	Timeout Interval TLV (0x0005) TLV, length 1, 5s
-	Device Name TLV (0x0006) TLV, length 2, S1
-	Sequence Number TLV (0x0007) TLV, length 4, 1
+	Device-ID TLV (0x0001) TLV, length 15, FOC1031Z7JG
+	Port-ID TLV (0x0002) TLV, length 9, Gi0/1
+	Echo TLV (0x0003) TLV, length 28, ^@^@^@^A^@^KFOC1025X4W3^@^EFa0/1
+	Message Interval TLV (0x0004) TLV, length 5, 7s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S1
+	Sequence Number TLV (0x0007) TLV, length 8, 1
 UDLDv1, Code Echo message (2), Flags [RT] (0x00), length 80
 	Checksum 0x805c (unverified)
-	Device-ID TLV (0x0001) TLV, length 11, FOC1025X4W3
-	Port-ID TLV (0x0002) TLV, length 5, Fa0/1
-	Echo TLV (0x0003) TLV, length 24, 
-	Message Interval TLV (0x0004) TLV, length 1, 7s
-	Timeout Interval TLV (0x0005) TLV, length 1, 5s
-	Device Name TLV (0x0006) TLV, length 2, S2
-	Sequence Number TLV (0x0007) TLV, length 4, 2
+	Device-ID TLV (0x0001) TLV, length 15, FOC1025X4W3
+	Port-ID TLV (0x0002) TLV, length 9, Fa0/1
+	Echo TLV (0x0003) TLV, length 28, ^@^@^@^A^@^KFOC1031Z7JG^@^EGi0/1
+	Message Interval TLV (0x0004) TLV, length 5, 7s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S2
+	Sequence Number TLV (0x0007) TLV, length 8, 2
 UDLDv1, Code Echo message (2), Flags [RT] (0x00), length 80
 	Checksum 0x805d (unverified)
-	Device-ID TLV (0x0001) TLV, length 11, FOC1031Z7JG
-	Port-ID TLV (0x0002) TLV, length 5, Gi0/1
-	Echo TLV (0x0003) TLV, length 24, 
-	Message Interval TLV (0x0004) TLV, length 1, 7s
-	Timeout Interval TLV (0x0005) TLV, length 1, 5s
-	Device Name TLV (0x0006) TLV, length 2, S1
-	Sequence Number TLV (0x0007) TLV, length 4, 2
+	Device-ID TLV (0x0001) TLV, length 15, FOC1031Z7JG
+	Port-ID TLV (0x0002) TLV, length 9, Gi0/1
+	Echo TLV (0x0003) TLV, length 28, ^@^@^@^A^@^KFOC1025X4W3^@^EFa0/1
+	Message Interval TLV (0x0004) TLV, length 5, 7s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S1
+	Sequence Number TLV (0x0007) TLV, length 8, 2
 UDLDv1, Code Echo message (2), Flags [RT] (0x00), length 80
 	Checksum 0x805b (unverified)
-	Device-ID TLV (0x0001) TLV, length 11, FOC1025X4W3
-	Port-ID TLV (0x0002) TLV, length 5, Fa0/1
-	Echo TLV (0x0003) TLV, length 24, 
-	Message Interval TLV (0x0004) TLV, length 1, 7s
-	Timeout Interval TLV (0x0005) TLV, length 1, 5s
-	Device Name TLV (0x0006) TLV, length 2, S2
-	Sequence Number TLV (0x0007) TLV, length 4, 3
+	Device-ID TLV (0x0001) TLV, length 15, FOC1025X4W3
+	Port-ID TLV (0x0002) TLV, length 9, Fa0/1
+	Echo TLV (0x0003) TLV, length 28, ^@^@^@^A^@^KFOC1031Z7JG^@^EGi0/1
+	Message Interval TLV (0x0004) TLV, length 5, 7s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S2
+	Sequence Number TLV (0x0007) TLV, length 8, 3
 UDLDv1, Code Echo message (2), Flags [RT] (0x00), length 80
 	Checksum 0x805c (unverified)
-	Device-ID TLV (0x0001) TLV, length 11, FOC1031Z7JG
-	Port-ID TLV (0x0002) TLV, length 5, Gi0/1
-	Echo TLV (0x0003) TLV, length 24, 
-	Message Interval TLV (0x0004) TLV, length 1, 7s
-	Timeout Interval TLV (0x0005) TLV, length 1, 5s
-	Device Name TLV (0x0006) TLV, length 2, S1
-	Sequence Number TLV (0x0007) TLV, length 4, 3
+	Device-ID TLV (0x0001) TLV, length 15, FOC1031Z7JG
+	Port-ID TLV (0x0002) TLV, length 9, Gi0/1
+	Echo TLV (0x0003) TLV, length 28, ^@^@^@^A^@^KFOC1025X4W3^@^EFa0/1
+	Message Interval TLV (0x0004) TLV, length 5, 7s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S1
+	Sequence Number TLV (0x0007) TLV, length 8, 3
 UDLDv1, Code Echo message (2), Flags [RT] (0x00), length 80
 	Checksum 0x805a (unverified)
-	Device-ID TLV (0x0001) TLV, length 11, FOC1025X4W3
-	Port-ID TLV (0x0002) TLV, length 5, Fa0/1
-	Echo TLV (0x0003) TLV, length 24, 
-	Message Interval TLV (0x0004) TLV, length 1, 7s
-	Timeout Interval TLV (0x0005) TLV, length 1, 5s
-	Device Name TLV (0x0006) TLV, length 2, S2
-	Sequence Number TLV (0x0007) TLV, length 4, 4
+	Device-ID TLV (0x0001) TLV, length 15, FOC1025X4W3
+	Port-ID TLV (0x0002) TLV, length 9, Fa0/1
+	Echo TLV (0x0003) TLV, length 28, ^@^@^@^A^@^KFOC1031Z7JG^@^EGi0/1
+	Message Interval TLV (0x0004) TLV, length 5, 7s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S2
+	Sequence Number TLV (0x0007) TLV, length 8, 4
 UDLDv1, Code Echo message (2), Flags [RT] (0x00), length 80
 	Checksum 0x805b (unverified)
-	Device-ID TLV (0x0001) TLV, length 11, FOC1031Z7JG
-	Port-ID TLV (0x0002) TLV, length 5, Gi0/1
-	Echo TLV (0x0003) TLV, length 24, 
-	Message Interval TLV (0x0004) TLV, length 1, 7s
-	Timeout Interval TLV (0x0005) TLV, length 1, 5s
-	Device Name TLV (0x0006) TLV, length 2, S1
-	Sequence Number TLV (0x0007) TLV, length 4, 4
+	Device-ID TLV (0x0001) TLV, length 15, FOC1031Z7JG
+	Port-ID TLV (0x0002) TLV, length 9, Gi0/1
+	Echo TLV (0x0003) TLV, length 28, ^@^@^@^A^@^KFOC1025X4W3^@^EFa0/1
+	Message Interval TLV (0x0004) TLV, length 5, 7s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S1
+	Sequence Number TLV (0x0007) TLV, length 8, 4
 UDLDv1, Code Echo message (2), Flags [RT] (0x00), length 80
 	Checksum 0x8059 (unverified)
-	Device-ID TLV (0x0001) TLV, length 11, FOC1025X4W3
-	Port-ID TLV (0x0002) TLV, length 5, Fa0/1
-	Echo TLV (0x0003) TLV, length 24, 
-	Message Interval TLV (0x0004) TLV, length 1, 7s
-	Timeout Interval TLV (0x0005) TLV, length 1, 5s
-	Device Name TLV (0x0006) TLV, length 2, S2
-	Sequence Number TLV (0x0007) TLV, length 4, 5
+	Device-ID TLV (0x0001) TLV, length 15, FOC1025X4W3
+	Port-ID TLV (0x0002) TLV, length 9, Fa0/1
+	Echo TLV (0x0003) TLV, length 28, ^@^@^@^A^@^KFOC1031Z7JG^@^EGi0/1
+	Message Interval TLV (0x0004) TLV, length 5, 7s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S2
+	Sequence Number TLV (0x0007) TLV, length 8, 5
 UDLDv1, Code Echo message (2), Flags [RT] (0x00), length 80
 	Checksum 0x805a (unverified)
-	Device-ID TLV (0x0001) TLV, length 11, FOC1031Z7JG
-	Port-ID TLV (0x0002) TLV, length 5, Gi0/1
-	Echo TLV (0x0003) TLV, length 24, 
-	Message Interval TLV (0x0004) TLV, length 1, 7s
-	Timeout Interval TLV (0x0005) TLV, length 1, 5s
-	Device Name TLV (0x0006) TLV, length 2, S1
-	Sequence Number TLV (0x0007) TLV, length 4, 5
+	Device-ID TLV (0x0001) TLV, length 15, FOC1031Z7JG
+	Port-ID TLV (0x0002) TLV, length 9, Gi0/1
+	Echo TLV (0x0003) TLV, length 28, ^@^@^@^A^@^KFOC1025X4W3^@^EFa0/1
+	Message Interval TLV (0x0004) TLV, length 5, 7s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S1
+	Sequence Number TLV (0x0007) TLV, length 8, 5
 UDLDv1, Code Probe message (1), Flags [RT, RSY] (0x01), length 80
 	Checksum 0x795c (unverified)
-	Device-ID TLV (0x0001) TLV, length 11, FOC1025X4W3
-	Port-ID TLV (0x0002) TLV, length 5, Fa0/1
-	Echo TLV (0x0003) TLV, length 24, 
-	Message Interval TLV (0x0004) TLV, length 1, 15s
-	Timeout Interval TLV (0x0005) TLV, length 1, 5s
-	Device Name TLV (0x0006) TLV, length 2, S2
-	Sequence Number TLV (0x0007) TLV, length 4, 1
+	Device-ID TLV (0x0001) TLV, length 15, FOC1025X4W3
+	Port-ID TLV (0x0002) TLV, length 9, Fa0/1
+	Echo TLV (0x0003) TLV, length 28, ^@^@^@^A^@^KFOC1031Z7JG^@^EGi0/1
+	Message Interval TLV (0x0004) TLV, length 5, 15s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S2
+	Sequence Number TLV (0x0007) TLV, length 8, 1
 UDLDv1, Code Probe message (1), Flags [RT, RSY] (0x01), length 80
 	Checksum 0x795d (unverified)
-	Device-ID TLV (0x0001) TLV, length 11, FOC1031Z7JG
-	Port-ID TLV (0x0002) TLV, length 5, Gi0/1
-	Echo TLV (0x0003) TLV, length 24, 
-	Message Interval TLV (0x0004) TLV, length 1, 15s
-	Timeout Interval TLV (0x0005) TLV, length 1, 5s
-	Device Name TLV (0x0006) TLV, length 2, S1
-	Sequence Number TLV (0x0007) TLV, length 4, 1
+	Device-ID TLV (0x0001) TLV, length 15, FOC1031Z7JG
+	Port-ID TLV (0x0002) TLV, length 9, Gi0/1
+	Echo TLV (0x0003) TLV, length 28, ^@^@^@^A^@^KFOC1025X4W3^@^EFa0/1
+	Message Interval TLV (0x0004) TLV, length 5, 15s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S1
+	Sequence Number TLV (0x0007) TLV, length 8, 1
 UDLDv1, Code Probe message (1), Flags [RT, RSY] (0x01), length 80
 	Checksum 0x795b (unverified)
-	Device-ID TLV (0x0001) TLV, length 11, FOC1025X4W3
-	Port-ID TLV (0x0002) TLV, length 5, Fa0/1
-	Echo TLV (0x0003) TLV, length 24, 
-	Message Interval TLV (0x0004) TLV, length 1, 15s
-	Timeout Interval TLV (0x0005) TLV, length 1, 5s
-	Device Name TLV (0x0006) TLV, length 2, S2
-	Sequence Number TLV (0x0007) TLV, length 4, 2
+	Device-ID TLV (0x0001) TLV, length 15, FOC1025X4W3
+	Port-ID TLV (0x0002) TLV, length 9, Fa0/1
+	Echo TLV (0x0003) TLV, length 28, ^@^@^@^A^@^KFOC1031Z7JG^@^EGi0/1
+	Message Interval TLV (0x0004) TLV, length 5, 15s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S2
+	Sequence Number TLV (0x0007) TLV, length 8, 2
 UDLDv1, Code Probe message (1), Flags [RT, RSY] (0x01), length 80
 	Checksum 0x795c (unverified)
-	Device-ID TLV (0x0001) TLV, length 11, FOC1031Z7JG
-	Port-ID TLV (0x0002) TLV, length 5, Gi0/1
-	Echo TLV (0x0003) TLV, length 24, 
-	Message Interval TLV (0x0004) TLV, length 1, 15s
-	Timeout Interval TLV (0x0005) TLV, length 1, 5s
-	Device Name TLV (0x0006) TLV, length 2, S1
-	Sequence Number TLV (0x0007) TLV, length 4, 2
+	Device-ID TLV (0x0001) TLV, length 15, FOC1031Z7JG
+	Port-ID TLV (0x0002) TLV, length 9, Gi0/1
+	Echo TLV (0x0003) TLV, length 28, ^@^@^@^A^@^KFOC1025X4W3^@^EFa0/1
+	Message Interval TLV (0x0004) TLV, length 5, 15s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S1
+	Sequence Number TLV (0x0007) TLV, length 8, 2
 UDLDv1, Code Probe message (1), Flags [RT, RSY] (0x01), length 80
 	Checksum 0x795a (unverified)
-	Device-ID TLV (0x0001) TLV, length 11, FOC1025X4W3
-	Port-ID TLV (0x0002) TLV, length 5, Fa0/1
-	Echo TLV (0x0003) TLV, length 24, 
-	Message Interval TLV (0x0004) TLV, length 1, 15s
-	Timeout Interval TLV (0x0005) TLV, length 1, 5s
-	Device Name TLV (0x0006) TLV, length 2, S2
-	Sequence Number TLV (0x0007) TLV, length 4, 3
+	Device-ID TLV (0x0001) TLV, length 15, FOC1025X4W3
+	Port-ID TLV (0x0002) TLV, length 9, Fa0/1
+	Echo TLV (0x0003) TLV, length 28, ^@^@^@^A^@^KFOC1031Z7JG^@^EGi0/1
+	Message Interval TLV (0x0004) TLV, length 5, 15s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S2
+	Sequence Number TLV (0x0007) TLV, length 8, 3
 UDLDv1, Code Probe message (1), Flags [RT, RSY] (0x01), length 80
 	Checksum 0x795b (unverified)
-	Device-ID TLV (0x0001) TLV, length 11, FOC1031Z7JG
-	Port-ID TLV (0x0002) TLV, length 5, Gi0/1
-	Echo TLV (0x0003) TLV, length 24, 
-	Message Interval TLV (0x0004) TLV, length 1, 15s
-	Timeout Interval TLV (0x0005) TLV, length 1, 5s
-	Device Name TLV (0x0006) TLV, length 2, S1
-	Sequence Number TLV (0x0007) TLV, length 4, 3
+	Device-ID TLV (0x0001) TLV, length 15, FOC1031Z7JG
+	Port-ID TLV (0x0002) TLV, length 9, Gi0/1
+	Echo TLV (0x0003) TLV, length 28, ^@^@^@^A^@^KFOC1025X4W3^@^EFa0/1
+	Message Interval TLV (0x0004) TLV, length 5, 15s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S1
+	Sequence Number TLV (0x0007) TLV, length 8, 3
 UDLDv1, Code Probe message (1), Flags [RT, RSY] (0x01), length 80
 	Checksum 0x7959 (unverified)
-	Device-ID TLV (0x0001) TLV, length 11, FOC1025X4W3
-	Port-ID TLV (0x0002) TLV, length 5, Fa0/1
-	Echo TLV (0x0003) TLV, length 24, 
-	Message Interval TLV (0x0004) TLV, length 1, 15s
-	Timeout Interval TLV (0x0005) TLV, length 1, 5s
-	Device Name TLV (0x0006) TLV, length 2, S2
-	Sequence Number TLV (0x0007) TLV, length 4, 4
+	Device-ID TLV (0x0001) TLV, length 15, FOC1025X4W3
+	Port-ID TLV (0x0002) TLV, length 9, Fa0/1
+	Echo TLV (0x0003) TLV, length 28, ^@^@^@^A^@^KFOC1031Z7JG^@^EGi0/1
+	Message Interval TLV (0x0004) TLV, length 5, 15s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S2
+	Sequence Number TLV (0x0007) TLV, length 8, 4
 UDLDv1, Code Probe message (1), Flags [RT, RSY] (0x01), length 80
 	Checksum 0x795a (unverified)
-	Device-ID TLV (0x0001) TLV, length 11, FOC1031Z7JG
-	Port-ID TLV (0x0002) TLV, length 5, Gi0/1
-	Echo TLV (0x0003) TLV, length 24, 
-	Message Interval TLV (0x0004) TLV, length 1, 15s
-	Timeout Interval TLV (0x0005) TLV, length 1, 5s
-	Device Name TLV (0x0006) TLV, length 2, S1
-	Sequence Number TLV (0x0007) TLV, length 4, 4
+	Device-ID TLV (0x0001) TLV, length 15, FOC1031Z7JG
+	Port-ID TLV (0x0002) TLV, length 9, Gi0/1
+	Echo TLV (0x0003) TLV, length 28, ^@^@^@^A^@^KFOC1025X4W3^@^EFa0/1
+	Message Interval TLV (0x0004) TLV, length 5, 15s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S1
+	Sequence Number TLV (0x0007) TLV, length 8, 4
 UDLDv1, Code Probe message (1), Flags [RT, RSY] (0x01), length 80
 	Checksum 0x7958 (unverified)
-	Device-ID TLV (0x0001) TLV, length 11, FOC1025X4W3
-	Port-ID TLV (0x0002) TLV, length 5, Fa0/1
-	Echo TLV (0x0003) TLV, length 24, 
-	Message Interval TLV (0x0004) TLV, length 1, 15s
-	Timeout Interval TLV (0x0005) TLV, length 1, 5s
-	Device Name TLV (0x0006) TLV, length 2, S2
-	Sequence Number TLV (0x0007) TLV, length 4, 5
+	Device-ID TLV (0x0001) TLV, length 15, FOC1025X4W3
+	Port-ID TLV (0x0002) TLV, length 9, Fa0/1
+	Echo TLV (0x0003) TLV, length 28, ^@^@^@^A^@^KFOC1031Z7JG^@^EGi0/1
+	Message Interval TLV (0x0004) TLV, length 5, 15s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S2
+	Sequence Number TLV (0x0007) TLV, length 8, 5
 UDLDv1, Code Probe message (1), Flags [RT, RSY] (0x01), length 80
 	Checksum 0x7959 (unverified)
-	Device-ID TLV (0x0001) TLV, length 11, FOC1031Z7JG
-	Port-ID TLV (0x0002) TLV, length 5, Gi0/1
-	Echo TLV (0x0003) TLV, length 24, 
-	Message Interval TLV (0x0004) TLV, length 1, 15s
-	Timeout Interval TLV (0x0005) TLV, length 1, 5s
-	Device Name TLV (0x0006) TLV, length 2, S1
-	Sequence Number TLV (0x0007) TLV, length 4, 5
+	Device-ID TLV (0x0001) TLV, length 15, FOC1031Z7JG
+	Port-ID TLV (0x0002) TLV, length 9, Gi0/1
+	Echo TLV (0x0003) TLV, length 28, ^@^@^@^A^@^KFOC1025X4W3^@^EFa0/1
+	Message Interval TLV (0x0004) TLV, length 5, 15s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S1
+	Sequence Number TLV (0x0007) TLV, length 8, 5
 UDLDv1, Code Probe message (1), Flags [RT, RSY] (0x01), length 80
 	Checksum 0x7957 (unverified)
-	Device-ID TLV (0x0001) TLV, length 11, FOC1025X4W3
-	Port-ID TLV (0x0002) TLV, length 5, Fa0/1
-	Echo TLV (0x0003) TLV, length 24, 
-	Message Interval TLV (0x0004) TLV, length 1, 15s
-	Timeout Interval TLV (0x0005) TLV, length 1, 5s
-	Device Name TLV (0x0006) TLV, length 2, S2
-	Sequence Number TLV (0x0007) TLV, length 4, 6
+	Device-ID TLV (0x0001) TLV, length 15, FOC1025X4W3
+	Port-ID TLV (0x0002) TLV, length 9, Fa0/1
+	Echo TLV (0x0003) TLV, length 28, ^@^@^@^A^@^KFOC1031Z7JG^@^EGi0/1
+	Message Interval TLV (0x0004) TLV, length 5, 15s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S2
+	Sequence Number TLV (0x0007) TLV, length 8, 6
 UDLDv1, Code Probe message (1), Flags [RT, RSY] (0x01), length 80
 	Checksum 0x7958 (unverified)
-	Device-ID TLV (0x0001) TLV, length 11, FOC1031Z7JG
-	Port-ID TLV (0x0002) TLV, length 5, Gi0/1
-	Echo TLV (0x0003) TLV, length 24, 
-	Message Interval TLV (0x0004) TLV, length 1, 15s
-	Timeout Interval TLV (0x0005) TLV, length 1, 5s
-	Device Name TLV (0x0006) TLV, length 2, S1
-	Sequence Number TLV (0x0007) TLV, length 4, 6
+	Device-ID TLV (0x0001) TLV, length 15, FOC1031Z7JG
+	Port-ID TLV (0x0002) TLV, length 9, Gi0/1
+	Echo TLV (0x0003) TLV, length 28, ^@^@^@^A^@^KFOC1025X4W3^@^EFa0/1
+	Message Interval TLV (0x0004) TLV, length 5, 15s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S1
+	Sequence Number TLV (0x0007) TLV, length 8, 6
 UDLDv1, Code Probe message (1), Flags [RT, RSY] (0x01), length 80
 	Checksum 0x7956 (unverified)
-	Device-ID TLV (0x0001) TLV, length 11, FOC1025X4W3
-	Port-ID TLV (0x0002) TLV, length 5, Fa0/1
-	Echo TLV (0x0003) TLV, length 24, 
-	Message Interval TLV (0x0004) TLV, length 1, 15s
-	Timeout Interval TLV (0x0005) TLV, length 1, 5s
-	Device Name TLV (0x0006) TLV, length 2, S2
-	Sequence Number TLV (0x0007) TLV, length 4, 7
+	Device-ID TLV (0x0001) TLV, length 15, FOC1025X4W3
+	Port-ID TLV (0x0002) TLV, length 9, Fa0/1
+	Echo TLV (0x0003) TLV, length 28, ^@^@^@^A^@^KFOC1031Z7JG^@^EGi0/1
+	Message Interval TLV (0x0004) TLV, length 5, 15s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S2
+	Sequence Number TLV (0x0007) TLV, length 8, 7
 UDLDv1, Code Probe message (1), Flags [RT, RSY] (0x01), length 80
 	Checksum 0x7957 (unverified)
-	Device-ID TLV (0x0001) TLV, length 11, FOC1031Z7JG
-	Port-ID TLV (0x0002) TLV, length 5, Gi0/1
-	Echo TLV (0x0003) TLV, length 24, 
-	Message Interval TLV (0x0004) TLV, length 1, 15s
-	Timeout Interval TLV (0x0005) TLV, length 1, 5s
-	Device Name TLV (0x0006) TLV, length 2, S1
-	Sequence Number TLV (0x0007) TLV, length 4, 7
+	Device-ID TLV (0x0001) TLV, length 15, FOC1031Z7JG
+	Port-ID TLV (0x0002) TLV, length 9, Gi0/1
+	Echo TLV (0x0003) TLV, length 28, ^@^@^@^A^@^KFOC1025X4W3^@^EFa0/1
+	Message Interval TLV (0x0004) TLV, length 5, 15s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S1
+	Sequence Number TLV (0x0007) TLV, length 8, 7
 UDLDv1, Code Probe message (1), Flags [RT, RSY] (0x01), length 80
 	Checksum 0x7955 (unverified)
-	Device-ID TLV (0x0001) TLV, length 11, FOC1025X4W3
-	Port-ID TLV (0x0002) TLV, length 5, Fa0/1
-	Echo TLV (0x0003) TLV, length 24, 
-	Message Interval TLV (0x0004) TLV, length 1, 15s
-	Timeout Interval TLV (0x0005) TLV, length 1, 5s
-	Device Name TLV (0x0006) TLV, length 2, S2
-	Sequence Number TLV (0x0007) TLV, length 4, 8
+	Device-ID TLV (0x0001) TLV, length 15, FOC1025X4W3
+	Port-ID TLV (0x0002) TLV, length 9, Fa0/1
+	Echo TLV (0x0003) TLV, length 28, ^@^@^@^A^@^KFOC1031Z7JG^@^EGi0/1
+	Message Interval TLV (0x0004) TLV, length 5, 15s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S2
+	Sequence Number TLV (0x0007) TLV, length 8, 8
 UDLDv1, Code Probe message (1), Flags [RT, RSY] (0x01), length 80
 	Checksum 0x7956 (unverified)
-	Device-ID TLV (0x0001) TLV, length 11, FOC1031Z7JG
-	Port-ID TLV (0x0002) TLV, length 5, Gi0/1
-	Echo TLV (0x0003) TLV, length 24, 
-	Message Interval TLV (0x0004) TLV, length 1, 15s
-	Timeout Interval TLV (0x0005) TLV, length 1, 5s
-	Device Name TLV (0x0006) TLV, length 2, S1
-	Sequence Number TLV (0x0007) TLV, length 4, 8
+	Device-ID TLV (0x0001) TLV, length 15, FOC1031Z7JG
+	Port-ID TLV (0x0002) TLV, length 9, Gi0/1
+	Echo TLV (0x0003) TLV, length 28, ^@^@^@^A^@^KFOC1025X4W3^@^EFa0/1
+	Message Interval TLV (0x0004) TLV, length 5, 15s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S1
+	Sequence Number TLV (0x0007) TLV, length 8, 8
 UDLDv1, Code Probe message (1), Flags [RT, RSY] (0x01), length 80
 	Checksum 0x7954 (unverified)
-	Device-ID TLV (0x0001) TLV, length 11, FOC1025X4W3
-	Port-ID TLV (0x0002) TLV, length 5, Fa0/1
-	Echo TLV (0x0003) TLV, length 24, 
-	Message Interval TLV (0x0004) TLV, length 1, 15s
-	Timeout Interval TLV (0x0005) TLV, length 1, 5s
-	Device Name TLV (0x0006) TLV, length 2, S2
-	Sequence Number TLV (0x0007) TLV, length 4, 9
+	Device-ID TLV (0x0001) TLV, length 15, FOC1025X4W3
+	Port-ID TLV (0x0002) TLV, length 9, Fa0/1
+	Echo TLV (0x0003) TLV, length 28, ^@^@^@^A^@^KFOC1031Z7JG^@^EGi0/1
+	Message Interval TLV (0x0004) TLV, length 5, 15s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S2
+	Sequence Number TLV (0x0007) TLV, length 8, 9
 UDLDv1, Code Probe message (1), Flags [RT, RSY] (0x01), length 80
 	Checksum 0x7955 (unverified)
-	Device-ID TLV (0x0001) TLV, length 11, FOC1031Z7JG
-	Port-ID TLV (0x0002) TLV, length 5, Gi0/1
-	Echo TLV (0x0003) TLV, length 24, 
-	Message Interval TLV (0x0004) TLV, length 1, 15s
-	Timeout Interval TLV (0x0005) TLV, length 1, 5s
-	Device Name TLV (0x0006) TLV, length 2, S1
-	Sequence Number TLV (0x0007) TLV, length 4, 9
+	Device-ID TLV (0x0001) TLV, length 15, FOC1031Z7JG
+	Port-ID TLV (0x0002) TLV, length 9, Gi0/1
+	Echo TLV (0x0003) TLV, length 28, ^@^@^@^A^@^KFOC1025X4W3^@^EFa0/1
+	Message Interval TLV (0x0004) TLV, length 5, 15s
+	Timeout Interval TLV (0x0005) TLV, length 5, 5s
+	Device Name TLV (0x0006) TLV, length 6, S1
+	Sequence Number TLV (0x0007) TLV, length 8, 9
diff --git a/tests/udp-length-heapoverflow.out b/tests/udp-length-heapoverflow.out
new file mode 100644
index 0000000..1515117
--- /dev/null
+++ b/tests/udp-length-heapoverflow.out
@@ -0,0 +1,2 @@
+IP (tos 0x30, ttl 48, id 12336, offset 0, flags [none], proto UDP (17), length 12336, bad cksum 3030 (->699d)!)
+    48.48.48.48.12336 > 48.48.48.48.12336:  [|udp]
diff --git a/tests/udp-length-heapoverflow.pcap b/tests/udp-length-heapoverflow.pcap
new file mode 100644
index 0000000..67e899f
--- /dev/null
+++ b/tests/udp-length-heapoverflow.pcap
Binary files differ
diff --git a/tests/unaligned-nfs-1.out b/tests/unaligned-nfs-1.out
new file mode 100644
index 0000000..e74aa30
--- /dev/null
+++ b/tests/unaligned-nfs-1.out
@@ -0,0 +1,2 @@
+IP (tos 0x0, ttl 63, id 38810, offset 0, flags [DF], proto TCP (6), length 168)
+    128.112.130.130.2049 > 140.180.226.200.1023: Flags [P.], cksum 0x6f82 (correct), seq 271994717:271994833, ack 3625862383, win 12274, options [nop,nop,TS val 801481683 ecr 243357584], length 116: NFS reply xid 3532485149 reply ok 112
diff --git a/tests/unaligned-nfs-1.pcap b/tests/unaligned-nfs-1.pcap
new file mode 100644
index 0000000..5f12c13
--- /dev/null
+++ b/tests/unaligned-nfs-1.pcap
Binary files differ
diff --git a/tests/vxlan.out b/tests/vxlan.out
new file mode 100644
index 0000000..b422586
--- /dev/null
+++ b/tests/vxlan.out
@@ -0,0 +1,20 @@
+    1  36:dc:85:1e:b3:40 > 00:16:3e:08:71:cf, ethertype IPv4 (0x0800), length 148: 192.168.203.1.45149 > 192.168.202.1.4789: VXLAN, flags [I] (0x08), vni 100
+00:16:3e:37:f6:04 > 00:30:88:01:00:02, ethertype IPv4 (0x0800), length 98: 192.168.203.3 > 192.168.203.5: ICMP echo request, id 1292, seq 1, length 64
+    2  00:16:3e:08:71:cf > 36:dc:85:1e:b3:40, ethertype IPv4 (0x0800), length 92: 192.168.202.1.42710 > 192.168.203.1.4789: VXLAN, flags [I] (0x08), vni 100
+00:30:88:01:00:02 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 192.168.203.3 tell 192.168.203.5, length 28
+    3  36:dc:85:1e:b3:40 > 00:16:3e:08:71:cf, ethertype IPv4 (0x0800), length 92: 192.168.203.1.52102 > 192.168.202.1.4789: VXLAN, flags [I] (0x08), vni 100
+00:16:3e:37:f6:04 > 00:30:88:01:00:02, ethertype ARP (0x0806), length 42: Reply 192.168.203.3 is-at 00:16:3e:37:f6:04, length 28
+    4  00:16:3e:08:71:cf > 36:dc:85:1e:b3:40, ethertype IPv4 (0x0800), length 148: 192.168.202.1.32894 > 192.168.203.1.4789: VXLAN, flags [I] (0x08), vni 100
+00:30:88:01:00:02 > 00:16:3e:37:f6:04, ethertype IPv4 (0x0800), length 98: 192.168.203.5 > 192.168.203.3: ICMP echo reply, id 1292, seq 1, length 64
+    5  36:dc:85:1e:b3:40 > 00:16:3e:08:71:cf, ethertype IPv4 (0x0800), length 148: 192.168.203.1.45149 > 192.168.202.1.4789: VXLAN, flags [I] (0x08), vni 100
+00:16:3e:37:f6:04 > 00:30:88:01:00:02, ethertype IPv4 (0x0800), length 98: 192.168.203.3 > 192.168.203.5: ICMP echo request, id 1292, seq 2, length 64
+    6  00:16:3e:08:71:cf > 36:dc:85:1e:b3:40, ethertype IPv4 (0x0800), length 148: 192.168.202.1.32894 > 192.168.203.1.4789: VXLAN, flags [I] (0x08), vni 100
+00:30:88:01:00:02 > 00:16:3e:37:f6:04, ethertype IPv4 (0x0800), length 98: 192.168.203.5 > 192.168.203.3: ICMP echo reply, id 1292, seq 2, length 64
+    7  36:dc:85:1e:b3:40 > 00:16:3e:08:71:cf, ethertype IPv4 (0x0800), length 148: 192.168.203.1.45149 > 192.168.202.1.4789: VXLAN, flags [I] (0x08), vni 100
+00:16:3e:37:f6:04 > 00:30:88:01:00:02, ethertype IPv4 (0x0800), length 98: 192.168.203.3 > 192.168.203.5: ICMP echo request, id 1292, seq 3, length 64
+    8  00:16:3e:08:71:cf > 36:dc:85:1e:b3:40, ethertype IPv4 (0x0800), length 148: 192.168.202.1.32894 > 192.168.203.1.4789: VXLAN, flags [I] (0x08), vni 100
+00:30:88:01:00:02 > 00:16:3e:37:f6:04, ethertype IPv4 (0x0800), length 98: 192.168.203.5 > 192.168.203.3: ICMP echo reply, id 1292, seq 3, length 64
+    9  36:dc:85:1e:b3:40 > 00:16:3e:08:71:cf, ethertype IPv4 (0x0800), length 148: 192.168.203.1.45149 > 192.168.202.1.4789: VXLAN, flags [I] (0x08), vni 100
+00:16:3e:37:f6:04 > 00:30:88:01:00:02, ethertype IPv4 (0x0800), length 98: 192.168.203.3 > 192.168.203.5: ICMP echo request, id 1292, seq 4, length 64
+   10  00:16:3e:08:71:cf > 36:dc:85:1e:b3:40, ethertype IPv4 (0x0800), length 148: 192.168.202.1.32894 > 192.168.203.1.4789: VXLAN, flags [I] (0x08), vni 100
+00:30:88:01:00:02 > 00:16:3e:37:f6:04, ethertype IPv4 (0x0800), length 98: 192.168.203.5 > 192.168.203.3: ICMP echo reply, id 1292, seq 4, length 64
diff --git a/tests/vxlan.pcap b/tests/vxlan.pcap
new file mode 100644
index 0000000..04f0c2f
--- /dev/null
+++ b/tests/vxlan.pcap
Binary files differ
diff --git a/tests/zmtp1-inf-loop-1.out b/tests/zmtp1-inf-loop-1.out
new file mode 100644
index 0000000..2404848
--- /dev/null
+++ b/tests/zmtp1-inf-loop-1.out
@@ -0,0 +1,2 @@
+IP 196.59.48.65.14214 > 192.168.1.1.179: Flags [P.], seq 2470159403:2470159437, ack 160570221, win 8224, length 34: ZMTP/1.0
+	 frame flags+body (64-bit) length 18446744073709551607 (25 captured), flags 0xff [|zmtp1]
diff --git a/tests/zmtp1-inf-loop-1.pcap b/tests/zmtp1-inf-loop-1.pcap
new file mode 100644
index 0000000..280e397
--- /dev/null
+++ b/tests/zmtp1-inf-loop-1.pcap
Binary files differ
diff --git a/timeval-operations.h b/timeval-operations.h
new file mode 100644
index 0000000..4f4e85c
--- /dev/null
+++ b/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/udp.h b/udp.h
index 743ddfa..409cc59 100644
--- a/udp.h
+++ b/udp.h
@@ -44,60 +44,273 @@
 	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/util.c b/util-print.c
similarity index 75%
rename from util.c
rename to util-print.c
index b37f3d8..5db042a 100644
--- a/util.c
+++ b/util-print.c
@@ -35,29 +35,61 @@
  * FOR A PARTICULAR PURPOSE.
  */
 
-#define NETDISSECT_REWORKED
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <sys/stat.h>
 
 #ifdef HAVE_FCNTL_H
 #include <fcntl.h>
 #endif
+#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
 
-#include "interface.h"
+#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,
@@ -87,9 +119,60 @@
 }
 
 /*
+ * 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,
@@ -117,6 +200,8 @@
  * 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,
@@ -155,9 +240,8 @@
 #ifndef HAVE_PCAP_SET_TSTAMP_PRECISION
 _U_
 #endif
-, int sec, int usec)
+, int sec, int usec, char *buf)
 {
-	static char buf[sizeof("00:00:00.000000000")];
 	const char *format;
 
 #ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
@@ -172,20 +256,57 @@
 		break;
 
 	default:
-		format = "%02d:%02d:%02d.{unknown precision}";
+		format = "%02d:%02d:%02d.{unknown}";
 		break;
 	}
 #else
 	format = "%02d:%02d:%02d.%06u";
 #endif
 
-	snprintf(buf, sizeof(buf), format,
+	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
@@ -195,52 +316,63 @@
 	register int s;
 	struct tm *tm;
 	time_t Time;
-	static unsigned b_sec;
-	static unsigned b_usec;
-	int d_usec;
-	int d_sec;
+	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)));
+		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, "%u.%06u ",
-			     (unsigned)tvp->tv_sec,
-			     (unsigned)tvp->tv_usec));
+		ND_PRINT((ndo, "%s ", ts_unix_format(ndo,
+			  tvp->tv_sec, tvp->tv_usec, buf)));
 		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;
-                }
+	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 */
 
-                d_usec = tvp->tv_usec - b_usec;
-                d_sec = tvp->tv_sec - b_sec;
+		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);
 
-                while (d_usec < 0) {
-                    d_usec += 1000000;
-                    d_sec--;
-                }
+		ND_PRINT((ndo, (negative_offset ? "-" : " ")));
 
-                ND_PRINT((ndo, "%s ", ts_format(ndo, d_sec, d_usec)));
+		ND_PRINT((ndo, "%s ", ts_format(ndo,
+			  tv_result.tv_sec, tv_result.tv_usec, buf)));
 
-                if (ndo->ndo_tflag == 3) { /* set timestamp for last packet */
-                    b_sec = tvp->tv_sec;
-                    b_usec = tvp->tv_usec;
-                }
+                if (ndo->ndo_tflag == 3)
+			tv_ref = *tvp; /* set timestamp for previous packet */
 		break;
 
-	case 4: /* Default + Date*/
+	case 4: /* Default + Date */
 		s = (tvp->tv_sec + thiszone) % 86400;
 		Time = (tvp->tv_sec + thiszone) - s;
 		tm = gmtime (&Time);
@@ -249,33 +381,29 @@
 		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)));
+                               ts_format(ndo, s, tvp->tv_usec, buf)));
 		break;
 	}
 }
 
 /*
- * Print a relative number of seconds (e.g. hold time, prune timer)
+ * 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
-relts_print(netdissect_options *ndo,
-            int secs)
+unsigned_relts_print(netdissect_options *ndo,
+                     uint32_t secs)
 {
 	static const char *lengths[] = {"y", "w", "d", "h", "m", "s"};
-	static const int seconds[] = {31536000, 604800, 86400, 3600, 60, 1};
+	static const u_int seconds[] = {31536000, 604800, 86400, 3600, 60, 1};
 	const char **l = lengths;
-	const int *s = seconds;
+	const u_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));
@@ -287,6 +415,42 @@
 }
 
 /*
+ * 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
@@ -339,7 +503,7 @@
 tok2str(register const struct tok *lp, register const char *fmt,
 	register u_int v)
 {
-	static char buf[4][128];
+	static char buf[4][TOKBUFSIZE];
 	static int idx = 0;
 	char *ret;
 
@@ -413,7 +577,7 @@
 
 /*
  * Convert a value to a string using an array; the macro
- * tok2strary() in <interface.h> is the public interface to
+ * tok2strary() in <netdissect.h> is the public interface to
  * this function and ensures that the second argument is
  * correct for bounds-checking.
  */
@@ -421,7 +585,7 @@
 tok2strary_internal(register const char **lp, int n, register const char *fmt,
 	register int v)
 {
-	static char buf[128];
+	static char buf[TOKBUFSIZE];
 
 	if (v >= 0 && v < n && lp[v] != NULL)
 		return lp[v];
@@ -462,7 +626,6 @@
 	return (prefix_len);
 }
 
-#ifdef INET6
 int
 mask62plen(const u_char *mask)
 {
@@ -489,7 +652,6 @@
 	}
 	return (cidr_len);
 }
-#endif /* INET6 */
 
 /*
  * Routine to print out information for text-based protocols such as FTP,
@@ -663,7 +825,7 @@
 		if (idx != 0) {
 			/* Is this a valid request name? */
 			while ((cmd = *cmds++) != NULL) {
-				if (strcasecmp((const char *)token, cmd) == 0) {
+				if (ascii_strcasecmp((const char *)token, cmd) == 0) {
 					/* Yes. */
 					is_reqresp = 1;
 					break;
@@ -703,7 +865,7 @@
 
 	/* Capitalize the protocol name */
 	for (pnp = protoname; *pnp != '\0'; pnp++)
-		ND_PRINT((ndo, "%c", toupper(*pnp)));
+		ND_PRINT((ndo, "%c", toupper((u_char)*pnp)));
 
 	if (is_reqresp) {
 		/*
@@ -734,121 +896,6 @@
 	}
 }
 
-/* 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)
@@ -888,3 +935,4 @@
 	return (memcmp(p, q, l));
 }
 #endif
+
diff --git a/version.c b/version.c
index e7db708..391a8db 100644
--- a/version.c
+++ b/version.c
@@ -1 +1 @@
-const char version[] = "4.7.4";
+const char version[] = "4.9.0";
diff --git a/vfprintf.c b/vfprintf.c
index 6f3e15f..ae28bcf 100644
--- a/vfprintf.c
+++ b/vfprintf.c
@@ -30,7 +30,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 
-#include "interface.h"
+#include "netdissect.h"
 
 /*
  * Stock 4.3 doesn't have vfprintf.
diff --git a/win32/Include/w32_fzs.h b/win32/Include/w32_fzs.h
deleted file mode 100644
index 8b5e598..0000000
--- a/win32/Include/w32_fzs.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 1999
- * 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.
- *
- */
-
-#ifndef _WINSOCKAPI_
-#define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */
-#endif /* _WINSOCKAPI_ */
-#include <windows.h>
-#include <winsock2.h>
-
-extern int progress;
-int wsockinit();
-void InitP();
-void PrintCapBegins (char* program_name, char* device);
-extern char* AdapterName1;
-#ifndef WIN95
-WCHAR* SChar2WChar(char* nome);
-#else
-BOOLEAN StartPacketDriver(LPTSTR ServiceName);
-#endif
diff --git a/win32/prj/WinDump.dsp b/win32/prj/WinDump.dsp
index acafddd..ea05ba0 100644
--- a/win32/prj/WinDump.dsp
+++ b/win32/prj/WinDump.dsp
@@ -41,8 +41,8 @@
 # PROP Intermediate_Dir "Release"
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /W3 /GX /O2 /I "../../../winpcap/wpcap/libpcap/bpf" /I "../../../winpcap/wpcap/libpcap" /I "../../../winpcap/wpcap/libpcap/Win32/Include" /I "../../../winpcap/wpcap/libpcap/Win32/Include/net" /I "../../Win32/Include" /I "../../linux-Include" /I "../../lbl" /I "../../" /I "../../../winpcap/wpcap/win32-extensions" /D "NDEBUG" /D "INET6" /D "WIN32" /D "_MBCS" /D "_CONSOLE" /D "__STDC__" /D "WPCAP" /D HAVE_ADDRINFO=1 /D HAVE_SOCKADDR_STORAGE=1 /D HAVE_PCAP_LIST_DATALINKS=1 /D HAVE_PCAP_SET_DATALINK=1 /D HAVE_PCAP_DATALINK_NAME_TO_VAL=1 /D HAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION=1 /D HAVE_PCAP_DUMP_FTELL=1 /D HAVE_BPF_DUMP=1 /D HAVE_PCAP_DUMP_FLUSH=1 /D HAVE_PCAP_FINDALLDEVS=1 /D HAVE_PCAP_IF_T=1 /D HAVE_PCAP_LIB_VERSION=1 /D "HAVE_REMOTE" /D _U_= /DUSE_ETHER_NTOHOST /YX /FD /c
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "../../../winpcap/wpcap/libpcap/bpf" /I "../../../winpcap/wpcap/libpcap" /I "../../../winpcap/wpcap/libpcap/Win32/Include" /I "../../../winpcap/wpcap/libpcap/Win32/Include/net" /I "../../lbl" /I "../../" /I "../../../winpcap/wpcap/win32-extensions" /D "NDEBUG" /D "_MBCS" /D "_CONSOLE" /D "__STDC__" /D "WPCAP" /D HAVE_PCAP_LIST_DATALINKS=1 /D HAVE_PCAP_SET_DATALINK=1 /D HAVE_PCAP_DATALINK_NAME_TO_VAL=1 /D HAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION=1 /D HAVE_PCAP_DUMP_FTELL=1 /D HAVE_BPF_DUMP=1 /D HAVE_PCAP_DUMP_FLUSH=1 /D HAVE_PCAP_FINDALLDEVS=1 /D HAVE_PCAP_IF_T=1 /D HAVE_PCAP_LIB_VERSION=1 /D "HAVE_REMOTE" /D _U_= /DUSE_ETHER_NTOHOST /YX /FD /c
 # ADD BASE RSC /l 0x410 /d "NDEBUG"
 # ADD RSC /l 0x410 /d "NDEBUG"
 BSC32=bscmake.exe
@@ -65,8 +65,8 @@
 # PROP Intermediate_Dir "Debug"
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /W3 /Gm /Gi /GX /ZI /I "../../../winpcap/wpcap/libpcap/bpf" /I "../../../winpcap/wpcap/libpcap" /I "../../../winpcap/wpcap/libpcap/Win32/Include" /I "../../../winpcap/wpcap/libpcap/Win32/Include/net" /I "../../Win32/Include" /I "../../linux-Include" /I "../../lbl" /I "../../" /I "../../../winpcap/wpcap/win32-extensions" /D "_DEBUG" /D "_WINDOWS" /D "INET6" /D "WIN32" /D "_MBCS" /D "_CONSOLE" /D "__STDC__" /D "WPCAP" /D HAVE_ADDRINFO=1 /D HAVE_SOCKADDR_STORAGE=1 /D HAVE_PCAP_LIST_DATALINKS=1 /D HAVE_PCAP_SET_DATALINK=1 /D HAVE_PCAP_DATALINK_NAME_TO_VAL=1 /D HAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION=1 /D HAVE_PCAP_DUMP_FTELL=1 /D HAVE_BPF_DUMP=1 /D HAVE_PCAP_DUMP_FLUSH=1 /D HAVE_PCAP_FINDALLDEVS=1 /D HAVE_PCAP_IF_T=1 /D HAVE_PCAP_LIB_VERSION=1 /D "HAVE_REMOTE" /D _U_= /DUSE_ETHER_NTOHOST /FR /YX /FD /c
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /Gm /Gi /GX /ZI /I "../../../winpcap/wpcap/libpcap/bpf" /I "../../../winpcap/wpcap/libpcap" /I "../../../winpcap/wpcap/libpcap/Win32/Include" /I "../../../winpcap/wpcap/libpcap/Win32/Include/net" /I "../../Win32/Include" /I "../../lbl" /I "../../" /I "../../../winpcap/wpcap/win32-extensions" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_CONSOLE" /D "__STDC__" /D "WPCAP" /D HAVE_PCAP_LIST_DATALINKS=1 /D HAVE_PCAP_SET_DATALINK=1 /D HAVE_PCAP_DATALINK_NAME_TO_VAL=1 /D HAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION=1 /D HAVE_PCAP_DUMP_FTELL=1 /D HAVE_BPF_DUMP=1 /D HAVE_PCAP_DUMP_FLUSH=1 /D HAVE_PCAP_FINDALLDEVS=1 /D HAVE_PCAP_IF_T=1 /D HAVE_PCAP_LIB_VERSION=1 /D "HAVE_REMOTE" /D _U_= /DUSE_ETHER_NTOHOST /FR /YX /FD /c
 # ADD BASE RSC /l 0x410 /d "_DEBUG"
 # ADD RSC /l 0x410 /d "_DEBUG"
 BSC32=bscmake.exe
@@ -89,10 +89,18 @@
 # End Source File
 # Begin Source File
 
+SOURCE=..\..\addrtostr.c
+# End Source File
+# Begin Source File
+
 SOURCE=..\..\af.c
 # End Source File
 # Begin Source File
 
+SOURCE=..\..\ascii_strcasecmp.c
+# End Source File
+# Begin Source File
+
 SOURCE=..\..\bpf_dump.c
 # End Source File
 # Begin Source File
@@ -125,15 +133,7 @@
 # End Source File
 # Begin Source File
 
-SOURCE=..\..\missing\inet_aton.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\missing\inet_ntop.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\missing\inet_pton.c
+SOURCE=..\..\in_cksum.c
 # End Source File
 # Begin Source File
 
@@ -165,14 +165,26 @@
 # End Source File
 # Begin Source File
 
+SOURCE=..\..\print-802_15_4.c
+# End Source File
+# Begin Source File
+
 SOURCE="..\..\print-ah.c"
 # End Source File
 # Begin Source File
 
+SOURCE="..\..\print-ahcp.c"
+# End Source File
+# Begin Source File
+
 SOURCE="..\..\print-aodv.c"
 # End Source File
 # Begin Source File
 
+SOURCE="..\..\print-aoe.c"
+# End Source File
+# Begin Source File
+
 SOURCE="..\..\print-ap1394.c"
 # End Source File
 # Begin Source File
@@ -197,6 +209,10 @@
 # End Source File
 # Begin Source File
 
+SOURCE="..\..\print-babel.c"
+# End Source File
+# Begin Source File
+
 SOURCE="..\..\print-beep.c"
 # End Source File
 # Begin Source File
@@ -217,6 +233,14 @@
 # End Source File
 # Begin Source File
 
+SOURCE="..\..\print-calm-fast.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\..\print-carp.c"
+# End Source File
+# Begin Source File
+
 SOURCE="..\..\print-cdp.c"
 # End Source File
 # Begin Source File
@@ -289,6 +313,10 @@
 # End Source File
 # Begin Source File
 
+SOURCE="..\..\print-forces.c"
+# End Source File
+# Begin Source File
+
 SOURCE="..\..\print-fr.c"
 # End Source File
 # Begin Source File
@@ -297,6 +325,18 @@
 # End Source File
 # Begin Source File
 
+SOURCE="..\..\print-ftp.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\..\print-geneve.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\..\print-geonet.c"
+# End Source File
+# Begin Source File
+
 SOURCE="..\..\print-gre.c"
 # End Source File
 # Begin Source File
@@ -305,6 +345,10 @@
 # End Source File
 # Begin Source File
 
+SOURCE="..\..\print-http.c"
+# End Source File
+# Begin Source File
+
 SOURCE="..\..\print-icmp.c"
 # End Source File
 # Begin Source File
@@ -341,6 +385,10 @@
 # End Source File
 # Begin Source File
 
+SOURCE="..\..\print-ipnet.c"
+# End Source File
+# Begin Source File
+
 SOURCE="..\..\print-ipx.c"
 # End Source File
 # Begin Source File
@@ -385,6 +433,10 @@
 # End Source File
 # Begin Source File
 
+SOURCE="..\..\print-loopback.c"
+# End Source File
+# Begin Source File
+
 SOURCE="..\..\print-lspping.c"
 # End Source File
 # Begin Source File
@@ -397,6 +449,14 @@
 # End Source File
 # Begin Source File
 
+SOURCE="..\..\print-m3ua.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\..\print-medsa.c"
+# End Source File
+# Begin Source File
+
 SOURCE="..\..\print-mobile.c"
 # End Source File
 # Begin Source File
@@ -413,11 +473,19 @@
 # End Source File
 # Begin Source File
 
+SOURCE="..\..\print-mptcp.c"
+# End Source File
+# Begin Source File
+
 SOURCE="..\..\print-msdp.c"
 # End Source File
 # Begin Source File
 
-SOURCE="..\..\print-netbios.c"
+SOURCE="..\..\print-msnlb.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\..\print-nflog.c"
 # End Source File
 # Begin Source File
 
@@ -437,6 +505,14 @@
 # End Source File
 # Begin Source File
 
+SOURCE="..\..\print-openflow-1.0.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\..\print-openflow.c"
+# End Source File
+# Begin Source File
+
 SOURCE="..\..\print-ospf.c"
 # End Source File
 # Begin Source File
@@ -445,6 +521,10 @@
 # End Source File
 # Begin Source File
 
+SOURCE="..\..\print-otv.c"
+# End Source File
+# Begin Source File
+
 SOURCE="..\..\print-pgm.c"
 # End Source File
 # Begin Source File
@@ -453,6 +533,14 @@
 # End Source File
 # Begin Source File
 
+SOURCE="..\..\print-pktap.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\..\print-ppi.c"
+# End Source File
+# Begin Source File
+
 SOURCE="..\..\print-ppp.c"
 # End Source File
 # Begin Source File
@@ -497,6 +585,10 @@
 # End Source File
 # Begin Source File
 
+SOURCE="..\..\print-rtsp.c"
+# End Source File
+# Begin Source File
+
 SOURCE="..\..\print-rx.c"
 # End Source File
 # Begin Source File
@@ -529,6 +621,10 @@
 # End Source File
 # Begin Source File
 
+SOURCE="..\..\print-smtp.c"
+# End Source File
+# Begin Source File
+
 SOURCE="..\..\print-snmp.c"
 # End Source File
 # Begin Source File
@@ -537,6 +633,10 @@
 # End Source File
 # Begin Source File
 
+SOURCE="..\..\missing\strdup.c"
+# End Source File
+# Begin Source File
+
 SOURCE="..\..\print-sunatm.c"
 # End Source File
 # Begin Source File
@@ -569,6 +669,10 @@
 # End Source File
 # Begin Source File
 
+SOURCE="..\..\print-tipc.c"
+# End Source File
+# Begin Source File
+
 SOURCE="..\..\print-token.c"
 # End Source File
 # Begin Source File
@@ -581,6 +685,10 @@
 # End Source File
 # Begin Source File
 
+SOURCE="..\..\print-usb.c"
+# End Source File
+# Begin Source File
+
 SOURCE="..\..\print-vjc.c"
 # End Source File
 # Begin Source File
@@ -597,6 +705,10 @@
 # End Source File
 # Begin Source File
 
+SOURCE="..\..\print-vxlan.c"
+# End Source File
+# Begin Source File
+
 SOURCE="..\..\print-wb.c"
 # End Source File
 # Begin Source File
@@ -613,10 +725,6 @@
 # End Source File
 # Begin Source File
 
-SOURCE=..\..\strcasecmp.c
-# End Source File
-# Begin Source File
-
 SOURCE=..\..\missing\strlcat.c
 # End Source File
 # Begin Source File
@@ -629,7 +737,7 @@
 # End Source File
 # Begin Source File
 
-SOURCE=..\..\Tcpdump.c
+SOURCE=..\..\tcpdump.c
 # End Source File
 # Begin Source File
 
@@ -637,6 +745,26 @@
 # End Source File
 # Begin Source File
 
+SOURCE="..\..\print-zeromq.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\..\print.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\..\signature.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\..\strtoaddr.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\..\util-print.c"
+# End Source File
+# Begin Source File
+
 SOURCE=..\..\util.c
 # End Source File
 # End Target
diff --git a/win32/prj/WinDump.sln b/win32/prj/WinDump.sln
new file mode 100644
index 0000000..55a842f
--- /dev/null
+++ b/win32/prj/WinDump.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinDump", "WinDump.vcproj", "{CA799811-AF71-4C88-BBDA-CDC49B13758B}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{CA799811-AF71-4C88-BBDA-CDC49B13758B}.Debug|Win32.ActiveCfg = Debug|Win32
+		{CA799811-AF71-4C88-BBDA-CDC49B13758B}.Debug|Win32.Build.0 = Debug|Win32
+		{CA799811-AF71-4C88-BBDA-CDC49B13758B}.Release|Win32.ActiveCfg = Release|Win32
+		{CA799811-AF71-4C88-BBDA-CDC49B13758B}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/win32/prj/WinDump.vcproj b/win32/prj/WinDump.vcproj
new file mode 100644
index 0000000..d1787ab
--- /dev/null
+++ b/win32/prj/WinDump.vcproj
@@ -0,0 +1,3950 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="WinDump"
+	ProjectGUID="{CA799811-AF71-4C88-BBDA-CDC49B13758B}"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\../.."
+			IntermediateDirectory=".\Debug"
+			ConfigurationType="1"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TypeLibraryName=".\../../WinDump.tlb"
+				HeaderFileName=""
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="4"
+				AdditionalIncludeDirectories="../../../winpcap/wpcap/libpcap/bpf,../../../winpcap/wpcap/libpcap,../../../winpcap/wpcap/libpcap/Win32/Include,../../../winpcap/wpcap/libpcap/Win32/Include/net,../../Win32/Include,../../linux-Include,../../lbl,../../,../../../winpcap/wpcap/win32-extensions"
+				PreprocessorDefinitions="_DEBUG;_WINDOWS;_CONSOLE;__STDC__;WPCAP;HAVE_PCAP_LIST_DATALINKS=1;HAVE_PCAP_SET_DATALINK=1;HAVE_PCAP_DATALINK_NAME_TO_VAL=1;HAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION=1;HAVE_PCAP_DUMP_FTELL=1;HAVE_BPF_DUMP=1;HAVE_PCAP_DUMP_FLUSH=1;HAVE_PCAP_FINDALLDEVS=1;HAVE_PCAP_IF_T=1;HAVE_PCAP_LIB_VERSION=1;HAVE_REMOTE;_U_=;_CRT_SECURE_NO_WARNINGS;USE_ETHER_NTOHOST"
+				MinimalRebuild="true"
+				RuntimeLibrary="1"
+				PrecompiledHeaderFile=".\Debug/WinDump.pch"
+				AssemblerListingLocation=".\Debug/"
+				ObjectFile=".\Debug/"
+				ProgramDataBaseFileName=".\Debug/"
+				BrowseInformation="1"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1040"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="wpcap.lib odbc32.lib odbccp32.lib wsock32.lib"
+				OutputFile="debug/WinDump.exe"
+				LinkIncremental="2"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="../../../winpcap/wpcap/PRJ/Debug/x86"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=".\../../WinDump.pdb"
+				GenerateMapFile="true"
+				MapFileName=".\Debug/WinDump.map"
+				SubSystem="1"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+				SuppressStartupBanner="true"
+				OutputFile=".\../../WinDump.bsc"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\../.."
+			IntermediateDirectory=".\Release"
+			ConfigurationType="1"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TypeLibraryName=".\../../WinDump.tlb"
+				HeaderFileName=""
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="../../../winpcap/wpcap/libpcap/bpf,../../../winpcap/wpcap/libpcap,../../../winpcap/wpcap/libpcap/Win32/Include,../../../winpcap/wpcap/libpcap/Win32/Include/net,../../Win32/Include,../../linux-Include,../../lbl,../../,../../../winpcap/wpcap/win32-extensions"
+				PreprocessorDefinitions="NDEBUG;_CONSOLE;__STDC__;WPCAP;HAVE_PCAP_LIST_DATALINKS=1;HAVE_PCAP_SET_DATALINK=1;HAVE_PCAP_DATALINK_NAME_TO_VAL=1;HAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION=1;HAVE_PCAP_DUMP_FTELL=1;HAVE_BPF_DUMP=1;HAVE_PCAP_DUMP_FLUSH=1;HAVE_PCAP_FINDALLDEVS=1;HAVE_PCAP_IF_T=1;HAVE_PCAP_LIB_VERSION=1;HAVE_REMOTE;_U_=;_CRT_SECURE_NO_WARNINGS"
+				StringPooling="true"
+				RuntimeLibrary="0"
+				EnableFunctionLevelLinking="true"
+				PrecompiledHeaderFile=".\Release/WinDump.pch"
+				AssemblerListingLocation=".\Release/"
+				ObjectFile=".\Release/"
+				ProgramDataBaseFileName=".\Release/"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1040"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="odbc32.lib odbccp32.lib wsock32.lib wpcap.lib"
+				OutputFile="release/WinDump.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="../../../winpcap/wpcap/PRJ/Release/x86"
+				ProgramDatabaseFile=".\../../WinDump.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+				SuppressStartupBanner="true"
+				OutputFile=".\../../WinDump.bsc"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\..\addrtoname.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\addrtostr.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\af.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\ascii_strcasecmp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\bpf_dump.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\checksum.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\cpack.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\missing\datalinks.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\missing\dlnames.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\missing\getopt_long.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\gmpls.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\gmt2local.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\in_cksum.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\ipproto.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\l2vpn.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\machdep.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\nlpid.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\oui.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\parsenfsfh.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-802_11.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-802_15_4.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-ah.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-ahcp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-aodv.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-aoe.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-ap1394.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-arcnet.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-arp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-ascii.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-atalk.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-atm.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-babel.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-beep.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-bfd.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-bgp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-bootp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-bt.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-calm-fast.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-carp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-cdp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-cfm.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-chdlc.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-cip.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-cnfp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-dccp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-decnet.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-dhcp6.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-domain.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-dtp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-dvmrp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-eap.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-egp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-eigrp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-enc.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-esp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-ether.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-fddi.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-forces.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-fr.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-frag6.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-ftp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-geneve.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-geonet.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-gre.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-hsrp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-http.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-icmp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-icmp6.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-igmp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-igrp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-ip.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-ip6.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-ip6opts.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-ipcomp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-ipfc.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-ipnet.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-ipx.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-isakmp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-isoclns.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-juniper.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-krb.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-l2tp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-lane.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-ldp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-llc.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-lldp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-lmp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-loopback.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-lspping.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-lwapp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-lwres.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-m3ua.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-medsa.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-mobile.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-mobility.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-mpcp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-mpls.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-mptcp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-msdp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-msnlb.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-nflog.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-nfs.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-ntp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-null.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-olsr.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-openflow-1.0.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-openflow.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-ospf.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-ospf6.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-otv.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-pgm.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-pim.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-pktap.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-ppi.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-ppp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-pppoe.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-pptp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-radius.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-raw.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-rip.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-ripng.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-rpki-rtr.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-rrcp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-rsvp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-rt6.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-rtsp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-rx.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-sctp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-sflow.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-sip.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-sl.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-sll.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-slow.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-smb.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-smtp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-snmp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-stp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-sunatm.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-sunrpc.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-symantec.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-syslog.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-tcp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-telnet.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-tftp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-timed.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-tipc.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-token.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-udld.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-udp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-usb.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-vjc.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-vqp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-vrrp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-vtp.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-vxlan.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-wb.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print-zephyr.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\setsignal.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\signature.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\smbutil.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\missing\strlcat.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\missing\strlcpy.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\missing\strsep.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+
+		<File RelativePath="..\Src\ether_ntohost.c">
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+
+		<File
+			RelativePath="..\..\print-zeromq.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\print.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\strtoaddr.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\tcpdump.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\util-print.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\util.c"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories=""
+					PreprocessorDefinitions=""
+				/>
+			</FileConfiguration>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/win32/src/ether_ntohost.c b/win32/src/ether_ntohost.c
new file mode 100644
index 0000000..4a58cfc
--- /dev/null
+++ b/win32/src/ether_ntohost.c
@@ -0,0 +1,219 @@
+/*
+ * 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.
+ *
+ * tcpdump/Win32 functions for reading and parsing system's Ethernet
+ * address file:
+ *    '%SystemRoot%/drivers/etc/ethers'  (Win-NT+)
+ * or '%Windir%/etc/ethers'              (Win-9x/ME)
+ *
+ * G. Vanem <gvanem@yahoo.no> 2012.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <netdissect-stdinc.h>
+
+#include "ether.h"
+#include "netdissect.h"
+#include "addrtoname.h"
+
+typedef struct ether_addr {
+        unsigned char octet[ETHER_ADDR_LEN];
+      } ether_address;
+
+typedef struct ether_entry {
+        ether_address      eth_addr;  /* MAC address */
+        char               *name;     /* name of MAC-address */
+        struct ether_entry *next;
+      } ether_entry;
+
+static struct ether_entry *eth0 = NULL;
+
+/*
+ * The reason to avoid using 'pcap_next_etherent()' in addrtoname.c
+ * are several:
+ *   1) wpcap.dll and 'pcap_next_etherent()' could have been built in
+ *      debug-mode (-MDd) or release-mode (-MD) and tcpdump in
+ *      the opposite model.
+ *   2) If this is built by MSVC, wpcap.dll could have been built by
+ *      MingW. It has no debug-model.
+ *   3) It may not have been exported from wpcap.dll (present in wpcap.def).
+ *
+ * So we shoe-horn the building of tcpdump with '-DUSE_ETHER_NTOHOST' to
+ * make 'init_etherarray()' call the below 'ether_ntohost()' instead.
+ */
+#if !defined(USE_ETHER_NTOHOST)
+#error "'-DUSE_ETHER_NTOHOST' must be set"
+#endif
+
+/*
+ * Return TRUE if running under Win-95/98/ME.
+ */
+static BOOL is_win9x (void)
+{
+  OSVERSIONINFO ovi;
+  DWORD os_ver = GetVersion();
+  DWORD major_ver = LOBYTE (LOWORD(os_ver));
+
+  return (os_ver >= 0x80000000 && major_ver >= 4);
+}
+
+/*
+ * Return path to "%SystemRoot%/drivers/etc/<file>"  (Win-NT+)
+ *          or to "%Windir%/etc/<file>"              (Win-9x/ME)
+ */
+const char *etc_path (const char *file)
+{
+  BOOL win9x = is_win9x();
+  const char *env = win9x ? getenv("WinDir") : getenv("SystemRoot");
+  static char path[MAX_PATH];
+
+  if (!env)
+    return (file);
+
+  if (win9x)
+    snprintf (path, sizeof(path), "%s\\etc\\%s", env, file);
+  else
+    snprintf (path, sizeof(path), "%s\\system32\\drivers\\etc\\%s", env, file);
+
+  return (path);
+}
+
+/*
+ * Parse a string-buf containing an MAC address and name.
+ * Accepts MAC addresses on both "xx:xx:xx.." and "xx-xx-xx.." forms.
+ *
+ * We could have used pcap_ether_aton(), but problem 3) above could apply.
+ * or we could have cut & pasted 'pcap_next_etherent(FILE *fp)' below.
+ */
+#define MIN_LEN  sizeof("0:0:0:0:0:0 X")
+
+static
+int parse_ether_buf (const char *buf, char **result, struct ether_addr *e)
+{
+  const char *fmt;
+  char       *name;
+  char       *str = (char*)buf;
+  unsigned    eth [sizeof(*e)];
+  int         i;
+
+  /* Find first non-blank in 'buf' */
+  while (str[0] && str[1] && isspace((int)str[0]))
+       str++;
+
+  if (*str == '#' || *str == ';' || *str == '\n' || strlen(str) < MIN_LEN)
+     return (0);
+
+  if (str[2] == ':')
+    fmt = "%02x:%02x:%02x:%02x:%02x:%02x";
+  else
+    fmt = "%02x-%02x-%02x-%02x-%02x-%02x";
+
+  if (sscanf(str, fmt, &eth[0], &eth[1], &eth[2], &eth[3], &eth[4], &eth[5]) != ETHER_ADDR_LEN)
+     return (0);
+
+  str  = strtok (str, " \t");
+  name = strtok (NULL, " #\t\n");
+
+  if (!str || !name || strlen(name) < 1)
+     return (0);
+
+  *result = name;
+
+  for (i = 0; i < ETHER_ADDR_LEN; i++)
+      e->octet[i] = eth[i];
+
+  return (1);
+}
+
+static void free_ethers (void)
+{
+  struct ether_entry *e, *next;
+
+  for (e = eth0; e; e = next) {
+    next = e->next;
+    free(e->name);
+    free(e);
+  }
+  eth0 = NULL;
+}
+
+static int init_ethers (void)
+{
+  char  buf[BUFSIZE];
+  FILE *fp = fopen (etc_path("ethers"), "r");
+
+  if (!fp)
+     return (0);
+
+  while (fgets(buf,sizeof(buf),fp))
+  {
+    struct ether_entry *e;
+    char  *name;
+    ether_address eth;
+
+    if (!parse_ether_buf(buf,&name,&eth))
+       continue;
+
+    e = calloc (sizeof(*e), 1);
+    if (!e)
+       break;
+
+    memcpy(&e->eth_addr, &eth, ETHER_ADDR_LEN);
+    e->name = strdup(name);
+    if (!e->name) {
+      free(e);
+      break;
+    }
+
+    e->next = eth0;
+    eth0 = e;
+  }
+  fclose(fp);
+  atexit(free_ethers);
+  return (1);
+}
+
+/*
+ * Map an ethernet address 'e' to a 'name'.
+ * Returns 0 on success.
+ *
+ * This function is called at startup by init_etherarray() and then
+ * by etheraddr_string() as needed. To avoid doing an expensive fopen()
+ * on each call, the contents of 'etc_path("ethers")' is cached here in
+ * a linked-list 'eth0'.
+ */
+int ether_ntohost (char *name, struct ether_addr *e)
+{
+  const struct ether_entry *cache;
+  static int init = 0;
+
+  if (!init) {
+    init_ethers();
+    init = 1;
+  }
+
+  for (cache = eth0; cache; cache = cache->next)
+     if (!memcmp(&e->octet, &cache->eth_addr, ETHER_ADDR_LEN)) {
+       strcpy (name,cache->name);
+       return (0);
+     }
+  return (1);
+}
+