aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AUTHORS4
-rw-r--r--docbook/wsug_src/WSUG_app_tools.xml3
-rw-r--r--epan/dissectors/packet-usb.c770
-rw-r--r--wiretap/pcap-common.c2
-rw-r--r--wiretap/wtap.c9
-rw-r--r--wiretap/wtap.h1
6 files changed, 648 insertions, 141 deletions
diff --git a/AUTHORS b/AUTHORS
index 043d8119ea..2f055bfbef 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -3508,6 +3508,10 @@ Peter Hatina <phatina[AT]redhat.com> {
Gtk3 Wireshark fixes
}
+Tomasz Mon <desowin[AT]gmail.com> {
+ USBPcap support
+}
+
and by:
diff --git a/docbook/wsug_src/WSUG_app_tools.xml b/docbook/wsug_src/WSUG_app_tools.xml
index 88fdc4f401..f2b50bf8d8 100644
--- a/docbook/wsug_src/WSUG_app_tools.xml
+++ b/docbook/wsug_src/WSUG_app_tools.xml
@@ -550,6 +550,7 @@ editcap: The available encapsulation types for the "-T" flag are:
ieee-802-11-radio - IEEE 802.11 Wireless LAN with radio information
ieee-802-11-radiotap - IEEE 802.11 plus radiotap radio header
ieee-802-16-mac-cps - IEEE 802.16 MAC Common Part Sublayer
+ infiniband - InfiniBand
ios - Cisco IOS internal
ip-over-fc - RFC 2625 IP-over-Fibre Channel
ip-over-ib - IP over Infiniband
@@ -570,6 +571,7 @@ editcap: The available encapsulation types for the "-T" flag are:
juniper-mlppp - Juniper MLPPP
juniper-ppp - Juniper PPP
juniper-pppoe - Juniper PPPoE
+ juniper-svcs - Juniper Services
juniper-vp - Juniper Voice PIC
k12 - K12 protocol analyzer
lapb - LAPB
@@ -627,6 +629,7 @@ editcap: The available encapsulation types for the "-T" flag are:
usb - Raw USB packets
usb-linux - USB packets with Linux header
usb-linux-mmap - USB packets with Linux header and padding
+ usb-usbpcap - USB packets with USBPcap header
user0 - USER 0
user1 - USER 1
user10 - USER 10
diff --git a/epan/dissectors/packet-usb.c b/epan/dissectors/packet-usb.c
index 2d5de723f9..c4faa83736 100644
--- a/epan/dissectors/packet-usb.c
+++ b/epan/dissectors/packet-usb.c
@@ -42,6 +42,11 @@
#include "packet-usb.h"
#include "packet-usb-hid.h"
+/* internal header flags */
+#define USB_HEADER_IS_LINUX (1 << 0)
+#define USB_HEADER_IS_64_BYTES (1 << 1)
+#define USB_HEADER_IS_USBPCAP (1 << 2)
+
/* protocols and header fields */
static int proto_usb = -1;
@@ -62,6 +67,27 @@ static int hf_usb_urb_status = -1;
static int hf_usb_urb_len = -1;
static int hf_usb_urb_data_len = -1;
+/* Win32 USBPcap pseudoheader fields */
+static int hf_usb_win32_header_len = -1;
+static int hf_usb_irp_id = -1;
+static int hf_usb_usbd_status = -1;
+static int hf_usb_function = -1;
+static int hf_usb_info = -1;
+static int hf_usb_usbpcap_info_reserved = -1;
+static int hf_usb_usbpcap_info_direction = -1;
+static int hf_usb_win32_device_address = -1;
+/* hf_usb_bus_id, hf_usb_endpoint_number, hf_usb_endpoint_direction,
+ * hf_usb_endpoint_number_value, hf_usb_transfer_type are common with
+ * Linux pseudoheader */
+static int hf_usb_win32_data_len = -1;
+static int hf_usb_control_stage = -1;
+static int hf_usb_win32_iso_start_frame = -1;
+static int hf_usb_win32_iso_num_packets = -1;
+static int hf_usb_win32_iso_error_count = -1;
+static int hf_usb_win32_iso_offset = -1;
+static int hf_usb_win32_iso_length = -1;
+static int hf_usb_win32_iso_status = -1;
+
static int hf_usb_request = -1;
static int hf_usb_request_unknown_class = -1;
static int hf_usb_value = -1;
@@ -144,8 +170,10 @@ static int hf_usb_iFunction = -1;
static gint usb_hdr = -1;
static gint usb_setup_hdr = -1;
static gint usb_isodesc = -1;
+static gint usb_win32_iso_packet = -1;
static gint ett_usb_endpoint = -1;
static gint ett_usb_setup_bmrequesttype = -1;
+static gint ett_usb_usbpcap_info = -1;
static gint ett_descriptor_device = -1;
static gint ett_configuration_bmAttributes = -1;
static gint ett_configuration_bEndpointAddress = -1;
@@ -158,6 +186,12 @@ static const int *usb_endpoint_fields[] = {
NULL
};
+static const int *usb_usbpcap_info_fields[] = {
+ &hf_usb_usbpcap_info_reserved,
+ &hf_usb_usbpcap_info_direction,
+ NULL
+};
+
static int usb_tap = -1;
static gboolean try_heuristics = TRUE;
@@ -816,6 +850,145 @@ static const value_string usb_urb_status_vals[] = {
};
static value_string_ext usb_urb_status_vals_ext = VALUE_STRING_EXT_INIT(usb_urb_status_vals);
+#define USB_CONTROL_STAGE_SETUP 0x00
+#define USB_CONTROL_STAGE_DATA 0x01
+#define USB_CONTROL_STAGE_STATUS 0x02
+
+static const value_string usb_control_stage_vals[] = {
+ {USB_CONTROL_STAGE_SETUP, "Setup"},
+ {USB_CONTROL_STAGE_DATA, "Data"},
+ {USB_CONTROL_STAGE_STATUS, "Status"},
+ {0, NULL}
+};
+
+static const value_string win32_urb_function_vals[] = {
+ {0x0000, "URB_FUNCTION_SELECT_CONFIGURATION"},
+ {0x0001, "URB_FUNCTION_SELECT_INTERFACE"},
+ {0x0002, "URB_FUNCTION_ABORT_PIPE"},
+ {0x0003, "URB_FUNCTION_TAKE_FRAME_LENGTH_CONTROL"},
+ {0x0004, "URB_FUNCTION_RELEASE_FRAME_LENGTH_CONTROL"},
+ {0x0005, "URB_FUNCTION_GET_FRAME_LENGTH"},
+ {0x0006, "URB_FUNCTION_SET_FRAME_LENGTH"},
+ {0x0007, "URB_FUNCTION_GET_CURRENT_FRAME_NUMBER"},
+ {0x0008, "URB_FUNCTION_CONTROL_TRANSFER"},
+ {0x0009, "URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER"},
+ {0x000A, "URB_FUNCTION_ISOCH_TRANSFER"},
+ {0x000B, "URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE"},
+ {0x000C, "URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE"},
+ {0x000D, "URB_FUNCTION_SET_FEATURE_TO_DEVICE"},
+ {0x000E, "URB_FUNCTION_SET_FEATURE_TO_INTERFACE"},
+ {0x000F, "URB_FUNCTION_SET_FEATURE_TO_ENDPOINT"},
+ {0x0010, "URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE"},
+ {0x0011, "URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE"},
+ {0x0012, "URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT"},
+ {0x0013, "URB_FUNCTION_GET_STATUS_FROM_DEVICE"},
+ {0x0014, "URB_FUNCTION_GET_STATUS_FROM_INTERFACE"},
+ {0x0015, "URB_FUNCTION_GET_STATUS_FROM_ENDPOINT"},
+ {0x0016, "URB_FUNCTION_RESERVED_0X0016"},
+ {0x0017, "URB_FUNCTION_VENDOR_DEVICE"},
+ {0x0018, "URB_FUNCTION_VENDOR_INTERFACE"},
+ {0x0019, "URB_FUNCTION_VENDOR_ENDPOINT"},
+ {0x001A, "URB_FUNCTION_CLASS_DEVICE"},
+ {0x001B, "URB_FUNCTION_CLASS_INTERFACE"},
+ {0x001C, "URB_FUNCTION_CLASS_ENDPOINT"},
+ {0x001D, "URB_FUNCTION_RESERVE_0X001D"},
+ {0x001E, "URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL"},
+ {0x001F, "URB_FUNCTION_CLASS_OTHER"},
+ {0x0020, "URB_FUNCTION_VENDOR_OTHER"},
+ {0x0021, "URB_FUNCTION_GET_STATUS_FROM_OTHER"},
+ {0x0022, "URB_FUNCTION_CLEAR_FEATURE_TO_OTHER"},
+ {0x0023, "URB_FUNCTION_SET_FEATURE_TO_OTHER"},
+ {0x0024, "URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT"},
+ {0x0025, "URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT"},
+ {0x0026, "URB_FUNCTION_GET_CONFIGURATION"},
+ {0x0027, "URB_FUNCTION_GET_INTERFACE"},
+ {0x0028, "URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE"},
+ {0x0029, "URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE"},
+ {0x002A, "URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR"},
+ {0x002B, "URB_FUNCTION_RESERVE_0X002B"},
+ {0x002C, "URB_FUNCTION_RESERVE_0X002C"},
+ {0x002D, "URB_FUNCTION_RESERVE_0X002D"},
+ {0x002E, "URB_FUNCTION_RESERVE_0X002E"},
+ {0x002F, "URB_FUNCTION_RESERVE_0X002F"},
+ {0x0030, "URB_FUNCTION_SYNC_RESET_PIPE"},
+ {0x0031, "URB_FUNCTION_SYNC_CLEAR_STALL"},
+ {0x0032, "URB_FUNCTION_CONTROL_TRANSFER_EX"},
+ {0x0033, "URB_FUNCTION_RESERVE_0X0033"},
+ {0x0034, "URB_FUNCTION_RESERVE_0X0034"},
+ {0, NULL}
+};
+value_string_ext win32_urb_function_vals_ext = VALUE_STRING_EXT_INIT(win32_urb_function_vals);
+
+static const value_string win32_usbd_status_vals[] = {
+ {0x00000000, "USBD_STATUS_SUCCESS"},
+ {0x40000000, "USBD_STATUS_PENDING"},
+
+ {0x80000200, "USBD_STATUS_INVALID_URB_FUNCTION"},
+ {0x80000300, "USBD_STATUS_INVALID_PARAMETER"},
+ {0x80000400, "USBD_STATUS_ERROR_BUSY"},
+ {0x80000600, "USBD_STATUS_INVALID_PIPE_HANDLE"},
+ {0x80000700, "USBD_STATUS_NO_BANDWIDTH"},
+ {0x80000800, "USBD_STATUS_INTERNAL_HC_ERROR"},
+ {0x80000900, "USBD_STATUS_ERROR_SHORT_TRANSFER"},
+
+ {0xC0000001, "USBD_STATUS_CRC"},
+ {0xC0000002, "USBD_STATUS_BTSTUFF"},
+ {0xC0000003, "USBD_STATUS_DATA_TOGGLE_MISMATCH"},
+ {0xC0000004, "USBD_STATUS_STALL_PID"},
+ {0xC0000005, "USBD_STATUS_DEV_NOT_RESPONDING"},
+ {0xC0000006, "USBD_STATUS_PID_CHECK_FAILURE"},
+ {0xC0000007, "USBD_STATUS_UNEXPECTED_PID"},
+ {0xC0000008, "USBD_STATUS_DATA_OVERRUN"},
+ {0xC0000009, "USBD_STATUS_DATA_UNDERRUN"},
+ {0xC000000A, "USBD_STATUS_RESERVED1"},
+ {0xC000000B, "USBD_STATUS_RESERVED2"},
+ {0xC000000C, "USBD_STATUS_BUFFER_OVERRUN"},
+ {0xC000000D, "USBD_STATUS_BUFFER_UNDERRUN"},
+ {0xC000000F, "USBD_STATUS_NOT_ACCESSED"},
+ {0xC0000010, "USBD_STATUS_FIFO"},
+ {0xC0000011, "USBD_STATUS_XACT_ERROR"},
+ {0xC0000012, "USBD_STATUS_BABBLE_DETECTED"},
+ {0xC0000013, "USBD_STATUS_DATA_BUFFER_ERROR"},
+ {0xC0000030, "USBD_STATUS_ENDPOINT_HALTED"},
+
+ {0xC0000A00, "USBD_STATUS_BAD_START_FRAME"},
+ {0xC0000B00, "USBD_STATUS_ISOCH_REQUEST_FAILED"},
+ {0xC0000C00, "USBD_STATUS_FRAME_CONTROL_OWNED"},
+ {0xC0000D00, "USBD_STATUS_FRAME_CONTROL_NOT_OWNED"},
+ {0xC0000E00, "USBD_STATUS_NOT_SUPPORTED"},
+ {0xC0000F00, "USBD_STATUS_INVALID_CONFIGURATION_DESCRIPTOR"},
+ {0xC0001000, "USBD_STATUS_INSUFFICIENT_RESOURCES"},
+ {0xC0002000, "USBD_STATUS_SET_CONFIG_FAILED"},
+ {0xC0003000, "USBD_STATUS_BUFFER_TOO_SMALL"},
+ {0xC0004000, "USBD_STATUS_INTERFACE_NOT_FOUND"},
+ {0xC0005000, "USBD_STATUS_INVALID_PIPE_FLAGS"},
+ {0xC0006000, "USBD_STATUS_TIMEOUT"},
+ {0xC0007000, "USBD_STATUS_DEVICE_GONE"},
+ {0xC0008000, "USBD_STATUS_STATUS_NOT_MAPPED"},
+ {0xC0009000, "USBD_STATUS_HUB_INTERNAL_ERROR"},
+ {0xC0010000, "USBD_STATUS_CANCELED"},
+ {0xC0020000, "USBD_STATUS_ISO_NOT_ACCESSED_BY_HW"},
+ {0xC0030000, "USBD_STATUS_ISO_TD_ERROR"},
+ {0xC0040000, "USBD_STATUS_ISO_NA_LATE_USBPORT"},
+ {0xC0050000, "USBD_STATUS_ISO_NOT_ACCESSED_LATE"},
+ {0xC0100000, "USBD_STATUS_BAD_DESCRIPTOR"},
+ {0xC0100001, "USBD_STATUS_BAD_DESCRIPTOR_BLEN"},
+ {0xC0100002, "USBD_STATUS_BAD_DESCRIPTOR_TYPE"},
+ {0xC0100003, "USBD_STATUS_BAD_INTERFACE_DESCRIPTOR"},
+ {0xC0100004, "USBD_STATUS_BAD_ENDPOINT_DESCRIPTOR"},
+ {0xC0100005, "USBD_STATUS_BAD_INTERFACE_ASSOC_DESCRIPTOR"},
+ {0xC0100006, "USBD_STATUS_BAD_CONFIG_DESC_LENGTH"},
+ {0xC0100007, "USBD_STATUS_BAD_NUMBER_OF_INTERFACES"},
+ {0xC0100008, "USBD_STATUS_BAD_NUMBER_OF_ENDPOINTS"},
+ {0xC0100009, "USBD_STATUS_BAD_ENDPOINT_ADDRESS"},
+ {0, NULL}
+};
+
+static const value_string win32_usb_info_direction_vals[] = {
+ {0, "FDO -> PDO"},
+ {1, "PDO -> FDO"},
+ {0, NULL}
+};
static usb_conv_info_t *
get_usb_conv_info(conversation_t *conversation)
@@ -2304,13 +2477,67 @@ dissect_linux_usb_pseudo_header_ext(tvbuff_t *tvb, int offset,
return offset;
}
+/* Adds the win32 USBPcap pseudo header fields to the tree. */
+static void
+dissect_win32_usb_pseudo_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+ guint *bus_id, guint *device_address)
+{
+ guint8 transfer_type;
+ guint8 endpoint_number;
+ guint8 transfer_type_and_direction;
+
+ proto_tree_add_item(tree, hf_usb_win32_header_len, tvb, 0, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_usb_irp_id, tvb, 2, 8, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_usb_usbd_status, tvb, 10, 4, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_usb_function, tvb, 14, 2, ENC_LITTLE_ENDIAN);
+
+ proto_tree_add_bitmask(tree, tvb, 16, hf_usb_info, ett_usb_usbpcap_info, usb_usbpcap_info_fields, ENC_LITTLE_ENDIAN);
+
+ proto_tree_add_item(tree, hf_usb_bus_id, tvb, 17, 2, ENC_LITTLE_ENDIAN);
+ *bus_id = tvb_get_letohs(tvb, 17);
+
+ proto_tree_add_item(tree, hf_usb_win32_device_address, tvb, 19, 2, ENC_LITTLE_ENDIAN);
+ *device_address = tvb_get_letohs(tvb, 19);
+
+ transfer_type = tvb_get_guint8(tvb, 22);
+
+ endpoint_number = tvb_get_guint8(tvb, 21);
+ transfer_type_and_direction = (transfer_type & 0x7F) | (endpoint_number & 0x80);
+ col_append_str(pinfo->cinfo, COL_INFO,
+ val_to_str(transfer_type_and_direction, usb_transfer_type_and_direction_vals, "Unknown type %x"));
+
+ proto_tree_add_bitmask(tree, tvb, 21, hf_usb_endpoint_number, ett_usb_endpoint, usb_endpoint_fields, ENC_LITTLE_ENDIAN);
+
+ proto_tree_add_item(tree, hf_usb_transfer_type, tvb, 22, 1, ENC_LITTLE_ENDIAN);
+
+ proto_tree_add_item(tree, hf_usb_win32_data_len, tvb, 23, 4, ENC_LITTLE_ENDIAN);
+
+ /* Handle transfer specific data */
+ switch (transfer_type)
+ {
+ case URB_ISOCHRONOUS:
+ /* dissection in handled in dissect_usb_common() */
+ break;
+ case URB_INTERRUPT:
+ break;
+ case URB_CONTROL:
+ proto_tree_add_item(tree, hf_usb_control_stage, tvb, 27, 1, ENC_LITTLE_ENDIAN);
+ break;
+ case URB_BULK:
+ break;
+ }
+}
+
static void
-dissect_linux_usb_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent,
- gboolean header_len_64_bytes)
+dissect_usb_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent,
+ guint8 header_info)
{
unsigned int offset = 0;
- int type, endpoint;
+ int type, endpoint, endpoint_with_dir;
+ guint8 urb_type, usbpcap_control_stage = 0;
guint8 setup_flag;
+ guint16 hdr_len;
+ guint32 win32_data_len = 0;
proto_tree *tree = NULL;
guint32 tmp_addr;
static usb_address_t src_addr, dst_addr; /* has to be static due to SET_ADDRESS */
@@ -2328,28 +2555,76 @@ dissect_linux_usb_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent,
col_set_str(pinfo->cinfo, COL_PROTOCOL, "USB");
- /* add usb hdr*/
- if (parent) {
- proto_item *ti;
- ti = proto_tree_add_protocol_format(parent, proto_usb, tvb, 0,
- header_len_64_bytes ? 64 : 48, "USB URB");
- tree = proto_item_add_subtree(ti, usb_hdr);
- }
+ if (header_info & USB_HEADER_IS_LINUX) {
+ /* add usb hdr*/
+ if (parent) {
+ proto_item *ti;
+ ti = proto_tree_add_protocol_format(parent, proto_usb, tvb, 0,
+ (header_info & USB_HEADER_IS_64_BYTES) ? 64 : 48, "USB URB");
+ tree = proto_item_add_subtree(ti, usb_hdr);
+ }
- dissect_linux_usb_pseudo_header(tvb, pinfo, tree, &bus_id, &device_address);
- is_request = (tvb_get_guint8(tvb, 8) == URB_SUBMIT) ? TRUE : FALSE;
- type = tvb_get_guint8(tvb, 9);
- endpoint = tvb_get_guint8(tvb, 10) & (~URB_TRANSFER_IN);
- tmp_addr = tvb_get_guint8(tvb, 11);
- setup_flag = tvb_get_guint8(tvb, 14);
- offset += 40; /* skip first part of the pseudo-header */
+ dissect_linux_usb_pseudo_header(tvb, pinfo, tree, &bus_id, &device_address);
+ urb_type = tvb_get_guint8(tvb, 8);
+ is_request = (urb_type == URB_SUBMIT) ? TRUE : FALSE;
+ type = tvb_get_guint8(tvb, 9);
+ endpoint_with_dir = tvb_get_guint8(tvb, 10);
+ endpoint = endpoint_with_dir & (~URB_TRANSFER_IN);
+ tmp_addr = tvb_get_guint8(tvb, 11);
+ setup_flag = tvb_get_guint8(tvb, 14);
+ offset += 40; /* skip first part of the pseudo-header */
+ } else if (header_info & USB_HEADER_IS_USBPCAP) {
+ guint8 tmp_val8;
+
+ tvb_memcpy(tvb, (guint8 *)&hdr_len, 0, 2);
+ /* add usb hdr */
+ if (parent) {
+ proto_item *ti;
+ ti = proto_tree_add_protocol_format(parent, proto_usb, tvb, 0,
+ hdr_len, "USB URB");
+ tree = proto_item_add_subtree(ti, usb_hdr);
+ }
+
+ dissect_win32_usb_pseudo_header(tvb, pinfo, tree, &bus_id, &device_address);
+
+ hdr_len = tvb_get_letohs(tvb, 0);
+ tmp_val8 = tvb_get_guint8(tvb, 16);
+ /* TODO: Handle errors */
+ if (tmp_val8 & 0x01) {
+ urb_type = URB_COMPLETE;
+ } else {
+ urb_type = URB_SUBMIT;
+ }
+ is_request = (urb_type == URB_SUBMIT) ? TRUE : FALSE;
+ type = tvb_get_guint8(tvb, 22);
+ endpoint_with_dir = tvb_get_guint8(tvb, 21);
+ endpoint = endpoint_with_dir & (~URB_TRANSFER_IN);
+ tmp_addr = device_address;
+
+ win32_data_len = tvb_get_letohl(tvb, 23);
+ usbpcap_control_stage = tvb_get_guint8(tvb, 27);
+ if (usbpcap_control_stage == USB_CONTROL_STAGE_SETUP) {
+ setup_flag = 0;
+ } else {
+ setup_flag = 0xFF;
+ }
+
+ if (type == URB_ISOCHRONOUS) {
+ offset += 27; /* Skip the part of pseudo-header already dissected */
+ } else {
+ offset += hdr_len; /* Skip the pseudo-header */
+ }
+ } else {
+ /* Unknown pseudo-header type */
+ return;
+ }
usb_data = se_new(usb_data_t);
usb_data->bus_id = bus_id;
usb_data->device_address = device_address;
usb_data->endpoint = endpoint;
- if (tvb_get_guint8(tvb, 10) & URB_TRANSFER_IN) {
+ if (endpoint_with_dir & URB_TRANSFER_IN) {
usb_data->direction = P2P_DIR_RECV;
} else {
usb_data->direction = P2P_DIR_SENT;
@@ -2395,7 +2670,7 @@ dissect_linux_usb_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent,
usb_trans_info = se_new0(usb_trans_info_t);
usb_trans_info->request_in = pinfo->fd->num;
usb_trans_info->req_time = pinfo->fd->abs_ts;
- usb_trans_info->header_len_64 = header_len_64_bytes;
+ usb_trans_info->header_len_64 = (header_info & USB_HEADER_IS_64_BYTES) ? TRUE : FALSE;
se_tree_insert32(usb_conv_info->transactions, pinfo->fd->num, usb_trans_info);
}
@@ -2435,7 +2710,7 @@ dissect_linux_usb_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent,
}
tap_data = ep_new(usb_tap_data_t);
- tap_data->urb_type = tvb_get_guint8(tvb, 8);
+ tap_data->urb_type = urb_type;
tap_data->transfer_type = (guint8)type;
tap_data->conv_info = usb_conv_info;
tap_data->trans_info = usb_trans_info;
@@ -2452,15 +2727,18 @@ dissect_linux_usb_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent,
item = proto_tree_add_uint(tree, hf_usb_bInterfaceClass, tvb, 0, 0, usb_conv_info->interfaceClass);
PROTO_ITEM_SET_GENERATED(item);
- /* Skip setup/isochronous header - it's not applicable */
- offset += 8;
+ if (header_info & USB_HEADER_IS_LINUX) {
+ /* Skip setup/isochronous header - it's not applicable */
+ offset += 8;
- /*
- * If this has a 64-byte header, process the extra 16 bytes of
- * pseudo-header information.
- */
- if (header_len_64_bytes)
- offset = dissect_linux_usb_pseudo_header_ext(tvb, offset, pinfo, tree);
+ /*
+ * If this has a 64-byte header, process the extra 16 bytes of
+ * pseudo-header information.
+ */
+ if (header_info & USB_HEADER_IS_64_BYTES) {
+ offset = dissect_linux_usb_pseudo_header_ext(tvb, offset, pinfo, tree);
+ }
+ }
if (tvb_reported_length_remaining(tvb, offset)) {
pinfo->usb_conv_info = usb_conv_info;
@@ -2481,15 +2759,18 @@ dissect_linux_usb_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent,
item = proto_tree_add_uint(tree, hf_usb_bInterfaceClass, tvb, 0, 0, usb_conv_info->interfaceClass);
PROTO_ITEM_SET_GENERATED(item);
- /* Skip setup/isochronous header - it's not applicable */
- offset += 8;
+ if (header_info & USB_HEADER_IS_LINUX) {
+ /* Skip setup/isochronous header - it's not applicable */
+ offset += 8;
- /*
- * If this has a 64-byte header, process the extra 16 bytes of
- * pseudo-header information.
- */
- if (header_len_64_bytes)
- offset = dissect_linux_usb_pseudo_header_ext(tvb, offset, pinfo, tree);
+ /*
+ * If this has a 64-byte header, process the extra 16 bytes of
+ * pseudo-header information.
+ */
+ if (header_info & USB_HEADER_IS_64_BYTES) {
+ offset = dissect_linux_usb_pseudo_header_ext(tvb, offset, pinfo, tree);
+ }
+ }
if (tvb_reported_length_remaining(tvb, offset)) {
pinfo->usb_conv_info = usb_conv_info;
@@ -2628,16 +2909,20 @@ dissect_linux_usb_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent,
offset += 2;
}
} else {
- /* Skip setup/isochronous header - it's not applicable */
- offset += 8;
+ if (header_info & USB_HEADER_IS_LINUX) {
+ /* Skip setup/isochronous header - it's not applicable */
+ offset += 8;
+ }
}
/*
* If this has a 64-byte header, process the extra 16 bytes of
* pseudo-header information.
*/
- if (header_len_64_bytes)
+ if ((header_info & USB_HEADER_IS_LINUX) &&
+ (header_info & USB_HEADER_IS_64_BYTES)) {
offset = dissect_linux_usb_pseudo_header_ext(tvb, offset, pinfo, tree);
+ }
if (tvb_reported_length_remaining(tvb, offset) != 0) {
next_tvb = tvb_new_subset_remaining(tvb, offset);
@@ -2651,8 +2936,10 @@ dissect_linux_usb_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent,
} else {
/* this is a response */
- /* Skip setup header - it's never applicable for responses */
- offset += 8;
+ if (header_info & USB_HEADER_IS_LINUX) {
+ /* Skip setup header - it's never applicable for responses */
+ offset += 8;
+ }
/* Make sure we have the proper conversation */
if (usb_trans_info) {
@@ -2687,10 +2974,23 @@ dissect_linux_usb_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent,
* If this has a 64-byte header, process the extra 16 bytes of
* pseudo-header information.
*/
- if (header_len_64_bytes)
+ if ((header_info & USB_HEADER_IS_LINUX) &&
+ (header_info & USB_HEADER_IS_64_BYTES)) {
offset = dissect_linux_usb_pseudo_header_ext(tvb, offset, pinfo, tree);
+ }
+
if (usb_trans_info) {
+ /* Check if this is status stage */
+ if ((header_info & USB_HEADER_IS_USBPCAP) &&
+ (usbpcap_control_stage == USB_CONTROL_STAGE_STATUS)) {
+ col_add_fstr(pinfo->cinfo, COL_INFO, "%s Status",
+ val_to_str(usb_conv_info->usb_trans_info->setup.request,
+ setup_request_names_vals, "Unknown type %x"));
+ /* There is no data to dissect */
+ return;
+ }
+
/* Try to find a class specific dissector */
next_tvb = tvb_new_subset_remaining(tvb, offset);
if (try_heuristics && dissector_try_heuristic(heur_control_subdissector_list, next_tvb, pinfo, parent, NULL)) {
@@ -2750,125 +3050,215 @@ dissect_linux_usb_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent,
}
break;
case URB_ISOCHRONOUS:
- {
- guint32 iso_numdesc = 0;
- proto_item *tii;
- tii = proto_tree_add_uint(tree, hf_usb_bInterfaceClass, tvb, offset, 0, usb_conv_info->interfaceClass);
- PROTO_ITEM_SET_GENERATED(tii);
- /* All fields which belong to Linux usbmon headers are in host-endian
- * byte order. The fields coming from the USB communication are in little
- * endian format (see usb_20.pdf, chapter 8.1 Byte/Bit ordering).
- *
- * When a capture file is transfered to a host with different endianness
- * than packet was captured then the necessary swapping happens in
- * wiretap/pcap-common.c, pcap_process_linux_usb_pseudoheader().
- */
+ if (header_info & USB_HEADER_IS_LINUX) {
+ guint32 iso_numdesc = 0;
+ proto_item *tii;
+ tii = proto_tree_add_uint(tree, hf_usb_bInterfaceClass, tvb, offset, 0, usb_conv_info->interfaceClass);
+ PROTO_ITEM_SET_GENERATED(tii);
+ /* All fields which belong to Linux usbmon headers are in host-endian
+ * byte order. The fields coming from the USB communication are in little
+ * endian format (see usb_20.pdf, chapter 8.1 Byte/Bit ordering).
+ *
+ * When a capture file is transfered to a host with different endianness
+ * than packet was captured then the necessary swapping happens in
+ * wiretap/pcap-common.c, pcap_process_linux_usb_pseudoheader().
+ */
- if (setup_flag == 0) {
- proto_item *ti;
- proto_tree *setup_tree;
- int type_2;
+ if (setup_flag == 0) {
+ proto_item *ti;
+ proto_tree *setup_tree;
+ int type_2;
- /* Dissect the setup header - it's applicable */
+ /* Dissect the setup header - it's applicable */
- ti = proto_tree_add_protocol_format(parent, proto_usb, tvb, offset, 8, "URB setup");
- setup_tree = proto_item_add_subtree(ti, usb_setup_hdr);
+ ti = proto_tree_add_protocol_format(parent, proto_usb, tvb, offset, 8, "URB setup");
+ setup_tree = proto_item_add_subtree(ti, usb_setup_hdr);
- offset = dissect_usb_bmrequesttype(setup_tree, tvb, offset, &type_2);
- proto_tree_add_item(setup_tree, hf_usb_request, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- offset += 1;
- proto_tree_add_item(setup_tree, hf_usb_value, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- proto_tree_add_item(setup_tree, hf_usb_index, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- proto_tree_add_item(setup_tree, hf_usb_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- } else {
+ offset = dissect_usb_bmrequesttype(setup_tree, tvb, offset, &type_2);
+ proto_tree_add_item(setup_tree, hf_usb_request, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ offset += 1;
+ proto_tree_add_item(setup_tree, hf_usb_value, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(setup_tree, hf_usb_index, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(setup_tree, hf_usb_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ } else {
+
+ /* Process ISO related fields (usbmon_packet.iso). The fields are
+ * in host endian byte order so use tvb_memcopy() and
+ * proto_tree_add_uint() pair.
+ */
+ guint32 val32;
+
+ tvb_memcpy(tvb, (guint8 *)&val32, offset, 4);
+ proto_tree_add_uint(tree, hf_usb_iso_error_count, tvb, offset, 4, val32);
+ offset += 4;
- /* Process ISO related fields (usbmon_packet.iso). The fields are
- * in host endian byte order so use tvb_memcopy() and
- * proto_tree_add_uint() pair.
+ tvb_memcpy(tvb, (guint8 *)&iso_numdesc, offset, 4);
+ proto_tree_add_uint(tree, hf_usb_iso_numdesc, tvb, offset, 4, iso_numdesc);
+ offset += 4;
+ }
+
+ /*
+ * If this has a 64-byte header, process the extra 16 bytes of
+ * pseudo-header information.
*/
- guint32 val32;
+ if (header_info & USB_HEADER_IS_64_BYTES) {
+ guint32 ndesc;
- tvb_memcpy(tvb, (guint8 *)&val32, offset, 4);
- proto_tree_add_uint(tree, hf_usb_iso_error_count, tvb, offset, 4, val32);
- offset += 4;
+ offset += 4; /* interval */
+ offset += 4; /* start_frame */
+ offset += 4; /* copy of URB's transfer flags */
- tvb_memcpy(tvb, (guint8 *)&iso_numdesc, offset, 4);
- proto_tree_add_uint(tree, hf_usb_iso_numdesc, tvb, offset, 4, iso_numdesc);
- offset += 4;
- }
+ tvb_memcpy(tvb, (guint8 *)&ndesc, offset, 4);
+ offset += 4;
+ }
- /*
- * If this has a 64-byte header, process the extra 16 bytes of
- * pseudo-header information.
- */
- if (header_len_64_bytes) {
- guint32 ndesc;
+ if (setup_flag != 0) {
+ proto_tree *urb_tree;
+ guint32 i;
+ unsigned int data_base;
+ guint32 iso_status;
+ guint32 iso_off;
+ guint32 iso_len;
+ guint32 iso_pad;
+
+ data_base = offset + iso_numdesc * 16;
+ urb_tree = tree;
+ for (i = 0; i != iso_numdesc; i++) {
+ /* Fetch ISO descriptor fields stored in host
+ * endian byte order.
+ */
+ tvb_memcpy(tvb, (guint8 *)&iso_status, offset, 4);
+ tvb_memcpy(tvb, (guint8 *)&iso_off, offset+4, 4);
+ tvb_memcpy(tvb, (guint8 *)&iso_len, offset+8, 4);
+
+ if (parent) {
+ proto_item *ti;
+ if (iso_len > 0) {
+ ti = proto_tree_add_protocol_format(urb_tree, proto_usb, tvb, offset,
+ 16, "USB isodesc %u [%s] (%u bytes)", i,
+ val_to_str_ext(iso_status, &usb_urb_status_vals_ext, "Error %d"), iso_len);
+ } else {
+ ti = proto_tree_add_protocol_format(urb_tree, proto_usb, tvb, offset,
+ 16, "USB isodesc %u [%s]", i, val_to_str_ext(iso_status, &usb_urb_status_vals_ext, "Error %d"));
+ }
+ tree = proto_item_add_subtree(ti, usb_isodesc);
+ }
- offset += 4; /* interval */
- offset += 4; /* start_frame */
- offset += 4; /* copy of URB's transfer flags */
+ proto_tree_add_int(tree, hf_usb_iso_status, tvb, offset, 4, iso_status);
+ offset += 4;
- tvb_memcpy(tvb, (guint8 *)&ndesc, offset, 4);
+ proto_tree_add_uint(tree, hf_usb_iso_off, tvb, offset, 4, iso_off);
+ offset += 4;
+
+ proto_tree_add_uint(tree, hf_usb_iso_len, tvb, offset, 4, iso_len);
+ offset += 4;
+
+ /* When the ISO status is OK and there is ISO data and this ISO data is
+ * fully captured then show this data.
+ */
+ if (!iso_status && iso_len && data_base + iso_off + iso_len <= tvb_length(tvb))
+ proto_tree_add_item(tree, hf_usb_iso_data, tvb, data_base + iso_off, iso_len, ENC_NA);
+
+ tvb_memcpy(tvb, (guint8 *)&iso_pad, offset, 4);
+ proto_tree_add_uint(tree, hf_usb_iso_pad, tvb, offset, 4, iso_pad);
+ offset += 4;
+ }
+ }
+ } else if (header_info & USB_HEADER_IS_USBPCAP) {
+ guint32 num_packets;
+ guint32 i;
+ guint32 data_start_offset;
+ proto_tree *urb_tree;
+
+ /* 27 bytes of header were dissected in dissect_win32_usb_pseudo_header() */
+ data_start_offset = offset - 27 + hdr_len;
+ urb_tree = parent;
+
+ proto_tree_add_item(tree, hf_usb_win32_iso_start_frame, tvb, offset, 4, ENC_LITTLE_ENDIAN);
offset += 4;
- }
+ num_packets = tvb_get_letohl(tvb, offset);
+ proto_tree_add_item(tree, hf_usb_win32_iso_num_packets, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
- if (setup_flag != 0) {
- proto_tree *urb_tree;
- guint32 i;
- unsigned int data_base;
- guint32 iso_status;
- guint32 iso_off;
- guint32 iso_len;
- guint32 iso_pad;
-
- data_base = offset + iso_numdesc * 16;
- urb_tree = tree;
- for (i = 0; i != iso_numdesc; i++) {
- /* Fetch ISO descriptor fields stored in host
- * endian byte order.
- */
- tvb_memcpy(tvb, (guint8 *)&iso_status, offset, 4);
- tvb_memcpy(tvb, (guint8 *)&iso_off, offset+4, 4);
- tvb_memcpy(tvb, (guint8 *)&iso_len, offset+8, 4);
+ proto_tree_add_item(tree, hf_usb_win32_iso_error_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+
+ for (i = 0; i < num_packets; i++)
+ {
+ guint32 this_offset;
+ guint32 next_offset;
+ guint32 iso_len;
+ proto_item *ti;
if (parent) {
- proto_item *ti;
- if (iso_len > 0) {
- ti = proto_tree_add_protocol_format(urb_tree, proto_usb, tvb, offset,
- 16, "USB isodesc %u [%s] (%u bytes)", i,
- val_to_str_ext(iso_status, &usb_urb_status_vals_ext, "Error %d"), iso_len);
- } else {
- ti = proto_tree_add_protocol_format(urb_tree, proto_usb, tvb, offset,
- 16, "USB isodesc %u [%s]", i, val_to_str_ext(iso_status, &usb_urb_status_vals_ext, "Error %d"));
- }
- tree = proto_item_add_subtree(ti, usb_isodesc);
+ ti = proto_tree_add_protocol_format(urb_tree, proto_usb, tvb, offset,
+ 12, "USB isochronous packet");
+ tree = proto_item_add_subtree(ti, usb_win32_iso_packet);
}
- proto_tree_add_int(tree, hf_usb_iso_status, tvb, offset, 4, iso_status);
- offset += 4;
+ this_offset = tvb_get_letohl(tvb, offset);
+ if (num_packets - i == 1) {
+ /* this is the last packet */
+ next_offset = win32_data_len;
+ } else {
+ /* there is next packet */
+ next_offset = tvb_get_letohl(tvb, offset + 12);
+ }
- proto_tree_add_uint(tree, hf_usb_iso_off, tvb, offset, 4, iso_off);
- offset += 4;
+ if (next_offset > this_offset) {
+ iso_len = next_offset - this_offset;
+ } else {
+ iso_len = 0;
+ }
+
+ /* If this packet does not contain isochrounous data, do not try to display it */
+ if (!((is_request && !(endpoint_with_dir & URB_TRANSFER_IN)) ||
+ (!is_request && (endpoint_with_dir & URB_TRANSFER_IN)))) {
+ iso_len = 0;
+ }
- proto_tree_add_uint(tree, hf_usb_iso_len, tvb, offset, 4, iso_len);
+ proto_tree_add_item(tree, hf_usb_win32_iso_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
offset += 4;
- /* When the ISO status is OK and there is ISO data and this ISO data is
- * fully captured then show this data.
- */
- if (!iso_status && iso_len && data_base + iso_off + iso_len <= tvb_length(tvb))
- proto_tree_add_item(tree, hf_usb_iso_data, tvb, data_base + iso_off, iso_len, ENC_NA);
+ ti = proto_tree_add_item(tree, hf_usb_win32_iso_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ if (!(endpoint_with_dir & URB_TRANSFER_IN)) {
+ /* Isochronous OUT transfer */
+ proto_item_append_text(ti, " (not used)");
+ } else {
+ /* Isochronous IN transfer.
+ * Length field is being set by host controller.
+ */
+ if (is_request) {
+ /* Length was not yet set */
+ proto_item_append_text(ti, " (irrelevant)");
+ } else {
+ /* Length was set and (should be) valid */
+ proto_item_append_text(ti, " (relevant)");
+ iso_len = tvb_get_letohl(tvb, offset);
+ }
+ }
+ offset += 4;
- tvb_memcpy(tvb, (guint8 *)&iso_pad, offset, 4);
- proto_tree_add_uint(tree, hf_usb_iso_pad, tvb, offset, 4, iso_pad);
+ ti = proto_tree_add_item(tree, hf_usb_win32_iso_status, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ if (urb_type == URB_SUBMIT) {
+ proto_item_append_text(ti, " (irrelevant)");
+ } else {
+ proto_item_append_text(ti, " (relevant)");
+ }
offset += 4;
- }
- }
+ if (iso_len && data_start_offset + this_offset + iso_len <= tvb_length(tvb))
+ proto_tree_add_item(tree, hf_usb_iso_data, tvb, (gint)(data_start_offset + this_offset), (gint)iso_len, ENC_NA);
+ }
+ if ((is_request && !(endpoint_with_dir & URB_TRANSFER_IN)) ||
+ (!is_request && (endpoint_with_dir & URB_TRANSFER_IN))) {
+ /* We have dissected all the isochronous data */
+ offset += win32_data_len;
+ }
}
break;
@@ -2894,16 +3284,20 @@ dissect_linux_usb_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent,
proto_tree_add_item(setup_tree, hf_usb_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
offset += 2;
} else {
- /* Skip setup/isochronous header - it's not applicable */
- offset += 8;
+ if (header_info & USB_HEADER_IS_LINUX) {
+ /* Skip setup/isochronous header - it's not applicable */
+ offset += 8;
+ }
}
/*
* If this has a 64-byte header, process the extra 16 bytes of
* pseudo-header information.
*/
- if (header_len_64_bytes)
+ if ((header_info & USB_HEADER_IS_LINUX) &&
+ (header_info & USB_HEADER_IS_64_BYTES)) {
offset = dissect_linux_usb_pseudo_header_ext(tvb, offset, pinfo, tree);
+ }
break;
}
@@ -2960,13 +3354,20 @@ dissect_linux_usb_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent,
static void
dissect_linux_usb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent)
{
- dissect_linux_usb_common(tvb, pinfo, parent, FALSE);
+ dissect_usb_common(tvb, pinfo, parent, USB_HEADER_IS_LINUX);
}
static void
dissect_linux_usb_mmapped(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent)
{
- dissect_linux_usb_common(tvb, pinfo, parent, TRUE);
+ dissect_usb_common(tvb, pinfo, parent, USB_HEADER_IS_LINUX | USB_HEADER_IS_64_BYTES);
+}
+
+
+static void
+dissect_win32_usb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent)
+{
+ dissect_usb_common(tvb, pinfo, parent, USB_HEADER_IS_USBPCAP);
}
void
@@ -3051,6 +3452,88 @@ proto_register_usb(void)
FT_UINT32, BASE_DEC, NULL, 0x0,
"URB data length in bytes", HFILL }},
+ /* Win32 USBPcap pseudoheader */
+ { &hf_usb_win32_header_len,
+ { "USBPcap pseudoheader length", "usb.usbpcap_header_len",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_usb_irp_id,
+ { "IRP ID", "usb.irp_id",
+ FT_UINT64, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_usb_usbd_status,
+ { "IRP USBD_STATUS", "usb.usbd_status",
+ FT_UINT32, BASE_HEX, VALS(win32_usbd_status_vals), 0x0,
+ "USB request status value", HFILL }},
+
+ { &hf_usb_function,
+ { "URB Function", "usb.function",
+ FT_UINT16, BASE_HEX|BASE_EXT_STRING, &win32_urb_function_vals_ext, 0x0,
+ NULL, HFILL }},
+
+ { &hf_usb_info,
+ { "IRP information", "usb.irp_info",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_usb_usbpcap_info_reserved,
+ { "Reserved", "usb.irp_info.reserved",
+ FT_UINT8, BASE_HEX, NULL, 0xFE,
+ NULL, HFILL }},
+
+ { &hf_usb_usbpcap_info_direction,
+ { "Direction", "usb.irp_info.direction",
+ FT_UINT8, BASE_HEX, VALS(win32_usb_info_direction_vals), 0x01,
+ NULL, HFILL }},
+
+ { &hf_usb_win32_device_address,
+ { "Device address", "usb.device_address",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ "Windows USB device address", HFILL }},
+
+ { &hf_usb_win32_data_len,
+ { "Packet Data Length", "usb.data_len",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_usb_control_stage,
+ { "Control transfer stage", "usb.control_stage",
+ FT_UINT8, BASE_DEC, VALS(usb_control_stage_vals), 0x0,
+ NULL, HFILL }},
+
+ { &hf_usb_win32_iso_start_frame,
+ { "Isochronous transfer start frame", "usb.win32.iso_frame",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_usb_win32_iso_num_packets,
+ { "Isochronous transfer number of packets", "usb.win32.iso_num_packets",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_usb_win32_iso_error_count,
+ { "Isochronous transfer error count", "usb.win32.iso_error_count",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_usb_win32_iso_offset,
+ { "ISO Data offset", "usb.win32.iso_offset",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_usb_win32_iso_length,
+ { "ISO Data length", "usb.win32.iso_data_len",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_usb_win32_iso_status,
+ { "ISO USBD status", "usb.win32.iso_status",
+ FT_UINT32, BASE_HEX, VALS(win32_usbd_status_vals), 0x0,
+ NULL, HFILL }},
+
+
{ &hf_usb_bmRequestType,
{ "bmRequestType", "usb.bmRequestType",
FT_UINT8, BASE_HEX, NULL, 0x0,
@@ -3438,8 +3921,10 @@ proto_register_usb(void)
&usb_hdr,
&usb_setup_hdr,
&usb_isodesc,
+ &usb_win32_iso_packet,
&ett_usb_endpoint,
&ett_usb_setup_bmrequesttype,
+ &ett_usb_usbpcap_info,
&ett_descriptor_device,
&ett_configuration_bmAttributes,
&ett_configuration_bEndpointAddress,
@@ -3485,11 +3970,14 @@ proto_reg_handoff_usb(void)
{
dissector_handle_t linux_usb_handle;
dissector_handle_t linux_usb_mmapped_handle;
+ dissector_handle_t win32_usb_handle;
linux_usb_handle = create_dissector_handle(dissect_linux_usb, proto_usb);
linux_usb_mmapped_handle = create_dissector_handle(dissect_linux_usb_mmapped,
proto_usb);
+ win32_usb_handle = create_dissector_handle(dissect_win32_usb, proto_usb);
dissector_add_uint("wtap_encap", WTAP_ENCAP_USB_LINUX, linux_usb_handle);
dissector_add_uint("wtap_encap", WTAP_ENCAP_USB_LINUX_MMAPPED, linux_usb_mmapped_handle);
+ dissector_add_uint("wtap_encap", WTAP_ENCAP_USBPCAP, win32_usb_handle);
}
diff --git a/wiretap/pcap-common.c b/wiretap/pcap-common.c
index 435d4f561a..682c822a58 100644
--- a/wiretap/pcap-common.c
+++ b/wiretap/pcap-common.c
@@ -395,6 +395,8 @@ static const struct {
{ 245, WTAP_ENCAP_NFC_LLCP },
/* SCTP */
{ 248, WTAP_ENCAP_SCTP},
+ /* USBPcap */
+ { 249, WTAP_ENCAP_USBPCAP},
/*
* To repeat:
diff --git a/wiretap/wtap.c b/wiretap/wtap.c
index f9934fece0..198e6f77ce 100644
--- a/wiretap/wtap.c
+++ b/wiretap/wtap.c
@@ -599,6 +599,15 @@ static struct encap_type_info encap_table_base[] = {
/* WTAP_ENCAP_SCTP */
{ "SCTP", "sctp" },
+
+ /* WTAP_ENCAP_INFINIBAND */
+ { "InfiniBand", "infiniband" },
+
+ /* WTAP_ENCAP_JUNIPER_SVCS */
+ { "Juniper Services", "juniper-svcs" },
+
+ /* WTAP_ENCAP_USBPCAP */
+ { "USB packets with USBPcap header", "usb-usbpcap" },
};
WS_DLL_LOCAL
diff --git a/wiretap/wtap.h b/wiretap/wtap.h
index a77094ad02..8baf366026 100644
--- a/wiretap/wtap.h
+++ b/wiretap/wtap.h
@@ -243,6 +243,7 @@ extern "C" {
#define WTAP_ENCAP_SCTP 150
#define WTAP_ENCAP_INFINIBAND 151
#define WTAP_ENCAP_JUNIPER_SVCS 152
+#define WTAP_ENCAP_USBPCAP 153
#define WTAP_NUM_ENCAP_TYPES wtap_get_num_encap_types()