diff options
author | Deep Datta <deep.datta@keysight.com> | 2020-04-03 20:00:06 -0500 |
---|---|---|
committer | Martin Mathieson <martin.r.mathieson@googlemail.com> | 2020-04-14 16:48:47 +0000 |
commit | 4b060b739eca967c66a278a934bb968978c6c6b6 (patch) | |
tree | 01a5f986647892839ddbb101b5dae6c1299262c6 | |
parent | 6b589151a29ff7a3cb3ce05d1c86bfd34bb1ae5d (diff) |
cflow: Add support for dissecting fields with data type subTemplateList
SubTemplateList is one of the 3 hierarchical data types supported by IPFIX.
Adding the capability to dissect fields of this type and show the list
of sub elements along with the 2 header fields in the subtemplate;
semantic and subtemplate id.
Tested with multiple level of nesting with subtemplate list fields
inside another list.
reference: https://tools.ietf.org/html/rfc6313#section-4.5.2
+ Review comment Changes
Change-Id: Iad00944c935cad8c0cdba457b9453fd13c68a6c2
Reviewed-on: https://code.wireshark.org/review/36745
Petri-Dish: Martin Mathieson <martin.r.mathieson@googlemail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Martin Mathieson <martin.r.mathieson@googlemail.com>
-rw-r--r-- | epan/dissectors/packet-netflow.c | 96 |
1 files changed, 95 insertions, 1 deletions
diff --git a/epan/dissectors/packet-netflow.c b/epan/dissectors/packet-netflow.c index 1f23eba2e2..8bf054bf17 100644 --- a/epan/dissectors/packet-netflow.c +++ b/epan/dissectors/packet-netflow.c @@ -2224,6 +2224,7 @@ static int ett_dataflowset = -1; static int ett_fwdstat = -1; static int ett_mpls_label = -1; static int ett_tcpflags = -1; +static int ett_subtemplate_list = -1; /* * cflow header */ @@ -2280,6 +2281,8 @@ static int hf_cflow_template_ipfix_pen_provided = -1; static int hf_cflow_template_ipfix_field_type = -1; static int hf_cflow_template_ipfix_field_type_enterprise = -1; static int hf_cflow_template_ipfix_field_pen = -1; +static int hf_cflow_subtemplate_id = -1; +static int hf_cflow_subtemplate_semantic = -1; /* IPFIX / vendor */ static int hf_cflow_template_plixer_field_type = -1; @@ -2554,6 +2557,7 @@ static int hf_cflow_information_element_index = -1; / static int hf_cflow_p2p_technology = -1; /* ID: 288 */ static int hf_cflow_tunnel_technology = -1; /* ID: 289 */ static int hf_cflow_encrypted_technology = -1; /* ID: 290 */ +static int hf_cflow_subtemplate_list = -1; /* ID: 292 */ static int hf_cflow_bgp_validity_state = -1; /* ID: 294 */ static int hf_cflow_ipsec_spi = -1; /* ID: 295 */ static int hf_cflow_gre_key = -1; /* ID: 296 */ @@ -3606,6 +3610,7 @@ static expert_field ei_cflow_flowsets_impossible = EI_INIT static expert_field ei_cflow_no_template_found = EI_INIT; static expert_field ei_transport_bytes_out_of_order = EI_INIT; static expert_field ei_unexpected_sequence_number = EI_INIT; +static expert_field ei_cflow_subtemplate_bad_length = EI_INIT; static const value_string special_mpls_top_label_type[] = { {0, "Unknown"}, @@ -4731,6 +4736,68 @@ enum duration_type_e { duration_type_max /* not used - for sizing only */ }; +/* SubTemplateList reference https://tools.ietf.org/html/rfc6313#section-4.5.2 */ +static void +dissect_v10_pdu_subtemplate_list(tvbuff_t* tvb, packet_info* pinfo, proto_item* pduitem, int offset, + guint16 length, hdrinfo_t* hdrinfo_p) +{ + int start_offset = offset; + int end_offset = offset + length; + guint32 semantic, subtemplate_id; + v9_v10_tmplt_t *subtmplt_p; + v9_v10_tmplt_t tmplt_key; + proto_tree *pdutree = proto_item_add_subtree(pduitem, ett_subtemplate_list); + + proto_tree_add_item_ret_uint(pdutree, hf_cflow_subtemplate_semantic, tvb, offset, 1, ENC_BIG_ENDIAN, &semantic); + proto_tree_add_item_ret_uint(pdutree, hf_cflow_subtemplate_id, tvb, offset+1, 2, ENC_BIG_ENDIAN, &subtemplate_id); + proto_item_append_text(pdutree, " (semantic = %u, subtemplate-id = %u)", semantic, subtemplate_id); + offset += 3; + + /* Look up template */ + v9_v10_tmplt_build_key(&tmplt_key, pinfo, hdrinfo_p->src_id, subtemplate_id); + subtmplt_p = (v9_v10_tmplt_t *)wmem_map_lookup(v9_v10_tmplt_table, &tmplt_key); + + if (subtmplt_p != NULL) { + proto_item *ti; + int count = 1; + proto_tree *sub_tree; + guint consumed; + + /* Provide a link back to template frame */ + ti = proto_tree_add_uint(pdutree, hf_template_frame, tvb, + 0, 0, subtmplt_p->template_frame_number); + if (subtmplt_p->template_frame_number > pinfo->num) { + proto_item_append_text(ti, " (received after this frame)"); + } + proto_item_set_generated(ti); + + while (offset < end_offset) { + sub_tree = proto_tree_add_subtree_format(pdutree, tvb, offset, subtmplt_p->length, + ett_subtemplate_list, NULL, "List Item %d", count++); + consumed = dissect_v9_v10_pdu_data(tvb, pinfo, sub_tree, offset, subtmplt_p, hdrinfo_p, TF_ENTRIES); + if (0 == consumed) { + /* To protect against infinite loop in case of malformed records with + 0 length template or tmplt_p->fields_p[1] == NULL or tmplt_p->field_count == 0 + */ + break; + } + offset += consumed; + } + if (offset != end_offset) { + int data_bytes = offset - start_offset; + proto_tree_add_expert_format(pdutree, NULL, &ei_cflow_subtemplate_bad_length, + tvb, offset, length, + "Field Length (%u bytes), Data Found (%u byte%s)", + length, data_bytes, plurality(data_bytes, "", "s")); + } + } else { + proto_tree_add_expert_format(pdutree, NULL, &ei_cflow_no_template_found, + tvb, offset, length, + "Subtemplate Data (%u byte%s), template %u not found", + length, plurality(length, "", "s"), subtemplate_id); + } +} + static guint dissect_v9_v10_pdu_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *pdutree, int offset, v9_v10_tmplt_t *tmplt_p, hdrinfo_t *hdrinfo_p, v9_v10_tmplt_fields_type_t fields_type) @@ -6377,6 +6444,12 @@ dissect_v9_v10_pdu_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *pdutree, tvb, offset, length, ENC_UTF_8|ENC_NA); break; + case 292: + ti = proto_tree_add_item(pdutree, hf_cflow_subtemplate_list, + tvb, offset, length, ENC_NA); + dissect_v10_pdu_subtemplate_list(tvb, pinfo, ti, offset, length, hdrinfo_p); + break; + case 294: ti = proto_tree_add_item(pdutree, hf_cflow_bgp_validity_state, tvb, offset, length, ENC_BIG_ENDIAN); @@ -12157,6 +12230,18 @@ proto_register_netflow(void) FT_UINT16, BASE_DEC, NULL, 0x0, "Template field length", HFILL} }, + {&hf_cflow_subtemplate_id, + {"SubTemplateList Id", "cflow.subtemplate_id", + FT_UINT16, BASE_DEC, NULL, 0x0, + "ID of the Template used to encode and decode" + " the subTemplateList Content", HFILL} + }, + {&hf_cflow_subtemplate_semantic, + {"SubTemplateList Semantic", "cflow.subtemplate_semantic", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Indicates the relationship among the different Data Records" + " within this Structured Data Information Element", HFILL} + }, /* options */ {&hf_cflow_option_scope_length, @@ -13465,6 +13550,11 @@ proto_register_netflow(void) FT_STRING, STR_UNICODE, NULL, 0x0, NULL, HFILL} }, + {&hf_cflow_subtemplate_list, + {"SubTemplate List", "cflow.subtemplate_list", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL} + }, {&hf_cflow_bgp_validity_state, {"Bgp Validity State", "cflow.bgp_validity_state", FT_UINT8, BASE_DEC, NULL, 0x0, @@ -19320,7 +19410,8 @@ proto_register_netflow(void) &ett_dataflowset, &ett_fwdstat, &ett_mpls_label, - &ett_tcpflags + &ett_tcpflags, + &ett_subtemplate_list }; static ei_register_info ei[] = { @@ -19360,6 +19451,9 @@ proto_register_netflow(void) { &ei_unexpected_sequence_number, { "cflow.unexpected_sequence_number", PI_SEQUENCE, PI_WARN, "Unexpected flow sequence for domain ID", EXPFILL}}, + { &ei_cflow_subtemplate_bad_length, + { "cflow.subtemplate_bad_length", PI_UNDECODED, PI_WARN, + "SubTemplateList bad length", EXPFILL}}, }; module_t *netflow_module; |