diff options
author | Anders Broman <anders.broman@ericsson.com> | 2013-12-04 20:55:52 +0000 |
---|---|---|
committer | Anders Broman <anders.broman@ericsson.com> | 2013-12-04 20:55:52 +0000 |
commit | 5c40dde043bf95889c90284b05e624da71581ea0 (patch) | |
tree | 9dfdf5fbc08d2eecc4b4e8e8da33793c5f407775 /epan/dissectors/packet-diameter.c | |
parent | a8ed2cf767939cb5d45056c7f5f94c33fa8e3873 (diff) |
"RFC 6733 [5] specifies the Experimental-Result AVP containing Vendor-Id AVP and Experimental-Result-Code AVP. The Experimental-Result-Code AVP (AVP Code 298) is of type Unsigned32 and contains a vendor-assigned value representing the result of processing a request."
This means we have to store the value of the Vendor Id AVP in the grouped Experimental-Result AVP to be able to dissect the value of
Experimental-Result-Code according to the vendor specified values(if known). This patch implements that with a dissector table to register vendor dissectors for the result code.
svn path=/trunk/; revision=53785
Diffstat (limited to 'epan/dissectors/packet-diameter.c')
-rw-r--r-- | epan/dissectors/packet-diameter.c | 66 |
1 files changed, 64 insertions, 2 deletions
diff --git a/epan/dissectors/packet-diameter.c b/epan/dissectors/packet-diameter.c index 9aa08c29f9..ba3834a62d 100644 --- a/epan/dissectors/packet-diameter.c +++ b/epan/dissectors/packet-diameter.c @@ -271,6 +271,7 @@ static int hf_framed_ipv6_prefix_reserved = -1; static int hf_framed_ipv6_prefix_length = -1; static int hf_framed_ipv6_prefix_bytes = -1; static int hf_framed_ipv6_prefix_ipv6 = -1; +static int hf_diameter_3gpp2_exp_res = -1; static gint ett_diameter = -1; static gint ett_diameter_flags = -1; @@ -311,6 +312,7 @@ static gboolean gbl_diameter_desegment = TRUE; static dissector_table_t diameter_dissector_table; static dissector_table_t diameter_3gpp_avp_dissector_table; static dissector_table_t diameter_ericsson_avp_dissector_table; +static dissector_table_t diameter_expr_result_vnd_table; static const char *avpflags_str[] = { "---", @@ -383,6 +385,29 @@ dissect_diameter_eap_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree return tvb_length(tvb); } +/* http://www.3gpp2.org/public_html/X/VSA-VSE.cfm */ +static const value_string diameter_3gpp2_exp_res_vals[]= { + { 5001, "Diameter_Error_User_No_WLAN_Subscription"}, + { 5002, "Diameter_Error_Roaming_Not_Allowed(Obsoleted)"}, + { 5003, "Diameter_Error_User_No_FAP_Subscription"}, + {0,NULL} +}; + +static int +dissect_diameter_3gpp2_exp_res(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data) { + proto_item *pi; + diam_sub_dis_t *diam_sub_dis = (diam_sub_dis_t*)data; + + pi = proto_tree_add_item(tree, hf_diameter_3gpp2_exp_res, tvb, 0, 4, ENC_BIG_ENDIAN); + diam_sub_dis->avp_str = (char *)wmem_alloc(wmem_packet_scope(), ITEM_LABEL_LENGTH+1); + proto_item_fill_label(PITEM_FINFO(pi), diam_sub_dis->avp_str); + diam_sub_dis->avp_str = strstr(diam_sub_dis->avp_str,": ")+2; + + + return 4; +} + + /* From RFC 3162 section 2.3 */ static int dissect_diameter_base_framed_ipv6_prefix(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_) @@ -560,13 +585,33 @@ dissect_diameter_avp(diam_ctx_t *c, tvbuff_t *tvb, int offset, diam_sub_dis_t *d /* pad_len is always 0 in this case, but kept here for consistency */ return len+pad_len; } + /* If we are dissecting a grouped AVP and find a Vendor Id AVP(266), save it */ + if((diam_sub_dis_inf->dis_gouped)&&(!vendor_flag)&&(code==266)){ + diam_sub_dis_inf->vendor_id = tvb_get_ntohl(tvb,offset); + } subtvb = tvb_new_subset(tvb,offset,len-(8+(vendor_flag?4:0)),len-(8+(vendor_flag?4:0))); offset += len-(8+(vendor_flag?4:0)); save_tree = c->tree; c->tree = avp_tree; - if (c->version_rfc) { + + /* If we are dissecting a grouped AVP and find Experimental-Result-Code AVP(298) + * it might be Vendor defined e.g we can't use the enum from the .xml file. + * Actually the xml enum is for 3GPP so let the AVP dissector handle that too + */ + if((diam_sub_dis_inf->dis_gouped) + &&(!vendor_flag) + &&(code==298) + &&(diam_sub_dis_inf->vendor_id != 0) + &&(diam_sub_dis_inf->vendor_id != VENDOR_THE3GPP)) + { + /* call subdissector */ + dissector_try_uint_new(diameter_expr_result_vnd_table, diam_sub_dis_inf->vendor_id, subtvb, c->pinfo, avp_tree, FALSE, diam_sub_dis_inf); + if(diam_sub_dis_inf->avp_str){ + proto_item_append_text(avp_item," val=%s", diam_sub_dis_inf->avp_str); + } + }else if (c->version_rfc) { avp_str = a->dissector_rfc(c,a,subtvb, diam_sub_dis_inf); } else { avp_str = a->dissector_v16(c,a,subtvb, diam_sub_dis_inf); @@ -885,9 +930,15 @@ grouped_avp(diam_ctx_t *c, diam_avp_t *a, tvbuff_t *tvb, diam_sub_dis_t *diam_su c->tree = proto_item_add_subtree(pi,a->ett); + /* Set the flag that we are dissecting a grouped AVP */ + diam_sub_dis_inf->dis_gouped = TRUE; while (offset < len) { offset += dissect_diameter_avp(c, tvb, offset, diam_sub_dis_inf); } + /* Clear info collected in grouped AVP */ + diam_sub_dis_inf->vendor_id = 0; + diam_sub_dis_inf->dis_gouped = FALSE; + diam_sub_dis_inf->avp_str = NULL; c->tree = pt; @@ -1815,7 +1866,12 @@ real_proto_register_diameter(void) FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, { &hf_framed_ipv6_prefix_ipv6, { "Framed IPv6 Prefix as an IPv6 address", "diameter.framed_ipv6_prefix_ipv6", - FT_IPv6, BASE_NONE, NULL, 0, "This field is present only if the prefix length is 128", HFILL }} + FT_IPv6, BASE_NONE, NULL, 0, "This field is present only if the prefix length is 128", HFILL }}, + { &hf_diameter_3gpp2_exp_res, + { "Experimental-Result-Code", "diameter.ericsson.exp_res", + FT_UINT32, BASE_DEC, VALS(diameter_3gpp2_exp_res_vals), 0x0, NULL, HFILL } + }, + }; gint *ett_base[] = { @@ -1863,6 +1919,8 @@ real_proto_register_diameter(void) diameter_3gpp_avp_dissector_table = register_dissector_table("diameter.3gpp", "DIAMETER_3GPP_AVPS", FT_UINT32, BASE_DEC); diameter_ericsson_avp_dissector_table = register_dissector_table("diameter.ericsson", "DIAMETER_ERICSSON_AVPS", FT_UINT32, BASE_DEC); + diameter_expr_result_vnd_table = register_dissector_table("diameter.vnd_exp_res", "DIAMETER Experimental-Result-Code", FT_UINT32, BASE_DEC); + /* Set default TCP ports */ range_convert_str(&global_diameter_tcp_port_range, DEFAULT_DIAMETER_PORT_RANGE, MAX_UDP_PORT); range_convert_str(&global_diameter_sctp_port_range, DEFAULT_DIAMETER_PORT_RANGE, MAX_SCTP_PORT); @@ -1959,6 +2017,10 @@ proto_reg_handoff_diameter(void) dissector_add_uint("diameter.base", 463, new_create_dissector_handle(dissect_diameter_eap_payload, proto_diameter)); + /* Register dissector for Experimental result code, with 3GPP2:s vendor Id */ + dissector_add_uint("diameter.vnd_exp_res", VENDOR_THE3GPP2, + new_create_dissector_handle(dissect_diameter_3gpp2_exp_res, proto_diameter)); + Initialized=TRUE; } else { dissector_delete_uint_range("tcp.port", diameter_tcp_port_range, diameter_tcp_handle); |