aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-fc.c
diff options
context:
space:
mode:
authorJaap Keuter <jaap.keuter@xs4all.nl>2007-09-16 09:07:30 +0000
committerJaap Keuter <jaap.keuter@xs4all.nl>2007-09-16 09:07:30 +0000
commit2f3869cbbe931365ab97fdc2f281bb9b03412a63 (patch)
tree7a1fc7b0fcadfe0562a96e8bbe0f147195385eca /epan/dissectors/packet-fc.c
parentde33c21ae8737ffdb99af549bcf259ca4e71e53f (diff)
The Fibre Channel protocol defines a virtual fabric tag (VFT) similar to
ethernet's VLAN tag. It is sometimes called the VSAN tag. It used to be proprietary, but now it's standard. Wireshark currently displays it as an 8-byte field without dissecting it further. It'd be nice to have it broken down into fields. A patch is attached. svn path=/trunk/; revision=22879
Diffstat (limited to 'epan/dissectors/packet-fc.c')
-rw-r--r--epan/dissectors/packet-fc.c118
1 files changed, 93 insertions, 25 deletions
diff --git a/epan/dissectors/packet-fc.c b/epan/dissectors/packet-fc.c
index 386bb7b523..320411b669 100644
--- a/epan/dissectors/packet-fc.c
+++ b/epan/dissectors/packet-fc.c
@@ -57,7 +57,7 @@
#include <epan/emem.h>
#define FC_HEADER_SIZE 24
-#define FC_RCTL_EISL 0x50
+#define FC_RCTL_VFT 0x50
#define MDSHDR_TRAILER_SIZE 6
/* Size of various fields in FC header in bytes */
@@ -107,9 +107,17 @@ static int hf_fc_rxid = -1;
static int hf_fc_param = -1;
static int hf_fc_ftype = -1; /* Derived field, non-existent in FC hdr */
static int hf_fc_reassembled = -1;
-static int hf_fc_eisl = -1;
static int hf_fc_relative_offset = -1;
+/* VFT fields */
+static int hf_fc_vft = -1;
+static int hf_fc_vft_rctl = -1;
+static int hf_fc_vft_ver = -1;
+static int hf_fc_vft_type = -1;
+static int hf_fc_vft_pri = -1;
+static int hf_fc_vft_vf_id = -1;
+static int hf_fc_vft_hop_ct = -1;
+
/* Network_Header fields */
static int hf_fc_nh_da = -1;
static int hf_fc_nh_sa = -1;
@@ -130,6 +138,7 @@ static int hf_fc_bls_vendor = -1;
static gint ett_fc = -1;
static gint ett_fctl = -1;
static gint ett_fcbls = -1;
+static gint ett_fc_vft = -1;
static dissector_table_t fcftype_dissector_table;
static dissector_handle_t data_handle;
@@ -203,7 +212,7 @@ const value_string fc_fc4_val[] = {
{FC_TYPE_SNMP, "SNMP"},
{FC_TYPE_SB_FROM_CU, "SB-3(CU->Channel)"},
{FC_TYPE_SB_TO_CU, "SB-3(Channel->CU)"},
- {0, NULL},
+ {0, NULL}
};
static const value_string fc_ftype_vals [] = {
@@ -219,7 +228,7 @@ static const value_string fc_ftype_vals [] = {
{FC_FTYPE_LINKCTL, "Link Ctl"},
{FC_FTYPE_SBCCS, "SBCCS"},
{FC_FTYPE_OHMS, "OHMS(Cisco MDS)"},
- {0, NULL},
+ {0, NULL}
};
static const value_string fc_wka_vals[] _U_ = {
@@ -234,7 +243,7 @@ static const value_string fc_wka_vals[] _U_ = {
{FC_WKA_FABRIC_CTRLR, "Fabric Ctlr"},
{FC_WKA_FPORT, "F_Port Server"},
{FC_WKA_BCAST, "Broadcast ID"},
- {0, NULL},
+ {0, NULL}
};
static const value_string fc_routing_val[] = {
@@ -244,7 +253,7 @@ static const value_string fc_routing_val[] = {
{FC_RCTL_VIDEO, "Video_Data"},
{FC_RCTL_BLS, "Basic Link Services"},
{FC_RCTL_LINK_CTL, "Link_Control Frame"},
- {0, NULL},
+ {0, NULL}
};
static const value_string fc_iu_val[] = {
@@ -256,7 +265,7 @@ static const value_string fc_iu_val[] = {
{FC_IU_DATA_DESCRIPTOR , "Data Descriptor"},
{FC_IU_UNSOLICITED_CMD , "Unsolicited Command"},
{FC_IU_CMD_STATUS , "Command Status"},
- {0, NULL},
+ {0, NULL}
};
@@ -444,8 +453,45 @@ static const true_false_string tfs_fc_fctl_rel_offset = {
"rel offset NOT set"
};
-
-
+/*
+ * Dissect the VFT header.
+ */
+static void
+dissect_fc_vft(proto_tree *parent_tree,
+ tvbuff_t *tvb, int offset)
+{
+ proto_item *item = NULL;
+ proto_tree *tree = NULL;
+ guint8 rctl;
+ guint8 ver;
+ guint8 type;
+ guint8 pri;
+ guint16 vf_id;
+ guint8 hop_ct;
+
+ rctl = tvb_get_guint8(tvb, offset);
+ type = tvb_get_guint8(tvb, offset + 1);
+ ver = (type >> 6) & 3;
+ type = (type >> 2) & 0xf;
+ vf_id = tvb_get_ntohs(tvb, offset + 2);
+ pri = (vf_id >> 13) & 7;
+ vf_id = (vf_id >> 1) & 0xfff;
+ hop_ct = tvb_get_guint8(tvb, offset + 4);
+
+ if (parent_tree) {
+ item = proto_tree_add_uint_format(parent_tree, hf_fc_vft, tvb, offset,
+ 8, vf_id, "VFT Header: "
+ "VF_ID %d Pri %d Hop Count %d",
+ vf_id, pri, hop_ct);
+ tree = proto_item_add_subtree(item, ett_fc_vft);
+ }
+ proto_tree_add_uint(tree, hf_fc_vft_rctl, tvb, offset, 1, rctl);
+ proto_tree_add_uint(tree, hf_fc_vft_ver, tvb, offset + 1, 1, ver);
+ proto_tree_add_uint(tree, hf_fc_vft_type, tvb, offset + 1, 1, type);
+ proto_tree_add_uint(tree, hf_fc_vft_pri, tvb, offset + 2, 1, pri);
+ proto_tree_add_uint(tree, hf_fc_vft_vf_id, tvb, offset + 2, 2, vf_id);
+ proto_tree_add_uint(tree, hf_fc_vft_hop_ct, tvb, offset + 4, 1, hop_ct);
+}
/* code to dissect the F_CTL bitmask */
static void
@@ -563,14 +609,14 @@ static const value_string fc_bls_proto_val[] = {
{FC_BLS_BAACC , "BA_ACC"},
{FC_BLS_BARJT , "BA_RJT"},
{FC_BLS_PRMT , "PRMT"},
- {0, NULL},
+ {0, NULL}
};
static const value_string fc_els_proto_val[] = {
{0x01 , "Solicited Data"},
{0x02 , "Request"},
{0x03 , "Reply"},
- {0, NULL},
+ {0, NULL}
};
/* Code to actually dissect the packets */
@@ -581,7 +627,8 @@ dissect_fc_helper (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean
proto_item *ti=NULL;
proto_tree *fc_tree = NULL;
tvbuff_t *next_tvb;
- int offset = 0, next_offset, eisl_offset = -1;
+ int offset = 0, next_offset;
+ int vft_offset = -1;
gboolean is_lastframe_inseq, is_1frame_inseq, is_valid_frame;
gboolean is_exchg_resp = 0;
fragment_data *fcfrag_head;
@@ -611,11 +658,16 @@ dissect_fc_helper (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean
fchdr.r_ctl = tvb_get_guint8 (tvb, offset);
- /* If the R_CTL is the EISL field, skip the first 8 bytes to retrieve the
- * real FC header. EISL is Cisco-proprietary and is not decoded.
+ /*
+ * If the frame contains a VFT (virtual fabric tag), decode it
+ * as a separate header before the FC frame header.
+ *
+ * This used to be called the Cisco-proprietary EISL field, but is now
+ * standardized in FC-FS-2. See section 10.2.4.
*/
- if (fchdr.r_ctl == FC_RCTL_EISL) {
- eisl_offset = offset;
+ if (fchdr.r_ctl == FC_RCTL_VFT) {
+ pinfo->vsan = (tvb_get_ntohs(tvb, offset + 2) >> 1) & 0xfff;
+ vft_offset = offset;
offset += 8;
fchdr.r_ctl = tvb_get_guint8 (tvb, offset);
}
@@ -710,7 +762,6 @@ dissect_fc_helper (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean
fc_tree = proto_item_add_subtree (ti, ett_fc);
}
-
/* put some nice exchange data in the tree */
if(!(fchdr.fctl&FC_FCTL_EXCHANGE_FIRST)){
proto_item *it;
@@ -759,13 +810,10 @@ dissect_fc_helper (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean
fc_lctl_proto_val,
"LCTL 0x%x"));
}
-
- /* Highlight EISL header, if present */
- if (eisl_offset != -1) {
- proto_tree_add_item (fc_tree, hf_fc_eisl, tvb, eisl_offset, 8, 0);
- }
-
+ if (vft_offset >= 0) {
+ dissect_fc_vft(fc_tree, tvb, vft_offset);
+ }
switch (fchdr.r_ctl & 0xF0) {
case FC_RCTL_DEV_DATA:
@@ -1284,17 +1332,37 @@ proto_register_fc(void)
{ &hf_fc_time,
{ "Time from Exchange First", "fc.time", FT_RELATIVE_TIME, BASE_NONE, NULL,
0, "Time since the first frame of the Exchange", HFILL }},
- { &hf_fc_eisl,
- {"EISL Header", "fc.eisl", FT_BYTES, BASE_HEX, NULL, 0, "EISL Header", HFILL}},
{ &hf_fc_relative_offset,
{"Relative Offset", "fc.relative_offset", FT_UINT32, BASE_DEC, NULL,
0, "Relative offset of data", HFILL}},
+ { &hf_fc_vft,
+ {"VFT Header", "fc.vft", FT_UINT16, BASE_DEC, NULL,
+ 0, "VFT Header", HFILL}},
+ { &hf_fc_vft_rctl,
+ {"R_CTL", "fc.vft.rctl", FT_UINT8, BASE_HEX, NULL,
+ 0, "R_CTL", HFILL}},
+ { &hf_fc_vft_ver,
+ {"Version", "fc.vft.ver", FT_UINT8, BASE_DEC, NULL,
+ 0, "Version of VFT header", HFILL}},
+ { &hf_fc_vft_type,
+ {"Type", "fc.vft.type", FT_UINT8, BASE_DEC, NULL,
+ 0, "Type of tagged frame", HFILL}},
+ { &hf_fc_vft_pri,
+ {"Priority", "fc.vft.type", FT_UINT8, BASE_DEC, NULL,
+ 0, "QoS Priority", HFILL}},
+ { &hf_fc_vft_vf_id,
+ {"VF_ID", "fc.vft.vf_id", FT_UINT16, BASE_DEC, NULL,
+ 0, "Virtual Fabric ID", HFILL}},
+ { &hf_fc_vft_hop_ct,
+ {"HopCT", "fc.vft.hop_ct", FT_UINT8, BASE_DEC, NULL,
+ 0, "Hop Count", HFILL}},
};
/* Setup protocol subtree array */
static gint *ett[] = {
&ett_fc,
&ett_fcbls,
+ &ett_fc_vft,
&ett_fctl
};