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
This commit is contained in:
Ronnie Sahlberg 2006-04-21 11:08:24 +00:00
parent 73ded54b05
commit 60e65f4869
14 changed files with 110 additions and 183 deletions

View File

@ -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));

View File

@ -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_ */

View File

@ -43,6 +43,7 @@
#include <epan/packet.h>
#include <epan/etypes.h>
#include <epan/conversation.h>
#include "packet-fc.h"
#include "packet-fcct.h"

View File

@ -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"

View File

@ -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);

View File

@ -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"

View File

@ -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

View File

@ -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"

View File

@ -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;
}

View File

@ -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.
*/
itl_nexus_t *itl;
} 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;
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){
nstime_t delta_time;
ti=proto_tree_add_uint(scsi_tree, hf_scsi_request_frame, tvb, 0, 0, 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);
nstime_delta(&delta_time, &pinfo->fd->abs_ts, &scsi_ed->fc_time);
}
if(itlq->first_exchange_frame){
nstime_t delta_time;
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, &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";

View File

@ -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);
/*

View File

@ -39,6 +39,7 @@
#include <epan/value_string.h>
#include <epan/tap.h>
#include <epan/conversation.h>
#include <epan/dissectors/packet-fc.h>
#include "../register.h"
#include "../timestats.h"

View File

@ -39,6 +39,7 @@
#include <epan/tap.h>
#include "../register.h"
#include "hostlist_table.h"
#include <epan/conversation.h>
#include <epan/dissectors/packet-fc.h>

View File

@ -38,6 +38,7 @@
#include <epan/emem.h>
#include <epan/addr_resolv.h>
#include <epan/tap.h>
#include <epan/conversation.h>
#include <epan/stat_cmd_args.h>
#include "register.h"
#include <epan/dissectors/packet-ip.h>