summary history branches tags files
README.md

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:

  1. Filter on the Product ID of a specific USB keyboard
  2. Set a StartFilter to begin capturing when the ESC key is pressed
  3. Set an ActiveFilter to only output device-to-host packets with data payloads
  4. 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

Related Software