]> The Tcpdump Group git mirrors - libpcap/blobdiff - gencode.c
Fix building without protochain support. (GH #852)
[libpcap] / gencode.c
index 8c5e281c8fc4da32fadf723782d992b41d070b4d..ea272e17649aff9c1123b88d8f0c01ec76f55067 100644 (file)
--- a/gencode.c
+++ b/gencode.c
@@ -1,4 +1,3 @@
-/*#define CHASE_CHAIN*/
 /*
  * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
  *     The Regents of the University of California.  All rights reserved.
@@ -41,6 +40,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <memory.h>
+#include <setjmp.h>
 #include <stdarg.h>
 
 #ifdef MSDOS
 #include "ieee80211.h"
 #include "atmuni31.h"
 #include "sunatmpos.h"
+#include "pflog.h"
 #include "ppp.h"
 #include "pcap/sll.h"
 #include "pcap/ipnet.h"
 #include "arcnet.h"
+#include "diag-control.h"
 
-#include "grammar.h"
 #include "scanner.h"
 
-#if defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER)
+#if defined(linux)
 #include <linux/types.h>
 #include <linux/if_packet.h>
 #include <linux/filter.h>
 #endif
 
-#ifdef HAVE_NET_PFVAR_H
-#include <sys/socket.h>
-#include <net/if.h>
-#include <net/pfvar.h>
-#include <net/if_pflog.h>
-#endif
-
 #ifndef offsetof
 #define offsetof(s, e) ((size_t)&((s *)0)->e)
 #endif
@@ -138,10 +132,6 @@ struct addrinfo {
 
 #define ETHERMTU       1500
 
-#ifndef ETHERTYPE_TEB
-#define ETHERTYPE_TEB 0x6558
-#endif
-
 #ifndef IPPROTO_HOPOPTS
 #define IPPROTO_HOPOPTS 0
 #endif
@@ -173,13 +163,13 @@ struct addrinfo {
  */
 #define PUSH_LINKHDR(cs, new_linktype, new_is_variable, new_constant_part, new_reg) \
 { \
-       (cs)->cgstate->prevlinktype = (cs)->cgstate->linktype; \
-       (cs)->cgstate->off_prevlinkhdr = (cs)->cgstate->off_linkhdr; \
-       (cs)->cgstate->linktype = (new_linktype); \
-       (cs)->cgstate->off_linkhdr.is_variable = (new_is_variable); \
-       (cs)->cgstate->off_linkhdr.constant_part = (new_constant_part); \
-       (cs)->cgstate->off_linkhdr.reg = (new_reg); \
-       (cs)->cgstate->is_geneve = 0; \
+       (cs)->prevlinktype = (cs)->linktype; \
+       (cs)->off_prevlinkhdr = (cs)->off_linkhdr; \
+       (cs)->linktype = (new_linktype); \
+       (cs)->off_linkhdr.is_variable = (new_is_variable); \
+       (cs)->off_linkhdr.constant_part = (new_constant_part); \
+       (cs)->off_linkhdr.reg = (new_reg); \
+       (cs)->is_geneve = 0; \
 }
 
 /*
@@ -244,7 +234,11 @@ struct chunk {
 
 /* Code generator state */
 
-struct _codegen_state {
+struct _compiler_state {
+       jmp_buf top_ctx;
+       pcap_t *bpf_pcap;
+       int error_set;
+
        struct icode ic;
 
        int snaplen;
@@ -422,34 +416,64 @@ struct _codegen_state {
        int cur_chunk;
 };
 
-void PCAP_NORETURN
-bpf_parser_error(compiler_state_t *cstate, const char *msg)
+/*
+ * For use by routines outside this file.
+ */
+/* VARARGS */
+void
+bpf_set_error(compiler_state_t *cstate, const char *fmt, ...)
 {
-       bpf_error(cstate, "can't parse filter expression: %s", msg);
-       /* NOTREACHED */
+       va_list ap;
+
+       /*
+        * If we've already set an error, don't override it.
+        * The lexical analyzer reports some errors by setting
+        * the error and then returning a LEX_ERROR token, which
+        * is not recognized by any grammar rule, and thus forces
+        * the parse to stop.  We don't want the error reported
+        * by the lexical analyzer to be overwritten by the syntax
+        * error.
+        */
+       if (!cstate->error_set) {
+               va_start(ap, fmt);
+               (void)vsnprintf(cstate->bpf_pcap->errbuf, PCAP_ERRBUF_SIZE,
+                   fmt, ap);
+               va_end(ap);
+               cstate->error_set = 1;
+       }
 }
 
+/*
+ * For use *ONLY* in routines in this file.
+ */
+static void PCAP_NORETURN bpf_error(compiler_state_t *, const char *, ...)
+    PCAP_PRINTFLIKE(2, 3);
+
 /* VARARGS */
-void PCAP_NORETURN
+static void PCAP_NORETURN
 bpf_error(compiler_state_t *cstate, const char *fmt, ...)
 {
        va_list ap;
 
        va_start(ap, fmt);
-       (void)pcap_vsnprintf(cstate->bpf_pcap->errbuf, PCAP_ERRBUF_SIZE,
+       (void)vsnprintf(cstate->bpf_pcap->errbuf, PCAP_ERRBUF_SIZE,
            fmt, ap);
        va_end(ap);
        longjmp(cstate->top_ctx, 1);
-       /* NOTREACHED */
+       /*NOTREACHED*/
+#ifdef _AIX
+       PCAP_UNREACHABLE
+#endif /* _AIX */
 }
 
-static void init_linktype(compiler_state_t *, pcap_t *);
+static int init_linktype(compiler_state_t *, pcap_t *);
 
 static void init_regs(compiler_state_t *);
 static int alloc_reg(compiler_state_t *);
 static void free_reg(compiler_state_t *, int);
 
 static void initchunks(compiler_state_t *cstate);
+static void *newchunk_nolongjmp(compiler_state_t *cstate, size_t);
 static void *newchunk(compiler_state_t *cstate, size_t);
 static void freechunks(compiler_state_t *cstate);
 static inline struct block *new_block(compiler_state_t *cstate, int);
@@ -460,21 +484,21 @@ static inline void syntax(compiler_state_t *cstate);
 static void backpatch(struct block *, struct block *);
 static void merge(struct block *, struct block *);
 static struct block *gen_cmp(compiler_state_t *, enum e_offrel, u_int,
-    u_int, bpf_int32);
+    u_int, bpf_u_int32);
 static struct block *gen_cmp_gt(compiler_state_t *, enum e_offrel, u_int,
-    u_int, bpf_int32);
+    u_int, bpf_u_int32);
 static struct block *gen_cmp_ge(compiler_state_t *, enum e_offrel, u_int,
-    u_int, bpf_int32);
+    u_int, bpf_u_int32);
 static struct block *gen_cmp_lt(compiler_state_t *, enum e_offrel, u_int,
-    u_int, bpf_int32);
+    u_int, bpf_u_int32);
 static struct block *gen_cmp_le(compiler_state_t *, enum e_offrel, u_int,
-    u_int, bpf_int32);
+    u_int, bpf_u_int32);
 static struct block *gen_mcmp(compiler_state_t *, enum e_offrel, u_int,
-    u_int, bpf_int32, bpf_u_int32);
+    u_int, bpf_u_int32, bpf_u_int32);
 static struct block *gen_bcmp(compiler_state_t *, enum e_offrel, u_int,
     u_int, const u_char *);
-static struct block *gen_ncmp(compiler_state_t *, enum e_offrel, bpf_u_int32,
-    bpf_u_int32, bpf_u_int32, bpf_u_int32, int, bpf_int32);
+static struct block *gen_ncmp(compiler_state_t *, enum e_offrel, u_int,
+    u_int, bpf_u_int32, int, int, bpf_u_int32);
 static struct slist *gen_load_absoffsetrel(compiler_state_t *, bpf_abs_offset *,
     u_int, u_int);
 static struct slist *gen_load_a(compiler_state_t *, enum e_offrel, u_int,
@@ -483,9 +507,10 @@ static struct slist *gen_loadx_iphdrlen(compiler_state_t *);
 static struct block *gen_uncond(compiler_state_t *, int);
 static inline struct block *gen_true(compiler_state_t *);
 static inline struct block *gen_false(compiler_state_t *);
-static struct block *gen_ether_linktype(compiler_state_t *, int);
-static struct block *gen_ipnet_linktype(compiler_state_t *, int);
-static struct block *gen_linux_sll_linktype(compiler_state_t *, int);
+static struct block *gen_ether_linktype(compiler_state_t *, bpf_u_int32);
+static struct block *gen_ipnet_linktype(compiler_state_t *, bpf_u_int32);
+static struct block *gen_linux_sll_linktype(compiler_state_t *, bpf_u_int32);
+static struct slist *gen_load_pflog_llprefixlen(compiler_state_t *);
 static struct slist *gen_load_prism_llprefixlen(compiler_state_t *);
 static struct slist *gen_load_avs_llprefixlen(compiler_state_t *);
 static struct slist *gen_load_radiotap_llprefixlen(compiler_state_t *);
@@ -493,15 +518,15 @@ static struct slist *gen_load_ppi_llprefixlen(compiler_state_t *);
 static void insert_compute_vloffsets(compiler_state_t *, struct block *);
 static struct slist *gen_abs_offset_varpart(compiler_state_t *,
     bpf_abs_offset *);
-static int ethertype_to_ppptype(int);
-static struct block *gen_linktype(compiler_state_t *, int);
+static bpf_u_int32 ethertype_to_ppptype(bpf_u_int32);
+static struct block *gen_linktype(compiler_state_t *, bpf_u_int32);
 static struct block *gen_snap(compiler_state_t *, bpf_u_int32, bpf_u_int32);
-static struct block *gen_llc_linktype(compiler_state_t *, int);
+static struct block *gen_llc_linktype(compiler_state_t *, bpf_u_int32);
 static struct block *gen_hostop(compiler_state_t *, bpf_u_int32, bpf_u_int32,
-    int, int, u_int, u_int);
+    int, bpf_u_int32, u_int, u_int);
 #ifdef INET6
 static struct block *gen_hostop6(compiler_state_t *, struct in6_addr *,
-    struct in6_addr *, int, int, u_int, u_int);
+    struct in6_addr *, int, bpf_u_int32, u_int, u_int);
 #endif
 static struct block *gen_ahostop(compiler_state_t *, const u_char *, int);
 static struct block *gen_ehostop(compiler_state_t *, const u_char *, int);
@@ -510,7 +535,7 @@ static struct block *gen_thostop(compiler_state_t *, const u_char *, int);
 static struct block *gen_wlanhostop(compiler_state_t *, const u_char *, int);
 static struct block *gen_ipfchostop(compiler_state_t *, const u_char *, int);
 static struct block *gen_dnhostop(compiler_state_t *, bpf_u_int32, int);
-static struct block *gen_mpls_linktype(compiler_state_t *, int);
+static struct block *gen_mpls_linktype(compiler_state_t *, bpf_u_int32);
 static struct block *gen_host(compiler_state_t *, bpf_u_int32, bpf_u_int32,
     int, int, int);
 #ifdef INET6
@@ -522,23 +547,27 @@ static struct block *gen_gateway(compiler_state_t *, const u_char *,
     struct addrinfo *, int, int);
 #endif
 static struct block *gen_ipfrag(compiler_state_t *);
-static struct block *gen_portatom(compiler_state_t *, int, bpf_int32);
-static struct block *gen_portrangeatom(compiler_state_t *, int, bpf_int32,
-    bpf_int32);
-static struct block *gen_portatom6(compiler_state_t *, int, bpf_int32);
-static struct block *gen_portrangeatom6(compiler_state_t *, int, bpf_int32,
-    bpf_int32);
-struct block *gen_portop(compiler_state_t *, int, int, int);
-static struct block *gen_port(compiler_state_t *, int, int, int);
-struct block *gen_portrangeop(compiler_state_t *, int, int, int, int);
-static struct block *gen_portrange(compiler_state_t *, int, int, int, int);
-struct block *gen_portop6(compiler_state_t *, int, int, int);
-static struct block *gen_port6(compiler_state_t *, int, int, int);
-struct block *gen_portrangeop6(compiler_state_t *, int, int, int, int);
-static struct block *gen_portrange6(compiler_state_t *, int, int, int, int);
+static struct block *gen_portatom(compiler_state_t *, int, bpf_u_int32);
+static struct block *gen_portrangeatom(compiler_state_t *, u_int, bpf_u_int32,
+    bpf_u_int32);
+static struct block *gen_portatom6(compiler_state_t *, int, bpf_u_int32);
+static struct block *gen_portrangeatom6(compiler_state_t *, u_int, bpf_u_int32,
+    bpf_u_int32);
+static struct block *gen_portop(compiler_state_t *, u_int, u_int, int);
+static struct block *gen_port(compiler_state_t *, u_int, int, int);
+static struct block *gen_portrangeop(compiler_state_t *, u_int, u_int,
+    bpf_u_int32, int);
+static struct block *gen_portrange(compiler_state_t *, u_int, u_int, int, int);
+struct block *gen_portop6(compiler_state_t *, u_int, u_int, int);
+static struct block *gen_port6(compiler_state_t *, u_int, int, int);
+static struct block *gen_portrangeop6(compiler_state_t *, u_int, u_int,
+    bpf_u_int32, int);
+static struct block *gen_portrange6(compiler_state_t *, u_int, u_int, int, int);
 static int lookup_proto(compiler_state_t *, const char *, int);
-static struct block *gen_protochain(compiler_state_t *, int, int, int);
-static struct block *gen_proto(compiler_state_t *, int, int, int);
+#if !defined(NO_PROTOCHAIN)
+static struct block *gen_protochain(compiler_state_t *, bpf_u_int32, int);
+#endif /* !defined(NO_PROTOCHAIN) */
+static struct block *gen_proto(compiler_state_t *, bpf_u_int32, int, int);
 static struct slist *xfer_to_x(compiler_state_t *, struct arth *);
 static struct slist *xfer_to_a(compiler_state_t *, struct arth *);
 static struct block *gen_mac_multicast(compiler_state_t *, int);
@@ -547,6 +576,9 @@ static struct block *gen_check_802_11_data_frame(compiler_state_t *);
 static struct block *gen_geneve_ll_check(compiler_state_t *cstate);
 
 static struct block *gen_ppi_dlt_check(compiler_state_t *);
+static struct block *gen_atmfield_code_internal(compiler_state_t *, int,
+    bpf_u_int32, int, int);
+static struct block *gen_atmtype_llc(compiler_state_t *);
 static struct block *gen_msg_abbrev(compiler_state_t *, int type);
 
 static void
@@ -555,14 +587,14 @@ initchunks(compiler_state_t *cstate)
        int i;
 
        for (i = 0; i < NCHUNKS; i++) {
-               cstate->cgstate->chunks[i].n_left = 0;
-               cstate->cgstate->chunks[i].m = NULL;
+               cstate->chunks[i].n_left = 0;
+               cstate->chunks[i].m = NULL;
        }
-       cstate->cgstate->cur_chunk = 0;
+       cstate->cur_chunk = 0;
 }
 
 static void *
-newchunk(compiler_state_t *cstate, size_t n)
+newchunk_nolongjmp(compiler_state_t *cstate, size_t n)
 {
        struct chunk *cp;
        int k;
@@ -576,44 +608,68 @@ newchunk(compiler_state_t *cstate, size_t n)
        n = ALIGN(n);
 #endif
 
-       cp = &cstate->cgstate->chunks[cstate->cgstate->cur_chunk];
+       cp = &cstate->chunks[cstate->cur_chunk];
        if (n > cp->n_left) {
                ++cp;
-               k = ++cstate->cgstate->cur_chunk;
-               if (k >= NCHUNKS)
-                       bpf_error(cstate, "out of memory");
+               k = ++cstate->cur_chunk;
+               if (k >= NCHUNKS) {
+                       bpf_set_error(cstate, "out of memory");
+                       return (NULL);
+               }
                size = CHUNK0SIZE << k;
                cp->m = (void *)malloc(size);
-               if (cp->m == NULL)
-                       bpf_error(cstate, "out of memory");
+               if (cp->m == NULL) {
+                       bpf_set_error(cstate, "out of memory");
+                       return (NULL);
+               }
                memset((char *)cp->m, 0, size);
                cp->n_left = size;
-               if (n > size)
-                       bpf_error(cstate, "out of memory");
+               if (n > size) {
+                       bpf_set_error(cstate, "out of memory");
+                       return (NULL);
+               }
        }
        cp->n_left -= n;
        return (void *)((char *)cp->m + cp->n_left);
 }
 
+static void *
+newchunk(compiler_state_t *cstate, size_t n)
+{
+       void *p;
+
+       p = newchunk_nolongjmp(cstate, n);
+       if (p == NULL) {
+               longjmp(cstate->top_ctx, 1);
+               /*NOTREACHED*/
+       }
+       return (p);
+}
+
 static void
 freechunks(compiler_state_t *cstate)
 {
        int i;
 
        for (i = 0; i < NCHUNKS; ++i)
-               if (cstate->cgstate->chunks[i].m != NULL)
-                       free(cstate->cgstate->chunks[i].m);
+               if (cstate->chunks[i].m != NULL)
+                       free(cstate->chunks[i].m);
 }
 
 /*
  * A strdup whose allocations are freed after code generation is over.
+ * This is used by the lexical analyzer, so it can't longjmp; it just
+ * returns NULL on an allocation error, and the callers must check
+ * for it.
  */
 char *
 sdup(compiler_state_t *cstate, const char *s)
 {
        size_t n = strlen(s) + 1;
-       char *cp = newchunk(cstate, n);
+       char *cp = newchunk_nolongjmp(cstate, n);
 
+       if (cp == NULL)
+               return (NULL);
        pcap_strlcpy(cp, s, n);
        return (cp);
 }
@@ -664,7 +720,6 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
        static int done = 0;
 #endif
        compiler_state_t cstate;
-       codegen_state_t cgstate;
        const char * volatile xbuf = buf;
        yyscan_t scanner = NULL;
        volatile YY_BUFFER_STATE in_buffer = NULL;
@@ -676,9 +731,9 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
         * link-layer type, so we can't use it.
         */
        if (!p->activated) {
-               pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+               snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
                    "not-yet-activated pcap_t passed to pcap_compile");
-               return (-1);
+               return (PCAP_ERROR);
        }
 
 #ifdef _WIN32
@@ -702,31 +757,31 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
         * filter for this pcap_t; we might be running it from userland
         * on captured packets to do packet classification.  We really
         * need a better way of handling this, but this is all that
-        * the WinPcap code did.
+        * the WinPcap remote capture code did.
         */
        if (p->save_current_filter_op != NULL)
                (p->save_current_filter_op)(p, buf);
 #endif
 
-       cstate.cgstate = &cgstate;
        initchunks(&cstate);
-       cstate.cgstate->no_optimize = 0;
+       cstate.no_optimize = 0;
 #ifdef INET6
-       cstate.cgstate->ai = NULL;
+       cstate.ai = NULL;
 #endif
-       cstate.cgstate->e = NULL;
-       cstate.cgstate->ic.root = NULL;
-       cstate.cgstate->ic.cur_mark = 0;
+       cstate.e = NULL;
+       cstate.ic.root = NULL;
+       cstate.ic.cur_mark = 0;
        cstate.bpf_pcap = p;
+       cstate.error_set = 0;
        init_regs(&cstate);
 
-       cstate.cgstate->netmask = mask;
+       cstate.netmask = mask;
 
-       cstate.cgstate->snaplen = pcap_snapshot(p);
-       if (cstate.cgstate->snaplen == 0) {
-               pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+       cstate.snaplen = pcap_snapshot(p);
+       if (cstate.snaplen == 0) {
+               snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
                         "snaplen of 0 rejects all packets");
-               rc = -1;
+               rc = PCAP_ERROR;
                goto quit;
        }
 
@@ -741,40 +796,51 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
         */
        pcap_set_extra(&cstate, scanner);
 
-       init_linktype(&cstate, p);
+       if (init_linktype(&cstate, p) == -1) {
+               rc = PCAP_ERROR;
+               goto quit;
+       }
        if (pcap_parse(scanner, &cstate) != 0) {
 #ifdef INET6
-               if (cstate.cgstate->ai != NULL)
-                       freeaddrinfo(cstate.cgstate->ai);
+               if (cstate.ai != NULL)
+                       freeaddrinfo(cstate.ai);
 #endif
-               if (cstate.cgstate->e != NULL)
-                       free(cstate.cgstate->e);
-               rc = -1;
+               if (cstate.e != NULL)
+                       free(cstate.e);
+               rc = PCAP_ERROR;
                goto quit;
        }
 
-       if (cstate.cgstate->ic.root == NULL)
-               cstate.cgstate->ic.root = gen_retblk(&cstate, cstate.cgstate->snaplen);
+       if (cstate.ic.root == NULL) {
+               /*
+                * Catch errors reported by gen_retblk().
+                */
+               if (setjmp(cstate.top_ctx)) {
+                       rc = PCAP_ERROR;
+                       goto quit;
+               }
+               cstate.ic.root = gen_retblk(&cstate, cstate.snaplen);
+       }
 
