Coverage Report

Created: 2026-05-14 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
 */