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.
20 * https://www.kernel.org/doc/Documentation/usb/usbip_protocol.txt
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 */
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" },
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" },
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" },
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" },
165 static expert_field ei_usbip
;
167 typedef struct _usbip_transaction_t
175 uint32_t unlink_seqnum
;
176 } usbip_transaction_t
;
178 typedef struct _usbip_conv_info_t
180 /* holds OP_{CMD|RET}_{SUBMIT|UNLINK} */
185 dissect_device_list_request(packet_info
*pinfo
)
187 col_set_str(pinfo
->cinfo
, COL_INFO
, "Device List Request");
192 dissect_device(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
)
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
);
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
);
207 proto_tree_add_item(tree
, hf_usbip_busnum
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
211 proto_tree_add_item(tree
, hf_usbip_devnum
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
215 proto_tree_add_item(tree
, hf_usbip_speed
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
219 proto_tree_add_item_ret_uint(tree
, hf_usbip_idVendor
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &vendor_id
);
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
);
232 proto_tree_add_item(tree
, hf_usbip_bcdDevice
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
236 proto_tree_add_item(tree
, hf_usbip_bDeviceClass
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
239 /* Device Sub Class */
240 proto_tree_add_item(tree
, hf_usbip_bDeviceSubClass
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
243 /* Device Protocol */
244 proto_tree_add_item(tree
, hf_usbip_bDeviceProtocol
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
247 /* Current Configuration */
248 proto_tree_add_item(tree
, hf_usbip_bConfigurationValue
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
251 /* Number of Configurations */
252 proto_tree_add_item(tree
, hf_usbip_bNumConfigurations
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
255 /* Number of Interfaces */
256 proto_tree_add_item(tree
, hf_usbip_bNumInterfaces
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
262 dissect_device_list_response(packet_info
*pinfo
, proto_tree
*tree
,
268 proto_tree
*intf_tree
= NULL
;
269 proto_tree
*dev_tree
= NULL
;
270 uint32_t num_of_devs
;
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
);
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
,
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
);
299 proto_tree_add_item(intf_tree
, hf_usbip_bInterfaceSubClass
, tvb
,
300 offset
, 1, ENC_BIG_ENDIAN
);
303 proto_tree_add_item(intf_tree
, hf_usbip_bInterfaceProtocol
, tvb
,
304 offset
, 1, ENC_BIG_ENDIAN
);
307 proto_tree_add_item(intf_tree
, hf_usbip_padding
, tvb
,
316 dissect_import_request(packet_info
*pinfo
, proto_tree
*tree
, tvbuff_t
*tvb
,
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
);
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");
330 offset
= dissect_device(tree
, tvb
, offset
);
335 dissect_cmd_submit(packet_info
*pinfo
, proto_tree
*tree
, tvbuff_t
*tvb
,
338 col_set_str(pinfo
->cinfo
, COL_INFO
, "URB Submit");
340 dissect_urb_transfer_flags(tvb
, offset
, tree
, hf_usbip_transfer_flags
,
344 proto_tree_add_item(tree
, hf_usbip_transfer_buffer_length
, tvb
, offset
, 4,
348 proto_tree_add_item(tree
, hf_usbip_start_frame
, tvb
, offset
, 4,
352 proto_tree_add_item(tree
, hf_usbip_number_of_packets
, tvb
, offset
, 4,
356 proto_tree_add_item(tree
, hf_usbip_interval
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
359 proto_tree_add_item(tree
, hf_usbip_setup
, tvb
, offset
, 8, ENC_NA
);
365 dissect_ret_submit(packet_info
*pinfo
, proto_tree
*tree
, tvbuff_t
*tvb
,
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
);
373 proto_tree_add_item(tree
, hf_usbip_actual_length
, tvb
, offset
, 4,
377 proto_tree_add_item(tree
, hf_usbip_start_frame
, tvb
, offset
, 4,
381 proto_tree_add_item(tree
, hf_usbip_number_of_packets
, tvb
, offset
, 4,
385 proto_tree_add_item(tree
, hf_usbip_error_count
, tvb
, offset
, 4,
389 proto_tree_add_item(tree
, hf_usbip_setup
, tvb
, offset
, 8, ENC_NA
);
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
;
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
;
408 victim
= (usbip_transaction_t
*) wmem_tree_lookup32(usbip_info
->pdus
, seqnum
);
412 ti
= proto_tree_add_uint(tree
, hf_usbip_vic_frame
, NULL
, 0, 0,
414 proto_item_set_generated(ti
);
420 dissect_ret_unlink(packet_info
*pinfo
, proto_tree
*tree
, tvbuff_t
*tvb
,
421 int offset
, usbip_conv_info_t
*usbip_info
,
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
);
432 victim
->ret_frame
= pinfo
->num
;
433 ti
= proto_tree_add_uint(tree
, hf_usbip_vic_frame
, NULL
, 0, 0,
435 proto_item_set_generated(ti
);
437 proto_tree_add_item(tree
, hf_usbip_status
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
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
,
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
);
460 usbip_dissect_op(packet_info
*pinfo
, tvbuff_t
*tvb
, proto_tree
*tree
,
463 proto_item
*ti
= NULL
;
467 proto_tree_add_item(tree
, hf_usbip_version
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
469 proto_tree_add_item_ret_uint(tree
, hf_usbip_operation
, tvb
, offset
, 2,
470 ENC_BIG_ENDIAN
, &operation
);
472 proto_tree_add_item_ret_int(tree
, hf_usbip_status
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &status
);
478 offset
= dissect_import_request(pinfo
, tree
, tvb
, offset
);
482 offset
= dissect_import_response(pinfo
, tree
, tvb
, offset
, status
);
486 offset
= dissect_device_list_request(pinfo
);
490 offset
= dissect_device_list_response(pinfo
, tree
, tvb
, offset
);
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",
502 proto_item_append_text(ti
, ": Undecoded");
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
;
520 struct usbip_header header
;
522 proto_tree_add_item_ret_uint(tree
, hf_usbip_command
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &command
);
524 proto_tree_add_item_ret_uint(tree
, hf_usbip_seqnum
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &seqnum
);
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
);
543 usbip_trans
= (usbip_transaction_t
*) wmem_tree_lookup32(usbip_info
->pdus
, seqnum
);
545 usbip_trans
->ret_frame
= pinfo
->num
;
548 usbip_trans
= (usbip_transaction_t
*) wmem_tree_lookup32(usbip_info
->pdus
, seqnum
);
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
);
582 proto_tree_add_item(tree
, hf_usbip_direction
, tvb
, offset
, 4,
585 proto_tree_add_item(tree
, hf_usbip_ep
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
590 header
.devid
= devid
& 0x00ff;
591 header
.busid
= devid
>> 16;
596 offset
= dissect_cmd_submit(pinfo
, tree
, tvb
, offset
);
597 dissect_usb_common(tvb
, pinfo
, orig
, USB_HEADER_USBIP
, &header
);
601 offset
= dissect_cmd_unlink(pinfo
, tree
, tvb
, offset
, usbip_info
,
605 case OP_RET_SUBMIT
: {
608 status
= tvb_get_ntohl(tvb
, offset
);
609 offset
= dissect_ret_submit(pinfo
, tree
, tvb
, offset
);
611 dissect_usb_common(tvb
, pinfo
, orig
, USB_HEADER_USBIP
, &header
);
616 offset
= dissect_ret_unlink(pinfo
, tree
, tvb
, offset
, usbip_info
,
617 usbip_trans
->unlink_seqnum
);
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",
629 proto_item_append_text(ti
, ": Undecoded");
636 dissect_usbip_common(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
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
,
667 proto_tree_add_item(usbip_tree
, hf_usbip_urb_data
, tvb
, offset
, -1,
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");
681 #define FRAME_HEADER_LEN 8
684 get_usbip_message_len(packet_info
*pinfo _U_
, tvbuff_t
*tvb
, int offset
,
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
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);
720 if (tvb_get_ntohl(tvb
, offset
+ 4) == 0) {
731 case OP_REP_DEVLIST
: {
732 unsigned int expected_size
= 0xc;
733 unsigned int num_of_devs
;
736 if (tvb_captured_length(tvb
) < 0xc) {
737 /* not enough segments to calculate the size */
743 num_of_devs
= tvb_get_ntohl(tvb
, offset
);
746 if (num_of_devs
== 0)
747 return expected_size
;
749 if (tvb_captured_length_remaining(tvb
, offset
) < (int) (0x138 * num_of_devs
))
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
)
771 return USBIP_HEADER_LEN
;
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
;
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);
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
;
810 expected_size
+= n_iso
* 4 * 4;
813 expected_size
= tvb_captured_length(tvb
);
815 return expected_size
;
820 return tvb_captured_length(tvb
);
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 */
835 proto_register_usbip(void)
837 /* Setup list of header fields */
838 static hf_register_info hf
[] = {
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
,
848 "USBIP Operation", HFILL
}},
851 {"Command", "usbip.urb",
852 FT_UINT32
, BASE_HEX
| BASE_EXT_STRING
, &usbip_urb_vals_ext
, 0x0,
853 "USBIP URB Transaction", HFILL
}},
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,
866 {"System Path", "usbip.system_path",
867 FT_STRING
, BASE_NONE
, NULL
, 0,
871 {"Devid", "usbip.devid",
872 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
876 {"Busid", "usbip.busid",
877 FT_STRING
, BASE_NONE
, NULL
, 0,
881 {"Bus number", "usbip.bus_num",
882 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
886 {"Device Number", "usbip.dev_num",
887 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
891 {"Connected Speed", "usbip.speed",
892 FT_UINT32
, BASE_DEC
| BASE_EXT_STRING
, &usbip_speed_vals_ext
, 0,
896 {"idVendor", "usbip.idVendor",
897 FT_UINT16
, BASE_HEX
| BASE_EXT_STRING
, &ext_usb_vendors_vals
, 0x0,
900 {&hf_usbip_idProduct
,
901 {"idProduct", "usbip.idProduct",
902 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
905 {&hf_usbip_bcdDevice
,
906 {"bcdDevice", "usbip.bcdDevice",
907 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
910 {&hf_usbip_bDeviceClass
,
911 {"bDeviceClass", "usbip.bDeviceClass",
912 FT_UINT8
, BASE_HEX
| BASE_EXT_STRING
, &usb_class_vals_ext
, 0x0,
915 {&hf_usbip_bDeviceSubClass
,
916 {"bDeviceSubClass", "usbip.bDeviceSubClass",
917 FT_UINT8
, BASE_DEC
, NULL
, 0,
920 {&hf_usbip_bDeviceProtocol
,
921 {"bDeviceProtocol", "usbip.bDeviceProtocol",
922 FT_UINT8
, BASE_DEC
, NULL
, 0,
925 {&hf_usbip_bConfigurationValue
,
926 {"bConfigurationValue", "usbip.bConfigurationValue",
927 FT_UINT8
, BASE_DEC
, NULL
, 0,
930 {&hf_usbip_bNumConfigurations
,
931 {"bNumConfigurations", "usbip.bNumConfigurations",
932 FT_UINT8
, BASE_DEC
, NULL
, 0,
935 {&hf_usbip_bNumInterfaces
,
936 {"bNumInterfaces", "usbip.bNumInterfaces",
937 FT_UINT8
, BASE_DEC
, NULL
, 0,
940 {&hf_usbip_bInterfaceClass
,
941 {"bInterfaceClass", "usbip.bInterfaceClass",
942 FT_UINT8
, BASE_HEX
| BASE_EXT_STRING
, &usb_class_vals_ext
, 0x0,
945 {&hf_usbip_bInterfaceSubClass
,
946 {"bInterfaceSubClass", "usbip.bInterfaceSubClass",
947 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
950 {&hf_usbip_bInterfaceProtocol
,
951 {"bInterfaceProtocol", "usbip.bInterfaceProtocol",
952 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
956 {"Padding", "usbip.padding",
957 FT_BYTES
, BASE_NONE
, NULL
, 0,
961 {"Device", "usbip.device",
962 FT_UINT32
, BASE_DEC
, NULL
, 0,
965 {&hf_usbip_interface
,
966 {"Interface", "usbip.interface",
967 FT_UINT32
, BASE_DEC
, NULL
, 0,
971 {"Interval", "usbip.interval",
972 FT_UINT32
, BASE_DEC
, NULL
, 0,
973 "maximum time for the request on the server-side host controller",
976 {&hf_usbip_actual_length
,
977 {"Actual length", "usbip.actual_length",
978 FT_UINT32
, BASE_DEC
, NULL
, 0,
981 {&hf_usbip_error_count
,
982 {"ISO error count", "usbip.iso.error_count",
983 FT_UINT32
, BASE_DEC
, NULL
, 0,
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,
996 {&hf_usbip_ret_frame
,
997 {"Return frame", "usbip.ret_frame",
998 FT_FRAMENUM
, BASE_NONE
, NULL
, 0,
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
}},
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,
1037 {"Setup Data", "usbip.setup",
1038 FT_BYTES
, BASE_NONE
, NULL
, 0,
1041 {&hf_usbip_urb_data
,
1042 {"Data", "usbip.data",
1043 FT_BYTES
, BASE_NONE
, NULL
, 0,
1044 "Raw Data", HFILL
}},
1047 static int *ett
[] = {
1053 static ei_register_info ei
[] = {
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
));
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
1085 * indent-tabs-mode: nil
1088 * ex: set shiftwidth=2 tabstop=8 expandtab:
1089 * :indentSize=2:tabSize=8:noTabs=true: