1 | initial version |
If you're looking for an alternate work-around solution that is nearly identical to the correctly-generated BPF instructions from the original capture filter expression of (ether[len - 4:4] == 0x1d10c0da) and not (icmp or (vlan and icmp))
, then you might try this filter:
(ether[len - 4:4] = 0x1d10c0da) and not (icmp or ((ether[12:2] = 0x8100 or ether[12:2] = 0x88a8 or ether[12:2] = 0x9100) and (ether[16:2] = 0x0800 and ether[27:1] = 1)))
This basically handles vlan
the old-fashioned hard way, but a way that works regardless of the libpcap version. The generated BPF is as follows, which adds only 1 extra instruction to reload the Ethertype (i.e., the 2-byte value at ether[12:2]
), since there's an implicit loading of that value when comparing the first icmp
expression, as it first ensures that the Ethertype is IP before looking at the value of the IP header's Protocol field.
(000) ld #pktlen
(001) sub #4
(002) tax
(003) ld [x + 0]
(004) jeq #0x1d10c0da jt 5 jf 18
(005) ldh [12]
(006) jeq #0x800 jt 7 jf 9
(007) ldb [23]
(008) jeq #0x1 jt 18 jf 9
(009) ldh [12]
(010) jeq #0x8100 jt 13 jf 11
(011) jeq #0x88a8 jt 13 jf 12
(012) jeq #0x9100 jt 13 jf 17
(013) ldh [16]
(014) jeq #0x800 jt 15 jf 17
(015) ldb [27]
(016) jeq #0x1 jt 18 jf 17
(017) ret #262144
(018) ret #0
Now if you're looking for an alternate work-around solution that produces identical correctly-generated BPF instructions, then you could try this filter:
(ether[len - 4:4] = 0x1d10c0da) and not ((ether[12:2] = 0x0800 and ether[23:1] = 1) or ((ether[12:2] = 0x8100 or ether[12:2] = 0x88a8 or ether[12:2] = 0x9100) and (ether[16:2] = 0x0800 and ether[27:1] = 1)))
This one explicitly loads the Ethertype to ensure it is IP before comparing the IP Protocol to ICMP, but in doing so allows the optimizer to only load that value once. Now we get the exact same output as bpfexam
produces and which is 1 instruction fewer than the previous attempt:
(000) ld #pktlen
(001) sub #4
(002) tax
(003) ld [x + 0]
(004) jeq #0x1d10c0da jt 5 jf 17
(005) ldh [12]
(006) jeq #0x800 jt 7 jf 9
(007) ldb [23]
(008) jeq #0x1 jt 17 jf 16
(009) jeq #0x8100 jt 12 jf 10
(010) jeq #0x88a8 jt 12 jf 11
(011) jeq #0x9100 jt 12 jf 16
(012) ldh [16]
(013) jeq #0x800 jt 14 jf 16
(014) ldb [27]
(015) jeq #0x1 jt 17 jf 16
(016) ret #262144
(017) ret #0