summaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-usb-masstorage.c
blob: 3ee17bf6fef8ea14409ba21f9074b89265e6f595 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/* packet-usb-masstorage.c
 * USB Mass Storage class stub dissector
 * Copyright 2021, Aidan MacDonald <amachronic@protonmail.com>
 *
 * Wireshark - Network traffic analyzer
 * By Gerald Combs <gerald@wireshark.org>
 * Copyright 1998 Gerald Combs
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#include "config.h"

#include <epan/packet.h>
#include "packet-usb.h"

static int proto_usb_ms;

static dissector_handle_t usb_ms_bulk_handle;
static dissector_handle_t usb_ms_control_handle;
static dissector_handle_t usb_ms_interrupt_handle;
static dissector_handle_t usb_ms_descriptor_handle;

static dissector_table_t usb_ms_bulk_dissector_table;
static dissector_table_t usb_ms_control_dissector_table;
static dissector_table_t usb_ms_interrupt_dissector_table;
static dissector_table_t usb_ms_descriptor_dissector_table;

void proto_register_usb_ms(void);
void proto_reg_handoff_usb_ms(void);

#define MSC_SUBCLASS_SCSI_COMMAND_SET_NOT_REPORTED 0x00
#define MSC_SUBCLASS_RBC                           0x01
#define MSC_SUBCLASS_MMC_5_ATAPI                   0x02
#define MSC_SUBCLASS_OBSOLETE_QIC_157              0x03
#define MSC_SUBCLASS_UFI                           0x04
#define MSC_SUBCLASS_OBSOLETE_SFF_8070I            0x05
#define MSC_SUBCLASS_SCSI_TRANSPARENT_COMMAND_SET  0x06
#define MSC_SUBCLASS_LSD_FS                        0x07
#define MSC_SUBCLASS_IEEE_1667                     0x08
#define MSC_SUBCLASS_VENDOR                        0xFF

static const value_string usb_massstorage_subclass_vals[] = {
    {MSC_SUBCLASS_SCSI_COMMAND_SET_NOT_REPORTED, "SCSI command set not reported"},
    {MSC_SUBCLASS_RBC,                           "RBC"},
    {MSC_SUBCLASS_MMC_5_ATAPI,                   "MMC-5 (ATAPI)"},
    {MSC_SUBCLASS_OBSOLETE_QIC_157,              "Obsolete (was QIC-157)"},
    {MSC_SUBCLASS_UFI,                           "UFI"},
    {MSC_SUBCLASS_OBSOLETE_SFF_8070I,            "Obsolete (was SFF-8070i)"},
    {MSC_SUBCLASS_SCSI_TRANSPARENT_COMMAND_SET,  "SCSI transparent command set"},
    {MSC_SUBCLASS_LSD_FS,                        "LSD FS"},
    {MSC_SUBCLASS_IEEE_1667,                     "IEEE 1667"},
    {MSC_SUBCLASS_VENDOR,                        "Specific to device vendor"},
    {0, NULL}
};
value_string_ext ext_usb_massstorage_subclass_vals = VALUE_STRING_EXT_INIT(usb_massstorage_subclass_vals);

#define MSC_PROTOCOL_CBI_NO_INTERRUPT   0x00
#define MSC_PROTOCOL_CBI_WITH_INTERRUPT 0x01
#define MSC_PROTOCOL_OBSOLETE           0x02
#define MSC_PROTOCOL_BULK_ONLY          0x50
#define MSC_PROTOCOL_UAS                0x62
#define MSC_PROTOCOL_VENDOR             0xFF

static const value_string usb_massstorage_protocol_vals[] = {
    {MSC_PROTOCOL_CBI_NO_INTERRUPT,   "Control/Bulk/Interrupt (CBI) Transport with command completion interrupt"},
    {MSC_PROTOCOL_CBI_WITH_INTERRUPT, "Control/Bulk/Interrupt (CBI) Transport with no command completion interrupt"},
    {MSC_PROTOCOL_OBSOLETE,           "Obsolete"},
    {MSC_PROTOCOL_BULK_ONLY,          "Bulk-Only (BBB) Transport"},
    {MSC_PROTOCOL_UAS,                "UAS"},
    {MSC_PROTOCOL_VENDOR,             "Specific to device vendor"},
    {0, NULL}
};
value_string_ext usb_massstorage_protocol_vals_ext = VALUE_STRING_EXT_INIT(usb_massstorage_protocol_vals);

static int
dissect_usb_ms_bulk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data)
{
    urb_info_t *urb;

    urb = (urb_info_t *)data;

    return dissector_try_uint_new(usb_ms_bulk_dissector_table, urb->conv->interfaceProtocol, tvb, pinfo, parent_tree, true, urb);
}

static int
dissect_usb_ms_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data)
{
    urb_info_t *urb;

    urb = (urb_info_t *)data;

    return dissector_try_uint_new(usb_ms_control_dissector_table, urb->conv->interfaceProtocol, tvb, pinfo, parent_tree, true, urb);
}

static int
dissect_usb_ms_interrupt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data)
{
    urb_info_t *urb;

    urb = (urb_info_t *)data;

    return dissector_try_uint_new(usb_ms_interrupt_dissector_table, urb->conv->interfaceProtocol, tvb, pinfo, parent_tree, true, urb);
}

static int
dissect_usb_ms_descriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data)
{
    urb_info_t *urb;

    urb = (urb_info_t *)data;

    return dissector_try_uint_new(usb_ms_descriptor_dissector_table, urb->conv->interfaceProtocol, tvb, pinfo, parent_tree, true, urb);
}

void
proto_register_usb_ms(void)
{
    proto_usb_ms = proto_register_protocol("USB Mass Storage Class", "USBMSClass", "usbmsclass");

    usb_ms_bulk_handle = register_dissector("usbmsclass.bulk", dissect_usb_ms_bulk, proto_usb_ms);
    usb_ms_control_handle = register_dissector("usbmsclass.control", dissect_usb_ms_control, proto_usb_ms);
    usb_ms_interrupt_handle = register_dissector("usbmsclass.interrupt", dissect_usb_ms_interrupt, proto_usb_ms);
    usb_ms_descriptor_handle = register_dissector("usbmsclass.descriptor", dissect_usb_ms_descriptor, proto_usb_ms);

    usb_ms_bulk_dissector_table = register_dissector_table("usbms.bulk",
        "USBMS bulk endpoint", proto_usb_ms, FT_UINT8, BASE_HEX);
    usb_ms_control_dissector_table = register_dissector_table("usbms.control",
        "USBMS control endpoint", proto_usb_ms, FT_UINT8, BASE_HEX);
    usb_ms_interrupt_dissector_table = register_dissector_table("usbms.interrupt",
        "USBMS interrupt endpoint", proto_usb_ms, FT_UINT8, BASE_HEX);
    usb_ms_descriptor_dissector_table = register_dissector_table("usbms.descriptor",
        "USBMS descriptor", proto_usb_ms, FT_UINT8, BASE_HEX);
}

void
proto_reg_handoff_usb_ms(void)
{
    dissector_add_uint("usb.bulk", IF_CLASS_MASS_STORAGE, usb_ms_bulk_handle);
    dissector_add_uint("usb.control", IF_CLASS_MASS_STORAGE, usb_ms_control_handle);
    dissector_add_uint("usb.interrupt", IF_CLASS_MASS_STORAGE, usb_ms_interrupt_handle);
    dissector_add_uint("usb.descriptor", IF_CLASS_MASS_STORAGE, usb_ms_descriptor_handle);
}

/*
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
 *
 * Local variables:
 * c-basic-offset: 4
 * tab-width: 8
 * indent-tabs-mode: nil
 * End:
 *
 * vi: set shiftwidth=4 tabstop=8 expandtab:
 * :indentSize=4:tabSize=8:noTabs=true:
 */