aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorAnders Broman <anders.broman@ericsson.com>2011-12-25 11:25:39 +0000
committerAnders Broman <anders.broman@ericsson.com>2011-12-25 11:25:39 +0000
commitc4a88586f35c8b5ed814ff087de9c574c62822a4 (patch)
treeca4e50848ad1b7a79eb134c6d13c6a12d3cbfb65 /epan
parent43466d9eb1041dfd6f68e7522ae44f3270d38d58 (diff)
Use packet-radius.c to dissect embedded AVP:s.
svn path=/trunk/; revision=40288
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/packet-3g-a11.c327
-rw-r--r--epan/dissectors/packet-radius.c5
-rw-r--r--epan/dissectors/packet-radius.h1
3 files changed, 95 insertions, 238 deletions
diff --git a/epan/dissectors/packet-3g-a11.c b/epan/dissectors/packet-3g-a11.c
index 016cbfe642..65a98a4825 100644
--- a/epan/dissectors/packet-3g-a11.c
+++ b/epan/dissectors/packet-3g-a11.c
@@ -49,6 +49,8 @@
/* Include vendor id translation */
#include <epan/sminmpec.h>
+#include "packet-radius.h"
+
static int registration_request_msg =0;
/* Initialize the protocol and registered fields */
@@ -117,6 +119,9 @@ static int hf_a11_ase_reverse_mrru = -1;
static int hf_a11_ase_reverse_large_cids = -1;
static int hf_a11_ase_reverse_profile_count = -1;
static int hf_a11_ase_reverse_profile = -1;
+static int hf_a11_aut_flow_prof_sub_type = -1;
+static int hf_a11_aut_flow_prof_sub_type_len = -1;
+static int hf_a11_aut_flow_prof_sub_type_value = -1;
/* Forward QoS Information */
static int hf_a11_fqi_srid = -1;
@@ -190,6 +195,7 @@ static gint ett_a11_forward_rohc = -1;
static gint ett_a11_reverse_rohc = -1;
static gint ett_a11_forward_profile = -1;
static gint ett_a11_reverse_profile = -1;
+static gint ett_a11_aut_flow_profile_ids = -1;
/* Port used for Mobile IP based Tunneling Protocol (A11) */
@@ -393,65 +399,10 @@ static const value_string a11_airlink_types[]= {
};
-#define ATTRIBUTE_NAME_LEN_MAX 128
-#define ATTR_TYPE_NULL 0
-#define ATTR_TYPE_INT 1
-#define ATTR_TYPE_STR 2
-#define ATTR_TYPE_IPV4 3
-#define ATTR_TYPE_TYPE 4
-#define ATTR_TYPE_MSID 5
#define A11_MSG_MSID_ELEM_LEN_MAX 8
#define A11_MSG_MSID_LEN_MAX 15
-struct radius_attribute {
- char attrname[ATTRIBUTE_NAME_LEN_MAX];
- int type;
- int subtype;
- int bytes;
- int data_type;
-};
-
-static const struct radius_attribute attrs[]={
- {"Airlink Record", 26, 40, 4, ATTR_TYPE_TYPE},
- {"R-P Session ID", 26, 41, 4, ATTR_TYPE_INT},
- {"Airlink Sequence Number", 26, 42, 4, ATTR_TYPE_INT},
-#if 0
- {"MSID", 31, -1, 15, ATTR_TYPE_MSID},
-#endif
- {"Serving PCF", 26, 9, 4, ATTR_TYPE_IPV4},
- {"BSID", 26, 10, 12, ATTR_TYPE_STR},
- {"ESN", 26, 52, 15, ATTR_TYPE_STR},
- {"User Zone", 26, 11, 4, ATTR_TYPE_INT},
- {"Forward FCH Mux Option", 26, 12, 4, ATTR_TYPE_INT},
- {"Reverse FCH Mux Option", 26, 13, 4, ATTR_TYPE_INT},
- {"Forward Fundamental Rate (IOS 4.1)",26, 14, 4, ATTR_TYPE_INT},
- {"Reverse Fundamental Rate (IOS 4.1)",26, 15, 4, ATTR_TYPE_INT},
- {"Service Option", 26, 16, 4, ATTR_TYPE_INT},
- {"Forward Traffic Type", 26, 17, 4, ATTR_TYPE_INT},
- {"Reverse Traffic Type", 26, 18, 4, ATTR_TYPE_INT},
- {"FCH Frame Size", 26, 19, 4, ATTR_TYPE_INT},
- {"Forward FCH RC", 26, 20, 4, ATTR_TYPE_INT},
- {"Reverse FCH RC", 26, 21, 4, ATTR_TYPE_INT},
- {"DCCH Frame Size 0/5/20", 26, 50, 4, ATTR_TYPE_INT},
- {"Forward DCCH Mux Option", 26, 84, 4, ATTR_TYPE_INT},
- {"Reverse DCCH Mux Option", 26, 85, 4, ATTR_TYPE_INT},
- {"Forward DCCH RC", 26, 86, 4, ATTR_TYPE_INT},
- {"Reverse DCCH RC", 26, 87, 4, ATTR_TYPE_INT},
- {"Airlink Priority", 26, 39, 4, ATTR_TYPE_INT},
- {"Active Connection Time", 26, 49, 4, ATTR_TYPE_INT},
- {"Mobile Orig/Term Ind.", 26, 45, 4, ATTR_TYPE_INT},
- {"SDB Octet Count (Term.)", 26, 31, 4, ATTR_TYPE_INT},
- {"SDB Octet Count (Orig.)", 26, 32, 4, ATTR_TYPE_INT},
- {"ESN (Integer)", 26, 48, 4, ATTR_TYPE_INT},
- {"Sublink", 26, 108, 4, ATTR_TYPE_STR},
- {"MEID", 26, 116, 14, ATTR_TYPE_STR},
- {"Reverse PDCH RC", 26, 114, 2, ATTR_TYPE_INT},
- {"Flow ID Parameter", 26, 144, 4, ATTR_TYPE_INT},
- {"Granted QoS Parameters", 26, 132, 4, ATTR_TYPE_INT},
- {"Flow Status", 26, 145, 4, ATTR_TYPE_INT},
- {"Unknown", -1, -1, -1, ATTR_TYPE_NULL},
-};
/* XXXX ToDo This should be imported from packet-rohc.h */
static const value_string a11_rohc_profile_vals[] =
@@ -626,25 +577,14 @@ decode_sse(proto_tree* ext_tree, tvbuff_t* tvb, int offset, guint ext_len)
/* RADIUS attributed */
static void
-dissect_a11_radius( tvbuff_t *tvb, int offset, proto_tree *tree, int app_len)
+dissect_a11_radius( tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree, int app_len)
{
proto_item *ti;
proto_tree *radius_tree;
- gint radius_len;
- guint8 radius_type;
- guint8 radius_subtype;
- int attribute_type;
- gint attribute_len;
- gint offset0;
- gint radius_offset;
- guint i;
- guint8 *str_val;
- guint radius_vendor_id;
/* None of this really matters if we don't have a tree */
- if (!tree) return;
-
- offset0 = offset;
+ if (!tree)
+ return;
/* return if length of extension is not valid */
if (tvb_reported_length_remaining(tvb, offset) < 12) {
@@ -655,176 +595,68 @@ dissect_a11_radius( tvbuff_t *tvb, int offset, proto_tree *tree, int app_len)
radius_tree = proto_item_add_subtree(ti, ett_a11_radiuses);
- /* And, handle each record */
- while ((tvb_reported_length_remaining(tvb, offset) > 0)
- && ((offset-offset0) < (app_len-2)))
- {
-
- radius_type = tvb_get_guint8(tvb, offset);
- radius_len = tvb_get_guint8(tvb, offset + 1);
- if (radius_len < 2)
- {
- proto_tree_add_text(radius_tree, tvb, offset, 2,
- "Bogus RADIUS length %u, should be >= 2",
- radius_len);
- break;
- }
-
- if (radius_type == RADIUS_VENDOR_SPECIFIC)
- {
- if (radius_len < SKIP_HDR_LEN)
- {
- proto_tree_add_text(radius_tree, tvb, offset, radius_len,
- "Bogus RADIUS length %u, should be >= %u",
- radius_len, SKIP_HDR_LEN);
- offset += radius_len;
- continue;
- }
- radius_vendor_id = tvb_get_ntohl(tvb, offset +2);
-
- if(radius_vendor_id != VENDOR_THE3GPP2)
- {
- proto_tree_add_text(radius_tree, tvb, offset, radius_len,
- "Unknown Vendor-specific Attribute (Vendor Id: %x)", radius_vendor_id);
- offset += radius_len;
- continue;
- }
- }
- else
- {
-
- /**** ad-hoc ***/
- if(radius_type == 31)
- {
- str_val = tvb_get_ephemeral_string(tvb,offset+2,radius_len-2);
- proto_tree_add_text(radius_tree, tvb, offset, radius_len,
- "MSID: %s", str_val);
- }
- else if (radius_type == 46)
- {
- if (radius_len < (2+4))
- {
- proto_tree_add_text(radius_tree, tvb, offset, radius_len,
- "Bogus RADIUS length %u, should be >= %u",
- radius_len, 2+4);
- }
- else
- {
- proto_tree_add_text(radius_tree, tvb, offset, radius_len,
- "Acct Session Time: %d",tvb_get_ntohl(tvb,offset+2));
- }
- }
- else
- {
- proto_tree_add_text(radius_tree, tvb, offset, radius_len,
- "Unknown RADIUS Attributes (Type: %d)", radius_type);
- }
-
- offset += radius_len;
- continue;
- }
-
- offset += SKIP_HDR_LEN;
- radius_len -= SKIP_HDR_LEN;
- radius_offset = 0;
+ dissect_attribute_value_pairs(radius_tree, pinfo, tvb, offset, app_len-2);
- /* Detect Airlink Record Type */
- while (radius_len > radius_offset)
- {
- if (radius_len < (radius_offset + 2))
- {
- proto_tree_add_text(radius_tree, tvb, offset + radius_offset, 2,
- "Bogus RADIUS length %u, should be >= %u",
- radius_len + SKIP_HDR_LEN,
- radius_offset + 2 + SKIP_HDR_LEN);
- return;
- }
-
- radius_subtype = tvb_get_guint8(tvb, offset + radius_offset);
- attribute_len = tvb_get_guint8(tvb, offset + radius_offset + 1);
- if (attribute_len < 2)
- {
- proto_tree_add_text(radius_tree, tvb, offset + radius_offset, 2,
- "Bogus attribute length %u, should be >= 2", attribute_len);
- return;
- }
- if (attribute_len > (radius_len - radius_offset))
- {
- proto_tree_add_text(radius_tree, tvb, offset + radius_offset, 2,
- "Bogus attribute length %u, should be <= %u",
- attribute_len, radius_len - radius_offset);
- return;
- }
-
- attribute_type = -1;
- for(i = 0; i < NUM_ATTR; i++) {
- if (attrs[i].subtype == radius_subtype) {
- attribute_type = i;
- break;
- }
- }
-
- if ((radius_subtype == 48) &&
- (attribute_len == 0x0a))
- {
- /*
- * trying to compensate for Spec. screwups where
- * certain versions had subtype 48 being a 4 octet integer
- * and others had it being a 15 octet string!
- */
- str_val = tvb_get_ephemeral_string(tvb,offset+radius_offset+2,attribute_len-2);
- proto_tree_add_text(radius_tree, tvb, offset+radius_offset,
- attribute_len,
- "3GPP2: ESN-48 (String) (%s)", str_val);
- }
- else if(attribute_type >= 0) {
- switch(attrs[attribute_type].data_type) {
- case ATTR_TYPE_INT:
- proto_tree_add_text(radius_tree, tvb, offset + radius_offset,
- attribute_len, "3GPP2: %s (0x%04x)", attrs[attribute_type].attrname,
- tvb_get_ntohl(tvb,offset + radius_offset + 2));
- break;
- case ATTR_TYPE_IPV4:
- proto_tree_add_text(radius_tree, tvb, offset + radius_offset,
- attribute_len, "3GPP2: %s (%s)", attrs[attribute_type].attrname,
- tvb_ip_to_str(tvb, offset + radius_offset + 2));
- break;
- case ATTR_TYPE_TYPE:
- proto_tree_add_text(radius_tree, tvb, offset + radius_offset,
- attribute_len, "3GPP2: %s (%s)", attrs[attribute_type].attrname,
- val_to_str(tvb_get_ntohl(tvb,offset+radius_offset+2),
- a11_airlink_types,"Unknown"));
- break;
- case ATTR_TYPE_STR:
- str_val = tvb_get_ephemeral_string(tvb,offset+radius_offset+2,attribute_len-2);
- proto_tree_add_text(radius_tree, tvb, offset+radius_offset,
- attribute_len,
- "3GPP2: %s (%s)", attrs[attribute_type].attrname, str_val);
- break;
- case ATTR_TYPE_NULL:
- break;
- default:
- proto_tree_add_text(radius_tree, tvb, offset+radius_offset, attribute_len,
- "RADIUS: %s", attrs[attribute_type].attrname);
- break;
- }
- }
- else {
- proto_tree_add_text(radius_tree, tvb, offset+radius_offset, attribute_len,
- "RADIUS: Unknown 3GPP2 Attribute (Type:%d, SubType:%d)",
- radius_type,radius_subtype);
- }
+}
- radius_offset += attribute_len;
- }
- offset += radius_len;
+static const value_string a11_aut_flow_prof_subtype_vals[] = {
+ {0x1, "ProfileID-Forward"},
+ {0x2, "ProfileID-Reverse"},
+ {0x3, "ProfileID-Bi-direction"},
+ {0, NULL},
+};
- }
+/* X.S0011-005-D v2.0 Authorized Flow Profile IDs for the User */
+static const gchar *dissect_3gpp2_radius_aut_flow_profile_ids(proto_tree * tree, tvbuff_t * tvb, packet_info* pinfo _U_)
+{
+ proto_tree* sub_tree;
+ int offset = 0;
+ proto_item *item;
+ guint8 sub_type, sub_type_length;
+ guint32 value;
+
+ while (tvb_length_remaining(tvb,offset)>0){
+ sub_type = tvb_get_guint8(tvb,offset);
+ sub_type_length = tvb_get_guint8(tvb,offset+1);
+ switch(sub_type_length){
+ case 3:
+ /* value is 1 octet */
+ value = tvb_get_guint8(tvb,offset+2);
+ break;
+ case 4:
+ /* value is 2 octets */
+ value = tvb_get_ntohs(tvb,offset+2);
+ break;
+ case 5:
+ /* value is 3 octets */
+ value = tvb_get_ntoh24(tvb,offset+2);
+ break;
+ case 6:
+ /* value is 4 octets */
+ value = tvb_get_ntohl(tvb,offset+2);
+ break;
+ default:
+ break;
+ }
+ item = proto_tree_add_text(tree, tvb, offset, sub_type_length, "%s = %u",
+ val_to_str(sub_type, a11_aut_flow_prof_subtype_vals, "Unknown"), value);
+ sub_tree = proto_item_add_subtree(item, ett_a11_aut_flow_profile_ids);
+
+ sub_type = tvb_get_guint8(tvb,offset);
+ proto_tree_add_item(sub_tree, hf_a11_aut_flow_prof_sub_type, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ proto_tree_add_item(sub_tree, hf_a11_aut_flow_prof_sub_type_len, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ proto_tree_add_item(sub_tree, hf_a11_aut_flow_prof_sub_type_value, tvb, offset, sub_type_length-2, ENC_BIG_ENDIAN);
+
+ offset = offset+sub_type_length-2;
+ }
+
+ return "";
}
-
/* Code to dissect Additional Session Info */
static void dissect_ase(tvbuff_t* tvb, int offset, guint ase_len, proto_tree* ext_tree)
{
@@ -1264,7 +1096,7 @@ static void dissect_rev_qosinfo(tvbuff_t* tvb, int offset, proto_tree* ext_tree)
/* Code to dissect Subscriber QoS Profile */
-static void dissect_subscriber_qos_profile(tvbuff_t* tvb, int offset, int ext_len, proto_tree* ext_tree)
+static void dissect_subscriber_qos_profile(tvbuff_t* tvb, packet_info *pinfo, int offset, int ext_len, proto_tree* ext_tree)
{
proto_tree* exts_tree;
@@ -1283,6 +1115,8 @@ static void dissect_subscriber_qos_profile(tvbuff_t* tvb, int offset, int ext_le
proto_tree_add_item
(exts_tree, hf_a11_subsciber_profile, tvb, offset,
qos_profile_len, ENC_NA);
+
+ dissect_attribute_value_pairs(exts_tree, pinfo, tvb, offset, qos_profile_len);
}
}
@@ -1372,7 +1206,7 @@ static void dissect_rev_qosupdate_info(tvbuff_t* tvb, int offset, proto_tree* ex
/* Code to dissect extensions */
static void
-dissect_a11_extensions( tvbuff_t *tvb, int offset, proto_tree *tree)
+dissect_a11_extensions( tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree)
{
proto_item *ti;
proto_tree *exts_tree;
@@ -1507,7 +1341,7 @@ dissect_a11_extensions( tvbuff_t *tvb, int offset, proto_tree *tree)
ext_len -= 2;
if(apptype == 0x0101) {
if (tvb_reported_length_remaining(tvb, offset) > 0) {
- dissect_a11_radius(tvb, offset, ext_tree, ext_len + 2);
+ dissect_a11_radius(tvb, pinfo, offset, ext_tree, ext_len + 2);
}
}
break;
@@ -1577,7 +1411,7 @@ dissect_a11_extensions( tvbuff_t *tvb, int offset, proto_tree *tree)
dissect_rev_qosinfo(tvb, offset, ext_tree);
break;
case 0x0D03:
- dissect_subscriber_qos_profile(tvb, offset, ext_len, ext_tree);
+ dissect_subscriber_qos_profile(tvb, pinfo, offset, ext_len, ext_tree);
break;
case 0x0DFE:
dissect_fwd_qosupdate_info(tvb, offset, ext_tree);
@@ -1914,7 +1748,7 @@ dissect_a11( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
if (tree && a11_tree) {
if (tvb_reported_length_remaining(tvb, offset) > 0)
- dissect_a11_extensions(tvb, offset, a11_tree);
+ dissect_a11_extensions(tvb, pinfo, offset, a11_tree);
}
return tvb_length(tvb);
} /* dissect_a11 */
@@ -2431,6 +2265,21 @@ proto_register_a11(void)
FT_UINT16, BASE_DEC, VALS(a11_rohc_profile_vals), 0,
NULL, HFILL }
},
+ { &hf_a11_aut_flow_prof_sub_type,
+ { "Sub type", "a11.aut_flow_prof.sub_type",
+ FT_UINT8, BASE_DEC, VALS(a11_aut_flow_prof_subtype_vals), 0,
+ NULL, HFILL }
+ },
+ { &hf_a11_aut_flow_prof_sub_type_len,
+ { "Length", "a11.aut_flow_prof.length",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_a11_aut_flow_prof_sub_type_value,
+ { "Value", "a11.aut_flow_prof.value",
+ FT_UINT32, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
};
/* Setup protocol subtree array */
@@ -2460,6 +2309,7 @@ proto_register_a11(void)
&ett_a11_reverse_rohc,
&ett_a11_forward_profile,
&ett_a11_reverse_profile,
+ &ett_a11_aut_flow_profile_ids,
};
/* Register the protocol name and description */
@@ -2480,4 +2330,7 @@ proto_reg_handoff_a11(void)
a11_handle = find_dissector("a11");
dissector_add_uint("udp.port", UDP_PORT_3GA11, a11_handle);
+
+ /* 3GPP2-Authorized-Flow-Profile-IDs(131) */
+ radius_register_avp_dissector(VENDOR_THE3GPP2, 131, dissect_3gpp2_radius_aut_flow_profile_ids);
}
diff --git a/epan/dissectors/packet-radius.c b/epan/dissectors/packet-radius.c
index 054393b53c..82e135cfa5 100644
--- a/epan/dissectors/packet-radius.c
+++ b/epan/dissectors/packet-radius.c
@@ -888,7 +888,7 @@ static void vsa_buffer_table_destroy(void *table) {
}
-static void dissect_attribute_value_pairs(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset, guint length) {
+void dissect_attribute_value_pairs(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset, guint length) {
proto_item* item;
gboolean last_eap = FALSE;
guint8* eap_buffer = NULL;
@@ -900,6 +900,9 @@ static void dissect_attribute_value_pairs(proto_tree *tree, packet_info *pinfo,
GHashTable* vsa_buffer_table = NULL;
+ /* Forces load of header fields, if not already done so */
+ DISSECTOR_ASSERT(proto_registrar_get_byname("radius.code"));
+
/*
* In case we throw an exception, clean up whatever stuff we've
* allocated (if any).
diff --git a/epan/dissectors/packet-radius.h b/epan/dissectors/packet-radius.h
index 5d1aa83722..4702913f95 100644
--- a/epan/dissectors/packet-radius.h
+++ b/epan/dissectors/packet-radius.h
@@ -132,6 +132,7 @@ radius_attr_dissector_t radius_combo_ip;
radius_attr_dissector_t radius_tlv;
extern void radius_register_avp_dissector(guint32 vendor_id, guint32 attribute_id, radius_avp_dissector_t dissector);
+void dissect_attribute_value_pairs(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset, guint length);
/* from radius_dict.l */
gboolean radius_load_dictionary (radius_dictionary_t* dict, gchar* directory, const gchar* filename, gchar** err_str);