From Fedora Project Wiki

usbmon is a kernel level interface to USB-packets. Displaying to USB-traffic can useful for problem solving or reverse engineering undocumented protocols.

🔗 Kernel module

USB module can be compiled into kernel statically, or it can be module that can be loaded into kernel. Fedora should have it statically part of the kernel.

# grep USB_MON /boot/config-5.9.*
/boot/config-5.9.11-100.fc32.x86_64:CONFIG_USB_MON=y
/boot/config-5.9.8-100.fc32.x86_64:CONFIG_USB_MON=y
/boot/config-5.9.9-100.fc32.x86_64:CONFIG_USB_MON=y

shows that it was selected to be part of monolitic kernel, rather than module (CONFIG_USB_MON=m). Hence it does not need, or can be loaded into running kernel.

If it was compiled as module, it can be loaded into kernel:

# modprobe usbmon
# lsmod | grep usbmon

should list it as module.

If directory /sys/kernel/debug/usb/usbmon/ has files in it, kernel support should be ready.

# ls /sys/kernel/debug/usb/usbmon/
0s  0u  1s  1t  1u  2s  2t  2u
# ls -l /dev/usbmon*
crw-r----- 1 root usbmon 244, 0 Dec  4 19:25 /dev/usbmon0
crw-r----- 1 root usbmon 244, 1 Dec  4 19:25 /dev/usbmon1
crw-r----- 1 root usbmon 244, 2 Dec  4 19:25 /dev/usbmon2


🔗 User access rights

In Fedora, debugging users should belong to usbmon group, and additionally wireshark group in order to have access to debugging device files.

# usermod -a -G usbmon tuju
# id tuju
uid=1001(tuju) gid=1001(tuju) 
groups=1001(tuju),10(wheel),18(dialout),135(mock),498(wireshark),497(usbmon),494(vboxusers),48(apache)

🔗 Capturing USB packets

To be able to capture right device from multiple others, the bus and device numbers must be known.

# lsusb
Bus 002 Device 011: ID 08e6:3437 Gemalto (was Gemplus) GemPC Twin SmartCard Reader
Bus 002 Device 012: ID 0590:0028 Omron Corp. HJ-720IT / HEM-7080IT-E / HEM-790IT
Bus 002 Device 005: ID 046d:0843 Logitech, Inc. Webcam C930e
Bus 002 Device 008: ID 046d:c318 Logitech, Inc. Illuminated Keyboard
Bus 002 Device 007: ID 04b3:3108 IBM Corp. 800dpi Optical Mouse w/ Scroll Point
Bus 002 Device 009: ID 0424:4063 Microchip Technology, Inc. (formerly SMSC) 
Bus 002 Device 006: ID 0424:2640 Microchip Technology, Inc. (formerly SMSC) USB 2.0 Hub
Bus 002 Device 004: ID 0424:2514 Microchip Technology, Inc. (formerly SMSC) USB 2.0 Hub
Bus 002 Device 003: ID 08e6:3437 Gemalto (was Gemplus) GemPC Twin SmartCard Reader
Bus 002 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

displays two buses, 002 and 001. Capturing is done whole bus-wise, not by device. It's up to post processing to filter out irrelevant traffic to show the ones that are being analyzed.

🔗 Command line

To capture output from bus number two:

# cat /sys/kernel/debug/usb/usbmon/2u > /tmp/usbmon_out

replacing 2u with given bus number (i.e. Bus003 -> 3u, Bus008 -> 8u) and so on.

This will continue to write to the file until it is terminated.


🔗 Wireshark CLI

$ tshark -i usbmon2 -w /var/tmp/usbmon2.pcap 

captures whole bus 002 into file.

🔗 Wireshark GUI

Wireshark GUI can be used to capture USB-traffic directly.

Display filters with USB follow the notation

usb.src == "2.12.1"
usb.dst == "2.12.1"

where first number is bus, second device and last ? which can change with the same device between runs.

🔗 External Links

The existing usbmon documentation is very good.