aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorRonnie Sahlberg <ronnie_sahlberg@ozemail.com.au>2006-04-21 11:08:24 +0000
committerRonnie Sahlberg <ronnie_sahlberg@ozemail.com.au>2006-04-21 11:08:24 +0000
commit60e65f48697444409cc1ef1fb03f53ef034b7ef0 (patch)
tree9b9982fd6ecf1923b319e5c7b4da98dc6c3372aa /epan
parent73ded54b052d6a434a039a835b5f594116c3d9e7 (diff)
updates to get the fc and scsi dissectors
and get rid of some breakage in the design let the scsi transport keep track of itl (initiator, target, lun) matching and let it pass a itl structure to scsi that is persistent across packets. let scsi use this itl structure to track device type for a specific itl instead of the (must have been) broken hashtable. update both iscsi and fc to track the itl structure for scsi and schange the scsi signature to accept itl as a parameter. more to come. svn path=/trunk/; revision=17942
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/packet-fc.c1
-rw-r--r--epan/dissectors/packet-fc.h10
-rw-r--r--epan/dissectors/packet-fcct.c1
-rw-r--r--epan/dissectors/packet-fclctl.c1
-rw-r--r--epan/dissectors/packet-fcp.c63
-rw-r--r--epan/dissectors/packet-ipfc.c1
-rw-r--r--epan/dissectors/packet-iscsi.c35
-rw-r--r--epan/dissectors/packet-llc.c1
-rw-r--r--epan/dissectors/packet-ndmp.c4
-rw-r--r--epan/dissectors/packet-scsi.c165
-rw-r--r--epan/dissectors/packet-scsi.h6
11 files changed, 106 insertions, 182 deletions
diff --git a/epan/dissectors/packet-fc.c b/epan/dissectors/packet-fc.c
index 64b5bb54f9..74437b28bb 100644
--- a/epan/dissectors/packet-fc.c
+++ b/epan/dissectors/packet-fc.c
@@ -657,6 +657,7 @@ dissect_fc_helper (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean
pinfo->ptype, pinfo->srcport,
pinfo->destport, 0);
}
+ fchdr.conversation=conversation;
fc_conv_data=conversation_get_proto_data(conversation, proto_fc);
if(!fc_conv_data){
fc_conv_data=se_alloc(sizeof(fc_conv_data_t));
diff --git a/epan/dissectors/packet-fc.h b/epan/dissectors/packet-fc.h
index aff334ab45..cd69456958 100644
--- a/epan/dissectors/packet-fc.h
+++ b/epan/dissectors/packet-fc.h
@@ -125,11 +125,18 @@ ETH_VAR_IMPORT const value_string fc_fc4_val[];
#define FC_FCTL_ABTS_MASK 0x000030
#define FC_FCTL_REL_OFFSET 0x000008
+/* 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 {
+ guint8 cmdset; /* initialized to 0xff == unknown */
+} 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.
*/
-/* XXX the LUN field will later be moved into an itl_nexusu_t structure */
typedef struct _itlq_nexus_t {
guint32 first_exchange_frame;
guint32 last_exchange_frame;
@@ -150,6 +157,7 @@ typedef struct _fc_hdr {
guint8 r_ctl;
guint8 cs_ctl;
itlq_nexus_t *itlq;
+ conversation_t *conversation;
} fc_hdr;
#endif /* __PACKET_FC_H_ */
diff --git a/epan/dissectors/packet-fcct.c b/epan/dissectors/packet-fcct.c
index 15f211ecfe..08e75066f2 100644
--- a/epan/dissectors/packet-fcct.c
+++ b/epan/dissectors/packet-fcct.c
@@ -43,6 +43,7 @@
#include <epan/packet.h>
#include <epan/etypes.h>
+#include <epan/conversation.h>
#include "packet-fc.h"
#include "packet-fcct.h"
diff --git a/epan/dissectors/packet-fclctl.c b/epan/dissectors/packet-fclctl.c
index 9839daa9f3..55ec3898f5 100644
--- a/epan/dissectors/packet-fclctl.c
+++ b/epan/dissectors/packet-fclctl.c
@@ -44,6 +44,7 @@
#include <epan/packet.h>
#include <epan/emem.h>
#include <epan/etypes.h>
+#include <epan/conversation.h>
#include "packet-fc.h"
#include "packet-fclctl.h"
diff --git a/epan/dissectors/packet-fcp.c b/epan/dissectors/packet-fcp.c
index 56efe71d89..0989d14ac4 100644
--- a/epan/dissectors/packet-fcp.c
+++ b/epan/dissectors/packet-fcp.c
@@ -96,6 +96,10 @@ static gint ett_fcp = -1;
static gint ett_fcp_taskmgmt = -1;
static gint ett_fcp_rsp_flags = -1;
+typedef struct _fcp_conv_data_t {
+ se_tree_t *luns;
+} fcp_conv_data_t;
+
static dissector_table_t fcp_dissector;
static dissector_handle_t data_handle;
@@ -388,7 +392,7 @@ dissect_rsp_flags(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
}
static void
-dissect_fcp_cmnd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, proto_tree *tree, conversation_t *conversation, fc_hdr *fchdr)
+dissect_fcp_cmnd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, proto_tree *tree, conversation_t *conversation, fc_hdr *fchdr, fcp_conv_data_t *fcp_conv_data)
{
int offset = 0;
int len,
@@ -398,6 +402,7 @@ dissect_fcp_cmnd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, pro
guint16 lun=0xffff;
tvbuff_t *cdb_tvb;
int tvb_len, tvb_rlen;
+ itl_nexus_t *itl=NULL;
/* Determine the length of the FCP part of the packet */
flags = tvb_get_guint8 (tvb, offset+10);
@@ -429,13 +434,19 @@ dissect_fcp_cmnd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, pro
lun=tvb_get_guint8(tvb, offset)&0x3f;
lun<<=8;
lun|=tvb_get_guint8(tvb, offset+1);
- }
- else {
- fchdr->itlq->lun=tvb_get_guint8 (tvb, offset+1);
+ } else {
proto_tree_add_item(tree, hf_fcp_singlelun, tvb, offset+1,
1, 0);
lun=tvb_get_guint8(tvb, offset+1);
}
+ fchdr->itlq->lun=lun;
+
+ itl=(itl_nexus_t *)se_tree_lookup32(fcp_conv_data->luns, lun);
+ if(!itl){
+ itl=se_alloc(sizeof(itl_nexus_t));
+ itl->cmdset=0xff;
+ se_tree_insert32(fcp_conv_data->luns, lun, itl);
+ }
proto_tree_add_item(tree, hf_fcp_crn, tvb, offset+8, 1, 0);
proto_tree_add_item(tree, hf_fcp_taskattr, tvb, offset+9, 1, 0);
@@ -451,14 +462,14 @@ dissect_fcp_cmnd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, pro
if(tvb_rlen>(16+add_len))
tvb_rlen=16+add_len;
cdb_tvb=tvb_new_subset(tvb, offset+12, tvb_len, tvb_rlen);
- dissect_scsi_cdb(cdb_tvb, pinfo, parent_tree, SCSI_DEV_UNKNOWN, lun);
+ dissect_scsi_cdb(cdb_tvb, pinfo, parent_tree, SCSI_DEV_UNKNOWN, lun, itl);
proto_tree_add_item(tree, hf_fcp_dl, tvb, offset+12+16+add_len,
4, 0);
}
static void
-dissect_fcp_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, conversation_t *conversation, fc_hdr *fchdr)
+dissect_fcp_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, conversation_t *conversation, fc_hdr *fchdr, itl_nexus_t *itl)
{
scsi_task_id_t task_key;
@@ -466,7 +477,7 @@ dissect_fcp_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, con
task_key.task_id = conversation->index;
pinfo->private_data = (void *)&task_key;
- dissect_scsi_payload(tvb, pinfo, parent_tree, FALSE, fchdr->itlq->lun);
+ dissect_scsi_payload(tvb, pinfo, parent_tree, FALSE, fchdr->itlq->lun, itl);
}
/* fcp-3 9.5 table 24 */
@@ -485,7 +496,7 @@ dissect_fcp_rspinfo(tvbuff_t *tvb, proto_tree *tree, int offset)
}
static void
-dissect_fcp_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, proto_tree *tree, conversation_t *conversation, fc_hdr *fchdr)
+dissect_fcp_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, proto_tree *tree, conversation_t *conversation, fc_hdr *fchdr, itl_nexus_t *itl)
{
guint32 offset = 0;
gint32 snslen = 0,
@@ -522,7 +533,7 @@ dissect_fcp_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, prot
/* scsi status code */
proto_tree_add_item(tree, hf_fcp_scsistatus, tvb, offset, 1, 0);
- dissect_scsi_rsp(tvb, pinfo, parent_tree, fchdr->itlq, tvb_get_guint8(tvb, offset));
+ dissect_scsi_rsp(tvb, pinfo, parent_tree, fchdr->itlq, itl, tvb_get_guint8(tvb, offset));
offset++;
/* residual count */
@@ -595,9 +606,10 @@ dissect_fcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_item *ti=NULL;
proto_tree *fcp_tree = NULL;
- conversation_t *conversation;
fc_hdr *fchdr;
guint8 r_ctl;
+ fcp_conv_data_t *fcp_conv_data=NULL;
+ itl_nexus_t *itl=NULL;
fchdr=(fc_hdr *)pinfo->private_data;
@@ -622,22 +634,15 @@ dissect_fcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
- /* find the conversation for this transaction and create a new one if it
- * doesnt exist already.
- * XXX since FCP is always transported atop FC and FC also keeps track of
- * transactions we should grab the conversation off FC instead
- * we guarantee that conversation is non-NULL so the helpers we call
- * do not need to check it before dereferencing.
- */
- conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
- pinfo->ptype, pinfo->oxid,
- pinfo->rxid, NO_PORT2);
- if (!conversation) {
- /* NO_PORT2: Dont check RXID, iFCP traces i have all have
- * RXID==0xffff in the command PDU. ronnie */
- conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst,
- pinfo->ptype, pinfo->oxid,
- pinfo->rxid, NO_PORT2);
+ fcp_conv_data=conversation_get_proto_data(fchdr->conversation, proto_fcp);
+ if(!fcp_conv_data){
+ fcp_conv_data=se_alloc(sizeof(fcp_conv_data_t));
+ fcp_conv_data->luns=se_tree_create_non_persistent(SE_TREE_TYPE_RED_BLACK, "FCP Luns");
+ conversation_add_proto_data(fchdr->conversation, proto_fcp, fcp_conv_data);
+ }
+
+ if(r_ctl!=FCP_IU_CMD){
+ itl=(itl_nexus_t *)se_tree_lookup32(fcp_conv_data->luns, fchdr->itlq->lun);
}
/* put a request_in in all frames except the command frame */
@@ -664,7 +669,7 @@ dissect_fcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
switch (r_ctl) {
case FCP_IU_DATA:
- dissect_fcp_data(tvb, pinfo, tree, conversation, fchdr);
+ dissect_fcp_data(tvb, pinfo, tree, fchdr->conversation, fchdr, itl);
break;
case FCP_IU_CONFIRM:
/* Nothing to be done here */
@@ -673,10 +678,10 @@ dissect_fcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
dissect_fcp_xfer_rdy(tvb, fcp_tree);
break;
case FCP_IU_CMD:
- dissect_fcp_cmnd(tvb, pinfo, tree, fcp_tree, conversation, fchdr);
+ dissect_fcp_cmnd(tvb, pinfo, tree, fcp_tree, fchdr->conversation, fchdr, fcp_conv_data);
break;
case FCP_IU_RSP:
- dissect_fcp_rsp(tvb, pinfo, tree, fcp_tree, conversation, fchdr);
+ dissect_fcp_rsp(tvb, pinfo, tree, fcp_tree, fchdr->conversation, fchdr, itl);
break;
default:
call_dissector(data_handle, tvb, pinfo, tree);
diff --git a/epan/dissectors/packet-ipfc.c b/epan/dissectors/packet-ipfc.c
index 4a613ab24f..60b9640d33 100644
--- a/epan/dissectors/packet-ipfc.c
+++ b/epan/dissectors/packet-ipfc.c
@@ -38,6 +38,7 @@
#include <epan/packet.h>
#include <epan/etypes.h>
+#include <epan/conversation.h>
#include "packet-fc.h"
#include "packet-ipfc.h"
#include "packet-llc.h"
diff --git a/epan/dissectors/packet-iscsi.c b/epan/dissectors/packet-iscsi.c
index 0cbdb29b04..c7ce1c9f09 100644
--- a/epan/dissectors/packet-iscsi.c
+++ b/epan/dissectors/packet-iscsi.c
@@ -212,7 +212,8 @@ static gint ett_iscsi_ISID = -1;
/* this structure contains session wide state for a specific tcp conversation */
typedef struct _iscsi_session_t {
guint32 header_digest;
- se_tree_t *exchanges; /* indexed by ITT */
+ se_tree_t *itlq; /* indexed by ITT */
+ se_tree_t *itl; /* indexed by LUN */
} iscsi_session_t;
@@ -742,6 +743,7 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
guint16 lun=0xffff;
guint immediate_data_length=0;
guint immediate_data_offset=0;
+ itl_nexus_t *itl=NULL;
if(paddedDataSegmentLength & 3)
paddedDataSegmentLength += 4 - (paddedDataSegmentLength & 3);
@@ -751,7 +753,7 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
col_set_str(pinfo->cinfo, COL_PROTOCOL, "iSCSI");
/* XXX we need a way to handle replayed iscsi itt here */
- cdata=(iscsi_conv_data_t *)se_tree_lookup32(iscsi_session->exchanges, tvb_get_ntohl(tvb, offset+16));
+ cdata=(iscsi_conv_data_t *)se_tree_lookup32(iscsi_session->itlq, tvb_get_ntohl(tvb, offset+16));
if(!cdata){
cdata = se_alloc (sizeof(iscsi_conv_data_t));
cdata->itlq.lun=0xffff;
@@ -762,7 +764,7 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
cdata->data_in_frame=0;
cdata->data_out_frame=0;
- se_tree_insert32(iscsi_session->exchanges, tvb_get_ntohl(tvb, offset+16), cdata);
+ se_tree_insert32(iscsi_session->itlq, tvb_get_ntohl(tvb, offset+16), cdata);
}
if (opcode == ISCSI_OPCODE_SCSI_RESPONSE ||
@@ -819,6 +821,14 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
cdata->itlq.lun=lun;
cdata->itlq.first_exchange_frame=pinfo->fd->num;
+ itl=(itl_nexus_t *)se_tree_lookup32(iscsi_session->itl, lun);
+ if(!itl){
+ itl=se_alloc(sizeof(itl_nexus_t));
+ itl->cmdset=0xff;
+ se_tree_insert32(iscsi_session->itl, lun, itl);
+ }
+
+
/* The SCSI protocol uses this as the key to detect a
* SCSI-level conversation. */
task_key.conv_id = (int)iscsi_session;
@@ -829,6 +839,12 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
pinfo->private_data = NULL;
}
+
+ if(!itl){
+ itl=(itl_nexus_t *)se_tree_lookup32(iscsi_session->itl, cdata->itlq.lun);
+ }
+
+
if (check_col(pinfo->cinfo, COL_INFO)) {
if (opcode != ISCSI_OPCODE_SCSI_COMMAND) {
@@ -1494,7 +1510,7 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
if(tvb_rlen>16)
tvb_rlen=16;
cdb_tvb=tvb_new_subset(tvb, cdb_offset, tvb_len, tvb_rlen);
- dissect_scsi_cdb (cdb_tvb, pinfo, tree, SCSI_DEV_UNKNOWN, lun);
+ dissect_scsi_cdb(cdb_tvb, pinfo, tree, SCSI_DEV_UNKNOWN, lun, itl);
/* we dont want the immediata below to overwrite our CDB info */
if (check_col(pinfo->cinfo, COL_INFO)) {
col_set_fence(pinfo->cinfo, COL_INFO);
@@ -1511,7 +1527,7 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
data_tvb=tvb_new_subset(tvb, immediate_data_offset, tvb_len, tvb_rlen);
dissect_scsi_payload (data_tvb, pinfo, tree,
TRUE,
- lun );
+ lun, itl);
}
}
else if (opcode == ISCSI_OPCODE_SCSI_RESPONSE) {
@@ -1541,7 +1557,7 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
}
}
else {
- dissect_scsi_rsp(tvb, pinfo, tree, &cdata->itlq, scsi_status);
+ dissect_scsi_rsp(tvb, pinfo, tree, &cdata->itlq, itl, scsi_status);
}
}
else if ((opcode == ISCSI_OPCODE_SCSI_DATA_IN) ||
@@ -1559,11 +1575,11 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
data_tvb=tvb_new_subset(tvb, offset, tvb_len, tvb_rlen);
dissect_scsi_payload (data_tvb, pinfo, tree,
(opcode==ISCSI_OPCODE_SCSI_DATA_OUT),
- cdata->itlq.lun);
+ cdata->itlq.lun, itl);
}
if(S_bit){
- dissect_scsi_rsp(tvb, pinfo, tree, &cdata->itlq, scsi_status);
+ dissect_scsi_rsp(tvb, pinfo, tree, &cdata->itlq, itl, scsi_status);
}
}
@@ -1691,7 +1707,8 @@ dissect_iscsi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean chec
if(!iscsi_session){
iscsi_session=se_alloc(sizeof(iscsi_session_t));
iscsi_session->header_digest=ISCSI_HEADER_DIGEST_AUTO;
- iscsi_session->exchanges=se_tree_create_non_persistent(SE_TREE_TYPE_RED_BLACK, "iSCSI Exchanges");
+ iscsi_session->itlq=se_tree_create_non_persistent(SE_TREE_TYPE_RED_BLACK, "iSCSI ITLQ");
+ iscsi_session->itl=se_tree_create_non_persistent(SE_TREE_TYPE_RED_BLACK, "iSCSI ITL");
conversation_add_proto_data(conversation, proto_iscsi, iscsi_session);
/* DataOut PDUs are often mistaken by DCERPC heuristics to be
diff --git a/epan/dissectors/packet-llc.c b/epan/dissectors/packet-llc.c
index 3ed98301b8..85e86de084 100644
--- a/epan/dissectors/packet-llc.c
+++ b/epan/dissectors/packet-llc.c
@@ -36,6 +36,7 @@
#include <epan/bridged_pids.h>
#include <epan/ppptypes.h>
#include <epan/arcnet_pids.h>
+#include <epan/conversation.h>
#include "packet-fc.h"
#include "packet-ip.h"
#include "packet-ipx.h"
diff --git a/epan/dissectors/packet-ndmp.c b/epan/dissectors/packet-ndmp.c
index aecd9ed011..aba9213597 100644
--- a/epan/dissectors/packet-ndmp.c
+++ b/epan/dissectors/packet-ndmp.c
@@ -1116,7 +1116,7 @@ dissect_execute_cdb_cdb(tvbuff_t *tvb, int offset, packet_info *pinfo,
if(tvb_rlen>16)
tvb_rlen=16;
cdb_tvb=tvb_new_subset(tvb, offset, tvb_len, tvb_rlen);
- dissect_scsi_cdb(cdb_tvb, pinfo, tree, devtype, 0xffff);
+ dissect_scsi_cdb(cdb_tvb, pinfo, tree, devtype, 0xffff, NULL);
offset += cdb_len_full;
}
@@ -1159,7 +1159,7 @@ dissect_execute_cdb_payload(tvbuff_t *tvb, int offset, packet_info *pinfo, proto
data_tvb=tvb_new_subset(tvb, offset, tvb_len, tvb_rlen);
dissect_scsi_payload(data_tvb, pinfo, tree, isreq,
- 0xffff);
+ 0xffff, NULL);
offset += payload_len_full;
}
diff --git a/epan/dissectors/packet-scsi.c b/epan/dissectors/packet-scsi.c
index c0b8b20988..77e879eca7 100644
--- a/epan/dissectors/packet-scsi.c
+++ b/epan/dissectors/packet-scsi.c
@@ -40,17 +40,17 @@
* There are four main routines that are provided:
* o dissect_scsi_cdb - invoked on receiving a SCSI Command
* void dissect_scsi_cdb (tvbuff_t *, packet_info *, proto_tree *,
- * guint, guint16);
+ * guint, guint16, itl_nexus_t *);
* o dissect_scsi_payload - invoked to decode SCSI responses
* void dissect_scsi_payload (tvbuff_t *, packet_info *, proto_tree *, guint,
- * gboolean, guint32, guint16);
+ * gboolean, guint32, guint16, itl_nexus_t *);
* The final parameter is the length of the response field that is negotiated
* as part of the SCSI transport layer. If this is not tracked by the
* transport, it can be set to 0.
* o dissect_scsi_rsp - invoked to dissect the scsi status code in a response
* SCSI task.
* void dissect_scsi_rsp (tvbuff_t *, packet_info *, proto_tree *,
- * itlq_nexus_t *, guint8);
+ * itlq_nexus_t *, itl_nexus_t *, guint8);
* o dissect_scsi_snsinfo - invoked to decode the sense data provided in case of
* an error.
* void dissect_scsi_snsinfo (tvbuff_t *, packet_info *, proto_tree *, guint,
@@ -88,6 +88,7 @@
#include <epan/packet.h>
#include <epan/prefs.h>
#include <epan/emem.h>
+#include <epan/conversation.h>
#include "packet-fc.h"
#include "packet-scsi.h"
@@ -1665,35 +1666,12 @@ typedef struct _scsi_task_data {
* the DATA pdus for some opcodes.
*/
-} scsi_task_data_t;
-/*
- * 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;
-
-typedef struct _scsi_devtype_data {
- scsi_device_type devtype;
-} scsi_devtype_data_t;
+ itl_nexus_t *itl;
+} scsi_task_data_t;
static GHashTable *scsi_req_hash = NULL;
-static GHashTable *scsidev_req_hash = NULL;
-
static dissector_handle_t data_handle;
/*
@@ -1719,33 +1697,6 @@ scsi_hash (gconstpointer v)
return val;
}
-static gint
-scsidev_equal (gconstpointer v, gconstpointer w)
-{
- const scsi_devtype_key_t *k1 = (const scsi_devtype_key_t *)v;
- const scsi_devtype_key_t *k2 = (const scsi_devtype_key_t *)w;
-
- if (ADDRESSES_EQUAL (&k1->devid, &k2->devid))
- return 1;
- else
- return 0;
-}
-
-static guint
-scsidev_hash (gconstpointer v)
-{
- const scsi_devtype_key_t *key = (const scsi_devtype_key_t *)v;
- guint val;
- int i;
-
- val = 0;
- for (i = 0; i < key->devid.len; i++)
- val += key->devid.data[i];
- val += key->devid.type;
-
- return val;
-}
-
static scsi_task_data_t *
scsi_new_task (packet_info *pinfo)
{
@@ -1800,44 +1751,14 @@ 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_hash)
g_hash_table_destroy(scsi_req_hash);
- if (scsidev_req_hash)
- g_hash_table_destroy (scsidev_req_hash);
scsi_req_hash = g_hash_table_new(scsi_hash, scsi_equal);
- scsidev_req_hash = g_hash_table_new (scsidev_hash, scsidev_equal);
}
static void
@@ -2233,42 +2154,16 @@ dissect_spc3_inquiry (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint offset, gboolean isreq, gboolean iscdb,
guint32 payload_len, scsi_task_data_t *cdata)
{
- guint8 flags, i, devtype;
- scsi_devtype_data_t *devdata = NULL;
- scsi_devtype_key_t dkey, *req_key;
+ guint8 flags, i;
if (!isreq && (cdata == NULL || !(cdata->flags & 0x3))
&& (tvb_length_remaining(tvb, offset)>=1) ) {
/*
* INQUIRY response with device type information; add device type
* to list of known devices & their types if not already known.
- *
- * 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->src;
- devdata = (scsi_devtype_data_t *)g_hash_table_lookup (scsidev_req_hash,
- &dkey);
- if (!devdata) {
- req_key = se_alloc (sizeof(scsi_devtype_key_t));
- COPY_ADDRESS (&(req_key->devid), &(pinfo->src));
-
- devdata = se_alloc (sizeof(scsi_devtype_data_t));
- devdata->devtype = tvb_get_guint8 (tvb, offset) & SCSI_DEV_BITS;
-
- g_hash_table_insert (scsidev_req_hash, req_key, devdata);
- } else {
- devtype = tvb_get_guint8 (tvb, offset);
- if ((devtype & SCSI_DEV_BITS) != SCSI_DEV_NOLUN) {
- /* Some initiators probe more than the available LUNs which
- * results in Inquiry data being returned indicating that a LUN
- * is not supported. We don't want to overwrite the device type
- * with such responses.
- */
- devdata->devtype = (devtype & SCSI_DEV_BITS);
- }
+ if(cdata && cdata->itl){
+ cdata->itl->cmdset=tvb_get_guint8(tvb, offset)&SCSI_DEV_BITS;
}
}
@@ -6435,7 +6330,8 @@ dissect_smc2_readelementstatus (tvbuff_t *tvb, packet_info *pinfo,
void
dissect_scsi_rsp (tvbuff_t *tvb, packet_info *pinfo,
- proto_tree *tree, itlq_nexus_t *scsi_ed, guint8 scsi_status)
+ proto_tree *tree, itlq_nexus_t *itlq, itl_nexus_t *itl,
+ guint8 scsi_status)
{
proto_item *ti;
proto_tree *scsi_tree = NULL;
@@ -6448,14 +6344,19 @@ dissect_scsi_rsp (tvbuff_t *tvb, packet_info *pinfo,
scsi_tree = proto_item_add_subtree (ti, ett_scsi);
}
- ti=proto_tree_add_uint(scsi_tree, hf_scsi_lun, tvb, 0, 0, scsi_ed->lun);
+ ti=proto_tree_add_uint(scsi_tree, hf_scsi_lun, tvb, 0, 0, itlq->lun);
PROTO_ITEM_SET_GENERATED(ti);
- if(scsi_ed->first_exchange_frame){
+ if(itl){
+ ti=proto_tree_add_uint_format(scsi_tree, hf_scsi_inq_devtype, tvb, 0, 0, itl->cmdset, "Command Set:%s (0x%02x)", val_to_str(itl->cmdset, scsi_devtype_val, "Unknown"), itl->cmdset);
+ PROTO_ITEM_SET_GENERATED(ti);
+ }
+
+ if(itlq->first_exchange_frame){
nstime_t delta_time;
- ti=proto_tree_add_uint(scsi_tree, hf_scsi_request_frame, tvb, 0, 0, scsi_ed->first_exchange_frame);
+ ti=proto_tree_add_uint(scsi_tree, hf_scsi_request_frame, tvb, 0, 0, itlq->first_exchange_frame);
PROTO_ITEM_SET_GENERATED(ti);
- nstime_delta(&delta_time, &pinfo->fd->abs_ts, &scsi_ed->fc_time);
+ nstime_delta(&delta_time, &pinfo->fd->abs_ts, &itlq->fc_time);
ti=proto_tree_add_time(scsi_tree, hf_scsi_time, tvb, 0, 0, &delta_time);
PROTO_ITEM_SET_GENERATED(ti);
}
@@ -6463,7 +6364,7 @@ dissect_scsi_rsp (tvbuff_t *tvb, packet_info *pinfo,
ti=proto_tree_add_uint(scsi_tree, hf_scsi_status, tvb, 0, 0, scsi_status);
PROTO_ITEM_SET_GENERATED(ti);
if (check_col (pinfo->cinfo, COL_INFO)) {
- col_add_fstr (pinfo->cinfo, COL_INFO, "SCSI: Response LUN: 0x%02x (%s)", scsi_ed->lun, val_to_str(scsi_status, scsi_status_val, "Unknown (0x%08x)"));
+ col_add_fstr (pinfo->cinfo, COL_INFO, "SCSI: Response LUN: 0x%02x (%s)", itlq->lun, val_to_str(scsi_status, scsi_status_val, "Unknown (0x%08x)"));
col_set_fence(pinfo->cinfo, COL_INFO);
}
@@ -7811,7 +7712,7 @@ static scsi_cdb_table_t mmc[256] = {
void
dissect_scsi_cdb (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
- gint devtype_arg, guint16 lun)
+ gint devtype_arg, guint16 lun, itl_nexus_t *itl)
{
int offset = 0;
proto_item *ti;
@@ -7821,8 +7722,6 @@ dissect_scsi_cdb (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
scsi_cmnd_type cmd = 0; /* 0 is undefined type */
const gchar *valstr;
scsi_task_data_t *cdata;
- scsi_devtype_key_t dkey;
- scsi_devtype_data_t *devdata;
scsi_cdb_table_t *cdb_table=NULL;
const value_string *cdb_vals = NULL;
int hf_opcode=-1;
@@ -7836,20 +7735,8 @@ dissect_scsi_cdb (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
if (devtype_arg != SCSI_DEV_UNKNOWN) {
devtype = devtype_arg;
} else {
- /*
- * 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;
+ if (itl) {
+ devtype = itl->cmdset;
} else {
devtype = (scsi_device_type)scsi_def_devtype;
}
@@ -7932,6 +7819,7 @@ dissect_scsi_cdb (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
cdata->cdb_table = cdb_table;
cdata->cdb_vals = cdb_vals;
cdata->alloc_len=0;
+ cdata->itl=itl;
}
if (tree) {
@@ -7976,7 +7864,7 @@ dissect_scsi_cdb (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
void
dissect_scsi_payload (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
- gboolean isreq, guint16 lun)
+ gboolean isreq, guint16 lun, itl_nexus_t *itl)
{
int offset=0;
proto_item *ti;
@@ -7996,6 +7884,7 @@ dissect_scsi_payload (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
*/
return;
}
+ cdata->itl=itl;
old_proto=pinfo->current_proto;
pinfo->current_proto="SCSI";
diff --git a/epan/dissectors/packet-scsi.h b/epan/dissectors/packet-scsi.h
index b71ae093da..0e0b1b4d0b 100644
--- a/epan/dissectors/packet-scsi.h
+++ b/epan/dissectors/packet-scsi.h
@@ -63,10 +63,10 @@ extern const value_string scsi_status_val[];
* FCP/iSCSI
*/
void dissect_scsi_cdb (tvbuff_t *, packet_info *, proto_tree *,
- gint, guint16);
-void dissect_scsi_rsp (tvbuff_t *, packet_info *, proto_tree *, itlq_nexus_t *, guint8);
+ gint, guint16, 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, guint16);
+ gboolean, guint16, itl_nexus_t *);
void dissect_scsi_snsinfo (tvbuff_t *, packet_info *, proto_tree *, guint, guint, guint16);
/*