aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/dissectors/packet-scsi.c')
-rw-r--r--epan/dissectors/packet-scsi.c90
1 files changed, 66 insertions, 24 deletions
diff --git a/epan/dissectors/packet-scsi.c b/epan/dissectors/packet-scsi.c
index 77e879eca7..76d10a7be6 100644
--- a/epan/dissectors/packet-scsi.c
+++ b/epan/dissectors/packet-scsi.c
@@ -40,10 +40,10 @@
* 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, itl_nexus_t *);
+ * guint, itlq_nexus_t *, 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, itl_nexus_t *);
+ * gboolean, itlq_nexusu_t *, 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.
@@ -1656,9 +1656,7 @@ static gint scsi_def_devtype = SCSI_DEV_SBC;
* of the response data depends on data from the command.
*/
typedef struct _scsi_task_data {
- guint32 opcode;
scsi_cmnd_type cmd;
- scsi_device_type devtype;
guint16 flags;
struct _scsi_cdb_table_t *cdb_table;
const value_string *cdb_vals;
@@ -1667,6 +1665,7 @@ typedef struct _scsi_task_data {
*/
+ itlq_nexus_t *itlq;
itl_nexus_t *itl;
} scsi_task_data_t;
@@ -2387,7 +2386,7 @@ dissect_scsi_blockdescs (tvbuff_t *tvb, packet_info *pinfo _U_,
tvb_get_ntohl (tvb, offset));
offset += 4;
} else {
- if (cdata->devtype == SCSI_DEV_SBC) {
+ if (cdata->itl->cmdset == SCSI_DEV_SBC) {
if(tvb_length_remaining(tvb, offset)<4)
return;
proto_tree_add_text (scsi_tree, tvb, offset, 4, "No. of Blocks: %u",
@@ -3164,7 +3163,7 @@ dissect_spc3_modeselect6 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
if (payload_len < 1)
return;
- switch (cdata->devtype) {
+ switch (cdata->itl->cmdset) {
case SCSI_DEV_SBC:
proto_tree_add_text (tree, tvb, offset, 1, "Medium Type: %s",
@@ -3206,7 +3205,7 @@ dissect_spc3_modeselect6 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
/* offset points to the start of the mode page */
while ((payload_len > 0) && tvb_bytes_exist (tvb, offset, 2)) {
- plen = dissect_scsi_modepage (tvb, pinfo, tree, offset, cdata->devtype);
+ plen = dissect_scsi_modepage (tvb, pinfo, tree, offset, cdata->itl->cmdset);
offset += plen;
payload_len -= plen;
}
@@ -3263,7 +3262,9 @@ dissect_spc3_modeselect10 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
if (payload_len < 1)
return;
- switch (cdata->devtype) {
+ if(!cdata->itl)
+ return;
+ switch (cdata->itl->cmdset) {
case SCSI_DEV_SBC:
proto_tree_add_text (tree, tvb, offset, 1, "Medium Type: %s",
@@ -3312,7 +3313,7 @@ dissect_spc3_modeselect10 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
/* offset points to the start of the mode page */
while ((payload_len > 0) && tvb_bytes_exist (tvb, offset, 2)) {
- plen = dissect_scsi_modepage (tvb, pinfo, tree, offset, cdata->devtype);
+ plen = dissect_scsi_modepage (tvb, pinfo, tree, offset, cdata->itl->cmdset);
offset += plen;
payload_len -= plen;
}
@@ -3340,7 +3341,7 @@ dissect_scsi_pagecode (tvbuff_t *tvb, packet_info *pinfo _U_,
* device types; try to interpret it based on what we deduced,
* or were told, the device type is.
*/
- switch (cdata->devtype) {
+ switch (cdata->itl->cmdset) {
case SCSI_DEV_SBC:
hf_pagecode = hf_scsi_sbcpagecode;
break;
@@ -3453,7 +3454,7 @@ dissect_spc3_modesense6 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
/* offset points to the start of the mode page */
while ((tot_len > 0) && tvb_bytes_exist (tvb, offset, 2)) {
- plen = dissect_scsi_modepage (tvb, pinfo, tree, offset, cdata->devtype);
+ plen = dissect_scsi_modepage (tvb, pinfo, tree, offset, cdata->itl->cmdset);
offset += plen;
tot_len -= plen;
}
@@ -3553,7 +3554,7 @@ dissect_spc3_modesense10 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
/* offset points to the start of the mode page */
while ((tot_len > 0) && tvb_bytes_exist (tvb, offset, 2)) {
- plen = dissect_scsi_modepage (tvb, pinfo, tree, offset, cdata->devtype);
+ plen = dissect_scsi_modepage (tvb, pinfo, tree, offset, cdata->itl->cmdset);
offset += plen;
tot_len -= plen;
}
@@ -6348,8 +6349,39 @@ 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;
+
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);
+
+ 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;
+ }
+
+ if(itlq && itlq->scsi_opcode!=0xffff){
+ ti=proto_tree_add_uint(scsi_tree, hf_opcode, tvb, 0, 0, itlq->scsi_opcode);
+ PROTO_ITEM_SET_GENERATED(ti);
+ }
}
if(itlq->first_exchange_frame){
@@ -7712,7 +7744,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, itl_nexus_t *itl)
+ gint devtype_arg, itlq_nexus_t *itlq, itl_nexus_t *itl)
{
int offset = 0;
proto_item *ti;
@@ -7731,6 +7763,9 @@ dissect_scsi_cdb (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
pinfo->current_proto="SCSI";
opcode = tvb_get_guint8 (tvb, offset);
+ if(itlq){
+ itlq->scsi_opcode=opcode;
+ }
if (devtype_arg != SCSI_DEV_UNKNOWN) {
devtype = devtype_arg;
@@ -7801,9 +7836,9 @@ dissect_scsi_cdb (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
if (check_col (pinfo->cinfo, COL_INFO)) {
if (valstr != NULL) {
- col_add_fstr (pinfo->cinfo, COL_INFO, "SCSI: %s LUN: 0x%02x ", valstr, lun);
+ col_add_fstr (pinfo->cinfo, COL_INFO, "SCSI: %s LUN: 0x%02x ", valstr, itlq->lun);
} else {
- col_add_fstr (pinfo->cinfo, COL_INFO, "SCSI Command: 0x%02x LUN:0x%02x ", opcode, lun);
+ col_add_fstr (pinfo->cinfo, COL_INFO, "SCSI Command: 0x%02x LUN:0x%02x ", opcode, itlq->lun);
}
/* make sure no one will overwrite this in the info column */
col_set_fence(pinfo->cinfo, COL_INFO);
@@ -7812,14 +7847,13 @@ dissect_scsi_cdb (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
cdata = scsi_new_task (pinfo);
if (cdata) {
- cdata->opcode = opcode;
cdata->cmd = cmd;
- cdata->devtype = devtype;
cdata->flags = 0;
cdata->cdb_table = cdb_table;
cdata->cdb_vals = cdb_vals;
cdata->alloc_len=0;
cdata->itl=itl;
+ cdata->itlq=itlq;
}
if (tree) {
@@ -7831,7 +7865,7 @@ dissect_scsi_cdb (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
);
scsi_tree = proto_item_add_subtree (ti, ett_scsi);
- ti=proto_tree_add_uint(scsi_tree, hf_scsi_lun, tvb, 0, 0, lun);
+ ti=proto_tree_add_uint(scsi_tree, hf_scsi_lun, tvb, 0, 0, itlq->lun);
PROTO_ITEM_SET_GENERATED(ti);
@@ -7864,17 +7898,24 @@ 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, itl_nexus_t *itl)
+ gboolean isreq, itlq_nexus_t *itlq, itl_nexus_t *itl)
{
int offset=0;
proto_item *ti;
proto_tree *scsi_tree = NULL;
guint8 opcode = 0xFF;
- scsi_device_type devtype;
+ scsi_device_type devtype=0xff;
scsi_task_data_t *cdata = NULL;
int payload_len;
const char *old_proto;
+ if(!itlq){
+ /* we have no record of this exchange and so we can't dissect the
+ * payload
+ */
+ return;
+ }
+
payload_len=tvb_length(tvb);
cdata = scsi_find_task (pinfo);
@@ -7885,12 +7926,13 @@ dissect_scsi_payload (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
return;
}
cdata->itl=itl;
+ cdata->itlq=itlq;
old_proto=pinfo->current_proto;
pinfo->current_proto="SCSI";
- opcode = cdata->opcode;
- devtype = cdata->devtype;
+ opcode = cdata->itlq->scsi_opcode;
+ devtype = cdata->itl->cmdset;
if (tree) {
ti = proto_tree_add_protocol_format (tree, proto_scsi, tvb, offset,
@@ -7907,7 +7949,7 @@ dissect_scsi_payload (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
col_add_fstr (pinfo->cinfo, COL_INFO,
"SCSI: Data %s LUN: 0x%02x (%s %s) ",
isreq ? "Out" : "In",
- lun,
+ itlq->lun,
val_to_str (opcode, cdata->cdb_vals, "0x%02x"),
isreq ? "Request" : "Response");
@@ -7915,7 +7957,7 @@ 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, lun);
+ ti=proto_tree_add_uint(scsi_tree, hf_scsi_lun, tvb, 0, 0, itlq->lun);
PROTO_ITEM_SET_GENERATED(ti);
switch(cdata->cmd){