Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple VLAN IDs and ranges with a single vlan option in capture filter #815

Open
dandreye opened this issue Apr 18, 2019 · 13 comments
Open

Comments

@dandreye
Copy link

dandreye commented Apr 18, 2019

Hello,

I've been redirected here with my capture filter related inquiry at Wireshark Ask:
https://ask.wireshark.org/question/8487/tshark-capture-filter-using-vlan-id/

Would it be possible to extend vlan option syntax in a capture filter so that a single vlan option accepts >1 VLAN ID and ideally also VLAN ID ranges, e.g. something like "vlan 2001-2006,1506-1507, 1552-1553, 2025-2026"?

Many thanks in anticipation!

@dandreye dandreye changed the title Multiple VLAN IDs and VLAN ID ranges with a single vlan option in capture filter Multiple VLAN IDs and ranges with a single vlan option in capture filter Apr 18, 2019
@mcr
Copy link
Member

mcr commented Apr 18, 2019

It would be possible, it requires code.

@guyharris
Copy link
Member

It would probably be handled similarly to the way port is handled, so it might be something such as
vlanrange 2001-2006 or 1506-1507 or 1552-1553 or 2025-2026.

@dandreye
Copy link
Author

dandreye commented Apr 19, 2019

guyharris: such syntax consistent with portrange would be perfect (e.g. easier to remember from user perspective); perhaps any further similar requests for other options raised by others can also follow the same pattern.

@dandreye
Copy link
Author

dandreye commented Apr 26, 2019

Really sorry for being annoying but is there a chance to see it implemented anytime soon? We're currently having to deal with gigabyte long packet captures for mere minutes of capturing...

@syn-bit
Copy link

syn-bit commented Jul 11, 2019

Really sorry for being annoying but is there a chance to see it implemented anytime soon? We're currently having to deal with gigabyte long packet captures for mere minutes of capturing...

As a workaround you can use:

vlan and (ether[14:2]&0x0fff=2001 or ether[14:2]&0x0fff=2002 or ... or ether[14:2]&0x0fff=2026)

Of course with a whole list of vlans to capture this filter can be quite long, but at least, you get to have small capture files. Another option would be to filter out those vlans that carry the most traffic (if there are a couple of really chatty vlans).

@dandreye
Copy link
Author

Thanks for your reply. Unfortunately it no longer works:

"The kernel no longer passes vlan tag information as-is to libpcap, instead BPF needs to access ancillary data."
https://bugs.launchpad.net/ubuntu/+source/tcpdump/+bug/1641429

Please find my thread @ Wireshark Ask preceding my libpcap enhancement request:
https://ask.wireshark.org/question/8487/tshark-capture-filter-using-vlan-id/

@syn-bit
Copy link

syn-bit commented Jul 11, 2019

In that case, I just tried to use negative offsets (thanks for the link, I learned something new):

sake@x201:~$ sudo tcpdump -d -i enp0s25 vlan 100
[sudo] password for sake: 
(000) ldb      [-4048]
(001) jeq      #0x1             jt 2	jf 5
(002) ldb      [-4052]
(003) jeq      #0x64            jt 4	jf 5
(004) ret      #262144
(005) ret      #0
sake@x201:~$ sudo tcpdump -d -i enp0s25 vlan and ether[-4052:2]=100
(000) ldb      [-4048]
(001) jeq      #0x1             jt 2	jf 5
(002) ldh      [-4052]
(003) jeq      #0x64            jt 4	jf 5
(004) ret      #262144
(005) ret      #0
sake@x201:~$ sudo tcpdump -d -i enp0s25 "vlan and (ether[-4052:2]=100 or ether[-4052:2]=200)"
(000) ldb      [-4048]
(001) jeq      #0x1             jt 2	jf 6
(002) ldh      [-4052]
(003) jeq      #0x64            jt 5	jf 4
(004) jeq      #0xc8            jt 5	jf 6
(005) ret      #262144
(006) ret      #0
sake@x201:~$

Which seems to result in valid BPF code that is similar to code for the the "vlan 100" filter. I have not tried it myself (no vlan tagged interface available for testing at the moment), but I expect it to work.

And yes, we met on ask.wireshark.org too, I showed you the "vlan.id in {x..y a..b}" syntax :-)

@dandreye
Copy link
Author

Thank you: I'll then give these negative offsets a try and report on the outcome.

Btw thanks for sharing the "vlan.id in {x..y a..b}" back then: the life with it got much better )

@fenner
Copy link
Collaborator

fenner commented Jul 11, 2019

I recommend using ether[-4052]=100 - note that the code that libpcap uses ldb and your examples use ldh. The negative offset is simply a flag, I suspect that any load would work, but if you want to match what libpcap does, use the single byte mechanism.

