diff options
-rw-r--r-- | epan/dissectors/packet-fc.c | 2 | ||||
-rw-r--r-- | epan/dissectors/packet-fc.h | 4 | ||||
-rw-r--r-- | epan/dissectors/packet-fcp.c | 18 | ||||
-rw-r--r-- | epan/dissectors/packet-iscsi.c | 17 | ||||
-rw-r--r-- | epan/dissectors/packet-ndmp.c | 13 | ||||
-rw-r--r-- | epan/dissectors/packet-scsi.c | 436 | ||||
-rw-r--r-- | epan/dissectors/packet-scsi.h | 11 |
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 |