aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPascal Quantin <pascal.quantin@gmail.com>2015-03-21 16:42:08 +0100
committerPascal Quantin <pascal.quantin@gmail.com>2015-03-26 19:10:24 +0000
commit55de704f8242f30fc2c412d6cd3e83c43f4e80ec (patch)
tree470af08e673c2a08d7366873a36d7e66b4b3ce6c
parent91addef79cf6031cd19aecaafe10517d0f729261 (diff)
USB: use URB/IRP ID for request/response tracking
Bug: 11072 Change-Id: I5f1824d602e4b88c9c5c8520b0aac9945206f093 Reviewed-on: https://code.wireshark.org/review/7781 Petri-Dish: Pascal Quantin <pascal.quantin@gmail.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Pascal Quantin <pascal.quantin@gmail.com>
-rw-r--r--epan/dissectors/packet-mausb.c27
-rw-r--r--epan/dissectors/packet-usb.c49
-rw-r--r--epan/dissectors/packet-usb.h4
3 files changed, 51 insertions, 29 deletions
diff --git a/epan/dissectors/packet-mausb.c b/epan/dissectors/packet-mausb.c
index d7e1d2becc..dff03da2a7 100644
--- a/epan/dissectors/packet-mausb.c
+++ b/epan/dissectors/packet-mausb.c
@@ -1448,20 +1448,6 @@ dissect_mausb_pkt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
mausb_is_data_pkt(&header),
mausb_is_from_host(&header));
- /* If there is a usb conversation, find it */
- if (mausb_is_data_pkt(&header) & !(mausb_is_transfer_ack(&header))) {
-
- usb_conv_info = get_usb_conv_info(conversation);
-
- /* TODO: set all the usb_conv_info values */
- usb_conv_info->is_request = mausb_is_transfer_req(&header);
-
- usb_trans_info = usb_get_trans_info(tvb, pinfo, tree,
- USB_HEADER_MAUSB, usb_conv_info);
- usb_conv_info->usb_trans_info = usb_trans_info;
- }
-
-
if (mausb_is_mgmt_pkt(&header)) {
proto_tree_add_item(mausb_tree, hf_mausb_dev_handle, tvb,
@@ -1619,6 +1605,19 @@ dissect_mausb_pkt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
offset += 4;
}
+ /* If there is a usb conversation, find it */
+ if (!(mausb_is_transfer_ack(&header))) {
+
+ usb_conv_info = get_usb_conv_info(conversation);
+
+ /* TODO: set all the usb_conv_info values */
+ usb_conv_info->is_request = mausb_is_transfer_req(&header);
+
+ usb_trans_info = usb_get_trans_info(tvb, pinfo, tree, USB_HEADER_MAUSB,
+ usb_conv_info, header.u.s.req_id);
+ usb_conv_info->usb_trans_info = usb_trans_info;
+ }
+
/* If this packet contains USB Setup Data */
if (mausb_has_setup_data(&header)) {
offset = dissect_usb_setup_request(pinfo, mausb_tree, tvb, offset,
diff --git a/epan/dissectors/packet-usb.c b/epan/dissectors/packet-usb.c
index 3b734cbee8..25db658802 100644
--- a/epan/dissectors/packet-usb.c
+++ b/epan/dissectors/packet-usb.c
@@ -3060,7 +3060,7 @@ dissect_usb_setup_request(packet_info *pinfo, proto_tree *tree,
return the number of dissected bytes */
static gint
dissect_linux_usb_pseudo_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
- usb_conv_info_t *usb_conv_info)
+ usb_conv_info_t *usb_conv_info, guint64 *urb_id)
{
guint8 transfer_type;
guint8 endpoint_byte;
@@ -3068,7 +3068,8 @@ dissect_linux_usb_pseudo_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
guint8 urb_type;
guint8 flag[2];
- proto_tree_add_item(tree, hf_usb_urb_id, tvb, 0, 8, ENC_HOST_ENDIAN);
+ *urb_id = tvb_get_guint64(tvb, 0, ENC_HOST_ENDIAN);
+ proto_tree_add_uint64(tree, hf_usb_urb_id, tvb, 0, 8, *urb_id);
/* show the urb type of this URB as string and as a character */
urb_type = tvb_get_guint8(tvb, 8);
@@ -3139,7 +3140,7 @@ dissect_linux_usb_pseudo_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
return the number of bytes processed */
static gint
dissect_usbpcap_buffer_packet_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
- usb_conv_info_t *usb_conv_info, guint32 *win32_data_len)
+ usb_conv_info_t *usb_conv_info, guint32 *win32_data_len, guint64 *irp_id)
{
guint8 transfer_type;
guint8 endpoint_byte;
@@ -3147,7 +3148,8 @@ dissect_usbpcap_buffer_packet_header(tvbuff_t *tvb, packet_info *pinfo, proto_tr
guint8 tmp_val8;
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);
+ *irp_id = tvb_get_guint64(tvb, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_uint64(tree, hf_usb_irp_id, tvb, 2, 8, *irp_id);
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);
@@ -3249,25 +3251,34 @@ usb_set_addr(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, guint16 bus_id
* Also adds request/response info to the tree for the given packet */
usb_trans_info_t
*usb_get_trans_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
- usb_header_t header_type, usb_conv_info_t *usb_conv_info)
+ usb_header_t header_type, usb_conv_info_t *usb_conv_info, guint64 usb_id)
{
usb_trans_info_t *usb_trans_info;
proto_item *ti;
nstime_t t, deltat;
+ wmem_tree_key_t key[3];
/* request/response matching so we can keep track of transaction specific
* data.
*/
+ key[0].length = 2;
+ key[0].key = (guint32 *)&usb_id;
+ key[1].length = 1;
+ key[1].key = &PINFO_FD_NUM(pinfo);
+ key[2].length = 0;
+ key[2].key = NULL;
+
if (usb_conv_info->is_request) {
/* this is a request */
- usb_trans_info = (usb_trans_info_t *)wmem_tree_lookup32(usb_conv_info->transactions, pinfo->fd->num);
+ usb_trans_info = (usb_trans_info_t *)wmem_tree_lookup32_array(usb_conv_info->transactions, key);
if (!usb_trans_info) {
usb_trans_info = wmem_new0(wmem_file_scope(), 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_type = header_type;
+ usb_trans_info->usb_id = usb_id;
- wmem_tree_insert32(usb_conv_info->transactions, pinfo->fd->num, usb_trans_info);
+ wmem_tree_insert32_array(usb_conv_info->transactions, key, usb_trans_info);
}
if (usb_trans_info->response_in) {
@@ -3278,13 +3289,20 @@ usb_trans_info_t
} else {
/* this is a response */
if (pinfo->fd->flags.visited) {
- usb_trans_info = (usb_trans_info_t *)wmem_tree_lookup32(usb_conv_info->transactions, pinfo->fd->num);
+ usb_trans_info = (usb_trans_info_t *)wmem_tree_lookup32_array(usb_conv_info->transactions, key);
} else {
- usb_trans_info = (usb_trans_info_t *)wmem_tree_lookup32_le(usb_conv_info->transactions, pinfo->fd->num);
+ usb_trans_info = (usb_trans_info_t *)wmem_tree_lookup32_array_le(usb_conv_info->transactions, key);
if (usb_trans_info) {
- usb_trans_info->response_in = pinfo->fd->num;
- wmem_tree_insert32(usb_conv_info->transactions, pinfo->fd->num, usb_trans_info);
+ if (usb_trans_info->usb_id == usb_id) {
+ if (usb_trans_info->response_in == 0) {
+ /* USBPcap generates 2 frames for response; store the first one */
+ usb_trans_info->response_in = pinfo->fd->num;
+ }
+ wmem_tree_insert32_array(usb_conv_info->transactions, key, usb_trans_info);
+ } else {
+ usb_trans_info = NULL;
+ }
}
}
@@ -3526,6 +3544,7 @@ dissect_usb_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent,
guint32 k_device_address;
guint32 k_bus_id;
guint8 usbpcap_control_stage = 0;
+ guint64 usb_id;
/* the goal is to get the conversation struct as early as possible
@@ -3573,21 +3592,23 @@ dissect_usb_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent,
case USB_HEADER_LINUX_48_BYTES:
case USB_HEADER_LINUX_64_BYTES:
proto_item_set_len(urb_tree_ti, (header_type == USB_HEADER_LINUX_64_BYTES) ? 64 : 48);
- offset = dissect_linux_usb_pseudo_header(tvb, pinfo, tree, usb_conv_info);
+ offset = dissect_linux_usb_pseudo_header(tvb, pinfo, tree, usb_conv_info, &usb_id);
break;
case USB_HEADER_USBPCAP:
- offset = dissect_usbpcap_buffer_packet_header(tvb, pinfo, tree, usb_conv_info, &win32_data_len);
+ offset = dissect_usbpcap_buffer_packet_header(tvb, pinfo, tree, usb_conv_info, &win32_data_len, &usb_id);
/* the length that we're setting here might have to be corrected
if there's a transfer-specific pseudo-header following */
proto_item_set_len(urb_tree_ti, offset);
break;
case USB_HEADER_MAUSB:
+ default:
+ usb_id = 0;
break;
}
- usb_conv_info->usb_trans_info = usb_get_trans_info(tvb, pinfo, tree, header_type, usb_conv_info);
+ usb_conv_info->usb_trans_info = usb_get_trans_info(tvb, pinfo, tree, header_type, usb_conv_info, usb_id);
if (usb_conv_info->transfer_type != URB_CONTROL) {
usb_tap_queue_packet(pinfo, urb_type, usb_conv_info);
diff --git a/epan/dissectors/packet-usb.h b/epan/dissectors/packet-usb.h
index e4246cbe5f..d84a7c2138 100644
--- a/epan/dissectors/packet-usb.h
+++ b/epan/dissectors/packet-usb.h
@@ -85,6 +85,8 @@ typedef struct _usb_trans_info_t {
* Valid only during GET CONFIGURATION response.
*/
usb_conv_info_t *interface_info;
+
+ guint64 usb_id;
} usb_trans_info_t;
/* Conversation Structure
@@ -267,7 +269,7 @@ usb_set_addr(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, guint16 bus_id
usb_trans_info_t
*usb_get_trans_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
- usb_header_t header_type, usb_conv_info_t *usb_conv_info);
+ usb_header_t header_type, usb_conv_info_t *usb_conv_info, guint64 usb_id);
#endif