Import tcpdump-4.2.1.
authorPeter Avalos <pavalos@dragonflybsd.org>
Mon, 23 Jan 2012 01:08:25 +0000 (17:08 -0800)
committerPeter Avalos <pavalos@dragonflybsd.org>
Mon, 23 Jan 2012 01:17:02 +0000 (17:17 -0800)
See the CHANGES files for the details.

133 files changed:
contrib/tcpdump/CHANGES
contrib/tcpdump/INSTALL.txt
contrib/tcpdump/README
contrib/tcpdump/README.DELETED
contrib/tcpdump/VERSION
contrib/tcpdump/addrtoname.c
contrib/tcpdump/addrtoname.h
contrib/tcpdump/af.c
contrib/tcpdump/af.h
contrib/tcpdump/atmuni31.h
contrib/tcpdump/bootp.h
contrib/tcpdump/bpf_dump.c [deleted file]
contrib/tcpdump/checksum.c
contrib/tcpdump/cpack.c
contrib/tcpdump/cpack.h
contrib/tcpdump/ethertype.h
contrib/tcpdump/forces.h [new file with mode: 0644]
contrib/tcpdump/gmpls.c
contrib/tcpdump/gmpls.h
contrib/tcpdump/gmt2local.h
contrib/tcpdump/icmp6.h
contrib/tcpdump/ieee802_11.h
contrib/tcpdump/ieee802_11_radio.h
contrib/tcpdump/in_cksum.c [new file with mode: 0644]
contrib/tcpdump/interface.h
contrib/tcpdump/ip.h
contrib/tcpdump/ip6.h
contrib/tcpdump/ipnet.h [new file with mode: 0644]
contrib/tcpdump/ipproto.c
contrib/tcpdump/ipproto.h
contrib/tcpdump/isakmp.h
contrib/tcpdump/l2vpn.c
contrib/tcpdump/l2vpn.h
contrib/tcpdump/makemib [deleted file]
contrib/tcpdump/netdissect.h
contrib/tcpdump/nfs.h
contrib/tcpdump/nlpid.c
contrib/tcpdump/nlpid.h
contrib/tcpdump/ospf.h
contrib/tcpdump/oui.c
contrib/tcpdump/oui.h
contrib/tcpdump/pcap_dump_ftell.c [deleted file]
contrib/tcpdump/ppi.h [new file with mode: 0644]
contrib/tcpdump/print-802_11.c
contrib/tcpdump/print-802_15_4.c [new file with mode: 0644]
contrib/tcpdump/print-ap1394.c
contrib/tcpdump/print-arcnet.c
contrib/tcpdump/print-arp.c
contrib/tcpdump/print-atalk.c
contrib/tcpdump/print-atm.c
contrib/tcpdump/print-babel.c [new file with mode: 0644]
contrib/tcpdump/print-bfd.c
contrib/tcpdump/print-bgp.c
contrib/tcpdump/print-bootp.c
contrib/tcpdump/print-bt.c [new file with mode: 0644]
contrib/tcpdump/print-carp.c [new file with mode: 0644]
contrib/tcpdump/print-cdp.c
contrib/tcpdump/print-cfm.c
contrib/tcpdump/print-chdlc.c
contrib/tcpdump/print-dccp.c
contrib/tcpdump/print-dhcp6.c
contrib/tcpdump/print-domain.c
contrib/tcpdump/print-eigrp.c
contrib/tcpdump/print-enc.c
contrib/tcpdump/print-esp.c
contrib/tcpdump/print-ether.c
contrib/tcpdump/print-forces.c [new file with mode: 0644]
contrib/tcpdump/print-fr.c
contrib/tcpdump/print-gre.c
contrib/tcpdump/print-icmp.c
contrib/tcpdump/print-icmp6.c
contrib/tcpdump/print-igmp.c
contrib/tcpdump/print-ip.c
contrib/tcpdump/print-ip6.c
contrib/tcpdump/print-ipnet.c [new file with mode: 0644]
contrib/tcpdump/print-ipx.c
contrib/tcpdump/print-isakmp.c
contrib/tcpdump/print-isoclns.c
contrib/tcpdump/print-juniper.c
contrib/tcpdump/print-l2tp.c
contrib/tcpdump/print-lane.c
contrib/tcpdump/print-ldp.c
contrib/tcpdump/print-llc.c
contrib/tcpdump/print-lldp.c
contrib/tcpdump/print-lmp.c
contrib/tcpdump/print-lspping.c
contrib/tcpdump/print-mobile.c
contrib/tcpdump/print-mpls.c
contrib/tcpdump/print-nfs.c
contrib/tcpdump/print-ntp.c
contrib/tcpdump/print-null.c
contrib/tcpdump/print-olsr.c
contrib/tcpdump/print-ospf.c
contrib/tcpdump/print-pflog.c
contrib/tcpdump/print-pgm.c
contrib/tcpdump/print-pim.c
contrib/tcpdump/print-ppi.c [new file with mode: 0644]
contrib/tcpdump/print-ppp.c
contrib/tcpdump/print-rpki-rtr.c [new file with mode: 0644]
contrib/tcpdump/print-rrcp.c
contrib/tcpdump/print-rsvp.c
contrib/tcpdump/print-rx.c
contrib/tcpdump/print-sctp.c
contrib/tcpdump/print-sflow.c
contrib/tcpdump/print-sip.c
contrib/tcpdump/print-sl.c
contrib/tcpdump/print-sll.c
contrib/tcpdump/print-slow.c
contrib/tcpdump/print-smb.c
contrib/tcpdump/print-sunrpc.c
contrib/tcpdump/print-symantec.c
contrib/tcpdump/print-tcp.c
contrib/tcpdump/print-tftp.c
contrib/tcpdump/print-token.c
contrib/tcpdump/print-udp.c
contrib/tcpdump/print-usb.c [new file with mode: 0644]
contrib/tcpdump/print-vrrp.c
contrib/tcpdump/setsignal.h
contrib/tcpdump/signature.c [new file with mode: 0644]
contrib/tcpdump/signature.h [copied from contrib/tcpdump/l2vpn.h with 63% similarity, mode: 0644]
contrib/tcpdump/sll.h
contrib/tcpdump/smbutil.c
contrib/tcpdump/strcasecmp.c [deleted file]
contrib/tcpdump/tcp.h
contrib/tcpdump/tcpdump-stdinc.h
contrib/tcpdump/tcpdump.1.in [moved from contrib/tcpdump/tcpdump.1 with 94% similarity]
contrib/tcpdump/tcpdump.c
contrib/tcpdump/tftp.h
contrib/tcpdump/timed.h
contrib/tcpdump/token.h
contrib/tcpdump/udp.h
contrib/tcpdump/util.c
contrib/tcpdump/vfprintf.c [deleted file]

index 3f3b675..2fa51b9 100644 (file)
@@ -1,4 +1,106 @@
-$Header: /tcpdump/master/tcpdump/CHANGES,v 1.98.2.2 2008-10-15 23:26:30 ken Exp $
+Friday  December 9, 2011.  guy@alum.mit.edu.
+  Summary for 4.2.1 tcpdump release
+       Only build the Babel printer if IPv6 is enabled.
+       Support Babel on port 6696 as well as 6697.
+       Include ppi.h in release tarball.
+       Include all the test files in the release tarball, and don't
+        "include" test files that no longer exist.
+       Don't assume we have <rpc/rpc.h> - check for it.
+       Support "-T carp" as a way of dissecting IP protocol 112 as CARP
+        rather than VRRP.
+       Support Hilscher NetAnalyzer link-layer header format.
+       Constify some pointers and fix compiler warnings.
+       Get rid of never-true test.
+       Fix an unintended fall-through in a case statement in the ARP
+        printer.
+       Fix several cases where sizeof(sizeof(XXX)) was used when just
+        sizeof(XXX) was intended.
+       Make stricter sanity checks in the ES-IS printer.
+       Get rid of some GCCisms that caused builds to fai with compilers
+        that don't support them.
+       Fix typo in man page.
+       Added length checks to Babel printer.
+
+Sunday  July 24, 2011.  mcr@sandelman.ca.
+  Summary for 4.2.+
+       merged 802.15.4 decoder from Dmitry Eremin-Solenikov <dbaryshkov
+         at gmail dot com>
+        updates to forces for new port numbers
+        Use "-H", not "-h", for the 802.11s option. (-h always help)
+        Better ICMPv6 checksum handling.
+        add support for the RPKI/Router Protocol, per -ietf-sidr-rpki-rtr-12
+        get rid of uuencoded pcap test files, git can do binary.
+        sFlow changes for 64-bit counters.
+        fixes for PPI packet header handling and printing.
+        Add DCB Exchange protocol (DCBX) version 1.01.
+        Babel dissector, from Juliusz Chroboczek and GrĂ©goire Henry.
+        improvements to radiotap for rate values > 127.
+        Many improvements to ForCES decode, including fix SCTP TML port
+        updated RPL type code to RPL-17 draft
+        Improve printout of DHCPv6 options.
+        added support and test case for QinQ (802.1q VLAN) packets
+        Handle DLT_IEEE802_15_4_NOFCS like DLT_IEEE802_15_4.
+        Build fixes for Sparc and other machines with alignment restrictions.
+        Merged changes from Debian package.
+        PGM: Add ACK decoding and add PGMCC DATA and FEEDBACK options.
+        Build fixes for OSX (Snow Leopard and others)
+        Add support for IEEE 802.15.4 packets
+
+Tue.    July 20, 2010.  guy@alum.mit.edu.
+  Summary for 4.1.2 tcpdump release
+       If -U is specified, flush the file after creating it, so it's
+         not zero-length
+       Fix TCP flags output description, and some typoes, in the man
+         page
+       Add a -h flag, and only attempt to recognize 802.11s mesh
+         headers if it's set
+       When printing the link-layer type list, send *all* output to
+         stderr
+       Include the CFLAGS setting when configure was run in the
+         compiler flags
+
+Thu.   April 1, 2010.  guy@alum.mit.edu.
+  Summary for 4.1.1 tcpdump release
+       Fix build on systems with PF, such as FreeBSD and OpenBSD.
+       Don't blow up if a zero-length link-layer address is passed to
+         linkaddr_string(). 
+
+Thu.   March 11, 2010.  ken@netfunctional.ca/guy@alum.mit.edu.
+  Summary for 4.1.0 tcpdump release
+       Fix printing of MAC addresses for VLAN frames with a length
+         field
+       Add some additional bounds checks and use the EXTRACT_ macros
+         more
+       Add a -b flag to print the AS number in BGP packets in ASDOT
+         notation rather than ASPLAIN notation
+       Add ICMPv6 RFC 5006 support
+       Decode the access flags in NFS access requests
+       Handle the new DLT_ for memory-mapped USB captures on Linux
+       Make the default snapshot (-s) the maximum
+       Print name of device (when -L is used)
+       Support for OpenSolaris (and SXCE build 125 and later)
+       Print new TCP flags
+       Add support for RPL DIO
+       Add support for TCP User Timeout (UTO)
+       Add support for non-standard Ethertypes used by 3com PPPoE gear
+       Add support for 802.11n and 802.11s
+       Add support for Transparent Ethernet Bridge ethertype in GRE
+       Add 4 byte AS support for BGP printer
+       Add support for the MDT SAFI 66 BG printer
+       Add basic IPv6 support to print-olsr
+       Add USB printer
+       Add printer for ForCES
+       Handle frames with an FCS
+       Handle 802.11n Control Wrapper, Block Acq Req and Block Ack frames
+       Fix TCP sequence number printing 
+       Report 802.2 packets as 802.2 instead of 802.3
+       Don't include -L/usr/lib in LDFLAGS
+       On x86_64 Linux, look in lib64 directory too
+       Lots of code clean ups
+       Autoconf clean ups
+       Update testcases to make output changes
+       Fix compiling with/out smi (--with{,out}-smi)
+       Fix compiling without IPv6 support (--disable-ipv6)
 
 Mon.    October 27, 2008.  ken@netfunctional.ca.  Summary for 4.0.0 tcpdump release
         Add support for Bluetooth Sniffing
