summaryrefslogtreecommitdiff
path: root/epan/dissectors/packet-fip.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/dissectors/packet-fip.c')
-rw-r--r--epan/dissectors/packet-fip.c81
1 files changed, 43 insertions, 38 deletions
diff --git a/epan/dissectors/packet-fip.c b/epan/dissectors/packet-fip.c
index 0903c35a5e..dae528f04f 100644
--- a/epan/dissectors/packet-fip.c
+++ b/epan/dissectors/packet-fip.c
@@ -211,6 +211,7 @@ static int hf_fip_flag_rec_p2p = -1;
static int hf_fip_flag_avail = -1;
static int hf_fip_flag_sol = -1;
static int hf_fip_flag_fport = -1;
+static int hf_fip_descriptors = -1;
static const int *hf_fip_flags_fields[] = {
&hf_fip_flag_fpma,
@@ -266,16 +267,24 @@ static int ett_fip_dt_fc4f = -1;
static int ett_fip_dt_fc4f_types = -1;
static int ett_fip_dt_fcp_feat = -1;
+static expert_field ei_fip_descriptors = EI_INIT;
+
static dissector_handle_t fc_handle;
/*
* Insert common descriptor type and length fields.
*/
-static void
-fip_desc_type_len(proto_tree *tree, tvbuff_t *tvb)
+static proto_tree*
+fip_desc_type_len(proto_tree *tree, tvbuff_t *tvb, guint8 dtype, int ett, proto_item** item)
{
- proto_tree_add_item(tree, hf_fip_desc_type, tvb, 0, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(tree, hf_fip_desc_len, tvb, 1, 1, ENC_BIG_ENDIAN);
+ proto_tree* ret_tree;
+
+ ret_tree = proto_tree_add_subtree_format(tree, tvb, 0, -1, ett, item,
+ "Descriptor: %s ", val_to_str(dtype, fip_desc_types, "Unknown 0x%x"));
+ proto_tree_add_item(ret_tree, hf_fip_desc_type, tvb, 0, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(ret_tree, hf_fip_desc_len, tvb, 1, 1, ENC_BIG_ENDIAN);
+
+ return ret_tree;
}
/*
@@ -419,13 +428,12 @@ dissect_fip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
desc_offset = FIP_HEADER_LEN;
rlen *= FIP_BPW;
- proto_tree_add_text(fip_tree, tvb, desc_offset, rlen, "Descriptors:");
+ proto_tree_add_bytes_format(fip_tree, hf_fip_descriptors, tvb, desc_offset, rlen, NULL, "Descriptors");
while ((rlen > 0) && tvb_bytes_exist(tvb, desc_offset, 2)) {
dlen = tvb_get_guint8(tvb, desc_offset + 1) * FIP_BPW;
if (!dlen) {
- proto_tree_add_text(fip_tree, tvb, desc_offset, -1,
- "Descriptor [length error]");
+ proto_tree_add_expert(fip_tree, pinfo, &ei_fip_descriptors, tvb, desc_offset, -1);
break;
}
if (!tvb_bytes_exist(tvb, desc_offset, dlen) || dlen > rlen) {
@@ -436,44 +444,36 @@ dissect_fip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
desc_offset += dlen;
rlen -= dlen;
- item = proto_tree_add_text(fip_tree, desc_tvb, 0, -1, "Descriptor: %s ",
- val_to_str(dtype, fip_desc_types, "Unknown 0x%x"));
-
switch (dtype) {
case FIP_DT_PRI:
- subtree = proto_item_add_subtree(item, ett_fip_dt_pri);
- fip_desc_type_len(subtree, desc_tvb);
+ subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_pri, &item);
proto_tree_add_item(subtree, hf_fip_desc_pri, desc_tvb,
3, 1, ENC_BIG_ENDIAN);
proto_item_append_text(item, "%u", tvb_get_guint8(desc_tvb, 3));
break;
case FIP_DT_MAC:
- subtree = proto_item_add_subtree(item, ett_fip_dt_mac);
- fip_desc_type_len(subtree, desc_tvb);
+ subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_mac, &item);
proto_tree_add_item(subtree, hf_fip_desc_mac, desc_tvb,
2, 6, ENC_NA);
proto_item_append_text(item, "%s",
tvb_bytes_to_ep_str_punct(desc_tvb, 2, 6, ':'));
break;
case FIP_DT_MAP_OUI:
- subtree = proto_item_add_subtree(item, ett_fip_dt_map);
- fip_desc_type_len(subtree, desc_tvb);
+ subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_map, &item);
text = tvb_fc_to_str(desc_tvb, 5);
proto_tree_add_string(subtree, hf_fip_desc_map, desc_tvb,
5, 3, text);
proto_item_append_text(item, "%s", text);
break;
case FIP_DT_NAME:
- subtree = proto_item_add_subtree(item, ett_fip_dt_name);
- fip_desc_type_len(subtree, desc_tvb);
+ subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_name, &item);
text = tvb_fcwwn_to_str(desc_tvb, 4);
proto_tree_add_string(subtree, hf_fip_desc_name,
desc_tvb, 4, 8, text);
proto_item_append_text(item, "%s", text);
break;
case FIP_DT_FAB:
- subtree = proto_item_add_subtree(item, ett_fip_dt_fab);
- fip_desc_type_len(subtree, desc_tvb);
+ subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_fab, &item);
proto_tree_add_item(subtree, hf_fip_desc_fab_vfid, desc_tvb,
2, 2, ENC_BIG_ENDIAN);
text = tvb_fc_to_str(desc_tvb, 5);
@@ -485,8 +485,7 @@ dissect_fip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_item_append_text(item, "%s", text);
break;
case FIP_DT_FCOE_SIZE:
- subtree = proto_item_add_subtree(item, ett_fip_dt_mdl);
- fip_desc_type_len(subtree, desc_tvb);
+ subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_mdl, &item);
proto_tree_add_item(subtree, hf_fip_desc_fcoe_size, desc_tvb,
2, 2, ENC_BIG_ENDIAN);
proto_item_append_text(item, "%u", tvb_get_ntohs(desc_tvb, 2));
@@ -498,16 +497,14 @@ dissect_fip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
tvbuff_t *ls_tvb;
fc_data_t fc_data = {ETHERTYPE_FIP, 0};
- subtree = proto_item_add_subtree(item, ett_fip_dt_caps);
- fip_desc_type_len(subtree, desc_tvb);
+ subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_caps, &item);
ls_tvb = tvb_new_subset(desc_tvb, 4, dlen - 4, -1);
call_dissector_with_data(fc_handle, ls_tvb, pinfo, subtree, &fc_data);
proto_item_append_text(item, "%u bytes", dlen - 4);
}
break;
case FIP_DT_VN:
- subtree = proto_item_add_subtree(item, ett_fip_dt_vn);
- fip_desc_type_len(subtree, desc_tvb);
+ subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_vn, &item);
proto_tree_add_item(subtree, hf_fip_desc_vn_mac, desc_tvb,
2, 6, ENC_NA);
proto_tree_add_item(subtree, hf_fip_desc_vn_fid, desc_tvb,
@@ -520,16 +517,14 @@ dissect_fip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
tvb_get_ntoh24(desc_tvb, 9));
break;
case FIP_DT_FKA:
- subtree = proto_item_add_subtree(item, ett_fip_dt_fka);
- fip_desc_type_len(subtree, desc_tvb);
+ subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_fka, &item);
val = tvb_get_ntohl(desc_tvb, 4);
proto_tree_add_uint_format_value(subtree, hf_fip_desc_fka,
desc_tvb, 4, 4, val, "%u ms", val);
proto_item_append_text(item, "%u ms", val);
break;
case FIP_DT_VEND:
- subtree = proto_item_add_subtree(item, ett_fip_dt_vend);
- fip_desc_type_len(subtree, desc_tvb);
+ subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_vend, &item);
proto_tree_add_item(subtree, hf_fip_desc_vend, desc_tvb,
4, 8, ENC_NA);
if (tvb_bytes_exist(desc_tvb, 9, -1)) {
@@ -538,20 +533,17 @@ dissect_fip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
break;
case FIP_DT_VLAN:
- subtree = proto_item_add_subtree(item, ett_fip_dt_vlan);
- fip_desc_type_len(subtree, desc_tvb);
+ subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_vlan, &item);
proto_tree_add_item(subtree, hf_fip_desc_vlan, desc_tvb,
2, 2, ENC_BIG_ENDIAN);
proto_item_append_text(item, "%u", tvb_get_ntohs(desc_tvb, 2));
break;
case FIP_DT_FC4F:
- subtree = proto_item_add_subtree(item, ett_fip_dt_fc4f);
- fip_desc_type_len(subtree, desc_tvb);
+ subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_fc4f, &item);
fip_desc_fc4f(desc_tvb, subtree, item);
break;
default:
- subtree = proto_item_add_subtree(item, ett_fip_dt_unk);
- fip_desc_type_len(subtree, desc_tvb);
+ subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_unk, &item);
proto_tree_add_item(subtree, hf_fip_desc_unk, desc_tvb,
2, -1, ENC_NA);
break;
@@ -772,9 +764,14 @@ proto_register_fip(void)
NULL, HFILL}},
{ &hf_fip_desc_unk,
- { "Unknown Descriptor", "fip.desc",
+ { "Unknown Descriptor", "fip.desc_unk",
+ FT_BYTES, BASE_NONE, NULL, 0,
+ NULL, HFILL}},
+
+ { &hf_fip_descriptors,
+ { "Descriptors", "fip.descriptors",
FT_BYTES, BASE_NONE, NULL, 0,
- NULL, HFILL}}
+ NULL, HFILL}},
};
static gint *ett[] = {
@@ -797,6 +794,12 @@ proto_register_fip(void)
&ett_fip_dt_unk
};
+ static ei_register_info ei[] = {
+ { &ei_fip_descriptors, { "fip.descriptors.length_error", PI_MALFORMED, PI_ERROR, "Descriptor [length error]", EXPFILL }},
+ };
+
+ expert_module_t* expert_fip;
+
/* Register the protocol name and description */
proto_fip = proto_register_protocol("FCoE Initialization Protocol",
"FIP", "fip");
@@ -805,6 +808,8 @@ proto_register_fip(void)
* subtrees used */
proto_register_field_array(proto_fip, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
+ expert_fip = expert_register_protocol(proto_fip);
+ expert_register_field_array(expert_fip, ei, array_length(ei));
}
/*