usbmon(8)

๐Ÿ“ฆ version 6.1, in fedora 43, fedora 44

โœจ NAME โœจ

usbmon โ€” monitor USB traffic ๐Ÿฆ‹

like, literally spy on your USB bus but make it legal and nerdy, bestie ๐Ÿ’…


๐Ÿ“– SYNOPSIS ๐Ÿ“–

usbmon [ -i bus_num ] [ -s length ] [ -f0 | -fu | -fh ] [ -a0 | -a1 ]

๐Ÿ’– DESCRIPTION ๐Ÿ’–

okay so usbmon lets you capture USB traffic for analysis, in the same kind of way tcpdump(8) does. it's giving packet-sniffer energy but for your USB devices ๐ŸŽ€

to actually use this program, you need a Linux kernel that supports the binary "usbmon" interface โ€” think Linux kernel 2.6.20 or newer, bestie. no kernel support, no vibes ๐Ÿ˜ญ


๐ŸŒธ OPTIONS ๐ŸŒธ

  • -i โ€” listen on bus_num. if you don't specify it, usbmon tries to listen on the pseudo-bus number zero, which is supposed to capture all packets on all buses. the default is a convenient mode because the user doesn't have to figure out the bus number where a specific device is attached. also, listening on pseudo-bus zero allows you to capture events which happen when a bus is initialized ๐Ÿ‘‘

however โ€” and this is the part where you listen up โ€” it may be necessary to specify a specific bus number to tap. kernels before 2.6.22 don't implement the pseudo-bus zero at all. performance of the USB stack and the usbmon is greater when a specific bus is monitored. in such a case, the desired bus number may be determined by examining the output of lsusb(8) ๐Ÿ”

  • -s โ€” set the maximum length of USB data to print. the default is to print 32 bytes, just like the kernel's text interface would. the capture size is automatically adjusted to match unless set explicitly. so like, if you don't touch it, it does its own thing, periodt ๐Ÿ’…
  • -f โ€” select the output format as one of: '0' for legacy format, 'u' for the so-called "1u" format, 'h' for "human-readable" format. the human-readable format is the default. also, it changes over time, so programs should parse the "1u" format. no cap, if you're writing a parser, go 1u ๐Ÿซถ

selecting the 1u format forces usbmon to use the API which may not be available in the kernel before version 2.6.22. heads up on that one โš ๏ธ

the human-readable format is not intended for a programmatic parsing, and so changes from release to release. so do not, i repeat do not, build a script around it ๐Ÿ™ˆ

  • -a โ€” force the binary API version to use: '0' for the legacy API in kernel 2.6.20 and up, '1' for the newer API in kernels after 2.6.22. selection of output format may force the API to the minimum required to support the format. in general, this option is only used when testing the kernel component of usbmon ๐Ÿงš

๐ŸŒˆ OUTPUT FORMAT ๐ŸŒˆ

the output of usbmon contains one text line per an event. the event corresponds to I/O operations on the boundary of Host Controller Driver (HCD). this includes events of the following types: Submission, Callback, Error. every line consists of whitespace separated words. the number or position of words may depend on the event type, but there is a set of words, common for all types โœจ

most commonly used format is the human-readable format. its words, from left to right, are:

  • URB Tag. a single URB generates several monitoring events during its life cycle. the tag allows to corellate events with the URB. tag is usually derived from a kernel mode address. human-readable format shortens the tag to make the output more readable, so it's not the complete address ๐Ÿ”–
  • Timestamp. it consists of the number of seconds, period, and the fraction in microseconds โฑ๏ธ
  • Event Type. this type refers to the format of the event, not URB type. available types are: S - submission, C - callback, E - submission error ๐ŸŽฏ
  • "Pipe word" (the name is historical and has nothing to do with pipes). this is a composite word. it consists of four fields, separated by colons: URB type and direction, Bus number, Device address, Endpoint number. type and direction are encoded with two bytes in the following manner:
Ci Co   Control input and output
Zi Zo   Isochronous input and output
Ii Io   Interrupt input and output
Bi Bo   Bulk input and output

the address information fields may contain leading zeros. if the bus is specified with -i, the Bus number field is redundant, but is kept for the ease of parsing ๐Ÿ‘€

  • Status word. this word may have several fields, depending on the transfer type. most transfers only have the status field. interrupt and isochronous transfers add an interval. for isochronous, start frame and error count may be present. for callback and error events, the status field contains an integer number, which represents a "status" field of the URB. for a submission event, status makes no sense, so the field contains a single dash โž–