-       if (optimize && !cstate.cgstate->no_optimize) {
-               if (bpf_optimize(&cstate.cgstate->ic, p->errbuf) == -1) {
+       if (optimize && !cstate.no_optimize) {
+               if (bpf_optimize(&cstate.ic, p->errbuf) == -1) {
                        /* Failure */
-                       rc = -1;
+                       rc = PCAP_ERROR;
                        goto quit;
                }
-               if (cstate.cgstate->ic.root == NULL ||
-                   (cstate.cgstate->ic.root->s.code == (BPF_RET|BPF_K) && cstate.cgstate->ic.root->s.k == 0)) {
-                       (void)pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+               if (cstate.ic.root == NULL ||
+                   (cstate.ic.root->s.code == (BPF_RET|BPF_K) && cstate.ic.root->s.k == 0)) {
+                       (void)snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
                            "expression rejects all packets");
-                       rc = -1;
+                       rc = PCAP_ERROR;
                        goto quit;
                }
        }
-       program->bf_insns = icode_to_fcode(&cstate.cgstate->ic,
-           cstate.cgstate->ic.root, &len, p->errbuf);
+       program->bf_insns = icode_to_fcode(&cstate.ic,
+           cstate.ic.root, &len, p->errbuf);
        if (program->bf_insns == NULL) {
                /* Failure */
-               rc = -1;
+               rc = PCAP_ERROR;
                goto quit;
        }
        program->bf_len = len;
@@ -812,7 +878,7 @@ pcap_compile_nopcap(int snaplen_arg, int linktype_arg,
 
        p = pcap_open_dead(linktype_arg, snaplen_arg);
        if (p == NULL)
-               return (-1);
+               return (PCAP_ERROR);
        ret = pcap_compile(p, program, buf, optimize, mask);
        pcap_close(p);
        return (ret);
@@ -872,11 +938,18 @@ merge(struct block *b0, struct block *b1)
        *p = b1;
 }
 
-void
+int
 finish_parse(compiler_state_t *cstate, struct block *p)
 {
        struct block *ppi_dlt_check;
 
+       /*
+        * Catch errors reported by us and routines below us, and return -1
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (-1);
+
        /*
         * Insert before the statements of the first (root) block any
         * statements needed to load the lengths of any variable-length
@@ -915,10 +988,11 @@ finish_parse(compiler_state_t *cstate, struct block *p)
        if (ppi_dlt_check != NULL)
                gen_and(ppi_dlt_check, p);
 
-       backpatch(p, gen_retblk(cstate, cstate->cgstate->snaplen));
+       backpatch(p, gen_retblk(cstate, cstate->snaplen));
        p->sense = !p->sense;
        backpatch(p, gen_retblk(cstate, 0));
-       cstate->cgstate->ic.root = p->head;
+       cstate->ic.root = p->head;
+       return (0);
 }
 
 void
@@ -950,42 +1024,42 @@ gen_not(struct block *b)
 
 static struct block *
 gen_cmp(compiler_state_t *cstate, enum e_offrel offrel, u_int offset,
-    u_int size, bpf_int32 v)
+    u_int size, bpf_u_int32 v)
 {
        return gen_ncmp(cstate, offrel, offset, size, 0xffffffff, BPF_JEQ, 0, v);
 }
 
 static struct block *
 gen_cmp_gt(compiler_state_t *cstate, enum e_offrel offrel, u_int offset,
-    u_int size, bpf_int32 v)
+    u_int size, bpf_u_int32 v)
 {
        return gen_ncmp(cstate, offrel, offset, size, 0xffffffff, BPF_JGT, 0, v);
 }
 
 static struct block *
 gen_cmp_ge(compiler_state_t *cstate, enum e_offrel offrel, u_int offset,
-    u_int size, bpf_int32 v)
+    u_int size, bpf_u_int32 v)
 {
        return gen_ncmp(cstate, offrel, offset, size, 0xffffffff, BPF_JGE, 0, v);
 }
 
 static struct block *
 gen_cmp_lt(compiler_state_t *cstate, enum e_offrel offrel, u_int offset,
-    u_int size, bpf_int32 v)
+    u_int size, bpf_u_int32 v)
 {
        return gen_ncmp(cstate, offrel, offset, size, 0xffffffff, BPF_JGE, 1, v);
 }
 
 static struct block *
 gen_cmp_le(compiler_state_t *cstate, enum e_offrel offrel, u_int offset,
-    u_int size, bpf_int32 v)
+    u_int size, bpf_u_int32 v)
 {
        return gen_ncmp(cstate, offrel, offset, size, 0xffffffff, BPF_JGT, 1, v);
 }
 
 static struct block *
 gen_mcmp(compiler_state_t *cstate, enum e_offrel offrel, u_int offset,
-    u_int size, bpf_int32 v, bpf_u_int32 mask)
+    u_int size, bpf_u_int32 v, bpf_u_int32 mask)
 {
        return gen_ncmp(cstate, offrel, offset, size, mask, BPF_JEQ, 0, v);
 }
@@ -996,22 +1070,12 @@ 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];
 
                tmp = gen_cmp(cstate, offrel, offset + size - 4, BPF_W,
-                   (bpf_int32)EXTRACT_BE_U_4(p));
+                   EXTRACT_BE_U_4(p));
                if (b != NULL)
                        gen_and(b, tmp);
                b = tmp;
@@ -1021,14 +1085,14 @@ gen_bcmp(compiler_state_t *cstate, enum e_offrel offrel, u_int offset,
                register const u_char *p = &v[size - 2];
 
                tmp = gen_cmp(cstate, offrel, offset + size - 2, BPF_H,
-                   (bpf_int32)EXTRACT_BE_U_2(p));
+                   EXTRACT_BE_U_2(p));
                if (b != NULL)
                        gen_and(b, tmp);
                b = tmp;
                size -= 2;
        }
        if (size > 0) {
-               tmp = gen_cmp(cstate, offrel, offset, BPF_B, (bpf_int32)v[0]);
+               tmp = gen_cmp(cstate, offrel, offset, BPF_B, v[0]);
                if (b != NULL)
                        gen_and(b, tmp);
                b = tmp;
@@ -1043,9 +1107,9 @@ gen_bcmp(compiler_state_t *cstate, enum e_offrel offrel, u_int offset,
  * should test the opposite of "jtype".
  */
 static struct block *
-gen_ncmp(compiler_state_t *cstate, enum e_offrel offrel, bpf_u_int32 offset,
-    bpf_u_int32 size, bpf_u_int32 mask, bpf_u_int32 jtype, int reverse,
-    bpf_int32 v)
+gen_ncmp(compiler_state_t *cstate, enum e_offrel offrel, u_int offset,
+    u_int size, bpf_u_int32 mask, int jtype, int reverse,
+    bpf_u_int32 v)
 {
        struct slist *s, *s2;
        struct block *b;
@@ -1066,93 +1130,93 @@ gen_ncmp(compiler_state_t *cstate, enum e_offrel offrel, bpf_u_int32 offset,
        return b;
 }
 
-static void
+static int
 init_linktype(compiler_state_t *cstate, pcap_t *p)
 {
-       cstate->cgstate->pcap_fddipad = p->fddipad;
+       cstate->pcap_fddipad = p->fddipad;
 
        /*
         * We start out with only one link-layer header.
         */
-       cstate->cgstate->outermostlinktype = pcap_datalink(p);
-       cstate->cgstate->off_outermostlinkhdr.constant_part = 0;
-       cstate->cgstate->off_outermostlinkhdr.is_variable = 0;
-       cstate->cgstate->off_outermostlinkhdr.reg = -1;
+       cstate->outermostlinktype = pcap_datalink(p);
+       cstate->off_outermostlinkhdr.constant_part = 0;
+       cstate->off_outermostlinkhdr.is_variable = 0;
+       cstate->off_outermostlinkhdr.reg = -1;
 
-       cstate->cgstate->prevlinktype = cstate->cgstate->outermostlinktype;
-       cstate->cgstate->off_prevlinkhdr.constant_part = 0;
-       cstate->cgstate->off_prevlinkhdr.is_variable = 0;
-       cstate->cgstate->off_prevlinkhdr.reg = -1;
+       cstate->prevlinktype = cstate->outermostlinktype;
+       cstate->off_prevlinkhdr.constant_part = 0;
+       cstate->off_prevlinkhdr.is_variable = 0;
+       cstate->off_prevlinkhdr.reg = -1;
 
-       cstate->cgstate->linktype = cstate->cgstate->outermostlinktype;
-       cstate->cgstate->off_linkhdr.constant_part = 0;
-       cstate->cgstate->off_linkhdr.is_variable = 0;
-       cstate->cgstate->off_linkhdr.reg = -1;
+       cstate->linktype = cstate->outermostlinktype;
+       cstate->off_linkhdr.constant_part = 0;
+       cstate->off_linkhdr.is_variable = 0;
+       cstate->off_linkhdr.reg = -1;
 
        /*
         * XXX
         */
-       cstate->cgstate->off_linkpl.constant_part = 0;
-       cstate->cgstate->off_linkpl.is_variable = 0;
-       cstate->cgstate->off_linkpl.reg = -1;
+       cstate->off_linkpl.constant_part = 0;
+       cstate->off_linkpl.is_variable = 0;
+       cstate->off_linkpl.reg = -1;
 
-       cstate->cgstate->off_linktype.constant_part = 0;
-       cstate->cgstate->off_linktype.is_variable = 0;
-       cstate->cgstate->off_linktype.reg = -1;
+       cstate->off_linktype.constant_part = 0;
+       cstate->off_linktype.is_variable = 0;
+       cstate->off_linktype.reg = -1;
 
        /*
         * Assume it's not raw ATM with a pseudo-header, for now.
         */
-       cstate->cgstate->is_atm = 0;
-       cstate->cgstate->off_vpi = OFFSET_NOT_SET;
-       cstate->cgstate->off_vci = OFFSET_NOT_SET;
-       cstate->cgstate->off_proto = OFFSET_NOT_SET;
-       cstate->cgstate->off_payload = OFFSET_NOT_SET;
+       cstate->is_atm = 0;
+       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.
         */
-       cstate->cgstate->is_geneve = 0;
+       cstate->is_geneve = 0;
 
        /*
         * No variable length VLAN offset by default
         */
-       cstate->cgstate->is_vlan_vloffset = 0;
+       cstate->is_vlan_vloffset = 0;
 
        /*
         * And assume we're not doing SS7.
         */
-       cstate->cgstate->off_li = OFFSET_NOT_SET;
-       cstate->cgstate->off_li_hsl = OFFSET_NOT_SET;
-       cstate->cgstate->off_sio = OFFSET_NOT_SET;
-       cstate->cgstate->off_opc = OFFSET_NOT_SET;
-       cstate->cgstate->off_dpc = OFFSET_NOT_SET;
-       cstate->cgstate->off_sls = OFFSET_NOT_SET;
+       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->cgstate->label_stack_depth = 0;
-       cstate->cgstate->vlan_stack_depth = 0;
+       cstate->label_stack_depth = 0;
+       cstate->vlan_stack_depth = 0;
 
-       switch (cstate->cgstate->linktype) {
+       switch (cstate->linktype) {
 
        case DLT_ARCNET:
-               cstate->cgstate->off_linktype.constant_part = 2;
-               cstate->cgstate->off_linkpl.constant_part = 6;
-               cstate->cgstate->off_nl = 0;            /* XXX in reality, variable! */
-               cstate->cgstate->off_nl_nosnap = 0;     /* no 802.2 LLC */
+               cstate->off_linktype.constant_part = 2;
+               cstate->off_linkpl.constant_part = 6;
+               cstate->off_nl = 0;             /* XXX in reality, variable! */
+               cstate->off_nl_nosnap = 0;      /* no 802.2 LLC */
                break;
 
        case DLT_ARCNET_LINUX:
-               cstate->cgstate->off_linktype.constant_part = 4;
-               cstate->cgstate->off_linkpl.constant_part = 8;
-               cstate->cgstate->off_nl = 0;            /* XXX in reality, variable! */
-               cstate->cgstate->off_nl_nosnap = 0;     /* no 802.2 LLC */
+               cstate->off_linktype.constant_part = 4;
+               cstate->off_linkpl.constant_part = 8;
+               cstate->off_nl = 0;             /* XXX in reality, variable! */
+               cstate->off_nl_nosnap = 0;      /* no 802.2 LLC */
                break;
 
        case DLT_EN10MB:
-               cstate->cgstate->off_linktype.constant_part = 12;
-               cstate->cgstate->off_linkpl.constant_part = 14; /* Ethernet header length */
-               cstate->cgstate->off_nl = 0;            /* Ethernet II */
-               cstate->cgstate->off_nl_nosnap = 3;     /* 802.3+802.2 */
+               cstate->off_linktype.constant_part = 12;
+               cstate->off_linkpl.constant_part = 14;  /* Ethernet header length */
+               cstate->off_nl = 0;             /* Ethernet II */
+               cstate->off_nl_nosnap = 3;      /* 802.3+802.2 */
                break;
 
        case DLT_SLIP:
@@ -1160,44 +1224,45 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
                 * SLIP doesn't have a link level type.  The 16 byte
                 * header is hacked into our SLIP driver.
                 */
-               cstate->cgstate->off_linktype.constant_part = OFFSET_NOT_SET;
-               cstate->cgstate->off_linkpl.constant_part = 16;
-               cstate->cgstate->off_nl = 0;
-               cstate->cgstate->off_nl_nosnap = 0;     /* no 802.2 LLC */
+               cstate->off_linktype.constant_part = OFFSET_NOT_SET;
+               cstate->off_linkpl.constant_part = 16;
+               cstate->off_nl = 0;
+               cstate->off_nl_nosnap = 0;      /* no 802.2 LLC */
                break;
 
        case DLT_SLIP_BSDOS:
                /* XXX this may be the same as the DLT_PPP_BSDOS case */
-               cstate->cgstate->off_linktype.constant_part = OFFSET_NOT_SET;
+               cstate->off_linktype.constant_part = OFFSET_NOT_SET;
                /* XXX end */
-               cstate->cgstate->off_linkpl.constant_part = 24;
-               cstate->cgstate->off_nl = 0;
-               cstate->cgstate->off_nl_nosnap = 0;     /* no 802.2 LLC */
+               cstate->off_linkpl.constant_part = 24;
+               cstate->off_nl = 0;
+               cstate->off_nl_nosnap = 0;      /* no 802.2 LLC */
                break;
 
        case DLT_NULL:
        case DLT_LOOP:
-               cstate->cgstate->off_linktype.constant_part = 0;
-               cstate->cgstate->off_linkpl.constant_part = 4;
-               cstate->cgstate->off_nl = 0;
-               cstate->cgstate->off_nl_nosnap = 0;     /* no 802.2 LLC */
+               cstate->off_linktype.constant_part = 0;
+               cstate->off_linkpl.constant_part = 4;
+               cstate->off_nl = 0;
+               cstate->off_nl_nosnap = 0;      /* no 802.2 LLC */
                break;
 
        case DLT_ENC:
-               cstate->cgstate->off_linktype.constant_part = 0;
-               cstate->cgstate->off_linkpl.constant_part = 12;
-               cstate->cgstate->off_nl = 0;
-               cstate->cgstate->off_nl_nosnap = 0;     /* no 802.2 LLC */
+               cstate->off_linktype.constant_part = 0;
+               cstate->off_linkpl.constant_part = 12;
+               cstate->off_nl = 0;
+               cstate->off_nl_nosnap = 0;      /* no 802.2 LLC */
                break;
 
        case DLT_PPP:
        case DLT_PPP_PPPD:
        case DLT_C_HDLC:                /* BSD/OS Cisco HDLC */
+       case DLT_HDLC:                  /* NetBSD (Cisco) HDLC */
        case DLT_PPP_SERIAL:            /* NetBSD sync/async serial PPP */
-               cstate->cgstate->off_linktype.constant_part = 2;        /* skip HDLC-like framing */
-               cstate->cgstate->off_linkpl.constant_part = 4;  /* skip HDLC-like framing and protocol field */
-               cstate->cgstate->off_nl = 0;
-               cstate->cgstate->off_nl_nosnap = 0;     /* no 802.2 LLC */
+               cstate->off_linktype.constant_part = 2; /* skip HDLC-like framing */
+               cstate->off_linkpl.constant_part = 4;   /* skip HDLC-like framing and protocol field */
+               cstate->off_nl = 0;
+               cstate->off_nl_nosnap = 0;      /* no 802.2 LLC */
                break;
 
        case DLT_PPP_ETHER:
@@ -1205,17 +1270,17 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
                 * This does no include the Ethernet header, and
                 * only covers session state.
                 */
-               cstate->cgstate->off_linktype.constant_part = 6;
-               cstate->cgstate->off_linkpl.constant_part = 8;
-               cstate->cgstate->off_nl = 0;
-               cstate->cgstate->off_nl_nosnap = 0;     /* no 802.2 LLC */
+               cstate->off_linktype.constant_part = 6;
+               cstate->off_linkpl.constant_part = 8;
+               cstate->off_nl = 0;
+               cstate->off_nl_nosnap = 0;      /* no 802.2 LLC */
                break;
 
        case DLT_PPP_BSDOS:
-               cstate->cgstate->off_linktype.constant_part = 5;
-               cstate->cgstate->off_linkpl.constant_part = 24;
-               cstate->cgstate->off_nl = 0;
-               cstate->cgstate->off_nl_nosnap = 0;     /* no 802.2 LLC */
+               cstate->off_linktype.constant_part = 5;
+               cstate->off_linkpl.constant_part = 24;
+               cstate->off_nl = 0;
+               cstate->off_nl_nosnap = 0;      /* no 802.2 LLC */
                break;
 
        case DLT_FDDI:
@@ -1227,12 +1292,12 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
                 * is being used and pick out the encapsulated Ethernet type.
                 * XXX - should we generate code to check for SNAP?
                 */
-               cstate->cgstate->off_linktype.constant_part = 13;
-               cstate->cgstate->off_linktype.constant_part += cstate->cgstate->pcap_fddipad;
-               cstate->cgstate->off_linkpl.constant_part = 13; /* FDDI MAC header length */
-               cstate->cgstate->off_linkpl.constant_part += cstate->cgstate->pcap_fddipad;
-               cstate->cgstate->off_nl = 8;            /* 802.2+SNAP */
-               cstate->cgstate->off_nl_nosnap = 3;     /* 802.2 */
+               cstate->off_linktype.constant_part = 13;
+               cstate->off_linktype.constant_part += cstate->pcap_fddipad;
+               cstate->off_linkpl.constant_part = 13;  /* FDDI MAC header length */
+               cstate->off_linkpl.constant_part += cstate->pcap_fddipad;
+               cstate->off_nl = 8;             /* 802.2+SNAP */
+               cstate->off_nl_nosnap = 3;      /* 802.2 */
                break;
 
        case DLT_IEEE802:
@@ -1259,18 +1324,19 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
                 * the 16-bit value at an offset of 14 (shifted right
                 * 8 - figure out which byte that is).
                 */
-               cstate->cgstate->off_linktype.constant_part = 14;
-               cstate->cgstate->off_linkpl.constant_part = 14; /* Token Ring MAC header length */
-               cstate->cgstate->off_nl = 8;            /* 802.2+SNAP */
-               cstate->cgstate->off_nl_nosnap = 3;     /* 802.2 */
+               cstate->off_linktype.constant_part = 14;
+               cstate->off_linkpl.constant_part = 14;  /* Token Ring MAC header length */
+               cstate->off_nl = 8;             /* 802.2+SNAP */
+               cstate->off_nl_nosnap = 3;      /* 802.2 */
                break;
 
        case DLT_PRISM_HEADER:
        case DLT_IEEE802_11_RADIO_AVS:
        case DLT_IEEE802_11_RADIO:
-               cstate->cgstate->off_linkhdr.is_variable = 1;
+               cstate->off_linkhdr.is_variable = 1;
                /* Fall through, 802.11 doesn't have a variable link
                 * prefix but is otherwise the same. */
+               /* FALLTHROUGH */
 
        case DLT_IEEE802_11:
                /*
@@ -1291,11 +1357,11 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
                 * header or an AVS header, so, in practice, it's
                 * variable-length.
                 */
-               cstate->cgstate->off_linktype.constant_part = 24;
-               cstate->cgstate->off_linkpl.constant_part = 0;  /* link-layer header is variable-length */
-               cstate->cgstate->off_linkpl.is_variable = 1;
-               cstate->cgstate->off_nl = 8;            /* 802.2+SNAP */
-               cstate->cgstate->off_nl_nosnap = 3;     /* 802.2 */
+               cstate->off_linktype.constant_part = 24;
+               cstate->off_linkpl.constant_part = 0;   /* link-layer header is variable-length */
+               cstate->off_linkpl.is_variable = 1;
+               cstate->off_nl = 8;             /* 802.2+SNAP */
+               cstate->off_nl_nosnap = 3;      /* 802.2 */
                break;
 
        case DLT_PPI:
@@ -1308,12 +1374,12 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
                 * the encapsulated DLT should be DLT_IEEE802_11) we
                 * generate code to check for this too.
                 */
-               cstate->cgstate->off_linktype.constant_part = 24;
-               cstate->cgstate->off_linkpl.constant_part = 0;  /* link-layer header is variable-length */
-               cstate->cgstate->off_linkpl.is_variable = 1;
-               cstate->cgstate->off_linkhdr.is_variable = 1;
-               cstate->cgstate->off_nl = 8;            /* 802.2+SNAP */
-               cstate->cgstate->off_nl_nosnap = 3;     /* 802.2 */
+               cstate->off_linktype.constant_part = 24;
+               cstate->off_linkpl.constant_part = 0;   /* link-layer header is variable-length */
+               cstate->off_linkpl.is_variable = 1;
+               cstate->off_linkhdr.is_variable = 1;
+               cstate->off_nl = 8;             /* 802.2+SNAP */
+               cstate->off_nl_nosnap = 3;      /* 802.2 */
                break;
 
        case DLT_ATM_RFC1483:
@@ -1329,10 +1395,10 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
                 * or "pppoa and tcp port 80" and have it check for
                 * PPPo{A,E} and a PPP protocol of IP and....
                 */
-               cstate->cgstate->off_linktype.constant_part = 0;
-               cstate->cgstate->off_linkpl.constant_part = 0;  /* packet begins with LLC header */
-               cstate->cgstate->off_nl = 8;            /* 802.2+SNAP */
-               cstate->cgstate->off_nl_nosnap = 3;     /* 802.2 */
+               cstate->off_linktype.constant_part = 0;
+               cstate->off_linkpl.constant_part = 0;   /* packet begins with LLC header */
+               cstate->off_nl = 8;             /* 802.2+SNAP */
+               cstate->off_nl_nosnap = 3;      /* 802.2 */
                break;
 
        case DLT_SUNATM:
@@ -1340,38 +1406,38 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
                 * Full Frontal ATM; you get AALn PDUs with an ATM
                 * pseudo-header.
                 */
-               cstate->cgstate->is_atm = 1;
-               cstate->cgstate->off_vpi = SUNATM_VPI_POS;
-               cstate->cgstate->off_vci = SUNATM_VCI_POS;
-               cstate->cgstate->off_proto = PROTO_POS;
-               cstate->cgstate->off_payload = SUNATM_PKT_BEGIN_POS;
-               cstate->cgstate->off_linktype.constant_part = cstate->cgstate->off_payload;
-               cstate->cgstate->off_linkpl.constant_part = cstate->cgstate->off_payload;       /* if LLC-encapsulated */
-               cstate->cgstate->off_nl = 8;            /* 802.2+SNAP */
-               cstate->cgstate->off_nl_nosnap = 3;     /* 802.2 */
+               cstate->is_atm = 1;
+               cstate->off_vpi = SUNATM_VPI_POS;
+               cstate->off_vci = SUNATM_VCI_POS;
+               cstate->off_proto = PROTO_POS;
+               cstate->off_payload = SUNATM_PKT_BEGIN_POS;
+               cstate->off_linktype.constant_part = cstate->off_payload;
+               cstate->off_linkpl.constant_part = cstate->off_payload; /* if LLC-encapsulated */
+               cstate->off_nl = 8;             /* 802.2+SNAP */
+               cstate->off_nl_nosnap = 3;      /* 802.2 */
                break;
 
        case DLT_RAW:
        case DLT_IPV4:
        case DLT_IPV6:
-               cstate->cgstate->off_linktype.constant_part = OFFSET_NOT_SET;
-               cstate->cgstate->off_linkpl.constant_part = 0;
-               cstate->cgstate->off_nl = 0;
-               cstate->cgstate->off_nl_nosnap = 0;     /* no 802.2 LLC */
+               cstate->off_linktype.constant_part = OFFSET_NOT_SET;
+               cstate->off_linkpl.constant_part = 0;
+               cstate->off_nl = 0;
+               cstate->off_nl_nosnap = 0;      /* no 802.2 LLC */
                break;
 
        case DLT_LINUX_SLL:     /* fake header for Linux cooked socket v1 */
-               cstate->cgstate->off_linktype.constant_part = 14;
-               cstate->cgstate->off_linkpl.constant_part = 16;
-               cstate->cgstate->off_nl = 0;
-               cstate->cgstate->off_nl_nosnap = 0;     /* no 802.2 LLC */
+               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->cgstate->off_linktype.constant_part = 0;
-               cstate->cgstate->off_linkpl.constant_part = 20;
-               cstate->cgstate->off_nl = 0;
-               cstate->cgstate->off_nl_nosnap = 0;     /* no 802.2 LLC */
+               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:
@@ -1380,10 +1446,10 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
                 * but really it just indicates whether there is a "short" or
                 * "long" DDP packet following.
                 */
-               cstate->cgstate->off_linktype.constant_part = OFFSET_NOT_SET;
-               cstate->cgstate->off_linkpl.constant_part = 0;
-               cstate->cgstate->off_nl = 0;
-               cstate->cgstate->off_nl_nosnap = 0;     /* no 802.2 LLC */
+               cstate->off_linktype.constant_part = OFFSET_NOT_SET;
+               cstate->off_linkpl.constant_part = 0;
+               cstate->off_nl = 0;
+               cstate->off_nl_nosnap = 0;      /* no 802.2 LLC */
                break;
 
        case DLT_IP_OVER_FC:
@@ -1397,10 +1463,10 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
                 * XXX - should we generate code to check for SNAP? RFC
                 * 2625 says SNAP should be used.
                 */
-               cstate->cgstate->off_linktype.constant_part = 16;
-               cstate->cgstate->off_linkpl.constant_part = 16;
-               cstate->cgstate->off_nl = 8;            /* 802.2+SNAP */
-               cstate->cgstate->off_nl_nosnap = 3;     /* 802.2 */
+               cstate->off_linktype.constant_part = 16;
+               cstate->off_linkpl.constant_part = 16;
+               cstate->off_nl = 8;             /* 802.2+SNAP */
+               cstate->off_nl_nosnap = 3;      /* 802.2 */
                break;
 
        case DLT_FRELAY:
@@ -1408,10 +1474,10 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
                 * XXX - we should set this to handle SNAP-encapsulated
                 * frames (NLPID of 0x80).
                 */
-               cstate->cgstate->off_linktype.constant_part = OFFSET_NOT_SET;
-               cstate->cgstate->off_linkpl.constant_part = 0;
-               cstate->cgstate->off_nl = 0;
-               cstate->cgstate->off_nl_nosnap = 0;     /* no 802.2 LLC */
+               cstate->off_linktype.constant_part = OFFSET_NOT_SET;
+               cstate->off_linkpl.constant_part = 0;
+               cstate->off_nl = 0;
+               cstate->off_nl_nosnap = 0;      /* no 802.2 LLC */
                break;
 
                 /*
@@ -1420,34 +1486,33 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
                  * so lets start with offset 4 for now and increments later on (FIXME);
                  */
        case DLT_MFR:
-               cstate->cgstate->off_linktype.constant_part = OFFSET_NOT_SET;
-               cstate->cgstate->off_linkpl.constant_part = 0;
-               cstate->cgstate->off_nl = 4;
-               cstate->cgstate->off_nl_nosnap = 0;     /* XXX - for now -> no 802.2 LLC */
+               cstate->off_linktype.constant_part = OFFSET_NOT_SET;
+               cstate->off_linkpl.constant_part = 0;
+               cstate->off_nl = 4;
+               cstate->off_nl_nosnap = 0;      /* XXX - for now -> no 802.2 LLC */
                break;
 
        case DLT_APPLE_IP_OVER_IEEE1394:
-               cstate->cgstate->off_linktype.constant_part = 16;
-               cstate->cgstate->off_linkpl.constant_part = 18;
-               cstate->cgstate->off_nl = 0;
-               cstate->cgstate->off_nl_nosnap = 0;     /* no 802.2 LLC */
+               cstate->off_linktype.constant_part = 16;
+               cstate->off_linkpl.constant_part = 18;
+               cstate->off_nl = 0;
+               cstate->off_nl_nosnap = 0;      /* no 802.2 LLC */
                break;
 
        case DLT_SYMANTEC_FIREWALL:
-               cstate->cgstate->off_linktype.constant_part = 6;
-               cstate->cgstate->off_linkpl.constant_part = 44;
-               cstate->cgstate->off_nl = 0;            /* Ethernet II */
-               cstate->cgstate->off_nl_nosnap = 0;     /* XXX - what does it do with 802.3 packets? */
+               cstate->off_linktype.constant_part = 6;
+               cstate->off_linkpl.constant_part = 44;
+               cstate->off_nl = 0;             /* Ethernet II */
+               cstate->off_nl_nosnap = 0;      /* XXX - what does it do with 802.3 packets? */
                break;
 
-#ifdef HAVE_NET_PFVAR_H
        case DLT_PFLOG:
-               cstate->cgstate->off_linktype.constant_part = 0;
-               cstate->cgstate->off_linkpl.constant_part = PFLOG_HDRLEN;
-               cstate->cgstate->off_nl = 0;
-               cstate->cgstate->off_nl_nosnap = 0;     /* no 802.2 LLC */
+               cstate->off_linktype.constant_part = 0;
+               cstate->off_linkpl.constant_part = 0;   /* link-layer header is variable-length */
+               cstate->off_linkpl.is_variable = 1;
+               cstate->off_nl = 0;
+               cstate->off_nl_nosnap = 0;      /* no 802.2 LLC */
                break;
-#endif
 
         case DLT_JUNIPER_MFR:
         case DLT_JUNIPER_MLFR:
@@ -1455,186 +1520,186 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
         case DLT_JUNIPER_PPP:
         case DLT_JUNIPER_CHDLC:
         case DLT_JUNIPER_FRELAY:
-               cstate->cgstate->off_linktype.constant_part = 4;
-               cstate->cgstate->off_linkpl.constant_part = 4;
-               cstate->cgstate->off_nl = 0;
-               cstate->cgstate->off_nl_nosnap = OFFSET_NOT_SET;        /* no 802.2 LLC */
+               cstate->off_linktype.constant_part = 4;
+               cstate->off_linkpl.constant_part = 4;
+               cstate->off_nl = 0;
+               cstate->off_nl_nosnap = OFFSET_NOT_SET; /* no 802.2 LLC */
                 break;
 
        case DLT_JUNIPER_ATM1:
-               cstate->cgstate->off_linktype.constant_part = 4;                /* in reality variable between 4-8 */
-               cstate->cgstate->off_linkpl.constant_part = 4;  /* in reality variable between 4-8 */
-               cstate->cgstate->off_nl = 0;
-               cstate->cgstate->off_nl_nosnap = 10;
+               cstate->off_linktype.constant_part = 4;         /* in reality variable between 4-8 */
+               cstate->off_linkpl.constant_part = 4;   /* in reality variable between 4-8 */
+               cstate->off_nl = 0;
+               cstate->off_nl_nosnap = 10;
                break;
 
        case DLT_JUNIPER_ATM2:
-               cstate->cgstate->off_linktype.constant_part = 8;                /* in reality variable between 8-12 */
-               cstate->cgstate->off_linkpl.constant_part = 8;  /* in reality variable between 8-12 */
-               cstate->cgstate->off_nl = 0;
-               cstate->cgstate->off_nl_nosnap = 10;
+               cstate->off_linktype.constant_part = 8;         /* in reality variable between 8-12 */
+               cstate->off_linkpl.constant_part = 8;   /* in reality variable between 8-12 */
+               cstate->off_nl = 0;
+               cstate->off_nl_nosnap = 10;
                break;
 
                /* frames captured on a Juniper PPPoE service PIC
                 * contain raw ethernet frames */
        case DLT_JUNIPER_PPPOE:
         case DLT_JUNIPER_ETHER:
-               cstate->cgstate->off_linkpl.constant_part = 14;
-               cstate->cgstate->off_linktype.constant_part = 16;
-               cstate->cgstate->off_nl = 18;           /* Ethernet II */
-               cstate->cgstate->off_nl_nosnap = 21;    /* 802.3+802.2 */
+               cstate->off_linkpl.constant_part = 14;
+               cstate->off_linktype.constant_part = 16;
+               cstate->off_nl = 18;            /* Ethernet II */
+               cstate->off_nl_nosnap = 21;     /* 802.3+802.2 */
                break;
 
        case DLT_JUNIPER_PPPOE_ATM:
-               cstate->cgstate->off_linktype.constant_part = 4;
-               cstate->cgstate->off_linkpl.constant_part = 6;
-               cstate->cgstate->off_nl = 0;
-               cstate->cgstate->off_nl_nosnap = OFFSET_NOT_SET;        /* no 802.2 LLC */
+               cstate->off_linktype.constant_part = 4;
+               cstate->off_linkpl.constant_part = 6;
+               cstate->off_nl = 0;
+               cstate->off_nl_nosnap = OFFSET_NOT_SET; /* no 802.2 LLC */
                break;
 
        case DLT_JUNIPER_GGSN:
-               cstate->cgstate->off_linktype.constant_part = 6;
-               cstate->cgstate->off_linkpl.constant_part = 12;
-               cstate->cgstate->off_nl = 0;
-               cstate->cgstate->off_nl_nosnap = OFFSET_NOT_SET;        /* no 802.2 LLC */
+               cstate->off_linktype.constant_part = 6;
+               cstate->off_linkpl.constant_part = 12;
+               cstate->off_nl = 0;
+               cstate->off_nl_nosnap = OFFSET_NOT_SET; /* no 802.2 LLC */
                break;
 
        case DLT_JUNIPER_ES:
-               cstate->cgstate->off_linktype.constant_part = 6;
-               cstate->cgstate->off_linkpl.constant_part = OFFSET_NOT_SET;     /* not really a network layer but raw IP addresses */
-               cstate->cgstate->off_nl = OFFSET_NOT_SET;       /* not really a network layer but raw IP addresses */
-               cstate->cgstate->off_nl_nosnap = OFFSET_NOT_SET;        /* no 802.2 LLC */
+               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 = 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->cgstate->off_linktype.constant_part = 12;
-               cstate->cgstate->off_linkpl.constant_part = 12;
-               cstate->cgstate->off_nl = 0;                    /* raw IP/IP6 header */
-               cstate->cgstate->off_nl_nosnap = OFFSET_NOT_SET;        /* no 802.2 LLC */
+               cstate->off_linktype.constant_part = 12;
+               cstate->off_linkpl.constant_part = 12;
+               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->cgstate->off_linktype.constant_part = OFFSET_NOT_SET;
-               cstate->cgstate->off_linkpl.constant_part = OFFSET_NOT_SET;
-               cstate->cgstate->off_nl = OFFSET_NOT_SET;
-               cstate->cgstate->off_nl_nosnap = OFFSET_NOT_SET;
+               cstate->off_linktype.constant_part = OFFSET_NOT_SET;
+               cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
+               cstate->off_nl = OFFSET_NOT_SET;
+               cstate->off_nl_nosnap = OFFSET_NOT_SET;
                break;
 
        case DLT_JUNIPER_SERVICES:
-               cstate->cgstate->off_linktype.constant_part = 12;
-               cstate->cgstate->off_linkpl.constant_part = OFFSET_NOT_SET;     /* L3 proto location dep. on cookie type */
-               cstate->cgstate->off_nl = OFFSET_NOT_SET;       /* L3 proto location dep. on cookie type */
-               cstate->cgstate->off_nl_nosnap = OFFSET_NOT_SET;        /* no 802.2 LLC */
+               cstate->off_linktype.constant_part = 12;
+               cstate->off_linkpl.constant_part = OFFSET_NOT_SET;      /* L3 proto location dep. on cookie type */
+               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->cgstate->off_linktype.constant_part = 18;
-               cstate->cgstate->off_linkpl.constant_part = OFFSET_NOT_SET;
-               cstate->cgstate->off_nl = OFFSET_NOT_SET;
-               cstate->cgstate->off_nl_nosnap = OFFSET_NOT_SET;
+               cstate->off_linktype.constant_part = 18;
+               cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
+               cstate->off_nl = OFFSET_NOT_SET;
+               cstate->off_nl_nosnap = OFFSET_NOT_SET;
                break;
 
        case DLT_JUNIPER_ST:
-               cstate->cgstate->off_linktype.constant_part = 18;
-               cstate->cgstate->off_linkpl.constant_part = OFFSET_NOT_SET;
-               cstate->cgstate->off_nl = OFFSET_NOT_SET;
-               cstate->cgstate->off_nl_nosnap = OFFSET_NOT_SET;
+               cstate->off_linktype.constant_part = 18;
+               cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
+               cstate->off_nl = OFFSET_NOT_SET;
+               cstate->off_nl_nosnap = OFFSET_NOT_SET;
                break;
 
        case DLT_JUNIPER_ISM:
-               cstate->cgstate->off_linktype.constant_part = 8;
-               cstate->cgstate->off_linkpl.constant_part = OFFSET_NOT_SET;
-               cstate->cgstate->off_nl = OFFSET_NOT_SET;
-               cstate->cgstate->off_nl_nosnap = OFFSET_NOT_SET;
+               cstate->off_linktype.constant_part = 8;
+               cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
+               cstate->off_nl = OFFSET_NOT_SET;
+               cstate->off_nl_nosnap = OFFSET_NOT_SET;
                break;
 
        case DLT_JUNIPER_VS:
        case DLT_JUNIPER_SRX_E2E:
        case DLT_JUNIPER_FIBRECHANNEL:
        case DLT_JUNIPER_ATM_CEMIC:
-               cstate->cgstate->off_linktype.constant_part = 8;
-               cstate->cgstate->off_linkpl.constant_part = OFFSET_NOT_SET;
-               cstate->cgstate->off_nl = OFFSET_NOT_SET;
-               cstate->cgstate->off_nl_nosnap = OFFSET_NOT_SET;
+               cstate->off_linktype.constant_part = 8;
+               cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
+               cstate->off_nl = OFFSET_NOT_SET;
+               cstate->off_nl_nosnap = OFFSET_NOT_SET;
                break;
 
        case DLT_MTP2:
-               cstate->cgstate->off_li = 2;
-               cstate->cgstate->off_li_hsl = 4;
-               cstate->cgstate->off_sio = 3;
-               cstate->cgstate->off_opc = 4;
-               cstate->cgstate->off_dpc = 4;
-               cstate->cgstate->off_sls = 7;
-               cstate->cgstate->off_linktype.constant_part = OFFSET_NOT_SET;
-               cstate->cgstate->off_linkpl.constant_part = OFFSET_NOT_SET;
-               cstate->cgstate->off_nl = OFFSET_NOT_SET;
-               cstate->cgstate->off_nl_nosnap = OFFSET_NOT_SET;
+               cstate->off_li = 2;
+               cstate->off_li_hsl = 4;
+               cstate->off_sio = 3;
+               cstate->off_opc = 4;
+               cstate->off_dpc = 4;
+               cstate->off_sls = 7;
+               cstate->off_linktype.constant_part = OFFSET_NOT_SET;
+               cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
+               cstate->off_nl = OFFSET_NOT_SET;
+               cstate->off_nl_nosnap = OFFSET_NOT_SET;
                break;
 
        case DLT_MTP2_WITH_PHDR:
-               cstate->cgstate->off_li = 6;
-               cstate->cgstate->off_li_hsl = 8;
-               cstate->cgstate->off_sio = 7;
-               cstate->cgstate->off_opc = 8;
-               cstate->cgstate->off_dpc = 8;
-               cstate->cgstate->off_sls = 11;
-               cstate->cgstate->off_linktype.constant_part = OFFSET_NOT_SET;
-               cstate->cgstate->off_linkpl.constant_part = OFFSET_NOT_SET;
-               cstate->cgstate->off_nl = OFFSET_NOT_SET;
-               cstate->cgstate->off_nl_nosnap = OFFSET_NOT_SET;
+               cstate->off_li = 6;
+               cstate->off_li_hsl = 8;
+               cstate->off_sio = 7;
+               cstate->off_opc = 8;
+               cstate->off_dpc = 8;
+               cstate->off_sls = 11;
+               cstate->off_linktype.constant_part = OFFSET_NOT_SET;
+               cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
+               cstate->off_nl = OFFSET_NOT_SET;
+               cstate->off_nl_nosnap = OFFSET_NOT_SET;
                break;
 
        case DLT_ERF:
-               cstate->cgstate->off_li = 22;
-               cstate->cgstate->off_li_hsl = 24;
-               cstate->cgstate->off_sio = 23;
-               cstate->cgstate->off_opc = 24;
-               cstate->cgstate->off_dpc = 24;
-               cstate->cgstate->off_sls = 27;
-               cstate->cgstate->off_linktype.constant_part = OFFSET_NOT_SET;
-               cstate->cgstate->off_linkpl.constant_part = OFFSET_NOT_SET;
-               cstate->cgstate->off_nl = OFFSET_NOT_SET;
-               cstate->cgstate->off_nl_nosnap = OFFSET_NOT_SET;
+               cstate->off_li = 22;
+               cstate->off_li_hsl = 24;
+               cstate->off_sio = 23;
+               cstate->off_opc = 24;
+               cstate->off_dpc = 24;
+               cstate->off_sls = 27;
+               cstate->off_linktype.constant_part = OFFSET_NOT_SET;
+               cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
+               cstate->off_nl = OFFSET_NOT_SET;
+               cstate->off_nl_nosnap = OFFSET_NOT_SET;
                break;
 
        case DLT_PFSYNC:
-               cstate->cgstate->off_linktype.constant_part = OFFSET_NOT_SET;
-               cstate->cgstate->off_linkpl.constant_part = 4;
-               cstate->cgstate->off_nl = 0;
-               cstate->cgstate->off_nl_nosnap = 0;
+               cstate->off_linktype.constant_part = OFFSET_NOT_SET;
+               cstate->off_linkpl.constant_part = 4;
+               cstate->off_nl = 0;
+               cstate->off_nl_nosnap = 0;
                break;
 
        case DLT_AX25_KISS:
                /*
                 * Currently, only raw "link[N:M]" filtering is supported.
                 */
-               cstate->cgstate->off_linktype.constant_part = OFFSET_NOT_SET;   /* variable, min 15, max 71 steps of 7 */
-               cstate->cgstate->off_linkpl.constant_part = OFFSET_NOT_SET;
-               cstate->cgstate->off_nl = OFFSET_NOT_SET;       /* variable, min 16, max 71 steps of 7 */
-               cstate->cgstate->off_nl_nosnap = OFFSET_NOT_SET;        /* no 802.2 LLC */
+               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 = 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->cgstate->off_linktype.constant_part = 1;
-               cstate->cgstate->off_linkpl.constant_part = 24; /* ipnet header length */
-               cstate->cgstate->off_nl = 0;
-               cstate->cgstate->off_nl_nosnap = OFFSET_NOT_SET;
+               cstate->off_linktype.constant_part = 1;
+               cstate->off_linkpl.constant_part = 24;  /* ipnet header length */
+               cstate->off_nl = 0;
+               cstate->off_nl_nosnap = OFFSET_NOT_SET;
                break;
 
        case DLT_NETANALYZER:
-               cstate->cgstate->off_linkhdr.constant_part = 4; /* Ethernet header is past 4-byte pseudo-header */
-               cstate->cgstate->off_linktype.constant_part = cstate->cgstate->off_linkhdr.constant_part + 12;
-               cstate->cgstate->off_linkpl.constant_part = cstate->cgstate->off_linkhdr.constant_part + 14;    /* pseudo-header+Ethernet header length */
-               cstate->cgstate->off_nl = 0;            /* Ethernet II */
-               cstate->cgstate->off_nl_nosnap = 3;     /* 802.3+802.2 */
+               cstate->off_linkhdr.constant_part = 4;  /* Ethernet header is past 4-byte pseudo-header */
+               cstate->off_linktype.constant_part = cstate->off_linkhdr.constant_part + 12;
+               cstate->off_linkpl.constant_part = cstate->off_linkhdr.constant_part + 14;      /* pseudo-header+Ethernet header length */
+               cstate->off_nl = 0;             /* Ethernet II */
+               cstate->off_nl_nosnap = 3;      /* 802.3+802.2 */
                break;
 
        case DLT_NETANALYZER_TRANSPARENT:
-               cstate->cgstate->off_linkhdr.constant_part = 12;        /* MAC header is past 4-byte pseudo-header, preamble, and SFD */
-               cstate->cgstate->off_linktype.constant_part = cstate->cgstate->off_linkhdr.constant_part + 12;
-               cstate->cgstate->off_linkpl.constant_part = cstate->cgstate->off_linkhdr.constant_part + 14;    /* pseudo-header+preamble+SFD+Ethernet header length */
-               cstate->cgstate->off_nl = 0;            /* Ethernet II */
-               cstate->cgstate->off_nl_nosnap = 3;     /* 802.3+802.2 */
+               cstate->off_linkhdr.constant_part = 12; /* MAC header is past 4-byte pseudo-header, preamble, and SFD */
+               cstate->off_linktype.constant_part = cstate->off_linkhdr.constant_part + 12;
+               cstate->off_linkpl.constant_part = cstate->off_linkhdr.constant_part + 14;      /* pseudo-header+preamble+SFD+Ethernet header length */
+               cstate->off_nl = 0;             /* Ethernet II */
+               cstate->off_nl_nosnap = 3;      /* 802.3+802.2 */
                break;
 
        default:
@@ -1642,19 +1707,22 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
                 * For values in the range in which we've assigned new
                 * DLT_ values, only raw "link[N:M]" filtering is supported.
                 */
-               if (cstate->cgstate->linktype >= DLT_MATCHING_MIN &&
-                   cstate->cgstate->linktype <= DLT_MATCHING_MAX) {
-                       cstate->cgstate->off_linktype.constant_part = OFFSET_NOT_SET;
-                       cstate->cgstate->off_linkpl.constant_part = OFFSET_NOT_SET;
-                       cstate->cgstate->off_nl = OFFSET_NOT_SET;
-                       cstate->cgstate->off_nl_nosnap = OFFSET_NOT_SET;
+               if (cstate->linktype >= DLT_MATCHING_MIN &&
+                   cstate->linktype <= DLT_MATCHING_MAX) {
+                       cstate->off_linktype.constant_part = OFFSET_NOT_SET;
+                       cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
+                       cstate->off_nl = OFFSET_NOT_SET;
+                       cstate->off_nl_nosnap = OFFSET_NOT_SET;
                } else {
-                       bpf_error(cstate, "unknown data link type %d", cstate->cgstate->linktype);
+                       bpf_set_error(cstate, "unknown data link type %d (min %d, max %d)",
+                           cstate->linktype, DLT_MATCHING_MIN, DLT_MATCHING_MAX);
+                       return (-1);
                }
                break;
        }
 
-       cstate->cgstate->off_outermostlinkhdr = cstate->cgstate->off_prevlinkhdr = cstate->cgstate->off_linkhdr;
+       cstate->off_outermostlinkhdr = cstate->off_prevlinkhdr = cstate->off_linkhdr;
+       return (0);
 }
 
 /*
@@ -1706,6 +1774,19 @@ gen_load_a(compiler_state_t *cstate, enum e_offrel offrel, u_int offset,
 {
        struct slist *s, *s2;
 
+       /*
+        * Squelch warnings from compilers that *don't* assume that
+        * offrel always has a valid enum value and therefore don't
+        * assume that we'll always go through one of the case arms.
+        *
+        * If we have a default case, compilers that *do* assume that
+        * will then complain about the default case code being
+        * unreachable.
+        *
+        * Damned if you do, damned if you don't.
+        */
+       s = NULL;
+
        switch (offrel) {
 
        case OR_PACKET:
@@ -1714,31 +1795,31 @@ gen_load_a(compiler_state_t *cstate, enum e_offrel offrel, u_int offset,
                break;
 
        case OR_LINKHDR:
-               s = gen_load_absoffsetrel(cstate, &cstate->cgstate->off_linkhdr, offset, size);
+               s = gen_load_absoffsetrel(cstate, &cstate->off_linkhdr, offset, size);
                break;
 
        case OR_PREVLINKHDR:
-               s = gen_load_absoffsetrel(cstate, &cstate->cgstate->off_prevlinkhdr, offset, size);
+               s = gen_load_absoffsetrel(cstate, &cstate->off_prevlinkhdr, offset, size);
                break;
 
        case OR_LLC:
-               s = gen_load_absoffsetrel(cstate, &cstate->cgstate->off_linkpl, offset, size);
+               s = gen_load_absoffsetrel(cstate, &cstate->off_linkpl, offset, size);
                break;
 
        case OR_PREVMPLSHDR:
-               s = gen_load_absoffsetrel(cstate, &cstate->cgstate->off_linkpl, cstate->cgstate->off_nl - 4 + offset, size);
+               s = gen_load_absoffsetrel(cstate, &cstate->off_linkpl, cstate->off_nl - 4 + offset, size);
                break;
 
        case OR_LINKPL:
-               s = gen_load_absoffsetrel(cstate, &cstate->cgstate->off_linkpl, cstate->cgstate->off_nl + offset, size);
+               s = gen_load_absoffsetrel(cstate, &cstate->off_linkpl, cstate->off_nl + offset, size);
                break;
 
        case OR_LINKPL_NOSNAP:
-               s = gen_load_absoffsetrel(cstate, &cstate->cgstate->off_linkpl, cstate->cgstate->off_nl_nosnap + offset, size);
+               s = gen_load_absoffsetrel(cstate, &cstate->off_linkpl, cstate->off_nl_nosnap + offset, size);
                break;
 
        case OR_LINKTYPE:
-               s = gen_load_absoffsetrel(cstate, &cstate->cgstate->off_linktype, offset, size);
+               s = gen_load_absoffsetrel(cstate, &cstate->off_linktype, offset, size);
                break;
 
        case OR_TRAN_IPV4:
@@ -1762,17 +1843,13 @@ gen_load_a(compiler_state_t *cstate, enum e_offrel offrel, u_int offset,
                 * part in the offset of the load.
                 */
                s2 = new_stmt(cstate, BPF_LD|BPF_IND|size);
-               s2->s.k = cstate->cgstate->off_linkpl.constant_part + cstate->cgstate->off_nl + offset;
+               s2->s.k = cstate->off_linkpl.constant_part + cstate->off_nl + offset;
                sappend(s, s2);
                break;
 
        case OR_TRAN_IPV6:
-               s = gen_load_absoffsetrel(cstate, &cstate->cgstate->off_linkpl, cstate->cgstate->off_nl + 40 + offset, size);
+               s = gen_load_absoffsetrel(cstate, &cstate->off_linkpl, cstate->off_nl + 40 + offset, size);
                break;
-
-       default:
-               abort();
-               /* NOTREACHED */
        }
        return s;
 }
@@ -1787,7 +1864,7 @@ gen_loadx_iphdrlen(compiler_state_t *cstate)
 {
        struct slist *s, *s2;
 
-       s = gen_abs_offset_varpart(cstate, &cstate->cgstate->off_linkpl);
+       s = gen_abs_offset_varpart(cstate, &cstate->off_linkpl);
        if (s != NULL) {
                /*
                 * The offset of the link-layer payload has a variable
@@ -1800,7 +1877,7 @@ gen_loadx_iphdrlen(compiler_state_t *cstate)
                 * the value from the X register.
                 */
                s2 = new_stmt(cstate, BPF_LD|BPF_IND|BPF_B);
-               s2->s.k = cstate->cgstate->off_linkpl.constant_part + cstate->cgstate->off_nl;
+               s2->s.k = cstate->off_linkpl.constant_part + cstate->off_nl;
                sappend(s, s2);
                s2 = new_stmt(cstate, BPF_ALU|BPF_AND|BPF_K);
                s2->s.k = 0xf;
@@ -1825,13 +1902,13 @@ gen_loadx_iphdrlen(compiler_state_t *cstate)
                 *
                 * This means we can use the 4*([k]&0xf) addressing
                 * mode.  Load the length of the IPv4 header, which
-                * is at an offset of cstate->cgstate->off_nl from the beginning of
+                * is at an offset of cstate->off_nl from the beginning of
                 * the link-layer payload, and thus at an offset of
-                * cstate->cgstate->off_linkpl.constant_part + cstate->cgstate->off_nl from the beginning
+                * cstate->off_linkpl.constant_part + cstate->off_nl from the beginning
                 * of the raw packet data, using that addressing mode.
                 */
                s = new_stmt(cstate, BPF_LDX|BPF_MSH|BPF_B);
-               s->s.k = cstate->cgstate->off_linkpl.constant_part + cstate->cgstate->off_nl;
+               s->s.k = cstate->off_linkpl.constant_part + cstate->off_nl;
        }
        return s;
 }
@@ -1881,11 +1958,11 @@ gen_false(compiler_state_t *cstate)
  * the appropriate test.
  */
 static struct block *
-gen_ether_linktype(compiler_state_t *cstate, int proto)
+gen_ether_linktype(compiler_state_t *cstate, bpf_u_int32 ll_proto)
 {
        struct block *b0, *b1;
 
-       switch (proto) {
+       switch (ll_proto) {
 
        case LLCSAP_ISONS:
        case LLCSAP_IP:
@@ -1904,8 +1981,7 @@ gen_ether_linktype(compiler_state_t *cstate, int proto)
                 */
                b0 = gen_cmp_gt(cstate, OR_LINKTYPE, 0, BPF_H, ETHERMTU);
                gen_not(b0);
-               b1 = gen_cmp(cstate, OR_LLC, 0, BPF_H, (bpf_int32)
-                            ((proto << 8) | proto));
+               b1 = gen_cmp(cstate, OR_LLC, 0, BPF_H, (ll_proto << 8) | ll_proto);
                gen_and(b0, b1);
                return b1;
 
@@ -1942,8 +2018,8 @@ gen_ether_linktype(compiler_state_t *cstate, int proto)
                 * This generates code to check both for the
                 * IPX LSAP (Ethernet_802.2) and for Ethernet_802.3.
                 */
-               b0 = gen_cmp(cstate, OR_LLC, 0, BPF_B, (bpf_int32)LLCSAP_IPX);
-               b1 = gen_cmp(cstate, OR_LLC, 0, BPF_H, (bpf_int32)0xFFFF);
+               b0 = gen_cmp(cstate, OR_LLC, 0, BPF_B, LLCSAP_IPX);
+               b1 = gen_cmp(cstate, OR_LLC, 0, BPF_H, 0xFFFF);
                gen_or(b0, b1);
 
                /*
@@ -1973,7 +2049,7 @@ gen_ether_linktype(compiler_state_t *cstate, int proto)
                 * do that before checking for the other frame
                 * types.
                 */
-               b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, (bpf_int32)ETHERTYPE_IPX);
+               b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, ETHERTYPE_IPX);
                gen_or(b0, b1);
                return b1;
 
@@ -2003,9 +2079,9 @@ gen_ether_linktype(compiler_state_t *cstate, int proto)
                 * 0x000000 (encapsulated Ethernet) and a protocol
                 * type of ETHERTYPE_AARP (Appletalk ARP).
                 */
-               if (proto == ETHERTYPE_ATALK)
+               if (ll_proto == ETHERTYPE_ATALK)
                        b1 = gen_snap(cstate, 0x080007, ETHERTYPE_ATALK);
-               else    /* proto == ETHERTYPE_AARP */
+               else    /* ll_proto == ETHERTYPE_AARP */
                        b1 = gen_snap(cstate, 0x000000, ETHERTYPE_AARP);
                gen_and(b0, b1);
 
@@ -2014,13 +2090,13 @@ gen_ether_linktype(compiler_state_t *cstate, int proto)
                 * phase 1?); we just check for the Ethernet
                 * protocol type.
                 */
-               b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, (bpf_int32)proto);
+               b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, ll_proto);
 
                gen_or(b0, b1);
                return b1;
 
        default:
-               if (proto <= ETHERMTU) {
+               if (ll_proto <= ETHERMTU) {
                        /*
                         * This is an LLC SAP value, so the frames
                         * that match would be 802.2 frames.
@@ -2031,7 +2107,7 @@ gen_ether_linktype(compiler_state_t *cstate, int proto)
                         */
                        b0 = gen_cmp_gt(cstate, OR_LINKTYPE, 0, BPF_H, ETHERMTU);
                        gen_not(b0);
-                       b1 = gen_cmp(cstate, OR_LINKTYPE, 2, BPF_B, (bpf_int32)proto);
+                       b1 = gen_cmp(cstate, OR_LINKTYPE, 2, BPF_B, ll_proto);
                        gen_and(b0, b1);
                        return b1;
                } else {
@@ -2040,18 +2116,17 @@ gen_ether_linktype(compiler_state_t *cstate, int proto)
                         * the length/type field with it (if
                         * the frame is an 802.2 frame, the length
                         * field will be <= ETHERMTU, and, as
-                        * "proto" is > ETHERMTU, this test
+                        * "ll_proto" is > ETHERMTU, this test
                         * will fail and the frame won't match,
                         * which is what we want).
                         */
-                       return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H,
-                           (bpf_int32)proto);
+                       return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, ll_proto);
                }
        }
 }
 
 static struct block *
-gen_loopback_linktype(compiler_state_t *cstate, int proto)
+gen_loopback_linktype(compiler_state_t *cstate, bpf_u_int32 ll_proto)
 {
        /*
         * For DLT_NULL, the link-layer header is a 32-bit word
@@ -2066,7 +2141,7 @@ gen_loopback_linktype(compiler_state_t *cstate, int proto)
         * For DLT_LOOP, the link-layer header is a 32-bit
         * word containing an AF_ value in *network* byte order.
         */
-       if (cstate->cgstate->linktype == DLT_NULL || cstate->cgstate->linktype == DLT_ENC) {
+       if (cstate->linktype == DLT_NULL || cstate->linktype == DLT_ENC) {
                /*
                 * The AF_ value is in host byte order, but the BPF
                 * interpreter will convert it to network byte order.
@@ -2079,10 +2154,10 @@ gen_loopback_linktype(compiler_state_t *cstate, int proto)
                 * code to compare against the result.
                 */
                if (cstate->bpf_pcap->rfile != NULL && cstate->bpf_pcap->swapped)
-                       proto = SWAPLONG(proto);
-               proto = htonl(proto);
+                       ll_proto = SWAPLONG(ll_proto);
+               ll_proto = htonl(ll_proto);
        }
-       return (gen_cmp(cstate, OR_LINKHDR, 0, BPF_W, (bpf_int32)proto));
+       return (gen_cmp(cstate, OR_LINKHDR, 0, BPF_W, ll_proto));
 }
 
 /*
@@ -2090,18 +2165,17 @@ gen_loopback_linktype(compiler_state_t *cstate, int proto)
  * or IPv6 then we have an error.
  */
 static struct block *
-gen_ipnet_linktype(compiler_state_t *cstate, int proto)
+gen_ipnet_linktype(compiler_state_t *cstate, bpf_u_int32 ll_proto)
 {
-       switch (proto) {
+       switch (ll_proto) {
 
        case ETHERTYPE_IP:
-               return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B, (bpf_int32)IPH_AF_INET);
-               /* NOTREACHED */
+               return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B, IPH_AF_INET);
+               /*NOTREACHED*/
 
        case ETHERTYPE_IPV6:
-               return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B,
-                   (bpf_int32)IPH_AF_INET6);
-               /* NOTREACHED */
+               return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B, IPH_AF_INET6);
+               /*NOTREACHED*/
 
        default:
                break;
@@ -2113,17 +2187,17 @@ gen_ipnet_linktype(compiler_state_t *cstate, int proto)
 /*
  * Generate code to match a particular packet type.
  *
- * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP
+ * "ll_proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP
  * value, if <= ETHERMTU.  We use that to determine whether to
  * match the type field or to check the type field for the special
  * LINUX_SLL_P_802_2 value and then do the appropriate test.
  */
 static struct block *
-gen_linux_sll_linktype(compiler_state_t *cstate, int proto)
+gen_linux_sll_linktype(compiler_state_t *cstate, bpf_u_int32 ll_proto)
 {
        struct block *b0, *b1;
 
-       switch (proto) {
+       switch (ll_proto) {
 
        case LLCSAP_ISONS:
        case LLCSAP_IP:
@@ -2141,8 +2215,7 @@ gen_linux_sll_linktype(compiler_state_t *cstate, int proto)
                 * (i.e., other SAP values)?
                 */
                b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, LINUX_SLL_P_802_2);
-               b1 = gen_cmp(cstate, OR_LLC, 0, BPF_H, (bpf_int32)
-                            ((proto << 8) | proto));
+               b1 = gen_cmp(cstate, OR_LLC, 0, BPF_H, (ll_proto << 8) | ll_proto);
                gen_and(b0, b1);
                return b1;
 
@@ -2172,7 +2245,7 @@ gen_linux_sll_linktype(compiler_state_t *cstate, int proto)
                 * then put a check for LINUX_SLL_P_802_2 frames
                 * before it.
                 */
-               b0 = gen_cmp(cstate, OR_LLC, 0, BPF_B, (bpf_int32)LLCSAP_IPX);
+               b0 = gen_cmp(cstate, OR_LLC, 0, BPF_B, LLCSAP_IPX);
                b1 = gen_snap(cstate, 0x000000, ETHERTYPE_IPX);
                gen_or(b0, b1);
                b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, LINUX_SLL_P_802_2);
@@ -2190,7 +2263,7 @@ gen_linux_sll_linktype(compiler_state_t *cstate, int proto)
                 * do that before checking for the other frame
                 * types.
                 */
-               b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, (bpf_int32)ETHERTYPE_IPX);
+               b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, ETHERTYPE_IPX);
                gen_or(b0, b1);
                return b1;
 
