aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors
diff options
context:
space:
mode:
authorJeff Morriss <jeff.morriss@ulticom.com>2012-03-13 15:06:40 +0000
committerJeff Morriss <jeff.morriss@ulticom.com>2012-03-13 15:06:40 +0000
commite04377414359132b4a1a4acee2df071563f15688 (patch)
treefe49ee231f027ee154a36d1e9427b309a59ce8c9 /epan/dissectors
parent55634ab2e375efd58c2c027bb74380c3e9253673 (diff)
Add detailed decoding for Framed-IPv6-Prefix.
svn path=/trunk/; revision=41532
Diffstat (limited to 'epan/dissectors')
-rw-r--r--epan/dissectors/packet-diameter.c66
1 files changed, 56 insertions, 10 deletions
diff --git a/epan/dissectors/packet-diameter.c b/epan/dissectors/packet-diameter.c
index 009df30ea5..0f2c6776fc 100644
--- a/epan/dissectors/packet-diameter.c
+++ b/epan/dissectors/packet-diameter.c
@@ -258,6 +258,12 @@ static int hf_diameter_answer_in = -1;
static int hf_diameter_answer_to = -1;
static int hf_diameter_answer_time = -1;
+/* AVPs with special/extra decoding */
+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 gint ett_diameter = -1;
static gint ett_diameter_flags = -1;
static gint ett_diameter_avp_flags = -1;
@@ -316,14 +322,12 @@ compare_avps (gconstpointer a, gconstpointer b)
static int
dissect_diameter_vendor_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{
-
int offset = 0;
proto_tree_add_item(tree, hf_diameter_vendor_id, tvb, 0, 4, ENC_BIG_ENDIAN);
offset++;
return offset;
-
}
static int
@@ -341,6 +345,29 @@ dissect_diameter_eap_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
return tvb_length(tvb);
}
+/* From RFC 3162 section 2.3 */
+static int
+dissect_diameter_base_framed_ipv6_prefix(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ guint8 prefix_len, prefix_len_bytes;
+
+ proto_tree_add_item(tree, hf_framed_ipv6_prefix_reserved, tvb, 0, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_framed_ipv6_prefix_length, tvb, 1, 1, ENC_BIG_ENDIAN);
+
+ prefix_len = tvb_get_guint8(tvb, 1);
+ prefix_len_bytes = prefix_len / 8;
+ if (prefix_len % 8)
+ prefix_len_bytes++;
+
+ proto_tree_add_item(tree, hf_framed_ipv6_prefix_bytes, tvb, 2, prefix_len_bytes, ENC_NA);
+
+ /* If we have a fully IPv6 address, display it as such */
+ if (prefix_len_bytes == 16)
+ proto_tree_add_item(tree, hf_framed_ipv6_prefix_ipv6, tvb, 2, prefix_len_bytes, ENC_NA);
+
+ return(prefix_len_bytes+2);
+}
+
/* Dissect an AVP at offset */
static int
dissect_diameter_avp(diam_ctx_t* c, tvbuff_t* tvb, int offset)
@@ -386,7 +413,7 @@ dissect_diameter_avp(diam_ctx_t* c, tvbuff_t* tvb, int offset)
{ /* Debug code */
value_string* vendor_avp_vs=VALUE_STRING_EXT_VS_P(vendor->vs_avps_ext);
gint i = 0;
- while(vendor_avp_vs[i].strptr!=NULL){
+ while(vendor_avp_vs[i].strptr!=NULL) {
g_warning("%u %s",vendor_avp_vs[i].value,vendor_avp_vs[i].strptr);
i++;
}
@@ -477,7 +504,7 @@ dissect_diameter_avp(diam_ctx_t* c, tvbuff_t* tvb, int offset)
if (avp_str) proto_item_append_text(avp_item," val=%s", avp_str);
/* Call subdissectors for AVP:s */
- switch (vendorid){
+ switch (vendorid) {
case 0:
dissector_try_uint(diameter_dissector_table, code, subtvb, c->pinfo, avp_tree);
break;
@@ -1073,11 +1100,11 @@ static void
dissect_diameter_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
/* Check if we have the start of a PDU or if this is segment */
- if (!check_diameter(tvb)){
+ if (!check_diameter(tvb)) {
col_set_str(pinfo->cinfo, COL_PROTOCOL, "DIAMETER");
col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
call_dissector(data_handle, tvb, pinfo, tree);
- }else{
+ } else {
tcp_dissect_pdus(tvb, pinfo, tree, gbl_diameter_desegment, 4,
get_diameter_pdu_len, dissect_diameter_common);
}
@@ -1118,7 +1145,7 @@ reginfo(int* hf_ptr, const char* name, const char* abbr, const char* desc,
g_strdup(desc),
HFILL }};
- if(vs_ext){
+ if(vs_ext) {
hf.hfinfo.strings = vs_ext;
}
@@ -1141,7 +1168,7 @@ basic_avp_reginfo(diam_avp_t* a, const char* name, enum ftenum ft,
hf->hfinfo.name = g_strdup_printf("%s",name);
hf->hfinfo.abbrev = alnumerize(g_strdup_printf("diameter.%s",name));
- if(vs_ext){
+ if(vs_ext) {
hf->hfinfo.strings = vs_ext;
}
@@ -1679,7 +1706,22 @@ proto_register_diameter(void)
{ &hf_diameter_answer_time,
{ "Response Time", "diameter.resp_time", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
"The time between the request and the answer", HFILL }},
-
+ { &hf_framed_ipv6_prefix_reserved,
+ { "Framed IPv6 Prefix Reserved byte", "diameter.framed_ipv6_prefix_reserved",
+ FT_UINT8, BASE_HEX, NULL, 0,
+ NULL, HFILL }},
+ { &hf_framed_ipv6_prefix_length,
+ { "Framed IPv6 Prefix length (in bits)", "diameter.framed_ipv6_prefix_length",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }},
+ { &hf_framed_ipv6_prefix_bytes,
+ { "Framed IPv6 Prefix as a bytestring", "diameter.framed_ipv6_prefix_bytes",
+ 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 }}
};
gint *ett_base[] = {
@@ -1774,10 +1816,14 @@ proto_reg_handoff_diameter(void)
proto_diameter);
data_handle = find_dissector("data");
eap_handle = find_dissector("eap");
+
/* Register special decoding for some AVP:s */
+ /* AVP Code: 97 Framed-IPv6-Address */
+ dissector_add_uint("diameter.base", 97,
+ new_create_dissector_handle(dissect_diameter_base_framed_ipv6_prefix, proto_diameter));
/* AVP Code: 266 Vendor-Id */
dissector_add_uint("diameter.base", 266,
- new_create_dissector_handle(dissect_diameter_vendor_id, proto_diameter));
+ new_create_dissector_handle(dissect_diameter_vendor_id, proto_diameter));
/* AVP Code: 462 EAP-Payload */
dissector_add_uint("diameter.base", 462,
new_create_dissector_handle(dissect_diameter_eap_payload, proto_diameter));