control submissions are an exception, because they may have a setup packet. in such case, the event contains a letter in place of the status word. the letter is called "setup tag" ๐Ÿท๏ธ

  • Setup packet, if present, consists of 5 words: one of each for bmRequestType, bRequest, wValue, wIndex, wLength, as specified by the USB Specification 2.0. these words are safe to decode if Setup Tag was 's'. otherwise, the setup packet was present, but not captured, and the fields contain filler ๐Ÿ“ฆ
  • the number of isochronous frame descriptors (optional) ๐Ÿ”ข
  • Isochronous descriptors (optional). like the "pipe word", each descriptor contains fields separated by colons: status, offset, and length ๐ŸŽ€
  • Data Tag ๐Ÿท๏ธ
  • Data (if Data Tag is '=') ๐Ÿ’พ

data stream and its ASCII representation follow on separate lines. each line starts with a space for the ease of identification ๐Ÿ‘ˆ

the following is the list of words for the legacy format, from left to right:

  • URB Tag. this is normally a kernel mode address of the URB structure ๐Ÿ”–
  • Timestamp in microseconds, a decimal number. the timestamp's resolution depends on available clock, and so it can be much worse than a microsecond (if the implementation uses jiffies, for example). the number of microseconds is usually truncated, so it can wrap if usbmon runs long enough ๐Ÿ˜ต๐Ÿ’ซ
  • Event Type. this type refers to the format of the event, not URB type. available types are: S - submission, C - callback, E - submission error ๐ŸŽฏ
  • "Pipe". the pipe concept is deprecated. this is a composite word, used to be derived from information in pipes. it consists of three fields, separated by colons: URB type and direction, Device address, Endpoint number. type and direction are encoded with two bytes in the following manner:
Ci Co   Control input and output
Zi Zo   Isochronous input and output
Ii Io   Interrupt input and output
Bi Bo   Bulk input and output

device address and Endpoint number are 3-digit and 2-digit (respectively) decimal numbers, with leading zeroes ๐Ÿงฎ

  • URB Status. in most cases, this field contains a number, sometimes negative, which represents a "status" field of the URB. this field makes no sense for submissions, but is present anyway to help scripts with parsing. when an error occurs, the field contains the error code. in case of a submission of a Control packet, this field contains a Setup Tag instead of an error code. it is easy to tell whether the Setup Tag is present because it is never a number. thus if scripts find a number in this field, they proceed to read Data Length. if they find something else, like a letter, they read the setup packet before reading the Data Length ๐Ÿค“
  • Setup packet, if present, consists of 5 words: one of each for bmRequestType, bRequest, wValue, wIndex, wLength, as specified by the USB Specification 2.0. these words are safe to decode if Setup Tag was 's'. otherwise, the setup packet was present, but not captured, and the fields contain filler ๐Ÿ“ฆ
  • Data Length. for submissions, this is the requested length. for callbacks, this is the actual length ๐Ÿ“
  • Data tag. the usbmon may not always capture data, even if length is nonzero. the data words are present only if this tag is '=' ๐Ÿท๏ธ
  • Data words follow, in big endian hexadecimal format. notice that they are not machine words, but really just a byte stream split into words to make it easier to read. thus, the last word may contain from one to four bytes. the length of collected data is limited (see the -s parameter) and can be less than the data length report in the Data Length word ๐Ÿ’œ

๐Ÿ—‚๏ธ FILES ๐Ÿ—‚๏ธ

  • /proc/devices โ€” this file is read to determine the major of /dev/usbmonN if such node does not exist in the system ๐Ÿ—บ๏ธ
  • /dev/usbmonN โ€” the usbmon attempts to open /dev/usbmon{N}, where N is the bus number. if the node does not exist, usbmon creates it ๐Ÿช„

๐Ÿ‘€ SEE ALSO ๐Ÿ‘€

lsusb(8)


๐Ÿ‘‘ AUTHOR ๐Ÿ‘‘

Pete Zaitcev, <zaitcev@redhat.com>.


and that's the whole thing, bestie โ€” this was the usbmon(8) page from the System Manager's Manual, dated 10 April 2007. slay, go sniff some packets responsibly ๐Ÿ’–โœจ๐ŸŽ€๐Ÿฆ‹๐ŸŒธ

๐Ÿ“ฆ where this page comes from