@@ -2219,9 +2292,9 @@ gen_linux_sll_linktype(compiler_state_t *cstate, int proto)
                 * 0x000000 (encapsulated Ethernet) and a protocol
                 * type of ETHERTYPE_AARP (Appletalk ARP).
                 */
-               if (proto == ETHERTYPE_ATALK)
+               if (ll_proto == ETHERTYPE_ATALK)
                        b1 = gen_snap(cstate, 0x080007, ETHERTYPE_ATALK);
-               else    /* proto == ETHERTYPE_AARP */
+               else    /* ll_proto == ETHERTYPE_AARP */
                        b1 = gen_snap(cstate, 0x000000, ETHERTYPE_AARP);
                gen_and(b0, b1);
 
@@ -2230,13 +2303,13 @@ gen_linux_sll_linktype(compiler_state_t *cstate, int proto)
                 * phase 1?); we just check for the Ethernet
                 * protocol type.
                 */
-               b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, (bpf_int32)proto);
+               b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, ll_proto);
 
                gen_or(b0, b1);
                return b1;
 
        default:
-               if (proto <= ETHERMTU) {
+               if (ll_proto <= ETHERMTU) {
                        /*
                         * This is an LLC SAP value, so the frames
                         * that match would be 802.2 frames.
@@ -2245,8 +2318,8 @@ gen_linux_sll_linktype(compiler_state_t *cstate, int proto)
                         * then check the DSAP.
                         */
                        b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, LINUX_SLL_P_802_2);
-                       b1 = gen_cmp(cstate, OR_LINKHDR, cstate->cgstate->off_linkpl.constant_part, BPF_B,
-                            (bpf_int32)proto);
+                       b1 = gen_cmp(cstate, OR_LINKHDR, cstate->off_linkpl.constant_part, BPF_B,
+                            ll_proto);
                        gen_and(b0, b1);
                        return b1;
                } else {
@@ -2255,15 +2328,68 @@ gen_linux_sll_linktype(compiler_state_t *cstate, int proto)
                         * the length/type field with it (if
                         * the frame is an 802.2 frame, the length
                         * field will be <= ETHERMTU, and, as
-                        * "proto" is > ETHERMTU, this test
+                        * "ll_proto" is > ETHERMTU, this test
                         * will fail and the frame won't match,
                         * which is what we want).
                         */
-                       return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, (bpf_int32)proto);
+                       return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, ll_proto);
                }
        }
 }
 
+/*
+ * Load a value relative to the beginning of the link-layer header after the
+ * pflog header.
+ */
+static struct slist *
+gen_load_pflog_llprefixlen(compiler_state_t *cstate)
+{
+       struct slist *s1, *s2;
+
+       /*
+        * Generate code to load the length of the pflog 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 (cstate->off_linkpl.reg != -1) {
+               /*
+                * The length is in the first byte of the header.
+                */
+               s1 = new_stmt(cstate, BPF_LD|BPF_B|BPF_ABS);
+               s1->s.k = 0;
+
+               /*
+                * Round it up to a multiple of 4.
+                * Add 3, and clear the lower 2 bits.
+                */
+               s2 = new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_K);
+               s2->s.k = 3;
+               sappend(s1, s2);
+               s2 = new_stmt(cstate, BPF_ALU|BPF_AND|BPF_K);
+               s2->s.k = 0xfffffffc;
+               sappend(s1, s2);
+
+               /*
+                * Now allocate a register to hold that value and store
+                * it.
+                */
+               s2 = new_stmt(cstate, BPF_ST);
+               s2->s.k = cstate->off_linkpl.reg;
+               sappend(s1, s2);
+
+               /*
+                * Now move it into the X register.
+                */
+               s2 = new_stmt(cstate, BPF_MISC|BPF_TAX);
+               sappend(s1, s2);
+
+               return (s1);
+       } else
+               return (NULL);
+}
+
 static struct slist *
 gen_load_prism_llprefixlen(compiler_state_t *cstate)
 {
@@ -2276,7 +2402,7 @@ gen_load_prism_llprefixlen(compiler_state_t *cstate)
         * we are generating jmp instructions within a normal
         * slist of instructions
         */
-       cstate->cgstate->no_optimize = 1;
+       cstate->no_optimize = 1;
 
        /*
         * Generate code to load the length of the radio header into
@@ -2297,7 +2423,7 @@ gen_load_prism_llprefixlen(compiler_state_t *cstate)
         * but no known software generates headers that aren't 144
         * bytes long.
         */
-       if (cstate->cgstate->off_linkhdr.reg != -1) {
+       if (cstate->off_linkhdr.reg != -1) {
                /*
                 * Load the cookie.
                 */
@@ -2359,7 +2485,7 @@ gen_load_prism_llprefixlen(compiler_state_t *cstate)
                 * loading the length of the AVS header.
                 */
                s2 = new_stmt(cstate, BPF_ST);
-               s2->s.k = cstate->cgstate->off_linkhdr.reg;
+               s2->s.k = cstate->off_linkhdr.reg;
                sappend(s1, s2);
                sjcommon->s.jf = s2;
 
@@ -2386,7 +2512,7 @@ gen_load_avs_llprefixlen(compiler_state_t *cstate)
         * generated uses that prefix, so we don't need to generate any
         * code to load it.)
         */
-       if (cstate->cgstate->off_linkhdr.reg != -1) {
+       if (cstate->off_linkhdr.reg != -1) {
                /*
                 * The 4 bytes at an offset of 4 from the beginning of
                 * the AVS header are the length of the AVS header.
@@ -2400,7 +2526,7 @@ gen_load_avs_llprefixlen(compiler_state_t *cstate)
                 * it.
                 */
                s2 = new_stmt(cstate, BPF_ST);
-               s2->s.k = cstate->cgstate->off_linkhdr.reg;
+               s2->s.k = cstate->off_linkhdr.reg;
                sappend(s1, s2);
 
                /*
@@ -2426,7 +2552,7 @@ gen_load_radiotap_llprefixlen(compiler_state_t *cstate)
         * generated uses that prefix, so we don't need to generate any
         * code to load it.)
         */
-       if (cstate->cgstate->off_linkhdr.reg != -1) {
+       if (cstate->off_linkhdr.reg != -1) {
                /*
                 * The 2 bytes at offsets of 2 and 3 from the beginning
                 * of the radiotap header are the length of the radiotap
@@ -2461,7 +2587,7 @@ gen_load_radiotap_llprefixlen(compiler_state_t *cstate)
                 * it.
                 */
                s2 = new_stmt(cstate, BPF_ST);
-               s2->s.k = cstate->cgstate->off_linkhdr.reg;
+               s2->s.k = cstate->off_linkhdr.reg;
                sappend(s1, s2);
 
                /*
@@ -2494,7 +2620,7 @@ gen_load_ppi_llprefixlen(compiler_state_t *cstate)
         * into the register assigned to hold that length, if one has
         * been assigned.
         */
-       if (cstate->cgstate->off_linkhdr.reg != -1) {
+       if (cstate->off_linkhdr.reg != -1) {
                /*
                 * The 2 bytes at offsets of 2 and 3 from the beginning
                 * of the radiotap header are the length of the radiotap
@@ -2529,7 +2655,7 @@ gen_load_ppi_llprefixlen(compiler_state_t *cstate)
                 * it.
                 */
                s2 = new_stmt(cstate, BPF_ST);
-               s2->s.k = cstate->cgstate->off_linkhdr.reg;
+               s2->s.k = cstate->off_linkhdr.reg;
                sappend(s1, s2);
 
                /*
@@ -2563,7 +2689,7 @@ gen_load_802_11_header_len(compiler_state_t *cstate, struct slist *s, struct sli
        struct slist *sjset_tsft_datapad, *sjset_notsft_datapad;
        struct slist *s_roundup;
 
-       if (cstate->cgstate->off_linkpl.reg == -1) {
+       if (cstate->off_linkpl.reg == -1) {
                /*
                 * No register has been assigned to the offset of
                 * the link-layer payload, which means nobody needs
@@ -2578,7 +2704,7 @@ gen_load_802_11_header_len(compiler_state_t *cstate, struct slist *s, struct sli
         * we are generating jmp instructions within a normal
         * slist of instructions
         */
-       cstate->cgstate->no_optimize = 1;
+       cstate->no_optimize = 1;
 
        /*
         * If "s" is non-null, it has code to arrange that the X register
@@ -2595,18 +2721,18 @@ gen_load_802_11_header_len(compiler_state_t *cstate, struct slist *s, struct sli
                 *
                 * Load the length of the fixed-length prefix preceding
                 * the link-layer header (if any) into the X register,
-                * and store it in the cstate->cgstate->off_linkpl.reg register.
+                * and store it in the cstate->off_linkpl.reg register.
                 * That length is off_outermostlinkhdr.constant_part.
                 */
                s = new_stmt(cstate, BPF_LDX|BPF_IMM);
-               s->s.k = cstate->cgstate->off_outermostlinkhdr.constant_part;
+               s->s.k = cstate->off_outermostlinkhdr.constant_part;
        }
 
        /*
         * 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 cstate->cgstate->off_linkpl.reg, and then load the Frame Control field,
+        * in cstate->off_linkpl.reg, and then load the Frame Control field,
         * which is at the offset in the X register, with an indexed load.
         */
        s2 = new_stmt(cstate, BPF_MISC|BPF_TXA);
@@ -2615,7 +2741,7 @@ gen_load_802_11_header_len(compiler_state_t *cstate, struct slist *s, struct sli
        s2->s.k = 24;
        sappend(s, s2);
        s2 = new_stmt(cstate, BPF_ST);
-       s2->s.k = cstate->cgstate->off_linkpl.reg;
+       s2->s.k = cstate->off_linkpl.reg;
        sappend(s, s2);
 
        s2 = new_stmt(cstate, BPF_LD|BPF_IND|BPF_B);
@@ -2651,19 +2777,19 @@ gen_load_802_11_header_len(compiler_state_t *cstate, struct slist *s, struct sli
        sappend(s, sjset_qos);
 
        /*
-        * If it's set, add 2 to cstate->cgstate->off_linkpl.reg, to skip the QoS
+        * If it's set, add 2 to cstate->off_linkpl.reg, to skip the QoS
         * field.
         * Otherwise, go to the first statement of the rest of the
         * program.
         */
        sjset_qos->s.jt = s2 = new_stmt(cstate, BPF_LD|BPF_MEM);
-       s2->s.k = cstate->cgstate->off_linkpl.reg;
+       s2->s.k = cstate->off_linkpl.reg;
        sappend(s, s2);
        s2 = new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_IMM);
        s2->s.k = 2;
        sappend(s, s2);
        s2 = new_stmt(cstate, BPF_ST);
-       s2->s.k = cstate->cgstate->off_linkpl.reg;
+       s2->s.k = cstate->off_linkpl.reg;
        sappend(s, s2);
 
        /*
@@ -2685,7 +2811,7 @@ gen_load_802_11_header_len(compiler_state_t *cstate, struct slist *s, struct sli
         * annoying padding don't have multiple antennae and therefore
         * do not generate radiotap headers with multiple presence words.
         */
-       if (cstate->cgstate->linktype == DLT_IEEE802_11_RADIO) {
+       if (cstate->linktype == DLT_IEEE802_11_RADIO) {
                /*
                 * Is the IEEE80211_RADIOTAP_FLAGS bit (0x0000002) set
                 * in the first presence flag word?
@@ -2767,16 +2893,16 @@ gen_load_802_11_header_len(compiler_state_t *cstate, struct slist *s, struct sli
                 * ANDing with ~3.
                 */
                s_roundup = new_stmt(cstate, BPF_LD|BPF_MEM);
-               s_roundup->s.k = cstate->cgstate->off_linkpl.reg;
+               s_roundup->s.k = cstate->off_linkpl.reg;
                sappend(s, s_roundup);
                s2 = new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_IMM);
                s2->s.k = 3;
                sappend(s, s2);
                s2 = new_stmt(cstate, BPF_ALU|BPF_AND|BPF_IMM);
-               s2->s.k = ~3;
+               s2->s.k = (bpf_u_int32)~3;
                sappend(s, s2);
                s2 = new_stmt(cstate, BPF_ST);
-               s2->s.k = cstate->cgstate->off_linkpl.reg;
+               s2->s.k = cstate->off_linkpl.reg;
                sappend(s, s2);
 
                sjset_tsft_datapad->s.jt = s_roundup;
@@ -2799,9 +2925,9 @@ insert_compute_vloffsets(compiler_state_t *cstate, struct block *b)
         * includes the variable part of the header. Therefore,
         * if nobody else has allocated a register for the link
         * header and we need it, do it now. */
-       if (cstate->cgstate->off_linkpl.reg != -1 && cstate->cgstate->off_linkhdr.is_variable &&
-           cstate->cgstate->off_linkhdr.reg == -1)
-               cstate->cgstate->off_linkhdr.reg = alloc_reg(cstate);
+       if (cstate->off_linkpl.reg != -1 && cstate->off_linkhdr.is_variable &&
+           cstate->off_linkhdr.reg == -1)
+               cstate->off_linkhdr.reg = alloc_reg(cstate);
 
        /*
         * For link-layer types that have a variable-length header
@@ -2814,7 +2940,7 @@ insert_compute_vloffsets(compiler_state_t *cstate, struct block *b)
         * some other protocol stack.  That's significantly more
         * complicated.
         */
-       switch (cstate->cgstate->outermostlinktype) {
+       switch (cstate->outermostlinktype) {
 
        case DLT_PRISM_HEADER:
                s = gen_load_prism_llprefixlen(cstate);
@@ -2842,7 +2968,7 @@ insert_compute_vloffsets(compiler_state_t *cstate, struct block *b)
         * header, generate code to load the offset of the link-layer
         * payload into the register assigned to that offset, if any.
         */
-       switch (cstate->cgstate->outermostlinktype) {
+       switch (cstate->outermostlinktype) {
 
        case DLT_IEEE802_11:
        case DLT_PRISM_HEADER:
@@ -2851,27 +2977,31 @@ insert_compute_vloffsets(compiler_state_t *cstate, struct block *b)
        case DLT_PPI:
                s = gen_load_802_11_header_len(cstate, s, b->stmts);
                break;
+
+       case DLT_PFLOG:
+               s = gen_load_pflog_llprefixlen(cstate);
+               break;
        }
 
        /*
-        * If there there is no initialization yet and we need variable
+        * If there is no initialization yet and we need variable
         * length offsets for VLAN, initialize them to zero
         */
-       if (s == NULL && cstate->cgstate->is_vlan_vloffset) {
+       if (s == NULL && cstate->is_vlan_vloffset) {
                struct slist *s2;
 
-               if (cstate->cgstate->off_linkpl.reg == -1)
-                       cstate->cgstate->off_linkpl.reg = alloc_reg(cstate);
-               if (cstate->cgstate->off_linktype.reg == -1)
-                       cstate->cgstate->off_linktype.reg = alloc_reg(cstate);
+               if (cstate->off_linkpl.reg == -1)
+                       cstate->off_linkpl.reg = alloc_reg(cstate);
+               if (cstate->off_linktype.reg == -1)
+                       cstate->off_linktype.reg = alloc_reg(cstate);
 
                s = new_stmt(cstate, BPF_LD|BPF_W|BPF_IMM);
                s->s.k = 0;
                s2 = new_stmt(cstate, BPF_ST);
-               s2->s.k = cstate->cgstate->off_linkpl.reg;
+               s2->s.k = cstate->off_linkpl.reg;
                sappend(s, s2);
                s2 = new_stmt(cstate, BPF_ST);
-               s2->s.k = cstate->cgstate->off_linktype.reg;
+               s2->s.k = cstate->off_linktype.reg;
                sappend(s, s2);
        }
 
@@ -2893,7 +3023,7 @@ gen_ppi_dlt_check(compiler_state_t *cstate)
        struct slist *s_load_dlt;
        struct block *b;
 
-       if (cstate->cgstate->linktype == DLT_PPI)
+       if (cstate->linktype == DLT_PPI)
        {
                /* Create the statements that check for the DLT
                 */
@@ -2960,33 +3090,33 @@ 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(int proto)
+static bpf_u_int32
+ethertype_to_ppptype(bpf_u_int32 ll_proto)
 {
-       switch (proto) {
+       switch (ll_proto) {
 
        case ETHERTYPE_IP:
-               proto = PPP_IP;
+               ll_proto = PPP_IP;
                break;
 
        case ETHERTYPE_IPV6:
-               proto = PPP_IPV6;
+               ll_proto = PPP_IPV6;
                break;
 
        case ETHERTYPE_DN:
-               proto = PPP_DECNET;
+               ll_proto = PPP_DECNET;
                break;
 
        case ETHERTYPE_ATALK:
-               proto = PPP_APPLE;
+               ll_proto = PPP_APPLE;
                break;
 
        case ETHERTYPE_NS:
-               proto = PPP_NS;
+               ll_proto = PPP_NS;
                break;
 
        case LLCSAP_ISONS:
-               proto = PPP_OSI;
+               ll_proto = PPP_OSI;
                break;
 
        case LLCSAP_8021D:
@@ -2995,14 +3125,14 @@ ethertype_to_ppptype(int proto)
                 * over PPP are Spanning Tree Protocol
                 * Bridging PDUs.
                 */
-               proto = PPP_BRPDU;
+               ll_proto = PPP_BRPDU;
                break;
 
        case LLCSAP_IPX:
-               proto = PPP_IPX;
+               ll_proto = PPP_IPX;
                break;
        }
-       return (proto);
+       return (ll_proto);
 }
 
 /*
@@ -3016,10 +3146,10 @@ gen_prevlinkhdr_check(compiler_state_t *cstate)
 {
        struct block *b0;
 
-       if (cstate->cgstate->is_geneve)
+       if (cstate->is_geneve)
                return gen_geneve_ll_check(cstate);
 
-       switch (cstate->cgstate->prevlinktype) {
+       switch (cstate->prevlinktype) {
 
        case DLT_SUNATM:
                /*
@@ -3058,62 +3188,45 @@ gen_prevlinkhdr_check(compiler_state_t *cstate)
  * value, if <= ETHERMTU.
  */
 static struct block *
-gen_linktype(compiler_state_t *cstate, int proto)
+gen_linktype(compiler_state_t *cstate, bpf_u_int32 ll_proto)
 {
        struct block *b0, *b1, *b2;
        const char *description;
 
        /* are we checking MPLS-encapsulated packets? */
-       if (cstate->cgstate->label_stack_depth > 0) {
-               switch (proto) {
-               case ETHERTYPE_IP:
-               case PPP_IP:
-                       /* FIXME add other L3 proto IDs */
-                       return gen_mpls_linktype(cstate, Q_IP);
-
-               case ETHERTYPE_IPV6:
-               case PPP_IPV6:
-                       /* FIXME add other L3 proto IDs */
-                       return gen_mpls_linktype(cstate, Q_IPV6);
-
-               default:
-                       bpf_error(cstate, "unsupported protocol over mpls");
-                       /* NOTREACHED */
-               }
-       }
+       if (cstate->label_stack_depth > 0)
+               return gen_mpls_linktype(cstate, ll_proto);
 
-       switch (cstate->cgstate->linktype) {
+       switch (cstate->linktype) {
 
        case DLT_EN10MB:
        case DLT_NETANALYZER:
        case DLT_NETANALYZER_TRANSPARENT:
                /* Geneve has an EtherType regardless of whether there is an
                 * L2 header. */
-               if (!cstate->cgstate->is_geneve)
+               if (!cstate->is_geneve)
                        b0 = gen_prevlinkhdr_check(cstate);
                else
                        b0 = NULL;
 
-               b1 = gen_ether_linktype(cstate, proto);
+               b1 = gen_ether_linktype(cstate, ll_proto);
                if (b0 != NULL)
                        gen_and(b0, b1);
                return b1;
                /*NOTREACHED*/
-               break;
 
        case DLT_C_HDLC:
-               switch (proto) {
+       case DLT_HDLC:
+               switch (ll_proto) {
 
                case LLCSAP_ISONS:
-                       proto = (proto << 8 | LLCSAP_ISONS);
+                       ll_proto = (ll_proto << 8 | LLCSAP_ISONS);
                        /* fall through */
 
                default:
-                       return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, (bpf_int32)proto);
+                       return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, ll_proto);
                        /*NOTREACHED*/
-                       break;
                }
-               break;
 
        case DLT_IEEE802_11:
        case DLT_PRISM_HEADER:
@@ -3128,34 +3241,30 @@ gen_linktype(compiler_state_t *cstate, int proto)
                /*
                 * Now check for the specified link-layer type.
                 */
-               b1 = gen_llc_linktype(cstate, proto);
+               b1 = gen_llc_linktype(cstate, ll_proto);
                gen_and(b0, b1);
                return b1;
                /*NOTREACHED*/
-               break;
 
        case DLT_FDDI:
                /*
                 * XXX - check for LLC frames.
                 */
-               return gen_llc_linktype(cstate, proto);
+               return gen_llc_linktype(cstate, ll_proto);
                /*NOTREACHED*/
-               break;
 
        case DLT_IEEE802:
                /*
                 * XXX - check for LLC PDUs, as per IEEE 802.5.
                 */
-               return gen_llc_linktype(cstate, proto);
+               return gen_llc_linktype(cstate, ll_proto);
                /*NOTREACHED*/
-               break;
 
        case DLT_ATM_RFC1483:
        case DLT_ATM_CLIP:
        case DLT_IP_OVER_FC:
-               return gen_llc_linktype(cstate, proto);
+               return gen_llc_linktype(cstate, ll_proto);
                /*NOTREACHED*/
-               break;
 
        case DLT_SUNATM:
                /*
@@ -3165,17 +3274,15 @@ gen_linktype(compiler_state_t *cstate, int proto)
                 *
                 * Check for LLC encapsulation and then check the protocol.
                 */
-               b0 = gen_atmfield_code(cstate, A_PROTOTYPE, PT_LLC, BPF_JEQ, 0);
-               b1 = gen_llc_linktype(cstate, proto);
+               b0 = gen_atmfield_code_internal(cstate, A_PROTOTYPE, PT_LLC, BPF_JEQ, 0);
+               b1 = gen_llc_linktype(cstate, ll_proto);
                gen_and(b0, b1);
                return b1;
                /*NOTREACHED*/
-               break;
 
        case DLT_LINUX_SLL:
-               return gen_linux_sll_linktype(cstate, proto);
+               return gen_linux_sll_linktype(cstate, ll_proto);
                /*NOTREACHED*/
-               break;
 
        case DLT_SLIP:
        case DLT_SLIP_BSDOS:
@@ -3187,7 +3294,7 @@ gen_linktype(compiler_state_t *cstate, int proto)
                 * XXX - for IPv4, check for a version number of 4, and,
                 * for IPv6, check for a version number of 6?
                 */
-               switch (proto) {
+               switch (ll_proto) {
 
                case ETHERTYPE_IP:
                        /* Check for a version number of 4. */
@@ -3201,31 +3308,28 @@ gen_linktype(compiler_state_t *cstate, int proto)
                        return gen_false(cstate);       /* always false */
                }
                /*NOTREACHED*/
-               break;
 
        case DLT_IPV4:
                /*
                 * Raw IPv4, so no type field.
                 */
-               if (proto == ETHERTYPE_IP)
+               if (ll_proto == ETHERTYPE_IP)
                        return gen_true(cstate);        /* always true */
 
                /* Checking for something other than IPv4; always false */
                return gen_false(cstate);
                /*NOTREACHED*/
-               break;
 
        case DLT_IPV6:
                /*
                 * Raw IPv6, so no type field.
                 */
-               if (proto == ETHERTYPE_IPV6)
+               if (ll_proto == ETHERTYPE_IPV6)
                        return gen_true(cstate);        /* always true */
 
                /* Checking for something other than IPv6; always false */
                return gen_false(cstate);
                /*NOTREACHED*/
-               break;
 
        case DLT_PPP:
        case DLT_PPP_PPPD:
@@ -3235,17 +3339,16 @@ gen_linktype(compiler_state_t *cstate, int proto)
                 * We use Ethernet protocol types inside libpcap;
                 * map them to the corresponding PPP protocol types.
                 */
-               proto = ethertype_to_ppptype(proto);
-               return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, (bpf_int32)proto);
+               return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H,
+                   ethertype_to_ppptype(ll_proto));
                /*NOTREACHED*/
-               break;
 
        case DLT_PPP_BSDOS:
                /*
                 * We use Ethernet protocol types inside libpcap;
                 * map them to the corresponding PPP protocol types.
                 */
-               switch (proto) {
+               switch (ll_proto) {
 
                case ETHERTYPE_IP:
                        /*
@@ -3260,17 +3363,15 @@ gen_linktype(compiler_state_t *cstate, int proto)
                        return b0;
 
                default:
-                       proto = ethertype_to_ppptype(proto);
                        return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H,
-                               (bpf_int32)proto);
+                           ethertype_to_ppptype(ll_proto));
                }
                /*NOTREACHED*/
-               break;
 
        case DLT_NULL:
        case DLT_LOOP:
        case DLT_ENC:
-               switch (proto) {
+               switch (ll_proto) {
 
                case ETHERTYPE_IP:
                        return (gen_loopback_linktype(cstate, AF_INET));
@@ -3345,23 +3446,20 @@ gen_linktype(compiler_state_t *cstate, int proto)
                        return gen_false(cstate);
                }
 
-#ifdef HAVE_NET_PFVAR_H
        case DLT_PFLOG:
                /*
                 * af field is host byte order in contrast to the rest of
                 * the packet.
                 */
-               if (proto == ETHERTYPE_IP)
+               if (ll_proto == ETHERTYPE_IP)
                        return (gen_cmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, af),
-                           BPF_B, (bpf_int32)AF_INET));
-               else if (proto == ETHERTYPE_IPV6)
+                           BPF_B, AF_INET));
+               else if (ll_proto == ETHERTYPE_IPV6)
                        return (gen_cmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, af),
-                           BPF_B, (bpf_int32)AF_INET6));
+                           BPF_B, AF_INET6));
                else
                        return gen_false(cstate);
                /*NOTREACHED*/
-               break;
-#endif /* HAVE_NET_PFVAR_H */
 
        case DLT_ARCNET:
        case DLT_ARCNET_LINUX:
@@ -3369,58 +3467,56 @@ gen_linktype(compiler_state_t *cstate, int proto)
                 * XXX should we check for first fragment if the protocol
                 * uses PHDS?
                 */
-               switch (proto) {
+               switch (ll_proto) {
 
                default:
                        return gen_false(cstate);
 
                case ETHERTYPE_IPV6:
                        return (gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B,
-                               (bpf_int32)ARCTYPE_INET6));
+                               ARCTYPE_INET6));
 
                case ETHERTYPE_IP:
                        b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B,
-                                    (bpf_int32)ARCTYPE_IP);
+                           ARCTYPE_IP);
                        b1 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B,
-                                    (bpf_int32)ARCTYPE_IP_OLD);
+                           ARCTYPE_IP_OLD);
                        gen_or(b0, b1);
                        return (b1);
 
                case ETHERTYPE_ARP:
                        b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B,
-                                    (bpf_int32)ARCTYPE_ARP);
+                           ARCTYPE_ARP);
                        b1 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B,
-                                    (bpf_int32)ARCTYPE_ARP_OLD);
+                           ARCTYPE_ARP_OLD);
                        gen_or(b0, b1);
                        return (b1);
 
                case ETHERTYPE_REVARP:
                        return (gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B,
-                                       (bpf_int32)ARCTYPE_REVARP));
+                           ARCTYPE_REVARP));
 
                case ETHERTYPE_ATALK:
                        return (gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B,
-                                       (bpf_int32)ARCTYPE_ATALK));
+                           ARCTYPE_ATALK));
                }
                /*NOTREACHED*/
