Byte-swap the extra fields in the "version 1" USB monitor header.
This commit is contained in:
parent
f9c2f9a852
commit
ecd955e0df
|
@ -1123,9 +1123,10 @@ linktype_to_dlt(int linktype)
|
||||||
* the reading host's byte order.
|
* the reading host's byte order.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf)
|
swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf,
|
||||||
|
int header_len_64_bytes)
|
||||||
{
|
{
|
||||||
pcap_usb_header *uhdr = (pcap_usb_header *)buf;
|
pcap_usb_header_mmapped *uhdr = (pcap_usb_header_mmapped *)buf;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The URB id is a totally opaque value; do we really need to
|
* The URB id is a totally opaque value; do we really need to
|
||||||
|
@ -1152,4 +1153,27 @@ swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf)
|
||||||
if (hdr->caplen < 40)
|
if (hdr->caplen < 40)
|
||||||
return;
|
return;
|
||||||
uhdr->data_len = SWAPLONG(uhdr->data_len);
|
uhdr->data_len = SWAPLONG(uhdr->data_len);
|
||||||
|
|
||||||
|
if (header_len_64_bytes) {
|
||||||
|
/*
|
||||||
|
* This is either the "version 1" header, with
|
||||||
|
* 16 bytes of additional fields at the end, or
|
||||||
|
* a "version 0" header from a memory-mapped
|
||||||
|
* capture, with 16 bytes of zeroed-out padding
|
||||||
|
* at the end. Byte swap them as if this were
|
||||||
|
* a "version 1" header.
|
||||||
|
*/
|
||||||
|
if (hdr->caplen < 52)
|
||||||
|
return;
|
||||||
|
uhdr->interval = SWAPLONG(uhdr->interval);
|
||||||
|
if (hdr->caplen < 56)
|
||||||
|
return;
|
||||||
|
uhdr->start_frame = SWAPLONG(uhdr->start_frame);
|
||||||
|
if (hdr->caplen < 60)
|
||||||
|
return;
|
||||||
|
uhdr->xfer_flags = SWAPLONG(uhdr->xfer_flags);
|
||||||
|
if (hdr->caplen < 64)
|
||||||
|
return;
|
||||||
|
uhdr->ndesc = SWAPLONG(uhdr->ndesc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,4 +21,5 @@ extern int dlt_to_linktype(int dlt);
|
||||||
|
|
||||||
extern int linktype_to_dlt(int linktype);
|
extern int linktype_to_dlt(int linktype);
|
||||||
|
|
||||||
extern void swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf);
|
extern void swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf,
|
||||||
|
int header_len_64_bytes);
|
||||||
|
|
41
pcap/usb.h
41
pcap/usb.h
|
@ -54,7 +54,7 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* USB setup header as defined in USB specification.
|
* USB setup header as defined in USB specification.
|
||||||
* Appears at the front of each packet in DLT_USB captures.
|
* Appears at the front of each Control S-type packet in DLT_USB captures.
|
||||||
*/
|
*/
|
||||||
typedef struct _usb_setup {
|
typedef struct _usb_setup {
|
||||||
u_int8_t bmRequestType;
|
u_int8_t bmRequestType;
|
||||||
|
@ -64,6 +64,13 @@ typedef struct _usb_setup {
|
||||||
u_int16_t wLength;
|
u_int16_t wLength;
|
||||||
} pcap_usb_setup;
|
} pcap_usb_setup;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Information from the URB for Isochronous transfers.
|
||||||
|
*/
|
||||||
|
typedef struct _iso_rec {
|
||||||
|
int32_t error_count;
|
||||||
|
int32_t numdesc;
|
||||||
|
} iso_rec;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Header prepended by linux kernel to each event.
|
* Header prepended by linux kernel to each event.
|
||||||
|
@ -87,8 +94,11 @@ typedef struct _usb_header {
|
||||||
} pcap_usb_header;
|
} pcap_usb_header;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Header prepended by linux kernel to each event, plus padding in the
|
* Header prepended by linux kernel to each event for the 2.6.31
|
||||||
* internal buffer.
|
* and later kernels; for the 2.6.21 through 2.6.30 kernels, the
|
||||||
|
* "iso_rec" information, and the fields starting with "interval"
|
||||||
|
* are zeroed-out padding fields.
|
||||||
|
*
|
||||||
* Appears at the front of each packet in DLT_USB_LINUX_MMAPPED captures.
|
* Appears at the front of each packet in DLT_USB_LINUX_MMAPPED captures.
|
||||||
*/
|
*/
|
||||||
typedef struct _usb_header_mmapped {
|
typedef struct _usb_header_mmapped {
|
||||||
|
@ -105,8 +115,29 @@ typedef struct _usb_header_mmapped {
|
||||||
int32_t status;
|
int32_t status;
|
||||||
u_int32_t urb_len;
|
u_int32_t urb_len;
|
||||||
u_int32_t data_len; /* amount of urb data really present in this event*/
|
u_int32_t data_len; /* amount of urb data really present in this event*/
|
||||||
pcap_usb_setup setup;
|
union {
|
||||||
u_int8_t padding[16];
|
pcap_usb_setup setup;
|
||||||
|
iso_rec iso;
|
||||||
|
} s;
|
||||||
|
int32_t interval; /* for Interrupt and Isochronous events */
|
||||||
|
int32_t start_frame; /* for Isochronous events */
|
||||||
|
u_int32_t xfer_flags; /* copy of URB's transfer flags */
|
||||||
|
u_int32_t ndesc; /* number of isochronous descriptors */
|
||||||
} pcap_usb_header_mmapped;
|
} pcap_usb_header_mmapped;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Isochronous descriptors; for isochronous transfers there might be
|
||||||
|
* one or more of these at the beginning of the packet data. The
|
||||||
|
* number of descriptors is given by the "ndesc" field in the header;
|
||||||
|
* as indicated, in older kernels that don't put the descriptors at
|
||||||
|
* the beginning of the packet, that field is zeroed out, so that field
|
||||||
|
* can be trusted even in captures from older kernels.
|
||||||
|
*/
|
||||||
|
typedef struct _usb_isodesc {
|
||||||
|
int32_t status;
|
||||||
|
u_int32_t offset;
|
||||||
|
u_int32_t len;
|
||||||
|
u_int8_t pad[4];
|
||||||
|
} usb_isodesc;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1100,8 +1100,11 @@ found:
|
||||||
switch (p->linktype) {
|
switch (p->linktype) {
|
||||||
|
|
||||||
case DLT_USB_LINUX:
|
case DLT_USB_LINUX:
|
||||||
|
swap_linux_usb_header(hdr, *data, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
case DLT_USB_LINUX_MMAPPED:
|
case DLT_USB_LINUX_MMAPPED:
|
||||||
swap_linux_usb_header(hdr, *data);
|
swap_linux_usb_header(hdr, *data, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -422,8 +422,11 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
|
||||||
switch (p->linktype) {
|
switch (p->linktype) {
|
||||||
|
|
||||||
case DLT_USB_LINUX:
|
case DLT_USB_LINUX:
|
||||||
|
swap_linux_usb_header(hdr, *data, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
case DLT_USB_LINUX_MMAPPED:
|
case DLT_USB_LINUX_MMAPPED:
|
||||||
swap_linux_usb_header(hdr, *data);
|
swap_linux_usb_header(hdr, *data, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue