From: Bill Fenner Date: Wed, 1 May 2019 18:06:03 +0000 (-0700) Subject: New filter "ifindex" for LINUX_SLL2 and live Linux captures X-Git-Tag: libpcap-1.10-bp~174^2 X-Git-Url: https://git.tcpdump.org/libpcap/commitdiff_plain/014e6a0fca0a25ba74242ba76e27afaa5799e0b7 New filter "ifindex" for LINUX_SLL2 and live Linux captures --- diff --git a/gencode.c b/gencode.c index df00dd8d..4359c102 100644 --- 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 diff --git a/gencode.h b/gencode.h index bffb71b6..dc099f53 100644 --- 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 *); diff --git a/grammar.y b/grammar.y index b73e44bf..8492378e 100644 --- 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))); } 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 diff --git a/scanner.l b/scanner.l index 83091c94..06b9acc1 100644 --- 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;