epan/dissectors/pidl/samr/samr.cnf cnf_dissect_lsa_BinaryString => lsarpc_dissect_str...
[wireshark-sm.git] / epan / dissectors / packet-usbip.c
blob6480b0827392b4c2dbfb3cbba775bd0b98f51259
1 /* packet-usbip.c
2 * Routines for USB/IP dissection
3 * Copyright 2016, Christian Lamparter <chunkeey@googlemail.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
13 * The USB/IP protocol follows a server/client architecture. It runs
14 * on top of TCP/IP. The server exports the USB devices and the
15 * clients imports them. The device driver for the exported USB
16 * device runs on the client machine.
18 * See
20 * https://www.kernel.org/doc/Documentation/usb/usbip_protocol.txt
23 #include <config.h>
25 #include <epan/packet.h>
26 #include <epan/expert.h>
27 #include <epan/etypes.h>
28 #include <epan/conversation.h>
30 #include "packet-usbip.h"
31 #include "packet-usb.h"
32 #include "packet-tcp.h"
34 void proto_register_usbip(void);
35 void proto_reg_handoff_usbip(void);
37 static dissector_handle_t usbip_handle;
39 /* Initialize the protocol and registered fields
41 static int proto_usbip;
43 static int hf_usbip_version;
44 static int hf_usbip_operation;
45 static int hf_usbip_command;
46 static int hf_usbip_status;
47 static int hf_usbip_number_devices;
48 static int hf_usbip_path;
49 static int hf_usbip_devid;
50 static int hf_usbip_busid;
51 static int hf_usbip_busnum;
52 static int hf_usbip_devnum;
53 static int hf_usbip_speed;
54 static int hf_usbip_idVendor;
55 static int hf_usbip_idProduct;
56 static int hf_usbip_bcdDevice;
57 static int hf_usbip_bDeviceClass;
58 static int hf_usbip_bDeviceSubClass;
59 static int hf_usbip_bDeviceProtocol;
60 static int hf_usbip_bConfigurationValue;
61 static int hf_usbip_bNumConfigurations;
62 static int hf_usbip_bNumInterfaces;
63 static int hf_usbip_bInterfaceClass;
64 static int hf_usbip_bInterfaceSubClass;
65 static int hf_usbip_bInterfaceProtocol;
66 static int hf_usbip_padding;
68 static int hf_usbip_device;
69 static int hf_usbip_interface;
70 static int hf_usbip_interval;
72 static int hf_usbip_actual_length;
73 static int hf_usbip_error_count;
75 static int hf_usbip_seqnum;
76 static int hf_usbip_cmd_frame;
77 static int hf_usbip_ret_frame;
78 static int hf_usbip_vic_frame;
79 static int hf_usbip_direction;
80 static int hf_usbip_ep;
81 static int hf_usbip_transfer_flags;
82 static int hf_usbip_transfer_buffer_length;
83 static int hf_usbip_start_frame;
84 static int hf_usbip_number_of_packets;
85 static int hf_usbip_setup;
86 static int hf_usbip_urb_data;
88 /* Initialize the subtree pointers */
89 static int ett_usbip;
90 static int ett_usbip_dev;
91 static int ett_usbip_intf;
93 enum usb_device_speed {
94 USBIP_SPEED_UNKNOWN = 0, /* enumerating */
95 USBIP_SPEED_LOW, /* usb 1.0 */
96 USBIP_SPEED_FULL, /* usb 1.1 */
97 USBIP_SPEED_HIGH, /* usb 2.0 */
98 USBIP_SPEED_WIRELESS, /* wireless (usb 2.5) */
99 USBIP_SPEED_SUPER, /* usb 3.0 */
102 #define USBIP_SUPPORTED_VERSION 0x111
104 #define OP_REQUEST (0x80 << 8)
105 #define OP_REPLY (0x00 << 8)
107 /* ----------------------------------------------------------------------
108 * Import a remote USB device. */
109 #define OP_IMPORT 0x03
110 #define OP_REQ_IMPORT (OP_REQUEST | OP_IMPORT)
111 #define OP_REP_IMPORT (OP_REPLY | OP_IMPORT)
113 /* ----------------------------------------------------------------------
114 * Retrieve the list of exported USB devices. */
115 #define OP_DEVLIST 0x05
116 #define OP_REQ_DEVLIST (OP_REQUEST | OP_DEVLIST)
117 #define OP_REP_DEVLIST (OP_REPLY | OP_DEVLIST)
119 #define OP_CMD_SUBMIT 0x0001
120 #define OP_CMD_UNLINK 0x0002
121 #define OP_RET_SUBMIT 0x0003
122 #define OP_RET_UNLINK 0x0004
124 static const value_string usbip_operation_vals[] = {
125 {OP_REP_IMPORT, "OP_REP_IMPORT" },
126 {OP_REP_DEVLIST, "OP_REP_DEVLIST" },
128 {OP_REQ_IMPORT, "OP_REQ_IMPORT" },
129 {OP_REQ_DEVLIST, "OP_REQ_DEVLIST" },
130 {0, NULL }
133 static const value_string usbip_urb_vals[] = {
134 {OP_CMD_SUBMIT, "OP_CMD_SUBMIT" },
135 {OP_CMD_UNLINK, "OP_CMD_UNLINK" },
136 {OP_RET_SUBMIT, "OP_RET_SUBMIT" },
137 {OP_RET_UNLINK, "OP_RET_UNLINK" },
138 {0, NULL }
141 static const value_string usbip_speed_vals[] = {
142 {USBIP_SPEED_UNKNOWN, "Speed Unknown" },
143 {USBIP_SPEED_LOW, "Low Speed" },
144 {USBIP_SPEED_FULL, "Full Speed" },
145 {USBIP_SPEED_HIGH, "High Speed" },
146 {USBIP_SPEED_WIRELESS, "Wireless Speed" },
147 {USBIP_SPEED_SUPER, "Super Speed" },
148 {0, NULL }
151 static value_string_ext usbip_speed_vals_ext = VALUE_STRING_EXT_INIT(usbip_speed_vals);
152 static value_string_ext usbip_operation_vals_ext = VALUE_STRING_EXT_INIT(usbip_operation_vals);
153 static value_string_ext usbip_urb_vals_ext = VALUE_STRING_EXT_INIT(usbip_urb_vals);
155 extern value_string_ext ext_usb_vendors_vals;
156 extern value_string_ext ext_usb_products_vals;
157 extern value_string_ext linux_negative_errno_vals_ext;
159 static const value_string usb_endpoint_direction_vals[] = {
160 {USBIP_DIR_OUT, "OUT" },
161 {USBIP_DIR_IN, "IN" },
162 {0, NULL }
165 static expert_field ei_usbip;
167 typedef struct _usbip_transaction_t
169 uint32_t seqnum;
170 uint32_t devid;
171 uint32_t ep;
172 uint32_t dir;
173 uint32_t cmd_frame;
174 uint32_t ret_frame;
175 uint32_t unlink_seqnum;
176 } usbip_transaction_t;
178 typedef struct _usbip_conv_info_t
180 /* holds OP_{CMD|RET}_{SUBMIT|UNLINK} */
181 wmem_tree_t *pdus;
182 } usbip_conv_info_t;
184 static int
185 dissect_device_list_request(packet_info *pinfo)
187 col_set_str(pinfo->cinfo, COL_INFO, "Device List Request");
188 return 0;
191 static int
192 dissect_device(proto_tree *tree, tvbuff_t *tvb, int offset)
194 uint32_t product;
195 uint32_t vendor_id;
196 uint32_t product_id;
198 /* Device path on host (usually /sys/devices/usb/... */
199 proto_tree_add_item(tree, hf_usbip_path, tvb, offset, 256, ENC_ASCII | ENC_NA);
200 offset += 256;
202 /* Bus id string - Id of the bus the device is connected to */
203 proto_tree_add_item(tree, hf_usbip_busid, tvb, offset, 32, ENC_ASCII | ENC_NA);
204 offset += 32;
206 /* bus number */
207 proto_tree_add_item(tree, hf_usbip_busnum, tvb, offset, 4, ENC_BIG_ENDIAN);
208 offset += 4;
210 /* device number */
211 proto_tree_add_item(tree, hf_usbip_devnum, tvb, offset, 4, ENC_BIG_ENDIAN);
212 offset += 4;
214 /* USB Speed */
215 proto_tree_add_item(tree, hf_usbip_speed, tvb, offset, 4, ENC_BIG_ENDIAN);
216 offset += 4;
218 /* idVendor */
219 proto_tree_add_item_ret_uint(tree, hf_usbip_idVendor, tvb, offset, 2, ENC_BIG_ENDIAN, &vendor_id);
220 offset += 2;
222 /* idProduct */
223 product_id = tvb_get_ntohs(tvb, offset);
224 product = vendor_id << 16 | product_id;
226 proto_tree_add_uint_format_value(tree, hf_usbip_idProduct, tvb, offset, 2,
227 product_id, "%s (0x%04x)", val_to_str_ext_const(product, &ext_usb_products_vals,
228 "Unknown"), product_id);
229 offset += 2;
231 /* bcdDevice */
232 proto_tree_add_item(tree, hf_usbip_bcdDevice, tvb, offset, 2, ENC_BIG_ENDIAN);
233 offset += 2;
235 /* Device Class */
236 proto_tree_add_item(tree, hf_usbip_bDeviceClass, tvb, offset, 1, ENC_BIG_ENDIAN);
237 offset += 1;
239 /* Device Sub Class */
240 proto_tree_add_item(tree, hf_usbip_bDeviceSubClass, tvb, offset, 1, ENC_BIG_ENDIAN);
241 offset += 1;
243 /* Device Protocol */
244 proto_tree_add_item(tree, hf_usbip_bDeviceProtocol, tvb, offset, 1, ENC_BIG_ENDIAN);
245 offset += 1;
247 /* Current Configuration */
248 proto_tree_add_item(tree, hf_usbip_bConfigurationValue, tvb, offset, 1, ENC_BIG_ENDIAN);
249 offset += 1;
251 /* Number of Configurations */
252 proto_tree_add_item(tree, hf_usbip_bNumConfigurations, tvb, offset, 1, ENC_BIG_ENDIAN);
253 offset += 1;
255 /* Number of Interfaces */
256 proto_tree_add_item(tree, hf_usbip_bNumInterfaces, tvb, offset, 1, ENC_BIG_ENDIAN);
257 offset += 1;
258 return offset;
261 static int
262 dissect_device_list_response(packet_info *pinfo, proto_tree *tree,
263 tvbuff_t *tvb,
264 int offset)
266 proto_item *ti_intf;
267 proto_item *ti_dev;
268 proto_tree *intf_tree = NULL;
269 proto_tree *dev_tree = NULL;
270 uint32_t num_of_devs;
271 uint32_t i;
272 uint8_t num_of_intf;
273 uint8_t j;
275 col_set_str(pinfo->cinfo, COL_INFO, "Device List Response");
277 proto_tree_add_item_ret_uint(tree, hf_usbip_number_devices, tvb, offset, 4,
278 ENC_BIG_ENDIAN, &num_of_devs);
279 offset += 4;
281 for (i = 0; i < num_of_devs; i++) {
282 num_of_intf = tvb_get_uint8(tvb, offset + 0x137);
283 ti_dev = proto_tree_add_uint(tree, hf_usbip_device, tvb, offset,
284 0x138 + 4 * num_of_intf, i + 1);
285 proto_item_set_generated(ti_dev);
287 dev_tree = proto_item_add_subtree(ti_dev, ett_usbip_dev);
288 offset = dissect_device(dev_tree, tvb, offset);
290 for (j = 0; j < num_of_intf; j++) {
291 ti_intf = proto_tree_add_uint(dev_tree, hf_usbip_interface, tvb,
292 offset, 3, j + 1);
293 intf_tree = proto_item_add_subtree(ti_intf, ett_usbip_intf);
295 proto_tree_add_item(intf_tree, hf_usbip_bInterfaceClass, tvb,
296 offset, 1, ENC_BIG_ENDIAN);
297 offset += 1;
299 proto_tree_add_item(intf_tree, hf_usbip_bInterfaceSubClass, tvb,
300 offset, 1, ENC_BIG_ENDIAN);
301 offset += 1;
303 proto_tree_add_item(intf_tree, hf_usbip_bInterfaceProtocol, tvb,
304 offset, 1, ENC_BIG_ENDIAN);
305 offset += 1;
307 proto_tree_add_item(intf_tree, hf_usbip_padding, tvb,
308 offset, 1, ENC_NA);
309 offset += 1;
312 return offset;
315 static int
316 dissect_import_request(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
317 int offset)
319 col_set_str(pinfo->cinfo, COL_INFO, "Import Request");
320 proto_tree_add_item(tree, hf_usbip_busid, tvb, offset, 32, ENC_ASCII | ENC_NA);
321 return offset + 32;
324 static int
325 dissect_import_response(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
326 int offset, uint32_t status)
328 col_set_str(pinfo->cinfo, COL_INFO, "Import Response");
329 if (status == 0)
330 offset = dissect_device(tree, tvb, offset);
331 return offset;
334 static int
335 dissect_cmd_submit(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
336 int offset)
338 col_set_str(pinfo->cinfo, COL_INFO, "URB Submit");
340 dissect_urb_transfer_flags(tvb, offset, tree, hf_usbip_transfer_flags,
341 ENC_BIG_ENDIAN);
342 offset += 4;
344 proto_tree_add_item(tree, hf_usbip_transfer_buffer_length, tvb, offset, 4,
345 ENC_BIG_ENDIAN);
346 offset += 4;
348 proto_tree_add_item(tree, hf_usbip_start_frame, tvb, offset, 4,
349 ENC_BIG_ENDIAN);
350 offset += 4;
352 proto_tree_add_item(tree, hf_usbip_number_of_packets, tvb, offset, 4,
353 ENC_BIG_ENDIAN);
354 offset += 4;
356 proto_tree_add_item(tree, hf_usbip_interval, tvb, offset, 4, ENC_BIG_ENDIAN);
357 offset += 4;
359 proto_tree_add_item(tree, hf_usbip_setup, tvb, offset, 8, ENC_NA);
360 offset += 8;
361 return offset;
364 static int
365 dissect_ret_submit(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
366 int offset)
368 col_set_str(pinfo->cinfo, COL_INFO, "URB Response");
370 proto_tree_add_item(tree, hf_usbip_status, tvb, offset, 4, ENC_BIG_ENDIAN);
371 offset += 4;
373 proto_tree_add_item(tree, hf_usbip_actual_length, tvb, offset, 4,
374 ENC_BIG_ENDIAN);
375 offset += 4;
377 proto_tree_add_item(tree, hf_usbip_start_frame, tvb, offset, 4,
378 ENC_BIG_ENDIAN);
379 offset += 4;
381 proto_tree_add_item(tree, hf_usbip_number_of_packets, tvb, offset, 4,
382 ENC_BIG_ENDIAN);
383 offset += 4;
385 proto_tree_add_item(tree, hf_usbip_error_count, tvb, offset, 4,
386 ENC_BIG_ENDIAN);
387 offset += 4;
389 proto_tree_add_item(tree, hf_usbip_setup, tvb, offset, 8, ENC_NA);
390 offset += 8;
391 return offset;
394 static int
395 dissect_cmd_unlink(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
396 int offset, usbip_conv_info_t *usbip_info,
397 usbip_transaction_t *trans)
399 usbip_transaction_t *victim;
400 uint32_t seqnum;
402 col_set_str(pinfo->cinfo, COL_INFO, "URB Unlink");
404 proto_tree_add_item_ret_uint(tree, hf_usbip_seqnum, tvb, offset, 4, ENC_BIG_ENDIAN, &seqnum);
405 trans->unlink_seqnum = seqnum;
406 offset += 4;
408 victim = (usbip_transaction_t *) wmem_tree_lookup32(usbip_info->pdus, seqnum);
409 if (victim) {
410 proto_item *ti;
412 ti = proto_tree_add_uint(tree, hf_usbip_vic_frame, NULL, 0, 0,
413 victim->cmd_frame);
414 proto_item_set_generated(ti);
416 return offset;
419 static int
420 dissect_ret_unlink(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
421 int offset, usbip_conv_info_t *usbip_info,
422 uint32_t seqnum)
424 usbip_transaction_t *victim;
426 col_set_str(pinfo->cinfo, COL_INFO, "URB Unlink Response");
428 victim = (usbip_transaction_t *) wmem_tree_lookup32(usbip_info->pdus, seqnum);
429 if (victim) {
430 proto_item *ti;
432 victim->ret_frame = pinfo->num;
433 ti = proto_tree_add_uint(tree, hf_usbip_vic_frame, NULL, 0, 0,
434 victim->cmd_frame);
435 proto_item_set_generated(ti);
437 proto_tree_add_item(tree, hf_usbip_status, tvb, offset, 4, ENC_BIG_ENDIAN);
438 offset += 4;
439 return offset;
442 static usbip_conv_info_t *
443 usbip_get_usbip_conv(packet_info *pinfo)
445 conversation_t *conversation;
446 usbip_conv_info_t *usbip_info;
448 conversation = find_or_create_conversation(pinfo);
449 usbip_info = (usbip_conv_info_t *) conversation_get_proto_data(conversation,
450 proto_usbip);
451 if (!usbip_info) {
452 usbip_info = wmem_new(wmem_file_scope(), usbip_conv_info_t);
453 usbip_info->pdus = wmem_tree_new(wmem_file_scope());
454 conversation_add_proto_data(conversation, proto_usbip, usbip_info);
456 return usbip_info;
459 static int
460 usbip_dissect_op(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tree,
461 int offset)
463 proto_item *ti = NULL;
464 uint32_t operation;
465 int32_t status;
467 proto_tree_add_item(tree, hf_usbip_version, tvb, offset, 2, ENC_BIG_ENDIAN);
468 offset += 2;
469 proto_tree_add_item_ret_uint(tree, hf_usbip_operation, tvb, offset, 2,
470 ENC_BIG_ENDIAN, &operation);
471 offset += 2;
472 proto_tree_add_item_ret_int(tree, hf_usbip_status, tvb, offset, 4, ENC_BIG_ENDIAN, &status);
473 offset += 4;
475 switch (operation) {
477 case OP_REQ_IMPORT:
478 offset = dissect_import_request(pinfo, tree, tvb, offset);
479 break;
481 case OP_REP_IMPORT:
482 offset = dissect_import_response(pinfo, tree, tvb, offset, status);
483 break;
485 case OP_REQ_DEVLIST:
486 offset = dissect_device_list_request(pinfo);
487 break;
489 case OP_REP_DEVLIST:
490 offset = dissect_device_list_response(pinfo, tree, tvb, offset);
491 break;
493 default:
494 proto_tree_add_item(tree, hf_usbip_urb_data, tvb, offset, -1, ENC_NA);
495 offset = tvb_reported_length_remaining(tvb, offset);
496 expert_add_info_format(
497 pinfo, ti, &ei_usbip,
498 "Dissector for USBIP Operation"
499 " (%x) code not implemented, Contact"
500 " Wireshark developers if you want this supported",
501 operation);
502 proto_item_append_text(ti, ": Undecoded");
503 break;
505 return offset;
508 static int
509 usbip_dissect_urb(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tree,
510 proto_tree *orig, int offset,
511 usbip_conv_info_t *usbip_info)
513 proto_item *ti = NULL;
514 usbip_transaction_t *usbip_trans;
515 uint32_t command;
516 uint32_t devid;
517 uint32_t seqnum;
518 uint32_t dir;
519 uint32_t ep;
520 struct usbip_header header;
522 proto_tree_add_item_ret_uint(tree, hf_usbip_command, tvb, offset, 4, ENC_BIG_ENDIAN, &command);
523 offset += 4;
524 proto_tree_add_item_ret_uint(tree, hf_usbip_seqnum, tvb, offset, 4, ENC_BIG_ENDIAN, &seqnum);
525 offset += 4;
527 dir = tvb_get_ntohl(tvb, offset + 4);
528 ep = tvb_get_ntohl(tvb, offset + 8);
529 devid = tvb_get_ntohl(tvb, offset);
531 if (!PINFO_FD_VISITED(pinfo)) {
532 if (command == OP_CMD_SUBMIT || command == OP_CMD_UNLINK) {
533 usbip_trans = wmem_new(wmem_file_scope(), usbip_transaction_t);
534 usbip_trans->devid = devid;
535 usbip_trans->dir = dir;
536 usbip_trans->ep = ep;
537 usbip_trans->seqnum = seqnum;
538 usbip_trans->cmd_frame = pinfo->num;
539 usbip_trans->ret_frame = 0;
540 usbip_trans->unlink_seqnum = 0;
541 wmem_tree_insert32(usbip_info->pdus, seqnum, (void *) usbip_trans);
542 } else {
543 usbip_trans = (usbip_transaction_t *) wmem_tree_lookup32(usbip_info->pdus, seqnum);
544 if (usbip_trans)
545 usbip_trans->ret_frame = pinfo->num;
547 } else {
548 usbip_trans = (usbip_transaction_t *) wmem_tree_lookup32(usbip_info->pdus, seqnum);
551 if (!usbip_trans) {
552 usbip_trans = wmem_new(pinfo->pool, usbip_transaction_t);
553 usbip_trans->cmd_frame = 0;
554 usbip_trans->ret_frame = 0;
555 usbip_trans->devid = 0;
556 usbip_trans->unlink_seqnum = 0;
557 usbip_trans->seqnum = seqnum;
560 /* only the OP_CMD_SUBMIT has a valid devid - in all other case we have to restore it from the transaction */
561 if (command == OP_RET_SUBMIT || command == OP_RET_UNLINK) {
562 devid = usbip_trans->devid;
563 ep = usbip_trans->ep;
564 dir = usbip_trans->dir;
567 ti = proto_tree_add_uint(tree, hf_usbip_cmd_frame, NULL, 0, 0,
568 usbip_trans->cmd_frame);
569 proto_item_set_generated(ti);
570 ti = proto_tree_add_uint(tree, hf_usbip_ret_frame, NULL, 0, 0,
571 usbip_trans->ret_frame);
572 proto_item_set_generated(ti);
573 ti = proto_tree_add_uint(tree, hf_usbip_devid, NULL, 0, 0, devid);
574 proto_item_set_generated(ti);
575 ti = proto_tree_add_uint(tree, hf_usbip_direction, NULL, 0, 0, dir);
576 proto_item_set_generated(ti);
577 ti = proto_tree_add_uint(tree, hf_usbip_ep, NULL, 0, 0, ep);
578 proto_item_set_generated(ti);
580 proto_tree_add_item(tree, hf_usbip_devid, tvb, offset, 4, ENC_BIG_ENDIAN);
581 offset += 4;
582 proto_tree_add_item(tree, hf_usbip_direction, tvb, offset, 4,
583 ENC_BIG_ENDIAN);
584 offset += 4;
585 proto_tree_add_item(tree, hf_usbip_ep, tvb, offset, 4, ENC_BIG_ENDIAN);
586 offset += 4;
588 header.ep = ep;
589 header.dir = dir;
590 header.devid = devid & 0x00ff;
591 header.busid = devid >> 16;
593 switch (command) {
595 case OP_CMD_SUBMIT:
596 offset = dissect_cmd_submit(pinfo, tree, tvb, offset);
597 dissect_usb_common(tvb, pinfo, orig, USB_HEADER_USBIP, &header);
598 break;
600 case OP_CMD_UNLINK:
601 offset = dissect_cmd_unlink(pinfo, tree, tvb, offset, usbip_info,
602 usbip_trans);
603 break;
605 case OP_RET_SUBMIT: {
606 uint32_t status;
608 status = tvb_get_ntohl(tvb, offset);
609 offset = dissect_ret_submit(pinfo, tree, tvb, offset);
610 if (status == 0)
611 dissect_usb_common(tvb, pinfo, orig, USB_HEADER_USBIP, &header);
612 break;
615 case OP_RET_UNLINK:
616 offset = dissect_ret_unlink(pinfo, tree, tvb, offset, usbip_info,
617 usbip_trans->unlink_seqnum);
618 break;
620 default:
621 proto_tree_add_item(tree, hf_usbip_urb_data, tvb, offset, -1, ENC_NA);
622 offset = tvb_reported_length_remaining(tvb, offset);
623 expert_add_info_format(
624 pinfo, ti, &ei_usbip,
625 "Dissector for USBIP Command"
626 " (%x) code not implemented, Contact"
627 " Wireshark developers if you want this supported",
628 command);
629 proto_item_append_text(ti, ": Undecoded");
630 break;
632 return offset;
635 static int
636 dissect_usbip_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
637 void *data _U_)
639 uint16_t version;
640 int offset = 0;
642 proto_item *ti = NULL;
643 proto_tree *usbip_tree = NULL;
645 usbip_conv_info_t *usbip_info;
647 /* Make entries in Protocol column and Info column on summary display */
648 col_set_str(pinfo->cinfo, COL_PROTOCOL, "USBIP");
649 col_clear(pinfo->cinfo, COL_INFO);
651 usbip_info = usbip_get_usbip_conv(pinfo);
653 /* create display subtree for the protocol */
654 ti = proto_tree_add_item(tree, proto_usbip, tvb, 0, -1, ENC_NA);
655 usbip_tree = proto_item_add_subtree(ti, ett_usbip);
657 /* Get some values from the packet header */
658 version = tvb_get_ntohs(tvb, 0);
660 /* check if this is a operation code by checking the version. */
661 if (version == USBIP_SUPPORTED_VERSION) {
662 offset = usbip_dissect_op(pinfo, tvb, usbip_tree, offset);
663 } else if (version == 0x0000) {
664 offset = usbip_dissect_urb(pinfo, tvb, usbip_tree, tree, offset,
665 usbip_info);
666 } else {
667 proto_tree_add_item(usbip_tree, hf_usbip_urb_data, tvb, offset, -1,
668 ENC_NA);
669 offset = tvb_reported_length_remaining(tvb, offset);
670 expert_add_info_format(
671 pinfo, ti, &ei_usbip,
672 "Dissector for USBIP Version"
673 " (%d.%d) not implemented, Contact"
674 " Wireshark developers if you want this supported",
675 version >> 8, version & 0xff);
676 proto_item_append_text(ti, ": Undecoded");
678 return offset;
681 #define FRAME_HEADER_LEN 8
683 static unsigned int
684 get_usbip_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset,
685 void *data _U_)
687 uint16_t version;
689 /* Get some values from the packet header */
690 version = tvb_get_ntohs(tvb, offset);
692 /* The USBIP's is split in two parts.
693 * There's an userspace portion which consists of the usbipd daemon
694 * and usbip tool.
695 * The kernel part is done by two modules usbip-host.ko and vhci-hcd.ko (client).
697 * The userspace programs are generating and parsing the OP_REQ_* and OP_REP_*
698 * data packets. They have all have a proper protocol version field. But data
699 * can be split up in multiple packages, so reassembly is required. There's no
700 * session id or sequence number to track packages.
702 * The kernel modules are handling the OP_CMD_* and OP_RET_* data packets.
703 * There's no protocol version (The version is simply always 0x0000, because
704 * the OP_CMD|RET are 4-Bytes long, whereas OP_REQ/OP_REP are only 2-Bytes).
705 * data frames can be split into multiple packages. But it also can happen that
706 * multiple data frames are aggregated into a single package. The OP_CMD_* and
707 * OP_RET_* frames have a 4-Byte sequence number to track individual URBs. The
708 * sequence counter will wrap around eventually.
711 if (version == USBIP_SUPPORTED_VERSION) {
712 uint16_t op = tvb_get_ntohs(tvb, offset + 2);
714 switch (op) {
716 case OP_REQ_IMPORT:
717 return 40;
719 case OP_REP_IMPORT:
720 if (tvb_get_ntohl(tvb, offset + 4) == 0) {
721 /* Status: OK */
722 return 0x140;
723 } else {
724 /* Status: Error */
725 return 0x8;
728 case OP_REQ_DEVLIST:
729 return 8;
731 case OP_REP_DEVLIST: {
732 unsigned int expected_size = 0xc;
733 unsigned int num_of_devs;
734 unsigned int i;
736 if (tvb_captured_length(tvb) < 0xc) {
737 /* not enough segments to calculate the size */
738 return 0x0;
741 offset += 8;
743 num_of_devs = tvb_get_ntohl(tvb, offset);
744 offset += 4;
746 if (num_of_devs == 0)
747 return expected_size;
749 if (tvb_captured_length_remaining(tvb, offset) < (int) (0x138 * num_of_devs))
750 return 0;
752 for (i = 0; i < num_of_devs; i++) {
753 uint8_t num_of_intf = tvb_get_uint8(tvb, offset + 0x137);
754 int skip = num_of_intf * 4;
756 expected_size += 0x138 + skip;
757 offset += 0x138 + skip;
759 return expected_size;
762 } else if (version == 0x0000) {
763 uint32_t cmd = tvb_get_ntohl(tvb, offset);
765 if (tvb_captured_length_remaining(tvb, offset) < USBIP_HEADER_LEN)
766 return 0;
768 switch (cmd) {
770 case OP_RET_UNLINK:
771 return USBIP_HEADER_LEN;
773 case OP_CMD_UNLINK:
774 return USBIP_HEADER_LEN;
776 case OP_CMD_SUBMIT: {
777 int expected_size = USBIP_HEADER_LEN;
778 int actual_length = tvb_get_ntohl(tvb, offset + 0x18);
779 int dir = tvb_get_ntohl(tvb, offset + 0xc);
780 int n_iso = tvb_get_ntohl(tvb, offset + 0x20);
782 if (dir == USBIP_DIR_OUT)
783 expected_size += actual_length;
785 if (n_iso > 0)
786 expected_size += n_iso * 4 * 4;
788 return expected_size;
791 case OP_RET_SUBMIT: {
792 int expected_size = USBIP_HEADER_LEN;
793 int actual_length = tvb_get_ntohl(tvb, offset + 0x18);
794 int n_iso = tvb_get_ntohl(tvb, offset + 0x20);
796 usbip_transaction_t *usbip_trans = NULL;
797 usbip_conv_info_t *usbip_info = usbip_get_usbip_conv(pinfo);
798 uint32_t status = tvb_get_ntohl(tvb, offset + 0x14);
800 if (usbip_info) {
801 usbip_trans = (usbip_transaction_t *) wmem_tree_lookup32(
802 usbip_info->pdus, tvb_get_ntohl(tvb, offset + 4));
804 if (usbip_trans && usbip_trans->dir == USBIP_DIR_IN && status == 0)
805 expected_size += actual_length;
808 if (status == 0) {
809 if (n_iso >= 0)
810 expected_size += n_iso * 4 * 4;
812 else
813 expected_size = tvb_captured_length(tvb);
815 return expected_size;
820 return tvb_captured_length(tvb);
823 static int
824 dissect_usbip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
826 tcp_dissect_pdus(tvb, pinfo, tree, true, FRAME_HEADER_LEN,
827 get_usbip_message_len, dissect_usbip_common, data);
829 return tvb_captured_length(tvb);
832 /* Register the protocol with Wireshark */
834 void
835 proto_register_usbip(void)
837 /* Setup list of header fields */
838 static hf_register_info hf[] = {
839 {&hf_usbip_version,
840 {"Version", "usbip.version",
841 FT_UINT16, BASE_HEX, NULL, 0x0,
842 "Version of the protocol", HFILL}},
844 {&hf_usbip_operation,
845 {"Operation", "usbip.operation",
846 FT_UINT16, BASE_HEX | BASE_EXT_STRING, &usbip_operation_vals_ext,
847 0x0,
848 "USBIP Operation", HFILL}},
850 {&hf_usbip_command,
851 {"Command", "usbip.urb",
852 FT_UINT32, BASE_HEX | BASE_EXT_STRING, &usbip_urb_vals_ext, 0x0,
853 "USBIP URB Transaction", HFILL}},
855 {&hf_usbip_status,
856 {"Status", "usbip.status",
857 FT_INT32, BASE_DEC | BASE_EXT_STRING, &linux_negative_errno_vals_ext, 0,
858 "USBIP Status", HFILL}},
860 {&hf_usbip_number_devices,
861 {"Number of exported Devices", "usbip.number_of_devices",
862 FT_UINT32, BASE_DEC, NULL, 0,
863 NULL, HFILL}},
865 {&hf_usbip_path,
866 {"System Path", "usbip.system_path",
867 FT_STRING, BASE_NONE, NULL, 0,
868 NULL, HFILL}},
870 {&hf_usbip_devid,
871 {"Devid", "usbip.devid",
872 FT_UINT32, BASE_HEX, NULL, 0x0,
873 NULL, HFILL}},
875 {&hf_usbip_busid,
876 {"Busid", "usbip.busid",
877 FT_STRING, BASE_NONE, NULL, 0,
878 NULL, HFILL}},
880 {&hf_usbip_busnum,
881 {"Bus number", "usbip.bus_num",
882 FT_UINT32, BASE_HEX, NULL, 0x0,
883 NULL, HFILL}},
885 {&hf_usbip_devnum,
886 {"Device Number", "usbip.dev_num",
887 FT_UINT32, BASE_HEX, NULL, 0x0,
888 NULL, HFILL}},
890 {&hf_usbip_speed,
891 {"Connected Speed", "usbip.speed",
892 FT_UINT32, BASE_DEC | BASE_EXT_STRING, &usbip_speed_vals_ext, 0,
893 NULL, HFILL}},
895 {&hf_usbip_idVendor,
896 {"idVendor", "usbip.idVendor",
897 FT_UINT16, BASE_HEX | BASE_EXT_STRING, &ext_usb_vendors_vals, 0x0,
898 NULL, HFILL}},
900 {&hf_usbip_idProduct,
901 {"idProduct", "usbip.idProduct",
902 FT_UINT16, BASE_HEX, NULL, 0x0,
903 NULL, HFILL}},
905 {&hf_usbip_bcdDevice,
906 {"bcdDevice", "usbip.bcdDevice",
907 FT_UINT16, BASE_HEX, NULL, 0x0,
908 NULL, HFILL}},
910 {&hf_usbip_bDeviceClass,
911 {"bDeviceClass", "usbip.bDeviceClass",
912 FT_UINT8, BASE_HEX | BASE_EXT_STRING, &usb_class_vals_ext, 0x0,
913 NULL, HFILL}},
915 {&hf_usbip_bDeviceSubClass,
916 {"bDeviceSubClass", "usbip.bDeviceSubClass",
917 FT_UINT8, BASE_DEC, NULL, 0,
918 NULL, HFILL}},
920 {&hf_usbip_bDeviceProtocol,
921 {"bDeviceProtocol", "usbip.bDeviceProtocol",
922 FT_UINT8, BASE_DEC, NULL, 0,
923 NULL, HFILL}},
925 {&hf_usbip_bConfigurationValue,
926 {"bConfigurationValue", "usbip.bConfigurationValue",
927 FT_UINT8, BASE_DEC, NULL, 0,
928 NULL, HFILL}},
930 {&hf_usbip_bNumConfigurations,
931 {"bNumConfigurations", "usbip.bNumConfigurations",
932 FT_UINT8, BASE_DEC, NULL, 0,
933 NULL, HFILL}},
935 {&hf_usbip_bNumInterfaces,
936 {"bNumInterfaces", "usbip.bNumInterfaces",
937 FT_UINT8, BASE_DEC, NULL, 0,
938 NULL, HFILL}},
940 {&hf_usbip_bInterfaceClass,
941 {"bInterfaceClass", "usbip.bInterfaceClass",
942 FT_UINT8, BASE_HEX | BASE_EXT_STRING, &usb_class_vals_ext, 0x0,
943 NULL, HFILL}},
945 {&hf_usbip_bInterfaceSubClass,
946 {"bInterfaceSubClass", "usbip.bInterfaceSubClass",
947 FT_UINT8, BASE_HEX, NULL, 0x0,
948 NULL, HFILL}},
950 {&hf_usbip_bInterfaceProtocol,
951 {"bInterfaceProtocol", "usbip.bInterfaceProtocol",
952 FT_UINT8, BASE_HEX, NULL, 0x0,
953 NULL, HFILL}},
955 {&hf_usbip_padding,
956 {"Padding", "usbip.padding",
957 FT_BYTES, BASE_NONE, NULL, 0,
958 NULL, HFILL}},
960 {&hf_usbip_device,
961 {"Device", "usbip.device",
962 FT_UINT32, BASE_DEC, NULL, 0,
963 NULL, HFILL}},
965 {&hf_usbip_interface,
966 {"Interface", "usbip.interface",
967 FT_UINT32, BASE_DEC, NULL, 0,
968 NULL, HFILL}},
970 {&hf_usbip_interval,
971 {"Interval", "usbip.interval",
972 FT_UINT32, BASE_DEC, NULL, 0,
973 "maximum time for the request on the server-side host controller",
974 HFILL}},
976 {&hf_usbip_actual_length,
977 {"Actual length", "usbip.actual_length",
978 FT_UINT32, BASE_DEC, NULL, 0,
979 NULL, HFILL}},
981 {&hf_usbip_error_count,
982 {"ISO error count", "usbip.iso.error_count",
983 FT_UINT32, BASE_DEC, NULL, 0,
984 NULL, HFILL}},
986 {&hf_usbip_seqnum,
987 {"Sequence", "usbip.sequence_no",
988 FT_UINT32, BASE_DEC, NULL, 0,
989 "Sequence number", HFILL}},
991 {&hf_usbip_cmd_frame,
992 {"Command frame", "usbip.cmd_frame",
993 FT_FRAMENUM, BASE_NONE, NULL, 0,
994 NULL, HFILL}},
996 {&hf_usbip_ret_frame,
997 {"Return frame", "usbip.ret_frame",
998 FT_FRAMENUM, BASE_NONE, NULL, 0,
999 NULL, HFILL}},
1001 {&hf_usbip_vic_frame,
1002 {"Victim frame", "usbip.vic_frame",
1003 FT_FRAMENUM, BASE_NONE, NULL, 0,
1004 "Frame which was forcefully cancelled", HFILL}},
1006 {&hf_usbip_direction,
1007 {"Direction", "usbip.endpoint_number.direction",
1008 FT_UINT32, BASE_HEX, VALS(usb_endpoint_direction_vals), 0x00000001,
1009 "USB endpoint direction", HFILL}},
1011 {&hf_usbip_ep,
1012 {"Endpoint", "usbip.endpoint_number",
1013 FT_UINT32, BASE_HEX, NULL, 0x0000000f,
1014 "USB endpoint number", HFILL}},
1016 {&hf_usbip_transfer_flags,
1017 {"Transfer flags", "usbip.transfer_flags",
1018 FT_UINT32, BASE_HEX, NULL, 0x0,
1019 "USBIP Transferflag", HFILL}},
1021 {&hf_usbip_transfer_buffer_length,
1022 {"Transfer buffer length [bytes]", "usbip.transfer_buffer_length",
1023 FT_UINT32, BASE_DEC, NULL, 0,
1024 "Data length in bytes", HFILL}},
1026 {&hf_usbip_start_frame,
1027 {"ISO Start frame", "usbip.iso.start_frame",
1028 FT_INT32, BASE_DEC, NULL, 0,
1029 "For an ISO frame the actually selected frame to transmit", HFILL}},
1031 {&hf_usbip_number_of_packets,
1032 {"Number of ISO descriptors", "usbip.iso.num_of_packets",
1033 FT_UINT32, BASE_DEC, NULL, 0,
1034 NULL, HFILL}},
1036 {&hf_usbip_setup,
1037 {"Setup Data", "usbip.setup",
1038 FT_BYTES, BASE_NONE, NULL, 0,
1039 NULL, HFILL}},
1041 {&hf_usbip_urb_data,
1042 {"Data", "usbip.data",
1043 FT_BYTES, BASE_NONE, NULL, 0,
1044 "Raw Data", HFILL}},
1047 static int *ett[] = {
1048 &ett_usbip,
1049 &ett_usbip_dev,
1050 &ett_usbip_intf,
1053 static ei_register_info ei[] = {
1054 {&ei_usbip,
1055 { "usbip.unsupported_version", PI_MALFORMED, PI_ERROR,
1056 "Unsupported element", EXPFILL}},
1059 expert_module_t *expert_usbip;
1061 proto_usbip = proto_register_protocol("USBIP Protocol", "USBIP", "usbip");
1063 proto_register_field_array(proto_usbip, hf, array_length(hf));
1064 proto_register_subtree_array(ett, array_length(ett));
1066 usbip_handle = register_dissector("usbip", dissect_usbip, proto_usbip);
1068 expert_usbip = expert_register_protocol(proto_usbip);
1069 expert_register_field_array(expert_usbip, ei, array_length(ei));
1073 void
1074 proto_reg_handoff_usbip(void)
1076 dissector_add_for_decode_as_with_preference("tcp.port", usbip_handle);
1080 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1082 * Local Variables:
1083 * c-basic-offset: 2
1084 * tab-width: 8
1085 * indent-tabs-mode: nil
1086 * End:
1088 * ex: set shiftwidth=2 tabstop=8 expandtab:
1089 * :indentSize=2:tabSize=8:noTabs=true: