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