add a dissector table for class specific control input/output pdus
[obnox/wireshark/wip.git] / epan / dissectors / packet-usb.c
1 /* Man this is suboptimal.
2  * The USB Header and the setup data are BIG ENDIAN
3  * but all the real usb data is LITTLE ENDIAN.
4  */
5
6 /* packet-usb.c
7  *
8  * $Id$
9  *
10  * usb basic dissector
11  * By Paolo Abeni <paolo.abeni@email.com>
12  * Ronnie Sahlberg 2006
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27  */
28  
29
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
33
34 #include <glib.h>
35 #include <epan/packet.h>
36 #include <epan/prefs.h>
37 #include <epan/etypes.h>
38 #include <epan/addr_resolv.h>
39 #include <epan/emem.h>
40 #include <epan/conversation.h>
41 #include <string.h>
42 #include "packet-usb.h"
43
44 /* protocols and header fields */
45 static int proto_usb = -1;
46 static int hf_usb_urb_type = -1;
47 static int hf_usb_device_address = -1;
48 static int hf_usb_setup = -1;
49 static int hf_usb_endpoint_number = -1;
50 static int hf_usb_src_endpoint_number = -1;
51 static int hf_usb_dst_endpoint_number = -1;
52 static int hf_usb_request = -1;
53 static int hf_usb_value = -1;
54 static int hf_usb_index = -1;
55 static int hf_usb_length = -1;
56 static int hf_usb_data = -1;
57 static int hf_usb_setup_bmRequestType = -1;
58 static int hf_usb_setup_bmRequestType_direction = -1;
59 static int hf_usb_setup_bmRequestType_type = -1;
60 static int hf_usb_setup_bmRequestType_recipient = -1;
61 static int hf_usb_bDescriptorType = -1;
62 static int hf_usb_descriptor_index = -1;
63 static int hf_usb_language_id = -1;
64 static int hf_usb_bLength = -1;
65 static int hf_usb_bcdUSB = -1;
66 static int hf_usb_bDeviceClass = -1;
67 static int hf_usb_bDeviceSubClass = -1;
68 static int hf_usb_bDeviceProtocol = -1;
69 static int hf_usb_bMaxPacketSize0 = -1;
70 static int hf_usb_idVendor = -1;
71 static int hf_usb_idProduct = -1;
72 static int hf_usb_bcdDevice = -1;
73 static int hf_usb_iManufacturer = -1;
74 static int hf_usb_iProduct = -1;
75 static int hf_usb_iSerialNumber = -1;
76 static int hf_usb_bNumConfigurations = -1;
77 static int hf_usb_wLANGID = -1;
78 static int hf_usb_bString = -1;
79 static int hf_usb_bInterfaceNumber = -1;
80 static int hf_usb_bAlternateSetting = -1;
81 static int hf_usb_bNumEndpoints = -1;
82 static int hf_usb_bInterfaceClass = -1;
83 static int hf_usb_bInterfaceSubClass = -1;
84 static int hf_usb_bInterfaceProtocol = -1;
85 static int hf_usb_iInterface = -1;
86 static int hf_usb_bEndpointAddress = -1;
87 static int hf_usb_bmAttributes = -1;
88 static int hf_usb_wMaxPacketSize = -1;
89 static int hf_usb_bInterval = -1;
90 static int hf_usb_wTotalLength = -1;
91 static int hf_usb_bNumInterfaces = -1;
92 static int hf_usb_bConfigurationValue = -1;
93 static int hf_usb_iConfiguration = -1;
94 static int hf_usb_bMaxPower = -1;
95 static int hf_usb_configuration_bmAttributes = -1;
96 static int hf_usb_configuration_selfpowered = -1;
97 static int hf_usb_configuration_remotewakeup = -1;
98 static int hf_usb_bEndpointAddress_direction = -1;
99 static int hf_usb_bEndpointAddress_number = -1;
100
101 static gint usb_hdr = -1;
102 static gint usb_setup_hdr = -1;
103 static gint ett_usb_setup_bmrequesttype = -1;
104 static gint ett_descriptor_device = -1;
105 static gint ett_configuration_bmAttributes = -1;
106 static gint ett_configuration_bEndpointAddress = -1;
107
108
109 static dissector_table_t usb_bulk_dissector_table;
110 static dissector_table_t usb_control_dissector_table;
111
112
113 typedef enum { 
114   URB_CONTROL_INPUT,
115   URB_CONTROL_OUTPUT,
116   URB_ISOCHRONOUS_INPUT,
117   URB_ISOCHRONOUS_OUTPUT,
118   URB_INTERRUPT_INPUT,
119   URB_INTERRUPT_OUTPUT,
120   URB_BULK_INPUT,
121   URB_BULK_OUTPUT,
122   URB_UNKNOWN
123 } urb_type_t;
124
125 typedef struct usb_header {
126   guint32 urb_type;  
127   guint32 device_address;
128   guint32 endpoint_number;
129   guint32 setup_packet;
130 } usb_header_t;
131
132 typedef struct usb_setup {
133   guint8 bmRequestType;
134   guint8 bRequest;
135   guint16 wValue;
136   guint16 wIndex;
137   guint16 wLength;
138 } usb_setup_t;
139
140
141 static const value_string usb_langid_vals[] = {
142     {0x0000,    "no language specified"},
143     {0x0409,    "English (United States)"},
144     {0, NULL}
145 };
146
147 static const value_string usb_interfaceclass_vals[] = {
148     {IF_CLASS_MASSTORAGE,       "Mass Storage Class"},
149     {0, NULL}
150 };
151
152
153 static const value_string usb_urb_type_vals[] = {
154     {URB_CONTROL_INPUT, "URB_CONTROL_INPUT"},
155     {URB_CONTROL_OUTPUT,"URB_CONTROL_OUTPUT"},
156     {URB_ISOCHRONOUS_INPUT,"URB_ISOCHRONOUS_INPUT"},
157     {URB_ISOCHRONOUS_OUTPUT,"URB_ISOCHRONOUS_OUTPUT"},
158     {URB_INTERRUPT_INPUT,"URB_INTERRUPT_INPUT"},
159     {URB_INTERRUPT_OUTPUT,"URB_INTERRUPT_OUTPUT"},
160     {URB_BULK_INPUT,"URB_BULK_INPUT"},
161     {URB_BULK_OUTPUT,"URB_BULK_OUTPUT"},
162     {URB_UNKNOWN, "URB_UNKNOWN"},
163     {0, NULL}
164 };
165
166 #define USB_DT_DEVICE           1
167 #define USB_DT_CONFIGURATION    2
168 #define USB_DT_STRING           3
169 #define USB_DT_INTERFACE        4
170 #define USB_DT_ENDPOINT         5
171 #define USB_DT_DEVICE_QUALIFIER 6
172 #define USB_DT_OTHER_SPEED_CONFIGURATION        7
173 #define USB_DT_INTERFACE_POWER  8
174 static const value_string descriptor_type_vals[] = {
175     {USB_DT_DEVICE,                     "DEVICE"},
176     {USB_DT_CONFIGURATION,              "CONFIGURATION"},
177     {USB_DT_STRING,                     "STRING"},
178     {USB_DT_INTERFACE,                  "INTERFACE"},
179     {USB_DT_ENDPOINT,                   "ENDPOINT"},
180     {USB_DT_DEVICE_QUALIFIER,           "DEVICE_QUALIFIER"},
181     {USB_DT_OTHER_SPEED_CONFIGURATION,  "OTHER_SPEED_CONFIGURATION"},
182     {USB_DT_INTERFACE_POWER,            "INTERFACE_POWER"},
183     {0,NULL}
184 };
185
186
187 static usb_conv_info_t *
188 get_usb_conv_info(conversation_t *conversation)
189 {
190     usb_conv_info_t *usb_conv_info;
191
192     /* do we have conversation specific data ? */
193     usb_conv_info = conversation_get_proto_data(conversation, proto_usb);
194     if(!usb_conv_info){
195         /* no not yet so create some */
196         usb_conv_info = se_alloc(sizeof(usb_conv_info_t));
197         usb_conv_info->class=IF_CLASS_UNKNOWN;
198         usb_conv_info->transactions=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "usb transactions");
199         usb_conv_info->masstorage=NULL;
200
201         conversation_add_proto_data(conversation, proto_usb, usb_conv_info);
202     }
203  
204     return usb_conv_info;
205 }  
206
207 static conversation_t *
208 get_usb_conversation(packet_info *pinfo, guint32 src_endpoint, guint32 dst_endpoint)
209 {
210     conversation_t *conversation;
211
212     /*
213      * Do we have a conversation for this connection?
214      */
215     conversation = find_conversation(pinfo->fd->num, 
216                                &pinfo->src, &pinfo->dst,
217                                pinfo->ptype, 
218                                src_endpoint, dst_endpoint, 0);
219     if(conversation){
220         return conversation;
221     }
222
223     /* We don't yet have a conversation, so create one. */
224     conversation = conversation_new(pinfo->fd->num, 
225                            &pinfo->src, &pinfo->dst,
226                            pinfo->ptype,
227                            src_endpoint, dst_endpoint, 0);
228     return conversation;
229 }
230
231
232
233 /* SETUP dissectors */
234
235
236 /*
237  * This dissector is used to dissect the setup part and the data
238  * for URB_CONTROL_INPUT / GET DESCRIPTOR
239  */
240
241
242 /* 9.6.2 */
243 static int
244 dissect_usb_device_qualifier_descriptor(packet_info *pinfo _U_, proto_tree *parent_tree, tvbuff_t *tvb, int offset, usb_trans_info_t *usb_trans_info _U_, usb_conv_info_t *usb_conv_info _U_)
245 {
246     proto_item *item=NULL;
247     proto_tree *tree=NULL;
248     int old_offset=offset;
249
250     if(parent_tree){
251         item=proto_tree_add_text(parent_tree, tvb, offset, 0, "DEVICE QUALIFIER DESCRIPTOR");
252         tree=proto_item_add_subtree(item, ett_descriptor_device);
253     }
254
255     /* bLength */
256     proto_tree_add_item(tree, hf_usb_bLength, tvb, offset, 1, TRUE);
257     offset++;
258
259     /* bDescriptorType */
260     proto_tree_add_item(tree, hf_usb_bDescriptorType, tvb, offset, 1, TRUE);
261     offset++;
262
263     /* bcdUSB */
264     proto_tree_add_item(tree, hf_usb_bcdUSB, tvb, offset, 2, TRUE);
265     offset+=2;
266
267     /* bDeviceClass */
268     proto_tree_add_item(tree, hf_usb_bDeviceClass, tvb, offset, 1, TRUE);
269     offset++;
270
271     /* bDeviceSubClass */
272     proto_tree_add_item(tree, hf_usb_bDeviceSubClass, tvb, offset, 1, TRUE);
273     offset++;
274
275     /* bDeviceProtocol */
276     proto_tree_add_item(tree, hf_usb_bDeviceProtocol, tvb, offset, 1, TRUE);
277     offset++;
278
279     /* bMaxPacketSize0 */
280     proto_tree_add_item(tree, hf_usb_bMaxPacketSize0, tvb, offset, 1, TRUE);
281     offset++;
282
283     /* bNumConfigurations */
284     proto_tree_add_item(tree, hf_usb_bNumConfigurations, tvb, offset, 1, TRUE);
285     offset++;
286
287     /* one reserved byte */
288     offset++;
289
290     if(item){
291         proto_item_set_len(item, offset-old_offset);
292     }
293
294     return offset;
295 }
296
297 /* 9.6.1 */
298 static int
299 dissect_usb_device_descriptor(packet_info *pinfo _U_, proto_tree *parent_tree, tvbuff_t *tvb, int offset, usb_trans_info_t *usb_trans_info _U_, usb_conv_info_t *usb_conv_info _U_)
300 {
301     proto_item *item=NULL;
302     proto_tree *tree=NULL;
303     int old_offset=offset;
304
305     if(parent_tree){
306         item=proto_tree_add_text(parent_tree, tvb, offset, 0, "DEVICE DESCRIPTOR");
307         tree=proto_item_add_subtree(item, ett_descriptor_device);
308     }
309
310     /* bLength */
311     proto_tree_add_item(tree, hf_usb_bLength, tvb, offset, 1, TRUE);
312     offset++;
313
314     /* bDescriptorType */
315     proto_tree_add_item(tree, hf_usb_bDescriptorType, tvb, offset, 1, TRUE);
316     offset++;
317
318     /* bcdUSB */
319     proto_tree_add_item(tree, hf_usb_bcdUSB, tvb, offset, 2, TRUE);
320     offset+=2;
321
322     /* bDeviceClass */
323     proto_tree_add_item(tree, hf_usb_bDeviceClass, tvb, offset, 1, TRUE);
324     offset++;
325
326     /* bDeviceSubClass */
327     proto_tree_add_item(tree, hf_usb_bDeviceSubClass, tvb, offset, 1, TRUE);
328     offset++;
329
330     /* bDeviceProtocol */
331     proto_tree_add_item(tree, hf_usb_bDeviceProtocol, tvb, offset, 1, TRUE);
332     offset++;
333
334     /* bMaxPacketSize0 */
335     proto_tree_add_item(tree, hf_usb_bMaxPacketSize0, tvb, offset, 1, TRUE);
336     offset++;
337
338     /* idVendor */
339     proto_tree_add_item(tree, hf_usb_idVendor, tvb, offset, 2, TRUE);
340     offset+=2;
341
342     /* idProduct */
343     proto_tree_add_item(tree, hf_usb_idProduct, tvb, offset, 2, TRUE);
344     offset+=2;
345
346     /* bcdDevice */
347     proto_tree_add_item(tree, hf_usb_bcdDevice, tvb, offset, 2, TRUE);
348     offset+=2;
349
350     /* iManufacturer */
351     proto_tree_add_item(tree, hf_usb_iManufacturer, tvb, offset, 1, TRUE);
352     offset++;
353
354     /* iProduct */
355     proto_tree_add_item(tree, hf_usb_iProduct, tvb, offset, 1, TRUE);
356     offset++;
357
358     /* iSerialNumber */
359     proto_tree_add_item(tree, hf_usb_iSerialNumber, tvb, offset, 1, TRUE);
360     offset++;
361
362     /* bNumConfigurations */
363     proto_tree_add_item(tree, hf_usb_bNumConfigurations, tvb, offset, 1, TRUE);
364     offset++;
365
366     if(item){
367         proto_item_set_len(item, offset-old_offset);
368     }
369
370     return offset;
371 }
372
373 /* 9.6.7 */
374 static int
375 dissect_usb_string_descriptor(packet_info *pinfo _U_, proto_tree *parent_tree, tvbuff_t *tvb, int offset, usb_trans_info_t *usb_trans_info, usb_conv_info_t *usb_conv_info _U_)
376 {
377     proto_item *item=NULL;
378     proto_tree *tree=NULL;
379     int old_offset=offset;
380     guint8 len;
381
382     if(parent_tree){
383         item=proto_tree_add_text(parent_tree, tvb, offset, 0, "STRING DESCRIPTOR");
384         tree=proto_item_add_subtree(item, ett_descriptor_device);
385     }
386
387     /* bLength */
388     proto_tree_add_item(tree, hf_usb_bLength, tvb, offset, 1, TRUE);
389     len=tvb_get_guint8(tvb, offset);
390     offset++;
391
392     /* bDescriptorType */
393     proto_tree_add_item(tree, hf_usb_bDescriptorType, tvb, offset, 1, TRUE);
394     offset++;
395
396     if(!usb_trans_info->get_descriptor.index){
397         /* list of languanges */
398         while(len>(offset-old_offset)){
399             /* wLANGID */
400             proto_tree_add_item(tree, hf_usb_wLANGID, tvb, offset, 2, TRUE);
401             offset+=2;
402         }
403     } else {
404         char *str;        
405
406         /* unicode string */
407         str=tvb_get_ephemeral_faked_unicode(tvb, offset, (len-2)/2, TRUE);
408         proto_tree_add_string(tree, hf_usb_bString, tvb, offset, len-2, str);
409     }
410
411     if(item){
412         proto_item_set_len(item, offset-old_offset);
413     }
414
415     return offset;
416 }
417
418
419
420 /* 9.6.5 */
421 static int
422 dissect_usb_interface_descriptor(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, int offset, usb_trans_info_t *usb_trans_info, usb_conv_info_t *usb_conv_info)
423 {
424     proto_item *item=NULL;
425     proto_tree *tree=NULL;
426     int old_offset=offset;
427
428     if(parent_tree){
429         item=proto_tree_add_text(parent_tree, tvb, offset, 0, "INTERFACE DESCRIPTOR");
430         tree=proto_item_add_subtree(item, ett_descriptor_device);
431     }
432
433     /* bLength */
434     proto_tree_add_item(tree, hf_usb_bLength, tvb, offset, 1, TRUE);
435     offset++;
436
437     /* bDescriptorType */
438     proto_tree_add_item(tree, hf_usb_bDescriptorType, tvb, offset, 1, TRUE);
439     offset++;
440
441     /* bInterfaceNumber */
442     proto_tree_add_item(tree, hf_usb_bInterfaceNumber, tvb, offset, 1, TRUE);
443     offset++;
444
445     /* bAlternateSetting */
446     proto_tree_add_item(tree, hf_usb_bAlternateSetting, tvb, offset, 1, TRUE);
447     offset++;
448
449     /* bNumEndpoints */
450     proto_tree_add_item(tree, hf_usb_bNumEndpoints, tvb, offset, 1, TRUE);
451     offset++;
452
453     /* bInterfaceClass */
454     proto_tree_add_item(tree, hf_usb_bInterfaceClass, tvb, offset, 1, TRUE);
455     /* save the class so we can access it later in the endpoint descriptor */
456     usb_conv_info->class=tvb_get_guint8(tvb, offset);
457     if(!pinfo->fd->flags.visited){
458         usb_trans_info->interface_info=se_alloc(sizeof(usb_conv_info_t));
459         usb_trans_info->interface_info->class=tvb_get_guint8(tvb, offset);
460         usb_trans_info->interface_info->transactions=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "usb transactions");
461         usb_trans_info->interface_info->masstorage=NULL;
462     }
463     offset++;
464
465     /* bInterfaceSubClass */
466     proto_tree_add_item(tree, hf_usb_bInterfaceSubClass, tvb, offset, 1, TRUE);
467     offset++;
468
469     /* bInterfaceProtocol */
470     proto_tree_add_item(tree, hf_usb_bInterfaceProtocol, tvb, offset, 1, TRUE);
471     offset++;
472
473     /* iInterface */
474     proto_tree_add_item(tree, hf_usb_iInterface, tvb, offset, 1, TRUE);
475     offset++;
476
477     if(item){
478         proto_item_set_len(item, offset-old_offset);
479     }
480
481     return offset;
482 }
483
484 /* 9.6.6 */
485 static const true_false_string tfs_endpoint_direction = {
486     "IN Endpoint",
487     "OUT Endpoint"
488 };
489 static int
490 dissect_usb_endpoint_descriptor(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, int offset, usb_trans_info_t *usb_trans_info _U_, usb_conv_info_t *usb_conv_info _U_)
491 {
492     proto_item *item=NULL;
493     proto_tree *tree=NULL;
494     proto_item *endpoint_item=NULL;
495     proto_tree *endpoint_tree=NULL;
496     int old_offset=offset;
497     guint8 endpoint;
498
499     if(parent_tree){
500         item=proto_tree_add_text(parent_tree, tvb, offset, 0, "ENDPOINT DESCRIPTOR");
501         tree=proto_item_add_subtree(item, ett_descriptor_device);
502     }
503
504     /* bLength */
505     proto_tree_add_item(tree, hf_usb_bLength, tvb, offset, 1, TRUE);
506     offset++;
507
508     /* bDescriptorType */
509     proto_tree_add_item(tree, hf_usb_bDescriptorType, tvb, offset, 1, TRUE);
510     offset++;
511
512     /* bEndpointAddress */
513     if(tree){
514         endpoint_item=proto_tree_add_item(tree, hf_usb_bEndpointAddress, tvb, offset, 1, TRUE);
515         endpoint_tree=proto_item_add_subtree(endpoint_item, ett_configuration_bEndpointAddress);
516     }
517     endpoint=tvb_get_guint8(tvb, offset)&0x0f;
518     proto_tree_add_item(endpoint_tree, hf_usb_bEndpointAddress_direction, tvb, offset, 1, TRUE);
519     proto_item_append_text(endpoint_item, "  %s", (tvb_get_guint8(tvb, offset)&0x80)?"IN":"OUT");
520     proto_tree_add_item(endpoint_tree, hf_usb_bEndpointAddress_number, tvb, offset, 1, TRUE);
521     proto_item_append_text(endpoint_item, "  Endpoint:%d", endpoint);
522     offset++;
523
524     /* Together with class from the interface descriptor we know what kind
525      * of class the device at endpoint is.
526      * Make sure a conversation exists for this endpoint and attach a 
527      * usb_conv_into_t structure to it.
528      *
529      * All endpoints for the same interface descriptor share the same
530      * usb_conv_info structure.
531      */
532     if((!pinfo->fd->flags.visited)&&usb_trans_info->interface_info){
533         conversation_t *conversation;
534
535         if(pinfo->destport==NO_ENDPOINT){
536             conversation=get_usb_conversation(pinfo, endpoint, pinfo->destport);
537         } else {
538             conversation=get_usb_conversation(pinfo, pinfo->srcport, endpoint);
539         }
540
541         conversation_add_proto_data(conversation, proto_usb, usb_trans_info->interface_info);
542     }
543
544     /* bmAttributes */
545     proto_tree_add_item(tree, hf_usb_bmAttributes, tvb, offset, 1, TRUE);
546     offset++;
547
548     /* wMaxPacketSize */
549     proto_tree_add_item(tree, hf_usb_wMaxPacketSize, tvb, offset, 2, TRUE);
550     offset+=2;
551
552     /* bInterval */
553     proto_tree_add_item(tree, hf_usb_bInterval, tvb, offset, 1, TRUE);
554     offset++;
555
556     if(item){
557         proto_item_set_len(item, offset-old_offset);
558     }
559
560     return offset;
561 }
562
563 /* 9.6.3 */
564 static const true_false_string tfs_selfpowered = {
565     "This device is SELF-POWERED",
566     "This device is powered from the USB bus"
567 };
568 static const true_false_string tfs_remotewakeup = {
569     "This device supports REMOTE WAKEUP",
570     "This device does NOT support remote wakeup"
571 };
572 static int
573 dissect_usb_configuration_descriptor(packet_info *pinfo _U_, proto_tree *parent_tree, tvbuff_t *tvb, int offset, usb_trans_info_t *usb_trans_info, usb_conv_info_t *usb_conv_info)
574 {
575     proto_item *item=NULL;
576     proto_tree *tree=NULL;
577     int old_offset=offset;
578     guint16 len;
579     proto_item *flags_item=NULL;
580     proto_tree *flags_tree=NULL;
581     guint8 flags;
582     proto_item *power_item=NULL;
583     guint8 power;
584
585     if(parent_tree){
586         item=proto_tree_add_text(parent_tree, tvb, offset, 0, "CONFIGURATION DESCRIPTOR");
587         tree=proto_item_add_subtree(item, ett_descriptor_device);
588     }
589
590     /* bLength */
591     proto_tree_add_item(tree, hf_usb_bLength, tvb, offset, 1, TRUE);
592     offset++;
593
594     /* bDescriptorType */
595     proto_tree_add_item(tree, hf_usb_bDescriptorType, tvb, offset, 1, TRUE);
596     offset++;
597
598     /* wTotalLength */
599     proto_tree_add_item(tree, hf_usb_wTotalLength, tvb, offset, 2, TRUE);
600     len=tvb_get_letohs(tvb, offset);
601     offset+=2;
602
603     /* bNumInterfaces */
604     proto_tree_add_item(tree, hf_usb_bNumInterfaces, tvb, offset, 1, TRUE);
605     offset++;
606
607     /* bConfigurationValue */
608     proto_tree_add_item(tree, hf_usb_bConfigurationValue, tvb, offset, 1, TRUE);
609     offset++;
610
611     /* iConfiguration */
612     proto_tree_add_item(tree, hf_usb_iConfiguration, tvb, offset, 1, TRUE);
613     offset++;
614
615     /* bmAttributes */
616     if(tree){
617         flags_item=proto_tree_add_item(tree, hf_usb_configuration_bmAttributes, tvb, offset, 1, TRUE);
618         flags_tree=proto_item_add_subtree(flags_item, ett_configuration_bmAttributes);
619     }
620     flags=tvb_get_guint8(tvb, offset);
621     proto_tree_add_item(flags_tree, hf_usb_configuration_selfpowered, tvb, offset, 1, TRUE);
622     proto_item_append_text(flags_item, "  %sSELF-POWERED", (flags&0x40)?"":"NOT ");
623     flags&=~0x40;
624     proto_tree_add_item(flags_tree, hf_usb_configuration_remotewakeup, tvb, offset, 1, TRUE);
625     proto_item_append_text(flags_item, "  %sREMOTE-WAKEUP", (flags&0x20)?"":"NO ");
626     flags&=~0x20;
627     offset++;
628
629     /* bMaxPower */
630     power_item=proto_tree_add_item(tree, hf_usb_bMaxPower, tvb, offset, 1, TRUE);
631     power=tvb_get_guint8(tvb, offset);
632     proto_item_append_text(power_item, "  (%dmA)", power*2);
633     offset++;
634
635     /* initialize interface_info to NULL */
636     usb_trans_info->interface_info=NULL;
637
638     /* decode any additional interface and endpoint descriptors */
639     while(len>(old_offset-offset)){
640         guint8 next_type;
641
642         if(tvb_length_remaining(tvb, offset)<2){
643             break;
644         }
645         next_type=tvb_get_guint8(tvb, offset+1);
646         switch(next_type){
647         case USB_DT_INTERFACE:
648             offset=dissect_usb_interface_descriptor(pinfo, parent_tree, tvb, offset, usb_trans_info, usb_conv_info);
649             break;
650         case USB_DT_ENDPOINT:
651             offset=dissect_usb_endpoint_descriptor(pinfo, parent_tree, tvb, offset, usb_trans_info, usb_conv_info);
652             break;
653         default:
654             return offset;
655         }
656     }
657
658     if(item){
659         proto_item_set_len(item, offset-old_offset);
660     }
661
662     return offset;
663 }
664
665
666 static void
667 dissect_usb_setup_get_descriptor(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, gboolean is_request, usb_trans_info_t *usb_trans_info, usb_conv_info_t *usb_conv_info)
668 {
669     if(is_request){
670         /* descriptor type */
671         proto_tree_add_item(tree, hf_usb_bDescriptorType, tvb, offset, 1, FALSE);
672         usb_trans_info->get_descriptor.type=tvb_get_guint8(tvb, offset);
673         offset++;
674         if (check_col(pinfo->cinfo, COL_INFO)) {
675             col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
676                 val_to_str(usb_trans_info->get_descriptor.type, descriptor_type_vals, "Unknown type %x"));
677         }
678
679         /* descriptor index */
680         proto_tree_add_item(tree, hf_usb_descriptor_index, tvb, offset, 1, FALSE);
681         usb_trans_info->get_descriptor.index=tvb_get_guint8(tvb, offset);
682         offset++;
683
684         /* language id */
685         proto_tree_add_item(tree, hf_usb_language_id, tvb, offset, 2, FALSE);
686         offset+=2;
687
688         /* length */
689         proto_tree_add_item(tree, hf_usb_length, tvb, offset, 2, FALSE);
690         offset += 2;
691     } else {
692         if (check_col(pinfo->cinfo, COL_INFO)) {
693             col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
694                 val_to_str(usb_trans_info->get_descriptor.type, descriptor_type_vals, "Unknown type %x"));
695         }
696         switch(usb_trans_info->get_descriptor.type){
697         case USB_DT_DEVICE:
698             offset=dissect_usb_device_descriptor(pinfo, tree, tvb, offset, usb_trans_info, usb_conv_info);
699             break;
700         case USB_DT_CONFIGURATION:
701             offset=dissect_usb_configuration_descriptor(pinfo, tree, tvb, offset, usb_trans_info, usb_conv_info);
702             break;
703         case USB_DT_STRING: 
704             offset=dissect_usb_string_descriptor(pinfo, tree, tvb, offset, usb_trans_info, usb_conv_info);
705             break;
706         case USB_DT_INTERFACE:
707             offset=dissect_usb_interface_descriptor(pinfo, tree, tvb, offset, usb_trans_info, usb_conv_info);
708             break;
709         case USB_DT_ENDPOINT:
710             offset=dissect_usb_endpoint_descriptor(pinfo, tree, tvb, offset, usb_trans_info, usb_conv_info);
711             break;
712         case USB_DT_DEVICE_QUALIFIER:
713             offset=dissect_usb_device_qualifier_descriptor(pinfo, tree, tvb, offset, usb_trans_info, usb_conv_info);
714             break;
715         default:
716             /* XXX dissect the descriptor coming back from the device */
717             proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "get descriptor  data...");
718         }
719     }
720 }
721
722
723
724
725 typedef void (*usb_setup_dissector)(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, gboolean is_request, usb_trans_info_t *usb_trans_info, usb_conv_info_t *usb_conv_info);
726
727 typedef struct _usb_setup_dissector_table_t {
728     guint8 request;
729     usb_setup_dissector dissector;
730 } usb_setup_dissector_table_t;
731 #define USB_SETUP_GET_DESCRIPTOR        6
732 static const usb_setup_dissector_table_t setup_dissectors[] = {
733     {USB_SETUP_GET_DESCRIPTOR,  dissect_usb_setup_get_descriptor},
734     {0, NULL}
735 };  
736 static const value_string setup_request_names_vals[] = {
737     {USB_SETUP_GET_DESCRIPTOR,          "GET DESCRIPTOR"},
738     {0, NULL}
739 };  
740
741
742
743
744
745
746
747
748 static const true_false_string tfs_bmrequesttype_direction = {
749         "Device-to-host",
750         "Host-to-device"
751 };
752 static const value_string bmrequesttype_type_vals[] = {
753     {0, "Standard"},
754     {1, "Class"},
755     {2, "Vendor"},
756     {3, "Reserved"},
757     {0, NULL}
758 };
759 static const value_string bmrequesttype_recipient_vals[] = {
760     {0, "Device"},
761     {1, "Interface"},
762     {2, "Endpoint"},
763     {3, "Other"},
764     {0, NULL}
765 };
766
767 static int
768 dissect_usb_setup_bmrequesttype(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
769 {
770         proto_item *item=NULL;
771         proto_tree *tree=NULL;
772
773         if(parent_tree){
774                 item=proto_tree_add_item(parent_tree, hf_usb_setup_bmRequestType, tvb, offset, 1, TRUE);
775                 tree = proto_item_add_subtree(item, ett_usb_setup_bmrequesttype);
776         }
777
778         proto_tree_add_item(tree, hf_usb_setup_bmRequestType_direction, tvb, offset, 1, TRUE);
779         proto_tree_add_item(tree, hf_usb_setup_bmRequestType_type, tvb, offset, 1, TRUE);
780         proto_tree_add_item(tree, hf_usb_setup_bmRequestType_recipient, tvb, offset, 1, TRUE);
781
782         offset++;
783         return offset;
784 }
785
786
787
788
789
790 static void
791 dissect_usb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent)
792 {
793     int offset = 0;
794     int type, endpoint;
795     gboolean setup;
796     proto_tree *tree = NULL;
797     static guint32 src_addr, dst_addr, tmp_addr; /* has to be static due to SET_ADDRESS */
798     guint32 src_port, dst_port;
799     gboolean is_request;
800     usb_conv_info_t *usb_conv_info;
801     conversation_t *conversation;
802     
803     if (check_col(pinfo->cinfo, COL_PROTOCOL))
804         col_set_str(pinfo->cinfo, COL_PROTOCOL, "USB");
805
806     /* add usb hdr*/    
807     if (parent) {
808       proto_item *ti = NULL;
809       ti = proto_tree_add_protocol_format(parent, proto_usb, tvb, 0, sizeof(usb_header_t), "USB URB");
810
811       tree = proto_item_add_subtree(ti, usb_hdr);
812     }
813
814     
815     type = tvb_get_ntohl(tvb, offset);
816     proto_tree_add_item(tree, hf_usb_urb_type, tvb, offset, 4, FALSE);
817     offset += 4;
818     if (check_col(pinfo->cinfo, COL_INFO)) {
819         col_append_fstr(pinfo->cinfo, COL_INFO, "%s",
820             val_to_str(type, usb_urb_type_vals, "Unknown type %x"));
821     }
822
823 #define USB_ADDR_LEN 4
824     proto_tree_add_item(tree, hf_usb_device_address, tvb, offset, 4, FALSE);
825     tmp_addr=tvb_get_ntohl(tvb, offset);
826     offset += 4;
827
828     proto_tree_add_item(tree, hf_usb_endpoint_number, tvb, offset, 4, FALSE);
829     endpoint=tvb_get_ntohl(tvb, offset);
830     offset += 4;
831
832     /* check for setup hdr presence */
833     proto_tree_add_item(tree, hf_usb_setup, tvb, offset, 4, FALSE);
834     setup = tvb_get_ntohl(tvb, offset);
835     offset += 4;
836
837
838     /* set up addresses and ports */
839     switch(type){
840     case URB_BULK_INPUT:
841         /* Bulk input are responses if they contain payload data and
842          * requests otherwise.
843          */
844         if(tvb_length_remaining(tvb, offset)>0){
845             src_addr=tmp_addr;
846             src_port=endpoint;
847             dst_addr=0xffffffff;
848             dst_port=NO_ENDPOINT;
849             is_request=FALSE;
850         } else {
851             src_addr=0xffffffff;
852             src_port=NO_ENDPOINT;
853             dst_addr=tmp_addr;
854             dst_port=endpoint;
855             is_request=TRUE;
856         }
857         break;
858     case URB_BULK_OUTPUT:
859         /* Bulk output are requests if they contain payload data and
860          * responses otherwise.
861          */
862         if(tvb_length_remaining(tvb, offset)>0){
863             src_addr=0xffffffff;
864             src_port=NO_ENDPOINT;
865             dst_addr=tmp_addr;
866             dst_port=endpoint;
867             is_request=TRUE;
868         } else {
869             src_addr=tmp_addr;
870             src_port=endpoint;
871             dst_addr=0xffffffff;
872             dst_port=NO_ENDPOINT;
873             is_request=FALSE;
874         }
875         break;
876     case URB_CONTROL_INPUT:
877         /* CONTROL INPUT packets are requests if they contain a "setup"
878          * blob and responses othervise
879          */
880         if(setup){
881             src_addr=0xffffffff;
882             src_port=NO_ENDPOINT;
883             dst_addr=tmp_addr;
884             dst_port=endpoint;
885             is_request=TRUE;
886         } else {
887             src_addr=tmp_addr;
888             src_port=endpoint;
889             dst_addr=0xffffffff;
890             dst_port=NO_ENDPOINT;
891             is_request=FALSE;
892         }
893         break;
894     default:
895         /* dont know */
896         src_addr=0xffffffff;
897         dst_addr=0xffffffff;
898         src_port=NO_ENDPOINT;
899         dst_port=NO_ENDPOINT;
900         is_request=FALSE;
901     }
902     SET_ADDRESS(&pinfo->net_src, AT_USB, USB_ADDR_LEN, (char *)&src_addr);
903     SET_ADDRESS(&pinfo->src, AT_USB, USB_ADDR_LEN, (char *)&src_addr);
904     SET_ADDRESS(&pinfo->net_dst, AT_USB, USB_ADDR_LEN, (char *)&dst_addr);
905     SET_ADDRESS(&pinfo->dst, AT_USB, USB_ADDR_LEN, (char *)&dst_addr);
906     pinfo->ptype=PT_USB;
907     pinfo->srcport=src_port;
908     pinfo->destport=dst_port;
909
910
911     conversation=get_usb_conversation(pinfo, pinfo->srcport, pinfo->destport);
912
913     usb_conv_info=get_usb_conv_info(conversation);
914
915     /* do we have conversation specific data ? */
916     usb_conv_info = conversation_get_proto_data(conversation, proto_usb);
917     if(!usb_conv_info){
918         /* no not yet so create some */
919         usb_conv_info = se_alloc(sizeof(usb_conv_info_t));
920         usb_conv_info->class=IF_CLASS_UNKNOWN;
921         usb_conv_info->transactions=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "usb transactions");
922         usb_conv_info->masstorage=NULL;
923
924         conversation_add_proto_data(conversation, proto_usb, usb_conv_info);
925     }
926    
927
928
929
930
931     switch(type){
932     case URB_BULK_INPUT:
933         {
934         proto_item *item;
935
936         item=proto_tree_add_uint(tree, hf_usb_bInterfaceClass, tvb, offset, 0, usb_conv_info->class);
937         PROTO_ITEM_SET_GENERATED(item);
938         if(tvb_length_remaining(tvb, offset)){
939             tvbuff_t *next_tvb;
940
941             pinfo->usb_conv_info=usb_conv_info;
942             next_tvb=tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), tvb_reported_length_remaining(tvb, offset));
943             if(dissector_try_port(usb_bulk_dissector_table, usb_conv_info->class, next_tvb, pinfo, parent)){
944                 return;
945             }
946         }
947         }
948         break;
949     case URB_BULK_OUTPUT:
950         {
951         proto_item *item;
952
953         item=proto_tree_add_uint(tree, hf_usb_bInterfaceClass, tvb, offset, 0, usb_conv_info->class);
954         PROTO_ITEM_SET_GENERATED(item);
955         if(tvb_length_remaining(tvb, offset)){
956             tvbuff_t *next_tvb;
957
958             pinfo->usb_conv_info=usb_conv_info;
959             next_tvb=tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), tvb_reported_length_remaining(tvb, offset));
960             if(dissector_try_port(usb_bulk_dissector_table, usb_conv_info->class, next_tvb, pinfo, parent)){
961                 return;
962             }
963         }
964         }
965         break;
966     case URB_CONTROL_INPUT:
967         {
968         const usb_setup_dissector_table_t *tmp;
969         usb_setup_dissector dissector;
970         proto_item *ti = NULL;
971         proto_tree *setup_tree = NULL;
972         guint8 requesttype, request;
973         usb_trans_info_t *usb_trans_info;
974
975         ti=proto_tree_add_uint(tree, hf_usb_bInterfaceClass, tvb, offset, 0, usb_conv_info->class);
976         PROTO_ITEM_SET_GENERATED(ti);
977
978         if(is_request){
979             tvbuff_t *next_tvb;
980
981             /* this is a request */
982             ti = proto_tree_add_protocol_format(tree, proto_usb, tvb, offset, sizeof(usb_setup_t), "URB setup");
983             setup_tree = proto_item_add_subtree(ti, usb_setup_hdr);
984             requesttype=tvb_get_guint8(tvb, offset);        
985             offset=dissect_usb_setup_bmrequesttype(setup_tree, tvb, offset);
986
987
988             /* read the request code and spawn off to a class specific 
989              * dissector if found 
990              */
991             request=tvb_get_guint8(tvb, offset);
992             usb_trans_info=se_tree_lookup32(usb_conv_info->transactions, pinfo->fd->num);
993             if(!usb_trans_info){
994                 usb_trans_info=se_alloc(sizeof(usb_trans_info_t));
995                 usb_trans_info->request_in=pinfo->fd->num;
996                 usb_trans_info->response_in=0;
997                 usb_trans_info->requesttype=requesttype;
998                 usb_trans_info->request=request;
999                 se_tree_insert32(usb_conv_info->transactions, pinfo->fd->num, usb_trans_info);
1000             }
1001             usb_conv_info->usb_trans_info=usb_trans_info;
1002             pinfo->usb_conv_info=usb_conv_info;
1003
1004             /* Try to find a class specific dissector */  
1005             next_tvb=tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), tvb_reported_length_remaining(tvb, offset));
1006             if(dissector_try_port(usb_control_dissector_table, usb_conv_info->class, next_tvb, pinfo, tree)){
1007                 return;
1008             }
1009
1010             /* 
1011              * This was a standard request which is managed by this dissector
1012              */
1013             proto_tree_add_item(setup_tree, hf_usb_request, tvb, offset, 1, TRUE);
1014             offset += 1;
1015
1016             if (check_col(pinfo->cinfo, COL_INFO)) {
1017                 col_clear(pinfo->cinfo, COL_INFO);
1018                 col_append_fstr(pinfo->cinfo, COL_INFO, "%s Request",
1019                     val_to_str(usb_trans_info->request, setup_request_names_vals, "Unknown type %x"));
1020             }
1021
1022             dissector=NULL;
1023             for(tmp=setup_dissectors;tmp->dissector;tmp++){
1024                 if(tmp->request==request){
1025                     dissector=tmp->dissector;
1026                     break;
1027                 }
1028             }
1029   
1030             if(dissector){
1031                 dissector(pinfo, setup_tree, tvb, offset, is_request, usb_trans_info, usb_conv_info);
1032                 offset+=6;
1033             } else {
1034                 proto_tree_add_item(setup_tree, hf_usb_value, tvb, offset, 2, FALSE);
1035                 offset += 2;
1036                 proto_tree_add_item(setup_tree, hf_usb_index, tvb, offset, 2, FALSE);
1037                 offset += 2;
1038                 proto_tree_add_item(setup_tree, hf_usb_length, tvb, offset, 2, FALSE);
1039                 offset += 2;
1040             }
1041         } else {
1042             tvbuff_t *next_tvb;
1043
1044             /* this is a response */
1045             if(pinfo->fd->flags.visited){
1046                 usb_trans_info=se_tree_lookup32(usb_conv_info->transactions, pinfo->fd->num);
1047             } else {
1048                 usb_trans_info=se_tree_lookup32_le(usb_conv_info->transactions, pinfo->fd->num);
1049                 if(usb_trans_info){
1050                     usb_trans_info->response_in=pinfo->fd->num;
1051                     se_tree_insert32(usb_conv_info->transactions, pinfo->fd->num, usb_trans_info);
1052                 }
1053             }
1054             if(usb_trans_info){
1055                 usb_conv_info->usb_trans_info=usb_trans_info;
1056                 dissector=NULL;
1057                 for(tmp=setup_dissectors;tmp->dissector;tmp++){
1058                     if(tmp->request==usb_trans_info->request){
1059                         dissector=tmp->dissector;
1060                         break;
1061                     }
1062                 }
1063
1064                 /* Try to find a class specific dissector */  
1065                 usb_conv_info->usb_trans_info=usb_trans_info;
1066                 pinfo->usb_conv_info=usb_conv_info;
1067                 next_tvb=tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), tvb_reported_length_remaining(tvb, offset));
1068                 if(dissector_try_port(usb_control_dissector_table, usb_conv_info->class, next_tvb, pinfo, tree)){
1069                     return;
1070                 }
1071
1072                 if (check_col(pinfo->cinfo, COL_INFO)) {
1073                     col_clear(pinfo->cinfo, COL_INFO);
1074                     col_append_fstr(pinfo->cinfo, COL_INFO, "%s Response",
1075                         val_to_str(usb_trans_info->request, setup_request_names_vals, "Unknown type %x"));
1076                 }
1077
1078                 if(dissector){
1079                     dissector(pinfo, tree, tvb, offset, is_request, usb_trans_info, usb_conv_info);
1080                 }
1081             } else {
1082                 /* could not find a matching request */
1083             }
1084         }
1085         return;
1086         }
1087         break;
1088     default:
1089         /* dont know */
1090         ;
1091     }
1092
1093
1094     if (setup) {
1095         proto_item *ti = NULL;
1096         proto_tree *setup_tree = NULL;
1097         guint8 requesttype, request;
1098
1099         ti = proto_tree_add_protocol_format(tree, proto_usb, tvb, offset, sizeof(usb_setup_t), "URB setup");
1100         setup_tree = proto_item_add_subtree(ti, usb_setup_hdr);
1101
1102
1103         requesttype=tvb_get_guint8(tvb, offset);        
1104         offset=dissect_usb_setup_bmrequesttype(setup_tree, tvb, offset);
1105
1106         request=tvb_get_guint8(tvb, offset);
1107         proto_tree_add_item(setup_tree, hf_usb_request, tvb, offset, 1, FALSE);
1108         offset += 1;
1109
1110         proto_tree_add_item(tree, hf_usb_value, tvb, offset, 2, FALSE);
1111         offset += 2;
1112         proto_tree_add_item(tree, hf_usb_index, tvb, offset, 2, FALSE);
1113         offset += 2;
1114         proto_tree_add_item(tree, hf_usb_length, tvb, offset, 2, FALSE);
1115         offset += 2;
1116     }
1117     
1118     proto_tree_add_item(tree, hf_usb_data, tvb,
1119         offset, tvb_length_remaining(tvb, offset), FALSE);
1120 }
1121
1122 void
1123 proto_register_usb(void)
1124 {
1125     static hf_register_info hf[] = {
1126     
1127         { &hf_usb_urb_type,
1128         { "URB type", "usb.urb_type", FT_UINT32, BASE_DEC, 
1129                 VALS(usb_urb_type_vals), 0x0,
1130                 "URB type", HFILL }},
1131
1132         { &hf_usb_device_address,
1133         { "Device", "usb.device_address", FT_UINT32, BASE_DEC, NULL, 0x0,
1134                 "USB device address", HFILL }},
1135
1136         { &hf_usb_setup,
1137         { "Setup", "usb.setup", FT_UINT32, BASE_DEC, NULL, 0x0,
1138                  "USB setup", HFILL }},
1139
1140         { &hf_usb_endpoint_number,
1141         { "Endpoint", "usb.endpoint_number", FT_UINT32, BASE_HEX, NULL, 0x0,
1142                 "usb endpoint number", HFILL }},
1143
1144         { &hf_usb_src_endpoint_number,
1145         { "Src Endpoint", "usb.src.endpoint", FT_UINT32, BASE_HEX, NULL, 0x0,
1146                 "src usb endpoint number", HFILL }},
1147
1148         { &hf_usb_dst_endpoint_number,
1149         { "Dst Endpoint", "usb.dst.endpoint", FT_UINT32, BASE_HEX, NULL, 0x0,
1150                 "dst usb endpoint number", HFILL }},
1151
1152         { &hf_usb_setup_bmRequestType,
1153         { "bmRequestType", "usb.setup.bmRequestType", FT_UINT8, BASE_HEX, NULL, 0x0,
1154                 "", HFILL }},
1155
1156         { &hf_usb_request,
1157         { "bRequest", "usb.setup.bRequest", FT_UINT8, BASE_HEX, VALS(setup_request_names_vals), 0x0,
1158                 "", HFILL }},
1159
1160         { &hf_usb_value,
1161         { "wValue", "usb.setup.wValue", FT_UINT16, BASE_HEX, NULL, 0x0,
1162                 "", HFILL }},
1163
1164         { &hf_usb_index,
1165         { "wIndex", "usb.setup.wIndex", FT_UINT16, BASE_DEC, NULL, 0x0,
1166                 "", HFILL }},
1167
1168         { &hf_usb_length,
1169         { "wLength", "usb.setup.wLength", FT_UINT16, BASE_DEC, NULL, 0x0,
1170                 "", HFILL }},
1171                 
1172         { &hf_usb_data,
1173         {"Application Data", "usb.data",
1174             FT_BYTES, BASE_HEX, NULL, 0x0,
1175             "Payload is application data", HFILL }},
1176     
1177         { &hf_usb_setup_bmRequestType_direction,
1178         { "Direction", "usb.setup.bmRequestType.direction", FT_BOOLEAN, 8, 
1179           TFS(&tfs_bmrequesttype_direction), 0x80, "", HFILL }},
1180
1181         { &hf_usb_setup_bmRequestType_type,
1182         { "Type", "usb.setup.bmRequestType.type", FT_UINT8, BASE_HEX, 
1183           VALS(bmrequesttype_type_vals), 0x70, "", HFILL }},
1184
1185         { &hf_usb_setup_bmRequestType_recipient,
1186         { "Recipient", "usb.setup.bmRequestType.recipient", FT_UINT8, BASE_HEX, 
1187           VALS(bmrequesttype_recipient_vals), 0x0f, "", HFILL }},
1188
1189         { &hf_usb_bDescriptorType,
1190         { "bDescriptorType", "usb.bDescriptorType", FT_UINT8, BASE_HEX, 
1191           VALS(descriptor_type_vals), 0x0, "", HFILL }},
1192
1193         { &hf_usb_descriptor_index,
1194         { "Descriptor Index", "usb.DescriptorIndex", FT_UINT8, BASE_HEX, 
1195           NULL, 0x0, "", HFILL }},
1196
1197         { &hf_usb_language_id,
1198         { "Language Id", "usb.LanguageId", FT_UINT16, BASE_HEX, 
1199           VALS(usb_langid_vals), 0x0, "", HFILL }},
1200
1201         { &hf_usb_bLength,
1202         { "bLength", "usb.bLength", FT_UINT8, BASE_DEC, 
1203           NULL, 0x0, "", HFILL }},
1204
1205         { &hf_usb_bcdUSB,
1206         { "bcdUSB", "usb.bcdUSB", FT_UINT16, BASE_HEX, 
1207           NULL, 0x0, "", HFILL }},
1208
1209         { &hf_usb_bDeviceClass,
1210         { "bDeviceClass", "usb.bDeviceClass", FT_UINT8, BASE_DEC, 
1211           NULL, 0x0, "", HFILL }},
1212
1213         { &hf_usb_bDeviceSubClass,
1214         { "bDeviceSubClass", "usb.bDeviceSubClass", FT_UINT8, BASE_DEC, 
1215           NULL, 0x0, "", HFILL }},
1216
1217         { &hf_usb_bDeviceProtocol,
1218         { "bDeviceProtocol", "usb.bDeviceProtocol", FT_UINT8, BASE_DEC, 
1219           NULL, 0x0, "", HFILL }},
1220
1221         { &hf_usb_bMaxPacketSize0,
1222         { "bMaxPacketSize0", "usb.bMaxPacketSize0", FT_UINT8, BASE_DEC, 
1223           NULL, 0x0, "", HFILL }},
1224
1225         { &hf_usb_idVendor,
1226         { "idVendor", "usb.idVendor", FT_UINT16, BASE_HEX, 
1227           NULL, 0x0, "", HFILL }},
1228
1229         { &hf_usb_idProduct,
1230         { "idProduct", "usb.idProduct", FT_UINT16, BASE_HEX, 
1231           NULL, 0x0, "", HFILL }},
1232
1233         { &hf_usb_bcdDevice,
1234         { "bcdDevice", "usb.bcdDevice", FT_UINT16, BASE_HEX, 
1235           NULL, 0x0, "", HFILL }},
1236
1237         { &hf_usb_iManufacturer,
1238         { "iManufacturer", "usb.iManufacturer", FT_UINT8, BASE_DEC, 
1239           NULL, 0x0, "", HFILL }},
1240
1241         { &hf_usb_iProduct,
1242         { "iProduct", "usb.iProduct", FT_UINT8, BASE_DEC, 
1243           NULL, 0x0, "", HFILL }},
1244
1245         { &hf_usb_iSerialNumber,
1246         { "iSerialNumber", "usb.iSerialNumber", FT_UINT8, BASE_DEC, 
1247           NULL, 0x0, "", HFILL }},
1248
1249         { &hf_usb_bNumConfigurations,
1250         { "bNumConfigurations", "usb.bNumConfigurations", FT_UINT8, BASE_DEC, 
1251           NULL, 0x0, "", HFILL }},
1252
1253         { &hf_usb_wLANGID,
1254         { "wLANGID", "usb.wLANGID", FT_UINT16, BASE_HEX, 
1255           VALS(usb_langid_vals), 0x0, "", HFILL }},
1256
1257         { &hf_usb_bString,
1258         { "bString", "usb.bString", FT_STRING, BASE_NONE, 
1259           NULL, 0x0, "", HFILL }},
1260
1261         { &hf_usb_bInterfaceNumber,
1262         { "bInterfaceNumber", "usb.bInterfaceNumber", FT_UINT8, BASE_DEC, 
1263           NULL, 0x0, "", HFILL }},
1264
1265         { &hf_usb_bAlternateSetting,
1266         { "bAlternateSetting","usb.bAlternateSetting", FT_UINT8, BASE_DEC, 
1267           NULL, 0x0, "", HFILL }},
1268
1269         { &hf_usb_bNumEndpoints,
1270         { "bNumEndpoints","usb.bNumEndpoints", FT_UINT8, BASE_DEC, 
1271           NULL, 0x0, "", HFILL }},
1272
1273         { &hf_usb_bInterfaceClass,
1274         { "bInterfaceClass", "usb.bInterfaceClass", FT_UINT8, BASE_HEX, 
1275           VALS(usb_interfaceclass_vals), 0x0, "", HFILL }},
1276
1277         { &hf_usb_bInterfaceSubClass,
1278         { "bInterfaceSubClass", "usb.bInterfaceSubClass", FT_UINT8, BASE_HEX, 
1279           NULL, 0x0, "", HFILL }},
1280
1281         { &hf_usb_bInterfaceProtocol,
1282         { "bInterfaceProtocol", "usb.bInterfaceProtocol", FT_UINT8, BASE_HEX, 
1283           NULL, 0x0, "", HFILL }},
1284
1285         { &hf_usb_iInterface,
1286         { "iInterface", "usb.iInterface", FT_UINT8, BASE_DEC, 
1287           NULL, 0x0, "", HFILL }},
1288
1289         { &hf_usb_bEndpointAddress,
1290         { "bEndpointAddress", "usb.bEndpointAddress", FT_UINT8, BASE_HEX, 
1291           NULL, 0x0, "", HFILL }},
1292
1293         { &hf_usb_configuration_bmAttributes,
1294         { "Configuration bmAttributes", "usb.configuration.bmAttributes", FT_UINT8, BASE_HEX, 
1295           NULL, 0x0, "", HFILL }},
1296
1297         { &hf_usb_bmAttributes,
1298         { "bmAttributes", "usb.bmAttributes", FT_UINT8, BASE_HEX, 
1299           NULL, 0x0, "", HFILL }},
1300
1301         { &hf_usb_wMaxPacketSize,
1302         { "wMaxPacketSize", "usb.wMaxPacketSize", FT_UINT16, BASE_DEC, 
1303           NULL, 0x0, "", HFILL }},
1304
1305         { &hf_usb_bInterval,
1306         { "bInterval", "usb.bInterval", FT_UINT8, BASE_DEC, 
1307           NULL, 0x0, "", HFILL }},
1308
1309         { &hf_usb_wTotalLength,
1310         { "wTotalLength", "usb.wTotalLength", FT_UINT16, BASE_DEC, 
1311           NULL, 0x0, "", HFILL }},
1312
1313         { &hf_usb_bNumInterfaces,
1314         { "bNumInterfaces", "usb.bNumInterfaces", FT_UINT8, BASE_DEC, 
1315           NULL, 0x0, "", HFILL }},
1316
1317         { &hf_usb_bConfigurationValue,
1318         { "bConfigurationValue", "usb.bConfigurationValue", FT_UINT8, BASE_DEC, 
1319           NULL, 0x0, "", HFILL }},
1320
1321         { &hf_usb_iConfiguration,
1322         { "iConfiguration", "usb.iConfiguration", FT_UINT8, BASE_DEC, 
1323           NULL, 0x0, "", HFILL }},
1324
1325         { &hf_usb_bMaxPower,
1326         { "bMaxPower", "usb.bMaxPower", FT_UINT8, BASE_DEC, 
1327           NULL, 0x0, "", HFILL }},
1328
1329         { &hf_usb_configuration_selfpowered,
1330         { "Self-Powered", "usb.configuration.selfpowered", FT_BOOLEAN, 8, 
1331           TFS(&tfs_selfpowered), 0x40, "", HFILL }},
1332
1333         { &hf_usb_configuration_remotewakeup,
1334         { "Remote Wakeup", "usb.configuration.remotewakeup", FT_BOOLEAN, 8, 
1335           TFS(&tfs_remotewakeup), 0x20, "", HFILL }},
1336
1337         { &hf_usb_bEndpointAddress_number,
1338         { "Endpoint Number", "usb.bEndpointAddress.number", FT_UINT8, BASE_HEX, 
1339           NULL, 0x0f, "", HFILL }},
1340
1341         { &hf_usb_bEndpointAddress_direction,
1342         { "Direction", "usb.bEndpointAddress.direction", FT_BOOLEAN, 8, 
1343           TFS(&tfs_endpoint_direction), 0x80, "", HFILL }},
1344
1345     };
1346     
1347     static gint *usb_subtrees[] = {
1348             &usb_hdr,
1349             &usb_setup_hdr,
1350             &ett_usb_setup_bmrequesttype,
1351             &ett_descriptor_device,
1352             &ett_configuration_bmAttributes,
1353             &ett_configuration_bEndpointAddress
1354     };
1355
1356      
1357     proto_usb = proto_register_protocol("USB", "USB", "usb");
1358     proto_register_field_array(proto_usb, hf, array_length(hf));
1359     proto_register_subtree_array(usb_subtrees, array_length(usb_subtrees));
1360
1361     register_dissector("usb", dissect_usb, proto_usb);
1362
1363     usb_bulk_dissector_table = register_dissector_table("usb.bulk",
1364         "USB bulk endpoint", FT_UINT8, BASE_DEC);
1365
1366     usb_control_dissector_table = register_dissector_table("usb.control",
1367         "USB control endpoint", FT_UINT8, BASE_DEC);
1368
1369 }
1370
1371 void
1372 proto_reg_handoff_usb(void)
1373 {
1374     dissector_handle_t usb_handle;
1375     usb_handle = create_dissector_handle(dissect_usb, proto_usb);
1376
1377     dissector_add("wtap_encap", WTAP_ENCAP_USB, usb_handle);
1378 }