]> The Tcpdump Group git mirrors - libpcap/blobdiff - gencode.c
Improve handling of DLT_PFLOG when generating filter code.
[libpcap] / gencode.c
index 703bb20e2ca86171d6c6e69e2c07aa7454cde698..9b16a5c1cf845b17f057be02b4ab699f7c76877e 100644 (file)
--- a/gencode.c
+++ b/gencode.c
 #include "pcap-dos.h"
 #endif
 
-#ifdef HAVE_NET_PFVAR_H
-/*
- * In NetBSD <net/if.h> includes <net/dlt.h>, 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 <sys/socket.h>
-#include <net/if.h>
-#include <net/pfvar.h>
-#include <net/if_pflog.h>
-#endif /* HAVE_NET_PFVAR_H */
-
 #include "pcap-int.h"
 
 #include "extract.h"
@@ -73,6 +59,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 +511,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 *);
@@ -1517,14 +1505,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 +2336,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 = 0xfffffffe;
+               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 +2976,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 +3445,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 +3459,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:
@@ -8307,12 +8349,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 +8443,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 +8593,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 *