diff options
author | Bill Fenner <fenner@gmail.com> | 2019-05-01 11:06:03 -0700 |
---|---|---|
committer | Bill Fenner <fenner@gmail.com> | 2020-05-19 04:51:22 -0700 |
commit | 014e6a0fca0a25ba74242ba76e27afaa5799e0b7 (patch) | |
tree | 70d617073680a1dcd83d636e991691864ad00157 | |
parent | f2d84366a864f7b41f59ef47334f6a53aa914b32 (diff) | |
download | libpcap-014e6a0fca0a25ba74242ba76e27afaa5799e0b7.tar.gz |
New filter "ifindex" for LINUX_SLL2 and live Linux captures
-rw-r--r-- | gencode.c | 47 | ||||
-rw-r--r-- | gencode.h | 1 | ||||
-rw-r--r-- | grammar.y | 2 | ||||
-rw-r--r-- | pcap-linux.c | 6 | ||||
-rw-r--r-- | scanner.l | 2 |
5 files changed, 58 insertions, 0 deletions
@@ -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 @@ -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 *); @@ -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))); } diff --git a/pcap-linux.c b/pcap-linux.c index a783aaba..bf0bc812 100644 --- a/pcap-linux.c +++ b/pcap-linux.c @@ -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 @@ -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; |