-               break;
 
        case DLT_LTALK:
-               switch (proto) {
+               switch (ll_proto) {
                case ETHERTYPE_ATALK:
                        return gen_true(cstate);
                default:
                        return gen_false(cstate);
                }
                /*NOTREACHED*/
-               break;
 
        case DLT_FRELAY:
                /*
                 * XXX - assumes a 2-byte Frame Relay header with
                 * DLCI and flags.  What if the address is longer?
                 */
-               switch (proto) {
+               switch (ll_proto) {
 
                case ETHERTYPE_IP:
                        /*
@@ -3457,7 +3553,6 @@ gen_linktype(compiler_state_t *cstate, int proto)
                        return gen_false(cstate);
                }
                /*NOTREACHED*/
-               break;
 
        case DLT_MFR:
                bpf_error(cstate, "Multi-link Frame Relay link-layer type filtering not implemented");
@@ -3498,7 +3593,7 @@ gen_linktype(compiler_state_t *cstate, int proto)
                return gen_mcmp(cstate, OR_LINKHDR, 0, BPF_W, 0x55FF0000, 0xffff0000);
 
        case DLT_IPNET:
-               return gen_ipnet_linktype(cstate, proto);
+               return gen_ipnet_linktype(cstate, ll_proto);
 
        case DLT_LINUX_IRDA:
                bpf_error(cstate, "IrDA link-layer type filtering not implemented");
@@ -3537,6 +3632,7 @@ gen_linktype(compiler_state_t *cstate, int proto)
        case DLT_IEEE802_15_4_LINUX:
        case DLT_IEEE802_15_4_NONASK_PHY:
        case DLT_IEEE802_15_4_NOFCS:
+       case DLT_IEEE802_15_4_TAP:
                bpf_error(cstate, "IEEE 802.15.4 link-layer type filtering not implemented");
 
        case DLT_IEEE802_16_MAC_CPS_RADIO:
@@ -3548,7 +3644,8 @@ gen_linktype(compiler_state_t *cstate, int proto)
        case DLT_RAIF1:
                bpf_error(cstate, "RAIF1 link-layer type filtering not implemented");
 
-       case DLT_IPMB:
+       case DLT_IPMB_KONTRON:
+       case DLT_IPMB_LINUX:
                bpf_error(cstate, "IPMB link-layer type filtering not implemented");
 
        case DLT_AX25_KISS:
@@ -3568,27 +3665,23 @@ gen_linktype(compiler_state_t *cstate, int proto)
                 * so, off_linktype.constant_part will be the offset of that
                 * field in the packet; if not, it will be OFFSET_NOT_SET.
                 */
-               if (cstate->cgstate->off_linktype.constant_part != OFFSET_NOT_SET) {
+               if (cstate->off_linktype.constant_part != OFFSET_NOT_SET) {
                        /*
                         * Yes; assume it's an Ethernet type.  (If
                         * it's not, it needs to be handled specially
                         * above.)
                         */
-                       return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, (bpf_int32)proto);
+                       return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, ll_proto);
+                       /*NOTREACHED */
                } else {
                        /*
                         * No; report an error.
                         */
-                       description = pcap_datalink_val_to_description(cstate->cgstate->linktype);
-                       if (description != NULL) {
-                               bpf_error(cstate, "%s link-layer type filtering not implemented",
-                                   description);
-                       } else {
-                               bpf_error(cstate, "DLT %u link-layer type filtering not implemented",
-                                   cstate->cgstate->linktype);
-                       }
+                       description = pcap_datalink_val_to_description_or_dlt(cstate->linktype);
+                       bpf_error(cstate, "%s link-layer type filtering not implemented",
+                           description);
+                       /*NOTREACHED */
                }
-               break;
        }
 }
 
@@ -3618,12 +3711,12 @@ gen_snap(compiler_state_t *cstate, bpf_u_int32 orgcode, bpf_u_int32 ptype)
 /*
  * Generate code to match frames with an LLC header.
  */
-struct block *
-gen_llc(compiler_state_t *cstate)
+static struct block *
+gen_llc_internal(compiler_state_t *cstate)
 {
        struct block *b0, *b1;
 
-       switch (cstate->cgstate->linktype) {
+       switch (cstate->linktype) {
 
        case DLT_EN10MB:
                /*
@@ -3637,7 +3730,7 @@ gen_llc(compiler_state_t *cstate)
                 * Now check for the purported DSAP and SSAP not being
                 * 0xFF, to rule out NetWare-over-802.3.
                 */
-               b1 = gen_cmp(cstate, OR_LLC, 0, BPF_H, (bpf_int32)0xFFFF);
+               b1 = gen_cmp(cstate, OR_LLC, 0, BPF_H, 0xFFFF);
                gen_not(b1);
                gen_and(b0, b1);
                return b1;
@@ -3646,7 +3739,7 @@ gen_llc(compiler_state_t *cstate)
                /*
                 * We check for LLC traffic.
                 */
-               b0 = gen_atmtype_abbrev(cstate, A_LLC);
+               b0 = gen_atmtype_llc(cstate);
                return b0;
 
        case DLT_IEEE802:       /* Token Ring */
@@ -3684,21 +3777,42 @@ gen_llc(compiler_state_t *cstate)
                return b0;
 
        default:
-               bpf_error(cstate, "'llc' not supported for linktype %d", cstate->cgstate->linktype);
-               /* NOTREACHED */
+               bpf_error(cstate, "'llc' not supported for %s",
+                         pcap_datalink_val_to_description_or_dlt(cstate->linktype));
+               /*NOTREACHED*/
        }
 }
 
+struct block *
+gen_llc(compiler_state_t *cstate)
+{
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
+       return gen_llc_internal(cstate);
+}
+
 struct block *
 gen_llc_i(compiler_state_t *cstate)
 {
        struct block *b0, *b1;
        struct slist *s;
 
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
        /*
         * Check whether this is an LLC frame.
         */
-       b0 = gen_llc(cstate);
+       b0 = gen_llc_internal(cstate);
 
        /*
         * Load the control byte and test the low-order bit; it must
@@ -3718,10 +3832,17 @@ gen_llc_s(compiler_state_t *cstate)
 {
        struct block *b0, *b1;
 
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
        /*
         * Check whether this is an LLC frame.
         */
-       b0 = gen_llc(cstate);
+       b0 = gen_llc_internal(cstate);
 
        /*
         * Now compare the low-order 2 bit of the control byte against
@@ -3737,10 +3858,17 @@ gen_llc_u(compiler_state_t *cstate)
 {
        struct block *b0, *b1;
 
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
        /*
         * Check whether this is an LLC frame.
         */
-       b0 = gen_llc(cstate);
+       b0 = gen_llc_internal(cstate);
 
        /*
         * Now compare the low-order 2 bit of the control byte against
@@ -3756,10 +3884,17 @@ gen_llc_s_subtype(compiler_state_t *cstate, bpf_u_int32 subtype)
 {
        struct block *b0, *b1;
 
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
        /*
         * Check whether this is an LLC frame.
         */
-       b0 = gen_llc(cstate);
+       b0 = gen_llc_internal(cstate);
 
        /*
         * Now check for an S frame with the appropriate type.
@@ -3774,10 +3909,17 @@ gen_llc_u_subtype(compiler_state_t *cstate, bpf_u_int32 subtype)
 {
        struct block *b0, *b1;
 
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
        /*
         * Check whether this is an LLC frame.
         */
-       b0 = gen_llc(cstate);
+       b0 = gen_llc_internal(cstate);
 
        /*
         * Now check for a U frame with the appropriate type.
@@ -3800,12 +3942,12 @@ gen_llc_u_subtype(compiler_state_t *cstate, bpf_u_int32 subtype)
  * protocol ID in a SNAP header.
  */
 static struct block *
-gen_llc_linktype(compiler_state_t *cstate, int proto)
+gen_llc_linktype(compiler_state_t *cstate, bpf_u_int32 ll_proto)
 {
        /*
         * XXX - handle token-ring variable-length header.
         */
-       switch (proto) {
+       switch (ll_proto) {
 
        case LLCSAP_IP:
        case LLCSAP_ISONS:
@@ -3816,15 +3958,14 @@ gen_llc_linktype(compiler_state_t *cstate, int proto)
                 * DSAP, as we do for other SAP values?
                 */
                return gen_cmp(cstate, OR_LLC, 0, BPF_H, (bpf_u_int32)
-                            ((proto << 8) | proto));
+                            ((ll_proto << 8) | ll_proto));
 
        case LLCSAP_IPX:
                /*
                 * XXX - are there ever SNAP frames for IPX on
                 * non-Ethernet 802.x networks?
                 */
-               return gen_cmp(cstate, OR_LLC, 0, BPF_B,
-                   (bpf_int32)LLCSAP_IPX);
+               return gen_cmp(cstate, OR_LLC, 0, BPF_B, LLCSAP_IPX);
 
        case ETHERTYPE_ATALK:
                /*
@@ -3843,12 +3984,12 @@ gen_llc_linktype(compiler_state_t *cstate, int proto)
                 * XXX - we don't have to check for IPX 802.3
                 * here, but should we check for the IPX Ethertype?
                 */
-               if (proto <= ETHERMTU) {
+               if (ll_proto <= ETHERMTU) {
                        /*
                         * This is an LLC SAP value, so check
                         * the DSAP.
                         */
-                       return gen_cmp(cstate, OR_LLC, 0, BPF_B, (bpf_int32)proto);
+                       return gen_cmp(cstate, OR_LLC, 0, BPF_B, ll_proto);
                } else {
                        /*
                         * This is an Ethernet type; we assume that it's
@@ -3863,20 +4004,20 @@ gen_llc_linktype(compiler_state_t *cstate, int proto)
                         * organization code of 0x000000 (encapsulated
                         * Ethernet), we'd do
                         *
-                        *      return gen_snap(cstate, 0x000000, proto);
+                        *      return gen_snap(cstate, 0x000000, ll_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(cstate, OR_LLC, 6, BPF_H, (bpf_int32)proto);
+                       return gen_cmp(cstate, OR_LLC, 6, BPF_H, ll_proto);
                }
        }
 }
 
 static struct block *
 gen_hostop(compiler_state_t *cstate, bpf_u_int32 addr, bpf_u_int32 mask,
-    int dir, int proto, u_int src_off, u_int dst_off)
+    int dir, bpf_u_int32 ll_proto, u_int src_off, u_int dst_off)
 {
        struct block *b0, *b1;
        u_int offset;
@@ -3892,47 +4033,48 @@ gen_hostop(compiler_state_t *cstate, bpf_u_int32 addr, bpf_u_int32 mask,
                break;
 
        case Q_AND:
-               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);
+               b0 = gen_hostop(cstate, addr, mask, Q_SRC, ll_proto, src_off, dst_off);
+               b1 = gen_hostop(cstate, addr, mask, Q_DST, ll_proto, src_off, dst_off);
                gen_and(b0, b1);
                return b1;
 
        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);
+               b0 = gen_hostop(cstate, addr, mask, Q_SRC, ll_proto, src_off, dst_off);
+               b1 = gen_hostop(cstate, addr, mask, Q_DST, ll_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;
+               /*NOTREACHED*/
 
        case Q_ADDR2:
                bpf_error(cstate, "'addr2' and 'address2' are not valid qualifiers for addresses other than 802.11 MAC addresses");
-               break;
+               /*NOTREACHED*/
 
        case Q_ADDR3:
                bpf_error(cstate, "'addr3' and 'address3' are not valid qualifiers for addresses other than 802.11 MAC addresses");
-               break;
+               /*NOTREACHED*/
 
        case Q_ADDR4:
                bpf_error(cstate, "'addr4' and 'address4' are not valid qualifiers for addresses other than 802.11 MAC addresses");
-               break;
+               /*NOTREACHED*/
 
        case Q_RA:
                bpf_error(cstate, "'ra' is not a valid qualifier for addresses other than 802.11 MAC addresses");
-               break;
+               /*NOTREACHED*/
 
        case Q_TA:
                bpf_error(cstate, "'ta' is not a valid qualifier for addresses other than 802.11 MAC addresses");
-               break;
+               /*NOTREACHED*/
 
        default:
                abort();
+               /*NOTREACHED*/
        }
-       b0 = gen_linktype(cstate, proto);
-       b1 = gen_mcmp(cstate, OR_LINKPL, offset, BPF_W, (bpf_int32)addr, mask);
+       b0 = gen_linktype(cstate, ll_proto);
+       b1 = gen_mcmp(cstate, OR_LINKPL, offset, BPF_W, addr, mask);
        gen_and(b0, b1);
        return b1;
 }
@@ -3940,7 +4082,8 @@ gen_hostop(compiler_state_t *cstate, bpf_u_int32 addr, bpf_u_int32 mask,
 #ifdef INET6
 static struct block *
 gen_hostop6(compiler_state_t *cstate, struct in6_addr *addr,
-    struct in6_addr *mask, int dir, int proto, u_int src_off, u_int dst_off)
+    struct in6_addr *mask, int dir, bpf_u_int32 ll_proto, u_int src_off,
+    u_int dst_off)
 {
        struct block *b0, *b1;
        u_int offset;
@@ -3957,44 +4100,45 @@ gen_hostop6(compiler_state_t *cstate, struct in6_addr *addr,
                break;
 
        case Q_AND:
-               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);
+               b0 = gen_hostop6(cstate, addr, mask, Q_SRC, ll_proto, src_off, dst_off);
+               b1 = gen_hostop6(cstate, addr, mask, Q_DST, ll_proto, src_off, dst_off);
                gen_and(b0, b1);
                return b1;
 
        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);
+               b0 = gen_hostop6(cstate, addr, mask, Q_SRC, ll_proto, src_off, dst_off);
+               b1 = gen_hostop6(cstate, addr, mask, Q_DST, ll_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;
+               /*NOTREACHED*/
 
        case Q_ADDR2:
                bpf_error(cstate, "'addr2' and 'address2' are not valid qualifiers for addresses other than 802.11 MAC addresses");
-               break;
+               /*NOTREACHED*/
 
        case Q_ADDR3:
                bpf_error(cstate, "'addr3' and 'address3' are not valid qualifiers for addresses other than 802.11 MAC addresses");
-               break;
+               /*NOTREACHED*/
 
        case Q_ADDR4:
                bpf_error(cstate, "'addr4' and 'address4' are not valid qualifiers for addresses other than 802.11 MAC addresses");
-               break;
+               /*NOTREACHED*/
 
        case Q_RA:
                bpf_error(cstate, "'ra' is not a valid qualifier for addresses other than 802.11 MAC addresses");
-               break;
+               /*NOTREACHED*/
 
        case Q_TA:
                bpf_error(cstate, "'ta' is not a valid qualifier for addresses other than 802.11 MAC addresses");
-               break;
+               /*NOTREACHED*/
 
        default:
                abort();
+               /*NOTREACHED*/
        }
        /* this order is important */
        a = (uint32_t *)addr;
@@ -4006,7 +4150,7 @@ gen_hostop6(compiler_state_t *cstate, struct in6_addr *addr,
        gen_and(b0, b1);
        b0 = gen_mcmp(cstate, OR_LINKPL, offset + 0, BPF_W, ntohl(a[0]), ntohl(m[0]));
        gen_and(b0, b1);
-       b0 = gen_linktype(cstate, proto);
+       b0 = gen_linktype(cstate, ll_proto);
        gen_and(b0, b1);
        return b1;
 }
@@ -4039,30 +4183,30 @@ gen_ehostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
 
        case Q_ADDR1:
                bpf_error(cstate, "'addr1' and 'address1' are only supported on 802.11 with 802.11 headers");
-               break;
+               /*NOTREACHED*/
 
        case Q_ADDR2:
                bpf_error(cstate, "'addr2' and 'address2' are only supported on 802.11 with 802.11 headers");
-               break;
+               /*NOTREACHED*/
 
        case Q_ADDR3:
                bpf_error(cstate, "'addr3' and 'address3' are only supported on 802.11 with 802.11 headers");
-               break;
+               /*NOTREACHED*/
 
        case Q_ADDR4:
                bpf_error(cstate, "'addr4' and 'address4' are only supported on 802.11 with 802.11 headers");
-               break;
+               /*NOTREACHED*/
 
        case Q_RA:
                bpf_error(cstate, "'ra' is only supported on 802.11 with 802.11 headers");
-               break;
+               /*NOTREACHED*/
 
        case Q_TA:
                bpf_error(cstate, "'ta' is only supported on 802.11 with 802.11 headers");
-               break;
+               /*NOTREACHED*/
        }
        abort();
-       /* NOTREACHED */
+       /*NOTREACHED*/
 }
 
 /*
@@ -4075,10 +4219,10 @@ gen_fhostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
 
        switch (dir) {
        case Q_SRC:
-               return gen_bcmp(cstate, OR_LINKHDR, 6 + 1 + cstate->cgstate->pcap_fddipad, 6, eaddr);
+               return gen_bcmp(cstate, OR_LINKHDR, 6 + 1 + cstate->pcap_fddipad, 6, eaddr);
 
        case Q_DST:
-               return gen_bcmp(cstate, OR_LINKHDR, 0 + 1 + cstate->cgstate->pcap_fddipad, 6, eaddr);
+               return gen_bcmp(cstate, OR_LINKHDR, 0 + 1 + cstate->pcap_fddipad, 6, eaddr);
 
        case Q_AND:
                b0 = gen_fhostop(cstate, eaddr, Q_SRC);
@@ -4095,30 +4239,30 @@ gen_fhostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
 
        case Q_ADDR1:
                bpf_error(cstate, "'addr1' and 'address1' are only supported on 802.11");
-               break;
+               /*NOTREACHED*/
 
        case Q_ADDR2:
                bpf_error(cstate, "'addr2' and 'address2' are only supported on 802.11");
-               break;
+               /*NOTREACHED*/
 
        case Q_ADDR3:
                bpf_error(cstate, "'addr3' and 'address3' are only supported on 802.11");
-               break;
+               /*NOTREACHED*/
 
        case Q_ADDR4:
                bpf_error(cstate, "'addr4' and 'address4' are only supported on 802.11");
-               break;
+               /*NOTREACHED*/
 
        case Q_RA:
                bpf_error(cstate, "'ra' is only supported on 802.11");
-               break;
+               /*NOTREACHED*/
 
        case Q_TA:
                bpf_error(cstate, "'ta' is only supported on 802.11");
-               break;
+               /*NOTREACHED*/
        }
        abort();
-       /* NOTREACHED */
+       /*NOTREACHED*/
 }
 
 /*
@@ -4151,30 +4295,30 @@ gen_thostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
 
        case Q_ADDR1:
                bpf_error(cstate, "'addr1' and 'address1' are only supported on 802.11");
-               break;
+               /*NOTREACHED*/
 
        case Q_ADDR2:
                bpf_error(cstate, "'addr2' and 'address2' are only supported on 802.11");
-               break;
+               /*NOTREACHED*/
 
        case Q_ADDR3:
                bpf_error(cstate, "'addr3' and 'address3' are only supported on 802.11");
-               break;
+               /*NOTREACHED*/
 
        case Q_ADDR4:
                bpf_error(cstate, "'addr4' and 'address4' are only supported on 802.11");
-               break;
+               /*NOTREACHED*/
 
        case Q_RA:
                bpf_error(cstate, "'ra' is only supported on 802.11");
-               break;
+               /*NOTREACHED*/
 
        case Q_TA:
                bpf_error(cstate, "'ta' is only supported on 802.11");
-               break;
+               /*NOTREACHED*/
        }
        abort();
-       /* NOTREACHED */
+       /*NOTREACHED*/
 }
 
 /*
@@ -4194,7 +4338,7 @@ gen_wlanhostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
         * and wipes out some LD instructions generated by the below
         * code to validate the Frame Control bits
         */
-       cstate->cgstate->no_optimize = 1;
+       cstate->no_optimize = 1;
 #endif /* ENABLE_WLAN_FILTERING_PATCH */
 
        switch (dir) {
@@ -4597,7 +4741,7 @@ gen_wlanhostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
                return b1;
        }
        abort();
-       /* NOTREACHED */
+       /*NOTREACHED*/
 }
 
 /*
@@ -4632,30 +4776,30 @@ gen_ipfchostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
 
        case Q_ADDR1:
                bpf_error(cstate, "'addr1' and 'address1' are only supported on 802.11");
-               break;
+               /*NOTREACHED*/
 
        case Q_ADDR2:
                bpf_error(cstate, "'addr2' and 'address2' are only supported on 802.11");
-               break;
+               /*NOTREACHED*/
 
        case Q_ADDR3:
                bpf_error(cstate, "'addr3' and 'address3' are only supported on 802.11");
-               break;
+               /*NOTREACHED*/
 
        case Q_ADDR4:
                bpf_error(cstate, "'addr4' and 'address4' are only supported on 802.11");
-               break;
+               /*NOTREACHED*/
 
        case Q_RA:
                bpf_error(cstate, "'ra' is only supported on 802.11");
-               break;
+               /*NOTREACHED*/
 
        case Q_TA:
                bpf_error(cstate, "'ta' is only supported on 802.11");
