aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-iscsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/dissectors/packet-iscsi.c')
-rw-r--r--epan/dissectors/packet-iscsi.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/epan/dissectors/packet-iscsi.c b/epan/dissectors/packet-iscsi.c
index 0cbdb29b04..c7ce1c9f09 100644
--- a/epan/dissectors/packet-iscsi.c
+++ b/epan/dissectors/packet-iscsi.c
@@ -212,7 +212,8 @@ static gint ett_iscsi_ISID = -1;
/* this structure contains session wide state for a specific tcp conversation */
typedef struct _iscsi_session_t {
guint32 header_digest;
- se_tree_t *exchanges; /* indexed by ITT */
+ se_tree_t *itlq; /* indexed by ITT */
+ se_tree_t *itl; /* indexed by LUN */
} iscsi_session_t;
@@ -742,6 +743,7 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
guint16 lun=0xffff;
guint immediate_data_length=0;
guint immediate_data_offset=0;
+ itl_nexus_t *itl=NULL;
if(paddedDataSegmentLength & 3)
paddedDataSegmentLength += 4 - (paddedDataSegmentLength & 3);
@@ -751,7 +753,7 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
col_set_str(pinfo->cinfo, COL_PROTOCOL, "iSCSI");
/* XXX we need a way to handle replayed iscsi itt here */
- cdata=(iscsi_conv_data_t *)se_tree_lookup32(iscsi_session->exchanges, tvb_get_ntohl(tvb, offset+16));
+ cdata=(iscsi_conv_data_t *)se_tree_lookup32(iscsi_session->itlq, tvb_get_ntohl(tvb, offset+16));
if(!cdata){
cdata = se_alloc (sizeof(iscsi_conv_data_t));
cdata->itlq.lun=0xffff;
@@ -762,7 +764,7 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
cdata->data_in_frame=0;
cdata->data_out_frame=0;
- se_tree_insert32(iscsi_session->exchanges, tvb_get_ntohl(tvb, offset+16), cdata);
+ se_tree_insert32(iscsi_session->itlq, tvb_get_ntohl(tvb, offset+16), cdata);
}
if (opcode == ISCSI_OPCODE_SCSI_RESPONSE ||
@@ -819,6 +821,14 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
cdata->itlq.lun=lun;
cdata->itlq.first_exchange_frame=pinfo->fd->num;
+ itl=(itl_nexus_t *)se_tree_lookup32(iscsi_session->itl, lun);
+ if(!itl){
+ itl=se_alloc(sizeof(itl_nexus_t));
+ itl->cmdset=0xff;
+ se_tree_insert32(iscsi_session->itl, lun, itl);
+ }
+
+
/* The SCSI protocol uses this as the key to detect a
* SCSI-level conversation. */
task_key.conv_id = (int)iscsi_session;
@@ -829,6 +839,12 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
pinfo->private_data = NULL;
}
+
+ if(!itl){
+ itl=(itl_nexus_t *)se_tree_lookup32(iscsi_session->itl, cdata->itlq.lun);
+ }
+
+
if (check_col(pinfo->cinfo, COL_INFO)) {
if (opcode != ISCSI_OPCODE_SCSI_COMMAND) {
@@ -1494,7 +1510,7 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
if(tvb_rlen>16)
tvb_rlen=16;
cdb_tvb=tvb_new_subset(tvb, cdb_offset, tvb_len, tvb_rlen);
- dissect_scsi_cdb (cdb_tvb, pinfo, tree, SCSI_DEV_UNKNOWN, lun);
+ dissect_scsi_cdb(cdb_tvb, pinfo, tree, SCSI_DEV_UNKNOWN, lun, itl);
/* we dont want the immediata below to overwrite our CDB info */
if (check_col(pinfo->cinfo, COL_INFO)) {
col_set_fence(pinfo->cinfo, COL_INFO);
@@ -1511,7 +1527,7 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
data_tvb=tvb_new_subset(tvb, immediate_data_offset, tvb_len, tvb_rlen);
dissect_scsi_payload (data_tvb, pinfo, tree,
TRUE,
- lun );
+ lun, itl);
}
}
else if (opcode == ISCSI_OPCODE_SCSI_RESPONSE) {
@@ -1541,7 +1557,7 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
}
}
else {
- dissect_scsi_rsp(tvb, pinfo, tree, &cdata->itlq, scsi_status);
+ dissect_scsi_rsp(tvb, pinfo, tree, &cdata->itlq, itl, scsi_status);
}
}
else if ((opcode == ISCSI_OPCODE_SCSI_DATA_IN) ||
@@ -1559,11 +1575,11 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
data_tvb=tvb_new_subset(tvb, offset, tvb_len, tvb_rlen);
dissect_scsi_payload (data_tvb, pinfo, tree,
(opcode==ISCSI_OPCODE_SCSI_DATA_OUT),
- cdata->itlq.lun);
+ cdata->itlq.lun, itl);
}
if(S_bit){
- dissect_scsi_rsp(tvb, pinfo, tree, &cdata->itlq, scsi_status);
+ dissect_scsi_rsp(tvb, pinfo, tree, &cdata->itlq, itl, scsi_status);
}
}
@@ -1691,7 +1707,8 @@ dissect_iscsi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean chec
if(!iscsi_session){
iscsi_session=se_alloc(sizeof(iscsi_session_t));
iscsi_session->header_digest=ISCSI_HEADER_DIGEST_AUTO;
- iscsi_session->exchanges=se_tree_create_non_persistent(SE_TREE_TYPE_RED_BLACK, "iSCSI Exchanges");
+ iscsi_session->itlq=se_tree_create_non_persistent(SE_TREE_TYPE_RED_BLACK, "iSCSI ITLQ");
+ iscsi_session->itl=se_tree_create_non_persistent(SE_TREE_TYPE_RED_BLACK, "iSCSI ITL");
conversation_add_proto_data(conversation, proto_iscsi, iscsi_session);
/* DataOut PDUs are often mistaken by DCERPC heuristics to be