]> The Tcpdump Group git mirrors - libpcap/blobdiff - gencode.c
Report an error for MPLS labels that don't fit in 20 bits.
[libpcap] / gencode.c
index f0ad3426ce86cfdf45432946d6176ff309374257..09f72d437cb17b9aaa85d8b61f3a0474c57d9009 100644 (file)
--- a/gencode.c
+++ b/gencode.c
 
 #include <pcap-types.h>
 #ifdef _WIN32
-#include <pcap-stdinc.h>
-#else /* _WIN32 */
-#include <sys/socket.h>
-#endif /* _WIN32 */
-
-#ifndef _WIN32
-
-#ifdef __NetBSD__
-#include <sys/param.h>
-#endif
+  #include <ws2tcpip.h>
+#else
+  #include <sys/socket.h>
 
-#include <netinet/in.h>
-#include <arpa/inet.h>
+  #ifdef __NetBSD__
+    #include <sys/param.h>
+  #endif
 
+  #include <netinet/in.h>
+  #include <arpa/inet.h>
 #endif /* _WIN32 */
 
 #include <stdlib.h>
@@ -54,6 +50,8 @@
 
 #include "pcap-int.h"
 
+#include "extract.h"
+
 #include "ethertype.h"
 #include "nlpid.h"
 #include "llc.h"
 #define offsetof(s, e) ((size_t)&((s *)0)->e)
 #endif
 
-#ifdef INET6
 #ifdef _WIN32
-#if defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF)
+  #ifdef INET6
+    #if defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF)
 /* IPv6 address */
 struct in6_addr
   {
     union
       {
-       u_int8_t                u6_addr8[16];
-       u_int16_t       u6_addr16[8];
-       u_int32_t       u6_addr32[4];
+       uint8_t         u6_addr8[16];
+       uint16_t        u6_addr16[8];
+       uint32_t        u6_addr32[4];
       } in6_u;
 #define s6_addr                        in6_u.u6_addr8
 #define s6_addr16              in6_u.u6_addr16
@@ -113,12 +111,12 @@ typedef unsigned short    sa_family_t;
 struct sockaddr_in6
   {
     __SOCKADDR_COMMON (sin6_);
-    u_int16_t sin6_port;               /* Transport layer port # */
-    u_int32_t sin6_flowinfo;   /* IPv6 flow information */
+    uint16_t sin6_port;                /* Transport layer port # */
+    uint32_t sin6_flowinfo;    /* IPv6 flow information */
     struct in6_addr sin6_addr; /* IPv6 address */
   };
 
-#ifndef EAI_ADDRFAMILY
+      #ifndef EAI_ADDRFAMILY
 struct addrinfo {
        int     ai_flags;       /* AI_PASSIVE, AI_CANONNAME */
        int     ai_family;      /* PF_xxx */
@@ -129,12 +127,12 @@ struct addrinfo {
        struct sockaddr *ai_addr;       /* binary address */
        struct addrinfo *ai_next;       /* next structure in linked list */
 };
-#endif /* EAI_ADDRFAMILY */
-#endif /* defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF) */
+      #endif /* EAI_ADDRFAMILY */
+    #endif /* defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF) */
+  #endif /* INET6 */
 #else /* _WIN32 */
-#include <netdb.h>     /* for "struct addrinfo" */
+  #include <netdb.h>   /* for "struct addrinfo" */
 #endif /* _WIN32 */
-#endif /* INET6 */
 #include <pcap/namedb.h>
 
 #include "nametoaddr.h"
@@ -269,7 +267,6 @@ struct _compiler_state {
        /* XXX */
        u_int pcap_fddipad;
 
-#ifdef INET6
        /*
         * As errors are handled by a longjmp, anything allocated must
         * be freed in the longjmp handler, so it must be reachable
@@ -280,7 +277,13 @@ struct _compiler_state {
         * any addrinfo structure that would need to be freed.
         */
        struct addrinfo *ai;
-#endif
+
+       /*
+        * Another thing that's allocated is the result of pcap_ether_aton();
+        * it must be freed with free().  This variable points to any
+        * address that would need to be freed.
+        */
+       u_char *e;
 
        /*
         * Various code constructs need to know the layout of the packet.
@@ -423,25 +426,42 @@ struct _compiler_state {
        int cur_chunk;
 };
 
+void PCAP_NORETURN
+bpf_parser_error(compiler_state_t *cstate, const char *msg)
+{
+       bpf_error(cstate, "can't parse filter expression: %s", msg);
+       /* NOTREACHED */
+}
+
+/*
+ * For use by the optimizer, which needs to do its *own* cleanup before
+ * delivering a longjmp-based exception.
+ */
 void
-bpf_syntax_error(compiler_state_t *cstate, const char *msg)
+bpf_vset_error(compiler_state_t *cstate, const char *fmt, va_list ap)
+{
+       if (cstate->bpf_pcap != NULL)
+               (void)pcap_vsnprintf(pcap_geterr(cstate->bpf_pcap),
+                   PCAP_ERRBUF_SIZE, fmt, ap);
+}
+
+void PCAP_NORETURN
+bpf_abort_compilation(compiler_state_t *cstate)
 {
-       bpf_error(cstate, "syntax error in filter expression: %s", msg);
+       longjmp(cstate->top_ctx, 1);
        /* NOTREACHED */
 }
 
 /* VARARGS */
-void
+void PCAP_NORETURN
 bpf_error(compiler_state_t *cstate, const char *fmt, ...)
 {
        va_list ap;
 
        va_start(ap, fmt);
-       if (cstate->bpf_pcap != NULL)
-               (void)pcap_vsnprintf(pcap_geterr(cstate->bpf_pcap),
-                   PCAP_ERRBUF_SIZE, fmt, ap);
+       bpf_vset_error(cstate, fmt, ap);
        va_end(ap);
-       longjmp(cstate->top_ctx, 1);
+       bpf_abort_compilation(cstate);
        /* NOTREACHED */
 }
 
@@ -521,7 +541,7 @@ static struct block *gen_host6(compiler_state_t *, struct in6_addr *,
 #endif
 #ifndef INET6
 static struct block *gen_gateway(compiler_state_t *, const u_char *,
-    bpf_u_int32 **, int, int);
+    struct addrinfo *, int, int);
 #endif
 static struct block *gen_ipfrag(compiler_state_t *);
 static struct block *gen_portatom(compiler_state_t *, int, bpf_int32);
@@ -580,7 +600,8 @@ newchunk(compiler_state_t *cstate, size_t n)
 
        cp = &cstate->chunks[cstate->cur_chunk];
        if (n > cp->n_left) {
-               ++cp, k = ++cstate->cur_chunk;
+               ++cp;
+               k = ++cstate->cur_chunk;
                if (k >= NCHUNKS)
                        bpf_error(cstate, "out of memory");
                size = CHUNK0SIZE << k;
@@ -615,7 +636,7 @@ sdup(compiler_state_t *cstate, const char *s)
        size_t n = strlen(s) + 1;
        char *cp = newchunk(cstate, n);
 
-       strlcpy(cp, s, n);
+       pcap_strlcpy(cp, s, n);
        return (cp);
 }
 
@@ -651,7 +672,7 @@ gen_retblk(compiler_state_t *cstate, int v)
        return b;
 }
 
-static inline void
+static inline PCAP_NORETURN_DEF void
 syntax(compiler_state_t *cstate)
 {
        bpf_error(cstate, "syntax error in filter expression");
@@ -667,7 +688,7 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
        compiler_state_t cstate;
        const char * volatile xbuf = buf;
        yyscan_t scanner = NULL;
-       YY_BUFFER_STATE in_buffer = NULL;
+       volatile YY_BUFFER_STATE in_buffer = NULL;
        u_int len;
        int  rc;
 
@@ -687,7 +708,7 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
        done = 1;
 #endif
 
-#ifdef HAVE_REMOTE
+#ifdef ENABLE_REMOTE
        /*
         * If the device on which we're capturing need to be notified
         * that a new filter is being compiled, do so.
@@ -713,6 +734,7 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
 #ifdef INET6
        cstate.ai = NULL;
 #endif
+       cstate.e = NULL;
        cstate.ic.root = NULL;
        cstate.ic.cur_mark = 0;
        cstate.bpf_pcap = p;
@@ -723,6 +745,8 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
                if (cstate.ai != NULL)
                        freeaddrinfo(cstate.ai);
 #endif
+               if (cstate.e != NULL)
+                       free(cstate.e);
                rc = -1;
                goto quit;
        }
@@ -738,7 +762,8 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
        }
 
        if (pcap_lex_init(&scanner) != 0)
-               bpf_error(&cstate, "can't initialize scanner: %s", pcap_strerror(errno));
+               pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+                   errno, "can't initialize scanner");
        in_buffer = pcap__scan_string(xbuf ? xbuf : "", scanner);
 
        /*
@@ -822,8 +847,7 @@ pcap_freecode(struct bpf_program *program)
  * in each block is already resolved.
  */
 static void
-backpatch(list, target)
-       struct block *list, *target;
+backpatch(struct block *list, struct block *target)
 {
        struct block *next;
 
@@ -844,8 +868,7 @@ backpatch(list, target)
  * which of jt and jf is the link.
  */
 static void
-merge(b0, b1)
-       struct block *b0, *b1;
+merge(struct block *b0, struct block *b1)
 {
        register struct block **p = &b0;
 
@@ -907,8 +930,7 @@ finish_parse(compiler_state_t *cstate, struct block *p)
 }
 
 void
-gen_and(b0, b1)
-       struct block *b0, *b1;
+gen_and(struct block *b0, struct block *b1)
 {
        backpatch(b0, b1->head);
        b0->sense = !b0->sense;
@@ -919,8 +941,7 @@ gen_and(b0, b1)
 }
 
 void
-gen_or(b0, b1)
-       struct block *b0, *b1;
+gen_or(struct block *b0, struct block *b1)
 {
        b0->sense = !b0->sense;
        backpatch(b0, b1->head);
@@ -930,8 +951,7 @@ gen_or(b0, b1)
 }
 
 void
-gen_not(b)
-       struct block *b;
+gen_not(struct block *b)
 {
        b->sense = !b->sense;
 }
@@ -984,13 +1004,22 @@ gen_bcmp(compiler_state_t *cstate, enum e_offrel offrel, u_int offset,
 {
        register struct block *b, *tmp;
 
+       /*
+        * XXX - the actual *instructions* do unsigned comparisons on
+        * most platforms, and the load instructions don't do sign
+        * extension, so gen_cmp() should really take an unsigned
+        * value argument.
+        *
+        * As the load instructons also don't do sign-extension, we
+        * fetch the values from the byte array as unsigned.  We don't
+        * want to use the signed versions of the extract calls.
+        */
        b = NULL;
        while (size >= 4) {
                register const u_char *p = &v[size - 4];
-               bpf_int32 w = ((bpf_int32)p[0] << 24) |
-                   ((bpf_int32)p[1] << 16) | ((bpf_int32)p[2] << 8) | p[3];
 
-               tmp = gen_cmp(cstate, offrel, offset + size - 4, BPF_W, w);
+               tmp = gen_cmp(cstate, offrel, offset + size - 4, BPF_W,
+                   (bpf_int32)EXTRACT_BE_U_4(p));
                if (b != NULL)
                        gen_and(b, tmp);
                b = tmp;
@@ -998,9 +1027,9 @@ gen_bcmp(compiler_state_t *cstate, enum e_offrel offrel, u_int offset,
        }
        while (size >= 2) {
                register const u_char *p = &v[size - 2];
-               bpf_int32 w = ((bpf_int32)p[0] << 8) | p[1];
 
-               tmp = gen_cmp(cstate, offrel, offset + size - 2, BPF_H, w);
+               tmp = gen_cmp(cstate, offrel, offset + size - 2, BPF_H,
+                   (bpf_int32)EXTRACT_BE_U_2(p));
                if (b != NULL)
                        gen_and(b, tmp);
                b = tmp;
@@ -1083,10 +1112,10 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
         * Assume it's not raw ATM with a pseudo-header, for now.
         */
        cstate->is_atm = 0;
-       cstate->off_vpi = -1;
-       cstate->off_vci = -1;
-       cstate->off_proto = -1;
-       cstate->off_payload = -1;
+       cstate->off_vpi = OFFSET_NOT_SET;
+       cstate->off_vci = OFFSET_NOT_SET;
+       cstate->off_proto = OFFSET_NOT_SET;
+       cstate->off_payload = OFFSET_NOT_SET;
 
        /*
         * And not Geneve.
@@ -1101,12 +1130,12 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
        /*
         * And assume we're not doing SS7.
         */
-       cstate->off_li = -1;
-       cstate->off_li_hsl = -1;
-       cstate->off_sio = -1;
-       cstate->off_opc = -1;
-       cstate->off_dpc = -1;
-       cstate->off_sls = -1;
+       cstate->off_li = OFFSET_NOT_SET;
+       cstate->off_li_hsl = OFFSET_NOT_SET;
+       cstate->off_sio = OFFSET_NOT_SET;
+       cstate->off_opc = OFFSET_NOT_SET;
+       cstate->off_dpc = OFFSET_NOT_SET;
+       cstate->off_sls = OFFSET_NOT_SET;
 
        cstate->label_stack_depth = 0;
        cstate->vlan_stack_depth = 0;
@@ -1116,7 +1145,7 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
        case DLT_ARCNET:
                cstate->off_linktype.constant_part = 2;
                cstate->off_linkpl.constant_part = 6;
-               cstate->off_nl = 0;     /* XXX in reality, variable! */
+               cstate->off_nl = 0;             /* XXX in reality, variable! */
                cstate->off_nl_nosnap = 0;      /* no 802.2 LLC */
                break;
 
@@ -1339,13 +1368,20 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
                cstate->off_nl_nosnap = 0;      /* no 802.2 LLC */
                break;
 
-       case DLT_LINUX_SLL:     /* fake header for Linux cooked socket */
+       case DLT_LINUX_SLL:     /* fake header for Linux cooked socket v1 */
                cstate->off_linktype.constant_part = 14;
                cstate->off_linkpl.constant_part = 16;
                cstate->off_nl = 0;
                cstate->off_nl_nosnap = 0;      /* no 802.2 LLC */
                break;
 
+       case DLT_LINUX_SLL2:    /* fake header for Linux cooked socket v2 */
+               cstate->off_linktype.constant_part = 0;
+               cstate->off_linkpl.constant_part = 20;
+               cstate->off_nl = 0;
+               cstate->off_nl_nosnap = 0;      /* no 802.2 LLC */
+               break;
+
        case DLT_LTALK:
                /*
                 * LocalTalk does have a 1-byte type field in the LLAP header,
@@ -1430,7 +1466,7 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
                cstate->off_linktype.constant_part = 4;
                cstate->off_linkpl.constant_part = 4;
                cstate->off_nl = 0;
-               cstate->off_nl_nosnap = -1;     /* no 802.2 LLC */
+               cstate->off_nl_nosnap = OFFSET_NOT_SET; /* no 802.2 LLC */
                 break;
 
        case DLT_JUNIPER_ATM1:
@@ -1461,63 +1497,63 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
                cstate->off_linktype.constant_part = 4;
                cstate->off_linkpl.constant_part = 6;
                cstate->off_nl = 0;
-               cstate->off_nl_nosnap = -1;     /* no 802.2 LLC */
+               cstate->off_nl_nosnap = OFFSET_NOT_SET; /* no 802.2 LLC */
                break;
 
        case DLT_JUNIPER_GGSN:
                cstate->off_linktype.constant_part = 6;
                cstate->off_linkpl.constant_part = 12;
                cstate->off_nl = 0;
-               cstate->off_nl_nosnap = -1;     /* no 802.2 LLC */
+               cstate->off_nl_nosnap = OFFSET_NOT_SET; /* no 802.2 LLC */
                break;
 
        case DLT_JUNIPER_ES:
                cstate->off_linktype.constant_part = 6;
                cstate->off_linkpl.constant_part = OFFSET_NOT_SET;      /* not really a network layer but raw IP addresses */
-               cstate->off_nl = -1;            /* not really a network layer but raw IP addresses */
-               cstate->off_nl_nosnap = -1;     /* no 802.2 LLC */
+               cstate->off_nl = OFFSET_NOT_SET;        /* not really a network layer but raw IP addresses */
+               cstate->off_nl_nosnap = OFFSET_NOT_SET; /* no 802.2 LLC */
                break;
 
        case DLT_JUNIPER_MONITOR:
                cstate->off_linktype.constant_part = 12;
                cstate->off_linkpl.constant_part = 12;
-               cstate->off_nl = 0;             /* raw IP/IP6 header */
-               cstate->off_nl_nosnap = -1;     /* no 802.2 LLC */
+               cstate->off_nl = 0;                     /* raw IP/IP6 header */
+               cstate->off_nl_nosnap = OFFSET_NOT_SET; /* no 802.2 LLC */
                break;
 
        case DLT_BACNET_MS_TP:
                cstate->off_linktype.constant_part = OFFSET_NOT_SET;
                cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
-               cstate->off_nl = -1;
-               cstate->off_nl_nosnap = -1;
+               cstate->off_nl = OFFSET_NOT_SET;
+               cstate->off_nl_nosnap = OFFSET_NOT_SET;
                break;
 
        case DLT_JUNIPER_SERVICES:
                cstate->off_linktype.constant_part = 12;
                cstate->off_linkpl.constant_part = OFFSET_NOT_SET;      /* L3 proto location dep. on cookie type */
-               cstate->off_nl = -1;            /* L3 proto location dep. on cookie type */
-               cstate->off_nl_nosnap = -1;     /* no 802.2 LLC */
+               cstate->off_nl = OFFSET_NOT_SET;        /* L3 proto location dep. on cookie type */
+               cstate->off_nl_nosnap = OFFSET_NOT_SET; /* no 802.2 LLC */
                break;
 
        case DLT_JUNIPER_VP:
                cstate->off_linktype.constant_part = 18;
                cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
-               cstate->off_nl = -1;
-               cstate->off_nl_nosnap = -1;
+               cstate->off_nl = OFFSET_NOT_SET;
+               cstate->off_nl_nosnap = OFFSET_NOT_SET;
                break;
 
        case DLT_JUNIPER_ST:
                cstate->off_linktype.constant_part = 18;
                cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
-               cstate->off_nl = -1;
-               cstate->off_nl_nosnap = -1;
+               cstate->off_nl = OFFSET_NOT_SET;
+               cstate->off_nl_nosnap = OFFSET_NOT_SET;
                break;
 
        case DLT_JUNIPER_ISM:
                cstate->off_linktype.constant_part = 8;
                cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
-               cstate->off_nl = -1;
-               cstate->off_nl_nosnap = -1;
+               cstate->off_nl = OFFSET_NOT_SET;
+               cstate->off_nl_nosnap = OFFSET_NOT_SET;
                break;
 
        case DLT_JUNIPER_VS:
@@ -1526,8 +1562,8 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
        case DLT_JUNIPER_ATM_CEMIC:
                cstate->off_linktype.constant_part = 8;
                cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
-               cstate->off_nl = -1;
-               cstate->off_nl_nosnap = -1;
+               cstate->off_nl = OFFSET_NOT_SET;
+               cstate->off_nl_nosnap = OFFSET_NOT_SET;
                break;
 
        case DLT_MTP2:
@@ -1539,8 +1575,8 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
                cstate->off_sls = 7;
                cstate->off_linktype.constant_part = OFFSET_NOT_SET;
                cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
-               cstate->off_nl = -1;
-               cstate->off_nl_nosnap = -1;
+               cstate->off_nl = OFFSET_NOT_SET;
+               cstate->off_nl_nosnap = OFFSET_NOT_SET;
                break;
 
        case DLT_MTP2_WITH_PHDR:
@@ -1552,8 +1588,8 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
                cstate->off_sls = 11;
                cstate->off_linktype.constant_part = OFFSET_NOT_SET;
                cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
-               cstate->off_nl = -1;
-               cstate->off_nl_nosnap = -1;
+               cstate->off_nl = OFFSET_NOT_SET;
+               cstate->off_nl_nosnap = OFFSET_NOT_SET;
                break;
 
        case DLT_ERF:
@@ -1565,8 +1601,8 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
                cstate->off_sls = 27;
                cstate->off_linktype.constant_part = OFFSET_NOT_SET;
                cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
-               cstate->off_nl = -1;
-               cstate->off_nl_nosnap = -1;
+               cstate->off_nl = OFFSET_NOT_SET;
+               cstate->off_nl_nosnap = OFFSET_NOT_SET;
                break;
 
        case DLT_PFSYNC:
@@ -1582,15 +1618,15 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
                 */
                cstate->off_linktype.constant_part = OFFSET_NOT_SET;    /* variable, min 15, max 71 steps of 7 */
                cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
-               cstate->off_nl = -1;            /* variable, min 16, max 71 steps of 7 */
-               cstate->off_nl_nosnap = -1;     /* no 802.2 LLC */
+               cstate->off_nl = OFFSET_NOT_SET;        /* variable, min 16, max 71 steps of 7 */
+               cstate->off_nl_nosnap = OFFSET_NOT_SET; /* no 802.2 LLC */
                break;
 
        case DLT_IPNET:
                cstate->off_linktype.constant_part = 1;
                cstate->off_linkpl.constant_part = 24;  /* ipnet header length */
                cstate->off_nl = 0;
-               cstate->off_nl_nosnap = -1;
+               cstate->off_nl_nosnap = OFFSET_NOT_SET;
                break;
 
        case DLT_NETANALYZER:
@@ -1618,8 +1654,8 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
                    cstate->linktype <= DLT_MATCHING_MAX) {
                        cstate->off_linktype.constant_part = OFFSET_NOT_SET;
                        cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
-                       cstate->off_nl = -1;
-                       cstate->off_nl_nosnap = -1;
+                       cstate->off_nl = OFFSET_NOT_SET;
+                       cstate->off_nl_nosnap = OFFSET_NOT_SET;
                } else {
                        bpf_error(cstate, "unknown data link type %d", cstate->linktype);
                }
@@ -1744,7 +1780,7 @@ gen_load_a(compiler_state_t *cstate, enum e_offrel offrel, u_int offset,
 
        default:
                abort();
-               return NULL;
+               /* NOTREACHED */
        }
        return s;
 }
@@ -1808,6 +1844,7 @@ gen_loadx_iphdrlen(compiler_state_t *cstate)
        return s;
 }
 
+
 static struct block *
 gen_uncond(compiler_state_t *cstate, int rsense)
 {
@@ -2932,8 +2969,7 @@ gen_abs_offset_varpart(compiler_state_t *cstate, bpf_abs_offset *off)
  * Map an Ethernet type to the equivalent PPP type.
  */
 static int
-ethertype_to_ppptype(proto)
-       int proto;
+ethertype_to_ppptype(int proto)
 {
        switch (proto) {
 
@@ -3020,7 +3056,7 @@ gen_prevlinkhdr_check(compiler_state_t *cstate)
  */
 #define BSD_AFNUM_INET6_BSD    24      /* NetBSD, OpenBSD, BSD/OS, Npcap */
 #define BSD_AFNUM_INET6_FREEBSD        28      /* FreeBSD */
-#define BSD_AFNUM_INET6_DARWIN 30      /* OS X, iOS, other Darwin-based OSes */
+#define BSD_AFNUM_INET6_DARWIN 30      /* macOS, iOS, other Darwin-based OSes */
 
 /*
  * Generate code to match a particular packet type by matching the
@@ -3576,14 +3612,14 @@ gen_snap(compiler_state_t *cstate, bpf_u_int32 orgcode, bpf_u_int32 ptype)
 {
        u_char snapblock[8];
 
-       snapblock[0] = LLCSAP_SNAP;     /* DSAP = SNAP */
-       snapblock[1] = LLCSAP_SNAP;     /* SSAP = SNAP */
-       snapblock[2] = 0x03;            /* control = UI */
-       snapblock[3] = (orgcode >> 16); /* upper 8 bits of organization code */
-       snapblock[4] = (orgcode >> 8);  /* middle 8 bits of organization code */
-       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 */
+       snapblock[0] = LLCSAP_SNAP;             /* DSAP = SNAP */
+       snapblock[1] = LLCSAP_SNAP;             /* SSAP = SNAP */
+       snapblock[2] = 0x03;                    /* control = UI */
+       snapblock[3] = (u_char)(orgcode >> 16); /* upper 8 bits of organization code */
+       snapblock[4] = (u_char)(orgcode >> 8);  /* middle 8 bits of organization code */
+       snapblock[5] = (u_char)(orgcode >> 0);  /* lower 8 bits of organization code */
+       snapblock[6] = (u_char)(ptype >> 8);    /* upper 8 bits of protocol type */
+       snapblock[7] = (u_char)(ptype >> 0);    /* lower 8 bits of protocol type */
        return gen_bcmp(cstate, OR_LLC, 0, 8, snapblock);
 }
 
@@ -3869,13 +3905,37 @@ gen_hostop(compiler_state_t *cstate, bpf_u_int32 addr, bpf_u_int32 mask,
                gen_and(b0, b1);
                return b1;
 
-       case Q_OR:
        case Q_DEFAULT:
+       case Q_OR:
                b0 = gen_hostop(cstate, addr, mask, Q_SRC, proto, src_off, dst_off);
                b1 = gen_hostop(cstate, addr, mask, Q_DST, proto, src_off, dst_off);
                gen_or(b0, b1);
                return b1;
 
+       case Q_ADDR1:
+               bpf_error(cstate, "'addr1' and 'address1' are not valid qualifiers for addresses other than 802.11 MAC addresses");
+               break;
+
+       case Q_ADDR2:
+               bpf_error(cstate, "'addr2' and 'address2' are not valid qualifiers for addresses other than 802.11 MAC addresses");
+               break;
+
+       case Q_ADDR3:
+               bpf_error(cstate, "'addr3' and 'address3' are not valid qualifiers for addresses other than 802.11 MAC addresses");
+               break;
+
+       case Q_ADDR4:
+               bpf_error(cstate, "'addr4' and 'address4' are not valid qualifiers for addresses other than 802.11 MAC addresses");
+               break;
+
+       case Q_RA:
+               bpf_error(cstate, "'ra' is not a valid qualifier for addresses other than 802.11 MAC addresses");
+               break;
+
+       case Q_TA:
+               bpf_error(cstate, "'ta' is not a valid qualifier for addresses other than 802.11 MAC addresses");
+               break;
+
        default:
                abort();
        }
@@ -3892,7 +3952,7 @@ gen_hostop6(compiler_state_t *cstate, struct in6_addr *addr,
 {
        struct block *b0, *b1;
        u_int offset;
-       u_int32_t *a, *m;
+       uint32_t *a, *m;
 
        switch (dir) {
 
@@ -3910,19 +3970,43 @@ gen_hostop6(compiler_state_t *cstate, struct in6_addr *addr,
                gen_and(b0, b1);
                return b1;
 
-       case Q_OR:
        case Q_DEFAULT:
+       case Q_OR:
                b0 = gen_hostop6(cstate, addr, mask, Q_SRC, proto, src_off, dst_off);
                b1 = gen_hostop6(cstate, addr, mask, Q_DST, proto, src_off, dst_off);
                gen_or(b0, b1);
                return b1;
 
+       case Q_ADDR1:
+               bpf_error(cstate, "'addr1' and 'address1' are not valid qualifiers for addresses other than 802.11 MAC addresses");
+               break;
+
+       case Q_ADDR2:
+               bpf_error(cstate, "'addr2' and 'address2' are not valid qualifiers for addresses other than 802.11 MAC addresses");
+               break;
+
+       case Q_ADDR3:
+               bpf_error(cstate, "'addr3' and 'address3' are not valid qualifiers for addresses other than 802.11 MAC addresses");
+               break;
+
+       case Q_ADDR4:
+               bpf_error(cstate, "'addr4' and 'address4' are not valid qualifiers for addresses other than 802.11 MAC addresses");
+               break;
+
+       case Q_RA:
+               bpf_error(cstate, "'ra' is not a valid qualifier for addresses other than 802.11 MAC addresses");
+               break;
+
+       case Q_TA:
+               bpf_error(cstate, "'ta' is not a valid qualifier for addresses other than 802.11 MAC addresses");
+               break;
+
        default:
                abort();
        }
        /* this order is important */
-       a = (u_int32_t *)addr;
-       m = (u_int32_t *)mask;
+       a = (uint32_t *)addr;
+       m = (uint32_t *)mask;
        b1 = gen_mcmp(cstate, OR_LINKPL, offset + 12, BPF_W, ntohl(a[3]), ntohl(m[3]));
        b0 = gen_mcmp(cstate, OR_LINKPL, offset + 8, BPF_W, ntohl(a[2]), ntohl(m[2]));
        gen_and(b0, b1);
@@ -3962,19 +4046,19 @@ gen_ehostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
                return b1;
 
        case Q_ADDR1:
-               bpf_error(cstate, "'addr1' is only supported on 802.11 with 802.11 headers");
+               bpf_error(cstate, "'addr1' and 'address1' are only supported on 802.11 with 802.11 headers");
                break;
 
        case Q_ADDR2:
-               bpf_error(cstate, "'addr2' is only supported on 802.11 with 802.11 headers");
+               bpf_error(cstate, "'addr2' and 'address2' are only supported on 802.11 with 802.11 headers");
                break;
 
        case Q_ADDR3:
-               bpf_error(cstate, "'addr3' is only supported on 802.11 with 802.11 headers");
+               bpf_error(cstate, "'addr3' and 'address3' are only supported on 802.11 with 802.11 headers");
                break;
 
        case Q_ADDR4:
-               bpf_error(cstate, "'addr4' is only supported on 802.11 with 802.11 headers");
+               bpf_error(cstate, "'addr4' and 'address4' are only supported on 802.11 with 802.11 headers");
                break;
 
        case Q_RA:
@@ -4018,19 +4102,19 @@ gen_fhostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
                return b1;
 
        case Q_ADDR1:
-               bpf_error(cstate, "'addr1' is only supported on 802.11");
+               bpf_error(cstate, "'addr1' and 'address1' are only supported on 802.11");
                break;
 
        case Q_ADDR2:
-               bpf_error(cstate, "'addr2' is only supported on 802.11");
+               bpf_error(cstate, "'addr2' and 'address2' are only supported on 802.11");
                break;
 
        case Q_ADDR3:
-               bpf_error(cstate, "'addr3' is only supported on 802.11");
+               bpf_error(cstate, "'addr3' and 'address3' are only supported on 802.11");
                break;
 
        case Q_ADDR4:
-               bpf_error(cstate, "'addr4' is only supported on 802.11");
+               bpf_error(cstate, "'addr4' and 'address4' are only supported on 802.11");
                break;
 
        case Q_RA:
@@ -4074,19 +4158,19 @@ gen_thostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
                return b1;
 
        case Q_ADDR1:
-               bpf_error(cstate, "'addr1' is only supported on 802.11");
+               bpf_error(cstate, "'addr1' and 'address1' are only supported on 802.11");
                break;
 
        case Q_ADDR2:
-               bpf_error(cstate, "'addr2' is only supported on 802.11");
+               bpf_error(cstate, "'addr2' and 'address2' are only supported on 802.11");
                break;
 
        case Q_ADDR3:
-               bpf_error(cstate, "'addr3' is only supported on 802.11");
+               bpf_error(cstate, "'addr3' and 'address3' are only supported on 802.11");
                break;
 
        case Q_ADDR4:
-               bpf_error(cstate, "'addr4' is only supported on 802.11");
+               bpf_error(cstate, "'addr4' and 'address4' are only supported on 802.11");
                break;
 
        case Q_RA:
@@ -4387,6 +4471,68 @@ gen_wlanhostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
                gen_and(b1, b0);
                return b0;
 
+       case Q_AND:
+               b0 = gen_wlanhostop(cstate, eaddr, Q_SRC);
+               b1 = gen_wlanhostop(cstate, eaddr, Q_DST);
+               gen_and(b0, b1);
+               return b1;
+
+       case Q_DEFAULT:
+       case Q_OR:
+               b0 = gen_wlanhostop(cstate, eaddr, Q_SRC);
+               b1 = gen_wlanhostop(cstate, eaddr, Q_DST);
+               gen_or(b0, b1);
+               return b1;
+
+       /*
+        * XXX - add BSSID keyword?
+        */
+       case Q_ADDR1:
+               return (gen_bcmp(cstate, OR_LINKHDR, 4, 6, eaddr));
+
+       case Q_ADDR2:
+               /*
+                * Not present in CTS or ACK control frames.
+                */
+               b0 = gen_mcmp(cstate, OR_LINKHDR, 0, BPF_B, IEEE80211_FC0_TYPE_CTL,
+                       IEEE80211_FC0_TYPE_MASK);
+               gen_not(b0);
+               b1 = gen_mcmp(cstate, OR_LINKHDR, 0, BPF_B, IEEE80211_FC0_SUBTYPE_CTS,
+                       IEEE80211_FC0_SUBTYPE_MASK);
+               gen_not(b1);
+               b2 = gen_mcmp(cstate, OR_LINKHDR, 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(cstate, OR_LINKHDR, 10, 6, eaddr);
+               gen_and(b2, b1);
+               return b1;
+
+       case Q_ADDR3:
+               /*
+                * Not present in control frames.
+                */
+               b0 = gen_mcmp(cstate, OR_LINKHDR, 0, BPF_B, IEEE80211_FC0_TYPE_CTL,
+                       IEEE80211_FC0_TYPE_MASK);
+               gen_not(b0);
+               b1 = gen_bcmp(cstate, OR_LINKHDR, 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(cstate, OR_LINKHDR, 1, BPF_B,
+                       IEEE80211_FC1_DIR_DSTODS, IEEE80211_FC1_DIR_MASK);
+               b1 = gen_bcmp(cstate, OR_LINKHDR, 24, 6, eaddr);
+               gen_and(b0, b1);
+               return b1;
+
        case Q_RA:
                /*
                 * Not present in management frames; addr1 in other
@@ -4457,68 +4603,6 @@ gen_wlanhostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
                b1 = gen_bcmp(cstate, OR_LINKHDR, 10, 6, eaddr);
                gen_and(b2, b1);
                return b1;
-
-       /*
-        * XXX - add BSSID keyword?
-        */
-       case Q_ADDR1:
-               return (gen_bcmp(cstate, OR_LINKHDR, 4, 6, eaddr));
-
-       case Q_ADDR2:
-               /*
-                * Not present in CTS or ACK control frames.
-                */
-               b0 = gen_mcmp(cstate, OR_LINKHDR, 0, BPF_B, IEEE80211_FC0_TYPE_CTL,
-                       IEEE80211_FC0_TYPE_MASK);
-               gen_not(b0);
-               b1 = gen_mcmp(cstate, OR_LINKHDR, 0, BPF_B, IEEE80211_FC0_SUBTYPE_CTS,
-                       IEEE80211_FC0_SUBTYPE_MASK);
-               gen_not(b1);
-               b2 = gen_mcmp(cstate, OR_LINKHDR, 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(cstate, OR_LINKHDR, 10, 6, eaddr);
-               gen_and(b2, b1);
-               return b1;
-
-       case Q_ADDR3:
-               /*
-                * Not present in control frames.
-                */
-               b0 = gen_mcmp(cstate, OR_LINKHDR, 0, BPF_B, IEEE80211_FC0_TYPE_CTL,
-                       IEEE80211_FC0_TYPE_MASK);
-               gen_not(b0);
-               b1 = gen_bcmp(cstate, OR_LINKHDR, 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(cstate, OR_LINKHDR, 1, BPF_B,
-                       IEEE80211_FC1_DIR_DSTODS, IEEE80211_FC1_DIR_MASK);
-               b1 = gen_bcmp(cstate, OR_LINKHDR, 24, 6, eaddr);
-               gen_and(b0, b1);
-               return b1;
-
-       case Q_AND:
-               b0 = gen_wlanhostop(cstate, eaddr, Q_SRC);
-               b1 = gen_wlanhostop(cstate, eaddr, Q_DST);
-               gen_and(b0, b1);
-               return b1;
-
-       case Q_DEFAULT:
-       case Q_OR:
-               b0 = gen_wlanhostop(cstate, eaddr, Q_SRC);
-               b1 = gen_wlanhostop(cstate, eaddr, Q_DST);
-               gen_or(b0, b1);
-               return b1;
        }
        abort();
        /* NOTREACHED */
@@ -4555,19 +4639,19 @@ gen_ipfchostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
                return b1;
 
        case Q_ADDR1:
-               bpf_error(cstate, "'addr1' is only supported on 802.11");
+               bpf_error(cstate, "'addr1' and 'address1' are only supported on 802.11");
                break;
 
        case Q_ADDR2:
-               bpf_error(cstate, "'addr2' is only supported on 802.11");
+               bpf_error(cstate, "'addr2' and 'address2' are only supported on 802.11");
                break;
 
        case Q_ADDR3:
-               bpf_error(cstate, "'addr3' is only supported on 802.11");
+               bpf_error(cstate, "'addr3' and 'address3' are only supported on 802.11");
                break;
 
        case Q_ADDR4:
-               bpf_error(cstate, "'addr4' is only supported on 802.11");
+               bpf_error(cstate, "'addr4' and 'address4' are only supported on 802.11");
                break;
 
        case Q_RA:
@@ -4626,16 +4710,37 @@ gen_dnhostop(compiler_state_t *cstate, bpf_u_int32 addr, int dir)
                gen_and(b0, b1);
                return b1;
 
-       case Q_OR:
        case Q_DEFAULT:
+       case Q_OR:
                /* Inefficient because we do our Calvinball dance twice */
                b0 = gen_dnhostop(cstate, addr, Q_SRC);
                b1 = gen_dnhostop(cstate, addr, Q_DST);
                gen_or(b0, b1);
                return b1;
 
-       case Q_ISO:
-               bpf_error(cstate, "ISO host filtering not implemented");
+       case Q_ADDR1:
+               bpf_error(cstate, "'addr1' and 'address1' are not valid qualifiers for addresses other than 802.11 MAC addresses");
+               break;
+
+       case Q_ADDR2:
+               bpf_error(cstate, "'addr2' and 'address2' are not valid qualifiers for addresses other than 802.11 MAC addresses");
+               break;
+
+       case Q_ADDR3:
+               bpf_error(cstate, "'addr3' and 'address3' are not valid qualifiers for addresses other than 802.11 MAC addresses");
+               break;
+
+       case Q_ADDR4:
+               bpf_error(cstate, "'addr4' and 'address4' are not valid qualifiers for addresses other than 802.11 MAC addresses");
+               break;
+
+       case Q_RA:
+               bpf_error(cstate, "'ra' is not a valid qualifier for addresses other than 802.11 MAC addresses");
+               break;
+
+       case Q_TA:
+               bpf_error(cstate, "'ta' is not a valid qualifier for addresses other than 802.11 MAC addresses");
+               break;
 
        default:
                abort();
@@ -4683,7 +4788,7 @@ gen_mpls_linktype(compiler_state_t *cstate, int proto)
 
         case Q_IP:
                 /* match the bottom-of-stack bit */
-                b0 = gen_mcmp(cstate, OR_LINKPL, -2, BPF_B, 0x01, 0x01);
+                b0 = gen_mcmp(cstate, OR_LINKPL, (u_int)-2, BPF_B, 0x01, 0x01);
                 /* match the IPv4 version number */
                 b1 = gen_mcmp(cstate, OR_LINKPL, 0, BPF_B, 0x40, 0xf0);
                 gen_and(b0, b1);
@@ -4691,7 +4796,7 @@ gen_mpls_linktype(compiler_state_t *cstate, int proto)
 
        case Q_IPV6:
                 /* match the bottom-of-stack bit */
-                b0 = gen_mcmp(cstate, OR_LINKPL, -2, BPF_B, 0x01, 0x01);
+                b0 = gen_mcmp(cstate, OR_LINKPL, (u_int)-2, BPF_B, 0x01, 0x01);
                 /* match the IPv4 version number */
                 b1 = gen_mcmp(cstate, OR_LINKPL, 0, BPF_B, 0x60, 0xf0);
                 gen_and(b0, b1);
@@ -4730,6 +4835,9 @@ gen_host(compiler_state_t *cstate, bpf_u_int32 addr, bpf_u_int32 mask,
                }
                return b0;
 
+       case Q_LINK:
+               bpf_error(cstate, "link-layer modifier applied to %s", typestr);
+
        case Q_IP:
                return gen_hostop(cstate, addr, mask, dir, ETHERTYPE_IP, 12, 16);
 
@@ -4739,12 +4847,12 @@ gen_host(compiler_state_t *cstate, bpf_u_int32 addr, bpf_u_int32 mask,
        case Q_ARP:
                return gen_hostop(cstate, addr, mask, dir, ETHERTYPE_ARP, 14, 24);
 
-       case Q_TCP:
-               bpf_error(cstate, "'tcp' modifier applied to %s", typestr);
-
        case Q_SCTP:
                bpf_error(cstate, "'sctp' modifier applied to %s", typestr);
 
+       case Q_TCP:
+               bpf_error(cstate, "'tcp' modifier applied to %s", typestr);
+
        case Q_UDP:
                bpf_error(cstate, "'udp' modifier applied to %s", typestr);
 
@@ -4757,36 +4865,24 @@ gen_host(compiler_state_t *cstate, bpf_u_int32 addr, bpf_u_int32 mask,
        case Q_IGRP:
                bpf_error(cstate, "'igrp' modifier applied to %s", typestr);
 
-       case Q_PIM:
-               bpf_error(cstate, "'pim' modifier applied to %s", typestr);
-
-       case Q_VRRP:
-               bpf_error(cstate, "'vrrp' modifier applied to %s", typestr);
-
-       case Q_CARP:
-               bpf_error(cstate, "'carp' modifier applied to %s", typestr);
-
        case Q_ATALK:
-               bpf_error(cstate, "ATALK host filtering not implemented");
-
-       case Q_AARP:
-               bpf_error(cstate, "AARP host filtering not implemented");
+               bpf_error(cstate, "AppleTalk host filtering not implemented");
 
        case Q_DECNET:
                return gen_dnhostop(cstate, addr, dir);
 
-       case Q_SCA:
-               bpf_error(cstate, "SCA host filtering not implemented");
-
        case Q_LAT:
                bpf_error(cstate, "LAT host filtering not implemented");
 
-       case Q_MOPDL:
-               bpf_error(cstate, "MOPDL host filtering not implemented");
+       case Q_SCA:
+               bpf_error(cstate, "SCA host filtering not implemented");
 
        case Q_MOPRC:
                bpf_error(cstate, "MOPRC host filtering not implemented");
 
+       case Q_MOPDL:
+               bpf_error(cstate, "MOPDL host filtering not implemented");
+
        case Q_IPV6:
                bpf_error(cstate, "'ip6' modifier applied to ip host");
 
@@ -4799,6 +4895,15 @@ gen_host(compiler_state_t *cstate, bpf_u_int32 addr, bpf_u_int32 mask,
        case Q_ESP:
                bpf_error(cstate, "'esp' modifier applied to %s", typestr);
 
+       case Q_PIM:
+               bpf_error(cstate, "'pim' modifier applied to %s", typestr);
+
+       case Q_VRRP:
+               bpf_error(cstate, "'vrrp' modifier applied to %s", typestr);
+
+       case Q_AARP:
+               bpf_error(cstate, "AARP host filtering not implemented");
+
        case Q_ISO:
                bpf_error(cstate, "ISO host filtering not implemented");
 
@@ -4820,9 +4925,33 @@ gen_host(compiler_state_t *cstate, bpf_u_int32 addr, bpf_u_int32 mask,
        case Q_NETBEUI:
                bpf_error(cstate, "'netbeui' modifier applied to %s", typestr);
 
+       case Q_ISIS_L1:
+               bpf_error(cstate, "'l1' modifier applied to %s", typestr);
+
+       case Q_ISIS_L2:
+               bpf_error(cstate, "'l2' modifier applied to %s", typestr);
+
+       case Q_ISIS_IIH:
+               bpf_error(cstate, "'iih' modifier applied to %s", typestr);
+
+       case Q_ISIS_SNP:
+               bpf_error(cstate, "'snp' modifier applied to %s", typestr);
+
+       case Q_ISIS_CSNP:
+               bpf_error(cstate, "'csnp' modifier applied to %s", typestr);
+
+       case Q_ISIS_PSNP:
+               bpf_error(cstate, "'psnp' modifier applied to %s", typestr);
+
+       case Q_ISIS_LSP:
+               bpf_error(cstate, "'lsp' modifier applied to %s", typestr);
+
        case Q_RADIO:
                bpf_error(cstate, "'radio' modifier applied to %s", typestr);
 
+       case Q_CARP:
+               bpf_error(cstate, "'carp' modifier applied to %s", typestr);
+
        default:
                abort();
        }
@@ -4859,88 +4988,109 @@ gen_host6(compiler_state_t *cstate, struct in6_addr *addr,
                bpf_error(cstate, "'arp' modifier applied to ip6 %s", typestr);
 
        case Q_SCTP:
-               bpf_error(cstate, "'sctp' modifier applied to %s", typestr);
+               bpf_error(cstate, "'sctp' modifier applied to ip6 %s", typestr);
 
        case Q_TCP:
-               bpf_error(cstate, "'tcp' modifier applied to %s", typestr);
+               bpf_error(cstate, "'tcp' modifier applied to ip6 %s", typestr);
 
        case Q_UDP:
-               bpf_error(cstate, "'udp' modifier applied to %s", typestr);
+               bpf_error(cstate, "'udp' modifier applied to ip6 %s", typestr);
 
        case Q_ICMP:
-               bpf_error(cstate, "'icmp' modifier applied to %s", typestr);
+               bpf_error(cstate, "'icmp' modifier applied to ip6 %s", typestr);
 
        case Q_IGMP:
-               bpf_error(cstate, "'igmp' modifier applied to %s", typestr);
+               bpf_error(cstate, "'igmp' modifier applied to ip6 %s", typestr);
 
        case Q_IGRP:
-               bpf_error(cstate, "'igrp' modifier applied to %s", typestr);
-
-       case Q_PIM:
-               bpf_error(cstate, "'pim' modifier applied to %s", typestr);
-
-       case Q_VRRP:
-               bpf_error(cstate, "'vrrp' modifier applied to %s", typestr);
-
-       case Q_CARP:
-               bpf_error(cstate, "'carp' modifier applied to %s", typestr);
+               bpf_error(cstate, "'igrp' modifier applied to ip6 %s", typestr);
 
        case Q_ATALK:
-               bpf_error(cstate, "ATALK host filtering not implemented");
-
-       case Q_AARP:
-               bpf_error(cstate, "AARP host filtering not implemented");
+               bpf_error(cstate, "AppleTalk modifier applied to ip6 %s", typestr);
 
        case Q_DECNET:
                bpf_error(cstate, "'decnet' modifier applied to ip6 %s", typestr);
 
-       case Q_SCA:
-               bpf_error(cstate, "SCA host filtering not implemented");
-
        case Q_LAT:
-               bpf_error(cstate, "LAT host filtering not implemented");
+               bpf_error(cstate, "'lat' modifier applied to ip6 %s", typestr);
 
-       case Q_MOPDL:
-               bpf_error(cstate, "MOPDL host filtering not implemented");
+       case Q_SCA:
+               bpf_error(cstate, "'sca' modifier applied to ip6 %s", typestr);
 
        case Q_MOPRC:
-               bpf_error(cstate, "MOPRC host filtering not implemented");
+               bpf_error(cstate, "'moprc' modifier applied to ip6 %s", typestr);
+
+       case Q_MOPDL:
+               bpf_error(cstate, "'mopdl' modifier applied to ip6 %s", typestr);
 
        case Q_IPV6:
                return gen_hostop6(cstate, addr, mask, dir, ETHERTYPE_IPV6, 8, 24);
 
        case Q_ICMPV6:
-               bpf_error(cstate, "'icmp6' modifier applied to %s", typestr);
+               bpf_error(cstate, "'icmp6' modifier applied to ip6 %s", typestr);
 
        case Q_AH:
-               bpf_error(cstate, "'ah' modifier applied to %s", typestr);
+               bpf_error(cstate, "'ah' modifier applied to ip6 %s", typestr);
 
        case Q_ESP:
-               bpf_error(cstate, "'esp' modifier applied to %s", typestr);
+               bpf_error(cstate, "'esp' modifier applied to ip6 %s", typestr);
+
+       case Q_PIM:
+               bpf_error(cstate, "'pim' modifier applied to ip6 %s", typestr);
+
+       case Q_VRRP:
+               bpf_error(cstate, "'vrrp' modifier applied to ip6 %s", typestr);
+
+       case Q_AARP:
+               bpf_error(cstate, "'aarp' modifier applied to ip6 %s", typestr);
 
        case Q_ISO:
-               bpf_error(cstate, "ISO host filtering not implemented");
+               bpf_error(cstate, "'iso' modifier applied to ip6 %s", typestr);
 
        case Q_ESIS:
-               bpf_error(cstate, "'esis' modifier applied to %s", typestr);
+               bpf_error(cstate, "'esis' modifier applied to ip6 %s", typestr);
 
        case Q_ISIS:
-               bpf_error(cstate, "'isis' modifier applied to %s", typestr);
+               bpf_error(cstate, "'isis' modifier applied to ip6 %s", typestr);
 
        case Q_CLNP:
-               bpf_error(cstate, "'clnp' modifier applied to %s", typestr);
+               bpf_error(cstate, "'clnp' modifier applied to ip6 %s", typestr);
 
        case Q_STP:
-               bpf_error(cstate, "'stp' modifier applied to %s", typestr);
+               bpf_error(cstate, "'stp' modifier applied to ip6 %s", typestr);
 
        case Q_IPX:
-               bpf_error(cstate, "IPX host filtering not implemented");
+               bpf_error(cstate, "'ipx' modifier applied to ip6 %s", typestr);
 
        case Q_NETBEUI:
-               bpf_error(cstate, "'netbeui' modifier applied to %s", typestr);
+               bpf_error(cstate, "'netbeui' modifier applied to ip6 %s", typestr);
+
+       case Q_ISIS_L1:
+               bpf_error(cstate, "'l1' modifier applied to ip6 %s", typestr);
+
+       case Q_ISIS_L2:
+               bpf_error(cstate, "'l2' modifier applied to ip6 %s", typestr);
+
+       case Q_ISIS_IIH:
+               bpf_error(cstate, "'iih' modifier applied to ip6 %s", typestr);
+
+       case Q_ISIS_SNP:
+               bpf_error(cstate, "'snp' modifier applied to ip6 %s", typestr);
+
+       case Q_ISIS_CSNP:
+               bpf_error(cstate, "'csnp' modifier applied to ip6 %s", typestr);
+
+       case Q_ISIS_PSNP:
+               bpf_error(cstate, "'psnp' modifier applied to ip6 %s", typestr);
+
+       case Q_ISIS_LSP:
+               bpf_error(cstate, "'lsp' modifier applied to ip6 %s", typestr);
 
        case Q_RADIO:
-               bpf_error(cstate, "'radio' modifier applied to %s", typestr);
+               bpf_error(cstate, "'radio' modifier applied to ip6 %s", typestr);
+
+       case Q_CARP:
+               bpf_error(cstate, "'carp' modifier applied to ip6 %s", typestr);
 
        default:
                abort();
@@ -4951,10 +5101,12 @@ gen_host6(compiler_state_t *cstate, struct in6_addr *addr,
 
 #ifndef INET6
 static struct block *
-gen_gateway(compiler_state_t *cstate, const u_char *eaddr, bpf_u_int32 **alist,
-    int proto, int dir)
+gen_gateway(compiler_state_t *cstate, const u_char *eaddr,
+    struct addrinfo *alist, int proto, int dir)
 {
        struct block *b0, *b1, *tmp;
+       struct addrinfo *ai;
+       struct sockaddr_in *sin;
 
        if (dir != 0)
                bpf_error(cstate, "direction applied to 'gateway'");
@@ -5002,12 +5154,48 @@ gen_gateway(compiler_state_t *cstate, const u_char *eaddr, bpf_u_int32 **alist,
                        bpf_error(cstate,
                            "'gateway' supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel");
                }
-               b1 = gen_host(cstate, **alist++, 0xffffffff, proto, Q_OR, Q_HOST);
-               while (*alist) {
-                       tmp = gen_host(cstate, **alist++, 0xffffffff, proto, Q_OR,
-                           Q_HOST);
-                       gen_or(b1, tmp);
-                       b1 = tmp;
+               b1 = NULL;
+               for (ai = alist; ai != NULL; ai = ai->ai_next) {
+                       /*
+                        * Does it have an address?
+                        */
+                       if (ai->ai_addr != NULL) {
+                               /*
+                                * Yes.  Is it an IPv4 address?
+                                */
+                               if (ai->ai_addr->sa_family == AF_INET) {
+                                       /*
+                                        * Generate an entry for it.
+                                        */
+                                       sin = (struct sockaddr_in *)ai->ai_addr;
+                                       tmp = gen_host(cstate,
+                                           ntohl(sin->sin_addr.s_addr),
+                                           0xffffffff, proto, Q_OR, Q_HOST);
+                                       /*
+                                        * Is it the *first* IPv4 address?
+                                        */
+                                       if (b1 == NULL) {
+                                               /*
+                                                * Yes, so start with it.
+                                                */
+                                               b1 = tmp;
+                                       } else {
+                                               /*
+                                                * No, so OR it into the
+                                                * existing set of
+                                                * addresses.
+                                                */
+                                               gen_or(b1, tmp);
+                                               b1 = tmp;
+                                       }
+                               }
+                       }
+               }
+               if (b1 == NULL) {
+                       /*
+                        * No IPv4 addresses found.
+                        */
+                       return (NULL);
                }
                gen_not(b1);
                gen_and(b0, b1);
@@ -5314,17 +5502,41 @@ gen_portop(compiler_state_t *cstate, int port, int proto, int dir)
                b1 = gen_portatom(cstate, 2, (bpf_int32)port);
                break;
 
-       case Q_OR:
-       case Q_DEFAULT:
+       case Q_AND:
                tmp = gen_portatom(cstate, 0, (bpf_int32)port);
                b1 = gen_portatom(cstate, 2, (bpf_int32)port);
-               gen_or(tmp, b1);
+               gen_and(tmp, b1);
                break;
 
-       case Q_AND:
+       case Q_DEFAULT:
+       case Q_OR:
                tmp = gen_portatom(cstate, 0, (bpf_int32)port);
                b1 = gen_portatom(cstate, 2, (bpf_int32)port);
-               gen_and(tmp, b1);
+               gen_or(tmp, b1);
+               break;
+
+       case Q_ADDR1:
+               bpf_error(cstate, "'addr1' and 'address1' are not valid qualifiers for ports");
+               break;
+
+       case Q_ADDR2:
+               bpf_error(cstate, "'addr2' and 'address2' are not valid qualifiers for ports");
+               break;
+
+       case Q_ADDR3:
+               bpf_error(cstate, "'addr3' and 'address3' are not valid qualifiers for ports");
+               break;
+
+       case Q_ADDR4:
+               bpf_error(cstate, "'addr4' and 'address4' are not valid qualifiers for ports");
+               break;
+
+       case Q_RA:
+               bpf_error(cstate, "'ra' is not a valid qualifier for ports");
+               break;
+
+       case Q_TA:
+               bpf_error(cstate, "'ta' is not a valid qualifier for ports");
                break;
 
        default:
@@ -5399,17 +5611,17 @@ gen_portop6(compiler_state_t *cstate, int port, int proto, int dir)
                b1 = gen_portatom6(cstate, 2, (bpf_int32)port);
                break;
 
-       case Q_OR:
-       case Q_DEFAULT:
+       case Q_AND:
                tmp = gen_portatom6(cstate, 0, (bpf_int32)port);
                b1 = gen_portatom6(cstate, 2, (bpf_int32)port);
-               gen_or(tmp, b1);
+               gen_and(tmp, b1);
                break;
 
-       case Q_AND:
+       case Q_DEFAULT:
+       case Q_OR:
                tmp = gen_portatom6(cstate, 0, (bpf_int32)port);
                b1 = gen_portatom6(cstate, 2, (bpf_int32)port);
-               gen_and(tmp, b1);
+               gen_or(tmp, b1);
                break;
 
        default:
@@ -5496,17 +5708,41 @@ gen_portrangeop(compiler_state_t *cstate, int port1, int port2, int proto,
                b1 = gen_portrangeatom(cstate, 2, (bpf_int32)port1, (bpf_int32)port2);
                break;
 
-       case Q_OR:
-       case Q_DEFAULT:
+       case Q_AND:
                tmp = gen_portrangeatom(cstate, 0, (bpf_int32)port1, (bpf_int32)port2);
                b1 = gen_portrangeatom(cstate, 2, (bpf_int32)port1, (bpf_int32)port2);
-               gen_or(tmp, b1);
+               gen_and(tmp, b1);
                break;
 
-       case Q_AND:
+       case Q_DEFAULT:
+       case Q_OR:
                tmp = gen_portrangeatom(cstate, 0, (bpf_int32)port1, (bpf_int32)port2);
                b1 = gen_portrangeatom(cstate, 2, (bpf_int32)port1, (bpf_int32)port2);
-               gen_and(tmp, b1);
+               gen_or(tmp, b1);
+               break;
+
+       case Q_ADDR1:
+               bpf_error(cstate, "'addr1' and 'address1' are not valid qualifiers for port ranges");
+               break;
+
+       case Q_ADDR2:
+               bpf_error(cstate, "'addr2' and 'address2' are not valid qualifiers for port ranges");
+               break;
+
+       case Q_ADDR3:
+               bpf_error(cstate, "'addr3' and 'address3' are not valid qualifiers for port ranges");
+               break;
+
+       case Q_ADDR4:
+               bpf_error(cstate, "'addr4' and 'address4' are not valid qualifiers for port ranges");
+               break;
+
+       case Q_RA:
+               bpf_error(cstate, "'ra' is not a valid qualifier for port ranges");
+               break;
+
+       case Q_TA:
+               bpf_error(cstate, "'ta' is not a valid qualifier for port ranges");
                break;
 
        default:
@@ -5592,17 +5828,17 @@ gen_portrangeop6(compiler_state_t *cstate, int port1, int port2, int proto,
                b1 = gen_portrangeatom6(cstate, 2, (bpf_int32)port1, (bpf_int32)port2);
                break;
 
-       case Q_OR:
-       case Q_DEFAULT:
+       case Q_AND:
                tmp = gen_portrangeatom6(cstate, 0, (bpf_int32)port1, (bpf_int32)port2);
                b1 = gen_portrangeatom6(cstate, 2, (bpf_int32)port1, (bpf_int32)port2);
-               gen_or(tmp, b1);
+               gen_and(tmp, b1);
                break;
 
-       case Q_AND:
+       case Q_DEFAULT:
+       case Q_OR:
                tmp = gen_portrangeatom6(cstate, 0, (bpf_int32)port1, (bpf_int32)port2);
                b1 = gen_portrangeatom6(cstate, 2, (bpf_int32)port1, (bpf_int32)port2);
-               gen_and(tmp, b1);
+               gen_or(tmp, b1);
                break;
 
        default:
@@ -5689,9 +5925,7 @@ lookup_proto(compiler_state_t *cstate, const char *name, int proto)
 
 #if 0
 struct stmt *
-gen_joinsp(s, n)
-       struct stmt **s;
-       int n;
+gen_joinsp(struct stmt **s, int n)
 {
        return NULL;
 }
@@ -5741,7 +5975,7 @@ gen_protochain(compiler_state_t *cstate, int v, int proto, int dir)
        if (cstate->off_linkpl.is_variable)
                bpf_error(cstate, "'protochain' not supported with variable length headers");
 
-       cstate->no_optimize = 1; /*this code is not compatible with optimzer yet */
+       cstate->no_optimize = 1; /* this code is not compatible with optimizer yet */
 
        /*
         * s[0] is a dummy entry to protect other BPF insn from damage
@@ -6099,13 +6333,13 @@ gen_proto(compiler_state_t *cstate, int v, int proto, int dir)
                         */
                        b0 = gen_linktype(cstate, LLCSAP_ISONS<<8 | LLCSAP_ISONS);
                        /* OSI in C-HDLC is stuffed with a fudge byte */
-                       b1 = gen_cmp(cstate, OR_LINKPL_NOSNAP, 1, BPF_B, (long)v);
+                       b1 = gen_cmp(cstate, OR_LINKPL_NOSNAP, 1, BPF_B, (bpf_int32)v);
                        gen_and(b0, b1);
                        return b1;
 
                default:
                        b0 = gen_linktype(cstate, LLCSAP_ISONS);
-                       b1 = gen_cmp(cstate, OR_LINKPL_NOSNAP, 0, BPF_B, (long)v);
+                       b1 = gen_cmp(cstate, OR_LINKPL_NOSNAP, 0, BPF_B, (bpf_int32)v);
                        gen_and(b0, b1);
                        return b1;
                }
@@ -6116,7 +6350,7 @@ gen_proto(compiler_state_t *cstate, int v, int proto, int dir)
                 * 4 is the offset of the PDU type relative to the IS-IS
                 * header.
                 */
-               b1 = gen_cmp(cstate, OR_LINKPL_NOSNAP, 4, BPF_B, (long)v);
+               b1 = gen_cmp(cstate, OR_LINKPL_NOSNAP, 4, BPF_B, (bpf_int32)v);
                gen_and(b0, b1);
                return b1;
 
@@ -6245,13 +6479,11 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
        int tproto;
        u_char *eaddr;
        bpf_u_int32 mask, addr;
-#ifndef INET6
-       bpf_u_int32 **alist;
-#else
-       int tproto6;
+       struct addrinfo *res, *res0;
        struct sockaddr_in *sin4;
+#ifdef INET6
+       int tproto6;
        struct sockaddr_in6 *sin6;
-       struct addrinfo *res, *res0;
        struct in6_addr mask128;
 #endif /*INET6*/
        struct block *b, *tmp;
@@ -6350,46 +6582,39 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
                         */
                        return (gen_host(cstate, dn_addr, 0, proto, dir, q.addr));
                } else {
-#ifndef INET6
-                       alist = pcap_nametoaddr(name);
-                       if (alist == NULL || *alist == NULL)
-                               bpf_error(cstate, "unknown host '%s'", name);
-                       tproto = proto;
-                       if (cstate->off_linktype.constant_part == OFFSET_NOT_SET &&
-                           tproto == Q_DEFAULT)
-                               tproto = Q_IP;
-                       b = gen_host(cstate, **alist++, 0xffffffff, tproto, dir, q.addr);
-                       while (*alist) {
-                               tmp = gen_host(cstate, **alist++, 0xffffffff,
-                                              tproto, dir, q.addr);
-                               gen_or(b, tmp);
-                               b = tmp;
-                       }
-                       return b;
-#else
+#ifdef INET6
                        memset(&mask128, 0xff, sizeof(mask128));
+#endif
                        res0 = res = pcap_nametoaddrinfo(name);
                        if (res == NULL)
                                bpf_error(cstate, "unknown host '%s'", name);
                        cstate->ai = res;
                        b = tmp = NULL;
-                       tproto = tproto6 = proto;
+                       tproto = proto;
+#ifdef INET6
+                       tproto6 = proto;
+#endif
                        if (cstate->off_linktype.constant_part == OFFSET_NOT_SET &&
                            tproto == Q_DEFAULT) {
                                tproto = Q_IP;
+#ifdef INET6
                                tproto6 = Q_IPV6;
+#endif
                        }
                        for (res = res0; res; res = res->ai_next) {
                                switch (res->ai_family) {
                                case AF_INET:
+#ifdef INET6
                                        if (tproto == Q_IPV6)
                                                continue;
+#endif
 
                                        sin4 = (struct sockaddr_in *)
                                                res->ai_addr;
                                        tmp = gen_host(cstate, ntohl(sin4->sin_addr.s_addr),
                                                0xffffffff, tproto, dir, q.addr);
                                        break;
+#ifdef INET6
                                case AF_INET6:
                                        if (tproto6 == Q_IP)
                                                continue;
@@ -6399,6 +6624,7 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
                                        tmp = gen_host6(cstate, &sin6->sin6_addr,
                                                &mask128, tproto6, dir, q.addr);
                                        break;
+#endif
                                default:
                                        continue;
                                }
@@ -6415,7 +6641,6 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
                                        : " for specified address family");
                        }
                        return b;
-#endif /*INET6*/
                }
 
        case Q_PORT:
@@ -6513,11 +6738,15 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
                if (eaddr == NULL)
                        bpf_error(cstate, "unknown ether host: %s", name);
 
-               alist = pcap_nametoaddr(name);
-               if (alist == NULL || *alist == NULL)
+               res = pcap_nametoaddrinfo(name);
+               cstate->ai = res;
+               if (res == NULL)
+                       bpf_error(cstate, "unknown host '%s'", name);
+               b = gen_gateway(cstate, eaddr, res, proto, dir);
+               cstate->ai = NULL;
+               freeaddrinfo(res);
+               if (b == NULL)
                        bpf_error(cstate, "unknown host '%s'", name);
-               b = gen_gateway(cstate, eaddr, alist, proto, dir);
-               free(eaddr);
                return b;
 #else
                bpf_error(cstate, "'gateway' not supported in this configuration");
@@ -6590,7 +6819,6 @@ gen_mcode(compiler_state_t *cstate, const char *s1, const char *s2,
                /* NOTREACHED */
        }
        /* NOTREACHED */
-       return NULL;
 }
 
 struct block *
@@ -6709,7 +6937,7 @@ gen_mcode6(compiler_state_t *cstate, const char *s1, const char *s2,
        struct in6_addr *addr;
        struct in6_addr mask;
        struct block *b;
-       u_int32_t *a, *m;
+       uint32_t *a, *m;
 
        if (s2)
                bpf_error(cstate, "no mask %s supported", s2);
@@ -6731,8 +6959,8 @@ gen_mcode6(compiler_state_t *cstate, const char *s1, const char *s2,
                        (0xff << (8 - masklen % 8)) & 0xff;
        }
 
-       a = (u_int32_t *)addr;
-       m = (u_int32_t *)&mask;
+       a = (uint32_t *)addr;
+       m = (uint32_t *)&mask;
        if ((a[0] & ~m[0]) || (a[1] & ~m[1])
         || (a[2] & ~m[2]) || (a[3] & ~m[3])) {
                bpf_error(cstate, "non-network bits set in \"%s/%d\"", s1, masklen);
@@ -6756,50 +6984,60 @@ gen_mcode6(compiler_state_t *cstate, const char *s1, const char *s2,
                bpf_error(cstate, "invalid qualifier against IPv6 address");
                /* NOTREACHED */
        }
-       return NULL;
 }
 #endif /*INET6*/
 
 struct block *
-gen_ecode(compiler_state_t *cstate, const u_char *eaddr, struct qual q)
+gen_ecode(compiler_state_t *cstate, const char *s, struct qual q)
 {
        struct block *b, *tmp;
 
        if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) {
+               cstate->e = pcap_ether_aton(s);
+               if (cstate->e == NULL)
+                       bpf_error(cstate, "malloc");
                switch (cstate->linktype) {
                case DLT_EN10MB:
                case DLT_NETANALYZER:
                case DLT_NETANALYZER_TRANSPARENT:
                        tmp = gen_prevlinkhdr_check(cstate);
-                       b = gen_ehostop(cstate, eaddr, (int)q.dir);
+                       b = gen_ehostop(cstate, cstate->e, (int)q.dir);
                        if (tmp != NULL)
                                gen_and(tmp, b);
-                       return b;
+                       break;
                case DLT_FDDI:
-                       return gen_fhostop(cstate, eaddr, (int)q.dir);
+                       b = gen_fhostop(cstate, cstate->e, (int)q.dir);
+                       break;
                case DLT_IEEE802:
-                       return gen_thostop(cstate, eaddr, (int)q.dir);
+                       b = gen_thostop(cstate, cstate->e, (int)q.dir);
+                       break;
                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(cstate, eaddr, (int)q.dir);
+                       b = gen_wlanhostop(cstate, cstate->e, (int)q.dir);
+                       break;
                case DLT_IP_OVER_FC:
-                       return gen_ipfchostop(cstate, eaddr, (int)q.dir);
+                       b = gen_ipfchostop(cstate, cstate->e, (int)q.dir);
+                       break;
                default:
+                       free(cstate->e);
+                       cstate->e = NULL;
                        bpf_error(cstate, "ethernet addresses supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel");
+                       /* NOTREACHED */
                        break;
                }
+               free(cstate->e);
+               cstate->e = NULL;
+               return (b);
        }
        bpf_error(cstate, "ethernet address used in non-ether expression");
        /* NOTREACHED */
-       return NULL;
 }
 
 void
-sappend(s0, s1)
-       struct slist *s0, *s1;
+sappend(struct slist *s0, struct slist *s1)
 {
        /*
         * This is definitely not the best way to do this, but the
@@ -7049,8 +7287,58 @@ gen_load(compiler_state_t *cstate, int proto, struct arth *inst, int size)
                inst->b = b;
                break;
        case Q_ICMPV6:
-               bpf_error(cstate, "IPv6 upper-layer protocol is not supported by proto[x]");
-               /*NOTREACHED*/
+        /*
+        * Do the computation only if the packet contains
+        * the protocol in question.
+        */
+        b = gen_proto_abbrev(cstate, Q_IPV6);
+        if (inst->b) {
+            gen_and(inst->b, b);
+        }
+        inst->b = b;
+
+        /*
+        * Check if we have an icmp6 next header
+        */
+        b = gen_cmp(cstate, OR_LINKPL, 6, BPF_B, 58);
+        if (inst->b) {
+            gen_and(inst->b, b);
+        }
+        inst->b = b;
+
+
+        s = gen_abs_offset_varpart(cstate, &cstate->off_linkpl);
+        /*
+        * If "s" is non-null, it has code to arrange that the
+        * X register contains the variable part of the offset
+        * of the link-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 specified by "index".
+        */
+        if (s != NULL) {
+            sappend(s, xfer_to_a(cstate, inst));
+            sappend(s, new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_X));
+            sappend(s, new_stmt(cstate, BPF_MISC|BPF_TAX));
+        } else {
+            s = xfer_to_x(cstate, inst);
+        }
+
+        /*
+        * 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 from the beginning of the link-layer
+        * payload, and the constant part of the offset of the
+        * start of the link-layer payload.
+        */
+        tmp = new_stmt(cstate, BPF_LD|BPF_IND|size);
+        tmp->s.k = cstate->off_linkpl.constant_part + cstate->off_nl + 40;
+
+        sappend(s, tmp);
+        sappend(inst->s, s);
+
+        break;
        }
        inst->regno = regno;
        s = new_stmt(cstate, BPF_ST);
@@ -7167,6 +7455,9 @@ gen_arth(compiler_state_t *cstate, int code, struct arth *a0,
        /*
         * Disallow division by, or modulus by, zero; we do this here
         * so that it gets done even if the optimizer is disabled.
+        *
+        * Also disallow shifts by a value greater than 31; we do this
+        * here, for the same reason.
         */
        if (code == BPF_DIV) {
                if (a1->s->s.code == (BPF_LD|BPF_IMM) && a1->s->s.k == 0)
@@ -7174,6 +7465,15 @@ gen_arth(compiler_state_t *cstate, int code, struct arth *a0,
        } else if (code == BPF_MOD) {
                if (a1->s->s.code == (BPF_LD|BPF_IMM) && a1->s->s.k == 0)
                        bpf_error(cstate, "modulus by zero");
+       } else if (code == BPF_LSH || code == BPF_RSH) {
+               /*
+                * XXX - we need to make up our minds as to what integers
+                * are signed and what integers are unsigned in BPF programs
+                * and in our IR.
+                */
+               if (a1->s->s.code == (BPF_LD|BPF_IMM) &&
+                   (a1->s->s.k < 0 || a1->s->s.k > 31))
+                       bpf_error(cstate, "shift by more than 31 bits");
        }
        s0 = xfer_to_x(cstate, a1);
        s1 = xfer_to_a(cstate, a0);
@@ -7222,7 +7522,6 @@ alloc_reg(compiler_state_t *cstate)
        }
        bpf_error(cstate, "too many registers needed to evaluate expression");
        /* NOTREACHED */
-       return 0;
 }
 
 /*
@@ -7377,7 +7676,6 @@ gen_broadcast(compiler_state_t *cstate, int proto)
        }
        bpf_error(cstate, "only link-layer/IP broadcast filters supported");
        /* NOTREACHED */
-       return NULL;
 }
 
 /*
@@ -7573,7 +7871,6 @@ gen_multicast(compiler_state_t *cstate, int proto)
        }
        bpf_error(cstate, "link-layer multicast filters supported only on ethernet/FDDI/token ring/ARCNET/802.11/ATM LANE/Fibre Channel");
        /* NOTREACHED */
-       return NULL;
 }
 
 /*
@@ -7620,6 +7917,15 @@ gen_inbound(compiler_state_t *cstate, int dir)
                }
                break;
 
+       case DLT_LINUX_SLL2:
+               /* match outgoing packets */
+               b0 = gen_cmp(cstate, OR_LINKHDR, 10, BPF_B, LINUX_SLL_OUTGOING);
+               if (!dir) {
+                       /* to filter on inbound traffic, invert the match */
+                       gen_not(b0);
+               }
+               break;
+
 #ifdef HAVE_NET_PFVAR_H
        case DLT_PFLOG:
                b0 = gen_cmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, dir), BPF_B,
@@ -7674,8 +7980,18 @@ gen_inbound(compiler_state_t *cstate, int dir)
        default:
                /*
                 * If we have packet meta-data indicating a direction,
-                * check it, otherwise give up as this link-layer type
-                * has nothing in the packet data.
+                * and that metadata can be checked by BPF code, check
+                * it.  Otherwise, give up, as this link-layer type has
+                * nothing in the packet data.
+                *
+                * Currently, the only platform where a BPF filter can
+                * check that metadata is Linux with the in-kernel
+                * BPF interpreter.  If other packet capture mechanisms
+                * and BPF filters also supported this, it would be
+                * nice.  It would be even better if they made that
+                * metadata available so that we could provide it
+                * with newer capture APIs, allowing it to be saved
+                * in pcapng files.
                 */
 #if defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER)
                /*
@@ -7701,7 +8017,6 @@ gen_inbound(compiler_state_t *cstate, int dir)
 #else /* defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */
                bpf_error(cstate, "inbound/outbound not supported on linktype %d",
                    cstate->linktype);
-               b0 = NULL;
                /* NOTREACHED */
 #endif /* defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */
        }
@@ -7818,51 +8133,45 @@ gen_pf_action(compiler_state_t *cstate, int action)
 }
 #else /* !HAVE_NET_PFVAR_H */
 struct block *
-gen_pf_ifname(compiler_state_t *cstate, const char *ifname)
+gen_pf_ifname(compiler_state_t *cstate, const char *ifname _U_)
 {
        bpf_error(cstate, "libpcap was compiled without pf support");
        /* NOTREACHED */
-       return (NULL);
 }
 
 struct block *
-gen_pf_ruleset(compiler_state_t *cstate, char *ruleset)
+gen_pf_ruleset(compiler_state_t *cstate, char *ruleset _U_)
 {
        bpf_error(cstate, "libpcap was compiled on a machine without pf support");
        /* NOTREACHED */
-       return (NULL);
 }
 
 struct block *
-gen_pf_rnr(compiler_state_t *cstate, int rnr)
+gen_pf_rnr(compiler_state_t *cstate, int rnr _U_)
 {
        bpf_error(cstate, "libpcap was compiled on a machine without pf support");
        /* NOTREACHED */
-       return (NULL);
 }
 
 struct block *
-gen_pf_srnr(compiler_state_t *cstate, int srnr)
+gen_pf_srnr(compiler_state_t *cstate, int srnr _U_)
 {
        bpf_error(cstate, "libpcap was compiled on a machine without pf support");
        /* NOTREACHED */
-       return (NULL);
 }
 
 struct block *
-gen_pf_reason(compiler_state_t *cstate, int reason)
+gen_pf_reason(compiler_state_t *cstate, int reason _U_)
 {
        bpf_error(cstate, "libpcap was compiled on a machine without pf support");
        /* NOTREACHED */
-       return (NULL);
 }
 
 struct block *
-gen_pf_action(compiler_state_t *cstate, int action)
+gen_pf_action(compiler_state_t *cstate, int action _U_)
 {
        bpf_error(cstate, "libpcap was compiled on a machine without pf support");
        /* NOTREACHED */
-       return (NULL);
 }
 #endif /* HAVE_NET_PFVAR_H */
 
@@ -7915,16 +8224,24 @@ gen_p80211_fcdir(compiler_state_t *cstate, int fcdir)
 }
 
 struct block *
-gen_acode(compiler_state_t *cstate, const u_char *eaddr, struct qual q)
+gen_acode(compiler_state_t *cstate, const char *s, struct qual q)
 {
+       struct block *b;
+
        switch (cstate->linktype) {
 
        case DLT_ARCNET:
        case DLT_ARCNET_LINUX:
                if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) &&
-                   q.proto == Q_LINK)
-                       return (gen_ahostop(cstate, eaddr, (int)q.dir));
-               else {
+                   q.proto == Q_LINK) {
+                       cstate->e = pcap_ether_aton(s);
+                       if (cstate->e == NULL)
+                               bpf_error(cstate, "malloc");
+                       b = gen_ahostop(cstate, cstate->e, (int)q.dir);
+                       free(cstate->e);
+                       cstate->e = NULL;
+                       return (b);
+               } else {
                        bpf_error(cstate, "ARCnet address used in non-arc expression");
                        /* NOTREACHED */
                }
@@ -7934,9 +8251,6 @@ gen_acode(compiler_state_t *cstate, const u_char *eaddr, struct qual q)
                bpf_error(cstate, "aid supported only on ARCnet");
                /* NOTREACHED */
        }
-       bpf_error(cstate, "ARCnet address used in non-arc expression");
-       /* NOTREACHED */
-       return NULL;
 }
 
 static struct block *
@@ -7966,19 +8280,19 @@ gen_ahostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
                return b1;
 
        case Q_ADDR1:
-               bpf_error(cstate, "'addr1' is only supported on 802.11");
+               bpf_error(cstate, "'addr1' and 'address1' are only supported on 802.11");
                break;
 
        case Q_ADDR2:
-               bpf_error(cstate, "'addr2' is only supported on 802.11");
+               bpf_error(cstate, "'addr2' and 'address2' are only supported on 802.11");
                break;
 
        case Q_ADDR3:
-               bpf_error(cstate, "'addr3' is only supported on 802.11");
+               bpf_error(cstate, "'addr3' and 'address3' are only supported on 802.11");
                break;
 
        case Q_ADDR4:
-               bpf_error(cstate, "'addr4' is only supported on 802.11");
+               bpf_error(cstate, "'addr4' and 'address4' are only supported on 802.11");
                break;
 
        case Q_RA:
@@ -8038,7 +8352,7 @@ gen_vlan_no_bpf_extensions(compiler_state_t *cstate, int vlan_num)
        return b0;
 }
 
-#if defined(SKF_AD_VLAN_TAG) && defined(SKF_AD_VLAN_TAG_PRESENT)
+#if defined(SKF_AD_VLAN_TAG_PRESENT)
 /* add v to variable part of off */
 static void
 gen_vlan_vloffset_add(compiler_state_t *cstate, bpf_abs_offset *off, int v, struct slist *s)
@@ -8105,12 +8419,15 @@ gen_vlan_patch_vid_test(compiler_state_t *cstate, struct block *b_vid)
        sappend(s, s2);
        sjeq->s.jt = s2;
 
-       /* jump to the test in b_vid (bypass loading VID from packet data) */
+       /* Jump to the test in b_vid. We need to jump one instruction before
+        * the end of the b_vid block so that we only skip loading the TCI
+        * from packet data and not the 'and' instruction extractging VID.
+        */
        cnt = 0;
        for (s2 = b_vid->stmts; s2; s2 = s2->next)
                cnt++;
        s2 = new_stmt(cstate, JMP(BPF_JA));
-       s2->s.k = cnt;
+       s2->s.k = cnt - 1;
        sappend(s, s2);
 
        /* insert our statements at the beginning of b_vid */
@@ -8129,7 +8446,7 @@ gen_vlan_patch_vid_test(compiler_state_t *cstate, struct block *b_vid)
 static struct block *
 gen_vlan_bpf_extensions(compiler_state_t *cstate, int vlan_num)
 {
-        struct block *b0, *b_tpid, *b_vid;
+        struct block *b0, *b_tpid, *b_vid = NULL;
         struct slist *s;
 
         /* generate new filter code based on extracting packet
@@ -8217,7 +8534,7 @@ gen_vlan(compiler_state_t *cstate, int vlan_num)
        case DLT_EN10MB:
        case DLT_NETANALYZER:
        case DLT_NETANALYZER_TRANSPARENT:
-#if defined(SKF_AD_VLAN_TAG) && defined(SKF_AD_VLAN_TAG_PRESENT)
+#if defined(SKF_AD_VLAN_TAG_PRESENT)
                /* Verify that this is the outer part of the packet and
                 * not encapsulated somehow. */
                if (cstate->vlan_stack_depth == 0 && !cstate->off_linkhdr.is_variable &&
@@ -8257,7 +8574,7 @@ gen_vlan(compiler_state_t *cstate, int vlan_num)
  * support for MPLS
  */
 struct block *
-gen_mpls(compiler_state_t *cstate, int label_num)
+gen_mpls(compiler_state_t *cstate, bpf_u_int32 label_num, int has_label_num)
 {
        struct  block   *b0, *b1;
 
@@ -8289,14 +8606,17 @@ gen_mpls(compiler_state_t *cstate, int label_num)
             default:
                     bpf_error(cstate, "no MPLS support for data link type %d",
                           cstate->linktype);
-                    b0 = NULL;
                     /*NOTREACHED*/
                     break;
             }
         }
 
        /* If a specific MPLS label is requested, check it */
-       if (label_num >= 0) {
+       if (has_label_num) {
+               if (label_num > 0xFFFFF) {
+                       bpf_error(cstate, "MPLS label %u greater than maximum %u",
+                           label_num, 0xFFFFF);
+               }
                label_num = label_num << 12; /* label is shifted 12 bits on the wire */
                b1 = gen_mcmp(cstate, OR_LINKPL, 0, BPF_W, (bpf_int32)label_num,
                    0xfffff000); /* only compare the first 20 bits */
@@ -8710,7 +9030,7 @@ gen_atmfield_code(compiler_state_t *cstate, int atmfield, bpf_int32 jvalue,
        case A_VPI:
                if (!cstate->is_atm)
                        bpf_error(cstate, "'vpi' supported only on raw ATM");
-               if (cstate->off_vpi == (u_int)-1)
+               if (cstate->off_vpi == OFFSET_NOT_SET)
                        abort();
                b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_vpi, BPF_B, 0xffffffff, jtype,
                    reverse, jvalue);
@@ -8719,21 +9039,21 @@ gen_atmfield_code(compiler_state_t *cstate, int atmfield, bpf_int32 jvalue,
        case A_VCI:
                if (!cstate->is_atm)
                        bpf_error(cstate, "'vci' supported only on raw ATM");
-               if (cstate->off_vci == (u_int)-1)
+               if (cstate->off_vci == OFFSET_NOT_SET)
                        abort();
                b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_vci, BPF_H, 0xffffffff, jtype,
                    reverse, jvalue);
                break;
 
        case A_PROTOTYPE:
-               if (cstate->off_proto == (u_int)-1)
+               if (cstate->off_proto == OFFSET_NOT_SET)
                        abort();        /* XXX - this isn't on FreeBSD */
                b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_proto, BPF_B, 0x0f, jtype,
                    reverse, jvalue);
                break;
 
        case A_MSGTYPE:
-               if (cstate->off_payload == (u_int)-1)
+               if (cstate->off_payload == OFFSET_NOT_SET)
                        abort();
                b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_payload + MSG_TYPE_POS, BPF_B,
                    0xffffffff, jtype, reverse, jvalue);
@@ -8742,7 +9062,7 @@ gen_atmfield_code(compiler_state_t *cstate, int atmfield, bpf_int32 jvalue,
        case A_CALLREFTYPE:
                if (!cstate->is_atm)
                        bpf_error(cstate, "'callref' supported only on raw ATM");
-               if (cstate->off_proto == (u_int)-1)
+               if (cstate->off_proto == OFFSET_NOT_SET)
                        abort();
                b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_proto, BPF_B, 0xffffffff,
                    jtype, reverse, jvalue);
@@ -8944,7 +9264,7 @@ gen_mtp3field_code(compiler_state_t *cstate, int mtp3field, bpf_u_int32 jvalue,
                /* FALLTHROUGH */
 
        case M_SIO:
-               if (cstate->off_sio == (u_int)-1)
+               if (cstate->off_sio == OFFSET_NOT_SET)
                        bpf_error(cstate, "'sio' supported only on SS7");
                /* sio coded on 1 byte so max value 255 */
                if(jvalue > 255)
@@ -8957,7 +9277,7 @@ gen_mtp3field_code(compiler_state_t *cstate, int mtp3field, bpf_u_int32 jvalue,
        case MH_OPC:
                newoff_opc+=3;
         case M_OPC:
-               if (cstate->off_opc == (u_int)-1)
+               if (cstate->off_opc == OFFSET_NOT_SET)
                        bpf_error(cstate, "'opc' supported only on SS7");
                /* opc coded on 14 bits so max value 16383 */
                if (jvalue > 16383)
@@ -8981,7 +9301,7 @@ gen_mtp3field_code(compiler_state_t *cstate, int mtp3field, bpf_u_int32 jvalue,
                /* FALLTHROUGH */
 
        case M_DPC:
-               if (cstate->off_dpc == (u_int)-1)
+               if (cstate->off_dpc == OFFSET_NOT_SET)
                        bpf_error(cstate, "'dpc' supported only on SS7");
                /* dpc coded on 14 bits so max value 16383 */
                if (jvalue > 16383)
@@ -9001,7 +9321,7 @@ gen_mtp3field_code(compiler_state_t *cstate, int mtp3field, bpf_u_int32 jvalue,
        case MH_SLS:
          newoff_sls+=3;
        case M_SLS:
-               if (cstate->off_sls == (u_int)-1)
+               if (cstate->off_sls == OFFSET_NOT_SET)
                        bpf_error(cstate, "'sls' supported only on SS7");
                /* sls coded on 4 bits so max value 15 */
                if (jvalue > 15)