-               break;
+               /*NOTREACHED*/
        }
        abort();
-       /* NOTREACHED */
+       /*NOTREACHED*/
 }
 
 /*
@@ -4712,56 +4856,62 @@ gen_dnhostop(compiler_state_t *cstate, bpf_u_int32 addr, int dir)
 
        case Q_ADDR1:
                bpf_error(cstate, "'addr1' and 'address1' are not valid qualifiers for addresses other than 802.11 MAC addresses");
-               break;
+               /*NOTREACHED*/
 
        case Q_ADDR2:
                bpf_error(cstate, "'addr2' and 'address2' are not valid qualifiers for addresses other than 802.11 MAC addresses");
-               break;
+               /*NOTREACHED*/
 
        case Q_ADDR3:
                bpf_error(cstate, "'addr3' and 'address3' are not valid qualifiers for addresses other than 802.11 MAC addresses");
-               break;
+               /*NOTREACHED*/
 
        case Q_ADDR4:
                bpf_error(cstate, "'addr4' and 'address4' are not valid qualifiers for addresses other than 802.11 MAC addresses");
-               break;
+               /*NOTREACHED*/
 
        case Q_RA:
                bpf_error(cstate, "'ra' is not a valid qualifier for addresses other than 802.11 MAC addresses");
-               break;
+               /*NOTREACHED*/
 
        case Q_TA:
                bpf_error(cstate, "'ta' is not a valid qualifier for addresses other than 802.11 MAC addresses");
-               break;
+               /*NOTREACHED*/
 
        default:
                abort();
+               /*NOTREACHED*/
        }
        b0 = gen_linktype(cstate, ETHERTYPE_DN);
        /* Check for pad = 1, long header case */
        tmp = gen_mcmp(cstate, OR_LINKPL, 2, BPF_H,
-           (bpf_int32)ntohs(0x0681), (bpf_int32)ntohs(0x07FF));
+           (bpf_u_int32)ntohs(0x0681), (bpf_u_int32)ntohs(0x07FF));
        b1 = gen_cmp(cstate, OR_LINKPL, 2 + 1 + offset_lh,
-           BPF_H, (bpf_int32)ntohs((u_short)addr));
+           BPF_H, (bpf_u_int32)ntohs((u_short)addr));
        gen_and(tmp, b1);
        /* Check for pad = 0, long header case */
-       tmp = gen_mcmp(cstate, OR_LINKPL, 2, BPF_B, (bpf_int32)0x06, (bpf_int32)0x7);
-       b2 = gen_cmp(cstate, OR_LINKPL, 2 + offset_lh, BPF_H, (bpf_int32)ntohs((u_short)addr));
+       tmp = gen_mcmp(cstate, OR_LINKPL, 2, BPF_B, (bpf_u_int32)0x06,
+           (bpf_u_int32)0x7);
+       b2 = gen_cmp(cstate, OR_LINKPL, 2 + offset_lh, BPF_H,
+           (bpf_u_int32)ntohs((u_short)addr));
        gen_and(tmp, b2);
        gen_or(b2, b1);
        /* Check for pad = 1, short header case */
        tmp = gen_mcmp(cstate, OR_LINKPL, 2, BPF_H,
-           (bpf_int32)ntohs(0x0281), (bpf_int32)ntohs(0x07FF));
-       b2 = gen_cmp(cstate, OR_LINKPL, 2 + 1 + offset_sh, BPF_H, (bpf_int32)ntohs((u_short)addr));
+           (bpf_u_int32)ntohs(0x0281), (bpf_u_int32)ntohs(0x07FF));
+       b2 = gen_cmp(cstate, OR_LINKPL, 2 + 1 + offset_sh, BPF_H,
+           (bpf_u_int32)ntohs((u_short)addr));
        gen_and(tmp, b2);
        gen_or(b2, b1);
        /* Check for pad = 0, short header case */
-       tmp = gen_mcmp(cstate, OR_LINKPL, 2, BPF_B, (bpf_int32)0x02, (bpf_int32)0x7);
-       b2 = gen_cmp(cstate, OR_LINKPL, 2 + offset_sh, BPF_H, (bpf_int32)ntohs((u_short)addr));
+       tmp = gen_mcmp(cstate, OR_LINKPL, 2, BPF_B, (bpf_u_int32)0x02,
+           (bpf_u_int32)0x7);
+       b2 = gen_cmp(cstate, OR_LINKPL, 2 + offset_sh, BPF_H,
+           (bpf_u_int32)ntohs((u_short)addr));
        gen_and(tmp, b2);
        gen_or(b2, b1);
 
-       /* Combine with test for cstate->cgstate->linktype */
+       /* Combine with test for cstate->linktype */
        gen_and(b0, b1);
        return b1;
 }
@@ -4772,13 +4922,13 @@ gen_dnhostop(compiler_state_t *cstate, bpf_u_int32 addr, int dir)
  * field in the IP header.
  */
 static struct block *
