summaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-scsi.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
commite4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc (patch)
tree68cb5ef9081156392f1dd62a00c6ccc1451b93df /epan/dissectors/packet-scsi.h
parentInitial commit. (diff)
downloadwireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.tar.xz
wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.zip
Adding upstream version 4.2.2.upstream/4.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'epan/dissectors/packet-scsi.h')
-rw-r--r--epan/dissectors/packet-scsi.h323
1 files changed, 323 insertions, 0 deletions
diff --git a/epan/dissectors/packet-scsi.h b/epan/dissectors/packet-scsi.h
new file mode 100644
index 0000000..26fd292
--- /dev/null
+++ b/epan/dissectors/packet-scsi.h
@@ -0,0 +1,323 @@
+/* packet-scsi.h
+ * Author: Dinesh G Dutt (ddutt@cisco.com)
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 2002 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef __PACKET_SCSI_H_
+#define __PACKET_SCSI_H_
+
+#include <epan/exceptions.h>
+#include <epan/srt_table.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Structure containing itl nexus data :
+ * The itlq nexus is a structure containing data specific
+ * for a initiator target lun combination.
+ */
+typedef struct _itl_nexus_t {
+#define SCSI_CMDSET_DEFAULT 0x80
+#define SCSI_CMDSET_MASK 0x7f
+ guint8 cmdset; /* This is a bitfield.
+ * The MSB (0x80) represents whether
+ * 0: the commandset is known from a INQ PDU
+ * 1: is using the "default" from preferences.
+ * The lower 7 bits represent the commandset used
+ * for decoding commands on this itl nexus.
+ * The field is initialized to 0xff == unknown.
+ */
+ conversation_t *conversation;
+} itl_nexus_t;
+
+/* Structure containing itlq nexus data :
+ * The itlq nexus is a structure containing data specific
+ * for a initiator target lun queue/commandid combination.
+ */
+typedef struct _itlq_nexus_t {
+ guint32 first_exchange_frame;
+ guint32 last_exchange_frame;
+ guint16 lun; /* initialized to 0xffff == unknown */
+ guint16 scsi_opcode; /* initialized to 0xffff == unknown */
+ guint16 flags;
+
+#define SCSI_DATA_READ 0x0001
+#define SCSI_DATA_WRITE 0x0002
+ guint16 task_flags; /* Flags set by the transport for this
+ * scsi task.
+ *
+ * If there is no data being transferred both flags
+ * are 0 and both data lengths below are undefined.
+ *
+ * If one of the flags are set the amount of
+ * data being transferred is held in data_length
+ * and bidir_data_length is undefined.
+ *
+ * If both flags are set (a bidirectional transfer)
+ * data_length specifies the amount of DATA-OUT and
+ * bidir_data_length specifies the amount of DATA-IN
+ */
+ guint32 data_length;
+ guint32 bidir_data_length;
+
+ guint32 alloc_len; /* we need to track alloc_len between the CDB and
+ * the DATA pdus for some opcodes.
+ */
+ nstime_t fc_time;
+
+
+ void *extra_data; /* extra data that is task specific */
+} itlq_nexus_t;
+
+
+#define SCSI_PDU_TYPE_CDB 1
+#define SCSI_PDU_TYPE_DATA 2
+#define SCSI_PDU_TYPE_RSP 4
+#define SCSI_PDU_TYPE_SNS 5
+typedef struct _scsi_task_data {
+ int type;
+ itlq_nexus_t *itlq;
+ itl_nexus_t *itl;
+} scsi_task_data_t;
+
+
+/* list of commands for each commandset */
+typedef void (*scsi_dissector_t)(tvbuff_t *tvb, packet_info *pinfo,
+ proto_tree *tree, guint offset,
+ gboolean isreq, gboolean iscdb,
+ guint32 payload_len, scsi_task_data_t *cdata);
+
+typedef struct _scsi_cdb_table_t {
+ scsi_dissector_t func;
+} scsi_cdb_table_t;
+
+
+/* SPC Commands */
+#define SCSI_SPC_ACCESS_CONTROL_IN 0x86
+#define SCSI_SPC_ACCESS_CONTROL_OUT 0x87
+#define SCSI_SPC_CHANGE_DEFINITION 0x40
+#define SCSI_SPC_COMPARE 0x39
+#define SCSI_SPC_COPY 0x18
+#define SCSI_SPC_COPY_AND_VERIFY 0x3A
+#define SCSI_SPC_INQUIRY 0x12
+#define SCSI_SPC_EXTCOPY 0x83
+#define SCSI_SPC_RECVCOPY 0x84
+#define SCSI_SPC_LOGSELECT 0x4C
+#define SCSI_SPC_LOGSENSE 0x4D
+#define SCSI_SPC_MODESELECT6 0x15
+#define SCSI_SPC_MODESELECT10 0x55
+#define SCSI_SPC_MODESENSE6 0x1A
+#define SCSI_SPC_MODESENSE10 0x5A
+#define SCSI_SPC_PERSRESVIN 0x5E
+#define SCSI_SPC_PERSRESVOUT 0x5F
+#define SCSI_SPC_PREVMEDREMOVAL 0x1E
+#define SCSI_SPC_READBUFFER 0x3C
+#define SCSI_SPC_RCVDIAGRESULTS 0x1C
+#define SCSI_SPC_RELEASE6 0x17
+#define SCSI_SPC_RELEASE10 0x57
+#define SCSI_SPC_MGMT_PROTOCOL_IN 0xA3
+#define SCSI_SPC_REPORTLUNS 0xA0
+#define SCSI_SPC_REQSENSE 0x03
+#define SCSI_SPC_RESERVE6 0x16
+#define SCSI_SPC_RESERVE10 0x56
+#define SCSI_SPC_SENDDIAG 0x1D
+#define SCSI_SPC_SETDEVICEID 0xA4
+#define SCSI_SPC_TESTUNITRDY 0x00
+#define SCSI_SPC_WRITEBUFFER 0x3B
+#define SCSI_SPC_VARLENCDB 0x7F
+
+void dissect_spc_inquiry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gboolean isreq, gboolean iscdb, guint32 payload_len, scsi_task_data_t *cdata);
+void dissect_spc_logselect(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset, gboolean isreq, gboolean iscdb, guint payload_len _U_, scsi_task_data_t *cdata _U_);
+void dissect_spc_logsense(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset, gboolean isreq, gboolean iscdb, guint payload_len _U_, scsi_task_data_t *cdata _U_);
+void dissect_spc_mgmt_protocol_in(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset, gboolean isreq, gboolean iscdb, guint payload_len _U_, scsi_task_data_t *cdata _U_);
+void dissect_spc_modeselect6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gboolean isreq, gboolean iscdb, guint payload_len, scsi_task_data_t *cdata);
+void dissect_spc_modesense6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gboolean isreq, gboolean iscdb, guint payload_len, scsi_task_data_t *cdata);
+void dissect_spc_modeselect10(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gboolean isreq, gboolean iscdb, guint payload_len, scsi_task_data_t *cdata);
+void dissect_spc_modesense10(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gboolean isreq, gboolean iscdb, guint payload_len, scsi_task_data_t *cdata);
+void dissect_spc_persistentreservein(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset, gboolean isreq, gboolean iscdb, guint payload_len, scsi_task_data_t *cdata);
+void dissect_spc_persistentreserveout(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset, gboolean isreq, gboolean iscdb, guint payload_len _U_, scsi_task_data_t *cdata _U_);
+void dissect_spc_reportluns(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset, gboolean isreq, gboolean iscdb, guint payload_len _U_, scsi_task_data_t *cdata _U_);
+void dissect_spc_testunitready (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset, gboolean isreq, gboolean iscdb, guint payload_len _U_, scsi_task_data_t *cdata _U_);
+void dissect_spc_requestsense (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset, gboolean isreq, gboolean iscdb, guint payload_len _U_, scsi_task_data_t *cdata _U_);
+void dissect_spc_preventallowmediaremoval (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset, gboolean isreq, gboolean iscdb, guint payload_len _U_, scsi_task_data_t *cdata _U_);
+void dissect_spc_writebuffer (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset, gboolean isreq, gboolean iscdb _U_, guint payload_len _U_, scsi_task_data_t *cdata _U_);
+void dissect_spc_reserve6 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset, gboolean isreq, gboolean iscdb, guint payload_len _U_, scsi_task_data_t *cdata _U_);
+void dissect_spc_release6 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset, gboolean isreq, gboolean iscdb, guint payload_len _U_, scsi_task_data_t *cdata _U_);
+void dissect_spc_reserve10 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset, gboolean isreq, gboolean iscdb, guint payload_len _U_, scsi_task_data_t *cdata _U_);
+void dissect_spc_release10 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset, gboolean isreq, gboolean iscdb, guint payload_len _U_, scsi_task_data_t *cdata _U_);
+void dissect_spc_senddiagnostic (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset, gboolean isreq, gboolean iscdb, guint payload_len _U_, scsi_task_data_t *cdata _U_);
+void dissect_spc_extcopy (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset, gboolean isreq, gboolean iscdb, guint payload_len _U_, scsi_task_data_t *cdata _U_);
+void dissect_spc_recvcopy (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset, gboolean isreq, gboolean iscdb, guint payload_len _U_, scsi_task_data_t *cdata _U_);
+
+
+
+
+
+
+extern const value_string scsi_status_val[];
+
+/*
+ * SCSI Device Types.
+ *
+ * These can be supplied to the dissection routines if the caller happens
+ * to know the device type (e.g., NDMP assumes that a "jukebox" is a
+ * media changer, SCSI_DEV_SMC, and a "tape" is a sequential access device,
+ * SCSI_DEV_SSC).
+ *
+ * If the caller doesn't know the device type, it supplies SCSI_DEV_UNKNOWN.
+ */
+#define SCSI_DEV_UNKNOWN -1
+#define SCSI_DEV_SBC 0x0
+#define SCSI_DEV_SSC 0x1
+#define SCSI_DEV_PRNT 0x2
+#define SCSI_DEV_PROC 0x3
+#define SCSI_DEV_WORM 0x4
+#define SCSI_DEV_CDROM 0x5
+#define SCSI_DEV_SCAN 0x6
+#define SCSI_DEV_OPTMEM 0x7
+#define SCSI_DEV_SMC 0x8
+#define SCSI_DEV_COMM 0x9
+#define SCSI_DEV_RAID 0xC
+#define SCSI_DEV_SES 0xD
+#define SCSI_DEV_RBC 0xE
+#define SCSI_DEV_OCRW 0xF
+#define SCSI_DEV_OSD 0x11
+#define SCSI_DEV_ADC 0x12
+#define SCSI_DEV_NOLUN 0x1F
+
+#define SCSI_DEV_BITS 0x1F /* the lower 5 bits indicate device type */
+#define SCSI_MS_PCODE_BITS 0x3F /* Page code bits in Mode Sense */
+
+/* Function Decls; functions invoked by SAM-2 transport protocols such as
+ * FCP/iSCSI
+ */
+void dissect_scsi_cdb (tvbuff_t *, packet_info *, proto_tree *,
+ gint, itlq_nexus_t *, itl_nexus_t *);
+void dissect_scsi_rsp (tvbuff_t *, packet_info *, proto_tree *, itlq_nexus_t *, itl_nexus_t *, guint8);
+void dissect_scsi_payload (tvbuff_t *, packet_info *, proto_tree *,
+ gboolean, itlq_nexus_t *, itl_nexus_t *,
+ guint32 relative_offset);
+void dissect_scsi_snsinfo (tvbuff_t *, packet_info *, proto_tree *, guint, guint, itlq_nexus_t *, itl_nexus_t *);
+
+void dissect_scsi_lun(proto_tree *, tvbuff_t *, guint);
+
+extern int * const cdb_control_fields[6];
+extern gint ett_scsi_control;
+extern int hf_scsi_control;
+extern int hf_scsi_alloclen16;
+
+/* service actions */
+#define SHORT_FORM_BLOCK_ID 0x00
+#define SHORT_FORM_VENDOR_SPECIFIC 0x01
+#define LONG_FORM 0x06
+#define EXTENDED_FORM 0x08
+#define SERVICE_READ_CAPACITY16 0x10
+#define SERVICE_READ_LONG16 0x11
+#define SERVICE_WRITE_LONG16 0x11
+#define SERVICE_GET_LBA_STATUS 0x12
+#define SERVICE_REPORT_REFERRALS 0x13
+
+extern const value_string service_action_vals[];
+extern const value_string scsi_devid_codeset_val[];
+extern const value_string scsi_devid_idtype_val[];
+extern value_string_ext scsi_asc_val_ext;
+
+/* 0xA3 MGMT PROTOCOL IN service actions */
+#define MPI_MANAGEMENT_PROTOCOL_IN 0x10
+#define MPI_REPORT_SUPPORTED_OPERATION_CODES 0x0C
+
+/* These two defines are used to handle cases where data coming back from
+ * the device is truncated due to a too short allocation_length specified
+ * in the command CDB.
+ * This is semi-common in SCSI and it would be wrong to mark these packets
+ * as [malformed packets].
+ * These macros will reset the reported length to what the data pdu specified
+ * and if a ContainedBoundsError or ReportedBoundsError is generated we will
+ * instead throw ScsiBoundsError
+ *
+ * Please see dissect_spc_inquiry() for an example how to use these
+ * macros.
+ *
+ * Note that try_tvb & try_offset are initialized to be used in the code
+ * bounded by TRY_SCSI_ALLOC_LEN and END_TRY_SCSI_CDB_ALLOC_LEN
+ */
+
+#define TRY_SCSI_CDB_ALLOC_LEN(length_arg) \
+ { \
+ tvbuff_t *try_tvb; \
+ volatile guint try_offset; \
+ guint32 try_end_data_offset=0; \
+ \
+ try_tvb=tvb_new_subset_length(tvb_a, offset_a, length_arg); \
+ try_offset=0; \
+ TRY {
+
+#define END_TRY_SCSI_CDB_ALLOC_LEN \
+ if(try_end_data_offset){ \
+ /* just verify we can read all the bytes we were\
+ * supposed to. \
+ */ \
+ tvb_get_guint8(try_tvb,try_end_data_offset); \
+ } \
+ } /* TRY */ \
+ CATCH(BoundsError) { \
+ /* this was a short packet */ \
+ RETHROW; \
+ } \
+ CATCH(ContainedBoundsError) { \
+ /* We probably tried to dissect beyond the end \
+ * of the alloc len reported in the data \
+ * pdu. This is not an error so don't flag it \
+ * as one \
+ * it is the alloc_len in the CDB that is the \
+ * important one \
+ */ \
+ } \
+ CATCH(ReportedBoundsError) { \
+ /* this packet was not really short but limited \
+ * due to a short SCSI allocation length \
+ */ \
+ THROW(ScsiBoundsError); \
+ } \
+ ENDTRY; \
+ }
+
+/* If the data pdu contains an alloc_len as well, this macro can be set
+ * to registe this offset for the TRY section above.
+ * At the end of the TRY section we will, if set, verify that the data
+ * pdu contained all bytes that was specified in the data alloc len.
+ *
+ * This macro does currently not do anything but we might enhance it in
+ * the future. There is no harm in teaching the dissector about how long
+ * the data pdu is supposed to be according to alloc_len in the data pdu
+ */
+#define SET_SCSI_DATA_END(offset_arg) \
+ try_end_data_offset=offset_arg;
+
+
+WS_DLL_PUBLIC guint scsistat_param(register_srt_t* srt, const char* opt_arg, char** err);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+
+/*
+ * Editor modelines - https://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 8
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * End:
+ *
+ * vi: set shiftwidth=8 tabstop=8 noexpandtab:
+ * :indentSize=8:tabSize=8:noTabs=false:
+ */