As you might have noted I decided to implement the existing USBPcap capture format. A capture format is required because USB packets do not include all the necessary information to properly interpret them. I first thought I would implement libpcap's DLT_USB but then I quickly realize that this was not a standard. It is instead a FreeBSD specific format which has been since then renamed DLT_USB_FREEBSD.

But I didn't want to embrace xkcd #927, so I look at the existing formats: DLT_USB_FREEBSD, DLT_USB_LINUX, DLT_USB_LINUX_MMAPPED, DLT_USB_DARWIN and DLT_USBPCAP. I was first a bit sad to see that nobody could agree on a common format then I moved on and picked the simplest one: USBPcap.

Implementing an already existing format gives us out-of-box support for all the tools supporting it. That's why having common formats let us share our energy. In the case of USBPcap it is already supported by Wireshark, so you can already inspect your packet graphically. For that you need to first capture raw packets:

# tcpdump -s 3303 -w usb.pcap -i usb0
tcpdump: listening on usb0, link-type USBPCAP
^C
208 packets received by filter
0 packets dropped by kernel

USB packets can be quite big, that's why I'm not using tcpdump(8)'s default packet size. In this case, I want to make sure I can dump the complete uaudio(4) frames.

Once the capture completed, time to look at it:

wireshark-usb.jpg

It is important to say that what is dumped to userland is what the USB stack sees. Packets sent on the wire might differ, especially when it comes to retries and timing. So this feature is not here to replace any USB analyser, however I hope that it will help people understand how things work and what the USB stack is doing. Even I found some interesting timing issues while implementing isochronous support.