-gen_mpls_linktype(compiler_state_t *cstate, int proto)
+gen_mpls_linktype(compiler_state_t *cstate, bpf_u_int32 ll_proto)
 {
        struct block *b0, *b1;
 
-        switch (proto) {
+        switch (ll_proto) {
 
-        case Q_IP:
+        case ETHERTYPE_IP:
                 /* match the bottom-of-stack bit */
                 b0 = gen_mcmp(cstate, OR_LINKPL, (u_int)-2, BPF_B, 0x01, 0x01);
                 /* match the IPv4 version number */
@@ -4786,7 +4936,7 @@ gen_mpls_linktype(compiler_state_t *cstate, int proto)
                 gen_and(b0, b1);
                 return b1;
 
-       case Q_IPV6:
+        case ETHERTYPE_IPV6:
                 /* match the bottom-of-stack bit */
                 b0 = gen_mcmp(cstate, OR_LINKPL, (u_int)-2, BPF_B, 0x01, 0x01);
                 /* match the IPv4 version number */
@@ -4794,8 +4944,10 @@ gen_mpls_linktype(compiler_state_t *cstate, int proto)
                 gen_and(b0, b1);
                 return b1;
 
-       default:
-                abort();
+        default:
+               /* FIXME add other L3 proto IDs */
+               bpf_error(cstate, "unsupported protocol over mpls");
+               /*NOTREACHED*/
         }
 }
 
@@ -4819,7 +4971,7 @@ gen_host(compiler_state_t *cstate, bpf_u_int32 addr, bpf_u_int32 mask,
                 * Only check for non-IPv4 addresses if we're not
                 * checking MPLS-encapsulated packets.
                 */
-               if (cstate->cgstate->label_stack_depth == 0) {
+               if (cstate->label_stack_depth == 0) {
                        b1 = gen_host(cstate, addr, mask, Q_ARP, dir, type);
                        gen_or(b0, b1);
                        b0 = gen_host(cstate, addr, mask, Q_RARP, dir, type);
@@ -4947,7 +5099,7 @@ gen_host(compiler_state_t *cstate, bpf_u_int32 addr, bpf_u_int32 mask,
        default:
                abort();
        }
-       /* NOTREACHED */
+       /*NOTREACHED*/
 }
 
 #ifdef INET6
@@ -5087,7 +5239,7 @@ gen_host6(compiler_state_t *cstate, struct in6_addr *addr,
        default:
                abort();
        }
-       /* NOTREACHED */
+       /*NOTREACHED*/
 }
 #endif
 
@@ -5108,7 +5260,7 @@ gen_gateway(compiler_state_t *cstate, const u_char *eaddr,
        case Q_IP:
        case Q_ARP:
        case Q_RARP:
-               switch (cstate->cgstate->linktype) {
+               switch (cstate->linktype) {
                case DLT_EN10MB:
                case DLT_NETANALYZER:
                case DLT_NETANALYZER_TRANSPARENT:
@@ -5133,7 +5285,7 @@ gen_gateway(compiler_state_t *cstate, const u_char *eaddr,
                case DLT_SUNATM:
                        /*
                         * This is LLC-multiplexed traffic; if it were
-                        * LANE, cstate->cgstate->linktype would have been set to
+                        * LANE, cstate->linktype would have been set to
                         * DLT_EN10MB.
                         */
                        bpf_error(cstate,
@@ -5194,12 +5346,12 @@ gen_gateway(compiler_state_t *cstate, const u_char *eaddr,
                return b1;
        }
        bpf_error(cstate, "illegal modifier of 'gateway'");
-       /* NOTREACHED */
+       /*NOTREACHED*/
 }
 #endif
 
-struct block *
-gen_proto_abbrev(compiler_state_t *cstate, int proto)
+static struct block *
+gen_proto_abbrev_internal(compiler_state_t *cstate, int proto)
 {
        struct block *b0;
        struct block *b1;
@@ -5207,21 +5359,15 @@ gen_proto_abbrev(compiler_state_t *cstate, int proto)
        switch (proto) {
 
        case Q_SCTP:
-               b1 = gen_proto(cstate, IPPROTO_SCTP, Q_IP, Q_DEFAULT);
-               b0 = gen_proto(cstate, IPPROTO_SCTP, Q_IPV6, Q_DEFAULT);
-               gen_or(b0, b1);
+               b1 = gen_proto(cstate, IPPROTO_SCTP, Q_DEFAULT, Q_DEFAULT);
                break;
 
        case Q_TCP:
-               b1 = gen_proto(cstate, IPPROTO_TCP, Q_IP, Q_DEFAULT);
-               b0 = gen_proto(cstate, IPPROTO_TCP, Q_IPV6, Q_DEFAULT);
-               gen_or(b0, b1);
+               b1 = gen_proto(cstate, IPPROTO_TCP, Q_DEFAULT, Q_DEFAULT);
                break;
 
        case Q_UDP:
-               b1 = gen_proto(cstate, IPPROTO_UDP, Q_IP, Q_DEFAULT);
-               b0 = gen_proto(cstate, IPPROTO_UDP, Q_IPV6, Q_DEFAULT);
-               gen_or(b0, b1);
+               b1 = gen_proto(cstate, IPPROTO_UDP, Q_DEFAULT, Q_DEFAULT);
                break;
 
        case Q_ICMP:
@@ -5248,9 +5394,7 @@ gen_proto_abbrev(compiler_state_t *cstate, int proto)
 #endif
 
        case Q_PIM:
-               b1 = gen_proto(cstate, IPPROTO_PIM, Q_IP, Q_DEFAULT);
-               b0 = gen_proto(cstate, IPPROTO_PIM, Q_IPV6, Q_DEFAULT);
-               gen_or(b0, b1);
+               b1 = gen_proto(cstate, IPPROTO_PIM, Q_DEFAULT, Q_DEFAULT);
                break;
 
 #ifndef IPPROTO_VRRP
@@ -5327,18 +5471,14 @@ gen_proto_abbrev(compiler_state_t *cstate, int proto)
 #define IPPROTO_AH     51
 #endif
        case Q_AH:
-               b1 = gen_proto(cstate, IPPROTO_AH, Q_IP, Q_DEFAULT);
-               b0 = gen_proto(cstate, IPPROTO_AH, Q_IPV6, Q_DEFAULT);
-               gen_or(b0, b1);
+               b1 = gen_proto(cstate, IPPROTO_AH, Q_DEFAULT, Q_DEFAULT);
                break;
 
 #ifndef IPPROTO_ESP
 #define IPPROTO_ESP    50
 #endif
        case Q_ESP:
-               b1 = gen_proto(cstate, IPPROTO_ESP, Q_IP, Q_DEFAULT);
-               b0 = gen_proto(cstate, IPPROTO_ESP, Q_IPV6, Q_DEFAULT);
-               gen_or(b0, b1);
+               b1 = gen_proto(cstate, IPPROTO_ESP, Q_DEFAULT, Q_DEFAULT);
                break;
 
        case Q_ISO:
@@ -5438,6 +5578,19 @@ gen_proto_abbrev(compiler_state_t *cstate, int proto)
        return b1;
 }
 
+struct block *
+gen_proto_abbrev(compiler_state_t *cstate, int proto)
+{
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
+       return gen_proto_abbrev_internal(cstate, proto);
+}
+
 static struct block *
 gen_ipfrag(compiler_state_t *cstate)
 {
@@ -5464,75 +5617,76 @@ gen_ipfrag(compiler_state_t *cstate)
  * headers).
  */
 static struct block *
-gen_portatom(compiler_state_t *cstate, int off, bpf_int32 v)
+gen_portatom(compiler_state_t *cstate, int off, bpf_u_int32 v)
 {
        return gen_cmp(cstate, OR_TRAN_IPV4, off, BPF_H, v);
 }
 
 static struct block *
-gen_portatom6(compiler_state_t *cstate, int off, bpf_int32 v)
+gen_portatom6(compiler_state_t *cstate, int off, bpf_u_int32 v)
 {
        return gen_cmp(cstate, OR_TRAN_IPV6, off, BPF_H, v);
 }
 
-struct block *
-gen_portop(compiler_state_t *cstate, int port, int proto, int dir)
+static struct block *
+gen_portop(compiler_state_t *cstate, u_int port, u_int proto, int dir)
 {
        struct block *b0, *b1, *tmp;
 
        /* ip proto 'proto' and not a fragment other than the first fragment */
-       tmp = gen_cmp(cstate, OR_LINKPL, 9, BPF_B, (bpf_int32)proto);
+       tmp = gen_cmp(cstate, OR_LINKPL, 9, BPF_B, proto);
        b0 = gen_ipfrag(cstate);
        gen_and(tmp, b0);
 
        switch (dir) {
        case Q_SRC:
-               b1 = gen_portatom(cstate, 0, (bpf_int32)port);
+               b1 = gen_portatom(cstate, 0, port);
                break;
 
        case Q_DST:
-               b1 = gen_portatom(cstate, 2, (bpf_int32)port);
+               b1 = gen_portatom(cstate, 2, port);
                break;
 
        case Q_AND:
-               tmp = gen_portatom(cstate, 0, (bpf_int32)port);
-               b1 = gen_portatom(cstate, 2, (bpf_int32)port);
+               tmp = gen_portatom(cstate, 0, port);
+               b1 = gen_portatom(cstate, 2, port);
                gen_and(tmp, b1);
                break;
 
        case Q_DEFAULT:
        case Q_OR:
-               tmp = gen_portatom(cstate, 0, (bpf_int32)port);
-               b1 = gen_portatom(cstate, 2, (bpf_int32)port);
+               tmp = gen_portatom(cstate, 0, port);
+               b1 = gen_portatom(cstate, 2, port);
                gen_or(tmp, b1);
                break;
 
        case Q_ADDR1:
                bpf_error(cstate, "'addr1' and 'address1' are not valid qualifiers for ports");
-               break;
+               /*NOTREACHED*/
 
        case Q_ADDR2:
                bpf_error(cstate, "'addr2' and 'address2' are not valid qualifiers for ports");
-               break;
+               /*NOTREACHED*/
 
        case Q_ADDR3:
                bpf_error(cstate, "'addr3' and 'address3' are not valid qualifiers for ports");
-               break;
+               /*NOTREACHED*/
 
        case Q_ADDR4:
                bpf_error(cstate, "'addr4' and 'address4' are not valid qualifiers for ports");
-               break;
+               /*NOTREACHED*/
 
        case Q_RA:
                bpf_error(cstate, "'ra' is not a valid qualifier for ports");
-               break;
+               /*NOTREACHED*/
 
        case Q_TA:
                bpf_error(cstate, "'ta' is not a valid qualifier for ports");
-               break;
+               /*NOTREACHED*/
 
        default:
                abort();
+               /*NOTREACHED*/
        }
        gen_and(b0, b1);
 
@@ -5540,7 +5694,7 @@ gen_portop(compiler_state_t *cstate, int port, int proto, int dir)
 }
 
 static struct block *
-gen_port(compiler_state_t *cstate, int port, int ip_proto, int dir)
+gen_port(compiler_state_t *cstate, u_int port, int ip_proto, int dir)
 {
        struct block *b0, *b1, *tmp;
 
@@ -5567,7 +5721,7 @@ gen_port(compiler_state_t *cstate, int port, int ip_proto, int dir)
        case IPPROTO_UDP:
        case IPPROTO_TCP:
        case IPPROTO_SCTP:
-               b1 = gen_portop(cstate, port, ip_proto, dir);
+               b1 = gen_portop(cstate, port, (u_int)ip_proto, dir);
                break;
 
        case PROTO_UNDEF:
@@ -5586,33 +5740,33 @@ gen_port(compiler_state_t *cstate, int port, int ip_proto, int dir)
 }
 
 struct block *
-gen_portop6(compiler_state_t *cstate, int port, int proto, int dir)
+gen_portop6(compiler_state_t *cstate, u_int port, u_int proto, int dir)
 {
        struct block *b0, *b1, *tmp;
 
        /* ip6 proto 'proto' */
        /* XXX - catch the first fragment of a fragmented packet? */
-       b0 = gen_cmp(cstate, OR_LINKPL, 6, BPF_B, (bpf_int32)proto);
+       b0 = gen_cmp(cstate, OR_LINKPL, 6, BPF_B, proto);
 
        switch (dir) {
        case Q_SRC:
-               b1 = gen_portatom6(cstate, 0, (bpf_int32)port);
+               b1 = gen_portatom6(cstate, 0, port);
                break;
 
        case Q_DST:
-               b1 = gen_portatom6(cstate, 2, (bpf_int32)port);
+               b1 = gen_portatom6(cstate, 2, port);
                break;
 
        case Q_AND:
-               tmp = gen_portatom6(cstate, 0, (bpf_int32)port);
-               b1 = gen_portatom6(cstate, 2, (bpf_int32)port);
+               tmp = gen_portatom6(cstate, 0, port);
+               b1 = gen_portatom6(cstate, 2, port);
                gen_and(tmp, b1);
                break;
 
        case Q_DEFAULT:
        case Q_OR:
-               tmp = gen_portatom6(cstate, 0, (bpf_int32)port);
-               b1 = gen_portatom6(cstate, 2, (bpf_int32)port);
+               tmp = gen_portatom6(cstate, 0, port);
+               b1 = gen_portatom6(cstate, 2, port);
                gen_or(tmp, b1);
                break;
 
@@ -5625,7 +5779,7 @@ gen_portop6(compiler_state_t *cstate, int port, int proto, int dir)
 }
 
 static struct block *
-gen_port6(compiler_state_t *cstate, int port, int ip_proto, int dir)
+gen_port6(compiler_state_t *cstate, u_int port, int ip_proto, int dir)
 {
        struct block *b0, *b1, *tmp;
 
@@ -5636,7 +5790,7 @@ gen_port6(compiler_state_t *cstate, int port, int ip_proto, int dir)
        case IPPROTO_UDP:
        case IPPROTO_TCP:
        case IPPROTO_SCTP:
-               b1 = gen_portop6(cstate, port, ip_proto, dir);
+               b1 = gen_portop6(cstate, port, (u_int)ip_proto, dir);
                break;
 
        case PROTO_UNDEF:
@@ -5656,8 +5810,8 @@ gen_port6(compiler_state_t *cstate, int port, int ip_proto, int dir)
 
 /* gen_portrange code */
 static struct block *
-gen_portrangeatom(compiler_state_t *cstate, int off, bpf_int32 v1,
-    bpf_int32 v2)
+gen_portrangeatom(compiler_state_t *cstate, u_int off, bpf_u_int32 v1,
+    bpf_u_int32 v2)
 {
        struct block *b1, *b2;
 
@@ -5665,7 +5819,7 @@ gen_portrangeatom(compiler_state_t *cstate, int off, bpf_int32 v1,
                /*
                 * Reverse the order of the ports, so v1 is the lower one.
                 */
-               bpf_int32 vtemp;
+               bpf_u_int32 vtemp;
 
                vtemp = v1;
                v1 = v2;
@@ -5680,65 +5834,66 @@ gen_portrangeatom(compiler_state_t *cstate, int off, bpf_int32 v1,
        return b2;
 }
 
-struct block *
-gen_portrangeop(compiler_state_t *cstate, int port1, int port2, int proto,
-    int dir)
+static struct block *
+gen_portrangeop(compiler_state_t *cstate, u_int port1, u_int port2,
+    bpf_u_int32 proto, int dir)
 {
        struct block *b0, *b1, *tmp;
 
        /* ip proto 'proto' and not a fragment other than the first fragment */
-       tmp = gen_cmp(cstate, OR_LINKPL, 9, BPF_B, (bpf_int32)proto);
+       tmp = gen_cmp(cstate, OR_LINKPL, 9, BPF_B, proto);
        b0 = gen_ipfrag(cstate);
        gen_and(tmp, b0);
 
        switch (dir) {
        case Q_SRC:
-               b1 = gen_portrangeatom(cstate, 0, (bpf_int32)port1, (bpf_int32)port2);
+               b1 = gen_portrangeatom(cstate, 0, port1, port2);
                break;
 
        case Q_DST:
-               b1 = gen_portrangeatom(cstate, 2, (bpf_int32)port1, (bpf_int32)port2);
+               b1 = gen_portrangeatom(cstate, 2, port1, port2);
                break;
 
        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);
+               tmp = gen_portrangeatom(cstate, 0, port1, port2);
+               b1 = gen_portrangeatom(cstate, 2, port1, port2);
                gen_and(tmp, b1);
                break;
 
        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);
+               tmp = gen_portrangeatom(cstate, 0, port1, port2);
+               b1 = gen_portrangeatom(cstate, 2, port1, port2);
                gen_or(tmp, b1);
                break;
 
        case Q_ADDR1:
                bpf_error(cstate, "'addr1' and 'address1' are not valid qualifiers for port ranges");
-               break;
+               /*NOTREACHED*/
 
        case Q_ADDR2:
                bpf_error(cstate, "'addr2' and 'address2' are not valid qualifiers for port ranges");
-               break;
+               /*NOTREACHED*/
 
        case Q_ADDR3:
                bpf_error(cstate, "'addr3' and 'address3' are not valid qualifiers for port ranges");
-               break;
+               /*NOTREACHED*/
 
        case Q_ADDR4:
                bpf_error(cstate, "'addr4' and 'address4' are not valid qualifiers for port ranges");
-               break;
+               /*NOTREACHED*/
 
        case Q_RA:
                bpf_error(cstate, "'ra' is not a valid qualifier for port ranges");
-               break;
+               /*NOTREACHED*/
 
        case Q_TA:
                bpf_error(cstate, "'ta' is not a valid qualifier for port ranges");
-               break;
+               /*NOTREACHED*/
 
        default:
                abort();
+               /*NOTREACHED*/
        }
        gen_and(b0, b1);
 
@@ -5746,7 +5901,7 @@ gen_portrangeop(compiler_state_t *cstate, int port1, int port2, int proto,
 }
 
 static struct block *
-gen_portrange(compiler_state_t *cstate, int port1, int port2, int ip_proto,
+gen_portrange(compiler_state_t *cstate, u_int port1, u_int port2, int ip_proto,
     int dir)
 {
        struct block *b0, *b1, *tmp;
@@ -5758,7 +5913,8 @@ gen_portrange(compiler_state_t *cstate, int port1, int port2, int ip_proto,
        case IPPROTO_UDP:
        case IPPROTO_TCP:
        case IPPROTO_SCTP:
-               b1 = gen_portrangeop(cstate, port1, port2, ip_proto, dir);
+               b1 = gen_portrangeop(cstate, port1, port2, (bpf_u_int32)ip_proto,
+                   dir);
                break;
 
        case PROTO_UNDEF:
@@ -5777,8 +5933,8 @@ gen_portrange(compiler_state_t *cstate, int port1, int port2, int ip_proto,
 }
 
 static struct block *
-gen_portrangeatom6(compiler_state_t *cstate, int off, bpf_int32 v1,
-    bpf_int32 v2)
+gen_portrangeatom6(compiler_state_t *cstate, u_int off, bpf_u_int32 v1,
+    bpf_u_int32 v2)
 {
        struct block *b1, *b2;
 
@@ -5786,7 +5942,7 @@ gen_portrangeatom6(compiler_state_t *cstate, int off, bpf_int32 v1,
                /*
                 * Reverse the order of the ports, so v1 is the lower one.
                 */
-               bpf_int32 vtemp;
+               bpf_u_int32 vtemp;
 
                vtemp = v1;
                v1 = v2;
@@ -5801,35 +5957,35 @@ gen_portrangeatom6(compiler_state_t *cstate, int off, bpf_int32 v1,
        return b2;
 }
 
-struct block *
-gen_portrangeop6(compiler_state_t *cstate, int port1, int port2, int proto,
-    int dir)
+static struct block *
+gen_portrangeop6(compiler_state_t *cstate, u_int port1, u_int port2,
+    bpf_u_int32 proto, int dir)
 {
        struct block *b0, *b1, *tmp;
 
        /* ip6 proto 'proto' */
        /* XXX - catch the first fragment of a fragmented packet? */
-       b0 = gen_cmp(cstate, OR_LINKPL, 6, BPF_B, (bpf_int32)proto);
+       b0 = gen_cmp(cstate, OR_LINKPL, 6, BPF_B, proto);
 
        switch (dir) {
        case Q_SRC:
-               b1 = gen_portrangeatom6(cstate, 0, (bpf_int32)port1, (bpf_int32)port2);
+               b1 = gen_portrangeatom6(cstate, 0, port1, port2);
                break;
 
        case Q_DST:
-               b1 = gen_portrangeatom6(cstate, 2, (bpf_int32)port1, (bpf_int32)port2);
+               b1 = gen_portrangeatom6(cstate, 2, port1, port2);
                break;
 
        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);
+               tmp = gen_portrangeatom6(cstate, 0, port1, port2);
+               b1 = gen_portrangeatom6(cstate, 2, port1, port2);
                gen_and(tmp, b1);
                break;
 
        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);
+               tmp = gen_portrangeatom6(cstate, 0, port1, port2);
+               b1 = gen_portrangeatom6(cstate, 2, port1, port2);
                gen_or(tmp, b1);
                break;
 
@@ -5842,7 +5998,7 @@ gen_portrangeop6(compiler_state_t *cstate, int port1, int port2, int proto,
 }
 
 static struct block *
-gen_portrange6(compiler_state_t *cstate, int port1, int port2, int ip_proto,
+gen_portrange6(compiler_state_t *cstate, u_int port1, u_int port2, int ip_proto,
     int dir)
 {
        struct block *b0, *b1, *tmp;
@@ -5854,7 +6010,8 @@ gen_portrange6(compiler_state_t *cstate, int port1, int port2, int ip_proto,
        case IPPROTO_UDP:
        case IPPROTO_TCP:
        case IPPROTO_SCTP:
-               b1 = gen_portrangeop6(cstate, port1, port2, ip_proto, dir);
+               b1 = gen_portrangeop6(cstate, port1, port2, (bpf_u_int32)ip_proto,
+                   dir);
                break;
 
        case PROTO_UNDEF:
@@ -5888,7 +6045,7 @@ lookup_proto(compiler_state_t *cstate, const char *name, int proto)
                break;
 
        case Q_LINK:
-               /* XXX should look up h/w protocol type based on cstate->cgstate->linktype */
+               /* XXX should look up h/w protocol type based on cstate->linktype */
                v = pcap_nametoeproto(name);
                if (v == PROTO_UNDEF) {
                        v = pcap_nametollc(name);
@@ -5915,20 +6072,10 @@ lookup_proto(compiler_state_t *cstate, const char *name, int proto)
        return v;
 }
 
-#if 0
-struct stmt *
-gen_joinsp(struct stmt **s, int n)
-{
-       return NULL;
-}
-#endif
-
+#if !defined(NO_PROTOCHAIN)
 static struct block *
-gen_protochain(compiler_state_t *cstate, int v, int proto, int dir)
+gen_protochain(compiler_state_t *cstate, bpf_u_int32 v, int proto)
 {
-#ifdef NO_PROTOCHAIN
-       return gen_proto(cstate, v, proto, dir);
-#else
        struct block *b0, *b;
        struct slist *s[100];
        int fix2, fix3, fix4, fix5;
@@ -5944,8 +6091,8 @@ gen_protochain(compiler_state_t *cstate, int v, int proto, int dir)
        case Q_IPV6:
                break;
        case Q_DEFAULT:
-               b0 = gen_protochain(cstate, v, Q_IP, dir);
-               b = gen_protochain(cstate, v, Q_IPV6, dir);
+               b0 = gen_protochain(cstate, v, Q_IP);
+               b = gen_protochain(cstate, v, Q_IPV6);
                gen_or(b0, b);
                return b;
        default:
@@ -5964,10 +6111,21 @@ gen_protochain(compiler_state_t *cstate, int v, int proto, int dir)
         * branches, and backward branch support is unlikely to appear
         * in kernel BPF engines.)
         */
-       if (cstate->cgstate->off_linkpl.is_variable)
+       if (cstate->off_linkpl.is_variable)
                bpf_error(cstate, "'protochain' not supported with variable length headers");
 
-       cstate->cgstate->no_optimize = 1; /* this code is not compatible with optimizer yet */
+       /*
+        * To quote a comment in optimize.c:
+        *
+        * "These data structures are used in a Cocke and Shwarz style
+        * value numbering scheme.  Since the flowgraph is acyclic,
+        * exit values can be propagated from a node's predecessors
+        * provided it is uniquely defined."
+        *
+        * "Acyclic" means "no backward branches", which means "no
+        * loops", so we have to turn the optimizer off.
+        */
+       cstate->no_optimize = 1;
 
        /*
         * s[0] is a dummy entry to protect other BPF insn from damage
@@ -5984,11 +6142,11 @@ gen_protochain(compiler_state_t *cstate, int v, int proto, int dir)
 
                /* A = ip->ip_p */
                s[i] = new_stmt(cstate, BPF_LD|BPF_ABS|BPF_B);
-               s[i]->s.k = cstate->cgstate->off_linkpl.constant_part + cstate->cgstate->off_nl + 9;
+               s[i]->s.k = cstate->off_linkpl.constant_part + cstate->off_nl + 9;
                i++;
                /* X = ip->ip_hl << 2 */
                s[i] = new_stmt(cstate, BPF_LDX|BPF_MSH|BPF_B);
-               s[i]->s.k = cstate->cgstate->off_linkpl.constant_part + cstate->cgstate->off_nl;
+               s[i]->s.k = cstate->off_linkpl.constant_part + cstate->off_nl;
                i++;
                break;
 
@@ -5997,7 +6155,7 @@ gen_protochain(compiler_state_t *cstate, int v, int proto, int dir)
 
                /* A = ip6->ip_nxt */
                s[i] = new_stmt(cstate, BPF_LD|BPF_ABS|BPF_B);
-               s[i]->s.k = cstate->cgstate->off_linkpl.constant_part + cstate->cgstate->off_nl + 6;
+               s[i]->s.k = cstate->off_linkpl.constant_part + cstate->off_nl + 6;
                i++;
                /* X = sizeof(struct ip6_hdr) */
                s[i] = new_stmt(cstate, BPF_LDX|BPF_IMM);
@@ -6073,7 +6231,7 @@ gen_protochain(compiler_state_t *cstate, int v, int proto, int dir)
                 */
                /* A = P[X + packet head] */
                s[i] = new_stmt(cstate, BPF_LD|BPF_IND|BPF_B);
-               s[i]->s.k = cstate->cgstate->off_linkpl.constant_part + cstate->cgstate->off_nl;
+               s[i]->s.k = cstate->off_linkpl.constant_part + cstate->off_nl;
                i++;
                /* MEM[reg2] = A */
                s[i] = new_stmt(cstate, BPF_ST);
@@ -6081,7 +6239,7 @@ gen_protochain(compiler_state_t *cstate, int v, int proto, int dir)
                i++;
                /* A = P[X + packet head + 1]; */
                s[i] = new_stmt(cstate, BPF_LD|BPF_IND|BPF_B);
-               s[i]->s.k = cstate->cgstate->off_linkpl.constant_part + cstate->cgstate->off_nl + 1;
+               s[i]->s.k = cstate->off_linkpl.constant_part + cstate->off_nl + 1;
                i++;
                /* A += 1 */
                s[i] = new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_K);
@@ -6142,7 +6300,7 @@ gen_protochain(compiler_state_t *cstate, int v, int proto, int dir)
        i++;
        /* A = P[X + packet head]; */
        s[i] = new_stmt(cstate, BPF_LD|BPF_IND|BPF_B);
-       s[i]->s.k = cstate->cgstate->off_linkpl.constant_part + cstate->cgstate->off_nl;
+       s[i]->s.k = cstate->off_linkpl.constant_part + cstate->off_nl;
        i++;
        /* MEM[reg2] = A */
        s[i] = new_stmt(cstate, BPF_ST);
@@ -6160,7 +6318,7 @@ gen_protochain(compiler_state_t *cstate, int v, int proto, int dir)
        i++;
        /* A = P[X + packet head] */
        s[i] = new_stmt(cstate, BPF_LD|BPF_IND|BPF_B);
-       s[i]->s.k = cstate->cgstate->off_linkpl.constant_part + cstate->cgstate->off_nl;
+       s[i]->s.k = cstate->off_linkpl.constant_part + cstate->off_nl;
        i++;
        /* A += 2 */
        s[i] = new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_K);
@@ -6211,8 +6369,8 @@ gen_protochain(compiler_state_t *cstate, int v, int proto, int dir)
 
        gen_and(b0, b);
        return b;
-#endif
 }
+#endif /* !defined(NO_PROTOCHAIN) */
 
 static struct block *
 gen_check_802_11_data_frame(compiler_state_t *cstate)
@@ -6250,12 +6408,10 @@ gen_check_802_11_data_frame(compiler_state_t *cstate)
  * against Q_IP and Q_IPV6.
  */
 static struct block *
-gen_proto(compiler_state_t *cstate, int v, int proto, int dir)
+gen_proto(compiler_state_t *cstate, bpf_u_int32 v, int proto, int dir)
 {
        struct block *b0, *b1;
-#ifndef CHASE_CHAIN
        struct block *b2;
-#endif
 
        if (dir != Q_DEFAULT)
                bpf_error(cstate, "direction applied to 'proto'");
@@ -6287,114 +6443,106 @@ gen_proto(compiler_state_t *cstate, int v, int proto, int dir)
                 * So we always check for ETHERTYPE_IP.
                 */
                b0 = gen_linktype(cstate, ETHERTYPE_IP);
-#ifndef CHASE_CHAIN
-               b1 = gen_cmp(cstate, OR_LINKPL, 9, BPF_B, (bpf_int32)v);
-#else
-               b1 = gen_protochain(cstate, v, Q_IP);
-#endif
+               b1 = gen_cmp(cstate, OR_LINKPL, 9, BPF_B, v);
                gen_and(b0, b1);
                return b1;
 
        case Q_ARP:
                bpf_error(cstate, "arp does not encapsulate another protocol");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_RARP:
                bpf_error(cstate, "rarp does not encapsulate another protocol");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_SCTP:
                bpf_error(cstate, "'sctp proto' is bogus");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_TCP:
                bpf_error(cstate, "'tcp proto' is bogus");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_UDP:
                bpf_error(cstate, "'udp proto' is bogus");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_ICMP:
                bpf_error(cstate, "'icmp proto' is bogus");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_IGMP:
                bpf_error(cstate, "'igmp proto' is bogus");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_IGRP:
                bpf_error(cstate, "'igrp proto' is bogus");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_ATALK:
                bpf_error(cstate, "AppleTalk encapsulation is not specifiable");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_DECNET:
                bpf_error(cstate, "DECNET encapsulation is not specifiable");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_LAT:
                bpf_error(cstate, "LAT does not encapsulate another protocol");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_SCA:
                bpf_error(cstate, "SCA does not encapsulate another protocol");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_MOPRC:
                bpf_error(cstate, "MOPRC does not encapsulate another protocol");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_MOPDL:
                bpf_error(cstate, "MOPDL does not encapsulate another protocol");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_IPV6:
                b0 = gen_linktype(cstate, ETHERTYPE_IPV6);
-#ifndef CHASE_CHAIN
                /*
                 * Also check for a fragment header before the final
                 * header.
                 */
                b2 = gen_cmp(cstate, OR_LINKPL, 6, BPF_B, IPPROTO_FRAGMENT);
-               b1 = gen_cmp(cstate, OR_LINKPL, 40, BPF_B, (bpf_int32)v);
+               b1 = gen_cmp(cstate, OR_LINKPL, 40, BPF_B, v);
                gen_and(b2, b1);
-               b2 = gen_cmp(cstate, OR_LINKPL, 6, BPF_B, (bpf_int32)v);
+               b2 = gen_cmp(cstate, OR_LINKPL, 6, BPF_B, v);
                gen_or(b2, b1);
-#else
-               b1 = gen_protochain(cstate, v, Q_IPV6);
-#endif
                gen_and(b0, b1);
                return b1;
 
        case Q_ICMPV6:
                bpf_error(cstate, "'icmp6 proto' is bogus");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_AH:
                bpf_error(cstate, "'ah proto' is bogus");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_ESP:
-               bpf_error(cstate, "'ah proto' is bogus");
-               /* NOTREACHED */
+               bpf_error(cstate, "'esp proto' is bogus");
+               /*NOTREACHED*/
 
        case Q_PIM:
                bpf_error(cstate, "'pim proto' is bogus");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_VRRP:
                bpf_error(cstate, "'vrrp proto' is bogus");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_AARP:
                bpf_error(cstate, "'aarp proto' is bogus");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_ISO:
-               switch (cstate->cgstate->linktype) {
+               switch (cstate->linktype) {
 
                case DLT_FRELAY:
                        /*
@@ -6417,29 +6565,29 @@ gen_proto(compiler_state_t *cstate, int v, int proto, int dir)
                         */
                        return gen_cmp(cstate, OR_LINKHDR, 2, BPF_H, (0x03<<8) | v);
                        /*NOTREACHED*/
-                       break;
 
                case DLT_C_HDLC:
+               case DLT_HDLC:
                        /*
                         * Cisco uses an Ethertype lookalike - for OSI,
                         * it's 0xfefe.
                         */
                        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, (bpf_int32)v);
+                       b1 = gen_cmp(cstate, OR_LINKPL_NOSNAP, 1, BPF_B, v);
                        gen_and(b0, b1);
                        return b1;
 
                default:
                        b0 = gen_linktype(cstate, LLCSAP_ISONS);
-                       b1 = gen_cmp(cstate, OR_LINKPL_NOSNAP, 0, BPF_B, (bpf_int32)v);
+                       b1 = gen_cmp(cstate, OR_LINKPL_NOSNAP, 0, BPF_B, v);
                        gen_and(b0, b1);
                        return b1;
                }
 
        case Q_ESIS:
                bpf_error(cstate, "'esis proto' is bogus");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_ISIS:
                b0 = gen_proto(cstate, ISO10589_ISIS, Q_ISO, Q_DEFAULT);
@@ -6447,67 +6595,67 @@ 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, (bpf_int32)v);
+               b1 = gen_cmp(cstate, OR_LINKPL_NOSNAP, 4, BPF_B, v);
                gen_and(b0, b1);
                return b1;
 
        case Q_CLNP:
                bpf_error(cstate, "'clnp proto' is not supported");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_STP:
                bpf_error(cstate, "'stp proto' is bogus");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_IPX:
                bpf_error(cstate, "'ipx proto' is bogus");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_NETBEUI:
                bpf_error(cstate, "'netbeui proto' is bogus");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_ISIS_L1:
                bpf_error(cstate, "'l1 proto' is bogus");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_ISIS_L2:
                bpf_error(cstate, "'l2 proto' is bogus");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_ISIS_IIH:
                bpf_error(cstate, "'iih proto' is bogus");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_ISIS_SNP:
                bpf_error(cstate, "'snp proto' is bogus");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_ISIS_CSNP:
                bpf_error(cstate, "'csnp proto' is bogus");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_ISIS_PSNP:
                bpf_error(cstate, "'psnp proto' is bogus");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_ISIS_LSP:
                bpf_error(cstate, "'lsp proto' is bogus");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_RADIO:
                bpf_error(cstate, "'radio proto' is bogus");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_CARP:
                bpf_error(cstate, "'carp proto' is bogus");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        default:
                abort();
-               /* NOTREACHED */
+               /*NOTREACHED*/
        }
-       /* NOTREACHED */
+       /*NOTREACHED*/
 }
 
 struct block *
@@ -6529,6 +6677,13 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
        int port, real_proto;
        int port1, port2;
 
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
        switch (q.addr) {
 
        case Q_NET:
@@ -6546,7 +6701,7 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
        case Q_DEFAULT:
        case Q_HOST:
                if (proto == Q_LINK) {
-                       switch (cstate->cgstate->linktype) {
+                       switch (cstate->linktype) {
 
                        case DLT_EN10MB:
                        case DLT_NETANALYZER:
@@ -6627,13 +6782,13 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
                        res0 = res = pcap_nametoaddrinfo(name);
                        if (res == NULL)
                                bpf_error(cstate, "unknown host '%s'", name);
-                       cstate->cgstate->ai = res;
+                       cstate->ai = res;
                        b = tmp = NULL;
                        tproto = proto;
 #ifdef INET6
                        tproto6 = proto;
 #endif
-                       if (cstate->cgstate->off_linktype.constant_part == OFFSET_NOT_SET &&
+                       if (cstate->off_linktype.constant_part == OFFSET_NOT_SET &&
                            tproto == Q_DEFAULT) {
                                tproto = Q_IP;
 #ifdef INET6
@@ -6671,7 +6826,7 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
                                        gen_or(b, tmp);
                                b = tmp;
                        }
-                       cstate->cgstate->ai = NULL;
+                       cstate->ai = NULL;
                        freeaddrinfo(res0);
                        if (b == NULL) {
                                bpf_error(cstate, "unknown host '%s'%s", name,
@@ -6778,11 +6933,11 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
                        bpf_error(cstate, "unknown ether host: %s", name);
 
                res = pcap_nametoaddrinfo(name);
-               cstate->cgstate->ai = res;
+               cstate->ai = res;
                if (res == NULL)
                        bpf_error(cstate, "unknown host '%s'", name);
                b = gen_gateway(cstate, eaddr, res, proto, dir);
-               cstate->cgstate->ai = NULL;
+               cstate->ai = NULL;
                freeaddrinfo(res);
                if (b == NULL)
                        bpf_error(cstate, "unknown host '%s'", name);
@@ -6798,34 +6953,47 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
                else
                        bpf_error(cstate, "unknown protocol: %s", name);
 
+#if !defined(NO_PROTOCHAIN)
        case Q_PROTOCHAIN:
                real_proto = lookup_proto(cstate, name, proto);
                if (real_proto >= 0)
-                       return gen_protochain(cstate, real_proto, proto, dir);
+                       return gen_protochain(cstate, real_proto, proto);
                else
                        bpf_error(cstate, "unknown protocol: %s", name);
+#endif /* !defined(NO_PROTOCHAIN) */
 
        case Q_UNDEF:
                syntax(cstate);
-               /* NOTREACHED */
+               /*NOTREACHED*/
        }
        abort();
-       /* NOTREACHED */
+       /*NOTREACHED*/
 }
 
 struct block *
 gen_mcode(compiler_state_t *cstate, const char *s1, const char *s2,
-    unsigned int masklen, struct qual q)
+    bpf_u_int32 masklen, struct qual q)
 {
        register int nlen, mlen;
        bpf_u_int32 n, m;
 
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
        nlen = __pcap_atoin(s1, &n);
+       if (nlen < 0)
+               bpf_error(cstate, "invalid IPv4 address '%s'", s1);
        /* Promote short ipaddr */
        n <<= 32 - nlen;
 
        if (s2 != NULL) {
                mlen = __pcap_atoin(s2, &m);
+               if (mlen < 0)
+                       bpf_error(cstate, "invalid IPv4 address '%s'", s2);
                /* Promote short ipaddr */
                m <<= 32 - mlen;
                if ((n & ~m) != 0)
@@ -6855,27 +7023,39 @@ gen_mcode(compiler_state_t *cstate, const char *s1, const char *s2,
 
        default:
                bpf_error(cstate, "Mask syntax for networks only");
-               /* NOTREACHED */
+               /*NOTREACHED*/
        }
-       /* NOTREACHED */
+       /*NOTREACHED*/
 }
 
 struct block *
 gen_ncode(compiler_state_t *cstate, const char *s, bpf_u_int32 v, struct qual q)
 {
        bpf_u_int32 mask;
-       int proto = q.proto;
-       int dir = q.dir;
+       int proto;
+       int dir;
        register int vlen;
 
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
+       proto = q.proto;
+       dir = q.dir;
        if (s == NULL)
                vlen = 32;
        else if (q.proto == Q_DECNET) {
                vlen = __pcap_atodn(s, &v);
                if (vlen == 0)
                        bpf_error(cstate, "malformed decnet address '%s'", s);
-       } else
+       } else {
                vlen = __pcap_atoin(s, &v);
+               if (vlen < 0)
+                       bpf_error(cstate, "invalid IPv4 address '%s'", s);
+       }
 
        switch (q.addr) {
 
@@ -6919,8 +7099,8 @@ gen_ncode(compiler_state_t *cstate, const char *s, bpf_u_int32 v, struct qual q)
 
            {
                struct block *b;
-               b = gen_port(cstate, (int)v, proto, dir);
-               gen_or(gen_port6(cstate, (int)v, proto, dir), b);
+               b = gen_port(cstate, v, proto, dir);
+               gen_or(gen_port6(cstate, v, proto, dir), b);
                return b;
            }
 
@@ -6941,36 +7121,38 @@ gen_ncode(compiler_state_t *cstate, const char *s, bpf_u_int32 v, struct qual q)
 
            {
                struct block *b;
-               b = gen_portrange(cstate, (int)v, (int)v, proto, dir);
-               gen_or(gen_portrange6(cstate, (int)v, (int)v, proto, dir), b);
+               b = gen_portrange(cstate, v, v, proto, dir);
+               gen_or(gen_portrange6(cstate, v, v, proto, dir), b);
                return b;
            }
 
        case Q_GATEWAY:
                bpf_error(cstate, "'gateway' requires a name");
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        case Q_PROTO:
-               return gen_proto(cstate, (int)v, proto, dir);
+               return gen_proto(cstate, v, proto, dir);
 
+#if !defined(NO_PROTOCHAIN)
        case Q_PROTOCHAIN:
-               return gen_protochain(cstate, (int)v, proto, dir);
+               return gen_protochain(cstate, v, proto);
+#endif
 
        case Q_UNDEF:
                syntax(cstate);
-               /* NOTREACHED */
+               /*NOTREACHED*/
 
        default:
                abort();
-               /* NOTREACHED */
+               /*NOTREACHED*/
        }
-       /* NOTREACHED */
+       /*NOTREACHED*/
 }
 
 #ifdef INET6
 struct block *
 gen_mcode6(compiler_state_t *cstate, const char *s1, const char *s2,
-    unsigned int masklen, struct qual q)
+    bpf_u_int32 masklen, struct qual q)
 {
        struct addrinfo *res;
        struct in6_addr *addr;
@@ -6978,21 +7160,28 @@ gen_mcode6(compiler_state_t *cstate, const char *s1, const char *s2,
        struct block *b;
        uint32_t *a, *m;
 
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
        if (s2)
                bpf_error(cstate, "no mask %s supported", s2);
 
        res = pcap_nametoaddrinfo(s1);
        if (!res)
                bpf_error(cstate, "invalid ip6 address %s", s1);
-       cstate->cgstate->ai = res;
+       cstate->ai = res;
        if (res->ai_next)
                bpf_error(cstate, "%s resolved to multiple address", s1);
        addr = &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
 
-       if (sizeof(mask) * 8 < masklen)
-               bpf_error(cstate, "mask length must be <= %u", (unsigned int)(sizeof(mask) * 8));
+       if (masklen > sizeof(mask.s6_addr) * 8)
+               bpf_error(cstate, "mask length must be <= %u", (unsigned int)(sizeof(mask.s6_addr) * 8));
        memset(&mask, 0, sizeof(mask));
-       memset(&mask, 0xff, masklen / 8);
+       memset(&mask.s6_addr, 0xff, masklen / 8);
        if (masklen % 8) {
                mask.s6_addr[masklen / 8] =
                        (0xff << (8 - masklen % 8)) & 0xff;
@@ -7015,13 +7204,13 @@ gen_mcode6(compiler_state_t *cstate, const char *s1, const char *s2,
 
        case Q_NET:
                b = gen_host6(cstate, addr, &mask, q.proto, q.dir, q.addr);
-               cstate->cgstate->ai = NULL;
+               cstate->ai = NULL;
                freeaddrinfo(res);
                return b;
 
        default:
                bpf_error(cstate, "invalid qualifier against IPv6 address");
-               /* NOTREACHED */
+               /*NOTREACHED*/
        }
 }
 #endif /*INET6*/
@@ -7031,48 +7220,54 @@ gen_ecode(compiler_state_t *cstate, const char *s, struct qual q)
 {
        struct block *b, *tmp;
 
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
        if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) {
-               cstate->cgstate->e = pcap_ether_aton(s);
-               if (cstate->cgstate->e == NULL)
+               cstate->e = pcap_ether_aton(s);
+               if (cstate->e == NULL)
                        bpf_error(cstate, "malloc");
-               switch (cstate->cgstate->linktype) {
+               switch (cstate->linktype) {
                case DLT_EN10MB:
                case DLT_NETANALYZER:
                case DLT_NETANALYZER_TRANSPARENT:
                        tmp = gen_prevlinkhdr_check(cstate);
-                       b = gen_ehostop(cstate, cstate->cgstate->e, (int)q.dir);
+                       b = gen_ehostop(cstate, cstate->e, (int)q.dir);
                        if (tmp != NULL)
                                gen_and(tmp, b);
                        break;
                case DLT_FDDI:
-                       b = gen_fhostop(cstate, cstate->cgstate->e, (int)q.dir);
+                       b = gen_fhostop(cstate, cstate->e, (int)q.dir);
                        break;
                case DLT_IEEE802:
-                       b = gen_thostop(cstate, cstate->cgstate->e, (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:
-                       b = gen_wlanhostop(cstate, cstate->cgstate->e, (int)q.dir);
+                       b = gen_wlanhostop(cstate, cstate->e, (int)q.dir);
                        break;
                case DLT_IP_OVER_FC:
-                       b = gen_ipfchostop(cstate, cstate->cgstate->e, (int)q.dir);
+                       b = gen_ipfchostop(cstate, cstate->e, (int)q.dir);
                        break;
                default:
-                       free(cstate->cgstate->e);
-                       cstate->cgstate->e = NULL;
+                       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;
+                       /*NOTREACHED*/
                }
-               free(cstate->cgstate->e);
-               cstate->cgstate->e = NULL;
+               free(cstate->e);
+               cstate->e = NULL;
                return (b);
        }
        bpf_error(cstate, "ethernet address used in non-ether expression");
-       /* NOTREACHED */
+       /*NOTREACHED*/
 }
 
 void
@@ -7114,9 +7309,11 @@ xfer_to_a(compiler_state_t *cstate, struct arth *a)
  * (1, 2, or 4) at that offset into that register, making it the register
  * for "index".
  */
-struct arth *
-gen_load(compiler_state_t *cstate, int proto, struct arth *inst, int size)
+static struct arth *
+gen_load_internal(compiler_state_t *cstate, int proto, struct arth *inst,
+    bpf_u_int32 size)
 {
+       int size_code;
        struct slist *s, *tmp;
        struct block *b;
        int regno = alloc_reg(cstate);
@@ -7126,17 +7323,18 @@ gen_load(compiler_state_t *cstate, int proto, struct arth *inst, int size)
 
        default:
                bpf_error(cstate, "data size must be 1, 2, or 4");
+               /*NOTREACHED*/
 
        case 1:
-               size = BPF_B;
+               size_code = BPF_B;
                break;
 
        case 2:
-               size = BPF_H;
+               size_code = BPF_H;
                break;
 
        case 4:
-               size = BPF_W;
+               size_code = BPF_W;
                break;
        }
        switch (proto) {
@@ -7149,9 +7347,9 @@ gen_load(compiler_state_t *cstate, int proto, struct arth *inst, int size)
                 * data, if we have a radio header.  (If we don't, this
                 * is an error.)
                 */
-               if (cstate->cgstate->linktype != DLT_IEEE802_11_RADIO_AVS &&
-                   cstate->cgstate->linktype != DLT_IEEE802_11_RADIO &&
-                   cstate->cgstate->linktype != DLT_PRISM_HEADER)
+               if (cstate->linktype != DLT_IEEE802_11_RADIO_AVS &&
+                   cstate->linktype != DLT_IEEE802_11_RADIO &&
+                   cstate->linktype != DLT_PRISM_HEADER)
                        bpf_error(cstate, "radio information not present in capture");
 
                /*
@@ -7163,7 +7361,7 @@ gen_load(compiler_state_t *cstate, int proto, struct arth *inst, int size)
                /*
                 * Load the item at that offset.
                 */
-               tmp = new_stmt(cstate, BPF_LD|BPF_IND|size);
+               tmp = new_stmt(cstate, BPF_LD|BPF_IND|size_code);
                sappend(s, tmp);
                sappend(inst->s, s);
                break;
@@ -7180,7 +7378,7 @@ gen_load(compiler_state_t *cstate, int proto, struct arth *inst, int size)
                 * frame, so that 0 refers, for Ethernet LANE, to
                 * the beginning of the destination address?
                 */
-               s = gen_abs_offset_varpart(cstate, &cstate->cgstate->off_linkhdr);
+               s = gen_abs_offset_varpart(cstate, &cstate->off_linkhdr);
 
                /*
                 * If "s" is non-null, it has code to arrange that the
@@ -7205,8 +7403,8 @@ gen_load(compiler_state_t *cstate, int proto, struct arth *inst, int size)
                 * variable-length; that header length is what we put
                 * into the X register and then added to the index).
                 */
-               tmp = new_stmt(cstate, BPF_LD|BPF_IND|size);
-               tmp->s.k = cstate->cgstate->off_linkhdr.constant_part;
+               tmp = new_stmt(cstate, BPF_LD|BPF_IND|size_code);
+               tmp->s.k = cstate->off_linkhdr.constant_part;
                sappend(s, tmp);
                sappend(inst->s, s);
                break;
@@ -7225,9 +7423,9 @@ gen_load(compiler_state_t *cstate, int proto, struct arth *inst, int size)
                 * The offset is relative to the beginning of
                 * the network-layer header.
                 * XXX - are there any cases where we want
-                * cstate->cgstate->off_nl_nosnap?
+                * cstate->off_nl_nosnap?
                 */
-               s = gen_abs_offset_varpart(cstate, &cstate->cgstate->off_linkpl);
+               s = gen_abs_offset_varpart(cstate, &cstate->off_linkpl);
 
                /*
                 * If "s" is non-null, it has code to arrange that the
@@ -7252,8 +7450,8 @@ gen_load(compiler_state_t *cstate, int proto, struct arth *inst, int size)
                 * 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->cgstate->off_linkpl.constant_part + cstate->cgstate->off_nl;
+               tmp = new_stmt(cstate, BPF_LD|BPF_IND|size_code);
+               tmp->s.k = cstate->off_linkpl.constant_part + cstate->off_nl;
                sappend(s, tmp);
                sappend(inst->s, s);
 
@@ -7261,7 +7459,7 @@ gen_load(compiler_state_t *cstate, int proto, struct arth *inst, int size)
                 * Do the computation only if the packet contains
                 * the protocol in question.
                 */
-               b = gen_proto_abbrev(cstate, proto);
+               b = gen_proto_abbrev_internal(cstate, proto);
                if (inst->b)
                        gen_and(inst->b, b);
                inst->b = b;
@@ -7285,7 +7483,7 @@ gen_load(compiler_state_t *cstate, int proto, struct arth *inst, int size)
                 * a variable-length header), in bytes.
                 *
                 * XXX - are there any cases where we want
-                * cstate->cgstate->off_nl_nosnap?
+                * cstate->off_nl_nosnap?
                 * XXX - we should, if we're built with
                 * IPv6 support, generate code to load either
                 * IPv4, IPv6, or both, as appropriate.
@@ -7309,8 +7507,8 @@ gen_load(compiler_state_t *cstate, int proto, struct arth *inst, int size)
                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));
-               sappend(s, tmp = new_stmt(cstate, BPF_LD|BPF_IND|size));
-               tmp->s.k = cstate->cgstate->off_linkpl.constant_part + cstate->cgstate->off_nl;
+               sappend(s, tmp = new_stmt(cstate, BPF_LD|BPF_IND|size_code));
+               tmp->s.k = cstate->off_linkpl.constant_part + cstate->off_nl;
                sappend(inst->s, s);
 
                /*
@@ -7319,10 +7517,10 @@ gen_load(compiler_state_t *cstate, int proto, struct arth *inst, int size)
                 * if this is an IP datagram and is the first or
                 * only fragment of that datagram.
                 */
-               gen_and(gen_proto_abbrev(cstate, proto), b = gen_ipfrag(cstate));
+               gen_and(gen_proto_abbrev_internal(cstate, proto), b = gen_ipfrag(cstate));
                if (inst->b)
                        gen_and(inst->b, b);
-               gen_and(gen_proto_abbrev(cstate, Q_IP), b);
+               gen_and(gen_proto_abbrev_internal(cstate, Q_IP), b);
                inst->b = b;
                break;
        case Q_ICMPV6:
@@ -7330,7 +7528,7 @@ gen_load(compiler_state_t *cstate, int proto, struct arth *inst, int size)
         * Do the computation only if the packet contains
         * the protocol in question.
         */
-        b = gen_proto_abbrev(cstate, Q_IPV6);
+        b = gen_proto_abbrev_internal(cstate, Q_IPV6);
         if (inst->b) {
             gen_and(inst->b, b);
         }
@@ -7346,7 +7544,7 @@ gen_load(compiler_state_t *cstate, int proto, struct arth *inst, int size)
         inst->b = b;
 
 
-        s = gen_abs_offset_varpart(cstate, &cstate->cgstate->off_linkpl);
+        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
@@ -7371,8 +7569,8 @@ gen_load(compiler_state_t *cstate, int proto, struct arth *inst, int size)
         * 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->cgstate->off_linkpl.constant_part + cstate->cgstate->off_nl + 40;
+        tmp = new_stmt(cstate, BPF_LD|BPF_IND|size_code);
+        tmp->s.k = cstate->off_linkpl.constant_part + cstate->off_nl + 40;
 
         sappend(s, tmp);
         sappend(inst->s, s);
@@ -7387,8 +7585,22 @@ gen_load(compiler_state_t *cstate, int proto, struct arth *inst, int size)
        return inst;
 }
 
-struct block *
-gen_relation(compiler_state_t *cstate, int code, struct arth *a0,
+struct arth *
+gen_load(compiler_state_t *cstate, int proto, struct arth *inst,
+    bpf_u_int32 size)
+{
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
+       return gen_load_internal(cstate, proto, inst, size);
+}
+
+static struct block *
+gen_relation_internal(compiler_state_t *cstate, int code, struct arth *a0,
     struct arth *a1, int reversed)
 {
        struct slist *s0, *s1, *s2;
@@ -7431,13 +7643,36 @@ gen_relation(compiler_state_t *cstate, int code, struct arth *a0,
        return b;
 }
 
+struct block *
+gen_relation(compiler_state_t *cstate, int code, struct arth *a0,
+    struct arth *a1, int reversed)
+{
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
+       return gen_relation_internal(cstate, code, a0, a1, reversed);
+}
+
 struct arth *
 gen_loadlen(compiler_state_t *cstate)
 {
-       int regno = alloc_reg(cstate);
-       struct arth *a = (struct arth *)newchunk(cstate, sizeof(*a));
+       int regno;
+       struct arth *a;
        struct slist *s;
 
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
+       regno = alloc_reg(cstate);
+       a = (struct arth *)newchunk(cstate, sizeof(*a));
        s = new_stmt(cstate, BPF_LD|BPF_LEN);
        s->next = new_stmt(cstate, BPF_ST);
        s->next->s.k = regno;
@@ -7447,8 +7682,8 @@ gen_loadlen(compiler_state_t *cstate)
        return a;
 }
 
-struct arth *
-gen_loadi(compiler_state_t *cstate, int val)
+static struct arth *
+gen_loadi_internal(compiler_state_t *cstate, bpf_u_int32 val)
 {
        struct arth *a;
        struct slist *s;
@@ -7469,10 +7704,36 @@ gen_loadi(compiler_state_t *cstate, int val)
 }
 
 struct arth *
-gen_neg(compiler_state_t *cstate, struct arth *a)
+gen_loadi(compiler_state_t *cstate, bpf_u_int32 val)
 {
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
+       return gen_loadi_internal(cstate, val);
+}
+
+/*
+ * The a_arg dance is to avoid annoying whining by compilers that
+ * a might be clobbered by longjmp - yeah, it might, but *WHO CARES*?
+ * It's not *used* after setjmp returns.
+ */
+struct arth *
+gen_neg(compiler_state_t *cstate, struct arth *a_arg)
+{
+       struct arth *a = a_arg;
        struct slist *s;
 
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
        s = xfer_to_a(cstate, a);
        sappend(a->s, s);
        s = new_stmt(cstate, BPF_ALU|BPF_NEG);
@@ -7485,12 +7746,25 @@ gen_neg(compiler_state_t *cstate, struct arth *a)
        return a;
 }
 
+/*
+ * The a0_arg dance is to avoid annoying whining by compilers that
+ * a0 might be clobbered by longjmp - yeah, it might, but *WHO CARES*?
+ * It's not *used* after setjmp returns.
+ */
 struct arth *
-gen_arth(compiler_state_t *cstate, int code, struct arth *a0,
+gen_arth(compiler_state_t *cstate, int code, struct arth *a0_arg,
     struct arth *a1)
 {
+       struct arth *a0 = a0_arg;
        struct slist *s0, *s1, *s2;
 
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
        /*
         * Disallow division by, or modulus by, zero; we do this here
         * so that it gets done even if the optimizer is disabled.
@@ -7505,13 +7779,7 @@ gen_arth(compiler_state_t *cstate, int code, struct arth *a0,
                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))
+               if (a1->s->s.code == (BPF_LD|BPF_IMM) && a1->s->s.k > 31)
                        bpf_error(cstate, "shift by more than 31 bits");
        }
        s0 = xfer_to_x(cstate, a1);
@@ -7539,8 +7807,8 @@ gen_arth(compiler_state_t *cstate, int code, struct arth *a0,
 static void
 init_regs(compiler_state_t *cstate)
 {
-       cstate->cgstate->curreg = 0;
-       memset(cstate->cgstate->regused, 0, sizeof cstate->cgstate->regused);
+       cstate->curreg = 0;
+       memset(cstate->regused, 0, sizeof cstate->regused);
 }
 
 /*
@@ -7552,15 +7820,15 @@ alloc_reg(compiler_state_t *cstate)
        int n = BPF_MEMWORDS;
 
        while (--n >= 0) {
-               if (cstate->cgstate->regused[cstate->cgstate->curreg])
-                       cstate->cgstate->curreg = (cstate->cgstate->curreg + 1) % BPF_MEMWORDS;
+               if (cstate->regused[cstate->curreg])
+                       cstate->curreg = (cstate->curreg + 1) % BPF_MEMWORDS;
                else {
-                       cstate->cgstate->regused[cstate->cgstate->curreg] = 1;
-                       return cstate->cgstate->curreg;
+                       cstate->regused[cstate->curreg] = 1;
+                       return cstate->curreg;
                }
        }
        bpf_error(cstate, "too many registers needed to evaluate expression");
-       /* NOTREACHED */
+       /*NOTREACHED*/
 }
 
 /*
@@ -7570,7 +7838,7 @@ alloc_reg(compiler_state_t *cstate)
 static void
 free_reg(compiler_state_t *cstate, int n)
 {
-       cstate->cgstate->regused[n] = 0;
+       cstate->regused[n] = 0;
 }
 
 static struct block *
@@ -7590,6 +7858,13 @@ gen_len(compiler_state_t *cstate, int jmp, int n)
 struct block *
 gen_greater(compiler_state_t *cstate, int n)
 {
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
        return gen_len(cstate, BPF_JGE, n);
 }
 
@@ -7601,6 +7876,13 @@ gen_less(compiler_state_t *cstate, int n)
 {
        struct block *b;
 
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
        b = gen_len(cstate, BPF_JGT, n);
        gen_not(b);
 
@@ -7618,24 +7900,31 @@ gen_less(compiler_state_t *cstate, int n)
  * would generate code appropriate to the radio header in question.
  */
 struct block *
-gen_byteop(compiler_state_t *cstate, int op, int idx, int val)
+gen_byteop(compiler_state_t *cstate, int op, int idx, bpf_u_int32 val)
 {
        struct block *b;
        struct slist *s;
 
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
        switch (op) {
        default:
                abort();
 
        case '=':
-               return gen_cmp(cstate, OR_LINKHDR, (u_int)idx, BPF_B, (bpf_int32)val);
+               return gen_cmp(cstate, OR_LINKHDR, (u_int)idx, BPF_B, val);
 
        case '<':
-               b = gen_cmp_lt(cstate, OR_LINKHDR, (u_int)idx, BPF_B, (bpf_int32)val);
+               b = gen_cmp_lt(cstate, OR_LINKHDR, (u_int)idx, BPF_B, val);
                return b;
 
        case '>':
-               b = gen_cmp_gt(cstate, OR_LINKHDR, (u_int)idx, BPF_B, (bpf_int32)val);
+               b = gen_cmp_gt(cstate, OR_LINKHDR, (u_int)idx, BPF_B, val);
                return b;
 
        case '|':
@@ -7663,11 +7952,18 @@ gen_broadcast(compiler_state_t *cstate, int proto)
        struct block *b0, *b1, *b2;
        static const u_char ebroadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
        switch (proto) {
 
        case Q_DEFAULT:
        case Q_LINK:
-               switch (cstate->cgstate->linktype) {
+               switch (cstate->linktype) {
                case DLT_ARCNET:
                case DLT_ARCNET_LINUX:
                        return gen_ahostop(cstate, abroadcast, Q_DST);
@@ -7694,7 +7990,7 @@ gen_broadcast(compiler_state_t *cstate, int proto)
                default:
                        bpf_error(cstate, "not a broadcast link");
                }
-               break;
+               /*NOTREACHED*/
 
        case Q_IP:
                /*
@@ -7702,19 +7998,19 @@ gen_broadcast(compiler_state_t *cstate, int proto)
                 * as an indication that we don't know the netmask, and fail
                 * in that case.
                 */
-               if (cstate->cgstate->netmask == PCAP_NETMASK_UNKNOWN)
+               if (cstate->netmask == PCAP_NETMASK_UNKNOWN)
                        bpf_error(cstate, "netmask not known, so 'ip broadcast' not supported");
                b0 = gen_linktype(cstate, ETHERTYPE_IP);
-               hostmask = ~cstate->cgstate->netmask;
-               b1 = gen_mcmp(cstate, OR_LINKPL, 16, BPF_W, (bpf_int32)0, hostmask);
+               hostmask = ~cstate->netmask;
+               b1 = gen_mcmp(cstate, OR_LINKPL, 16, BPF_W, 0, hostmask);
                b2 = gen_mcmp(cstate, OR_LINKPL, 16, BPF_W,
-                             (bpf_int32)(~0 & hostmask), hostmask);
+                             ~0 & hostmask, hostmask);
                gen_or(b1, b2);
                gen_and(b0, b2);
                return b2;
        }
        bpf_error(cstate, "only link-layer/IP broadcast filters supported");
-       /* NOTREACHED */
+       /*NOTREACHED*/
 }
 
 /*
@@ -7741,11 +8037,18 @@ gen_multicast(compiler_state_t *cstate, int proto)
        register struct block *b0, *b1, *b2;
        register struct slist *s;
 
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
        switch (proto) {
 
        case Q_DEFAULT:
        case Q_LINK:
-               switch (cstate->cgstate->linktype) {
+               switch (cstate->linktype) {
                case DLT_ARCNET:
                case DLT_ARCNET_LINUX:
                        /* all ARCnet multicasts use the same address */
@@ -7898,18 +8201,65 @@ gen_multicast(compiler_state_t *cstate, int proto)
 
        case Q_IP:
                b0 = gen_linktype(cstate, ETHERTYPE_IP);
-               b1 = gen_cmp_ge(cstate, OR_LINKPL, 16, BPF_B, (bpf_int32)224);
+               b1 = gen_cmp_ge(cstate, OR_LINKPL, 16, BPF_B, 224);
                gen_and(b0, b1);
                return b1;
 
        case Q_IPV6:
                b0 = gen_linktype(cstate, ETHERTYPE_IPV6);
-               b1 = gen_cmp(cstate, OR_LINKPL, 24, BPF_B, (bpf_int32)255);
+               b1 = gen_cmp(cstate, OR_LINKPL, 24, BPF_B, 255);
                gen_and(b0, b1);
                return b1;
        }
        bpf_error(cstate, "link-layer multicast filters supported only on ethernet/FDDI/token ring/ARCNET/802.11/ATM LANE/Fibre Channel");
-       /* NOTREACHED */
+       /*NOTREACHED*/
+}
+
+struct block *
+gen_ifindex(compiler_state_t *cstate, int ifindex)
+{
+       register struct block *b0;
+
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
+       /*
+        * Only some data link types support ifindex qualifiers.
+        */
+       switch (cstate->linktype) {
+       case DLT_LINUX_SLL2:
+               /* match packets on this interface */
+               b0 = gen_cmp(cstate, OR_LINKHDR, 4, BPF_W, ifindex);
+               break;
+        default:
+#if defined(linux)
+               /*
+                * This is Linux; we require PF_PACKET support.
+                * If this is a *live* capture, we can look at
+                * special meta-data in the filter expression;
+                * if it's a savefile, we can't.
+                */
+               if (cstate->bpf_pcap->rfile != NULL) {
+                       /* We have a FILE *, so this is a savefile */
+                       bpf_error(cstate, "ifindex not supported on %s when reading savefiles",
+                           pcap_datalink_val_to_description_or_dlt(cstate->linktype));
+                       b0 = NULL;
+                       /*NOTREACHED*/
+               }
+               /* match ifindex */
+               b0 = gen_cmp(cstate, OR_LINKHDR, SKF_AD_OFF + SKF_AD_IFINDEX, BPF_W,
+                            ifindex);
+#else /* defined(linux) */
+               bpf_error(cstate, "ifindex not supported on %s",
+                   pcap_datalink_val_to_description_or_dlt(cstate->linktype));
+               /*NOTREACHED*/
+#endif /* defined(linux) */
+       }
+       return (b0);
 }
 
 /*
@@ -7926,14 +8276,21 @@ gen_inbound(compiler_state_t *cstate, int dir)
 {
        register struct block *b0;
 
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
        /*
         * Only some data link types support inbound/outbound qualifiers.
         */
-       switch (cstate->cgstate->linktype) {
+       switch (cstate->linktype) {
        case DLT_SLIP:
-               b0 = gen_relation(cstate, BPF_JEQ,
-                         gen_load(cstate, Q_LINK, gen_loadi(cstate, 0), 1),
-                         gen_loadi(cstate, 0),
+               b0 = gen_relation_internal(cstate, BPF_JEQ,
+                         gen_load_internal(cstate, Q_LINK, gen_loadi_internal(cstate, 0), 1),
+                         gen_loadi_internal(cstate, 0),
                          dir);
                break;
 
@@ -7965,12 +8322,10 @@ gen_inbound(compiler_state_t *cstate, int dir)
                }
                break;
 
-#ifdef HAVE_NET_PFVAR_H
        case DLT_PFLOG:
                b0 = gen_cmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, dir), BPF_B,
-                   (bpf_int32)((dir == 0) ? PF_IN : PF_OUT));
+                   ((dir == 0) ? PF_IN : PF_OUT));
                break;
-#endif
 
        case DLT_PPP_PPPD:
                if (dir) {
@@ -8032,19 +8387,18 @@ gen_inbound(compiler_state_t *cstate, int dir)
                 * with newer capture APIs, allowing it to be saved
                 * in pcapng files.
                 */
-#if defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER)
+#if defined(linux)
                /*
-                * This is Linux with PF_PACKET support.
+                * This is Linux; we require PF_PACKET support.
                 * If this is a *live* capture, we can look at
                 * special meta-data in the filter expression;
                 * if it's a savefile, we can't.
                 */
                if (cstate->bpf_pcap->rfile != NULL) {
                        /* We have a FILE *, so this is a savefile */
-                       bpf_error(cstate, "inbound/outbound not supported on linktype %d when reading savefiles",
-                           cstate->cgstate->linktype);
-                       b0 = NULL;
-                       /* NOTREACHED */
+                       bpf_error(cstate, "inbound/outbound not supported on %s when reading savefiles",
+                           pcap_datalink_val_to_description_or_dlt(cstate->linktype));
+                       /*NOTREACHED*/
                }
                /* match outgoing packets */
                b0 = gen_cmp(cstate, OR_LINKHDR, SKF_AD_OFF + SKF_AD_PKTTYPE, BPF_H,
@@ -8053,16 +8407,15 @@ gen_inbound(compiler_state_t *cstate, int dir)
                        /* to filter on inbound traffic, invert the match */
                        gen_not(b0);
                }
-#else /* defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */
-               bpf_error(cstate, "inbound/outbound not supported on linktype %d",
-                   cstate->cgstate->linktype);
-               /* NOTREACHED */
-#endif /* defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */
+#else /* defined(linux) */
+               bpf_error(cstate, "inbound/outbound not supported on %s",
+                   pcap_datalink_val_to_description_or_dlt(cstate->linktype));
+               /*NOTREACHED*/
+#endif /* defined(linux) */
        }
        return (b0);
 }
 
-#ifdef HAVE_NET_PFVAR_H
 /* PF firewall log matched interface */
 struct block *
 gen_pf_ifname(compiler_state_t *cstate, const char *ifname)
@@ -8070,18 +8423,26 @@ gen_pf_ifname(compiler_state_t *cstate, const char *ifname)
        struct block *b0;
        u_int len, off;
 
-       if (cstate->cgstate->linktype != DLT_PFLOG) {
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
+       if (cstate->linktype != DLT_PFLOG) {
                bpf_error(cstate, "ifname supported only on PF linktype");
-               /* NOTREACHED */
+               /*NOTREACHED*/
        }
        len = sizeof(((struct pfloghdr *)0)->ifname);
        off = offsetof(struct pfloghdr, ifname);
        if (strlen(ifname) >= len) {
                bpf_error(cstate, "ifname interface names can only be %d characters",
                    len-1);
-               /* NOTREACHED */
+               /*NOTREACHED*/
        }
-       b0 = gen_bcmp(cstate, OR_LINKHDR, off, strlen(ifname), (const u_char *)ifname);
+       b0 = gen_bcmp(cstate, OR_LINKHDR, off, (u_int)strlen(ifname),
+           (const u_char *)ifname);
        return (b0);
 }
 
@@ -8091,19 +8452,26 @@ gen_pf_ruleset(compiler_state_t *cstate, char *ruleset)
 {
        struct block *b0;
 
-       if (cstate->cgstate->linktype != DLT_PFLOG) {
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
+       if (cstate->linktype != DLT_PFLOG) {
                bpf_error(cstate, "ruleset supported only on PF linktype");
-               /* NOTREACHED */
+               /*NOTREACHED*/
        }
 
        if (strlen(ruleset) >= sizeof(((struct pfloghdr *)0)->ruleset)) {
                bpf_error(cstate, "ruleset names can only be %ld characters",
                    (long)(sizeof(((struct pfloghdr *)0)->ruleset) - 1));
-               /* NOTREACHED */
+               /*NOTREACHED*/
        }
 
        b0 = gen_bcmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, ruleset),
-           strlen(ruleset), (const u_char *)ruleset);
+           (u_int)strlen(ruleset), (const u_char *)ruleset);
        return (b0);
 }
 
@@ -8113,13 +8481,20 @@ gen_pf_rnr(compiler_state_t *cstate, int rnr)
 {
        struct block *b0;
 
-       if (cstate->cgstate->linktype != DLT_PFLOG) {
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
+       if (cstate->linktype != DLT_PFLOG) {
                bpf_error(cstate, "rnr supported only on PF linktype");
-               /* NOTREACHED */
+               /*NOTREACHED*/
        }
 
        b0 = gen_cmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, rulenr), BPF_W,
-                (bpf_int32)rnr);
+                (bpf_u_int32)rnr);
        return (b0);
 }
 
@@ -8129,13 +8504,20 @@ gen_pf_srnr(compiler_state_t *cstate, int srnr)
 {
        struct block *b0;
 
-       if (cstate->cgstate->linktype != DLT_PFLOG) {
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
+       if (cstate->linktype != DLT_PFLOG) {
                bpf_error(cstate, "srnr supported only on PF linktype");
-               /* NOTREACHED */
+               /*NOTREACHED*/
        }
 
        b0 = gen_cmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, subrulenr), BPF_W,
-           (bpf_int32)srnr);
+           (bpf_u_int32)srnr);
        return (b0);
 }
 
@@ -8145,13 +8527,20 @@ gen_pf_reason(compiler_state_t *cstate, int reason)
 {
        struct block *b0;
 
-       if (cstate->cgstate->linktype != DLT_PFLOG) {
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
+       if (cstate->linktype != DLT_PFLOG) {
                bpf_error(cstate, "reason supported only on PF linktype");
-               /* NOTREACHED */
+               /*NOTREACHED*/
        }
 
        b0 = gen_cmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, reason), BPF_B,
-           (bpf_int32)reason);
+           (bpf_u_int32)reason);
        return (b0);
 }
 
@@ -8161,89 +8550,66 @@ gen_pf_action(compiler_state_t *cstate, int action)
 {
        struct block *b0;
 
-       if (cstate->cgstate->linktype != DLT_PFLOG) {
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
+       if (cstate->linktype != DLT_PFLOG) {
                bpf_error(cstate, "action supported only on PF linktype");
-               /* NOTREACHED */
+               /*NOTREACHED*/
        }
 
        b0 = gen_cmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, action), BPF_B,
-           (bpf_int32)action);
+           (bpf_u_int32)action);
        return (b0);
 }
-#else /* !HAVE_NET_PFVAR_H */
-struct block *
-gen_pf_ifname(compiler_state_t *cstate, const char *ifname _U_)
-{
-       bpf_error(cstate, "libpcap was compiled without pf support");
-       /* NOTREACHED */
-}
-
-struct block *
-gen_pf_ruleset(compiler_state_t *cstate, char *ruleset _U_)
-{
-       bpf_error(cstate, "libpcap was compiled on a machine without pf support");
-       /* NOTREACHED */
-}
-
-struct block *
-gen_pf_rnr(compiler_state_t *cstate, int rnr _U_)
-{
-       bpf_error(cstate, "libpcap was compiled on a machine without pf support");
-       /* NOTREACHED */
-}
-
-struct block *
-gen_pf_srnr(compiler_state_t *cstate, int srnr _U_)
-{
-       bpf_error(cstate, "libpcap was compiled on a machine without pf support");
-       /* NOTREACHED */
-}
-
-struct block *
-gen_pf_reason(compiler_state_t *cstate, int reason _U_)
-{
-       bpf_error(cstate, "libpcap was compiled on a machine without pf support");
-       /* NOTREACHED */
-}
-
-struct block *
-gen_pf_action(compiler_state_t *cstate, int action _U_)
-{
-       bpf_error(cstate, "libpcap was compiled on a machine without pf support");
-       /* NOTREACHED */
-}
-#endif /* HAVE_NET_PFVAR_H */
 
 /* IEEE 802.11 wireless header */
 struct block *
-gen_p80211_type(compiler_state_t *cstate, int type, int mask)
+gen_p80211_type(compiler_state_t *cstate, bpf_u_int32 type, bpf_u_int32 mask)
 {
        struct block *b0;
 
-       switch (cstate->cgstate->linktype) {
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
+       switch (cstate->linktype) {
 
        case DLT_IEEE802_11:
        case DLT_PRISM_HEADER:
        case DLT_IEEE802_11_RADIO_AVS:
        case DLT_IEEE802_11_RADIO:
-               b0 = gen_mcmp(cstate, OR_LINKHDR, 0, BPF_B, (bpf_int32)type,
-                   (bpf_int32)mask);
+               b0 = gen_mcmp(cstate, OR_LINKHDR, 0, BPF_B, type, mask);
                break;
 
        default:
                bpf_error(cstate, "802.11 link-layer types supported only on 802.11");
-               /* NOTREACHED */
+               /*NOTREACHED*/
        }
 
        return (b0);
 }
 
 struct block *
-gen_p80211_fcdir(compiler_state_t *cstate, int fcdir)
+gen_p80211_fcdir(compiler_state_t *cstate, bpf_u_int32 fcdir)
 {
        struct block *b0;
 
-       switch (cstate->cgstate->linktype) {
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
+       switch (cstate->linktype) {
 
        case DLT_IEEE802_11:
        case DLT_PRISM_HEADER:
@@ -8253,11 +8619,11 @@ gen_p80211_fcdir(compiler_state_t *cstate, int fcdir)
 
        default:
                bpf_error(cstate, "frame direction supported only with 802.11 headers");
-               /* NOTREACHED */
+               /*NOTREACHED*/
        }
 
-       b0 = gen_mcmp(cstate, OR_LINKHDR, 1, BPF_B, (bpf_int32)fcdir,
-               (bpf_u_int32)IEEE80211_FC1_DIR_MASK);
+       b0 = gen_mcmp(cstate, OR_LINKHDR, 1, BPF_B, fcdir,
+           IEEE80211_FC1_DIR_MASK);
 
        return (b0);
 }
@@ -8267,28 +8633,33 @@ gen_acode(compiler_state_t *cstate, const char *s, struct qual q)
 {
        struct block *b;
 
-       switch (cstate->cgstate->linktype) {
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
+       switch (cstate->linktype) {
 
        case DLT_ARCNET:
        case DLT_ARCNET_LINUX:
                if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) &&
                    q.proto == Q_LINK) {
-                       cstate->cgstate->e = pcap_ether_aton(s);
-                       if (cstate->cgstate->e == NULL)
+                       cstate->e = pcap_ether_aton(s);
+                       if (cstate->e == NULL)
                                bpf_error(cstate, "malloc");
-                       b = gen_ahostop(cstate, cstate->cgstate->e, (int)q.dir);
-                       free(cstate->cgstate->e);
-                       cstate->cgstate->e = NULL;
+                       b = gen_ahostop(cstate, cstate->e, (int)q.dir);
+                       free(cstate->e);
+                       cstate->e = NULL;
                        return (b);
-               } else {
+               } else
                        bpf_error(cstate, "ARCnet address used in non-arc expression");
-                       /* NOTREACHED */
-               }
-               break;
+               /*NOTREACHED*/
 
        default:
                bpf_error(cstate, "aid supported only on ARCnet");
-               /* NOTREACHED */
+               /*NOTREACHED*/
        }
 }
 
@@ -8320,30 +8691,30 @@ gen_ahostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
 
        case Q_ADDR1:
                bpf_error(cstate, "'addr1' and 'address1' are only supported on 802.11");
-               break;
+               /*NOTREACHED*/
 
        case Q_ADDR2:
                bpf_error(cstate, "'addr2' and 'address2' are only supported on 802.11");
-               break;
+               /*NOTREACHED*/
 
        case Q_ADDR3:
                bpf_error(cstate, "'addr3' and 'address3' are only supported on 802.11");
-               break;
+               /*NOTREACHED*/
 
        case Q_ADDR4:
                bpf_error(cstate, "'addr4' and 'address4' are only supported on 802.11");
-               break;
+               /*NOTREACHED*/
 
        case Q_RA:
                bpf_error(cstate, "'ra' is only supported on 802.11");
-               break;
+               /*NOTREACHED*/
 
        case Q_TA:
                bpf_error(cstate, "'ta' is only supported on 802.11");
-               break;
+               /*NOTREACHED*/
        }
        abort();
-       /* NOTREACHED */
+       /*NOTREACHED*/
 }
 
 static struct block *
@@ -8369,7 +8740,7 @@ gen_vlan_vid_test(compiler_state_t *cstate, bpf_u_int32 vlan_num)
                bpf_error(cstate, "VLAN tag %u greater than maximum %u",
                    vlan_num, 0x0fff);
        }
-       return gen_mcmp(cstate, OR_LINKPL, 0, BPF_H, (bpf_int32)vlan_num, 0x0fff);
+       return gen_mcmp(cstate, OR_LINKPL, 0, BPF_H, vlan_num, 0x0fff);
 }
 
 static struct block *
@@ -8390,8 +8761,8 @@ gen_vlan_no_bpf_extensions(compiler_state_t *cstate, bpf_u_int32 vlan_num,
         * Both payload and link header type follow the VLAN tags so that
         * both need to be updated.
         */
-       cstate->cgstate->off_linkpl.constant_part += 4;
-       cstate->cgstate->off_linktype.constant_part += 4;
+       cstate->off_linkpl.constant_part += 4;
+       cstate->off_linktype.constant_part += 4;
 
        return b0;
 }
@@ -8399,7 +8770,8 @@ gen_vlan_no_bpf_extensions(compiler_state_t *cstate, bpf_u_int32 vlan_num,
 #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)
+gen_vlan_vloffset_add(compiler_state_t *cstate, bpf_abs_offset *off,
+    bpf_u_int32 v, struct slist *s)
 {
        struct slist *s2;
 
@@ -8430,9 +8802,9 @@ gen_vlan_patch_tpid_test(compiler_state_t *cstate, struct block *b_tpid)
 
        /* offset determined at run time, shift variable part */
        s.next = NULL;
-       cstate->cgstate->is_vlan_vloffset = 1;
-       gen_vlan_vloffset_add(cstate, &cstate->cgstate->off_linkpl, 4, &s);
-       gen_vlan_vloffset_add(cstate, &cstate->cgstate->off_linktype, 4, &s);
+       cstate->is_vlan_vloffset = 1;
+       gen_vlan_vloffset_add(cstate, &cstate->off_linkpl, 4, &s);
+       gen_vlan_vloffset_add(cstate, &cstate->off_linktype, 4, &s);
 
        /* we get a pointer to a chain of or-ed blocks, patch first of them */
        sappend(s.next, b_tpid->head->stmts);
@@ -8505,7 +8877,7 @@ gen_vlan_bpf_extensions(compiler_state_t *cstate, bpf_u_int32 vlan_num,
 
        /*
         * This is tricky. We need to insert the statements updating variable
-        * parts of offsets before the the traditional TPID and VID tests so
+        * parts of offsets before the traditional TPID and VID tests so
         * that they are called whenever SKF_AD_VLAN_TAG_PRESENT fails but
         * we do not want this update to affect those checks. That's why we
         * generate both test blocks first and insert the statements updating
@@ -8539,8 +8911,15 @@ gen_vlan(compiler_state_t *cstate, bpf_u_int32 vlan_num, int has_vlan_tag)
 {
        struct  block   *b0;
 
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
        /* can't check for VLAN-encapsulated packets inside MPLS */
-       if (cstate->cgstate->label_stack_depth > 0)
+       if (cstate->label_stack_depth > 0)
                bpf_error(cstate, "no VLAN match after MPLS");
 
        /*
@@ -8574,7 +8953,7 @@ gen_vlan(compiler_state_t *cstate, bpf_u_int32 vlan_num, int has_vlan_tag)
         * be done assuming a VLAN, even though the "or" could be viewed
         * as meaning "or, if this isn't a VLAN packet...".
         */
-       switch (cstate->cgstate->linktype) {
+       switch (cstate->linktype) {
 
        case DLT_EN10MB:
        case DLT_NETANALYZER:
@@ -8582,9 +8961,9 @@ gen_vlan(compiler_state_t *cstate, bpf_u_int32 vlan_num, int has_vlan_tag)
 #if defined(SKF_AD_VLAN_TAG_PRESENT)
                /* Verify that this is the outer part of the packet and
                 * not encapsulated somehow. */
-               if (cstate->cgstate->vlan_stack_depth == 0 && !cstate->cgstate->off_linkhdr.is_variable &&
-                   cstate->cgstate->off_linkhdr.constant_part ==
-                   cstate->cgstate->off_outermostlinkhdr.constant_part) {
+               if (cstate->vlan_stack_depth == 0 && !cstate->off_linkhdr.is_variable &&
+                   cstate->off_linkhdr.constant_part ==
+                   cstate->off_outermostlinkhdr.constant_part) {
                        /*
                         * Do we need special VLAN handling?
                         */
@@ -8608,25 +8987,38 @@ gen_vlan(compiler_state_t *cstate, bpf_u_int32 vlan_num, int has_vlan_tag)
                break;
 
        default:
-               bpf_error(cstate, "no VLAN support for data link type %d",
-                     cstate->cgstate->linktype);
+               bpf_error(cstate, "no VLAN support for %s",
+                     pcap_datalink_val_to_description_or_dlt(cstate->linktype));
                /*NOTREACHED*/
        }
 
-        cstate->cgstate->vlan_stack_depth++;
+        cstate->vlan_stack_depth++;
 
        return (b0);
 }
 
 /*
  * support for MPLS
+ *
+ * The label_num_arg dance is to avoid annoying whining by compilers that
+ * label_num might be clobbered by longjmp - yeah, it might, but *WHO CARES*?
+ * It's not *used* after setjmp returns.
  */
 struct block *
-gen_mpls(compiler_state_t *cstate, bpf_u_int32 label_num, int has_label_num)
+gen_mpls(compiler_state_t *cstate, bpf_u_int32 label_num_arg,
+    int has_label_num)
 {
+       volatile bpf_u_int32 label_num = label_num_arg;
        struct  block   *b0, *b1;
 
-        if (cstate->cgstate->label_stack_depth > 0) {
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
+        if (cstate->label_stack_depth > 0) {
             /* just match the bottom-of-stack bit clear */
             b0 = gen_mcmp(cstate, OR_PREVMPLSHDR, 2, BPF_B, 0, 0x01);
         } else {
@@ -8634,9 +9026,10 @@ gen_mpls(compiler_state_t *cstate, bpf_u_int32 label_num, int has_label_num)
              * We're not in an MPLS stack yet, so check the link-layer
              * type against MPLS.
              */
-            switch (cstate->cgstate->linktype) {
+            switch (cstate->linktype) {
 
             case DLT_C_HDLC: /* fall through */
+            case DLT_HDLC:
             case DLT_EN10MB:
             case DLT_NETANALYZER:
             case DLT_NETANALYZER_TRANSPARENT:
@@ -8652,10 +9045,9 @@ gen_mpls(compiler_state_t *cstate, bpf_u_int32 label_num, int has_label_num)
                      * leave it for now */
 
             default:
-                    bpf_error(cstate, "no MPLS support for data link type %d",
-                          cstate->cgstate->linktype);
+                    bpf_error(cstate, "no MPLS support for %s",
+                          pcap_datalink_val_to_description_or_dlt(cstate->linktype));
                     /*NOTREACHED*/
-                    break;
             }
         }
 
@@ -8666,7 +9058,7 @@ gen_mpls(compiler_state_t *cstate, bpf_u_int32 label_num, int has_label_num)
                            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,
+               b1 = gen_mcmp(cstate, OR_LINKPL, 0, BPF_W, label_num,
                    0xfffff000); /* only compare the first 20 bits */
                gen_and(b0, b1);
                b0 = b1;
@@ -8686,9 +9078,9 @@ gen_mpls(compiler_state_t *cstate, bpf_u_int32 label_num, int has_label_num)
          *
          * XXX - this is a bit of a kludge.  See comments in gen_vlan().
          */
-        cstate->cgstate->off_nl_nosnap += 4;
-        cstate->cgstate->off_nl += 4;
-        cstate->cgstate->label_stack_depth++;
+        cstate->off_nl_nosnap += 4;
+        cstate->off_nl += 4;
+        cstate->label_stack_depth++;
        return (b0);
 }
 
@@ -8698,8 +9090,15 @@ gen_mpls(compiler_state_t *cstate, bpf_u_int32 label_num, int has_label_num)
 struct block *
 gen_pppoed(compiler_state_t *cstate)
 {
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
        /* check for PPPoE discovery */
-       return gen_linktype(cstate, (bpf_int32)ETHERTYPE_PPPOED);
+       return gen_linktype(cstate, ETHERTYPE_PPPOED);
 }
 
 struct block *
@@ -8707,10 +9106,17 @@ gen_pppoes(compiler_state_t *cstate, bpf_u_int32 sess_num, int has_sess_num)
 {
        struct block *b0, *b1;
 
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
        /*
         * Test against the PPPoE session link-layer type.
         */
-       b0 = gen_linktype(cstate, (bpf_int32)ETHERTYPE_PPPOES);
+       b0 = gen_linktype(cstate, ETHERTYPE_PPPOES);
 
        /* If a specific session is requested, check PPPoE session id */
        if (has_sess_num) {
@@ -8718,8 +9124,7 @@ gen_pppoes(compiler_state_t *cstate, bpf_u_int32 sess_num, int has_sess_num)
                        bpf_error(cstate, "PPPoE session number %u greater than maximum %u",
                            sess_num, 0x0000ffff);
                }
-               b1 = gen_mcmp(cstate, OR_LINKPL, 0, BPF_W,
-                   (bpf_int32)sess_num, 0x0000ffff);
+               b1 = gen_mcmp(cstate, OR_LINKPL, 0, BPF_W, sess_num, 0x0000ffff);
                gen_and(b0, b1);
                b0 = b1;
        }
@@ -8729,29 +9134,8 @@ gen_pppoes(compiler_state_t *cstate, bpf_u_int32 sess_num, int has_sess_num)
         * 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
-        * generates an expression tree, and a code generator that
-        * takes an expression tree (which could come from our
-        * parser or from some other parser) and generates BPF code,
-        * we could perhaps make the offsets parameters of routines
-        * and, in the handler for an "AND" node, pass to subnodes
-        * other than the PPPoE node the adjusted offsets.
-        *
-        * This would mean that "pppoes" would, instead of changing the
-        * behavior of *all* tests after it, change only the behavior
-        * of tests ANDed with it.  That would change the documented
-        * semantics of "pppoes", which might break some expressions.
-        * However, it would mean that "(pppoes and ip) or ip" would check
-        * both for VLAN-encapsulated IP and IP-over-Ethernet, rather than
-        * checking only for VLAN-encapsulated IP, so that could still
-        * be considered worth doing; it wouldn't break expressions
-        * that are of the form "pppoes and ..." which I suspect are the
-        * most common expressions involving "pppoes".  "pppoes or ..."
-        * doesn't necessarily do what the user would really want, now,
-        * as all the "or ..." tests would be done assuming PPPoE, even
-        * though the "or" could be viewed as meaning "or, if this isn't
-        * a PPPoE packet...".
+        * XXX - this is a bit of a kludge.  See the comments in
+        * gen_vlan().
         *
         * The "network-layer" protocol is PPPoE, which has a 6-byte
         * PPPoE header, followed by a PPP packet.
@@ -8761,17 +9145,17 @@ gen_pppoes(compiler_state_t *cstate, bpf_u_int32 sess_num, int has_sess_num)
         * 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 cstate->cgstate->off_nl.
+        * it's 6 bytes past cstate->off_nl.
         */
-       PUSH_LINKHDR(cstate, DLT_PPP, cstate->cgstate->off_linkpl.is_variable,
-           cstate->cgstate->off_linkpl.constant_part + cstate->cgstate->off_nl + 6, /* 6 bytes past the PPPoE header */
-           cstate->cgstate->off_linkpl.reg);
+       PUSH_LINKHDR(cstate, DLT_PPP, cstate->off_linkpl.is_variable,
+           cstate->off_linkpl.constant_part + cstate->off_nl + 6, /* 6 bytes past the PPPoE header */
+           cstate->off_linkpl.reg);
 
-       cstate->cgstate->off_linktype = cstate->cgstate->off_linkhdr;
-       cstate->cgstate->off_linkpl.constant_part = cstate->cgstate->off_linkhdr.constant_part + 2;
+       cstate->off_linktype = cstate->off_linkhdr;
+       cstate->off_linkpl.constant_part = cstate->off_linkhdr.constant_part + 2;
 
-       cstate->cgstate->off_nl = 0;
-       cstate->cgstate->off_nl_nosnap = 0;     /* no 802.2 LLC */
+       cstate->off_nl = 0;
+       cstate->off_nl_nosnap = 0;      /* no 802.2 LLC */
 
        return b0;
 }
@@ -8780,7 +9164,7 @@ gen_pppoes(compiler_state_t *cstate, bpf_u_int32 sess_num, int has_sess_num)
  * specified. Parameterized to handle both IPv4 and IPv6. */
 static struct block *
 gen_geneve_check(compiler_state_t *cstate,
-    struct block *(*gen_portfn)(compiler_state_t *, int, int, int),
+    struct block *(*gen_portfn)(compiler_state_t *, u_int, int, int),
     enum e_offrel offrel, bpf_u_int32 vni, int has_vni)
 {
        struct block *b0, *b1;
@@ -8790,7 +9174,7 @@ gen_geneve_check(compiler_state_t *cstate,
        /* Check that we are operating on version 0. Otherwise, we
         * can't decode the rest of the fields. The version is 2 bits
         * in the first byte of the Geneve header. */
-       b1 = gen_mcmp(cstate, offrel, 8, BPF_B, (bpf_int32)0, 0xc0);
+       b1 = gen_mcmp(cstate, offrel, 8, BPF_B, 0, 0xc0);
        gen_and(b0, b1);
        b0 = b1;
 
@@ -8800,8 +9184,7 @@ gen_geneve_check(compiler_state_t *cstate,
                            vni, 0xffffff);
                }
                vni <<= 8; /* VNI is in the upper 3 bytes */
-               b1 = gen_mcmp(cstate, offrel, 12, BPF_W, (bpf_int32)vni,
-                             0xffffff00);
+               b1 = gen_mcmp(cstate, offrel, 12, BPF_W, vni, 0xffffff00);
                gen_and(b0, b1);
                b0 = b1;
        }
@@ -8850,7 +9233,7 @@ gen_geneve6(compiler_state_t *cstate, bpf_u_int32 vni, int has_vni)
 
        /* Load the IP header length. We need to account for a
         * variable length link prefix if there is one. */
-       s = gen_abs_offset_varpart(cstate, &cstate->cgstate->off_linkpl);
+       s = gen_abs_offset_varpart(cstate, &cstate->off_linkpl);
        if (s) {
                s1 = new_stmt(cstate, BPF_LD|BPF_IMM);
                s1->s.k = 40;
@@ -8894,7 +9277,7 @@ gen_geneve_offsets(compiler_state_t *cstate)
         * fixed sized headers (fixed link prefix, MAC length, and UDP
         * header). */
        s = new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_K);
-       s->s.k = cstate->cgstate->off_linkpl.constant_part + cstate->cgstate->off_nl + 8;
+       s->s.k = cstate->off_linkpl.constant_part + cstate->off_nl + 8;
 
        /* Stash this in X since we'll need it later. */
        s1 = new_stmt(cstate, BPF_MISC|BPF_TAX);
@@ -8906,12 +9289,12 @@ gen_geneve_offsets(compiler_state_t *cstate)
        s1->s.k = 2;
        sappend(s, s1);
 
-       cstate->cgstate->off_linktype.reg = alloc_reg(cstate);
-       cstate->cgstate->off_linktype.is_variable = 1;
-       cstate->cgstate->off_linktype.constant_part = 0;
+       cstate->off_linktype.reg = alloc_reg(cstate);
+       cstate->off_linktype.is_variable = 1;
+       cstate->off_linktype.constant_part = 0;
 
        s1 = new_stmt(cstate, BPF_ST);
-       s1->s.k = cstate->cgstate->off_linktype.reg;
+       s1->s.k = cstate->off_linktype.reg;
        sappend(s, s1);
 
        /* Load the Geneve option length and mask and shift to get the
@@ -8950,7 +9333,7 @@ gen_geneve_offsets(compiler_state_t *cstate)
        PUSH_LINKHDR(cstate, DLT_EN10MB, 1, 0, alloc_reg(cstate));
 
        s1 = new_stmt(cstate, BPF_ST);
-       s1->s.k = cstate->cgstate->off_linkhdr.reg;
+       s1->s.k = cstate->off_linkhdr.reg;
        sappend(s, s1);
 
        /* Calculate whether we have an Ethernet header or just raw IP/
@@ -8959,7 +9342,7 @@ gen_geneve_offsets(compiler_state_t *cstate)
         * seamlessly. Otherwise, keep what we've calculated already. */
 
        /* We have a bare jmp so we can't use the optimizer. */
-       cstate->cgstate->no_optimize = 1;
+       cstate->no_optimize = 1;
 
        /* Load the EtherType in the Geneve header, 2 bytes in. */
        s1 = new_stmt(cstate, BPF_LD|BPF_IND|BPF_H);
@@ -8968,7 +9351,7 @@ gen_geneve_offsets(compiler_state_t *cstate)
 
        /* Load X with the end of the Geneve header. */
        s1 = new_stmt(cstate, BPF_LDX|BPF_MEM);
-       s1->s.k = cstate->cgstate->off_linkhdr.reg;
+       s1->s.k = cstate->off_linkhdr.reg;
        sappend(s, s1);
 
        /* Check if the EtherType is Transparent Ethernet Bridging. At the
@@ -8989,7 +9372,7 @@ gen_geneve_offsets(compiler_state_t *cstate)
        sappend(s, s1);
 
        s1 = new_stmt(cstate, BPF_ST);
-       s1->s.k = cstate->cgstate->off_linktype.reg;
+       s1->s.k = cstate->off_linktype.reg;
        sappend(s, s1);
 
        /* Advance two bytes further to get the end of the Ethernet
@@ -9003,16 +9386,16 @@ gen_geneve_offsets(compiler_state_t *cstate)
        sappend(s, s1);
 
        /* Store the final result of our linkpl calculation. */
-       cstate->cgstate->off_linkpl.reg = alloc_reg(cstate);
-       cstate->cgstate->off_linkpl.is_variable = 1;
-       cstate->cgstate->off_linkpl.constant_part = 0;
+       cstate->off_linkpl.reg = alloc_reg(cstate);
+       cstate->off_linkpl.is_variable = 1;
+       cstate->off_linkpl.constant_part = 0;
 
        s1 = new_stmt(cstate, BPF_STX);
-       s1->s.k = cstate->cgstate->off_linkpl.reg;
+       s1->s.k = cstate->off_linkpl.reg;
        sappend(s, s1);
        s_proto->s.jf = s1;
 
-       cstate->cgstate->off_nl = 0;
+       cstate->off_nl = 0;
 
        return s;
 }
@@ -9024,6 +9407,13 @@ gen_geneve(compiler_state_t *cstate, bpf_u_int32 vni, int has_vni)
        struct block *b0, *b1;
        struct slist *s;
 
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
        b0 = gen_geneve4(cstate, vni, has_vni);
        b1 = gen_geneve6(cstate, vni, has_vni);
 
@@ -9041,7 +9431,7 @@ gen_geneve(compiler_state_t *cstate, bpf_u_int32 vni, int has_vni)
 
        gen_and(b0, b1);
 
-       cstate->cgstate->is_geneve = 1;
+       cstate->is_geneve = 1;
 
        return b1;
 }
@@ -9061,10 +9451,10 @@ gen_geneve_ll_check(compiler_state_t *cstate)
        /* Geneve always generates pure variable offsets so we can
         * compare only the registers. */
        s = new_stmt(cstate, BPF_LD|BPF_MEM);
-       s->s.k = cstate->cgstate->off_linkhdr.reg;
+       s->s.k = cstate->off_linkhdr.reg;
 
        s1 = new_stmt(cstate, BPF_LDX|BPF_MEM);
-       s1->s.k = cstate->cgstate->off_linkpl.reg;
+       s1->s.k = cstate->off_linkpl.reg;
        sappend(s, s1);
 
        b0 = new_block(cstate, BPF_JMP|BPF_JEQ|BPF_X);
@@ -9075,53 +9465,53 @@ gen_geneve_ll_check(compiler_state_t *cstate)
        return b0;
 }
 
-struct block *
-gen_atmfield_code(compiler_state_t *cstate, int atmfield, bpf_int32 jvalue,
-    bpf_u_int32 jtype, int reverse)
+static struct block *
+gen_atmfield_code_internal(compiler_state_t *cstate, int atmfield,
+    bpf_u_int32 jvalue, int jtype, int reverse)
 {
        struct block *b0;
 
        switch (atmfield) {
 
        case A_VPI:
-               if (!cstate->cgstate->is_atm)
+               if (!cstate->is_atm)
                        bpf_error(cstate, "'vpi' supported only on raw ATM");
-               if (cstate->cgstate->off_vpi == OFFSET_NOT_SET)
+               if (cstate->off_vpi == OFFSET_NOT_SET)
                        abort();
-               b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->cgstate->off_vpi, BPF_B, 0xffffffff, jtype,
-                   reverse, jvalue);
+               b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_vpi, BPF_B,
+                   0xffffffffU, jtype, reverse, jvalue);
                break;
 
        case A_VCI:
-               if (!cstate->cgstate->is_atm)
+               if (!cstate->is_atm)
                        bpf_error(cstate, "'vci' supported only on raw ATM");
-               if (cstate->cgstate->off_vci == OFFSET_NOT_SET)
+               if (cstate->off_vci == OFFSET_NOT_SET)
                        abort();
-               b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->cgstate->off_vci, BPF_H, 0xffffffff, jtype,
-                   reverse, jvalue);
+               b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_vci, BPF_H,
+                   0xffffffffU, jtype, reverse, jvalue);
                break;
 
        case A_PROTOTYPE:
-               if (cstate->cgstate->off_proto == OFFSET_NOT_SET)
+               if (cstate->off_proto == OFFSET_NOT_SET)
                        abort();        /* XXX - this isn't on FreeBSD */
-               b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->cgstate->off_proto, BPF_B, 0x0f, jtype,
-                   reverse, jvalue);
+               b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_proto, BPF_B,
+                   0x0fU, jtype, reverse, jvalue);
                break;
 
        case A_MSGTYPE:
-               if (cstate->cgstate->off_payload == OFFSET_NOT_SET)
+               if (cstate->off_payload == OFFSET_NOT_SET)
                        abort();
-               b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->cgstate->off_payload + MSG_TYPE_POS, BPF_B,
-                   0xffffffff, jtype, reverse, jvalue);
+               b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_payload + MSG_TYPE_POS, BPF_B,
+                   0xffffffffU, jtype, reverse, jvalue);
                break;
 
        case A_CALLREFTYPE:
