make dissect_scsi_rsp() take an exchange structure as parameter instead of just a lun.

this finally allows us to have scsi.time  for scsi transactions   but we need to cleanup and refactor the other three scsi entrypoints before we should implement scsi srt    to make the other three also take an exchange data structure as parameter from their transports (and get rid of the pinfo->private_data )


svn path=/trunk/; revision=17838
This commit is contained in:
Ronnie Sahlberg 2006-04-07 10:15:15 +00:00
parent 5683612f36
commit 9481eac669
5 changed files with 122 additions and 103 deletions

View File

@ -522,7 +522,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->fced->lun, tvb_get_guint8(tvb, offset));
dissect_scsi_rsp(tvb, pinfo, parent_tree, fchdr->fced, tvb_get_guint8(tvb, offset));
offset++;
/* residual count */

View File

@ -750,6 +750,21 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
if (check_col(pinfo->cinfo, COL_PROTOCOL))
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));
if(!cdata){
cdata = se_alloc (sizeof(iscsi_conv_data_t));
cdata->scsi_ed.lun=0xffff;
cdata->scsi_ed.scsi_opcode=0xffff;
cdata->scsi_ed.fc_time = pinfo->fd->abs_ts;
cdata->scsi_ed.first_exchange_frame=0;
cdata->scsi_ed.last_exchange_frame=0;
cdata->data_in_frame=0;
cdata->data_out_frame=0;
se_tree_insert32(iscsi_session->exchanges, tvb_get_ntohl(tvb, offset+16), cdata);
}
if (opcode == ISCSI_OPCODE_SCSI_RESPONSE ||
opcode == ISCSI_OPCODE_SCSI_DATA_IN) {
scsi_status = tvb_get_guint8 (tvb, offset+3);
@ -758,33 +773,26 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
if ((opcode == ISCSI_OPCODE_SCSI_RESPONSE) ||
(opcode == ISCSI_OPCODE_SCSI_DATA_IN) ||
(opcode == ISCSI_OPCODE_SCSI_DATA_OUT)) {
cdata=(iscsi_conv_data_t *)se_tree_lookup32(iscsi_session->exchanges, tvb_get_ntohl(tvb, offset+16));
/* first time we see this packet. check if we can find the request */
if(cdata){
switch(opcode){
case ISCSI_OPCODE_SCSI_RESPONSE:
switch(opcode){
case ISCSI_OPCODE_SCSI_RESPONSE:
cdata->scsi_ed.last_exchange_frame=pinfo->fd->num;
break;
case ISCSI_OPCODE_SCSI_DATA_IN:
/* a bit ugly but we need to check the S bit here */
if(tvb_get_guint8(tvb, offset+1)&ISCSI_SCSI_DATA_FLAG_S){
cdata->scsi_ed.last_exchange_frame=pinfo->fd->num;
break;
case ISCSI_OPCODE_SCSI_DATA_IN:
/* a bit ugly but we need to check the S bit here */
if(tvb_get_guint8(tvb, offset+1)&ISCSI_SCSI_DATA_FLAG_S){
cdata->scsi_ed.last_exchange_frame=pinfo->fd->num;
}
cdata->data_in_frame=pinfo->fd->num;
break;
case ISCSI_OPCODE_SCSI_DATA_OUT:
cdata->data_out_frame=pinfo->fd->num;
break;
}
cdata->data_in_frame=pinfo->fd->num;
break;
case ISCSI_OPCODE_SCSI_DATA_OUT:
cdata->data_out_frame=pinfo->fd->num;
break;
}
if (cdata){
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;
}
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
@ -807,31 +815,15 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
} else {
lun=tvb_get_guint8(tvb,offset+9);
}
/* 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));
if(!cdata){
/* add this new transaction to the unmatched table */
cdata = se_alloc (sizeof(iscsi_conv_data_t));
cdata->scsi_ed.lun=lun;
cdata->scsi_ed.scsi_opcode=0xffff;
cdata->scsi_ed.fc_time = pinfo->fd->abs_ts;
cdata->scsi_ed.first_exchange_frame=pinfo->fd->num;
cdata->scsi_ed.last_exchange_frame=0;
cdata->data_in_frame=0;
cdata->data_out_frame=0;
se_tree_insert32(iscsi_session->exchanges, tvb_get_ntohl(tvb, offset+16), cdata);
}
cdata->scsi_ed.lun=lun;
cdata->scsi_ed.first_exchange_frame=pinfo->fd->num;
if (cdata){
/* 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;
}
/* 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;
@ -1434,56 +1426,54 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
/* handle request/response matching */
if (cdata){
switch(opcode){
case ISCSI_OPCODE_SCSI_RESPONSE:
if (cdata->scsi_ed.first_exchange_frame){
nstime_t delta_time;
proto_tree_add_uint(ti, hf_iscsi_request_frame, tvb, 0, 0, cdata->scsi_ed.first_exchange_frame);
nstime_delta(&delta_time, &pinfo->fd->abs_ts, &cdata->scsi_ed.fc_time);
proto_tree_add_time(ti, hf_iscsi_time, tvb, 0, 0, &delta_time);
}
if (cdata->data_in_frame)
proto_tree_add_uint(ti, hf_iscsi_data_in_frame, tvb, 0, 0, cdata->data_in_frame);
if (cdata->data_out_frame)
proto_tree_add_uint(ti, hf_iscsi_data_out_frame, tvb, 0, 0, cdata->data_out_frame);
break;
case ISCSI_OPCODE_SCSI_DATA_IN:
/* if we have phase collaps then we might have the
response embedded in the last DataIn segment */
if(!S_bit){
if (cdata->scsi_ed.first_exchange_frame)
proto_tree_add_uint(ti, hf_iscsi_request_frame, tvb, 0, 0, cdata->scsi_ed.first_exchange_frame);
if (cdata->scsi_ed.last_exchange_frame)
proto_tree_add_uint(ti, hf_iscsi_response_frame, tvb, 0, 0, cdata->scsi_ed.last_exchange_frame);
} else {
if (cdata->scsi_ed.first_exchange_frame){
nstime_t delta_time;
proto_tree_add_uint(ti, hf_iscsi_request_frame, tvb, 0, 0, cdata->scsi_ed.first_exchange_frame);
nstime_delta(&delta_time, &pinfo->fd->abs_ts, &cdata->scsi_ed.fc_time);
proto_tree_add_time(ti, hf_iscsi_time, tvb, 0, 0, &delta_time);
}
}
if (cdata->data_out_frame)
proto_tree_add_uint(ti, hf_iscsi_data_out_frame, tvb, 0, 0, cdata->data_out_frame);
break;
case ISCSI_OPCODE_SCSI_DATA_OUT:
switch(opcode){
case ISCSI_OPCODE_SCSI_RESPONSE:
if (cdata->scsi_ed.first_exchange_frame){
nstime_t delta_time;
proto_tree_add_uint(ti, hf_iscsi_request_frame, tvb, 0, 0, cdata->scsi_ed.first_exchange_frame);
nstime_delta(&delta_time, &pinfo->fd->abs_ts, &cdata->scsi_ed.fc_time);
proto_tree_add_time(ti, hf_iscsi_time, tvb, 0, 0, &delta_time);
}
if (cdata->data_in_frame)
proto_tree_add_uint(ti, hf_iscsi_data_in_frame, tvb, 0, 0, cdata->data_in_frame);
if (cdata->data_out_frame)
proto_tree_add_uint(ti, hf_iscsi_data_out_frame, tvb, 0, 0, cdata->data_out_frame);
break;
case ISCSI_OPCODE_SCSI_DATA_IN:
/* if we have phase collaps then we might have the
response embedded in the last DataIn segment */
if(!S_bit){
if (cdata->scsi_ed.first_exchange_frame)
proto_tree_add_uint(ti, hf_iscsi_request_frame, tvb, 0, 0, cdata->scsi_ed.first_exchange_frame);
if (cdata->data_in_frame)
proto_tree_add_uint(ti, hf_iscsi_data_in_frame, tvb, 0, 0, cdata->data_in_frame);
if (cdata->scsi_ed.last_exchange_frame)
proto_tree_add_uint(ti, hf_iscsi_response_frame, tvb, 0, 0, cdata->scsi_ed.last_exchange_frame);
break;
case ISCSI_OPCODE_SCSI_COMMAND:
if (cdata->data_in_frame)
proto_tree_add_uint(ti, hf_iscsi_data_in_frame, tvb, 0, 0, cdata->data_in_frame);
if (cdata->data_out_frame)
proto_tree_add_uint(ti, hf_iscsi_data_out_frame, tvb, 0, 0, cdata->data_out_frame);
if (cdata->scsi_ed.last_exchange_frame)
proto_tree_add_uint(ti, hf_iscsi_response_frame, tvb, 0, 0, cdata->scsi_ed.last_exchange_frame);
break;
} else {
if (cdata->scsi_ed.first_exchange_frame){
nstime_t delta_time;
proto_tree_add_uint(ti, hf_iscsi_request_frame, tvb, 0, 0, cdata->scsi_ed.first_exchange_frame);
nstime_delta(&delta_time, &pinfo->fd->abs_ts, &cdata->scsi_ed.fc_time);
proto_tree_add_time(ti, hf_iscsi_time, tvb, 0, 0, &delta_time);
}
}
if (cdata->data_out_frame)
proto_tree_add_uint(ti, hf_iscsi_data_out_frame, tvb, 0, 0, cdata->data_out_frame);
break;
case ISCSI_OPCODE_SCSI_DATA_OUT:
if (cdata->scsi_ed.first_exchange_frame)
proto_tree_add_uint(ti, hf_iscsi_request_frame, tvb, 0, 0, cdata->scsi_ed.first_exchange_frame);
if (cdata->data_in_frame)
proto_tree_add_uint(ti, hf_iscsi_data_in_frame, tvb, 0, 0, cdata->data_in_frame);
if (cdata->scsi_ed.last_exchange_frame)
proto_tree_add_uint(ti, hf_iscsi_response_frame, tvb, 0, 0, cdata->scsi_ed.last_exchange_frame);
break;
case ISCSI_OPCODE_SCSI_COMMAND:
if (cdata->data_in_frame)
proto_tree_add_uint(ti, hf_iscsi_data_in_frame, tvb, 0, 0, cdata->data_in_frame);
if (cdata->data_out_frame)
proto_tree_add_uint(ti, hf_iscsi_data_out_frame, tvb, 0, 0, cdata->data_out_frame);
if (cdata->scsi_ed.last_exchange_frame)
proto_tree_add_uint(ti, hf_iscsi_response_frame, tvb, 0, 0, cdata->scsi_ed.last_exchange_frame);
break;
}
@ -1546,13 +1536,12 @@ 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_snsinfo (data_tvb, pinfo, tree, 0,
tvb_len,
(guint16) (cdata?cdata->scsi_ed.lun:0xffff) );
cdata->scsi_ed.lun);
}
}
}
else {
dissect_scsi_rsp (tvb, pinfo, tree,
(guint16) (cdata?cdata->scsi_ed.lun:0xffff), scsi_status);
dissect_scsi_rsp(tvb, pinfo, tree, &cdata->scsi_ed, scsi_status);
}
}
else if ((opcode == ISCSI_OPCODE_SCSI_DATA_IN) ||
@ -1570,7 +1559,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),
(guint16) (cdata?cdata->scsi_ed.lun:0xffff) );
cdata->scsi_ed.lun);
}
if(S_bit){
dissect_scsi_rsp(tvb, pinfo, tree, &cdata->scsi_ed, scsi_status);
}
}

