]> The Tcpdump Group git mirrors - libpcap/commitdiff
New filter "ifindex" for LINUX_SLL2 and live Linux captures 829/head
authorBill Fenner <[email protected]>
Wed, 1 May 2019 18:06:03 +0000 (11:06 -0700)
committerBill Fenner <[email protected]>
Tue, 19 May 2020 11:51:22 +0000 (04:51 -0700)
gencode.c
gencode.h
grammar.y
pcap-linux.c
scanner.l

index df00dd8dd4f799a4add30404d4a44d808ec42c0e..4359c102ff7239253b4115d121a69c482c972444 100644 (file)
--- a/gencode.c
+++ b/gencode.c
@@ -8175,6 +8175,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 with 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
index bffb71b6264d1608696ab5ee3f7726631b438bed..dc099f53d8d0a54ea8b35e296c531e25725f63e9 100644 (file)
--- a/gencode.h
+++ b/gencode.h
@@ -328,6 +328,7 @@ struct block *gen_greater(compiler_state_t *, int);
 struct block *gen_byteop(compiler_state_t *, int, int, bpf_u_int32);
 struct block *gen_broadcast(compiler_state_t *, int);
 struct block *gen_multicast(compiler_state_t *, int);
+struct block *gen_ifindex(compiler_state_t *, int);
 struct block *gen_inbound(compiler_state_t *, int);
 
 struct block *gen_llc(compiler_state_t *);
index b73e44bf4585953c7c55700d721aaf9bfc81c1d1..8492378e9870b4e6f8720c284e0bf362ca3476c5 100644 (file)
--- a/grammar.y
+++ b/grammar.y
@@ -355,6 +355,7 @@ DIAG_OFF_BISON_BYACC
 %token  ATALK AARP DECNET LAT SCA MOPRC MOPDL
 %token  TK_BROADCAST TK_MULTICAST
 %token  NUM INBOUND OUTBOUND
+%token  IFINDEX
 %token  PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION
 %token TYPE SUBTYPE DIR ADDR1 ADDR2 ADDR3 ADDR4 RA TA
 %token  LINK
@@ -581,6 +582,7 @@ other:        pqual TK_BROADCAST    { CHECK_PTR_VAL(($$ = gen_broadcast(cstate, $1))); }
        | CBYTE NUM byteop NUM  { CHECK_PTR_VAL(($$ = gen_byteop(cstate, $3, $2, $4))); }
        | INBOUND               { CHECK_PTR_VAL(($$ = gen_inbound(cstate, 0))); }
        | OUTBOUND              { CHECK_PTR_VAL(($$ = gen_inbound(cstate, 1))); }
+       | IFINDEX NUM           { CHECK_PTR_VAL(($$ = gen_ifindex(cstate, $2))); }
        | VLAN pnum             { CHECK_PTR_VAL(($$ = gen_vlan(cstate, $2, 1))); }
        | VLAN                  { CHECK_PTR_VAL(($$ = gen_vlan(cstate, 0, 0))); }
        | MPLS pnum             { CHECK_PTR_VAL(($$ = gen_mpls(cstate, $2, 1))); }
index a783aabac5029e465e84f2c27564f6778e423b0a..bf0bc812bc257dec2ecbe813913a5658b90f798a 100644 (file)
@@ -5923,6 +5923,12 @@ fix_offset(pcap_t *handle, struct bpf_insn *p)
                         * special magic kernel offset for that field.
                         */
                        p->k = SKF_AD_OFF + SKF_AD_PROTOCOL;
+               } else if (p->k == 4) {
+                       /*
+                        * It's the ifindex field; map it to the
+                        * special magic kernel offset for that field.
+                        */
+                       p->k = SKF_AD_OFF + SKF_AD_IFINDEX;
                } else if (p->k == 10) {
                        /*
                         * It's the packet type field; map it to the
index 83091c94656fb77b4e45fff82599ab9581700a56..06b9acc14ce16d955c642a84d3119c831321e954 100644 (file)
--- a/scanner.l
+++ b/scanner.l
@@ -337,6 +337,8 @@ len|length  return LEN;
 inbound                return INBOUND;
 outbound       return OUTBOUND;
 
+ifindex                return IFINDEX;
+
 vlan           return VLAN;
 mpls           return MPLS;
 pppoed         return PPPOED;