aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPascal Quantin <pascal.quantin@gmail.com>2014-08-26 10:38:20 +0200
committerMartin Kaiser <wireshark@kaiser.cx>2014-08-26 13:50:29 +0000
commit8fee04ab512e957f3e5a1bc371fe4601eb8ba5a9 (patch)
treefff438d51f1e9a979b7cdda7e7acb59ffbb6aac8
parentff59722529bd3f9acbe6a234375dea59def2b48e (diff)
USB: fix dissection of non standard USB setup requests
Otherwise captures like the one found in bug 8161 do not dissect properly anymore (sub dissector is called twice) While we are at it, reorganize functions order to void a forward declaration Change-Id: Id02ef835ba24981902a1702f976db099fa07b0fd Reviewed-on: https://code.wireshark.org/review/3858 Reviewed-by: Martin Kaiser <wireshark@kaiser.cx>
-rw-r--r--epan/dissectors/packet-usb.c93
1 files changed, 43 insertions, 50 deletions
diff --git a/epan/dissectors/packet-usb.c b/epan/dissectors/packet-usb.c
index 05b2aeb731..f62eaf0ca6 100644
--- a/epan/dissectors/packet-usb.c
+++ b/epan/dissectors/packet-usb.c
@@ -2793,9 +2793,40 @@ dissect_usb_bmrequesttype(proto_tree *parent_tree, tvbuff_t *tvb, int offset, in
}
static int
-try_dissect_linux_usb_pseudo_header_ext(tvbuff_t *tvb, int offset,
+dissect_linux_usb_pseudo_header_ext(tvbuff_t *tvb, int offset,
packet_info *pinfo _U_,
- proto_tree *tree, guint8 header_info);
+ proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_usb_urb_interval, tvb, offset, 4, ENC_HOST_ENDIAN);
+ offset += 4;
+
+ proto_tree_add_item(tree, hf_usb_urb_start_frame, tvb, offset, 4, ENC_HOST_ENDIAN);
+ offset += 4;
+
+ proto_tree_add_item(tree, hf_usb_urb_copy_of_transfer_flags, tvb, offset, 4, ENC_HOST_ENDIAN);
+ offset += 4;
+
+ proto_tree_add_item(tree, hf_usb_iso_numdesc, tvb, offset, 4, ENC_HOST_ENDIAN);
+ offset += 4;
+
+ return offset;
+}
+
+static int
+try_dissect_linux_usb_pseudo_header_ext(tvbuff_t *tvb, int offset,
+ packet_info *pinfo,
+ proto_tree *tree, guint8 header_info)
+{
+ /*
+ * If this has a 64-byte header, process the extra 16 bytes of
+ * pseudo-header information.
+ */
+ 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);
+ }
+ return offset;
+}
static int
dissect_nonstandard_usb_setup_request(packet_info *pinfo, proto_tree *tree, proto_tree *parent,
@@ -2803,12 +2834,12 @@ dissect_nonstandard_usb_setup_request(packet_info *pinfo, proto_tree *tree, prot
usb_conv_info_t *usb_conv_info, guint8 urb_type,
guint8 header_info)
{
- tvbuff_t *setup_tvb = tvb_new_composite();
- tvbuff_t *next_tvb = tvb_new_subset_length(tvb, offset - 7, 7);
-
+ tvbuff_t *next_tvb;
if (header_info & (USB_HEADER_IS_LINUX | USB_HEADER_IS_64_BYTES)) {
+ tvbuff_t *setup_tvb = tvb_new_composite();
+ next_tvb = tvb_new_subset_length(tvb, offset - 7, 7);
tvb_composite_append(setup_tvb, next_tvb);
offset = try_dissect_linux_usb_pseudo_header_ext(tvb, offset, pinfo, tree, header_info);
@@ -2822,13 +2853,12 @@ dissect_nonstandard_usb_setup_request(packet_info *pinfo, proto_tree *tree, prot
add_new_data_source(pinfo, next_tvb, "Linux USB Control");
proto_tree_add_item(*setup_tree, hf_usb_data_fragment, tvb, offset, -1, ENC_NA);
- }
- else
+ } else {
tvb_composite_finalize(setup_tvb);
-
+ }
} else {
- next_tvb = tvb_new_subset_remaining(tvb, offset - 7);
offset = try_dissect_linux_usb_pseudo_header_ext(tvb, offset, pinfo, tree, header_info);
+ next_tvb = tvb_new_subset_remaining(tvb, offset - 7);
}
offset = try_dissect_next_protocol(tree, parent, next_tvb, offset, pinfo, usb_conv_info, urb_type);
@@ -2891,11 +2921,11 @@ dissect_usb_setup_request(packet_info *pinfo, proto_tree *tree,
}
if (req_type != RQT_SETUP_TYPE_STANDARD) {
- dissect_nonstandard_usb_setup_request(pinfo, tree, parent, &setup_tree, tvb, offset,
- usb_conv_info, urb_type, header_info);
- } else
+ offset = dissect_nonstandard_usb_setup_request(pinfo, tree, parent, &setup_tree, tvb, offset,
+ usb_conv_info, urb_type, header_info);
+ } else {
offset = try_dissect_linux_usb_pseudo_header_ext(tvb, offset, pinfo, tree, header_info);
-
+ }
return offset;
}
@@ -2979,43 +3009,6 @@ dissect_linux_usb_pseudo_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
return 40;
}
-static int
-dissect_linux_usb_pseudo_header_ext(tvbuff_t *tvb, int offset,
- packet_info *pinfo _U_,
- proto_tree *tree)
-{
- proto_tree_add_item(tree, hf_usb_urb_interval, tvb, offset, 4, ENC_HOST_ENDIAN);
- offset += 4;
-
- proto_tree_add_item(tree, hf_usb_urb_start_frame, tvb, offset, 4, ENC_HOST_ENDIAN);
- offset += 4;
-
- proto_tree_add_item(tree, hf_usb_urb_copy_of_transfer_flags, tvb, offset, 4, ENC_HOST_ENDIAN);
- offset += 4;
-
- proto_tree_add_item(tree, hf_usb_iso_numdesc, tvb, offset, 4, ENC_HOST_ENDIAN);
- offset += 4;
-
- return offset;
-}
-
-static int
-try_dissect_linux_usb_pseudo_header_ext(tvbuff_t *tvb, int offset,
- packet_info *pinfo _U_,
- proto_tree *tree, guint8 header_info)
-{
- /*
- * If this has a 64-byte header, process the extra 16 bytes of
- * pseudo-header information.
- */
- 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);
- }
- return offset;
-}
-
-
/* dissect the usbpcap_buffer_packet_header and fill the conversation struct
this function does not handle the transfer-specific headers
return the number of bytes processed */