Ask Your Question

Revision history [back]

click to hide/show revision 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