X-Git-Url: https://git.tcpdump.org/libpcap/blobdiff_plain/0e411dc63dfb0dd5dc30c310e42364f57a9de24b..bc594f185299d9d4e3b39ba94e91a5b9ca8a938d:/gencode.c diff --git a/gencode.c b/gencode.c index 703bb20e..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. @@ -48,20 +47,6 @@ #include "pcap-dos.h" #endif -#ifdef HAVE_NET_PFVAR_H -/* - * In NetBSD includes , which is an older version of - * "pcap/dlt.h" with a lower value of DLT_MATCHING_MAX. Include the headers - * below before "pcap-int.h", which eventually includes "pcap/dlt.h", which - * redefines DLT_MATCHING_MAX from what this version of NetBSD has to what - * this version of libpcap has. - */ -#include -#include -#include -#include -#endif /* HAVE_NET_PFVAR_H */ - #include "pcap-int.h" #include "extract.h" @@ -73,6 +58,7 @@ #include "ieee80211.h" #include "atmuni31.h" #include "sunatmpos.h" +#include "pflog.h" #include "ppp.h" #include "pcap/sll.h" #include "pcap/ipnet.h" @@ -524,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 *); @@ -577,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 *); @@ -744,7 +733,7 @@ pcap_compile(pcap_t *p, struct bpf_program *program, if (!p->activated) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "not-yet-activated pcap_t passed to pcap_compile"); - return (-1); + return (PCAP_ERROR); } #ifdef _WIN32 @@ -792,7 +781,7 @@ pcap_compile(pcap_t *p, struct bpf_program *program, if (cstate.snaplen == 0) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snaplen of 0 rejects all packets"); - rc = -1; + rc = PCAP_ERROR; goto quit; } @@ -808,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) { @@ -818,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; } @@ -827,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); @@ -836,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)snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "expression rejects all packets"); - rc = -1; + rc = PCAP_ERROR; goto quit; } } @@ -851,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; @@ -889,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); @@ -1517,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: @@ -2349,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) { @@ -2936,6 +2977,10 @@ 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; } /* @@ -3401,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 @@ -3416,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: @@ -5316,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: @@ -5357,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 @@ -5436,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: @@ -6041,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; @@ -6348,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) @@ -6390,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'"); @@ -6424,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; @@ -6490,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. @@ -6500,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; @@ -6942,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); @@ -7120,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); @@ -8307,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) { @@ -8403,7 +8416,6 @@ gen_inbound(compiler_state_t *cstate, int dir) return (b0); } -#ifdef HAVE_NET_PFVAR_H /* PF firewall log matched interface */ struct block * gen_pf_ifname(compiler_state_t *cstate, const char *ifname) @@ -8554,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 *