-               if (!cstate->cgstate->is_atm)
+               if (!cstate->is_atm)
                        bpf_error(cstate, "'callref' supported only on raw ATM");
-               if (cstate->cgstate->off_proto == OFFSET_NOT_SET)
+               if (cstate->off_proto == OFFSET_NOT_SET)
                        abort();
-               b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->cgstate->off_proto, BPF_B, 0xffffffff,
-                   jtype, reverse, jvalue);
+               b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_proto, BPF_B,
+                   0xffffffffU, jtype, reverse, jvalue);
                break;
 
        default:
@@ -9130,72 +9520,122 @@ gen_atmfield_code(compiler_state_t *cstate, int atmfield, bpf_int32 jvalue,
        return b0;
 }
 
+static struct block *
+gen_atmtype_metac(compiler_state_t *cstate)
+{
+       struct block *b0, *b1;
+
+       b0 = gen_atmfield_code_internal(cstate, A_VPI, 0, BPF_JEQ, 0);
+       b1 = gen_atmfield_code_internal(cstate, A_VCI, 1, BPF_JEQ, 0);
+       gen_and(b0, b1);
+       return b1;
+}
+
+static struct block *
+gen_atmtype_sc(compiler_state_t *cstate)
+{
+       struct block *b0, *b1;
+
+       b0 = gen_atmfield_code_internal(cstate, A_VPI, 0, BPF_JEQ, 0);
+       b1 = gen_atmfield_code_internal(cstate, A_VCI, 5, BPF_JEQ, 0);
+       gen_and(b0, b1);
+       return b1;
+}
+
+static struct block *
+gen_atmtype_llc(compiler_state_t *cstate)
+{
+       struct block *b0;
+
+       b0 = gen_atmfield_code_internal(cstate, A_PROTOTYPE, PT_LLC, BPF_JEQ, 0);
+       cstate->linktype = cstate->prevlinktype;
+       return b0;
+}
+
+struct block *
+gen_atmfield_code(compiler_state_t *cstate, int atmfield,
+    bpf_u_int32 jvalue, int jtype, int reverse)
+{
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
+       return gen_atmfield_code_internal(cstate, atmfield, jvalue, jtype,
+           reverse);
+}
+
 struct block *
 gen_atmtype_abbrev(compiler_state_t *cstate, int type)
 {
        struct block *b0, *b1;
 
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
        switch (type) {
 
        case A_METAC:
                /* Get all packets in Meta signalling Circuit */
-               if (!cstate->cgstate->is_atm)
+               if (!cstate->is_atm)
                        bpf_error(cstate, "'metac' supported only on raw ATM");
-               b0 = gen_atmfield_code(cstate, A_VPI, 0, BPF_JEQ, 0);
-               b1 = gen_atmfield_code(cstate, A_VCI, 1, BPF_JEQ, 0);
-               gen_and(b0, b1);
+               b1 = gen_atmtype_metac(cstate);
                break;
 
        case A_BCC:
                /* Get all packets in Broadcast Circuit*/
-               if (!cstate->cgstate->is_atm)
+               if (!cstate->is_atm)
                        bpf_error(cstate, "'bcc' supported only on raw ATM");
-               b0 = gen_atmfield_code(cstate, A_VPI, 0, BPF_JEQ, 0);
-               b1 = gen_atmfield_code(cstate, A_VCI, 2, BPF_JEQ, 0);
+               b0 = gen_atmfield_code_internal(cstate, A_VPI, 0, BPF_JEQ, 0);
+               b1 = gen_atmfield_code_internal(cstate, A_VCI, 2, BPF_JEQ, 0);
                gen_and(b0, b1);
                break;
 
        case A_OAMF4SC:
                /* Get all cells in Segment OAM F4 circuit*/
-               if (!cstate->cgstate->is_atm)
+               if (!cstate->is_atm)
                        bpf_error(cstate, "'oam4sc' supported only on raw ATM");
-               b0 = gen_atmfield_code(cstate, A_VPI, 0, BPF_JEQ, 0);
-               b1 = gen_atmfield_code(cstate, A_VCI, 3, BPF_JEQ, 0);
+               b0 = gen_atmfield_code_internal(cstate, A_VPI, 0, BPF_JEQ, 0);
+               b1 = gen_atmfield_code_internal(cstate, A_VCI, 3, BPF_JEQ, 0);
                gen_and(b0, b1);
                break;
 
        case A_OAMF4EC:
                /* Get all cells in End-to-End OAM F4 Circuit*/
-               if (!cstate->cgstate->is_atm)
+               if (!cstate->is_atm)
                        bpf_error(cstate, "'oam4ec' supported only on raw ATM");
-               b0 = gen_atmfield_code(cstate, A_VPI, 0, BPF_JEQ, 0);
-               b1 = gen_atmfield_code(cstate, A_VCI, 4, BPF_JEQ, 0);
+               b0 = gen_atmfield_code_internal(cstate, A_VPI, 0, BPF_JEQ, 0);
+               b1 = gen_atmfield_code_internal(cstate, A_VCI, 4, BPF_JEQ, 0);
                gen_and(b0, b1);
                break;
 
        case A_SC:
                /*  Get all packets in connection Signalling Circuit */
-               if (!cstate->cgstate->is_atm)
+               if (!cstate->is_atm)
                        bpf_error(cstate, "'sc' supported only on raw ATM");
-               b0 = gen_atmfield_code(cstate, A_VPI, 0, BPF_JEQ, 0);
-               b1 = gen_atmfield_code(cstate, A_VCI, 5, BPF_JEQ, 0);
-               gen_and(b0, b1);
+               b1 = gen_atmtype_sc(cstate);
                break;
 
        case A_ILMIC:
                /* Get all packets in ILMI Circuit */
-               if (!cstate->cgstate->is_atm)
+               if (!cstate->is_atm)
                        bpf_error(cstate, "'ilmic' supported only on raw ATM");
-               b0 = gen_atmfield_code(cstate, A_VPI, 0, BPF_JEQ, 0);
-               b1 = gen_atmfield_code(cstate, A_VCI, 16, BPF_JEQ, 0);
+               b0 = gen_atmfield_code_internal(cstate, A_VPI, 0, BPF_JEQ, 0);
+               b1 = gen_atmfield_code_internal(cstate, A_VCI, 16, BPF_JEQ, 0);
                gen_and(b0, b1);
                break;
 
        case A_LANE:
                /* Get all LANE packets */
-               if (!cstate->cgstate->is_atm)
+               if (!cstate->is_atm)
                        bpf_error(cstate, "'lane' supported only on raw ATM");
-               b1 = gen_atmfield_code(cstate, A_PROTOTYPE, PT_LANE, BPF_JEQ, 0);
+               b1 = gen_atmfield_code_internal(cstate, A_PROTOTYPE, PT_LANE, BPF_JEQ, 0);
 
                /*
                 * Arrange that all subsequent tests assume LANE
@@ -9206,20 +9646,19 @@ gen_atmtype_abbrev(compiler_state_t *cstate, int type)
                 * We assume LANE means Ethernet, not Token Ring.
                 */
                PUSH_LINKHDR(cstate, DLT_EN10MB, 0,
-                   cstate->cgstate->off_payload + 2,   /* Ethernet header */
+                   cstate->off_payload + 2,    /* Ethernet header */
                    -1);
-               cstate->cgstate->off_linktype.constant_part = cstate->cgstate->off_linkhdr.constant_part + 12;
-               cstate->cgstate->off_linkpl.constant_part = cstate->cgstate->off_linkhdr.constant_part + 14;    /* Ethernet */
-               cstate->cgstate->off_nl = 0;                    /* Ethernet II */
-               cstate->cgstate->off_nl_nosnap = 3;             /* 802.3+802.2 */
+               cstate->off_linktype.constant_part = cstate->off_linkhdr.constant_part + 12;
+               cstate->off_linkpl.constant_part = cstate->off_linkhdr.constant_part + 14;      /* Ethernet */
+               cstate->off_nl = 0;                     /* Ethernet II */
+               cstate->off_nl_nosnap = 3;              /* 802.3+802.2 */
                break;
 
        case A_LLC:
                /* Get all LLC-encapsulated packets */
-               if (!cstate->cgstate->is_atm)
+               if (!cstate->is_atm)
                        bpf_error(cstate, "'llc' supported only on raw ATM");
-               b1 = gen_atmfield_code(cstate, A_PROTOTYPE, PT_LLC, BPF_JEQ, 0);
-               cstate->cgstate->linktype = cstate->cgstate->prevlinktype;
+               b1 = gen_atmtype_llc(cstate);
                break;
 
        default:
@@ -9240,60 +9679,75 @@ gen_mtp2type_abbrev(compiler_state_t *cstate, int type)
 {
        struct block *b0, *b1;
 
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
        switch (type) {
 
        case M_FISU:
-               if ( (cstate->cgstate->linktype != DLT_MTP2) &&
-                    (cstate->cgstate->linktype != DLT_ERF) &&
-                    (cstate->cgstate->linktype != DLT_MTP2_WITH_PHDR) )
+               if ( (cstate->linktype != DLT_MTP2) &&
+                    (cstate->linktype != DLT_ERF) &&
+                    (cstate->linktype != DLT_MTP2_WITH_PHDR) )
                        bpf_error(cstate, "'fisu' supported only on MTP2");
                /* gen_ncmp(cstate, offrel, offset, size, mask, jtype, reverse, value) */
-               b0 = gen_ncmp(cstate, OR_PACKET, cstate->cgstate->off_li, BPF_B, 0x3f, BPF_JEQ, 0, 0);
+               b0 = gen_ncmp(cstate, OR_PACKET, cstate->off_li, BPF_B,
+                   0x3fU, BPF_JEQ, 0, 0U);
                break;
 
        case M_LSSU:
-               if ( (cstate->cgstate->linktype != DLT_MTP2) &&
-                    (cstate->cgstate->linktype != DLT_ERF) &&
-                    (cstate->cgstate->linktype != DLT_MTP2_WITH_PHDR) )
+               if ( (cstate->linktype != DLT_MTP2) &&
+                    (cstate->linktype != DLT_ERF) &&
+                    (cstate->linktype != DLT_MTP2_WITH_PHDR) )
                        bpf_error(cstate, "'lssu' supported only on MTP2");
-               b0 = gen_ncmp(cstate, OR_PACKET, cstate->cgstate->off_li, BPF_B, 0x3f, BPF_JGT, 1, 2);
-               b1 = gen_ncmp(cstate, OR_PACKET, cstate->cgstate->off_li, BPF_B, 0x3f, BPF_JGT, 0, 0);
+               b0 = gen_ncmp(cstate, OR_PACKET, cstate->off_li, BPF_B,
+                   0x3fU, BPF_JGT, 1, 2U);
+               b1 = gen_ncmp(cstate, OR_PACKET, cstate->off_li, BPF_B,
+                   0x3fU, BPF_JGT, 0, 0U);
                gen_and(b1, b0);
                break;
 
        case M_MSU:
-               if ( (cstate->cgstate->linktype != DLT_MTP2) &&
-                    (cstate->cgstate->linktype != DLT_ERF) &&
-                    (cstate->cgstate->linktype != DLT_MTP2_WITH_PHDR) )
+               if ( (cstate->linktype != DLT_MTP2) &&
+                    (cstate->linktype != DLT_ERF) &&
+                    (cstate->linktype != DLT_MTP2_WITH_PHDR) )
                        bpf_error(cstate, "'msu' supported only on MTP2");
-               b0 = gen_ncmp(cstate, OR_PACKET, cstate->cgstate->off_li, BPF_B, 0x3f, BPF_JGT, 0, 2);
+               b0 = gen_ncmp(cstate, OR_PACKET, cstate->off_li, BPF_B,
+                   0x3fU, BPF_JGT, 0, 2U);
                break;
 
        case MH_FISU:
-               if ( (cstate->cgstate->linktype != DLT_MTP2) &&
-                    (cstate->cgstate->linktype != DLT_ERF) &&
-                    (cstate->cgstate->linktype != DLT_MTP2_WITH_PHDR) )
+               if ( (cstate->linktype != DLT_MTP2) &&
+                    (cstate->linktype != DLT_ERF) &&
+                    (cstate->linktype != DLT_MTP2_WITH_PHDR) )
                        bpf_error(cstate, "'hfisu' supported only on MTP2_HSL");
                /* gen_ncmp(cstate, offrel, offset, size, mask, jtype, reverse, value) */
-               b0 = gen_ncmp(cstate, OR_PACKET, cstate->cgstate->off_li_hsl, BPF_H, 0xff80, BPF_JEQ, 0, 0);
+               b0 = gen_ncmp(cstate, OR_PACKET, cstate->off_li_hsl, BPF_H,
+                   0xff80U, BPF_JEQ, 0, 0U);
                break;
 
        case MH_LSSU:
-               if ( (cstate->cgstate->linktype != DLT_MTP2) &&
-                    (cstate->cgstate->linktype != DLT_ERF) &&
-                    (cstate->cgstate->linktype != DLT_MTP2_WITH_PHDR) )
+               if ( (cstate->linktype != DLT_MTP2) &&
+                    (cstate->linktype != DLT_ERF) &&
+                    (cstate->linktype != DLT_MTP2_WITH_PHDR) )
                        bpf_error(cstate, "'hlssu' supported only on MTP2_HSL");
-               b0 = gen_ncmp(cstate, OR_PACKET, cstate->cgstate->off_li_hsl, BPF_H, 0xff80, BPF_JGT, 1, 0x0100);
-               b1 = gen_ncmp(cstate, OR_PACKET, cstate->cgstate->off_li_hsl, BPF_H, 0xff80, BPF_JGT, 0, 0);
+               b0 = gen_ncmp(cstate, OR_PACKET, cstate->off_li_hsl, BPF_H,
+                   0xff80U, BPF_JGT, 1, 0x0100U);
+               b1 = gen_ncmp(cstate, OR_PACKET, cstate->off_li_hsl, BPF_H,
+                   0xff80U, BPF_JGT, 0, 0U);
                gen_and(b1, b0);
                break;
 
        case MH_MSU:
-               if ( (cstate->cgstate->linktype != DLT_MTP2) &&
-                    (cstate->cgstate->linktype != DLT_ERF) &&
-                    (cstate->cgstate->linktype != DLT_MTP2_WITH_PHDR) )
+               if ( (cstate->linktype != DLT_MTP2) &&
+                    (cstate->linktype != DLT_ERF) &&
+                    (cstate->linktype != DLT_MTP2_WITH_PHDR) )
                        bpf_error(cstate, "'hmsu' supported only on MTP2_HSL");
-               b0 = gen_ncmp(cstate, OR_PACKET, cstate->cgstate->off_li_hsl, BPF_H, 0xff80, BPF_JGT, 0, 0x0100);
+               b0 = gen_ncmp(cstate, OR_PACKET, cstate->off_li_hsl, BPF_H,
+                   0xff80U, BPF_JGT, 0, 0x0100U);
                break;
 
        default:
@@ -9302,17 +9756,34 @@ gen_mtp2type_abbrev(compiler_state_t *cstate, int type)
        return b0;
 }
 
+/*
+ * The jvalue_arg dance is to avoid annoying whining by compilers that
+ * jvalue might be clobbered by longjmp - yeah, it might, but *WHO CARES*?
+ * It's not *used* after setjmp returns.
+ */
 struct block *
-gen_mtp3field_code(compiler_state_t *cstate, int mtp3field, bpf_u_int32 jvalue,
-    bpf_u_int32 jtype, int reverse)
+gen_mtp3field_code(compiler_state_t *cstate, int mtp3field,
+    bpf_u_int32 jvalue_arg, int jtype, int reverse)
 {
+       volatile bpf_u_int32 jvalue = jvalue_arg;
        struct block *b0;
        bpf_u_int32 val1 , val2 , val3;
-       u_int newoff_sio = cstate->cgstate->off_sio;
-       u_int newoff_opc = cstate->cgstate->off_opc;
-       u_int newoff_dpc = cstate->cgstate->off_dpc;
-       u_int newoff_sls = cstate->cgstate->off_sls;
+       u_int newoff_sio;
+       u_int newoff_opc;
+       u_int newoff_dpc;
+       u_int newoff_sls;
 
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
+       newoff_sio = cstate->off_sio;
+       newoff_opc = cstate->off_opc;
+       newoff_dpc = cstate->off_dpc;
+       newoff_sls = cstate->off_sls;
        switch (mtp3field) {
 
        case MH_SIO:
@@ -9320,20 +9791,22 @@ gen_mtp3field_code(compiler_state_t *cstate, int mtp3field, bpf_u_int32 jvalue,
                /* FALLTHROUGH */
 
        case M_SIO:
-               if (cstate->cgstate->off_sio == OFFSET_NOT_SET)
+               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)
                        bpf_error(cstate, "sio value %u too big; max value = 255",
                            jvalue);
-               b0 = gen_ncmp(cstate, OR_PACKET, newoff_sio, BPF_B, 0xffffffff,
-                   (u_int)jtype, reverse, (u_int)jvalue);
+               b0 = gen_ncmp(cstate, OR_PACKET, newoff_sio, BPF_B, 0xffffffffU,
+                   jtype, reverse, jvalue);
                break;
 
        case MH_OPC:
-               newoff_opc+=3;
+               newoff_opc += 3;
+
+               /* FALLTHROUGH */
         case M_OPC:
-               if (cstate->cgstate->off_opc == OFFSET_NOT_SET)
+               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)
@@ -9348,8 +9821,8 @@ gen_mtp3field_code(compiler_state_t *cstate, int mtp3field, bpf_u_int32 jvalue,
                val3 = jvalue & 0x00000003;
                val3 = val3 <<22;
                jvalue = val1 + val2 + val3;
-               b0 = gen_ncmp(cstate, OR_PACKET, newoff_opc, BPF_W, 0x00c0ff0f,
-                   (u_int)jtype, reverse, (u_int)jvalue);
+               b0 = gen_ncmp(cstate, OR_PACKET, newoff_opc, BPF_W, 0x00c0ff0fU,
+                   jtype, reverse, jvalue);
                break;
 
        case MH_DPC:
@@ -9357,7 +9830,7 @@ gen_mtp3field_code(compiler_state_t *cstate, int mtp3field, bpf_u_int32 jvalue,
                /* FALLTHROUGH */
 
        case M_DPC:
-               if (cstate->cgstate->off_dpc == OFFSET_NOT_SET)
+               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)
@@ -9370,14 +9843,16 @@ gen_mtp3field_code(compiler_state_t *cstate, int mtp3field, bpf_u_int32 jvalue,
                val2 = jvalue & 0x00003f00;
                val2 = val2 << 8;
                jvalue = val1 + val2;
-               b0 = gen_ncmp(cstate, OR_PACKET, newoff_dpc, BPF_W, 0xff3f0000,
-                   (u_int)jtype, reverse, (u_int)jvalue);
+               b0 = gen_ncmp(cstate, OR_PACKET, newoff_dpc, BPF_W, 0xff3f0000U,
+                   jtype, reverse, jvalue);
                break;
 
        case MH_SLS:
-         newoff_sls+=3;
+               newoff_sls += 3;
+               /* FALLTHROUGH */
+
        case M_SLS:
-               if (cstate->cgstate->off_sls == OFFSET_NOT_SET)
+               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)
@@ -9386,8 +9861,8 @@ gen_mtp3field_code(compiler_state_t *cstate, int mtp3field, bpf_u_int32 jvalue,
                /* the following instruction is made to convert jvalue
                 * to the forme used to write sls in an ss7 message*/
                jvalue = jvalue << 4;
-               b0 = gen_ncmp(cstate, OR_PACKET, newoff_sls, BPF_B, 0xf0,
-                   (u_int)jtype,reverse, (u_int)jvalue);
+               b0 = gen_ncmp(cstate, OR_PACKET, newoff_sls, BPF_B, 0xf0U,
+                   jtype, reverse, jvalue);
                break;
 
        default:
@@ -9408,27 +9883,27 @@ gen_msg_abbrev(compiler_state_t *cstate, int type)
        switch (type) {
 
        case A_SETUP:
-               b1 = gen_atmfield_code(cstate, A_MSGTYPE, SETUP, BPF_JEQ, 0);
+               b1 = gen_atmfield_code_internal(cstate, A_MSGTYPE, SETUP, BPF_JEQ, 0);
                break;
 
        case A_CALLPROCEED:
-               b1 = gen_atmfield_code(cstate, A_MSGTYPE, CALL_PROCEED, BPF_JEQ, 0);
+               b1 = gen_atmfield_code_internal(cstate, A_MSGTYPE, CALL_PROCEED, BPF_JEQ, 0);
                break;
 
        case A_CONNECT:
-               b1 = gen_atmfield_code(cstate, A_MSGTYPE, CONNECT, BPF_JEQ, 0);
+               b1 = gen_atmfield_code_internal(cstate, A_MSGTYPE, CONNECT, BPF_JEQ, 0);
                break;
 
        case A_CONNECTACK:
-               b1 = gen_atmfield_code(cstate, A_MSGTYPE, CONNECT_ACK, BPF_JEQ, 0);
+               b1 = gen_atmfield_code_internal(cstate, A_MSGTYPE, CONNECT_ACK, BPF_JEQ, 0);
                break;
 
        case A_RELEASE:
-               b1 = gen_atmfield_code(cstate, A_MSGTYPE, RELEASE, BPF_JEQ, 0);
+               b1 = gen_atmfield_code_internal(cstate, A_MSGTYPE, RELEASE, BPF_JEQ, 0);
                break;
 
        case A_RELEASE_DONE:
-               b1 = gen_atmfield_code(cstate, A_MSGTYPE, RELEASE_DONE, BPF_JEQ, 0);
+               b1 = gen_atmfield_code_internal(cstate, A_MSGTYPE, RELEASE_DONE, BPF_JEQ, 0);
                break;
 
        default:
@@ -9442,22 +9917,34 @@ gen_atmmulti_abbrev(compiler_state_t *cstate, int type)
 {
        struct block *b0, *b1;
 
+       /*
+        * Catch errors reported by us and routines below us, and return NULL
+        * on an error.
+        */
+       if (setjmp(cstate->top_ctx))
+               return (NULL);
+
        switch (type) {
 
        case A_OAM:
-               if (!cstate->cgstate->is_atm)
+               if (!cstate->is_atm)
                        bpf_error(cstate, "'oam' supported only on raw ATM");
-               b1 = gen_atmmulti_abbrev(cstate, A_OAMF4);
+               /* OAM F4 type */
+               b0 = gen_atmfield_code_internal(cstate, A_VCI, 3, BPF_JEQ, 0);
+               b1 = gen_atmfield_code_internal(cstate, A_VCI, 4, BPF_JEQ, 0);
+               gen_or(b0, b1);
+               b0 = gen_atmfield_code_internal(cstate, A_VPI, 0, BPF_JEQ, 0);
+               gen_and(b0, b1);
                break;
 
        case A_OAMF4:
-               if (!cstate->cgstate->is_atm)
+               if (!cstate->is_atm)
                        bpf_error(cstate, "'oamf4' supported only on raw ATM");
                /* OAM F4 type */
-               b0 = gen_atmfield_code(cstate, A_VCI, 3, BPF_JEQ, 0);
-               b1 = gen_atmfield_code(cstate, A_VCI, 4, BPF_JEQ, 0);
+               b0 = gen_atmfield_code_internal(cstate, A_VCI, 3, BPF_JEQ, 0);
+               b1 = gen_atmfield_code_internal(cstate, A_VCI, 4, BPF_JEQ, 0);
                gen_or(b0, b1);
-               b0 = gen_atmfield_code(cstate, A_VPI, 0, BPF_JEQ, 0);
+               b0 = gen_atmfield_code_internal(cstate, A_VPI, 0, BPF_JEQ, 0);
                gen_and(b0, b1);
                break;
 
@@ -9466,7 +9953,7 @@ gen_atmmulti_abbrev(compiler_state_t *cstate, int type)
                 * Get Q.2931 signalling messages for switched
                 * virtual connection
                 */
-               if (!cstate->cgstate->is_atm)
+               if (!cstate->is_atm)
                        bpf_error(cstate, "'connectmsg' supported only on raw ATM");
                b0 = gen_msg_abbrev(cstate, A_SETUP);
                b1 = gen_msg_abbrev(cstate, A_CALLPROCEED);
@@ -9479,12 +9966,12 @@ gen_atmmulti_abbrev(compiler_state_t *cstate, int type)
                gen_or(b0, b1);
                b0 = gen_msg_abbrev(cstate, A_RELEASE_DONE);
                gen_or(b0, b1);
-               b0 = gen_atmtype_abbrev(cstate, A_SC);
+               b0 = gen_atmtype_sc(cstate);
                gen_and(b0, b1);
                break;
 
        case A_METACONNECT:
-               if (!cstate->cgstate->is_atm)
+               if (!cstate->is_atm)
                        bpf_error(cstate, "'metaconnect' supported only on raw ATM");
                b0 = gen_msg_abbrev(cstate, A_SETUP);
                b1 = gen_msg_abbrev(cstate, A_CALLPROCEED);
@@ -9495,7 +9982,7 @@ gen_atmmulti_abbrev(compiler_state_t *cstate, int type)
                gen_or(b0, b1);
                b0 = gen_msg_abbrev(cstate, A_RELEASE_DONE);
                gen_or(b0, b1);
-               b0 = gen_atmtype_abbrev(cstate, A_METAC);
+               b0 = gen_atmtype_metac(cstate);
                gen_and(b0, b1);
                break;