BPF Filter for 2 or more VLANs

Prev Next

It seems pretty trivial, writing a BPF filter fetching 2 different VLANs. One would think the below would work

vlan 1 or vlan 2     (does not work!)

However that does not work as expected

What it does is filter for VLAN 1, then if VLAN 2 is present within VLAN 1 then will pass thru the data + any packets in VLAN 1. Effectively vlan 2 is completely ignored.

The reason is how BPF works, any time the vlan keyword is put in a BPF filter it will offset all remaining protocol decoding by 4 bytes (the size of the VLAN header). This is stated in the man pages…


https://www.tcpdump.org/manpages/pcap-filter.7.html

vlan [vlan_id]

True if the packet is an IEEE 802.1Q VLAN packet. If the optional vlan_id is specified, only true if the packet has the specified vlan_id. Note that the first vlan keyword encountered in an expression changes the decoding offsets for the remainder of the expression on the assumption that the packet is a VLAN packet. The `vlan [vlan_id]` keyword may be used more than once, to filter on VLAN hierarchies. Each use of that keyword increments the filter offsets by 4.

For example:

vlan 100 && vlan 200

filters on VLAN 200 encapsulated within VLAN 100, and

vlan && vlan 300 && ip

filters IPv4 protocol encapsulated in VLAN 300 encapsulated within any higher order VLAN.


So what is a filter that will filter for multiple VLANs ?

Need to use the following by checking for 802.1q (standard single tagged VLAN Ether Type), then manually checking the tag id

Example below will check for VLAN 2 or VLAN 3

ether[12:2] = 0x8100 and (ether[14:2] = 2 or ether[14:2] = 3)

Which is not exactly pretty (or easy to remember) way of filtering… thus its written here to remember it.