index e263f53..a03e2c0 100644 (file)
@@ -1,4 +1,4 @@
-@(#) $Header: /tcpdump/master/tcpdump/INSTALL.txt,v 1.1.2.1 2008-02-06 10:49:22 guy Exp $ (LBL)
+@(#) $Header: /tcpdump/master/tcpdump/INSTALL.txt,v 1.2 2008-02-06 10:47:53 guy Exp $ (LBL)
 
 If you have not built libpcap, and your system does not have libpcap
 installed, install libpcap first.  Your system might provide a version
@@ -221,6 +221,7 @@ print-tftp.c        - Trivial File Transfer Protocol printer routines
 print-timed.c  - BSD time daemon protocol printer routines
 print-token.c  - Token Ring printer routines
 print-udp.c    - UDP printer routines
+print-usb.c    - USB printer routines
 print-vjc.c    - PPP Van Jacobson compression (RFC1144) printer routines
 print-vrrp.c   - Virtual Router Redundancy Protocol
 print-wb.c     - White Board printer routines
index c2b6760..ed657c1 100644 (file)
@@ -1,19 +1,17 @@
-@(#) $Header: /tcpdump/master/tcpdump/README,v 1.66.2.1 2008-05-30 01:38:20 guy Exp $ (LBL)
+@(#) $Header: /tcpdump/master/tcpdump/README,v 1.68 2008-12-15 00:05:27 guy Exp $ (LBL)
 
-TCPDUMP 3.9
+TCPDUMP 4.x.y
 Now maintained by "The Tcpdump Group"
 See            www.tcpdump.org
 
 Please send inquiries/comments/reports to:
        tcpdump-workers@lists.tcpdump.org
 
-Anonymous CVS is available via:
-       cvs -d :pserver:cvs.tcpdump.org:/tcpdump/master login
-       (password "anoncvs")
-       cvs -d :pserver:cvs.tcpdump.org:/tcpdump/master checkout tcpdump
+Anonymous Git is available via:
+       git clone git://bpf.tcpdump.org/tcpdump
 
-Version 3.9 of TCPDUMP can be retrieved with the CVS tag "tcpdump_3_9rel1":
-       cvs -d :pserver:cvs.tcpdump.org:/tcpdump/master checkout -r tcpdump_3_9rel1 tcpdump
+Version 4.x.y of TCPDUMP can be retrieved with the CVS tag "tcpdump_4_xrely":
+       cvs -d :pserver:cvs.tcpdump.org:/tcpdump/master checkout -r tcpdump_4_xrely tcpdump
 
 Please submit patches against the master copy to the tcpdump project on
 sourceforge.net.
index faea7ee..005d29e 100644 (file)
@@ -1,9 +1,11 @@
 CREDITS
+Makefile-devel-adds
 Makefile.in
 Readme.Win32
 acconfig.h
 aclocal.m4
 atime.awk
+bpf_dump.c
 config.guess
 config.h.in
 config.sub
@@ -11,10 +13,14 @@ configure
 configure.in
 install-sh
 lbl/
+makemib
 missing/
 mkdep
 packetdat.awk
-print-bt.c
+pcap_dump_ftell.c
 send-ack.awk
 stime.awk
+strcasecmp.c
+tests/
+vfprintf.c
 win32/
index e67d114..d77f27b 100644 (file)
@@ -86,12 +86,12 @@ struct hnamemem {
        struct hnamemem *nxt;
 };
 
-struct hnamemem hnametable[HASHNAMESIZE];
-struct hnamemem tporttable[HASHNAMESIZE];
-struct hnamemem uporttable[HASHNAMESIZE];
-struct hnamemem eprototable[HASHNAMESIZE];
-struct hnamemem dnaddrtable[HASHNAMESIZE];
-struct hnamemem ipxsaptable[HASHNAMESIZE];
+static struct hnamemem hnametable[HASHNAMESIZE];
+static struct hnamemem tporttable[HASHNAMESIZE];
+static struct hnamemem uporttable[HASHNAMESIZE];
+static struct hnamemem eprototable[HASHNAMESIZE];
+static struct hnamemem dnaddrtable[HASHNAMESIZE];
+static struct hnamemem ipxsaptable[HASHNAMESIZE];
 
 #if defined(INET6) && defined(WIN32)
 /*
@@ -140,7 +140,7 @@ struct h6namemem {
        struct h6namemem *nxt;
 };
 
-struct h6namemem h6nametable[HASHNAMESIZE];
+static struct h6namemem h6nametable[HASHNAMESIZE];
 #endif /* INET6 */
 
 struct enamemem {
@@ -153,9 +153,9 @@ struct enamemem {
        struct enamemem *e_nxt;
 };
 
-struct enamemem enametable[HASHNAMESIZE];
-struct enamemem nsaptable[HASHNAMESIZE];
-struct enamemem bytestringtable[HASHNAMESIZE];
+static struct enamemem enametable[HASHNAMESIZE];
+static struct enamemem nsaptable[HASHNAMESIZE];
+static struct enamemem bytestringtable[HASHNAMESIZE];
 
 struct protoidmem {
        u_int32_t p_oui;
@@ -164,7 +164,7 @@ struct protoidmem {
        struct protoidmem *p_nxt;
 };
 
-struct protoidmem protoidtable[HASHNAMESIZE];
+static struct protoidmem protoidtable[HASHNAMESIZE];
 
 /*
  * A faster replacement for inet_ntoa().
@@ -311,7 +311,7 @@ getname6(const u_char *ap)
 }
 #endif /* INET6 */
 
-static char hex[] = "0123456789abcdef";
+static const char hex[] = "0123456789abcdef";
 
 
 /* Find the hash node that corresponds the ether address 'ep' */
@@ -507,6 +507,34 @@ etheraddr_string(register const u_char *ep)
        return (tp->e_name);
 }
 
+const char *
+le64addr_string(const u_char *ep)
+{
+       const unsigned int len = 8;
+       register u_int i;
+       register char *cp;
+       register struct enamemem *tp;
+       char buf[BUFSIZE];
+
+       tp = lookup_bytestring(ep, len);
+       if (tp->e_name)
+               return (tp->e_name);
+
+       cp = buf;
+       for (i = len; i > 0 ; --i) {
+               *cp++ = hex[*(ep + i - 1) >> 4];
+               *cp++ = hex[*(ep + i - 1) & 0xf];
+               *cp++ = ':';
+       }
+       cp --;
+
+       *cp = '\0';
+
+       tp->e_name = strdup(buf);
+
+       return (tp->e_name);
+}
+
 const char *
 linkaddr_string(const u_char *ep, const unsigned int type, const unsigned int len)
 {
@@ -514,13 +542,14 @@ linkaddr_string(const u_char *ep, const unsigned int type, const unsigned int le
        register char *cp;
        register struct enamemem *tp;
 
-       if (type == LINKADDR_ETHER && len == ETHER_ADDR_LEN) {
-            return etheraddr_string(ep);
-        }
+       if (len == 0)
+               return ("<empty>");
+
+       if (type == LINKADDR_ETHER && len == ETHER_ADDR_LEN)
+               return (etheraddr_string(ep));
 
-        if (type == LINKADDR_FRELAY) {
-            return q922_string(ep);
-        }
+       if (type == LINKADDR_FRELAY)
+               return (q922_string(ep));
 
        tp = lookup_bytestring(ep, len);
        if (tp->e_name)
@@ -747,7 +776,7 @@ init_eprotoarray(void)
        }
 }
 
-static struct protoidlist {
+static const struct protoidlist {
        const u_char protoid[5];
        const char *name;
 } protoidlist[] = {
@@ -768,7 +797,7 @@ init_protoidarray(void)
 {
        register int i;
        register struct protoidmem *tp;
-       struct protoidlist *pl;
+       const struct protoidlist *pl;
        u_char protoid[5];
 
        protoid[0] = 0;
@@ -792,7 +821,7 @@ init_protoidarray(void)
        }
 }
 
-static struct etherlist {
+static const struct etherlist {
        const u_char addr[6];
        const char *name;
 } etherlist[] = {
@@ -817,7 +846,7 @@ static struct etherlist {
 static void
 init_etherarray(void)
 {
-       register struct etherlist *el;
+       register const struct etherlist *el;
        register struct enamemem *tp;
 #ifdef USE_ETHER_NTOHOST
        char name[256];
@@ -861,7 +890,7 @@ init_etherarray(void)
        }
 }
 
-static struct tok ipxsap_db[] = {
+static const struct tok ipxsap_db[] = {
        { 0x0000, "Unknown" },
        { 0x0001, "User" },
        { 0x0002, "User Group" },
index 1df204a..cd5c41f 100644 (file)
@@ -34,6 +34,7 @@ enum {
 
 extern const char *linkaddr_string(const u_char *, const unsigned int, const unsigned int);
 extern const char *etheraddr_string(const u_char *);
+extern const char *le64addr_string(const u_char *);
 extern const char *etherproto_string(u_short);
 extern const char *tcpport_string(u_short);
 extern const char *udpport_string(u_short);
index e3c77bf..2c8a928 100644 (file)
@@ -28,7 +28,7 @@ static const char rcsid[] _U_ =
 #include "interface.h"
 #include "af.h"
 
-struct tok af_values[] = {
+const struct tok af_values[] = {
     { 0,                      "Reserved"},
     { AFNUM_INET,             "IPv4"},
     { AFNUM_INET6,            "IPv6"},
@@ -50,7 +50,7 @@ struct tok af_values[] = {
     { 0, NULL},
 };
 
-struct tok bsd_af_values[] = {
+const struct tok bsd_af_values[] = {
     { BSD_AFNUM_INET, "IPv4" },
     { BSD_AFNUM_NS, "NS" },
     { BSD_AFNUM_ISO, "ISO" },
index c036cef..679cc8e 100644 (file)
@@ -17,8 +17,8 @@
  * Original code by Hannes Gredler (hannes@juniper.net)
  */
 
-extern struct tok af_values[];
-extern struct tok bsd_af_values[];
+extern const struct tok af_values[];
+extern const struct tok bsd_af_values[];
 
 /* RFC1700 address family numbers */
 #define AFNUM_INET     1
index 32acfb1..ab7a03d 100644 (file)
@@ -29,7 +29,7 @@
  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- * @(#) $Header: /tcpdump/master/tcpdump/atmuni31.h,v 1.2.6.1 2007-10-22 19:39:12 guy Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/tcpdump/atmuni31.h,v 1.3 2007-10-22 19:37:51 guy Exp $ (LBL)
  */
 
 /* Based on UNI3.1 standard by ATM Forum */
index 8f61b13..b1b81dc 100644 (file)
@@ -1,4 +1,4 @@
-/* @(#) $Header: /tcpdump/master/tcpdump/bootp.h,v 1.18 2007-08-21 21:59:11 guy Exp $ (LBL) */
+/* @(#) $Header: /tcpdump/master/tcpdump/bootp.h,v 1.19 2008-04-22 09:46:03 hannes Exp $ (LBL) */
 /*
  * Bootstrap Protocol (BOOTP).  RFC951 and RFC1048.
  *
@@ -27,7 +27,8 @@ struct bootp {
        u_int8_t        bp_hops;        /* gateway hops */
        u_int32_t       bp_xid;         /* transaction ID */
        u_int16_t       bp_secs;        /* seconds since boot began */
-       u_int16_t       bp_flags;       /* flags - see bootp_flag_values[] in print-bootp.c */
+       u_int16_t       bp_flags;       /* flags - see bootp_flag_values[]
+                                          in print-bootp.c */
        struct in_addr  bp_ciaddr;      /* client IP address */
        struct in_addr  bp_yiaddr;      /* 'your' IP address */
        struct in_addr  bp_siaddr;      /* server IP address */
@@ -36,7 +37,7 @@ struct bootp {
        u_int8_t        bp_sname[64];   /* server host name */
        u_int8_t        bp_file[128];   /* boot file name */
        u_int8_t        bp_vend[64];    /* vendor-specific area */
-};
+} UNALIGNED;
 
 /*
  * UDP port numbers, server and client.
@@ -216,7 +217,7 @@ struct cmu_vend {
        struct in_addr  v_ins1, v_ins2; /* IEN-116 name servers */
        struct in_addr  v_ts1, v_ts2;   /* Time servers */
        u_int8_t        v_unused[24];   /* currently unused */
-};
+} UNALIGNED;
 
 
 /* v_flags values */
diff --git a/contrib/tcpdump/bpf_dump.c b/contrib/tcpdump/bpf_dump.c
deleted file mode 100644 (file)
index f509b7e..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 1992, 1993, 1994, 1995, 1996
- *     The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the University of California,
- * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
- * the University nor the names of its contributors may be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#ifndef lint
-static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/tcpdump/bpf_dump.c,v 1.16.4.1 2008-02-14 20:54:53 guy Exp $ (LBL)";
-#endif
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <tcpdump-stdinc.h>
-
-#include <pcap.h>
-#include <stdio.h>
-
-#include "interface.h"
-
-void
-bpf_dump(const struct bpf_program *p, int option)
-{
-       struct bpf_insn *insn;
-       int i;
-       int n = p->bf_len;
-
-       insn = p->bf_insns;
-       if (option > 2) {
-               printf("%d\n", n);
-               for (i = 0; i < n; ++insn, ++i) {
-                       printf("%u %u %u %u\n", insn->code,
-                              insn->jt, insn->jf, insn->k);
-               }
-               return ;
-       }
-       if (option > 1) {
-               for (i = 0; i < n; ++insn, ++i)
-                       printf("{ 0x%x, %d, %d, 0x%08x },\n",
-                              insn->code, insn->jt, insn->jf, insn->k);
-               return;
-       }
-       for (i = 0; i < n; ++insn, ++i) {
-#ifdef BDEBUG
-               extern int bids[];
-               printf(bids[i] > 0 ? "[%02d]" : " -- ", bids[i] - 1);
-#endif
-               puts(bpf_image(insn, i));
-       }
-}
index f441be3..da4718f 100644 (file)
@@ -31,17 +31,73 @@ static const char rcsid[] _U_ =
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <assert.h>
 
 #include "interface.h"
 
-#define CRC10_POLYNOMIAL 0x633
-static u_int16_t crc10_table[256];
+/*
+ * CRC-10 table generated using the following Python snippet:
+
+import sys
+
+crc_table = []
+for i in range(256):
+       accum = i << 2
+       for j in range(8):
+               accum <<= 1
+               if accum & 0x400:
+                       accum ^= 0x633
+       crc_table.append(accum)
+
+for i in range(len(crc_table)/8):
+       for j in range(8):
+               sys.stdout.write("0x%04x, " % crc_table[i*8+j])
+       sys.stdout.write("\n")
+
+ */
+static const u_int16_t crc10_table[256] =
+{
+       0x0000, 0x0233, 0x0255, 0x0066, 0x0299, 0x00aa, 0x00cc, 0x02ff,
+       0x0301, 0x0132, 0x0154, 0x0367, 0x0198, 0x03ab, 0x03cd, 0x01fe,
+       0x0031, 0x0202, 0x0264, 0x0057, 0x02a8, 0x009b, 0x00fd, 0x02ce,
+       0x0330, 0x0103, 0x0165, 0x0356, 0x01a9, 0x039a, 0x03fc, 0x01cf,
+       0x0062, 0x0251, 0x0237, 0x0004, 0x02fb, 0x00c8, 0x00ae, 0x029d,
+       0x0363, 0x0150, 0x0136, 0x0305, 0x01fa, 0x03c9, 0x03af, 0x019c,
+       0x0053, 0x0260, 0x0206, 0x0035, 0x02ca, 0x00f9, 0x009f, 0x02ac,
+       0x0352, 0x0161, 0x0107, 0x0334, 0x01cb, 0x03f8, 0x039e, 0x01ad,
+       0x00c4, 0x02f7, 0x0291, 0x00a2, 0x025d, 0x006e, 0x0008, 0x023b,
+       0x03c5, 0x01f6, 0x0190, 0x03a3, 0x015c, 0x036f, 0x0309, 0x013a,
+       0x00f5, 0x02c6, 0x02a0, 0x0093, 0x026c, 0x005f, 0x0039, 0x020a,
+       0x03f4, 0x01c7, 0x01a1, 0x0392, 0x016d, 0x035e, 0x0338, 0x010b,
+       0x00a6, 0x0295, 0x02f3, 0x00c0, 0x023f, 0x000c, 0x006a, 0x0259,
+       0x03a7, 0x0194, 0x01f2, 0x03c1, 0x013e, 0x030d, 0x036b, 0x0158,
+       0x0097, 0x02a4, 0x02c2, 0x00f1, 0x020e, 0x003d, 0x005b, 0x0268,
+       0x0396, 0x01a5, 0x01c3, 0x03f0, 0x010f, 0x033c, 0x035a, 0x0169,
+       0x0188, 0x03bb, 0x03dd, 0x01ee, 0x0311, 0x0122, 0x0144, 0x0377,
+       0x0289, 0x00ba, 0x00dc, 0x02ef, 0x0010, 0x0223, 0x0245, 0x0076,
+       0x01b9, 0x038a, 0x03ec, 0x01df, 0x0320, 0x0113, 0x0175, 0x0346,
+       0x02b8, 0x008b, 0x00ed, 0x02de, 0x0021, 0x0212, 0x0274, 0x0047,
+       0x01ea, 0x03d9, 0x03bf, 0x018c, 0x0373, 0x0140, 0x0126, 0x0315,
+       0x02eb, 0x00d8, 0x00be, 0x028d, 0x0072, 0x0241, 0x0227, 0x0014,
+       0x01db, 0x03e8, 0x038e, 0x01bd, 0x0342, 0x0171, 0x0117, 0x0324,
+       0x02da, 0x00e9, 0x008f, 0x02bc, 0x0043, 0x0270, 0x0216, 0x0025,
+       0x014c, 0x037f, 0x0319, 0x012a, 0x03d5, 0x01e6, 0x0180, 0x03b3,
+       0x024d, 0x007e, 0x0018, 0x022b, 0x00d4, 0x02e7, 0x0281, 0x00b2,
+       0x017d, 0x034e, 0x0328, 0x011b, 0x03e4, 0x01d7, 0x01b1, 0x0382,
+       0x027c, 0x004f, 0x0029, 0x021a, 0x00e5, 0x02d6, 0x02b0, 0x0083,
+       0x012e, 0x031d, 0x037b, 0x0148, 0x03b7, 0x0184, 0x01e2, 0x03d1,
+       0x022f, 0x001c, 0x007a, 0x0249, 0x00b6, 0x0285, 0x02e3, 0x00d0,
+       0x011f, 0x032c, 0x034a, 0x0179, 0x0386, 0x01b5, 0x01d3, 0x03e0,
+       0x021e, 0x002d, 0x004b, 0x0278, 0x0087, 0x02b4, 0x02d2, 0x00e1
+};
 
 static void
 init_crc10_table(void)
 {   
+#define CRC10_POLYNOMIAL 0x633
     register int i, j;
     register u_int16_t accum;
+    u_int16_t verify_crc10_table[256];
     
     for ( i = 0;  i < 256;  i++ )
     {
@@ -50,9 +106,12 @@ init_crc10_table(void)
         {
             if ((accum <<= 1) & 0x400) accum ^= CRC10_POLYNOMIAL;
         }
-        crc10_table[i] = accum;
+        verify_crc10_table[i] = accum;
     }
-    return;
+    assert(memcmp(verify_crc10_table,
+                                 crc10_table,
+                                 sizeof(verify_crc10_table)) == 0);
+#undef CRC10_POLYNOMIAL
 }
 
 u_int16_t
index 14c0a9e..c921b39 100644 (file)
@@ -38,7 +38,7 @@
 #include "cpack.h"
 #include "extract.h"
 
-static u_int8_t *
+u_int8_t *
 cpack_next_boundary(u_int8_t *buf, u_int8_t *p, size_t alignment)
 {
        size_t misalignment = (size_t)(p - buf) % alignment;
@@ -53,7 +53,7 @@ cpack_next_boundary(u_int8_t *buf, u_int8_t *p, size_t alignment)
  * wordsize bytes remain in the buffer after the boundary.  Otherwise,
  * return a pointer to the boundary.
  */
-static u_int8_t *
+u_int8_t *
 cpack_align_and_reserve(struct cpack_state *cs, size_t wordsize)
 {
        u_int8_t *next;
index 14ed376..74f9796 100644 (file)
@@ -43,6 +43,9 @@ int cpack_uint16(struct cpack_state *, u_int16_t *);
 int cpack_uint32(struct cpack_state *, u_int32_t *);
 int cpack_uint64(struct cpack_state *, u_int64_t *);
 
+u_int8_t *cpack_next_boundary(u_int8_t *buf, u_int8_t *p, size_t alignment);
+u_int8_t *cpack_align_and_reserve(struct cpack_state *cs, size_t wordsize);
+
 #define cpack_int8(__s, __p)   cpack_uint8((__s),  (u_int8_t*)(__p))
 #define cpack_int16(__s, __p)  cpack_uint16((__s), (u_int16_t*)(__p))
 #define cpack_int32(__s, __p)  cpack_uint32((__s), (u_int32_t*)(__p))
index 97550c7..fc5e515 100644 (file)
@@ -18,7 +18,7 @@
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- * @(#) $Header: /tcpdump/master/tcpdump/ethertype.h,v 1.29.2.1 2008-02-06 10:49:22 guy Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/tcpdump/ethertype.h,v 1.30 2008-02-06 10:47:53 guy Exp $ (LBL)
  */
 
 /*
@@ -76,6 +76,9 @@
 #ifndef ETHERTYPE_SCA
 #define ETHERTYPE_SCA          0x6007
 #endif
+#ifndef ETHERTYPE_TEB
+#define ETHERTYPE_TEB          0x6558
+#endif
 #ifndef        ETHERTYPE_LANBRIDGE
 #define        ETHERTYPE_LANBRIDGE     0x8038
 #endif
 #ifndef        ETHERTYPE_8021Q
 #define        ETHERTYPE_8021Q         0x8100
 #endif
+
+/* see:
+        http://en.wikipedia.org/wiki/IEEE_802.1Q
+    and http://en.wikipedia.org/wiki/QinQ
+*/
+#ifndef        ETHERTYPE_8021Q9100
+#define        ETHERTYPE_8021Q9100     0x9100
+#endif
+#ifndef        ETHERTYPE_8021Q9200
+#define        ETHERTYPE_8021Q9200     0x9200
+#endif
+#ifndef        ETHERTYPE_8021QinQ
+#define        ETHERTYPE_8021QinQ      0x88a8
+#endif
 #ifndef ETHERTYPE_IPX
 #define ETHERTYPE_IPX          0x8137
 #endif
 #ifndef ETHERTYPE_PPPOES
 #define ETHERTYPE_PPPOES       0x8864
 #endif
+#ifndef ETHERTYPE_PPPOED2
+#define ETHERTYPE_PPPOED2      0x3c12
+#endif
+#ifndef ETHERTYPE_PPPOES2
+#define ETHERTYPE_PPPOES2      0x3c13
+#endif
 #ifndef ETHERTYPE_JUMBO
 #define ETHERTYPE_JUMBO         0x8870
 #endif
diff --git a/contrib/tcpdump/forces.h b/contrib/tcpdump/forces.h
new file mode 100644 (file)
index 0000000..ed497d4
--- /dev/null
@@ -0,0 +1,679 @@
+/*
+ * Copyright (c) 1982, 1986, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Copyright (c) 2009 Mojatatu Networks, Inc
+ *
+ */
+
+/*
+ * Per draft-ietf-forces-protocol-22
+*/
+#define        ForCES_VERS     1
+#define        ForCES_HDRL     24
+#define        ForCES_ALNL     4U
+#define TLV_HDRL       4
+#define ILV_HDRL       8
+
+#define TOM_RSVD       0x0
+#define TOM_ASSNSETUP  0x1
+#define TOM_ASSNTEARD  0x2
+#define TOM_CONFIG     0x3
+#define TOM_QUERY      0x4
+#define TOM_EVENTNOT   0x5
+#define TOM_PKTREDIR   0x6
+#define TOM_HEARTBT    0x0F
+#define TOM_ASSNSETREP         0x11
+#define TOM_CONFIGREP  0x13
+#define TOM_QUERYREP   0x14
+
+/*
+ * tom_h Flags: resv1(8b):maxtlvs(4b):resv2(2b):mintlv(2b)
+*/
+#define ZERO_TTLV      0x01
+#define ZERO_MORE_TTLV 0x02
+#define ONE_MORE_TTLV  0x04
+#define ZERO_TLV       0x00
+#define ONE_TLV                0x10
+#define TWO_TLV                0x20
+#define MAX_TLV                0xF0
+
+#define TTLV_T1                (ONE_MORE_TTLV|ONE_TLV)
+#define TTLV_T2                (ONE_MORE_TTLV|MAX_TLV)
+
+struct tom_h {
+       u_int32_t v;
+       u_int16_t flags;
+       u_int16_t op_msk;
+       const char *s;
+       int (*print) (register const u_char * pptr, register u_int len,
+                     u_int16_t op_msk, int indent);
+};
+
+enum {
+       TOM_RSV_I,
+       TOM_ASS_I,
+       TOM_AST_I,
+       TOM_CFG_I,
+       TOM_QRY_I,
+       TOM_EVN_I,
+       TOM_RED_I,
+       TOM_HBT_I,
+       TOM_ASR_I,
+       TOM_CNR_I,
+       TOM_QRR_I,
+       _TOM_RSV_MAX
+};
+#define TOM_MAX_IND (_TOM_RSV_MAX - 1)
+
+int lfbselect_print(register const u_char * pptr, register u_int len,
+                   u_int16_t op_msk, int indent);
+int redirect_print(register const u_char * pptr, register u_int len,
+                  u_int16_t op_msk, int indent);
+int asrtlv_print(register const u_char * pptr, register u_int len,
+                u_int16_t op_msk, int indent);
+int asttlv_print(register const u_char * pptr, register u_int len,
+                u_int16_t op_msk, int indent);
+int gentltlv_print(register const u_char * pptr, register u_int len,
+                  u_int16_t op_msk, int indent);
+int print_metailv(register const u_char * pptr, register u_int len,
+             u_int16_t op_msk, int indent);
+int print_metatlv(register const u_char * pptr, register u_int len,
+             u_int16_t op_msk, int indent);
+int print_reddata(register const u_char * pptr, register u_int len,
+             u_int16_t op_msk, int indent);
+
+static inline int tom_valid(u_int8_t tom)
+{
+       if (tom > 0) {
+               if (tom >= 0x7 && tom <= 0xe)
+                       return 0;
+               if (tom == 0x10)
+                       return 0;
+               if (tom > 0x14)
+                       return 0;
+               return 1;
+       } else
+               return 0;
+}
+
+static inline const char *ForCES_node(u_int32_t node)
+{
+       if (node <= 0x3FFFFFFF)
+               return "FE";
+       if (node >= 0x40000000 && node <= 0x7FFFFFFF)
+               return "CE";
+       if (node >= 0xC0000000 && node <= 0xFFFFFFEF)
+               return "AllMulticast";
+       if (node == 0xFFFFFFFD)
+               return "AllCEsBroadcast";
+       if (node == 0xFFFFFFFE)
+               return "AllFEsBroadcast";
+       if (node == 0xFFFFFFFF)
+               return "AllBroadcast";
+
+       return "ForCESreserved";
+
+}
+
+static inline const char *ForCES_ACKp(u_int32_t flg)
+{
+       if (flg == 0x0)
+               return "NoACK";
+       if (flg == 0x1)
+               return "SuccessACK";
+       if (flg == 0x2)
+               return "FailureACK";
+       if (flg == 0x3)
+               return "AlwaysACK";
+       return "ACKUnknown";
+}
+
+static inline const char *ForCES_EMp(u_int32_t flg)
+{
+       if (flg == 0x0)
+               return "EMReserved";
+       if (flg == 0x1)
+               return "execute-all-or-none";
+       if (flg == 0x2)
+               return "execute-until-failure";
+       if (flg == 0x3)
+               return "continue-execute-on-failure";
+       return "EMUnknown";
+}
+
+static inline const char *ForCES_ATp(u_int32_t flg)
+{
+       if (flg == 0x0)
+               return "Standalone";
+       if (flg == 0x1)
+               return "2PCtransaction";
+       return "ATUnknown";
+}
+
+static inline const char *ForCES_TPp(u_int32_t flg)
+{
+       if (flg == 0x0)
+               return "StartofTransaction";
+       if (flg == 0x1)
+               return "MiddleofTransaction";
+       if (flg == 0x2)
+               return "EndofTransaction";
+       if (flg == 0x3)
+               return "abort";
+       return "TPUnknown";
+}
+
+/*
+ * Structure of forces header, naked of TLVs.
+ */
+struct forcesh {
+       u_int8_t fm_vrsvd;      /* version and reserved */
+#define ForCES_V(forcesh)      ((forcesh)->fm_vrsvd >> 4)
+       u_int8_t fm_tom;        /* type of message */
+       u_int16_t fm_len;       /* total length * 4 bytes */
+#define ForCES_BLN(forcesh)    ((u_int32_t)(EXTRACT_16BITS(&(forcesh)->fm_len) << 2))
+       u_int32_t fm_sid;       /* Source ID */
+#define ForCES_SID(forcesh)    EXTRACT_32BITS(&(forcesh)->fm_sid)
+       u_int32_t fm_did;       /* Destination ID */
+#define ForCES_DID(forcesh)    EXTRACT_32BITS(&(forcesh)->fm_did)
+       u_int8_t fm_cor[8];     /* correlator */
+       u_int32_t fm_flags;     /* flags */
+#define ForCES_ACK(forcesh)    ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0xC0000000) >> 30)
+#define ForCES_PRI(forcesh)    ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x38000000) >> 27)
+#define ForCES_RS1(forcesh)    ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x07000000) >> 24)
+#define ForCES_EM(forcesh)     ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x00C00000) >> 22)
+#define ForCES_AT(forcesh)     ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x00200000) >> 21)
+#define ForCES_TP(forcesh)     ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x00180000) >> 19)
+#define ForCES_RS2(forcesh)    ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x0007FFFF) >> 0)
+};
+
+#define ForCES_HLN_VALID(fhl,tlen) ((tlen) >= ForCES_HDRL && \
+                                  (fhl) >= ForCES_HDRL && \
+                                  (fhl) == (tlen))
+
+#define F_LFB_RSVD 0x0
+#define F_LFB_FEO 0x1
+#define F_LFB_FEPO 0x2
+const struct tok ForCES_LFBs[] = {
+       {F_LFB_RSVD, "Invalid TLV"},
+       {F_LFB_FEO, "FEObj LFB"},
+       {F_LFB_FEPO, "FEProtoObj LFB"},
+       {0, NULL}
+};
+
+int forces_type_print(register const u_char * pptr, const struct forcesh *fhdr,
+                 register u_int mlen, const struct tom_h *tops);
+
+enum {
+       F_OP_RSV,
+       F_OP_SET,
+       F_OP_SETPROP,
+       F_OP_SETRESP,
+       F_OP_SETPRESP,
+       F_OP_DEL,
+       F_OP_DELRESP,
+       F_OP_GET,
+       F_OP_GETPROP,
+       F_OP_GETRESP,
+       F_OP_GETPRESP,
+       F_OP_REPORT,
+       F_OP_COMMIT,
+       F_OP_RCOMMIT,
+       F_OP_RTRCOMP,
+       _F_OP_MAX
+};
+
+#define F_OP_MAX       (_F_OP_MAX - 1)
+enum {
+       B_OP_SET = 1 << (F_OP_SET - 1),
+       B_OP_SETPROP = 1 << (F_OP_SETPROP - 1),
+       B_OP_SETRESP = 1 << (F_OP_SETRESP - 1),
+       B_OP_SETPRESP = 1 << (F_OP_SETPRESP - 1),
+       B_OP_DEL = 1 << (F_OP_DEL - 1),
+       B_OP_DELRESP = 1 << (F_OP_DELRESP - 1),
+       B_OP_GET = 1 << (F_OP_GET - 1),
+       B_OP_GETPROP = 1 << (F_OP_GETPROP - 1),
+       B_OP_GETRESP = 1 << (F_OP_GETRESP - 1),
+       B_OP_GETPRESP = 1 << (F_OP_GETPRESP - 1),
+       B_OP_REPORT = 1 << (F_OP_REPORT - 1),
+       B_OP_COMMIT = 1 << (F_OP_COMMIT - 1),
+       B_OP_RCOMMIT = 1 << (F_OP_RCOMMIT - 1),
+       B_OP_RTRCOMP = 1 << (F_OP_RTRCOMP - 1),
+};
+
+struct optlv_h {
+       u_int16_t flags;
+       u_int16_t op_msk;
+       const char *s;
+       int (*print) (register const u_char * pptr, register u_int len,
+                     u_int16_t op_msk, int indent);
+};
+
+int genoptlv_print(register const u_char * pptr, register u_int len,
+                  u_int16_t op_msk, int indent);
+int recpdoptlv_print(register const u_char * pptr, register u_int len,
+                    u_int16_t op_msk, int indent);
+int invoptlv_print(register const u_char * pptr, register u_int len,
+                  u_int16_t op_msk, int indent);
+
+#define OP_MIN_SIZ 8
+struct pathdata_h {
+       u_int16_t pflags;
+       u_int16_t pIDcnt;
+};
+
+#define        B_FULLD         0x1
+#define        B_SPARD         0x2
+#define B_RESTV                0x4
+#define B_KEYIN                0x8
+
+static const struct optlv_h OPTLV_msg[F_OP_MAX + 1] = {
+       /* F_OP_RSV */ {ZERO_TTLV, 0, "Invalid OPTLV", invoptlv_print},
+       /* F_OP_SET */ {TTLV_T2, B_FULLD | B_SPARD, " Set", recpdoptlv_print},
+       /* F_OP_SETPROP */
+           {TTLV_T2, B_FULLD | B_SPARD, " SetProp", recpdoptlv_print},
+       /* F_OP_SETRESP */ {TTLV_T2, B_RESTV, " SetResp", recpdoptlv_print},
+       /* F_OP_SETPRESP */ {TTLV_T2, B_RESTV, " SetPropResp", recpdoptlv_print},
+       /* F_OP_DEL */ {ZERO_TTLV, 0, " Del", recpdoptlv_print},
+       /* F_OP_DELRESP */ {TTLV_T2, B_RESTV, " DelResp", recpdoptlv_print},
+       /* F_OP_GET */ {ZERO_TTLV, 0, " Get", recpdoptlv_print},
+       /* F_OP_GETPROP */ {ZERO_TTLV, 0, " GetProp", recpdoptlv_print},
+       /* F_OP_GETRESP */
+           {TTLV_T2, B_FULLD | B_RESTV, " GetResp", recpdoptlv_print},
+       /* F_OP_GETPRESP */
+           {TTLV_T2, B_FULLD | B_RESTV, " GetPropResp", recpdoptlv_print},
+       /* F_OP_REPORT */
+           {TTLV_T2, B_FULLD | B_SPARD, " Report", recpdoptlv_print},
+       /* F_OP_COMMIT */ {ZERO_TTLV, 0, " Commit", NULL},
+       /* F_OP_RCOMMIT */ {TTLV_T1, B_RESTV, " RCommit", genoptlv_print},
+       /* F_OP_RTRCOMP */ {ZERO_TTLV, 0, " RTRCOMP", NULL},
+};
+
+static inline const struct optlv_h *get_forces_optlv_h(u_int16_t opt)
+{
+       if (opt > F_OP_MAX || opt <= F_OP_RSV)
+               return &OPTLV_msg[F_OP_RSV];
+
+       return &OPTLV_msg[opt];
+}
+
+#define IND_SIZE 256
+#define IND_CHR ' '
+#define IND_PREF '\n'
+#define IND_SUF 0x0
+char ind_buf[IND_SIZE];
+
+static inline char *indent_pr(int indent, int nlpref)
+{
+       int i = 0;
+       char *r = ind_buf;
+
+       if (indent > (IND_SIZE - 1))
+               indent = IND_SIZE - 1;
+
+       if (nlpref) {
+               r[i] = IND_PREF;
+               i++;
+               indent--;
+       }
+
+       while (--indent >= 0)
+               r[i++] = IND_CHR;
+
+       r[i] = IND_SUF;
+       return r;
+}
+
+static inline int op_valid(u_int16_t op, u_int16_t mask)
+{
+       int opb = 1 << (op - 1);
+
+       if (op == 0)
+               return 0;
+       if (opb & mask)
+               return 1;
+       /* I guess we should allow vendor operations? */
+       if (op >= 0x8000)
+               return 1;
+       return 0;
+}
+
+#define F_TLV_RSVD     0x0000
+#define F_TLV_REDR     0x0001
+#define F_TLV_ASRS     0x0010
+#define F_TLV_ASRT     0x0011
+#define F_TLV_LFBS     0x1000
+#define F_TLV_PDAT     0x0110
+#define F_TLV_KEYI     0x0111
+#define F_TLV_FULD     0x0112
+#define F_TLV_SPAD     0x0113
+#define F_TLV_REST     0x0114
+#define F_TLV_METD     0x0115
+#define F_TLV_REDD     0x0116
+#define F_TLV_VNST     0x8000
+
+static const struct tok ForCES_TLV[] = {
+       {F_TLV_RSVD, "Invalid TLV"},
+       {F_TLV_REDR, "REDIRECT TLV"},
+       {F_TLV_ASRS, "ASResult TLV"},
+       {F_TLV_ASRT, "ASTreason TLV"},
+       {F_TLV_LFBS, "LFBselect TLV"},
+       {F_TLV_PDAT, "PATH-DATA TLV"},
+       {F_TLV_KEYI, "KEYINFO TLV"},
+       {F_TLV_FULD, "FULLDATA TLV"},
+       {F_TLV_SPAD, "SPARSEDATA TLV"},
+       {F_TLV_REST, "RESULT TLV"},
+       {F_TLV_METD, "METADATA TLV"},
+       {F_TLV_REDD, "REDIRECTDATA TLV"},
+       {0, NULL}
+};
+
+#define TLV_HLN        4
+static inline int ttlv_valid(u_int16_t ttlv)
+{
+       if (ttlv > 0) {
+               if (ttlv == 1 || ttlv == 0x1000)
+                       return 1;
+               if (ttlv >= 0x10 && ttlv <= 0x11)
+                       return 1;
+               if (ttlv >= 0x110 && ttlv <= 0x116)
+                       return 1;
+               if (ttlv >= 0x8000)
+                       return 0;       /* XXX: */
+       }
+
+       return 0;
+}
+
+struct forces_ilv {
+       u_int32_t type;
+       u_int32_t length;
+};
+
+struct forces_tlv {
+       u_int16_t type;
+       u_int16_t length;
+};
+
+int otlv_print(const struct forces_tlv *otlv, u_int16_t op_msk, int indent);
+
+#define F_ALN_LEN(len) ( ((len)+ForCES_ALNL-1) & ~(ForCES_ALNL-1) )
+#define        GET_TOP_TLV(fhdr) ((struct forces_tlv *)((fhdr) + sizeof (struct forcesh)))
+#define TLV_SET_LEN(len)  (F_ALN_LEN(TLV_HDRL) + (len))
+#define TLV_ALN_LEN(len)  F_ALN_LEN(TLV_SET_LEN(len))
+#define TLV_RDAT_LEN(tlv) ((int)(EXTRACT_16BITS(&(tlv)->length) - TLV_SET_LEN(0))
+#define TLV_DATA(tlvp)   ((void*)(((char*)(tlvp)) + TLV_SET_LEN(0)))
+#define GO_NXT_TLV(tlv,rlen) ((rlen) -= F_ALN_LEN(EXTRACT_16BITS(&(tlv)->length)), \
+                             (struct forces_tlv*)(((char*)(tlv)) \
+                                     + F_ALN_LEN(EXTRACT_16BITS(&(tlv)->length))))
+#define ILV_SET_LEN(len)  (F_ALN_LEN(ILV_HDRL) + (len))
+#define ILV_ALN_LEN(len)  F_ALN_LEN(ILV_SET_LEN(len))
+#define ILV_RDAT_LEN(ilv) ((int)(EXTRACT_32BITS(&(ilv)->length)) - ILV_SET_LEN(0))
+#define ILV_DATA(ilvp)   ((void*)(((char*)(ilvp)) + ILV_SET_LEN(0)))
+#define GO_NXT_ILV(ilv,rlen) ((rlen) -= F_ALN_LEN(EXTRACT_32BITS(&(ilv)->length)), \
+                             (struct forces_ilv *)(((char*)(ilv)) \
+                                     + F_ALN_LEN(EXTRACT_32BITS(&(ilv)->length))))
+#define INVALID_RLEN -1
+#define INVALID_STLN -2
+#define INVALID_LTLN -3
+#define INVALID_ALEN -4
+
+static const struct tok ForCES_TLV_err[] = {
+       {INVALID_RLEN, "Invalid total length"},
+       {INVALID_STLN, "xLV too short"},
+       {INVALID_LTLN, "xLV too long"},
+       {INVALID_ALEN, "data padding missing"},
+       {0, NULL}
+};
+
+static inline int tlv_valid(const struct forces_tlv *tlv, u_int rlen)
+{
+       if (rlen < TLV_HDRL)
+               return INVALID_RLEN;
+       if (EXTRACT_16BITS(&tlv->length) < TLV_HDRL)
+               return INVALID_STLN;
+       if (EXTRACT_16BITS(&tlv->length) > rlen)
+               return INVALID_LTLN;
+       if (rlen < F_ALN_LEN(EXTRACT_16BITS(&tlv->length)))
+               return INVALID_ALEN;
+
+       return 0;
+}
+
+static inline int ilv_valid(const struct forces_ilv *ilv, u_int rlen)
+{
+       if (rlen < ILV_HDRL)
+               return INVALID_RLEN;
+       if (EXTRACT_32BITS(&ilv->length) < ILV_HDRL)
+               return INVALID_STLN;
+       if (EXTRACT_32BITS(&ilv->length) > rlen)
+               return INVALID_LTLN;
+       if (rlen < F_ALN_LEN(EXTRACT_32BITS(&ilv->length)))
+               return INVALID_ALEN;
+
+       return 0;
+}
+
+struct forces_lfbsh {
+       u_int32_t class;
+       u_int32_t instance;
+};
+
+#define ASSNS_OPS (B_OP_REPORT)
+#define CFG_OPS        (B_OP_SET|B_OP_SETPROP|B_OP_DEL|B_OP_COMMIT|B_OP_RTRCOMP)
+#define CFG_ROPS (B_OP_SETRESP|B_OP_SETPRESP|B_OP_DELRESP|B_OP_RCOMMIT)
+#define CFG_QY (B_OP_GET|B_OP_GETPROP)
+#define CFG_QYR (B_OP_GETRESP|B_OP_GETPRESP)
+#define CFG_EVN (B_OP_REPORT)
+
+static const struct tom_h ForCES_msg[TOM_MAX_IND + 1] = {
+       /* TOM_RSV_I */ {TOM_RSVD, ZERO_TTLV, 0, "Invalid message", NULL},
+       /* TOM_ASS_I */ {TOM_ASSNSETUP, ZERO_MORE_TTLV | TWO_TLV, ASSNS_OPS,
+                      "Association Setup", lfbselect_print},
+       /* TOM_AST_I */
+           {TOM_ASSNTEARD, TTLV_T1, 0, "Association TearDown", asttlv_print},
+       /* TOM_CFG_I */ {TOM_CONFIG, TTLV_T2, CFG_OPS, "Config", lfbselect_print},
+       /* TOM_QRY_I */ {TOM_QUERY, TTLV_T2, CFG_QY, "Query", lfbselect_print},
+       /* TOM_EVN_I */ {TOM_EVENTNOT, TTLV_T1, CFG_EVN, "Event Notification",
+                      lfbselect_print},
+       /* TOM_RED_I */
+           {TOM_PKTREDIR, TTLV_T2, 0, "Packet Redirect", redirect_print},
+       /* TOM_HBT_I */ {TOM_HEARTBT, ZERO_TTLV, 0, "HeartBeat", NULL},
+       /* TOM_ASR_I */
+           {TOM_ASSNSETREP, TTLV_T1, 0, "Association Response", asrtlv_print},
+       /* TOM_CNR_I */ {TOM_CONFIGREP, TTLV_T2, CFG_ROPS, "Config Response",
+                      lfbselect_print},
+       /* TOM_QRR_I */
+           {TOM_QUERYREP, TTLV_T2, CFG_QYR, "Query Response", lfbselect_print},
+};
+
+static inline const struct tom_h *get_forces_tom(u_int8_t tom)
+{
+       int i;
+       for (i = TOM_RSV_I; i <= TOM_MAX_IND; i++) {
+               const struct tom_h *th = &ForCES_msg[i];
+               if (th->v == tom)
+                       return th;
+       }
+       return &ForCES_msg[TOM_RSV_I];
+}
+
+struct pdata_ops {
+       u_int32_t v;
+       u_int16_t flags;
+       u_int16_t op_msk;
+       const char *s;
+       int (*print) (register const u_char * pptr, register u_int len,
+                     u_int16_t op_msk, int indent);
+};
+
+enum {
+       PD_RSV_I,
+       PD_SEL_I,
+       PD_FDT_I,
+       PD_SDT_I,
+       PD_RES_I,
+       PD_PDT_I,
+       _PD_RSV_MAX
+};
+#define PD_MAX_IND (_TOM_RSV_MAX - 1)
+
+static inline int pd_valid(u_int16_t pd)
+{
+       if (pd >= F_TLV_PDAT && pd <= F_TLV_REST)
+               return 1;
+       return 0;
+}
+
+static inline void chk_op_type(u_int16_t type, u_int16_t msk, u_int16_t omsk)
+{
+       if (type != F_TLV_PDAT) {
+               if (msk & B_KEYIN) {
+                       if (type != F_TLV_KEYI) {
+                               printf
+                                   ("Based on flags expected KEYINFO TLV!\n");
+                       }
+               } else {
+                       if (!(msk & omsk)) {
+                               printf
+                                   ("Illegal DATA encoding for type 0x%x programmed %x got %x \n",
+                                    type, omsk, msk);
+                       }
+               }
+       }
+
+}
+
+int fdatatlv_print(register const u_char * pptr, register u_int len,
+                  u_int16_t op_msk, int indent);
+int sdatailv_print(register const u_char * pptr, register u_int len,
+              u_int16_t op_msk, int indent);
+int sdatatlv_print(register const u_char * pptr, register u_int len,
+                  u_int16_t op_msk, int indent);
+int pdatatlv_print(register const u_char * pptr, register u_int len,
+                  u_int16_t op_msk, int indent);
+int pkeyitlv_print(register const u_char * pptr, register u_int len,
+                  u_int16_t op_msk, int indent);
+
+int pdatacnt_print(register const u_char * pptr, register u_int len,
+              u_int16_t IDcnt, u_int16_t op_msk, int indent);
+int pdata_print(register const u_char * pptr, register u_int len,
+           u_int16_t op_msk, int indent);
+
+int prestlv_print(register const u_char * pptr, register u_int len,
+                 u_int16_t op_msk, int indent);
+#define F_SELKEY 1
+
+struct res_val {
+       u_int8_t result;
+       u_int8_t resv1;
+       u_int16_t resv2;
+};
+
+static const struct pdata_ops ForCES_pdata[PD_MAX_IND + 1] = {
+       /* PD_RSV_I */ {0, 0, 0, "Invalid message", NULL},
+       /* PD_SEL_I */ {F_TLV_KEYI, 0, 0, "KEYINFO TLV", pkeyitlv_print},
+       /* PD_FDT_I */ {F_TLV_FULD, 0, B_FULLD, "FULLDATA TLV", fdatatlv_print},
+       /* PD_SDT_I */ {F_TLV_SPAD, 0, B_SPARD, "SPARSEDATA TLV", sdatatlv_print},
+       /* PD_RES_I */ {F_TLV_REST, 0, B_RESTV, "RESULT TLV", prestlv_print},
+       /* PD_PDT_I */
+           {F_TLV_PDAT, 0, 0, "Inner PATH-DATA TLV", recpdoptlv_print},
+};
+
+static inline const struct pdata_ops *get_forces_pd(u_int16_t pd)
+{
+       int i;
+       for (i = PD_RSV_I + 1; i <= PD_MAX_IND; i++) {
+               const struct pdata_ops *pdo = &ForCES_pdata[i];
+               if (pdo->v == pd)
+                       return pdo;
+       }
+       return &ForCES_pdata[TOM_RSV_I];
+}
+
+enum {
+       E_SUCCESS,
+       E_INVALID_HEADER,
+       E_LENGTH_MISMATCH,
+       E_VERSION_MISMATCH,
+       E_INVALID_DESTINATION_PID,
+       E_LFB_UNKNOWN,
+       E_LFB_NOT_FOUND,
+       E_LFB_INSTANCE_ID_NOT_FOUND,
+       E_INVALID_PATH,
+       E_COMPONENT_DOES_NOT_EXIST,
+       E_EXISTS,
+       E_NOT_FOUND,
+       E_READ_ONLY,
+       E_INVALID_ARRAY_CREATION,
+       E_VALUE_OUT_OF_RANGE,
+       E_CONTENTS_TOO_LONG,
+       E_INVALID_PARAMETERS,
+       E_INVALID_MESSAGE_TYPE,
+       E_INVALID_FLAGS,
+       E_INVALID_TLV,
+       E_EVENT_ERROR,
+       E_NOT_SUPPORTED,
+       E_MEMORY_ERROR,
+       E_INTERNAL_ERROR,
+       /* 0x18-0xFE are reserved .. */
+       E_UNSPECIFIED_ERROR = 0XFF
+};
+
+const struct tok ForCES_errs[] = {
+       {E_SUCCESS, "SUCCESS"},
+       {E_INVALID_HEADER, "INVALID HEADER"},
+       {E_LENGTH_MISMATCH, "LENGTH MISMATCH"},
+       {E_VERSION_MISMATCH, "VERSION MISMATCH"},
+       {E_INVALID_DESTINATION_PID, "INVALID DESTINATION PID"},
+       {E_LFB_UNKNOWN, "LFB UNKNOWN"},
+       {E_LFB_NOT_FOUND, "LFB NOT FOUND"},
+       {E_LFB_INSTANCE_ID_NOT_FOUND, "LFB INSTANCE ID NOT FOUND"},
+       {E_INVALID_PATH, "INVALID PATH"},
+       {E_COMPONENT_DOES_NOT_EXIST, "COMPONENT DOES NOT EXIST"},
+       {E_EXISTS, "EXISTS ALREADY"},
+       {E_NOT_FOUND, "NOT FOUND"},
+       {E_READ_ONLY, "READ ONLY"},
+       {E_INVALID_ARRAY_CREATION, "INVALID ARRAY CREATION"},
+       {E_VALUE_OUT_OF_RANGE, "VALUE OUT OF RANGE"},
+       {E_CONTENTS_TOO_LONG, "CONTENTS TOO LONG"},
+       {E_INVALID_PARAMETERS, "INVALID PARAMETERS"},
+       {E_INVALID_MESSAGE_TYPE, "INVALID MESSAGE TYPE"},
+       {E_INVALID_FLAGS, "INVALID FLAGS"},
+       {E_INVALID_TLV, "INVALID TLV"},
+       {E_EVENT_ERROR, "EVENT ERROR"},
+       {E_NOT_SUPPORTED, "NOT SUPPORTED"},
+       {E_MEMORY_ERROR, "MEMORY ERROR"},
+       {E_INTERNAL_ERROR, "INTERNAL ERROR"},
+       {E_UNSPECIFIED_ERROR, "UNSPECIFIED ERROR"},
+       {0, NULL}
+};
index ff9adb5..7391767 100644 (file)
@@ -28,7 +28,7 @@ static const char rcsid[] _U_ =
 #include "gmpls.h"
 
 /* rfc3471 */
-struct tok gmpls_link_prot_values[] = {
+const struct tok gmpls_link_prot_values[] = {
     { 0x01, "Extra Traffic"},
     { 0x02, "Unprotected"},
     { 0x04, "Shared"},
@@ -41,7 +41,7 @@ struct tok gmpls_link_prot_values[] = {
 };
 
 /* rfc3471 */
-struct tok gmpls_switch_cap_values[] = {
+const struct tok gmpls_switch_cap_values[] = {
     { GMPLS_PSC1, "Packet-Switch Capable-1"},
     { GMPLS_PSC2, "Packet-Switch Capable-2"},
     { GMPLS_PSC3, "Packet-Switch Capable-3"},
@@ -54,14 +54,14 @@ struct tok gmpls_switch_cap_values[] = {
 };
 
 /* rfc4205 */
-struct tok gmpls_switch_cap_tsc_indication_values[] = {
+const struct tok gmpls_switch_cap_tsc_indication_values[] = {
     { 0, "Standard SONET/SDH" },
     { 1, "Arbitrary SONET/SDH" },
     { 0, NULL }
 };
 
 /* rfc3471 */
-struct tok gmpls_encoding_values[] = {
+const struct tok gmpls_encoding_values[] = {
     { 1,    "Packet"},
     { 2,    "Ethernet V2/DIX"},
     { 3,    "ANSI/ETSI PDH"},
@@ -77,7 +77,7 @@ struct tok gmpls_encoding_values[] = {
 };
 
 /* rfc3471 */
-struct tok gmpls_payload_values[] = {
+const struct tok gmpls_payload_values[] = {
     {  0,   "Unknown"},
     {  1,   "Reserved"},
     {  2,   "Reserved"},
@@ -145,7 +145,7 @@ struct tok gmpls_payload_values[] = {
  * Link Type values used by LMP Service Discovery (specifically, the Client 
  * Port Service Attributes Object). See UNI 1.0 section 9.4.2 for details.
  */
-struct tok lmp_sd_service_config_cpsa_link_type_values[] = {
+const struct tok lmp_sd_service_config_cpsa_link_type_values[] = {
     { 5, "SDH ITU-T G.707"},
     { 6, "SONET ANSI T1.105"},
     { 0, NULL}
@@ -156,7 +156,7 @@ struct tok lmp_sd_service_config_cpsa_link_type_values[] = {
  * the Client Port Service Attributes Object). See UNI 1.0 section 9.4.2 for 
  * details.
  */
-struct tok lmp_sd_service_config_cpsa_signal_type_sdh_values[] = {
+const struct tok lmp_sd_service_config_cpsa_signal_type_sdh_values[] = {
     { 5,  "VC-3"},
     { 6,  "VC-4"},
     { 7,  "STM-0"},
@@ -173,7 +173,7 @@ struct tok lmp_sd_service_config_cpsa_signal_type_sdh_values[] = {
  * the Client Port Service Attributes Object). See UNI 1.0 section 9.4.2 for 
  * details.
  */
-struct tok lmp_sd_service_config_cpsa_signal_type_sonet_values[] = {
+const struct tok lmp_sd_service_config_cpsa_signal_type_sonet_values[] = {
     { 5,  "STS-1 SPE"},
     { 6,  "STS-3c SPE"},
     { 7,  "STS-1"},
@@ -189,7 +189,7 @@ struct tok lmp_sd_service_config_cpsa_signal_type_sonet_values[] = {
 #define DIFFSERV_BC_MODEL_MAM           1   /* draft-ietf-tewg-diff-te-proto-07 */ 
 #define DIFFSERV_BC_MODEL_EXTD_MAM      254 /* experimental */
 
-struct tok diffserv_te_bc_values[] = {
+const struct tok diffserv_te_bc_values[] = {
     {  DIFFSERV_BC_MODEL_RDM, "Russian dolls"},
     {  DIFFSERV_BC_MODEL_MAM, "Maximum allocation"},
     {  DIFFSERV_BC_MODEL_EXTD_MAM, "Maximum allocation with E-LSP support"},
index 6b2db23..8db99de 100644 (file)
 #define GMPLS_LSC  150
 #define GMPLS_FSC  200
 
-extern struct tok gmpls_link_prot_values[];
-extern struct tok gmpls_switch_cap_values[];
-extern struct tok gmpls_switch_cap_tsc_indication_values[];
-extern struct tok gmpls_encoding_values[];
-extern struct tok gmpls_payload_values[];
-extern struct tok diffserv_te_bc_values[];
-extern struct tok lmp_sd_service_config_cpsa_link_type_values[];
-extern struct tok lmp_sd_service_config_cpsa_signal_type_sdh_values[];
-extern struct tok lmp_sd_service_config_cpsa_signal_type_sonet_values[];
+extern const struct tok gmpls_link_prot_values[];
+extern const struct tok gmpls_switch_cap_values[];
+extern const struct tok gmpls_switch_cap_tsc_indication_values[];
+extern const struct tok gmpls_encoding_values[];
+extern const struct tok gmpls_payload_values[];
+extern const struct tok diffserv_te_bc_values[];
+extern const struct tok lmp_sd_service_config_cpsa_link_type_values[];
+extern const struct tok lmp_sd_service_config_cpsa_signal_type_sdh_values[];
+extern const struct tok lmp_sd_service_config_cpsa_signal_type_sonet_values[];
index 17120c5..f7b3841 100644 (file)
@@ -18,7 +18,7 @@
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- * @(#) $Header: /tcpdump/master/tcpdump/gmt2local.h,v 1.2.1.1 1999-10-07 23:47:10 mcr Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/tcpdump/gmt2local.h,v 1.2 1999-10-07 23:47:10 mcr Exp $ (LBL)
  */
 #ifndef gmt2local_h
 #define gmt2local_h
index 5d27270..168a708 100644 (file)
@@ -276,7 +276,7 @@ struct nd_opt_hdr {         /* Neighbor discovery option header */
 #define ND_OPT_ADVINTERVAL             7
 #define ND_OPT_HOMEAGENT_INFO          8
 #define ND_OPT_ROUTE_INFO              9       /* draft-ietf-ipngwg-router-preference, not officially assigned yet */
-
+#define ND_OPT_RDNSS                   25
 
 struct nd_opt_prefix_info {    /* prefix information */
        u_int8_t        nd_opt_pi_type;
@@ -308,6 +308,14 @@ struct nd_opt_mtu {                /* MTU option */
        u_int32_t       nd_opt_mtu_mtu;
 };
 
+struct nd_opt_rdnss {          /* RDNSS RFC 5006 */
+       u_int8_t        nd_opt_rdnss_type;
+       u_int8_t        nd_opt_rdnss_len;
+       u_int16_t       nd_opt_rdnss_reserved;
+       u_int32_t       nd_opt_rdnss_lifetime;
+       struct in6_addr nd_opt_rdnss_addr[1];   /* variable-length */
+};
+
 struct nd_opt_advinterval {    /* Advertisement interval option */
        u_int8_t        nd_opt_adv_type;
        u_int8_t        nd_opt_adv_len;
index 3bcda7d..2aa1345 100644 (file)
@@ -30,6 +30,7 @@
 #define        IEEE802_11_RA_LEN               6
 #define        IEEE802_11_TA_LEN               6
 #define        IEEE802_11_SEQ_LEN              2
+#define        IEEE802_11_CTL_LEN              2
 #define        IEEE802_11_IV_LEN               3
 #define        IEEE802_11_KID_LEN              1
 
 #define        ST_DISASSOC             0xA
 #define        ST_AUTH                 0xB
 #define        ST_DEAUTH               0xC
-/* RESERVED                    0xD  */
+#define        ST_ACTION               0xD
 /* RESERVED                    0xE  */
 /* RESERVED                    0xF  */
 
 
+#define CTRL_CONTROL_WRAPPER   0x7
+#define        CTRL_BAR        0x8
+#define        CTRL_BA         0x9
 #define        CTRL_PS_POLL    0xA
 #define        CTRL_RTS        0xB
 #define        CTRL_CTS        0xC
@@ -140,12 +144,6 @@ struct mgmt_header_t {
 #define        CAPABILITY_CFP_REQ(cap) ((cap) & 0x0008)
 #define        CAPABILITY_PRIVACY(cap) ((cap) & 0x0010)
 
-typedef enum {
-       NOT_PRESENT,
-       PRESENT,
-       TRUNCATED
-} elem_status_t;
-
 struct ssid_t {
        u_int8_t        element_id;
        u_int8_t        length;
@@ -233,20 +231,20 @@ struct mgmt_body_t {
        u_int16_t       reason_code;
        u_int16_t       auth_alg;
        u_int16_t       auth_trans_seq_num;
-       elem_status_t   challenge_status;
+       int             challenge_present;
        struct challenge_t  challenge;
        u_int16_t       capability_info;
-       elem_status_t   ssid_status;
+       int             ssid_present;
        struct ssid_t   ssid;
-       elem_status_t   rates_status;
+       int             rates_present;
        struct rates_t  rates;
-       elem_status_t   ds_status;
+       int             ds_present;
        struct ds_t     ds;
-       elem_status_t   cf_status;
+       int             cf_present;
        struct cf_t     cf;
-       elem_status_t   fh_status;
+       int             fh_present;
        struct fh_t     fh;
-       elem_status_t   tim_status;
+       int             tim_present;
        struct tim_t    tim;
 };
 
@@ -312,6 +310,38 @@ struct ctrl_end_ack_t {
 #define        CTRL_END_ACK_HDRLEN     (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
                                 IEEE802_11_RA_LEN+IEEE802_11_BSSID_LEN)
 
+struct ctrl_ba_t {
+       u_int16_t       fc;
+       u_int16_t       duration;
+       u_int8_t        ra[6];
+       u_int8_t        fcs[4];
+};
+
+#define        CTRL_BA_HDRLEN  (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN)
+
+struct ctrl_bar_t {
+       u_int16_t       fc;
+       u_int16_t       dur;
+       u_int8_t        ra[6];
+       u_int8_t        ta[6];
+       u_int16_t       ctl;
+       u_int16_t       seq;
+       u_int8_t        fcs[4];
+};
+
+#define        CTRL_BAR_HDRLEN         (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
+                                IEEE802_11_RA_LEN+IEEE802_11_TA_LEN+\
+                                IEEE802_11_CTL_LEN+IEEE802_11_SEQ_LEN)
+
+struct meshcntl_t {
+       u_int8_t        flags;
+       u_int8_t        ttl;
+       u_int8_t        seq[4];
+       u_int8_t        addr4[6];
+       u_int8_t        addr5[6];
+       u_int8_t        addr6[6];
+};
+
 #define        IV_IV(iv)       ((iv) & 0xFFFFFF)
 #define        IV_PAD(iv)      (((iv) >> 24) & 0x3F)
 #define        IV_KEYID(iv)    (((iv) >> 30) & 0x03)
index 3f2b836..5aff137 100644 (file)
 #ifndef _NET_IF_IEEE80211RADIOTAP_H_
 #define _NET_IF_IEEE80211RADIOTAP_H_
 
-/* A generic radio capture format is desirable. There is one for
- * Linux, but it is neither rigidly defined (there were not even
- * units given for some fields) nor easily extensible.
+/* A generic radio capture format is desirable. It must be
+ * rigidly defined (e.g., units for fields should be given),
+ * and easily extensible.
  *
- * I suggest the following extensible radio capture format. It is
+ * The following is an extensible radio capture format. It is
  * based on a bitmap indicating which fields are present.
  *
  * I am trying to describe precisely what the application programmer
  * function of...") that I cannot set false expectations for lawyerly
  * readers.
  */
-#if defined(__KERNEL__) || defined(_KERNEL)
-#ifndef DLT_IEEE802_11_RADIO
-#define        DLT_IEEE802_11_RADIO    127     /* 802.11 plus WLAN header */
-#endif
-#endif /* defined(__KERNEL__) || defined(_KERNEL) */
 
-/* The radio capture header precedes the 802.11 header. */
+/*
+ * The radio capture header precedes the 802.11 header.
+ *
+ * Note well: all radiotap fields are little-endian.
+ */
 struct ieee80211_radiotap_header {
        u_int8_t        it_version;     /* Version 0. Only increases
                                         * for drastic changes,
@@ -73,7 +72,7 @@ struct ieee80211_radiotap_header {
                                         * Additional extensions are made
                                         * by setting bit 31.
                                         */
-} __attribute__((__packed__));
+};
 
 /* Name                                 Data type       Units
  * ----                                 ---------       -----
@@ -87,15 +86,19 @@ struct ieee80211_radiotap_header {
  * IEEE80211_RADIOTAP_CHANNEL           2 x u_int16_t   MHz, bitmap
  *
  *      Tx/Rx frequency in MHz, followed by flags (see below).
+ *     Note that IEEE80211_RADIOTAP_XCHANNEL must be used to
+ *     represent an HT channel as there is not enough room in
+ *     the flags word.
  *
  * IEEE80211_RADIOTAP_FHSS              u_int16_t       see below
  *
  *      For frequency-hopping radios, the hop set (first byte)
  *      and pattern (second byte).
  *
- * IEEE80211_RADIOTAP_RATE              u_int8_t        500kb/s
+ * IEEE80211_RADIOTAP_RATE              u_int8_t        500kb/s or index
  *
- *      Tx/Rx data rate
+ *      Tx/Rx data rate.  If bit 0x80 is set then it represents an
+ *     an MCS index and not an IEEE rate.
  *
  * IEEE80211_RADIOTAP_DBM_ANTSIGNAL     int8_t          decibels from
  *                                                      one milliwatt (dBm)
@@ -155,9 +158,39 @@ struct ieee80211_radiotap_header {
  *      Unitless indication of the Rx/Tx antenna for this packet.
  *      The first antenna is antenna 0.
  *
- * IEEE80211_RADIOTAP_FCS              u_int32_t       data
+ * IEEE80211_RADIOTAP_RX_FLAGS          u_int16_t       bitmap
+ *
+ *     Properties of received frames. See flags defined below.
+ *
+ * IEEE80211_RADIOTAP_XCHANNEL          u_int32_t      bitmap
+ *                                     u_int16_t       MHz
+ *                                     u_int8_t        channel number
+ *                                     u_int8_t        .5 dBm
+ *
+ *     Extended channel specification: flags (see below) followed by
+ *     frequency in MHz, the corresponding IEEE channel number, and
+ *     finally the maximum regulatory transmit power cap in .5 dBm
+ *     units.  This property supersedes IEEE80211_RADIOTAP_CHANNEL
+ *     and only one of the two should be present.
+ *
+ * IEEE80211_RADIOTAP_MCS              u_int8_t        known
+ *                                     u_int8_t        flags
+ *                                     u_int8_t        mcs
+ *
+ *     Bitset indicating which fields have known values, followed
+ *     by bitset of flag values, followed by the MCS rate index as
+ *     in IEEE 802.11n.
+ *
+ * IEEE80211_RADIOTAP_VENDOR_NAMESPACE
+ *                                     u_int8_t  OUI[3]
+ *                                   u_int8_t  subspace
+ *                                   u_int16_t length
+ *
+ *     The Vendor Namespace Field contains three sub-fields. The first
+ *     sub-field is 3 bytes long. It contains the vendor's IEEE 802
+ *     Organizationally Unique Identifier (OUI). The fourth byte is a
+ *     vendor-specific "namespace selector."
  *
- *     FCS from frame in network byte order.
  */
 enum ieee80211_radiotap_type {
        IEEE80211_RADIOTAP_TSFT = 0,
@@ -174,20 +207,44 @@ enum ieee80211_radiotap_type {
        IEEE80211_RADIOTAP_ANTENNA = 11,
        IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
        IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
+       IEEE80211_RADIOTAP_RX_FLAGS = 14,
+       /* NB: gap for netbsd definitions */
+       IEEE80211_RADIOTAP_XCHANNEL = 18,
+       IEEE80211_RADIOTAP_MCS = 19,
+       IEEE80211_RADIOTAP_NAMESPACE = 29,
+       IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30,
        IEEE80211_RADIOTAP_EXT = 31
 };
 
-#ifndef _KERNEL
-/* Channel flags. */
-#define        IEEE80211_CHAN_TURBO    0x0010  /* Turbo channel */
-#define        IEEE80211_CHAN_CCK      0x0020  /* CCK channel */
-#define        IEEE80211_CHAN_OFDM     0x0040  /* OFDM channel */
-#define        IEEE80211_CHAN_2GHZ     0x0080  /* 2 GHz spectrum channel. */
-#define        IEEE80211_CHAN_5GHZ     0x0100  /* 5 GHz spectrum channel */
-#define        IEEE80211_CHAN_PASSIVE  0x0200  /* Only passive scan allowed */
-#define        IEEE80211_CHAN_DYN      0x0400  /* Dynamic CCK-OFDM channel */
-#define        IEEE80211_CHAN_GFSK     0x0800  /* GFSK channel (FHSS PHY) */
-#endif /* !_KERNEL */
+/* channel attributes */
+#define        IEEE80211_CHAN_TURBO    0x00010 /* Turbo channel */
+#define        IEEE80211_CHAN_CCK      0x00020 /* CCK channel */
+#define        IEEE80211_CHAN_OFDM     0x00040 /* OFDM channel */
+#define        IEEE80211_CHAN_2GHZ     0x00080 /* 2 GHz spectrum channel. */
+#define        IEEE80211_CHAN_5GHZ     0x00100 /* 5 GHz spectrum channel */
+#define        IEEE80211_CHAN_PASSIVE  0x00200 /* Only passive scan allowed */
+#define        IEEE80211_CHAN_DYN      0x00400 /* Dynamic CCK-OFDM channel */
+#define        IEEE80211_CHAN_GFSK     0x00800 /* GFSK channel (FHSS PHY) */
+#define        IEEE80211_CHAN_GSM      0x01000 /* 900 MHz spectrum channel */
+#define        IEEE80211_CHAN_STURBO   0x02000 /* 11a static turbo channel only */
+#define        IEEE80211_CHAN_HALF     0x04000 /* Half rate channel */
+#define        IEEE80211_CHAN_QUARTER  0x08000 /* Quarter rate channel */
+#define        IEEE80211_CHAN_HT20     0x10000 /* HT 20 channel */
+#define        IEEE80211_CHAN_HT40U    0x20000 /* HT 40 channel w/ ext above */
+#define        IEEE80211_CHAN_HT40D    0x40000 /* HT 40 channel w/ ext below */
+
+/* Useful combinations of channel characteristics, borrowed from Ethereal */
+#define IEEE80211_CHAN_A \
+        (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
+#define IEEE80211_CHAN_B \
+        (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
+#define IEEE80211_CHAN_G \
+        (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
+#define IEEE80211_CHAN_TA \
+        (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO)
+#define IEEE80211_CHAN_TG \
+        (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN  | IEEE80211_CHAN_TURBO)
+
 
 /* For IEEE80211_RADIOTAP_FLAGS */
 #define        IEEE80211_RADIOTAP_F_CFP        0x01    /* sent/received
@@ -210,4 +267,25 @@ enum ieee80211_radiotap_type {
                                                 */
 #define        IEEE80211_RADIOTAP_F_BADFCS     0x40    /* does not pass FCS check */
 
+/* For IEEE80211_RADIOTAP_RX_FLAGS */
+#define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001  /* frame failed crc check */
+#define IEEE80211_RADIOTAP_F_RX_PLCP_CRC       0x0002  /* frame failed PLCP CRC check */
+
+/* For IEEE80211_RADIOTAP_MCS known */
+#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN         0x01
+#define IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN         0x02    /* MCS index field */
+#define IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN    0x04
+#define IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN         0x08
+#define IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN          0x10
+
+/* For IEEE80211_RADIOTAP_MCS flags */
+#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK  0x03
+#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20    0
+#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_40    1
+#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20L   2
+#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20U   3
+#define IEEE80211_RADIOTAP_MCS_SHORT_GI                0x04 /* short guard interval */
+#define IEEE80211_RADIOTAP_MCS_HT_GREENFIELD   0x08
+#define IEEE80211_RADIOTAP_MCS_FEC_LDPC                0x10
+
 #endif /* _NET_IF_IEEE80211RADIOTAP_H_ */
diff --git a/contrib/tcpdump/in_cksum.c b/contrib/tcpdump/in_cksum.c
new file mode 100644 (file)
index 0000000..93cdfc9
--- /dev/null
@@ -0,0 +1,200 @@
+/* in_cksum.c
+ * 4.4-Lite-2 Internet checksum routine, modified to take a vector of
+ * pointers/lengths giving the pieces to be checksummed.  Also using
+ * Tahoe/CGI version of ADDCARRY(x) macro instead of from portable version.
+ */
+
+/*
+ * Copyright (c) 1988, 1992, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)in_cksum.c  8.1 (Berkeley) 6/10/93
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include "interface.h"
+
+/*
+ * Checksum routine for Internet Protocol family headers (Portable Version).
+ *
+ * This routine is very heavily used in the network
+ * code and should be modified for each CPU to be as fast as possible.
+ */
+
+#define ADDCARRY(x)  {if ((x) > 65535) (x) -= 65535;}
+#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);}
+
+u_int16_t
+in_cksum(const struct cksum_vec *vec, int veclen)
+{
+       register const u_int16_t *w;
+       register int sum = 0;
+       register int mlen = 0;
+       int byte_swapped = 0;
+
+       union {
+               u_int8_t        c[2];
+               u_int16_t       s;
+       } s_util;
+       union {
+               u_int16_t       s[2];
+               u_int32_t       l;
+       } l_util;
+
+       for (; veclen != 0; vec++, veclen--) {
+               if (vec->len == 0)
+                       continue;
+               w = (const u_int16_t *)(void *)vec->ptr;
+               if (mlen == -1) {
+                       /*
+                        * The first byte of this chunk is the continuation
+                        * of a word spanning between this chunk and the
+                        * last chunk.
+                        *
+                        * s_util.c[0] is already saved when scanning previous
+                        * chunk.
+                        */
+                       s_util.c[1] = *(const u_int8_t *)w;
+                       sum += s_util.s;
+                       w = (const u_int16_t *)(void *)((const u_int8_t *)w + 1);
+                       mlen = vec->len - 1;
+               } else
+                       mlen = vec->len;
+               /*
+                * Force to even boundary.
+                */
+               if ((1 & (unsigned long) w) && (mlen > 0)) {
+                       REDUCE;
+                       sum <<= 8;
+                       s_util.c[0] = *(const u_int8_t *)w;
+                       w = (const u_int16_t *)(void *)((const u_int8_t *)w + 1);
+                       mlen--;
+                       byte_swapped = 1;
+               }
+               /*
+                * Unroll the loop to make overhead from
+                * branches &c small.
+                */
+               while ((mlen -= 32) >= 0) {
+                       sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
+                       sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
+                       sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11];
+                       sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15];
+                       w += 16;
+               }
+               mlen += 32;
+               while ((mlen -= 8) >= 0) {
+                       sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
+                       w += 4;
+               }
+               mlen += 8;
+               if (mlen == 0 && byte_swapped == 0)
+                       continue;
+               REDUCE;
+               while ((mlen -= 2) >= 0) {
+                       sum += *w++;
+               }
+               if (byte_swapped) {
+                       REDUCE;
+                       sum <<= 8;
+                       byte_swapped = 0;
+                       if (mlen == -1) {
+                               s_util.c[1] = *(const u_int8_t *)w;
+                               sum += s_util.s;
+                               mlen = 0;
+                       } else
+                               mlen = -1;
+               } else if (mlen == -1)
+                       s_util.c[0] = *(const u_int8_t *)w;
+       }
+       if (mlen == -1) {
+               /* The last mbuf has odd # of bytes. Follow the
+                  standard (the odd byte may be shifted left by 8 bits
+                  or not as determined by endian-ness of the machine) */
+               s_util.c[1] = 0;
+               sum += s_util.s;
+       }
+       REDUCE;
+       return (~sum & 0xffff);
+}
+
+/*
+ * Given the host-byte-order value of the checksum field in a packet
+ * header, and the network-byte-order computed checksum of the data
+ * that the checksum covers (including the checksum itself), compute
+ * what the checksum field *should* have been.
+ */
+u_int16_t
+in_cksum_shouldbe(u_int16_t sum, u_int16_t computed_sum)
+{
+       u_int32_t shouldbe;
+
+       /*
+        * The value that should have gone into the checksum field
+        * is the negative of the value gotten by summing up everything
+        * *but* the checksum field.
+        *
+        * We can compute that by subtracting the value of the checksum
+        * field from the sum of all the data in the packet, and then
+        * computing the negative of that value.
+        *
+        * "sum" is the value of the checksum field, and "computed_sum"
+        * is the negative of the sum of all the data in the packets,
+        * so that's -(-computed_sum - sum), or (sum + computed_sum).
+        *
+        * All the arithmetic in question is one's complement, so the
+        * addition must include an end-around carry; we do this by
+        * doing the arithmetic in 32 bits (with no sign-extension),
+        * and then adding the upper 16 bits of the sum, which contain
+        * the carry, to the lower 16 bits of the sum, and then do it
+        * again in case *that* sum produced a carry.
+        *
+        * As RFC 1071 notes, the checksum can be computed without
+        * byte-swapping the 16-bit words; summing 16-bit words
+        * on a big-endian machine gives a big-endian checksum, which
+        * can be directly stuffed into the big-endian checksum fields
+        * in protocol headers, and summing words on a little-endian
+        * machine gives a little-endian checksum, which must be
+        * byte-swapped before being stuffed into a big-endian checksum
+        * field.
+        *
+        * "computed_sum" is a network-byte-order value, so we must put
+        * it in host byte order before subtracting it from the
+        * host-byte-order value from the header; the adjusted checksum
+        * will be in host byte order, which is what we'll return.
+        */
+       shouldbe = sum;
+       shouldbe += ntohs(computed_sum);
+       shouldbe = (shouldbe & 0xFFFF) + (shouldbe >> 16);
+       shouldbe = (shouldbe & 0xFFFF) + (shouldbe >> 16);
+       return shouldbe;
+}
index 1f03123..18668a2 100644 (file)
@@ -18,7 +18,7 @@
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- * @(#) $Header: /tcpdump/master/tcpdump/interface.h,v 1.280.2.4 2008-04-04 19:42:52 guy Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/tcpdump/interface.h,v 1.285 2008-08-16 11:36:20 hannes Exp $ (LBL)
  */
 
 #ifndef tcpdump_interface_h
 #include "os-proto.h"
 #endif
 
-#ifndef HAVE___ATTRIBUTE__
-#define __attribute__(x)
-#endif
-
 /* snprintf et al */
 
 #include <stdarg.h>
@@ -74,6 +70,7 @@ extern char *strsep(char **, const char *);
 #define PT_CNFP                7       /* Cisco NetFlow protocol */
 #define PT_TFTP                8       /* trivial file transfer protocol */
 #define PT_AODV                9       /* Ad-hoc On-demand Distance Vector Protocol */
+#define PT_CARP         10      /* Common Address Redundancy Protocol */
 
 #ifndef min
 #define min(a,b) ((a)>(b)?(b):(a))
@@ -82,21 +79,6 @@ extern char *strsep(char **, const char *);
 #define max(a,b) ((b)>(a)?(b):(a))
 #endif
 
-/*
- * The default snapshot length.  This value allows most printers to print
- * useful information while keeping the amount of unwanted data down.
- */
-#ifndef INET6
-#define DEFAULT_SNAPLEN 68     /* ether + IPv4 + TCP + 14 */
-#else
-#define DEFAULT_SNAPLEN 96     /* ether + IPv6 + TCP + 22 */
-#endif
-
-#ifndef BIG_ENDIAN
-#define BIG_ENDIAN 4321
-#define LITTLE_ENDIAN 1234
-#endif
-
 #define ESRC(ep) ((ep)->ether_shost)
 #define EDST(ep) ((ep)->ether_dhost)
 
@@ -181,10 +163,9 @@ extern void hex_and_ascii_print(const char *, const u_char *, u_int);
 extern void hex_print_with_offset(const char *, const u_char *, u_int, u_int);
 extern void hex_print(const char *, const u_char *, u_int);
 extern void telnet_print(const u_char *, u_int);
-extern int ether_encap_print(u_short, const u_char *, u_int, u_int, u_short *);
 extern int llc_print(const u_char *, u_int, u_int, const u_char *,
        const u_char *, u_short *);
-extern int snap_print(const u_char *, u_int, u_int, u_short *, u_int);
+extern int snap_print(const u_char *, u_int, u_int, u_int);
 extern void aarp_print(const u_char *, u_int);
 extern void aodv_print(const u_char *, u_int, int);
 extern void atalk_print(const u_char *, u_int);
@@ -204,8 +185,6 @@ extern u_int enc_if_print(const struct pcap_pkthdr *, const u_char *);
 extern u_int pflog_if_print(const struct pcap_pkthdr *, const u_char *);
 extern u_int arcnet_if_print(const struct pcap_pkthdr *, const u_char *);
 extern u_int arcnet_linux_if_print(const struct pcap_pkthdr *, const u_char *);
-extern void ether_print(const u_char *, u_int, u_int);
-extern u_int ether_if_print(const struct pcap_pkthdr *, const u_char *);
 extern u_int token_print(const u_char *, u_int, u_int);
 extern u_int token_if_print(const struct pcap_pkthdr *, const u_char *);
 extern void fddi_print(const u_char *, u_int, u_int);
@@ -239,19 +218,20 @@ extern void ns_print(const u_char *, u_int, int);
 extern void ntp_print(const u_char *, u_int);
 extern u_int null_if_print(const struct pcap_pkthdr *, const u_char *);
 extern void ospf_print(const u_char *, u_int, const u_char *);
-extern void olsr_print (const u_char *, u_int);
+extern void olsr_print (const u_char *, u_int, int);
 extern void pimv1_print(const u_char *, u_int);
 extern void cisco_autorp_print(const u_char *, u_int);
 extern void rsvp_print(const u_char *, u_int);
 extern void ldp_print(const u_char *, u_int);
 extern void lldp_print(const u_char *, u_int);
+extern void rpki_rtr_print(const u_char *, u_int);
 extern void lmp_print(const u_char *, u_int);
 extern void lspping_print(const u_char *, u_int);
 extern void lwapp_control_print(const u_char *, u_int, int);
 extern void lwapp_data_print(const u_char *, u_int);
 extern void eigrp_print(const u_char *, u_int);
 extern void mobile_print(const u_char *, u_int);
-extern void pim_print(const u_char *, u_int);
+extern void pim_print(const u_char *, u_int, u_int);
 extern u_int pppoe_print(const u_char *, u_int);
 extern u_int ppp_print(register const u_char *, u_int);
 extern u_int ppp_if_print(const struct pcap_pkthdr *, const u_char *);
@@ -311,6 +291,7 @@ extern const char *nt_errstr(u_int32_t);
 extern void print_data(const unsigned char *, int);
 extern void l2tp_print(const u_char *, u_int);
 extern void vrrp_print(const u_char *, u_int, int);
+extern void carp_print(const u_char *, u_int, int);
 extern void slow_print(const u_char *, u_int);
 extern void sflow_print(const u_char *, u_int);
 extern void mpcp_print(const u_char *, u_int);
@@ -324,6 +305,7 @@ extern void lwres_print(const u_char *, u_int);
 extern void pptp_print(const u_char *);
 extern void dccp_print(const u_char *, const u_char *, u_int);
 extern void sctp_print(const u_char *, const u_char *, u_int);
+extern void forces_print(const u_char *, u_int);
 extern void mpls_print(const u_char *, u_int);
 extern void mpls_lsp_ping_print(const u_char *, u_int);
 extern void zephyr_print(const u_char *, int);
@@ -332,21 +314,29 @@ extern void bfd_print(const u_char *, u_int, u_int);
 extern void sip_print(const u_char *, u_int);
 extern void syslog_print(const u_char *, u_int);
 extern u_int bt_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int usb_linux_48_byte_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int usb_linux_64_byte_print(const struct pcap_pkthdr *, const u_char *);
+
 
 #ifdef INET6
-extern void ip6_print(const u_char *, u_int);
 extern void ip6_opt_print(const u_char *, int);
 extern int hbhopt_print(const u_char *);
 extern int dstopt_print(const u_char *);
 extern int frag6_print(const u_char *, const u_char *);
 extern int mobility_print(const u_char *, const u_char *);
-extern void icmp6_print(const u_char *, u_int, const u_char *, int);
 extern void ripng_print(const u_char *, unsigned int);
 extern int rt6_print(const u_char *, const u_char *);
 extern void ospf6_print(const u_char *, u_int);
 extern void dhcp6_print(const u_char *, u_int);
+extern void babel_print(const u_char *, u_int);
+extern int mask62plen(const u_char *);
 #endif /*INET6*/
-extern u_short in_cksum(const u_short *, register u_int, int);
+
+struct cksum_vec {
+       const u_int8_t  *ptr;
+       int             len;
+};
+extern u_int16_t in_cksum(const struct cksum_vec *, int);
 extern u_int16_t in_cksum_shouldbe(u_int16_t, u_int16_t);
 
 #ifndef HAVE_BPF_DUMP
@@ -363,8 +353,10 @@ extern void bpf_dump(const struct bpf_program *, int);
 #ifndef NETDISSECT_REWORKED
 extern netdissect_options *gndo;
 
+#define bflag gndo->ndo_bflag 
 #define eflag gndo->ndo_eflag 
 #define fflag gndo->ndo_fflag 
+#define jflag gndo->ndo_jflag
 #define Kflag gndo->ndo_Kflag 
 #define nflag gndo->ndo_nflag 
 #define Nflag gndo->ndo_Nflag 
@@ -387,12 +379,13 @@ extern netdissect_options *gndo;
 #define Iflag gndo->ndo_Iflag 
 #define suppress_default_print gndo->ndo_suppress_default_print
 #define packettype gndo->ndo_packettype
-#define tcpmd5secret gndo->ndo_tcpmd5secret
+#define sigsecret gndo->ndo_sigsecret
 #define Wflag gndo->ndo_Wflag
 #define WflagChars gndo->ndo_WflagChars
 #define Cflag_count gndo->ndo_Cflag_count
 #define Gflag_count gndo->ndo_Gflag_count
 #define Gflag_time gndo->ndo_Gflag_time 
+#define Hflag gndo->ndo_Hflag
 #define snaplen     gndo->ndo_snaplen
 #define snapend     gndo->ndo_snapend
 
index a01d0f0..8a97632 100644 (file)
@@ -62,7 +62,7 @@ struct ip {
        u_int8_t        ip_p;           /* protocol */
        u_int16_t       ip_sum;         /* checksum */
        struct  in_addr ip_src,ip_dst;  /* source and dest address */
-};
+} UNALIGNED;
 
 #define        IP_MAXPACKET    65535           /* maximum packet size */
 
@@ -134,7 +134,7 @@ struct      ip_timestamp {
                        u_int32_t ipt_time;
                } ipt_ta[1];
        } ipt_timestamp;
-};
+} UNALIGNED;
 
 /* flag bits for ipt_flg */
 #define        IPOPT_TS_TSONLY         0               /* timestamps only */
@@ -161,4 +161,4 @@ struct      ip_timestamp {
 #define        IP_MSS          576             /* default maximum segment size */
 
 /* in print-ip.c */
-extern u_int32_t ip_finddst(const struct ip *);
+extern int nextproto4_cksum(const struct ip *, const u_int8_t *, u_int, u_int);
index e4f9fe1..12c87ad 100644 (file)
@@ -86,7 +86,7 @@ struct ip6_hdr {
        } ip6_ctlun;
        struct in6_addr ip6_src;        /* source address */
        struct in6_addr ip6_dst;        /* destination address */
-};
+} UNALIGNED;
 
 #define ip6_vfc                ip6_ctlun.ip6_un2_vfc
 #define ip6_flow       ip6_ctlun.ip6_un1.ip6_un1_flow
@@ -109,25 +109,23 @@ struct ip6_hdr {
  */
 
 struct ip6_ext {
-       u_char  ip6e_nxt;
-       u_char  ip6e_len;
-};
+       u_int8_t ip6e_nxt;
+       u_int8_t ip6e_len;
+} UNALIGNED;
 
 /* Hop-by-Hop options header */
-/* XXX should we pad it to force alignment on an 8-byte boundary? */
 struct ip6_hbh {
        u_int8_t ip6h_nxt;      /* next header */
        u_int8_t ip6h_len;      /* length in units of 8 octets */
        /* followed by options */
-};
+} UNALIGNED;
 
 /* Destination options header */
-/* XXX should we pad it to force alignment on an 8-byte boundary? */
 struct ip6_dest {
        u_int8_t ip6d_nxt;      /* next header */
        u_int8_t ip6d_len;      /* length in units of 8 octets */
        /* followed by options */
-};
+} UNALIGNED;
 
 /* Option types and related macros */
 #define IP6OPT_PAD1            0x00    /* 00 0 00000 */
@@ -163,7 +161,7 @@ struct ip6_rthdr {
        u_int8_t  ip6r_type;    /* routing type */
        u_int8_t  ip6r_segleft; /* segments left */
        /* followed by routing type specific data */
-};
+} UNALIGNED;
 
 /* Type 0 Routing header */
 struct ip6_rthdr0 {
@@ -174,7 +172,7 @@ struct ip6_rthdr0 {
        u_int8_t  ip6r0_reserved;       /* reserved field */
        u_int8_t  ip6r0_slmap[3];       /* strict/loose bit map */
        struct in6_addr ip6r0_addr[1];  /* up to 23 addresses */
-};
+} UNALIGNED;
 
 /* Fragment header */
 struct ip6_frag {
@@ -182,10 +180,13 @@ struct ip6_frag {
        u_int8_t  ip6f_reserved;        /* reserved field */
        u_int16_t ip6f_offlg;           /* offset, reserved, and flag */
        u_int32_t ip6f_ident;           /* identification */
-};
+} UNALIGNED;
 
 #define IP6F_OFF_MASK          0xfff8  /* mask out offset from ip6f_offlg */
 #define IP6F_RESERVED_MASK     0x0006  /* reserved bits in ip6f_offlg */
 #define IP6F_MORE_FRAG         0x0001  /* more-fragments flag */
 
+/* in print-ip6.c */
+extern int nextproto6_cksum(const struct ip6_hdr *, const u_int8_t *, u_int, u_int);
+
 #endif /* not _NETINET_IP6_H_ */
diff --git a/contrib/tcpdump/ipnet.h b/contrib/tcpdump/ipnet.h
new file mode 100644 (file)
index 0000000..ae69284
--- /dev/null
@@ -0,0 +1,13 @@
+typedef struct ipnet_hdr {
+       uint8_t         iph_version;
+       uint8_t         iph_family;
+       uint16_t        iph_htype;
+       uint32_t        iph_pktlen;
+       uint32_t        iph_ifindex;
+       uint32_t        iph_grifindex;
+       uint32_t        iph_zsrc;
+       uint32_t        iph_zdst;
+} ipnet_hdr_t;
+
+#define        IPH_AF_INET     2               /* Matches Solaris's AF_INET */
+#define        IPH_AF_INET6    26              /* Matches Solaris's AF_INET6 */
index 7b89afb..cbb9bf3 100755 (executable)
@@ -27,7 +27,7 @@ static const char rcsid[] _U_ =
 #include "interface.h"
 #include "ipproto.h"
 
-struct tok ipproto_values[] = {
+const struct tok ipproto_values[] = {
     { IPPROTO_HOPOPTS, "Options" },
     { IPPROTO_ICMP, "ICMP" },
     { IPPROTO_IGMP, "IGMP" },
@@ -55,6 +55,7 @@ struct tok ipproto_values[] = {
     { IPPROTO_PGM, "PGM" },
     { IPPROTO_SCTP, "SCTP" },
     { IPPROTO_MOBILITY, "Mobility" },
+    { IPPROTO_CARP, "CARP" },
     { 0, NULL }
 };
 
index f525786..c9801a6 100644 (file)
@@ -37,7 +37,7 @@
  * $FreeBSD: src/sys/netinet/in.h,v 1.38.2.3 1999/08/29 16:29:34 peter Exp $
  */
 
-extern struct tok ipproto_values[];
+extern const struct tok ipproto_values[];
 
 #ifndef IPPROTO_IP
 #define        IPPROTO_IP              0               /* dummy for IP */
@@ -133,6 +133,9 @@ extern struct tok ipproto_values[];
 #ifndef IPPROTO_VRRP
 #define IPPROTO_VRRP           112
 #endif
+#ifndef IPPROTO_CARP
+#define IPPROTO_CARP           112
+#endif
 #ifndef IPPROTO_PGM
 #define IPPROTO_PGM             113
 #endif
index 85d383d..d628f7a 100644 (file)
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-/* YIPS @(#)$Id: isakmp.h,v 1.11 2007-08-29 02:38:14 mcr Exp $ */
+/* YIPS @(#)$Id: isakmp.h,v 1.12 2007-11-24 18:13:33 mcr Exp $ */
 
 /* refer to RFC 2408 */
 
@@ -127,6 +127,7 @@ struct isakmp {
 #define ISAKMP_NPTYPE_N     11 /* Notification */
 #define ISAKMP_NPTYPE_D     12 /* Delete */
 #define ISAKMP_NPTYPE_VID   13 /* Vendor ID */
+#define ISAKMP_NPTYPE_v2E   46 /* v2 Encrypted payload */
 
 #define IKEv1_MAJOR_VERSION  1
 #define IKEv1_MINOR_VERSION  0
@@ -422,14 +423,31 @@ struct ikev2_ke {
 };
 
 
+/* 3.5.  Identification Payloads */
+enum ikev2_id_type {
+       ID_IPV4_ADDR=1,
+       ID_FQDN=2,
+       ID_RFC822_ADDR=3,
+       ID_IPV6_ADDR=5,
+       ID_DER_ASN1_DN=9,
+       ID_DER_ASN1_GN=10,
+       ID_KEY_ID=11,
+};
+struct ikev2_id {
+       struct isakmp_gen h;
+       u_int8_t  type;        /* ID type */
+       u_int8_t  res1;
+       u_int16_t res2;
+       /* SPI */
+       /* Notification Data */
+};
+
 /* 3.10 Notification Payload */
 struct ikev2_n {
        struct isakmp_gen h;
        u_int8_t  prot_id;  /* Protocol-ID */
        u_int8_t  spi_size; /* SPI Size */
        u_int16_t type;     /* Notify Message Type */
-       /* SPI */
-       /* Notification Data */
 };
 
 enum ikev2_n_type {
index a822191..021e7f0 100755 (executable)
@@ -27,7 +27,7 @@ static const char rcsid[] _U_ =
 #include "l2vpn.h"
 
 /* draft-ietf-pwe3-iana-allocation-04 */
-struct tok l2vpn_encaps_values[] = {
+const struct tok l2vpn_encaps_values[] = {
     { 0x00, "Reserved"},
     { 0x01, "Frame Relay"},
     { 0x02, "ATM AAL5 VCC transport"},
index 766cda5..871eca0 100755 (executable)
@@ -14,4 +14,4 @@
  * Original code by Hannes Gredler (hannes@juniper.net)
  */
 
-extern struct tok l2vpn_encaps_values[];
+extern const struct tok l2vpn_encaps_values[];
diff --git a/contrib/tcpdump/makemib b/contrib/tcpdump/makemib
deleted file mode 100755 (executable)
index b59e2f1..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 1990, 1996
-#      John Robert LoVerso. All rights reserved.
-# SMIv2 parsing copyright (c) 1999
-#      William C. Fenner.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# 1. Redistributions of source code must retain the above copyright
-#    notices, this list of conditions and the following disclaimer.
-#
-# 2. Redistributions in binary form must reproduce the above copyright
-#    notices, this list of conditions and the following disclaimer in the
-#    documentation and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# @(#) $Id: makemib,v 1.3 2001-09-17 22:16:52 fenner Exp $ (jlv)
-
-#
-# This script will read either ASN.1-style MIB files or the ".defs" files
-# created by the ISODE "mosy" program on such files.
-#
-# The output of this script is the "mib.h" file used by tcpdumps' ASN.1/SNMP
-# decoding code.
-#
-# This script needs to be run by "gawk" (GNU awk).  "nawk" will work, but
-# dump will get a recursion error if you process LARGE mibs.  While it would
-# by farily easy to rewrite this not to use recursion (and also easy to
-# eliminate use of gsub and functions to use classic "awk"), you have to 
-# order the structure declarations in defined-first order for the compiler
-# not to barf; too bad tsort doesn't take arguments.
-#
-
-cat << EOF
-/*
- * This file was generated by tcpdump/makemib on `date`
- * You probably don't want to edit this by hand!
- *
- * struct mib somename = { desc, oid-octet, type, child-pointer, next-pointer 
-};
- */
-
-EOF
-
-awk '
-BEGIN {
-       debug=0;
-       # for sanity, we prep the namespace with objects from RFC-1155
-       # (we manually establish the root)
-       oid["iso"]=1
-       oidadd("org", "iso", 3)
-       oidadd("dod", "org", 6)
-       oidadd("internet", "dod", 1)
-       oidadd("directory", "internet", 1)
-       oidadd("mgmt", "internet", 2)
-#XXX   oidadd("mib", "mgmt", 1)
-       oidadd("mib-2", "mgmt", 1)
-       oidadd("experimental", "internet", 3)
-       oidadd("private", "internet", 4)
-       oidadd("enterprises", "private", 1)
-       oidadd("ip", "mib-2", 4)
-       oidadd("transmission", "mib-2", 10)
-
-       holddesc="none"
-}
-
-#
-# Read mosy "*.defs" file.  mosy does all the parsing work; we just read
-# its simple and straightforward output.  It would not be too hard to make
-# tcpdump directly read mosy output, but...
-#
-# Ignore these unless the current file is called something.defs; false
-# positives are too common in DESCRIPTIONs.
-
-NF > 1 && index($2,".")>0 && FILENAME ~ /\.defs/ {
-       # currently ignore items of the form "{ iso.3.6.1 }"
-       if (split($2, p, ".") == 2) {
-               oidadd($1, p[1], p[2])
-       }
-       next
-}
-
-#
-# Must be a MIB file
-# Make it easier to parse - used to be done by sed
-{ sub(/--\*.*\*--/, ""); sub(/--.*/, ""); gsub(/[{}]/, " & "); }
-
-#
-# this next section is simple and naive, but does the job ok
-#
-
-# foo OBJECT IDENTIFIER ::= { baz 17 }
-# or
-# foo OBJECT IDENTIFIER ::=
-# { baz 17 }
-$2$3$4 == "OBJECTIDENTIFIER::=" {
-       holddesc="none"
-       if (NF == 8)
-               oidadd($1, $6, $7)
-       if (NF == 4)
-               holddesc=$1
-       next
-}
-$1 == "{" && holddesc != "none" && NF == 4 {
-       oidadd(holddesc, $2, $3)
-       holddesc="none"
-}
-#
-# foo OBJECT IDENTIFIER
-#  ::= { bar 1 }
-$2$3 == "OBJECTIDENTIFIER" && $1 != "SYNTAX" && NF == 3 {
-       holddesc=$1
-}
-#
-# foo
-# OBJECT IDENTIFIER ::= { bar 1 }
-# a couple of heuristics to exclude single words in e.g. long
-#  DESCRIPTION clauses
-NF == 1 && $1 ~ "[a-z][a-z]*[A-Z]" && $1 !~ /[(){}.,]/ && holddesc == "none" {
-       holddesc=$1
-}
-$1$2$3 == "OBJECTIDENTIFIER::=" && holddesc != "none" {
-       oidadd(holddesc, $5, $6)
-       holddesc="none"
-}
-#
-# "normal" style
-# foo OBJECT-TYPE ...
-# ...
-#   ::= { baz 5 }
-$2 == "MODULE-IDENTITY" || $2 == "MODULE-COMPLIANCE" ||
-       $2 == "OBJECT-IDENTITY" || $2 == "OBJECT-TYPE" ||
-       $2 == "OBJECT-GROUP" ||
-       $2 == "NOTIFICATION-TYPE" || $2 == "NOTIFICATION-GROUP" {
-       holddesc=$1
-}
-$1 == "::=" && holddesc != "none" && NF == 5 {
-       oidadd(holddesc, $3, $4)
-       holddesc="none"
-}
-#
-# foo ::= { baz 17 }
-$2$3 == "::={" {
-       oidadd($1,$4,$5)
-       holddesc="none"
-}
-
-
-# 
-# End of the road - output the data.
-#
-
-END {
-       print "struct obj"
-       dump("iso")
-       print "*mibroot = &_iso_obj;"
-}
-
-function inn(file) {
-       if (file == "" || file == "-")
-               return ""
-       return " in " file
-}
-
-#
-# add a new object to the tree
-#
-#              new OBJECT IDENTIFIER ::= { parent value }
-#
-
-function oidadd(new, parent, value) {
-       # Ignore 0.0
-       if (parent == "0" && value == 0)
-               return
-       if (debug)
-               print "/* oidadd" inn(FILENAME) ":", new, "in", parent, "as", value, "line", $0, "*/"
-       # use safe C identifiers
-       gsub(/[-&\/]/,"",new)
-       gsub(/[-&\/]/,"",parent)
-       # check if parent missing
-       if (oid[parent] == "") {
-               printf "/* parse problem%s: no parent for %s.%s(%d) */\n", \
-                       inn(FILENAME), parent, new, value
-               return
-       }
-       # check if parent.value already exists
-       if (oid[new] > 0 && oid[new] != value) {
-               printf "/* parse problem%s: dup %s.%s(%d) != old (%d) */\n", \
-                       inn(FILENAME), parent, new, value, oid[new]
-               return
-       }
-       # check for new name for parent.value
-       if (child[parent] != "") {
-               for (sib = child[parent]; sib != ""; sib = sibling[sib])
-                       if (oid[sib] == value) {
-                               if (new != sib)
-                                       printf "/* parse problem%s: new name" \
-                                               " \"%s\"" \
-                                               " for %s.%s(%d) ignored */\n", \
-                                               inn(FILENAME), new, parent, \
-                                               sib, value
-                               return
-                       }
-       }
-
-       oid[new]=value
-       if (child[parent] == "") {
-               child[parent] = new
-       } else {
-               sibling[new] = child[parent]
-               child[parent] = new
-       }
-}
-
-#
-# old(?) routine to recurse down the tree (in postfix order for convenience)
-#
-
-function dump(item, c, s) {
-#      newitem=sofar"."item"("oid[item]")"
-#      printf "/* %s c=%s s=%s */\n", newitem, child[item], sibling[item]
-       c="NULL"
-       if (child[item] != "") {
-               dump(child[item])
-               c = "&_"child[item]"_obj"
-       }
-       s="NULL"
-       if (sibling[item] != "") {
-               dump(sibling[item])
-               s = "&_"sibling[item]"_obj"
-       }
-       printf "_%s_obj = {\n\t\"%s\", %d, 0,\n\t%s, %s\n},\n", \
-               item, item, oid[item], c, s
-}
-' $@
-exit 0
index cd6f2f1..0c66dfa 100644 (file)
@@ -21,7 +21,7 @@
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- * @(#) $Header: /tcpdump/master/tcpdump/netdissect.h,v 1.23.2.2 2008-04-04 19:42:52 guy Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/tcpdump/netdissect.h,v 1.27 2008-08-16 11:36:20 hannes Exp $ (LBL)
  */
 
 #ifndef netdissect_h
@@ -84,6 +84,7 @@ typedef struct netdissect_options netdissect_options;
 
 struct netdissect_options {
   int ndo_aflag;               /* translate network and broadcast addresses */
+  int ndo_bflag;               /* print 4 byte ASes in ASDOT notation */
   int ndo_eflag;               /* print ethernet header */
   int ndo_fflag;               /* don't translate "foreign" IP address */
   int ndo_Kflag;               /* don't check TCP checksums */
@@ -106,6 +107,7 @@ struct netdissect_options {
   int ndo_Iflag;               /* rfmon (monitor) mode */
   int ndo_Oflag;                /* run filter code optimizer */
   int ndo_dlt;                  /* if != -1, ask libpcap for the DLT it names*/
+  int ndo_jflag;                /* packet time stamp source */
   int ndo_pflag;                /* don't go promiscuous */
 
   int ndo_Cflag;                /* rotate dump files after this many bytes */ 
@@ -115,6 +117,7 @@ struct netdissect_options {
   time_t ndo_Gflag_time;    /* The last time_t the dump file was rotated. */
   int ndo_Wflag;          /* recycle output files after this number of files */
   int ndo_WflagChars;
+  int ndo_Hflag;               /* dissect 802.11s draft mesh standard */
   int ndo_suppress_default_print; /* don't use default_print() for unknown packet types */
   const char *ndo_dltname;
 
@@ -122,7 +125,7 @@ struct netdissect_options {
   struct sa_list *ndo_sa_list_head;  /* used by print-esp.c */
   struct sa_list *ndo_sa_default;
 
-  char *ndo_tcpmd5secret;      /* TCP-MD5 secret key */
+  char *ndo_sigsecret;         /* Signature verification secret key */
 
   struct esp_algorithm *ndo_espsecret_xform;   /* cache of decoded  */
   char                 *ndo_espsecret_key;
@@ -148,11 +151,23 @@ struct netdissect_options {
   void (*ndo_info)(netdissect_options *, int verbose);
 
   int  (*ndo_printf)(netdissect_options *,
-                    const char *fmt, ...);
+                    const char *fmt, ...)
+#ifdef __ATTRIBUTE___FORMAT_OK_FOR_FUNCTION_POINTERS
+                    __attribute__ ((format (printf, 2, 3)))
+#endif
+                    ;
   void (*ndo_error)(netdissect_options *,
-                   const char *fmt, ...);
+                   const char *fmt, ...)
+#ifdef __ATTRIBUTE___FORMAT_OK_FOR_FUNCTION_POINTERS
+                    __attribute__ ((noreturn, format (printf, 2, 3)))
+#endif
+                    ;
   void (*ndo_warning)(netdissect_options *,
-                     const char *fmt, ...);
+                     const char *fmt, ...)
+#ifdef __ATTRIBUTE___FORMAT_OK_FOR_FUNCTION_POINTERS
+                    __attribute__ ((format (printf, 2, 3)))
+#endif
+                    ;
 };
 
 #define PT_VAT         1       /* Visual Audio Tool */
@@ -170,22 +185,21 @@ struct netdissect_options {
 #define max(a,b) ((b)>(a)?(b):(a))
 #endif
 
-#ifndef INET6
 /*
- * The default snapshot length.  This value allows most printers to print
- * useful information while keeping the amount of unwanted data down.
- * In particular, it allows for an ethernet header, tcp/ip header, and
- * 14 bytes of data (assuming no ip options).
+ * Maximum snapshot length.  This should be enough to capture the full
+ * packet on most network interfaces.
+ *
+ * XXX - could it be larger?  If so, should it?  Some applications might
+ * use the snapshot length in a savefile header to control the size of
+ * the buffer they allocate, so a size of, say, 2^31-1 might not work
+ * well.
  */
-#define DEFAULT_SNAPLEN 68
-#else
-#define DEFAULT_SNAPLEN 96
-#endif
+#define MAXIMUM_SNAPLEN        65535
 
-#ifndef BIG_ENDIAN
-#define BIG_ENDIAN 4321
-#define LITTLE_ENDIAN 1234
-#endif
+/*
+ * The default snapshot length is the maximum.
+ */
+#define DEFAULT_SNAPLEN        MAXIMUM_SNAPLEN
 
 #define ESRC(ep) ((ep)->ether_shost)
 #define EDST(ep) ((ep)->ether_dhost)
@@ -240,6 +254,9 @@ extern char *copy_argv(netdissect_options *, char **);
 extern void safeputchar(int);
 extern void safeputs(const char *, int);
 
+#define PLURAL_SUFFIX(n) \
+       (((n) != 1) ? "s" : "")
+
 #if 0
 extern const char *isonsap_string(netdissect_options *, const u_char *);
 extern const char *protoid_string(netdissect_options *, const u_char *);
@@ -251,12 +268,20 @@ extern const char *dnnum_string(netdissect_options *, u_short);
 
 #include <pcap.h>
 
+typedef u_int (*if_ndo_printer)(struct netdissect_options *ndo,
+                               const struct pcap_pkthdr *, const u_char *);
+typedef u_int (*if_printer)(const struct pcap_pkthdr *, const u_char *);
+
+extern if_ndo_printer lookup_ndo_printer(int);
+extern if_printer lookup_printer(int);
 
 extern void eap_print(netdissect_options *,const u_char *, u_int);
 extern int esp_print(netdissect_options *,
                     register const u_char *bp, int len, register const u_char *bp2,
                     int *nhdr, int *padlen);
 extern void arp_print(netdissect_options *,const u_char *, u_int, u_int);
+extern void icmp6_print(netdissect_options *ndo, const u_char *,
+                        u_int, const u_char *, int);
 extern void isakmp_print(netdissect_options *,const u_char *,
                         u_int, const u_char *);
 extern void isakmp_rfc3948_print(netdissect_options *,const u_char *,
@@ -267,6 +292,22 @@ extern void ip_print_inner(netdissect_options *ndo,
                           const u_char *bp2);
 extern void rrcp_print(netdissect_options *,const u_char *, u_int);
 
+extern void ether_print(netdissect_options *,
+                        const u_char *, u_int, u_int,
+                        void (*)(netdissect_options *, const u_char *),
+                        const u_char *);
+
+extern u_int ether_if_print(netdissect_options *, 
+                            const struct pcap_pkthdr *,const u_char *);
+extern u_int netanalyzer_if_print(netdissect_options *, 
+                                  const struct pcap_pkthdr *,const u_char *);
+extern u_int netanalyzer_transparent_if_print(netdissect_options *, 
+                                              const struct pcap_pkthdr *,
+                                              const u_char *);
+
+extern int ethertype_print(netdissect_options *,u_short, const u_char *,
+                            u_int, u_int);
+
 /* stuff that has not yet been rototiled */
 #if 0
 extern void ascii_print(netdissect_options *,u_int);
@@ -277,8 +318,6 @@ extern void hex_print_with_offset(netdissect_options *,const char *,
                                  u_int, u_int);
 extern void hex_print(netdissect_options *,const char *, u_int);
 extern void telnet_print(netdissect_options *,const u_char *, u_int);
-extern int ether_encap_print(netdissect_options *,u_short, const u_char *,
-                            u_int, u_int, u_short *);
 extern int llc_print(netdissect_options *,
                     const u_char *, u_int, u_int, const u_char *,
                     const u_char *, u_short *);
@@ -305,7 +344,6 @@ extern void egp_print(netdissect_options *,const u_char *, u_int,
                      const u_char *);
 
 extern void arcnet_if_print(u_char*,const struct pcap_pkthdr *,const u_char *);
-extern void ether_if_print(u_char *,const struct pcap_pkthdr *,const u_char *);
 extern void token_if_print(u_char *,const struct pcap_pkthdr *,const u_char *);
 extern void fddi_if_print(u_char *,const struct pcap_pkthdr *, const u_char *);
 
@@ -319,6 +357,7 @@ extern void igmp_print(netdissect_options *,
                       register const u_char *, u_int);
 extern void igrp_print(netdissect_options *,const u_char *, u_int,
                       const u_char *);
+extern int nextproto4_cksum(const struct ip *, const u_int8_t *, u_int, u_int);
 extern void ipN_print(netdissect_options *,const u_char *, u_int);
 extern void ipx_print(netdissect_options *,const u_char *, u_int);
 extern void isoclns_print(netdissect_options *,const u_char *,
@@ -345,7 +384,7 @@ extern void ospf_print(netdissect_options *,const u_char *,
                       u_int, const u_char *);
 extern void pimv1_print(netdissect_options *,const u_char *, u_int);
 extern void mobile_print(netdissect_options *,const u_char *, u_int);
-extern void pim_print(netdissect_options *,const u_char *, u_int);
+extern void pim_print(netdissect_options *,const u_char *, u_int, u_int);
 extern void pppoe_if_print(u_char *,const struct pcap_pkthdr *, const u_char *);
 extern void pppoe_print(netdissect_options *,const u_char *, u_int);
 extern void ppp_print(netdissect_options *,
@@ -364,6 +403,7 @@ extern void raw_if_print(u_char *,
                         const struct pcap_pkthdr *, const u_char *);
 
 extern void rip_print(netdissect_options *,const u_char *, u_int);
+extern void rpki_rtr_print(netdissect_options *,const u_char *, u_int);
 
 extern void sctp_print(netdissect_options *ndo,
                       const u_char *bp, const u_char *bp2,       
@@ -410,16 +450,26 @@ extern void l2tp_print(netdissect_options *,const u_char *, u_int);
 extern void lcp_print(netdissect_options *,const u_char *, u_int);
 extern void vrrp_print(netdissect_options *,const u_char *bp,
                       u_int len, int ttl);
+extern void carp_print(netdissect_options *,const u_char *bp,
+                      u_int len, int ttl);
 extern void cdp_print(netdissect_options *,const u_char *,
                      u_int, u_int, const u_char *, const u_char *);
 extern void stp_print(netdissect_options *,const u_char *p, u_int length);
 extern void radius_print(netdissect_options *,const u_char *, u_int);
 extern void lwres_print(netdissect_options *,const u_char *, u_int);
 extern void pptp_print(netdissect_options *,const u_char *, u_int);
+#endif
+
+extern u_int ipnet_if_print(netdissect_options *,const struct pcap_pkthdr *, const u_char *);
+extern u_int ppi_if_print(netdissect_options *,const struct pcap_pkthdr *, const u_char *);
+
+extern u_int ieee802_15_4_if_print(netdissect_options *,const struct pcap_pkthdr *, const u_char *);
 
 #ifdef INET6
 extern void ip6_print(netdissect_options *,const u_char *, u_int);
+#if 0
 extern void ip6_opt_print(netdissect_options *,const u_char *, int);
+extern int nextproto6_cksum(const struct ip6_hdr *, const u_int8_t *, u_int, u_int);
 extern int hbhopt_print(netdissect_options *,const u_char *);
 extern int dstopt_print(netdissect_options *,const u_char *);
 extern int frag6_print(netdissect_options *,const u_char *,
@@ -434,11 +484,24 @@ extern void dhcp6_print(netdissect_options *,const u_char *,
 
 extern void zephyr_print(netdissect_options * ndo,
                         const u_char *cp, int length);
+#endif /* 0 */
 
 #endif /*INET6*/
-extern u_short in_cksum(const u_short *,
-                       register u_int, int);
 
+#if 0
+struct cksum_vec {
+       const u_int8_t  *ptr;
+       int             len;
+};
+extern u_int16_t in_cksum(const struct cksum_vec *, int);
+extern u_int16_t in_cksum_shouldbe(u_int16_t, u_int16_t);
 #endif
 
+extern void esp_print_decodesecret(netdissect_options *ndo);
+extern int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo,
+                                            int initiator,
+                                            u_char spii[8], u_char spir[8],
+                                            u_char *buf, u_char *end);
+
+
 #endif  /* netdissect_h */
index bf6c983..a5b5025 100644 (file)
@@ -1,4 +1,4 @@
-/* @(#) $Header: /tcpdump/master/tcpdump/nfs.h,v 1.8.2.1 2007-11-18 03:24:55 guy Exp $ (LBL) */
+/* @(#) $Header: /tcpdump/master/tcpdump/nfs.h,v 1.9 2007-11-18 03:24:38 guy Exp $ (LBL) */
 /*     NetBSD: nfs.h,v 1.1 1996/05/23 22:49:53 fvdl Exp        */
 
 /*
 #define NFSV3ACCESS_EXTEND             0x08
 #define NFSV3ACCESS_DELETE             0x10
 #define NFSV3ACCESS_EXECUTE            0x20
+#define NFSV3ACCESS_FULL               0x3f
 
 #define NFSV3WRITE_UNSTABLE            0
 #define NFSV3WRITE_DATASYNC            1
index 47ebb53..64a359b 100755 (executable)
@@ -26,7 +26,7 @@ static const char rcsid[] _U_ =
 #include "interface.h"
 #include "nlpid.h"
 
-struct tok nlpid_values[] = {
+const struct tok nlpid_values[] = {
     { NLPID_NULLNS, "NULL" },
     { NLPID_Q933, "Q.933" },
     { NLPID_LMI, "LMI" },
index 31f6b66..8931835 100644 (file)
@@ -14,7 +14,7 @@
  * Original code by Hannes Gredler (hannes@juniper.net)
  */
 
-extern struct tok nlpid_values[];
+extern const struct tok nlpid_values[];
 
 #define        NLPID_NULLNS    0x00
 #define NLPID_Q933      0x08 /* ANSI T1.617 Annex D or ITU-T Q.933 Annex A */
index 2b1c6ee..b86458b 100644 (file)
@@ -324,5 +324,5 @@ struct ospfhdr {
 #define        ospf_lsa        ospf_un.un_lsa
 
 /* Functions shared by ospf and ospf6 */
-extern int ospf_print_te_lsa(u_int8_t *, u_int);
-extern int ospf_print_grace_lsa(u_int8_t *, u_int);
+extern int ospf_print_te_lsa(const u_int8_t *, u_int);
+extern int ospf_print_grace_lsa(const u_int8_t *, u_int);
index e6569d4..1067aa1 100644 (file)
@@ -15,7 +15,7 @@
 
 #ifndef lint
 static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/tcpdump/oui.c,v 1.8.2.1 2008-01-09 09:44:39 hannes Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/oui.c,v 1.9 2008-01-09 09:40:47 hannes Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -28,7 +28,7 @@ static const char rcsid[] _U_ =
 
 /* FIXME complete OUI list using a script */
 
-struct tok oui_values[] = {
+const struct tok oui_values[] = {
     { OUI_ENCAP_ETHER, "Ethernet" },
     { OUI_CISCO, "Cisco" },
     { OUI_NORTEL, "Nortel Networks SONMP" },
@@ -42,6 +42,7 @@ struct tok oui_values[] = {
     { OUI_IEEE_8021_PRIVATE, "IEEE 802.1 Private"},
     { OUI_IEEE_8023_PRIVATE, "IEEE 802.3 Private"},
     { OUI_TIA, "ANSI/TIA"},
+    { OUI_DCBX, "DCBX"},
     { 0, NULL }
 };
 
@@ -55,7 +56,7 @@ struct tok oui_values[] = {
  *
  * List taken from Ethereal's epan/sminmpec.c.
  */
-struct tok smi_values[] = {
+const struct tok smi_values[] = {
     { SMI_IETF,                 "IETF (reserved)"},
     { SMI_ACC,                  "ACC"},
     { SMI_CISCO,                "Cisco"},
index e70f82a..d39cb6c 100644 (file)
@@ -1,4 +1,4 @@
-/* @(#) $Header: /tcpdump/master/tcpdump/oui.h,v 1.7.2.1 2008-01-09 09:44:39 hannes Exp $ (LBL) */
+/* @(#) $Header: /tcpdump/master/tcpdump/oui.h,v 1.8 2008-01-09 09:40:47 hannes Exp $ (LBL) */
 /* 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that: (1) source code
@@ -14,8 +14,8 @@
  * Original code by Hannes Gredler (hannes@juniper.net)
  */
 
-extern struct tok oui_values[];
-extern struct tok smi_values[];
+extern const struct tok oui_values[];
+extern const struct tok smi_values[];
 
 #define OUI_ENCAP_ETHER 0x000000        /* encapsulated Ethernet */
 #define OUI_CISCO       0x00000c        /* Cisco protocols */
@@ -30,6 +30,7 @@ extern struct tok smi_values[];
 #define OUI_IEEE_8021_PRIVATE 0x0080c2      /* IEEE 802.1 Organisation Specific - Annex F */
 #define OUI_IEEE_8023_PRIVATE 0x00120f      /* IEEE 802.3 Organisation Specific - Annex G */
 #define OUI_TIA         0x0012bb        /* TIA - Telecommunications Industry Association - ANSI/TIA-1057- 2006 */
+#define OUI_DCBX        0x001B21        /* DCBX */
 
 /*
  * These are SMI Network Management Private Enterprise Codes for
diff --git a/contrib/tcpdump/pcap_dump_ftell.c b/contrib/tcpdump/pcap_dump_ftell.c
deleted file mode 100644 (file)
index 6eb3a4a..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 1993, 1994, 1995, 1996, 1997
- *     The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the University of California,
- * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
- * the University nor the names of its contributors may be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef lint
-static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/tcpdump/pcap_dump_ftell.c,v 1.1 2005-06-03 22:08:52 guy Exp $ (LBL)";
-#endif
-
-#include <stdio.h>
-#include <pcap.h>
-
-#include "pcap-missing.h"
-
-long
-pcap_dump_ftell(pcap_dumper_t *p)
-{
-       return (ftell((FILE *)p));
-}
diff --git a/contrib/tcpdump/ppi.h b/contrib/tcpdump/ppi.h
new file mode 100644 (file)
index 0000000..733eb95
--- /dev/null
@@ -0,0 +1,9 @@
+typedef struct ppi_header {
+       uint8_t         ppi_ver;
+       uint8_t         ppi_flags;
+       uint16_t        ppi_len;
+       uint32_t        ppi_dlt;
+} ppi_header_t;
+
+#define        PPI_HDRLEN      8
+
index 835d21b..24ab625 100644 (file)
@@ -22,7 +22,7 @@
 
 #ifndef lint
 static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-802_11.c,v 1.47.2.2 2007-12-29 23:25:28 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-802_11.c,v 1.49 2007-12-29 23:25:02 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -46,94 +46,593 @@ static const char rcsid[] _U_ =
 #include "ieee802_11.h"
 #include "ieee802_11_radio.h"
 
+/* Radiotap state */
+/*  This is used to save state when parsing/processing parameters */
+struct radiotap_state
+{
+       u_int32_t       present;
+
+       u_int8_t        rate;
+};
+
 #define PRINT_SSID(p) \
-       switch (p.ssid_status) { \
-       case TRUNCATED: \
-               return 0; \
-       case PRESENT: \
+       if (p.ssid_present) { \
                printf(" ("); \
                fn_print(p.ssid.ssid, NULL); \
                printf(")"); \
-               break; \
-       case NOT_PRESENT: \
-               break; \
        }
 
 #define PRINT_RATE(_sep, _r, _suf) \
        printf("%s%2.1f%s", _sep, (.5 * ((_r) & 0x7f)), _suf)
 #define PRINT_RATES(p) \
-       switch (p.rates_status) { \
-       case TRUNCATED: \
-               return 0; \
-       case PRESENT: \
-               do { \
-                       int z; \
-                       const char *sep = " ["; \
-                       for (z = 0; z < p.rates.length ; z++) { \
-                               PRINT_RATE(sep, p.rates.rate[z], \
-                                       (p.rates.rate[z] & 0x80 ? "*" : "")); \
-                               sep = " "; \
-                       } \
-                       if (p.rates.length != 0) \
-                               printf(" Mbit]"); \
-               } while (0); \
-               break; \
-       case NOT_PRESENT: \
-               break; \
+       if (p.rates_present) { \
+               int z; \
+               const char *sep = " ["; \
+               for (z = 0; z < p.rates.length ; z++) { \
+                       PRINT_RATE(sep, p.rates.rate[z], \
+                               (p.rates.rate[z] & 0x80 ? "*" : "")); \
+                       sep = " "; \
+               } \
+               if (p.rates.length != 0) \
+                       printf(" Mbit]"); \
        }
 
 #define PRINT_DS_CHANNEL(p) \
-       switch (p.ds_status) { \
-       case TRUNCATED: \
-               return 0; \
-       case PRESENT: \
+       if (p.ds_present) \
                printf(" CH: %u", p.ds.channel); \
-               break; \
-       case NOT_PRESENT: \
-               break; \
-       } \
        printf("%s", \
            CAPABILITY_PRIVACY(p.capability_info) ? ", PRIVACY" : "" );
 
+#define MAX_MCS_INDEX  76
+
+/*
+ * Indices are:
+ *
+ *     the MCS index (0-76);
+ *
+ *     0 for 20 MHz, 1 for 40 MHz;
+ *
+ *     0 for a long guard interval, 1 for a short guard interval.
+ */
+static const float ieee80211_float_htrates[MAX_MCS_INDEX+1][2][2] = {
+       /* MCS  0  */
+       {       /* 20 Mhz */ {    6.5,          /* SGI */    7.2, },
+               /* 40 Mhz */ {   13.5,          /* SGI */   15.0, },
+       },
+
+       /* MCS  1  */
+       {       /* 20 Mhz */ {   13.0,          /* SGI */   14.4, },
+               /* 40 Mhz */ {   27.0,          /* SGI */   30.0, },
+       },
+
+       /* MCS  2  */
+       {       /* 20 Mhz */ {   19.5,          /* SGI */   21.7, },
+               /* 40 Mhz */ {   40.5,          /* SGI */   45.0, },
+       },
+
+       /* MCS  3  */
+       {       /* 20 Mhz */ {   26.0,          /* SGI */   28.9, },
+               /* 40 Mhz */ {   54.0,          /* SGI */   60.0, },
+       },
+
+       /* MCS  4  */
+       {       /* 20 Mhz */ {   39.0,          /* SGI */   43.3, },
+               /* 40 Mhz */ {   81.0,          /* SGI */   90.0, },
+       },
+
+       /* MCS  5  */
+       {       /* 20 Mhz */ {   52.0,          /* SGI */   57.8, },
+               /* 40 Mhz */ {  108.0,          /* SGI */  120.0, },
+       },
+
+       /* MCS  6  */
+       {       /* 20 Mhz */ {   58.5,          /* SGI */   65.0, },
+               /* 40 Mhz */ {  121.5,          /* SGI */  135.0, },
+       },
+
+       /* MCS  7  */
+       {       /* 20 Mhz */ {   65.0,          /* SGI */   72.2, },
+               /* 40 Mhz */ {   135.0,         /* SGI */  150.0, },
+       },
+
+       /* MCS  8  */
+       {       /* 20 Mhz */ {   13.0,          /* SGI */   14.4, },
+               /* 40 Mhz */ {   27.0,          /* SGI */   30.0, },
+       },
+
+       /* MCS  9  */
+       {       /* 20 Mhz */ {   26.0,          /* SGI */   28.9, },
+               /* 40 Mhz */ {   54.0,          /* SGI */   60.0, },
+       },
+
+       /* MCS 10  */
+       {       /* 20 Mhz */ {   39.0,          /* SGI */   43.3, },
+               /* 40 Mhz */ {   81.0,          /* SGI */   90.0, },
+       },
+
+       /* MCS 11  */
+       {       /* 20 Mhz */ {   52.0,          /* SGI */   57.8, },
+               /* 40 Mhz */ {  108.0,          /* SGI */  120.0, },
+       },
+
+       /* MCS 12  */
+       {       /* 20 Mhz */ {   78.0,          /* SGI */   86.7, },
+               /* 40 Mhz */ {  162.0,          /* SGI */  180.0, },
+       },
+
+       /* MCS 13  */
+       {       /* 20 Mhz */ {  104.0,          /* SGI */  115.6, },
+               /* 40 Mhz */ {  216.0,          /* SGI */  240.0, },
+       },
+
+       /* MCS 14  */
+       {       /* 20 Mhz */ {  117.0,          /* SGI */  130.0, },
+               /* 40 Mhz */ {  243.0,          /* SGI */  270.0, },
+       },
+
+       /* MCS 15  */
+       {       /* 20 Mhz */ {  130.0,          /* SGI */  144.4, },
+               /* 40 Mhz */ {  270.0,          /* SGI */  300.0, },
+       },
+
+       /* MCS 16  */
+       {       /* 20 Mhz */ {   19.5,          /* SGI */   21.7, },
+               /* 40 Mhz */ {   40.5,          /* SGI */   45.0, },
+       },
+
+       /* MCS 17  */
+       {       /* 20 Mhz */ {   39.0,          /* SGI */   43.3, },
+               /* 40 Mhz */ {   81.0,          /* SGI */   90.0, },
+       },
+
+       /* MCS 18  */
+       {       /* 20 Mhz */ {   58.5,          /* SGI */   65.0, },
+               /* 40 Mhz */ {  121.5,          /* SGI */  135.0, },
+       },
+
+       /* MCS 19  */
+       {       /* 20 Mhz */ {   78.0,          /* SGI */   86.7, },
+               /* 40 Mhz */ {  162.0,          /* SGI */  180.0, },
+       },
+
+       /* MCS 20  */
+       {       /* 20 Mhz */ {  117.0,          /* SGI */  130.0, },
+               /* 40 Mhz */ {  243.0,          /* SGI */  270.0, },
+       },
+
+       /* MCS 21  */
+       {       /* 20 Mhz */ {  156.0,          /* SGI */  173.3, },
+               /* 40 Mhz */ {  324.0,          /* SGI */  360.0, },
+       },
+
+       /* MCS 22  */
+       {       /* 20 Mhz */ {  175.5,          /* SGI */  195.0, },
+               /* 40 Mhz */ {  364.5,          /* SGI */  405.0, },
+       },
+
+       /* MCS 23  */
+       {       /* 20 Mhz */ {  195.0,          /* SGI */  216.7, },
+               /* 40 Mhz */ {  405.0,          /* SGI */  450.0, },
+       },
+
+       /* MCS 24  */
+       {       /* 20 Mhz */ {   26.0,          /* SGI */   28.9, },
+               /* 40 Mhz */ {   54.0,          /* SGI */   60.0, },
+       },
+
+       /* MCS 25  */
+       {       /* 20 Mhz */ {   52.0,          /* SGI */   57.8, },
+               /* 40 Mhz */ {  108.0,          /* SGI */  120.0, },
+       },
+
+       /* MCS 26  */
+       {       /* 20 Mhz */ {   78.0,          /* SGI */   86.7, },
+               /* 40 Mhz */ {  162.0,          /* SGI */  180.0, },
+       },
+
+       /* MCS 27  */
+       {       /* 20 Mhz */ {  104.0,          /* SGI */  115.6, },
+               /* 40 Mhz */ {  216.0,          /* SGI */  240.0, },
+       },
+
+       /* MCS 28  */
+       {       /* 20 Mhz */ {  156.0,          /* SGI */  173.3, },
+               /* 40 Mhz */ {  324.0,          /* SGI */  360.0, },
+       },
+
+       /* MCS 29  */
+       {       /* 20 Mhz */ {  208.0,          /* SGI */  231.1, },
+               /* 40 Mhz */ {  432.0,          /* SGI */  480.0, },
+       },
+
+       /* MCS 30  */
+       {       /* 20 Mhz */ {  234.0,          /* SGI */  260.0, },
+               /* 40 Mhz */ {  486.0,          /* SGI */  540.0, },
+       },
+
+       /* MCS 31  */
+       {       /* 20 Mhz */ {  260.0,          /* SGI */  288.9, },
+               /* 40 Mhz */ {  540.0,          /* SGI */  600.0, },
+       },
+
+       /* MCS 32  */
+       {       /* 20 Mhz */ {    0.0,          /* SGI */    0.0, }, /* not valid */
+               /* 40 Mhz */ {    6.0,          /* SGI */    6.7, },
+       },
+
+       /* MCS 33  */
+       {       /* 20 Mhz */ {   39.0,          /* SGI */   43.3, },
+               /* 40 Mhz */ {   81.0,          /* SGI */   90.0, },
+       },
+
+       /* MCS 34  */
+       {       /* 20 Mhz */ {   52.0,          /* SGI */   57.8, },
+               /* 40 Mhz */ {  108.0,          /* SGI */  120.0, },
+       },
+
+       /* MCS 35  */
+       {       /* 20 Mhz */ {   65.0,          /* SGI */   72.2, },
+               /* 40 Mhz */ {  135.0,          /* SGI */  150.0, },
+       },
+
+       /* MCS 36  */
+       {       /* 20 Mhz */ {   58.5,          /* SGI */   65.0, },
+               /* 40 Mhz */ {  121.5,          /* SGI */  135.0, },
+       },
+
+       /* MCS 37  */
+       {       /* 20 Mhz */ {   78.0,          /* SGI */   86.7, },
+               /* 40 Mhz */ {  162.0,          /* SGI */  180.0, },
+       },
+
+       /* MCS 38  */
+       {       /* 20 Mhz */ {   97.5,          /* SGI */  108.3, },
+               /* 40 Mhz */ {  202.5,          /* SGI */  225.0, },
+       },
+
+       /* MCS 39  */
+       {       /* 20 Mhz */ {   52.0,          /* SGI */   57.8, },
+               /* 40 Mhz */ {  108.0,          /* SGI */  120.0, },
+       },
+
+       /* MCS 40  */
+       {       /* 20 Mhz */ {   65.0,          /* SGI */   72.2, },
+               /* 40 Mhz */ {  135.0,          /* SGI */  150.0, },
+       },
+
+       /* MCS 41  */
+       {       /* 20 Mhz */ {   65.0,          /* SGI */   72.2, },
+               /* 40 Mhz */ {  135.0,          /* SGI */  150.0, },
+       },
+
+       /* MCS 42  */
+       {       /* 20 Mhz */ {   78.0,          /* SGI */   86.7, },
+               /* 40 Mhz */ {  162.0,          /* SGI */  180.0, },
+       },
+
+       /* MCS 43  */
+       {       /* 20 Mhz */ {   91.0,          /* SGI */  101.1, },
+               /* 40 Mhz */ {  189.0,          /* SGI */  210.0, },
+       },
+
+       /* MCS 44  */
+       {       /* 20 Mhz */ {   91.0,          /* SGI */  101.1, },
+               /* 40 Mhz */ {  189.0,          /* SGI */  210.0, },
+       },
+
+       /* MCS 45  */
+       {       /* 20 Mhz */ {  104.0,          /* SGI */  115.6, },
+               /* 40 Mhz */ {  216.0,          /* SGI */  240.0, },
+       },
+
+       /* MCS 46  */
+       {       /* 20 Mhz */ {   78.0,          /* SGI */   86.7, },
+               /* 40 Mhz */ {  162.0,          /* SGI */  180.0, },
+       },
+
+       /* MCS 47  */
+       {       /* 20 Mhz */ {   97.5,          /* SGI */  108.3, },
+               /* 40 Mhz */ {  202.5,          /* SGI */  225.0, },
+       },
+
+       /* MCS 48  */
+       {       /* 20 Mhz */ {   97.5,          /* SGI */  108.3, },
+               /* 40 Mhz */ {  202.5,          /* SGI */  225.0, },
+       },
+
+       /* MCS 49  */
+       {       /* 20 Mhz */ {  117.0,          /* SGI */  130.0, },
+               /* 40 Mhz */ {  243.0,          /* SGI */  270.0, },
+       },
+
+       /* MCS 50  */
+       {       /* 20 Mhz */ {  136.5,          /* SGI */  151.7, },
+               /* 40 Mhz */ {  283.5,          /* SGI */  315.0, },
+       },
+
+       /* MCS 51  */
+       {       /* 20 Mhz */ {  136.5,          /* SGI */  151.7, },
+               /* 40 Mhz */ {  283.5,          /* SGI */  315.0, },
+       },
+
+       /* MCS 52  */
+       {       /* 20 Mhz */ {  156.0,          /* SGI */  173.3, },
+               /* 40 Mhz */ {  324.0,          /* SGI */  360.0, },
+       },
+
+       /* MCS 53  */
+       {       /* 20 Mhz */ {   65.0,          /* SGI */   72.2, },
+               /* 40 Mhz */ {  135.0,          /* SGI */  150.0, },
+       },
+
+       /* MCS 54  */
+       {       /* 20 Mhz */ {   78.0,          /* SGI */   86.7, },
+               /* 40 Mhz */ {  162.0,          /* SGI */  180.0, },
+       },
+
+       /* MCS 55  */
+       {       /* 20 Mhz */ {   91.0,          /* SGI */  101.1, },
+               /* 40 Mhz */ {  189.0,          /* SGI */  210.0, },
+       },
+
+       /* MCS 56  */
+       {       /* 20 Mhz */ {   78.0,          /* SGI */   86.7, },
+               /* 40 Mhz */ {  162.0,          /* SGI */  180.0, },
+       },
+
+       /* MCS 57  */
+       {       /* 20 Mhz */ {   91.0,          /* SGI */  101.1, },
+               /* 40 Mhz */ {  189.0,          /* SGI */  210.0, },
+       },
+
+       /* MCS 58  */
+       {       /* 20 Mhz */ {  104.0,          /* SGI */  115.6, },
+               /* 40 Mhz */ {  216.0,          /* SGI */  240.0, },
+       },
+
+       /* MCS 59  */
+       {       /* 20 Mhz */ {  117.0,          /* SGI */  130.0, },
+               /* 40 Mhz */ {  243.0,          /* SGI */  270.0, },
+       },
+
+       /* MCS 60  */
+       {       /* 20 Mhz */ {  104.0,          /* SGI */  115.6, },
+               /* 40 Mhz */ {  216.0,          /* SGI */  240.0, },
+       },
+
+       /* MCS 61  */
+       {       /* 20 Mhz */ {  117.0,          /* SGI */  130.0, },
+               /* 40 Mhz */ {  243.0,          /* SGI */  270.0, },
+       },
+
+       /* MCS 62  */
+       {       /* 20 Mhz */ {  130.0,          /* SGI */  144.4, },
+               /* 40 Mhz */ {  270.0,          /* SGI */  300.0, },
+       },
+
+       /* MCS 63  */
+       {       /* 20 Mhz */ {  130.0,          /* SGI */  144.4, },
+               /* 40 Mhz */ {  270.0,          /* SGI */  300.0, },
+       },
+
+       /* MCS 64  */
+       {       /* 20 Mhz */ {  143.0,          /* SGI */  158.9, },
+               /* 40 Mhz */ {  297.0,          /* SGI */  330.0, },
+       },
+
+       /* MCS 65  */
+       {       /* 20 Mhz */ {   97.5,          /* SGI */  108.3, },
+               /* 40 Mhz */ {  202.5,          /* SGI */  225.0, },
+       },
+
+       /* MCS 66  */
+       {       /* 20 Mhz */ {  117.0,          /* SGI */  130.0, },
+               /* 40 Mhz */ {  243.0,          /* SGI */  270.0, },
+       },
+
+       /* MCS 67  */
+       {       /* 20 Mhz */ {  136.5,          /* SGI */  151.7, },
+               /* 40 Mhz */ {  283.5,          /* SGI */  315.0, },
+       },
+
+       /* MCS 68  */
+       {       /* 20 Mhz */ {  117.0,          /* SGI */  130.0, },
+               /* 40 Mhz */ {  243.0,          /* SGI */  270.0, },
+       },
+
+       /* MCS 69  */
+       {       /* 20 Mhz */ {  136.5,          /* SGI */  151.7, },
+               /* 40 Mhz */ {  283.5,          /* SGI */  315.0, },
+       },
+
+       /* MCS 70  */
+       {       /* 20 Mhz */ {  156.0,          /* SGI */  173.3, },
+               /* 40 Mhz */ {  324.0,          /* SGI */  360.0, },
+       },
+
+       /* MCS 71  */
+       {       /* 20 Mhz */ {  175.5,          /* SGI */  195.0, },
+               /* 40 Mhz */ {  364.5,          /* SGI */  405.0, },
+       },
+
+       /* MCS 72  */
+       {       /* 20 Mhz */ {  156.0,          /* SGI */  173.3, },
+               /* 40 Mhz */ {  324.0,          /* SGI */  360.0, },
+       },
+
+       /* MCS 73  */
+       {       /* 20 Mhz */ {  175.5,          /* SGI */  195.0, },
+               /* 40 Mhz */ {  364.5,          /* SGI */  405.0, },
+       },
+
+       /* MCS 74  */
+       {       /* 20 Mhz */ {  195.0,          /* SGI */  216.7, },
+               /* 40 Mhz */ {  405.0,          /* SGI */  450.0, },
+       },
+
+       /* MCS 75  */
+       {       /* 20 Mhz */ {  195.0,          /* SGI */  216.7, },
+               /* 40 Mhz */ {  405.0,          /* SGI */  450.0, },
+       },
+
+       /* MCS 76  */
+       {       /* 20 Mhz */ {  214.5,          /* SGI */  238.3, },
+               /* 40 Mhz */ {  445.5,          /* SGI */  495.0, },
+       },
+};
+
 static const char *auth_alg_text[]={"Open System","Shared Key","EAP"};
 #define NUM_AUTH_ALGS  (sizeof auth_alg_text / sizeof auth_alg_text[0])
 
 static const char *status_text[] = {
-       "Succesful",  /*  0  */
-       "Unspecified failure",  /*  1  */
-       "Reserved",       /*  2  */
-       "Reserved",       /*  3  */
-       "Reserved",       /*  4  */
-       "Reserved",       /*  5  */
-       "Reserved",       /*  6  */
-       "Reserved",       /*  7  */
-       "Reserved",       /*  8  */
-       "Reserved",       /*  9  */
-       "Cannot Support all requested capabilities in the Capability Information field",          /*  10  */
-       "Reassociation denied due to inability to confirm that association exists",       /*  11  */
-       "Association denied due to reason outside the scope of the standard",     /*  12  */
-       "Responding station does not support the specified authentication algorithm ",    /*  13  */
-       "Received an Authentication frame with authentication transaction " \
-               "sequence number out of expected sequence",       /*  14  */
-       "Authentication rejected because of challenge failure",   /*  15 */
-       "Authentication rejected due to timeout waiting for next frame in sequence",      /*  16 */
-       "Association denied because AP is unable to handle additional associated stations",       /*  17 */
-       "Association denied due to requesting station not supporting all of the " \
-               "data rates in BSSBasicRateSet parameter",        /*  18 */
+       "Succesful",                                            /*  0 */
+       "Unspecified failure",                                  /*  1 */
+       "Reserved",                                             /*  2 */
+       "Reserved",                                             /*  3 */
+       "Reserved",                                             /*  4 */
+       "Reserved",                                             /*  5 */
+       "Reserved",                                             /*  6 */
+       "Reserved",                                             /*  7 */
+       "Reserved",                                             /*  8 */
+       "Reserved",                                             /*  9 */
+       "Cannot Support all requested capabilities in the Capability "
+         "Information field",                                  /* 10 */
+       "Reassociation denied due to inability to confirm that association "
+         "exists",                                             /* 11 */
+       "Association denied due to reason outside the scope of the "
+         "standard",                                           /* 12 */
+       "Responding station does not support the specified authentication "
+         "algorithm ",                                         /* 13 */
+       "Received an Authentication frame with authentication transaction "
+         "sequence number out of expected sequence",           /* 14 */
+       "Authentication rejected because of challenge failure", /* 15 */
+       "Authentication rejected due to timeout waiting for next frame in "
+         "sequence",                                           /* 16 */
+       "Association denied because AP is unable to handle additional"
+         "associated stations",                                /* 17 */
+       "Association denied due to requesting station not supporting all of "
+         "the data rates in BSSBasicRateSet parameter",        /* 18 */
+       "Association denied due to requesting station not supporting "
+         "short preamble operation",                           /* 19 */
+       "Association denied due to requesting station not supporting "
+         "PBCC encoding",                                      /* 20 */
+       "Association denied due to requesting station not supporting "
+         "channel agility",                                    /* 21 */
+       "Association request rejected because Spectrum Management "
+         "capability is required",                             /* 22 */
+       "Association request rejected because the information in the "
+         "Power Capability element is unacceptable",           /* 23 */
+       "Association request rejected because the information in the "
+         "Supported Channels element is unacceptable",         /* 24 */
+       "Association denied due to requesting station not supporting "
+         "short slot operation",                               /* 25 */
+       "Association denied due to requesting station not supporting "
+         "DSSS-OFDM operation",                                /* 26 */
+       "Association denied because the requested STA does not support HT "
+         "features",                                           /* 27 */
+       "Reserved",                                             /* 28 */
+       "Association denied because the requested STA does not support "
+         "the PCO transition time required by the AP",         /* 29 */
+       "Reserved",                                             /* 30 */
+       "Reserved",                                             /* 31 */
+       "Unspecified, QoS-related failure",                     /* 32 */
+       "Association denied due to QAP having insufficient bandwidth "
+         "to handle another QSTA",                             /* 33 */
+       "Association denied due to excessive frame loss rates and/or "
+         "poor conditions on current operating channel",       /* 34 */
+       "Association (with QBSS) denied due to requesting station not "
+         "supporting the QoS facility",                        /* 35 */
+       "Association denied due to requesting station not supporting "
+         "Block Ack",                                          /* 36 */
+       "The request has been declined",                        /* 37 */
+       "The request has not been successful as one or more parameters "
+         "have invalid values",                                /* 38 */
+       "The TS has not been created because the request cannot be honored. "
+         "However, a suggested TSPEC is provided so that the initiating QSTA"
+         "may attempt to set another TS with the suggested changes to the "
+         "TSPEC",                                              /* 39 */
+       "Invalid Information Element",                          /* 40 */
+       "Group Cipher is not valid",                            /* 41 */
+       "Pairwise Cipher is not valid",                         /* 42 */
+       "AKMP is not valid",                                    /* 43 */
+       "Unsupported RSN IE version",                           /* 44 */
+       "Invalid RSN IE Capabilities",                          /* 45 */
+       "Cipher suite is rejected per security policy",         /* 46 */
+       "The TS has not been created. However, the HC may be capable of "
+         "creating a TS, in response to a request, after the time indicated "
+         "in the TS Delay element",                            /* 47 */
+       "Direct Link is not allowed in the BSS by policy",      /* 48 */
+       "Destination STA is not present within this QBSS.",     /* 49 */
+       "The Destination STA is not a QSTA.",                   /* 50 */
+
 };
 #define NUM_STATUSES   (sizeof status_text / sizeof status_text[0])
 
 static const char *reason_text[] = {
-       "Reserved", /* 0 */
-       "Unspecified reason", /* 1 */
-       "Previous authentication no longer valid",  /* 2 */
-       "Deauthenticated because sending station is leaving (or has left) IBSS or ESS", /* 3 */
-       "Disassociated due to inactivity", /* 4 */
-       "Disassociated because AP is unable to handle all currently associated stations", /* 5 */
+       "Reserved",                                             /* 0 */
+       "Unspecified reason",                                   /* 1 */
+       "Previous authentication no longer valid",              /* 2 */
+       "Deauthenticated because sending station is leaving (or has left) "
+         "IBSS or ESS",                                        /* 3 */
+       "Disassociated due to inactivity",                      /* 4 */
+       "Disassociated because AP is unable to handle all currently "
+         " associated stations",                               /* 5 */
        "Class 2 frame received from nonauthenticated station", /* 6 */
-       "Class 3 frame received from nonassociated station", /* 7 */
-       "Disassociated because sending station is leaving (or has left) BSS", /* 8 */
-       "Station requesting (re)association is not authenticated with responding station", /* 9 */
+       "Class 3 frame received from nonassociated station",    /* 7 */
+       "Disassociated because sending station is leaving "
+         "(or has left) BSS",                                  /* 8 */
+       "Station requesting (re)association is not authenticated with "
+         "responding station",                                 /* 9 */
+       "Disassociated because the information in the Power Capability "
+         "element is unacceptable",                            /* 10 */
+       "Disassociated because the information in the SupportedChannels "
+         "element is unacceptable",                            /* 11 */
+       "Invalid Information Element",                          /* 12 */
+       "Reserved",                                             /* 13 */
+       "Michael MIC failure",                                  /* 14 */
+       "4-Way Handshake timeout",                              /* 15 */
+       "Group key update timeout",                             /* 16 */
+       "Information element in 4-Way Handshake different from (Re)Association"
+         "Request/Probe Response/Beacon",                      /* 17 */
+       "Group Cipher is not valid",                            /* 18 */
+       "AKMP is not valid",                                    /* 20 */
+       "Unsupported RSN IE version",                           /* 21 */
+       "Invalid RSN IE Capabilities",                          /* 22 */
+       "IEEE 802.1X Authentication failed",                    /* 23 */
+       "Cipher suite is rejected per security policy",         /* 24 */
+       "Reserved",                                             /* 25 */
+       "Reserved",                                             /* 26 */
+       "Reserved",                                             /* 27 */
+       "Reserved",                                             /* 28 */
+       "Reserved",                                             /* 29 */
+       "Reserved",                                             /* 30 */
+       "TS deleted because QoS AP lacks sufficient bandwidth for this "
+         "QoS STA due to a change in BSS service characteristics or "
+         "operational mode (e.g. an HT BSS change from 40 MHz channel "
+         "to 20 MHz channel)",                                 /* 31 */
+       "Disassociated for unspecified, QoS-related reason",    /* 32 */
+       "Disassociated because QoS AP lacks sufficient bandwidth for this "
+         "QoS STA",                                            /* 33 */
+       "Disassociated because of excessive number of frames that need to be "
+          "acknowledged, but are not acknowledged for AP transmissions "
+         "and/or poor channel conditions",                     /* 34 */
+       "Disassociated because STA is transmitting outside the limits "
+         "of its TXOPs",                                       /* 35 */
+       "Requested from peer STA as the STA is leaving the BSS "
+         "(or resetting)",                                     /* 36 */
+       "Requested from peer STA as it does not want to use the "
+         "mechanism",                                          /* 37 */
+       "Requested from peer STA as the STA received frames using the "
+         "mechanism for which a set up is required",           /* 38 */
+       "Requested from peer STA due to time out",              /* 39 */
+       "Reserved",                                             /* 40 */
+       "Reserved",                                             /* 41 */
+       "Reserved",                                             /* 42 */
+       "Reserved",                                             /* 43 */
+       "Reserved",                                             /* 44 */
+       "Peer STA does not support the requested cipher suite", /* 45 */
+       "Association denied due to requesting STA not supporting HT "
+         "features",                                           /* 46 */
 };
 #define NUM_REASONS    (sizeof reason_text / sizeof reason_text[0])
 
@@ -152,141 +651,242 @@ wep_print(const u_char *p)
        return 1;
 }
 
-static void
-parse_elements(struct mgmt_body_t *pbody, const u_char *p, int offset)
+static int
+parse_elements(struct mgmt_body_t *pbody, const u_char *p, int offset,
+    u_int length)
 {
+       u_int elementlen;
+       struct ssid_t ssid;
+       struct challenge_t challenge;
+       struct rates_t rates;
+       struct ds_t ds;
+       struct cf_t cf;
+       struct tim_t tim;
+
        /*
         * We haven't seen any elements yet.
         */
-       pbody->challenge_status = NOT_PRESENT;
-       pbody->ssid_status = NOT_PRESENT;
-       pbody->rates_status = NOT_PRESENT;
-       pbody->ds_status = NOT_PRESENT;
-       pbody->cf_status = NOT_PRESENT;
-       pbody->tim_status = NOT_PRESENT;
-
-       for (;;) {
+       pbody->challenge_present = 0;
+       pbody->ssid_present = 0;
+       pbody->rates_present = 0;
+       pbody->ds_present = 0;
+       pbody->cf_present = 0;
+       pbody->tim_present = 0;
+
+       while (length != 0) {
                if (!TTEST2(*(p + offset), 1))
-                       return;
+                       return 0;
+               if (length < 1)
+                       return 0;
                switch (*(p + offset)) {
                case E_SSID:
-                       /* Present, possibly truncated */
-                       pbody->ssid_status = TRUNCATED;
                        if (!TTEST2(*(p + offset), 2))
-                               return;
-                       memcpy(&pbody->ssid, p + offset, 2);
+                               return 0;
+                       if (length < 2)
+                               return 0;
+                       memcpy(&ssid, p + offset, 2);
                        offset += 2;
-                       if (pbody->ssid.length != 0) {
-                               if (pbody->ssid.length >
-                                   sizeof(pbody->ssid.ssid) - 1)
-                                       return;
-                               if (!TTEST2(*(p + offset), pbody->ssid.length))
-                                       return;
-                               memcpy(&pbody->ssid.ssid, p + offset,
-                                   pbody->ssid.length);
-                               offset += pbody->ssid.length;
+                       length -= 2;
+                       if (ssid.length != 0) {
+                               if (ssid.length > sizeof(ssid.ssid) - 1)
+                                       return 0;
+                               if (!TTEST2(*(p + offset), ssid.length))
+                                       return 0;
+                               if (length < ssid.length)
+                                       return 0;
+                               memcpy(&ssid.ssid, p + offset, ssid.length);
+                               offset += ssid.length;
+                               length -= ssid.length;
+                       }
+                       ssid.ssid[ssid.length] = '\0';
+                       /*
+                        * Present and not truncated.
+                        *
+                        * If we haven't already seen an SSID IE,
+                        * copy this one, otherwise ignore this one,
+                        * so we later report the first one we saw.
+                        */
+                       if (!pbody->ssid_present) {
+                               pbody->ssid = ssid;
+                               pbody->ssid_present = 1;
                        }
-                       pbody->ssid.ssid[pbody->ssid.length] = '\0';
-                       /* Present and not truncated */
-                       pbody->ssid_status = PRESENT;
                        break;
                case E_CHALLENGE:
-                       /* Present, possibly truncated */
-                       pbody->challenge_status = TRUNCATED;
                        if (!TTEST2(*(p + offset), 2))
-                               return;
-                       memcpy(&pbody->challenge, p + offset, 2);
+                               return 0;
+                       if (length < 2)
+                               return 0;
+                       memcpy(&challenge, p + offset, 2);
                        offset += 2;
-                       if (pbody->challenge.length != 0) {
-                               if (pbody->challenge.length >
-                                   sizeof(pbody->challenge.text) - 1)
-                                       return;
-                               if (!TTEST2(*(p + offset), pbody->challenge.length))
-                                       return;
-                               memcpy(&pbody->challenge.text, p + offset,
-                                   pbody->challenge.length);
-                               offset += pbody->challenge.length;
+                       length -= 2;
+                       if (challenge.length != 0) {
+                               if (challenge.length >
+                                   sizeof(challenge.text) - 1)
+                                       return 0;
+                               if (!TTEST2(*(p + offset), challenge.length))
+                                       return 0;
+                               if (length < challenge.length)
+                                       return 0;
+                               memcpy(&challenge.text, p + offset,
+                                   challenge.length);
+                               offset += challenge.length;
+                               length -= challenge.length;
+                       }
+                       challenge.text[challenge.length] = '\0';
+                       /*
+                        * Present and not truncated.
+                        *
+                        * If we haven't already seen a challenge IE,
+                        * copy this one, otherwise ignore this one,
+                        * so we later report the first one we saw.
+                        */
+                       if (!pbody->challenge_present) {
+                               pbody->challenge = challenge;
+                               pbody->challenge_present = 1;
                        }
-                       pbody->challenge.text[pbody->challenge.length] = '\0';
-                       /* Present and not truncated */
-                       pbody->challenge_status = PRESENT;
                        break;
                case E_RATES:
-                       /* Present, possibly truncated */
-                       pbody->rates_status = TRUNCATED;
                        if (!TTEST2(*(p + offset), 2))
-                               return;
-                       memcpy(&(pbody->rates), p + offset, 2);
+                               return 0;
+                       if (length < 2)
+                               return 0;
+                       memcpy(&rates, p + offset, 2);
                        offset += 2;
-                       if (pbody->rates.length != 0) {
-                               if (pbody->rates.length > sizeof pbody->rates.rate)
-                                       return;
-                               if (!TTEST2(*(p + offset), pbody->rates.length))
-                                       return;
-                               memcpy(&pbody->rates.rate, p + offset,
-                                   pbody->rates.length);
-                               offset += pbody->rates.length;
+                       length -= 2;
+                       if (rates.length != 0) {
+                               if (rates.length > sizeof rates.rate)
+                                       return 0;
+                               if (!TTEST2(*(p + offset), rates.length))
+                                       return 0;
+                               if (length < rates.length)
+                                       return 0;
+                               memcpy(&rates.rate, p + offset, rates.length);
+                               offset += rates.length;
+                               length -= rates.length;
+                       }
+                       /*
+                        * Present and not truncated.
+                        *
+                        * If we haven't already seen a rates IE,
+                        * copy this one if it's not zero-length,
+                        * otherwise ignore this one, so we later
+                        * report the first one we saw.
+                        *
+                        * We ignore zero-length rates IEs as some
+                        * devices seem to put a zero-length rates
+                        * IE, followed by an SSID IE, followed by
+                        * a non-zero-length rates IE into frames,
+                        * even though IEEE Std 802.11-2007 doesn't
+                        * seem to indicate that a zero-length rates
+                        * IE is valid.
+                        */
+                       if (!pbody->rates_present && rates.length != 0) {
+                               pbody->rates = rates;
+                               pbody->rates_present = 1;
                        }
-                       /* Present and not truncated */
-                       pbody->rates_status = PRESENT;
                        break;
                case E_DS:
-                       /* Present, possibly truncated */
-                       pbody->ds_status = TRUNCATED;
                        if (!TTEST2(*(p + offset), 3))
-                               return;
-                       memcpy(&pbody->ds, p + offset, 3);
+                               return 0;
+                       if (length < 3)
+                               return 0;
+                       memcpy(&ds, p + offset, 3);
                        offset += 3;
-                       /* Present and not truncated */
-                       pbody->ds_status = PRESENT;
+                       length -= 3;
+                       /*
+                        * Present and not truncated.
+                        *
+                        * If we haven't already seen a DS IE,
+                        * copy this one, otherwise ignore this one,
+                        * so we later report the first one we saw.
+                        */
+                       if (!pbody->ds_present) {
+                               pbody->ds = ds;
+                               pbody->ds_present = 1;
+                       }
                        break;
                case E_CF:
-                       /* Present, possibly truncated */
-                       pbody->cf_status = TRUNCATED;
                        if (!TTEST2(*(p + offset), 8))
-                               return;
-                       memcpy(&pbody->cf, p + offset, 8);
+                               return 0;
+                       if (length < 8)
+                               return 0;
+                       memcpy(&cf, p + offset, 8);
                        offset += 8;
-                       /* Present and not truncated */
-                       pbody->cf_status = PRESENT;
+                       length -= 8;
+                       /*
+                        * Present and not truncated.
+                        *
+                        * If we haven't already seen a CF IE,
+                        * copy this one, otherwise ignore this one,
+                        * so we later report the first one we saw.
+                        */
+                       if (!pbody->cf_present) {
+                               pbody->cf = cf;
+                               pbody->cf_present = 1;
+                       }
                        break;
                case E_TIM:
-                       /* Present, possibly truncated */
-                       pbody->tim_status = TRUNCATED;
                        if (!TTEST2(*(p + offset), 2))
-                               return;
-                       memcpy(&pbody->tim, p + offset, 2);
+                               return 0;
+                       if (length < 2)
+                               return 0;
+                       memcpy(&tim, p + offset, 2);
                        offset += 2;
+                       length -= 2;
                        if (!TTEST2(*(p + offset), 3))
-                               return;
-                       memcpy(&pbody->tim.count, p + offset, 3);
+                               return 0;
+                       if (length < 3)
+                               return 0;
+                       memcpy(&tim.count, p + offset, 3);
                        offset += 3;
+                       length -= 3;
 
-                       if (pbody->tim.length <= 3)
+                       if (tim.length <= 3)
                                break;
-                       if (pbody->tim.length - 3 > (int)sizeof pbody->tim.bitmap)
-                               return;
-                       if (!TTEST2(*(p + offset), pbody->tim.length - 3))
-                               return;
-                       memcpy(pbody->tim.bitmap, p + (pbody->tim.length - 3),
-                           (pbody->tim.length - 3));
-                       offset += pbody->tim.length - 3;
-                       /* Present and not truncated */
-                       pbody->tim_status = PRESENT;
+                       if (tim.length - 3 > (int)sizeof tim.bitmap)
+                               return 0;
+                       if (!TTEST2(*(p + offset), tim.length - 3))
+                               return 0;
+                       if (length < (u_int)(tim.length - 3))
+                               return 0;
+                       memcpy(tim.bitmap, p + (tim.length - 3),
+                           (tim.length - 3));
+                       offset += tim.length - 3;
+                       length -= tim.length - 3;
+                       /*
+                        * Present and not truncated.
+                        *
+                        * If we haven't already seen a TIM IE,
+                        * copy this one, otherwise ignore this one,
+                        * so we later report the first one we saw.
+                        */
+                       if (!pbody->tim_present) {
+                               pbody->tim = tim;
+                               pbody->tim_present = 1;
+                       }
                        break;
                default:
 #if 0
                        printf("(1) unhandled element_id (%d)  ",
-                           *(p + offset) );
+                           *(p + offset));
 #endif
                        if (!TTEST2(*(p + offset), 2))
-                               return;
-                       if (!TTEST2(*(p + offset + 2), *(p + offset + 1)))
-                               return;
-                       offset += *(p + offset + 1) + 2;
+                               return 0;
+                       if (length < 2)
+                               return 0;
+                       elementlen = *(p + offset + 1);
+                       if (!TTEST2(*(p + offset + 2), elementlen))
+                               return 0;
+                       if (length < elementlen + 2)
+                               return 0;
+                       offset += elementlen + 2;
+                       length -= elementlen + 2;
                        break;
                }
        }
+
+       /* No problems found. */
+       return 1;
 }
 
 /*********************************************************************************
@@ -294,24 +894,31 @@ parse_elements(struct mgmt_body_t *pbody, const u_char *p, int offset)
  *********************************************************************************/
 
 static int
-handle_beacon(const u_char *p)
+handle_beacon(const u_char *p, u_int length)
 {
        struct mgmt_body_t pbody;
        int offset = 0;
+       int ret;
 
        memset(&pbody, 0, sizeof(pbody));
 
        if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
            IEEE802_11_CAPINFO_LEN))
                return 0;
+       if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
+           IEEE802_11_CAPINFO_LEN)
+               return 0;
        memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
        offset += IEEE802_11_TSTAMP_LEN;
+       length -= IEEE802_11_TSTAMP_LEN;
        pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
        offset += IEEE802_11_BCNINT_LEN;
+       length -= IEEE802_11_BCNINT_LEN;
        pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
        offset += IEEE802_11_CAPINFO_LEN;
+       length -= IEEE802_11_CAPINFO_LEN;
 
-       parse_elements(&pbody, p, offset);
+       ret = parse_elements(&pbody, p, offset, length);
 
        PRINT_SSID(pbody);
        PRINT_RATES(pbody);
@@ -319,50 +926,62 @@ handle_beacon(const u_char *p)
            CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS");
        PRINT_DS_CHANNEL(pbody);
 
-       return 1;
+       return ret;
 }
 
 static int
-handle_assoc_request(const u_char *p)
+handle_assoc_request(const u_char *p, u_int length)
 {
        struct mgmt_body_t pbody;
        int offset = 0;
+       int ret;
 
        memset(&pbody, 0, sizeof(pbody));
 
        if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN))
                return 0;
+       if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN)
+               return 0;
        pbody.capability_info = EXTRACT_LE_16BITS(p);
        offset += IEEE802_11_CAPINFO_LEN;
+       length -= IEEE802_11_CAPINFO_LEN;
        pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
        offset += IEEE802_11_LISTENINT_LEN;
+       length -= IEEE802_11_LISTENINT_LEN;
 
-       parse_elements(&pbody, p, offset);
+       ret = parse_elements(&pbody, p, offset, length);
 
        PRINT_SSID(pbody);
        PRINT_RATES(pbody);
-       return 1;
+       return ret;
 }
 
 static int
-handle_assoc_response(const u_char *p)
+handle_assoc_response(const u_char *p, u_int length)
 {
        struct mgmt_body_t pbody;
        int offset = 0;
+       int ret;
 
        memset(&pbody, 0, sizeof(pbody));
 
        if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
            IEEE802_11_AID_LEN))
                return 0;
+       if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
+           IEEE802_11_AID_LEN)
+               return 0;
        pbody.capability_info = EXTRACT_LE_16BITS(p);
        offset += IEEE802_11_CAPINFO_LEN;
+       length -= IEEE802_11_CAPINFO_LEN;
        pbody.status_code = EXTRACT_LE_16BITS(p+offset);
        offset += IEEE802_11_STATUS_LEN;
+       length -= IEEE802_11_STATUS_LEN;
        pbody.aid = EXTRACT_LE_16BITS(p+offset);
        offset += IEEE802_11_AID_LEN;
+       length -= IEEE802_11_AID_LEN;
 
-       parse_elements(&pbody, p, offset);
+       ret = parse_elements(&pbody, p, offset, length);
 
        printf(" AID(%x) :%s: %s", ((u_int16_t)(pbody.aid << 2 )) >> 2 ,
            CAPABILITY_PRIVACY(pbody.capability_info) ? " PRIVACY " : "",
@@ -370,84 +989,98 @@ handle_assoc_response(const u_char *p)
                ? status_text[pbody.status_code]
                : "n/a"));
 
-       return 1;
+       return ret;
 }
 
 static int
-handle_reassoc_request(const u_char *p)
+handle_reassoc_request(const u_char *p, u_int length)
 {
        struct mgmt_body_t pbody;
        int offset = 0;
+       int ret;
 
        memset(&pbody, 0, sizeof(pbody));
 
        if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
            IEEE802_11_AP_LEN))
                return 0;
+       if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
+           IEEE802_11_AP_LEN)
+               return 0;
        pbody.capability_info = EXTRACT_LE_16BITS(p);
        offset += IEEE802_11_CAPINFO_LEN;
+       length -= IEEE802_11_CAPINFO_LEN;
        pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
        offset += IEEE802_11_LISTENINT_LEN;
+       length -= IEEE802_11_LISTENINT_LEN;
        memcpy(&pbody.ap, p+offset, IEEE802_11_AP_LEN);
        offset += IEEE802_11_AP_LEN;
+       length -= IEEE802_11_AP_LEN;
 
-       parse_elements(&pbody, p, offset);
+       ret = parse_elements(&pbody, p, offset, length);
 
        PRINT_SSID(pbody);
        printf(" AP : %s", etheraddr_string( pbody.ap ));
 
-       return 1;
+       return ret;
 }
 
 static int
-handle_reassoc_response(const u_char *p)
+handle_reassoc_response(const u_char *p, u_int length)
 {
        /* Same as a Association Reponse */
-       return handle_assoc_response(p);
+       return handle_assoc_response(p, length);
 }
 
 static int
-handle_probe_request(const u_char *p)
+handle_probe_request(const u_char *p, u_int length)
 {
        struct mgmt_body_t  pbody;
        int offset = 0;
+       int ret;
 
        memset(&pbody, 0, sizeof(pbody));
 
-       parse_elements(&pbody, p, offset);
+       ret = parse_elements(&pbody, p, offset, length);
 
        PRINT_SSID(pbody);
        PRINT_RATES(pbody);
 
-       return 1;
+       return ret;
 }
 
 static int
-handle_probe_response(const u_char *p)
+handle_probe_response(const u_char *p, u_int length)
 {
        struct mgmt_body_t  pbody;
        int offset = 0;
+       int ret;
 
        memset(&pbody, 0, sizeof(pbody));
 
        if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
            IEEE802_11_CAPINFO_LEN))
                return 0;
-
+       if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
+           IEEE802_11_CAPINFO_LEN)
+               return 0;
        memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
        offset += IEEE802_11_TSTAMP_LEN;
+       length -= IEEE802_11_TSTAMP_LEN;
        pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
        offset += IEEE802_11_BCNINT_LEN;
+       length -= IEEE802_11_BCNINT_LEN;
        pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
        offset += IEEE802_11_CAPINFO_LEN;
+       length -= IEEE802_11_CAPINFO_LEN;
 
-       parse_elements(&pbody, p, offset);
+       ret = parse_elements(&pbody, p, offset, length);
 
        PRINT_SSID(pbody);
        PRINT_RATES(pbody);
        PRINT_DS_CHANNEL(pbody);
 
-       return 1;
+       return ret;
 }
 
 static int
@@ -458,7 +1091,7 @@ handle_atim(void)
 }
 
 static int
-handle_disassoc(const u_char *p)
+handle_disassoc(const u_char *p, u_int length)
 {
        struct mgmt_body_t  pbody;
 
@@ -466,6 +1099,8 @@ handle_disassoc(const u_char *p)
 
        if (!TTEST2(*p, IEEE802_11_REASON_LEN))
                return 0;
+       if (length < IEEE802_11_REASON_LEN)
+               return 0;
        pbody.reason_code = EXTRACT_LE_16BITS(p);
 
        printf(": %s",
@@ -477,23 +1112,29 @@ handle_disassoc(const u_char *p)
 }
 
 static int
-handle_auth(const u_char *p)
+handle_auth(const u_char *p, u_int length)
 {
        struct mgmt_body_t  pbody;
        int offset = 0;
+       int ret;
 
        memset(&pbody, 0, sizeof(pbody));
 
        if (!TTEST2(*p, 6))
                return 0;
+       if (length < 6)
+               return 0;
        pbody.auth_alg = EXTRACT_LE_16BITS(p);
        offset += 2;
+       length -= 2;
        pbody.auth_trans_seq_num = EXTRACT_LE_16BITS(p + offset);
        offset += 2;
+       length -= 2;
        pbody.status_code = EXTRACT_LE_16BITS(p + offset);
        offset += 2;
+       length -= 2;
 
-       parse_elements(&pbody, p, offset);
+       ret = parse_elements(&pbody, p, offset, length);
 
        if ((pbody.auth_alg == 1) &&
            ((pbody.auth_trans_seq_num == 2) ||
@@ -507,7 +1148,7 @@ handle_auth(const u_char *p)
                        ? ((pbody.status_code < NUM_STATUSES)
                               ? status_text[pbody.status_code]
                               : "n/a") : ""));
-               return 1;
+               return ret;
        }
        printf(" (%s)-%x: %s",
            (pbody.auth_alg < NUM_AUTH_ALGS)
@@ -520,11 +1161,11 @@ handle_auth(const u_char *p)
                    : "n/a")
                : "");
 
-       return 1;
+       return ret;
 }
 
 static int
-handle_deauth(const struct mgmt_header_t *pmh, const u_char *p)
+handle_deauth(const struct mgmt_header_t *pmh, const u_char *p, u_int length)
 {
        struct mgmt_body_t  pbody;
        int offset = 0;
@@ -534,8 +1175,11 @@ handle_deauth(const struct mgmt_header_t *pmh, const u_char *p)
 
        if (!TTEST2(*p, IEEE802_11_REASON_LEN))
                return 0;
+       if (length < IEEE802_11_REASON_LEN)
+               return 0;
        pbody.reason_code = EXTRACT_LE_16BITS(p);
        offset += IEEE802_11_REASON_LEN;
+       length -= IEEE802_11_REASON_LEN;
 
        reason = (pbody.reason_code < NUM_REASONS)
                        ? reason_text[pbody.reason_code]
@@ -549,6 +1193,68 @@ handle_deauth(const struct mgmt_header_t *pmh, const u_char *p)
        return 1;
 }
 
+#define        PRINT_HT_ACTION(v) (\
+       (v) == 0 ? printf("TxChWidth") : \
+       (v) == 1 ? printf("MIMOPwrSave") : \
+                  printf("Act#%d", (v)) \
+)
+#define        PRINT_BA_ACTION(v) (\
+       (v) == 0 ? printf("ADDBA Request") : \
+       (v) == 1 ? printf("ADDBA Response") : \
+       (v) == 2 ? printf("DELBA") : \
+                  printf("Act#%d", (v)) \
+)
+#define        PRINT_MESHLINK_ACTION(v) (\
+       (v) == 0 ? printf("Request") : \
+       (v) == 1 ? printf("Report") : \
+                  printf("Act#%d", (v)) \
+)
+#define        PRINT_MESHPEERING_ACTION(v) (\
+       (v) == 0 ? printf("Open") : \
+       (v) == 1 ? printf("Confirm") : \
+       (v) == 2 ? printf("Close") : \
+                  printf("Act#%d", (v)) \
+)
+#define        PRINT_MESHPATH_ACTION(v) (\
+       (v) == 0 ? printf("Request") : \
+       (v) == 1 ? printf("Report") : \
+       (v) == 2 ? printf("Error") : \
+       (v) == 3 ? printf("RootAnnouncement") : \
+                  printf("Act#%d", (v)) \
+)
+
+static int
+handle_action(const struct mgmt_header_t *pmh, const u_char *p, u_int length)
+{
+       if (!TTEST2(*p, 2))
+               return 0;
+       if (length < 2)
+               return 0;
+       if (eflag) {
+               printf(": ");
+       } else {
+               printf(" (%s): ", etheraddr_string(pmh->sa));
+       }
+       switch (p[0]) {
+       case 0: printf("Spectrum Management Act#%d", p[1]); break;
+       case 1: printf("QoS Act#%d", p[1]); break;
+       case 2: printf("DLS Act#%d", p[1]); break;
+       case 3: printf("BA "); PRINT_BA_ACTION(p[1]); break;
+       case 7: printf("HT "); PRINT_HT_ACTION(p[1]); break;
+       case 13: printf("MeshLMetric "); PRINT_MESHLINK_ACTION(p[1]); break;
+       case 15: printf("Interwork Act#%d", p[1]); break;
+       case 16: printf("Resource Act#%d", p[1]); break;
+       case 17: printf("Proxy Act#%d", p[1]); break;
+       case 30: printf("MeshPeering "); PRINT_MESHPEERING_ACTION(p[1]); break;
+       case 32: printf("MeshPath "); PRINT_MESHPATH_ACTION(p[1]); break;
+       case 127: printf("Vendor Act#%d", p[1]); break;
+       default:
+               printf("Reserved(%d) Act#%d", p[0], p[1]);
+               break;
+       }
+       return 1;
+}
+
 
 /*********************************************************************************
  * Print Body funcs
@@ -557,36 +1263,36 @@ handle_deauth(const struct mgmt_header_t *pmh, const u_char *p)
 
 static int
 mgmt_body_print(u_int16_t fc, const struct mgmt_header_t *pmh,
-    const u_char *p)
+    const u_char *p, u_int length)
 {
        switch (FC_SUBTYPE(fc)) {
        case ST_ASSOC_REQUEST:
                printf("Assoc Request");
-               return handle_assoc_request(p);
+               return handle_assoc_request(p, length);
        case ST_ASSOC_RESPONSE:
                printf("Assoc Response");
-               return handle_assoc_response(p);
+               return handle_assoc_response(p, length);
        case ST_REASSOC_REQUEST:
                printf("ReAssoc Request");
-               return handle_reassoc_request(p);
+               return handle_reassoc_request(p, length);
        case ST_REASSOC_RESPONSE:
                printf("ReAssoc Response");
-               return handle_reassoc_response(p);
+               return handle_reassoc_response(p, length);
        case ST_PROBE_REQUEST:
                printf("Probe Request");
-               return handle_probe_request(p);
+               return handle_probe_request(p, length);
        case ST_PROBE_RESPONSE:
                printf("Probe Response");
-               return handle_probe_response(p);
+               return handle_probe_response(p, length);
        case ST_BEACON:
                printf("Beacon");
-               return handle_beacon(p);
+               return handle_beacon(p, length);
        case ST_ATIM:
                printf("ATIM");
                return handle_atim();
        case ST_DISASSOC:
                printf("Disassociation");
-               return handle_disassoc(p);
+               return handle_disassoc(p, length);
        case ST_AUTH:
                printf("Authentication");
                if (!TTEST2(*p, 3))
@@ -595,10 +1301,14 @@ mgmt_body_print(u_int16_t fc, const struct mgmt_header_t *pmh,
                        printf("Authentication (Shared-Key)-3 ");
                        return wep_print(p);
                }
-               return handle_auth(p);
+               return handle_auth(p, length);
        case ST_DEAUTH:
                printf("DeAuthentication");
-               return handle_deauth(pmh, p);
+               return handle_deauth(pmh, p, length);
+               break;
+       case ST_ACTION:
+               printf("Action");
+               return handle_action(pmh, p, length);
                break;
        default:
                printf("Unhandled Management subtype(%x)",
@@ -616,6 +1326,29 @@ static int
 ctrl_body_print(u_int16_t fc, const u_char *p)
 {
        switch (FC_SUBTYPE(fc)) {
+       case CTRL_CONTROL_WRAPPER:
+               printf("Control Wrapper");
+               /* XXX - requires special handling */
+               break;
+       case CTRL_BAR:
+               printf("BAR");
+               if (!TTEST2(*p, CTRL_BAR_HDRLEN))
+                       return 0;
+               if (!eflag)
+                       printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
+                           etheraddr_string(((const struct ctrl_bar_t *)p)->ra),
+                           etheraddr_string(((const struct ctrl_bar_t *)p)->ta),
+                           EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)),
+                           EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)));
+               break;
+       case CTRL_BA:
+               printf("BA");
+               if (!TTEST2(*p, CTRL_BA_HDRLEN))
+                       return 0;
+               if (!eflag)
+                       printf(" RA:%s ",
+                           etheraddr_string(((const struct ctrl_ba_t *)p)->ra));
+               break;
        case CTRL_PS_POLL:
                printf("Power Save-Poll");
                if (!TTEST2(*p, CTRL_PS_POLL_HDRLEN))
@@ -789,6 +1522,17 @@ ctrl_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
                return;
 
        switch (FC_SUBTYPE(fc)) {
+       case CTRL_BAR:
+               printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
+                   etheraddr_string(((const struct ctrl_bar_t *)p)->ra),
+                   etheraddr_string(((const struct ctrl_bar_t *)p)->ta),
+                   EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)),
+                   EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)));
+               break;
+       case CTRL_BA:
+               printf("RA:%s ",
+                   etheraddr_string(((const struct ctrl_ba_t *)p)->ra));
+               break;
        case CTRL_PS_POLL:
                printf("BSSID:%s TA:%s ",
                    etheraddr_string(((const struct ctrl_ps_poll_t *)p)->bssid),
@@ -833,6 +1577,8 @@ extract_header_length(u_int16_t fc)
                return MGMT_HDRLEN;
        case T_CTRL:
                switch (FC_SUBTYPE(fc)) {
+               case CTRL_BAR:
+                       return CTRL_BAR_HDRLEN;
                case CTRL_PS_POLL:
                        return CTRL_PS_POLL_HDRLEN;
                case CTRL_RTS:
@@ -859,14 +1605,20 @@ extract_header_length(u_int16_t fc)
        }
 }
 
+static int
+extract_mesh_header_length(const u_char *p)
+{
+       return (p[0] &~ 3) ? 0 : 6*(1 + (p[0] & 3));
+}
+
 /*
  * Print the 802.11 MAC header if eflag is set, and set "*srcp" and "*dstp"
  * to point to the source and destination MAC addresses in any case if
  * "srcp" and "dstp" aren't null.
  */
-static inline void
-ieee_802_11_hdr_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
-    const u_int8_t **dstp)
+static void
+ieee_802_11_hdr_print(u_int16_t fc, const u_char *p, u_int hdrlen,
+    u_int meshdrlen, const u_int8_t **srcp, const u_int8_t **dstp)
 {
        if (vflag) {
                if (FC_MORE_DATA(fc))
@@ -886,6 +1638,21 @@ ieee_802_11_hdr_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
                            EXTRACT_LE_16BITS(
                                &((const struct mgmt_header_t *)p)->duration));
        }
+       if (meshdrlen != 0) {
+               const struct meshcntl_t *mc =
+                   (const struct meshcntl_t *)&p[hdrlen - meshdrlen];
+               int ae = mc->flags & 3;
+
+               printf("MeshData (AE %d TTL %u seq %u", ae, mc->ttl,
+                   EXTRACT_LE_32BITS(mc->seq));
+               if (ae > 0)
+                       printf(" A4:%s", etheraddr_string(mc->addr4));
+               if (ae > 1)
+                       printf(" A5:%s", etheraddr_string(mc->addr5));
+               if (ae > 2)
+                       printf(" A6:%s", etheraddr_string(mc->addr6));
+               printf(") ");
+       }
 
        switch (FC_TYPE(fc)) {
        case T_MGMT:
@@ -911,29 +1678,51 @@ ieee_802_11_hdr_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
 #endif
 
 static u_int
-ieee802_11_print(const u_char *p, u_int length, u_int caplen, int pad)
+ieee802_11_print(const u_char *p, u_int length, u_int orig_caplen, int pad,
+    u_int fcslen)
 {
        u_int16_t fc;
-       u_int hdrlen;
+       u_int caplen, hdrlen, meshdrlen;
        const u_int8_t *src, *dst;
        u_short extracted_ethertype;
 
-       if (caplen < IEEE802_11_FC_LEN) {
+       caplen = orig_caplen;
+       /* Remove FCS, if present */
+       if (length < fcslen) {
                printf("[|802.11]");
                return caplen;
        }
+       length -= fcslen;
+       if (caplen > length) {
+               /* Amount of FCS in actual packet data, if any */
+               fcslen = caplen - length;
+               caplen -= fcslen;
+               snapend -= fcslen;
+       }
+
+       if (caplen < IEEE802_11_FC_LEN) {
+               printf("[|802.11]");
+               return orig_caplen;
+       }
 
        fc = EXTRACT_LE_16BITS(p);
        hdrlen = extract_header_length(fc);
        if (pad)
                hdrlen = roundup2(hdrlen, 4);
+       if (Hflag && FC_TYPE(fc) == T_DATA &&
+           DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) {
+               meshdrlen = extract_mesh_header_length(p+hdrlen);
+               hdrlen += meshdrlen;
+       } else
+               meshdrlen = 0;
+
 
        if (caplen < hdrlen) {
                printf("[|802.11]");
                return hdrlen;
        }
 
-       ieee_802_11_hdr_print(fc, p, &src, &dst);
+       ieee_802_11_hdr_print(fc, p, hdrlen, meshdrlen, &src, &dst);
 
        /*
         * Go past the 802.11 header.
@@ -945,7 +1734,7 @@ ieee802_11_print(const u_char *p, u_int length, u_int caplen, int pad)
        switch (FC_TYPE(fc)) {
        case T_MGMT:
                if (!mgmt_body_print(fc,
-                   (const struct mgmt_header_t *)(p - hdrlen), p)) {
+                   (const struct mgmt_header_t *)(p - hdrlen), p, length)) {
                        printf("[|802.11]");
                        return hdrlen;
                }
@@ -972,8 +1761,8 @@ ieee802_11_print(const u_char *p, u_int length, u_int caplen, int pad)
                         * handle intelligently
                         */
                        if (!eflag)
-                               ieee_802_11_hdr_print(fc, p - hdrlen, NULL,
-                                   NULL);
+                               ieee_802_11_hdr_print(fc, p - hdrlen, hdrlen,
+                                   meshdrlen, NULL, NULL);
                        if (extracted_ethertype)
                                printf("(LLC %s) ",
                                    etherproto_string(
@@ -999,11 +1788,70 @@ ieee802_11_print(const u_char *p, u_int length, u_int caplen, int pad)
 u_int
 ieee802_11_if_print(const struct pcap_pkthdr *h, const u_char *p)
 {
-       return ieee802_11_print(p, h->len, h->caplen, 0);
+       return ieee802_11_print(p, h->len, h->caplen, 0, 0);
+}
+
+#define        IEEE80211_CHAN_FHSS \
+       (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
+#define        IEEE80211_CHAN_A \
+       (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
+#define        IEEE80211_CHAN_B \
+       (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
+#define        IEEE80211_CHAN_PUREG \
+       (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
+#define        IEEE80211_CHAN_G \
+       (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
+
+#define        IS_CHAN_FHSS(flags) \
+       ((flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS)
+#define        IS_CHAN_A(flags) \
+       ((flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A)
+#define        IS_CHAN_B(flags) \
+       ((flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B)
+#define        IS_CHAN_PUREG(flags) \
+       ((flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG)
+#define        IS_CHAN_G(flags) \
+       ((flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G)
+#define        IS_CHAN_ANYG(flags) \
+       (IS_CHAN_PUREG(flags) || IS_CHAN_G(flags))
+
+static void
+print_chaninfo(int freq, int flags)
+{
+       printf("%u MHz", freq);
+       if (IS_CHAN_FHSS(flags))
+               printf(" FHSS");
+       if (IS_CHAN_A(flags)) {
+               if (flags & IEEE80211_CHAN_HALF)
+                       printf(" 11a/10Mhz");
+               else if (flags & IEEE80211_CHAN_QUARTER)
+                       printf(" 11a/5Mhz");
+               else
+                       printf(" 11a");
+       }
+       if (IS_CHAN_ANYG(flags)) {
+               if (flags & IEEE80211_CHAN_HALF)
+                       printf(" 11g/10Mhz");
+               else if (flags & IEEE80211_CHAN_QUARTER)
+                       printf(" 11g/5Mhz");
+               else
+                       printf(" 11g");
+       } else if (IS_CHAN_B(flags))
+               printf(" 11b");
+       if (flags & IEEE80211_CHAN_TURBO)
+               printf(" Turbo");
+       if (flags & IEEE80211_CHAN_HT20)
+               printf(" ht/20");
+       else if (flags & IEEE80211_CHAN_HT40D)
+               printf(" ht/40-");
+       else if (flags & IEEE80211_CHAN_HT40U)
+               printf(" ht/40+");
+       printf(" ");
 }
 
 static int
-print_radiotap_field(struct cpack_state *s, u_int32_t bit, int *pad)
+print_radiotap_field(struct cpack_state *s, u_int32_t bit, u_int8_t *flags,
+                                               struct radiotap_state *state, u_int32_t presentflags)
 {
        union {
                int8_t          i8;
@@ -1012,16 +1860,24 @@ print_radiotap_field(struct cpack_state *s, u_int32_t bit, int *pad)
                u_int16_t       u16;
                u_int32_t       u32;
                u_int64_t       u64;
-       } u, u2;
+       } u, u2, u3, u4;
        int rc;
 
        switch (bit) {
        case IEEE80211_RADIOTAP_FLAGS:
                rc = cpack_uint8(s, &u.u8);
-               if (u.u8 & IEEE80211_RADIOTAP_F_DATAPAD)
-                       *pad = 1;
+               if (rc != 0)
+                       break;
+               *flags = u.u8;
                break;
        case IEEE80211_RADIOTAP_RATE:
+               rc = cpack_uint8(s, &u.u8);
+               if (rc != 0)
+                       break;
+
+               /* Save state rate */
+               state->rate = u.u8;
+               break;
        case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
        case IEEE80211_RADIOTAP_DB_ANTNOISE:
        case IEEE80211_RADIOTAP_ANTENNA:
@@ -1040,6 +1896,7 @@ print_radiotap_field(struct cpack_state *s, u_int32_t bit, int *pad)
        case IEEE80211_RADIOTAP_FHSS:
        case IEEE80211_RADIOTAP_LOCK_QUALITY:
        case IEEE80211_RADIOTAP_TX_ATTENUATION:
+       case IEEE80211_RADIOTAP_RX_FLAGS:
                rc = cpack_uint16(s, &u.u16);
                break;
        case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
@@ -1051,12 +1908,63 @@ print_radiotap_field(struct cpack_state *s, u_int32_t bit, int *pad)
        case IEEE80211_RADIOTAP_TSFT:
                rc = cpack_uint64(s, &u.u64);
                break;
+       case IEEE80211_RADIOTAP_XCHANNEL:
+               rc = cpack_uint32(s, &u.u32);
+               if (rc != 0)
+                       break;
+               rc = cpack_uint16(s, &u2.u16);
+               if (rc != 0)
+                       break;
+               rc = cpack_uint8(s, &u3.u8);
+               if (rc != 0)
+                       break;
+               rc = cpack_uint8(s, &u4.u8);
+               break;
+       case IEEE80211_RADIOTAP_MCS:
+               rc = cpack_uint8(s, &u.u8);
+               if (rc != 0)
+                       break;
+               rc = cpack_uint8(s, &u2.u8);
+               if (rc != 0)
+                       break;
+               rc = cpack_uint8(s, &u3.u8);
+               break;
+       case IEEE80211_RADIOTAP_VENDOR_NAMESPACE: {
+               u_int8_t vns[3];
+               u_int16_t length;
+               u_int8_t subspace;
+
+               if ((cpack_align_and_reserve(s, 2)) == NULL) {
+                       rc = -1;
+                       break;
+               }
+
+               rc = cpack_uint8(s, &vns[0]);
+               if (rc != 0)
+                       break;
+               rc = cpack_uint8(s, &vns[1]);
+               if (rc != 0)
+                       break;
+               rc = cpack_uint8(s, &vns[2]);
+               if (rc != 0)
+                       break;
+               rc = cpack_uint8(s, &subspace);
+               if (rc != 0)
+                       break;
+               rc = cpack_uint16(s, &length);
+               if (rc != 0)
+                       break;
+
+               /* Skip up to length */
+               s->c_next += length;
+               break;
+       }
        default:
                /* this bit indicates a field whose
                 * size we do not know, so we cannot
-                * proceed.
+                * proceed.  Just print the bit number.
                 */
-               printf("[0x%08x] ", bit);
+               printf("[bit %u] ", bit);
                return -1;
        }
 
@@ -1065,17 +1973,64 @@ print_radiotap_field(struct cpack_state *s, u_int32_t bit, int *pad)
                return rc;
        }
 
+       /* Preserve the state present flags */
+       state->present = presentflags;
+
        switch (bit) {
        case IEEE80211_RADIOTAP_CHANNEL:
-               printf("%u MHz ", u.u16);
-               if (u2.u16 != 0)
-                       printf("(0x%04x) ", u2.u16);
+               /*
+                * If CHANNEL and XCHANNEL are both present, skip
+                * CHANNEL.
+                */
+               if (presentflags & (1 << IEEE80211_RADIOTAP_XCHANNEL))
+                       break;
+               print_chaninfo(u.u16, u2.u16);
                break;
        case IEEE80211_RADIOTAP_FHSS:
                printf("fhset %d fhpat %d ", u.u16 & 0xff, (u.u16 >> 8) & 0xff);
                break;
        case IEEE80211_RADIOTAP_RATE:
-               PRINT_RATE("", u.u8, " Mb/s ");
+               /*
+                * XXX On FreeBSD rate & 0x80 means we have an MCS. On
+                * Linux and AirPcap it does not.  (What about
+                * Mac OS X, NetBSD, OpenBSD, and DragonFly BSD?)
+                *
+                * This is an issue either for proprietary extensions
+                * to 11a or 11g, which do exist, or for 11n
+                * implementations that stuff a rate value into
+                * this field, which also appear to exist.
+                *
+                * We currently handle that by assuming that
+                * if the 0x80 bit is set *and* the remaining
+                * bits have a value between 0 and 15 it's
+                * an MCS value, otherwise it's a rate.  If
+                * there are cases where systems that use
+                * "0x80 + MCS index" for MCS indices > 15,
+                * or stuff a rate value here between 64 and
+                * 71.5 Mb/s in here, we'll need a preference
+                * setting.  Such rates do exist, e.g. 11n
+                * MCS 7 at 20 MHz with a long guard interval.
+                */
+               if (u.u8 >= 0x80 && u.u8 <= 0x8f) {
+                       /*
+                        * XXX - we don't know the channel width
+                        * or guard interval length, so we can't
+                        * convert this to a data rate.
+                        *
+                        * If you want us to show a data rate,
+                        * use the MCS field, not the Rate field;
+                        * the MCS field includes not only the
+                        * MCS index, it also includes bandwidth
+                        * and guard interval information.
+                        *
+                        * XXX - can we get the channel width
+                        * from XChannel and the guard interval
+                        * information from Flags, at least on
+                        * FreeBSD?
+                        */
+                       printf("MCS %u ", u.u8 & 0x7f);
+               } else
+                       printf("%2.1f Mb/s ", .5*u.u8);
                break;
        case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
                printf("%ddB signal ", u.i8);
@@ -1119,6 +2074,89 @@ print_radiotap_field(struct cpack_state *s, u_int32_t bit, int *pad)
        case IEEE80211_RADIOTAP_TSFT:
                printf("%" PRIu64 "us tsft ", u.u64);
                break;
+       case IEEE80211_RADIOTAP_RX_FLAGS:
+               /* Do nothing for now */
+               break;
+       case IEEE80211_RADIOTAP_XCHANNEL:
+               print_chaninfo(u2.u16, u.u32);
+               break;
+       case IEEE80211_RADIOTAP_MCS: {
+               static const char *bandwidth[4] = {
+                       "20 MHz",
+                       "40 MHz",
+                       "20 MHz (L)",
+                       "20 MHz (U)"
+               };
+               float htrate;
+
+               if (u.u8 & IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN) {
+                       /*
+                        * We know the MCS index.
+                        */
+                       if (u3.u8 <= MAX_MCS_INDEX) {
+                               /*
+                                * And it's in-range.
+                                */
+                               if (u.u8 & (IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN|IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN)) {
+                                       /*
+                                        * And we know both the bandwidth and
+                                        * the guard interval, so we can look
+                                        * up the rate.
+                                        */
+                                       htrate = 
+                                               ieee80211_float_htrates \
+                                                       [u3.u8] \
+                                                       [((u2.u8 & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK) == IEEE80211_RADIOTAP_MCS_BANDWIDTH_40 ? 1 : 0)] \
+                                                       [((u2.u8 & IEEE80211_RADIOTAP_MCS_SHORT_GI) ? 1 : 0)];
+                               } else {
+                                       /*
+                                        * We don't know both the bandwidth
+                                        * and the guard interval, so we can
+                                        * only report the MCS index.
+                                        */
+                                       htrate = 0.0;
+                               }
+                       } else {
+                               /*
+                                * The MCS value is out of range.
+                                */
+                               htrate = 0.0;
+                       }
+                       if (htrate != 0.0) {
+                               /*
+                                * We have the rate.
+                                * Print it.
+                                */
+                               printf("%.1f Mb/s MCS %u ", htrate, u3.u8);
+                       } else {
+                               /*
+                                * We at least have the MCS index.
+                                * Print it.
+                                */
+                               printf("MCS %u ", u3.u8);
+                       }
+               }
+               if (u.u8 & IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN) {
+                       printf("%s ",
+                               bandwidth[u2.u8 & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK]);
+               }
+               if (u.u8 & IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN) {
+                       printf("%s GI ",
+                               (u2.u8 & IEEE80211_RADIOTAP_MCS_SHORT_GI) ?
+                               "short" : "lon");
+               }
+               if (u.u8 & IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN) {
+                       printf("%s ",
+                               (u2.u8 & IEEE80211_RADIOTAP_MCS_HT_GREENFIELD) ?
+                               "greenfield" : "mixed");
+               }
+               if (u.u8 & IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN) {
+                       printf("%s FEC ",
+                               (u2.u8 & IEEE80211_RADIOTAP_MCS_FEC_LDPC) ?
+                               "LDPC" : "BCC");
+               }
+               break;
+               }
        }
        return 0;
 }
@@ -1131,19 +2169,23 @@ ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen)
 #define        BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
 #define        BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
 #define        BITNO_2(x) (((x) & 2) ? 1 : 0)
-#define        BIT(n)  (1 << n)
+#define        BIT(n)  (1U << n)
 #define        IS_EXTENDED(__p)        \
            (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0
 
        struct cpack_state cpacker;
        struct ieee80211_radiotap_header *hdr;
        u_int32_t present, next_present;
+       u_int32_t presentflags = 0;
        u_int32_t *presentp, *last_presentp;
        enum ieee80211_radiotap_type bit;
        int bit0;
        const u_char *iter;
        u_int len;
+       u_int8_t flags;
        int pad;
+       u_int fcslen;
+       struct radiotap_state state;
 
        if (caplen < sizeof(*hdr)) {
                printf("[|802.11]");
@@ -1177,10 +2219,19 @@ ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen)
                return caplen;
        }
 
+       /* Assume no flags */
+       flags = 0;
        /* Assume no Atheros padding between 802.11 header and body */
        pad = 0;
+       /* Assume no FCS at end of frame */
+       fcslen = 0;
        for (bit0 = 0, presentp = &hdr->it_present; presentp <= last_presentp;
             presentp++, bit0 += 32) {
+               presentflags = EXTRACT_LE_32BITS(presentp);
+
+               /* Clear state. */
+               memset(&state, 0, sizeof(state));
+
                for (present = EXTRACT_LE_32BITS(presentp); present;
                     present = next_present) {
                        /* clear the least significant bit that is set */
@@ -1190,12 +2241,18 @@ ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen)
                        bit = (enum ieee80211_radiotap_type)
                            (bit0 + BITNO_32(present ^ next_present));
 
-                       if (print_radiotap_field(&cpacker, bit, &pad) != 0)
+                       if (print_radiotap_field(&cpacker, bit, &flags, &state, presentflags) != 0)
                                goto out;
                }
        }
+
 out:
-       return len + ieee802_11_print(p + len, length - len, caplen - len, pad);
+       if (flags & IEEE80211_RADIOTAP_F_DATAPAD)
+               pad = 1;        /* Atheros padding */
+       if (flags & IEEE80211_RADIOTAP_F_FCS)
+               fcslen = 4;     /* FCS at end of packet */
+       return len + ieee802_11_print(p + len, length - len, caplen - len, pad,
+           fcslen);
 #undef BITNO_32
 #undef BITNO_16
 #undef BITNO_8
@@ -1231,7 +2288,7 @@ ieee802_11_avs_radio_print(const u_char *p, u_int length, u_int caplen)
        }
 
        return caphdr_len + ieee802_11_print(p + caphdr_len,
-           length - caphdr_len, caplen - caphdr_len, 0);
+           length - caphdr_len, caplen - caphdr_len, 0, 0);
 }
 
 #define PRISM_HDR_LEN          144
@@ -1276,7 +2333,7 @@ prism_if_print(const struct pcap_pkthdr *h, const u_char *p)
        }
 
        return PRISM_HDR_LEN + ieee802_11_print(p + PRISM_HDR_LEN,
-           length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN, 0);
+           length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN, 0, 0);
 }
 
 /*
diff --git a/contrib/tcpdump/print-802_15_4.c b/contrib/tcpdump/print-802_15_4.c
new file mode 100644 (file)
index 0000000..2016552
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2009
+ *     Siemens AG, All rights reserved.
+ *     Dmitry Eremin-Solenikov (dbaryshkov@gmail.com)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <pcap.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+#include "extract.h"
+
+static const char *ftypes[] = {
+       "Beacon",                       /* 0 */
+       "Data",                         /* 1 */
+       "ACK",                          /* 2 */
+       "Command",                      /* 3 */
+       "Reserved",                     /* 4 */
+       "Reserved",                     /* 5 */
+       "Reserved",                     /* 6 */
+       "Reserved",                     /* 7 */
+};
+
+static int
+extract_header_length(u_int16_t fc)
+{
+       int len = 0;
+
+       switch ((fc >> 10) & 0x3) {
+       case 0x00:
+               if (fc & (1 << 6)) /* intra-PAN with none dest addr */
+                       return -1;
+               break;
+       case 0x01:
+               return -1;
+       case 0x02:
+               len += 4;
+               break;
+       case 0x03:
+               len += 10;
+               break;
+       }
+
+       switch ((fc >> 14) & 0x3) {
+       case 0x00:
+               break;
+       case 0x01:
+               return -1;
+       case 0x02:
+               len += 4;
+               break;
+       case 0x03:
+               len += 10;
+               break;
+       }
+
+       if (fc & (1 << 6)) {
+               if (len < 2)
+                       return -1;
+               len -= 2;
+       }
+
+       return len;
+}
+
+
+u_int
+ieee802_15_4_if_print(struct netdissect_options *ndo,
+                      const struct pcap_pkthdr *h, const u_char *p)
+{
+       u_int caplen = h->caplen;
+       int hdrlen;
+       u_int16_t fc;
+       u_int8_t seq;
+
+       if (caplen < 3) {
+               ND_PRINT((ndo, "[|802.15.4] %x", caplen));
+               return caplen;
+       }
+
+       fc = EXTRACT_LE_16BITS(p);
+       hdrlen = extract_header_length(fc);
+
+       seq = EXTRACT_LE_8BITS(p + 2);
+
+       p += 3;
+       caplen -= 3;
+
+       ND_PRINT((ndo,"IEEE 802.15.4 %s packet ", ftypes[fc & 0x7]));
+       if (vflag)
+               ND_PRINT((ndo,"seq %02x ", seq));
+       if (hdrlen == -1) {
+               ND_PRINT((ndo,"malformed! "));
+               return caplen;
+       }
+
+
+       if (!vflag) {
+               p+= hdrlen;
+               caplen -= hdrlen;
+       } else {
+               u_int16_t panid = 0;
+
+               switch ((fc >> 10) & 0x3) {
+               case 0x00:
+                       ND_PRINT((ndo,"none "));
+                       break;
+               case 0x01:
+                       ND_PRINT((ndo,"reserved destination addressing mode"));
+                       return 0;
+               case 0x02:
+                       panid = EXTRACT_LE_16BITS(p);
+                       p += 2;
+                       ND_PRINT((ndo,"%04x:%04x ", panid, EXTRACT_LE_16BITS(p)));
+                       p += 2;
+                       break;
+               case 0x03:
+                       panid = EXTRACT_LE_16BITS(p);
+                       p += 2;
+                       ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(p)));
+                       p += 8;
+                       break;
+               }
+               ND_PRINT((ndo,"< ");
+
+               switch ((fc >> 14) & 0x3) {
+               case 0x00:
+                       ND_PRINT((ndo,"none "));
+                       break;
+               case 0x01:
+                       ND_PRINT((ndo,"reserved source addressing mode"));
+                       return 0;
+               case 0x02:
+                       if (!(fc & (1 << 6))) {
+                               panid = EXTRACT_LE_16BITS(p);
+                               p += 2;
+                       }
+                       ND_PRINT((ndo,"%04x:%04x ", panid, EXTRACT_LE_16BITS(p)));
+                       p += 2;
+                       break;
+               case 0x03:
+                       if (!(fc & (1 << 6))) {
+                               panid = EXTRACT_LE_16BITS(p);
+                               p += 2;
+                       }
+                        ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(p))));
+                       p += 8;
+                       break;
+               }
+
+               caplen -= hdrlen;
+       }
+
+       if (!suppress_default_print)
+               (ndo->ndo_default_print)(ndo, p, caplen);
+
+       return 0;
+}
index dd9bc5a..ab0713b 100644 (file)
@@ -33,6 +33,7 @@ static const char rcsid[] _U_ =
 #include <pcap.h>
 
 #include "interface.h"
+#include "extract.h"
 #include "addrtoname.h"
 #include "ethertype.h"
 
@@ -57,18 +58,21 @@ static inline void
 ap1394_hdr_print(register const u_char *bp, u_int length)
 {
        register const struct firewire_header *fp;
+       u_int16_t firewire_type;
+
        fp = (const struct firewire_header *)bp;
 
        (void)printf("%s > %s",
                     linkaddr_string(fp->firewire_dhost, LINKADDR_IEEE1394, FIREWIRE_EUI64_LEN),
                     linkaddr_string(fp->firewire_shost, LINKADDR_IEEE1394, FIREWIRE_EUI64_LEN));
 
+       firewire_type = EXTRACT_16BITS(&fp->firewire_type);
        if (!qflag) {
                (void)printf(", ethertype %s (0x%04x)",
-                              tok2str(ethertype_values,"Unknown", ntohs(fp->firewire_type)),
-                               ntohs(fp->firewire_type));            
+                              tok2str(ethertype_values,"Unknown", firewire_type),
+                               firewire_type);
         } else {
-                (void)printf(", %s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", ntohs(fp->firewire_type)));  
+                (void)printf(", %s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", firewire_type));
         }
 
        (void)printf(", length %u: ", length);
@@ -87,7 +91,6 @@ ap1394_if_print(const struct pcap_pkthdr *h, const u_char *p)
        u_int caplen = h->caplen;
        struct firewire_header *fp;
        u_short ether_type;
-       u_short extracted_ether_type;
 
        if (caplen < FIREWIRE_HDRLEN) {
                printf("[|ap1394]");
@@ -102,11 +105,8 @@ ap1394_if_print(const struct pcap_pkthdr *h, const u_char *p)
        fp = (struct firewire_header *)p;
        p += FIREWIRE_HDRLEN;
 
-       ether_type = ntohs(fp->firewire_type);
-
-       extracted_ether_type = 0;
-       if (ether_encap_print(ether_type, p, length, caplen,
-           &extracted_ether_type) == 0) {
+       ether_type = EXTRACT_16BITS(&fp->firewire_type);
+       if (ethertype_print(gndo, ether_type, p, length, caplen) == 0) {
                /* ether_type not known, print raw packet */
                if (!eflag)
                        ap1394_hdr_print((u_char *)fp, length + FIREWIRE_HDRLEN);
index 48a4303..9531f34 100644 (file)
@@ -35,6 +35,7 @@ static const char rcsid[] _U_ =
 #include <pcap.h>
 
 #include "interface.h"
+#include "extract.h"
 #include "arcnet.h"
 
 static int arcnet_encap_print(u_char arctype, const u_char *p,
@@ -151,11 +152,11 @@ arcnet_if_print(const struct pcap_pkthdr *h, const u_char *p)
                                return (caplen);
                        }
                        flag = ap->arc_flag2;
-                       seqid = ntohs(ap->arc_seqid2);
+                       seqid = EXTRACT_16BITS(&ap->arc_seqid2);
                        archdrlen = ARC_HDRNEWLEN_EXC;
                } else {
                        flag = ap->arc_flag;
-                       seqid = ntohs(ap->arc_seqid);
+                       seqid = EXTRACT_16BITS(&ap->arc_seqid);
                        archdrlen = ARC_HDRNEWLEN;
                }
        }
@@ -264,14 +265,14 @@ arcnet_encap_print(u_char arctype, const u_char *p,
 
 #ifdef INET6
        case ARCTYPE_INET6:
-               ip6_print(p, length);
+               ip6_print(gndo, p, length);
                return (1);
 #endif /*INET6*/
 
        case ARCTYPE_ARP_OLD:
        case ARCTYPE_ARP:
        case ARCTYPE_REVARP:
-         arp_print(gndo, p, length, caplen);
+               arp_print(gndo, p, length, caplen);
                return (1);
 
        case ARCTYPE_ATALK:     /* XXX was this ever used? */
index 0ca86cf..905ef46 100644 (file)
@@ -318,6 +318,7 @@ arp_print(netdissect_options *ndo,
             return;
         case ARPHRD_FRELAY:
             linkaddr = LINKADDR_FRELAY;
+            break;
         default:
             linkaddr = LINKADDR_ETHER;
             break;
index 6ea1361..0a08ef9 100644 (file)
@@ -99,14 +99,10 @@ llap_print(register const u_char *bp, u_int length)
        u_short snet;
        u_int hdrlen;
 
-       /*
-        * Our packet is on a 4-byte boundary, as we're either called
-        * directly from a top-level link-layer printer (ltalk_if_print)
-        * or from the UDP printer.  The LLAP+DDP header is a multiple
-        * of 4 bytes in length, so the DDP payload is also on a 4-byte
-        * boundary, and we don't need to align it before calling
-        * "ddp_print()".
-        */
+       if (length < sizeof(*lp)) {
+               (void)printf(" [|llap %u]", length);
+               return (length);
+       }
        lp = (const struct LAP *)bp;
        bp += sizeof(*lp);
        length -= sizeof(*lp);
@@ -115,7 +111,7 @@ llap_print(register const u_char *bp, u_int length)
 
        case lapShortDDP:
                if (length < ddpSSize) {
-                       (void)printf(" [|sddp %d]", length);
+                       (void)printf(" [|sddp %u]", length);
                        return (length);
                }
                sdp = (const struct atShortDDP *)bp;
@@ -131,7 +127,7 @@ llap_print(register const u_char *bp, u_int length)
 
        case lapDDP:
                if (length < ddpSize) {
-                       (void)printf(" [|ddp %d]", length);
+                       (void)printf(" [|ddp %u]", length);
                        return (length);
                }
                dp = (const struct atDDP *)bp;
@@ -154,7 +150,7 @@ llap_print(register const u_char *bp, u_int length)
 #endif
 
        default:
-               printf("%d > %d at-lap#%d %d",
+               printf("%d > %d at-lap#%d %u",
                    lp->src, lp->dst, lp->type, length);
                break;
        }
@@ -176,7 +172,7 @@ atalk_print(register const u_char *bp, u_int length)
             printf("AT ");
 
        if (length < ddpSize) {
-               (void)printf(" [|ddp %d]", length);
+               (void)printf(" [|ddp %u]", length);
                return;
        }
        dp = (const struct atDDP *)bp;
@@ -213,7 +209,7 @@ aarp_print(register const u_char *bp, u_int length)
 
                case 2:                         /* response */
                        (void)printf("reply %s is-at %s",
-                           AT(pdaddr), etheraddr_string(ap->hdaddr));
+                           AT(psaddr), etheraddr_string(ap->hsaddr));
                        return;
 
                case 3:                         /* probe (oy!) */
@@ -265,6 +261,10 @@ atp_print(register const struct atATP *ap, u_int length)
                fputs(tstr, stdout);
                return;
        }
+       if (length < sizeof(*ap)) {
+               (void)printf(" [|atp %u]", length);
+               return;
+       }
        length -= sizeof(*ap);
        switch (ap->control & 0xc0) {
 
@@ -276,7 +276,7 @@ atp_print(register const struct atATP *ap, u_int length)
                atp_bitmap_print(ap->bitmap);
 
                if (length != 0)
-                       (void)printf(" [len=%d]", length);
+                       (void)printf(" [len=%u]", length);
 
                switch (ap->control & (atpEOM|atpSTS)) {
                case atpEOM:
@@ -292,7 +292,7 @@ atp_print(register const struct atATP *ap, u_int length)
                break;
 
        case atpRspCode:
-               (void)printf(" atp-resp%s%d:%d (%d)",
+               (void)printf(" atp-resp%s%d:%d (%u)",
                             ap->control & atpEOM? "*" : " ",
                             EXTRACT_16BITS(&ap->transID), ap->bitmap, length);
                switch (ap->control & (atpXO|atpSTS)) {
@@ -315,7 +315,7 @@ atp_print(register const struct atATP *ap, u_int length)
 
                /* length should be zero */
                if (length)
-                       (void)printf(" [len=%d]", length);
+                       (void)printf(" [len=%u]", length);
 
                /* there shouldn't be any control flags */
                if (ap->control & (atpXO|atpEOM|atpSTS)) {
@@ -337,7 +337,7 @@ atp_print(register const struct atATP *ap, u_int length)
                break;
 
        default:
-               (void)printf(" atp-0x%x  %d (%d)", ap->control,
+               (void)printf(" atp-0x%x  %d (%u)", ap->control,
                             EXTRACT_16BITS(&ap->transID), length);
                break;
        }
@@ -387,14 +387,14 @@ nbp_print(register const struct atNBP *np, u_int length, register u_short snet,
        const u_char *ep;
 
        if (length < nbpHeaderSize) {
-               (void)printf(" truncated-nbp %d", length);
+               (void)printf(" truncated-nbp %u", length);
                return;
        }
 
        length -= nbpHeaderSize;
        if (length < 8) {
                /* must be room for at least one tuple */
-               (void)printf(" truncated-nbp %d", length + nbpHeaderSize);
+               (void)printf(" truncated-nbp %u", length + nbpHeaderSize);
                return;
        }
        /* ep points to end of available data */
@@ -439,7 +439,7 @@ nbp_print(register const struct atNBP *np, u_int length, register u_short snet,
                break;
 
        default:
-               (void)printf(" nbp-0x%x  %d (%d)", np->control, np->id,
+               (void)printf(" nbp-0x%x  %d (%u)", np->control, np->id,
                                length);
                break;
        }
@@ -551,26 +551,24 @@ ataddr_string(u_short atnet, u_char athost)
        if (first && (first = 0, !nflag)
            && (fp = fopen("/etc/atalk.names", "r"))) {
                char line[256];
-               int i1, i2, i3;
+               int i1, i2;
 
                while (fgets(line, sizeof(line), fp)) {
                        if (line[0] == '\n' || line[0] == 0 || line[0] == '#')
                                continue;
-                       if (sscanf(line, "%d.%d.%d %256s", &i1, &i2, &i3,
-                                    nambuf) == 4)
+                       if (sscanf(line, "%d.%d %256s", &i1, &i2, nambuf) == 3)
                                /* got a hostname. */
-                               i3 |= ((i1 << 8) | i2) << 8;
-                       else if (sscanf(line, "%d.%d %256s", &i1, &i2,
-                                       nambuf) == 3)
+                               i2 |= (i1 << 8);
+                       else if (sscanf(line, "%d %256s", &i1, nambuf) == 2)
                                /* got a net name */
-                               i3 = (((i1 << 8) | i2) << 8) | 255;
+                               i2 = (i1 << 8) | 255;
                        else
                                continue;
 
-                       for (tp = &hnametable[i3 & (HASHNAMESIZE-1)];
+                       for (tp = &hnametable[i2 & (HASHNAMESIZE-1)];
                             tp->nxt; tp = tp->nxt)
                                ;
-                       tp->addr = i3;
+                       tp->addr = i2;
                        tp->nxt = newhnamemem();
                        tp->name = strdup(nambuf);
                }
@@ -596,11 +594,9 @@ ataddr_string(u_short atnet, u_char athost)
        tp->addr = (atnet << 8) | athost;
        tp->nxt = newhnamemem();
        if (athost != 255)
-               (void)snprintf(nambuf, sizeof(nambuf), "%d.%d.%d",
-                   atnet >> 8, atnet & 0xff, athost);
+               (void)snprintf(nambuf, sizeof(nambuf), "%d.%d", atnet, athost);
        else
-               (void)snprintf(nambuf, sizeof(nambuf), "%d.%d", atnet >> 8,
-                   atnet & 0xff);
+               (void)snprintf(nambuf, sizeof(nambuf), "%d", atnet);
        tp->name = strdup(nambuf);
 
        return (tp->name);
index f50918b..935d182 100644 (file)
@@ -20,7 +20,7 @@
  */
 #ifndef lint
 static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-atm.c,v 1.48.2.1 2007-10-22 19:39:12 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-atm.c,v 1.49 2007-10-22 19:37:51 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -270,10 +270,12 @@ sig_print(const u_char *p, int caplen)
                printf(":%s ",
                    tok2str(msgtype2str, "msgtype#%d", p[MSG_TYPE_POS]));
 
-               if (caplen < CALL_REF_POS+3) {
-                       printf("[|atm]");
-                       return;
-               }
+               /*
+                * The call reference comes before the message type,
+                * so if we know we have the message type, which we
+                * do from the caplen test above, we also know we have
+                * the call reference.
+                */
                call_ref = EXTRACT_24BITS(&p[CALL_REF_POS]);
                printf("CALL_REF:0x%06x", call_ref);
        } else {
diff --git a/contrib/tcpdump/print-babel.c b/contrib/tcpdump/print-babel.c
new file mode 100644 (file)
index 0000000..e787f8b
--- /dev/null
@@ -0,0 +1,414 @@
+/*
+ * Copyright (c) 2007-2011 GrĂ©goire Henry, Juliusz Chroboczek
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "addrtoname.h"
+#include "interface.h"
+#include "extract.h"
+
+static void babel_print_v2(const u_char *cp, u_int length);
+
+void
+babel_print(const u_char *cp, u_int length) {
+    printf("babel");
+
+    TCHECK2(*cp, 4);
+
+    if(cp[0] != 42) {
+        printf(" malformed header");
+        return;
+    } else {
+        printf(" %d", cp[1]);
+    }
+
+    switch(cp[1]) {
+    case 2:
+        babel_print_v2(cp,length);
+        break;
+    default:
+        printf(" unknown version");
+        break;
+    }
+
+    return;
+
+ trunc:
+    printf(" [|babel]");
+    return;
+}
+
+#define MESSAGE_PAD1 0
+#define MESSAGE_PADN 1
+#define MESSAGE_ACK_REQ 2
+#define MESSAGE_ACK 3
+#define MESSAGE_HELLO 4
+#define MESSAGE_IHU 5
+#define MESSAGE_ROUTER_ID 6
+#define MESSAGE_NH 7
+#define MESSAGE_UPDATE 8
+#define MESSAGE_REQUEST 9
+#define MESSAGE_MH_REQUEST 10
+
+static const char *
+format_id(const u_char *id)
+{
+    static char buf[25];
+    snprintf(buf, 25, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
+             id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7]);
+    buf[24] = '\0';
+    return buf;
+}
+
+static const unsigned char v4prefix[16] =
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 };
+
+static const char *
+format_prefix(const u_char *prefix, unsigned char plen)
+{
+    static char buf[50];
+    if(plen >= 96 && memcmp(prefix, v4prefix, 12) == 0)
+        snprintf(buf, 50, "%s/%u", ipaddr_string(prefix + 12), plen - 96);
+    else
+        snprintf(buf, 50, "%s/%u", ip6addr_string(prefix), plen);
+    buf[49] = '\0';
+    return buf;
+}
+
+static const char *
+format_address(const u_char *prefix)
+{
+    if(memcmp(prefix, v4prefix, 12) == 0)
+        return ipaddr_string(prefix + 12);
+    else
+        return ip6addr_string(prefix);
+}
+
+static int
+network_prefix(int ae, int plen, unsigned int omitted,
+               const unsigned char *p, const unsigned char *dp,
+               unsigned int len, unsigned char *p_r)
+{
+    unsigned pb;
+    unsigned char prefix[16];
+
+    if(plen >= 0)
+        pb = (plen + 7) / 8;
+    else if(ae == 1)
+        pb = 4;
+    else
+        pb = 16;
+
+    if(pb > 16)
+        return -1;
+
+    memset(prefix, 0, 16);
+
+    switch(ae) {
+    case 0: break;
+    case 1:
+        if(omitted > 4 || pb > 4 || (pb > omitted && len < pb - omitted))
+            return -1;
+        memcpy(prefix, v4prefix, 12);
+        if(omitted) {
+            if (dp == NULL) return -1;
+            memcpy(prefix, dp, 12 + omitted);
+        }
+        if(pb > omitted) memcpy(prefix + 12 + omitted, p, pb - omitted);
+        break;
+    case 2:
+        if(omitted > 16 || (pb > omitted && len < pb - omitted))
+            return -1;
+        if(omitted) {
+            if (dp == NULL) return -1;
+            memcpy(prefix, dp, omitted);
+        }
+        if(pb > omitted) memcpy(prefix + omitted, p, pb - omitted);
+        break;
+    case 3:
+        if(pb > 8 && len < pb - 8) return -1;
+        prefix[0] = 0xfe;
+        prefix[1] = 0x80;
+        if(pb > 8) memcpy(prefix + 8, p, pb - 8);
+        break;
+    default:
+        return -1;
+    }
+
+    memcpy(p_r, prefix, 16);
+    return 1;
+}
+
+static int
+network_address(int ae, const unsigned char *a, unsigned int len,
+                unsigned char *a_r)
+{
+    return network_prefix(ae, -1, 0, a, NULL, len, a_r);
+}
+
+#define ICHECK(i, l) \
+       if ((i) + (l) > bodylen || (i) + (l) > length) goto corrupt;
+
+static void
+babel_print_v2(const u_char *cp, u_int length) {
+    u_int i;
+    u_short bodylen;
+    u_char v4_prefix[16] =
+        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 };
+    u_char v6_prefix[16] = {0};
+
+    TCHECK2(*cp, 4);
+    if (length < 4)
+        goto corrupt;
+    bodylen = EXTRACT_16BITS(cp + 2);
+    printf(" (%u)", bodylen);
+
+    /* Process the TLVs in the body */
+    i = 0;
+    while(i < bodylen) {
+        const u_char *message;
+        u_char type, len;
+
+        message = cp + 4 + i;
+        TCHECK2(*message, 2);
+        ICHECK(i, 2);
+        type = message[0];
+        len = message[1];
+
+        TCHECK2(*message, 2 + len);
+        ICHECK(i, 2 + len);
+
+        switch(type) {
+        case MESSAGE_PAD1: {
+            if(!vflag)
+                printf(" pad1");
+            else
+                printf("\n\tPad 1");
+        }
+            break;
+
+        case MESSAGE_PADN: {
+            if(!vflag)
+                printf(" padN");
+            else
+                printf("\n\tPad %d", len + 2);
+        }
+            break;
+
+        case MESSAGE_ACK_REQ: {
+            u_short nonce, interval;
+            if(!vflag)
+                printf(" ack-req");
+            else {
+                printf("\n\tAcknowledgment Request ");
+                if(len < 6) goto corrupt;
+                nonce = EXTRACT_16BITS(message + 4);
+                interval = EXTRACT_16BITS(message + 6);
+                printf("%04x %d", nonce, interval);
+            }
+        }
+            break;
+
+        case MESSAGE_ACK: {
+            u_short nonce;
+            if(!vflag)
+                printf(" ack");
+            else {
+                printf("\n\tAcknowledgment ");
+                if(len < 2) goto corrupt;
+                nonce = EXTRACT_16BITS(message + 2);
+                printf("%04x", nonce);
+            }
+        }
+            break;
+
+        case MESSAGE_HELLO:  {
+            u_short seqno, interval;
+            if(!vflag)
+                printf(" hello");
+            else {
+                printf("\n\tHello ");
+                if(len < 6) goto corrupt;
+                seqno = EXTRACT_16BITS(message + 4);
+                interval = EXTRACT_16BITS(message + 6);
+                printf("seqno %u interval %u", seqno, interval);
+            }
+        }
+            break;
+
+        case MESSAGE_IHU: {
+            unsigned short txcost, interval;
+            if(!vflag)
+                printf(" ihu");
+            else {
+                u_char address[16];
+                int rc;
+                printf("\n\tIHU ");
+                if(len < 6) goto corrupt;
+                txcost = EXTRACT_16BITS(message + 4);
+                interval = EXTRACT_16BITS(message + 6);
+                rc = network_address(message[2], message + 8, len - 6, address);
+                if(rc < 0) { printf("[|babel]"); break; }
+                printf("%s txcost %u interval %d",
+                       format_address(address), txcost, interval);
+            }
+        }
+            break;
+
+        case MESSAGE_ROUTER_ID: {
+            if(!vflag)
+                printf(" router-id");
+            else {
+                printf("\n\tRouter Id");
+                if(len < 10) goto corrupt;
+                printf(" %s", format_id(message + 4));
+            }
+        }
+            break;
+
+        case MESSAGE_NH: {
+            if(!vflag)
+                printf(" nh");
+            else {
+                int rc;
+                u_char nh[16];
+                printf("\n\tNext Hop");
+                if(len < 2) goto corrupt;
+                rc = network_address(message[2], message + 4, len - 2, nh);
+                if(rc < 0) goto corrupt;
+                printf(" %s", format_address(nh));
+            }
+        }
+            break;
+
+        case MESSAGE_UPDATE: {
+            if(!vflag) {
+                printf(" update");
+                if(len < 1)
+                    printf("/truncated");
+                else
+                    printf("%s%s%s",
+                           (message[3] & 0x80) ? "/prefix": "",
+                           (message[3] & 0x40) ? "/id" : "",
+                           (message[3] & 0x3f) ? "/unknown" : "");
+            } else {
+                u_short interval, seqno, metric;
+                u_char plen;
+                int rc;
+                u_char prefix[16];
+                printf("\n\tUpdate");
+                if(len < 10) goto corrupt;
+                plen = message[4] + (message[2] == 1 ? 96 : 0);
+                rc = network_prefix(message[2], message[4], message[5],
+                                    message + 12,
+                                    message[2] == 1 ? v4_prefix : v6_prefix,
+                                    len - 10, prefix);
+                if(rc < 0) goto corrupt;
+                interval = EXTRACT_16BITS(message + 6);
+                seqno = EXTRACT_16BITS(message + 8);
+                metric = EXTRACT_16BITS(message + 10);
+                printf("%s%s%s %s metric %u seqno %u interval %u",
+                       (message[3] & 0x80) ? "/prefix": "",
+                       (message[3] & 0x40) ? "/id" : "",
+                       (message[3] & 0x3f) ? "/unknown" : "",
+                       format_prefix(prefix, plen),
+                       metric, seqno, interval);
+                if(message[3] & 0x80) {
+                    if(message[2] == 1)
+                        memcpy(v4_prefix, prefix, 16);
+                    else
+                        memcpy(v6_prefix, prefix, 16);
+                }
+            }
+        }
+            break;
+
+        case MESSAGE_REQUEST: {
+            if(!vflag)
+                printf(" request");
+            else {
+                int rc;
+                u_char prefix[16], plen;
+                printf("\n\tRequest ");
+                if(len < 2) goto corrupt;
+                plen = message[3] + (message[2] == 1 ? 96 : 0);
+                rc = network_prefix(message[2], message[3], 0,
+                                    message + 4, NULL, len - 2, prefix);
+                if(rc < 0) goto corrupt;
+                plen = message[3] + (message[2] == 1 ? 96 : 0);
+                printf("for %s",
+                       message[2] == 0 ? "any" : format_prefix(prefix, plen));
+            }
+        }
+            break;
+
+        case MESSAGE_MH_REQUEST : {
+            if(!vflag)
+                printf(" mh-request");
+            else {
+                int rc;
+                u_short seqno;
+                u_char prefix[16], plen;
+                printf("\n\tMH-Request ");
+                if(len < 14) goto corrupt;
+                seqno = EXTRACT_16BITS(message + 4);
+                rc = network_prefix(message[2], message[3], 0,
+                                    message + 16, NULL, len - 14, prefix);
+                if(rc < 0) goto corrupt;
+                plen = message[3] + (message[2] == 1 ? 96 : 0);
+                printf("(%u hops) for %s seqno %u id %s",
+                       message[6], format_prefix(prefix, plen),
+                       seqno, format_id(message + 8));
+            }
+        }
+            break;
+        default:
+            if(!vflag)
+                printf(" unknown");
+            else
+                printf("\n\tUnknown message type %d", type);
+        }
+        i += len + 2;
+    }
+    return;
+
+ trunc:
+    printf(" [|babel]");
+    return;
+
+ corrupt:
+    printf(" (corrupt)");
+    return;
+}
index 6406168..f157684 100644 (file)
@@ -171,13 +171,17 @@ bfd_print(register const u_char *pptr, register u_int len, register u_int port)
 {
         const struct bfd_header_t *bfd_header;
         const struct bfd_auth_header_t *bfd_auth_header;
-        u_int8_t version;
+        u_int8_t version = 0;
 
         bfd_header = (const struct bfd_header_t *)pptr;
-        TCHECK(*bfd_header);
-        version = BFD_EXTRACT_VERSION(bfd_header->version_diag);
-
-        switch (port << 8 | version) {
+        if (port == BFD_CONTROL_PORT) {
+            TCHECK(*bfd_header);
+            version = BFD_EXTRACT_VERSION(bfd_header->version_diag);
+        } else if (port == BFD_ECHO_PORT) {
+            /* Echo is BFD v1 only */
+            version = 1;
+        }
+        switch ((port << 8) | version) {
 
             /* BFDv0 */
         case (BFD_CONTROL_PORT << 8):
index 2dfdf52..6460a59 100644 (file)
@@ -36,7 +36,7 @@
 
 #ifndef lint
 static const char rcsid[] _U_ =
-     "@(#) $Header: /tcpdump/master/tcpdump/print-bgp.c,v 1.117.2.1 2007-12-08 10:08:07 hannes Exp $";
+     "@(#) $Header: /tcpdump/master/tcpdump/print-bgp.c,v 1.118 2007-12-07 15:54:52 hannes Exp $";
 #endif
 
 #include <tcpdump-stdinc.h>
@@ -346,7 +346,8 @@ static struct tok bgp_pmsi_flag_values[] = {
 #define SAFNUM_MULTICAST_VPN            5
 #define SAFNUM_TUNNEL                   64 /* XXX */
 #define SAFNUM_VPLS                     65 /* XXX */
-#define SAFNUM_MDT                      66 /* XXX */
+/* draft-nalawade-idr-mdt-safi-03 */
+#define SAFNUM_MDT                      66
 /* Section 4.3.4 of draft-rosen-rfc2547bis-03.txt  */
 #define SAFNUM_VPNUNICAST               128
 #define SAFNUM_VPNMULTICAST             129
@@ -400,8 +401,11 @@ static struct tok bgp_safi_values[] = {
 
 #define BGP_EXT_COM_L2INFO      0x800a  /* draft-kompella-ppvpn-l2vpn */
 
-#define BGP_EXT_COM_SOURCE_AS   0x0009  /* draft-ietf-l3vpn-2547bis-mcast-bgp-02.txt */
-#define BGP_EXT_COM_VRF_RT_IMP  0x010a  /* draft-ietf-l3vpn-2547bis-mcast-bgp-02.txt */
+#define BGP_EXT_COM_SOURCE_AS   0x0009  /* RFC-ietf-l3vpn-2547bis-mcast-bgp-08.txt */
+#define BGP_EXT_COM_VRF_RT_IMP  0x010b  /* RFC-ietf-l3vpn-2547bis-mcast-bgp-08.txt */
+#define BGP_EXT_COM_L2VPN_RT_0  0x000a  /* L2VPN Identifier,Format AS(2bytes):AN(4bytes) */
+#define BGP_EXT_COM_L2VPN_RT_1  0xF10a  /* L2VPN Identifier,Format IP address:AN(2bytes) */
+
 
 /* http://www.cisco.com/en/US/tech/tk436/tk428/technologies_tech_note09186a00801eb09a.shtml  */
 #define BGP_EXT_COM_EIGRP_GEN   0x8800
@@ -442,6 +446,8 @@ static struct tok bgp_extd_comm_subtype_values[] = {
     { BGP_EXT_COM_EIGRP_EXT_REMPROTO_REMMETRIC , "eigrp-external-route (remote-proto, remote-metric)" },
     { BGP_EXT_COM_SOURCE_AS, "source-AS" },
     { BGP_EXT_COM_VRF_RT_IMP, "vrf-route-import"},
+    { BGP_EXT_COM_L2VPN_RT_0, "l2vpn-id"},
+    { BGP_EXT_COM_L2VPN_RT_1, "l2vpn-id"},
     { 0, NULL},
 };
 
@@ -464,6 +470,29 @@ static struct tok bgp_extd_comm_ospf_rtype_values[] = {
   { 0, NULL },
 };
 
+#define TOKBUFSIZE 128
+static char astostr[20];
+
+/*
+ * as_printf
+ *
+ * Convert an AS number into a string and return string pointer.
+ *
+ * Bepending on bflag is set or not, AS number is converted into ASDOT notation
+ * or plain number notation.
+ *
+ */
+static char *
+as_printf (char *str, int size, u_int asnum)
+{
+       if (!bflag || asnum <= 0xFFFF) {
+               snprintf(str, size, "%u", asnum);
+       } else {
+               snprintf(str, size, "%u.%u", asnum >> 16, asnum & 0xFFFF);
+       }
+       return str;
+}
+
 int
 decode_prefix4(const u_char *pptr, char *buf, u_int buflen)
 {
@@ -656,9 +685,10 @@ bgp_vpn_rd_print (const u_char *pptr) {
 
         /* 4-byte-AS:number fmt*/
     case 2:
-        snprintf(pos, sizeof(rd) - (pos - rd), "%u:%u (%u.%u.%u.%u:%u)",
-            EXTRACT_32BITS(pptr+2), EXTRACT_16BITS(pptr+6),
-            *(pptr+2), *(pptr+3), *(pptr+4), *(pptr+5), EXTRACT_16BITS(pptr+6));
+       snprintf(pos, sizeof(rd) - (pos - rd), "%s:%u (%u.%u.%u.%u:%u)",
+           as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(pptr+2)),
+           EXTRACT_16BITS(pptr+6), *(pptr+2), *(pptr+3), *(pptr+4),
+           *(pptr+5), EXTRACT_16BITS(pptr+6));
         break;
     default:
         snprintf(pos, sizeof(rd) - (pos - rd), "unknown RD format");
@@ -696,9 +726,9 @@ decode_rt_routing_info(const u_char *pptr, char *buf, u_int buflen)
                ((u_char *)&route_target)[(plen + 7) / 8 - 1] &=
                        ((0xff00 >> (plen % 8)) & 0xff);
        }
-       snprintf(buf, buflen, "origin AS: %u, route target %s",
-                 EXTRACT_32BITS(pptr+1),
-                 bgp_vpn_rd_print((u_char *)&route_target));
+       snprintf(buf, buflen, "origin AS: %s, route target %s",
+           as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(pptr+1)),
+           bgp_vpn_rd_print((u_char *)&route_target));
 
        return 5 + (plen + 7) / 8;
 
@@ -744,6 +774,55 @@ trunc:
        return -2;
 }
 
+/*
+ * +-------------------------------+
+ * |                               |
+ * |  RD:IPv4-address (12 octets)  |
+ * |                               |
+ * +-------------------------------+
+ * |  MDT Group-address (4 octets) |
+ * +-------------------------------+
+ */
+
+#define MDT_VPN_NLRI_LEN 16
+
+static int
+decode_mdt_vpn_nlri(const u_char *pptr, char *buf, u_int buflen)
+{
+
+    const u_char *rd;
+    const u_char *vpn_ip;
+    
+    TCHECK(pptr[0]);
+
+    /* if the NLRI is not predefined length, quit.*/
+    if (*pptr != MDT_VPN_NLRI_LEN * NBBY)
+       return -1;
+    pptr++;
+
+    /* RD */
+    TCHECK2(pptr[0], 8);
+    rd = pptr;
+    pptr+=8;
+
+    /* IPv4 address */
+    TCHECK2(pptr[0], sizeof(struct in_addr));
+    vpn_ip = pptr;
+    pptr+=sizeof(struct in_addr);
+
+    /* MDT Group Address */
+    TCHECK2(pptr[0], sizeof(struct in_addr));
+
+    snprintf(buf, buflen, "RD: %s, VPN IP Address: %s, MC Group Address: %s",
+            bgp_vpn_rd_print(rd), ipaddr_string(vpn_ip), ipaddr_string(pptr));
+       
+    return MDT_VPN_NLRI_LEN + 1;
+
+ trunc:
+
+return -2;
+}
+
 #define BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI   1
 #define BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI   2
 #define BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI            3
@@ -789,9 +868,10 @@ decode_multicast_vpn(const u_char *pptr, char *buf, u_int buflen)
         case BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI:
             TCHECK2(pptr[0], BGP_VPN_RD_LEN + 4);
             offset = strlen(buf);
-            snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %u",
-                     bgp_vpn_rd_print(pptr),
-                     EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN));
+           snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s",
+               bgp_vpn_rd_print(pptr),
+               as_printf(astostr, sizeof(astostr),
+               EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN)));
             break;
 
         case BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI:
@@ -824,9 +904,10 @@ decode_multicast_vpn(const u_char *pptr, char *buf, u_int buflen)
         case BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN:
             TCHECK2(pptr[0], BGP_VPN_RD_LEN);
             offset = strlen(buf);
-            snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %u",
-                     bgp_vpn_rd_print(pptr),
-                     EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN));
+           snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s",
+               bgp_vpn_rd_print(pptr),
+               as_printf(astostr, sizeof(astostr),
+               EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN)));
             pptr += BGP_VPN_RD_LEN;
 
             bgp_vpn_sg_print(pptr, buf, buflen);
@@ -875,57 +956,84 @@ decode_labeled_vpn_l2(const u_char *pptr, char *buf, u_int buflen)
         plen=EXTRACT_16BITS(pptr);
         tlen=plen;
         pptr+=2;
-       TCHECK2(pptr[0],15);
-       buf[0]='\0';
-        strlen=snprintf(buf, buflen, "RD: %s, CE-ID: %u, Label-Block Offset: %u, Label Base %u",
-                        bgp_vpn_rd_print(pptr),
-                        EXTRACT_16BITS(pptr+8),
-                        EXTRACT_16BITS(pptr+10),
-                        EXTRACT_24BITS(pptr+12)>>4); /* the label is offsetted by 4 bits so lets shift it right */
-        UPDATE_BUF_BUFLEN(buf, buflen, strlen);
-        pptr+=15;
-        tlen-=15;
-
-        /* ok now the variable part - lets read out TLVs*/
-        while (tlen>0) {
-            if (tlen < 3)
-                return -1;
-            TCHECK2(pptr[0], 3);
-            tlv_type=*pptr++;
-            tlv_len=EXTRACT_16BITS(pptr);
-            ttlv_len=tlv_len;
-            pptr+=2;
-
-            switch(tlv_type) {
-            case 1:
-                if (buflen!=0) {
-                    strlen=snprintf(buf,buflen, "\n\t\tcircuit status vector (%u) length: %u: 0x",
-                                    tlv_type,
-                                    tlv_len);
-                    UPDATE_BUF_BUFLEN(buf, buflen, strlen);
-                }
-                ttlv_len=ttlv_len/8+1; /* how many bytes do we need to read ? */
-                while (ttlv_len>0) {
-                    TCHECK(pptr[0]);
-                    if (buflen!=0) {
-                        strlen=snprintf(buf,buflen, "%02x",*pptr++);
-                        UPDATE_BUF_BUFLEN(buf, buflen, strlen);
-                    }
-                    ttlv_len--;
-                }
-                break;
-            default:
-                if (buflen!=0) {
-                    strlen=snprintf(buf,buflen, "\n\t\tunknown TLV #%u, length: %u",
-                                    tlv_type,
-                                    tlv_len);
-                    UPDATE_BUF_BUFLEN(buf, buflen, strlen);
-                }
-                break;
-            }
-            tlen-=(tlv_len<<3); /* the tlv-length is expressed in bits so lets shift it right */
+       /* Old and new L2VPN NLRI share AFI/SAFI
+         *   -> Assume a 12 Byte-length NLRI is auto-discovery-only
+         *      and > 17 as old format. Complain for the middle case
+         */
+        if (plen==12) { 
+           /* assume AD-only with RD, BGPNH */
+           TCHECK2(pptr[0],12);
+           buf[0]='\0';
+           strlen=snprintf(buf, buflen, "RD: %s, BGPNH: %s",
+                           bgp_vpn_rd_print(pptr), 
+                           /* need something like getname() here */
+                           getname(pptr+8)
+                           );
+           UPDATE_BUF_BUFLEN(buf, buflen, strlen);
+           pptr+=12;
+           tlen-=12;
+           return plen;
+        } else if (plen>17) { 
+           /* assume old format */
+           /* RD, ID, LBLKOFF, LBLBASE */
+
+           TCHECK2(pptr[0],15);
+           buf[0]='\0';
+           strlen=snprintf(buf, buflen, "RD: %s, CE-ID: %u, Label-Block Offset: %u, Label Base %u",
+                           bgp_vpn_rd_print(pptr),
+                           EXTRACT_16BITS(pptr+8),
+                           EXTRACT_16BITS(pptr+10),
+                           EXTRACT_24BITS(pptr+12)>>4); /* the label is offsetted by 4 bits so lets shift it right */
+           UPDATE_BUF_BUFLEN(buf, buflen, strlen);
+           pptr+=15;
+           tlen-=15;
+
+           /* ok now the variable part - lets read out TLVs*/
+           while (tlen>0) {
+               if (tlen < 3)
+                   return -1;
+               TCHECK2(pptr[0], 3);
+               tlv_type=*pptr++;
+               tlv_len=EXTRACT_16BITS(pptr);
+               ttlv_len=tlv_len;
+               pptr+=2;
+
+               switch(tlv_type) {
+               case 1:
+                   if (buflen!=0) {
+                       strlen=snprintf(buf,buflen, "\n\t\tcircuit status vector (%u) length: %u: 0x",
+                                       tlv_type,
+                                       tlv_len);
+                       UPDATE_BUF_BUFLEN(buf, buflen, strlen);
+                   }
+                   ttlv_len=ttlv_len/8+1; /* how many bytes do we need to read ? */
+                   while (ttlv_len>0) {
+                       TCHECK(pptr[0]);
+                       if (buflen!=0) {
+                           strlen=snprintf(buf,buflen, "%02x",*pptr++);
+                           UPDATE_BUF_BUFLEN(buf, buflen, strlen);
+                       }
+                       ttlv_len--;
+                   }
+                   break;
+               default:
+                   if (buflen!=0) {
+                       strlen=snprintf(buf,buflen, "\n\t\tunknown TLV #%u, length: %u",
+                                       tlv_type,
+                                       tlv_len);
+                       UPDATE_BUF_BUFLEN(buf, buflen, strlen);
+                   }
+                   break;
+               }
+               tlen-=(tlv_len<<3); /* the tlv-length is expressed in bits so lets shift it right */
+           }
+           return plen+2;
+           
+        } else {
+           /* complain bitterly ? */
+           /* fall through */
+            goto trunc;
         }
-        return plen+2;
 
 trunc:
         return -2;
@@ -1222,9 +1330,11 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len)
                                                tokbuf, sizeof(tokbuf)));
                         for (i = 0; i < tptr[1] * as_size; i += as_size) {
                             TCHECK2(tptr[2 + i], as_size);
-                            printf("%u ",
-                                   as_size == 2 ?  EXTRACT_16BITS(&tptr[2 + i]) :
-                                                   EXTRACT_32BITS(&tptr[2 + i]));
+                           printf("%s ",
+                               as_printf(astostr, sizeof(astostr),
+                               as_size == 2 ? 
+                               EXTRACT_16BITS(&tptr[2 + i]) :
+                               EXTRACT_32BITS(&tptr[2 + i])));
                         }
                        TCHECK(tptr[0]);
                         printf("%s", tok2strbuf(bgp_as_path_segment_close_values,
@@ -1255,23 +1365,36 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len)
                if (len != 0)
                        printf("invalid len");
                break;
-       case BGPTYPE_AGGREGATOR:
-               if (len != 6) {
-                       printf("invalid len");
-                       break;
-               }
-               TCHECK2(tptr[0], 6);
-               printf(" AS #%u, origin %s", EXTRACT_16BITS(tptr),
+        case BGPTYPE_AGGREGATOR:
+
+                /*
+                 * Depending on the AS encoded is of 2 bytes or of 4 bytes,
+                 * the length of this PA can be either 6 bytes or 8 bytes.
+                 */
+                if (len != 6 && len != 8) {
+                    printf("invalid len");
+                    break;
+                }
+                TCHECK2(tptr[0], len);
+                if (len == 6) {
+                   printf(" AS #%s, origin %s",
+                       as_printf(astostr, sizeof(astostr), EXTRACT_16BITS(tptr)),
                        getname(tptr + 2));
-               break;
+                } else {
+                   printf(" AS #%s, origin %s",
+                       as_printf(astostr, sizeof(astostr),
+                       EXTRACT_32BITS(tptr)), getname(tptr + 4));
+                }
+                break;
        case BGPTYPE_AGGREGATOR4:
                if (len != 8) {
                        printf("invalid len");
                        break;
                }
                TCHECK2(tptr[0], 8);
-               printf(" AS #%u, origin %s", EXTRACT_32BITS(tptr),
-                       getname(tptr + 4));
+               printf(" AS #%s, origin %s",
+                   as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(tptr)),
+                   getname(tptr + 4));
                break;
        case BGPTYPE_COMMUNITIES:
                if (len % 4) {
@@ -1349,6 +1472,7 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len)
                 case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST):
                 case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST):
                 case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN):
+               case (AFNUM_INET<<8 | SAFNUM_MDT): 
 #ifdef INET6
                 case (AFNUM_INET6<<8 | SAFNUM_UNICAST):
                 case (AFNUM_INET6<<8 | SAFNUM_MULTICAST):
@@ -1395,7 +1519,8 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len)
                         case (AFNUM_INET<<8 | SAFNUM_LABUNICAST):
                         case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO):
                         case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN):
-                            if (tlen < (int)sizeof(struct in_addr)) {
+                        case (AFNUM_INET<<8 | SAFNUM_MDT):  
+                           if (tlen < (int)sizeof(struct in_addr)) {
                                 printf("invalid len");
                                 tlen = 0;
                             } else {
@@ -1579,6 +1704,16 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len)
                         else
                             printf("\n\t      %s", buf);
                         break;
+
+                   case (AFNUM_INET<<8 | SAFNUM_MDT):
+                     advance = decode_mdt_vpn_n