There are a number of attributes accessible via the negative mechanism. I usually look in the kernel source/headers, /usr/include/linux/filter.h or net/core/filter.c .

Note that on a Linux SLL or SLL2 socket (i.e., "-i any"), negative offsets will be corrupted until my pull request or something similar is implemented: #820

@syn-bit
Copy link

syn-bit commented Jul 11, 2019

I recommend using ether[-4052]=100 - note that the code that libpcap uses ldb and your examples use ldh. The negative offset is simply a flag, I suspect that any load would work, but if you want to match what libpcap does, use the single byte mechanism.

Good point, missed that in my quick test :-)

@dandreye
Copy link
Author

dandreye commented Jan 13, 2021

@syn-bit : really sorry for not getting back with the results back then. Soon after someone found a way to filter those VLANs in traffic before sending it to my VM, making these filters no longer necessary. I've just come across my old threads about it by chance and tried your negative offsets. They seem to work perfectly well with at least 2 of my VLANs, so I'll be using them for now whenever I have to filter it myself again: thank you! Meanwhile it'd be nice to see something like "vlanrange 2001-2006 or 1506-1507 or 1552-1553 or 2025-2026" implemented one day as per @guyharris 's reply above.

@fenner : could you please explain what ":?" I get when omitting ":2" as you advised? I thought ":2" means analyse 2 bytes starting at that offset, and as both of these seem to work equally well for my VLAN IDs >255 do I get it right that omitting ":2" makes it fall back to ":4" by default?

root@client:/tmp# tcpdump -d -i ens5 "vlan and (ether[-4052:2]=653 or ether[-4052:2]=654)"
(000) ldb      [-4048]
(001) jeq      #0x1             jt 2    jf 6
(002) ldh      [-4052]
(003) jeq      #0x28d           jt 5    jf 4
(004) jeq      #0x28e           jt 5    jf 6
(005) ret      #262144
(006) ret      #0
root@client:/tmp# 
root@client:/tmp# tcpdump -d -i ens5 "vlan and (ether[-4052]=653 or ether[-4052]=654)"
(000) ldb      [-4048]
(001) jeq      #0x1             jt 2    jf 6
(002) ldb      [-4052]
(003) jeq      #0x28d           jt 5    jf 4
(004) jeq      #0x28e           jt 5    jf 6
(005) ret      #262144
(006) ret      #0
root@client:/tmp#

@infrastation
Copy link
Member

See also #158.

@infrastation
Copy link
Member

I see the following structure of this problem space:

  1. In the current implementation the vlan keyword consumes the VLAN ID, hence the workarounds with ether[-4052:2]. It seems most reasonable to have a different VLAN keyword that does the same without advancing the offset, e.g. vlan-peek as suggested on the mailing list. In this case more than one VLAN ID could be matched using

    (vlan-peek 2001 or vlan-peek 2002 or vlan-peek 2003 or
    vlan-peek 2004 or vlan-peek 2005 or vlan-peek 2006) and vlan-pop
    

    (where vlan-pop is an alias of the current vlan).

  2. Let's imagine the first problem has a solution. The second problem is, in the current implementation the only relation the vlan keyword supports is "equals", which among other things makes it difficult to test ID ranges that are not very small. Using ether[-4052:2], this can be done much more efficiently using the existing binary operators and expressions, for example ether[-4052:2] >= 2001 and ether[-4052:2] <= 2006. This way, it is a bit odd to have a specialized keyword that implements only a fraction of the generic syntax.

    • One potential way to address the second problem could be extending the ATM and MTP field syntax onto the new keyword, e.g.:

      vlan-peek (2001 or 2002 or 2003 or 2004 or 2005 or 2006)
      
      vlan-peek >= 2001 and vlan-peek <= 2006
      

      This looks practicable and useful despite the rather small solution space of this syntax. Let's see what else could be done.

    • Another potential way could be making the VLAN ID available in the link-layer index operations space, then it would automatically be able to use all bitwise and arithmetic syntax. For example:

      ethervlan[vlanid] >= 2001 and ethervlan[vlanid] <= 2006
      
      ethervlan[vlanid] / 100 > 10
      

      This looks complicated because this syntax would need to apply to Ethernet VLANs only somehow, and would need to work for something that is not a multiple of 8 bits wide in size.

    • Perhaps the most generic and flexible approach would be implementing a keyword that works similar to length and instead of taking a value to compare with extracts and yields a value that other expressions can use as necessary, for example:

      vlan-peek >= 2001 and vlan-peek <= 2006
      
      vlan-peek & 0xFF % 10 < 5
      

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

6 participants