diff options
Diffstat (limited to 'epan/dissectors/packet-fip.c')
-rw-r--r-- | epan/dissectors/packet-fip.c | 81 |
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)); } /* |