menomonmon
A usbmon packet filtering library
What
menomonmon is a library for viewing all or a subset of the USB packets from the linux kernel's usbmon subsystem, optionally controlled by a set of triggers and filters.
Why
menomonmon is intended to help isolate and analyze specific transactions or events within a large stream of USB traffic. When you know what you are looking for, menomonmon will help you pluck it out of the firehose.
How
The core of menomonmon is built as a Rust library. This core is responsible for opening the usbmon bus device, reading and parsing the raw packets, applying optional filters and triggers, and finally printing the matching packets.
A simple menomonmon
binary is also provided, which can be used to dump all traffic (equivalent to cat /sys/kernel/debug/usb/usbmon/0u
) or apply basic filtration on USB bus, device vendor ID, or device product ID.
For more advanced usage, users are expected to write small Rust applications using the menomonmon library with custom filters. Several examples are provided in the examples/
directory.
menomonmon has four fundamental filter types:
- DeviceFilter -- This filter performs selection of which device(s) to monitor. Filters on USB bus (depends on your system's hardware hierarchy), device Vendor ID, or device Product ID.
- StartFilter -- This filter triggers on the contents of a USB packet. If provided, no packets are output until the StartFilter matches.
- EndFilter -- Same as StartFilter, but packets stop being output after EndFilter matches.
- ActiveFilter -- Same as StartFilter, but this filter further filters which packets are output in between the StartFilter and EndFilter packets.
As a conceptual example, one might write a program with the following four filters installed:
- Filter on the Product ID of a specific USB keyboard
- Set a StartFilter to begin capturing when the ESC key is pressed
- Set an ActiveFilter to only output device-to-host packets with data payloads
- Set an EndFilter to stop capturing when the RET key is pressed
menomonmon would then output all data payloads received from the attached keyboard between the pressing of the escape and return keys.
Project Status
menomonmon is a "one-off" project to scratch an itch. It is not under active development, but bug reports are welcome.
Building
$ git clone git://git.trevorbentley.com/menomonmon.git
$ cd menomonmon
$ cargo build --release --examples
$ sudo modprobe usbmon
$ sudo ./target/release/menomonmon --help
Limitations
- Packets are not saved in memory or to disk
- Filters apply to a single packet only. Multi-packet pattern detection is not supported.
- Questionable handling of device hot connect/disconnect
Example output
The following shows the provided example mon_fido_enumeration_data_only
in action, which outputs the bidirectional data payload packets during early device enumeration of a USB device that advertises a FIDO/U2F HID interface:
# ./target/debug/examples/mon_fido_enumeration_data_only
0000000000 05:98:00 < 83:02 [000]: |80 06 0100 0000 18|
0000000320 05:98:00 < 67:02 [018]: 12010002000000405010160149030102
0001
0000001428 05:98:00 < 67:02 [009]: 09029600030100800f
0000001798 05:98:00 < 67:02 [150]: 09029600030100800f09040000010301
01000921100100012247000705810308
000a0904010002030000000921100100
01222200070504034000020705840340
000209040200030b0000003621000100
0702000000a00f0000a00f00000000b0
040000b00400006e0500000000000000
000000fe00040078050000ffff000000
01070502024000000705820240000007
058303080020
0000001985 05:98:00 < 67:02 [004]: 04030904
0000002215 05:98:00 < 67:02 [050]: 320359007500620069006b0065007900
20004e0045004f0020004f0054005000
2b005500320046002b00430043004900
4400
0000002439 05:98:00 < 67:02 [014]: 0e03590075006200690063006f00
0000022725 05:98:00 < 67:02 [071]: 05010906a101050719e029e715002501
75019508810295017508810195057501
05081901290591029501750391019506
75081500256505071900296581000903
75089508b102c0
0000023101 05:98:00 > 83:02 [001]: |21 09 0200 0000 01|
00
0000080840 05:98:00 < 83:02 [000]: |81 06 2200 0001 34|
0000081213 05:98:00 < 67:02 [034]: 06d0f10901a1010920150026ff007508
954081020921150026ff007508954091
02c0
FIDO device enumerated in: 81213 µs
The space-separated fields are:
- timestamp (microseconds)
- usb_bus : device_number : endpoint
- direction ('<' is device-to-host, '>' is host-to-device)
- pkt_type : xfer_type
- [data_length]
- |setup_packet| (if present)
- data_payload (if present)
Main Dependencies
- nix -- linux ioctl access
- regex -- Regular expression matching
- clap -- Command-line arguments parsing