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.addr == "2.12.1" (src or dst)
usb.address == ?
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.