summaryrefslogtreecommitdiff
path: root/gencode.c
diff options
context:
space:
mode:
Diffstat (limited to 'gencode.c')
-rw-r--r--gencode.c346
1 files changed, 245 insertions, 101 deletions
diff --git a/gencode.c b/gencode.c
index 31c50a71e3e6..76fb2d8294f4 100644
--- a/gencode.c
+++ b/gencode.c
@@ -24,14 +24,7 @@
#ifdef _WIN32
#include <ws2tcpip.h>
#else
- #include <sys/socket.h>
-
- #ifdef __NetBSD__
- #include <sys/param.h>
- #endif
-
#include <netinet/in.h>
- #include <arpa/inet.h>
#endif /* _WIN32 */
#include <stdlib.h>
@@ -76,6 +69,10 @@
#endif
#ifdef _WIN32
+ #ifdef HAVE_NPCAP_BPF_H
+ /* Defines BPF extensions for Npcap */
+ #include <npcap-bpf.h>
+ #endif
#ifdef INET6
#if defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF)
/* IPv6 address */
@@ -230,6 +227,26 @@ struct chunk {
void *m;
};
+/*
+ * A chunk can store any of:
+ * - a string (guaranteed alignment 1 but present for completeness)
+ * - a block
+ * - an slist
+ * - an arth
+ * For this simple allocator every allocated chunk gets rounded up to the
+ * alignment needed for any chunk.
+ */
+struct chunk_align {
+ char dummy;
+ union {
+ char c;
+ struct block b;
+ struct slist s;
+ struct arth a;
+ } u;
+};
+#define CHUNK_ALIGN (offsetof(struct chunk_align, u))
+
/* Code generator state */
struct _compiler_state {
@@ -526,7 +543,7 @@ static struct block *gen_hostop(compiler_state_t *, bpf_u_int32, bpf_u_int32,
static struct block *gen_hostop6(compiler_state_t *, struct in6_addr *,
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_ahostop(compiler_state_t *, const uint8_t, int);
static struct block *gen_ehostop(compiler_state_t *, const u_char *, int);
static struct block *gen_fhostop(compiler_state_t *, const u_char *, int);
static struct block *gen_thostop(compiler_state_t *, const u_char *, int);
@@ -598,13 +615,8 @@ newchunk_nolongjmp(compiler_state_t *cstate, size_t n)
int k;
size_t size;
-#ifndef __NetBSD__
- /* XXX Round up to nearest long. */
- n = (n + sizeof(long) - 1) & ~(sizeof(long) - 1);
-#else
- /* XXX Round up to structure boundary. */
- n = ALIGN(n);
-#endif
+ /* Round up to chunk alignment. */
+ n = (n + CHUNK_ALIGN - 1) & ~(CHUNK_ALIGN - 1);
cp = &cstate->chunks[cstate->cur_chunk];
if (n > cp->n_left) {
@@ -696,7 +708,7 @@ new_stmt(compiler_state_t *cstate, int code)
}
static struct block *
-gen_retblk(compiler_state_t *cstate, int v)
+gen_retblk_internal(compiler_state_t *cstate, int v)
{
struct block *b = new_block(cstate, BPF_RET|BPF_K);
@@ -704,6 +716,22 @@ gen_retblk(compiler_state_t *cstate, int v)
return b;
}
+static struct block *
+gen_retblk(compiler_state_t *cstate, int v)
+{
+ if (setjmp(cstate->top_ctx)) {
+ /*
+ * gen_retblk() only fails because a memory
+ * allocation failed in newchunk(), meaning
+ * that it can't return a pointer.
+ *
+ * Return NULL.
+ */
+ return NULL;
+ }
+ return gen_retblk_internal(cstate, v);
+}
+
static inline PCAP_NORETURN_DEF void
syntax(compiler_state_t *cstate)
{
@@ -718,9 +746,8 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
static int done = 0;
#endif
compiler_state_t cstate;
- const char * volatile xbuf = buf;
yyscan_t scanner = NULL;
- volatile YY_BUFFER_STATE in_buffer = NULL;
+ YY_BUFFER_STATE in_buffer = NULL;
u_int len;
int rc;
@@ -790,7 +817,7 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
rc = PCAP_ERROR;
goto quit;
}
- in_buffer = pcap__scan_string(xbuf ? xbuf : "", scanner);
+ in_buffer = pcap__scan_string(buf ? buf : "", scanner);
/*
* Associate the compiler state with the lexical analyzer
@@ -814,14 +841,15 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
}
if (cstate.ic.root == NULL) {
+ cstate.ic.root = gen_retblk(&cstate, cstate.snaplen);
+
/*
* Catch errors reported by gen_retblk().
*/
- if (setjmp(cstate.top_ctx)) {
+ if (cstate.ic.root== NULL) {
rc = PCAP_ERROR;
goto quit;
}
- cstate.ic.root = gen_retblk(&cstate, cstate.snaplen);
}
if (optimize && !cstate.no_optimize) {
@@ -990,9 +1018,9 @@ 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->snaplen));
+ backpatch(p, gen_retblk_internal(cstate, cstate->snaplen));
p->sense = !p->sense;
- backpatch(p, gen_retblk(cstate, 0));
+ backpatch(p, gen_retblk_internal(cstate, 0));
cstate->ic.root = p->head;
return (0);
}
@@ -1704,6 +1732,83 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
cstate->off_nl_nosnap = 3; /* 802.3+802.2 */
break;
+ case DLT_EN3MB:
+ /*
+ * Currently, only raw "link[N:M]" filtering is supported.
+ */
+ 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_AX25:
+ /*
+ * Currently, only raw "link[N:M]" filtering is supported.
+ */
+ 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_PRONET:
+ /*
+ * Currently, only raw "link[N:M]" filtering is supported.
+ */
+ 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_CHAOS:
+ /*
+ * Currently, only raw "link[N:M]" filtering is supported.
+ */
+ 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;
+
+#ifdef DLT_HIPPI
+ case DLT_HIPPI:
+ /*
+ * Currently, only raw "link[N:M]" filtering is supported.
+ */
+ 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;
+
+#endif
+
+ case DLT_REDBACK_SMARTEDGE:
+ /*
+ * Currently, only raw "link[N:M]" filtering is supported.
+ */
+ 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;
+
+
+#ifdef DLT_HHDLC
+ case DLT_HHDLC:
+ /*
+ * Currently, only raw "link[N:M]" filtering is supported.
+ */
+ 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;
+
+#endif
+
default:
/*
* For values in the range in which we've assigned new
@@ -1716,8 +1821,8 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
cstate->off_nl = OFFSET_NOT_SET;
cstate->off_nl_nosnap = OFFSET_NOT_SET;
} else {
- bpf_set_error(cstate, "unknown data link type %d (min %d, max %d)",
- cstate->linktype, DLT_HIGH_MATCHING_MIN, DLT_HIGH_MATCHING_MAX);
+ bpf_set_error(cstate, "unknown data link type %d",
+ cstate->linktype);
return (-1);
}
break;
@@ -6945,7 +7050,8 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
int proto = q.proto;
int dir = q.dir;
int tproto;
- u_char *eaddr;
+ u_char *eaddrp;
+ u_char eaddr[6];
bpf_u_int32 mask, addr;
struct addrinfo *res, *res0;
struct sockaddr_in *sin4;
@@ -6987,33 +7093,36 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
case DLT_EN10MB:
case DLT_NETANALYZER:
case DLT_NETANALYZER_TRANSPARENT:
- eaddr = pcap_ether_hostton(name);
- if (eaddr == NULL)
+ eaddrp = pcap_ether_hostton(name);
+ if (eaddrp == NULL)
bpf_error(cstate,
"unknown ether host '%s'", name);
+ memcpy(eaddr, eaddrp, sizeof(eaddr));
+ free(eaddrp);
tmp = gen_prevlinkhdr_check(cstate);
b = gen_ehostop(cstate, eaddr, dir);
if (tmp != NULL)
gen_and(tmp, b);
- free(eaddr);
return b;
case DLT_FDDI:
- eaddr = pcap_ether_hostton(name);
- if (eaddr == NULL)
+ eaddrp = pcap_ether_hostton(name);
+ if (eaddrp == NULL)
bpf_error(cstate,
"unknown FDDI host '%s'", name);
+ memcpy(eaddr, eaddrp, sizeof(eaddr));
+ free(eaddrp);
b = gen_fhostop(cstate, eaddr, dir);
- free(eaddr);
return b;
case DLT_IEEE802:
- eaddr = pcap_ether_hostton(name);
- if (eaddr == NULL)
+ eaddrp = pcap_ether_hostton(name);
+ if (eaddrp == NULL)
bpf_error(cstate,
"unknown token ring host '%s'", name);
+ memcpy(eaddr, eaddrp, sizeof(eaddr));
+ free(eaddrp);
b = gen_thostop(cstate, eaddr, dir);
- free(eaddr);
return b;
case DLT_IEEE802_11:
@@ -7021,21 +7130,23 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
case DLT_IEEE802_11_RADIO_AVS:
case DLT_IEEE802_11_RADIO:
case DLT_PPI:
- eaddr = pcap_ether_hostton(name);
- if (eaddr == NULL)
+ eaddrp = pcap_ether_hostton(name);
+ if (eaddrp == NULL)
bpf_error(cstate,
"unknown 802.11 host '%s'", name);
+ memcpy(eaddr, eaddrp, sizeof(eaddr));
+ free(eaddrp);
b = gen_wlanhostop(cstate, eaddr, dir);
- free(eaddr);
return b;
case DLT_IP_OVER_FC:
- eaddr = pcap_ether_hostton(name);
- if (eaddr == NULL)
+ eaddrp = pcap_ether_hostton(name);
+ if (eaddrp == NULL)
bpf_error(cstate,
"unknown Fibre Channel host '%s'", name);
+ memcpy(eaddr, eaddrp, sizeof(eaddr));
+ free(eaddrp);
b = gen_ipfchostop(cstate, eaddr, dir);
- free(eaddr);
return b;
}
@@ -7080,6 +7191,11 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
switch (res->ai_family) {
case AF_INET:
#ifdef INET6
+ /*
+ * Ignore any IPv4 addresses when resolving
+ * "ip6 host NAME", validate all other proto
+ * qualifiers in gen_host().
+ */
if (tproto == Q_IPV6)
continue;
#endif
@@ -7091,7 +7207,13 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
break;
#ifdef INET6
case AF_INET6:
- if (tproto6 == Q_IP)
+ /*
+ * Ignore any IPv6 addresses when resolving
+ * "(arp|ip|rarp) host NAME", validate all
+ * other proto qualifiers in gen_host6().
+ */
+ if (tproto6 == Q_ARP || tproto6 == Q_IP ||
+ tproto6 == Q_RARP)
continue;
sin6 = (struct sockaddr_in6 *)
@@ -7204,9 +7326,11 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
case Q_GATEWAY:
#ifndef INET6
- eaddr = pcap_ether_hostton(name);
- if (eaddr == NULL)
+ eaddrp = pcap_ether_hostton(name);
+ if (eaddrp == NULL)
bpf_error(cstate, "unknown ether host: %s", name);
+ memcpy(eaddr, eaddrp, sizeof(eaddr));
+ free(eaddrp);
res = pcap_nametoaddrinfo(name);
cstate->ai = res;
@@ -7252,6 +7376,7 @@ gen_mcode(compiler_state_t *cstate, const char *s1, const char *s2,
{
register int nlen, mlen;
bpf_u_int32 n, m;
+ uint64_t m64;
/*
* Catch errors reported by us and routines below us, and return NULL
@@ -7279,14 +7404,8 @@ gen_mcode(compiler_state_t *cstate, const char *s1, const char *s2,
/* Convert mask len to mask */
if (masklen > 32)
bpf_error(cstate, "mask length must be <= 32");
- if (masklen == 0) {
- /*
- * X << 32 is not guaranteed by C to be 0; it's
- * undefined.
- */
- m = 0;
- } else
- m = 0xffffffff << (32 - masklen);
+ m64 = UINT64_C(0xffffffff) << (32 - masklen);
+ m = (bpf_u_int32)m64;
if ((n & ~m) != 0)
bpf_error(cstate, "non-network bits set in \"%s/%d\"",
s1, masklen);
@@ -7501,6 +7620,11 @@ gen_ecode(compiler_state_t *cstate, const char *s, struct qual q)
return (NULL);
if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) {
+ /*
+ * Because the lexer guards the input string format, in this
+ * context the function returns NULL iff the implicit malloc()
+ * has failed.
+ */
cstate->e = pcap_ether_aton(s);
if (cstate->e == NULL)
bpf_error(cstate, "malloc");
@@ -8212,8 +8336,6 @@ gen_byteop(compiler_state_t *cstate, int op, int idx, bpf_u_int32 val)
return b;
}
-static const u_char abroadcast[] = { 0x0 };
-
struct block *
gen_broadcast(compiler_state_t *cstate, int proto)
{
@@ -8235,7 +8357,8 @@ gen_broadcast(compiler_state_t *cstate, int proto)
switch (cstate->linktype) {
case DLT_ARCNET:
case DLT_ARCNET_LINUX:
- return gen_ahostop(cstate, abroadcast, Q_DST);
+ // ARCnet broadcast is [8-bit] destination address 0.
+ return gen_ahostop(cstate, 0, Q_DST);
case DLT_EN10MB:
case DLT_NETANALYZER:
case DLT_NETANALYZER_TRANSPARENT:
@@ -8320,8 +8443,8 @@ gen_multicast(compiler_state_t *cstate, int proto)
switch (cstate->linktype) {
case DLT_ARCNET:
case DLT_ARCNET_LINUX:
- /* all ARCnet multicasts use the same address */
- return gen_ahostop(cstate, abroadcast, Q_DST);
+ // ARCnet multicast is the same as broadcast.
+ return gen_ahostop(cstate, 0, Q_DST);
case DLT_EN10MB:
case DLT_NETANALYZER:
case DLT_NETANALYZER_TRANSPARENT:
@@ -8470,7 +8593,12 @@ 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, 224);
+
+ /*
+ * Compare address with 224.0.0.0/4
+ */
+ b1 = gen_mcmp(cstate, OR_LINKPL, 16, BPF_B, 0xe0, 0xf0);
+
gen_and(b0, b1);
return b1;
@@ -8896,11 +9024,10 @@ gen_p80211_fcdir(compiler_state_t *cstate, bpf_u_int32 fcdir)
return (b0);
}
+// Process an ARCnet host address string.
struct block *
gen_acode(compiler_state_t *cstate, const char *s, struct qual q)
{
- struct block *b;
-
/*
* Catch errors reported by us and routines below us, and return NULL
* on an error.
@@ -8914,13 +9041,16 @@ gen_acode(compiler_state_t *cstate, const char *s, struct qual q)
case DLT_ARCNET_LINUX:
if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) &&
q.proto == Q_LINK) {
- cstate->e = pcap_ether_aton(s);
- if (cstate->e == NULL)
- bpf_error(cstate, "malloc");
- b = gen_ahostop(cstate, cstate->e, (int)q.dir);
- free(cstate->e);
- cstate->e = NULL;
- return (b);
+ uint8_t addr;
+ /*
+ * The lexer currently defines the address format in a
+ * way that makes this error condition never true.
+ * Let's check it anyway in case this part of the lexer
+ * changes in future.
+ */
+ if (! pcapint_atoan(s, &addr))
+ bpf_error(cstate, "invalid ARCnet address '%s'", s);
+ return gen_ahostop(cstate, addr, (int)q.dir);
} else
bpf_error(cstate, "ARCnet address used in non-arc expression");
/*NOTREACHED*/
@@ -8931,18 +9061,25 @@ gen_acode(compiler_state_t *cstate, const char *s, struct qual q)
}
}
+// Compare an ARCnet host address with the given value.
static struct block *
-gen_ahostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
+gen_ahostop(compiler_state_t *cstate, const uint8_t eaddr, int dir)
{
register struct block *b0, *b1;
switch (dir) {
- /* src comes first, different from Ethernet */
+ /*
+ * ARCnet is different from Ethernet: the source address comes before
+ * the destination address, each is one byte long. This holds for all
+ * three "buffer formats" in RFC 1201 Section 2.1, see also page 4-10
+ * in the 1983 edition of the "ARCNET Designer's Handbook" published
+ * by Datapoint (document number 61610-01).
+ */
case Q_SRC:
- return gen_bcmp(cstate, OR_LINKHDR, 0, 1, eaddr);
+ return gen_cmp(cstate, OR_LINKHDR, 0, BPF_B, eaddr);
case Q_DST:
- return gen_bcmp(cstate, OR_LINKHDR, 1, 1, eaddr);
+ return gen_cmp(cstate, OR_LINKHDR, 1, BPF_B, eaddr);
case Q_AND:
b0 = gen_ahostop(cstate, eaddr, Q_SRC);
@@ -9090,7 +9227,7 @@ gen_vlan_patch_vid_test(compiler_state_t *cstate, struct block *b_vid)
unsigned cnt;
s = new_stmt(cstate, BPF_LD|BPF_B|BPF_ABS);
- s->s.k = SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT;
+ s->s.k = (bpf_u_int32)(SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT);
/* true -> next instructions, false -> beginning of b_vid */
sjeq = new_stmt(cstate, JMP(BPF_JEQ));
@@ -9098,8 +9235,8 @@ gen_vlan_patch_vid_test(compiler_state_t *cstate, struct block *b_vid)
sjeq->s.jf = b_vid->stmts;
sappend(s, sjeq);
- s2 = new_stmt(cstate, BPF_LD|BPF_B|BPF_ABS);
- s2->s.k = SKF_AD_OFF + SKF_AD_VLAN_TAG;
+ s2 = new_stmt(cstate, BPF_LD|BPF_H|BPF_ABS);
+ s2->s.k = (bpf_u_int32)(SKF_AD_OFF + SKF_AD_VLAN_TAG);
sappend(s, s2);
sjeq->s.jt = s2;
@@ -9137,7 +9274,7 @@ gen_vlan_bpf_extensions(compiler_state_t *cstate, bpf_u_int32 vlan_num,
/* generate new filter code based on extracting packet
* metadata */
s = new_stmt(cstate, BPF_LD|BPF_B|BPF_ABS);
- s->s.k = SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT;
+ s->s.k = (bpf_u_int32)(SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT);
b0 = new_block(cstate, JMP(BPF_JEQ));
b0->stmts = s;
@@ -9272,20 +9409,12 @@ gen_vlan(compiler_state_t *cstate, bpf_u_int32 vlan_num, int has_vlan_tag)
* 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_arg,
+static struct block *
+gen_mpls_internal(compiler_state_t *cstate, bpf_u_int32 label_num,
int has_label_num)
{
- volatile bpf_u_int32 label_num = label_num_arg;
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);
-
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);
@@ -9352,6 +9481,19 @@ gen_mpls(compiler_state_t *cstate, bpf_u_int32 label_num_arg,
return (b0);
}
+struct block *
+gen_mpls(compiler_state_t *cstate, bpf_u_int32 label_num, int has_label_num)
+{
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
+ return gen_mpls_internal(cstate, label_num, has_label_num);
+}
+
/*
* Support PPPOE discovery and session.
*/
@@ -10024,16 +10166,10 @@ 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_arg, int jtype, int reverse)
+static struct block *
+gen_mtp3field_code_internal(compiler_state_t *cstate, int mtp3field,
+ bpf_u_int32 jvalue, int jtype, int reverse)
{
- volatile bpf_u_int32 jvalue = jvalue_arg;
struct block *b0;
bpf_u_int32 val1 , val2 , val3;
u_int newoff_sio;
@@ -10041,13 +10177,6 @@ gen_mtp3field_code(compiler_state_t *cstate, int mtp3field,
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;
@@ -10139,6 +10268,21 @@ gen_mtp3field_code(compiler_state_t *cstate, int mtp3field,
return b0;
}
+struct block *
+gen_mtp3field_code(compiler_state_t *cstate, int mtp3field,
+ 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_mtp3field_code_internal(cstate, mtp3field, jvalue, jtype,
+ reverse);
+}
+
static struct block *
gen_msg_abbrev(compiler_state_t *cstate, int type)
{