I'm using Wireshark to capture USB traffic so I can analyze the descriptors of a HID device.
Each time this HID device is plugged in, the OS will assign a new USB port. So I cannot use a predefined filter. To find the current USB port, I have to exclude all noisy ports. This is quite cumbersome; especially since the enumeration could be different when the system is rebooted.
Is there a simpler way to filter the device of interest if I know that the device is in a certain range? For example "1.50.*" ... "1.99.*".
Current filter:
(usb.src != "1.1.0") && (usb.dst != "1.1.0") && (usb.src != "1.2.0") && (usb.dst != "1.2.0") && (usb.src != "1.3.0") && (usb.dst != "1.3.0") && (usb.src != "1.3.2") && (usb.dst != "1.3.2") && (usb.src != "1.4.0") && (usb.dst != "1.4.0") && (usb.src != "1.5.0") && (usb.dst != "1.5.0") && (usb.src != "1.5.1") && (usb.dst != "1.5.1") && (usb.src != "1.6.0") && (usb.dst != "1.6.0") && (usb.src != "1.7.0") && (usb.dst != "1.7.0") && (usb.src != "1.8.0") && (usb.dst != "1.8.0") && (usb.src != "1.8.1") && (usb.dst != "1.8.1") && (usb.src != "1.9.0") && (usb.dst != "1.9.0") && (usb.src != "1.9.1") && (usb.dst != "1.9.1") && (usb.src != "1.9.2") && (usb.dst != "1.9.2") && (usb.src != "1.13.0") && (usb.dst != "1.13.0") && (usb.src != "1.14.0") && (usb.dst != "1.14.0") && (usb.src != "1.23.0") && (usb.dst != "1.23.0")
Applied filter:

Improving over @Velvet answer.
You can use addr to match both src and dst, and slices to match the start of a string.
ie, this would match the handshake and the 1.9* range
(usb.addr[0:4] == "1.1.") or (usb.addr[0:3] == "1.9")
A bit slower, but you can also use regexp for fitlering:
usb.addr matches "^1\.[5-9][0-9]\."
I didn't realize at first that usb.src and usb.dst seem to represent regular strings. You can access the separate characters with array indices.
To filter the USB port range "1.50.*" to "1.59.*":
((usb.src[0] == "1") && (usb.src[1] == ".") && (usb.src[2] == "5") && (usb.src[3] != ".")) || ((usb.dst[0] == "1") && (usb.dst[1] == ".") && (usb.dst[2] == "5") && (usb.dst[3] != "."))
If the same filter is applied to usb.src and usb.dst, you can simplify the expression using only usb.addr:
(usb.addr[0] == "1") && (usb.addr[1] == ".") && (usb.addr[2] == "5") && (usb.addr[3] != ".")
To filter the USB port range "1.50.*" to "1.99.*", you can use >= and <= to specify the range:
((usb.src[0] == "1") && (usb.src[1] == ".") && (usb.src[2] >= "5") && (usb.src[2] <= "9") && (usb.src[3] != ".")) || ((usb.dst[0] == "1") && (usb.dst[1] == ".") && (usb.dst[2] >= "5") && (usb.dst[2] <= "9") && (usb.dst[3] != "."))
Interestingly, when using >= and <=, the reduced form using usb.addr doesn't seem to work.
(usb.addr[0] == "1") && (usb.addr[1] >= ".") && (usb.addr[2] >= "5") && (usb.addr[2] <= "9") && (usb.addr[3] != ".")

You have to replace usb.addr of the terms containing >= and <= with the specific usb.src or usb.dst. Why this is the case I didn't find out.
(usb.addr[0] == "1") && (usb.addr[1] == ".") && (((usb.src[2] >= "5") && (usb.src[2] <= "9")) || ((usb.dst[2] >= "5") && (usb.dst[2] <= "9"))) && (usb.addr[3] != ".")

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With