tcpdump mailing list archives

sniffing from USB bus: current shortcoming and possible solutions


From: Paolo Abeni <paolo.abeni () email it>
Date: Tue, 28 Nov 2006 09:50:15 +0100

Hello list,

I'm sorry to say that the current code for sniffing from USB buses has
some issues, some introduced by me and others produced by current linux
kernel API for USB sniffing.

Currently the maximum amount of data captured for each USB Request Block
(URB) is limited by the linux kernel to 32 bytes. Moreover the kernel
produce the usb data in a text format. This has to be reconverted into
binary form by libpcap, possibly incurring in missing packets when
transfer rate is high. 

A new binary interface for USB sniffing is making it's way into the
current kernel tree and I hope that will be available in the near
future. This will solve both problem and the relevant ABI has yet been
fixed, so I can produce the pcap code to use it. The new ABI will
provide also a memory mapped access to the sniffed data, because the
sniffing process will require at least an in-kernel copy of whole URB
data. In order to achieve better performance, should I use this kind of
access  ?!?

Now comes the issues I produced. The kernel produce and make available
to libpcap a couple of 'events' for each transmitted/received URB. A
'submit' event when the transfer begin. A 'complete' event when the
transfer is completed with success and an 'error' event when the
transfer is completed without success. The actual URB data is present in
only one of this events. Currently all events are passed to the
application, but is not possible for the application to know which kind
of event it's processing, because this information is not available in
the header I build up and pass to the application with the data.

A few others useful information are missing in the build-up USB header: 
the usb bus the URB come from and a 'direction' flag for the occurred
transfer.

This data can be added to the current usb header retaining binary
compatibility with old traces for USB data link type, because there is
some room available in the current header format. 

The new header should look like this:

/* possible type of transfer mode used by URB */
typedef enum {
  URB_CONTROL_INPUT,
  URB_CONTROL_OUTPUT,
  URB_ISOCHRONOUS_INPUT,
  URB_ISOCHRONOUS_OUTPUT,
  URB_INTERRUPT_INPUT,
  URB_INTERRUPT_OUTPUT,
  URB_BULK_INPUT,
  URB_BULK_OUTPUT,
  URB_TRANSFER_UNKNOWN
} pcap_usb_transfer_t;

/*
 * possible types of events produced by URB transmission
 */
typedef enum {
  URB_EVENT_UNKNOWN,
  URB_SUBMIT,
  URB_COMPLETE,
  URB_ERROR
} pcap_usb_event_t;

/*
 * well known bits of usb_header_flags
 */
#define PCAP_USB_SETUP     0x1
#define PCAP_USB_INCOMING  0x2

typedef struct _usb_header {
  u_char transfer_type;
  u_char event_type;
  u_short bus_id;
  bpf_u_int32 device_address;
  bpf_u_int32 endpoint_number;
  bpf_u_int32 flags;
} pcap_usb_header;

But there is a (hopefully) last issue: due to my total ignorance of the
USB protocol at the time I wrote the code, I used the network byte order
for encoding each field of the headers I build up in the pcap
processing. Now I know that USB use a little endian encoding. In order
to retain the binary compatibility with old traces the the network byte
order should be retained, but this looks quite ugly... should I move to
the little endian encoding ?!? 

Note: the pcap_usb_setup header is currently build up from the pcap code
(in network byte order), but, with the new binary interface, will be
provided from the kernel (in little endian byte encoding). To retain
binary compatibility at the data link level, the pcap code has to
rewrite this header also with the new interface. 

Thanks for your attention,

Paolo Abeni

-
This is the tcpdump-workers list.
Visit https://cod.sandelman.ca/ to unsubscribe.


Current thread: