/*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
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 *);
%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
| 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))); }
* 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
inbound return INBOUND;
outbound return OUTBOUND;
+ifindex return IFINDEX;
+
vlan return VLAN;
mpls return MPLS;
pppoed return PPPOED;