Merge branch 'vendor/LIBPCAP' and updated build for new version.
authorPeter Avalos <pavalos@theshell.com>
Mon, 6 Jul 2009 06:11:42 +0000 (20:11 -1000)
committerPeter Avalos <pavalos@theshell.com>
Mon, 6 Jul 2009 06:11:42 +0000 (20:11 -1000)
1  2 
contrib/libpcap/bpf/net/bpf_filter.c
contrib/libpcap/gencode.c
contrib/libpcap/grammar.y
contrib/libpcap/pcap/pcap.h
etc/mtree/BSD.include.dist
lib/libpcap/Makefile
lib/libpcap/config.h
share/man/man7/hier.7

@@@ -40,7 -40,7 +40,7 @@@
  
  #if !(defined(lint) || defined(KERNEL) || defined(_KERNEL))
  static const char rcsid[] _U_ =
-     "@(#) $Header: /tcpdump/master/libpcap/bpf/net/bpf_filter.c,v 1.44 2003/11/15 23:24:07 guy Exp $ (LBL)";
+     "@(#) $Header: /tcpdump/master/libpcap/bpf/net/bpf_filter.c,v 1.45.2.1 2008/01/02 04:22:16 guy Exp $ (LBL)";
  #endif
  
  #ifdef HAVE_CONFIG_H
@@@ -71,7 -71,7 +71,7 @@@
  
  #endif /* WIN32 */
  
 -#include <pcap/bpf.h>
 +#include <net/bpf.h>
  
  #if !defined(KERNEL) && !defined(_KERNEL)
  #include <stdlib.h>
@@@ -200,8 -200,8 +200,8 @@@ m_xhalf(m, k, err
   */
  u_int
  bpf_filter(pc, p, wirelen, buflen)
-       register struct bpf_insn *pc;
-       register u_char *p;
+       register const struct bpf_insn *pc;
+       register const u_char *p;
        u_int wirelen;
        register u_int buflen;
  {
        }
  }
  
  /*
   * Return true if the 'fcode' is a valid filter program.
   * The constraints are that each jump be forward and to a valid
-  * code.  The code must terminate with either an accept or reject.
-  * 'valid' is an array for use by the routine (it must be at least
-  * 'len' bytes long).
+  * code, that memory accesses are within valid ranges (to the
+  * extent that this can be checked statically; loads of packet
+  * data have to be, and are, also checked at run time), and that
+  * the code terminates with either an accept or reject.
   *
   * The kernel needs to be able to verify an application's filter code.
   * Otherwise, a bogus program could easily crash the system.
   */
  int
  bpf_validate(f, len)
