diff options
Diffstat (limited to 'epan/dissectors')
-rw-r--r-- | epan/dissectors/packet-fcp.c | 2 | ||||
-rw-r--r-- | epan/dissectors/packet-iscsi.c | 183 | ||||
-rw-r--r-- | epan/dissectors/packet-ndmp.c | 1 | ||||
-rw-r--r-- | epan/dissectors/packet-scsi.c | 39 | ||||
-rw-r--r-- | epan/dissectors/packet-scsi.h | 2 |
5 files changed, 123 insertions, 104 deletions
diff --git a/epan/dissectors/packet-fcp.c b/epan/dissectors/packet-fcp.c index c3f4290982..fd65f957ef 100644 --- a/epan/dissectors/packet-fcp.c +++ b/epan/dissectors/packet-fcp.c @@ -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 */ diff --git a/epan/dissectors/packet-iscsi.c b/epan/dissectors/packet-iscsi.c index 34696ff5c1..c0f401adde 100644 --- a/epan/dissectors/packet-iscsi.c +++ b/epan/dissectors/packet-iscsi.c @@ -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); - } - 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; - } + cdata->scsi_ed.lun=lun; + cdata->scsi_ed.first_exchange_frame=pinfo->fd->num; + + /* 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); } } diff --git a/epan/dissectors/packet-ndmp.c b/epan/dissectors/packet-ndmp.c index bdae132fea..aecd9ed011 100644 --- a/epan/dissectors/packet-ndmp.c +++ b/epan/dissectors/packet-ndmp.c @@ -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> diff --git a/epan/dissectors/packet-scsi.c b/epan/dissectors/packet-scsi.c index a3b3e6b1f2..dfb531d248 100644 --- a/epan/dissectors/packet-scsi.c +++ b/epan/dissectors/packet-scsi.c @@ -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 */ diff --git a/epan/dissectors/packet-scsi.h b/epan/dissectors/packet-scsi.h index 00c64a48ff..89d5f3bae9 100644 --- a/epan/dissectors/packet-scsi.h +++ b/epan/dissectors/packet-scsi.h @@ -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); |