View File

@ -43,6 +43,7 @@
#include <epan/emem.h>
#include "packet-rpc.h"
#include "packet-tcp.h"
#include "packet-fc.h"
#include "packet-scsi.h"
#include "packet-frame.h"
#include <epan/prefs.h>

View File

@ -47,10 +47,10 @@
* 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 destroy the data structures associated with a
* 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 *, guint16,
* guint8);
* void dissect_scsi_rsp (tvbuff_t *, packet_info *, proto_tree *,
* fc_exchange_data *, 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,9 +88,13 @@
#include <epan/packet.h>
#include <epan/prefs.h>
#include <epan/emem.h>
#include "packet-fc.h"
#include "packet-scsi.h"
static int proto_scsi = -1;
static int hf_scsi_time = -1;
static int hf_scsi_request_frame = -1;
static int hf_scsi_response_frame = -1;
static int hf_scsi_lun = -1;
static int hf_scsi_status = -1;
static int hf_scsi_spcopcode = -1;
@ -6431,13 +6435,12 @@ dissect_smc2_readelementstatus (tvbuff_t *tvb, packet_info *pinfo,
void
dissect_scsi_rsp (tvbuff_t *tvb, packet_info *pinfo,
proto_tree *tree, guint16 lun, guint8 scsi_status)
proto_tree *tree, fc_exchange_data *scsi_ed, guint8 scsi_status)
{
proto_item *ti;
proto_tree *scsi_tree = NULL;
/* Nothing really to do here, just print some stuff passed to us
* and blow up the data structures for this SCSI task.
*/
if (tree) {
ti = proto_tree_add_protocol_format (tree, proto_scsi, tvb, 0,
@ -6445,12 +6448,22 @@ 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, lun);
ti=proto_tree_add_uint(scsi_tree, hf_scsi_lun, tvb, 0, 0, scsi_ed->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);
PROTO_ITEM_SET_GENERATED(ti);
nstime_delta(&delta_time, &pinfo->fd->abs_ts, &scsi_ed->fc_time);
ti=proto_tree_add_time(scsi_tree, hf_scsi_time, tvb, 0, 0, &delta_time);
PROTO_ITEM_SET_GENERATED(ti);
}
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)", 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)", scsi_ed->lun, val_to_str(scsi_status, scsi_status_val, "Unknown (0x%08x)"));
col_set_fence(pinfo->cinfo, COL_INFO);
}
@ -8851,6 +8864,18 @@ proto_register_scsi (void)
{ &hf_ssc3_locate16_loid,
{"Logical Identifier", "scsi.locate16.loid", FT_UINT64, BASE_DEC, NULL, 0x0,
"", HFILL}},
{ &hf_scsi_request_frame,
{ "Request in", "scsi.request_frame", FT_FRAMENUM, BASE_NONE, NULL, 0,
"The request to this transaction is in this frame", HFILL }},
{ &hf_scsi_time,
{ "Time from request", "scsi.time", FT_RELATIVE_TIME, BASE_NONE, NULL, 0,
"Time between the Command and the Response", HFILL }},
{ &hf_scsi_response_frame,
{ "Response in", "scsi.response_frame", FT_FRAMENUM, BASE_NONE, NULL, 0,
"The response to this transaction is in this frame", HFILL }},
};
/* Setup protocol subtree array */

View File

@ -64,7 +64,7 @@ extern const value_string scsi_status_val[];
*/
void dissect_scsi_cdb (tvbuff_t *, packet_info *, proto_tree *,
gint, guint16);
void dissect_scsi_rsp (tvbuff_t *, packet_info *, proto_tree *, guint16, guint8);
void dissect_scsi_rsp (tvbuff_t *, packet_info *, proto_tree *, fc_exchange_data *, guint8);
void dissect_scsi_payload (tvbuff_t *, packet_info *, proto_tree *,
gboolean, guint16);
void dissect_scsi_snsinfo (tvbuff_t *, packet_info *, proto_tree *, guint, guint, guint16);