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 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.

+

The BeagleBoard would then forward USB data, while logging it. In basic terms, there is a proxy driver running on the BeagleBoard, that acts both as a USB slave, and claims a USB device. According to the device descriptor, endpoints are activated on the USB slave controller, and packets are then forwarded back and forth between the host and the device.

−

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...

+

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... However, this doesn't allow low-level debugging of USB transactions, that a hardware solution would allow. Also, the solution can only be as reliable as the USB host controller driver (which is well tested), and as the USB device controller driver (the MUSB driver in the Linux still has some bugs).

−

== Build and run instructions ==

+

== Build instructions ==

−

To get the proxy driver to work, you need to follow these steps:

+

Latest recommended branches:

+

* Kernel tree:

+

**<tt>stable-20100726</tt> [http://gitorious.org/beagleboard-usbsniffer/beagleboard-usbsniffer-kernel/commits/stable-20100726], OR

+

**<tt>stable-20100809</tt> [http://gitorious.org/beagleboard-usbsniffer/beagleboard-usbsniffer-kernel/commits/stable-20100809]: this version may fix some problems with some devices, but will affect performance, for example when used with USB mass storage devices.

* Clone my kernel git tree. Use the <tt>stable-20100724</tt> branch [http://gitorious.org/beagleboard-usbsniffer/beagleboard-usbsniffer-kernel/commits/stable-20100724]. This can be done using the following commands:

+

To get the proxy driver to work, you need to follow these steps:

+

* Clone my kernel git tree. This can be done using the following commands:

* Do not reconfigure the kernel (unless you need some extra modules): the git tree comes with a ready-made <tt>.config</tt>.

* Do not reconfigure the kernel (unless you need some extra modules): the git tree comes with a ready-made <tt>.config</tt>.

* Compile and install the kernel.

* Compile and install the kernel.

Line 34:

Line 39:

** <tt>make modules</tt>

** <tt>make modules</tt>

** To install the modules, the easiest is probably to set <tt>INSTALL_MOD_PATH</tt> to some directory on your host computer, run <tt>make modules_install</tt>, and copy the modules to the SD card, or via the network.

** To install the modules, the easiest is probably to set <tt>INSTALL_MOD_PATH</tt> to some directory on your host computer, run <tt>make modules_install</tt>, and copy the modules to the SD card, or via the network.

+

** Note: in some cases, I had problem with the kernel not finding modules. In that case, run <tt>depmod -a</tt> on the BeagleBoard, and reboot.

* Install libpcap-1.1.1 and tcpdump-4.1.1.

* 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: [http://git.openembedded.org/cgit.cgi/openembedded/commit/?id=7b9e14891f7d69b5376041fc15df3d5f13f41855] and [http://git.openembedded.org/cgit.cgi/openembedded/commit/?id=d4f0fb310f7d40f7a50f50fb12083fa258aa1eed]: apply these 2 commits, or update your OpenEmbedded distribution to the latest git.

** If you don't have a recent enough OpenEmbedded install, the recipes can be found in these 2 commits: [http://git.openembedded.org/cgit.cgi/openembedded/commit/?id=7b9e14891f7d69b5376041fc15df3d5f13f41855] and [http://git.openembedded.org/cgit.cgi/openembedded/commit/?id=d4f0fb310f7d40f7a50f50fb12083fa258aa1eed]: apply these 2 commits, or update your OpenEmbedded distribution to the latest git.

Line 39:

Line 45:

** The 2 packages can be found in <tt>$OE_BASE/build/tmp-angstrom_2008_1/deploy/glibc/ipk/armv7a</tt>: <tt>libpcap_1.1.1-r1.5_armv7a.ipk</tt> and <tt>tcpdump_4.1.1-r1.5_armv7a.ipk</tt>.

** The 2 packages can be found in <tt>$OE_BASE/build/tmp-angstrom_2008_1/deploy/glibc/ipk/armv7a</tt>: <tt>libpcap_1.1.1-r1.5_armv7a.ipk</tt> and <tt>tcpdump_4.1.1-r1.5_armv7a.ipk</tt>.

** Copy these on the BeagleBoard, and run <tt>opkg install <i>name</i>.ipk</tt> for both packages.

** Copy these on the BeagleBoard, and run <tt>opkg install <i>name</i>.ipk</tt> for both packages.

** You need to modify <tt>load</tt>/<tt>setup</tt>/<tt>sniff</tt> scripts if you do not have have a copy of <tt>musb_hdrc.ko</tt> and <tt>g_proxy.ko</tt> in the same directory. That is, replace all <tt>insmod XXX.ko</tt> by <tt>modprobe XXX</tt> (remove the <tt>.ko</tt>). <b>TODO: This should be automated</b>.

One major problem with the device emulation model, using a proxy driver, is about bandwidth allocation.

+

+

The USB is polling-based, that is, the controller regularly interrogates all the endpoints of all the devices attached to it.

+

+

When a new USB device is added, some bandwidth is allocated for each of its endpoints, depending on some polling interval and packet size defined in the device descriptor. This bandwidth allocation defines the polling schedule, across all the endpoints, for all the devices present on the bus.

+

+

If insufficient bandwidth is available, the device may not work. For isochronous endpoints, the device usually defines several interfaces, with different bandwidth requirements (i.e., different packet sizes), and the driver can choose the appropriate interface, according to the bandwidth available on the bus.

+

+

One of the problems that could occur with our proxy driver, is that the host may decide to allocate more bandwidth than the bandwidth available on the USB host controller of the BeagleBoard. In that case, bandwidth allocation may fail on the BeagleBoard (with an <tt>ENOSPC</tt>, or <tt>-28</tt> error), and transfers on the affected endpoint would not work. From my experience, this seems to happen only with full-speed devices, that cannot be connected directly to the BeagleBoard, and need an intermediate USB hub.

Contents

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. In basic terms, there is a proxy driver running on the BeagleBoard, that acts both as a USB slave, and claims a USB device. According to the device descriptor, endpoints are activated on the USB slave controller, and packets are then forwarded back and forth between the host and the device.

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... However, this doesn't allow low-level debugging of USB transactions, that a hardware solution would allow. Also, the solution can only be as reliable as the USB host controller driver (which is well tested), and as the USB device controller driver (the MUSB driver in the Linux still has some bugs).

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).

Known issues

Bandwidth allocation

One major problem with the device emulation model, using a proxy driver, is about bandwidth allocation.

The USB is polling-based, that is, the controller regularly interrogates all the endpoints of all the devices attached to it.

When a new USB device is added, some bandwidth is allocated for each of its endpoints, depending on some polling interval and packet size defined in the device descriptor. This bandwidth allocation defines the polling schedule, across all the endpoints, for all the devices present on the bus.

If insufficient bandwidth is available, the device may not work. For isochronous endpoints, the device usually defines several interfaces, with different bandwidth requirements (i.e., different packet sizes), and the driver can choose the appropriate interface, according to the bandwidth available on the bus.

One of the problems that could occur with our proxy driver, is that the host may decide to allocate more bandwidth than the bandwidth available on the USB host controller of the BeagleBoard. In that case, bandwidth allocation may fail on the BeagleBoard (with an ENOSPC, or -28 error), and transfers on the affected endpoint would not work. From my experience, this seems to happen only with full-speed devices, that cannot be connected directly to the BeagleBoard, and need an intermediate USB hub.

MUSB testing code

Some instructions on how to use the code to trigger the MUSB bug with short isochronous packets:

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: