diff options
-rw-r--r-- | epan/dissectors/packet-usb.c | 96 | ||||
-rw-r--r-- | wiretap/libpcap.c | 6 | ||||
-rw-r--r-- | wiretap/wtap.c | 5 | ||||
-rw-r--r-- | wiretap/wtap.h | 1 |
4 files changed, 104 insertions, 4 deletions
diff --git a/epan/dissectors/packet-usb.c b/epan/dissectors/packet-usb.c index 22c7505dbb..b21edc771a 100644 --- a/epan/dissectors/packet-usb.c +++ b/epan/dissectors/packet-usb.c @@ -1642,7 +1642,8 @@ dissect_linux_usb_pseudo_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t } static void -dissect_linux_usb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent) +dissect_linux_usb_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent, + gboolean padded) { int offset = 0; int type, endpoint; @@ -1804,7 +1805,6 @@ dissect_linux_usb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent) tap_data->trans_info=usb_trans_info; tap_queue_packet(usb_tap, pinfo, tap_data); - switch(type){ case URB_BULK: { @@ -1816,6 +1816,20 @@ dissect_linux_usb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent) /* Skip setup header - it's never present */ offset += 8; + /* + * If this is padded (as is the case if the capture is done in + * memory-mapped mode), skip the padding; it's padded to a multiple + * of 64 bits *after* the pseudo-header and setup header. The + * pseudo-header is 40 bytes, and the setup header is 8 bytes, + * so that's 16 bytes of padding to 64 bytes. (The pseudo-header + * was removed from the packet data by Wiretap, so the offset + * is relative to the beginning of the setup header, not relative + * to the beginning of the raw packet data, so we can't just + * round it up to a multiple of 64.) + */ + if (padded) + offset += 16; + if(tvb_reported_length_remaining(tvb, offset)){ tvbuff_t *next_tvb; @@ -1892,6 +1906,23 @@ dissect_linux_usb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent) proto_tree_add_item(setup_tree, hf_usb_length, tvb, offset, 2, TRUE); offset += 2; } + + /* + * If this is padded (as is the case if the capture + * is done in memory-mapped mode), skip the padding; + * it's padded to a multiple of 64 bits *after* the + * pseudo-header and setup header. The pseudo-header + * is 40 bytes, and the setup header is 8 bytes, so + * that's 16 bytes of padding to 64 bytes. (The + * pseudo-header was removed from the packet data by + * Wiretap, so the offset is relative to the beginning + * of the setup header, not relative to the beginning + * of the raw packet data, so we can't just round it up + * to a multiple of 64.) + */ + if (padded) + offset += 16; + break; case RQT_SETUP_TYPE_CLASS: @@ -1907,6 +1938,21 @@ dissect_linux_usb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent) /* Skip setup header - it's not present */ offset += 8; + + /* + * If this is padded (as is the case if the capture is done + * in memory-mapped mode), skip the padding; it's padded to + * a multiple of 64 bits *after* the pseudo-header and setup + * header. The pseudo-header is 40 bytes, and the setup + * header is 8 bytes, so that's 16 bytes of padding to 64 + * bytes. (The pseudo-header was removed from the packet + * data by Wiretap, so the offset is relative to the beginning + * of the setup header, not relative to the beginning of the + * raw packet data, so we can't just round it up to a multiple + * of 64.) + */ + if (padded) + offset += 16; } } else { tvbuff_t *next_tvb; @@ -1916,6 +1962,20 @@ dissect_linux_usb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent) /* Skip setup header - it's never present for responses */ offset += 8; + /* + * If this is padded (as is the case if the capture is done in + * memory-mapped mode), skip the padding; it's padded to a multiple + * of 64 bits *after* the pseudo-header and setup header. The + * pseudo-header is 40 bytes, and the setup header is 8 bytes, + * so that's 16 bytes of padding to 64 bytes. (The pseudo-header + * was removed from the packet data by Wiretap, so the offset + * is relative to the beginning of the setup header, not relative + * to the beginning of the raw packet data, so we can't just + * round it up to a multiple of 64.) + */ + if (padded) + offset += 16; + if(usb_trans_info){ /* Try to find a class specific dissector */ next_tvb=tvb_new_subset(tvb, offset, -1, -1); @@ -1996,12 +2056,39 @@ dissect_linux_usb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent) offset += 8; } + + /* + * If this is padded (as is the case if the capture is done in + * memory-mapped mode), skip the padding; it's padded to a multiple + * of 64 bits *after* the pseudo-header and setup header. The + * pseudo-header is 40 bytes, and the setup header is 8 bytes, + * so that's 16 bytes of padding to 64 bytes. (The pseudo-header + * was removed from the packet data by Wiretap, so the offset + * is relative to the beginning of the setup header, not relative + * to the beginning of the raw packet data, so we can't just + * round it up to a multiple of 64.) + */ + if (padded) + offset += 16; + break; } if (tvb_reported_length_remaining(tvb, offset) != 0) proto_tree_add_item(tree, hf_usb_data, tvb, offset, -1, FALSE); } +static void +dissect_linux_usb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent) +{ + dissect_linux_usb_common(tvb, pinfo, parent, FALSE); +} + +static void +dissect_linux_usb_mmap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent) +{ + dissect_linux_usb_common(tvb, pinfo, parent, TRUE); +} + void proto_register_usb(void) { @@ -2336,9 +2423,12 @@ proto_register_usb(void) void proto_reg_handoff_usb(void) { - dissector_handle_t linux_usb_handle; + dissector_handle_t linux_usb_handle, linux_usb_mmap_handle; linux_usb_handle = create_dissector_handle(dissect_linux_usb, proto_usb); + linux_usb_mmap_handle = create_dissector_handle(dissect_linux_usb_mmap, + proto_usb); dissector_add("wtap_encap", WTAP_ENCAP_USB_LINUX, linux_usb_handle); + dissector_add("wtap_encap", WTAP_ENCAP_USB_LINUX_MMAP, linux_usb_mmap_handle); } diff --git a/wiretap/libpcap.c b/wiretap/libpcap.c index 87edbe6ffd..a7c804450b 100644 --- a/wiretap/libpcap.c +++ b/wiretap/libpcap.c @@ -484,6 +484,8 @@ static const struct { { 214, WTAP_ENCAP_X2E_XORAYA }, /* IEEE 802.15.4 Wireless PAN non-ASK PHY */ { 215, WTAP_ENCAP_IEEE802_15_4_NONASK_PHY }, + /* USB packets with padded Linux-specified header */ + { 220, WTAP_ENCAP_USB_LINUX_MMAP }, /* * To repeat: @@ -1447,6 +1449,7 @@ static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info, break; case WTAP_ENCAP_USB_LINUX: + case WTAP_ENCAP_USB_LINUX_MMAP: if (packet_size < sizeof (struct linux_usb_phdr)) { /* * Uh-oh, the packet isn't big enough to even @@ -1698,6 +1701,7 @@ libpcap_seek_read(wtap *wth, gint64 seek_off, break; case WTAP_ENCAP_USB_LINUX: + case WTAP_ENCAP_USB_LINUX_MMAP: if (!libpcap_read_linux_usb_pseudoheader(wth, wth->random_fh, pseudo_header, err)) return FALSE; /* Read error */ @@ -2628,6 +2632,7 @@ static gboolean libpcap_dump(wtap_dumper *wdh, break; case WTAP_ENCAP_USB_LINUX: + case WTAP_ENCAP_USB_LINUX_MMAP: hdrsize = sizeof (struct linux_usb_phdr); break; @@ -2871,6 +2876,7 @@ static gboolean libpcap_dump(wtap_dumper *wdh, break; case WTAP_ENCAP_USB_LINUX: + case WTAP_ENCAP_USB_LINUX_MMAP: /* * Write out the pseudo-header; it has the same format * as the Linux USB header, and that header is supposed diff --git a/wiretap/wtap.c b/wiretap/wtap.c index 02946c7dbd..1041e85de6 100644 --- a/wiretap/wtap.c +++ b/wiretap/wtap.c @@ -433,7 +433,10 @@ static struct encap_type_info encap_table_base[] = { { "IEEE 802.15.4 Wireless PAN non-ASK PHY", "wpan-nonask-phy" }, /* WTAP_ENCAP_TNEF */ - { "Transport-Neutral Encapsulation Format", "tnef" } + { "Transport-Neutral Encapsulation Format", "tnef" }, + + /* WTAP_ENCAP_USB_LINUX_MMAP */ + { "USB packets with Linux header and padding", "usb-linux-mmap" }, }; gint wtap_num_encap_types = sizeof(encap_table_base) / sizeof(struct encap_type_info); diff --git a/wiretap/wtap.h b/wiretap/wtap.h index c5cde96077..9599e7a87a 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -205,6 +205,7 @@ extern "C" { #define WTAP_ENCAP_I2C 112 #define WTAP_ENCAP_IEEE802_15_4_NONASK_PHY 113 #define WTAP_ENCAP_TNEF 114 +#define WTAP_ENCAP_USB_LINUX_MMAP 115 #define WTAP_NUM_ENCAP_TYPES wtap_get_num_encap_types() |