-       struct bpf_insn *f;
+       const struct bpf_insn *f;
        int len;
  {
-       register int i;
-       register struct bpf_insn *p;
+       u_int i, from;
+       const struct bpf_insn *p;
+       if (len < 1)
+               return 0;
+       /*
+        * There's no maximum program length in userland.
+        */
+ #if defined(KERNEL) || defined(_KERNEL)
+       if (len > BPF_MAXINSNS)
+               return 0;
+ #endif
  
        for (i = 0; i < len; ++i) {
+               p = &f[i];
+               switch (BPF_CLASS(p->code)) {
                /*
-                * Check that that jumps are forward, and within
-                * the code block.
+                * Check that memory operations use valid addresses.
                 */
-               p = &f[i];
-               if (BPF_CLASS(p->code) == BPF_JMP) {
-                       register int from = i + 1;
-                       if (BPF_OP(p->code) == BPF_JA) {
-                               if (from + p->k >= (unsigned)len)
+               case BPF_LD:
+               case BPF_LDX:
+                       switch (BPF_MODE(p->code)) {
+                       case BPF_IMM:
+                               break;
+                       case BPF_ABS:
+                       case BPF_IND:
+                       case BPF_MSH:
+                               /*
+                                * There's no maximum packet data size
+                                * in userland.  The runtime packet length
+                                * check suffices.
+                                */
+ #if defined(KERNEL) || defined(_KERNEL)
+                               /*
+                                * More strict check with actual packet length
+                                * is done runtime.
+                                */
+                               if (p->k >= bpf_maxbufsize)
                                        return 0;
+ #endif
+                               break;
+                       case BPF_MEM:
+                               if (p->k >= BPF_MEMWORDS)
+                                       return 0;
+                               break;
+                       case BPF_LEN:
+                               break;
+                       default:
+                               return 0;
                        }
-                       else if (from + p->jt >= len || from + p->jf >= len)
+                       break;
+               case BPF_ST:
+               case BPF_STX:
+                       if (p->k >= BPF_MEMWORDS)
                                return 0;
-               }
-               /*
-                * Check that memory operations use valid addresses.
-                */
-               if ((BPF_CLASS(p->code) == BPF_ST ||
-                    (BPF_CLASS(p->code) == BPF_LD &&
-                     (p->code & 0xe0) == BPF_MEM)) &&
-                   (p->k >= BPF_MEMWORDS || p->k < 0))
-                       return 0;
-               /*
-                * Check for constant division by 0.
-                */
-               if (p->code == (BPF_ALU|BPF_DIV|BPF_K) && p->k == 0)
+                       break;
+               case BPF_ALU:
+                       switch (BPF_OP(p->code)) {
+                       case BPF_ADD:
+                       case BPF_SUB:
+                       case BPF_MUL:
+                       case BPF_OR:
+                       case BPF_AND:
+                       case BPF_LSH:
+                       case BPF_RSH:
+                       case BPF_NEG:
+                               break;
+                       case BPF_DIV:
+                               /*
+                                * Check for constant division by 0.
+                                */
+                               if (BPF_RVAL(p->code) == BPF_K && p->k == 0)
+                                       return 0;
+                               break;
+                       default:
+                               return 0;
+                       }
+                       break;
+               case BPF_JMP:
+                       /*
+                        * Check that jumps are within the code block,
+                        * and that unconditional branches don't go
+                        * backwards as a result of an overflow.
+                        * Unconditional branches have a 32-bit offset,
+                        * so they could overflow; we check to make
+                        * sure they don't.  Conditional branches have
+                        * an 8-bit offset, and the from address is <=
+                        * BPF_MAXINSNS, and we assume that BPF_MAXINSNS
+                        * is sufficiently small that adding 255 to it
+                        * won't overflow.
+                        *
+                        * We know that len is <= BPF_MAXINSNS, and we
+                        * assume that BPF_MAXINSNS is < the maximum size
+                        * of a u_int, so that i + 1 doesn't overflow.
+                        *
+                        * For userland, we don't know that the from
+                        * or len are <= BPF_MAXINSNS, but we know that
+                        * from <= len, and, except on a 64-bit system,
+                        * it's unlikely that len, if it truly reflects
+                        * the size of the program we've been handed,
+                        * will be anywhere near the maximum size of
+                        * a u_int.  We also don't check for backward
+                        * branches, as we currently support them in
+                        * userland for the protochain operation.
+                        */
+                       from = i + 1;
+                       switch (BPF_OP(p->code)) {
+                       case BPF_JA:
+ #if defined(KERNEL) || defined(_KERNEL)
+                               if (from + p->k < from || from + p->k >= len)
+ #else
+                               if (from + p->k >= len)
+ #endif
+                                       return 0;
+                               break;
+                       case BPF_JEQ:
+                       case BPF_JGT:
+                       case BPF_JGE:
+                       case BPF_JSET:
+                               if (from + p->jt >= len || from + p->jf >= len)
+                                       return 0;
+                               break;
+                       default:
+                               return 0;
+                       }
+                       break;
+               case BPF_RET:
+                       break;
+               case BPF_MISC:
+                       break;
+               default:
                        return 0;
+               }
        }
        return BPF_CLASS(f[len - 1].code) == BPF_RET;
  }
@@@ -21,7 -21,7 +21,7 @@@
   */
  #ifndef lint
  static const char rcsid[] _U_ =
-     "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.221.2.53 2007/09/12 19:17:24 guy Exp $ (LBL)";
+     "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.290.2.16 2008-09-22 20:16:01 guy Exp $ (LBL)";
  #endif
  
  #ifdef HAVE_CONFIG_H
  #include "nlpid.h"
  #include "llc.h"
  #include "gencode.h"
 -#include "ieee80211.h"
++#include <netproto/802_11/ieee80211.h>
  #include "atmuni31.h"
  #include "sunatmpos.h"
  #include "ppp.h"
- #include "sll.h"
+ #include "pcap/sll.h"
  #include "arcnet.h"
  #ifdef HAVE_NET_PFVAR_H
  #include <sys/socket.h>
  #include <net/if.h>
 -#include <net/pfvar.h>
 -#include <net/if_pflog.h>
 +#include <net/if_var.h>
 +#include <net/pf/pfvar.h>
 +#include <net/pf/if_pflog.h>
  #endif
  #ifndef offsetof
  #define offsetof(s, e) ((size_t)&((s *)0)->e)
  #include <netdb.h>    /* for "struct addrinfo" */
  #endif /* WIN32 */
  #endif /*INET6*/
- #include <pcap-namedb.h>
+ #include <pcap/namedb.h>
  
- #include <netproto/802_11/ieee80211.h>
 +#include <netproto/802_11/ieee80211_radiotap.h>
 +
  #define ETHERMTU      1500
  
  #ifndef IPPROTO_SCTP
  static jmp_buf top_ctx;
  static pcap_t *bpf_pcap;
  
- #ifdef WIN32
  /* Hack for updating VLAN, MPLS, and PPPoE offsets. */
+ #ifdef WIN32
  static u_int  orig_linktype = (u_int)-1, orig_nl = (u_int)-1, label_stack_depth = (u_int)-1;
  #else
  static u_int  orig_linktype = -1U, orig_nl = -1U, label_stack_depth = -1U;
@@@ -138,6 -135,7 +138,7 @@@ bpf_error(const char *fmt, ...
  
  static void init_linktype(pcap_t *);
  
+ static void init_regs(void);
  static int alloc_reg(void);
  static void free_reg(int);
  
@@@ -149,7 -147,8 +150,8 @@@ static struct block *root
   */
  enum e_offrel {
        OR_PACKET,      /* relative to the beginning of the packet */
-       OR_LINK,        /* relative to the link-layer header */
+       OR_LINK,        /* relative to the beginning of the link-layer header */
+       OR_MACPL,       /* relative to the end of the MAC-layer header */
        OR_NET,         /* relative to the network-layer header */
        OR_NET_NOSNAP,  /* relative to the network-layer header, with no SNAP header at the link layer */
        OR_TRAN_IPV4,   /* relative to the transport-layer header, with IPv4 network layer */
@@@ -194,6 -193,7 +196,7 @@@ static struct block *gen_bcmp(enum e_of
  static struct block *gen_ncmp(enum e_offrel, bpf_u_int32, bpf_u_int32,
      bpf_u_int32, bpf_u_int32, int, bpf_int32);
  static struct slist *gen_load_llrel(u_int, u_int);
+ static struct slist *gen_load_macplrel(u_int, u_int);
  static struct slist *gen_load_a(enum e_offrel, u_int, u_int);
  static struct slist *gen_loadx_iphdrlen(void);
  static struct block *gen_uncond(int);
@@@ -201,12 -201,16 +204,16 @@@ static inline struct block *gen_true(vo
  static inline struct block *gen_false(void);
  static struct block *gen_ether_linktype(int);
  static struct block *gen_linux_sll_linktype(int);
- static void insert_radiotap_load_llprefixlen(struct block *);
- static void insert_ppi_load_llprefixlen(struct block *);
- static void insert_load_llprefixlen(struct block *);
+ static struct slist *gen_load_prism_llprefixlen(void);
+ static struct slist *gen_load_avs_llprefixlen(void);
+ static struct slist *gen_load_radiotap_llprefixlen(void);
+ static struct slist *gen_load_ppi_llprefixlen(void);
+ static void insert_compute_vloffsets(struct block *);
  static struct slist *gen_llprefixlen(void);
+ static struct slist *gen_off_macpl(void);
+ static int ethertype_to_ppptype(int);
  static struct block *gen_linktype(int);
- static struct block *gen_snap(bpf_u_int32, bpf_u_int32, u_int);
+ static struct block *gen_snap(bpf_u_int32, bpf_u_int32);
  static struct block *gen_llc_linktype(int);
  static struct block *gen_hostop(bpf_u_int32, bpf_u_int32, int, int, u_int, u_int);
  #ifdef INET6
@@@ -251,6 -255,7 +258,7 @@@ static struct slist *xfer_to_x(struct a
  static struct slist *xfer_to_a(struct arth *);
  static struct block *gen_mac_multicast(int);
  static struct block *gen_len(int, int);
+ static struct block *gen_check_802_11_data_frame(void);
  
  static struct block *gen_ppi_dlt_check(void);
  static struct block *gen_msg_abbrev(int type);
@@@ -373,6 -378,7 +381,7 @@@ pcap_compile(pcap_t *p, struct bpf_prog
        n_errors = 0;
        root = NULL;
        bpf_pcap = p;
+       init_regs();
        if (setjmp(top_ctx)) {
                lex_cleanup();
                freechunks();
@@@ -488,24 -494,11 +497,11 @@@ merge(b0, b1
        *p = b1;
  }
  
  void
  finish_parse(p)
        struct block *p;
  {
        struct block *ppi_dlt_check;
-       
-       ppi_dlt_check = gen_ppi_dlt_check();
-       if (ppi_dlt_check != NULL)
-       {
-               gen_and(ppi_dlt_check, p);
-       }
-       backpatch(p, gen_retblk(snaplen));
-       p->sense = !p->sense;
-       backpatch(p, gen_retblk(0));
-       root = p->head;
  
        /*
         * Insert before the statements of the first (root) block any
         * statements of all blocks that use those lengths and that
         * have no predecessors that use them, so that we only compute
         * the lengths if we need them.  There might be even better
-        * approaches than that.  However, as we're currently only
-        * handling variable-length radiotap headers, and as all
-        * filtering expressions other than raw link[M:N] tests
-        * require the length of that header, doing more for that
-        * header length isn't really worth the effort.
+        * approaches than that.
+        *
+        * However, those strategies would be more complicated, and
+        * as we don't generate code to compute a length if the
+        * program has no tests that use the length, and as most
+        * tests will probably use those lengths, we would just
+        * postpone computing the lengths so that it's not done
+        * for tests that fail early, and it's not clear that's
+        * worth the effort.
+        */
+       insert_compute_vloffsets(p->head);
+       
+       /*
+        * For DLT_PPI captures, generate a check of the per-packet
+        * DLT value to make sure it's DLT_IEEE802_11.
         */
+       ppi_dlt_check = gen_ppi_dlt_check();
+       if (ppi_dlt_check != NULL)
+               gen_and(ppi_dlt_check, p);
  
-       insert_load_llprefixlen(root);
+       backpatch(p, gen_retblk(snaplen));
+       p->sense = !p->sense;
+       backpatch(p, gen_retblk(0));
+       root = p->head;
  }
  
  void
@@@ -686,13 -695,7 +698,7 @@@ gen_ncmp(offrel, offset, size, mask, jt
   * Various code constructs need to know the layout of the data link
   * layer.  These variables give the necessary offsets from the beginning
   * of the packet data.
-  *
-  * If the link layer has variable_length headers, the offsets are offsets
-  * from the end of the link-link-layer header, and "reg_ll_size" is
-  * the register number for a register containing the length of the
-  * link-layer header.  Otherwise, "reg_ll_size" is -1.
   */
- static int reg_ll_size;
  
  /*
   * This is the offset of the beginning of the link-layer header from
  static u_int off_ll;
  
  /*
-  * This is the offset of the beginning of the MAC-layer header.
+  * If there's a variable-length header preceding the link-layer header,
+  * "reg_off_ll" is the register number for a register containing the
+  * length of that header, and therefore the offset of the link-layer
+  * header from the beginning of the raw packet data.  Otherwise,
+  * "reg_off_ll" is -1.
+  */
+ static int reg_off_ll;
+ /*
+  * This is the offset of the beginning of the MAC-layer header from
+  * the beginning of the link-layer header.
   * It's usually 0, except for ATM LANE, where it's the offset, relative
   * to the beginning of the raw packet data, of the Ethernet header.
   */
  static u_int off_mac;
  
+ /*
+  * This is the offset of the beginning of the MAC-layer payload,
+  * from the beginning of the raw packet data.
+  *
+  * I.e., it's the sum of the length of the link-layer header (without,
+  * for example, any 802.2 LLC header, so it's the MAC-layer
+  * portion of that header), plus any prefix preceding the
+  * link-layer header.
+  */
+ static u_int off_macpl;
+ /*
+  * This is 1 if the offset of the beginning of the MAC-layer payload
+  * from the beginning of the link-layer header is variable-length.
+  */
+ static int off_macpl_is_variable;
+ /*
+  * If the link layer has variable_length headers, "reg_off_macpl"
+  * is the register number for a register containing the length of the
+  * link-layer header plus the length of any variable-length header
+  * preceding the link-layer header.  Otherwise, "reg_off_macpl"
+  * is -1.
+  */
+ static int reg_off_macpl;
  /*
   * "off_linktype" is the offset to information in the link-layer header
   * giving the packet type.  This offset is relative to the beginning
   */
  static u_int off_linktype;
  
+ /*
+  * TRUE if "pppoes" appeared in the filter; it causes link-layer type
+  * checks to check the PPP header, assumed to follow a LAN-style link-
+  * layer header and a PPPoE session header.
+  */
+ static int is_pppoes = 0;
  /*
   * TRUE if the link layer includes an ATM pseudo-header.
   */
@@@ -772,8 -818,8 +821,8 @@@ static u_int off_payload
  
  /*
   * These are offsets to the beginning of the network-layer header.
-  * They are relative to the beginning of the link-layer header (i.e.,
-  * they don't include off_ll).
+  * They are relative to the beginning of the MAC-layer payload (i.e.,
+  * they don't include off_ll or off_macpl).
   *
   * If the link layer never uses 802.2 LLC:
   *
@@@ -819,6 -865,11 +868,11 @@@ init_linktype(p
        off_proto = -1;
        off_payload = -1;
  
+       /*
+        * And that we're not doing PPPoE.
+        */
+       is_pppoes = 0;
        /*
         * And assume we're not doing SS7.
         */
        off_sls = -1;
  
        /*
-        * Also assume it's not 802.11 with a fixed-length radio header.
+        * Also assume it's not 802.11.
         */
        off_ll = 0;
+       off_macpl = 0;
+       off_macpl_is_variable = 0;
  
        orig_linktype = -1;
        orig_nl = -1;
          label_stack_depth = 0;
  
-       reg_ll_size = -1;
+       reg_off_ll = -1;
+       reg_off_macpl = -1;
  
        switch (linktype) {
  
        case DLT_ARCNET:
                off_linktype = 2;
-               off_nl = 6;             /* XXX in reality, variable! */
-               off_nl_nosnap = 6;      /* no 802.2 LLC */
+               off_macpl = 6;
+               off_nl = 0;             /* XXX in reality, variable! */
+               off_nl_nosnap = 0;      /* no 802.2 LLC */
                return;
  
        case DLT_ARCNET_LINUX:
                off_linktype = 4;
-               off_nl = 8;             /* XXX in reality, variable! */
-               off_nl_nosnap = 8;      /* no 802.2 LLC */
+               off_macpl = 8;
+               off_nl = 0;             /* XXX in reality, variable! */
+               off_nl_nosnap = 0;      /* no 802.2 LLC */
                return;
  
        case DLT_EN10MB:
                off_linktype = 12;
-               off_nl = 14;            /* Ethernet II */
-               off_nl_nosnap = 17;     /* 802.3+802.2 */
+               off_macpl = 14;         /* Ethernet header length */
+               off_nl = 0;             /* Ethernet II */
+               off_nl_nosnap = 3;      /* 802.3+802.2 */
                return;
  
        case DLT_SLIP:
                 * header is hacked into our SLIP driver.
                 */
                off_linktype = -1;
-               off_nl = 16;
-               off_nl_nosnap = 16;     /* no 802.2 LLC */
+               off_macpl = 16;
+               off_nl = 0;
+               off_nl_nosnap = 0;      /* no 802.2 LLC */
                return;
  
        case DLT_SLIP_BSDOS:
                /* XXX this may be the same as the DLT_PPP_BSDOS case */
                off_linktype = -1;
                /* XXX end */
-               off_nl = 24;
-               off_nl_nosnap = 24;     /* no 802.2 LLC */
+               off_macpl = 24;
+               off_nl = 0;
+               off_nl_nosnap = 0;      /* no 802.2 LLC */
                return;
  
        case DLT_NULL:
        case DLT_LOOP:
                off_linktype = 0;
-               off_nl = 4;
-               off_nl_nosnap = 4;      /* no 802.2 LLC */
+               off_macpl = 4;
+               off_nl = 0;
+               off_nl_nosnap = 0;      /* no 802.2 LLC */
                return;
  
        case DLT_ENC:
                off_linktype = 0;
-               off_nl = 12;
-               off_nl_nosnap = 12;     /* no 802.2 LLC */
+               off_macpl = 12;
+               off_nl = 0;
+               off_nl_nosnap = 0;      /* no 802.2 LLC */
                return;
  
        case DLT_PPP:
        case DLT_C_HDLC:                /* BSD/OS Cisco HDLC */
        case DLT_PPP_SERIAL:            /* NetBSD sync/async serial PPP */
                off_linktype = 2;
-               off_nl = 4;
-               off_nl_nosnap = 4;      /* no 802.2 LLC */
+               off_macpl = 4;
+               off_nl = 0;
+               off_nl_nosnap = 0;      /* no 802.2 LLC */
                return;
  
        case DLT_PPP_ETHER:
                 * only covers session state.
                 */
                off_linktype = 6;
-               off_nl = 8;
-               off_nl_nosnap = 8;      /* no 802.2 LLC */
+               off_macpl = 8;
+               off_nl = 0;
+               off_nl_nosnap = 0;      /* no 802.2 LLC */
                return;
  
        case DLT_PPP_BSDOS:
                off_linktype = 5;
-               off_nl = 24;
-               off_nl_nosnap = 24;     /* no 802.2 LLC */
+               off_macpl = 24;
+               off_nl = 0;
+               off_nl_nosnap = 0;      /* no 802.2 LLC */
                return;
  
        case DLT_FDDI:
  #ifdef PCAP_FDDIPAD
                off_linktype += pcap_fddipad;
  #endif
-               off_nl = 21;            /* FDDI+802.2+SNAP */
-               off_nl_nosnap = 16;     /* FDDI+802.2 */
+               off_macpl = 13;         /* FDDI MAC header length */
  #ifdef PCAP_FDDIPAD
-               off_nl += pcap_fddipad;
-               off_nl_nosnap += pcap_fddipad;
+               off_macpl += pcap_fddipad;
  #endif
+               off_nl = 8;             /* 802.2+SNAP */
+               off_nl_nosnap = 3;      /* 802.2 */
                return;
  
        case DLT_IEEE802:
                 * 8 - figure out which byte that is).
                 */
                off_linktype = 14;
-               off_nl = 22;            /* Token Ring+802.2+SNAP */
-               off_nl_nosnap = 17;     /* Token Ring+802.2 */
+               off_macpl = 14;         /* Token Ring MAC header length */
+               off_nl = 8;             /* 802.2+SNAP */
+               off_nl_nosnap = 3;      /* 802.2 */
                return;
  
        case DLT_IEEE802_11:
+       case DLT_PRISM_HEADER:
+       case DLT_IEEE802_11_RADIO_AVS:
+       case DLT_IEEE802_11_RADIO:
                /*
                 * 802.11 doesn't really have a link-level type field.
                 * We set "off_linktype" to the offset of the LLC header.
                 * is being used and pick out the encapsulated Ethernet type.
                 * XXX - should we generate code to check for SNAP?
                 *
-                * XXX - the header is actually variable-length.  We
-                * assume a 24-byte link-layer header, as appears in
-                * data frames in networks with no bridges.  If the
-                * fromds and tods 802.11 header bits are both set,
-                * it's actually supposed to be 30 bytes.
-                */
-               off_linktype = 24;
-               off_nl = 32;            /* 802.11+802.2+SNAP */
-               off_nl_nosnap = 27;     /* 802.11+802.2 */
-               return;
-       case DLT_PRISM_HEADER:
-               /*
-                * Same as 802.11, but with an additional header before
-                * the 802.11 header, containing a bunch of additional
-                * information including radio-level information.
-                *
-                * The header is 144 bytes long.
-                *
-                * XXX - same variable-length header problem; at least
-                * the Prism header is fixed-length.
+                * We also handle variable-length radio headers here.
+                * The Prism header is in theory variable-length, but in
+                * practice it's always 144 bytes long.  However, some
+                * drivers on Linux use ARPHRD_IEEE80211_PRISM, but
+                * sometimes or always supply an AVS header, so we
+                * have to check whether the radio header is a Prism
+                * header or an AVS header, so, in practice, it's
+                * variable-length.
                 */
-               off_ll = 144;
                off_linktype = 24;
-               off_nl = 32;    /* Prism+802.11+802.2+SNAP */
-               off_nl_nosnap = 27;     /* Prism+802.11+802.2 */
-               return;
-       case DLT_IEEE802_11_RADIO_AVS:
-               /*
-                * Same as 802.11, but with an additional header before
-                * the 802.11 header, containing a bunch of additional
-                * information including radio-level information.
-                *
-                * The header is 64 bytes long, at least in its
-                * current incarnation.
-                *
-                * XXX - same variable-length header problem, only
-                * more so; this header is also variable-length,
-                * with the length being the 32-bit big-endian
-                * number at an offset of 4 from the beginning
-                * of the radio header.  We should handle that the
-                * same way we handle the length at the beginning
-                * of the radiotap header.
-                *
-                * XXX - in Linux, do any drivers that supply an AVS
-                * header supply a link-layer type other than
-                * ARPHRD_IEEE80211_PRISM?  If so, we should map that
-                * to DLT_IEEE802_11_RADIO_AVS; if not, or if there are
-                * any drivers that supply an AVS header but supply
-                * an ARPHRD value of ARPHRD_IEEE80211_PRISM, we'll
-                * have to check the header in the generated code to
-                * determine whether it's Prism or AVS.
-                */
-               off_ll = 64;
-               off_linktype = 24;
-               off_nl = 32;            /* Radio+802.11+802.2+SNAP */
-               off_nl_nosnap = 27;     /* Radio+802.11+802.2 */
+               off_macpl = 0;          /* link-layer header is variable-length */
+               off_macpl_is_variable = 1;
+               off_nl = 8;             /* 802.2+SNAP */
+               off_nl_nosnap = 3;      /* 802.2 */
                return;
  
-               
-               /* 
-                * At the moment we treat PPI as normal Radiotap encoded
-                * packets. The difference is in the function that generates
-                * the code at the beginning to compute the header length.
-                * Since this code generator of PPI supports bare 802.11
-                * encapsulation only (i.e. the encapsulated DLT should be
-                * DLT_IEEE802_11) we generate code to check for this too.
-                */
        case DLT_PPI:
-       case DLT_IEEE802_11_RADIO:
-               /*
-                * Same as 802.11, but with an additional header before
-                * the 802.11 header, containing a bunch of additional
-                * information including radio-level information.
-                *
-                * The radiotap header is variable length, and we
-                * generate code to compute its length and store it
-                * in a register.  These offsets are relative to the
-                * beginning of the 802.11 header.
+               /* 
+                * At the moment we treat PPI the same way that we treat
+                * normal Radiotap encoded packets. The difference is in
+                * the function that generates the code at the beginning
+                * to compute the header length.  Since this code generator
+                * of PPI supports bare 802.11 encapsulation only (i.e.
+                * the encapsulated DLT should be DLT_IEEE802_11) we
+                * generate code to check for this too.
                 */
                off_linktype = 24;
-               off_nl = 32;            /* 802.11+802.2+SNAP */
-               off_nl_nosnap = 27;     /* 802.11+802.2 */
+               off_macpl = 0;          /* link-layer header is variable-length */
+               off_macpl_is_variable = 1;
+               off_nl = 8;             /* 802.2+SNAP */
+               off_nl_nosnap = 3;      /* 802.2 */
                return;
  
        case DLT_ATM_RFC1483:
                 * PPPo{A,E} and a PPP protocol of IP and....
                 */
                off_linktype = 0;
+               off_macpl = 0;          /* packet begins with LLC header */
                off_nl = 8;             /* 802.2+SNAP */
                off_nl_nosnap = 3;      /* 802.2 */
                return;
                off_vpi = SUNATM_VPI_POS;
                off_vci = SUNATM_VCI_POS;
                off_proto = PROTO_POS;
-               off_mac = -1;   /* LLC-encapsulated, so no MAC-layer header */
+               off_mac = -1;   /* assume LLC-encapsulated, so no MAC-layer header */
                off_payload = SUNATM_PKT_BEGIN_POS;
                off_linktype = off_payload;
-               off_nl = off_payload+8;         /* 802.2+SNAP */
-               off_nl_nosnap = off_payload+3;  /* 802.2 */
+               off_macpl = off_payload;        /* if LLC-encapsulated */
+               off_nl = 8;             /* 802.2+SNAP */
+               off_nl_nosnap = 3;      /* 802.2 */
                return;
  
        case DLT_RAW:
                off_linktype = -1;
+               off_macpl = 0;
                off_nl = 0;
                off_nl_nosnap = 0;      /* no 802.2 LLC */
                return;
  
        case DLT_LINUX_SLL:     /* fake header for Linux cooked socket */
                off_linktype = 14;
-               off_nl = 16;
-               off_nl_nosnap = 16;     /* no 802.2 LLC */
+               off_macpl = 16;
+               off_nl = 0;
+               off_nl_nosnap = 0;      /* no 802.2 LLC */
                return;
  
        case DLT_LTALK:
                 * "long" DDP packet following.
                 */
                off_linktype = -1;
+               off_macpl = 0;
                off_nl = 0;
                off_nl_nosnap = 0;      /* no 802.2 LLC */
                return;
                 * 2625 says SNAP should be used.
                 */
                off_linktype = 16;
-               off_nl = 24;            /* IPFC+802.2+SNAP */
-               off_nl_nosnap = 19;     /* IPFC+802.2 */
+               off_macpl = 16;
+               off_nl = 8;             /* 802.2+SNAP */
+               off_nl_nosnap = 3;      /* 802.2 */
                return;
  
        case DLT_FRELAY:
                 * frames (NLPID of 0x80).
                 */
                off_linktype = -1;
+               off_macpl = 0;
                off_nl = 0;
                off_nl_nosnap = 0;      /* no 802.2 LLC */
                return;
                   */
        case DLT_MFR:
                off_linktype = -1;
+               off_macpl = 0;
                off_nl = 4;
                off_nl_nosnap = 0;      /* XXX - for now -> no 802.2 LLC */
                return;
  
        case DLT_APPLE_IP_OVER_IEEE1394:
                off_linktype = 16;
-               off_nl = 18;
-               off_nl_nosnap = 18;     /* no 802.2 LLC */
+               off_macpl = 18;
+               off_nl = 0;
+               off_nl_nosnap = 0;      /* no 802.2 LLC */
                return;
  
        case DLT_LINUX_IRDA:
                 * Currently, only raw "link[N:M]" filtering is supported.
                 */
                off_linktype = -1;
+               off_macpl = -1;
                off_nl = -1;
                off_nl_nosnap = -1;
                return;
                 * Currently, only raw "link[N:M]" filtering is supported.
                 */
                off_linktype = -1;
+               off_macpl = -1;
                off_nl = -1;
                off_nl_nosnap = -1;
                return;
  
        case DLT_SYMANTEC_FIREWALL:
                off_linktype = 6;
-               off_nl = 44;            /* Ethernet II */
-               off_nl_nosnap = 44;     /* XXX - what does it do with 802.3 packets? */
+               off_macpl = 44;
+               off_nl = 0;             /* Ethernet II */
+               off_nl_nosnap = 0;      /* XXX - what does it do with 802.3 packets? */
                return;
  
  #ifdef HAVE_NET_PFVAR_H
        case DLT_PFLOG:
                off_linktype = 0;
-               off_nl = PFLOG_HDRLEN;
-               off_nl_nosnap = PFLOG_HDRLEN;   /* no 802.2 LLC */
+               off_macpl = PFLOG_HDRLEN;
+               off_nl = 0;
+               off_nl_nosnap = 0;      /* no 802.2 LLC */
                return;
  #endif
  
          case DLT_JUNIPER_CHDLC:
          case DLT_JUNIPER_FRELAY:
                  off_linktype = 4;
-               off_nl = 4;
+               off_macpl = 4;
+               off_nl = 0;
                off_nl_nosnap = -1;     /* no 802.2 LLC */
                  return;
  
        case DLT_JUNIPER_ATM1:
-               off_linktype = 4; /* in reality variable between 4-8 */
-               off_nl = 4;
-               off_nl_nosnap = 14;
+               off_linktype = 4;       /* in reality variable between 4-8 */
+               off_macpl = 4;  /* in reality variable between 4-8 */
+               off_nl = 0;
+               off_nl_nosnap = 10;
                return;
  
        case DLT_JUNIPER_ATM2:
-               off_linktype = 8; /* in reality variable between 8-12 */
-               off_nl = 8;
-               off_nl_nosnap = 18;
+               off_linktype = 8;       /* in reality variable between 8-12 */
+               off_macpl = 8;  /* in reality variable between 8-12 */
+               off_nl = 0;
+               off_nl_nosnap = 10;
                return;
  
                /* frames captured on a Juniper PPPoE service PIC
                 * contain raw ethernet frames */
        case DLT_JUNIPER_PPPOE:
          case DLT_JUNIPER_ETHER:
+               off_macpl = 14;
                off_linktype = 16;
                off_nl = 18;            /* Ethernet II */
                off_nl_nosnap = 21;     /* 802.3+802.2 */
  
        case DLT_JUNIPER_PPPOE_ATM:
                off_linktype = 4;
-               off_nl = 6;
-               off_nl_nosnap = -1;      /* no 802.2 LLC */
+               off_macpl = 6;
+               off_nl = 0;
+               off_nl_nosnap = -1;     /* no 802.2 LLC */
                return;
  
        case DLT_JUNIPER_GGSN:
                off_linktype = 6;
-               off_nl = 12;
-               off_nl_nosnap = -1;      /* no 802.2 LLC */
+               off_macpl = 12;
+               off_nl = 0;
+               off_nl_nosnap = -1;     /* no 802.2 LLC */
                return;
  
        case DLT_JUNIPER_ES:
                off_linktype = 6;
-               off_nl = -1;            /* not really a network layer but raw IP adresses */
+               off_macpl = -1;         /* not really a network layer but raw IP addresses */
+               off_nl = -1;            /* not really a network layer but raw IP addresses */
                off_nl_nosnap = -1;     /* no 802.2 LLC */
                return;
  
        case DLT_JUNIPER_MONITOR:
                off_linktype = 12;
-               off_nl = 12;            /* raw IP/IP6 header */
+               off_macpl = 12;
+               off_nl = 0;             /* raw IP/IP6 header */
                off_nl_nosnap = -1;     /* no 802.2 LLC */
                return;
  
        case DLT_JUNIPER_SERVICES:
                off_linktype = 12;
+               off_macpl = -1;         /* L3 proto location dep. on cookie type */
                off_nl = -1;            /* L3 proto location dep. on cookie type */
                off_nl_nosnap = -1;     /* no 802.2 LLC */
                return;
  
        case DLT_JUNIPER_VP:
                off_linktype = 18;
+               off_macpl = -1;
+               off_nl = -1;
+               off_nl_nosnap = -1;
+               return;
+       case DLT_JUNIPER_ST:
+               off_linktype = 18;
+               off_macpl = -1;
+               off_nl = -1;
+               off_nl_nosnap = -1;
+               return;
+       case DLT_JUNIPER_ISM:
+               off_linktype = 8;
+               off_macpl = -1;
                off_nl = -1;
                off_nl_nosnap = -1;
                return;
                off_dpc = 4;
                off_sls = 7;
                off_linktype = -1;
+               off_macpl = -1;
                off_nl = -1;
                off_nl_nosnap = -1;
                return;
                off_dpc = 8;
                off_sls = 11;
                off_linktype = -1;
+               off_macpl = -1;
+               off_nl = -1;
+               off_nl_nosnap = -1;
+               return;
+       case DLT_ERF:
+               off_li = 22;
+               off_sio = 23;
+               off_opc = 24;
+               off_dpc = 24;
+               off_sls = 27;
+               off_linktype = -1;
+               off_macpl = -1;
                off_nl = -1;
                off_nl_nosnap = -1;
                return;
  #ifdef DLT_PFSYNC
        case DLT_PFSYNC:
                off_linktype = -1;
-               off_nl = 4;
-               off_nl_nosnap = 4;
+               off_macpl = 4;
+               off_nl = 0;
+               off_nl_nosnap = 0;
                return;
  #endif
  
                 * Currently, only raw "link[N:M]" filtering is supported.
                 */
                off_linktype = -1;
+               off_macpl = -1;
                off_nl = -1;
                off_nl_nosnap = -1;
                return;
                 * Currently, only raw "link[N:M]" filtering is supported.
                 */
                off_linktype = -1;
+               off_macpl = -1;
                off_nl = -1;
                off_nl_nosnap = -1;
                return;
                 * Currently, only raw "link[N:M]" filtering is supported.
                 */
                off_linktype = -1;
+               off_macpl = -1;
+               off_nl = -1;
+               off_nl_nosnap = -1;
+               return;
+       case DLT_USB_LINUX:
+               /*
+                * Currently, only raw "link[N:M]" filtering is supported.
+                */
+               off_linktype = -1;
+               off_macpl = -1;
+               off_nl = -1;
+               off_nl_nosnap = -1;
+               return;
+       case DLT_CAN20B:
+               /*
+                * Currently, only raw "link[N:M]" filtering is supported.
+                */
+               off_linktype = -1;
+               off_macpl = -1;
+               off_nl = -1;
+               off_nl_nosnap = -1;
+               return;
+       case DLT_IEEE802_15_4_LINUX:
+               /*
+                * Currently, only raw "link[N:M]" filtering is supported.
+                */
+               off_linktype = -1;
+               off_macpl = -1;
+               off_nl = -1;
+               off_nl_nosnap = -1;
+               return;
+       case DLT_IEEE802_16_MAC_CPS_RADIO:
+               /*
+                * Currently, only raw "link[N:M]" filtering is supported.
+                */
+               off_linktype = -1;
+               off_macpl = -1;
+               off_nl = -1;
+               off_nl_nosnap = -1;
+               return;
+       case DLT_IEEE802_15_4:
+               /*
+                * Currently, only raw "link[N:M]" filtering is supported.
+                */
+               off_linktype = -1;
+               off_macpl = -1;
+               off_nl = -1;
+               off_nl_nosnap = -1;
+               return;
+       case DLT_SITA:
+               /*
+                * Currently, only raw "link[N:M]" filtering is supported.
+                */
+               off_linktype = -1;
+               off_macpl = -1;
+               off_nl = -1;
+               off_nl_nosnap = -1;
+               return;
+       case DLT_RAIF1:
+               /*
+                * Currently, only raw "link[N:M]" filtering is supported.
+                */
+               off_linktype = -1;
+               off_macpl = -1;
+               off_nl = -1;
+               off_nl_nosnap = -1;
+               return;
+       case DLT_IPMB:
+               /*
+                * Currently, only raw "link[N:M]" filtering is supported.
+                */
+               off_linktype = -1;
+               off_macpl = -1;
+               off_nl = -1;
+               off_nl_nosnap = -1;
+               return;
+       case DLT_BLUETOOTH_HCI_H4_WITH_PHDR:
+               /*
+                * Currently, only raw "link[N:M]" filtering is supported.
+                */
+               off_linktype = -1;
+               off_macpl = -1;
+               off_nl = -1;
+               off_nl_nosnap = -1;
+               return;
+       case DLT_AX25_KISS:
+               /*
+                * Currently, only raw "link[N:M]" filtering is supported.
+                */
+               off_linktype = -1;      /* variable, min 15, max 71 steps of 7 */
+               off_macpl = -1;
+               off_nl = -1;            /* variable, min 16, max 71 steps of 7 */
+               off_nl_nosnap = -1;     /* no 802.2 LLC */
+               off_mac = 1;            /* step over the kiss length byte */
+               return;
+       case DLT_IEEE802_15_4_NONASK_PHY:
+               /*
+                * Currently, only raw "link[N:M]" filtering is supported.
+                */
+               off_linktype = -1;
+               off_macpl = -1;
                off_nl = -1;
                off_nl_nosnap = -1;
                return;
@@@ -1366,6 -1547,45 +1550,45 @@@ gen_load_llrel(offset, size
        return s;
  }
  
+ /*
+  * Load a value relative to the beginning of the MAC-layer payload.
+  */
+ static struct slist *
+ gen_load_macplrel(offset, size)
+       u_int offset, size;
+ {
+       struct slist *s, *s2;
+       s = gen_off_macpl();
+       /*
+        * If s is non-null, the offset of the MAC-layer payload is
+        * variable, and s points to a list of instructions that
+        * arrange that the X register contains that offset.
+        *
+        * Otherwise, the offset of the MAC-layer payload is constant,
+        * and is in off_macpl.
+        */
+       if (s != NULL) {
+               /*
+                * The offset of the MAC-layer payload is in the X
+                * register.  Do an indirect load, to use the X register
+                * as an offset.
+                */
+               s2 = new_stmt(BPF_LD|BPF_IND|size);
+               s2->s.k = offset;
+               sappend(s, s2);
+       } else {
+               /*
+                * The offset of the MAC-layer payload is constant,
+                * and is in off_macpl; load the value at that offset
+                * plus the specified offset.
+                */
+               s = new_stmt(BPF_LD|BPF_ABS|size);
+               s->s.k = off_macpl + offset;
+       }
+       return s;
+ }
  
  /*
   * Load a value relative to the beginning of the specified header.
@@@ -1388,12 -1608,16 +1611,16 @@@ gen_load_a(offrel, offset, size
                s = gen_load_llrel(offset, size);
                break;
  
+       case OR_MACPL:
+               s = gen_load_macplrel(offset, size);
+               break;
        case OR_NET:
-               s = gen_load_llrel(off_nl + offset, size);
+               s = gen_load_macplrel(off_nl + offset, size);
                break;
  
        case OR_NET_NOSNAP:
-               s = gen_load_llrel(off_nl_nosnap + offset, size);
+               s = gen_load_macplrel(off_nl_nosnap + offset, size);
                break;
  
        case OR_TRAN_IPV4:
                s = gen_loadx_iphdrlen();
  
                /*
-                * Load the item at {offset of the link-layer header} +
-                * {offset, relative to the start of the link-layer
-                * header, of the IPv4 header} + {length of the IPv4 header} +
+                * Load the item at {offset of the MAC-layer payload} +
+                * {offset, relative to the start of the MAC-layer
+                * paylod, of the IPv4 header} + {length of the IPv4 header} +
                 * {specified offset}.
                 *
-                * (If the link-layer is variable-length, it's included
-                * in the value in the X register, and off_ll is 0.)
+                * (If the offset of the MAC-layer payload is variable,
+                * it's included in the value in the X register, and
+                * off_macpl is 0.)
                 */
                s2 = new_stmt(BPF_LD|BPF_IND|size);
-               s2->s.k = off_ll + off_nl + offset;
+               s2->s.k = off_macpl + off_nl + offset;
                sappend(s, s2);
                break;
  
        case OR_TRAN_IPV6:
-               s = gen_load_llrel(off_nl + 40 + offset, size);
+               s = gen_load_macplrel(off_nl + 40 + offset, size);
                break;
  
        default:
@@@ -1440,12 -1665,15 +1668,15 @@@ gen_loadx_iphdrlen(
  {
        struct slist *s, *s2;
  
-       s = gen_llprefixlen();
+       s = gen_off_macpl();
        if (s != NULL) {
                /*
                 * There's a variable-length prefix preceding the
-                * link-layer header.  "s" points to a list of statements
-                * that put the length of that prefix into the X register.
+                * link-layer header, or the link-layer header is itself
+                * variable-length.  "s" points to a list of statements
+                * that put the offset of the MAC-layer payload into
+                * the X register.
+                *
                 * The 4*([k]&0xf) addressing mode can't be used, as we
                 * don't have a constant offset, so we have to load the
                 * value in question into the A register and add to it
  
                /*
                 * The A register now contains the length of the
-                * IP header.  We need to add to it the length
-                * of the prefix preceding the link-layer
-                * header, which is still in the X register, and
-                * move the result into the X register.
+                * IP header.  We need to add to it the offset of
+                * the MAC-layer payload, which is still in the X
+                * register, and move the result into the X register.
                 */
                sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X));
                sappend(s, new_stmt(BPF_MISC|BPF_TAX));
        } else {
                /*
                 * There is no variable-length header preceding the
-                * link-layer header; add in off_ll, which, if there's
-                * a fixed-length header preceding the link-layer header,
-                * is the length of that header.
+                * link-layer header, and the link-layer header is
+                * fixed-length; load the length of the IPv4 header,
+                * which is at an offset of off_nl from the beginning
+                * of the MAC-layer payload, and thus at an offset
+                * of off_mac_pl + off_nl from the beginning of the
+                * raw packet data.
                 */
                s = new_stmt(BPF_LDX|BPF_MSH|BPF_B);
-               s->s.k = off_ll + off_nl;
+               s->s.k = off_macpl + off_nl;
        }
        return s;
  }
@@@ -1552,7 -1782,7 +1785,7 @@@ gen_ether_linktype(proto
                 */
                b0 = gen_cmp_gt(OR_LINK, off_linktype, BPF_H, ETHERMTU);
                gen_not(b0);
-               b1 = gen_cmp(OR_LINK, off_linktype + 2, BPF_H, (bpf_int32)
+               b1 = gen_cmp(OR_MACPL, 0, BPF_H, (bpf_int32)
                             ((proto << 8) | proto));
                gen_and(b0, b1);
                return b1;
                 * This generates code to check both for the
                 * IPX LSAP (Ethernet_802.2) and for Ethernet_802.3.
                 */
-               b0 = gen_cmp(OR_LINK, off_linktype + 2, BPF_B,
-                   (bpf_int32)LLCSAP_IPX);
-               b1 = gen_cmp(OR_LINK, off_linktype + 2, BPF_H,
-                   (bpf_int32)0xFFFF);
+               b0 = gen_cmp(OR_MACPL, 0, BPF_B, (bpf_int32)LLCSAP_IPX);
+               b1 = gen_cmp(OR_MACPL, 0, BPF_H, (bpf_int32)0xFFFF);
                gen_or(b0, b1);
  
                /*
                 * Now we add code to check for SNAP frames with
                 * ETHERTYPE_IPX, i.e. Ethernet_SNAP.
                 */
-               b0 = gen_snap(0x000000, ETHERTYPE_IPX, 14);
+               b0 = gen_snap(0x000000, ETHERTYPE_IPX);
                gen_or(b0, b1);
  
                /*
                 * type of ETHERTYPE_AARP (Appletalk ARP).
                 */
                if (proto == ETHERTYPE_ATALK)
-                       b1 = gen_snap(0x080007, ETHERTYPE_ATALK, 14);
+                       b1 = gen_snap(0x080007, ETHERTYPE_ATALK);
                else    /* proto == ETHERTYPE_AARP */
-                       b1 = gen_snap(0x000000, ETHERTYPE_AARP, 14);
+                       b1 = gen_snap(0x000000, ETHERTYPE_AARP);
                gen_and(b0, b1);
  
                /*
@@@ -1734,7 -1962,7 +1965,7 @@@ gen_linux_sll_linktype(proto
                 * (i.e., other SAP values)?
                 */
                b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, LINUX_SLL_P_802_2);
-               b1 = gen_cmp(OR_LINK, off_linktype + 2, BPF_H, (bpf_int32)
+               b1 = gen_cmp(OR_MACPL, 0, BPF_H, (bpf_int32)
                             ((proto << 8) | proto));
                gen_and(b0, b1);
                return b1;
                 * then put a check for LINUX_SLL_P_802_2 frames
                 * before it.
                 */
-               b0 = gen_cmp(OR_LINK, off_linktype + 2, BPF_B,
-                   (bpf_int32)LLCSAP_IPX);
-               b1 = gen_snap(0x000000, ETHERTYPE_IPX,
-                   off_linktype + 2);
+               b0 = gen_cmp(OR_MACPL, 0, BPF_B, (bpf_int32)LLCSAP_IPX);
+               b1 = gen_snap(0x000000, ETHERTYPE_IPX);
                gen_or(b0, b1);
                b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, LINUX_SLL_P_802_2);
                gen_and(b0, b1);
                 * type of ETHERTYPE_AARP (Appletalk ARP).
                 */
                if (proto == ETHERTYPE_ATALK)
-                       b1 = gen_snap(0x080007, ETHERTYPE_ATALK,
-                           off_linktype + 2);
+                       b1 = gen_snap(0x080007, ETHERTYPE_ATALK);
                else    /* proto == ETHERTYPE_AARP */
-                       b1 = gen_snap(0x000000, ETHERTYPE_AARP,
-                           off_linktype + 2);
+                       b1 = gen_snap(0x000000, ETHERTYPE_AARP);
                gen_and(b0, b1);
  
                /*
                         */
                        b0 = gen_cmp(OR_LINK, off_linktype, BPF_H,
                            LINUX_SLL_P_802_2);
-                       b1 = gen_cmp(OR_LINK, off_linktype + 2, BPF_B,
+                       b1 = gen_cmp(OR_LINK, off_macpl, BPF_B,
                             (bpf_int32)proto);
                        gen_and(b0, b1);
                        return b1;
        }
  }
  
- static void
- insert_radiotap_load_llprefixlen(b)
-       struct block *b;
+ static struct slist *
+ gen_load_prism_llprefixlen()
+ {
+       struct slist *s1, *s2;
+       struct slist *sjeq_avs_cookie;
+       struct slist *sjcommon;
+       /*
+        * This code is not compatible with the optimizer, as
+        * we are generating jmp instructions within a normal
+        * slist of instructions
+        */
+       no_optimize = 1;
+       /*
+        * Generate code to load the length of the radio header into
+        * the register assigned to hold that length, if one has been
+        * assigned.  (If one hasn't been assigned, no code we've
+        * generated uses that prefix, so we don't need to generate any
+        * code to load it.)
+        *
+        * Some Linux drivers use ARPHRD_IEEE80211_PRISM but sometimes
+        * or always use the AVS header rather than the Prism header.
+        * We load a 4-byte big-endian value at the beginning of the
+        * raw packet data, and see whether, when masked with 0xFFFFF000,
+        * it's equal to 0x80211000.  If so, that indicates that it's
+        * an AVS header (the masked-out bits are the version number).
+        * Otherwise, it's a Prism header.
+        *
+        * XXX - the Prism header is also, in theory, variable-length,
+        * but no known software generates headers that aren't 144
+        * bytes long.
+        */
+       if (reg_off_ll != -1) {
+               /*
+                * Load the cookie.
+                */
+               s1 = new_stmt(BPF_LD|BPF_W|BPF_ABS);
+               s1->s.k = 0;
+               /*
+                * AND it with 0xFFFFF000.
+                */
+               s2 = new_stmt(BPF_ALU|BPF_AND|BPF_K);
+               s2->s.k = 0xFFFFF000;
+               sappend(s1, s2);
+               /*
+                * Compare with 0x80211000.
+                */
+               sjeq_avs_cookie = new_stmt(JMP(BPF_JEQ));
+               sjeq_avs_cookie->s.k = 0x80211000;
+               sappend(s1, sjeq_avs_cookie);
+               /*
+                * If it's AVS:
+                *
+                * The 4 bytes at an offset of 4 from the beginning of
+                * the AVS header are the length of the AVS header.
+                * That field is big-endian.
+                */
+               s2 = new_stmt(BPF_LD|BPF_W|BPF_ABS);
+               s2->s.k = 4;
+               sappend(s1, s2);
+               sjeq_avs_cookie->s.jt = s2;
+               /*
+                * Now jump to the code to allocate a register
+                * into which to save the header length and
+                * store the length there.  (The "jump always"
+                * instruction needs to have the k field set;
+                * it's added to the PC, so, as we're jumping
+                * over a single instruction, it should be 1.)
+                */
+               sjcommon = new_stmt(JMP(BPF_JA));
+               sjcommon->s.k = 1;
+               sappend(s1, sjcommon);
+               /*
+                * Now for the code that handles the Prism header.
+                * Just load the length of the Prism header (144)
+                * into the A register.  Have the test for an AVS
+                * header branch here if we don't have an AVS header.
+                */
+               s2 = new_stmt(BPF_LD|BPF_W|BPF_IMM);
+               s2->s.k = 144;
+               sappend(s1, s2);
+               sjeq_avs_cookie->s.jf = s2;
+               /*
+                * Now allocate a register to hold that value and store
+                * it.  The code for the AVS header will jump here after
+                * loading the length of the AVS header.
+                */
+               s2 = new_stmt(BPF_ST);
+               s2->s.k = reg_off_ll;
+               sappend(s1, s2);
+               sjcommon->s.jf = s2;
+               /*
+                * Now move it into the X register.
+                */
+               s2 = new_stmt(BPF_MISC|BPF_TAX);
+               sappend(s1, s2);
+               return (s1);
+       } else
+               return (NULL);
+ }
+ static struct slist *
+ gen_load_avs_llprefixlen()
+ {
+       struct slist *s1, *s2;
+       /*
+        * Generate code to load the length of the AVS header into
+        * the register assigned to hold that length, if one has been
+        * assigned.  (If one hasn't been assigned, no code we've
+        * generated uses that prefix, so we don't need to generate any
+        * code to load it.)
+        */
+       if (reg_off_ll != -1) {
+               /*
+                * The 4 bytes at an offset of 4 from the beginning of
+                * the AVS header are the length of the AVS header.
+                * That field is big-endian.
+                */
+               s1 = new_stmt(BPF_LD|BPF_W|BPF_ABS);
+               s1->s.k = 4;
+               /*
+                * Now allocate a register to hold that value and store
+                * it.
+                */
+               s2 = new_stmt(BPF_ST);
+               s2->s.k = reg_off_ll;
+               sappend(s1, s2);
+               /*
+                * Now move it into the X register.
+                */
+               s2 = new_stmt(BPF_MISC|BPF_TAX);
+               sappend(s1, s2);
+               return (s1);
+       } else
+               return (NULL);
+ }
+ static struct slist *
+ gen_load_radiotap_llprefixlen()
  {
        struct slist *s1, *s2;
  
        /*
-        * Prepend to the statements in this block code to load the
-        * length of the radiotap header into the register assigned
-        * to hold that length, if one has been assigned.
+        * Generate code to load the length of the radiotap header into
+        * the register assigned to hold that length, if one has been
+        * assigned.  (If one hasn't been assigned, no code we've
+        * generated uses that prefix, so we don't need to generate any
+        * code to load it.)
         */
-       if (reg_ll_size != -1) {
+       if (reg_off_ll != -1) {
                /*
                 * The 2 bytes at offsets of 2 and 3 from the beginning
                 * of the radiotap header are the length of the radiotap
                 * it.
                 */
                s2 = new_stmt(BPF_ST);
-               s2->s.k = reg_ll_size;
+               s2->s.k = reg_off_ll;
                sappend(s1, s2);
  
                /*
                s2 = new_stmt(BPF_MISC|BPF_TAX);
                sappend(s1, s2);
  
-               /*
-                * Now append all the existing statements in this
-                * block to these statements.
-                */
-               sappend(s1, b->stmts);
-               b->stmts = s1;
-       }
+               return (s1);
+       } else
+               return (NULL);
  }
  
  /* 
   * the code at the beginning to compute the header length.
   * Since this code generator of PPI supports bare 802.11
   * encapsulation only (i.e. the encapsulated DLT should be
-  * DLT_IEEE802_11) we generate code to check for this too.
+  * DLT_IEEE802_11) we generate code to check for this too;
+  * that's done in finish_parse().
   */
- static void
- insert_ppi_load_llprefixlen(b)
-       struct block *b;
+ static struct slist *
+ gen_load_ppi_llprefixlen()
  {
        struct slist *s1, *s2;
        
        /*
-        * Prepend to the statements in this block code to load the
-        * length of the radiotap header into the register assigned
-        * to hold that length, if one has been assigned.
+        * Generate code to load the length of the radiotap header
+        * into the register assigned to hold that length, if one has
+        * been assigned.
         */
-       if (reg_ll_size != -1) {
-           /*
+       if (reg_off_ll != -1) {
+               /*
                 * The 2 bytes at offsets of 2 and 3 from the beginning
                 * of the radiotap header are the length of the radiotap
                 * header; unfortunately, it's little-endian, so we have
                 * it.
                 */
                s2 = new_stmt(BPF_ST);
-               s2->s.k = reg_ll_size;
+               s2->s.k = reg_off_ll;
                sappend(s1, s2);
  
                /*
                s2 = new_stmt(BPF_MISC|BPF_TAX);
                sappend(s1, s2);
  
+               return (s1);
+       } else
+               return (NULL);
+ }
+ /*
+  * Load a value relative to the beginning of the link-layer header after the 802.11
+  * header, i.e. LLC_SNAP.
+  * The link-layer header doesn't necessarily begin at the beginning
+  * of the packet data; there might be a variable-length prefix containing
+  * radio information.
+  */
+ static struct slist *
+ gen_load_802_11_header_len(struct slist *s, struct slist *snext)
+ {
+       struct slist *s2;
+       struct slist *sjset_data_frame_1;
+       struct slist *sjset_data_frame_2;
+       struct slist *sjset_qos;
+       struct slist *sjset_radiotap_flags;
+       struct slist *sjset_radiotap_tsft;
+       struct slist *sjset_tsft_datapad, *sjset_notsft_datapad;
+       struct slist *s_roundup;
+       if (reg_off_macpl == -1) {
+               /*
+                * No register has been assigned to the offset of
+                * the MAC-layer payload, which means nobody needs
+                * it; don't bother computing it - just return
+                * what we already have.
+                */
+               return (s);
+       }
+       /*
+        * This code is not compatible with the optimizer, as
+        * we are generating jmp instructions within a normal
+        * slist of instructions
+        */
+       no_optimize = 1;
+       
+       /*
+        * If "s" is non-null, it has code to arrange that the X register
+        * contains the length of the prefix preceding the link-layer
+        * header.
+        *
+        * Otherwise, the length of the prefix preceding the link-layer
+        * header is "off_ll".
+        */
+       if (s == NULL) {
+               /*
+                * There is no variable-length header preceding the
+                * link-layer header.
+                *
+                * Load the length of the fixed-length prefix preceding
+                * the link-layer header (if any) into the X register,
+                * and store it in the reg_off_macpl register.
+                * That length is off_ll.
+                */
+               s = new_stmt(BPF_LDX|BPF_IMM);
+               s->s.k = off_ll;
+       }
+       /*
+        * The X register contains the offset of the beginning of the
+        * link-layer header; add 24, which is the minimum length
+        * of the MAC header for a data frame, to that, and store it
+        * in reg_off_macpl, and then load the Frame Control field,
+        * which is at the offset in the X register, with an indexed load.
+        */
+       s2 = new_stmt(BPF_MISC|BPF_TXA);
+       sappend(s, s2);
+       s2 = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
+       s2->s.k = 24;
+       sappend(s, s2);
+       s2 = new_stmt(BPF_ST);
+       s2->s.k = reg_off_macpl;
+       sappend(s, s2);
+       s2 = new_stmt(BPF_LD|BPF_IND|BPF_B);
+       s2->s.k = 0;
+       sappend(s, s2);
+       /*
+        * Check the Frame Control field to see if this is a data frame;
+        * a data frame has the 0x08 bit (b3) in that field set and the
+        * 0x04 bit (b2) clear.
+        */
+       sjset_data_frame_1 = new_stmt(JMP(BPF_JSET));
+       sjset_data_frame_1->s.k = 0x08;
+       sappend(s, sjset_data_frame_1);
+               
+       /*
+        * If b3 is set, test b2, otherwise go to the first statement of
+        * the rest of the program.
+        */
+       sjset_data_frame_1->s.jt = sjset_data_frame_2 = new_stmt(JMP(BPF_JSET));
+       sjset_data_frame_2->s.k = 0x04;
+       sappend(s, sjset_data_frame_2);
+       sjset_data_frame_1->s.jf = snext;
+       /*
+        * If b2 is not set, this is a data frame; test the QoS bit.
+        * Otherwise, go to the first statement of the rest of the
+        * program.
+        */
+       sjset_data_frame_2->s.jt = snext;
+       sjset_data_frame_2->s.jf = sjset_qos = new_stmt(JMP(BPF_JSET));
+       sjset_qos->s.k = 0x80;  /* QoS bit */
+       sappend(s, sjset_qos);
+               
+       /*
+        * If it's set, add 2 to reg_off_macpl, to skip the QoS
+        * field.
+        * Otherwise, go to the first statement of the rest of the
+        * program.
+        */
+       sjset_qos->s.jt = s2 = new_stmt(BPF_LD|BPF_MEM);
+       s2->s.k = reg_off_macpl;
+       sappend(s, s2);
+       s2 = new_stmt(BPF_ALU|BPF_ADD|BPF_IMM);
+       s2->s.k = 2;
+       sappend(s, s2);
+       s2 = new_stmt(BPF_ST);
+       s2->s.k = reg_off_macpl;
+       sappend(s, s2);
+       /*
+        * If we have a radiotap header, look at it to see whether
+        * there's Atheros padding between the MAC-layer header
+        * and the payload.
+        *
+        * Note: all of the fields in the radiotap header are
+        * little-endian, so we byte-swap all of the values
+        * we test against, as they will be loaded as big-endian
+        * values.
+        */
+       if (linktype == DLT_IEEE802_11_RADIO) {
+               /*
+                * Is the IEEE80211_RADIOTAP_FLAGS bit (0x0000002) set
+                * in the presence flag?
+                */
+               sjset_qos->s.jf = s2 = new_stmt(BPF_LD|BPF_ABS|BPF_W);
+               s2->s.k = 4;
+               sappend(s, s2);
+               sjset_radiotap_flags = new_stmt(JMP(BPF_JSET));
+               sjset_radiotap_flags->s.k = SWAPLONG(0x00000002);
+               sappend(s, sjset_radiotap_flags);
+               /*
+                * If not, skip all of this.
+                */
+               sjset_radiotap_flags->s.jf = snext;
+               /*
+                * Otherwise, is the IEEE80211_RADIOTAP_TSFT bit set?
+                */
+               sjset_radiotap_tsft = sjset_radiotap_flags->s.jt =
+                   new_stmt(JMP(BPF_JSET));
+               sjset_radiotap_tsft->s.k = SWAPLONG(0x00000001);
+               sappend(s, sjset_radiotap_tsft);
+               /*
+                * If IEEE80211_RADIOTAP_TSFT is set, the flags field is
+                * at an offset of 16 from the beginning of the raw packet
+                * data (8 bytes for the radiotap header and 8 bytes for
+                * the TSFT field).
+                *
+                * Test whether the IEEE80211_RADIOTAP_F_DATAPAD bit (0x20)
+                * is set.
+                */
+               sjset_radiotap_tsft->s.jt = s2 = new_stmt(BPF_LD|BPF_ABS|BPF_B);
+               s2->s.k = 16;
+               sappend(s, s2);
+               sjset_tsft_datapad = new_stmt(JMP(BPF_JSET));
+               sjset_tsft_datapad->s.k = 0x20;
+               sappend(s, sjset_tsft_datapad);
                /*
-                * Now append all the existing statements in this
-                * block to these statements.
+                * If IEEE80211_RADIOTAP_TSFT is not set, the flags field is
+                * at an offset of 8 from the beginning of the raw packet
+                * data (8 bytes for the radiotap header).
+                *
+                * Test whether the IEEE80211_RADIOTAP_F_DATAPAD bit (0x20)
+                * is set.
                 */
-               sappend(s1, b->stmts);
-               b->stmts = s1;
+               sjset_radiotap_tsft->s.jf = s2 = new_stmt(BPF_LD|BPF_ABS|BPF_B);
+               s2->s.k = 8;
+               sappend(s, s2);
+               sjset_notsft_datapad = new_stmt(JMP(BPF_JSET));
+               sjset_notsft_datapad->s.k = 0x20;
+               sappend(s, sjset_notsft_datapad);
+               /*
+                * In either case, if IEEE80211_RADIOTAP_F_DATAPAD is
+                * set, round the length of the 802.11 header to
+                * a multiple of 4.  Do that by adding 3 and then
+                * dividing by and multiplying by 4, which we do by
+                * ANDing with ~3.
+                */
+               s_roundup = new_stmt(BPF_LD|BPF_MEM);
+               s_roundup->s.k = reg_off_macpl;
+               sappend(s, s_roundup);
+               s2 = new_stmt(BPF_ALU|BPF_ADD|BPF_IMM);
+               s2->s.k = 3;
+               sappend(s, s2);
+               s2 = new_stmt(BPF_ALU|BPF_AND|BPF_IMM);
+               s2->s.k = ~3;
+               sappend(s, s2);
+               s2 = new_stmt(BPF_ST);
+               s2->s.k = reg_off_macpl;
+               sappend(s, s2);
  
+               sjset_tsft_datapad->s.jt = s_roundup;
+               sjset_tsft_datapad->s.jf = snext;
+               sjset_notsft_datapad->s.jt = s_roundup;
+               sjset_notsft_datapad->s.jf = snext;
+       } else
+               sjset_qos->s.jf = snext;
+       return s;
+ }
+ static void
+ insert_compute_vloffsets(b)
+       struct block *b;
+ {
+       struct slist *s;
+       /*
+        * For link-layer types that have a variable-length header
+        * preceding the link-layer header, generate code to load
+        * the offset of the link-layer header into the register
+        * assigned to that offset, if any.
+        */
+       switch (linktype) {
+       case DLT_PRISM_HEADER:
+               s = gen_load_prism_llprefixlen();
+               break;
+       case DLT_IEEE802_11_RADIO_AVS:
+               s = gen_load_avs_llprefixlen();
+               break;
+       case DLT_IEEE802_11_RADIO:
+               s = gen_load_radiotap_llprefixlen();
+               break;
+       case DLT_PPI:
+               s = gen_load_ppi_llprefixlen();
+               break;
+       default:
+               s = NULL;
+               break;
+       }
+       /*
+        * For link-layer types that have a variable-length link-layer
+        * header, generate code to load the offset of the MAC-layer
+        * payload into the register assigned to that offset, if any.
+        */
+       switch (linktype) {
+       case DLT_IEEE802_11:
+       case DLT_PRISM_HEADER:
+       case DLT_IEEE802_11_RADIO_AVS:
+       case DLT_IEEE802_11_RADIO:
+       case DLT_PPI:
+               s = gen_load_802_11_header_len(s, b->stmts);
+               break;
+       }
+       /*
+        * If we have any offset-loading code, append all the
+        * existing statements in the block to those statements,
+        * and make the resulting list the list of statements
+        * for the block.
+        */
+       if (s != NULL) {
+               sappend(s, b->stmts);
+               b->stmts = s;
        }
  }
-       
  static struct block *
  gen_ppi_dlt_check(void)
  {
        return b;
  }
  
- static void
- insert_load_llprefixlen(b)
-       struct block *b;
+ static struct slist *
+ gen_prism_llprefixlen(void)
+ {
+       struct slist *s;
+       if (reg_off_ll == -1) {
+               /*
+                * We haven't yet assigned a register for the length
+                * of the radio header; allocate one.
+                */
+               reg_off_ll = alloc_reg();
+       }
+       /*
+        * Load the register containing the radio length
+        * into the X register.
+        */
+       s = new_stmt(BPF_LDX|BPF_MEM);
+       s->s.k = reg_off_ll;
+       return s;
+ }
+ static struct slist *
+ gen_avs_llprefixlen(void)
  {
-       switch (linktype) {
-       /* 
-        * At the moment we treat PPI as normal Radiotap encoded
-        * packets. The difference is in the function that generates
-        * the code at the beginning to compute the header length.
-        * Since this code generator of PPI supports bare 802.11
-        * encapsulation only (i.e. the encapsulated DLT should be
-        * DLT_IEEE802_11) we generate code to check for this too.
-        */
-       case DLT_PPI:
-               insert_ppi_load_llprefixlen(b);
-               break;
+       struct slist *s;
  
-       case DLT_IEEE802_11_RADIO:
-               insert_radiotap_load_llprefixlen(b);
-               break;
+       if (reg_off_ll == -1) {
+               /*
+                * We haven't yet assigned a register for the length
+                * of the AVS header; allocate one.
+                */
+               reg_off_ll = alloc_reg();
        }
- }
  
+       /*
+        * Load the register containing the AVS length
+        * into the X register.
+        */
+       s = new_stmt(BPF_LDX|BPF_MEM);
+       s->s.k = reg_off_ll;
+       return s;
+ }
  
  static struct slist *
  gen_radiotap_llprefixlen(void)
  {
        struct slist *s;
  
-       if (reg_ll_size == -1) {
+       if (reg_off_ll == -1) {
                /*
                 * We haven't yet assigned a register for the length
                 * of the radiotap header; allocate one.
                 */
-               reg_ll_size = alloc_reg();
+               reg_off_ll = alloc_reg();
        }
  
        /*
         * into the X register.
         */
        s = new_stmt(BPF_LDX|BPF_MEM);
-       s->s.k = reg_ll_size;
+       s->s.k = reg_off_ll;
        return s;
  }
  
@@@ -2087,25 -2756,23 +2759,23 @@@ gen_ppi_llprefixlen(void
  {
        struct slist *s;
  
-       if (reg_ll_size == -1) {
+       if (reg_off_ll == -1) {
                /*
                 * We haven't yet assigned a register for the length
                 * of the radiotap header; allocate one.
                 */
-               reg_ll_size = alloc_reg();
+               reg_off_ll = alloc_reg();
        }
  
        /*
-        * Load the register containing the radiotap length
+        * Load the register containing the PPI length
         * into the X register.
         */
        s = new_stmt(BPF_LDX|BPF_MEM);
-       s->s.k = reg_ll_size;
+       s->s.k = reg_off_ll;
        return s;
  }
  
  /*
   * Generate code to compute the link-layer header length, if necessary,
   * putting it into the X register, and to return either a pointer to a
@@@ -2117,18 -2784,109 +2787,109 @@@ gen_llprefixlen(void
  {
        switch (linktype) {
  
-       case DLT_PPI:
-               return gen_ppi_llprefixlen();
+       case DLT_PRISM_HEADER:
+               return gen_prism_llprefixlen();
+       case DLT_IEEE802_11_RADIO_AVS:
+               return gen_avs_llprefixlen();
  
-       
        case DLT_IEEE802_11_RADIO:
                return gen_radiotap_llprefixlen();
  
+       case DLT_PPI:
+               return gen_ppi_llprefixlen();
        default:
                return NULL;
        }
  }
  
+ /*
+  * Generate code to load the register containing the offset of the
+  * MAC-layer payload into the X register; if no register for that offset
+  * has been allocated, allocate it first.
+  */
+ static struct slist *
+ gen_off_macpl(void)
+ {
+       struct slist *s;
+       if (off_macpl_is_variable) {
+               if (reg_off_macpl == -1) {
+                       /*
+                        * We haven't yet assigned a register for the offset
+                        * of the MAC-layer payload; allocate one.
+                        */
+                       reg_off_macpl = alloc_reg();
+               }
+               /*
+                * Load the register containing the offset of the MAC-layer
+                * payload into the X register.
+                */
+               s = new_stmt(BPF_LDX|BPF_MEM);
+               s->s.k = reg_off_macpl;
+               return s;
+       } else {
+               /*
+                * That offset isn't variable, so we don't need to
+                * generate any code.
+                */
+               return NULL;
+       }
+ }
+ /*
+  * Map an Ethernet type to the equivalent PPP type.
+  */
+ static int
+ ethertype_to_ppptype(proto)
+       int proto;
+ {
+       switch (proto) {
+       case ETHERTYPE_IP:
+               proto = PPP_IP;
+               break;
+ #ifdef INET6
+       case ETHERTYPE_IPV6:
+               proto = PPP_IPV6;
+               break;
+ #endif
+       case ETHERTYPE_DN:
+               proto = PPP_DECNET;
+               break;
+       case ETHERTYPE_ATALK:
+               proto = PPP_APPLE;
+               break;
+       case ETHERTYPE_NS:
+               proto = PPP_NS;
+               break;
+       case LLCSAP_ISONS:
+               proto = PPP_OSI;
+               break;
+       case LLCSAP_8021D:
+               /*
+                * I'm assuming the "Bridging PDU"s that go
+                * over PPP are Spanning Tree Protocol
+                * Bridging PDUs.
+                */
+               proto = PPP_BRPDU;
+               break;
+       case LLCSAP_IPX:
+               proto = PPP_IPX;
+               break;
+       }
+       return (proto);
+ }
  /*
   * Generate code to match a particular packet type by matching the
   * link-layer type field or fields in the 802.2 LLC header.
@@@ -2147,12 -2905,12 +2908,12 @@@ gen_linktype(proto
                switch (proto) {
                case ETHERTYPE_IP:
                case PPP_IP:
-               /* FIXME add other L3 proto IDs */
+                       /* FIXME add other L3 proto IDs */
                        return gen_mpls_linktype(Q_IP); 
  
                case ETHERTYPE_IPV6:
                case PPP_IPV6:
-               /* FIXME add other L3 proto IDs */
+                       /* FIXME add other L3 proto IDs */
                        return gen_mpls_linktype(Q_IPV6); 
  
                default:
                }
        }
  
+       /*
+        * Are we testing PPPoE packets?
+        */
+       if (is_pppoes) {
+               /*
+                * The PPPoE session header is part of the
+                * MAC-layer payload, so all references
+                * should be relative to the beginning of
+                * that payload.
+                */
+               /*
+                * We use Ethernet protocol types inside libpcap;
+                * map them to the corresponding PPP protocol types.
+                */
+               proto = ethertype_to_ppptype(proto);
+               return gen_cmp(OR_MACPL, off_linktype, BPF_H, (bpf_int32)proto);
+       }
        switch (linktype) {
  
        case DLT_EN10MB:
                }
                break;
  
-       case DLT_PPI:
-       case DLT_FDDI:
-       case DLT_IEEE802:
        case DLT_IEEE802_11:
+       case DLT_PRISM_HEADER:
        case DLT_IEEE802_11_RADIO_AVS:
        case DLT_IEEE802_11_RADIO:
-       case DLT_PRISM_HEADER:
+       case DLT_PPI:
+               /*
+                * Check that we have a data frame.
+                */
+               b0 = gen_check_802_11_data_frame();
+               /*
+                * Now check for the specified link-layer type.
+                */
+               b1 = gen_llc_linktype(proto);
+               gen_and(b0, b1);
+               return b1;
+               /*NOTREACHED*/
+               break;
+       case DLT_FDDI:
+               /*
+                * XXX - check for asynchronous frames, as per RFC 1103.
+                */
+               return gen_llc_linktype(proto);
+               /*NOTREACHED*/
+               break;
+       case DLT_IEEE802:
+               /*
+                * XXX - check for LLC PDUs, as per IEEE 802.5.
+                */
+               return gen_llc_linktype(proto);
+               /*NOTREACHED*/
+               break;
        case DLT_ATM_RFC1483:
        case DLT_ATM_CLIP:
        case DLT_IP_OVER_FC:
                 * We use Ethernet protocol types inside libpcap;
                 * map them to the corresponding PPP protocol types.
                 */
-               switch (proto) {
-               case ETHERTYPE_IP:
-                       proto = PPP_IP;
-                       break;
- #ifdef INET6
-               case ETHERTYPE_IPV6:
-                       proto = PPP_IPV6;
-                       break;
- #endif
-               case ETHERTYPE_DN:
-                       proto = PPP_DECNET;
-                       break;
-               case ETHERTYPE_ATALK:
-                       proto = PPP_APPLE;
-                       break;
-               case ETHERTYPE_NS:
-                       proto = PPP_NS;
-                       break;
-               case LLCSAP_ISONS:
-                       proto = PPP_OSI;
-                       break;
-               case LLCSAP_8021D:
-                       /*
-                        * I'm assuming the "Bridging PDU"s that go
-                        * over PPP are Spanning Tree Protocol
-                        * Bridging PDUs.
-                        */
-                       proto = PPP_BRPDU;
-                       break;
-               case LLCSAP_IPX:
-                       proto = PPP_IPX;
-                       break;
-               }
+               proto = ethertype_to_ppptype(proto);
+               return gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_int32)proto);
+               /*NOTREACHED*/
                break;
  
        case DLT_PPP_BSDOS:
                switch (proto) {
  
                case ETHERTYPE_IP:
+                       /*
+                        * Also check for Van Jacobson-compressed IP.
+                        * XXX - do this for other forms of PPP?
+                        */
                        b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, PPP_IP);
                        b1 = gen_cmp(OR_LINK, off_linktype, BPF_H, PPP_VJC);
                        gen_or(b0, b1);
                        gen_or(b1, b0);
                        return b0;
  
- #ifdef INET6
-               case ETHERTYPE_IPV6:
-                       proto = PPP_IPV6;
-                       /* more to go? */
-                       break;
- #endif
-               case ETHERTYPE_DN:
-                       proto = PPP_DECNET;
-                       break;
-               case ETHERTYPE_ATALK:
-                       proto = PPP_APPLE;
-                       break;
-               case ETHERTYPE_NS:
-                       proto = PPP_NS;
-                       break;
-               case LLCSAP_ISONS:
-                       proto = PPP_OSI;
-                       break;
-               case LLCSAP_8021D:
-                       /*
-                        * I'm assuming the "Bridging PDU"s that go
-                        * over PPP are Spanning Tree Protocol
-                        * Bridging PDUs.
-                        */
-                       proto = PPP_BRPDU;
-                       break;
-               case LLCSAP_IPX:
-                       proto = PPP_IPX;
-                       break;
+               default:
+                       proto = ethertype_to_ppptype(proto);
+                       return gen_cmp(OR_LINK, off_linktype, BPF_H,
+                               (bpf_int32)proto);
                }
+               /*NOTREACHED*/
                break;
  
        case DLT_NULL:
                /*NOTREACHED*/
                break;
  
+       case DLT_MFR:
+               bpf_error("Multi-link Frame Relay link-layer type filtering not implemented");
          case DLT_JUNIPER_MFR:
          case DLT_JUNIPER_MLFR:
          case DLT_JUNIPER_MLPPP:
          case DLT_JUNIPER_FRELAY:
          case DLT_JUNIPER_CHDLC:
          case DLT_JUNIPER_VP:
+         case DLT_JUNIPER_ST:
+         case DLT_JUNIPER_ISM:
                /* just lets verify the magic number for now -
                 * on ATM we may have up to 6 different encapsulations on the wire
                 * and need a lot of heuristics to figure out that the payload
        case DLT_DOCSIS:
                bpf_error("DOCSIS link-layer type filtering not implemented");
  
+       case DLT_MTP2:
+       case DLT_MTP2_WITH_PHDR:
+               bpf_error("MTP2 link-layer type filtering not implemented");
+       case DLT_ERF:
+               bpf_error("ERF link-layer type filtering not implemented");
+ #ifdef DLT_PFSYNC
+       case DLT_PFSYNC:
+               bpf_error("PFSYNC link-layer type filtering not implemented");
+ #endif
        case DLT_LINUX_LAPD:
                bpf_error("LAPD link-layer type filtering not implemented");
+       case DLT_USB:
+       case DLT_USB_LINUX:
+               bpf_error("USB link-layer type filtering not implemented");
+       case DLT_BLUETOOTH_HCI_H4:
+       case DLT_BLUETOOTH_HCI_H4_WITH_PHDR:
+               bpf_error("Bluetooth link-layer type filtering not implemented");
+       case DLT_CAN20B:
+               bpf_error("CAN20B link-layer type filtering not implemented");
+       case DLT_IEEE802_15_4:
+       case DLT_IEEE802_15_4_LINUX:
+       case DLT_IEEE802_15_4_NONASK_PHY:
+               bpf_error("IEEE 802.15.4 link-layer type filtering not implemented");
+       case DLT_IEEE802_16_MAC_CPS_RADIO:
+               bpf_error("IEEE 802.16 link-layer type filtering not implemented");
+       case DLT_SITA:
+               bpf_error("SITA link-layer type filtering not implemented");
+       case DLT_RAIF1:
+               bpf_error("RAIF1 link-layer type filtering not implemented");
+       case DLT_IPMB:
+               bpf_error("IPMB link-layer type filtering not implemented");
+       case DLT_AX25_KISS:
+               bpf_error("AX.25 link-layer type filtering not implemented");
        }
  
        /*
  
        /*
         * Any type not handled above should always have an Ethernet
-        * type at an offset of "off_linktype".  (PPP is partially
-        * handled above - the protocol type is mapped from the
-        * Ethernet and LLC types we use internally to the corresponding
-        * PPP type - but the PPP type is always specified by a value
-        * at "off_linktype", so we don't have to do the code generation
-        * above.)
+        * type at an offset of "off_linktype".
         */
        return gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_int32)proto);
  }
   * code and protocol type in the SNAP header.
   */
  static struct block *
- gen_snap(orgcode, ptype, offset)
+ gen_snap(orgcode, ptype)
        bpf_u_int32 orgcode;
        bpf_u_int32 ptype;
-       u_int offset;
  {
        u_char snapblock[8];
  
        snapblock[5] = (orgcode >> 0);  /* lower 8 bits of organization code */
        snapblock[6] = (ptype >> 8);    /* upper 8 bits of protocol type */
        snapblock[7] = (ptype >> 0);    /* lower 8 bits of protocol type */
-       return gen_bcmp(OR_LINK, offset, 8, snapblock);
+       return gen_bcmp(OR_MACPL, 0, 8, snapblock);
  }
  
  /*
@@@ -2672,7 -3455,7 +3458,7 @@@ gen_llc_linktype(proto
                 * DSAP, as we do for other types <= ETHERMTU
                 * (i.e., other SAP values)?
                 */
-               return gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_u_int32)
+               return gen_cmp(OR_MACPL, 0, BPF_H, (bpf_u_int32)
                             ((proto << 8) | proto));
  
        case LLCSAP_IPX:
                 * XXX - are there ever SNAP frames for IPX on
                 * non-Ethernet 802.x networks?
                 */
-               return gen_cmp(OR_LINK, off_linktype, BPF_B,
+               return gen_cmp(OR_MACPL, 0, BPF_B,
                    (bpf_int32)LLCSAP_IPX);
  
        case ETHERTYPE_ATALK:
                 * XXX - check for an organization code of
                 * encapsulated Ethernet as well?
                 */
-               return gen_snap(0x080007, ETHERTYPE_ATALK, off_linktype);
+               return gen_snap(0x080007, ETHERTYPE_ATALK);
  
        default:
                /*
                         * This is an LLC SAP value, so check
                         * the DSAP.
                         */
-                       return gen_cmp(OR_LINK, off_linktype, BPF_B,
-                           (bpf_int32)proto);
+                       return gen_cmp(OR_MACPL, 0, BPF_B, (bpf_int32)proto);
                } else {
                        /*
                         * This is an Ethernet type; we assume that it's
                         * organization code of 0x000000 (encapsulated
                         * Ethernet), we'd do
                         *
-                        *      return gen_snap(0x000000, proto,
-                        *          off_linktype);
+                        *      return gen_snap(0x000000, proto);
                         *
                         * here; for now, we don't, as per the above.
                         * I don't know whether it's worth the extra CPU
                         * time to do the right check or not.
                         */
-                       return gen_cmp(OR_LINK, off_linktype+6, BPF_H,
-                           (bpf_int32)proto);
+                       return gen_cmp(OR_MACPL, 6, BPF_H, (bpf_int32)proto);
                }
        }
  }
@@@ -2938,7 -3718,8 +3721,8 @@@ gen_thostop(eaddr, dir
  }
  
  /*
-  * Like gen_ehostop, but for DLT_IEEE802_11 (802.11 wireless LAN)
+  * Like gen_ehostop, but for DLT_IEEE802_11 (802.11 wireless LAN) and
+  * various 802.11 + radio headers.
   */
  static struct block *
  gen_wlanhostop(eaddr, dir)
        register struct block *b0, *b1, *b2;
        register struct slist *s;
  
+ #ifdef ENABLE_WLAN_FILTERING_PATCH
+       /*
+        * TODO GV 20070613
+        * We need to disable the optimizer because the optimizer is buggy
+        * and wipes out some LD instructions generated by the below
+        * code to validate the Frame Control bits
+        */
+       no_optimize = 1;
+ #endif /* ENABLE_WLAN_FILTERING_PATCH */
        switch (dir) {
        case Q_SRC:
                /*
                 * Now check for a data frame.
                 * I.e, check "link[0] & 0x08".
                 */
-               gen_load_a(OR_LINK, 0, BPF_B);
+               s = gen_load_a(OR_LINK, 0, BPF_B);
                b1 = new_block(JMP(BPF_JSET));
                b1->s.k = 0x08;
                b1->stmts = s;
                gen_and(b1, b0);
                return b0;
  
+       /*
+        * XXX - add RA, TA, and BSSID keywords?
+        */
+       case Q_ADDR1:
+               return (gen_bcmp(OR_LINK, 4, 6, eaddr));
+       case Q_ADDR2:
+               /*
+                * Not present in CTS or ACK control frames.
+                */
+               b0 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_TYPE_CTL,
+                       IEEE80211_FC0_TYPE_MASK);
+               gen_not(b0);
+               b1 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_SUBTYPE_CTS,
+                       IEEE80211_FC0_SUBTYPE_MASK);
+               gen_not(b1);
+               b2 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_SUBTYPE_ACK,
+                       IEEE80211_FC0_SUBTYPE_MASK);
+               gen_not(b2);
+               gen_and(b1, b2);
+               gen_or(b0, b2);
+               b1 = gen_bcmp(OR_LINK, 10, 6, eaddr);
+               gen_and(b2, b1);
+               return b1;
+       case Q_ADDR3:
+               /*
+                * Not present in control frames.
+                */
+               b0 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_TYPE_CTL,
+                       IEEE80211_FC0_TYPE_MASK);
+               gen_not(b0);
+               b1 = gen_bcmp(OR_LINK, 16, 6, eaddr);
+               gen_and(b0, b1);
+               return b1;
+       case Q_ADDR4:
+               /*
+                * Present only if the direction mask has both "From DS"
+                * and "To DS" set.  Neither control frames nor management
+                * frames should have both of those set, so we don't
+                * check the frame type.
+                */
+               b0 = gen_mcmp(OR_LINK, 1, BPF_B,
+                       IEEE80211_FC1_DIR_DSTODS, IEEE80211_FC1_DIR_MASK);
+               b1 = gen_bcmp(OR_LINK, 24, 6, eaddr);
+               gen_and(b0, b1);
+               return b1;
        case Q_AND:
                b0 = gen_wlanhostop(eaddr, Q_SRC);
                b1 = gen_wlanhostop(eaddr, Q_DST);
@@@ -3656,48 -4496,48 +4499,48 @@@ gen_gateway(eaddr, alist, proto, dir
        case Q_IP:
        case Q_ARP:
        case Q_RARP:
-                 switch (linktype) {
-                 case DLT_EN10MB:
-                     b0 = gen_ehostop(eaddr, Q_OR);
-                     break;
-                 case DLT_FDDI:
-                     b0 = gen_fhostop(eaddr, Q_OR);
-                     break;
+               switch (linktype) {
+               case DLT_EN10MB:
+                       b0 = gen_ehostop(eaddr, Q_OR);
+                       break;
+               case DLT_FDDI:
+                       b0 = gen_fhostop(eaddr, Q_OR);
+                       break;
                case DLT_IEEE802:
-                     b0 = gen_thostop(eaddr, Q_OR);
-                     break;
+                       b0 = gen_thostop(eaddr, Q_OR);
+                       break;
                case DLT_IEEE802_11:
+               case DLT_PRISM_HEADER:
                case DLT_IEEE802_11_RADIO_AVS:
-               case DLT_PPI:
                case DLT_IEEE802_11_RADIO:
-               case DLT_PRISM_HEADER:
-                     b0 = gen_wlanhostop(eaddr, Q_OR);
-                     break;
-                 case DLT_SUNATM:
-                     if (is_lane) {
-                       /*
-                        * Check that the packet doesn't begin with an
-                        * LE Control marker.  (We've already generated
-                        * a test for LANE.)
-                        */
-                       b1 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS, BPF_H,
-                           0xFF00);
-                       gen_not(b1);
+               case DLT_PPI:
+                       b0 = gen_wlanhostop(eaddr, Q_OR);
+                       break;
+               case DLT_SUNATM:
+                       if (is_lane) {
+                               /*
+                                * Check that the packet doesn't begin with an
+                                * LE Control marker.  (We've already generated
+                                * a test for LANE.)
+                                */
+                               b1 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS,
+                                   BPF_H, 0xFF00);
+                               gen_not(b1);
  
-                       /*
-                        * Now check the MAC address.
-                        */
-                       b0 = gen_ehostop(eaddr, Q_OR);
-                       gen_and(b1, b0);
-                     }
-                     break;
+                               /*
+                                * Now check the MAC address.
+                                */
+                               b0 = gen_ehostop(eaddr, Q_OR);
+                               gen_and(b1, b0);
+                       }
+                       break;
                case DLT_IP_OVER_FC:
-                     b0 = gen_ipfchostop(eaddr, Q_OR);
-                     break;
-                 default:
-                     bpf_error(
+                       b0 = gen_ipfchostop(eaddr, Q_OR);
+                       break;
+               default:
+                       bpf_error(
                            "'gateway' supported only on ethernet/FDDI/token ring/802.11/Fibre Channel");
-                 }
+               }
                b1 = gen_host(**alist++, 0xffffffff, proto, Q_OR, Q_HOST);
                while (*alist) {
                        tmp = gen_host(**alist++, 0xffffffff, proto, Q_OR,
@@@ -4462,7 -5302,8 +5305,8 @@@ gen_protochain(v, proto, dir
        }
  
        /*
-        * We don't handle variable-length radiotap here headers yet.
+        * We don't handle variable-length prefixes before the link-layer
+        * header, or variable-length link-layer headers, here yet.
         * We might want to add BPF instructions to do the protochain
         * work, to simplify that and, on platforms that have a BPF
         * interpreter with the new instructions, let the filtering
         * branches, and backward branch support is unlikely to appear
         * in kernel BPF engines.)
         */
-       if (linktype == DLT_IEEE802_11_RADIO)
-               bpf_error("'protochain' not supported with radiotap headers");
+       switch (linktype) {
  
-       if (linktype == DLT_PPI)
-               bpf_error("'protochain' not supported with PPI headers");
+       case DLT_IEEE802_11:
+       case DLT_PRISM_HEADER:
+       case DLT_IEEE802_11_RADIO_AVS:
+       case DLT_IEEE802_11_RADIO:
+       case DLT_PPI:
+               bpf_error("'protochain' not supported with 802.11");
+       }
  
        no_optimize = 1; /*this code is not compatible with optimzer yet */
  
  
                /* A = ip->ip_p */
                s[i] = new_stmt(BPF_LD|BPF_ABS|BPF_B);
-               s[i]->s.k = off_ll + off_nl + 9;
+               s[i]->s.k = off_macpl + off_nl + 9;
                i++;
                /* X = ip->ip_hl << 2 */
                s[i] = new_stmt(BPF_LDX|BPF_MSH|BPF_B);
-               s[i]->s.k = off_ll + off_nl;
+               s[i]->s.k = off_macpl + off_nl;
                i++;
                break;
  #ifdef INET6
  
                /* A = ip6->ip_nxt */
                s[i] = new_stmt(BPF_LD|BPF_ABS|BPF_B);
-               s[i]->s.k = off_ll + off_nl + 6;
+               s[i]->s.k = off_macpl + off_nl + 6;
                i++;
                /* X = sizeof(struct ip6_hdr) */
                s[i] = new_stmt(BPF_LDX|BPF_IMM);
                i++;
                /* A = P[X + packet head] */
                s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B);
-               s[i]->s.k = off_ll + off_nl;
+               s[i]->s.k = off_macpl + off_nl;
                i++;
                /* MEM[reg2] = A */
                s[i] = new_stmt(BPF_ST);
                i++;
                /* A = P[X + packet head]; */
                s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B);
-               s[i]->s.k = off_ll + off_nl;
+               s[i]->s.k = off_macpl + off_nl;
                i++;
                /* A += 1 */
                s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
        i++;
        /* A = P[X + packet head]; */
        s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B);
-       s[i]->s.k = off_ll + off_nl;
+       s[i]->s.k = off_macpl + off_nl;
        i++;
        /* MEM[reg2] = A */
        s[i] = new_stmt(BPF_ST);
        i++;
        /* A = P[X + packet head] */
        s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B);
-       s[i]->s.k = off_ll + off_nl;
+       s[i]->s.k = off_macpl + off_nl;
        i++;
        /* A += 2 */
        s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
  #endif
  }
  
+ static struct block *
+ gen_check_802_11_data_frame()
+ {
+       struct slist *s;
+       struct block *b0, *b1;
+       /*
+        * A data frame has the 0x08 bit (b3) in the frame control field set
+        * and the 0x04 bit (b2) clear.
+        */
+       s = gen_load_a(OR_LINK, 0, BPF_B);
+       b0 = new_block(JMP(BPF_JSET));
+       b0->s.k = 0x08;
+       b0->stmts = s;
+       
+       s = gen_load_a(OR_LINK, 0, BPF_B);
+       b1 = new_block(JMP(BPF_JSET));
+       b1->s.k = 0x04;
+       b1->stmts = s;
+       gen_not(b1);
+       gen_and(b1, b0);
+       return b0;
+ }
  
  /*
   * Generate code that checks whether the packet is a packet for protocol
@@@ -5023,9 -5893,9 +5896,9 @@@ gen_scode(name, q
                                return b;
  
                        case DLT_IEEE802_11:
+                       case DLT_PRISM_HEADER:
                        case DLT_IEEE802_11_RADIO_AVS:
                        case DLT_IEEE802_11_RADIO:
-                       case DLT_PRISM_HEADER:
                        case DLT_PPI:
                                eaddr = pcap_ether_hostton(name);
                                if (eaddr == NULL)
                else
                        bpf_error("unknown protocol: %s", name);
  
        case Q_UNDEF:
                syntax();
                /* NOTREACHED */
