- case Q_ADDR3:
- bpf_error(cstate, "'addr3' and 'address3' are only supported on 802.11 with 802.11 headers");
- /*NOTREACHED*/
-
- case Q_ADDR4:
- bpf_error(cstate, "'addr4' and 'address4' are only supported on 802.11 with 802.11 headers");
- /*NOTREACHED*/
-
- case Q_RA:
- bpf_error(cstate, "'ra' is only supported on 802.11 with 802.11 headers");
- /*NOTREACHED*/
-
- case Q_TA:
- bpf_error(cstate, "'ta' is only supported on 802.11 with 802.11 headers");
- /*NOTREACHED*/
- }
- abort();
- /*NOTREACHED*/
-}
-
-/*
- * Like gen_ehostop, but for DLT_FDDI
- */
-static struct block *
-gen_fhostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
-{
- struct block *b0, *b1;
-
- switch (dir) {
- case Q_SRC:
- return gen_bcmp(cstate, OR_LINKHDR, 6 + 1 + cstate->pcap_fddipad, 6, eaddr);
-
- case Q_DST:
- return gen_bcmp(cstate, OR_LINKHDR, 0 + 1 + cstate->pcap_fddipad, 6, eaddr);
-
- case Q_AND:
- b0 = gen_fhostop(cstate, eaddr, Q_SRC);
- b1 = gen_fhostop(cstate, eaddr, Q_DST);
- gen_and(b0, b1);
- return b1;
-
- case Q_DEFAULT:
- case Q_OR:
- b0 = gen_fhostop(cstate, eaddr, Q_SRC);
- b1 = gen_fhostop(cstate, eaddr, Q_DST);
- gen_or(b0, b1);
- return b1;
-
- case Q_ADDR1:
- bpf_error(cstate, "'addr1' and 'address1' are only supported on 802.11");
- /*NOTREACHED*/
-
- case Q_ADDR2:
- bpf_error(cstate, "'addr2' and 'address2' are only supported on 802.11");
- /*NOTREACHED*/
-
- case Q_ADDR3:
- bpf_error(cstate, "'addr3' and 'address3' are only supported on 802.11");
- /*NOTREACHED*/
-
- case Q_ADDR4:
- bpf_error(cstate, "'addr4' and 'address4' are only supported on 802.11");
- /*NOTREACHED*/
-
- case Q_RA:
- bpf_error(cstate, "'ra' is only supported on 802.11");
- /*NOTREACHED*/
-
- case Q_TA:
- bpf_error(cstate, "'ta' is only supported on 802.11");
- /*NOTREACHED*/
- }
- abort();
- /*NOTREACHED*/
-}
-
-/*
- * Like gen_ehostop, but for DLT_IEEE802 (Token Ring)
- */
-static struct block *
-gen_thostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
-{
- register struct block *b0, *b1;
-
- switch (dir) {
- case Q_SRC:
- return gen_bcmp(cstate, OR_LINKHDR, 8, 6, eaddr);
-
- case Q_DST:
- return gen_bcmp(cstate, OR_LINKHDR, 2, 6, eaddr);
-
- case Q_AND:
- b0 = gen_thostop(cstate, eaddr, Q_SRC);
- b1 = gen_thostop(cstate, eaddr, Q_DST);
- gen_and(b0, b1);
- return b1;
-
- case Q_DEFAULT:
- case Q_OR:
- b0 = gen_thostop(cstate, eaddr, Q_SRC);
- b1 = gen_thostop(cstate, eaddr, Q_DST);
- gen_or(b0, b1);
- return b1;
-
- case Q_ADDR1:
- bpf_error(cstate, "'addr1' and 'address1' are only supported on 802.11");
- /*NOTREACHED*/
-
- case Q_ADDR2:
- bpf_error(cstate, "'addr2' and 'address2' are only supported on 802.11");
- /*NOTREACHED*/
-
- case Q_ADDR3:
- bpf_error(cstate, "'addr3' and 'address3' are only supported on 802.11");
- /*NOTREACHED*/
-
- case Q_ADDR4:
- bpf_error(cstate, "'addr4' and 'address4' are only supported on 802.11");
- /*NOTREACHED*/
-
- case Q_RA:
- bpf_error(cstate, "'ra' is only supported on 802.11");
- /*NOTREACHED*/
-
- case Q_TA:
- bpf_error(cstate, "'ta' is only supported on 802.11");
- /*NOTREACHED*/
- }
- abort();
- /*NOTREACHED*/
-}
-
-/*
- * Like gen_ehostop, but for DLT_IEEE802_11 (802.11 wireless LAN) and
- * various 802.11 + radio headers.
- */
-static struct block *
-gen_wlanhostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
-{
- register struct block *b0, *b1, *b2;
- register struct slist *s;
-
-#ifdef ENABLE_WLAN_FILTERING_PATCH
- /*
- * TODO GV 20070613
- * We need to disable the optimizer because the optimizer is buggy
- * and wipes out some LD instructions generated by the below
- * code to validate the Frame Control bits
- */
- cstate->no_optimize = 1;
-#endif /* ENABLE_WLAN_FILTERING_PATCH */
-
- switch (dir) {
- case Q_SRC:
- /*
- * Oh, yuk.
- *
- * For control frames, there is no SA.
- *
- * For management frames, SA is at an
- * offset of 10 from the beginning of
- * the packet.
- *
- * For data frames, SA is at an offset
- * of 10 from the beginning of the packet
- * if From DS is clear, at an offset of
- * 16 from the beginning of the packet
- * if From DS is set and To DS is clear,
- * and an offset of 24 from the beginning
- * of the packet if From DS is set and To DS
- * is set.
- */
-
- /*
- * Generate the tests to be done for data frames
- * with From DS set.
- *
- * First, check for To DS set, i.e. check "link[1] & 0x01".
- */
- s = gen_load_a(cstate, OR_LINKHDR, 1, BPF_B);
- b1 = new_block(cstate, JMP(BPF_JSET));
- b1->s.k = 0x01; /* To DS */
- b1->stmts = s;
-
- /*
- * If To DS is set, the SA is at 24.
- */
- b0 = gen_bcmp(cstate, OR_LINKHDR, 24, 6, eaddr);
- gen_and(b1, b0);
-
- /*
- * Now, check for To DS not set, i.e. check
- * "!(link[1] & 0x01)".
- */
- s = gen_load_a(cstate, OR_LINKHDR, 1, BPF_B);
- b2 = new_block(cstate, JMP(BPF_JSET));
- b2->s.k = 0x01; /* To DS */
- b2->stmts = s;
- gen_not(b2);
-
- /*
- * If To DS is not set, the SA is at 16.
- */
- b1 = gen_bcmp(cstate, OR_LINKHDR, 16, 6, eaddr);
- gen_and(b2, b1);
-
- /*
- * Now OR together the last two checks. That gives
- * the complete set of checks for data frames with
- * From DS set.
- */
- gen_or(b1, b0);