X-Git-Url: https://git.tcpdump.org/libpcap/blobdiff_plain/82f5b14456853fd64be21f53162c19697ab6c4a2..bc594f185299d9d4e3b39ba94e91a5b9ca8a938d:/gencode.c diff --git a/gencode.c b/gencode.c index 585ea01e..ea272e17 100644 --- 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. @@ -59,27 +58,21 @@ #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 #include #include #endif -#ifdef HAVE_NET_PFVAR_H -#include -#include -#include -#include -#endif - #ifndef offsetof #define offsetof(s, e) ((size_t)&((s *)0)->e) #endif @@ -139,10 +132,6 @@ struct addrinfo { #define ETHERMTU 1500 -#ifndef ETHERTYPE_TEB -#define ETHERTYPE_TEB 0x6558 -#endif - #ifndef IPPROTO_HOPOPTS #define IPPROTO_HOPOPTS 0 #endif @@ -447,7 +436,7 @@ bpf_set_error(compiler_state_t *cstate, const char *fmt, ...) */ if (!cstate->error_set) { 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); cstate->error_set = 1; @@ -467,11 +456,14 @@ 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*/ +#ifdef _AIX + PCAP_UNREACHABLE +#endif /* _AIX */ } static int init_linktype(compiler_state_t *, pcap_t *); @@ -518,6 +510,7 @@ static inline struct block *gen_false(compiler_state_t *); 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 *); @@ -571,7 +564,9 @@ 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); +#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 *); @@ -736,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 @@ -784,9 +779,9 @@ pcap_compile(pcap_t *p, struct bpf_program *program, cstate.snaplen = pcap_snapshot(p); if (cstate.snaplen == 0) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snaplen of 0 rejects all packets"); - rc = -1; + rc = PCAP_ERROR; goto quit; } @@ -802,7 +797,7 @@ pcap_compile(pcap_t *p, struct bpf_program *program, pcap_set_extra(&cstate, scanner); if (init_linktype(&cstate, p) == -1) { - rc = -1; + rc = PCAP_ERROR; goto quit; } if (pcap_parse(scanner, &cstate) != 0) { @@ -812,7 +807,7 @@ pcap_compile(pcap_t *p, struct bpf_program *program, #endif if (cstate.e != NULL) free(cstate.e); - rc = -1; + rc = PCAP_ERROR; goto quit; } @@ -821,7 +816,7 @@ pcap_compile(pcap_t *p, struct bpf_program *program, * Catch errors reported by gen_retblk(). */ if (setjmp(cstate.top_ctx)) { - rc = -1; + rc = PCAP_ERROR; goto quit; } cstate.ic.root = gen_retblk(&cstate, cstate.snaplen); @@ -830,14 +825,14 @@ pcap_compile(pcap_t *p, struct bpf_program *program, if (optimize && !cstate.no_optimize) { if (bpf_optimize(&cstate.ic, p->errbuf) == -1) { /* Failure */ - rc = -1; + rc = PCAP_ERROR; goto quit; } if (cstate.ic.root == NULL || (cstate.ic.root->s.code == (BPF_RET|BPF_K) && cstate.ic.root->s.k == 0)) { - (void)pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + (void)snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "expression rejects all packets"); - rc = -1; + rc = PCAP_ERROR; goto quit; } } @@ -845,7 +840,7 @@ pcap_compile(pcap_t *p, struct bpf_program *program, cstate.ic.root, &len, p->errbuf); if (program->bf_insns == NULL) { /* Failure */ - rc = -1; + rc = PCAP_ERROR; goto quit; } program->bf_len = len; @@ -883,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); @@ -1262,6 +1257,7 @@ init_linktype(compiler_state_t *cstate, pcap_t *p) 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->off_linktype.constant_part = 2; /* skip HDLC-like framing */ cstate->off_linkpl.constant_part = 4; /* skip HDLC-like framing and protocol field */ @@ -1510,14 +1506,13 @@ init_linktype(compiler_state_t *cstate, pcap_t *p) cstate->off_nl_nosnap = 0; /* XXX - what does it do with 802.3 packets? */ break; -#ifdef HAVE_NET_PFVAR_H case DLT_PFLOG: cstate->off_linktype.constant_part = 0; - cstate->off_linkpl.constant_part = PFLOG_HDRLEN; + 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: @@ -1719,7 +1714,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", cstate->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; @@ -2341,6 +2337,59 @@ gen_linux_sll_linktype(compiler_state_t *cstate, bpf_u_int32 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) { @@ -2928,10 +2977,14 @@ 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->is_vlan_vloffset) { @@ -3163,6 +3216,7 @@ gen_linktype(compiler_state_t *cstate, bpf_u_int32 ll_proto) /*NOTREACHED*/ case DLT_C_HDLC: + case DLT_HDLC: switch (ll_proto) { case LLCSAP_ISONS: @@ -3392,7 +3446,6 @@ gen_linktype(compiler_state_t *cstate, bpf_u_int32 ll_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 @@ -3407,7 +3460,6 @@ gen_linktype(compiler_state_t *cstate, bpf_u_int32 ll_proto) else return gen_false(cstate); /*NOTREACHED*/ -#endif /* HAVE_NET_PFVAR_H */ case DLT_ARCNET: case DLT_ARCNET_LINUX: @@ -5307,21 +5359,15 @@ gen_proto_abbrev_internal(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: @@ -5348,9 +5394,7 @@ gen_proto_abbrev_internal(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 @@ -5427,18 +5471,14 @@ gen_proto_abbrev_internal(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: @@ -6032,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, bpf_u_int32 v, int proto) { -#ifdef NO_PROTOCHAIN - return gen_proto(cstate, v, proto); -#else struct block *b0, *b; struct slist *s[100]; int fix2, fix3, fix4, fix5; @@ -6084,7 +6114,18 @@ gen_protochain(compiler_state_t *cstate, bpf_u_int32 v, int proto) if (cstate->off_linkpl.is_variable) bpf_error(cstate, "'protochain' not supported with variable length headers"); - cstate->no_optimize = 1; /* this code is not compatible with 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 @@ -6328,8 +6369,8 @@ gen_protochain(compiler_state_t *cstate, bpf_u_int32 v, int proto) gen_and(b0, b); return b; -#endif } +#endif /* !defined(NO_PROTOCHAIN) */ static struct block * gen_check_802_11_data_frame(compiler_state_t *cstate) @@ -6370,9 +6411,7 @@ static struct block * 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'"); @@ -6404,11 +6443,7 @@ gen_proto(compiler_state_t *cstate, bpf_u_int32 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, v); -#else - b1 = gen_protochain(cstate, v, Q_IP); -#endif gen_and(b0, b1); return b1; @@ -6470,7 +6505,6 @@ gen_proto(compiler_state_t *cstate, bpf_u_int32 v, int proto, int dir) case Q_IPV6: b0 = gen_linktype(cstate, ETHERTYPE_IPV6); -#ifndef CHASE_CHAIN /* * Also check for a fragment header before the final * header. @@ -6480,9 +6514,6 @@ gen_proto(compiler_state_t *cstate, bpf_u_int32 v, int proto, int dir) gen_and(b2, b1); 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; @@ -6495,7 +6526,7 @@ gen_proto(compiler_state_t *cstate, bpf_u_int32 v, int proto, int dir) /*NOTREACHED*/ case Q_ESP: - bpf_error(cstate, "'ah proto' is bogus"); + bpf_error(cstate, "'esp proto' is bogus"); /*NOTREACHED*/ case Q_PIM: @@ -6536,6 +6567,7 @@ gen_proto(compiler_state_t *cstate, bpf_u_int32 v, int proto, int dir) /*NOTREACHED*/ case DLT_C_HDLC: + case DLT_HDLC: /* * Cisco uses an Ethertype lookalike - for OSI, * it's 0xfefe. @@ -6921,12 +6953,14 @@ 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); else bpf_error(cstate, "unknown protocol: %s", name); +#endif /* !defined(NO_PROTOCHAIN) */ case Q_UNDEF: syntax(cstate); @@ -6951,11 +6985,15 @@ gen_mcode(compiler_state_t *cstate, const char *s1, const char *s2, 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) @@ -7013,8 +7051,11 @@ gen_ncode(compiler_state_t *cstate, const char *s, bpf_u_int32 v, struct qual q) 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) { @@ -7092,8 +7133,10 @@ gen_ncode(compiler_state_t *cstate, const char *s, bpf_u_int32 v, struct qual q) case Q_PROTO: return gen_proto(cstate, v, proto, dir); +#if !defined(NO_PROTOCHAIN) case Q_PROTOCHAIN: return gen_protochain(cstate, v, proto); +#endif case Q_UNDEF: syntax(cstate); @@ -7135,10 +7178,10 @@ gen_mcode6(compiler_state_t *cstate, const char *s1, const char *s2, 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; @@ -8172,6 +8215,53 @@ gen_multicast(compiler_state_t *cstate, int proto) /*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); +} + /* * Filter on inbound (dir == 0) or outbound (dir == 1) traffic. * Outbound traffic is sent by this machine, while inbound traffic is @@ -8232,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, ((dir == 0) ? PF_IN : PF_OUT)); break; -#endif case DLT_PPP_PPPD: if (dir) { @@ -8299,9 +8387,9 @@ 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. @@ -8310,7 +8398,6 @@ gen_inbound(compiler_state_t *cstate, int dir) /* We have a FILE *, so this is a savefile */ bpf_error(cstate, "inbound/outbound not supported on %s when reading savefiles", pcap_datalink_val_to_description_or_dlt(cstate->linktype)); - b0 = NULL; /*NOTREACHED*/ } /* match outgoing packets */ @@ -8320,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) */ +#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) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */ +#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) @@ -8480,91 +8566,6 @@ gen_pf_action(compiler_state_t *cstate, int 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_) -{ - /* - * Catch errors reported by us and routines below us, and return NULL - * on an error. - */ - if (setjmp(cstate->top_ctx)) - return (NULL); - - bpf_error(cstate, "libpcap was compiled without pf support"); - /*NOTREACHED*/ -} - -struct block * -gen_pf_ruleset(compiler_state_t *cstate, char *ruleset _U_) -{ - /* - * Catch errors reported by us and routines below us, and return NULL - * on an error. - */ - if (setjmp(cstate->top_ctx)) - return (NULL); - - 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_) -{ - /* - * Catch errors reported by us and routines below us, and return NULL - * on an error. - */ - if (setjmp(cstate->top_ctx)) - return (NULL); - - 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_) -{ - /* - * Catch errors reported by us and routines below us, and return NULL - * on an error. - */ - if (setjmp(cstate->top_ctx)) - return (NULL); - - 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_) -{ - /* - * Catch errors reported by us and routines below us, and return NULL - * on an error. - */ - if (setjmp(cstate->top_ctx)) - return (NULL); - - 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_) -{ - /* - * Catch errors reported by us and routines below us, and return NULL - * on an error. - */ - if (setjmp(cstate->top_ctx)) - return (NULL); - - 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 * @@ -8876,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 @@ -9028,6 +9029,7 @@ gen_mpls(compiler_state_t *cstate, bpf_u_int32 label_num_arg, switch (cstate->linktype) { case DLT_C_HDLC: /* fall through */ + case DLT_HDLC: case DLT_EN10MB: case DLT_NETANALYZER: case DLT_NETANALYZER_TRANSPARENT: @@ -9132,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.