MSWSP: fix dissect_mswsp_smb()
[wireshark-wip.git] / epan / dissectors / packet-usb.c
blob5087f276eedcaee2ce9842912f40263f2d14a6fb
1 /* packet-usb.c
3 * $Id$
5 * USB basic dissector
6 * By Paolo Abeni <paolo.abeni@email.it>
7 * Ronnie Sahlberg 2006
9 * http://www.usb.org/developers/docs/usb_20_122909-2.zip
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include "config.h"
29 #include <ctype.h>
30 #include "isprint.h"
32 #include <glib.h>
33 #include <wsutil/pint.h>
34 #include <epan/packet.h>
35 #include <epan/exceptions.h>
36 #include <epan/etypes.h>
37 #include <epan/addr_resolv.h>
38 #include <epan/wmem/wmem.h>
39 #include <epan/tap.h>
40 #include <epan/conversation.h>
41 #include <epan/expert.h>
42 #include <epan/prefs.h>
44 #include "packet-usb.h"
45 #include "packet-usb-hid.h"
47 /* internal header flags */
48 #define USB_HEADER_IS_LINUX (1 << 0)
49 #define USB_HEADER_IS_64_BYTES (1 << 1)
50 #define USB_HEADER_IS_USBPCAP (1 << 2)
52 /* protocols and header fields */
53 static int proto_usb = -1;
55 /* Linux USB pseudoheader fields */
56 static int hf_usb_urb_id = -1;
57 static int hf_usb_urb_type = -1;
58 static int hf_usb_transfer_type = -1;
59 static int hf_usb_endpoint_number = -1;
60 static int hf_usb_endpoint_direction = -1;
61 static int hf_usb_endpoint_number_value = -1;
62 static int hf_usb_device_address = -1;
63 static int hf_usb_bus_id = -1;
64 static int hf_usb_setup_flag = -1;
65 static int hf_usb_data_flag = -1;
66 static int hf_usb_urb_ts_sec = -1;
67 static int hf_usb_urb_ts_usec = -1;
68 static int hf_usb_urb_status = -1;
69 static int hf_usb_urb_len = -1;
70 static int hf_usb_urb_data_len = -1;
72 /* Win32 USBPcap pseudoheader fields */
73 static int hf_usb_win32_header_len = -1;
74 static int hf_usb_irp_id = -1;
75 static int hf_usb_usbd_status = -1;
76 static int hf_usb_function = -1;
77 static int hf_usb_info = -1;
78 static int hf_usb_usbpcap_info_reserved = -1;
79 static int hf_usb_usbpcap_info_direction = -1;
80 static int hf_usb_win32_device_address = -1;
81 /* hf_usb_bus_id, hf_usb_endpoint_number, hf_usb_endpoint_direction,
82 * hf_usb_endpoint_number_value, hf_usb_transfer_type are common with
83 * Linux pseudoheader */
84 static int hf_usb_win32_data_len = -1;
85 static int hf_usb_control_stage = -1;
86 static int hf_usb_win32_iso_start_frame = -1;
87 static int hf_usb_win32_iso_num_packets = -1;
88 static int hf_usb_win32_iso_error_count = -1;
89 static int hf_usb_win32_iso_offset = -1;
90 static int hf_usb_win32_iso_length = -1;
91 static int hf_usb_win32_iso_status = -1;
93 static int hf_usb_request = -1;
94 static int hf_usb_request_unknown_class = -1;
95 static int hf_usb_value = -1;
96 static int hf_usb_index = -1;
97 static int hf_usb_length = -1;
98 /* static int hf_usb_data_len = -1; */
99 static int hf_usb_capdata = -1;
100 static int hf_usb_wFeatureSelector = -1;
101 static int hf_usb_wInterface = -1;
102 static int hf_usb_wStatus = -1;
103 static int hf_usb_wFrameNumber = -1;
105 static int hf_usb_iso_error_count = -1;
106 static int hf_usb_iso_numdesc = -1;
107 static int hf_usb_iso_status = -1;
108 static int hf_usb_iso_off = -1;
109 static int hf_usb_iso_len = -1;
110 static int hf_usb_iso_pad = -1;
111 static int hf_usb_iso_data = -1;
113 static int hf_usb_bmRequestType = -1;
114 static int hf_usb_bmRequestType_direction = -1;
115 static int hf_usb_bmRequestType_type = -1;
116 static int hf_usb_bmRequestType_recipient = -1;
117 static int hf_usb_bDescriptorType = -1;
118 static int hf_usb_descriptor_index = -1;
119 static int hf_usb_language_id = -1;
120 static int hf_usb_bLength = -1;
121 static int hf_usb_bcdUSB = -1;
122 static int hf_usb_bDeviceClass = -1;
123 static int hf_usb_bDeviceSubClass = -1;
124 static int hf_usb_bDeviceProtocol = -1;
125 static int hf_usb_bMaxPacketSize0 = -1;
126 static int hf_usb_idVendor = -1;
127 static int hf_usb_idProduct = -1;
128 static int hf_usb_bcdDevice = -1;
129 static int hf_usb_iManufacturer = -1;
130 static int hf_usb_iProduct = -1;
131 static int hf_usb_iSerialNumber = -1;
132 static int hf_usb_bNumConfigurations = -1;
133 static int hf_usb_wLANGID = -1;
134 static int hf_usb_bString = -1;
135 static int hf_usb_bInterfaceNumber = -1;
136 static int hf_usb_bAlternateSetting = -1;
137 static int hf_usb_bNumEndpoints = -1;
138 static int hf_usb_bInterfaceClass = -1;
139 static int hf_usb_bInterfaceSubClass = -1;
140 static int hf_usb_bInterfaceSubClass_cdc = -1;
141 static int hf_usb_bInterfaceSubClass_hid = -1;
142 static int hf_usb_bInterfaceProtocol = -1;
143 static int hf_usb_bInterfaceProtocol_cdc = -1;
144 static int hf_usb_bInterfaceProtocol_cdc_data = -1;
145 static int hf_usb_bInterfaceProtocol_hid_boot = -1;
146 static int hf_usb_iInterface = -1;
147 static int hf_usb_bEndpointAddress = -1;
148 static int hf_usb_bmAttributes = -1;
149 static int hf_usb_bEndpointAttributeTransfer = -1;
150 static int hf_usb_bEndpointAttributeSynchonisation = -1;
151 static int hf_usb_bEndpointAttributeBehaviour = -1;
152 static int hf_usb_wMaxPacketSize = -1;
153 static int hf_usb_wMaxPacketSize_size = -1;
154 static int hf_usb_wMaxPacketSize_slots = -1;
155 static int hf_usb_bInterval = -1;
156 static int hf_usb_wTotalLength = -1;
157 static int hf_usb_bNumInterfaces = -1;
158 static int hf_usb_bConfigurationValue = -1;
159 static int hf_usb_iConfiguration = -1;
160 static int hf_usb_bMaxPower = -1;
161 static int hf_usb_configuration_bmAttributes = -1;
162 static int hf_usb_configuration_legacy10buspowered = -1;
163 static int hf_usb_configuration_selfpowered = -1;
164 static int hf_usb_configuration_remotewakeup = -1;
165 static int hf_usb_bEndpointAddress_direction = -1;
166 static int hf_usb_bEndpointAddress_number = -1;
167 static int hf_usb_response_in = -1;
168 static int hf_usb_time = -1;
169 static int hf_usb_request_in = -1;
170 static int hf_usb_bFirstInterface = -1;
171 static int hf_usb_bInterfaceCount = -1;
172 static int hf_usb_bFunctionClass = -1;
173 static int hf_usb_bFunctionSubClass = -1;
174 static int hf_usb_bFunctionProtocol = -1;
175 static int hf_usb_iFunction = -1;
177 static gint usb_hdr = -1;
178 static gint usb_setup_hdr = -1;
179 static gint usb_isodesc = -1;
180 static gint usb_win32_iso_packet = -1;
181 static gint ett_usb_endpoint = -1;
182 static gint ett_usb_setup_bmrequesttype = -1;
183 static gint ett_usb_usbpcap_info = -1;
184 static gint ett_descriptor_device = -1;
185 static gint ett_configuration_bmAttributes = -1;
186 static gint ett_configuration_bEndpointAddress = -1;
187 static gint ett_endpoint_bmAttributes = -1;
188 static gint ett_endpoint_wMaxPacketSize = -1;
190 static expert_field ei_usb_bLength_even = EI_INIT;
191 static expert_field ei_usb_desc_length_invalid = EI_INIT;
193 static const int *usb_endpoint_fields[] = {
194 &hf_usb_endpoint_direction,
195 &hf_usb_endpoint_number_value,
196 NULL
199 static const int *usb_usbpcap_info_fields[] = {
200 &hf_usb_usbpcap_info_reserved,
201 &hf_usb_usbpcap_info_direction,
202 NULL
205 static int usb_tap = -1;
206 static gboolean try_heuristics = TRUE;
208 static dissector_handle_t linux_usb_handle;
210 static dissector_table_t usb_bulk_dissector_table;
211 static dissector_table_t usb_control_dissector_table;
212 static dissector_table_t usb_interrupt_dissector_table;
213 static dissector_table_t usb_descriptor_dissector_table;
215 static heur_dissector_list_t heur_bulk_subdissector_list;
216 static heur_dissector_list_t heur_control_subdissector_list;
217 static heur_dissector_list_t heur_interrupt_subdissector_list;
219 static wmem_tree_t *device_to_protocol_table = NULL;
220 static wmem_tree_t *device_to_product_table = NULL;
222 static dissector_table_t device_to_dissector;
223 static dissector_table_t protocol_to_dissector;
224 static dissector_table_t product_to_dissector;
226 typedef struct _device_product_data_t {
227 guint16 vendor;
228 guint16 product;
229 guint bus_id;
230 guint device_address;
231 } device_product_data_t;
233 typedef struct _device_protocol_data_t {
234 guint32 protocol;
235 guint bus_id;
236 guint device_address;
237 } device_protocol_data_t;
240 /* http://www.usb.org/developers/docs/USB_LANGIDs.pdf */
241 static const value_string usb_langid_vals[] = {
242 {0x0000, "no language specified"},
243 {0x0401, "Arabic (Saudi Arabia)"},
244 {0x0402, "Bulgarian"},
245 {0x0403, "Catalan"},
246 {0x0404, "Chinese (Taiwan)"},
247 {0x0405, "Czech"},
248 {0x0406, "Danish"},
249 {0x0407, "German (Standard)"},
250 {0x0408, "Greek"},
251 {0x0409, "English (United States)"},
252 {0x040a, "Spanish (Traditional Sort)"},
253 {0x040b, "Finnish"},
254 {0x040c, "French (Standard)"},
255 {0x040d, "Hebrew"},
256 {0x040e, "Hungarian"},
257 {0x040f, "Icelandic"},
258 {0x0410, "Italian (Standard)"},
259 {0x0411, "Japanese"},
260 {0x0412, "Korean"},
261 {0x0413, "Dutch (Netherlands)"},
262 {0x0414, "Norwegian (Bokmal)"},
263 {0x0415, "Polish"},
264 {0x0416, "Portuguese (Brazil)"},
265 {0x0418, "Romanian"},
266 {0x0419, "Russian"},
267 {0x041a, "Croatian"},
268 {0x041b, "Slovak"},
269 {0x041c, "Albanian"},
270 {0x041d, "Swedish"},
271 {0x041e, "Thai"},
272 {0x041f, "Turkish"},
273 {0x0420, "Urdu (Pakistan)"},
274 {0x0421, "Indonesian"},
275 {0x0422, "Ukrainian"},
276 {0x0423, "Belarussian"},
277 {0x0424, "Slovenian"},
278 {0x0425, "Estonian"},
279 {0x0426, "Latvian"},
280 {0x0427, "Lithuanian"},
281 {0x0429, "Farsi"},
282 {0x042a, "Vietnamese"},
283 {0x042b, "Armenian"},
284 {0x042c, "Azeri (Latin)"},
285 {0x042d, "Basque"},
286 {0x042f, "Macedonian"},
287 {0x0430, "Sutu"},
288 {0x0436, "Afrikaans"},
289 {0x0437, "Georgian"},
290 {0x0438, "Faeroese"},
291 {0x0439, "Hindi"},
292 {0x043e, "Malay (Malaysian)"},
293 {0x043f, "Kazakh"},
294 {0x0441, "Swahili (Kenya)"},
295 {0x0443, "Uzbek (Latin)"},
296 {0x0444, "Tatar (Tatarstan)"},
297 {0x0445, "Bengali"},
298 {0x0446, "Punjabi"},
299 {0x0447, "Gujarati"},
300 {0x0448, "Oriya"},
301 {0x0449, "Tamil"},
302 {0x044a, "Telugu"},
303 {0x044b, "Kannada"},
304 {0x044c, "Malayalam"},
305 {0x044d, "Assamese"},
306 {0x044e, "Marathi"},
307 {0x044f, "Sanskrit"},
308 {0x0455, "Burmese"},
309 {0x0457, "Konkani"},
310 {0x0458, "Manipuri"},
311 {0x0459, "Sindhi"},
312 {0x04ff, "HID (Usage Data Descriptor)"},
313 {0x0801, "Arabic (Iraq)"},
314 {0x0804, "Chinese (PRC)"},
315 {0x0807, "German (Switzerland)"},
316 {0x0809, "English (United Kingdom)"},
317 {0x080a, "Spanish (Mexican)"},
318 {0x080c, "French (Belgian)"},
319 {0x0810, "Italian (Switzerland)"},
320 {0x0812, "Korean (Johab)"},
321 {0x0813, "Dutch (Belgium)"},
322 {0x0814, "Norwegian (Nynorsk)"},
323 {0x0816, "Portuguese (Standard)"},
324 {0x081a, "Serbian (Latin)"},
325 {0x081d, "Swedish (Finland)"},
326 {0x0820, "Urdu (India)"},
327 {0x0827, "Lithuanian (Classic)"},
328 {0x082c, "Azeri (Cyrillic)"},
329 {0x083e, "Malay (Brunei Darussalam)"},
330 {0x0843, "Uzbek (Cyrillic)"},
331 {0x0860, "Kashmiri (India)"},
332 {0x0861, "Nepali (India)"},
333 {0x0c01, "Arabic (Egypt)"},
334 {0x0c04, "Chinese (Hong Kong SAR, PRC)"},
335 {0x0c07, "German (Austria)"},
336 {0x0c09, "English (Australian)"},
337 {0x0c0a, "Spanish (Modern Sort)"},
338 {0x0c0c, "French (Canadian)"},
339 {0x0c1a, "Serbian (Cyrillic)"},
340 {0x1001, "Arabic (Libya)"},
341 {0x1004, "Chinese (Singapore)"},
342 {0x1007, "German (Luxembourg)"},
343 {0x1009, "English (Canadian)"},
344 {0x100a, "Spanish (Guatemala)"},
345 {0x100c, "French (Switzerland)"},
346 {0x1401, "Arabic (Algeria)"},
347 {0x1404, "Chinese (Macau SAR)"},
348 {0x1407, "German (Liechtenstein)"},
349 {0x1409, "English (New Zealand)"},
350 {0x140a, "Spanish (Costa Rica)"},
351 {0x140c, "French (Luxembourg)"},
352 {0x1801, "Arabic (Morocco)"},
353 {0x1809, "English (Ireland)"},
354 {0x180a, "Spanish (Panama)"},
355 {0x180c, "French (Monaco)"},
356 {0x1c01, "Arabic (Tunisia)"},
357 {0x1c09, "English (South Africa)"},
358 {0x1c0a, "Spanish (Dominican Republic)"},
359 {0x2001, "Arabic (Oman)"},
360 {0x2009, "English (Jamaica)"},
361 {0x200a, "Spanish (Venezuela)"},
362 {0x2401, "Arabic (Yemen)"},
363 {0x2409, "English (Caribbean)"},
364 {0x240a, "Spanish (Colombia)"},
365 {0x2801, "Arabic (Syria)"},
366 {0x2809, "English (Belize)"},
367 {0x280a, "Spanish (Peru)"},
368 {0x2c01, "Arabic (Jordan)"},
369 {0x2c09, "English (Trinidad)"},
370 {0x2c0a, "Spanish (Argentina)"},
371 {0x3001, "Arabic (Lebanon)"},
372 {0x3009, "English (Zimbabwe)"},
373 {0x300a, "Spanish (Ecuador)"},
374 {0x3401, "Arabic (Kuwait)"},
375 {0x3409, "English (Philippines)"},
376 {0x340a, "Spanish (Chile)"},
377 {0x3801, "Arabic (U.A.E.)"},
378 {0x380a, "Spanish (Uruguay)"},
379 {0x3c01, "Arabic (Bahrain)"},
380 {0x3c0a, "Spanish (Paraguay)"},
381 {0x4001, "Arabic (Qatar)"},
382 {0x400a, "Spanish (Bolivia)"},
383 {0x440a, "Spanish (El Salvador)"},
384 {0x480a, "Spanish (Honduras)"},
385 {0x4c0a, "Spanish (Nicaragua)"},
386 {0x500a, "Spanish (Puerto Rico)"},
387 {0xf0ff, "HID (Vendor Defined 1)"},
388 {0xf4ff, "HID (Vendor Defined 2)"},
389 {0xf8ff, "HID (Vendor Defined 3)"},
390 {0xfcff, "HID (Vendor Defined 4)"},
391 {0, NULL}
393 value_string_ext usb_langid_vals_ext = VALUE_STRING_EXT_INIT(usb_langid_vals);
395 static const value_string usb_class_vals[] = {
396 {IF_CLASS_DEVICE, "Device"},
397 {IF_CLASS_AUDIO, "Audio"},
398 {IF_CLASS_COMMUNICATIONS, "Communications and CDC Control"},
399 {IF_CLASS_HID, "HID"},
400 {IF_CLASS_PHYSICAL, "Physical"},
401 {IF_CLASS_IMAGE, "Imaging"},
402 {IF_CLASS_PRINTER, "Printer"},
403 {IF_CLASS_MASS_STORAGE, "Mass Storage"},
404 {IF_CLASS_HUB, "Hub"},
405 {IF_CLASS_CDC_DATA, "CDC-Data"},
406 {IF_CLASS_SMART_CARD, "Smart Card"},
407 {IF_CLASS_CONTENT_SECURITY, "Content Security"},
408 {IF_CLASS_VIDEO, "Video"},
409 {IF_CLASS_PERSONAL_HEALTHCARE, "Personal Healthcare"},
410 {IF_CLASS_AUDIO_VIDEO, "Audio/Video Devices"},
411 {IF_CLASS_DIAGNOSTIC_DEVICE, "Diagnostic Device"},
412 {IF_CLASS_WIRELESS_CONTROLLER, "Wireless Controller"},
413 {IF_CLASS_MISCELLANEOUS, "Miscellaneous"},
414 {IF_CLASS_APPLICATION_SPECIFIC, "Application Specific"},
415 {IF_CLASS_VENDOR_SPECIFIC, "Vendor Specific"},
416 {0, NULL}
418 static value_string_ext usb_class_vals_ext = VALUE_STRING_EXT_INIT(usb_class_vals);
420 /* use usb class, subclass and protocol id together
421 http://www.usb.org/developers/defined_class
422 USB Class Definitions for Communications Devices, Revision 1.2 December 6, 2012
424 static const value_string usb_protocols[] = {
425 {0x000000, "Use class code info from Interface Descriptors"},
426 {0x060101, "Still Imaging"},
427 {0x090000, "Full speed Hub"},
428 {0x090001, "Hi-speed hub with single TT"},
429 {0x090002, "Hi-speed hub with multiple TTs"},
430 {0x0D0000, "Content Security"},
431 {0x100100, "AVControl Interface"},
432 {0x100200, "AVData Video Streaming Interface"},
433 {0x100300, "AVData Audio Streaming Interface"},
434 {0xDC0101, "USB2 Compliance Device"},
435 {0xE00101, "Bluetooth Programming Interface"},
436 {0xE00102, "UWB Radio Control Interface"},
437 {0xE00103, "Remote NDIS"},
438 {0xE00104, "Bluetooth AMP Controller"},
439 {0xE00201, "Host Wire Adapter Control/Data interface"},
440 {0xE00202, "Device Wire Adapter Control/Data interface"},
441 {0xE00203, "Device Wire Adapter Isochronous interface"},
442 {0xEF0101, "Active Sync device"},
443 {0xEF0102, "Palm Sync"},
444 {0xEF0201, "Interface Association Descriptor"},
445 {0xEF0202, "Wire Adapter Multifunction Peripheral programming interface"},
446 {0xEF0301, "Cable Based Association Framework"},
447 {0xFE0101, "Device Firmware Upgrade"},
448 {0xFE0200, "IRDA Bridge device"},
449 {0xFE0300, "USB Test and Measurement Device"},
450 {0xFE0301, "USB Test and Measurement Device conforming to the USBTMC USB488"},
451 {0, NULL}
454 static const value_string usb_transfer_type_vals[] = {
455 {URB_CONTROL, "URB_CONTROL"},
456 {URB_ISOCHRONOUS, "URB_ISOCHRONOUS"},
457 {URB_INTERRUPT, "URB_INTERRUPT"},
458 {URB_BULK, "URB_BULK"},
459 {0, NULL}
462 static const value_string usb_transfer_type_and_direction_vals[] = {
463 {URB_CONTROL, "URB_CONTROL out"},
464 {URB_ISOCHRONOUS, "URB_ISOCHRONOUS out"},
465 {URB_INTERRUPT, "URB_INTERRUPT out"},
466 {URB_BULK, "URB_BULK out"},
467 {URB_CONTROL | URB_TRANSFER_IN, "URB_CONTROL in"},
468 {URB_ISOCHRONOUS | URB_TRANSFER_IN, "URB_ISOCHRONOUS in"},
469 {URB_INTERRUPT | URB_TRANSFER_IN, "URB_INTERRUPT in"},
470 {URB_BULK | URB_TRANSFER_IN, "URB_BULK in"},
471 {0, NULL}
474 static const value_string usb_endpoint_direction_vals[] = {
475 {0, "OUT"},
476 {1, "IN"},
477 {0, NULL}
480 static const value_string usb_urb_type_vals[] = {
481 {URB_SUBMIT, "URB_SUBMIT"},
482 {URB_COMPLETE, "URB_COMPLETE"},
483 {URB_ERROR, "URB_ERROR"},
484 {0, NULL}
487 extern value_string_ext ext_usb_vendors_vals;
488 extern value_string_ext ext_usb_products_vals;
489 extern value_string_ext ext_usb_com_subclass_vals;
492 * Standard descriptor types.
494 * all class specific descriptor types were removed from this list
495 * a descriptor type is not globally unique
496 * dissectors for the USB classes should provide their own value string
497 * and pass it to dissect_usb_descriptor_header()
500 #define USB_DT_DEVICE 1
501 #define USB_DT_CONFIG 2
502 #define USB_DT_STRING 3
503 #define USB_DT_INTERFACE 4
504 #define USB_DT_ENDPOINT 5
505 #define USB_DT_DEVICE_QUALIFIER 6
506 #define USB_DT_OTHER_SPEED_CONFIG 7
507 #define USB_DT_INTERFACE_POWER 8
508 /* these are from a minor usb 2.0 revision (ECN) */
509 #define USB_DT_OTG 9
510 #define USB_DT_DEBUG 10
511 #define USB_DT_INTERFACE_ASSOCIATION 11
512 /* XXX - move into HID dissector */
513 #define USB_DT_RPIPE 34
515 static const value_string std_descriptor_type_vals[] = {
516 {USB_DT_DEVICE, "DEVICE"},
517 {USB_DT_CONFIG, "CONFIGURATION"},
518 {USB_DT_STRING, "STRING"},
519 {USB_DT_INTERFACE, "INTERFACE"},
520 {USB_DT_ENDPOINT, "ENDPOINT"},
521 {USB_DT_DEVICE_QUALIFIER, "DEVICE QUALIFIER"},
522 {USB_DT_OTHER_SPEED_CONFIG, "OTHER_SPEED CONFIG"},
523 {USB_DT_INTERFACE_POWER, "INTERFACE POWER"},
524 {USB_DT_OTG, "OTG"},
525 {USB_DT_DEBUG, "DEBUG"},
526 {USB_DT_INTERFACE_ASSOCIATION, "INTERFACE ASSOCIATION"},
527 {0,NULL}
529 static value_string_ext std_descriptor_type_vals_ext =
530 VALUE_STRING_EXT_INIT(std_descriptor_type_vals);
533 * Feature selectors.
535 #define USB_FS_ENDPOINT_HALT 0
536 #define USB_FS_DEVICE_REMOTE_WAKEUP 1
537 #define USB_FS_TEST_MODE 2
539 static const value_string usb_feature_selector_vals[] = {
540 {USB_FS_ENDPOINT_HALT, "ENDPOINT HALT"},
541 {USB_FS_DEVICE_REMOTE_WAKEUP, "DEVICE REMOTE WAKEUP"},
542 {USB_FS_TEST_MODE, "TEST MODE"},
543 {0, NULL}
546 static const value_string usb_bmAttributes_transfer_vals[] = {
547 {0x00, "Control-Transfer"},
548 {0x01, "Isochronous-Transfer"},
549 {0x02, "Bulk-Transfer"},
550 {0x03, "Interrupt-Transfer"},
551 {0, NULL}
554 static const value_string usb_bmAttributes_sync_vals[] = {
555 {0x00, "No Sync"},
556 {0x01, "Asynchronous"},
557 {0x02, "Adaptive"},
558 {0x03, "Synchronous"},
559 {0, NULL}
562 static const value_string usb_bmAttributes_behaviour_vals[] = {
563 {0x00, "Data-Endpoint"},
564 {0x01, "Explicit Feedback-Endpoint"},
565 {0x02, "Implicit Feedback-Data-Endpoint"},
566 {0x03, "Reserved"},
567 {0, NULL}
570 static const value_string usb_wMaxPacketSize_slots_vals[] = {
571 {0x00, "1"},
572 {0x01, "2"},
573 {0x02, "3"},
574 {0x03, "Reserved"},
575 {0, NULL}
578 /* from linux/include/asm-generic/errno.h */
579 #define EPERM 1 /* Operation not permitted */
580 #define ENOENT 2 /* No such file or directory */
581 #define ESRCH 3 /* No such process */
582 #define EINTR 4 /* Interrupted system call */
583 #define EIO 5 /* I/O error */
584 #define ENXIO 6 /* No such device or address */
585 #define E2BIG 7 /* Argument list too long */
586 #define ENOEXEC 8 /* Exec format error */
587 #define EBADF 9 /* Bad file number */
588 #define ECHILD 10 /* No child processes */
589 #define EAGAIN 11 /* Try again */
590 #define ENOMEM 12 /* Out of memory */
591 #define EACCES 13 /* Permission denied */
592 #define EFAULT 14 /* Bad address */
593 #define ENOTBLK 15 /* Block device required */
594 #define EBUSY 16 /* Device or resource busy */
595 #define EEXIST 17 /* File exists */
596 #define EXDEV 18 /* Cross-device link */
597 #define ENODEV 19 /* No such device */
598 #define ENOTDIR 20 /* Not a directory */
599 #define EISDIR 21 /* Is a directory */
600 #define EINVAL 22 /* Invalid argument */
601 #define ENFILE 23 /* File table overflow */
602 #define EMFILE 24 /* Too many open files */
603 #define ENOTTY 25 /* Not a typewriter */
604 #define ETXTBSY 26 /* Text file busy */
605 #define EFBIG 27 /* File too large */
606 #define ENOSPC 28 /* No space left on device */
607 #define ESPIPE 29 /* Illegal seek */
608 #define EROFS 30 /* Read-only file system */
609 #define EMLINK 31 /* Too many links */
610 #define EPIPE 32 /* Broken pipe */
611 #define EDOM 33 /* Math argument out of domain of func */
612 #define ERANGE 34 /* Math result not representable */
615 /* from linux/include/asm-generic/errno.h*/
616 #define EDEADLK 35 /* Resource deadlock would occur */
617 #define ENAMETOOLONG 36 /* File name too long */
618 #define ENOLCK 37 /* No record locks available */
619 #define ENOSYS 38 /* Function not implemented */
620 #define ENOTEMPTY 39 /* Directory not empty */
621 #define ELOOP 40 /* Too many symbolic links encountered */
622 #define EWOULDBLOCK EAGAIN /* Operation would block */
623 #define ENOMSG 42 /* No message of desired type */
624 #define EIDRM 43 /* Identifier removed */
625 #define ECHRNG 44 /* Channel number out of range */
626 #define EL2NSYNC 45 /* Level 2 not synchronized */
627 #define EL3HLT 46 /* Level 3 halted */
628 #define EL3RST 47 /* Level 3 reset */
629 #define ELNRNG 48 /* Link number out of range */
630 #define EUNATCH 49 /* Protocol driver not attached */
631 #define ENOCSI 50 /* No CSI structure available */
632 #define EL2HLT 51 /* Level 2 halted */
633 #define EBADE 52 /* Invalid exchange */
634 #define EBADR 53 /* Invalid request descriptor */
635 #define EXFULL 54 /* Exchange full */
636 #define ENOANO 55 /* No anode */
637 #define EBADRQC 56 /* Invalid request code */
638 #define EBADSLT 57 /* Invalid slot */
640 #define EDEADLOCK EDEADLK
642 #define EBFONT 59 /* Bad font file format */
643 #define ENOSTR 60 /* Device not a stream */
644 #define ENODATA 61 /* No data available */
645 #define ETIME 62 /* Timer expired */
646 #define ENOSR 63 /* Out of streams resources */
647 #define ENONET 64 /* Machine is not on the network */
648 #define ENOPKG 65 /* Package not installed */
649 #define EREMOTE 66 /* Object is remote */
650 #define ENOLINK 67 /* Link has been severed */
651 #define EADV 68 /* Advertise error */
652 #define ESRMNT 69 /* Srmount error */
653 #define ECOMM 70 /* Communication error on send */
654 #define EPROTO 71 /* Protocol error */
655 #define EMULTIHOP 72 /* Multihop attempted */
656 #define EDOTDOT 73 /* RFS specific error */
657 #define EBADMSG 74 /* Not a data message */
658 #define EOVERFLOW 75 /* Value too large for defined data type */
659 #define ENOTUNIQ 76 /* Name not unique on network */
660 #define EBADFD 77 /* File descriptor in bad state */
661 #define EREMCHG 78 /* Remote address changed */
662 #define ELIBACC 79 /* Can not access a needed shared library */
663 #define ELIBBAD 80 /* Accessing a corrupted shared library */
664 #define ELIBSCN 81 /* .lib section in a.out corrupted */
665 #define ELIBMAX 82 /* Attempting to link in too many shared libraries */
666 #define ELIBEXEC 83 /* Cannot exec a shared library directly */
667 #define EILSEQ 84 /* Illegal byte sequence */
668 #define ERESTART 85 /* Interrupted system call should be restarted */
669 #define ESTRPIPE 86 /* Streams pipe error */
670 #define EUSERS 87 /* Too many users */
671 #define ENOTSOCK 88 /* Socket operation on non-socket */
672 #define EDESTADDRREQ 89 /* Destination address required */
673 #define EMSGSIZE 90 /* Message too long */
674 #define EPROTOTYPE 91 /* Protocol wrong type for socket */
675 #define ENOPROTOOPT 92 /* Protocol not available */
676 #define EPROTONOSUPPORT 93 /* Protocol not supported */
677 #define ESOCKTNOSUPPORT 94 /* Socket type not supported */
678 #define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
679 #define EPFNOSUPPORT 96 /* Protocol family not supported */
680 #define EAFNOSUPPORT 97 /* Address family not supported by protocol */
681 #define EADDRINUSE 98 /* Address already in use */
682 #define EADDRNOTAVAIL 99 /* Cannot assign requested address */
683 #define ENETDOWN 100 /* Network is down */
684 #define ENETUNREACH 101 /* Network is unreachable */
685 #define ENETRESET 102 /* Network dropped connection because of reset */
686 #define ECONNABORTED 103 /* Software caused connection abort */
687 #define ECONNRESET 104 /* Connection reset by peer */
688 #define ENOBUFS 105 /* No buffer space available */
689 #define EISCONN 106 /* Transport endpoint is already connected */
690 #define ENOTCONN 107 /* Transport endpoint is not connected */
691 #define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
692 #define ETOOMANYREFS 109 /* Too many references: cannot splice */
693 #define ETIMEDOUT 110 /* Connection timed out */
694 #define ECONNREFUSED 111 /* Connection refused */
695 #define EHOSTDOWN 112 /* Host is down */
696 #define EHOSTUNREACH 113 /* No route to host */
697 #define EALREADY 114 /* Operation already in progress */
698 #define EINPROGRESS 115 /* Operation now in progress */
699 #define ESTALE 116 /* Stale NFS file handle */
700 #define EUCLEAN 117 /* Structure needs cleaning */
701 #define ENOTNAM 118 /* Not a XENIX named type file */
702 #define ENAVAIL 119 /* No XENIX semaphores available */
703 #define EISNAM 120 /* Is a named type file */
704 #define EREMOTEIO 121 /* Remote I/O error */
705 #define EDQUOT 122 /* Quota exceeded */
707 #define ENOMEDIUM 123 /* No medium found */
708 #define EMEDIUMTYPE 124 /* Wrong medium type */
709 #define ECANCELED 125 /* Operation Canceled */
710 #define ENOKEY 126 /* Required key not available */
711 #define EKEYEXPIRED 127 /* Key has expired */
712 #define EKEYREVOKED 128 /* Key has been revoked */
713 #define EKEYREJECTED 129 /* Key was rejected by service */
715 /* for robust mutexes */
716 #define EOWNERDEAD 130 /* Owner died */
717 #define ENOTRECOVERABLE 131 /* State not recoverable */
720 /* Note: sorted in (unsigned) ascending order */
721 static const value_string usb_urb_status_vals[] = {
722 { -ENOTRECOVERABLE, "State not recoverable (-ENOTRECOVERABLE)" },
723 { -EOWNERDEAD, "Owner died (-EOWNERDEAD)" },
724 { -EKEYREJECTED, "Key was rejected by service (-EKEYREJECTED)" },
725 { -EKEYREVOKED, "Key has been revoked (-EKEYREVOKED)" },
726 { -EKEYEXPIRED, "Key has expired (-EKEYEXPIRED)" },
727 { -ENOKEY, "Required key not available (-ENOKEY)" },
728 { -ECANCELED, "Operation Canceled (-ECANCELED)" },
729 { -EMEDIUMTYPE, "Wrong medium type (-EMEDIUMTYPE)" },
730 { -ENOMEDIUM, "No medium found (-ENOMEDIUM)" },
731 { -EDQUOT, "Quota exceeded (-EDQUOT)" },
732 { -EREMOTEIO, "Remote I/O error (-EREMOTEIO)" },
733 { -EISNAM, "Is a named type file (-EISNAM)" },
734 { -ENAVAIL, "No XENIX semaphores available (-ENAVAIL)" },
735 { -ENOTNAM, "Not a XENIX named type file (-ENOTNAM)" },
736 { -EUCLEAN, "Structure needs cleaning (-EUCLEAN)" },
737 { -ESTALE, "Stale NFS file handle (-ESTALE)" },
738 { -EINPROGRESS, "Operation now in progress (-EINPROGRESS)" },
739 { -EALREADY, "Operation already in progress (-EALREADY)" },
740 { -EHOSTUNREACH, "No route to host (-EHOSTUNREACH)" },
741 { -EHOSTDOWN, "Host is down (-EHOSTDOWN)" },
742 { -ECONNREFUSED, "Connection refused (-ECONNREFUSED)" },
743 { -ETIMEDOUT, "Connection timed out (-ETIMEDOUT)" },
744 { -ETOOMANYREFS, "Too many references: cannot splice (-ETOOMANYREFS)" },
745 { -ESHUTDOWN, "Cannot send after transport endpoint shutdown (-ESHUTDOWN)" },
746 { -ENOTCONN, "Transport endpoint is not connected (-ENOTCONN)" },
747 { -EISCONN, "Transport endpoint is already connected (-EISCONN)" },
748 { -ENOBUFS, "No buffer space available (-ENOBUFS)" },
749 { -ECONNRESET, "Connection reset by peer (-ECONNRESET)" },
750 { -ECONNABORTED, "Software caused connection abort (-ECONNABORTED)" },
751 { -ENETRESET, "Network dropped connection because of reset (-ENETRESET)" },
752 { -ENETUNREACH, "Network is unreachable (-ENETUNREACH)" },
753 { -ENETDOWN, "Network is down (-ENETDOWN)" },
754 { -EADDRNOTAVAIL, "Cannot assign requested address (-EADDRNOTAVAIL)" },
755 { -EADDRINUSE, "Address already in use (-EADDRINUSE)" },
756 { -EAFNOSUPPORT, "Address family not supported by protocol (-EAFNOSUPPORT)" },
757 { -EPFNOSUPPORT, "Protocol family not supported (-EPFNOSUPPORT)" },
758 { -EOPNOTSUPP, "Operation not supported on transport endpoint (-EOPNOTSUPP)" },
759 { -ESOCKTNOSUPPORT, "Socket type not supported (-ESOCKTNOSUPPORT)" },
760 { -EPROTONOSUPPORT, "Protocol not supported (-EPROTONOSUPPORT)" },
761 { -ENOPROTOOPT, "Protocol not available (-ENOPROTOOPT)" },
762 { -EPROTOTYPE, "Protocol wrong type for socket (-EPROTOTYPE)" },
763 { -EMSGSIZE, "Message too long (-EMSGSIZE)" },
764 { -EDESTADDRREQ, "Destination address required (-EDESTADDRREQ)" },
765 { -ENOTSOCK, "Socket operation on non-socket (-ENOTSOCK)" },
766 { -EUSERS, "Too many users (-EUSERS)" },
767 { -ESTRPIPE, "Streams pipe error (-ESTRPIPE)" },
768 { -ERESTART, "Interrupted system call should be restarted (-ERESTART)" },
769 { -EILSEQ, "Illegal byte sequence (-EILSEQ)" },
770 { -ELIBEXEC, "Cannot exec a shared library directly (-ELIBEXEC)" },
771 { -ELIBMAX, "Attempting to link in too many shared libraries (-ELIBMAX)" },
772 { -ELIBSCN, ".lib section in a.out corrupted (-ELIBSCN)" },
773 { -ELIBBAD, "Accessing a corrupted shared library (-ELIBBAD)" },
774 { -ELIBACC, "Can not access a needed shared library (-ELIBACC)" },
775 { -EREMCHG, "Remote address changed (-EREMCHG)" },
776 { -EBADFD, "File descriptor in bad state (-EBADFD)" },
777 { -ENOTUNIQ, "Name not unique on network (-ENOTUNIQ)" },
778 { -EOVERFLOW, "Value too large for defined data type (-EOVERFLOW)" },
779 { -EBADMSG, "Not a data message (-EBADMSG)" },
780 { -EDOTDOT, "RFS specific error (-EDOTDOT)" },
781 { -EMULTIHOP, "Multihop attempted (-EMULTIHOP)" },
782 { -EPROTO, "Protocol error (-EPROTO)" },
783 { -ECOMM, "Communication error on send (-ECOMM)" },
784 { -ESRMNT, "Srmount error (-ESRMNT)" },
785 { -EADV, "Advertise error (-EADV)" },
786 { -ENOLINK, "Link has been severed (-ENOLINK)" },
787 { -EREMOTE, "Object is remote (-EREMOTE)" },
788 { -ENOPKG, "Package not installed (-ENOPKG)" },
789 { -ENONET, "Machine is not on the network (-ENONET)" },
790 { -ENOSR, "Out of streams resources (-ENOSR)" },
791 { -ETIME, "Timer expired (-ETIME)" },
792 { -ENODATA, "No data available (-ENODATA)" },
793 { -ENOSTR, "Device not a stream (-ENOSTR)" },
794 { -EBFONT, "Bad font file format (-EBFONT)" },
795 { -58, "(-58 \?\?\?)" }, /* dummy so that there are no "gaps" */
796 { -EBADSLT, "Invalid slot (-EBADSLT)" },
797 { -EBADRQC, "Invalid request code (-EBADRQC)" },
798 { -ENOANO, "No anode (-ENOANO)" },
799 { -EXFULL, "Exchange full (-EXFULL)" },
800 { -EBADR, "Invalid request descriptor (-EBADR)" },
801 { -EBADE, "Invalid exchange (-EBADE)" },
802 { -EL2HLT, "Level 2 halted (-EL2HLT)" },
803 { -ENOCSI, "No CSI structure available (-ENOCSI)" },
804 { -EUNATCH, "Protocol driver not attached (-EUNATCH)" },
805 { -ELNRNG, "Link number out of range (-ELNRNG)" },
806 { -EL3RST, "Level 3 reset (-EL3RST)" },
807 { -EL3HLT, "Level 3 halted (-EL3HLT)" },
808 { -EL2NSYNC, "Level 2 not synchronized (-EL2NSYNC)" },
809 { -ECHRNG, "Channel number out of range (-ECHRNG)" },
810 { -EIDRM, "Identifier removed (-EIDRM)" },
811 { -ENOMSG, "No message of desired type (-ENOMSG)" },
812 { -41, "(-41 \?\?\?)" }, /* dummy so that there are no "gaps" */
813 { -ELOOP, "Too many symbolic links encountered (-ELOOP)" },
814 { -ENOTEMPTY, "Directory not empty (-ENOTEMPTY)" },
815 { -ENOSYS, "Function not implemented (-ENOSYS)" },
816 { -ENOLCK, "No record locks available (-ENOLCK)" },
817 { -ENAMETOOLONG, "File name too long (-ENAMETOOLONG)" },
818 { -EDEADLK, "Resource deadlock would occur (-EDEADLK)" },
819 { -ERANGE, "Math result not representable (-ERANGE)" },
820 { -EDOM, "Math argument out of domain of func (-EDOM)" },
821 { -EPIPE, "Broken pipe (-EPIPE)" },
822 { -EMLINK, "Too many links (-EMLINK)" },
823 { -EROFS, "Read-only file system (-EROFS)" },
824 { -ESPIPE, "Illegal seek (-ESPIPE)" },
825 { -ENOSPC, "No space left on device (-ENOSPC)" },
826 { -EFBIG, "File too large (-EFBIG)" },
827 { -ETXTBSY, "Text file busy (-ETXTBSY)" },
828 { -ENOTTY, "Not a typewriter (-ENOTTY)" },
829 { -EMFILE, "Too many open files (-EMFILE)" },
830 { -ENFILE, "File table overflow (-ENFILE)" },
831 { -EINVAL, "Invalid argument (-EINVAL)" },
832 { -EISDIR, "Is a directory (-EISDIR)" },
833 { -ENOTDIR, "Not a directory (-ENOTDIR)" },
834 { -ENODEV, "No such device (-ENODEV)" },
835 { -EXDEV, "Cross-device link (-EXDEV)" },
836 { -EEXIST, "File exists (-EEXIST)" },
837 { -EBUSY, "Device or resource busy (-EBUSY)" },
838 { -ENOTBLK, "Block device required (-ENOTBLK)" },
839 { -EFAULT, "Bad address (-EFAULT)" },
840 { -EACCES, "Permission denied (-EACCES)" },
841 { -ENOMEM, "Out of memory (-ENOMEM)" },
842 { -EAGAIN, "Try again (-EAGAIN)" },
843 { -ECHILD, "No child processes (-ECHILD)" },
844 { -EBADF, "Bad file number (-EBADF)" },
845 { -ENOEXEC, "Exec format error (-ENOEXEC)" },
846 { -E2BIG, "Argument list too long (-E2BIG)" },
847 { -ENXIO, "No such device or address (-ENXIO)" },
848 { -EIO, "I/O error (-EIO)" },
849 { -EINTR, "Interrupted system call (-EINTR)" },
850 { -ESRCH, "No such process (-ESRCH)" },
851 { -ENOENT, "No such file or directory (-ENOENT)" },
852 { -EPERM, "Operation not permitted (-EPERM)" },
853 { 0, "Success"},
854 { 0, NULL }
856 static value_string_ext usb_urb_status_vals_ext = VALUE_STRING_EXT_INIT(usb_urb_status_vals);
858 #define USB_CONTROL_STAGE_SETUP 0x00
859 #define USB_CONTROL_STAGE_DATA 0x01
860 #define USB_CONTROL_STAGE_STATUS 0x02
862 static const value_string usb_control_stage_vals[] = {
863 {USB_CONTROL_STAGE_SETUP, "Setup"},
864 {USB_CONTROL_STAGE_DATA, "Data"},
865 {USB_CONTROL_STAGE_STATUS, "Status"},
866 {0, NULL}
869 static const value_string win32_urb_function_vals[] = {
870 {0x0000, "URB_FUNCTION_SELECT_CONFIGURATION"},
871 {0x0001, "URB_FUNCTION_SELECT_INTERFACE"},
872 {0x0002, "URB_FUNCTION_ABORT_PIPE"},
873 {0x0003, "URB_FUNCTION_TAKE_FRAME_LENGTH_CONTROL"},
874 {0x0004, "URB_FUNCTION_RELEASE_FRAME_LENGTH_CONTROL"},
875 {0x0005, "URB_FUNCTION_GET_FRAME_LENGTH"},
876 {0x0006, "URB_FUNCTION_SET_FRAME_LENGTH"},
877 {0x0007, "URB_FUNCTION_GET_CURRENT_FRAME_NUMBER"},
878 {0x0008, "URB_FUNCTION_CONTROL_TRANSFER"},
879 {0x0009, "URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER"},
880 {0x000A, "URB_FUNCTION_ISOCH_TRANSFER"},
881 {0x000B, "URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE"},
882 {0x000C, "URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE"},
883 {0x000D, "URB_FUNCTION_SET_FEATURE_TO_DEVICE"},
884 {0x000E, "URB_FUNCTION_SET_FEATURE_TO_INTERFACE"},
885 {0x000F, "URB_FUNCTION_SET_FEATURE_TO_ENDPOINT"},
886 {0x0010, "URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE"},
887 {0x0011, "URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE"},
888 {0x0012, "URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT"},
889 {0x0013, "URB_FUNCTION_GET_STATUS_FROM_DEVICE"},
890 {0x0014, "URB_FUNCTION_GET_STATUS_FROM_INTERFACE"},
891 {0x0015, "URB_FUNCTION_GET_STATUS_FROM_ENDPOINT"},
892 {0x0016, "URB_FUNCTION_RESERVED_0X0016"},
893 {0x0017, "URB_FUNCTION_VENDOR_DEVICE"},
894 {0x0018, "URB_FUNCTION_VENDOR_INTERFACE"},
895 {0x0019, "URB_FUNCTION_VENDOR_ENDPOINT"},
896 {0x001A, "URB_FUNCTION_CLASS_DEVICE"},
897 {0x001B, "URB_FUNCTION_CLASS_INTERFACE"},
898 {0x001C, "URB_FUNCTION_CLASS_ENDPOINT"},
899 {0x001D, "URB_FUNCTION_RESERVE_0X001D"},
900 {0x001E, "URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL"},
901 {0x001F, "URB_FUNCTION_CLASS_OTHER"},
902 {0x0020, "URB_FUNCTION_VENDOR_OTHER"},
903 {0x0021, "URB_FUNCTION_GET_STATUS_FROM_OTHER"},
904 {0x0022, "URB_FUNCTION_CLEAR_FEATURE_TO_OTHER"},
905 {0x0023, "URB_FUNCTION_SET_FEATURE_TO_OTHER"},
906 {0x0024, "URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT"},
907 {0x0025, "URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT"},
908 {0x0026, "URB_FUNCTION_GET_CONFIGURATION"},
909 {0x0027, "URB_FUNCTION_GET_INTERFACE"},
910 {0x0028, "URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE"},
911 {0x0029, "URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE"},
912 {0x002A, "URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR"},
913 {0x002B, "URB_FUNCTION_RESERVE_0X002B"},
914 {0x002C, "URB_FUNCTION_RESERVE_0X002C"},
915 {0x002D, "URB_FUNCTION_RESERVE_0X002D"},
916 {0x002E, "URB_FUNCTION_RESERVE_0X002E"},
917 {0x002F, "URB_FUNCTION_RESERVE_0X002F"},
918 {0x0030, "URB_FUNCTION_SYNC_RESET_PIPE"},
919 {0x0031, "URB_FUNCTION_SYNC_CLEAR_STALL"},
920 {0x0032, "URB_FUNCTION_CONTROL_TRANSFER_EX"},
921 {0x0033, "URB_FUNCTION_RESERVE_0X0033"},
922 {0x0034, "URB_FUNCTION_RESERVE_0X0034"},
923 {0, NULL}
925 value_string_ext win32_urb_function_vals_ext = VALUE_STRING_EXT_INIT(win32_urb_function_vals);
927 static const value_string win32_usbd_status_vals[] = {
928 {0x00000000, "USBD_STATUS_SUCCESS"},
929 {0x40000000, "USBD_STATUS_PENDING"},
931 {0x80000200, "USBD_STATUS_INVALID_URB_FUNCTION"},
932 {0x80000300, "USBD_STATUS_INVALID_PARAMETER"},
933 {0x80000400, "USBD_STATUS_ERROR_BUSY"},
934 {0x80000600, "USBD_STATUS_INVALID_PIPE_HANDLE"},
935 {0x80000700, "USBD_STATUS_NO_BANDWIDTH"},
936 {0x80000800, "USBD_STATUS_INTERNAL_HC_ERROR"},
937 {0x80000900, "USBD_STATUS_ERROR_SHORT_TRANSFER"},
939 {0xC0000001, "USBD_STATUS_CRC"},
940 {0xC0000002, "USBD_STATUS_BTSTUFF"},
941 {0xC0000003, "USBD_STATUS_DATA_TOGGLE_MISMATCH"},
942 {0xC0000004, "USBD_STATUS_STALL_PID"},
943 {0xC0000005, "USBD_STATUS_DEV_NOT_RESPONDING"},
944 {0xC0000006, "USBD_STATUS_PID_CHECK_FAILURE"},
945 {0xC0000007, "USBD_STATUS_UNEXPECTED_PID"},
946 {0xC0000008, "USBD_STATUS_DATA_OVERRUN"},
947 {0xC0000009, "USBD_STATUS_DATA_UNDERRUN"},
948 {0xC000000A, "USBD_STATUS_RESERVED1"},
949 {0xC000000B, "USBD_STATUS_RESERVED2"},
950 {0xC000000C, "USBD_STATUS_BUFFER_OVERRUN"},
951 {0xC000000D, "USBD_STATUS_BUFFER_UNDERRUN"},
952 {0xC000000F, "USBD_STATUS_NOT_ACCESSED"},
953 {0xC0000010, "USBD_STATUS_FIFO"},
954 {0xC0000011, "USBD_STATUS_XACT_ERROR"},
955 {0xC0000012, "USBD_STATUS_BABBLE_DETECTED"},
956 {0xC0000013, "USBD_STATUS_DATA_BUFFER_ERROR"},
957 {0xC0000030, "USBD_STATUS_ENDPOINT_HALTED"},
959 {0xC0000A00, "USBD_STATUS_BAD_START_FRAME"},
960 {0xC0000B00, "USBD_STATUS_ISOCH_REQUEST_FAILED"},
961 {0xC0000C00, "USBD_STATUS_FRAME_CONTROL_OWNED"},
962 {0xC0000D00, "USBD_STATUS_FRAME_CONTROL_NOT_OWNED"},
963 {0xC0000E00, "USBD_STATUS_NOT_SUPPORTED"},
964 {0xC0000F00, "USBD_STATUS_INVALID_CONFIGURATION_DESCRIPTOR"},
965 {0xC0001000, "USBD_STATUS_INSUFFICIENT_RESOURCES"},
966 {0xC0002000, "USBD_STATUS_SET_CONFIG_FAILED"},
967 {0xC0003000, "USBD_STATUS_BUFFER_TOO_SMALL"},
968 {0xC0004000, "USBD_STATUS_INTERFACE_NOT_FOUND"},
969 {0xC0005000, "USBD_STATUS_INVALID_PIPE_FLAGS"},
970 {0xC0006000, "USBD_STATUS_TIMEOUT"},
971 {0xC0007000, "USBD_STATUS_DEVICE_GONE"},
972 {0xC0008000, "USBD_STATUS_STATUS_NOT_MAPPED"},
973 {0xC0009000, "USBD_STATUS_HUB_INTERNAL_ERROR"},
974 {0xC0010000, "USBD_STATUS_CANCELED"},
975 {0xC0020000, "USBD_STATUS_ISO_NOT_ACCESSED_BY_HW"},
976 {0xC0030000, "USBD_STATUS_ISO_TD_ERROR"},
977 {0xC0040000, "USBD_STATUS_ISO_NA_LATE_USBPORT"},
978 {0xC0050000, "USBD_STATUS_ISO_NOT_ACCESSED_LATE"},
979 {0xC0100000, "USBD_STATUS_BAD_DESCRIPTOR"},
980 {0xC0100001, "USBD_STATUS_BAD_DESCRIPTOR_BLEN"},
981 {0xC0100002, "USBD_STATUS_BAD_DESCRIPTOR_TYPE"},
982 {0xC0100003, "USBD_STATUS_BAD_INTERFACE_DESCRIPTOR"},
983 {0xC0100004, "USBD_STATUS_BAD_ENDPOINT_DESCRIPTOR"},
984 {0xC0100005, "USBD_STATUS_BAD_INTERFACE_ASSOC_DESCRIPTOR"},
985 {0xC0100006, "USBD_STATUS_BAD_CONFIG_DESC_LENGTH"},
986 {0xC0100007, "USBD_STATUS_BAD_NUMBER_OF_INTERFACES"},
987 {0xC0100008, "USBD_STATUS_BAD_NUMBER_OF_ENDPOINTS"},
988 {0xC0100009, "USBD_STATUS_BAD_ENDPOINT_ADDRESS"},
989 {0, NULL}
992 static const value_string win32_usb_info_direction_vals[] = {
993 {0, "FDO -> PDO"},
994 {1, "PDO -> FDO"},
995 {0, NULL}
998 static const value_string usb_cdc_protocol_vals[] = {
999 {0x00, "No class specific protocol required"},
1000 {0x01, "AT Commands: V.250 etc"},
1001 {0x02, "AT Commands defined by PCCA-101"},
1002 {0x03, "AT Commands defined by PCCA-101 & Annex O"},
1003 {0x04, "AT Commands defined by GSM 07.07"},
1004 {0x05, "AT Commands defined by 3GPP 27.007"},
1005 {0x06, "AT Commands defined by TIA for CDMA"},
1006 {0x07, "Ethernet Emulation Model"},
1007 {0xFE, "External Protocol: Commands defined by Command Set Functional Descriptor"},
1008 {0xFF, "Vendor-specific"},
1009 {0, NULL}
1012 static const value_string usb_cdc_data_protocol_vals[] = {
1013 {0x00, "No class specific protocol required"},
1014 {0x01, "Network Transfer Block"},
1015 {0x02, "Network Transfer Block (IP + DSS)"},
1016 {0x30, "Physical interface protocol for ISDN BRI"},
1017 {0x31, "HDLC"},
1018 {0x32, "Transparent"},
1019 {0x50, "Management protocol for Q.921 data link protocol"},
1020 {0x51, "Data link protocol for Q.931"},
1021 {0x52, "TEI-multiplexor for Q.921 data link protocol"},
1022 {0x90, "Data compression procedures"},
1023 {0x91, "Euro-ISDN protocol control"},
1024 {0x92, "V.24 rate adaptation to ISDN"},
1025 {0x93, "CAPI Commands"},
1026 {0xFE, "The protocol(s) are described using a Protocol Unit Functional Descriptors on Communications Class Interface"},
1027 {0xFF, "Vendor-specific"},
1028 {0, NULL}
1031 static const value_string usb_hid_subclass_vals[] = {
1032 {0, "No Subclass"},
1033 {1, "Boot Interface"},
1034 {0, NULL}
1037 static const value_string usb_hid_boot_protocol_vals[] = {
1038 {0, "None"},
1039 {1, "Keyboard"},
1040 {2, "Mouse"},
1041 {0, NULL}
1044 void proto_register_usb(void);
1045 void proto_reg_handoff_usb(void);
1047 static usb_conv_info_t *
1048 get_usb_conv_info(conversation_t *conversation)
1050 usb_conv_info_t *usb_conv_info;
1052 /* do we have conversation specific data ? */
1053 usb_conv_info = (usb_conv_info_t *)conversation_get_proto_data(conversation, proto_usb);
1054 if (!usb_conv_info) {
1055 /* no not yet so create some */
1056 usb_conv_info = wmem_new0(wmem_file_scope(), usb_conv_info_t);
1057 usb_conv_info->interfaceClass = IF_CLASS_UNKNOWN;
1058 usb_conv_info->interfaceSubclass = IF_SUBCLASS_UNKNOWN;
1059 usb_conv_info->interfaceProtocol = IF_PROTOCOL_UNKNOWN;
1060 usb_conv_info->deviceVendor = DEV_VENDOR_UNKNOWN;
1061 usb_conv_info->deviceProduct = DEV_PRODUCT_UNKNOWN;
1062 usb_conv_info->transactions = wmem_tree_new(wmem_file_scope());
1064 conversation_add_proto_data(conversation, proto_usb, usb_conv_info);
1067 return usb_conv_info;
1070 static conversation_t *
1071 get_usb_conversation(packet_info *pinfo,
1072 address *src_addr, address *dst_addr,
1073 guint32 src_endpoint, guint32 dst_endpoint)
1075 conversation_t *conversation;
1078 * Do we have a conversation for this connection?
1080 conversation = find_conversation(pinfo->fd->num,
1081 src_addr, dst_addr,
1082 pinfo->ptype,
1083 src_endpoint, dst_endpoint, 0);
1084 if (conversation) {
1085 return conversation;
1088 /* We don't yet have a conversation, so create one. */
1089 conversation = conversation_new(pinfo->fd->num,
1090 src_addr, dst_addr,
1091 pinfo->ptype,
1092 src_endpoint, dst_endpoint, 0);
1093 return conversation;
1096 /* Fetch or create usb_conv_info for a specified interface. */
1097 usb_conv_info_t *
1098 get_usb_iface_conv_info(packet_info *pinfo, guint8 interface_num)
1100 conversation_t *conversation;
1101 guint32 if_port;
1103 if_port = htolel(INTERFACE_PORT | interface_num);
1105 if (pinfo->srcport == NO_ENDPOINT) {
1106 conversation = get_usb_conversation(pinfo, &pinfo->src, &pinfo->dst, pinfo->srcport, if_port);
1107 } else {
1108 conversation = get_usb_conversation(pinfo, &pinfo->src, &pinfo->dst, if_port, pinfo->destport);
1111 return get_usb_conv_info(conversation);
1115 /* SETUP dissectors */
1119 * These dissectors are used to dissect the setup part and the data
1120 * for URB_CONTROL_INPUT / CLEAR FEATURE
1124 /* 9.4.1 */
1125 static int
1126 dissect_usb_setup_clear_feature_request(packet_info *pinfo _U_, proto_tree *tree,
1127 tvbuff_t *tvb, int offset,
1128 usb_trans_info_t *usb_trans_info _U_,
1129 usb_conv_info_t *usb_conv_info _U_,
1130 guint bus_id _U_, guint device_address _U_)
1132 /* feature selector */
1133 proto_tree_add_item(tree, hf_usb_wFeatureSelector, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1134 offset += 2;
1136 /* zero/interface/endpoint */
1137 /* XXX - check based on request type */
1138 proto_tree_add_item(tree, hf_usb_wInterface, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1139 offset += 2;
1141 /* length */
1142 proto_tree_add_item(tree, hf_usb_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1143 offset += 2;
1145 return offset;
1148 static int
1149 dissect_usb_setup_clear_feature_response(packet_info *pinfo _U_, proto_tree *tree _U_,
1150 tvbuff_t *tvb _U_, int offset,
1151 usb_trans_info_t *usb_trans_info _U_,
1152 usb_conv_info_t *usb_conv_info _U_,
1153 guint bus_id _U_, guint device_address _U_)
1155 return offset;
1160 * These dissectors are used to dissect the setup part and the data
1161 * for URB_CONTROL_INPUT / GET CONFIGURATION
1165 /* 9.4.2 */
1166 static int
1167 dissect_usb_setup_get_configuration_response(packet_info *pinfo _U_, proto_tree *tree _U_,
1168 tvbuff_t *tvb _U_, int offset,
1169 usb_trans_info_t *usb_trans_info _U_,
1170 usb_conv_info_t *usb_conv_info _U_,
1171 guint bus_id _U_, guint device_address _U_)
1173 proto_tree_add_item(tree, hf_usb_bConfigurationValue, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1174 offset += 1;
1176 return offset;
1181 * These dissectors are used to dissect the setup part and the data
1182 * for URB_CONTROL_INPUT / GET DESCRIPTOR
1185 void dissect_usb_descriptor_header(proto_tree *tree,
1186 tvbuff_t *tvb, int offset,
1187 value_string_ext *type_val_str)
1189 guint8 desc_type;
1190 proto_item *type_item = NULL;
1193 proto_tree_add_item(tree, hf_usb_bLength,
1194 tvb, offset, 1, ENC_LITTLE_ENDIAN);
1195 offset++;
1197 desc_type = tvb_get_guint8(tvb, offset);
1198 type_item = proto_tree_add_item(tree, hf_usb_bDescriptorType,
1199 tvb, offset, 1, ENC_LITTLE_ENDIAN);
1200 /* if the caller provided no class specific value string, we're
1201 * using the standard descriptor types */
1202 if (!type_val_str)
1203 type_val_str = &std_descriptor_type_vals_ext;
1204 proto_item_append_text(type_item, " (%s)",
1205 val_to_str_ext(desc_type, type_val_str, "unknown"));
1208 /* 9.6.2 */
1209 static int
1210 dissect_usb_device_qualifier_descriptor(packet_info *pinfo _U_, proto_tree *parent_tree,
1211 tvbuff_t *tvb, int offset,
1212 usb_trans_info_t *usb_trans_info _U_,
1213 usb_conv_info_t *usb_conv_info _U_,
1214 guint bus_id, guint device_address)
1216 proto_item *item = NULL;
1217 proto_tree *tree = NULL;
1218 proto_item *nitem = NULL;
1219 int old_offset = offset;
1220 guint32 protocol;
1221 const gchar *description;
1223 if (parent_tree) {
1224 item = proto_tree_add_text(parent_tree, tvb, offset, -1, "DEVICE QUALIFIER DESCRIPTOR");
1225 tree = proto_item_add_subtree(item, ett_descriptor_device);
1228 dissect_usb_descriptor_header(tree, tvb, offset, NULL);
1229 offset += 2;
1231 /* bcdUSB */
1232 proto_tree_add_item(tree, hf_usb_bcdUSB, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1233 offset += 2;
1235 protocol = tvb_get_ntoh24(tvb, offset);
1236 description = val_to_str_const(protocol, usb_protocols, "");
1238 /* bDeviceClass */
1239 proto_tree_add_item(tree, hf_usb_bDeviceClass, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1240 offset += 1;
1242 /* bDeviceSubClass */
1243 proto_tree_add_item(tree, hf_usb_bDeviceSubClass, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1244 offset += 1;
1246 /* bDeviceProtocol */
1247 nitem = proto_tree_add_item(tree, hf_usb_bDeviceProtocol, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1248 if (*description)
1249 proto_item_append_text(nitem, " (%s)", description);
1250 offset += 1;
1252 if (!pinfo->fd->flags.visited) {
1253 guint k_bus_id;
1254 guint k_device_address;
1255 guint k_frame_number;
1256 wmem_tree_key_t key[4];
1257 device_protocol_data_t *device_protocol_data;
1259 k_frame_number = pinfo->fd->num;
1260 k_device_address = device_address;
1261 k_bus_id = bus_id;
1263 key[0].length = 1;
1264 key[0].key = &k_device_address;
1265 key[1].length = 1;
1266 key[1].key = &k_bus_id;
1267 key[2].length = 1;
1268 key[2].key = &k_frame_number;
1269 key[3].length = 0;
1270 key[3].key = NULL;
1272 device_protocol_data = wmem_new(wmem_file_scope(), device_protocol_data_t);
1273 device_protocol_data->protocol = protocol;
1274 device_protocol_data->bus_id = bus_id;
1275 device_protocol_data->device_address = device_address;
1276 wmem_tree_insert32_array(device_to_protocol_table, key, device_protocol_data);
1279 /* bMaxPacketSize0 */
1280 proto_tree_add_item(tree, hf_usb_bMaxPacketSize0, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1281 offset += 1;
1283 /* bNumConfigurations */
1284 proto_tree_add_item(tree, hf_usb_bNumConfigurations, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1285 offset += 1;
1287 /* one reserved byte */
1288 offset += 1;
1290 if (item) {
1291 proto_item_set_len(item, offset-old_offset);
1294 return offset;
1297 /* 9.6.1 */
1298 static int
1299 dissect_usb_device_descriptor(packet_info *pinfo, proto_tree *parent_tree,
1300 tvbuff_t *tvb, int offset,
1301 usb_trans_info_t *usb_trans_info _U_,
1302 guint bus_id, guint device_address, usb_conv_info_t *usb_conv_info)
1304 proto_item *item = NULL;
1305 proto_tree *tree = NULL;
1306 proto_item *nitem = NULL;
1307 int old_offset = offset;
1308 guint32 protocol;
1309 const gchar *description;
1310 guint16 vendor_id;
1311 guint32 product;
1312 guint16 product_id;
1313 guint8 *field_description;
1314 gint field_description_length;
1315 header_field_info *hfi;
1317 if (parent_tree) {
1318 item = proto_tree_add_text(parent_tree, tvb, offset, -1, "DEVICE DESCRIPTOR");
1319 tree = proto_item_add_subtree(item, ett_descriptor_device);
1322 dissect_usb_descriptor_header(tree, tvb, offset, NULL);
1323 offset += 2;
1325 /* bcdUSB */
1326 proto_tree_add_item(tree, hf_usb_bcdUSB, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1327 offset += 2;
1329 protocol = tvb_get_ntoh24(tvb, offset);
1330 description = val_to_str_const(protocol, usb_protocols, "");
1332 /* bDeviceClass */
1333 proto_tree_add_item(tree, hf_usb_bDeviceClass, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1334 offset += 1;
1336 /* bDeviceSubClass */
1337 proto_tree_add_item(tree, hf_usb_bDeviceSubClass, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1338 offset += 1;
1340 /* bDeviceProtocol */
1341 nitem = proto_tree_add_item(tree, hf_usb_bDeviceProtocol, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1342 if (*description)
1343 proto_item_append_text(nitem, " (%s)", description);
1344 offset += 1;
1346 /* bMaxPacketSize0 */
1347 proto_tree_add_item(tree, hf_usb_bMaxPacketSize0, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1348 offset += 1;
1350 /* idVendor */
1351 proto_tree_add_item(tree, hf_usb_idVendor, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1352 vendor_id = tvb_get_letohs(tvb, offset);
1353 usb_conv_info->deviceVendor = vendor_id;
1354 offset += 2;
1356 /* idProduct */
1357 nitem = proto_tree_add_item(tree, hf_usb_idProduct, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1358 product_id = tvb_get_letohs(tvb, offset);
1359 usb_conv_info->deviceProduct = product_id;
1360 product = vendor_id << 16 | product_id;
1362 hfi = proto_registrar_get_nth(hf_usb_idProduct);
1363 field_description_length = (gint)strlen(hfi->name) + 14;
1364 field_description = (guint8 *)wmem_alloc(wmem_packet_scope(), field_description_length);
1365 g_strlcpy(field_description, hfi->name, field_description_length);
1366 g_strlcat(field_description, ": %s (0x%04x)", field_description_length);
1368 proto_item_set_text(nitem, field_description,
1369 val_to_str_ext_const(product, &ext_usb_products_vals, "Unknown"),
1370 product_id);
1371 offset += 2;
1373 if (!pinfo->fd->flags.visited) {
1374 guint k_bus_id;
1375 guint k_device_address;
1376 guint k_frame_number;
1377 wmem_tree_key_t key[4];
1378 device_product_data_t *device_product_data;
1379 device_protocol_data_t *device_protocol_data;
1381 k_frame_number = pinfo->fd->num;
1382 k_device_address = device_address;
1383 k_bus_id = bus_id;
1385 key[0].length = 1;
1386 key[0].key = &k_device_address;
1387 key[1].length = 1;
1388 key[1].key = &k_bus_id;
1389 key[2].length = 1;
1390 key[2].key = &k_frame_number;
1391 key[3].length = 0;
1392 key[3].key = NULL;
1394 device_product_data = wmem_new(wmem_file_scope(), device_product_data_t);
1395 device_product_data->vendor = vendor_id;
1396 device_product_data->product = product_id;
1397 device_product_data->bus_id = bus_id;
1398 device_product_data->device_address = device_address;
1399 wmem_tree_insert32_array(device_to_product_table, key, device_product_data);
1401 device_protocol_data = wmem_new(wmem_file_scope(), device_protocol_data_t);
1402 device_protocol_data->protocol = protocol;
1403 device_protocol_data->bus_id = bus_id;
1404 device_protocol_data->device_address = device_address;
1406 wmem_tree_insert32_array(device_to_protocol_table, key, device_protocol_data);
1409 /* bcdDevice */
1410 proto_tree_add_item(tree, hf_usb_bcdDevice, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1411 offset += 2;
1413 /* iManufacturer */
1414 proto_tree_add_item(tree, hf_usb_iManufacturer, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1415 offset += 1;
1417 /* iProduct */
1418 proto_tree_add_item(tree, hf_usb_iProduct, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1419 offset += 1;
1421 /* iSerialNumber */
1422 proto_tree_add_item(tree, hf_usb_iSerialNumber, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1423 offset += 1;
1425 /* bNumConfigurations */
1426 proto_tree_add_item(tree, hf_usb_bNumConfigurations, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1427 offset += 1;
1429 if (item) {
1430 proto_item_set_len(item, offset-old_offset);
1433 return offset;
1436 /* 9.6.7 */
1437 static int
1438 dissect_usb_string_descriptor(packet_info *pinfo _U_, proto_tree *parent_tree,
1439 tvbuff_t *tvb, int offset,
1440 usb_trans_info_t *usb_trans_info,
1441 usb_conv_info_t *usb_conv_info _U_)
1443 proto_item *item = NULL;
1444 proto_tree *tree = NULL;
1445 int old_offset = offset;
1446 guint8 len;
1448 if (parent_tree) {
1449 item = proto_tree_add_text(parent_tree, tvb, offset, -1, "STRING DESCRIPTOR");
1450 tree = proto_item_add_subtree(item, ett_descriptor_device);
1453 len = tvb_get_guint8(tvb, offset);
1454 /* The USB spec says that the languages / the string are UTF16 and not
1455 0-terminated, i.e. the length field must contain an even number */
1456 if (len & 0x1) {
1457 proto_item *len_item;
1459 /* bLength */
1460 len_item = proto_tree_add_item(tree, hf_usb_bLength, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1461 expert_add_info(pinfo, len_item, &ei_usb_bLength_even);
1463 /* bDescriptorType */
1464 proto_tree_add_item(tree, hf_usb_bDescriptorType, tvb, offset+1, 1, ENC_LITTLE_ENDIAN);
1466 else
1467 dissect_usb_descriptor_header(tree, tvb, offset, NULL);
1469 offset += 2;
1471 if (!usb_trans_info->u.get_descriptor.index) {
1472 /* list of languanges */
1473 while(len>(offset-old_offset)) {
1474 /* wLANGID */
1475 proto_tree_add_item(tree, hf_usb_wLANGID, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1476 offset+=2;
1478 } else {
1479 char *str;
1480 guint8 str_len;
1482 /* Make sure that tvb_get_unicode_string() gets an even
1483 string length even if the length field contains an (invalid)
1484 odd number.
1486 str_len = (len-2) & ~0x1;
1488 /* unicode string */
1489 str = tvb_get_unicode_string(wmem_packet_scope(), tvb, offset, str_len, ENC_LITTLE_ENDIAN);
1490 proto_tree_add_string(tree, hf_usb_bString, tvb, offset, len-2, str);
1491 offset += len-2;
1494 if (item) {
1495 proto_item_set_len(item, offset-old_offset);
1498 return offset;
1503 /* 9.6.5 */
1504 static int
1505 dissect_usb_interface_descriptor(packet_info *pinfo, proto_tree *parent_tree,
1506 tvbuff_t *tvb, int offset,
1507 usb_trans_info_t *usb_trans_info,
1508 usb_conv_info_t *usb_conv_info)
1510 proto_item *item = NULL;
1511 proto_tree *tree = NULL;
1512 const char *class_str = NULL;
1513 int old_offset = offset;
1514 guint8 len;
1515 guint8 interface_num;
1516 guint8 alt_setting;
1518 if (parent_tree) {
1519 item = proto_tree_add_text(parent_tree, tvb, offset, -1, "INTERFACE DESCRIPTOR");
1520 tree = proto_item_add_subtree(item, ett_descriptor_device);
1523 len = tvb_get_guint8(tvb, offset);
1524 dissect_usb_descriptor_header(tree, tvb, offset, NULL);
1525 offset += 2;
1527 /* bInterfaceNumber */
1528 interface_num = tvb_get_guint8(tvb, offset);
1529 proto_tree_add_item(tree, hf_usb_bInterfaceNumber, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1530 usb_conv_info->interfaceNum = interface_num;
1531 offset += 1;
1533 /* bAlternateSetting */
1534 alt_setting = tvb_get_guint8(tvb, offset);
1535 proto_tree_add_item(tree, hf_usb_bAlternateSetting, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1536 offset += 1;
1538 /* bNumEndpoints */
1539 proto_tree_add_item(tree, hf_usb_bNumEndpoints, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1540 offset += 1;
1542 /* bInterfaceClass */
1543 proto_tree_add_item(tree, hf_usb_bInterfaceClass, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1544 /* save the class so we can access it later in the endpoint descriptor */
1545 usb_conv_info->interfaceClass = tvb_get_guint8(tvb, offset);
1547 class_str = val_to_str_ext(usb_conv_info->interfaceClass, &usb_class_vals_ext, "unknown (0x%X)");
1548 proto_item_append_text(item, " (%u.%u): class %s", interface_num, alt_setting, class_str);
1550 if (!pinfo->fd->flags.visited && (alt_setting == 0)) {
1551 /* Register conversation for this interface in case CONTROL messages are sent to it */
1552 usb_trans_info->interface_info = get_usb_iface_conv_info(pinfo, interface_num);
1553 usb_trans_info->interface_info->interfaceClass = tvb_get_guint8(tvb, offset);
1554 /* save information useful to class-specific dissectors */
1555 usb_trans_info->interface_info->interfaceSubclass = tvb_get_guint8(tvb, offset+1);
1556 usb_trans_info->interface_info->interfaceProtocol = tvb_get_guint8(tvb, offset+2);
1557 usb_trans_info->interface_info->deviceVendor = usb_conv_info->deviceVendor;
1558 usb_trans_info->interface_info->deviceProduct = usb_conv_info->deviceProduct;
1560 offset += 1;
1562 /* bInterfaceSubClass */
1563 switch (usb_conv_info->interfaceClass) {
1564 case IF_CLASS_COMMUNICATIONS:
1565 proto_tree_add_item(tree, hf_usb_bInterfaceSubClass_cdc, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1566 break;
1567 case IF_CLASS_HID:
1568 proto_tree_add_item(tree, hf_usb_bInterfaceSubClass_hid, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1569 break;
1570 default:
1571 proto_tree_add_item(tree, hf_usb_bInterfaceSubClass, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1574 /* save the subclass so we can access it later in class-specific descriptors */
1575 usb_conv_info->interfaceSubclass = tvb_get_guint8(tvb, offset);
1576 offset += 1;
1578 /* bInterfaceProtocol */
1579 switch (usb_conv_info->interfaceClass) {
1580 case IF_CLASS_COMMUNICATIONS:
1581 proto_tree_add_item(tree, hf_usb_bInterfaceProtocol_cdc, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1582 break;
1583 case IF_CLASS_CDC_DATA:
1584 proto_tree_add_item(tree, hf_usb_bInterfaceProtocol_cdc_data, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1585 break;
1586 case IF_CLASS_HID:
1587 if (usb_conv_info->interfaceSubclass == 1) {
1588 proto_tree_add_item(tree, hf_usb_bInterfaceProtocol_hid_boot, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1589 break;
1590 } /* else default */
1591 default:
1592 proto_tree_add_item(tree, hf_usb_bInterfaceProtocol, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1595 usb_conv_info->interfaceProtocol = tvb_get_guint8(tvb, offset);
1596 offset += 1;
1598 /* iInterface */
1599 proto_tree_add_item(tree, hf_usb_iInterface, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1600 offset += 1;
1602 if (item) {
1603 proto_item_set_len(item, len);
1605 if (offset < old_offset+len) {
1606 /* skip unknown records */
1607 offset = old_offset + len;
1610 return offset;
1613 /* 9.6.6 */
1614 static const true_false_string tfs_endpoint_direction = {
1615 "IN Endpoint",
1616 "OUT Endpoint"
1619 void dissect_usb_endpoint_address(proto_tree *tree, tvbuff_t *tvb, int offset)
1621 proto_item *endpoint_item = NULL;
1622 proto_tree *endpoint_tree = NULL;
1623 guint8 endpoint;
1625 if (tree) {
1626 endpoint_item = proto_tree_add_item(tree, hf_usb_bEndpointAddress, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1627 endpoint_tree = proto_item_add_subtree(endpoint_item, ett_configuration_bEndpointAddress);
1629 endpoint = tvb_get_guint8(tvb, offset)&0x0f;
1630 proto_tree_add_item(endpoint_tree, hf_usb_bEndpointAddress_direction, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1631 proto_item_append_text(endpoint_item, " %s", (tvb_get_guint8(tvb, offset)&0x80)?"IN":"OUT");
1632 proto_tree_add_item(endpoint_tree, hf_usb_bEndpointAddress_number, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1633 proto_item_append_text(endpoint_item, " Endpoint:%d", endpoint);
1636 static int
1637 dissect_usb_endpoint_descriptor(packet_info *pinfo, proto_tree *parent_tree,
1638 tvbuff_t *tvb, int offset,
1639 usb_trans_info_t *usb_trans_info _U_,
1640 usb_conv_info_t *usb_conv_info _U_)
1642 proto_item *item = NULL;
1643 proto_tree *tree = NULL;
1644 proto_item *ep_attrib_item = NULL;
1645 proto_tree *ep_attrib_tree = NULL;
1646 proto_item *ep_pktsize_item;
1647 proto_tree *ep_pktsize_tree;
1648 int old_offset = offset;
1649 guint8 endpoint;
1650 guint8 ep_type;
1651 guint8 len;
1653 if (parent_tree) {
1654 item = proto_tree_add_text(parent_tree, tvb, offset, -1, "ENDPOINT DESCRIPTOR");
1655 tree = proto_item_add_subtree(item, ett_descriptor_device);
1658 len = tvb_get_guint8(tvb, offset);
1659 dissect_usb_descriptor_header(tree, tvb, offset, NULL);
1660 offset += 2;
1662 endpoint = tvb_get_guint8(tvb, offset)&0x0f;
1663 dissect_usb_endpoint_address(tree, tvb, offset);
1664 offset += 1;
1666 /* Together with class from the interface descriptor we know what kind
1667 * of class the device at endpoint is.
1668 * Make sure a conversation exists for this endpoint and attach a
1669 * usb_conv_into_t structure to it.
1671 * All endpoints for the same interface descriptor share the same
1672 * usb_conv_info structure.
1674 if ((!pinfo->fd->flags.visited)&&usb_trans_info->interface_info) {
1675 conversation_t *conversation;
1677 if (pinfo->destport == NO_ENDPOINT) {
1678 static address tmp_addr;
1679 static usb_address_t usb_addr;
1681 /* Create a new address structure that points to the same device
1682 * but the new endpoint.
1684 usb_addr.device = ((const usb_address_t *)(pinfo->src.data))->device;
1685 usb_addr.endpoint = htolel(endpoint);
1686 SET_ADDRESS(&tmp_addr, AT_USB, USB_ADDR_LEN, (char *)&usb_addr);
1687 conversation = get_usb_conversation(pinfo, &tmp_addr, &pinfo->dst, usb_addr.endpoint, pinfo->destport);
1688 } else {
1689 static address tmp_addr;
1690 static usb_address_t usb_addr;
1692 /* Create a new address structure that points to the same device
1693 * but the new endpoint.
1695 usb_addr.device = ((const usb_address_t *)(pinfo->dst.data))->device;
1696 usb_addr.endpoint = htolel(endpoint);
1697 SET_ADDRESS(&tmp_addr, AT_USB, USB_ADDR_LEN, (char *)&usb_addr);
1698 conversation = get_usb_conversation(pinfo, &pinfo->src, &tmp_addr, pinfo->srcport, usb_addr.endpoint);
1701 conversation_add_proto_data(conversation, proto_usb, usb_trans_info->interface_info);
1704 /* bmAttributes */
1705 ep_type = ENDPOINT_TYPE(tvb_get_guint8(tvb, offset));
1706 if (tree) {
1707 ep_attrib_item = proto_tree_add_item(tree, hf_usb_bmAttributes, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1708 ep_attrib_tree = proto_item_add_subtree(ep_attrib_item, ett_endpoint_bmAttributes);
1710 proto_tree_add_item(ep_attrib_tree, hf_usb_bEndpointAttributeTransfer, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1711 /* isochronous only */
1712 proto_tree_add_item(ep_attrib_tree, hf_usb_bEndpointAttributeSynchonisation, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1713 /* isochronous only */
1714 proto_tree_add_item(ep_attrib_tree, hf_usb_bEndpointAttributeBehaviour, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1715 offset += 1;
1717 /* wMaxPacketSize */
1718 ep_pktsize_item = proto_tree_add_item(tree, hf_usb_wMaxPacketSize, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1719 ep_pktsize_tree = proto_item_add_subtree(ep_pktsize_item, ett_endpoint_wMaxPacketSize);
1720 if ((ep_type == ENDPOINT_TYPE_INTERRUPT) || (ep_type == ENDPOINT_TYPE_ISOCHRONOUS)) {
1721 proto_tree_add_item(ep_pktsize_tree, hf_usb_wMaxPacketSize_slots, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1723 proto_tree_add_item(ep_pktsize_tree, hf_usb_wMaxPacketSize_size, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1724 offset+=2;
1726 /* bInterval */
1727 proto_tree_add_item(tree, hf_usb_bInterval, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1728 offset += 1;
1730 if (item) {
1731 proto_item_set_len(item, len);
1733 if (offset < old_offset+len) {
1734 /* skip unknown records */
1735 offset = old_offset + len;
1738 return offset;
1741 /* ECN */
1742 static int
1743 dissect_usb_interface_assn_descriptor(packet_info *pinfo _U_, proto_tree *parent_tree,
1744 tvbuff_t *tvb, int offset,
1745 usb_trans_info_t *usb_trans_info _U_,
1746 usb_conv_info_t *usb_conv_info _U_)
1748 proto_item *item = NULL;
1749 proto_tree *tree = NULL;
1750 int old_offset = offset;
1752 if (parent_tree) {
1753 item = proto_tree_add_text(parent_tree, tvb, offset, -1, "INTERFACE ASSOCIATION DESCRIPTOR");
1754 tree = proto_item_add_subtree(item, ett_descriptor_device);
1757 dissect_usb_descriptor_header(tree, tvb, offset, NULL);
1758 offset += 2;
1760 /* bFirstInterface */
1761 proto_tree_add_item(tree, hf_usb_bFirstInterface, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1762 offset += 1;
1764 /* bInterfaceCount */
1765 proto_tree_add_item(tree, hf_usb_bInterfaceCount, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1766 offset += 1;
1768 /* bFunctionClass */
1769 proto_tree_add_item(tree, hf_usb_bFunctionClass, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1770 offset += 1;
1772 /* bFunctionSubclass */
1773 proto_tree_add_item(tree, hf_usb_bFunctionSubClass, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1774 offset += 1;
1776 /* bFunctionProtocol */
1777 proto_tree_add_item(tree, hf_usb_bFunctionProtocol, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1778 offset += 1;
1780 /* iFunction */
1781 proto_tree_add_item(tree, hf_usb_iFunction, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1782 offset += 1;
1784 if (item) {
1785 proto_item_set_len(item, offset-old_offset);
1788 return offset;
1791 static int
1792 dissect_usb_unknown_descriptor(packet_info *pinfo _U_, proto_tree *parent_tree,
1793 tvbuff_t *tvb, int offset,
1794 usb_trans_info_t *usb_trans_info _U_,
1795 usb_conv_info_t *usb_conv_info _U_)
1797 proto_item *item = NULL;
1798 proto_tree *tree = NULL;
1799 guint8 bLength;
1801 if (parent_tree) {
1802 item = proto_tree_add_text(parent_tree, tvb, offset, -1, "UNKNOWN DESCRIPTOR");
1803 tree = proto_item_add_subtree(item, ett_descriptor_device);
1806 bLength = tvb_get_guint8(tvb, offset);
1807 dissect_usb_descriptor_header(tree, tvb, offset, NULL);
1808 offset += bLength;
1810 if (item) {
1811 proto_item_set_len(item, bLength);
1814 return offset;
1817 /* 9.6.3 */
1818 static const true_false_string tfs_mustbeone = {
1819 "Must be 1 for USB 1.1 and higher",
1820 "FIXME: Is this a USB 1.0 device"
1822 static const true_false_string tfs_selfpowered = {
1823 "This device is SELF-POWERED",
1824 "This device is powered from the USB bus"
1826 static const true_false_string tfs_remotewakeup = {
1827 "This device supports REMOTE WAKEUP",
1828 "This device does NOT support remote wakeup"
1830 static int
1831 dissect_usb_configuration_descriptor(packet_info *pinfo _U_, proto_tree *parent_tree,
1832 tvbuff_t *tvb, int offset,
1833 usb_trans_info_t *usb_trans_info,
1834 usb_conv_info_t *usb_conv_info)
1836 proto_item *item = NULL;
1837 proto_tree *tree = NULL;
1838 int old_offset = offset;
1839 guint16 len;
1840 proto_item *flags_item = NULL;
1841 proto_tree *flags_tree = NULL;
1842 guint8 flags;
1843 proto_item *power_item;
1844 guint8 power;
1845 gboolean truncation_expected;
1847 usb_conv_info->interfaceClass = IF_CLASS_UNKNOWN;
1848 usb_conv_info->interfaceSubclass = IF_SUBCLASS_UNKNOWN;
1849 usb_conv_info->interfaceProtocol = IF_PROTOCOL_UNKNOWN;
1851 if (parent_tree) {
1852 item = proto_tree_add_text(parent_tree, tvb, offset, -1, "CONFIGURATION DESCRIPTOR");
1853 tree = proto_item_add_subtree(item, ett_descriptor_device);
1856 dissect_usb_descriptor_header(tree, tvb, offset, NULL);
1857 offset += 2;
1859 /* wTotalLength */
1860 proto_tree_add_item(tree, hf_usb_wTotalLength, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1861 len = tvb_get_letohs(tvb, offset);
1862 offset+=2;
1864 /* bNumInterfaces */
1865 proto_tree_add_item(tree, hf_usb_bNumInterfaces, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1866 offset += 1;
1868 /* bConfigurationValue */
1869 proto_tree_add_item(tree, hf_usb_bConfigurationValue, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1870 offset += 1;
1872 /* iConfiguration */
1873 proto_tree_add_item(tree, hf_usb_iConfiguration, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1874 offset += 1;
1876 /* bmAttributes */
1877 if (tree) {
1878 flags_item = proto_tree_add_item(tree, hf_usb_configuration_bmAttributes, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1879 flags_tree = proto_item_add_subtree(flags_item, ett_configuration_bmAttributes);
1881 flags = tvb_get_guint8(tvb, offset);
1882 proto_tree_add_item(flags_tree, hf_usb_configuration_legacy10buspowered, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1883 proto_tree_add_item(flags_tree, hf_usb_configuration_selfpowered, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1884 proto_item_append_text(flags_item, " %sSELF-POWERED", (flags&0x40)?"":"NOT ");
1885 proto_tree_add_item(flags_tree, hf_usb_configuration_remotewakeup, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1886 proto_item_append_text(flags_item, " %sREMOTE-WAKEUP", (flags&0x20)?"":"NO ");
1887 offset += 1;
1889 /* bMaxPower */
1890 power_item = proto_tree_add_item(tree, hf_usb_bMaxPower, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1891 power = tvb_get_guint8(tvb, offset);
1892 proto_item_append_text(power_item, " (%dmA)", power*2);
1893 offset += 1;
1895 /* initialize interface_info to NULL */
1896 usb_trans_info->interface_info = NULL;
1898 truncation_expected = (usb_trans_info->setup.wLength < len);
1900 /* decode any additional interface and endpoint descriptors */
1901 while(len>(offset-old_offset)) {
1902 guint8 next_type;
1903 guint8 next_len = 0;
1904 gint remaining_tvb, remaining_len;
1905 tvbuff_t *next_tvb = NULL;
1907 /* Handle truncated descriptors appropriately */
1908 remaining_tvb = tvb_length_remaining(tvb, offset);
1909 if (remaining_tvb > 0) {
1910 next_len = tvb_get_guint8(tvb, offset);
1911 remaining_len = len - (offset - old_offset);
1912 if ((next_len < 3) || (next_len > remaining_len)) {
1913 proto_tree_add_expert_format(parent_tree, pinfo, &ei_usb_desc_length_invalid,
1914 tvb, offset, 1, "Invalid descriptor length: %u", next_len);
1915 item = NULL;
1916 break;
1920 if ((remaining_tvb == 0) || (next_len > remaining_tvb)) {
1921 if (!truncation_expected) {
1922 THROW(ReportedBoundsError);
1924 break;
1927 next_type = tvb_get_guint8(tvb, offset+1);
1928 switch(next_type) {
1929 case USB_DT_INTERFACE:
1930 offset = dissect_usb_interface_descriptor(pinfo, parent_tree, tvb, offset, usb_trans_info, usb_conv_info);
1931 break;
1932 case USB_DT_ENDPOINT:
1933 offset = dissect_usb_endpoint_descriptor(pinfo, parent_tree, tvb, offset, usb_trans_info, usb_conv_info);
1934 break;
1935 case USB_DT_INTERFACE_ASSOCIATION:
1936 offset = dissect_usb_interface_assn_descriptor(pinfo, parent_tree, tvb, offset, usb_trans_info, usb_conv_info);
1937 break;
1938 default:
1939 next_tvb = tvb_new_subset(tvb, offset, next_len, next_len);
1940 if (dissector_try_uint_new(usb_descriptor_dissector_table, usb_conv_info->interfaceClass, next_tvb, pinfo, parent_tree, TRUE, usb_conv_info)) {
1941 offset += next_len;
1942 } else {
1943 offset = dissect_usb_unknown_descriptor(pinfo, parent_tree, tvb, offset, usb_trans_info, usb_conv_info);
1945 break;
1946 /* was: return offset; */
1950 if (item) {
1951 proto_item_set_len(item, offset-old_offset);
1954 /* Clear any class association from the Control endpoint.
1955 * We need the association temporarily, to establish
1956 * context for class-specific descriptor dissectors,
1957 * but the association must not persist beyond this function.
1958 * If it did, all traffic on the Control endpoint would be labeled
1959 * as belonging to the class of the last INTERFACE descriptor,
1960 * which would be especially inappropriate for composite devices.
1962 usb_conv_info->interfaceClass = IF_CLASS_UNKNOWN;
1963 usb_conv_info->interfaceSubclass = IF_SUBCLASS_UNKNOWN;
1964 usb_conv_info->interfaceProtocol = IF_PROTOCOL_UNKNOWN;
1966 return offset;
1969 /* 9.4.3 */
1970 static int
1971 dissect_usb_setup_get_descriptor_request(packet_info *pinfo, proto_tree *tree,
1972 tvbuff_t *tvb, int offset,
1973 usb_trans_info_t *usb_trans_info,
1974 usb_conv_info_t *usb_conv_info _U_,
1975 guint bus_id _U_, guint device_address _U_)
1977 /* descriptor index */
1978 proto_tree_add_item(tree, hf_usb_descriptor_index, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1979 usb_trans_info->u.get_descriptor.index = tvb_get_guint8(tvb, offset);
1980 offset += 1;
1982 /* descriptor type */
1983 proto_tree_add_item(tree, hf_usb_bDescriptorType, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1984 usb_trans_info->u.get_descriptor.type = tvb_get_guint8(tvb, offset);
1985 offset += 1;
1986 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
1987 val_to_str_ext(usb_trans_info->u.get_descriptor.type, &std_descriptor_type_vals_ext, "Unknown type %u"));
1989 /* language id */
1990 proto_tree_add_item(tree, hf_usb_language_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1991 offset+=2;
1993 /* length */
1994 proto_tree_add_item(tree, hf_usb_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1995 offset += 2;
1997 return offset;
2000 static int
2001 dissect_usb_setup_get_descriptor_response(packet_info *pinfo, proto_tree *tree,
2002 tvbuff_t *tvb, int offset,
2003 usb_trans_info_t *usb_trans_info,
2004 usb_conv_info_t *usb_conv_info,
2005 guint bus_id, guint device_address)
2008 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
2009 val_to_str_ext(usb_trans_info->u.get_descriptor.type, &std_descriptor_type_vals_ext, "Unknown type %u"));
2011 switch(usb_trans_info->u.get_descriptor.type) {
2012 case USB_DT_DEVICE:
2013 offset = dissect_usb_device_descriptor(pinfo, tree, tvb, offset, usb_trans_info, bus_id, device_address, usb_conv_info);
2014 break;
2015 case USB_DT_CONFIG:
2016 offset = dissect_usb_configuration_descriptor(pinfo, tree, tvb, offset, usb_trans_info, usb_conv_info);
2017 break;
2018 case USB_DT_STRING:
2019 offset = dissect_usb_string_descriptor(pinfo, tree, tvb, offset, usb_trans_info, usb_conv_info);
2020 break;
2021 case USB_DT_INTERFACE:
2022 offset = dissect_usb_interface_descriptor(pinfo, tree, tvb, offset, usb_trans_info, usb_conv_info);
2023 break;
2024 case USB_DT_ENDPOINT:
2025 offset = dissect_usb_endpoint_descriptor(pinfo, tree, tvb, offset, usb_trans_info, usb_conv_info);
2026 break;
2027 case USB_DT_DEVICE_QUALIFIER:
2028 offset = dissect_usb_device_qualifier_descriptor(pinfo, tree, tvb, offset, usb_trans_info, usb_conv_info, bus_id, device_address);
2029 break;
2030 case USB_DT_RPIPE:
2031 if (usb_conv_info->interfaceClass == IF_CLASS_HID) {
2032 offset = dissect_usb_hid_get_report_descriptor(pinfo, tree, tvb, offset, usb_trans_info, usb_conv_info);
2033 break;
2035 /* else fall through as default/unknown */
2036 default:
2037 /* XXX dissect the descriptor coming back from the device */
2038 proto_tree_add_text(tree, tvb, offset, -1, "GET DESCRIPTOR data (unknown descriptor type %u)", usb_trans_info->u.get_descriptor.type);
2039 offset = tvb_length(tvb);
2040 break;
2043 return offset;
2048 * These dissectors are used to dissect the setup part and the data
2049 * for URB_CONTROL_INPUT / GET INTERFACE
2053 /* 9.4.4 */
2054 static int
2055 dissect_usb_setup_get_interface_request(packet_info *pinfo _U_, proto_tree *tree,
2056 tvbuff_t *tvb, int offset,
2057 usb_trans_info_t *usb_trans_info _U_,
2058 usb_conv_info_t *usb_conv_info _U_,
2059 guint bus_id _U_, guint device_address _U_)
2061 /* zero */
2062 proto_tree_add_item(tree, hf_usb_value, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2063 offset += 2;
2065 /* interface */
2066 proto_tree_add_item(tree, hf_usb_wInterface, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2067 offset += 2;
2069 /* length */
2070 proto_tree_add_item(tree, hf_usb_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2071 offset += 2;
2073 return offset;
2076 static int
2077 dissect_usb_setup_get_interface_response(packet_info *pinfo _U_, proto_tree *tree,
2078 tvbuff_t *tvb, int offset,
2079 usb_trans_info_t *usb_trans_info _U_,
2080 usb_conv_info_t *usb_conv_info _U_,
2081 guint bus_id _U_, guint device_address _U_)
2083 /* alternate setting */
2084 proto_tree_add_item(tree, hf_usb_bAlternateSetting, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2085 offset += 1;
2087 return offset;
2092 * These dissectors are used to dissect the setup part and the data
2093 * for URB_CONTROL_INPUT / GET STATUS
2097 /* 9.4.5 */
2098 static int
2099 dissect_usb_setup_get_status_request(packet_info *pinfo _U_, proto_tree *tree,
2100 tvbuff_t *tvb, int offset,
2101 usb_trans_info_t *usb_trans_info _U_,
2102 usb_conv_info_t *usb_conv_info _U_,
2103 guint bus_id _U_, guint device_address _U_)
2105 /* zero */
2106 proto_tree_add_item(tree, hf_usb_value, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2107 offset += 2;
2109 /* zero/interface/endpoint */
2110 /* XXX - check based on request type */
2111 proto_tree_add_item(tree, hf_usb_wInterface, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2112 offset += 2;
2114 /* length */
2115 proto_tree_add_item(tree, hf_usb_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2116 offset += 2;
2118 return offset;
2121 static int
2122 dissect_usb_setup_get_status_response(packet_info *pinfo _U_, proto_tree *tree,
2123 tvbuff_t *tvb, int offset,
2124 usb_trans_info_t *usb_trans_info _U_,
2125 usb_conv_info_t *usb_conv_info _U_,
2126 guint bus_id _U_, guint device_address _U_)
2128 /* status */
2129 /* XXX - show bits */
2130 proto_tree_add_item(tree, hf_usb_wStatus, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2131 offset += 2;
2133 return offset;
2138 * These dissectors are used to dissect the setup part and the data
2139 * for URB_CONTROL_INPUT / SET ADDRESS
2143 /* 9.4.6 */
2144 static int
2145 dissect_usb_setup_set_address_request(packet_info *pinfo _U_, proto_tree *tree,
2146 tvbuff_t *tvb, int offset,
2147 usb_trans_info_t *usb_trans_info _U_,
2148 usb_conv_info_t *usb_conv_info _U_,
2149 guint bus_id _U_, guint device_address _U_)
2151 /* device address */
2152 proto_tree_add_item(tree, hf_usb_device_address, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2153 offset += 2;
2155 /* zero */
2156 proto_tree_add_item(tree, hf_usb_index, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2157 offset += 2;
2159 /* zero */
2160 proto_tree_add_item(tree, hf_usb_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2161 offset += 2;
2163 return offset;
2166 static int
2167 dissect_usb_setup_set_address_response(packet_info *pinfo _U_, proto_tree *tree _U_,
2168 tvbuff_t *tvb _U_, int offset,
2169 usb_trans_info_t *usb_trans_info _U_,
2170 usb_conv_info_t *usb_conv_info _U_,
2171 guint bus_id _U_, guint device_address _U_)
2173 return offset;
2178 * These dissectors are used to dissect the setup part and the data
2179 * for URB_CONTROL_INPUT / SET CONFIGURATION
2183 /* 9.4.7 */
2184 static int
2185 dissect_usb_setup_set_configuration_request(packet_info *pinfo _U_, proto_tree *tree,
2186 tvbuff_t *tvb, int offset,
2187 usb_trans_info_t *usb_trans_info _U_,
2188 usb_conv_info_t *usb_conv_info _U_,
2189 guint bus_id _U_, guint device_address _U_)
2191 /* configuration value */
2192 proto_tree_add_item(tree, hf_usb_bConfigurationValue, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2193 offset += 2;
2195 /* zero */
2196 proto_tree_add_item(tree, hf_usb_index, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2197 offset += 2;
2199 /* zero */
2200 proto_tree_add_item(tree, hf_usb_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2201 offset += 2;
2203 return offset;
2206 static int
2207 dissect_usb_setup_set_configuration_response(packet_info *pinfo _U_, proto_tree *tree _U_,
2208 tvbuff_t *tvb _U_, int offset,
2209 usb_trans_info_t *usb_trans_info _U_,
2210 usb_conv_info_t *usb_conv_info _U_,
2211 guint bus_id _U_, guint device_address _U_)
2213 return offset;
2218 * These dissectors are used to dissect the setup part and the data
2219 * for URB_CONTROL_INPUT / SET FEATURE
2223 /* 9.4.9 */
2224 static int
2225 dissect_usb_setup_set_feature_request(packet_info *pinfo _U_, proto_tree *tree,
2226 tvbuff_t *tvb, int offset,
2227 usb_trans_info_t *usb_trans_info _U_,
2228 usb_conv_info_t *usb_conv_info _U_,
2229 guint bus_id _U_, guint device_address _U_)
2231 /* feature selector */
2232 proto_tree_add_item(tree, hf_usb_wFeatureSelector, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2233 offset += 2;
2235 /* zero/interface/endpoint or test selector */
2236 /* XXX - check based on request type */
2237 proto_tree_add_item(tree, hf_usb_wInterface, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2238 offset += 2;
2240 /* zero */
2241 proto_tree_add_item(tree, hf_usb_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2242 offset += 2;
2244 return offset;
2247 static int
2248 dissect_usb_setup_set_feature_response(packet_info *pinfo _U_, proto_tree *tree _U_,
2249 tvbuff_t *tvb _U_, int offset,
2250 usb_trans_info_t *usb_trans_info _U_,
2251 usb_conv_info_t *usb_conv_info _U_,
2252 guint bus_id _U_, guint device_address _U_)
2254 return offset;
2259 * These dissectors are used to dissect the setup part and the data
2260 * for URB_CONTROL_INPUT / SET INTERFACE
2264 /* 9.4.10 */
2265 static int
2266 dissect_usb_setup_set_interface_request(packet_info *pinfo _U_, proto_tree *tree,
2267 tvbuff_t *tvb, int offset,
2268 usb_trans_info_t *usb_trans_info _U_,
2269 usb_conv_info_t *usb_conv_info _U_,
2270 guint bus_id _U_, guint device_address _U_)
2272 /* alternate setting */
2273 proto_tree_add_item(tree, hf_usb_bAlternateSetting, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2274 offset += 2;
2276 /* interface */
2277 proto_tree_add_item(tree, hf_usb_wInterface, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2278 offset += 2;
2280 /* zero */
2281 proto_tree_add_item(tree, hf_usb_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2282 offset += 2;
2284 return offset;
2287 static int
2288 dissect_usb_setup_set_interface_response(packet_info *pinfo _U_, proto_tree *tree _U_,
2289 tvbuff_t *tvb _U_, int offset,
2290 usb_trans_info_t *usb_trans_info _U_,
2291 usb_conv_info_t *usb_conv_info _U_,
2292 guint bus_id _U_, guint device_address _U_)
2294 return offset;
2299 * These dissectors are used to dissect the setup part and the data
2300 * for URB_CONTROL_INPUT / SYNCH FRAME
2304 /* 9.4.11 */
2305 static int
2306 dissect_usb_setup_synch_frame_request(packet_info *pinfo _U_, proto_tree *tree,
2307 tvbuff_t *tvb, int offset,
2308 usb_trans_info_t *usb_trans_info _U_,
2309 usb_conv_info_t *usb_conv_info _U_,
2310 guint bus_id _U_, guint device_address _U_)
2312 /* zero */
2313 proto_tree_add_item(tree, hf_usb_value, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2314 offset += 2;
2316 /* endpoint */
2317 /* XXX */
2318 proto_tree_add_item(tree, hf_usb_wInterface, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2319 offset += 2;
2321 /* two */
2322 proto_tree_add_item(tree, hf_usb_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2323 offset += 2;
2325 return offset;
2328 static int
2329 dissect_usb_setup_synch_frame_response(packet_info *pinfo _U_, proto_tree *tree _U_,
2330 tvbuff_t *tvb _U_, int offset,
2331 usb_trans_info_t *usb_trans_info _U_,
2332 usb_conv_info_t *usb_conv_info _U_,
2333 guint bus_id _U_, guint device_address _U_)
2335 /* frame number */
2336 proto_tree_add_item(tree, hf_usb_wFrameNumber, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2337 offset += 2;
2339 return offset;
2343 typedef int (*usb_setup_dissector)(packet_info *pinfo, proto_tree *tree,
2344 tvbuff_t *tvb, int offset,
2345 usb_trans_info_t *usb_trans_info,
2346 usb_conv_info_t *usb_conv_info,
2347 guint bus_id, guint device_address);
2349 typedef struct _usb_setup_dissector_table_t {
2350 guint8 request;
2351 usb_setup_dissector dissector;
2353 } usb_setup_dissector_table_t;
2354 #define USB_SETUP_GET_STATUS 0
2355 #define USB_SETUP_CLEAR_FEATURE 1
2356 #define USB_SETUP_SET_FEATURE 3
2357 #define USB_SETUP_SET_ADDRESS 5
2358 #define USB_SETUP_GET_DESCRIPTOR 6
2359 #define USB_SETUP_SET_DESCRIPTOR 7
2360 #define USB_SETUP_GET_CONFIGURATION 8
2361 #define USB_SETUP_SET_CONFIGURATION 9
2362 #define USB_SETUP_GET_INTERFACE 10
2363 #define USB_SETUP_SET_INTERFACE 11
2364 #define USB_SETUP_SYNCH_FRAME 12
2365 #define USB_SETUP_SET_SEL 48
2366 #define USB_SETUP_SET_ISOCH_DELAY 49
2368 static const usb_setup_dissector_table_t setup_request_dissectors[] = {
2369 {USB_SETUP_GET_STATUS, dissect_usb_setup_get_status_request},
2370 {USB_SETUP_CLEAR_FEATURE, dissect_usb_setup_clear_feature_request},
2371 {USB_SETUP_SET_FEATURE, dissect_usb_setup_set_feature_request},
2372 {USB_SETUP_SET_ADDRESS, dissect_usb_setup_set_address_request},
2373 {USB_SETUP_GET_DESCRIPTOR, dissect_usb_setup_get_descriptor_request},
2374 {USB_SETUP_SET_CONFIGURATION, dissect_usb_setup_set_configuration_request},
2375 {USB_SETUP_GET_INTERFACE, dissect_usb_setup_get_interface_request},
2376 {USB_SETUP_SET_INTERFACE, dissect_usb_setup_set_interface_request},
2377 {USB_SETUP_SYNCH_FRAME, dissect_usb_setup_synch_frame_request},
2378 {0, NULL}
2381 static const usb_setup_dissector_table_t setup_response_dissectors[] = {
2382 {USB_SETUP_GET_STATUS, dissect_usb_setup_get_status_response},
2383 {USB_SETUP_CLEAR_FEATURE, dissect_usb_setup_clear_feature_response},
2384 {USB_SETUP_SET_FEATURE, dissect_usb_setup_set_feature_response},
2385 {USB_SETUP_SET_ADDRESS, dissect_usb_setup_set_address_response},
2386 {USB_SETUP_GET_DESCRIPTOR, dissect_usb_setup_get_descriptor_response},
2387 {USB_SETUP_GET_CONFIGURATION, dissect_usb_setup_get_configuration_response},
2388 {USB_SETUP_SET_CONFIGURATION, dissect_usb_setup_set_configuration_response},
2389 {USB_SETUP_GET_INTERFACE, dissect_usb_setup_get_interface_response},
2390 {USB_SETUP_SET_INTERFACE, dissect_usb_setup_set_interface_response},
2391 {USB_SETUP_SYNCH_FRAME, dissect_usb_setup_synch_frame_response},
2392 {0, NULL}
2395 static const value_string setup_request_names_vals[] = {
2396 {USB_SETUP_GET_STATUS, "GET STATUS"},
2397 {USB_SETUP_CLEAR_FEATURE, "CLEAR FEATURE"},
2398 {USB_SETUP_SET_FEATURE, "SET FEATURE"},
2399 {USB_SETUP_SET_ADDRESS, "SET ADDRESS"},
2400 {USB_SETUP_GET_DESCRIPTOR, "GET DESCRIPTOR"},
2401 {USB_SETUP_SET_DESCRIPTOR, "SET DESCRIPTOR"},
2402 {USB_SETUP_GET_CONFIGURATION, "GET CONFIGURATION"},
2403 {USB_SETUP_SET_CONFIGURATION, "SET CONFIGURATION"},
2404 {USB_SETUP_GET_INTERFACE, "GET INTERFACE"},
2405 {USB_SETUP_SET_INTERFACE, "SET INTERFACE"},
2406 {USB_SETUP_SYNCH_FRAME, "SYNCH FRAME"},
2407 {USB_SETUP_SET_SEL, "SET SEL"},
2408 {USB_SETUP_SET_ISOCH_DELAY, "SET ISOCH DELAY"},
2409 {0, NULL}
2413 static const true_false_string tfs_bmrequesttype_direction = {
2414 "Device-to-host",
2415 "Host-to-device"
2418 static const value_string bmrequesttype_type_vals[] = {
2419 {RQT_SETUP_TYPE_STANDARD, "Standard"},
2420 {RQT_SETUP_TYPE_CLASS, "Class"},
2421 {RQT_SETUP_TYPE_VENDOR, "Vendor"},
2422 {0, NULL}
2425 static const value_string bmrequesttype_recipient_vals[] = {
2426 {RQT_SETUP_RECIPIENT_DEVICE, "Device" },
2427 {RQT_SETUP_RECIPIENT_INTERFACE, "Interface" },
2428 {RQT_SETUP_RECIPIENT_ENDPOINT, "Endpoint" },
2429 {RQT_SETUP_RECIPIENT_OTHER, "Other" },
2430 {0, NULL }
2433 static int
2434 dissect_usb_bmrequesttype(proto_tree *parent_tree, tvbuff_t *tvb, int offset, int *type)
2436 proto_item *item = NULL;
2437 proto_tree *tree = NULL;
2439 if (parent_tree) {
2440 item = proto_tree_add_item(parent_tree, hf_usb_bmRequestType, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2441 tree = proto_item_add_subtree(item, ett_usb_setup_bmrequesttype);
2444 *type = USB_TYPE(tvb_get_guint8(tvb, offset));
2445 proto_tree_add_item(tree, hf_usb_bmRequestType_direction, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2446 proto_tree_add_item(tree, hf_usb_bmRequestType_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2447 proto_tree_add_item(tree, hf_usb_bmRequestType_recipient, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2449 return ++offset;
2452 /* Adds the Linux USB pseudo header fields to the tree.
2453 * NOTE: The multi-byte fields in this header, and the pseudo-header
2454 * extension, are in host-endian format so we can't
2455 * use proto_tree_add_item() nor the tvb_get_xyz() routines and is
2456 * the reason for the tvb_memcpy() and proto_tree_add_uint[64]()
2457 * pairs below. */
2458 static void
2459 dissect_linux_usb_pseudo_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2460 guint *bus_id, guint *device_address)
2462 guint8 transfer_type;
2463 guint8 endpoint_number;
2464 guint8 transfer_type_and_direction;
2465 guint8 type;
2466 guint8 flag[2];
2467 guint16 val16;
2468 guint32 val32;
2469 guint64 val64;
2471 tvb_memcpy(tvb, (guint8 *)&val64, 0, 8);
2472 proto_tree_add_uint64(tree, hf_usb_urb_id, tvb, 0, 8, val64);
2474 /* show the event type of this URB as string and as a character */
2475 type = tvb_get_guint8(tvb, 8);
2476 proto_tree_add_uint_format_value(tree, hf_usb_urb_type, tvb, 8, 1,
2477 type, "%s ('%c')", val_to_str(type, usb_urb_type_vals, "Unknown %d"),
2478 isprint(type) ? type : '.');
2479 proto_tree_add_item(tree, hf_usb_transfer_type, tvb, 9, 1, ENC_BIG_ENDIAN);
2481 transfer_type = tvb_get_guint8(tvb, 9);
2482 endpoint_number = tvb_get_guint8(tvb, 10);
2483 transfer_type_and_direction = (transfer_type & 0x7F) | (endpoint_number & 0x80);
2484 col_append_str(pinfo->cinfo, COL_INFO,
2485 val_to_str(transfer_type_and_direction, usb_transfer_type_and_direction_vals, "Unknown type %x"));
2487 proto_tree_add_bitmask(tree, tvb, 10, hf_usb_endpoint_number, ett_usb_endpoint, usb_endpoint_fields, ENC_BIG_ENDIAN);
2488 proto_tree_add_item(tree, hf_usb_device_address, tvb, 11, 1, ENC_BIG_ENDIAN);
2489 *device_address = tvb_get_guint8(tvb, 11);
2491 tvb_memcpy(tvb, (guint8 *)&val16, 12, 2);
2492 proto_tree_add_uint(tree, hf_usb_bus_id, tvb, 12, 2, val16);
2493 *bus_id = tvb_get_letohs(tvb, 12);
2495 /* Right after the pseudo header we always have
2496 * sizeof(struct usb_device_setup_hdr) bytes. The content of these
2497 * bytes only have meaning in case setup_flag == 0.
2499 flag[0] = tvb_get_guint8(tvb, 14);
2500 flag[1] = '\0';
2501 if (flag[0] == 0) {
2502 proto_tree_add_string(tree, hf_usb_setup_flag, tvb, 14, 1, "relevant (0)");
2503 } else {
2504 proto_tree_add_string_format_value(tree, hf_usb_setup_flag, tvb,
2505 14, 1, flag, "not relevant ('%c')", isprint(flag[0]) ? flag[0]: '.');
2508 flag[0] = tvb_get_guint8(tvb, 15);
2509 flag[1] = '\0';
2510 if (flag[0] == 0) {
2511 proto_tree_add_string(tree, hf_usb_data_flag, tvb, 15, 1, "present (0)");
2512 } else {
2513 proto_tree_add_string_format_value(tree, hf_usb_data_flag, tvb,
2514 15, 1, flag, "not present ('%c')", isprint(flag[0]) ? flag[0] : '.');
2517 tvb_memcpy(tvb, (guint8 *)&val64, 16, 8);
2518 proto_tree_add_uint64(tree, hf_usb_urb_ts_sec, tvb, 16, 8, val64);
2520 tvb_memcpy(tvb, (guint8 *)&val32, 24, 4);
2521 proto_tree_add_uint(tree, hf_usb_urb_ts_usec, tvb, 24, 4, val32);
2523 tvb_memcpy(tvb, (guint8 *)&val32, 28, 4);
2524 proto_tree_add_int(tree, hf_usb_urb_status, tvb, 28, 4, val32);
2526 tvb_memcpy(tvb, (guint8 *)&val32, 32, 4);
2527 proto_tree_add_uint(tree, hf_usb_urb_len, tvb, 32, 4, val32);
2529 tvb_memcpy(tvb, (guint8 *)&val32, 36, 4);
2530 proto_tree_add_uint(tree, hf_usb_urb_data_len, tvb, 36, 4, val32);
2534 * XXX - put these into the protocol tree as appropriate.
2536 static int
2537 dissect_linux_usb_pseudo_header_ext(tvbuff_t *tvb, int offset,
2538 packet_info *pinfo _U_,
2539 proto_tree *tree _U_)
2541 guint32 ndesc;
2543 offset += 4; /* interval */
2544 offset += 4; /* start_frame */
2545 offset += 4; /* copy of URB's transfer flags */
2547 tvb_memcpy(tvb, (guint8 *)&ndesc, offset, 4);
2548 offset += 4;
2551 * Isochronous descriptors. Each one is 16 bytes long.
2553 offset += ndesc*16;
2555 return offset;
2558 /* Adds the win32 USBPcap pseudo header fields to the tree. */
2559 static void
2560 dissect_win32_usb_pseudo_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2561 guint *bus_id, guint *device_address)
2563 guint8 transfer_type;
2564 guint8 endpoint_number;
2565 guint8 transfer_type_and_direction;
2567 proto_tree_add_item(tree, hf_usb_win32_header_len, tvb, 0, 2, ENC_LITTLE_ENDIAN);
2568 proto_tree_add_item(tree, hf_usb_irp_id, tvb, 2, 8, ENC_LITTLE_ENDIAN);
2569 proto_tree_add_item(tree, hf_usb_usbd_status, tvb, 10, 4, ENC_LITTLE_ENDIAN);
2570 proto_tree_add_item(tree, hf_usb_function, tvb, 14, 2, ENC_LITTLE_ENDIAN);
2572 proto_tree_add_bitmask(tree, tvb, 16, hf_usb_info, ett_usb_usbpcap_info, usb_usbpcap_info_fields, ENC_LITTLE_ENDIAN);
2574 proto_tree_add_item(tree, hf_usb_bus_id, tvb, 17, 2, ENC_LITTLE_ENDIAN);
2575 *bus_id = tvb_get_letohs(tvb, 17);
2577 proto_tree_add_item(tree, hf_usb_win32_device_address, tvb, 19, 2, ENC_LITTLE_ENDIAN);
2578 *device_address = tvb_get_letohs(tvb, 19);
2580 transfer_type = tvb_get_guint8(tvb, 22);
2582 endpoint_number = tvb_get_guint8(tvb, 21);
2583 transfer_type_and_direction = (transfer_type & 0x7F) | (endpoint_number & 0x80);
2584 col_append_str(pinfo->cinfo, COL_INFO,
2585 val_to_str(transfer_type_and_direction, usb_transfer_type_and_direction_vals, "Unknown type %x"));
2587 proto_tree_add_bitmask(tree, tvb, 21, hf_usb_endpoint_number, ett_usb_endpoint, usb_endpoint_fields, ENC_LITTLE_ENDIAN);
2589 proto_tree_add_item(tree, hf_usb_transfer_type, tvb, 22, 1, ENC_LITTLE_ENDIAN);
2591 proto_tree_add_item(tree, hf_usb_win32_data_len, tvb, 23, 4, ENC_LITTLE_ENDIAN);
2593 /* Handle transfer specific data */
2594 switch (transfer_type)
2596 case URB_ISOCHRONOUS:
2597 /* dissection in handled in dissect_usb_common() */
2598 break;
2599 case URB_INTERRUPT:
2600 break;
2601 case URB_CONTROL:
2602 proto_tree_add_item(tree, hf_usb_control_stage, tvb, 27, 1, ENC_LITTLE_ENDIAN);
2603 break;
2604 case URB_BULK:
2605 break;
2609 static void
2610 dissect_usb_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent,
2611 guint8 header_info)
2613 unsigned int offset = 0;
2614 int type, endpoint, endpoint_with_dir;
2615 guint8 urb_type, usbpcap_control_stage = 0;
2616 guint8 setup_flag;
2617 guint16 hdr_len;
2618 guint32 win32_data_len = 0;
2619 proto_tree *tree = NULL;
2620 guint32 tmp_addr;
2621 static usb_address_t src_addr, dst_addr; /* has to be static due to SET_ADDRESS */
2622 guint32 src_endpoint, dst_endpoint;
2623 gboolean is_request;
2624 usb_conv_info_t *usb_conv_info;
2625 usb_trans_info_t *usb_trans_info = NULL;
2626 conversation_t *conversation;
2627 usb_tap_data_t *tap_data;
2628 guint bus_id = 0;
2629 guint device_address = 0;
2630 tvbuff_t *next_tvb = NULL;
2632 col_set_str(pinfo->cinfo, COL_PROTOCOL, "USB");
2634 if (header_info & USB_HEADER_IS_LINUX) {
2635 /* add usb hdr*/
2636 if (parent) {
2637 proto_item *ti;
2638 ti = proto_tree_add_protocol_format(parent, proto_usb, tvb, 0,
2639 (header_info & USB_HEADER_IS_64_BYTES) ? 64 : 48, "USB URB");
2640 tree = proto_item_add_subtree(ti, usb_hdr);
2643 dissect_linux_usb_pseudo_header(tvb, pinfo, tree, &bus_id, &device_address);
2644 urb_type = tvb_get_guint8(tvb, 8);
2645 is_request = (urb_type == URB_SUBMIT) ? TRUE : FALSE;
2646 type = tvb_get_guint8(tvb, 9);
2647 endpoint_with_dir = tvb_get_guint8(tvb, 10);
2648 endpoint = endpoint_with_dir & (~URB_TRANSFER_IN);
2649 tmp_addr = tvb_get_guint8(tvb, 11);
2650 setup_flag = tvb_get_guint8(tvb, 14);
2651 offset += 40; /* skip first part of the pseudo-header */
2652 } else if (header_info & USB_HEADER_IS_USBPCAP) {
2653 guint8 tmp_val8;
2655 tvb_memcpy(tvb, (guint8 *)&hdr_len, 0, 2);
2656 /* add usb hdr */
2657 if (parent) {
2658 proto_item *ti;
2659 ti = proto_tree_add_protocol_format(parent, proto_usb, tvb, 0,
2660 hdr_len, "USB URB");
2661 tree = proto_item_add_subtree(ti, usb_hdr);
2664 dissect_win32_usb_pseudo_header(tvb, pinfo, tree, &bus_id, &device_address);
2666 hdr_len = tvb_get_letohs(tvb, 0);
2667 tmp_val8 = tvb_get_guint8(tvb, 16);
2668 /* TODO: Handle errors */
2669 if (tmp_val8 & 0x01) {
2670 urb_type = URB_COMPLETE;
2671 } else {
2672 urb_type = URB_SUBMIT;
2674 is_request = (urb_type == URB_SUBMIT) ? TRUE : FALSE;
2675 type = tvb_get_guint8(tvb, 22);
2676 endpoint_with_dir = tvb_get_guint8(tvb, 21);
2677 endpoint = endpoint_with_dir & (~URB_TRANSFER_IN);
2678 tmp_addr = device_address;
2680 win32_data_len = tvb_get_letohl(tvb, 23);
2681 usbpcap_control_stage = tvb_get_guint8(tvb, 27);
2682 if (usbpcap_control_stage == USB_CONTROL_STAGE_SETUP) {
2683 setup_flag = 0;
2684 } else {
2685 setup_flag = 0xFF;
2688 if (type == URB_ISOCHRONOUS) {
2689 offset += 27; /* Skip the part of pseudo-header already dissected */
2690 } else {
2691 offset += hdr_len; /* Skip the pseudo-header */
2693 } else {
2694 /* Unknown pseudo-header type */
2695 return;
2698 /* Set up addresses and ports. */
2699 if (is_request) {
2700 src_addr.device = 0xffffffff;
2701 src_addr.endpoint = src_endpoint = NO_ENDPOINT;
2702 dst_addr.device = htolel(tmp_addr);
2703 dst_addr.endpoint = dst_endpoint = htolel(endpoint);
2704 } else {
2705 src_addr.device = htolel(tmp_addr);
2706 src_addr.endpoint = src_endpoint = htolel(endpoint);
2707 dst_addr.device = 0xffffffff;
2708 dst_addr.endpoint = dst_endpoint = NO_ENDPOINT;
2711 SET_ADDRESS(&pinfo->net_src, AT_USB, USB_ADDR_LEN, (char *)&src_addr);
2712 SET_ADDRESS(&pinfo->src, AT_USB, USB_ADDR_LEN, (char *)&src_addr);
2713 SET_ADDRESS(&pinfo->net_dst, AT_USB, USB_ADDR_LEN, (char *)&dst_addr);
2714 SET_ADDRESS(&pinfo->dst, AT_USB, USB_ADDR_LEN, (char *)&dst_addr);
2715 pinfo->ptype = PT_USB;
2716 pinfo->srcport = src_endpoint;
2717 pinfo->destport = dst_endpoint;
2719 conversation = get_usb_conversation(pinfo, &pinfo->src, &pinfo->dst, pinfo->srcport, pinfo->destport);
2721 usb_conv_info = get_usb_conv_info(conversation);
2723 usb_conv_info->bus_id = bus_id;
2724 usb_conv_info->device_address = device_address;
2725 usb_conv_info->endpoint = endpoint;
2727 if (endpoint_with_dir & URB_TRANSFER_IN) {
2728 usb_conv_info->direction = P2P_DIR_RECV;
2729 } else {
2730 usb_conv_info->direction = P2P_DIR_SENT;
2733 /* request/response matching so we can keep track of transaction specific
2734 * data.
2736 if (is_request) {
2737 /* this is a request */
2738 usb_trans_info = (usb_trans_info_t *)wmem_tree_lookup32(usb_conv_info->transactions, pinfo->fd->num);
2739 if (!usb_trans_info) {
2740 usb_trans_info = wmem_new0(wmem_file_scope(), usb_trans_info_t);
2741 usb_trans_info->request_in = pinfo->fd->num;
2742 usb_trans_info->req_time = pinfo->fd->abs_ts;
2743 usb_trans_info->header_len_64 = (header_info & USB_HEADER_IS_64_BYTES) ? TRUE : FALSE;
2745 wmem_tree_insert32(usb_conv_info->transactions, pinfo->fd->num, usb_trans_info);
2747 usb_conv_info->usb_trans_info = usb_trans_info;
2749 if (usb_trans_info->response_in) {
2750 proto_item *ti;
2752 ti = proto_tree_add_uint(tree, hf_usb_response_in, tvb, 0, 0, usb_trans_info->response_in);
2753 PROTO_ITEM_SET_GENERATED(ti);
2755 } else {
2756 /* this is a response */
2757 if (pinfo->fd->flags.visited) {
2758 usb_trans_info = (usb_trans_info_t *)wmem_tree_lookup32(usb_conv_info->transactions, pinfo->fd->num);
2759 } else {
2760 usb_trans_info = (usb_trans_info_t *)wmem_tree_lookup32_le(usb_conv_info->transactions, pinfo->fd->num);
2761 if (usb_trans_info) {
2762 usb_trans_info->response_in = pinfo->fd->num;
2763 wmem_tree_insert32(usb_conv_info->transactions, pinfo->fd->num, usb_trans_info);
2766 usb_conv_info->usb_trans_info = usb_trans_info;
2768 if (usb_trans_info && usb_trans_info->request_in) {
2769 proto_item *ti;
2770 nstime_t t, deltat;
2772 ti = proto_tree_add_uint(tree, hf_usb_request_in, tvb, 0, 0, usb_trans_info->request_in);
2773 PROTO_ITEM_SET_GENERATED(ti);
2775 t = pinfo->fd->abs_ts;
2776 nstime_delta(&deltat, &t, &usb_trans_info->req_time);
2777 ti = proto_tree_add_time(tree, hf_usb_time, tvb, 0, 0, &deltat);
2778 PROTO_ITEM_SET_GENERATED(ti);
2782 tap_data = wmem_new(wmem_packet_scope(), usb_tap_data_t);
2783 tap_data->urb_type = urb_type;
2784 tap_data->transfer_type = (guint8)type;
2785 tap_data->conv_info = usb_conv_info;
2786 tap_data->trans_info = usb_trans_info;
2788 if (type != URB_CONTROL) {
2789 tap_queue_packet(usb_tap, pinfo, tap_data);
2792 switch(type) {
2793 case URB_BULK:
2795 proto_item *item;
2797 item = proto_tree_add_uint(tree, hf_usb_bInterfaceClass, tvb, 0, 0, usb_conv_info->interfaceClass);
2798 PROTO_ITEM_SET_GENERATED(item);
2800 if (header_info & USB_HEADER_IS_LINUX) {
2801 /* Skip setup/isochronous header - it's not applicable */
2802 offset += 8;
2805 * If this has a 64-byte header, process the extra 16 bytes of
2806 * pseudo-header information.
2808 if (header_info & USB_HEADER_IS_64_BYTES) {
2809 offset = dissect_linux_usb_pseudo_header_ext(tvb, offset, pinfo, tree);
2813 if (tvb_reported_length_remaining(tvb, offset)) {
2814 next_tvb = tvb_new_subset_remaining(tvb, offset);
2815 if (try_heuristics && dissector_try_heuristic(heur_bulk_subdissector_list, next_tvb, pinfo, parent, usb_conv_info)) {
2816 return;
2818 else if (dissector_try_uint_new(usb_bulk_dissector_table, usb_conv_info->interfaceClass, next_tvb, pinfo, parent, TRUE, usb_conv_info)) {
2819 return;
2823 break;
2824 case URB_INTERRUPT:
2826 proto_item *item;
2828 item = proto_tree_add_uint(tree, hf_usb_bInterfaceClass, tvb, 0, 0, usb_conv_info->interfaceClass);
2829 PROTO_ITEM_SET_GENERATED(item);
2831 if (header_info & USB_HEADER_IS_LINUX) {
2832 /* Skip setup/isochronous header - it's not applicable */
2833 offset += 8;
2836 * If this has a 64-byte header, process the extra 16 bytes of
2837 * pseudo-header information.
2839 if (header_info & USB_HEADER_IS_64_BYTES) {
2840 offset = dissect_linux_usb_pseudo_header_ext(tvb, offset, pinfo, tree);
2844 if (tvb_reported_length_remaining(tvb, offset)) {
2845 next_tvb = tvb_new_subset_remaining(tvb, offset);
2846 if (try_heuristics && dissector_try_heuristic(heur_interrupt_subdissector_list, next_tvb, pinfo, parent, usb_conv_info)) {
2847 return;
2849 else if (dissector_try_uint_new(usb_interrupt_dissector_table, usb_conv_info->interfaceClass, next_tvb, pinfo, parent, TRUE, usb_conv_info)) {
2850 return;
2854 break;
2855 case URB_CONTROL:
2857 const usb_setup_dissector_table_t *tmp;
2858 usb_setup_dissector dissector;
2859 proto_item *ti = NULL;
2860 proto_tree *setup_tree = NULL;
2861 int type_2;
2863 if (is_request) {
2864 if (setup_flag == 0) {
2865 /* this is a request */
2867 /* Dissect the setup header - it's applicable */
2869 ti = proto_tree_add_protocol_format(parent, proto_usb, tvb, offset, 8, "URB setup");
2870 setup_tree = proto_item_add_subtree(ti, usb_setup_hdr);
2871 usb_trans_info->setup.requesttype = tvb_get_guint8(tvb, offset);
2872 offset = dissect_usb_bmrequesttype(setup_tree, tvb, offset, &type_2);
2875 /* read the request code and spawn off to a class specific
2876 * dissector if found
2878 usb_trans_info->setup.request = tvb_get_guint8(tvb, offset);
2879 usb_trans_info->setup.wValue = tvb_get_letohs(tvb, offset+1);
2880 usb_trans_info->setup.wIndex = tvb_get_letohs(tvb, offset+3);
2881 usb_trans_info->setup.wLength = tvb_get_letohs(tvb, offset+5);
2883 if (type_2 != RQT_SETUP_TYPE_CLASS) {
2884 tap_queue_packet(usb_tap, pinfo, tap_data);
2887 switch (type_2) {
2889 case RQT_SETUP_TYPE_STANDARD:
2891 * This is a standard request which is managed by this
2892 * dissector
2894 proto_tree_add_item(setup_tree, hf_usb_request, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2895 offset += 1;
2897 col_add_fstr(pinfo->cinfo, COL_INFO, "%s Request",
2898 val_to_str(usb_trans_info->setup.request, setup_request_names_vals, "Unknown type %x"));
2900 dissector = NULL;
2901 for(tmp = setup_request_dissectors;tmp->dissector;tmp++) {
2902 if (tmp->request == usb_trans_info->setup.request) {
2903 dissector = tmp->dissector;
2904 break;
2908 if (dissector) {
2909 offset = dissector(pinfo, setup_tree, tvb, offset, usb_trans_info,
2910 usb_conv_info, bus_id, device_address);
2911 } else {
2912 proto_tree_add_item(setup_tree, hf_usb_value, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2913 offset += 2;
2914 proto_tree_add_item(setup_tree, hf_usb_index, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2915 offset += 2;
2916 proto_tree_add_item(setup_tree, hf_usb_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2917 offset += 2;
2919 break;
2921 case RQT_SETUP_TYPE_CLASS:
2922 /* Make sure we have the proper conversation */
2923 if (USB_RECIPIENT(usb_trans_info->setup.requesttype) == RQT_SETUP_RECIPIENT_INTERFACE) {
2924 guint8 interface_num = usb_trans_info->setup.wIndex & 0xff;
2925 usb_conv_info = get_usb_iface_conv_info(pinfo, interface_num);
2926 usb_conv_info->usb_trans_info = usb_trans_info;
2927 } else if (USB_RECIPIENT(usb_trans_info->setup.requesttype) == RQT_SETUP_RECIPIENT_ENDPOINT) {
2928 static address endpoint_addr;
2929 endpoint = usb_trans_info->setup.wIndex & 0x0f;
2931 dst_addr.endpoint = dst_endpoint = htolel(endpoint);
2932 SET_ADDRESS(&endpoint_addr, AT_USB, USB_ADDR_LEN, (char *)&dst_addr);
2934 conversation = get_usb_conversation(pinfo, &pinfo->src, &endpoint_addr, pinfo->srcport, dst_endpoint);
2935 usb_conv_info = get_usb_conv_info(conversation);
2936 usb_conv_info->usb_trans_info = usb_trans_info;
2939 tap_data->conv_info = usb_conv_info;
2940 tap_data->trans_info = usb_trans_info;
2941 tap_queue_packet(usb_tap, pinfo, tap_data);
2943 ti = proto_tree_add_uint(tree, hf_usb_bInterfaceClass, tvb, 0, 0, usb_conv_info->interfaceClass);
2944 PROTO_ITEM_SET_GENERATED(ti);
2946 /* Try to find a class specific dissector */
2947 next_tvb = tvb_new_subset_remaining(tvb, offset);
2948 if (try_heuristics && dissector_try_heuristic(heur_control_subdissector_list, next_tvb, pinfo, setup_tree, usb_conv_info)) {
2949 return;
2951 if (dissector_try_uint_new(usb_control_dissector_table, usb_conv_info->interfaceClass, next_tvb, pinfo, setup_tree, TRUE, usb_conv_info)) {
2952 return;
2954 /* Else no class dissector, just display generic fields */
2955 proto_tree_add_item(setup_tree, hf_usb_request_unknown_class, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2956 offset += 1;
2957 proto_tree_add_item(setup_tree, hf_usb_value, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2958 offset += 2;
2959 proto_tree_add_item(setup_tree, hf_usb_index, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2960 offset += 2;
2961 proto_tree_add_item(setup_tree, hf_usb_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2962 offset += 2;
2963 break;
2965 default:
2966 proto_tree_add_item(setup_tree, hf_usb_request_unknown_class, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2967 offset += 1;
2968 proto_tree_add_item(setup_tree, hf_usb_value, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2969 offset += 2;
2970 proto_tree_add_item(setup_tree, hf_usb_index, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2971 offset += 2;
2972 proto_tree_add_item(setup_tree, hf_usb_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2973 offset += 2;
2975 } else {
2976 if (header_info & USB_HEADER_IS_LINUX) {
2977 /* Skip setup/isochronous header - it's not applicable */
2978 offset += 8;
2983 * If this has a 64-byte header, process the extra 16 bytes of
2984 * pseudo-header information.
2986 if ((header_info & USB_HEADER_IS_LINUX) &&
2987 (header_info & USB_HEADER_IS_64_BYTES)) {
2988 offset = dissect_linux_usb_pseudo_header_ext(tvb, offset, pinfo, tree);
2991 if (tvb_reported_length_remaining(tvb, offset) != 0) {
2992 next_tvb = tvb_new_subset_remaining(tvb, offset);
2993 if (try_heuristics && dissector_try_heuristic(heur_control_subdissector_list, next_tvb, pinfo, parent, usb_conv_info)) {
2994 return;
2996 if (dissector_try_uint_new(usb_control_dissector_table, usb_conv_info->interfaceClass, next_tvb, pinfo, parent, TRUE, usb_conv_info)) {
2997 return;
3000 } else {
3001 /* this is a response */
3003 if (header_info & USB_HEADER_IS_LINUX) {
3004 /* Skip setup header - it's never applicable for responses */
3005 offset += 8;
3008 /* Make sure we have the proper conversation */
3009 if (usb_trans_info) {
3010 if (USB_TYPE(usb_trans_info->setup.requesttype) == RQT_SETUP_TYPE_CLASS) {
3011 if (USB_RECIPIENT(usb_trans_info->setup.requesttype) == RQT_SETUP_RECIPIENT_INTERFACE) {
3012 guint8 interface_num = usb_trans_info->setup.wIndex & 0xff;
3013 usb_conv_info = get_usb_iface_conv_info(pinfo, interface_num);
3014 usb_conv_info->usb_trans_info = usb_trans_info;
3015 } else if (USB_RECIPIENT(usb_trans_info->setup.requesttype) == RQT_SETUP_RECIPIENT_ENDPOINT) {
3016 static address endpoint_addr;
3017 endpoint = usb_trans_info->setup.wIndex & 0x0f;
3019 src_addr.endpoint = src_endpoint = htolel(endpoint);
3020 SET_ADDRESS(&endpoint_addr, AT_USB, USB_ADDR_LEN, (char *)&src_addr);
3022 conversation = get_usb_conversation(pinfo, &endpoint_addr, &pinfo->dst, src_endpoint, pinfo->destport);
3023 usb_conv_info = get_usb_conv_info(conversation);
3024 usb_conv_info->usb_trans_info = usb_trans_info;
3029 tap_data->conv_info = usb_conv_info;
3030 tap_data->trans_info = usb_trans_info;
3031 tap_queue_packet(usb_tap, pinfo, tap_data);
3032 ti = proto_tree_add_uint(tree, hf_usb_bInterfaceClass, tvb, 0, 0, usb_conv_info->interfaceClass);
3033 PROTO_ITEM_SET_GENERATED(ti);
3036 * If this has a 64-byte header, process the extra 16 bytes of
3037 * pseudo-header information.
3039 if ((header_info & USB_HEADER_IS_LINUX) &&
3040 (header_info & USB_HEADER_IS_64_BYTES)) {
3041 offset = dissect_linux_usb_pseudo_header_ext(tvb, offset, pinfo, tree);
3045 if (usb_trans_info) {
3046 /* Check if this is status stage */
3047 if ((header_info & USB_HEADER_IS_USBPCAP) &&
3048 (usbpcap_control_stage == USB_CONTROL_STAGE_STATUS)) {
3049 col_add_fstr(pinfo->cinfo, COL_INFO, "%s Status",
3050 val_to_str(usb_conv_info->usb_trans_info->setup.request,
3051 setup_request_names_vals, "Unknown type %x"));
3052 /* There is no data to dissect */
3053 return;
3056 /* Try to find a class specific dissector */
3057 next_tvb = tvb_new_subset_remaining(tvb, offset);
3058 if (try_heuristics && dissector_try_heuristic(heur_control_subdissector_list, next_tvb, pinfo, parent, usb_conv_info)) {
3059 return;
3061 if (dissector_try_uint_new(usb_control_dissector_table, usb_conv_info->interfaceClass, next_tvb, pinfo, parent, TRUE, usb_conv_info)) {
3062 return;
3065 type_2 = USB_TYPE(usb_trans_info->setup.requesttype);
3066 switch (type_2) {
3068 case RQT_SETUP_TYPE_STANDARD:
3070 * This is a standard response which is managed by this
3071 * dissector
3073 col_add_fstr(pinfo->cinfo, COL_INFO, "%s Response",
3074 val_to_str(usb_conv_info->usb_trans_info->setup.request,
3075 setup_request_names_vals, "Unknown type %x"));
3077 dissector = NULL;
3078 for(tmp = setup_response_dissectors;tmp->dissector;tmp++) {
3079 if (tmp->request == usb_conv_info->usb_trans_info->setup.request) {
3080 dissector = tmp->dissector;
3081 break;
3085 if (dissector) {
3086 offset = dissector(pinfo, parent, tvb, offset, usb_conv_info->usb_trans_info,
3087 usb_conv_info, bus_id, device_address);
3088 } else {
3089 if (tvb_reported_length_remaining(tvb, offset) != 0) {
3090 proto_tree_add_text(parent, tvb, offset, -1, "CONTROL response data");
3091 offset += tvb_length_remaining(tvb, offset);
3094 break;
3095 default:
3096 if (tvb_reported_length_remaining(tvb, offset) != 0) {
3097 proto_tree_add_text(parent, tvb, offset, -1, "CONTROL response data");
3098 offset += tvb_length_remaining(tvb, offset);
3100 break;
3102 } else {
3103 /* no matching request available */
3104 if (tvb_reported_length_remaining(tvb, offset) != 0) {
3105 proto_tree_add_text(parent, tvb, offset, -1, "CONTROL response data");
3106 offset += tvb_length_remaining(tvb, offset);
3111 break;
3112 case URB_ISOCHRONOUS:
3113 if (header_info & USB_HEADER_IS_LINUX) {
3114 guint32 iso_numdesc = 0;
3115 proto_item *tii;
3116 tii = proto_tree_add_uint(tree, hf_usb_bInterfaceClass, tvb, offset, 0, usb_conv_info->interfaceClass);
3117 PROTO_ITEM_SET_GENERATED(tii);
3118 /* All fields which belong to Linux usbmon headers are in host-endian
3119 * byte order. The fields coming from the USB communication are in little
3120 * endian format (see usb_20.pdf, chapter 8.1 Byte/Bit ordering).
3122 * When a capture file is transfered to a host with different endianness
3123 * than packet was captured then the necessary swapping happens in
3124 * wiretap/pcap-common.c, pcap_process_linux_usb_pseudoheader().
3127 if (setup_flag == 0) {
3128 proto_item *ti;
3129 proto_tree *setup_tree;
3130 int type_2;
3132 /* Dissect the setup header - it's applicable */
3134 ti = proto_tree_add_protocol_format(parent, proto_usb, tvb, offset, 8, "URB setup");
3135 setup_tree = proto_item_add_subtree(ti, usb_setup_hdr);
3137 offset = dissect_usb_bmrequesttype(setup_tree, tvb, offset, &type_2);
3138 proto_tree_add_item(setup_tree, hf_usb_request, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3139 offset += 1;
3140 proto_tree_add_item(setup_tree, hf_usb_value, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3141 offset += 2;
3142 proto_tree_add_item(setup_tree, hf_usb_index, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3143 offset += 2;
3144 proto_tree_add_item(setup_tree, hf_usb_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3145 offset += 2;
3146 } else {
3148 /* Process ISO related fields (usbmon_packet.iso). The fields are
3149 * in host endian byte order so use tvb_memcopy() and
3150 * proto_tree_add_uint() pair.
3152 guint32 val32;
3154 tvb_memcpy(tvb, (guint8 *)&val32, offset, 4);
3155 proto_tree_add_uint(tree, hf_usb_iso_error_count, tvb, offset, 4, val32);
3156 offset += 4;
3158 tvb_memcpy(tvb, (guint8 *)&iso_numdesc, offset, 4);
3159 proto_tree_add_uint(tree, hf_usb_iso_numdesc, tvb, offset, 4, iso_numdesc);
3160 offset += 4;
3164 * If this has a 64-byte header, process the extra 16 bytes of
3165 * pseudo-header information.
3167 if (header_info & USB_HEADER_IS_64_BYTES) {
3168 guint32 ndesc;
3170 offset += 4; /* interval */
3171 offset += 4; /* start_frame */
3172 offset += 4; /* copy of URB's transfer flags */
3174 tvb_memcpy(tvb, (guint8 *)&ndesc, offset, 4);
3175 offset += 4;
3178 if (setup_flag != 0) {
3179 proto_tree *urb_tree;
3180 guint32 i;
3181 unsigned int data_base;
3182 guint32 iso_status;
3183 guint32 iso_off;
3184 guint32 iso_len;
3185 guint32 iso_pad;
3187 data_base = offset + iso_numdesc * 16;
3188 urb_tree = tree;
3189 for (i = 0; i != iso_numdesc; i++) {
3190 /* Fetch ISO descriptor fields stored in host
3191 * endian byte order.
3193 tvb_memcpy(tvb, (guint8 *)&iso_status, offset, 4);
3194 tvb_memcpy(tvb, (guint8 *)&iso_off, offset+4, 4);
3195 tvb_memcpy(tvb, (guint8 *)&iso_len, offset+8, 4);
3197 if (parent) {
3198 proto_item *ti;
3199 if (iso_len > 0) {
3200 ti = proto_tree_add_protocol_format(urb_tree, proto_usb, tvb, offset,
3201 16, "USB isodesc %u [%s] (%u bytes)", i,
3202 val_to_str_ext(iso_status, &usb_urb_status_vals_ext, "Error %d"), iso_len);
3203 } else {
3204 ti = proto_tree_add_protocol_format(urb_tree, proto_usb, tvb, offset,
3205 16, "USB isodesc %u [%s]", i, val_to_str_ext(iso_status, &usb_urb_status_vals_ext, "Error %d"));
3207 tree = proto_item_add_subtree(ti, usb_isodesc);
3210 proto_tree_add_int(tree, hf_usb_iso_status, tvb, offset, 4, iso_status);
3211 offset += 4;
3213 proto_tree_add_uint(tree, hf_usb_iso_off, tvb, offset, 4, iso_off);
3214 offset += 4;
3216 proto_tree_add_uint(tree, hf_usb_iso_len, tvb, offset, 4, iso_len);
3217 offset += 4;
3219 /* When the ISO status is OK and there is ISO data and this ISO data is
3220 * fully captured then show this data.
3222 if (!iso_status && iso_len && data_base + iso_off + iso_len <= tvb_length(tvb))
3223 proto_tree_add_item(tree, hf_usb_iso_data, tvb, data_base + iso_off, iso_len, ENC_NA);
3225 tvb_memcpy(tvb, (guint8 *)&iso_pad, offset, 4);
3226 proto_tree_add_uint(tree, hf_usb_iso_pad, tvb, offset, 4, iso_pad);
3227 offset += 4;
3230 } else if (header_info & USB_HEADER_IS_USBPCAP) {
3231 guint32 num_packets;
3232 guint32 i;
3233 guint32 data_start_offset;
3234 proto_tree *urb_tree;
3236 /* 27 bytes of header were dissected in dissect_win32_usb_pseudo_header() */
3237 data_start_offset = offset - 27 + hdr_len;
3238 urb_tree = parent;
3240 proto_tree_add_item(tree, hf_usb_win32_iso_start_frame, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3241 offset += 4;
3243 num_packets = tvb_get_letohl(tvb, offset);
3244 proto_tree_add_item(tree, hf_usb_win32_iso_num_packets, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3245 offset += 4;
3247 proto_tree_add_item(tree, hf_usb_win32_iso_error_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3248 offset += 4;
3250 for (i = 0; i < num_packets; i++)
3252 guint32 this_offset;
3253 guint32 next_offset;
3254 guint32 iso_len;
3255 proto_item *ti;
3257 if (parent) {
3258 ti = proto_tree_add_protocol_format(urb_tree, proto_usb, tvb, offset,
3259 12, "USB isochronous packet");
3260 tree = proto_item_add_subtree(ti, usb_win32_iso_packet);
3263 this_offset = tvb_get_letohl(tvb, offset);
3264 if (num_packets - i == 1) {
3265 /* this is the last packet */
3266 next_offset = win32_data_len;
3267 } else {
3268 /* there is next packet */
3269 next_offset = tvb_get_letohl(tvb, offset + 12);
3272 if (next_offset > this_offset) {
3273 iso_len = next_offset - this_offset;
3274 } else {
3275 iso_len = 0;
3278 /* If this packet does not contain isochrounous data, do not try to display it */
3279 if (!((is_request && !(endpoint_with_dir & URB_TRANSFER_IN)) ||
3280 (!is_request && (endpoint_with_dir & URB_TRANSFER_IN)))) {
3281 iso_len = 0;
3284 proto_tree_add_item(tree, hf_usb_win32_iso_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3285 offset += 4;
3287 ti = proto_tree_add_item(tree, hf_usb_win32_iso_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3288 if (!(endpoint_with_dir & URB_TRANSFER_IN)) {
3289 /* Isochronous OUT transfer */
3290 proto_item_append_text(ti, " (not used)");
3291 } else {
3292 /* Isochronous IN transfer.
3293 * Length field is being set by host controller.
3295 if (is_request) {
3296 /* Length was not yet set */
3297 proto_item_append_text(ti, " (irrelevant)");
3298 } else {
3299 /* Length was set and (should be) valid */
3300 proto_item_append_text(ti, " (relevant)");
3301 iso_len = tvb_get_letohl(tvb, offset);
3304 offset += 4;
3306 ti = proto_tree_add_item(tree, hf_usb_win32_iso_status, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3307 if (urb_type == URB_SUBMIT) {
3308 proto_item_append_text(ti, " (irrelevant)");
3309 } else {
3310 proto_item_append_text(ti, " (relevant)");
3312 offset += 4;
3314 if (iso_len && data_start_offset + this_offset + iso_len <= tvb_length(tvb))
3315 proto_tree_add_item(tree, hf_usb_iso_data, tvb, (gint)(data_start_offset + this_offset), (gint)iso_len, ENC_NA);
3317 if ((is_request && !(endpoint_with_dir & URB_TRANSFER_IN)) ||
3318 (!is_request && (endpoint_with_dir & URB_TRANSFER_IN))) {
3319 /* We have dissected all the isochronous data */
3320 offset += win32_data_len;
3323 break;
3325 default:
3326 /* dont know */
3327 if (setup_flag == 0) {
3328 proto_item *ti;
3329 proto_tree *setup_tree;
3330 int type_2;
3332 /* Dissect the setup header - it's applicable */
3334 ti = proto_tree_add_protocol_format(parent, proto_usb, tvb, offset, 8, "URB setup");
3335 setup_tree = proto_item_add_subtree(ti, usb_setup_hdr);
3337 offset = dissect_usb_bmrequesttype(setup_tree, tvb, offset, &type_2);
3338 proto_tree_add_item(setup_tree, hf_usb_request, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3339 offset += 1;
3340 proto_tree_add_item(setup_tree, hf_usb_value, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3341 offset += 2;
3342 proto_tree_add_item(setup_tree, hf_usb_index, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3343 offset += 2;
3344 proto_tree_add_item(setup_tree, hf_usb_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3345 offset += 2;
3346 } else {
3347 if (header_info & USB_HEADER_IS_LINUX) {
3348 /* Skip setup/isochronous header - it's not applicable */
3349 offset += 8;
3354 * If this has a 64-byte header, process the extra 16 bytes of
3355 * pseudo-header information.
3357 if ((header_info & USB_HEADER_IS_LINUX) &&
3358 (header_info & USB_HEADER_IS_64_BYTES)) {
3359 offset = dissect_linux_usb_pseudo_header_ext(tvb, offset, pinfo, tree);
3362 break;
3365 next_tvb = tvb_new_subset_remaining(tvb, offset);
3367 if (!dissector_try_uint_new(device_to_dissector, (guint32) (bus_id << 8 | device_address), next_tvb, pinfo, parent, FALSE, usb_conv_info)) {
3368 wmem_tree_key_t key[4];
3369 guint32 k_frame_number;
3370 guint32 k_device_address;
3371 guint32 k_bus_id;
3372 device_protocol_data_t *device_protocol_data;
3374 k_frame_number = pinfo->fd->num;
3375 k_device_address = device_address;
3376 k_bus_id = bus_id;
3378 key[0].length = 1;
3379 key[0].key = &k_device_address;
3380 key[1].length = 1;
3381 key[1].key = &k_bus_id;
3382 key[2].length = 1;
3383 key[2].key = &k_frame_number;
3384 key[3].length = 0;
3385 key[3].key = NULL;
3387 device_protocol_data = (device_protocol_data_t *)wmem_tree_lookup32_array_le(device_to_protocol_table, key);
3388 if (device_protocol_data && device_protocol_data->bus_id == bus_id &&
3389 device_protocol_data->device_address == device_address &&
3390 dissector_try_uint_new(protocol_to_dissector, (guint32) device_protocol_data->protocol, next_tvb, pinfo, parent, FALSE, usb_conv_info)) {
3391 offset += tvb_length(next_tvb);
3392 } else {
3393 device_product_data_t *device_product_data;
3395 device_product_data = (device_product_data_t *)wmem_tree_lookup32_array_le(device_to_product_table, key);
3396 if (device_product_data && device_product_data->bus_id == bus_id &&
3397 device_product_data->device_address == device_address &&
3398 dissector_try_uint_new(product_to_dissector, (guint32) (device_product_data->vendor << 16 | device_product_data->product),
3399 next_tvb, pinfo, parent, FALSE, usb_conv_info)) {
3400 offset += tvb_length(next_tvb);
3403 } else {
3404 offset += tvb_length(next_tvb);
3407 if (tvb_reported_length_remaining(tvb, offset) != 0) {
3408 /* There is leftover capture data to add (padding?) */
3409 proto_tree_add_item(parent, hf_usb_capdata, tvb, offset, -1, ENC_NA);
3413 static void
3414 dissect_linux_usb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent)
3416 dissect_usb_common(tvb, pinfo, parent, USB_HEADER_IS_LINUX);
3419 static void
3420 dissect_linux_usb_mmapped(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent)
3422 dissect_usb_common(tvb, pinfo, parent, USB_HEADER_IS_LINUX | USB_HEADER_IS_64_BYTES);
3426 static void
3427 dissect_win32_usb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent)
3429 dissect_usb_common(tvb, pinfo, parent, USB_HEADER_IS_USBPCAP);
3432 void
3433 proto_register_usb(void)
3435 module_t *usb_module;
3436 static hf_register_info hf[] = {
3438 /* USB packet pseudoheader members */
3439 { &hf_usb_urb_id,
3440 { "URB id", "usb.urb_id",
3441 FT_UINT64, BASE_HEX, NULL, 0x0,
3442 NULL, HFILL }},
3444 { &hf_usb_urb_type,
3445 { "URB type", "usb.urb_type",
3446 FT_UINT8, BASE_DEC, VALS(usb_urb_type_vals), 0x0,
3447 NULL, HFILL }},
3449 { &hf_usb_transfer_type,
3450 { "URB transfer type", "usb.transfer_type",
3451 FT_UINT8, BASE_HEX, VALS(usb_transfer_type_vals), 0x0,
3452 NULL, HFILL }},
3454 { &hf_usb_endpoint_number,
3455 { "Endpoint", "usb.endpoint_number",
3456 FT_UINT8, BASE_HEX, NULL, 0x0,
3457 "USB endpoint number", HFILL }},
3459 { &hf_usb_endpoint_direction,
3460 { "Direction", "usb.endpoint_number.direction",
3461 FT_UINT8, BASE_DEC, VALS(usb_endpoint_direction_vals), 0x80,
3462 "USB endpoint direction", HFILL }},
3464 { &hf_usb_endpoint_number_value,
3465 { "Endpoint value", "usb.endpoint_number.endpoint",
3466 FT_UINT8, BASE_DEC, NULL, 0x7F,
3467 "USB endpoint value", HFILL }},
3469 { &hf_usb_device_address,
3470 { "Device", "usb.device_address",
3471 FT_UINT8, BASE_DEC, NULL, 0x0,
3472 "USB device address", HFILL }},
3474 { &hf_usb_bus_id,
3475 { "URB bus id", "usb.bus_id",
3476 FT_UINT16, BASE_DEC, NULL, 0x0,
3477 NULL, HFILL }},
3479 { &hf_usb_setup_flag,
3480 { "Device setup request", "usb.setup_flag",
3481 FT_STRING, BASE_NONE, NULL, 0x0,
3482 "USB device setup request is relevant (0) or not", HFILL }},
3484 { &hf_usb_data_flag,
3485 { "Data", "usb.data_flag",
3486 FT_STRING, BASE_NONE, NULL, 0x0,
3487 "USB data is present (0) or not", HFILL }},
3489 { &hf_usb_urb_ts_sec,
3490 { "URB sec", "usb.urb_ts_sec",
3491 FT_UINT64, BASE_DEC, NULL, 0x0,
3492 NULL, HFILL }},
3494 { &hf_usb_urb_ts_usec,
3495 { "URB usec", "usb.urb_ts_usec",
3496 FT_UINT32, BASE_DEC, NULL, 0x0,
3497 NULL, HFILL }},
3499 { &hf_usb_urb_status,
3500 { "URB status", "usb.urb_status",
3501 FT_INT32, BASE_DEC|BASE_EXT_STRING, &usb_urb_status_vals_ext, 0x0,
3502 NULL, HFILL }},
3504 { &hf_usb_urb_len,
3505 { "URB length [bytes]", "usb.urb_len",
3506 FT_UINT32, BASE_DEC, NULL, 0x0,
3507 "URB length in bytes", HFILL }},
3509 { &hf_usb_urb_data_len,
3510 { "Data length [bytes]", "usb.data_len",
3511 FT_UINT32, BASE_DEC, NULL, 0x0,
3512 "URB data length in bytes", HFILL }},
3514 /* Win32 USBPcap pseudoheader */
3515 { &hf_usb_win32_header_len,
3516 { "USBPcap pseudoheader length", "usb.usbpcap_header_len",
3517 FT_UINT16, BASE_DEC, NULL, 0x0,
3518 NULL, HFILL }},
3520 { &hf_usb_irp_id,
3521 { "IRP ID", "usb.irp_id",
3522 FT_UINT64, BASE_HEX, NULL, 0x0,
3523 NULL, HFILL }},
3525 { &hf_usb_usbd_status,
3526 { "IRP USBD_STATUS", "usb.usbd_status",
3527 FT_UINT32, BASE_HEX, VALS(win32_usbd_status_vals), 0x0,
3528 "USB request status value", HFILL }},
3530 { &hf_usb_function,
3531 { "URB Function", "usb.function",
3532 FT_UINT16, BASE_HEX|BASE_EXT_STRING, &win32_urb_function_vals_ext, 0x0,
3533 NULL, HFILL }},
3535 { &hf_usb_info,
3536 { "IRP information", "usb.irp_info",
3537 FT_UINT8, BASE_HEX, NULL, 0x0,
3538 NULL, HFILL }},
3540 { &hf_usb_usbpcap_info_reserved,
3541 { "Reserved", "usb.irp_info.reserved",
3542 FT_UINT8, BASE_HEX, NULL, 0xFE,
3543 NULL, HFILL }},
3545 { &hf_usb_usbpcap_info_direction,
3546 { "Direction", "usb.irp_info.direction",
3547 FT_UINT8, BASE_HEX, VALS(win32_usb_info_direction_vals), 0x01,
3548 NULL, HFILL }},
3550 { &hf_usb_win32_device_address,
3551 { "Device address", "usb.device_address",
3552 FT_UINT16, BASE_DEC, NULL, 0x0,
3553 "Windows USB device address", HFILL }},
3555 { &hf_usb_win32_data_len,
3556 { "Packet Data Length", "usb.data_len",
3557 FT_UINT16, BASE_DEC, NULL, 0x0,
3558 NULL, HFILL }},
3560 { &hf_usb_control_stage,
3561 { "Control transfer stage", "usb.control_stage",
3562 FT_UINT8, BASE_DEC, VALS(usb_control_stage_vals), 0x0,
3563 NULL, HFILL }},
3565 { &hf_usb_win32_iso_start_frame,
3566 { "Isochronous transfer start frame", "usb.win32.iso_frame",
3567 FT_UINT32, BASE_DEC, NULL, 0x0,
3568 NULL, HFILL }},
3570 { &hf_usb_win32_iso_num_packets,
3571 { "Isochronous transfer number of packets", "usb.win32.iso_num_packets",
3572 FT_UINT32, BASE_DEC, NULL, 0x0,
3573 NULL, HFILL }},
3575 { &hf_usb_win32_iso_error_count,
3576 { "Isochronous transfer error count", "usb.win32.iso_error_count",
3577 FT_UINT32, BASE_DEC, NULL, 0x0,
3578 NULL, HFILL }},
3580 { &hf_usb_win32_iso_offset,
3581 { "ISO Data offset", "usb.win32.iso_offset",
3582 FT_UINT32, BASE_HEX, NULL, 0x0,
3583 NULL, HFILL }},
3585 { &hf_usb_win32_iso_length,
3586 { "ISO Data length", "usb.win32.iso_data_len",
3587 FT_UINT32, BASE_HEX, NULL, 0x0,
3588 NULL, HFILL }},
3590 { &hf_usb_win32_iso_status,
3591 { "ISO USBD status", "usb.win32.iso_status",
3592 FT_UINT32, BASE_HEX, VALS(win32_usbd_status_vals), 0x0,
3593 NULL, HFILL }},
3596 { &hf_usb_bmRequestType,
3597 { "bmRequestType", "usb.bmRequestType",
3598 FT_UINT8, BASE_HEX, NULL, 0x0,
3599 NULL, HFILL }},
3601 { &hf_usb_request,
3602 { "bRequest", "usb.setup.bRequest",
3603 FT_UINT8, BASE_DEC, VALS(setup_request_names_vals), 0x0,
3604 NULL, HFILL }},
3606 /* Same as hf_usb_request but no descriptive text */
3607 { &hf_usb_request_unknown_class,
3608 { "bRequest", "usb.setup.bRequest",
3609 FT_UINT8, BASE_DEC, NULL, 0x0,
3610 NULL, HFILL }},
3612 { &hf_usb_value,
3613 { "wValue", "usb.setup.wValue",
3614 FT_UINT16, BASE_HEX, NULL, 0x0,
3615 NULL, HFILL }},
3617 { &hf_usb_index,
3618 { "wIndex", "usb.setup.wIndex",
3619 FT_UINT16, BASE_DEC, NULL, 0x0,
3620 NULL, HFILL }},
3622 { &hf_usb_length,
3623 { "wLength", "usb.setup.wLength",
3624 FT_UINT16, BASE_DEC, NULL, 0x0,
3625 NULL, HFILL }},
3627 { &hf_usb_wFeatureSelector,
3628 { "wFeatureSelector", "usb.setup.wFeatureSelector",
3629 FT_UINT16, BASE_DEC, VALS(usb_feature_selector_vals), 0x0,
3630 NULL, HFILL }},
3632 { &hf_usb_wInterface,
3633 { "wInterface", "usb.setup.wInterface",
3634 FT_UINT16, BASE_DEC, NULL, 0x0,
3635 NULL, HFILL }},
3637 { &hf_usb_wStatus,
3638 { "wStatus", "usb.setup.wStatus",
3639 FT_UINT16, BASE_HEX, NULL, 0x0,
3640 NULL, HFILL }},
3642 { &hf_usb_wFrameNumber,
3643 { "wFrameNumber", "usb.setup.wFrameNumber",
3644 FT_UINT16, BASE_DEC, NULL, 0x0,
3645 NULL, HFILL }},
3647 /* --------------------------------- */
3648 { &hf_usb_iso_error_count, /* host endian byte order */
3649 { "ISO error count", "usb.iso.error_count",
3650 FT_UINT16, BASE_DEC, NULL, 0x0,
3651 NULL, HFILL }},
3653 { &hf_usb_iso_numdesc, /* host endian byte order */
3654 { "Number of ISO descriptors", "usb.iso.numdesc",
3655 FT_UINT16, BASE_DEC, NULL, 0x0,
3656 NULL, HFILL }},
3658 /* fields of struct mon_bin_isodesc from linux/drivers/usb/mon/mon_bin.c */
3659 { &hf_usb_iso_status, /* host endian byte order */
3660 { "Status", "usb.iso.iso_status",
3661 FT_INT32, BASE_DEC|BASE_EXT_STRING, &usb_urb_status_vals_ext, 0x0,
3662 "ISO descriptor status", HFILL }},
3664 { &hf_usb_iso_off, /* host endian byte order */
3665 { "Offset [bytes]", "usb.iso.iso_off",
3666 FT_UINT32, BASE_DEC, NULL, 0x0,
3667 "ISO data offset in bytes starting from the end of the last ISO descriptor", HFILL }},
3669 { &hf_usb_iso_len, /* host endian byte order */
3670 { "Length [bytes]", "usb.iso.iso_len",
3671 FT_UINT32, BASE_DEC, NULL, 0x0,
3672 "ISO data length in bytes", HFILL }},
3674 { &hf_usb_iso_pad, /* host endian byte order */
3675 { "Padding", "usb.iso.pad",
3676 FT_UINT32, BASE_HEX, NULL, 0x0,
3677 "Padding field of ISO descriptor structure", HFILL }},
3679 { &hf_usb_iso_data,
3680 {"ISO Data", "usb.iso.data",
3681 FT_BYTES, BASE_NONE, NULL, 0x0,
3682 NULL, HFILL }},
3683 /* --------------------------------- */
3684 #if 0
3685 { &hf_usb_data_len,
3686 {"Application Data Length", "usb.data.length",
3687 FT_UINT32, BASE_DEC, NULL, 0x0,
3688 NULL, HFILL }},
3689 #endif
3691 { &hf_usb_capdata,
3692 {"Leftover Capture Data", "usb.capdata",
3693 FT_BYTES, BASE_NONE, NULL, 0x0,
3694 "Padding added by the USB capture system", HFILL }},
3696 { &hf_usb_bmRequestType_direction,
3697 { "Direction", "usb.bmRequestType.direction",
3698 FT_BOOLEAN, 8, TFS(&tfs_bmrequesttype_direction), USB_DIR_IN,
3699 NULL, HFILL }},
3701 { &hf_usb_bmRequestType_type,
3702 { "Type", "usb.bmRequestType.type",
3703 FT_UINT8, BASE_HEX, VALS(bmrequesttype_type_vals), USB_TYPE_MASK,
3704 NULL, HFILL }},
3706 { &hf_usb_bmRequestType_recipient,
3707 { "Recipient", "usb.bmRequestType.recipient",
3708 FT_UINT8, BASE_HEX, VALS(bmrequesttype_recipient_vals), 0x1f,
3709 NULL, HFILL }},
3711 { &hf_usb_bDescriptorType,
3712 { "bDescriptorType", "usb.bDescriptorType",
3713 FT_UINT8, BASE_HEX, NULL, 0x0,
3714 NULL, HFILL }},
3716 { &hf_usb_descriptor_index,
3717 { "Descriptor Index", "usb.DescriptorIndex",
3718 FT_UINT8, BASE_HEX, NULL, 0x0,
3719 NULL, HFILL }},
3721 { &hf_usb_language_id,
3722 { "Language Id", "usb.LanguageId",
3723 FT_UINT16, BASE_HEX|BASE_EXT_STRING,&usb_langid_vals_ext, 0x0,
3724 NULL, HFILL }},
3726 { &hf_usb_bLength,
3727 { "bLength", "usb.bLength",
3728 FT_UINT8, BASE_DEC, NULL, 0x0,
3729 NULL, HFILL }},
3731 { &hf_usb_bcdUSB,
3732 { "bcdUSB", "usb.bcdUSB",
3733 FT_UINT16, BASE_HEX, NULL, 0x0,
3734 NULL, HFILL }},
3736 { &hf_usb_bDeviceClass,
3737 { "bDeviceClass", "usb.bDeviceClass",
3738 FT_UINT8, BASE_HEX|BASE_EXT_STRING, &usb_class_vals_ext, 0x0,
3739 NULL, HFILL }},
3741 { &hf_usb_bDeviceSubClass,
3742 { "bDeviceSubClass", "usb.bDeviceSubClass",
3743 FT_UINT8, BASE_DEC, NULL, 0x0,
3744 NULL, HFILL }},
3746 { &hf_usb_bDeviceProtocol,
3747 { "bDeviceProtocol", "usb.bDeviceProtocol",
3748 FT_UINT8, BASE_DEC, NULL, 0x0,
3749 NULL, HFILL }},
3751 { &hf_usb_bMaxPacketSize0,
3752 { "bMaxPacketSize0", "usb.bMaxPacketSize0",
3753 FT_UINT8, BASE_DEC, NULL, 0x0,
3754 NULL, HFILL }},
3756 { &hf_usb_idVendor,
3757 { "idVendor", "usb.idVendor",
3758 FT_UINT16, BASE_HEX | BASE_EXT_STRING, &ext_usb_vendors_vals, 0x0,
3759 NULL, HFILL }},
3761 { &hf_usb_idProduct,
3762 { "idProduct", "usb.idProduct",
3763 FT_UINT16, BASE_HEX, NULL, 0x0,
3764 NULL, HFILL }},
3766 { &hf_usb_bcdDevice,
3767 { "bcdDevice", "usb.bcdDevice",
3768 FT_UINT16, BASE_HEX, NULL, 0x0,
3769 NULL, HFILL }},
3771 { &hf_usb_iManufacturer,
3772 { "iManufacturer", "usb.iManufacturer",
3773 FT_UINT8, BASE_DEC, NULL, 0x0,
3774 NULL, HFILL }},
3776 { &hf_usb_iProduct,
3777 { "iProduct", "usb.iProduct",
3778 FT_UINT8, BASE_DEC, NULL, 0x0,
3779 NULL, HFILL }},
3781 { &hf_usb_iSerialNumber,
3782 { "iSerialNumber", "usb.iSerialNumber",
3783 FT_UINT8, BASE_DEC, NULL, 0x0,
3784 NULL, HFILL }},
3786 { &hf_usb_bNumConfigurations,
3787 { "bNumConfigurations", "usb.bNumConfigurations",
3788 FT_UINT8, BASE_DEC, NULL, 0x0,
3789 NULL, HFILL }},
3791 { &hf_usb_wLANGID,
3792 { "wLANGID", "usb.wLANGID",
3793 FT_UINT16, BASE_HEX|BASE_EXT_STRING,&usb_langid_vals_ext, 0x0,
3794 NULL, HFILL }},
3796 { &hf_usb_bString,
3797 { "bString", "usb.bString",
3798 FT_STRING, BASE_NONE, NULL, 0x0,
3799 NULL, HFILL }},
3801 { &hf_usb_bInterfaceNumber,
3802 { "bInterfaceNumber", "usb.bInterfaceNumber",
3803 FT_UINT8, BASE_DEC, NULL, 0x0,
3804 NULL, HFILL }},
3806 { &hf_usb_bAlternateSetting,
3807 { "bAlternateSetting", "usb.bAlternateSetting",
3808 FT_UINT8, BASE_DEC, NULL, 0x0,
3809 NULL, HFILL }},
3811 { &hf_usb_bNumEndpoints,
3812 { "bNumEndpoints", "usb.bNumEndpoints",
3813 FT_UINT8, BASE_DEC, NULL, 0x0,
3814 NULL, HFILL }},
3816 { &hf_usb_bInterfaceClass,
3817 { "bInterfaceClass", "usb.bInterfaceClass",
3818 FT_UINT8, BASE_HEX|BASE_EXT_STRING, &usb_class_vals_ext, 0x0,
3819 NULL, HFILL }},
3821 { &hf_usb_bInterfaceSubClass,
3822 { "bInterfaceSubClass", "usb.bInterfaceSubClass",
3823 FT_UINT8, BASE_HEX, NULL, 0x0,
3824 NULL, HFILL }},
3826 { &hf_usb_bInterfaceSubClass_cdc,
3827 { "bInterfaceSubClass", "usb.bInterfaceSubClass",
3828 FT_UINT8, BASE_HEX | BASE_EXT_STRING, &ext_usb_com_subclass_vals, 0x0,
3829 NULL, HFILL }},
3831 { &hf_usb_bInterfaceSubClass_hid,
3832 { "bInterfaceSubClass", "usb.bInterfaceSubClass",
3833 FT_UINT8, BASE_HEX, VALS(usb_hid_subclass_vals), 0x0,
3834 NULL, HFILL }},
3836 { &hf_usb_bInterfaceProtocol,
3837 { "bInterfaceProtocol", "usb.bInterfaceProtocol",
3838 FT_UINT8, BASE_HEX, NULL, 0x0,
3839 NULL, HFILL }},
3841 { &hf_usb_bInterfaceProtocol_cdc,
3842 { "bInterfaceProtocol", "usb.bInterfaceProtocol",
3843 FT_UINT8, BASE_HEX, VALS(usb_cdc_protocol_vals), 0x0,
3844 NULL, HFILL }},
3846 { &hf_usb_bInterfaceProtocol_cdc_data,
3847 { "bInterfaceProtocol", "usb.bInterfaceProtocol",
3848 FT_UINT8, BASE_HEX, VALS(usb_cdc_data_protocol_vals), 0x0,
3849 NULL, HFILL }},
3851 { &hf_usb_bInterfaceProtocol_hid_boot,
3852 { "bInterfaceProtocol", "usb.bInterfaceProtocol",
3853 FT_UINT8, BASE_HEX, VALS(usb_hid_boot_protocol_vals), 0x0,
3854 NULL, HFILL }},
3856 { &hf_usb_iInterface,
3857 { "iInterface", "usb.iInterface",
3858 FT_UINT8, BASE_DEC, NULL, 0x0,
3859 NULL, HFILL }},
3861 { &hf_usb_bEndpointAddress,
3862 { "bEndpointAddress", "usb.bEndpointAddress",
3863 FT_UINT8, BASE_HEX, NULL, 0x0,
3864 NULL, HFILL }},
3866 { &hf_usb_configuration_bmAttributes,
3867 { "Configuration bmAttributes", "usb.configuration.bmAttributes",
3868 FT_UINT8, BASE_HEX, NULL, 0x0,
3869 NULL, HFILL }},
3871 { &hf_usb_bmAttributes,
3872 { "bmAttributes", "usb.bmAttributes",
3873 FT_UINT8, BASE_HEX, NULL, 0x0,
3874 NULL, HFILL }},
3876 { &hf_usb_bEndpointAttributeTransfer,
3877 { "Transfertype", "usb.bmAttributes.transfer",
3878 FT_UINT8, BASE_HEX, VALS(usb_bmAttributes_transfer_vals), 0x03,
3879 NULL, HFILL }},
3881 { &hf_usb_bEndpointAttributeSynchonisation,
3882 { "Synchronisationtype", "usb.bmAttributes.sync",
3883 FT_UINT8, BASE_HEX, VALS(usb_bmAttributes_sync_vals), 0x0c,
3884 NULL, HFILL }},
3886 { &hf_usb_bEndpointAttributeBehaviour,
3887 { "Behaviourtype", "usb.bmAttributes.behaviour",
3888 FT_UINT8, BASE_HEX, VALS(usb_bmAttributes_behaviour_vals), 0x30,
3889 NULL, HFILL }},
3891 { &hf_usb_wMaxPacketSize,
3892 { "wMaxPacketSize", "usb.wMaxPacketSize",
3893 FT_UINT16, BASE_DEC, NULL, 0x0,
3894 NULL, HFILL }},
3896 { &hf_usb_wMaxPacketSize_size,
3897 { "Maximum Packet Size", "usb.wMaxPacketSize.size",
3898 FT_UINT16, BASE_DEC, NULL, 0x3FF,
3899 NULL, HFILL }},
3901 { &hf_usb_wMaxPacketSize_slots,
3902 { "Transactions per microframe", "usb.wMaxPacketSize.slots",
3903 FT_UINT16, BASE_DEC, VALS(usb_wMaxPacketSize_slots_vals), (3<<11),
3904 NULL, HFILL }},
3906 { &hf_usb_bInterval,
3907 { "bInterval", "usb.bInterval",
3908 FT_UINT8, BASE_DEC, NULL, 0x0,
3909 NULL, HFILL }},
3911 { &hf_usb_wTotalLength,
3912 { "wTotalLength", "usb.wTotalLength",
3913 FT_UINT16, BASE_DEC, NULL, 0x0,
3914 NULL, HFILL }},
3916 { &hf_usb_bNumInterfaces,
3917 { "bNumInterfaces", "usb.bNumInterfaces",
3918 FT_UINT8, BASE_DEC, NULL, 0x0,
3919 NULL, HFILL }},
3921 { &hf_usb_bConfigurationValue,
3922 { "bConfigurationValue", "usb.bConfigurationValue",
3923 FT_UINT8, BASE_DEC, NULL, 0x0,
3924 NULL, HFILL }},
3926 { &hf_usb_iConfiguration,
3927 { "iConfiguration", "usb.iConfiguration",
3928 FT_UINT8, BASE_DEC, NULL, 0x0,
3929 NULL, HFILL }},
3931 { &hf_usb_bMaxPower,
3932 { "bMaxPower", "usb.bMaxPower",
3933 FT_UINT8, BASE_DEC, NULL, 0x0,
3934 NULL, HFILL }},
3936 { &hf_usb_configuration_legacy10buspowered,
3937 { "Must be 1", "usb.configuration.legacy10buspowered",
3938 FT_BOOLEAN, 8, TFS(&tfs_mustbeone), 0x80,
3939 "Legacy USB 1.0 bus powered", HFILL }},
3941 { &hf_usb_configuration_selfpowered,
3942 { "Self-Powered", "usb.configuration.selfpowered",
3943 FT_BOOLEAN, 8, TFS(&tfs_selfpowered), 0x40,
3944 NULL, HFILL }},
3946 { &hf_usb_configuration_remotewakeup,
3947 { "Remote Wakeup", "usb.configuration.remotewakeup",
3948 FT_BOOLEAN, 8, TFS(&tfs_remotewakeup), 0x20,
3949 NULL, HFILL }},
3951 { &hf_usb_bEndpointAddress_number,
3952 { "Endpoint Number", "usb.bEndpointAddress.number",
3953 FT_UINT8, BASE_HEX, NULL, 0x0f,
3954 NULL, HFILL }},
3956 { &hf_usb_bEndpointAddress_direction,
3957 { "Direction", "usb.bEndpointAddress.direction",
3958 FT_BOOLEAN, 8, TFS(&tfs_endpoint_direction), 0x80,
3959 NULL, HFILL }},
3961 { &hf_usb_request_in,
3962 { "Request in", "usb.request_in",
3963 FT_FRAMENUM, BASE_NONE, NULL, 0,
3964 "The request to this packet is in this packet", HFILL }},
3966 { &hf_usb_time,
3967 { "Time from request", "usb.time",
3968 FT_RELATIVE_TIME, BASE_NONE, NULL, 0,
3969 "Time between Request and Response for USB cmds", HFILL }},
3971 { &hf_usb_response_in,
3972 { "Response in", "usb.response_in",
3973 FT_FRAMENUM, BASE_NONE, NULL, 0,
3974 "The response to this packet is in this packet", HFILL }},
3976 { &hf_usb_bFirstInterface,
3977 { "bFirstInterface", "usb.bFirstInterface",
3978 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3980 { &hf_usb_bInterfaceCount,
3981 { "bInterfaceCount",
3982 "usb.bInterfaceCount", FT_UINT8, BASE_DEC,
3983 NULL, 0x0, NULL, HFILL }},
3985 { &hf_usb_bFunctionClass,
3986 { "bFunctionClass", "usb.bFunctionClass",
3987 FT_UINT8, BASE_HEX|BASE_EXT_STRING, &usb_class_vals_ext, 0x0, NULL, HFILL }},
3989 { &hf_usb_bFunctionSubClass,
3990 { "bFunctionSubClass",
3991 "usb.bFunctionSubClass", FT_UINT8, BASE_HEX,
3992 NULL, 0x0, NULL, HFILL }},
3994 { &hf_usb_bFunctionProtocol,
3995 { "bFunctionProtocol", "usb.bFunctionProtocol",
3996 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3998 { &hf_usb_iFunction,
3999 { "iFunction",
4000 "usb.iFunction", FT_UINT8, BASE_DEC,
4001 NULL, 0x0, NULL, HFILL }},
4004 static gint *usb_subtrees[] = {
4005 &usb_hdr,
4006 &usb_setup_hdr,
4007 &usb_isodesc,
4008 &usb_win32_iso_packet,
4009 &ett_usb_endpoint,
4010 &ett_usb_setup_bmrequesttype,
4011 &ett_usb_usbpcap_info,
4012 &ett_descriptor_device,
4013 &ett_configuration_bmAttributes,
4014 &ett_configuration_bEndpointAddress,
4015 &ett_endpoint_bmAttributes,
4016 &ett_endpoint_wMaxPacketSize
4019 static ei_register_info ei[] = {
4020 { &ei_usb_bLength_even, { "usb.bLength.even", PI_PROTOCOL, PI_WARN, "Invalid STRING DESCRIPTOR Length (must be even)", EXPFILL }},
4021 { &ei_usb_desc_length_invalid, { "usb.desc_length.invalid", PI_MALFORMED, PI_ERROR, "Invalid descriptor length", EXPFILL }},
4024 expert_module_t* expert_usb;
4026 expert_usb = expert_register_protocol(proto_usb);
4027 expert_register_field_array(expert_usb, ei, array_length(ei));
4029 device_to_product_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
4030 device_to_protocol_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
4031 device_to_dissector = register_dissector_table("usb.device", "USB device", FT_UINT32, BASE_HEX);
4032 protocol_to_dissector = register_dissector_table("usb.protocol", "USB protocol", FT_UINT32, BASE_HEX);
4033 product_to_dissector = register_dissector_table("usb.product", "USB product", FT_UINT32, BASE_HEX);
4035 proto_usb = proto_register_protocol("USB", "USB", "usb");
4036 proto_register_field_array(proto_usb, hf, array_length(hf));
4037 proto_register_subtree_array(usb_subtrees, array_length(usb_subtrees));
4038 linux_usb_handle = register_dissector("usb", dissect_linux_usb, proto_usb);
4040 usb_bulk_dissector_table = register_dissector_table("usb.bulk",
4041 "USB bulk endpoint", FT_UINT8, BASE_DEC);
4042 register_heur_dissector_list("usb.bulk", &heur_bulk_subdissector_list);
4043 usb_control_dissector_table = register_dissector_table("usb.control",
4044 "USB control endpoint", FT_UINT8, BASE_DEC);
4045 register_heur_dissector_list("usb.control", &heur_control_subdissector_list);
4046 usb_interrupt_dissector_table = register_dissector_table("usb.interrupt",
4047 "USB interrupt endpoint", FT_UINT8, BASE_DEC);
4048 register_heur_dissector_list("usb.interrupt", &heur_interrupt_subdissector_list);
4049 usb_descriptor_dissector_table = register_dissector_table("usb.descriptor",
4050 "USB descriptor", FT_UINT8, BASE_DEC);
4052 usb_module = prefs_register_protocol(proto_usb, NULL);
4053 prefs_register_bool_preference(usb_module, "try_heuristics",
4054 "Try heuristic sub-dissectors",
4055 "Try to decode a packet using a heuristic sub-dissector before "
4056 "attempting to dissect the packet using the \"usb.bulk\", \"usb.interrupt\" or "
4057 "\"usb.control\" dissector tables.", &try_heuristics);
4059 usb_tap = register_tap("usb");
4062 void
4063 proto_reg_handoff_usb(void)
4065 dissector_handle_t linux_usb_mmapped_handle;
4066 dissector_handle_t win32_usb_handle;
4068 linux_usb_mmapped_handle = create_dissector_handle(dissect_linux_usb_mmapped,
4069 proto_usb);
4070 win32_usb_handle = create_dissector_handle(dissect_win32_usb, proto_usb);
4072 dissector_add_uint("wtap_encap", WTAP_ENCAP_USB_LINUX, linux_usb_handle);
4073 dissector_add_uint("wtap_encap", WTAP_ENCAP_USB_LINUX_MMAPPED, linux_usb_mmapped_handle);
4074 dissector_add_uint("wtap_encap", WTAP_ENCAP_USBPCAP, win32_usb_handle);