aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--epan/dissectors/packet-usb.c96
-rw-r--r--wiretap/libpcap.c6
-rw-r--r--wiretap/wtap.c5
-rw-r--r--wiretap/wtap.h1
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()