aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--packet-iscsi.c4
-rw-r--r--packet-ndmp.c49
-rw-r--r--packet-scsi.c121
-rw-r--r--packet-scsi.h32
4 files changed, 146 insertions, 60 deletions
diff --git a/packet-iscsi.c b/packet-iscsi.c
index 8e321f184c..d46f1cfd70 100644
--- a/packet-iscsi.c
+++ b/packet-iscsi.c
@@ -2,7 +2,7 @@
* Routines for iSCSI dissection
* Copyright 2001, Eurologic and Mark Burton <markb@ordern.com>
*
- * $Id: packet-iscsi.c,v 1.36 2002/08/02 23:35:51 jmayer Exp $
+ * $Id: packet-iscsi.c,v 1.37 2002/08/20 22:33:16 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -1434,7 +1434,7 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
~(X_BIT | I_BIT) :
~I_BIT)) == ISCSI_OPCODE_SCSI_COMMAND) {
/* SCSI Command */
- dissect_scsi_cdb (tvb, pinfo, tree, cdb_offset, 16);
+ dissect_scsi_cdb (tvb, pinfo, tree, cdb_offset, 16, SCSI_DEV_UNKNOWN);
}
else if (opcode == ISCSI_OPCODE_SCSI_RESPONSE) {
if (scsi_status == 0x2) {
diff --git a/packet-ndmp.c b/packet-ndmp.c
index b81ad7020a..8dfe01c461 100644
--- a/packet-ndmp.c
+++ b/packet-ndmp.c
@@ -2,7 +2,7 @@
* Routines for NDMP dissection
* 2001 Ronnie Sahlberg (see AUTHORS for email)
*
- * $Id: packet-ndmp.c,v 1.21 2002/08/02 23:35:54 jmayer Exp $
+ * $Id: packet-ndmp.c,v 1.22 2002/08/20 22:33:16 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -421,7 +421,6 @@ static const value_string msg_vals[] = {
{0, NULL}
};
-
static int
dissect_connect_open_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
proto_tree *tree, guint32 seq _U_)
@@ -1051,7 +1050,8 @@ dissect_execute_cdb_flags(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
}
static int
-dissect_execute_cdb_cdb(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
+dissect_execute_cdb_cdb(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *parent_tree, gint devtype)
{
proto_item* item = NULL;
proto_tree* tree = NULL;
@@ -1072,7 +1072,7 @@ dissect_execute_cdb_cdb(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tre
offset += 4;
if (cdb_len != 0) {
- dissect_scsi_cdb(tvb, pinfo, tree, offset, cdb_len);
+ dissect_scsi_cdb(tvb, pinfo, tree, offset, cdb_len, devtype);
offset += cdb_len_full;
}
@@ -1111,9 +1111,24 @@ dissect_execute_cdb_payload(tvbuff_t *tvb, int offset, packet_info *pinfo, proto
return offset;
}
+/*
+ * XXX - we assume that NDMP_SCSI_EXECUTE_CDB requests only go to SCSI Media
+ * Changer devices and NDMP_TAPE_EXECUTE_CDB only go to SCSI Sequential
+ * Access devices.
+ *
+ * If that's not the case, we'll have to use the SCSI dissector's mechanisms
+ * for saving inquiry data for devices, and use inquiry data when available.
+ * Unfortunately, that means we need to save the name of the device, and
+ * use it as a device identifier; as the name isn't available in the
+ * NDMP_SCSI_EXECUTE_CDB or NDMP_TAPE_EXECUTE_CDB messages, that means
+ * we need to remember the currently-opened "SCSI" and "TAPE" devices
+ * from NDMP_SCSI_OPEN and NDMP_TAPE_OPEN, and attach to all frames
+ * that are the ones that trigger the dissection of NDMP_SCSI_EXECUTE_CDB
+ * or NDMP_TAPE_EXECUTE_CDB requests pointers to those names.
+ */
static int
dissect_execute_cdb_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
- proto_tree *tree, guint32 seq)
+ proto_tree *tree, guint32 seq, gint devtype)
{
conversation_t *conversation;
scsi_task_id_t task_key;
@@ -1132,7 +1147,7 @@ dissect_execute_cdb_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
}
task_key.conv_id = conversation->index;
task_key.task_id = seq;
- pinfo->private_data = &task_key;
+ pinfo->private_data = &task_key;
/* flags */
offset = dissect_execute_cdb_flags(tvb, offset, pinfo, tree);
@@ -1146,7 +1161,7 @@ dissect_execute_cdb_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
offset += 4;
/* CDB */
- offset = dissect_execute_cdb_cdb(tvb, offset, pinfo, tree);
+ offset = dissect_execute_cdb_cdb(tvb, offset, pinfo, tree, devtype);
/* dataout */
offset = dissect_execute_cdb_payload(tvb, offset, pinfo, tree,
@@ -1156,6 +1171,22 @@ dissect_execute_cdb_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
}
static int
+dissect_execute_cdb_request_mc(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint32 seq)
+{
+ return dissect_execute_cdb_request(tvb, offset, pinfo, tree, seq,
+ SCSI_DEV_SMC);
+}
+
+static int
+dissect_execute_cdb_request_tape(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint32 seq)
+{
+ return dissect_execute_cdb_request(tvb, offset, pinfo, tree, seq,
+ SCSI_DEV_SSC);
+}
+
+static int
dissect_execute_cdb_sns(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
{
proto_item* item = NULL;
@@ -2441,7 +2472,7 @@ static const ndmp_command ndmp_commands[] = {
{NDMP_SCSI_RESET_BUS,
NULL, dissect_error},
{NDMP_SCSI_EXECUTE_CDB,
- dissect_execute_cdb_request, dissect_execute_cdb_reply},
+ dissect_execute_cdb_request_mc, dissect_execute_cdb_reply},
{NDMP_TAPE_OPEN,
dissect_tape_open_request, dissect_error},
{NDMP_TAPE_CLOSE,
@@ -2455,7 +2486,7 @@ static const ndmp_command ndmp_commands[] = {
{NDMP_TAPE_READ,
dissect_tape_read_request, dissect_tape_read_reply},
{NDMP_TAPE_EXECUTE_CDB,
- dissect_execute_cdb_request, dissect_execute_cdb_reply},
+ dissect_execute_cdb_request_tape, dissect_execute_cdb_reply},
{NDMP_DATA_GET_STATE,
NULL, dissect_data_get_state_reply},
{NDMP_DATA_START_BACKUP,
diff --git a/packet-scsi.c b/packet-scsi.c
index da9d0868e5..433d7c4944 100644
--- a/packet-scsi.c
+++ b/packet-scsi.c
@@ -2,7 +2,7 @@
* Routines for decoding SCSI CDBs and responses
* Author: Dinesh G Dutt (ddutt@cisco.com)
*
- * $Id: packet-scsi.c,v 1.14 2002/08/20 03:21:42 guy Exp $
+ * $Id: packet-scsi.c,v 1.15 2002/08/20 22:33:16 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -520,23 +520,6 @@ static const value_string scsi_persresv_type_val[] = {
{0, NULL},
};
-/* SCSI Device Types */
-#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
-
static const value_string scsi_devtype_val[] = {
{SCSI_DEV_SBC , "Direct Access Device"},
{SCSI_DEV_SSC , "Sequential Access Device"},
@@ -1100,7 +1083,21 @@ typedef struct _scsi_task_data {
guint8 flags; /* used by SCSI Inquiry */
} scsi_task_data_t;
-/* The next two data structures are used to track SCSI device type */
+/*
+ * The next two data structures are used to track SCSI device type.
+ *
+ * XXX - it might not be sufficient to use the address of the server
+ * to which SCSI CDBs are being sent to identify the device, as
+ *
+ * 1) a server might have multiple targets or logical units;
+ *
+ * 2) a server might make a different logical unit refer to
+ * different devices for different clients;
+ *
+ * so we should really base this on the connection index for the
+ * connection and on a device identifier supplied to us by our caller,
+ * not on a network-layer address.
+ */
typedef struct _scsi_devtype_key {
address devid;
} scsi_devtype_key_t;
@@ -1230,8 +1227,31 @@ scsi_end_task (packet_info *pinfo)
* Protocol initialization
*/
static void
+free_devtype_key_dev_info(gpointer key_arg, gpointer value_arg _U_,
+ gpointer user_data _U_)
+{
+ scsi_devtype_key_t *key = key_arg;
+
+ if (key->devid.data != NULL) {
+ g_free((gpointer)key->devid.data);
+ key->devid.data = NULL;
+ }
+}
+
+static void
scsi_init_protocol(void)
{
+ /*
+ * First, free up the data for the addresses attached to
+ * scsi_devtype_key_t structures. Do so before we free
+ * those structures or destroy the hash table in which
+ * they're stored.
+ */
+ if (scsidev_req_hash != NULL) {
+ g_hash_table_foreach(scsidev_req_hash, free_devtype_key_dev_info,
+ NULL);
+ }
+
if (scsi_req_keys)
g_mem_chunk_destroy(scsi_req_keys);
if (scsi_req_vals)
@@ -1392,16 +1412,15 @@ dissect_scsi_inquiry (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
if (!isreq && (cdata == NULL || !(cdata->flags & 0x3))) {
/*
- * INQUIRY response; add device type to list of known devices &
- * their types if not already known.
+ * INQUIRY response with device type information; add device type
+ * to list of known devices & their types if not already known.
*
- * XXX - this assumes that the source address of the INQUIRY
- * reply uniquely identifies the device; that isn't the case, as,
- * for example, for iSCSI you could have more than one target
- * or LUN at a given IP address, and for NDMP more than one
- * device can be opened and closed in the same session.
+ * We don't use COPY_ADDRESS because "dkey.devid" isn't
+ * persistent, and therefore it can point to the stuff
+ * in "pinfo->src". (Were we to use COPY_ADDRESS, we'd
+ * have to free the address data it allocated before we return.)
*/
- COPY_ADDRESS (&(dkey.devid), &(pinfo->src));
+ dkey.devid = pinfo->src;
devdata = (scsi_devtype_data_t *)g_hash_table_lookup (scsidev_req_hash,
&dkey);
if (!devdata) {
@@ -2685,7 +2704,7 @@ dissect_scsi_ssc2_read6 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree
proto_tree_add_text (tree, tvb, offset, 1,
"SILI: %u, FIXED: %u",
(flags & 0x02) >> 1, flags & 0x01);
- proto_tree_add_item (tree, hf_scsi_rdwr6_xferlen, tvb, offset+1, 1, 0);
+ proto_tree_add_item (tree, hf_scsi_rdwr6_xferlen, tvb, offset+1, 3, 0);
flags = tvb_get_guint8 (tvb, offset+4);
proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
flags,
@@ -2710,7 +2729,8 @@ dissect_scsi_ssc2_write6 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tre
flags = tvb_get_guint8 (tvb, offset);
proto_tree_add_text (tree, tvb, offset, 1,
"FIXED: %u", flags & 0x01);
- proto_tree_add_item (tree, hf_scsi_rdwr6_xferlen, tvb, offset+1, 1, 0);
+ proto_tree_add_item (tree, hf_scsi_rdwr6_xferlen, tvb, offset+1, 3,
+ FALSE);
flags = tvb_get_guint8 (tvb, offset+4);
proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
flags,
@@ -2987,7 +3007,7 @@ dissect_scsi_snsinfo (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
void
dissect_scsi_cdb (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
- guint start, guint cdblen)
+ guint start, guint cdblen, gint devtype_arg)
{
int offset = start;
proto_item *ti;
@@ -3002,24 +3022,27 @@ dissect_scsi_cdb (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
opcode = tvb_get_guint8 (tvb, offset);
- /*
- * Try to look up the device data for this device.
- *
- * XXX - this assumes that the destination address of the request
- * uniquely identifies the device; that isn't the case, as,
- * for example, for iSCSI you could have more than one target
- * or LUN at a given IP address, and for NDMP more than one
- * device can be opened and closed in the same session.
- */
- COPY_ADDRESS (&(dkey.devid), &pinfo->dst);
-
- devdata = (scsi_devtype_data_t *)g_hash_table_lookup (scsidev_req_hash,
- &dkey);
- if (devdata != NULL) {
- devtype = devdata->devtype;
- }
+ if (devtype_arg != SCSI_DEV_UNKNOWN)
+ devtype = devtype_arg;
else {
- devtype = (scsi_device_type)scsi_def_devtype;
+ /*
+ * Try to look up the device data for this device.
+ *
+ * We don't use COPY_ADDRESS because "dkey.devid" isn't
+ * persistent, and therefore it can point to the stuff
+ * in "pinfo->src". (Were we to use COPY_ADDRESS, we'd
+ * have to free the address data it allocated before we return.)
+ */
+ dkey.devid = pinfo->dst;
+
+ devdata = (scsi_devtype_data_t *)g_hash_table_lookup (scsidev_req_hash,
+ &dkey);
+ if (devdata != NULL) {
+ devtype = devdata->devtype;
+ }
+ else {
+ devtype = (scsi_device_type)scsi_def_devtype;
+ }
}
if ((valstr = match_strval (opcode, scsi_spc2_val)) == NULL) {
@@ -3098,6 +3121,10 @@ dissect_scsi_cdb (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
"Opcode: %s (0x%02x)", valstr,
opcode);
}
+ else {
+ /* "Can't happen" */
+ g_assert_not_reached();
+ }
}
else {
proto_tree_add_item (scsi_tree, hf_scsi_spcopcode, tvb, offset, 1, 0);
diff --git a/packet-scsi.h b/packet-scsi.h
index a152ce7ac8..d2440605b5 100644
--- a/packet-scsi.h
+++ b/packet-scsi.h
@@ -1,7 +1,7 @@
/* packet-scsi.h
* Author: Dinesh G Dutt (ddutt@cisco.com)
*
- * $Id: packet-scsi.h,v 1.3 2002/02/13 01:17:58 guy Exp $
+ * $Id: packet-scsi.h,v 1.4 2002/08/20 22:33:17 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -27,10 +27,38 @@
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
+
/* Function Decls; functions invoked by SAM-2 transport protocols such as
* FCP/iSCSI
*/
-void dissect_scsi_cdb (tvbuff_t *, packet_info *, proto_tree *, guint, guint);
+void dissect_scsi_cdb (tvbuff_t *, packet_info *, proto_tree *, guint, guint,
+ gint);
void dissect_scsi_rsp (tvbuff_t *, packet_info *, proto_tree *);
void dissect_scsi_payload (tvbuff_t *, packet_info *, proto_tree *, guint,
gboolean, guint32);