diff options
author | Jaap Keuter <jaap.keuter@xs4all.nl> | 2009-10-17 10:19:18 +0000 |
---|---|---|
committer | Jaap Keuter <jaap.keuter@xs4all.nl> | 2009-10-17 10:19:18 +0000 |
commit | 80424e5ced9f0359fe3f6049369b6251783d9e0d (patch) | |
tree | b8696134b286ac447dbf080f8253e32053cbd7fa /epan/dissectors/packet-fcp.c | |
parent | 9c988fa8548f8d5eb2d31aa8699433c2356be984 (diff) | |
download | wireshark-80424e5ced9f0359fe3f6049369b6251783d9e0d.tar.gz |
From Joe Eykholt:
It would be nice to have dissection of the Fibre-Channel FCP
"Sequence retransmission request" (SRR) request.
This is like an FC ELS request, but it has FC type FCP, so it's
a little strange. It seemed like the best place to put it is in
packet-fcp.c but a slight hook is needed in packet-fc.c to
recognize that packet-fcp is the correct dissector.
svn path=/trunk/; revision=30587
Diffstat (limited to 'epan/dissectors/packet-fcp.c')
-rw-r--r-- | epan/dissectors/packet-fcp.c | 93 |
1 files changed, 85 insertions, 8 deletions
diff --git a/epan/dissectors/packet-fcp.c b/epan/dissectors/packet-fcp.c index e8212b1cae..e88095f105 100644 --- a/epan/dissectors/packet-fcp.c +++ b/epan/dissectors/packet-fcp.c @@ -48,6 +48,7 @@ #include "packet-scsi.h" #include "packet-fc.h" #include "packet-fcp.h" +#include "packet-fcels.h" /* Initialize the protocol and registered fields */ static int proto_fcp = -1; @@ -90,6 +91,10 @@ static int hf_fcp_rsp_flags_res_vld = -1; static int hf_fcp_request_in = -1; static int hf_fcp_response_in = -1; static int hf_fcp_time = -1; +static int hf_fcp_srr_op = -1; +static int hf_fcp_srr_ox_id = -1; +static int hf_fcp_srr_rx_id = -1; +static int hf_fcp_srr_r_ctl = -1; /* Initialize the subtree pointers */ static gint ett_fcp = -1; @@ -105,6 +110,8 @@ static dissector_handle_t data_handle; /* Information Categories based on lower 4 bits of R_CTL */ #define FCP_IU_DATA 0x1 +#define FCP_IU_UNSOL_CTL 0x2 +#define FCP_IU_SOL_CTL 0x3 #define FCP_IU_CONFIRM 0x3 #define FCP_IU_XFER_RDY 0x5 #define FCP_IU_CMD 0x6 @@ -112,6 +119,7 @@ static dissector_handle_t data_handle; static const value_string fcp_iu_val[] = { {FCP_IU_DATA , "FCP_DATA"}, + {FCP_IU_UNSOL_CTL , "Control"}, {FCP_IU_CONFIRM , "Confirm"}, {FCP_IU_XFER_RDY , "XFER_RDY"}, {FCP_IU_CMD , "FCP_CMND"}, @@ -616,6 +624,52 @@ dissect_fcp_xfer_rdy(tvbuff_t *tvb, proto_tree *tree) } static void +dissect_fcp_srr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + guint8 r_ctl; + + r_ctl = pinfo->r_ctl & 0xf; + if (r_ctl == FCP_IU_UNSOL_CTL) { /* request */ + proto_tree_add_item(tree, hf_fcp_srr_ox_id, tvb, 4, 2, FALSE); + proto_tree_add_item(tree, hf_fcp_srr_rx_id, tvb, 6, 2, FALSE); + proto_tree_add_item(tree, hf_fcp_data_ro, tvb, 8, 4, FALSE); + r_ctl = tvb_get_guint8(tvb, 12); + proto_tree_add_text(tree, tvb, 12, 1, "R_CTL: %s", + val_to_str(r_ctl, fcp_iu_val, "0x%02x")); + } +} + +static const value_string fcp_els_iu_val[] = { + {FCP_IU_UNSOL_CTL , "FCP ELS Request"}, + {FCP_IU_SOL_CTL , "FCP ELS Response"}, + {0, NULL}, +}; + +/* + * Dissect FC-4 ELS for FCP. + */ +static void +dissect_fcp_els(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + guint8 op; + + op = tvb_get_guint8(tvb, 0); + col_add_str(pinfo->cinfo, COL_INFO, val_to_str(op, fc_els_proto_val, "0x%x")); + proto_tree_add_text(tree, tvb, 0, 1, "Opcode: %s", + val_to_str(op, fc_els_proto_val, + "ELS 0x%02x")); + + switch (op) { /* XXX should switch based on conv for LS_ACC */ + case FC_ELS_SRR: + dissect_fcp_srr(tvb, pinfo, tree); + break; + default: + call_dissector(data_handle, tvb, pinfo, tree); + break; + } +} + +static void dissect_fcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti=NULL; @@ -624,6 +678,7 @@ dissect_fcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) guint8 r_ctl; fcp_conv_data_t *fcp_conv_data=NULL; itl_nexus_t *itl=NULL; + gboolean els; fchdr=(fc_hdr *)pinfo->private_data; @@ -631,18 +686,21 @@ dissect_fcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) col_set_str(pinfo->cinfo, COL_PROTOCOL, "FCP"); r_ctl = pinfo->r_ctl; - + els = (r_ctl & 0xf0) == FC_RCTL_LINK_DATA; r_ctl &= 0xF; if (check_col (pinfo->cinfo, COL_INFO)) { - col_add_str (pinfo->cinfo, COL_INFO, val_to_str (r_ctl, fcp_iu_val, - "0x%x")); + col_add_str (pinfo->cinfo, COL_INFO, + val_to_str (r_ctl, els ? fcp_els_iu_val : fcp_iu_val, + "0x%x")); } - if (tree) { ti = proto_tree_add_protocol_format(tree, proto_fcp, tvb, 0, -1, - "FCP: %s", val_to_str(r_ctl, fcp_iu_val, "Unknown 0x%02x")); + "FCP: %s", + val_to_str(r_ctl, + els ? fcp_els_iu_val : + fcp_iu_val, "Unknown 0x%02x")); fcp_tree = proto_item_add_subtree(ti, ett_fcp); } @@ -654,12 +712,13 @@ dissect_fcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) conversation_add_proto_data(fchdr->conversation, proto_fcp, fcp_conv_data); } - if(r_ctl!=FCP_IU_CMD){ + if((r_ctl!=FCP_IU_CMD) && (r_ctl!=FCP_IU_UNSOL_CTL)){ 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 */ - if((r_ctl!=FCP_IU_CMD)&&(fchdr->itlq->first_exchange_frame)){ + if((r_ctl!=FCP_IU_CMD) && (r_ctl!=FCP_IU_UNSOL_CTL) && + (fchdr->itlq->first_exchange_frame)){ proto_item *it; it=proto_tree_add_uint(fcp_tree, hf_fcp_singlelun, tvb, 0, 0, fchdr->itlq->lun); PROTO_ITEM_SET_GENERATED(it); @@ -674,12 +733,18 @@ dissect_fcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) } } /* put a response_in in all frames except the response frame */ - if((r_ctl!=FCP_IU_RSP)&&(fchdr->itlq->last_exchange_frame)){ + if((r_ctl!=FCP_IU_RSP) && (r_ctl!=FCP_IU_SOL_CTL) && + (fchdr->itlq->last_exchange_frame)){ proto_item *it; it=proto_tree_add_uint(fcp_tree, hf_fcp_response_in, tvb, 0, 0, fchdr->itlq->last_exchange_frame); PROTO_ITEM_SET_GENERATED(it); } + if (els) { + dissect_fcp_els(tvb, pinfo, fcp_tree); + return; + } + switch (r_ctl) { case FCP_IU_DATA: dissect_fcp_data(tvb, pinfo, tree, fchdr->conversation, fchdr, itl); @@ -813,6 +878,18 @@ proto_register_fcp (void) { &hf_fcp_time, { "Time from FCP_CMND", "fcp.time", FT_RELATIVE_TIME, BASE_NONE, NULL, 0, "Time since the FCP_CMND frame", HFILL }}, + { &hf_fcp_srr_op, + {"Opcode", "fcp.els.op", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, + HFILL}}, + { &hf_fcp_srr_ox_id, + {"OX_ID", "fcp.els.srr.ox_id", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, + HFILL}}, + { &hf_fcp_srr_rx_id, + {"RX_ID", "fcp.els.srr.rx_id", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, + HFILL}}, + { &hf_fcp_srr_r_ctl, + {"R_CTL", "fcp.els.srr.r_ctl", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, + HFILL}}, }; /* Setup protocol subtree array */ |