@@@ -5491,44 -6360,44 +6363,44 @@@ gen_ecode(eaddr, q
        struct block *b, *tmp;
  
        if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) {
-             switch (linktype) {
-             case DLT_EN10MB:
-                 return gen_ehostop(eaddr, (int)q.dir);
-             case DLT_FDDI:
-                 return gen_fhostop(eaddr, (int)q.dir);
-             case DLT_IEEE802:
-                 return gen_thostop(eaddr, (int)q.dir);
-                       case DLT_IEEE802_11:
-                       case DLT_IEEE802_11_RADIO_AVS:
-                       case DLT_IEEE802_11_RADIO:
-                       case DLT_PRISM_HEADER:
-                       case DLT_PPI:
-                               return gen_wlanhostop(eaddr, (int)q.dir);
-                       case DLT_SUNATM:
-                               if (is_lane) {
-                                       /*
-                                        * Check that the packet doesn't begin with an
-                                        * LE Control marker.  (We've already generated
-                                        * a test for LANE.)
-                                        */
-                                       tmp = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS, BPF_H,
-                                               0xFF00);
-                                       gen_not(tmp);
-                                       /*
-                                        * Now check the MAC address.
-                                        */
-                                       b = gen_ehostop(eaddr, (int)q.dir);
-                                       gen_and(tmp, b);
-                                       return b;
-                               }
-                               break;
-                       case DLT_IP_OVER_FC:
-                 return gen_ipfchostop(eaddr, (int)q.dir);
-             default:
-                               bpf_error("ethernet addresses supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel");
-                 break;
-             }
+               switch (linktype) {
+               case DLT_EN10MB:
+                       return gen_ehostop(eaddr, (int)q.dir);
+               case DLT_FDDI:
+                       return gen_fhostop(eaddr, (int)q.dir);
+               case DLT_IEEE802:
+                       return gen_thostop(eaddr, (int)q.dir);
+               case DLT_IEEE802_11:
+               case DLT_PRISM_HEADER:
+               case DLT_IEEE802_11_RADIO_AVS:
+               case DLT_IEEE802_11_RADIO:
+               case DLT_PPI:
+                       return gen_wlanhostop(eaddr, (int)q.dir);
+               case DLT_SUNATM:
+                       if (is_lane) {
+                               /*
+                                * Check that the packet doesn't begin with an
+                                * LE Control marker.  (We've already generated
+                                * a test for LANE.)
+                                */
+                               tmp = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS, BPF_H,
+                                       0xFF00);
+                               gen_not(tmp);
+                               /*
+                                * Now check the MAC address.
+                                */
+                               b = gen_ehostop(eaddr, (int)q.dir);
+                               gen_and(tmp, b);
+                               return b;
+                       }
+                       break;
+               case DLT_IP_OVER_FC:
+                       return gen_ipfchostop(eaddr, (int)q.dir);
+               default:
+                       bpf_error("ethernet addresses supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel");
+                       break;
+               }
        }
        bpf_error("ethernet address used in non-ether expression");
        /* NOTREACHED */
@@@ -5695,14 -6564,14 +6567,14 @@@ gen_load(proto, inst, size
                 * XXX - are there any cases where we want
                 * off_nl_nosnap?
                 */
-               s = gen_llprefixlen();
+               s = gen_off_macpl();
  
                /*
                 * If "s" is non-null, it has code to arrange that the
-                * X register contains the length of the prefix preceding
-                * the link-layer header.  Add to it the offset computed
-                * into the register specified by "index", and move that
-                * into the X register.  Otherwise, just load into the X
+                * X register contains the offset of the MAC-layer
+                * payload.  Add to it the offset computed into the
+                * register specified by "index", and move that into
+                * the X register.  Otherwise, just load into the X
                 * register the offset computed into the register specifed
                 * by "index".
                 */
                /*
                 * Load the item at the sum of the offset we've put in the
                 * X register, the offset of the start of the network
-                * layer header, and the offset of the start of the link
-                * layer header (which is 0 if the radio header is
-                * variable-length; that header length is what we put
-                * into the X register and then added to the index).
+                * layer header from the beginning of the MAC-layer
+                * payload, and the purported offset of the start of the
+                * MAC-layer payload (which might be 0 if there's a
+                * variable-length prefix before the link-layer header
+                * or the link-layer header itself is variable-length;
+                * the variable-length offset of the start of the
+                * MAC-layer payload is what we put into the X register
+                * and then added to the index).
                 */
                tmp = new_stmt(BPF_LD|BPF_IND|size);
-               tmp->s.k = off_ll + off_nl;
+               tmp->s.k = off_macpl + off_nl;
                sappend(s, tmp);
                sappend(inst->s, s);
  
                /*
                 * The X register now contains the sum of the length
                 * of any variable-length header preceding the link-layer
-                * header and the length of the network-layer header.
+                * header, any variable-length link-layer header, and the
+                * length of the network-layer header.
+                *
                 * Load into the A register the offset relative to
                 * the beginning of the transport layer header,
                 * add the X register to that, move that to the
                 * X register, and load with an offset from the
                 * X register equal to the offset of the network
                 * layer header relative to the beginning of
-                * the link-layer header plus the length of any
-                * fixed-length header preceding the link-layer
-                * header.
+                * the MAC-layer payload plus the fixed-length
+                * portion of the offset of the MAC-layer payload
+                * from the beginning of the raw packet data.
                 */
                sappend(s, xfer_to_a(inst));
                sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X));
                sappend(s, new_stmt(BPF_MISC|BPF_TAX));
                sappend(s, tmp = new_stmt(BPF_LD|BPF_IND|size));
-               tmp->s.k = off_ll + off_nl;
+               tmp->s.k = off_macpl + off_nl;
                sappend(inst->s, s);
  
                /*
@@@ -5944,6 -6819,16 +6822,16 @@@ gen_arth(code, a0, a1
  static int regused[BPF_MEMWORDS];
  static int curreg;
  
+ /*
+  * Initialize the table of used registers and the current register.
+  */
+ static void
+ init_regs()
+ {
+       curreg = 0;
+       memset(regused, 0, sizeof regused);
+ }
  /*
   * Return the next free register.
   */
@@@ -6075,46 -6960,46 +6963,46 @@@ gen_broadcast(proto
  
        case Q_DEFAULT:
        case Q_LINK:
-                 switch (linktype) {
-                 case DLT_ARCNET:
-                 case DLT_ARCNET_LINUX:
-                     return gen_ahostop(abroadcast, Q_DST);
-                 case DLT_EN10MB:    
-                     return gen_ehostop(ebroadcast, Q_DST);
-                 case DLT_FDDI:
-                     return gen_fhostop(ebroadcast, Q_DST);
-                 case DLT_IEEE802:
-                     return gen_thostop(ebroadcast, Q_DST);
-                 case DLT_IEEE802_11:
-                 case DLT_IEEE802_11_RADIO_AVS:
-                 case DLT_IEEE802_11_RADIO:
-                               case DLT_PPI:
-                 case DLT_PRISM_HEADER:
-                     return gen_wlanhostop(ebroadcast, Q_DST);
-                 case DLT_IP_OVER_FC:
-                     return gen_ipfchostop(ebroadcast, Q_DST);
-                 case DLT_SUNATM:
-                     if (is_lane) {
-                       /*
-                        * Check that the packet doesn't begin with an
-                        * LE Control marker.  (We've already generated
-                        * a test for LANE.)
-                        */
-                       b1 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS, BPF_H,
-                           0xFF00);
-                       gen_not(b1);
+               switch (linktype) {
+               case DLT_ARCNET:
+               case DLT_ARCNET_LINUX:
+                       return gen_ahostop(abroadcast, Q_DST);
+               case DLT_EN10MB:
+                       return gen_ehostop(ebroadcast, Q_DST);
+               case DLT_FDDI:
+                       return gen_fhostop(ebroadcast, Q_DST);
+               case DLT_IEEE802:
+                       return gen_thostop(ebroadcast, Q_DST);
+               case DLT_IEEE802_11:
+               case DLT_PRISM_HEADER:
+               case DLT_IEEE802_11_RADIO_AVS:
+               case DLT_IEEE802_11_RADIO:
+               case DLT_PPI:
+                       return gen_wlanhostop(ebroadcast, Q_DST);
+               case DLT_IP_OVER_FC:
+                       return gen_ipfchostop(ebroadcast, Q_DST);
+               case DLT_SUNATM:
+                       if (is_lane) {
+                               /*
+                                * Check that the packet doesn't begin with an
+                                * LE Control marker.  (We've already generated
+                                * a test for LANE.)
+                                */
+                               b1 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS,
+                                   BPF_H, 0xFF00);
+                               gen_not(b1);
  
-                       /*
-                        * Now check the MAC address.
-                        */
-                       b0 = gen_ehostop(ebroadcast, Q_DST);
-                       gen_and(b1, b0);
-                       return b0;
-                     }
-                     break;
-                 default:
-                     bpf_error("not a broadcast link");
-                 }
+                               /*
+                                * Now check the MAC address.
+                                */
+                               b0 = gen_ehostop(ebroadcast, Q_DST);
+                               gen_and(b1, b0);
+                               return b0;
+                       }
+                       break;
+               default:
+                       bpf_error("not a broadcast link");
+               }
                break;
  
        case Q_IP:
@@@ -6162,167 -7047,167 +7050,167 @@@ gen_multicast(proto
  
        case Q_DEFAULT:
        case Q_LINK:
-                 switch (linktype) {
-                 case DLT_ARCNET:
-                 case DLT_ARCNET_LINUX:
-                     /* all ARCnet multicasts use the same address */
-                     return gen_ahostop(abroadcast, Q_DST);
-                 case  DLT_EN10MB:
-                     /* ether[0] & 1 != 0 */
-                     return gen_mac_multicast(0);
-                 case DLT_FDDI:
-                     /*
-                      * XXX TEST THIS: MIGHT NOT PORT PROPERLY XXX
-                      *
-                      * XXX - was that referring to bit-order issues?
-                      */
-                     /* fddi[1] & 1 != 0 */
-                     return gen_mac_multicast(1);
-                 case DLT_IEEE802:
-                     /* tr[2] & 1 != 0 */
-                     return gen_mac_multicast(2);
-                 case DLT_IEEE802_11:
-                 case DLT_IEEE802_11_RADIO_AVS:
-                               case DLT_PPI:
-                 case DLT_IEEE802_11_RADIO:
-                 case DLT_PRISM_HEADER:
-                     /*
-                      * Oh, yuk.
-                      *
-                      *        For control frames, there is no DA.
-                      *
-                      *        For management frames, DA is at an
-                      *        offset of 4 from the beginning of
-                      *        the packet.
-                      *
-                      *        For data frames, DA is at an offset
-                      *        of 4 from the beginning of the packet
-                      *        if To DS is clear and at an offset of
-                      *        16 from the beginning of the packet
-                      *        if To DS is set.
-                      */
-                     
-                     /*
-                      * Generate the tests to be done for data frames.
-                      *
-                      * First, check for To DS set, i.e. "link[1] & 0x01".
-                      */
-                     s = gen_load_a(OR_LINK, 1, BPF_B);
-                     b1 = new_block(JMP(BPF_JSET));
-                     b1->s.k = 0x01;   /* To DS */
-                     b1->stmts = s;
-                     
-                     /*
-                      * If To DS is set, the DA is at 16.
-                      */
-                     b0 = gen_mac_multicast(16);
-                     gen_and(b1, b0);
-                     
-                     /*
-                      * Now, check for To DS not set, i.e. check
-                      * "!(link[1] & 0x01)".
-                      */
-                     s = gen_load_a(OR_LINK, 1, BPF_B);
-                     b2 = new_block(JMP(BPF_JSET));
-                     b2->s.k = 0x01;   /* To DS */
-                     b2->stmts = s;
-                     gen_not(b2);
-                     
-                     /*
-                      * If To DS is not set, the DA is at 4.
-                      */
-                     b1 = gen_mac_multicast(4);
-                     gen_and(b2, b1);
-                     
-                     /*
-                      * Now OR together the last two checks.  That gives
-                      * the complete set of checks for data frames.
-                      */
-                     gen_or(b1, b0);
-                     
-                     /*
-                      * Now check for a data frame.
-                      * I.e, check "link[0] & 0x08".
-                      */
-                     s = gen_load_a(OR_LINK, 0, BPF_B);
-                     b1 = new_block(JMP(BPF_JSET));
-                     b1->s.k = 0x08;
-                     b1->stmts = s;
-                     
-                     /*
-                      * AND that with the checks done for data frames.
-                      */
-                     gen_and(b1, b0);
-                     
-                     /*
-                      * If the high-order bit of the type value is 0, this
-                      * is a management frame.
-                      * I.e, check "!(link[0] & 0x08)".
-                      */
-                     s = gen_load_a(OR_LINK, 0, BPF_B);
-                     b2 = new_block(JMP(BPF_JSET));
-                     b2->s.k = 0x08;
-                     b2->stmts = s;
-                     gen_not(b2);
-                     
-                     /*
-                      * For management frames, the DA is at 4.
-                      */
-                     b1 = gen_mac_multicast(4);
-                     gen_and(b2, b1);
-                     
-                     /*
-                      * OR that with the checks done for data frames.
-                      * That gives the checks done for management and
-                      * data frames.
-                      */
-                     gen_or(b1, b0);
-                     
-                     /*
-                      * If the low-order bit of the type value is 1,
-                      * this is either a control frame or a frame
-                      * with a reserved type, and thus not a
-                      * frame with an SA.
-                      *
-                      * I.e., check "!(link[0] & 0x04)".
-                      */
-                     s = gen_load_a(OR_LINK, 0, BPF_B);
-                     b1 = new_block(JMP(BPF_JSET));
-                     b1->s.k = 0x04;
-                     b1->stmts = s;
-                     gen_not(b1);
-                     
-                     /*
-                      * AND that with the checks for data and management
-                      * frames.
-                      */
-                     gen_and(b1, b0);
-                     return b0;
-                 case DLT_IP_OVER_FC:
-                     b0 = gen_mac_multicast(2);
-                     return b0;
-                 case DLT_SUNATM:
-                     if (is_lane) {
+               switch (linktype) {
+               case DLT_ARCNET:
+               case DLT_ARCNET_LINUX:
+                       /* all ARCnet multicasts use the same address */
+                       return gen_ahostop(abroadcast, Q_DST);
+               case DLT_EN10MB:
+                       /* ether[0] & 1 != 0 */
+                       return gen_mac_multicast(0);
+               case DLT_FDDI:
                        /*
-                        * Check that the packet doesn't begin with an
-                        * LE Control marker.  (We've already generated
-                        * a test for LANE.)
+                        * XXX TEST THIS: MIGHT NOT PORT PROPERLY XXX
+                        *
+                        * XXX - was that referring to bit-order issues?
                         */
-                       b1 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS, BPF_H,
-                           0xFF00);
+                       /* fddi[1] & 1 != 0 */
+                       return gen_mac_multicast(1);
+               case DLT_IEEE802:
+                       /* tr[2] & 1 != 0 */
+                       return gen_mac_multicast(2);
+               case DLT_IEEE802_11:
+               case DLT_PRISM_HEADER:
+               case DLT_IEEE802_11_RADIO_AVS:
+               case DLT_IEEE802_11_RADIO:
+               case DLT_PPI:
+                       /*
+                        * Oh, yuk.
+                        *
+                        *      For control frames, there is no DA.
+                        *
+                        *      For management frames, DA is at an
+                        *      offset of 4 from the beginning of
+                        *      the packet.
+                        *
+                        *      For data frames, DA is at an offset
+                        *      of 4 from the beginning of the packet
+                        *      if To DS is clear and at an offset of
+                        *      16 from the beginning of the packet
+                        *      if To DS is set.
+                        */
+                       /*
+                        * Generate the tests to be done for data frames.
+                        *
+                        * First, check for To DS set, i.e. "link[1] & 0x01".
+                        */
+                       s = gen_load_a(OR_LINK, 1, BPF_B);
+                       b1 = new_block(JMP(BPF_JSET));
+                       b1->s.k = 0x01; /* To DS */
+                       b1->stmts = s;
+                       /*
+                        * If To DS is set, the DA is at 16.
+                        */
+                       b0 = gen_mac_multicast(16);
+                       gen_and(b1, b0);
+                       /*
+                        * Now, check for To DS not set, i.e. check
+                        * "!(link[1] & 0x01)".
+                        */
+                       s = gen_load_a(OR_LINK, 1, BPF_B);
+                       b2 = new_block(JMP(BPF_JSET));
+                       b2->s.k = 0x01; /* To DS */
+                       b2->stmts = s;
+                       gen_not(b2);
+                       /*
+                        * If To DS is not set, the DA is at 4.
+                        */
+                       b1 = gen_mac_multicast(4);
+                       gen_and(b2, b1);
+                       /*
+                        * Now OR together the last two checks.  That gives
+                        * the complete set of checks for data frames.
+                        */
+                       gen_or(b1, b0);
+                       /*
+                        * Now check for a data frame.
+                        * I.e, check "link[0] & 0x08".
+                        */
+                       s = gen_load_a(OR_LINK, 0, BPF_B);
+                       b1 = new_block(JMP(BPF_JSET));
+                       b1->s.k = 0x08;
+                       b1->stmts = s;
+                       /*
+                        * AND that with the checks done for data frames.
+                        */
+                       gen_and(b1, b0);
+                       /*
+                        * If the high-order bit of the type value is 0, this
+                        * is a management frame.
+                        * I.e, check "!(link[0] & 0x08)".
+                        */
+                       s = gen_load_a(OR_LINK, 0, BPF_B);
+                       b2 = new_block(JMP(BPF_JSET));
+                       b2->s.k = 0x08;
+                       b2->stmts = s;
+                       gen_not(b2);
+                       /*
+                        * For management frames, the DA is at 4.
+                        */
+                       b1 = gen_mac_multicast(4);
+                       gen_and(b2, b1);
+                       /*
+                        * OR that with the checks done for data frames.
+                        * That gives the checks done for management and
+                        * data frames.
+                        */
+                       gen_or(b1, b0);
+                       /*
+                        * If the low-order bit of the type value is 1,
+                        * this is either a control frame or a frame
+                        * with a reserved type, and thus not a
+                        * frame with an SA.
+                        *
+                        * I.e., check "!(link[0] & 0x04)".
+                        */
+                       s = gen_load_a(OR_LINK, 0, BPF_B);
+                       b1 = new_block(JMP(BPF_JSET));
+                       b1->s.k = 0x04;
+                       b1->stmts = s;
                        gen_not(b1);
  
-                       /* ether[off_mac] & 1 != 0 */
-                       b0 = gen_mac_multicast(off_mac);
+                       /*
+                        * AND that with the checks for data and management
+                        * frames.
+                        */
                        gen_and(b1, b0);
                        return b0;
-                     }
-                     break;
-                 default:
-                     break;
-                 }
-                 /* Link not known to support multicasts */
-                 break;
+               case DLT_IP_OVER_FC:
+                       b0 = gen_mac_multicast(2);
+                       return b0;
+               case DLT_SUNATM:
+                       if (is_lane) {
+                               /*
+                                * Check that the packet doesn't begin with an
+                                * LE Control marker.  (We've already generated
+                                * a test for LANE.)
+                                */
+                               b1 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS,
+                                   BPF_H, 0xFF00);
+                               gen_not(b1);
+                               /* ether[off_mac] & 1 != 0 */
+                               b0 = gen_mac_multicast(off_mac);
+                               gen_and(b1, b0);
+                               return b0;
+                       }
+                       break;
+               default:
+                       break;
+               }
+               /* Link not known to support multicasts */
+               break;
  
        case Q_IP:
                b0 = gen_linktype(ETHERTYPE_IP);
