wireshark/epan/dissectors/packet-usb-masstorage.c
Aidan MacDonald 660dded383 Refactor USB mass storage class dissector
The existing dissector only handles the Bulk-Only Transport
protocol but occupies the USB dissector hooks for all mass
storage class traffic.

To facilitate alternative protocols like UASP, direct all
mass storage class traffic to a stub dissector which will
dispatch to the real dissector based on other information,
such as the USB interface protocol.

Heuristic dissectors are still attached directly to the
core USB hooks.
2021-11-17 13:27:56 +01:00

157 lines
6.2 KiB
C

/* 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 = -1;
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)
{
usb_conv_info_t *usb_conv_info;
usb_conv_info = (usb_conv_info_t *)data;
return dissector_try_uint_new(usb_ms_bulk_dissector_table, usb_conv_info->interfaceProtocol, tvb, pinfo, parent_tree, TRUE, usb_conv_info);
}
static int
dissect_usb_ms_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data)
{
usb_conv_info_t *usb_conv_info;
usb_conv_info = (usb_conv_info_t *)data;
return dissector_try_uint_new(usb_ms_control_dissector_table, usb_conv_info->interfaceProtocol, tvb, pinfo, parent_tree, TRUE, usb_conv_info);
}
static int
dissect_usb_ms_interrupt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data)
{
usb_conv_info_t *usb_conv_info;
usb_conv_info = (usb_conv_info_t *)data;
return dissector_try_uint_new(usb_ms_interrupt_dissector_table, usb_conv_info->interfaceProtocol, tvb, pinfo, parent_tree, TRUE, usb_conv_info);
}
static int
dissect_usb_ms_descriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data)
{
usb_conv_info_t *usb_conv_info;
usb_conv_info = (usb_conv_info_t *)data;
return dissector_try_uint_new(usb_ms_descriptor_dissector_table, usb_conv_info->interfaceProtocol, tvb, pinfo, parent_tree, TRUE, usb_conv_info);
}
void
proto_register_usb_ms(void)
{
proto_usb_ms = proto_register_protocol("USB Mass Storage Class", "USBMSClass", "usbmsclass");
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_handle_t usb_ms_bulk_handle;
dissector_handle_t usb_ms_control_handle;
dissector_handle_t usb_ms_interrupt_handle;
dissector_handle_t usb_ms_descriptor_handle;
usb_ms_bulk_handle = create_dissector_handle(dissect_usb_ms_bulk, proto_usb_ms);
usb_ms_control_handle = create_dissector_handle(dissect_usb_ms_control, proto_usb_ms);
usb_ms_interrupt_handle = create_dissector_handle(dissect_usb_ms_interrupt, proto_usb_ms);
usb_ms_descriptor_handle = create_dissector_handle(dissect_usb_ms_descriptor, proto_usb_ms);
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:
*/