BeagleBoard/GSoC/2010 Projects/USBSniffer
Google Summer of Code 2010 Project
- Student: Nicolas Boichat
- Mentors: Hunyue Yau, Laine Walker-Avina, Frans Meulenbroeks
BeagleBoard project: usbsniffer
Project at gitorious.org: http://gitorious.org/beagleboard-usbsniffer
Blog: http://beagleboard-usbsniffer.blogspot.com/ (RSS)
Abstract
The goal of this project is to use the BeagleBoard as an USB sniffer. The host computer would be connected to the slave USB port of the BeagleBoard, and the device to be sniffed on the host USB port.
The BeagleBoard would then forward USB data, while logging it.
This presents the following advantages over a software-based solution: No software modification is required; support of proprietary OSes; allows debugging of new USB stacks; and possibly lower-level debugging of USB frames...
Build and run instructions
To get the proxy driver to work, you need to follow these steps:
- Clone my kernel git tree. Use the stable-20100724 branch [1]. This can be done using the following commands:
git clone git://gitorious.org/beagleboard-usbsniffer/beagleboard-usbsniffer-kernel.git cd beagleboard-usbsniffer-kernel git checkout origin/stable-20100724 -b stable-20100724
- Compile the kernel with the default beagleboard configuration (see BeagleBoard#Linux_kernel). You just need to add CONFIG_USB_G_PROXY=m. I also disabled MUSB in host and OTG mode, as well as USB suspend, but this may not be necessary.
- Install the new kernel on the board.
- Install libpcap-1.1.1 and tcpdump-4.1.1. If you don't have a recent enough OpenEmbedded install, the recipes can be found in these 2 commits: [2] and [3].
- Clone the helper scripts git tree, branch stable-20100724 [4], and copy the content of the arm directory to the BeagleBoard (you need to modify load/setup/sniff scripts if you do not have have a copy of musb_hdrc.ko and g_proxy.ko in the same directory).
Then, you have 2 options, the automatic way:
- Plug your device (through a USB hub if it is a low/full-speed device).
- Run ./sniff, and follow the instructions. Data transfers will be logged to /media/ram/dump. This resulting file can be displayed using wireshark.
- Use the device, it should work, and packets are captured.
or the manual way (mostly for testing purpose, as it does not log packets):
- Run ./setup on the BeagleBoard, this will unload the g_ether gadget driver.
- Plug your device (through a USB hub if it is a low/full-speed device).
- Plug your PC to the BeagleBoard USB slave port (this can be done earlier as well).
- Run ./unbind: This will unbind the device from the normal Linux driver.
- Run ./load: this will (re)load the g_proxy driver.
- Use the device, it should work.
Tested devices
Device | USB ID | Speed | Endpoints & types | Status | Branch | Notes |
---|---|---|---|---|---|---|
Logitech (M-BJ58/M-BJ69) Optical Wheel Mouse | 046d:c00e/046d:c018 | LS |
|
OK | >=stable-20100618 | |
Logitech Internet Keyboard | 046d:c309 | LS |
|
OK | stable-20100618 | |
FTDI FT232 USB-Serial (on Arduino) | 0403:6001 | FS |
|
OK | >=stable-20100618 | Programming + bidirectional serial communication |
CSR Bluetooth Dongle | 0a12:0001 | FS |
|
OK | >=stable-20100618 | Scanning devices (hcitool -i hci1 scan), and file transfers (odp and ussp-push) work. Didn't check anything that would use isochronous endpoints. |
Imation 4GB Flash Drive | 0718:0348 | HS |
|
OK | >=stable-20100702 | Works hdparm -t --direct /dev/sdX. On PC: 19.76 MB/sec; on BeagleBoard: 17.64 MB/sec; on PC through the BeagleBoard proxy: 19.18 MB/sec. |
AVerMedia Volar DVB-T dongle | 07ca:b808 | HS |
|
OK | >=stable-20100618 | No visible problem. |
Logitech, Inc. QuickCam Messanger (sic) | 046d:08da | FS |
|
OK (audio+video at the same time doesn't work) |
>stable-20100717 | No visible problem (video 640x480 OR audio). Needs musb_hdrc parameter fifo_mode=6. The FIFO mode is required, because EP1 needs 768 bytes per packet (and the default is only 512). The DMA has been fixed to handle ISO packets properly. Enabling both video + audio at the same time doesn't work (bandwidth allocation problem, but this is probably an USB hub problem). |
Logitech, Inc. Premium Stereo USB Headset 350 | 046d:0a02 | FS |
|
OK | >stable-20100717 | aplay -D default:CARD=Headset - works). Needs musb_hdrc parameter fifo_mode=7. The FIFO mode is required, because EP4 needs 96 bytes per packet (and the default is only 32). |
MUSB testing code
Some instructions on how to use the code to trigger the MUSB bug with short isochronous packets:
Checkout [5]. There are 2 directories: host, and device.
For the device side (on the beagleboard), you need to cross-compile usbtest. You need libaio, which can be built using Angstrom, and gadgetfs in the Linux kernel. Then, the gadgetfs driver is loaded as follows:
modprobe gadgetfs mkdir /dev/gadget/ -p mount -t gadgetfs none /dev/gadget ./usbtest -v -s 512 -p 2 -a 1 -I0 -x 18
The host code must be run on your host PC. It requires the usbtest module (CONFIG_USB_TEST=m), then isochronous IN transfers are tested with the following command:
./testusb -a -t 16 -g 1 -c 10
While running the test, you can monitor the USB traffic using usbmon, you should see isochronous packets of length 18, i.e., something like this:
... S Zi:2:100:1 -115:8:5232 1 -18:0:512 512 < ... C Zi:2:100:1 0:8:5240:0 1 0:0:18 18 = e6010203 e6050607 e6090a0b e60d0e0f e611
Every 4 bytes contains some kind of packet id (incrementing), the rest of the bytes are given by a mod 63 counter.
Bulk transfers can also be tested, with the following commands (device and host):
./usbtest -a 5 -s 514 ./testusb -a -t 4 -c 10 -s 1024
testusb will complain, since the packet is short (514 instead of 1024), but usbmon still shows that the transfer has been done correctly:
... S Bi:2:101:1 -115 1024 < ... C Bi:2:101:1 -121 514 = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000