@@@ -6419,6 -7304,8 +7307,8 @@@ gen_inbound(dir
          case DLT_JUNIPER_FRELAY:
          case DLT_JUNIPER_CHDLC:
          case DLT_JUNIPER_VP:
+         case DLT_JUNIPER_ST:
+         case DLT_JUNIPER_ISM:
                /* juniper flags (including direction) are stored
                 * the byte after the 3-byte magic number */
                if (dir) {
                        /* match incoming packets */
                        b0 = gen_mcmp(OR_LINK, 3, BPF_B, 1, 0x01);
                }
-           break;
+               break;
  
        default:
                bpf_error("inbound/outbound not supported on linktype %d",
@@@ -6447,13 -7334,12 +7337,12 @@@ gen_pf_ifname(const char *ifname
        struct block *b0;
        u_int len, off;
  
-       if (linktype == DLT_PFLOG) {
-               len = sizeof(((struct pfloghdr *)0)->ifname);
-               off = offsetof(struct pfloghdr, ifname);
-       } else {
-               bpf_error("ifname not supported on linktype 0x%x", linktype);
+       if (linktype != DLT_PFLOG) {
+               bpf_error("ifname supported only on PF linktype");
                /* NOTREACHED */
        }
+       len = sizeof(((struct pfloghdr *)0)->ifname);
+       off = offsetof(struct pfloghdr, ifname);
        if (strlen(ifname) >= len) {
                bpf_error("ifname interface names can only be %d characters",
                    len-1);
@@@ -6470,14 -7356,16 +7359,16 @@@ gen_pf_ruleset(char *ruleset
        struct block *b0;
  
        if (linktype != DLT_PFLOG) {
-               bpf_error("ruleset not supported on linktype 0x%x", linktype);
+               bpf_error("ruleset supported only on PF linktype");
                /* NOTREACHED */
        }
        if (strlen(ruleset) >= sizeof(((struct pfloghdr *)0)->ruleset)) {
                bpf_error("ruleset names can only be %ld characters",
                    (long)(sizeof(((struct pfloghdr *)0)->ruleset) - 1));
                /* NOTREACHED */
        }
        b0 = gen_bcmp(OR_LINK, offsetof(struct pfloghdr, ruleset),
            strlen(ruleset), (const u_char *)ruleset);
        return (b0);
@@@ -6489,14 -7377,13 +7380,13 @@@ gen_pf_rnr(int rnr
  {
        struct block *b0;
  
-       if (linktype == DLT_PFLOG) {
-               b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, rulenr), BPF_W,
-                        (bpf_int32)rnr);
-       } else {
-               bpf_error("rnr not supported on linktype 0x%x", linktype);
+       if (linktype != DLT_PFLOG) {
+               bpf_error("rnr supported only on PF linktype");
                /* NOTREACHED */
        }
  
+       b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, rulenr), BPF_W,
+                (bpf_int32)rnr);
        return (b0);
  }
  
@@@ -6507,7 -7394,7 +7397,7 @@@ gen_pf_srnr(int srnr
        struct block *b0;
  
        if (linktype != DLT_PFLOG) {
-               bpf_error("srnr not supported on linktype 0x%x", linktype);
+               bpf_error("srnr supported only on PF linktype");
                /* NOTREACHED */
        }
  
@@@ -6522,14 -7409,13 +7412,13 @@@ gen_pf_reason(int reason
  {
        struct block *b0;
  
-       if (linktype == DLT_PFLOG) {
-               b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, reason), BPF_B,
-                   (bpf_int32)reason);
-       } else {
-               bpf_error("reason not supported on linktype 0x%x", linktype);
+       if (linktype != DLT_PFLOG) {
+               bpf_error("reason supported only on PF linktype");
                /* NOTREACHED */
        }
  
+       b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, reason), BPF_B,
+           (bpf_int32)reason);
        return (b0);
  }
  
@@@ -6539,14 -7425,13 +7428,13 @@@ gen_pf_action(int action
  {
        struct block *b0;
  
-       if (linktype == DLT_PFLOG) {
-               b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, action), BPF_B,
-                   (bpf_int32)action);
-       } else {
-               bpf_error("action not supported on linktype 0x%x", linktype);
+       if (linktype != DLT_PFLOG) {
+               bpf_error("action supported only on PF linktype");
                /* NOTREACHED */
        }
  
+       b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, action), BPF_B,
+           (bpf_int32)action);
        return (b0);
  }
  #else /* !HAVE_NET_PFVAR_H */
@@@ -6605,12 -7490,45 +7493,45 @@@ gen_p80211_type(int type, int mask
  {
        struct block *b0;
  
-       if (linktype != DLT_IEEE802_11 && linktype != DLT_IEEE802_11_RADIO) {
-               bpf_error("action not supported on linktype 0x%x\n", linktype);
+       switch (linktype) {
+       case DLT_IEEE802_11:
+       case DLT_PRISM_HEADER:
+       case DLT_IEEE802_11_RADIO_AVS:
+       case DLT_IEEE802_11_RADIO:
+               b0 = gen_mcmp(OR_LINK, 0, BPF_B, (bpf_int32)type,
+                   (bpf_int32)mask);
+               break;
+       default:
+               bpf_error("802.11 link-layer types supported only on 802.11");
+               /* NOTREACHED */
+       }
+       return (b0);
+ }
+ struct block *
+ gen_p80211_fcdir(int fcdir)
+ {
+       struct block *b0;
+       switch (linktype) {
+       case DLT_IEEE802_11:
+       case DLT_PRISM_HEADER:
+       case DLT_IEEE802_11_RADIO_AVS:
+       case DLT_IEEE802_11_RADIO:
+               break;
+       default:
+               bpf_error("frame direction supported only with 802.11 headers");
                /* NOTREACHED */
        }
-       b0 = gen_mcmp(OR_LINK, offsetof(struct ieee80211_frame, i_fc[0]),
-                     BPF_B, (bpf_int32)type, (bpf_int32)mask);
+       b0 = gen_mcmp(OR_LINK, 1, BPF_B, (bpf_int32)fcdir,
+               (bpf_u_int32)IEEE80211_FC1_DIR_MASK);
        return (b0);
  }
  
@@@ -6619,9 -7537,22 +7540,22 @@@ gen_acode(eaddr, q
        register const u_char *eaddr;
        struct qual q;
  {
-       if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) {
-               if (linktype == DLT_ARCNET || linktype == DLT_ARCNET_LINUX)
-                       return gen_ahostop(eaddr, (int)q.dir);
+       switch (linktype) {
+       case DLT_ARCNET:
+       case DLT_ARCNET_LINUX:
+               if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) &&
+                   q.proto == Q_LINK)
+                       return (gen_ahostop(eaddr, (int)q.dir));
+               else {
+                       bpf_error("ARCnet address used in non-arc expression");
+                       /* NOTREACHED */
+               }
+               break;
+       default:
+               bpf_error("aid supported only on ARCnet");
+               /* NOTREACHED */
        }
        bpf_error("ARCnet address used in non-arc expression");
        /* NOTREACHED */
@@@ -6674,10 -7605,11 +7608,11 @@@ gen_vlan(vlan_num
                bpf_error("no VLAN match after MPLS");
  
        /*
-        * Change the offsets to point to the type and data fields within
-        * the VLAN packet.  Just increment the offsets, so that we
-        * can support a hierarchy, e.g. "vlan 300 && vlan 200" to
-        * capture VLAN 200 encapsulated within VLAN 100.
+        * Check for a VLAN packet, and then change the offsets to point
+        * to the type and data fields within the VLAN packet.  Just
+        * increment the offsets, so that we can support a hierarchy, e.g.
+        * "vlan 300 && vlan 200" to capture VLAN 200 encapsulated within
+        * VLAN 100.
         *
         * XXX - this is a bit of a kludge.  If we were to split the
         * compiler into a parser that parses an expression and
         * be done assuming a VLAN, even though the "or" could be viewed
         * as meaning "or, if this isn't a VLAN packet...".
         */
-       orig_linktype = off_linktype;   /* save original values */
        orig_nl = off_nl;
  
        switch (linktype) {
  
        case DLT_EN10MB:
+               /* check for VLAN */
+               b0 = gen_cmp(OR_LINK, off_linktype, BPF_H,
+                   (bpf_int32)ETHERTYPE_8021Q);
+               /* If a specific VLAN is requested, check VLAN id */
+               if (vlan_num >= 0) {
+                       b1 = gen_mcmp(OR_MACPL, 0, BPF_H,
+                           (bpf_int32)vlan_num, 0x0fff);
+                       gen_and(b0, b1);
+                       b0 = b1;
+               }
+               off_macpl += 4;
                off_linktype += 4;
+ #if 0
                off_nl_nosnap += 4;
                off_nl += 4;
+ #endif
                break;
  
        default:
                /*NOTREACHED*/
        }
  
-       /* check for VLAN */
-       b0 = gen_cmp(OR_LINK, orig_linktype, BPF_H, (bpf_int32)ETHERTYPE_8021Q);
-       /* If a specific VLAN is requested, check VLAN id */
-       if (vlan_num >= 0) {
-               b1 = gen_mcmp(OR_LINK, orig_nl, BPF_H, (bpf_int32)vlan_num,
-                   0x0fff);
-               gen_and(b0, b1);
-               b0 = b1;
-       }
        return (b0);
  }
  
@@@ -6756,7 -7691,7 +7694,7 @@@ gen_mpls(label_num
  
          if (label_stack_depth > 0) {
              /* just match the bottom-of-stack bit clear */
-             b0 = gen_mcmp(OR_LINK, orig_nl-2, BPF_B, 0, 0x01);
+             b0 = gen_mcmp(OR_MACPL, orig_nl-2, BPF_B, 0, 0x01);
          } else {
              /*
               * Indicate that we're checking MPLS-encapsulated headers,
        /* If a specific MPLS label is requested, check it */
        if (label_num >= 0) {
                label_num = label_num << 12; /* label is shifted 12 bits on the wire */
-               b1 = gen_mcmp(OR_LINK, orig_nl, BPF_W, (bpf_int32)label_num,
+               b1 = gen_mcmp(OR_MACPL, orig_nl, BPF_W, (bpf_int32)label_num,
                    0xfffff000); /* only compare the first 20 bits */
                gen_and(b0, b1);
                b0 = b1;
@@@ -6825,7 -7760,8 +7763,8 @@@ gen_pppoes(
  
        /*
         * Change the offsets to point to the type and data fields within
-        * the PPP packet.
+        * the PPP packet, and note that this is PPPoE rather than
+        * raw PPP.
         *
         * XXX - this is a bit of a kludge.  If we were to split the
         * compiler into a parser that parses an expression and
         */
        orig_linktype = off_linktype;   /* save original values */
        orig_nl = off_nl;
+       is_pppoes = 1;
  
        /*
         * The "network-layer" protocol is PPPoE, which has a 6-byte
-        * PPPoE header, followed by PPP payload, so we set the
-        * offsets to the network layer offset plus 6 bytes for
-        * the PPPoE header plus the values appropriate for PPP when
-        * encapsulated in Ethernet (which means there's no HDLC
-        * encapsulation).
+        * PPPoE header, followed by a PPP packet.
+        *
+        * There is no HDLC encapsulation for the PPP packet (it's
+        * encapsulated in PPPoES instead), so the link-layer type
+        * starts at the first byte of the PPP packet.  For PPPoE,
+        * that offset is relative to the beginning of the total
+        * link-layer payload, including any 802.2 LLC header, so
+        * it's 6 bytes past off_nl.
         */
-       off_linktype = orig_nl + 6;
-       off_nl = orig_nl + 6 + 2;
-       off_nl_nosnap = orig_nl + 6 + 2;
+       off_linktype = off_nl + 6;
  
        /*
-        * Set the link-layer type to PPP, as all subsequent tests will
-        * be on the encapsulated PPP header.
+        * The network-layer offsets are relative to the beginning
+        * of the MAC-layer payload; that's past the 6-byte
+        * PPPoE header and the 2-byte PPP header.
         */
-       linktype = DLT_PPP;
+       off_nl = 6+2;
+       off_nl_nosnap = 6+2;
  
        return b0;
  }
@@@ -7016,8 -7956,9 +7959,9 @@@ gen_atmtype_abbrev(type
                is_lane = 1;
                off_mac = off_payload + 2;      /* MAC header */
                off_linktype = off_mac + 12;
-               off_nl = off_mac + 14;          /* Ethernet II */
-               off_nl_nosnap = off_mac + 17;   /* 802.3+802.2 */
+               off_macpl = off_mac + 14;       /* Ethernet */
+               off_nl = 0;                     /* Ethernet II */
+               off_nl_nosnap = 3;              /* 802.3+802.2 */
                break;
  
        case A_LLC:
@@@ -7050,6 -7991,7 +7994,7 @@@ gen_mtp2type_abbrev(type
  
        case M_FISU:
                if ( (linktype != DLT_MTP2) &&
+                    (linktype != DLT_ERF) &&
                     (linktype != DLT_MTP2_WITH_PHDR) )
                        bpf_error("'fisu' supported only on MTP2");
                /* gen_ncmp(offrel, offset, size, mask, jtype, reverse, value) */
  
        case M_LSSU:
                if ( (linktype != DLT_MTP2) &&
+                    (linktype != DLT_ERF) &&
                     (linktype != DLT_MTP2_WITH_PHDR) )
                        bpf_error("'lssu' supported only on MTP2");
                b0 = gen_ncmp(OR_PACKET, off_li, BPF_B, 0x3f, BPF_JGT, 1, 2);
  
        case M_MSU:
                if ( (linktype != DLT_MTP2) &&
+                    (linktype != DLT_ERF) &&
                     (linktype != DLT_MTP2_WITH_PHDR) )
                        bpf_error("'msu' supported only on MTP2");
                b0 = gen_ncmp(OR_PACKET, off_li, BPF_B, 0x3f, BPF_JGT, 0, 2);
@@@ -22,7 -22,7 +22,7 @@@
   */
  #ifndef lint
  static const char rcsid[] _U_ =
-     "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.86.2.9 2007/09/12 19:17:25 guy Exp $ (LBL)";
+     "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.99.2.2 2007/11/18 02:04:55 guy Exp $ (LBL)";
  #endif
  
  #ifdef HAVE_CONFIG_H
@@@ -54,13 -54,11 +54,12 @@@ struct rtentry
  #include "gencode.h"
  #ifdef HAVE_NET_PFVAR_H
  #include <net/if.h>
 -#include <net/pfvar.h>
 -#include <net/if_pflog.h>
 +#include <net/if_var.h>
 +#include <net/pf/pfvar.h>
 +#include <net/pf/if_pflog.h>
  #endif
- #include <pcap-namedb.h>
 -#include "ieee80211.h"
 +#include <netproto/802_11/ieee80211.h>
+ #include <pcap/namedb.h>
  
  #ifdef HAVE_OS_PROTO_H
  #include "os-proto.h"
                         (q).dir = (d),\
                         (q).addr = (a)
  
- static const char *ieee80211_mgt_names[] = IEEE80211_MGT_SUBTYPE_NAMES;
- static const char *ieee80211_ctl_names[] = IEEE80211_CTL_SUBTYPE_NAMES;
- static const char *ieee80211_data_names[] = IEEE80211_DATA_SUBTYPE_NAMES;
+ struct tok {
+       int v;                  /* value */
+       const char *s;          /* string */
+ };
+ static const struct tok ieee80211_types[] = {
+       { IEEE80211_FC0_TYPE_DATA, "data" },
+       { IEEE80211_FC0_TYPE_MGT, "mgt" },
+       { IEEE80211_FC0_TYPE_MGT, "management" },
+       { IEEE80211_FC0_TYPE_CTL, "ctl" },
+       { IEEE80211_FC0_TYPE_CTL, "control" },
+       { 0, NULL }
+ };
+ static const struct tok ieee80211_mgt_subtypes[] = {
+       { IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assocreq" },
+       { IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assoc-req" },
+       { IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assocresp" },
+       { IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assoc-resp" },
+       { IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassocreq" },
+       { IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassoc-req" },
+       { IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassocresp" },
+       { IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassoc-resp" },
+       { IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probereq" },
+       { IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probe-req" },
+       { IEEE80211_FC0_SUBTYPE_PROBE_RESP, "proberesp" },
+       { IEEE80211_FC0_SUBTYPE_PROBE_RESP, "probe-resp" },
+       { IEEE80211_FC0_SUBTYPE_BEACON, "beacon" },
+       { IEEE80211_FC0_SUBTYPE_ATIM, "atim" },
+       { IEEE80211_FC0_SUBTYPE_DISASSOC, "disassoc" },
+       { IEEE80211_FC0_SUBTYPE_DISASSOC, "disassociation" },
+       { IEEE80211_FC0_SUBTYPE_AUTH, "auth" },
+       { IEEE80211_FC0_SUBTYPE_AUTH, "authentication" },
+       { IEEE80211_FC0_SUBTYPE_DEAUTH, "deauth" },
+       { IEEE80211_FC0_SUBTYPE_DEAUTH, "deauthentication" },
+       { 0, NULL }
+ };
+ static const struct tok ieee80211_ctl_subtypes[] = {
+       { IEEE80211_FC0_SUBTYPE_PS_POLL, "ps-poll" },
+       { IEEE80211_FC0_SUBTYPE_RTS, "rts" },
+       { IEEE80211_FC0_SUBTYPE_CTS, "cts" },
+       { IEEE80211_FC0_SUBTYPE_ACK, "ack" },
+       { IEEE80211_FC0_SUBTYPE_CF_END, "cf-end" },
+       { IEEE80211_FC0_SUBTYPE_CF_END_ACK, "cf-end-ack" },
+       { 0, NULL }
+ };
+ static const struct tok ieee80211_data_subtypes[] = {
+       { IEEE80211_FC0_SUBTYPE_DATA, "data" },
+       { IEEE80211_FC0_SUBTYPE_CF_ACK, "data-cf-ack" },
+       { IEEE80211_FC0_SUBTYPE_CF_POLL, "data-cf-poll" },
+       { IEEE80211_FC0_SUBTYPE_CF_ACPL, "data-cf-ack-poll" },
+       { IEEE80211_FC0_SUBTYPE_NODATA, "null" },
 -      { IEEE80211_FC0_SUBTYPE_NODATA_CF_ACK, "cf-ack" },
 -      { IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "cf-poll"  },
 -      { IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "cf-ack-poll" },
++      { IEEE80211_FC0_SUBTYPE_CFACK, "cf-ack" },
++      { IEEE80211_FC0_SUBTYPE_CFPOLL, "cf-poll"  },
++      { IEEE80211_FC0_SUBTYPE_CF_ACK_CF_ACK, "cf-ack-poll" },
+       { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_DATA, "qos-data" },
+       { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACK, "qos-data-cf-ack" },
+       { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_POLL, "qos-data-cf-poll" },
+       { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACPL, "qos-data-cf-ack-poll" },
+       { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA, "qos" },
 -      { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "qos-cf-poll" },
 -      { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "qos-cf-ack-poll" },
++      { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CFPOLL, "qos-cf-poll" },
++      { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACK_CF_ACK, "qos-cf-ack-poll" },
+       { 0, NULL }
+ };
+ struct type2tok {
+       int type;
+       const struct tok *tok;
+ };
+ static const struct type2tok ieee80211_type_subtypes[] = {
+       { IEEE80211_FC0_TYPE_MGT, ieee80211_mgt_subtypes },
+       { IEEE80211_FC0_TYPE_CTL, ieee80211_ctl_subtypes },
+       { IEEE80211_FC0_TYPE_DATA, ieee80211_data_subtypes },
+       { 0, NULL }
+ };
+ static int
+ str2tok(const char *str, const struct tok *toks)
+ {
+       int i;
+       for (i = 0; toks[i].s != NULL; i++) {
+               if (pcap_strcasecmp(toks[i].s, str) == 0)
+                       return (toks[i].v);
+       }
+       return (-1);
+ }
  
  int n_errors = 0;
  
@@@ -120,6 -200,16 +201,16 @@@ pfaction_to_num(const char *action
        else if (pcap_strcasecmp(action, "drop") == 0 ||
                pcap_strcasecmp(action, "block") == 0)
                return (PF_DROP);
+ #if HAVE_PF_NAT_THROUGH_PF_NORDR
+       else if (pcap_strcasecmp(action, "rdr") == 0)
+               return (PF_RDR);
+       else if (pcap_strcasecmp(action, "nat") == 0)
+               return (PF_NAT);
+       else if (pcap_strcasecmp(action, "binat") == 0)
+               return (PF_BINAT);
+       else if (pcap_strcasecmp(action, "nordr") == 0)
+               return (PF_NORDR);
+ #endif
        else {
                bpf_error("unknown PF action");
                /*NOTREACHED*/
@@@ -131,6 -221,9 +222,9 @@@ pfreason_to_num(const char *reason
  {
        bpf_error("libpcap was compiled on a machine without pf support");
        /*NOTREACHED*/
+       /* this is to make the VC compiler happy */
+       return -1;
  }
  
  static int
@@@ -138,6 -231,9 +232,9 @@@ pfaction_to_num(const char *action
  {
        bpf_error("libpcap was compiled on a machine without pf support");
        /*NOTREACHED*/
+       /* this is to make the VC compiler happy */
+       return -1;
  }
  #endif /* HAVE_NET_PFVAR_H */
  %}
  %token  TK_BROADCAST TK_MULTICAST
  %token  NUM INBOUND OUTBOUND
  %token  PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION
+ %token        TYPE SUBTYPE DIR ADDR1 ADDR2 ADDR3 ADDR4
  %token  LINK
  %token        GEQ LEQ NEQ
  %token        ID EID HID HID6 AID
  %token        RADIO
  %token        FISU LSSU MSU
  %token        SIO OPC DPC SLS
- %token        TYPE SUBTYPE
  
  %type <s> ID
  %type <e> EID
  %type <e> AID
  %type <s> HID HID6
- %type <i> NUM action reason type subtype type_subtype
+ %type <i> NUM action reason type subtype type_subtype dir
  
  %left OR AND
  %nonassoc  '!'
@@@ -246,6 -342,14 +343,14 @@@ nid:       ID                    { $$.b = gen_scode($1, $$.
        | HID                   {
                                  /* Decide how to parse HID based on proto */
                                  $$.q = $<blk>0.q;
+                                 if ($$.q.addr == Q_PORT)
+                                       bpf_error("'port' modifier applied to ip host");
+                                 else if ($$.q.addr == Q_PORTRANGE)
+                                       bpf_error("'portrange' modifier applied to ip host");
+                                 else if ($$.q.addr == Q_PROTO)
+                                       bpf_error("'proto' modifier applied to ip host");
+                                 else if ($$.q.addr == Q_PROTOCHAIN)
+                                       bpf_error("'protochain' modifier applied to ip host");
                                  $$.b = gen_ncode($1, 0, $$.q);
                                }
        | HID6 '/' NUM          {
@@@ -333,6 -437,10 +438,10 @@@ dqual:     SRC                   { $$ = Q_SRC; 
        | DST OR SRC            { $$ = Q_OR; }
        | SRC AND DST           { $$ = Q_AND; }
        | DST AND SRC           { $$ = Q_AND; }
+       | ADDR1                 { $$ = Q_ADDR1; }
+       | ADDR2                 { $$ = Q_ADDR2; }
+       | ADDR3                 { $$ = Q_ADDR3; }
+       | ADDR4                 { $$ = Q_ADDR4; }
        ;
  /* address type qualifiers */
  aqual:          HOST                  { $$ = Q_HOST; }
@@@ -419,71 -527,67 +528,67 @@@ p80211:   TYPE type SUBTYPE subtyp
                                        IEEE80211_FC0_TYPE_MASK |
                                        IEEE80211_FC0_SUBTYPE_MASK);
                                }
+       | DIR dir               { $$ = gen_p80211_fcdir($2); }
        ;
  
  type:   NUM
-       | ID                    { const char *names[] = IEEE80211_TYPE_NAMES;
-                                 int i, lim;
-                                 lim = (IEEE80211_FC0_TYPE_MASK >> IEEE80211_FC0_TYPE_SHIFT) + 1;
-                                 for (i = 0; i < lim; ++i) {
-                                       if (pcap_strcasecmp($1, names[i]) == 0) {
-                                               $$ = i << IEEE80211_FC0_TYPE_SHIFT;
-                                               break;
-                                       }
-                                 }
-                                 if (i == lim)
+       | ID                    { $$ = str2tok($1, ieee80211_types);
+                                 if ($$ == -1)
                                        bpf_error("unknown 802.11 type name");
                                }
        ;
  
  subtype:  NUM
-       | ID                    { const char **names;
-                                 int i, lim;
-                                 if ($<i>-1 == IEEE80211_FC0_TYPE_MGT)
-                                       names = ieee80211_mgt_names;
-                                 else if ($<i>-1 == IEEE80211_FC0_TYPE_CTL)
-                                       names = ieee80211_ctl_names;
-                                 else if ($<i>-1 == IEEE80211_FC0_TYPE_DATA)
-                                       names = ieee80211_data_names;
-                                 else
-                                       bpf_error("unknown 802.11 type");
-                                 lim = (IEEE80211_FC0_SUBTYPE_MASK >> IEEE80211_FC0_SUBTYPE_SHIFT) + 1;
-                                 for (i = 0; i < lim; ++i) {
-                                       if (pcap_strcasecmp($1, names[i]) == 0) {
-                                               $$ = i << IEEE80211_FC0_SUBTYPE_SHIFT;
+       | ID                    { const struct tok *types = NULL;
+                                 int i;
+                                 for (i = 0;; i++) {
+                                       if (ieee80211_type_subtypes[i].tok == NULL) {
+                                               /* Ran out of types */
+                                               bpf_error("unknown 802.11 type");
+                                               break;
+                                       }
+                                       if ($<i>-1 == ieee80211_type_subtypes[i].type) {
+                                               types = ieee80211_type_subtypes[i].tok;
                                                break;
                                        }
                                  }
-                                 if (i == lim)
-                                       bpf_error("unknown 802.11 subtype name");
+                                 $$ = str2tok($1, types);
+                                 if ($$ == -1)
+                                       bpf_error("unknown 802.11 subtype name");
                                }
        ;
  
- type_subtype: ID              { const char **sub_names[] = {
-                                       ieee80211_mgt_names,
-                                       ieee80211_ctl_names,
-                                       ieee80211_data_names
-                                 };
-                                 int i, j, lim, sub_lim;
-                                 sub_lim = sizeof(sub_names) / sizeof(sub_names[0]);
-                                 lim = (IEEE80211_FC0_SUBTYPE_MASK >> IEEE80211_FC0_SUBTYPE_SHIFT) + 1;
-                                 for (i = 0; i < sub_lim; ++i) {
-                                       const char **names = sub_names[i];
-                                       for (j = 0; j < lim; ++j) {
-                                               if (pcap_strcasecmp($1, names[j]) == 0)
-                                                       break;
+ type_subtype: ID              { int i;
+                                 for (i = 0;; i++) {
+                                       if (ieee80211_type_subtypes[i].tok == NULL) {
+                                               /* Ran out of types */
+                                               bpf_error("unknown 802.11 type name");
+                                               break;
                                        }
-                                       if (j != lim) {
-                                               $$ = (i << IEEE80211_FC0_TYPE_SHIFT) |
-                                                    (j << IEEE80211_FC0_SUBTYPE_SHIFT);
+                                       $$ = str2tok($1, ieee80211_type_subtypes[i].tok);
+                                       if ($$ != -1) {
+                                               $$ |= ieee80211_type_subtypes[i].type;
                                                break;
                                        }
                                  }
-                                 if (i == sub_lim)
-                                       bpf_error("unknown 802.11 subtype name");
                                }
                ;
  
+ dir:    NUM
+       | ID                    { if (pcap_strcasecmp($1, "nods") == 0)
+                                       $$ = IEEE80211_FC1_DIR_NODS;
+                                 else if (pcap_strcasecmp($1, "tods") == 0)
+                                       $$ = IEEE80211_FC1_DIR_TODS;
+                                 else if (pcap_strcasecmp($1, "fromds") == 0)
+                                       $$ = IEEE80211_FC1_DIR_FROMDS;
+                                 else if (pcap_strcasecmp($1, "dstods") == 0)
+                                       $$ = IEEE80211_FC1_DIR_DSTODS;
+                                 else
+                                       bpf_error("unknown 802.11 direction");
+                               }
+       ;
  reason:         NUM                   { $$ = $1; }
        | ID                    { $$ = pfreason_to_num($1); }
        ;
   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   *
-  * @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.52.2.7 2007/06/11 09:52:05 guy Exp $ (LBL)
+  * @(#) $Header: /tcpdump/master/libpcap/pcap/pcap.h,v 1.4.2.11 2008-10-06 15:38:39 gianluca Exp $ (LBL)
   */
  
- #ifndef lib_pcap_h
- #define lib_pcap_h
+ #ifndef lib_pcap_pcap_h
+ #define lib_pcap_pcap_h
  
  #if defined(WIN32)
    #include <pcap-stdinc.h>
@@@ -47,7 -47,9 +47,9 @@@
    #include <sys/time.h>
  #endif /* WIN32/MSDOS/UN*X */
  
 -#include <pcap/bpf.h>
+ #ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H
 +#include <net/bpf.h>
+ #endif
  
  #include <stdio.h>
  
@@@ -93,8 -95,8 +95,8 @@@ typedef struct pcap_addr pcap_addr_t
   *    introduce a new structure for the new format, if the layout
   *    of the structure changed;
   *
-  *    send mail to "tcpdump-workers@tcpdump.org", requesting a new
-  *    magic number for your new capture file format, and, when
+  *    send mail to "tcpdump-workers@lists.tcpdump.org", requesting
+  *    a new magic number for your new capture file format, and, when
   *    you get the new magic number, put it in "savefile.c";
   *
   *    use that magic number for save files with the changed file
   *    the old file header as well as files with the new file header
   *    (using the magic number to determine the header format).
   *
-  * Then supply the changes to "patches@tcpdump.org", so that future
-  * versions of libpcap and programs that use it (such as tcpdump) will
-  * be able to read your new capture file format.
+  * Then supply the changes as a patch at
+  *
+  *    http://sourceforge.net/projects/libpcap/
+  *
+  * so that future versions of libpcap and programs that use it (such as
+  * tcpdump) will be able to read your new capture file format.
   */
  struct pcap_file_header {
        bpf_u_int32 magic;
        bpf_u_int32 linktype;   /* data link type (LINKTYPE_*) */
  };
  
+ /*
+  * Macros for the value returned by pcap_datalink_ext().
+  * 
+  * If LT_FCS_LENGTH_PRESENT(x) is true, the LT_FCS_LENGTH(x) macro
+  * gives the FCS length of packets in the capture.
+  */
+ #define LT_FCS_LENGTH_PRESENT(x)      ((x) & 0x04000000)
+ #define LT_FCS_LENGTH(x)              (((x) & 0xF0000000) >> 28)
+ #define LT_FCS_DATALINK_EXT(x)                ((((x) & 0xF) << 28) | 0x04000000)
  typedef enum {
         PCAP_D_INOUT = 0,
         PCAP_D_IN,
@@@ -214,12 -229,57 +229,57 @@@ struct pcap_addr 
  typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
                             const u_char *);
  
+ /*
+  * Error codes for the pcap API.
+  * These will all be negative, so you can check for the success or
+  * failure of a call that returns these codes by checking for a
+  * negative value.
+  */
+ #define PCAP_ERROR                    -1      /* generic error code */
+ #define PCAP_ERROR_BREAK              -2      /* loop terminated by pcap_breakloop */
+ #define PCAP_ERROR_NOT_ACTIVATED      -3      /* the capture needs to be activated */
+ #define PCAP_ERROR_ACTIVATED          -4      /* the operation can't be performed on already activated captures */
+ #define PCAP_ERROR_NO_SUCH_DEVICE     -5      /* no such device exists */
+ #define PCAP_ERROR_RFMON_NOTSUP               -6      /* this device doesn't support rfmon (monitor) mode */
+ #define PCAP_ERROR_NOT_RFMON          -7      /* operation supported only in monitor mode */
+ #define PCAP_ERROR_PERM_DENIED                -8      /* no permission to open the device */
+ #define PCAP_ERROR_IFACE_NOT_UP               -9      /* interface isn't up */
+ /*
+  * Warning codes for the pcap API.
+  * These will all be positive and non-zero, so they won't look like
+  * errors.
+  */
+ #define PCAP_WARNING                  1       /* generic warning code */
+ #define PCAP_WARNING_PROMISC_NOTSUP   2       /* this device doesn't support promiscuous mode */
  char  *pcap_lookupdev(char *);
  int   pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
+ pcap_t        *pcap_create(const char *, char *);
+ int   pcap_set_snaplen(pcap_t *, int);
+ int   pcap_set_promisc(pcap_t *, int);
+ int   pcap_can_set_rfmon(pcap_t *);
+ int   pcap_set_rfmon(pcap_t *, int);
+ int   pcap_set_timeout(pcap_t *, int);
+ int   pcap_set_buffer_size(pcap_t *, int);
+ int   pcap_activate(pcap_t *);
  pcap_t        *pcap_open_live(const char *, int, int, int, char *);
  pcap_t        *pcap_open_dead(int, int);
  pcap_t        *pcap_open_offline(const char *, char *);
+ #if defined(WIN32)
+ pcap_t  *pcap_hopen_offline(intptr_t, char *);
+ #if !defined(LIBPCAP_EXPORTS)
+ #define pcap_fopen_offline(f,b) \
+       pcap_hopen_offline(_get_osfhandle(_fileno(f)), b)
+ #else /*LIBPCAP_EXPORTS*/
+ static pcap_t *pcap_fopen_offline(FILE *, char *);
+ #endif
+ #else /*WIN32*/
  pcap_t        *pcap_fopen_offline(FILE *, char *);
+ #endif /*WIN32*/
  void  pcap_close(pcap_t *);
  int   pcap_loop(pcap_t *, int, pcap_handler, u_char *);
  int   pcap_dispatch(pcap_t *, int, pcap_handler, u_char *);
@@@ -232,19 -292,24 +292,24 @@@ int     pcap_setfilter(pcap_t *, struct bpf
  int   pcap_setdirection(pcap_t *, pcap_direction_t);
  int   pcap_getnonblock(pcap_t *, char *);
  int   pcap_setnonblock(pcap_t *, int, char *);
- void  pcap_perror(pcap_t *, char *);
  int   pcap_inject(pcap_t *, const void *, size_t);
  int   pcap_sendpacket(pcap_t *, const u_char *, int);
+ const char *pcap_statustostr(int);
  const char *pcap_strerror(int);
  char  *pcap_geterr(pcap_t *);
+ void  pcap_perror(pcap_t *, char *);
  int   pcap_compile(pcap_t *, struct bpf_program *, const char *, int,
            bpf_u_int32);
  int   pcap_compile_nopcap(int, int, struct bpf_program *,
            const char *, int, bpf_u_int32);
  void  pcap_freecode(struct bpf_program *);
+ int   pcap_offline_filter(struct bpf_program *, const struct pcap_pkthdr *,
+           const u_char *);
  int   pcap_datalink(pcap_t *);
+ int   pcap_datalink_ext(pcap_t *);
  int   pcap_list_datalinks(pcap_t *, int **);
  int   pcap_set_datalink(pcap_t *, int);
+ void  pcap_free_datalinks(int *);
  int   pcap_datalink_name_to_val(const char *);
  const char *pcap_datalink_val_to_name(int);
  const char *pcap_datalink_val_to_description(int);
@@@ -271,10 -336,10 +336,10 @@@ void    pcap_freealldevs(pcap_if_t *)
  const char *pcap_lib_version(void);
  
  /* XXX this guy lives in the bpf tree */
- u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
- int   bpf_validate(struct bpf_insn *f, int len);
- char  *bpf_image(struct bpf_insn *, int);
- void  bpf_dump(struct bpf_program *, int);
+ u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int);
+ int   bpf_validate(const struct bpf_insn *f, int len);
+ char  *bpf_image(const struct bpf_insn *, int);
+ void  bpf_dump(const struct bpf_program *, int);
  
  #if defined(WIN32)
  
index 3715476,0000000..e9d8e57
mode 100644,000000..100644
--- /dev/null
@@@ -1,265 -1,0 +1,267 @@@
 +# $FreeBSD: src/etc/mtree/BSD.include.dist,v 1.32.2.14 2003/01/24 09:47:07 roam Exp $
 +# $DragonFly: src/etc/mtree/BSD.include.dist,v 1.29 2008/11/24 10:27:25 hasso Exp $
 +#
 +# Please see the file src/etc/mtree/README before making changes to this file.
 +#
 +
 +/set type=dir uname=root gname=wheel mode=0755
 +.
 +    arpa
 +    ..
 +    bus
 +        cam
 +            scsi
 +            ..
 +        ..
 +        pccard
 +        ..
 +        usb
 +        ..
 +        pci
 +        ..
 +        ppbus
 +        ..
 +        isa
 +        ..
 +    ..
 +    crypto
 +    ..
 +    dev
 +        acpica
 +        ..
 +        misc
 +            lpt
 +            ..
 +            ppi
 +            ..
 +        ..
 +        netif
 +            wi
 +            ..
 +        ..
 +        raid
 +            ciss
 +            ..
 +        ..
 +        video
 +            bktr
 +            ..
 +            meteor
 +            ..
 +        ..
 +    ..
 +    netproto
 +        802_11
 +        ..
 +        atalk
 +        ..
 +        atm
 +            ipatm
 +            ..
 +            sigpvc
 +            ..
 +            spans
 +            ..
 +            uni
 +            ..
 +        ..
 +        ipsec
 +        ..
 +        ipx
 +        ..
 +        key
 +        ..
 +        mpls
 +        ..
 +        natm
 +        ..
 +        ncp
 +        ..
 +        ns
 +        ..
 +        smb
 +        ..
 +    ..
 +    emulation
 +        posix4
 +        ..
 +        linux
 +        ..
 +    ..
 +    vfs
 +        hammer
 +        ..
 +        msdosfs
 +        ..
 +        nfs
 +        ..
 +        ntfs
 +        ..
 +        nwfs
 +        ..
 +        udf
 +        ..
 +        ufs
 +        ..
 +        mfs
 +        ..
 +        smbfs
 +        ..
 +        isofs
 +            cd9660
 +            ..
 +        ..
 +    ..
 +    c++
 +        3.4
 +            backward
 +            ..
 +            bits
 +            ..
 +            debug
 +            ..
 +            ext
 +            ..
 +        ..
 +        4.1
 +            backward
 +            ..
 +            bits
 +            ..
 +            debug
 +            ..
 +            ext
 +            ..
 +            tr1
 +            ..
 +        ..
 +    ..
 +    cpu
 +    ..
 +    isc
 +    ..
 +    libmilter
 +    ..
 +    machine
 +        pc
 +        ..
 +    ..
 +    i4b_machine
 +    ..
 +    net
 +        altq
 +        ..
 +        vlan
 +        ..
 +        ipfw
 +        ..
 +        ip6fw
 +        ..
 +        pf
 +        ..
 +        ppp
 +        ..
 +        ppp_layer
 +        ..
 +        sl
 +        ..
 +        dummynet
 +        ..
 +        sppp
 +        ..
 +        ip_mroute
 +        ..
 +        bridge
 +        ..
 +        tap
 +        ..
 +        tun
 +        ..
 +        i4b
 +            include
 +            ..
 +        ..
 +    ..
 +    netgraph
 +        UI
 +        ..
 +        async
 +        ..
 +        bpf
 +        ..
 +        bridge
 +        ..
 +        cisco
 +        ..
 +        echo
 +        ..
 +        eiface
 +        ..
 +        etf
 +        ..
 +        ether
 +        ..
 +        fec
 +        ..
 +        frame_relay
 +        ..
 +        hole
 +        ..
 +        iface
 +        ..
 +        ksocket
 +        ..
 +        l2tp
 +        ..
 +        lmi
 +        ..
 +        mppc
 +        ..
 +        one2many
 +        ..
 +        ppp
 +        ..
 +        pppoe
 +        ..
 +        pptpgre
 +        ..
 +        rfc1490
 +        ..
 +        socket
 +        ..
 +        tee
 +        ..
 +        tty
 +        ..
 +        vjc
 +        ..
 +    ..
 +    kadm5
 +    ..
 +    netbt
 +    ..
 +    netinet
 +    ..
 +    netinet6
 +    ..
 +    objc
 +    ..
 +    openssl
 +    ..
++    pcap
++    ..
 +    protocols
 +    ..
 +    readline
 +    ..
 +    rpc
 +    ..
 +    rpcsvc
 +    ..
 +    security
 +    ..
 +    sys
 +    ..
 +    vm
 +    ..
 +..
diff --combined lib/libpcap/Makefile
index a8ab51a,0000000..9e85fb9
mode 100644,000000..100644
--- /dev/null
@@@ -1,46 -1,0 +1,138 @@@
- MAN=  pcap.3
 +# Makefile for libpcap
 +# $FreeBSD: src/lib/libpcap/Makefile,v 1.24.2.4 2002/07/22 14:21:50 ru Exp $
 +# $DragonFly: src/lib/libpcap/Makefile,v 1.12 2007/10/11 01:07:29 pavalos Exp $
 +
 +SRCDIR=       ${.CURDIR}/../../contrib/libpcap
 +
 +LIB=    pcap
 +SRCS= grammar.y tokdefs.h pcap-bpf.c version.h \
 +      pcap.c inet.c fad-getad.c gencode.c optimize.c nametoaddr.c \
 +      etherent.c savefile.c bpf_filter.c bpf_image.c bpf_dump.c \
 +      scanner.l version.c
++
++# Old compatibility headers
 +INCS= pcap.h pcap-namedb.h pcap-int.h
++
++PCAPINCS=     pcap/pcap.h pcap/namedb.h
++PCAPINCSDIR=  ${INCLUDEDIR}/pcap
++INCSGROUPS=   INCS PCAPINCS
++
++MAN=  pcap.3 \
++      pcap_activate.3 \
++      pcap_breakloop.3 \
++      pcap_can_set_rfmon.3 \
++      pcap_close.3 \
++      pcap_compile.3 \
++      pcap_create.3 \
++      pcap_datalink.3 \
++      pcap_datalink_name_to_val.3 \
++      pcap_datalink_val_to_name.3 \
++      pcap_dump.3 \
++      pcap_dump_close.3 \
++      pcap_dump_file.3 \
++      pcap_dump_flush.3 \
++      pcap_dump_ftell.3 \
++      pcap_dump_open.3 \
++      pcap_file.3 \
++      pcap_fileno.3 \
++      pcap_findalldevs.3 \
++      pcap_free_datalinks.3 \
++      pcap_freealldevs.3 \
++      pcap_freecode.3 \
++      pcap_get_selectable_fd.3 \
++      pcap_geterr.3 \
++      pcap_inject.3 \
++      pcap_is_swapped.3 \
++      pcap_lib_version.3 \
++      pcap_list_datalinks.3 \
++      pcap_lookupdev.3 \
++      pcap_lookupnet.3 \
++      pcap_loop.3 \
++      pcap_major_version.3 \
++      pcap_next_ex.3 \
++      pcap_offline_filter.3 \
++      pcap_open_dead.3 \
++      pcap_open_live.3 \
++      pcap_open_offline.3 \
++      pcap_set_buffer_size.3 \
++      pcap_set_datalink.3 \
++      pcap_set_promisc.3 \
++      pcap_set_rfmon.3 \
++      pcap_set_snaplen.3 \
++      pcap_set_timeout.3 \
++      pcap_setdirection.3 \
++      pcap_setfilter.3 \
++      pcap_setnonblock.3 \
++      pcap_snapshot.3 \
++      pcap_stats.3 \
++      pcap_statustostr.3 \
++      pcap_strerror.3 \
++      pcap-savefile.5 \
++      pcap-filter.7 \
++      pcap-linktype.7
++MLINKS=       pcap_datalink_val_to_name.3 pcap_datalink_val_to_description.3 \
++      pcap_dump_open.3 pcap_dump_fopen.3 \
++      pcap_geterr.3 pcap_perror.3 \
++      pcap_inject.3 pcap_sendpacket.3 \
++      pcap_loop.3 pcap_dispatch.3 \
++      pcap_major_version.3 pcap_minor_version.3 \
++      pcap_next_ex.3 pcap_next.3 \
++      pcap_open_offline.3 pcap_fopen_offline.3 \
++      pcap_setnonblock.3 pcap_getnonblock.3
++
 +CLEANFILES=tokdefs.h version.c version.h
++CLEANFILES+=${MAN}
 +WARNS?=       2
 +
 +CFLAGS+=-DHAVE_CONFIG_H -Dyylval=pcap_lval -I${.CURDIR} -I.
 +CFLAGS+=-D_U_="__attribute__((unused))"
 +CFLAGS+=-DHAVE_STRUCT_ETHER_ADDR -DHAVE_NET_PFVAR_H
 +.if !defined(NOINET6)
 +CFLAGS+=-DINET6
 +.endif
 +
 +SHLIB_MAJOR=3
 +
 +#
 +# Magic to grab sources out of src/contrib
 +#
 +PCAP_DISTDIR?=${SRCDIR}
 +CFLAGS+=-I${PCAP_DISTDIR}
 +.PATH:        ${PCAP_DISTDIR}
 +.PATH:        ${PCAP_DISTDIR}/bpf/net
 +
 +version.c: ${PCAP_DISTDIR}/VERSION
 +      @rm -f $@
 +      sed 's/.*/char pcap_version[] = "&";/' ${PCAP_DISTDIR}/VERSION > $@
 +
 +version.h: ${PCAP_DISTDIR}/VERSION
 +      @rm -f $@
 +      sed 's/.*/static const char pcap_version_string[] = "libpcap version &";/' \
 +              ${PCAP_DISTDIR}/VERSION > $@
 +
 +tokdefs.h: grammar.h
 +      ${LN} -sf grammar.h tokdefs.h
 +
++#
++# Magic to convert the man pages to something non Solarish
++#
++.for _page in ${MAN}
++${_page}:
++      if [ -f ${PCAP_DISTDIR}/${_page:S/3$/3pcap/} ]; then            \
++              F=${_page:S/3$/3pcap/};                                 \
++      elif [ -f ${PCAP_DISTDIR}/${_page:S/3$/3pcap.in/} ]; then       \
++              F=${_page:S/3$/3pcap.in/};                              \
++      elif [ -f ${PCAP_DISTDIR}/${_page:S/5$/manfile/} ]; then        \
++              F=${_page:S/5$/manfile/};                               \
++      elif [ -f ${PCAP_DISTDIR}/${_page:S/5$/manfile.in/} ]; then     \
++              F=${_page:S/5$/manfile.in/};                            \
++      elif [ -f ${PCAP_DISTDIR}/${_page:S/7$/manmisc/} ]; then        \
++              F=${_page:S/7$/manmisc/};                               \
++      elif [ -f ${PCAP_DISTDIR}/${_page:S/7$/manmisc.in/} ]; then     \
++              F=${_page:S/7$/manmisc.in/};                            \
++      fi;                                                             \
++      sed -e 's/3PCAP/3/g' -e 's/@MAN_FILE_FORMATS@/5/g'              \
++              -e 's/@MAN_MISC_INFO@/7/g' ${PCAP_DISTDIR}/$$F > ${_page}
++.endfor
++
 +.include <bsd.lib.mk>
diff --combined lib/libpcap/config.h
index e454c8d,0000000..deb6248
mode 100644,000000..100644
--- /dev/null
@@@ -1,200 -1,0 +1,253 @@@
- /* $DragonFly: src/lib/libpcap/config.h,v 1.6 2007/10/11 01:07:29 pavalos Exp $ */
 +/* config.h.  Generated from config.h.in by configure.  */
 +/* config.h.in.  Generated from configure.in by autoheader.  */
 +/* Long story short: aclocal.m4 depends on autoconf 2.13
 + * implementation details wrt "const"; newer versions
 + * have different implementation details so for now we
 + * put "const" here.  This may cause duplicate definitions
 + * in config.h but that should be OK since they're the same.
 + */
 +/* #undef const */
 +
 +/* Enable optimizer debugging */
 +/* #undef BDEBUG */
 +
 +/* define if you have a cloning BPF device */
 +/* #undef HAVE_CLONING_BPF */
 +
 +/* define if you have the DAG API */
 +/* #undef HAVE_DAG_API */
 +
 +/* define if you have dag_get_erf_types() */
 +/* #undef HAVE_DAG_GET_ERF_TYPES */
 +
++/* define if you have dag_get_stream_erf_types() */
++/* #undef HAVE_DAG_GET_STREAM_ERF_TYPES */
++
 +/* define if you have streams capable DAG API */
 +/* #undef HAVE_DAG_STREAMS_API */
 +
 +/* Define to 1 if you have the declaration of `ether_hostton', and to 0 if you
 +   don't. */
 +#define HAVE_DECL_ETHER_HOSTTON 1
 +
 +/* define if you have a /dev/dlpi */
 +/* #undef HAVE_DEV_DLPI */
 +
++/* if passive_req_t primitive exists */
++/* #undef HAVE_DLPI_PASSIVE */
++
 +/* Define to 1 if you have the `ether_hostton' function. */
 +#define HAVE_ETHER_HOSTTON 1
 +
++/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
++#define HAVE_FSEEKO 1
++
 +/* on HP-UX 10.20 or later */
 +/* #undef HAVE_HPUX10_20_OR_LATER */
 +
 +/* on HP-UX 9.x */
 +/* #undef HAVE_HPUX9 */
 +
 +/* if ppa_info_t_dl_module_id exists */
 +/* #undef HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1 */
 +
 +/* Define to 1 if you have the <inttypes.h> header file. */
 +#define HAVE_INTTYPES_H 1
 +
++/* if libdlpi exists */
++/* #undef HAVE_LIBDLPI */
++
 +/* Define to 1 if you have the <limits.h> header file. */
 +#define HAVE_LIMITS_H 1
 +
++/* if tp_vlan_tci exists */
++/* #undef HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI */
++
++/* Define to 1 if you have the <linux/wireless.h> header file. */
++/* #undef HAVE_LINUX_WIRELESS_H */
++
 +/* Define to 1 if you have the <memory.h> header file. */
 +#define HAVE_MEMORY_H 1
 +
 +/* Define to 1 if you have the <netinet/ether.h> header file. */
 +/* #undef HAVE_NETINET_ETHER_H */
 +
 +/* Define to 1 if you have the <netinet/if_ether.h> header file. */
 +#define HAVE_NETINET_IF_ETHER_H 1
 +
++/* Define to 1 if you have the <net/if_media.h> header file. */
++#define HAVE_NET_IF_MEDIA_H 1
++
 +/* Define to 1 if you have the <net/pfvar.h> header file. */
 +/* #undef HAVE_NET_PFVAR_H */
 +
 +/* if there's an os_proto.h */
 +/* #undef HAVE_OS_PROTO_H */
 +
 +/* Define to 1 if you have the <paths.h> header file. */
 +#define HAVE_PATHS_H 1
 +
++/* define if net/pfvar.h defines PF_NAT through PF_NORDR */
++/* #undef HAVE_PF_NAT_THROUGH_PF_NORDR */
++
 +/* define if you have a /proc/net/dev */
 +/* #undef HAVE_PROC_NET_DEV */
 +
 +/* define if you have a Septel API */
 +/* #undef HAVE_SEPTEL_API */
 +
 +/* Define to 1 if you have the `snprintf' function. */
 +#define HAVE_SNPRINTF 1
 +
 +/* if struct sockaddr has sa_len */
 +#define HAVE_SOCKADDR_SA_LEN 1
 +
 +/* if struct sockaddr_storage exists */
 +#define HAVE_SOCKADDR_STORAGE 1
 +
++/* define if socklen_t is defined */
++#define HAVE_SOCKLEN_T 1
++
 +/* On solaris */
 +/* #undef HAVE_SOLARIS */
 +
 +/* Define to 1 if you have the <stdint.h> header file. */
 +#define HAVE_STDINT_H 1
 +
 +/* Define to 1 if you have the <stdlib.h> header file. */
 +#define HAVE_STDLIB_H 1
 +
 +/* Define to 1 if you have the `strerror' function. */
 +#define HAVE_STRERROR 1
 +
 +/* Define to 1 if you have the <strings.h> header file. */
 +#define HAVE_STRINGS_H 1
 +
 +/* Define to 1 if you have the <string.h> header file. */
 +#define HAVE_STRING_H 1
 +
 +/* Define to 1 if you have the `strlcpy' function. */
 +#define HAVE_STRLCPY 1
 +
 +/* Define to 1 if the system has the type `struct ether_addr'. */
 +/* #undef HAVE_STRUCT_ETHER_ADDR */
 +
 +/* Define to 1 if you have the <sys/bufmod.h> header file. */
 +/* #undef HAVE_SYS_BUFMOD_H */
 +
 +/* Define to 1 if you have the <sys/dlpi_ext.h> header file. */
 +/* #undef HAVE_SYS_DLPI_EXT_H */
 +
 +/* Define to 1 if you have the <sys/ioccom.h> header file. */
 +#define HAVE_SYS_IOCCOM_H 1
 +
 +/* Define to 1 if you have the <sys/sockio.h> header file. */
 +#define HAVE_SYS_SOCKIO_H 1
 +
 +/* Define to 1 if you have the <sys/stat.h> header file. */
 +#define HAVE_SYS_STAT_H 1
 +
 +/* Define to 1 if you have the <sys/types.h> header file. */
 +#define HAVE_SYS_TYPES_H 1
 +
 +/* if if_packet.h has tpacket_stats defined */
 +/* #undef HAVE_TPACKET_STATS */
 +
 +/* Define to 1 if you have the <unistd.h> header file. */
 +#define HAVE_UNISTD_H 1
 +
 +/* define if version.h is generated in the build procedure */
 +#define HAVE_VERSION_H 1
 +
 +/* Define to 1 if you have the `vsnprintf' function. */
 +#define HAVE_VSNPRINTF 1
 +
++/* define if the system supports zerocopy BPF */
++/* #undef HAVE_ZEROCOPY_BPF */
++
 +/* define if your compiler has __attribute__ */
 +#define HAVE___ATTRIBUTE__ 1
 +
 +/* IPv6 */
 +/* #undef INET6 */
 +
 +/* if unaligned access fails */
 +/* #undef LBL_ALIGN */
 +
++/* path for device for USB sniffing */
++/* #undef LINUX_USB_MON_DEV */
++
 +/* Define to 1 if netinet/ether.h declares `ether_hostton' */
 +/* #undef NETINET_ETHER_H_DECLARES_ETHER_HOSTTON */
 +
 +/* Define to 1 if netinet/if_ether.h declares `ether_hostton' */
 +#define NETINET_IF_ETHER_H_DECLARES_ETHER_HOSTTON 
 +
 +/* do not use protochain */
 +/* #undef NO_PROTOCHAIN */
 +
 +/* Define to the address where bug reports for this package should be sent. */
 +#define PACKAGE_BUGREPORT ""
 +
 +/* Define to the full name of this package. */
 +#define PACKAGE_NAME ""
 +
 +/* Define to the full name and version of this package. */
 +#define PACKAGE_STRING ""
 +
 +/* Define to the one symbol short name of this package. */
 +#define PACKAGE_TARNAME ""
 +
 +/* Define to the version of this package. */
 +#define PACKAGE_VERSION ""
 +
 +/* /dev/dlpi directory */
 +/* #undef PCAP_DEV_PREFIX */
 +
++/* target host supports Bluetooth sniffing */
++/* #undef PCAP_SUPPORT_BT */
++
++/* target host supports USB sniffing */
++/* #undef PCAP_SUPPORT_USB */
++
++/* include ACN support */
++/* #undef SITA */
++
 +/* Define to 1 if you have the ANSI C header files. */
 +#define STDC_HEADERS 1
 +
 +/* Enable parser debugging */
 +/* #undef YYDEBUG */
 +
++/* Number of bits in a file offset, on hosts where this is settable. */
++/* #undef _FILE_OFFSET_BITS */
++
 +/* needed on HP-UX */
 +/* #undef _HPUX_SOURCE */
 +
++/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
++/* #undef _LARGEFILE_SOURCE */
++
++/* Define for large files, on AIX-style hosts. */
++/* #undef _LARGE_FILES */
++
 +/* define on AIX to get certain functions */
 +/* #undef _SUN */
 +
 +/* Define as token for inline if inlining supported */
 +#define inline inline
 +
 +/* on sinix */
 +/* #undef sinix */
 +
 +/* if we have u_int16_t */
 +/* #undef u_int16_t */
 +
 +/* if we have u_int32_t */
 +/* #undef u_int32_t */
 +
++/* if we have u_int64_t */
++/* #undef u_int64_t */
++
 +/* if we have u_int8_t */
 +/* #undef u_int8_t */
diff --combined share/man/man7/hier.7
index 0c2d43f,0000000..bdd8ba0
mode 100644,000000..100644
--- /dev/null
@@@ -1,758 -1,0 +1,762 @@@
 +.\" Copyright (c) 1990, 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.
 +.\"
 +.\"   @(#)hier.7      8.1 (Berkeley) 6/5/93
 +.\" $FreeBSD: src/share/man/man7/hier.7,v 1.29.2.17 2003/01/13 21:43:50 ceri Exp $
 +.\" $DragonFly: src/share/man/man7/hier.7,v 1.26 2008/09/06 14:24:44 swildner Exp $
 +.\"
 +.Dd September 2, 2008
 +.Dt HIER 7
 +.Os
 +.Sh NAME
 +.Nm hier
 +.Nd layout of filesystems
 +.Sh DESCRIPTION
 +A sketch of the filesystem hierarchy.
 +.Bl -tag -width ".Pa /modules/"
 +.It Pa /
 +root directory of the filesystem
 +.It Pa /bin/
 +user utilities fundamental to both single-user and multi-user environments
 +.It Pa /boot/
 +programs and configuration files used during operating system bootstrap
 +.Pp
 +.Bl -tag -width ".Pa defaults/" -compact
 +.It Pa defaults/
 +default bootstrapping configuration files; see
 +.Xr loader.conf 5
 +.It Pa kernel
 +pure kernel executable (the operating system loaded into memory
 +at boot time).
 +.It Pa modules/
 +loadable kernel modules;
 +see
 +.Xr kldstat 8
 +.El
 +.It Pa /dev/
 +block and character device files
 +.Pp
 +.Bl -tag -width ".Pa MAKEDEV" -compact
 +.It Pa MAKEDEV
 +script for creating device files;
 +see
 +.Xr MAKEDEV 8
 +.It Pa fd/
 +file descriptor files;
 +see
 +.Xr \&fd 4
 +.El
 +.It Pa /etc/
 +system configuration files and scripts
 +.Pp
 +.Bl -tag -width ".Pa bluetooth/" -compact
 +.It Pa bluetooth/
 +bluetooth configuration files
 +.It Pa defaults/
 +default system configuration files;
 +see
 +.Xr rc 8
 +.It Pa dma/
 +.Xr dma 8
 +configuration files
 +.It Pa firmware/
 +Firmware image files;
 +see
 +.Xr firmware 9
 +.It Pa isdn/
 +isdn4bsd configuration files;
 +see
 +.Xr isdnd 8
 +.It Pa localtime
 +local timezone information;
 +see
 +.Xr ctime 3
 +.It Pa mail/
 +Sendmail control files
 +.It Pa mtree/
 +mtree configuration files;
 +see
 +.Xr mtree 8
 +.It Pa namedb/
 +named configuration files;
 +see
 +.Xr named 8
 +.It Pa pam.d/
 +configuration files for the Pluggable Authentication Modules (PAM)
 +library
 +.It Pa periodic/
 +scripts that are run daily, weekly, and monthly, via
 +.Xr cron 8 ;
 +see
 +.Xr periodic 8
 +.It Pa ppp/
 +ppp configuration files;
 +see
 +.Xr ppp 8
 +.It Pa rc.d/
 +System and daemon startup/control scripts;
 +see
 +.Xr rc 8
 +.It Pa ssh/
 +OpenSSH configuration files;
 +see
 +.Xr ssh 1
 +.It Pa ssl/
 +OpenSSL configuration files
 +.It Pa upgrade/
 +Files relevant to system upgrades
 +.It Pa uucp/
 +uucp configuration files;
 +see
 +.Xr uucp 1
 +.El
 +.It Pa /home/
 +HOME directories of non-root users
 +.It Pa /mnt/
 +empty directory commonly used by
 +system administrators as a temporary mount point
 +.It Pa /proc/
 +process file system;
 +see
 +.Xr procfs 5 ,
 +.Xr mount_procfs 8
 +.It Pa /root/
 +root's HOME directory
 +.It Pa /sbin/
 +system programs and administration utilities
 +fundamental to both single-user and multi-user environments
 +.It Pa /sys/
 +the kernel's source code (usually a symbolic link to
 +.Pa /usr/src/sys )
 +.It Pa /tmp/
 +temporary files that are not guaranteed to persist across system reboots
 +.It Pa /usr/
 +contains the majority of user utilities and applications
 +.Pp
 +.Bl -tag -width ".Pa libdata/" -compact
 +.It Pa bin/
 +common utilities, programming tools, and applications
 +.It Pa games/
 +useful and semi-frivolous programs
 +.It Pa include/
 +standard C include files
 +.Pp
 +.Bl -tag -width ".Pa libmilter/" -compact
 +.It Pa arpa/
 +C include files for Internet service protocols
 +.It Pa c++/
 +C++ include files
 +.It Pa cam/
 +C include files for the Common Access Methods Layer
 +.Pp
 +.Bl -tag -width ".Pa scsi/" -compact
 +.It Pa scsi/
 +The SCSI device on top of CAM
 +.El
 +.Pp
 +.It Pa dev/
 +C include files for programming various
 +.Dx
 +devices
 +.It Pa emulation/
 +Include Files for various emulation layers
 +.It Pa fs/
 +.Pp
 +.Bl -tag -width ".Pa smbfs/" -compact
 +.It Pa smbfs/
 +SMB/CIFS filesystem
 +.El
 +.Pp
 +.It Pa isc/
 +ISC utility library libisc include files
 +.It Pa isofs/
 +.Pp
 +.Bl -tag -width ".Pa cd9660/" -compact
 +.It Pa cd9660/
 +iso9660 filesystem
 +.El
 +.Pp
 +.It Pa libmilter/
 +C include files for libmilter,
 +the sendmail mail filter API
 +.It Pa machine/
 +machine-specific C include files
 +.It Pa msdosfs/
 +MS-DOS file system
 +.It Pa net/
 +misc network C include files
 +.It Pa netatalk/
 +Appletalk protocol
 +.It Pa netatm/
 +ATM include files;
 +see
 +.Xr atm 8
 +.It Pa netinet/
 +C include files for Internet standard protocols;
 +see
 +.Xr inet 4
 +.It Pa netinet6/
 +C include files for Internet protocol version 6;
 +see
 +.Xr inet6 4
 +.It Pa netipx/
 +IPX/SPX protocol stacks
 +.It Pa netkey/
 +kernel key-management service
 +.It Pa netnatm/
 +NATM include files;
 +see
 +.Xr natm 4
 +.It Pa netns/
 +Xerox NS protocols
 +.It Pa netsmb/
 +SMB/CIFS requester
 +.It Pa nfs/
 +C include files for NFS (Network File System)
 +.It Pa objc/
 +Objective C include files
 +.It Pa openssl/
 +OpenSSL (Cryptography/SSL toolkit) headers
++.It Pa pcap/
++Packet Capture (libpcap) headers;
++see
++.Xr pcap 3
 +.It Pa pccard/
 +PC-CARD controllers
 +.It Pa protocols/
 +C include files for Berkeley service protocols
 +.It Pa readline/
 +get a line from a user, with editing;
 +see
 +.Xr readline 3
 +.It Pa rpc/
 +remote procedure calls;
 +see
 +.Xr rpc 3
 +.It Pa rpcsvc/
 +definition of RPC service structures; see
 +.Xr rpc 3
 +.It Pa security/
 +PAM; see
 +.Xr pam 8
 +.It Pa sys/
 +system C include files (kernel data structures)
 +.It Pa ufs/
 +C include files for UFS (The U-word File System)
 +.Pp
 +.Bl -tag -width ".Pa ffs/" -compact
 +.It Pa ffs/
 +Fast filesystem
 +.It Pa mfs/
 +memory file system;
 +see
 +.Xr mount_mfs 8
 +.It Pa ufs/
 +UFS filesystem
 +.El
 +.Pp
 +.It Pa vm/
 +virtual memory;
 +see
 +.Xr vmstat 8
 +.El
 +.Pp
 +.It Pa lib/
 +archive libraries
 +.Pp
 +.Bl -tag -width ".Pa compat/" -compact
 +.It Pa aout/
 +a.out archive libraries
 +.It Pa compat/
 +shared libraries for compatibility
 +.Pp
 +.Bl -tag -width ".Pa aout/" -compact
 +.It Pa aout/
 +a.out backward compatibility libraries
 +.El
 +.El
 +.Pp
 +.It Pa libdata/
 +misc. utility data files
 +.Pp
 +.Bl -tag -width ".Pa stallion/" -compact
 +.It Pa doscmd/
 +files used by doscmd (drivers, fonts, etc.);
 +see
 +.Xr doscmd 1
 +.Pp
 +.Bl -tag -width ".Pa fonts/" -compact
 +.It Pa fonts/
 +fonts used by doscmd
 +.El
 +.Pp
 +.It Pa lint/
 +various prebuilt lint libraries;
 +see
 +.Xr lint 1
 +.It Pa msdosfs/
 +Character set conversion tables
 +.It Pa stallion/
 +holds the download firmware images
 +.El
 +.Pp
 +.It Pa libexec/
 +system daemons & system utilities (executed by other programs)
 +.Pp
 +.Bl -tag -width ".Pa binutils217/" -compact
 +.It Pa binutils217/
 +.Pp
 +.Bl -tag -width ".Pa ldscripts/" -compact
 +.It Pa ldscripts/
 +linker scripts;
 +see
 +.Xr ld 1
 +.El
 +.Pp
 +.It Pa lpr/
 +utilities and filters for LP print system;
 +see
 +.Xr lpr 1
 +.It Pa sendmail/
 +the sendmail binary;
 +see
 +.Xr mailwrapper 8
 +and
 +.Xr sendmail 8
 +.It Pa sm.bin/
 +restricted shell for sendmail;
 +see
 +.Xr smrsh 8
 +.It Pa uucp/
 +uucp utilities;
 +see
 +.Xr uucp 1
 +.El
 +.Pp
 +.It Pa local/
 +local executables, libraries, etc.
 +Within
 +.Pa local/ ,
 +the general layout sketched out by
 +.Xr hier 7
 +for
 +.Pa /usr
 +should be used.
 +Exceptions are the
 +.Pa man/
 +directory (directly under
 +.Pa local/
 +rather than under
 +.Pa local/share/ ) ,
 +documentation (in
 +.Pa share/doc/<app>/ ) ,
 +and
 +.Pa /usr/local/etc
 +.Pf ( mimics
 +.Pa /etc ) .
 +.It Pa obj/
 +architecture-specific target tree produced by building the
 +.Pa /usr/src
 +tree
 +.It Pa pkg/
 +default destination directory for the
 +.Xr pkgsrc 7
 +collection.
 +Within
 +.Pa pkg/ ,
 +the general layout sketched out by
 +.Xr hier 7
 +for
 +.Pa /usr
 +should be used.
 +Exceptions are the
 +.Pa man/
 +directory (directly under
 +.Pa pkg/
 +rather than under
 +.Pa pkg/share/ ) ,
 +documentation (in
 +.Pa share/doc/<pkg>/ ) ,
 +and
 +.Pa /usr/pkg/etc
 +.Pf ( mimics
 +.Pa /etc ) .
 +.It Pa pkgsrc/
 +The
 +.Xr pkgsrc 7
 +collection (optional).
 +.It Pa sbin/
 +system daemons & system utilities (executed by users)
 +.It Pa share/
 +architecture-independent files
 +.Pp
 +.Bl -tag -width ".Pa groff_font/" -compact
 +.It Pa calendar/
 +a variety of pre-fab calendar files;
 +see
 +.Xr calendar 1
 +.It Pa dict/
 +word lists;
 +see
 +.Xr look 1
 +.Pp
 +.Bl -tag -width ".Pa papers/" -compact
 +.It Pa web2
 +words from Webster's 2nd International
 +.It Pa words
 +common words
 +.It Pa papers/
 +reference databases;
 +see
 +.Xr refer 1
 +.El
 +.Pp
 +.It Pa examples/
 +various examples for users and programmers
 +.It Pa games/
 +ASCII text files used by various games
 +.It Pa groff_font/
 +device description file for device name
 +.It Pa i18n/
 +internationalization databases; see
 +.Xr iconv 3
 +.It Pa info/
 +GNU Info hypertext system
 +.It Pa isdn/
 +ISDN
 +.It Pa libg++/
 +libg++'s genclass prototype/template class files
 +.It Pa locale/
 +localization files;
 +see
 +.Xr setlocale 3
 +.It Pa man/
 +manual pages
 +.It Pa me/
 +macros for use with the me macro package;
 +see
 +.Xr me 7
 +.It Pa misc/
 +misc system-wide ASCII text files
 +.Pp
 +.Bl -tag -width ".Pa termcap" -compact
 +.It Pa termcap
 +terminal characteristics database;
 +see
 +.Xr termcap 5
 +.El
 +.Pp
 +.It Pa mk/
 +templates for make;
 +see
 +.Xr make 1
 +.It Pa nls/
 +national language support files;
 +see
 +.Xr mklocale 1
 +.It Pa openssl/
 +.Pp
 +.Bl -tag -width ".Pa man/" -compact
 +.It Pa man/
 +OpenSSL manual pages
 +.El
 +.Pp
 +.It Pa sendmail/
 +sendmail configuration files;
 +see
 +.Xr sendmail 8
 +.It Pa skel/
 +example . (dot) files for new accounts
 +.It Pa syscons/
 +files used by
 +.Xr syscons 4
 +.Pp
 +.Bl -tag -width ".Pa scrnmaps/" -compact
 +.It Pa fonts/
 +console fonts;
 +see
 +.Xr vidcontrol 1
 +and
 +.Xr vidfont 1
 +.It Pa keymaps/
 +console keyboard maps;
 +see
 +.Xr kbdcontrol 1
 +and
 +.Xr kbdmap 1
 +.It Pa scrnmaps/
 +console screen maps
 +.El
 +.Pp
 +.It Pa tabset/
 +tab description files for a variety of terminals; used in
 +the termcap file;
 +see
 +.Xr termcap 5
 +.It Pa tmac/
 +text processing macros;
 +see
 +.Xr nroff 1
 +and
 +.Xr troff 1
 +.It Pa vi/
 +localization support and utilities for
 +.Xr vi 1
 +.It Pa zoneinfo/
 +timezone configuration information;
 +see
 +.Xr tzfile 5
 +.El
 +.Pp
 +.It Pa src/
 +.Bx ,
 +third-party, and/or local source files
 +.Pp
 +.Bl -tag -width ".Pa kerberos5/" -compact
 +.It Pa bin/
 +source code for files in
 +.Pa /bin
 +.It Pa contrib/
 +source code for contributed software
 +.It Pa crypto/
 +source code for contributed cryptography software
 +.It Pa etc/
 +source code for files in
 +.Pa /etc
 +.It Pa games/
 +source code for files in
 +.Pa /usr/games
 +.It Pa gnu/
 +Utilities covered by the GNU General Public License
 +.It Pa include/
 +source code for files in
 +.Pa /usr/include
 +.It Pa kerberos5/
 +source code for kerberos version 5
 +.It Pa lib/
 +source code for files in
 +.Pa /usr/lib
 +.It Pa libexec/
 +source code for files in
 +.Pa /usr/libexec
 +.It Pa nrelease/
 +files required to produce a
 +.Dx
 +release
 +.It Pa sbin/
 +source code for files in
 +.Pa /sbin
 +.It Pa secure/
 +build directory for files in
 +.Pa /usr/src/crypto
 +.It Pa share/
 +source for files in
 +.Pa /usr/share
 +.It Pa sys/
 +kernel source code
 +.It Pa tools/
 +tools used for maintenance and testing of
 +.Dx
 +.It Pa usr.bin/
 +source code for files in
 +.Pa /usr/bin
 +.It Pa usr.sbin/
 +source code for files in
 +.Pa /usr/sbin
 +.El
 +.El
 +.It Pa /var/
 +multi-purpose log, temporary, transient, and spool files
 +.Pp
 +.Bl -tag -width ".Pa preserve/" -compact
 +.It Pa account/
 +system accounting files
 +.Pp
 +.Bl -tag -width ".Pa acct" -compact
 +.It Pa acct
 +execution accounting file;
 +see
 +.Xr acct 5
 +.El
 +.Pp
 +.It Pa at/
 +timed command scheduling files;
 +see
 +.Xr \&at 1
 +.Pp
 +.Bl -tag -width ".Pa spool/" -compact
 +.It Pa jobs/
 +directory containing job files
 +.It Pa spool/
 +directory containing output spool files
 +.El
 +.Pp
 +.It Pa backups/
 +misc. backup files
 +.It Pa crash/
 +default directory to store kernel crash dumps; see
 +.Xr crash 8
 +and
 +.Xr savecore 8
 +.It Pa cron/
 +files used by cron;
 +see
 +.Xr cron 8
 +.Pp
 +.Bl -tag -width ".Pa tabs/" -compact
 +.It Pa tabs/
 +crontab files;
 +see
 +.Xr crontab 5
 +.El
 +.Pp
 +.It Pa db/
 +misc. automatically generated system-specific database files
 +.It Pa empty/
 +empty directory used by
 +.Xr sshd 8
 +for privilege separation
 +.It Pa games/
 +misc. game status and score files
 +.It Pa heimdal/
 +kerberos server databases; see
 +.Xr kdc 8
 +.It Pa log/
 +misc. system log files
 +.Pp
 +.Bl -tag -width ".Pa wtmp" -compact
 +.It Pa wtmp
 +login/logout log;
 +see
 +.Xr wtmp 5
 +.El
 +.Pp
 +.It Pa mail/
 +user mailbox files
 +.It Pa msgs/
 +system messages database;
 +see
 +.Xr msgs 1
 +.It Pa preserve/
 +temporary home of files preserved after an accidental death
 +of an editor;
 +see
 +.Xr \&ex 1
 +.It Pa quotas/
 +filesystem quota information files
 +.It Pa run/
 +system information files describing various info about
 +system since it was booted
 +.Pp
 +.Bl -tag -width ".Pa ppp/" -compact
 +.It Pa ppp/
 +writable by the
 +.Dq network
 +group for command connection sockets; see
 +.Xr ppp 8
 +.It Pa utmp
 +database of current users;
 +see
 +.Xr utmp 5
 +.El
 +.Pp
 +.It Pa rwho/
 +rwho data files;
 +see
 +.Xr rwhod 8 ,
 +.Xr rwho 1 ,
 +and
 +.Xr ruptime 1
 +.It Pa spool/
 +misc. printer and mail system spooling directories
 +.Pp
 +.Bl -tag -width ".Pa clientmqueue/" -compact
 +.It Pa clientmqueue/
 +undelivered submission mail queue;
 +see
 +.Xr sendmail 8
 +.It Pa dma/
 +undelivered mail queue;
 +see
 +.Xr dma 8
 +.It Pa ftp/
 +commonly
 +.Pa ~ftp ;
 +the anonymous ftp root directory
 +.It Pa mqueue/
 +undelivered mail queue;
 +see
 +.Xr sendmail 8
 +.It Pa output/
 +line printer spooling directories
 +.It Pa uucp/
 +uucp spool directory
 +.It Pa uucppublic/
 +commonly
 +.Pa ~uucp ;
 +public uucp temporary directory
 +.El
 +.Pp
 +.It Pa tmp/
 +temporary files that are kept between system reboots
 +.Pp
 +.Bl -tag -width ".Pa vi.recover/" -compact
 +.It Pa vi.recover/
 +the directory where recovery files are stored
 +.El
 +.Pp
 +.It Pa yp/
 +the NIS maps
 +.El
 +.El
 +.Sh NOTES
 +This manual page documents the default
 +.Dx
 +filesystem layout, but
 +the actual hierarchy on a given system is defined at the system
 +administrator's discretion.
 +A well-maintained installation will include a customized version of
 +this document.
 +.Sh SEE ALSO
 +.Xr apropos 1 ,
 +.Xr find 1 ,
 +.Xr finger 1 ,
 +.Xr grep 1 ,
 +.Xr ls 1 ,
 +.Xr whatis 1 ,
 +.Xr whereis 1 ,
 +.Xr which 1 ,
 +.Xr fsck 8
 +.Sh HISTORY
 +A
 +.Nm
 +manual page appeared in
 +.At v7 .