2 * Routines for USB HUB dissection
3 * Copyright 2009, Marton Nemeth <nm127@freemail.hu>
7 * USB HUB Specification can be found in the Universal Serial Bus
8 * Specification 2.0, Chapter 11 Hub Specification.
9 * http://www.usb.org/developers/docs/usb_20_052709.zip
11 * Wireshark - Network traffic analyzer
12 * By Gerald Combs <gerald@wireshark.org>
13 * Copyright 1998 Gerald Combs
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License along
26 * with this program; if not, write to the Free Software Foundation, Inc.,
27 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
35 #include <epan/packet.h>
36 #include "packet-usb.h"
38 /* protocols and header fields */
39 static int proto_usb_hub = -1;
41 /* USB 2.0, Chapter 11.24.2 Class-Specific Requests */
42 static int hf_usb_hub_request = -1;
43 static int hf_usb_hub_value = -1;
44 static int hf_usb_hub_index = -1;
45 static int hf_usb_hub_length = -1;
47 static int hf_usb_hub_hub_feature_selector = -1;
48 static int hf_usb_hub_port_feature_selector = -1;
49 static int hf_usb_hub_dev_addr = -1;
50 static int hf_usb_hub_ep_num = -1;
51 static int hf_usb_hub_descriptor_type = -1;
52 static int hf_usb_hub_descriptor_index = -1;
53 static int hf_usb_hub_zero = -1;
54 static int hf_usb_hub_tt_flags = -1;
55 static int hf_usb_hub_tt_port = -1;
56 static int hf_usb_hub_tt_state_length = -1;
57 static int hf_usb_hub_port = -1;
58 static int hf_usb_hub_port_selector = -1;
59 static int hf_usb_hub_descriptor_length = -1;
61 static gint ett_usb_hub_wValue = -1;
62 static gint ett_usb_hub_wIndex = -1;
63 static gint ett_usb_hub_wLength = -1;
65 /* Table 11-16. Hub Class Request Codes */
66 #define USB_HUB_REQUEST_GET_STATUS 0
67 #define USB_HUB_REQUEST_CLEAR_FEATURE 1
68 #define USB_HUB_REQUEST_SET_FEATURE 3
69 #define USB_HUB_REQUEST_GET_DESCRIPTOR 6
70 #define USB_HUB_REQUEST_SET_DESCRIPTOR 7
71 #define USB_HUB_REQUEST_CLEAR_TT_BUFFER 8
72 #define USB_HUB_REQUEST_RESET_TT 9
73 #define USB_HUB_REQUEST_GET_TT_STATE 10
74 #define USB_HUB_REQUEST_STOP_TT 11
76 static const value_string setup_request_names_vals[] = {
77 { USB_HUB_REQUEST_GET_STATUS, "GET_STATUS" },
78 { USB_HUB_REQUEST_CLEAR_FEATURE, "CLEAR_FEATURE" },
79 { USB_HUB_REQUEST_SET_FEATURE, "SET_FEATURE" },
80 { USB_HUB_REQUEST_GET_DESCRIPTOR, "GET_DESCRIPTOR" },
81 { USB_HUB_REQUEST_SET_DESCRIPTOR, "SET_DESCRIPTOR" },
82 { USB_HUB_REQUEST_CLEAR_TT_BUFFER, "CLEAR_TT_BUFFER" },
83 { USB_HUB_REQUEST_GET_TT_STATE, "GET_TT_STATE" },
84 { USB_HUB_REQUEST_STOP_TT, "STOP_TT" },
89 /* Table 11-17 Hub Class Feature Selectors */
90 #define USB_HUB_FEATURE_C_HUB_LOCAL_POWER 0
91 #define USB_HUB_FEATURE_C_HUB_OVER_CURRENT 1
93 #define USB_HUB_FEATURE_PORT_CONNECTION 0
94 #define USB_HUB_FEATURE_PORT_ENABLE 1
95 #define USB_HUB_FEATURE_PORT_SUSPEND 2
96 #define USB_HUB_FEATURE_PORT_OVER_CURRENT 3
97 #define USB_HUB_FEATURE_PORT_RESET 4
98 #define USB_HUB_FEATURE_PORT_POWER 8
99 #define USB_HUB_FEATURE_PORT_LOW_SPEED 9
100 #define USB_HUB_FEATURE_C_PORT_CONNECTION 16
101 #define USB_HUB_FEATURE_C_PORT_ENABLE 17
102 #define USB_HUB_FEATURE_C_PORT_SUSPEND 18
103 #define USB_HUB_FEATURE_C_PORT_OVER_CURRENT 19
104 #define USB_HUB_FEATURE_C_PORT_RESET 20
105 #define USB_HUB_FEATURE_PORT_TEST 21
106 #define USB_HUB_FEATURE_PORT_INDICATOR 22
108 static const value_string hub_class_feature_selectors_recipient_hub_vals[] = {
109 { USB_HUB_FEATURE_C_HUB_LOCAL_POWER, "C_HUB_LOCAL_POWER" },
110 { USB_HUB_FEATURE_C_HUB_OVER_CURRENT, "C_HUB_OVER_CURRENT" },
114 static const value_string hub_class_feature_selectors_recipient_port_vals[] = {
115 { USB_HUB_FEATURE_PORT_CONNECTION, "PORT_CONNECTION" },
116 { USB_HUB_FEATURE_PORT_ENABLE, "PORT_ENABLE" },
117 { USB_HUB_FEATURE_PORT_SUSPEND, "PORT_SUSPEND" },
118 { USB_HUB_FEATURE_PORT_OVER_CURRENT, "PORT_OVER_CURRENT" },
119 { USB_HUB_FEATURE_PORT_RESET, "PORT_RESET" },
120 { USB_HUB_FEATURE_PORT_POWER, "PORT_POWER" },
121 { USB_HUB_FEATURE_PORT_LOW_SPEED, "PORT_LOW_SPEED" },
122 { USB_HUB_FEATURE_C_PORT_CONNECTION, "C_PORT_CONNECTION" },
123 { USB_HUB_FEATURE_C_PORT_ENABLE, "C_PORT_ENABLE" },
124 { USB_HUB_FEATURE_C_PORT_SUSPEND, "C_PORT_SUSPEND" },
125 { USB_HUB_FEATURE_C_PORT_OVER_CURRENT, "C_PORT_OVER_CURRENT" },
126 { USB_HUB_FEATURE_C_PORT_RESET, "C_PORT_RESET" },
127 { USB_HUB_FEATURE_PORT_TEST, "PORT_TEST" },
128 { USB_HUB_FEATURE_PORT_INDICATOR, "PORT_INDICATOR" },
133 /* Dissector for ClearHubFeature, Chapter 11.24.2.1 Clear Hub Feature */
135 dissect_usb_hub_clear_hub_feature(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, gboolean is_request, usb_trans_info_t *usb_trans_info _U_, usb_conv_info_t *usb_conv_info _U_)
137 proto_item *item = NULL;
138 proto_tree *subtree = NULL;
141 item = proto_tree_add_item(tree, hf_usb_hub_value, tvb, offset, 2, TRUE);
142 subtree = proto_item_add_subtree(item, ett_usb_hub_wValue);
143 proto_tree_add_item(subtree, hf_usb_hub_hub_feature_selector, tvb, offset, 2, TRUE);
146 item = proto_tree_add_item(tree, hf_usb_hub_index, tvb, offset, 2, TRUE);
147 subtree = proto_item_add_subtree(item, ett_usb_hub_wIndex);
148 proto_tree_add_item(subtree, hf_usb_hub_zero, tvb, offset, 2, TRUE);
151 item = proto_tree_add_item(tree, hf_usb_hub_length, tvb, offset, 2, TRUE);
152 subtree = proto_item_add_subtree(item, ett_usb_hub_wLength);
153 proto_tree_add_item(subtree, hf_usb_hub_zero, tvb, offset, 2, TRUE);
159 /* Dissector for ClearPortFeature, Chapter 11.24.2.2 Clear Port Feature */
161 dissect_usb_hub_clear_port_feature(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, gboolean is_request, usb_trans_info_t *usb_trans_info _U_, usb_conv_info_t *usb_conv_info _U_)
163 proto_item *item = NULL;
164 proto_tree *subtree = NULL;
167 item = proto_tree_add_item(tree, hf_usb_hub_value, tvb, offset, 2, TRUE);
168 subtree = proto_item_add_subtree(item, ett_usb_hub_wValue);
169 proto_tree_add_item(subtree, hf_usb_hub_port_feature_selector, tvb, offset, 2, TRUE);
172 item = proto_tree_add_item(tree, hf_usb_hub_index, tvb, offset, 2, TRUE);
173 subtree = proto_item_add_subtree(item, ett_usb_hub_wIndex);
174 proto_tree_add_item(subtree, hf_usb_hub_port, tvb, offset, 1, TRUE);
176 proto_tree_add_item(subtree, hf_usb_hub_port_selector, tvb, offset, 1, TRUE);
179 item = proto_tree_add_item(tree, hf_usb_hub_length, tvb, offset, 2, TRUE);
180 subtree = proto_item_add_subtree(item, ett_usb_hub_wLength);
181 proto_tree_add_item(subtree, hf_usb_hub_zero, tvb, offset, 2, TRUE);
187 /* Dissector for ClearTTBuffer, Chapter 11.24.2.3 Clear TT Buffer */
189 dissect_usb_hub_clear_tt_buffer(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, gboolean is_request, usb_trans_info_t *usb_trans_info _U_, usb_conv_info_t *usb_conv_info _U_)
191 proto_item *item = NULL;
192 proto_tree *subtree = NULL;
195 item = proto_tree_add_item(tree, hf_usb_hub_value, tvb, offset, 2, TRUE);
196 subtree = proto_item_add_subtree(item, ett_usb_hub_wValue);
197 proto_tree_add_item(subtree, hf_usb_hub_ep_num, tvb, offset, 1, TRUE);
199 proto_tree_add_item(subtree, hf_usb_hub_dev_addr, tvb, offset, 1, TRUE);
202 proto_tree_add_item(tree, hf_usb_hub_index, tvb, offset, 2, TRUE);
203 subtree = proto_item_add_subtree(item, ett_usb_hub_wIndex);
204 proto_tree_add_item(subtree, hf_usb_hub_tt_port, tvb, offset, 2, TRUE);
207 proto_tree_add_item(tree, hf_usb_hub_length, tvb, offset, 2, TRUE);
208 subtree = proto_item_add_subtree(item, ett_usb_hub_wLength);
209 proto_tree_add_item(subtree, hf_usb_hub_zero, tvb, offset, 2, TRUE);
215 /* Dissector for GetHubDescriptor, Chapter 11.24.2.5 Get Hub Descriptor */
217 dissect_usb_hub_get_hub_descriptor(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, gboolean is_request, usb_trans_info_t *usb_trans_info _U_, usb_conv_info_t *usb_conv_info _U_)
219 proto_item *item = NULL;
220 proto_tree *subtree = NULL;
223 item = proto_tree_add_item(tree, hf_usb_hub_value, tvb, offset, 2, TRUE);
224 subtree = proto_item_add_subtree(item, ett_usb_hub_wValue);
225 proto_tree_add_item(subtree, hf_usb_hub_descriptor_index, tvb, offset, 1, TRUE);
227 proto_tree_add_item(subtree, hf_usb_hub_descriptor_type, tvb, offset, 1, TRUE);
230 item = proto_tree_add_item(tree, hf_usb_hub_index, tvb, offset, 2, TRUE);
231 subtree = proto_item_add_subtree(item, ett_usb_hub_wIndex);
232 proto_tree_add_item(subtree, hf_usb_hub_zero, tvb, offset, 2, TRUE);
235 item = proto_tree_add_item(tree, hf_usb_hub_length, tvb, offset, 2, TRUE);
236 subtree = proto_item_add_subtree(item, ett_usb_hub_wLength);
237 proto_tree_add_item(subtree, hf_usb_hub_descriptor_length, tvb, offset, 2, TRUE);
243 /* Dissector for GetHubStatus, Chapter 11.24.2.6 Get Hub Status */
245 dissect_usb_hub_get_hub_status(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, gboolean is_request, usb_trans_info_t *usb_trans_info _U_, usb_conv_info_t *usb_conv_info _U_)
247 proto_item *item = NULL;
248 proto_tree *subtree = NULL;
251 item = proto_tree_add_item(tree, hf_usb_hub_value, tvb, offset, 2, TRUE);
252 subtree = proto_item_add_subtree(item, ett_usb_hub_wValue);
253 proto_tree_add_item(subtree, hf_usb_hub_zero, tvb, offset, 2, TRUE);
256 item = proto_tree_add_item(tree, hf_usb_hub_index, tvb, offset, 2, TRUE);
257 subtree = proto_item_add_subtree(item, ett_usb_hub_wIndex);
258 proto_tree_add_item(subtree, hf_usb_hub_zero, tvb, offset, 2, TRUE);
261 proto_tree_add_item(tree, hf_usb_hub_length, tvb, offset, 2, TRUE);
262 /* length shall always contain 4 */
268 /* Dissector for GetPortStatus, Chapter 11.24.2.7 Get Port Status */
270 dissect_usb_hub_get_port_status(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, gboolean is_request, usb_trans_info_t *usb_trans_info _U_, usb_conv_info_t *usb_conv_info _U_)
272 proto_item *item = NULL;
273 proto_tree *subtree = NULL;
276 item = proto_tree_add_item(tree, hf_usb_hub_value, tvb, offset, 2, TRUE);
277 subtree = proto_item_add_subtree(item, ett_usb_hub_wValue);
278 proto_tree_add_item(subtree, hf_usb_hub_zero, tvb, offset, 2, TRUE);
281 item = proto_tree_add_item(tree, hf_usb_hub_index, tvb, offset, 2, TRUE);
282 subtree = proto_item_add_subtree(item, ett_usb_hub_wIndex);
283 proto_tree_add_item(subtree, hf_usb_hub_port, tvb, offset, 2, TRUE);
286 proto_tree_add_item(tree, hf_usb_hub_length, tvb, offset, 2, TRUE);
287 /* length shall always contain 4 */
293 /* Dissector for GetTTState, Chapter 11.24.2.8 Get_TT_State */
295 dissect_usb_hub_get_tt_state(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, gboolean is_request, usb_trans_info_t *usb_trans_info _U_, usb_conv_info_t *usb_conv_info _U_)
297 proto_item *item = NULL;
298 proto_tree *subtree = NULL;
301 item = proto_tree_add_item(tree, hf_usb_hub_value, tvb, offset, 2, TRUE);
302 subtree = proto_item_add_subtree(item, ett_usb_hub_wValue);
303 proto_tree_add_item(subtree, hf_usb_hub_tt_flags, tvb, offset, 1, TRUE);
306 item = proto_tree_add_item(tree, hf_usb_hub_index, tvb, offset, 2, TRUE);
307 subtree = proto_item_add_subtree(item, ett_usb_hub_wIndex);
308 proto_tree_add_item(subtree, hf_usb_hub_tt_port, tvb, offset, 1, TRUE);
311 item = proto_tree_add_item(tree, hf_usb_hub_length, tvb, offset, 2, TRUE);
312 subtree = proto_item_add_subtree(item, ett_usb_hub_wLength);
313 proto_tree_add_item(subtree, hf_usb_hub_tt_state_length, tvb, offset, 1, TRUE);
319 /* Dissector for ResetTT, Chapter 11.24.2.9 Reset_TT */
321 dissect_usb_hub_reset_tt(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, gboolean is_request, usb_trans_info_t *usb_trans_info _U_, usb_conv_info_t *usb_conv_info _U_)
323 proto_item *item = NULL;
324 proto_tree *subtree = NULL;
327 item = proto_tree_add_item(tree, hf_usb_hub_value, tvb, offset, 2, TRUE);
328 subtree = proto_item_add_subtree(item, ett_usb_hub_wValue);
329 proto_tree_add_item(subtree, hf_usb_hub_zero, tvb, offset, 1, TRUE);
332 item = proto_tree_add_item(tree, hf_usb_hub_index, tvb, offset, 2, TRUE);
333 subtree = proto_item_add_subtree(item, ett_usb_hub_wIndex);
334 proto_tree_add_item(subtree, hf_usb_hub_tt_port, tvb, offset, 1, TRUE);
337 item = proto_tree_add_item(tree, hf_usb_hub_length, tvb, offset, 2, TRUE);
338 subtree = proto_item_add_subtree(item, ett_usb_hub_wLength);
339 proto_tree_add_item(subtree, hf_usb_hub_zero, tvb, offset, 1, TRUE);
345 /* Dissector for SetHubDescriptor, Chapter 11.24.2.10 Set Hub Descriptor */
347 dissect_usb_hub_set_hub_descriptor(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, gboolean is_request, usb_trans_info_t *usb_trans_info _U_, usb_conv_info_t *usb_conv_info _U_)
349 proto_item *item = NULL;
350 proto_tree *subtree = NULL;
353 item = proto_tree_add_item(tree, hf_usb_hub_value, tvb, offset, 2, TRUE);
354 subtree = proto_item_add_subtree(item, ett_usb_hub_wValue);
355 proto_tree_add_item(subtree, hf_usb_hub_descriptor_index, tvb, offset, 1, TRUE);
357 proto_tree_add_item(subtree, hf_usb_hub_descriptor_type, tvb, offset, 1, TRUE);
360 item = proto_tree_add_item(tree, hf_usb_hub_index, tvb, offset, 2, TRUE);
361 subtree = proto_item_add_subtree(item, ett_usb_hub_wIndex);
362 proto_tree_add_item(subtree, hf_usb_hub_zero, tvb, offset, 2, TRUE);
365 item = proto_tree_add_item(tree, hf_usb_hub_length, tvb, offset, 2, TRUE);
366 subtree = proto_item_add_subtree(item, ett_usb_hub_wLength);
367 proto_tree_add_item(subtree, hf_usb_hub_descriptor_length, tvb, offset, 2, TRUE);
373 /* Dissector for StopTT, Chapter 11.24.2.11 Stop TT */
375 dissect_usb_hub_stop_tt(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, gboolean is_request, usb_trans_info_t *usb_trans_info _U_, usb_conv_info_t *usb_conv_info _U_)
377 proto_item *item = NULL;
378 proto_tree *subtree = NULL;
381 item = proto_tree_add_item(tree, hf_usb_hub_value, tvb, offset, 2, TRUE);
382 subtree = proto_item_add_subtree(item, ett_usb_hub_wValue);
383 proto_tree_add_item(subtree, hf_usb_hub_zero, tvb, offset, 1, TRUE);
386 item = proto_tree_add_item(tree, hf_usb_hub_index, tvb, offset, 2, TRUE);
387 subtree = proto_item_add_subtree(item, ett_usb_hub_wIndex);
388 proto_tree_add_item(subtree, hf_usb_hub_tt_port, tvb, offset, 2, TRUE);
391 item = proto_tree_add_item(tree, hf_usb_hub_length, tvb, offset, 2, TRUE);
392 subtree = proto_item_add_subtree(item, ett_usb_hub_wLength);
393 proto_tree_add_item(subtree, hf_usb_hub_zero, tvb, offset, 2, TRUE);
399 /* Dissector for SetHubFeature, Chapter 11.24.2.12 Set Hub Feature */
401 dissect_usb_hub_set_hub_feature(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, gboolean is_request, usb_trans_info_t *usb_trans_info _U_, usb_conv_info_t *usb_conv_info _U_)
403 proto_item *item = NULL;
404 proto_tree *subtree = NULL;
407 item = proto_tree_add_item(tree, hf_usb_hub_value, tvb, offset, 2, TRUE);
408 subtree = proto_item_add_subtree(item, ett_usb_hub_wValue);
409 proto_tree_add_item(subtree, hf_usb_hub_hub_feature_selector, tvb, offset, 2, TRUE);
412 item = proto_tree_add_item(tree, hf_usb_hub_index, tvb, offset, 2, TRUE);
413 subtree = proto_item_add_subtree(item, ett_usb_hub_wIndex);
414 proto_tree_add_item(subtree, hf_usb_hub_zero, tvb, offset, 2, TRUE);
417 item = proto_tree_add_item(tree, hf_usb_hub_length, tvb, offset, 2, TRUE);
418 subtree = proto_item_add_subtree(item, ett_usb_hub_wLength);
419 proto_tree_add_item(subtree, hf_usb_hub_zero, tvb, offset, 2, TRUE);
425 /* Dissector for SetPortFeature, Chapter 11.24.2.13 Set Port Feature */
427 dissect_usb_hub_set_port_feature(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, gboolean is_request, usb_trans_info_t *usb_trans_info _U_, usb_conv_info_t *usb_conv_info _U_)
429 proto_item *item = NULL;
430 proto_tree *subtree = NULL;
433 item = proto_tree_add_item(tree, hf_usb_hub_value, tvb, offset, 2, TRUE);
434 subtree = proto_item_add_subtree(item, ett_usb_hub_wValue);
435 proto_tree_add_item(subtree, hf_usb_hub_port_feature_selector, tvb, offset, 2, TRUE);
438 item = proto_tree_add_item(tree, hf_usb_hub_index, tvb, offset, 2, TRUE);
439 subtree = proto_item_add_subtree(item, ett_usb_hub_wValue);
440 proto_tree_add_item(subtree, hf_usb_hub_port, tvb, offset, 1, TRUE);
442 proto_tree_add_item(subtree, hf_usb_hub_port_selector, tvb, offset, 1, TRUE);
445 item = proto_tree_add_item(tree, hf_usb_hub_length, tvb, offset, 2, TRUE);
446 subtree = proto_item_add_subtree(item, ett_usb_hub_wLength);
447 proto_tree_add_item(subtree, hf_usb_hub_zero, tvb, offset, 2, TRUE);
454 typedef void (*usb_setup_dissector)(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, gboolean is_request, usb_trans_info_t *usb_trans_info, usb_conv_info_t *usb_conv_info);
456 typedef struct _usb_setup_dissector_table_t {
459 usb_setup_dissector dissector;
460 } usb_setup_dissector_table_t;
463 /* USB 2.0, Table 11-15 Hub Class Requests */
464 static const usb_setup_dissector_table_t setup_dissectors[] = {
465 { USB_DIR_OUT | (RQT_SETUP_TYPE_CLASS << 5) | RQT_SETUP_RECIPIENT_DEVICE,
466 USB_HUB_REQUEST_CLEAR_FEATURE,
467 dissect_usb_hub_clear_hub_feature
470 { USB_DIR_OUT | (RQT_SETUP_TYPE_CLASS << 5) | RQT_SETUP_RECIPIENT_OTHER,
471 USB_HUB_REQUEST_CLEAR_FEATURE,
472 dissect_usb_hub_clear_port_feature
475 { USB_DIR_OUT | (RQT_SETUP_TYPE_CLASS << 5) | RQT_SETUP_RECIPIENT_OTHER,
476 USB_HUB_REQUEST_CLEAR_TT_BUFFER,
477 dissect_usb_hub_clear_tt_buffer
480 { USB_DIR_IN | (RQT_SETUP_TYPE_CLASS << 5) | RQT_SETUP_RECIPIENT_DEVICE,
481 USB_HUB_REQUEST_GET_DESCRIPTOR,
482 dissect_usb_hub_get_hub_descriptor
485 { USB_DIR_IN | (RQT_SETUP_TYPE_CLASS << 5) | RQT_SETUP_RECIPIENT_DEVICE,
486 USB_HUB_REQUEST_GET_STATUS,
487 dissect_usb_hub_get_hub_status
490 { USB_DIR_IN | (RQT_SETUP_TYPE_CLASS << 5) | RQT_SETUP_RECIPIENT_OTHER,
491 USB_HUB_REQUEST_GET_STATUS,
492 dissect_usb_hub_get_port_status
495 { USB_DIR_OUT | (RQT_SETUP_TYPE_CLASS << 5) | RQT_SETUP_RECIPIENT_OTHER,
496 USB_HUB_REQUEST_RESET_TT,
497 dissect_usb_hub_reset_tt
500 { USB_DIR_OUT | (RQT_SETUP_TYPE_CLASS << 5) | RQT_SETUP_RECIPIENT_DEVICE,
501 USB_HUB_REQUEST_SET_DESCRIPTOR,
502 dissect_usb_hub_set_hub_descriptor
505 { USB_DIR_OUT | (RQT_SETUP_TYPE_CLASS << 5) | RQT_SETUP_RECIPIENT_DEVICE,
506 USB_HUB_REQUEST_SET_FEATURE,
507 dissect_usb_hub_set_hub_feature
510 { USB_DIR_OUT | (RQT_SETUP_TYPE_CLASS << 5) | RQT_SETUP_RECIPIENT_OTHER,
511 USB_HUB_REQUEST_SET_FEATURE,
512 dissect_usb_hub_set_port_feature
515 { USB_DIR_IN | (RQT_SETUP_TYPE_CLASS << 5) | RQT_SETUP_RECIPIENT_OTHER,
516 USB_HUB_REQUEST_GET_TT_STATE,
517 dissect_usb_hub_get_tt_state
520 { USB_DIR_OUT | (RQT_SETUP_TYPE_CLASS << 5) | RQT_SETUP_RECIPIENT_OTHER,
521 USB_HUB_REQUEST_STOP_TT,
522 dissect_usb_hub_stop_tt
528 /* Dissector for USB HUB class-specific control request as defined in
529 * USB 2.0, Chapter 11.24.2 Class-specific Requests
530 * Returns TRUE if a class specific dissector was found
531 * and FALSE otherwise.
534 dissect_usb_hub_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
537 usb_conv_info_t *usb_conv_info;
538 usb_trans_info_t *usb_trans_info;
540 usb_setup_dissector dissector;
541 const usb_setup_dissector_table_t *tmp;
543 is_request = (pinfo->srcport==NO_ENDPOINT);
545 usb_conv_info = pinfo->usb_conv_info;
546 usb_trans_info = usb_conv_info->usb_trans_info;
548 /* See if we can find a class specific dissector for this request */
551 /* Check valid values for bmRequestType and bRequest */
552 for (tmp = setup_dissectors; tmp->dissector; tmp++) {
553 if (tmp->request_type == usb_trans_info->requesttype &&
554 tmp->request == usb_trans_info->request) {
555 dissector = tmp->dissector;
559 /* No, we could not find any class specific dissector for this request
560 * return FALSE and let USB try any of the standard requests.
566 col_set_str(pinfo->cinfo, COL_PROTOCOL, "USBHUB");
568 if (check_col(pinfo->cinfo, COL_INFO)) {
569 col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
570 val_to_str(usb_trans_info->request, setup_request_names_vals, "Unknown type %x"),
571 is_request ? "Request" : "Response");
575 proto_tree_add_item(tree, hf_usb_hub_request, tvb, offset, 1, TRUE);
579 dissector(pinfo, tree, tvb, offset, is_request, usb_trans_info, usb_conv_info);
584 proto_register_usb_hub(void)
586 static hf_register_info hf[] = {
587 /* USB HUB specific requests */
588 { &hf_usb_hub_request,
589 { "bRequest", "usbhub.setup.bRequest", FT_UINT8, BASE_HEX, VALS(setup_request_names_vals), 0x0,
593 { "wValue", "usbhub.setup.wValue", FT_UINT16, BASE_HEX, NULL, 0x0,
597 { "wIndex", "usbhub.setup.wIndex", FT_UINT16, BASE_DEC, NULL, 0x0,
600 { &hf_usb_hub_length,
601 { "wLength", "usbhub.setup.wLength", FT_UINT16, BASE_DEC, NULL, 0x0,
604 { &hf_usb_hub_hub_feature_selector,
605 { "HubFeatureSelector", "usbhub.setup.HubFeatureSelector", FT_UINT16, BASE_DEC,
606 VALS(hub_class_feature_selectors_recipient_hub_vals), 0x0,
609 { &hf_usb_hub_port_feature_selector,
610 { "PortFeatureSelector", "usbhub.setup.PortFeatureSelector", FT_UINT16, BASE_DEC,
611 VALS(hub_class_feature_selectors_recipient_port_vals), 0x0,
614 { &hf_usb_hub_dev_addr,
615 { "Dev_Addr", "usbhub.setup.Dev_Addr", FT_UINT8, BASE_DEC, NULL, 0x0,
618 { &hf_usb_hub_ep_num,
619 { "EP_Num", "usbhub.setup.EP_Num", FT_UINT8, BASE_DEC, NULL, 0x0,
622 { &hf_usb_hub_descriptor_type,
623 { "DescriptorType", "usbhub.setup.DescriptorType", FT_UINT8, BASE_DEC, NULL, 0x0,
626 { &hf_usb_hub_descriptor_index,
627 { "DescriptorIndex", "usbhub.setup.DescriptorIndex", FT_UINT8, BASE_DEC, NULL, 0x0,
630 { &hf_usb_hub_descriptor_length,
631 { "DescriptorLength", "usbhub.setup.DescriptorLength", FT_UINT8, BASE_DEC, NULL, 0x0,
635 { "(zero)", "usbhub.setup.zero", FT_UINT8, BASE_DEC, NULL, 0x0,
638 { &hf_usb_hub_tt_flags,
639 { "TT_Flags", "usbhub.setup.TT_Flags", FT_UINT8, BASE_DEC, NULL, 0x0,
642 { &hf_usb_hub_tt_port,
643 { "TT_Port", "usbhub.setup.TT_Port", FT_UINT16, BASE_DEC, NULL, 0x0,
646 { &hf_usb_hub_tt_state_length,
647 { "TT State Length", "usbhub.setup.TT_StateLength", FT_UINT16, BASE_DEC, NULL, 0x0,
650 { &hf_usb_hub_port_selector,
651 { "PortSelector", "usbhub.setup.PortSelector", FT_UINT8, BASE_DEC, NULL, 0x0,
655 { "Port", "usbhub.setup.Port", FT_UINT8, BASE_DEC, NULL, 0x0,
660 static gint *usb_hub_subtrees[] = {
666 proto_usb_hub = proto_register_protocol("USB HUB", "USBHUB", "usbhub");
667 proto_register_field_array(proto_usb_hub, hf, array_length(hf));
668 proto_register_subtree_array(usb_hub_subtrees, array_length(usb_hub_subtrees));
672 proto_reg_handoff_usb_hub(void) {
673 dissector_handle_t usb_hub_control_handle;
675 usb_hub_control_handle = new_create_dissector_handle(dissect_usb_hub_control, proto_usb_hub);
676 dissector_add("usb.control", IF_CLASS_HUB, usb_hub_control_handle);
677 dissector_add("usb.control", IF_CLASS_UNKNOWN, usb_hub_control_handle);