/src/wireshark/epan/dissectors/packet-usb-masstorage.c
Line | Count | Source |
1 | | /* packet-usb-masstorage.c |
2 | | * USB Mass Storage class stub dissector |
3 | | * Copyright 2021, Aidan MacDonald <amachronic@protonmail.com> |
4 | | * |
5 | | * Wireshark - Network traffic analyzer |
6 | | * By Gerald Combs <gerald@wireshark.org> |
7 | | * Copyright 1998 Gerald Combs |
8 | | * |
9 | | * SPDX-License-Identifier: GPL-2.0-or-later |
10 | | */ |
11 | | |
12 | | #include "config.h" |
13 | | |
14 | | #include <epan/packet.h> |
15 | | #include "packet-usb.h" |
16 | | |
17 | | static int proto_usb_ms; |
18 | | |
19 | | static dissector_handle_t usb_ms_bulk_handle; |
20 | | static dissector_handle_t usb_ms_control_handle; |
21 | | static dissector_handle_t usb_ms_interrupt_handle; |
22 | | static dissector_handle_t usb_ms_descriptor_handle; |
23 | | |
24 | | static dissector_table_t usb_ms_bulk_dissector_table; |
25 | | static dissector_table_t usb_ms_control_dissector_table; |
26 | | static dissector_table_t usb_ms_interrupt_dissector_table; |
27 | | static dissector_table_t usb_ms_descriptor_dissector_table; |
28 | | |
29 | | void proto_register_usb_ms(void); |
30 | | void proto_reg_handoff_usb_ms(void); |
31 | | |
32 | | #define MSC_SUBCLASS_SCSI_COMMAND_SET_NOT_REPORTED 0x00 |
33 | | #define MSC_SUBCLASS_RBC 0x01 |
34 | | #define MSC_SUBCLASS_MMC_5_ATAPI 0x02 |
35 | | #define MSC_SUBCLASS_OBSOLETE_QIC_157 0x03 |
36 | | #define MSC_SUBCLASS_UFI 0x04 |
37 | | #define MSC_SUBCLASS_OBSOLETE_SFF_8070I 0x05 |
38 | | #define MSC_SUBCLASS_SCSI_TRANSPARENT_COMMAND_SET 0x06 |
39 | | #define MSC_SUBCLASS_LSD_FS 0x07 |
40 | | #define MSC_SUBCLASS_IEEE_1667 0x08 |
41 | | #define MSC_SUBCLASS_VENDOR 0xFF |
42 | | |
43 | | static const value_string usb_massstorage_subclass_vals[] = { |
44 | | {MSC_SUBCLASS_SCSI_COMMAND_SET_NOT_REPORTED, "SCSI command set not reported"}, |
45 | | {MSC_SUBCLASS_RBC, "RBC"}, |
46 | | {MSC_SUBCLASS_MMC_5_ATAPI, "MMC-5 (ATAPI)"}, |
47 | | {MSC_SUBCLASS_OBSOLETE_QIC_157, "Obsolete (was QIC-157)"}, |
48 | | {MSC_SUBCLASS_UFI, "UFI"}, |
49 | | {MSC_SUBCLASS_OBSOLETE_SFF_8070I, "Obsolete (was SFF-8070i)"}, |
50 | | {MSC_SUBCLASS_SCSI_TRANSPARENT_COMMAND_SET, "SCSI transparent command set"}, |
51 | | {MSC_SUBCLASS_LSD_FS, "LSD FS"}, |
52 | | {MSC_SUBCLASS_IEEE_1667, "IEEE 1667"}, |
53 | | {MSC_SUBCLASS_VENDOR, "Specific to device vendor"}, |
54 | | {0, NULL} |
55 | | }; |
56 | | value_string_ext ext_usb_massstorage_subclass_vals = VALUE_STRING_EXT_INIT(usb_massstorage_subclass_vals); |
57 | | |
58 | | #define MSC_PROTOCOL_CBI_NO_INTERRUPT 0x00 |
59 | | #define MSC_PROTOCOL_CBI_WITH_INTERRUPT 0x01 |
60 | | #define MSC_PROTOCOL_OBSOLETE 0x02 |
61 | | #define MSC_PROTOCOL_BULK_ONLY 0x50 |
62 | | #define MSC_PROTOCOL_UAS 0x62 |
63 | | #define MSC_PROTOCOL_VENDOR 0xFF |
64 | | |
65 | | static const value_string usb_massstorage_protocol_vals[] = { |
66 | | {MSC_PROTOCOL_CBI_NO_INTERRUPT, "Control/Bulk/Interrupt (CBI) Transport with command completion interrupt"}, |
67 | | {MSC_PROTOCOL_CBI_WITH_INTERRUPT, "Control/Bulk/Interrupt (CBI) Transport with no command completion interrupt"}, |
68 | | {MSC_PROTOCOL_OBSOLETE, "Obsolete"}, |
69 | | {MSC_PROTOCOL_BULK_ONLY, "Bulk-Only (BBB) Transport"}, |
70 | | {MSC_PROTOCOL_UAS, "UAS"}, |
71 | | {MSC_PROTOCOL_VENDOR, "Specific to device vendor"}, |
72 | | {0, NULL} |
73 | | }; |
74 | | value_string_ext usb_massstorage_protocol_vals_ext = VALUE_STRING_EXT_INIT(usb_massstorage_protocol_vals); |
75 | | |
76 | | static int |
77 | | dissect_usb_ms_bulk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data) |
78 | 0 | { |
79 | 0 | urb_info_t *urb; |
80 | |
|
81 | 0 | urb = (urb_info_t *)data; |
82 | |
|
83 | 0 | return dissector_try_uint_with_data(usb_ms_bulk_dissector_table, urb->conv->interfaceProtocol, tvb, pinfo, parent_tree, true, urb); |
84 | 0 | } |
85 | | |
86 | | static int |
87 | | dissect_usb_ms_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data) |
88 | 0 | { |
89 | 0 | urb_info_t *urb; |
90 | |
|
91 | 0 | urb = (urb_info_t *)data; |
92 | |
|
93 | 0 | return dissector_try_uint_with_data(usb_ms_control_dissector_table, urb->conv->interfaceProtocol, tvb, pinfo, parent_tree, true, urb); |
94 | 0 | } |
95 | | |
96 | | static int |
97 | | dissect_usb_ms_interrupt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data) |
98 | 0 | { |
99 | 0 | urb_info_t *urb; |
100 | |
|
101 | 0 | urb = (urb_info_t *)data; |
102 | |
|
103 | 0 | return dissector_try_uint_with_data(usb_ms_interrupt_dissector_table, urb->conv->interfaceProtocol, tvb, pinfo, parent_tree, true, urb); |
104 | 0 | } |
105 | | |
106 | | static int |
107 | | dissect_usb_ms_descriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data) |
108 | 0 | { |
109 | 0 | urb_info_t *urb; |
110 | |
|
111 | 0 | urb = (urb_info_t *)data; |
112 | |
|
113 | 0 | return dissector_try_uint_with_data(usb_ms_descriptor_dissector_table, urb->conv->interfaceProtocol, tvb, pinfo, parent_tree, true, urb); |
114 | 0 | } |
115 | | |
116 | | void |
117 | | proto_register_usb_ms(void) |
118 | 15 | { |
119 | 15 | proto_usb_ms = proto_register_protocol("USB Mass Storage Class", "USBMSClass", "usbmsclass"); |
120 | | |
121 | 15 | usb_ms_bulk_handle = register_dissector("usbmsclass.bulk", dissect_usb_ms_bulk, proto_usb_ms); |
122 | 15 | usb_ms_control_handle = register_dissector("usbmsclass.control", dissect_usb_ms_control, proto_usb_ms); |
123 | 15 | usb_ms_interrupt_handle = register_dissector("usbmsclass.interrupt", dissect_usb_ms_interrupt, proto_usb_ms); |
124 | 15 | usb_ms_descriptor_handle = register_dissector("usbmsclass.descriptor", dissect_usb_ms_descriptor, proto_usb_ms); |
125 | | |
126 | 15 | usb_ms_bulk_dissector_table = register_dissector_table("usbms.bulk", |
127 | 15 | "USBMS bulk endpoint", proto_usb_ms, FT_UINT8, BASE_HEX); |
128 | 15 | usb_ms_control_dissector_table = register_dissector_table("usbms.control", |
129 | 15 | "USBMS control endpoint", proto_usb_ms, FT_UINT8, BASE_HEX); |
130 | 15 | usb_ms_interrupt_dissector_table = register_dissector_table("usbms.interrupt", |
131 | 15 | "USBMS interrupt endpoint", proto_usb_ms, FT_UINT8, BASE_HEX); |
132 | 15 | usb_ms_descriptor_dissector_table = register_dissector_table("usbms.descriptor", |
133 | 15 | "USBMS descriptor", proto_usb_ms, FT_UINT8, BASE_HEX); |
134 | 15 | } |
135 | | |
136 | | void |
137 | | proto_reg_handoff_usb_ms(void) |
138 | 15 | { |
139 | 15 | dissector_add_uint("usb.bulk", IF_CLASS_MASS_STORAGE, usb_ms_bulk_handle); |
140 | 15 | dissector_add_uint("usb.control", IF_CLASS_MASS_STORAGE, usb_ms_control_handle); |
141 | 15 | dissector_add_uint("usb.interrupt", IF_CLASS_MASS_STORAGE, usb_ms_interrupt_handle); |
142 | 15 | dissector_add_uint("usb.descriptor", IF_CLASS_MASS_STORAGE, usb_ms_descriptor_handle); |
143 | 15 | } |
144 | | |
145 | | /* |
146 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
147 | | * |
148 | | * Local variables: |
149 | | * c-basic-offset: 4 |
150 | | * tab-width: 8 |
151 | | * indent-tabs-mode: nil |
152 | | * End: |
153 | | * |
154 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
155 | | * :indentSize=4:tabSize=8:noTabs=true: |
156 | | */ |