aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsahlberg <sahlberg@f5534014-38df-0310-8fa8-9805f1628bb7>2006-04-22 02:16:52 +0000
committersahlberg <sahlberg@f5534014-38df-0310-8fa8-9805f1628bb7>2006-04-22 02:16:52 +0000
commit02f8436ab7edb1ed6e836f095c43b61f74cebf57 (patch)
tree55ac51d7f61e9e784a3dc5ac5d3f76b8cfae6721
parent66fec73301d522b98e80c808e94d7ade70fd4cf2 (diff)
the scsi transports (fc/fcp and iscsi) now track both itl and itlq
structures for scsi. we no longer need the scsi_task_id structure passed by pinfo->private_data so get rid of it. we no longer need the (broken by design) scsi_task_data hash table since this has been replaced byt hte itl and itlq structures and tracking git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@17952 f5534014-38df-0310-8fa8-9805f1628bb7
-rw-r--r--epan/dissectors/packet-fc.c2
-rw-r--r--epan/dissectors/packet-fc.h4
-rw-r--r--epan/dissectors/packet-fcp.c18
-rw-r--r--epan/dissectors/packet-iscsi.c17
-rw-r--r--epan/dissectors/packet-ndmp.c13
-rw-r--r--epan/dissectors/packet-scsi.c436
-rw-r--r--epan/dissectors/packet-scsi.h11
7 files changed, 140 insertions, 361 deletions
diff --git a/epan/dissectors/packet-fc.c b/epan/dissectors/packet-fc.c
index 74437b28bb..9e95a2a4d3 100644
--- a/epan/dissectors/packet-fc.c
+++ b/epan/dissectors/packet-fc.c
@@ -677,6 +677,8 @@ dissect_fc_helper (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean
fc_ex->lun=0xffff;
fc_ex->scsi_opcode=0xffff;
fc_ex->fc_time=pinfo->fd->abs_ts;
+ fc_ex->flags=0;
+ fc_ex->alloc_len=0;
se_tree_insert32(fc_conv_data->exchanges, fchdr.oxid, fc_ex);
}
/* populate the exchange struct */
diff --git a/epan/dissectors/packet-fc.h b/epan/dissectors/packet-fc.h
index cd69456958..a517a97e54 100644
--- a/epan/dissectors/packet-fc.h
+++ b/epan/dissectors/packet-fc.h
@@ -142,6 +142,10 @@ typedef struct _itlq_nexus_t {
guint32 last_exchange_frame;
guint16 lun; /* initialized to 0xffff == unknown */
guint16 scsi_opcode; /* initialized to 0xffff == unknown */
+ guint16 flags;
+ guint32 alloc_len; /* we need to track alloc_len between the CDB and
+ * the DATA pdus for some opcodes.
+ */
nstime_t fc_time;
} itlq_nexus_t;
diff --git a/epan/dissectors/packet-fcp.c b/epan/dissectors/packet-fcp.c
index efde328fc1..8e169a5883 100644
--- a/epan/dissectors/packet-fcp.c
+++ b/epan/dissectors/packet-fcp.c
@@ -398,8 +398,7 @@ dissect_fcp_cmnd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, pro
int len,
add_len = 0;
guint8 flags, lun0;
- scsi_task_id_t task_key;
- guint16 lun=0xffff;
+ guint16 lun=0xffff;
tvbuff_t *cdb_tvb;
int tvb_len, tvb_rlen;
itl_nexus_t *itl=NULL;
@@ -416,10 +415,6 @@ dissect_fcp_cmnd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, pro
len = FCP_DEF_CMND_LEN;
}
- task_key.conv_id = conversation->index;
- task_key.task_id = conversation->index;
- pinfo->private_data = (void *)&task_key;
-
proto_tree_add_uint_hidden(tree, hf_fcp_type, tvb, offset, 0, 0);
lun0 = tvb_get_guint8 (tvb, offset);
@@ -471,12 +466,6 @@ dissect_fcp_cmnd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, pro
static void
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;
-
- task_key.conv_id = conversation->index;
- task_key.task_id = conversation->index;
- pinfo->private_data = (void *)&task_key;
-
dissect_scsi_payload(tvb, pinfo, parent_tree, FALSE, fchdr->itlq, itl);
}
@@ -503,7 +492,6 @@ dissect_fcp_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, prot
rsplen = 0;
guint8 flags;
guint8 status;
- scsi_task_id_t task_key;
status = tvb_get_guint8 (tvb, offset+11);
@@ -512,13 +500,9 @@ dissect_fcp_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, prot
val_to_str (status, scsi_status_val, "0x%x"));
}
- task_key.conv_id = task_key.task_id = conversation->index;
- pinfo->private_data = (void *)&task_key;
-
proto_tree_add_uint_hidden(tree, hf_fcp_type, tvb, offset, 0, 0);
-
/* 8 reserved bytes */
offset+=8;
diff --git a/epan/dissectors/packet-iscsi.c b/epan/dissectors/packet-iscsi.c
index 3eea63e890..7b92e82caa 100644
--- a/epan/dissectors/packet-iscsi.c
+++ b/epan/dissectors/packet-iscsi.c
@@ -738,7 +738,6 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
guint cdb_offset = offset + 32; /* offset of CDB from start of PDU */
guint end_offset = offset + tvb_length_remaining(tvb, offset);
iscsi_conv_data_t *cdata = NULL;
- scsi_task_id_t task_key;
int paddedDataSegmentLength = data_segment_len;
guint16 lun=0xffff;
guint immediate_data_length=0;
@@ -761,6 +760,8 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
cdata->itlq.fc_time = pinfo->fd->abs_ts;
cdata->itlq.first_exchange_frame=0;
cdata->itlq.last_exchange_frame=0;
+ cdata->itlq.flags=0;
+ cdata->itlq.alloc_len=0;
cdata->data_in_frame=0;
cdata->data_out_frame=0;
@@ -792,10 +793,6 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
break;
}
- task_key.conv_id = (int)iscsi_session;
- task_key.task_id = tvb_get_ntohl(tvb, offset+16);
- pinfo->private_data = &task_key;
-
} else if (opcode == ISCSI_OPCODE_SCSI_COMMAND) {
/*we need the LUN value for some of the commands so we can pass it
across to the SCSI dissector.
@@ -828,17 +825,7 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
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;
- task_key.task_id = tvb_get_ntohl(tvb, offset+16);
- pinfo->private_data = &task_key;
}
- else {
- pinfo->private_data = NULL;
- }
-
if(!itl){
itl=(itl_nexus_t *)se_tree_lookup32(iscsi_session->itl, cdata->itlq.lun);
diff --git a/epan/dissectors/packet-ndmp.c b/epan/dissectors/packet-ndmp.c
index c0f1120ac9..6d490f3bb9 100644
--- a/epan/dissectors/packet-ndmp.c
+++ b/epan/dissectors/packet-ndmp.c
@@ -1205,7 +1205,6 @@ dissect_execute_cdb_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree, guint32 seq, gint devtype)
{
conversation_t *conversation;
- scsi_task_id_t task_key;
/*
* We need to provide SCSI task information to the SCSI
@@ -1219,9 +1218,6 @@ dissect_execute_cdb_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst,
pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
}
- task_key.conv_id = conversation->index;
- task_key.task_id = seq;
- pinfo->private_data = &task_key;
/* flags */
offset = dissect_execute_cdb_flags(tvb, offset, pinfo, tree);
@@ -1294,7 +1290,6 @@ dissect_execute_cdb_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree, guint32 seq)
{
conversation_t *conversation;
- scsi_task_id_t task_key;
/*
* We need to provide SCSI task information to the SCSI
@@ -1304,14 +1299,6 @@ dissect_execute_cdb_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
*/
conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
- if (conversation != NULL) {
- task_key.conv_id = conversation->index;
- task_key.task_id = seq;
- pinfo->private_data = &task_key;
- } else {
- /* no conversation, meaning we didn't see the request */
- pinfo->private_data = NULL;
- }
/* error */
offset=dissect_error(tvb, offset, pinfo, tree, seq);
diff --git a/epan/dissectors/packet-scsi.c b/epan/dissectors/packet-scsi.c
index 76d10a7be6..da6c2ed5e4 100644
--- a/epan/dissectors/packet-scsi.c
+++ b/epan/dissectors/packet-scsi.c
@@ -1641,124 +1641,32 @@ const true_false_string scsi_senddiag_pf_val = {
static gint scsi_def_devtype = SCSI_DEV_SBC;
-/*
- * We track SCSI requests and responses with a hash table.
- * The key is a "scsi_task_id_t" structure; the data is a
- * "scsi_task_data_t" structure.
- *
- * We remember:
- *
- * the command code and type of command (it's not present in the
- * response, and we need it to dissect the response);
- * the type of device it's on;
- *
- * and we also have a field to record flags in case the interpretation
- * of the response data depends on data from the command.
- */
-typedef struct _scsi_task_data {
- scsi_cmnd_type cmd;
- guint16 flags;
- struct _scsi_cdb_table_t *cdb_table;
- const value_string *cdb_vals;
- guint32 alloc_len; /* we need to track alloc_len between the CDB and
- * the DATA pdus for some opcodes.
- */
-
+typedef struct _scsi_task_data {
itlq_nexus_t *itlq;
itl_nexus_t *itl;
} scsi_task_data_t;
-static GHashTable *scsi_req_hash = NULL;
-
-static dissector_handle_t data_handle;
-
-/*
- * Hash Functions
- */
-static gint
-scsi_equal(gconstpointer v, gconstpointer w)
-{
- const scsi_task_id_t *v1 = (const scsi_task_id_t *)v;
- const scsi_task_id_t *v2 = (const scsi_task_id_t *)w;
-
- return (v1->conv_id == v2->conv_id && v1->task_id == v2->task_id);
-}
-
-static guint
-scsi_hash (gconstpointer v)
-{
- const scsi_task_id_t *key = (const scsi_task_id_t *)v;
- guint val;
-
- val = key->conv_id + key->task_id;
- return val;
-}
-
-static scsi_task_data_t *
-scsi_new_task (packet_info *pinfo)
-{
- scsi_task_data_t *cdata = NULL;
- scsi_task_id_t ckey, *req_key;
-
- if ((pinfo != NULL) && (pinfo->private_data)) {
- ckey = *(scsi_task_id_t *)pinfo->private_data;
-
- cdata = (scsi_task_data_t *)g_hash_table_lookup (scsi_req_hash,
- &ckey);
- if (!cdata) {
- req_key = se_alloc (sizeof(scsi_task_id_t));
- *req_key = *(scsi_task_id_t *)pinfo->private_data;
-
- cdata = se_alloc (sizeof(scsi_task_data_t));
-
- g_hash_table_insert (scsi_req_hash, req_key, cdata);
- }
- }
- return (cdata);
-}
-
-static scsi_task_data_t *
-scsi_find_task (packet_info *pinfo)
-{
- scsi_task_data_t *cdata = NULL;
- scsi_task_id_t ckey;
-
- if ((pinfo != NULL) && (pinfo->private_data)) {
- ckey = *(scsi_task_id_t *)pinfo->private_data;
-
- cdata = (scsi_task_data_t *)g_hash_table_lookup (scsi_req_hash,
- &ckey);
- }
- return (cdata);
-}
-
-static void
-scsi_end_task (packet_info *pinfo)
-{
- scsi_task_data_t *cdata = NULL;
- scsi_task_id_t ckey;
+/* 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);
- if ((pinfo != NULL) && (pinfo->private_data)) {
- ckey = *(scsi_task_id_t *)pinfo->private_data;
- cdata = (scsi_task_data_t *)g_hash_table_lookup (scsi_req_hash,
- &ckey);
- if (cdata) {
- g_hash_table_remove (scsi_req_hash, &ckey);
- }
- }
-}
+typedef struct _scsi_cdb_table_t {
+ scsi_dissector_t func;
+} scsi_cdb_table_t;
+typedef struct _cmdset_t {
+ int hf_opcode;
+ const value_string *cdb_vals;
+ scsi_cdb_table_t *cdb_table;
+} cmdset_t;
-static void
-scsi_init_protocol(void)
-{
- if (scsi_req_hash)
- g_hash_table_destroy(scsi_req_hash);
+static cmdset_t *get_cmdset_data(itlq_nexus_t *itlq, itl_nexus_t *itl);
- scsi_req_hash = g_hash_table_new(scsi_hash, scsi_equal);
-}
+static dissector_handle_t data_handle;
static void
dissect_scsi_evpd (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
@@ -2155,7 +2063,7 @@ dissect_spc3_inquiry (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
{
guint8 flags, i;
- if (!isreq && (cdata == NULL || !(cdata->flags & 0x3))
+ if (!isreq && (cdata == NULL || !(cdata->itlq->flags & 0x3))
&& (tvb_length_remaining(tvb, offset)>=1) ) {
/*
* INQUIRY response with device type information; add device type
@@ -2169,7 +2077,7 @@ dissect_spc3_inquiry (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
if (isreq && iscdb) {
flags = tvb_get_guint8 (tvb, offset);
if (cdata) {
- cdata->flags = flags;
+ cdata->itlq->flags = flags;
}
proto_tree_add_uint_format (tree, hf_scsi_inquiry_flags, tvb, offset, 1,
@@ -2187,7 +2095,7 @@ dissect_spc3_inquiry (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
proto_tree_add_item (tree, hf_scsi_alloclen, tvb, offset+3, 1, 0);
/* we need the alloc_len in the response */
if(cdata){
- cdata->alloc_len=tvb_get_guint8(tvb, offset+3);
+ cdata->itlq->alloc_len=tvb_get_guint8(tvb, offset+3);
}
flags = tvb_get_guint8 (tvb, offset+4);
@@ -2200,11 +2108,11 @@ dissect_spc3_inquiry (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
return;
}
- if (cdata->flags & 0x1) {
+ if (cdata->itlq->flags & 0x1) {
dissect_scsi_evpd (tvb, pinfo, tree, offset, payload_len);
return;
}
- if (cdata->flags & 0x2) {
+ if (cdata->itlq->flags & 0x2) {
dissect_scsi_cmddt (tvb, pinfo, tree, offset, payload_len);
return;
}
@@ -2213,7 +2121,7 @@ dissect_spc3_inquiry (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
/* These pdus are sometimes truncated by SCSI allocation length
* in the CDB
*/
- TRY_SCSI_CDB_ALLOC_LEN(pinfo, tvb, offset, cdata->alloc_len);
+ TRY_SCSI_CDB_ALLOC_LEN(pinfo, tvb, offset, cdata->itlq->alloc_len);
/* Qualifier and DeviceType */
proto_tree_add_item (tree, hf_scsi_inq_qualifier, tvb, offset,
@@ -3608,11 +3516,11 @@ dissect_spc3_persistentreservein (tvbuff_t *tvb, packet_info *pinfo _U_, proto_t
"Vendor Unique = %u, NACA = %u, Link = %u",
flags & 0xC0, flags & 0x4, flags & 0x1);
/* We store the service action since we want to interpret the data */
- cdata->flags = tvb_get_guint8 (tvb, offset+1);
+ cdata->itlq->flags = tvb_get_guint8 (tvb, offset+1);
}
else {
if (cdata) {
- flags = cdata->flags;
+ flags = cdata->itlq->flags;
}
else {
flags = 0xFF;
@@ -3748,7 +3656,7 @@ dissect_spc3_reportluns (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree
proto_tree_add_item (tree, hf_scsi_alloclen32, tvb, offset+5, 4, 0);
if(cdata){
- cdata->alloc_len=tvb_get_ntohl(tvb, offset+5);
+ cdata->itlq->alloc_len=tvb_get_ntohl(tvb, offset+5);
}
flags = tvb_get_guint8 (tvb, offset+10);
@@ -3761,7 +3669,7 @@ dissect_spc3_reportluns (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree
return;
}
- TRY_SCSI_CDB_ALLOC_LEN(pinfo, tvb, offset, cdata->alloc_len);
+ TRY_SCSI_CDB_ALLOC_LEN(pinfo, tvb, offset, cdata->itlq->alloc_len);
listlen = tvb_get_ntohl(tvb, offset);
proto_tree_add_text (tree, tvb, offset, 4, "LUN List Length: %u",
listlen);
@@ -4323,7 +4231,7 @@ dissect_mmc4_reportkey (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
}
proto_tree_add_uint (tree, hf_scsi_key_format, tvb, offset+9, 1, key_format);
/* save key_class/key_format so we can decode the response */
- cdata->flags=(key_format<<8)|key_class;
+ cdata->itlq->flags=(key_format<<8)|key_class;
flags = tvb_get_guint8 (tvb, offset+14);
proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+14, 1,
@@ -4332,7 +4240,7 @@ dissect_mmc4_reportkey (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
flags & 0xC0, flags & 0x4, flags & 0x1);
}
if(tree && (!isreq)) {
- switch(cdata->flags){
+ switch(cdata->itlq->flags){
case 0x0800: /* format:RPC State class:00 */
proto_tree_add_item (tree, hf_scsi_data_length, tvb, offset, 2, 0);
proto_tree_add_item (tree, hf_scsi_report_key_type_code, tvb, offset+4, 1, 0);
@@ -4344,7 +4252,7 @@ dissect_mmc4_reportkey (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
default:
ti = proto_tree_add_text (tree, tvb, 0, 0,
"SCSI/MMC Unknown Format:0x%02x/Class:0x%02x combination",
- cdata->flags>>8,cdata->flags&0xff);
+ cdata->itlq->flags>>8,cdata->itlq->flags&0xff);
PROTO_ITEM_SET_GENERATED(ti);
break;
}
@@ -4368,7 +4276,7 @@ dissect_mmc4_setstreaming (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
if (tree && isreq && iscdb) {
type=tvb_get_guint8(tvb, offset+7);
- cdata->flags=type;
+ cdata->itlq->flags=type;
proto_tree_add_item (tree, hf_scsi_setstreaming_type, tvb, offset+7, 1, 0);
proto_tree_add_item (tree, hf_scsi_setstreaming_param_len, tvb, offset+8, 2, 0);
@@ -4379,7 +4287,7 @@ dissect_mmc4_setstreaming (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
flags & 0xC0, flags & 0x4, flags & 0x1);
}
if(tree && isreq && (!iscdb)) {
- switch(cdata->flags){
+ switch(cdata->itlq->flags){
case 0x00: /* performance descriptor */
proto_tree_add_item (tree, hf_scsi_setstreaming_wrc, tvb, offset+0, 1, 0);
proto_tree_add_item (tree, hf_scsi_setstreaming_rdd, tvb, offset+0, 1, 0);
@@ -4394,7 +4302,7 @@ dissect_mmc4_setstreaming (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
break;
default:
ti = proto_tree_add_text (tree, tvb, 0, 0,
- "SCSI/MMC Unknown SetStreaming Type:0x%02x",cdata->flags);
+ "SCSI/MMC Unknown SetStreaming Type:0x%02x",cdata->itlq->flags);
PROTO_ITEM_SET_GENERATED(ti);
break;
}
@@ -4527,7 +4435,7 @@ dissect_mmc4_getconfiguration (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
proto_tree_add_item (tree, hf_scsi_alloclen16, tvb, offset+6, 2, 0);
/* we need the alloc_len in the response */
if(cdata){
- cdata->alloc_len=tvb_get_ntohs(tvb, offset+6);
+ cdata->itlq->alloc_len=tvb_get_ntohs(tvb, offset+6);
}
flags = tvb_get_guint8 (tvb, offset+8);
@@ -4541,7 +4449,7 @@ dissect_mmc4_getconfiguration (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
return;
}
- TRY_SCSI_CDB_ALLOC_LEN(pinfo, tvb, offset, cdata->alloc_len);
+ TRY_SCSI_CDB_ALLOC_LEN(pinfo, tvb, offset, cdata->itlq->alloc_len);
len=tvb_get_ntohl(tvb, offset+0);
proto_tree_add_item (tree, hf_scsi_data_length, tvb, offset, 4, 0);
@@ -4723,7 +4631,7 @@ dissect_mmc4_readtocpmaatip (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
if (tree && isreq && iscdb) {
format=tvb_get_guint8(tvb, offset+1)&0x0f;
/* save format so we can decode the response */
- cdata->flags=format;
+ cdata->itlq->flags=format;
switch(format){
case 0x00:
@@ -4731,7 +4639,7 @@ dissect_mmc4_readtocpmaatip (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
proto_tree_add_item (tree, hf_scsi_readtoc_time, tvb, offset, 1, 0);
/* save time so we can pick it up in the response */
if(tvb_get_guint8(tvb, offset)&0x02){
- cdata->flags|=0x0100;
+ cdata->itlq->flags|=0x0100;
}
break;
}
@@ -4741,12 +4649,12 @@ dissect_mmc4_readtocpmaatip (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
case 0x00:
proto_tree_add_item (tree, hf_scsi_track, tvb, offset+5, 1, 0);
/* save track so we can pick it up in the response */
- cdata->flags|=0x0200;
+ cdata->itlq->flags|=0x0200;
break;
case 0x02:
proto_tree_add_item (tree, hf_scsi_session, tvb, offset+5, 1, 0);
/* save session so we can pick it up in the response */
- cdata->flags|=0x0400;
+ cdata->itlq->flags|=0x0400;
break;
}
@@ -4762,23 +4670,23 @@ dissect_mmc4_readtocpmaatip (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
if(tree && (!isreq)) {
len=tvb_get_ntohs(tvb, offset);
proto_tree_add_item (tree, hf_scsi_data_length, tvb, offset, 2, 0);
- if(cdata->flags&0x0200){
+ if(cdata->itlq->flags&0x0200){
proto_tree_add_item (tree, hf_scsi_first_track, tvb, offset+2, 1, 0);
proto_tree_add_item (tree, hf_scsi_readtoc_last_track, tvb, offset+3, 1, 0);
}
- if(cdata->flags&0x0400){
+ if(cdata->itlq->flags&0x0400){
proto_tree_add_item (tree, hf_scsi_readtoc_first_session, tvb, offset+2, 1, 0);
proto_tree_add_item (tree, hf_scsi_readtoc_last_session, tvb, offset+3, 1, 0);
}
offset+=4;
len-=2;
- switch(cdata->flags&0x000f){
+ switch(cdata->itlq->flags&0x000f){
case 0x0:
while(len>0){
proto_tree_add_item (tree, hf_scsi_q_subchannel_adr, tvb, offset+1, 1, 0);
proto_tree_add_item (tree, hf_scsi_q_subchannel_control, tvb, offset+1, 1, 0);
proto_tree_add_item (tree, hf_scsi_track, tvb, offset+2, 1, 0);
- if(cdata->flags&0x0100){
+ if(cdata->itlq->flags&0x0100){
proto_tree_add_item (tree, hf_scsi_track_start_time, tvb, offset+4, 4, 0);
} else {
proto_tree_add_item (tree, hf_scsi_track_start_address, tvb, offset+4, 4, 0);
@@ -4789,7 +4697,7 @@ dissect_mmc4_readtocpmaatip (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
break;
default:
proto_tree_add_text (tree, tvb, offset, len,
- "SCSI/MMC Unknown READ TOC Format:0x%04x",cdata->flags&0x000f);
+ "SCSI/MMC Unknown READ TOC Format:0x%04x",cdata->itlq->flags&0x000f);
break;
}
}
@@ -4864,10 +4772,10 @@ dissect_mmc4_readbuffercapacity (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr
gint16 len;
if (tree && isreq && iscdb) {
- cdata->flags=0;
+ cdata->itlq->flags=0;
proto_tree_add_item (tree, hf_scsi_rbc_block, tvb, offset, 1, 0);
if(tvb_get_guint8(tvb, offset)&0x01){
- cdata->flags=1;
+ cdata->itlq->flags=1;
}
proto_tree_add_item (tree, hf_scsi_alloclen16, tvb, offset+6, 2, 0);
@@ -4882,7 +4790,7 @@ dissect_mmc4_readbuffercapacity (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr
if(tree && (!isreq)) {
len=tvb_get_ntohs(tvb, offset);
proto_tree_add_item (tree, hf_scsi_data_length, tvb, offset, 2, 0);
- if(cdata->flags){
+ if(cdata->itlq->flags){
proto_tree_add_item (tree, hf_scsi_rbc_lob_blocks, tvb, offset+4, 4, 0);
proto_tree_add_item (tree, hf_scsi_rbc_alob_blocks, tvb, offset+8, 4, 0);
} else {
@@ -5531,7 +5439,7 @@ dissect_ssc2_readposition (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
"Unknown (0x%02x)"));
/* Remember the service action so we can decode the reply */
if (cdata != NULL) {
- cdata->flags = service_action;
+ cdata->itlq->flags = service_action;
}
proto_tree_add_text (tree, tvb, offset+6, 2,
"Parameter Len: %u",
@@ -5544,7 +5452,7 @@ dissect_ssc2_readposition (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
}
else if (!isreq) {
if (cdata)
- service_action = cdata->flags;
+ service_action = cdata->itlq->flags;
else
service_action = -1; /* unknown */
switch (service_action) {
@@ -6349,37 +6257,15 @@ dissect_scsi_rsp (tvbuff_t *tvb, packet_info *pinfo,
PROTO_ITEM_SET_GENERATED(ti);
if(itl){
- int hf_opcode=-1;
- const value_string *cdb_vals = NULL;
+ cmdset_t *csdata;
- 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);
+ csdata=get_cmdset_data(itlq, itl);
- switch(itl->cmdset){
- case SCSI_DEV_SBC:
- hf_opcode=hf_scsi_sbcopcode;
- cdb_vals=scsi_sbc2_val;
- break;
- case SCSI_DEV_CDROM:
- hf_opcode=hf_scsi_mmcopcode;
- cdb_vals=scsi_mmc_val;
- break;
- case SCSI_DEV_SSC:
- hf_opcode=hf_scsi_sscopcode;
- cdb_vals=scsi_ssc2_val;
- break;
- case SCSI_DEV_SMC:
- hf_opcode=hf_scsi_smcopcode;
- cdb_vals=scsi_smc2_val;
- break;
- default:
- hf_opcode=hf_scsi_spcopcode;
- cdb_vals=scsi_spc2_val;
- break;
- }
+ 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, csdata->cdb_vals, "Unknown"), itl->cmdset);
+ PROTO_ITEM_SET_GENERATED(ti);
if(itlq && itlq->scsi_opcode!=0xffff){
- ti=proto_tree_add_uint(scsi_tree, hf_opcode, tvb, 0, 0, itlq->scsi_opcode);
+ ti=proto_tree_add_uint(scsi_tree, csdata->hf_opcode, tvb, 0, 0, itlq->scsi_opcode);
PROTO_ITEM_SET_GENERATED(ti);
}
}
@@ -6414,8 +6300,6 @@ dissect_scsi_snsinfo (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
old_proto=pinfo->current_proto;
pinfo->current_proto="SCSI";
- scsi_end_task (pinfo);
-
if (tree) {
ti = proto_tree_add_protocol_format (tree, proto_scsi, tvb, offset,
snslen, "SCSI: SNS Info");
@@ -6437,16 +6321,6 @@ dissect_scsi_snsinfo (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
}
-/* 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;
-
static scsi_cdb_table_t spc[256] = {
/*SPC 0x00*/{dissect_spc3_testunitready},
/*SPC 0x01*/{NULL},
@@ -7751,22 +7625,23 @@ dissect_scsi_cdb (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
proto_tree *scsi_tree = NULL;
guint8 opcode;
scsi_device_type devtype;
- scsi_cmnd_type cmd = 0; /* 0 is undefined type */
const gchar *valstr;
scsi_task_data_t *cdata;
- scsi_cdb_table_t *cdb_table=NULL;
- const value_string *cdb_vals = NULL;
- int hf_opcode=-1;
const char *old_proto;
+ cmdset_t *csdata;
+
old_proto=pinfo->current_proto;
pinfo->current_proto="SCSI";
- opcode = tvb_get_guint8 (tvb, offset);
- if(itlq){
- itlq->scsi_opcode=opcode;
+ if(!itlq){
+ g_assert_not_reached();
}
+ opcode = tvb_get_guint8 (tvb, offset);
+ itlq->scsi_opcode=opcode;
+ csdata=get_cmdset_data(itlq, itl);
+
if (devtype_arg != SCSI_DEV_UNKNOWN) {
devtype = devtype_arg;
} else {
@@ -7778,60 +7653,7 @@ dissect_scsi_cdb (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
}
if ((valstr = match_strval (opcode, scsi_spc2_val)) == NULL) {
- /*
- * This isn't a generic command that applies to all SCSI
- * device types; try to interpret it based on what we deduced,
- * or were told, the device type is.
- *
- * Right now, the only choices are SBC or SSC. If we ever expand
- * this to decode other device types, this piece of code needs to
- * be modified.
- */
- switch (devtype) {
- case SCSI_DEV_SBC:
- valstr = match_strval (opcode, scsi_sbc2_val);
- cmd = SCSI_CMND_SBC2;
- cdb_table=sbc;
- cdb_vals=scsi_sbc2_val;
- hf_opcode=hf_scsi_sbcopcode;
- break;
-
- case SCSI_DEV_CDROM:
- valstr = match_strval (opcode, scsi_mmc_val);
- cmd = SCSI_CMND_MMC;
- cdb_table=mmc;
- cdb_vals=scsi_mmc_val;
- hf_opcode=hf_scsi_mmcopcode;
- break;
-
- case SCSI_DEV_SSC:
- valstr = match_strval (opcode, scsi_ssc2_val);
- cmd = SCSI_CMND_SSC2;
- cdb_table=ssc;
- cdb_vals=scsi_ssc2_val;
- hf_opcode=hf_scsi_sscopcode;
- break;
-
- case SCSI_DEV_SMC:
- valstr = match_strval (opcode, scsi_smc2_val);
- cmd = SCSI_CMND_SMC2;
- cdb_table=smc;
- cdb_vals=scsi_smc2_val;
- hf_opcode=hf_scsi_smcopcode;
- break;
-
- default:
- cmd = SCSI_CMND_SPC2;
- cdb_table=spc;
- cdb_vals=scsi_spc2_val;
- hf_opcode=hf_scsi_spcopcode;
- break;
- }
- } else {
- cmd = SCSI_CMND_SPC2;
- cdb_table=spc;
- cdb_vals=scsi_spc2_val;
- hf_opcode=hf_scsi_spcopcode;
+ valstr = match_strval(opcode, csdata->cdb_vals);
}
if (check_col (pinfo->cinfo, COL_INFO)) {
@@ -7844,23 +7666,15 @@ dissect_scsi_cdb (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
col_set_fence(pinfo->cinfo, COL_INFO);
}
- cdata = scsi_new_task (pinfo);
-
- if (cdata) {
- cdata->cmd = cmd;
- cdata->flags = 0;
- cdata->cdb_table = cdb_table;
- cdata->cdb_vals = cdb_vals;
- cdata->alloc_len=0;
- cdata->itl=itl;
- cdata->itlq=itlq;
- }
+ cdata = ep_alloc(sizeof(scsi_task_data_t));
+ cdata->itl=itl;
+ cdata->itlq=itlq;
if (tree) {
ti = proto_tree_add_protocol_format (tree, proto_scsi, tvb, 0,
-1, "SCSI CDB %s",
val_to_str (opcode,
- cdb_vals,
+ csdata->cdb_vals,
"0x%02x")
);
scsi_tree = proto_item_add_subtree (ti, ett_scsi);
@@ -7870,7 +7684,7 @@ dissect_scsi_cdb (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
if (valstr != NULL) {
- proto_tree_add_uint_format (scsi_tree, hf_opcode, tvb,
+ proto_tree_add_uint_format (scsi_tree, csdata->hf_opcode, tvb,
offset, 1,
tvb_get_guint8 (tvb, offset),
"Opcode: %s (0x%02x)", valstr,
@@ -7880,11 +7694,8 @@ dissect_scsi_cdb (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
}
}
- /*
- All commandsets support SPC?
- */
- if(cdb_table && cdb_table[opcode].func){
- cdb_table[opcode].func(tvb, pinfo, scsi_tree, offset+1,
+ if(csdata->cdb_table[opcode].func){
+ csdata->cdb_table[opcode].func(tvb, pinfo, scsi_tree, offset+1,
TRUE, TRUE, 0, cdata);
} else if(spc[opcode].func){
spc[opcode].func(tvb, pinfo, scsi_tree, offset+1,
@@ -7908,6 +7719,7 @@ dissect_scsi_payload (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
scsi_task_data_t *cdata = NULL;
int payload_len;
const char *old_proto;
+ cmdset_t *csdata;
if(!itlq){
/* we have no record of this exchange and so we can't dissect the
@@ -7917,17 +7729,12 @@ dissect_scsi_payload (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
}
payload_len=tvb_length(tvb);
- cdata = scsi_find_task (pinfo);
-
- if (!cdata) {
- /* we have no record of this exchange and so we can't dissect the
- * payload
- */
- return;
- }
+ cdata = ep_alloc(sizeof(scsi_task_data_t));
cdata->itl=itl;
cdata->itlq=itlq;
+ csdata=get_cmdset_data(itlq, itl);
+
old_proto=pinfo->current_proto;
pinfo->current_proto="SCSI";
@@ -7939,7 +7746,7 @@ dissect_scsi_payload (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
payload_len,
"SCSI Payload (%s %s)",
val_to_str (opcode,
- cdata->cdb_vals,
+ csdata->cdb_vals,
"0x%02x"),
isreq ? "Request" : "Response");
scsi_tree = proto_item_add_subtree (ti, ett_scsi);
@@ -7950,7 +7757,7 @@ dissect_scsi_payload (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
"SCSI: Data %s LUN: 0x%02x (%s %s) ",
isreq ? "Out" : "In",
itlq->lun,
- val_to_str (opcode, cdata->cdb_vals, "0x%02x"),
+ val_to_str (opcode, csdata->cdb_vals, "0x%02x"),
isreq ? "Request" : "Response");
col_set_fence(pinfo->cinfo, COL_INFO);
@@ -7960,44 +7767,13 @@ dissect_scsi_payload (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
ti=proto_tree_add_uint(scsi_tree, hf_scsi_lun, tvb, 0, 0, itlq->lun);
PROTO_ITEM_SET_GENERATED(ti);
- switch(cdata->cmd){
- case SCSI_DEV_SBC:
- ti=proto_tree_add_uint_format (scsi_tree, hf_scsi_sbcopcode, tvb,
- offset, 0, opcode,
- "Opcode: %s (0x%02x)",
- val_to_str (opcode, cdata->cdb_vals,
- "0x%02x"),
- opcode);
- PROTO_ITEM_SET_GENERATED(ti);
- break;
- case SCSI_DEV_CDROM:
- ti=proto_tree_add_uint_format (scsi_tree, hf_scsi_mmcopcode, tvb,
- offset, 0, opcode,
- "Opcode: %s (0x%02x)",
- val_to_str (opcode, cdata->cdb_vals,
- "0x%02x"),
- opcode);
- PROTO_ITEM_SET_GENERATED(ti);
- break;
- case SCSI_DEV_SSC:
- ti=proto_tree_add_uint_format (scsi_tree, hf_scsi_sscopcode, tvb,
- offset, 0, opcode,
- "Opcode: %s (0x%02x)",
- val_to_str (opcode, cdata->cdb_vals,
- "0x%02x"),
- opcode);
- PROTO_ITEM_SET_GENERATED(ti);
- break;
- case SCSI_DEV_SMC:
- ti=proto_tree_add_uint_format (scsi_tree, hf_scsi_smcopcode, tvb,
+ ti=proto_tree_add_uint_format(scsi_tree, csdata->hf_opcode, tvb,
offset, 0, opcode,
"Opcode: %s (0x%02x)",
- val_to_str (opcode, cdata->cdb_vals,
+ val_to_str(opcode, csdata->cdb_vals,
"0x%02x"),
opcode);
- PROTO_ITEM_SET_GENERATED(ti);
- break;
- }
+ PROTO_ITEM_SET_GENERATED(ti);
if (tree == NULL) {
/*
@@ -8018,8 +7794,8 @@ dissect_scsi_payload (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
/*
All commandsets support SPC?
*/
- if(cdata->cdb_table && (cdata->cdb_table)[opcode].func){
- (cdata->cdb_table)[opcode].func(tvb, pinfo, scsi_tree, offset,
+ if(csdata->cdb_table && (csdata->cdb_table)[opcode].func){
+ (csdata->cdb_table)[opcode].func(tvb, pinfo, scsi_tree, offset,
isreq, FALSE, payload_len, cdata);
} else if(spc[opcode].func){
spc[opcode].func(tvb, pinfo, scsi_tree, offset,
@@ -8032,6 +7808,57 @@ dissect_scsi_payload (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
pinfo->current_proto=old_proto;
}
+static cmdset_t *
+get_cmdset_data(itlq_nexus_t *itlq, itl_nexus_t *itl)
+{
+ cmdset_t *csdata;
+ guint8 cmdset;
+
+ /* we must have an itlq structure */
+ if(!itlq){
+ g_assert_not_reached();
+ }
+
+ if(itl && itl->cmdset!=0xff){
+ cmdset=itl->cmdset;
+ } else {
+ cmdset=scsi_def_devtype;
+ }
+
+ csdata=ep_alloc(sizeof(cmdset_t));
+
+ switch(cmdset){
+ case SCSI_DEV_SBC:
+ csdata->hf_opcode=hf_scsi_sbcopcode;
+ csdata->cdb_vals=scsi_sbc2_val;
+ csdata->cdb_table=sbc;
+ break;
+ case SCSI_DEV_CDROM:
+ csdata->hf_opcode=hf_scsi_mmcopcode;
+ csdata->cdb_vals=scsi_mmc_val;
+ csdata->cdb_table=mmc;
+ break;
+ case SCSI_DEV_SSC:
+ csdata->hf_opcode=hf_scsi_sscopcode;
+ csdata->cdb_vals=scsi_ssc2_val;
+ csdata->cdb_table=ssc;
+ break;
+ case SCSI_DEV_SMC:
+ csdata->hf_opcode=hf_scsi_smcopcode;
+ csdata->cdb_vals=scsi_smc2_val;
+ csdata->cdb_table=smc;
+ break;
+ default:
+ csdata->hf_opcode=hf_scsi_spcopcode;
+ csdata->cdb_vals=scsi_spc2_val;
+ csdata->cdb_table=spc;
+ break;
+ }
+
+ return csdata;
+}
+
+
void
proto_register_scsi (void)
{
@@ -8827,7 +8654,6 @@ proto_register_scsi (void)
/* Required function calls to register the header fields and subtrees used */
proto_register_field_array(proto_scsi, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
- register_init_routine (&scsi_init_protocol);
data_handle = find_dissector ("data");
/* add preferences to decode SCSI message */
diff --git a/epan/dissectors/packet-scsi.h b/epan/dissectors/packet-scsi.h
index 0a0daec051..b698673620 100644
--- a/epan/dissectors/packet-scsi.h
+++ b/epan/dissectors/packet-scsi.h
@@ -69,15 +69,4 @@ void dissect_scsi_payload (tvbuff_t *, packet_info *, proto_tree *,
gboolean, itlq_nexus_t *, itl_nexus_t *);
void dissect_scsi_snsinfo (tvbuff_t *, packet_info *, proto_tree *, guint, guint, guint16);
-/*
- * Private data to be supplied to those functions via "pinfo->private_data";
- * the structure contains a 32-bit conversation ID and a 32-bit task
- * ID, where the former identifies a conversation between initiator and
- * target and the latter identifies a SCSI task within that conversation.
- */
-typedef struct {
- guint32 conv_id;
- guint32 task_id;
-} scsi_task_id_t;
-
#endif