diff options
-rw-r--r-- | packet-iscsi.c | 4 | ||||
-rw-r--r-- | packet-ndmp.c | 49 | ||||
-rw-r--r-- | packet-scsi.c | 121 | ||||
-rw-r--r-- | packet-scsi.h | 32 |
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); |