aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorLuis Ontanon <luis.ontanon@gmail.com>2007-07-20 00:15:17 +0000
committerLuis Ontanon <luis.ontanon@gmail.com>2007-07-20 00:15:17 +0000
commit5e290061f2690d39bad202179927049601bb4ca5 (patch)
treed98e9a1b037b2ebda595fd66dfabf9b3472f7d97 /epan
parentfae881dc4519ee7198d6e91955c0792a8cbb5e5f (diff)
- <?avp-proto and <?type-proto to instruct about which dissector to use for a given type or avp
- dissect timestamps - add all the avps that were commented out in the dictionary svn path=/trunk/; revision=22360
Diffstat (limited to 'epan')
-rw-r--r--epan/diam_dict.h8
-rw-r--r--epan/diam_dict.l67
-rw-r--r--epan/dissectors/packet-diameter.c147
3 files changed, 179 insertions, 43 deletions
diff --git a/epan/diam_dict.h b/epan/diam_dict.h
index a6b16c9022..83b3a73d3e 100644
--- a/epan/diam_dict.h
+++ b/epan/diam_dict.h
@@ -66,12 +66,20 @@ typedef struct _ddict_cmd_t {
struct _ddict_cmd_t* next;
} ddict_cmd_t;
+typedef struct _ddict_xmlpi_t {
+ char* name;
+ char* key;
+ char* value;
+ struct _ddict_xmlpi_t* next;
+} ddict_xmlpi_t;
+
typedef struct _ddict_t {
ddict_application_t* applications;
ddict_vendor_t* vendors;
ddict_cmd_t* cmds;
ddict_typedefn_t* typedefns;
ddict_avp_t* avps;
+ ddict_xmlpi_t* xmlpis;
} ddict_t;
extern void ddict_print(FILE* fh, ddict_t* d);
diff --git a/epan/diam_dict.l b/epan/diam_dict.l
index ecf4ac28d3..8ed7385172 100644
--- a/epan/diam_dict.l
+++ b/epan/diam_dict.l
@@ -42,6 +42,7 @@
#include <errno.h>
#include <stdlib.h>
#include <stdarg.h>
+#include "emem.h"
#include "diam_dict.h"
typedef struct entity_t {
@@ -80,6 +81,7 @@ static ddict_gavp_t* gavp;
static ddict_typedefn_t* typedefn;
static ddict_cmd_t* cmd;
static ddict_vendor_t* vnd;
+static ddict_xmlpi_t* xmlpi;
static ddict_application_t* last_appl;
static ddict_avp_t* last_avp;
@@ -88,6 +90,7 @@ static ddict_gavp_t* last_gavp;
static ddict_typedefn_t* last_typedefn;
static ddict_cmd_t* last_cmd;
static ddict_vendor_t* last_vnd;
+static ddict_xmlpi_t* last_xmlpi;
static char** attr_str;
static unsigned* attr_uint;
@@ -101,6 +104,8 @@ static FILE* ddict_open(const char*, const char*);
xmlpi_start [[:blank:] \r\n]*<\?[[:blank:] \r\n]*
xmlpi_end [[:blank:] \r\n]*\?>[[:blank:] \r\n]*
+xmlpi_key_attr [[:blank:] \r\n]*key[[:blank:] \r\n]*=[[:blank:] \r\n]*\042
+xmlpi_value_attr [[:blank:] \r\n]*value[[:blank:] \r\n]*=[[:blank:] \r\n]*\042
comment_start [[:blank:] \r\n]*<!--[[:blank:] \r\n]*
comment_end [[:blank:] \r\n]*-->[[:blank:] \r\n]*
@@ -117,11 +122,11 @@ doctype_end [[:blank:] \r\n]*\][[:blank:] \r\n]*>[[:blank:] \r\n]*
start_entity [[:blank:] \r\n]*<\!ENTITY[[:blank:] \r\n]*
system [[:blank:] \r\n]*SYSTEM[[:blank:] \r\n]*\042
-entityname [a-z0-9]+
+entityname [a-z0-9-]+
ndquot [^\042]+
end_entity \042[[:blank:] \r\n]*>[[:blank:] \r\n]*
-entity \&[a-z0-9]+;
+entity \&[a-z0-9-]+;
any .
@@ -175,7 +180,7 @@ description_attr description=\042
%S LOADING LOADING_COMMENT LOADING_XMLPI ENTITY GET_SYSTEM GET_FILE END_ENTITY
%S GET_ATTR GET_UINT_ATTR END_ATTR OUTSIDE IN_DICT IN_APPL IN_AVP APPL_ATTRS IGNORE_ATTR
%S TYPE_ATTRS GAVP_ATTRS ENUM_ATTRS AVP_ATTRS VENDOR_ATTRS COMMAND_ATTRS TYPEDEFN_ATTRS
-
+%S XMLPI_ATTRS XMLPI_GETKEY XMLPI_GETVAL XMLPI_ENDATTR
%%
<LOADING>{doctype} ;
<LOADING>{doctype_end} ;
@@ -185,8 +190,29 @@ description_attr description=\042
<LOADING_COMMENT>{comment_end} BEGIN LOADING;
<LOADING>{xmlpi_start} BEGIN LOADING_XMLPI;
-<LOADING_XMLPI>. ;
-<LOADING_XMLPI>{xmlpi_end} BEGIN LOADING;
+<LOADING_XMLPI>{whitespace} ;
+<LOADING_XMLPI>{entityname} {
+ xmlpi = g_malloc(sizeof(ddict_xmlpi_t));
+ xmlpi->name = g_strdup(yytext);
+ xmlpi->key = NULL;
+ xmlpi->value = NULL;
+ xmlpi->next = NULL;
+
+ if (!dict->xmlpis) last_xmlpi = dict->xmlpis = xmlpi;
+ else last_xmlpi = last_xmlpi->next = xmlpi;
+
+ BEGIN XMLPI_ATTRS;
+}
+
+<XMLPI_ATTRS>{xmlpi_key_attr} BEGIN XMLPI_GETKEY;
+<XMLPI_GETKEY>{ndquot} { xmlpi->key = strdup(yytext); BEGIN XMLPI_ATTRS; }
+
+<XMLPI_ATTRS>{xmlpi_value_attr} BEGIN XMLPI_GETVAL;
+<XMLPI_GETVAL>{ndquot} { xmlpi->value = strdup(yytext); BEGIN XMLPI_ATTRS; }
+
+<XMLPI_ATTRS>.
+<XMLPI_ATTRS>{xmlpi_end} BEGIN LOADING;
+
<LOADING>{start_entity} BEGIN ENTITY;
<ENTITY>{entityname} {
@@ -307,12 +333,6 @@ description_attr description=\042
<OUTSIDE>{dictionary_start} {
D(("dictionary_start\n"));
- dict = g_malloc(sizeof(ddict_t));
- dict->applications = NULL;
- dict->cmds = NULL;
- dict->vendors = NULL;
- dict->typedefns = NULL;
- dict->avps = NULL;
BEGIN IN_DICT;
}
@@ -604,15 +624,15 @@ ddict_t* ddict_scan(const char* system_directory, const char* filename, int dbg)
write_ptr = NULL;
read_ptr = NULL;
+
+ dict = g_malloc(sizeof(ddict_t));
+ dict->applications = NULL;
+ dict->cmds = NULL;
+ dict->vendors = NULL;
+ dict->typedefns = NULL;
+ dict->avps = NULL;
+ dict->xmlpis = NULL;
- ents.next = NULL;
- current_yyinput = file_input;
- BEGIN LOADING;
- yylex();
-
- D(("\n---------------\n%s\n------- %d -------\n",strbuf,len_strbuf));
-
- dict = NULL;
appl = NULL;
avp = NULL;
enumitem = NULL;
@@ -620,6 +640,7 @@ ddict_t* ddict_scan(const char* system_directory, const char* filename, int dbg)
typedefn = NULL;
cmd = NULL;
vnd = NULL;
+ xmlpi = NULL;
last_appl = NULL;
last_avp = NULL;
@@ -628,7 +649,15 @@ ddict_t* ddict_scan(const char* system_directory, const char* filename, int dbg)
last_typedefn = NULL;
last_cmd = NULL;
last_vnd = NULL;
+ last_xmlpi = NULL;
+ ents.next = NULL;
+ current_yyinput = file_input;
+ BEGIN LOADING;
+ yylex();
+
+ D(("\n---------------\n%s\n------- %d -------\n",strbuf,len_strbuf));
+
current_yyinput = string_input;
BEGIN OUTSIDE;
diff --git a/epan/dissectors/packet-diameter.c b/epan/dissectors/packet-diameter.c
index 5db7ed5efd..b29f8d1a4c 100644
--- a/epan/dissectors/packet-diameter.c
+++ b/epan/dissectors/packet-diameter.c
@@ -59,10 +59,9 @@
#include <epan/expert.h>
#include "packet-tcp.h"
#include "packet-sip.h"
+#include "packet-ntp.h"
#include "diam_dict.h"
-#define NTP_TIME_DIFF (2208988800U)
-
#define TCP_PORT_DIAMETER 3868
#define SCTP_PORT_DIAMETER 3868
@@ -139,7 +138,7 @@ typedef struct _diam_dictionary_t {
value_string* commands;
} diam_dictionary_t;
-typedef diam_avp_t* (*avp_constructor_t)(const avp_type_t*, guint32, const diam_vnd_t*, const char*, const value_string*);
+typedef diam_avp_t* (*avp_constructor_t)(const avp_type_t*, guint32, const diam_vnd_t*, const char*, const value_string*, void*);
struct _avp_type_t {
char* name;
@@ -166,6 +165,18 @@ typedef struct _address_avp_t {
int hf_other;
} address_avp_t;
+typedef enum {
+ REASEMBLE_NEVER = 0,
+ REASEMBLE_AT_END,
+ REASEMBLE_BY_LENGTH
+} avp_reassemble_mode_t;
+
+typedef struct _proto_avp_t {
+ char* name;
+ dissector_handle_t handle;
+ avp_reassemble_mode_t reassemble_mode;
+} proto_avp_t;
+
static const char* simple_avp(diam_ctx_t*, diam_avp_t*, tvbuff_t*);
static value_string no_vs[] = {{0, NULL} };
@@ -176,6 +187,8 @@ static diam_avp_t unknown_avp = {0, &unknown_vendor, simple_avp, simple_avp, -1,
static diam_dictionary_t dictionary = { NULL, NULL, NULL, NULL };
static struct _build_dict build_dict;
static value_string* vnd_short_vs;
+static dissector_handle_t data_handle;
+
static const true_false_string reserved_set = {
"Set",
"Unset"
@@ -414,6 +427,43 @@ static const char* address_rfc_avp(diam_ctx_t* c, diam_avp_t* a, tvbuff_t* tvb)
return label;
}
+static const char* proto_avp(diam_ctx_t* c, diam_avp_t* a, tvbuff_t* tvb)
+{
+ proto_avp_t* t = a->type_data;
+
+ col_set_writable(c->pinfo->cinfo, FALSE);
+
+ if (!t->handle) {
+ t->handle = find_dissector(t->name);
+ if(!t->handle) t->handle = data_handle;
+ }
+
+ call_dissector(t->handle, tvb, c->pinfo, c->tree);
+
+ return "";
+}
+
+static const char* time_avp(diam_ctx_t* c, diam_avp_t* a, tvbuff_t* tvb) {
+ int len = tvb_length_remaining(tvb,0);
+ guint8 ntptime[8] = {0,0,0,0,0,0,0,0};
+ char* label;
+ proto_item* pi;
+
+ if ( len != 4 ) {
+ proto_item* pi = proto_tree_add_text(c->tree, tvb, 0, 4,
+ "Error! AVP value MUST be 4 bytes");
+ expert_add_info_format(c->pinfo, pi, PI_MALFORMED, PI_NOTE,
+ "Bad Timestamp Length (%u)", len);
+ return "[Malformed]";
+ }
+
+ pi = proto_tree_add_item(c->tree, (a->hf_value), tvb, 0, 4, FALSE);
+ tvb_memcpy(tvb,ntptime,0,4);
+ label = ntp_fmt_ts(ntptime);
+ proto_item_append_text(pi," %s",label);
+ return label;
+}
+
static const char* address_v16_avp(diam_ctx_t* c, diam_avp_t* a, tvbuff_t* tvb) {
char* label = ep_alloc(ITEM_LABEL_LENGTH+1);
address_avp_t* t = a->type_data;
@@ -684,7 +734,8 @@ static diam_avp_t* build_address_avp(const avp_type_t* type _U_,
guint32 code,
const diam_vnd_t* vendor,
const char* name,
- const value_string* vs _U_) {
+ const value_string* vs _U_,
+ void* data _U_) {
diam_avp_t* a = g_malloc0(sizeof(diam_avp_t));
address_avp_t* t = g_malloc(sizeof(address_avp_t));
gint* ettp = &(t->ett);
@@ -726,12 +777,39 @@ static diam_avp_t* build_address_avp(const avp_type_t* type _U_,
return a;
}
+static diam_avp_t* build_proto_avp(const avp_type_t* type _U_,
+ guint32 code,
+ const diam_vnd_t* vendor,
+ const char* name _U_,
+ const value_string* vs _U_,
+ void* data) {
+ diam_avp_t* a = g_malloc0(sizeof(diam_avp_t));
+ proto_avp_t* t = g_malloc0(sizeof(proto_avp_t));
+ gint* ettp = &(a->ett);
+
+ a->code = code;
+ a->vendor = vendor;
+ a->dissector_v16 = proto_avp;
+ a->dissector_rfc = proto_avp;
+ a->ett = -1;
+ a->hf_value = -2;
+ a->type_data = t;
+
+ t->name = data;
+ t->handle = NULL;
+ t->reassemble_mode = 0;
+
+ g_array_append_vals(build_dict.ett,&ettp,1);
+
+ return a;
+}
static diam_avp_t* build_simple_avp(const avp_type_t* type,
guint32 code,
const diam_vnd_t* vendor,
const char* name,
- const value_string* vs) {
+ const value_string* vs,
+ void* data _U_) {
diam_avp_t* a = g_malloc0(sizeof(diam_avp_t));
a->code = code;
a->vendor = vendor;
@@ -746,26 +824,28 @@ static diam_avp_t* build_simple_avp(const avp_type_t* type,
}
+
static const avp_type_t basic_types[] = {
- {"octetstring" , simple_avp , simple_avp , FT_BYTES , BASE_NONE , build_simple_avp },
- {"utf8string" , simple_avp , simple_avp , FT_STRING , BASE_NONE , build_simple_avp },
- {"grouped" , grouped_avp , grouped_avp , FT_BYTES , BASE_NONE , build_simple_avp },
- {"integer32" , simple_avp , simple_avp , FT_INT32 , BASE_DEC , build_simple_avp },
- {"unsigned32" , simple_avp , simple_avp , FT_UINT32 , BASE_DEC , build_simple_avp },
- {"integer64" , simple_avp , simple_avp , FT_INT64 , BASE_DEC , build_simple_avp },
- {"unsigned64" , simple_avp , simple_avp , FT_UINT64 , BASE_DEC , build_simple_avp },
- {"float32" , simple_avp , simple_avp , FT_FLOAT , BASE_DEC , build_simple_avp },
- {"float64" , simple_avp , simple_avp , FT_DOUBLE , BASE_DEC , build_simple_avp },
+ {"octetstring" , simple_avp , simple_avp , FT_BYTES , BASE_NONE , build_simple_avp },
+ {"utf8string" , simple_avp , simple_avp , FT_STRING , BASE_NONE , build_simple_avp },
+ {"grouped" , grouped_avp , grouped_avp , FT_BYTES , BASE_NONE , build_simple_avp },
+ {"integer32" , simple_avp , simple_avp , FT_INT32 , BASE_DEC , build_simple_avp },
+ {"unsigned32" , simple_avp , simple_avp , FT_UINT32 , BASE_DEC , build_simple_avp },
+ {"integer64" , simple_avp , simple_avp , FT_INT64 , BASE_DEC , build_simple_avp },
+ {"unsigned64" , simple_avp , simple_avp , FT_UINT64 , BASE_DEC , build_simple_avp },
+ {"float32" , simple_avp , simple_avp , FT_FLOAT , BASE_DEC , build_simple_avp },
+ {"float64" , simple_avp , simple_avp , FT_DOUBLE , BASE_DEC , build_simple_avp },
{"ipaddress" , NULL , NULL , FT_NONE , BASE_NONE , build_address_avp },
- {"time" , simple_avp , simple_avp , FT_BYTES , BASE_NONE , build_simple_avp },
-/* {"diameteruri" , simple_avp , simple_avp , FT_STRING , BASE_NONE , build_simple_avp },
- {"diameteridentity" , simple_avp , simple_avp , FT_BYTES , BASE_NONE , build_simple_avp },
- {"ipfilterrule" , simple_avp , simple_avp , FT_BYTES , BASE_NONE , build_simple_avp },
- {"qosfilterrule" , simple_avp , simple_avp , FT_BYTES , BASE_NONE , build_simple_avp },
- {"mipregistrationrequest" , simple_avp , simple_avp , FT_BYTES , BASE_NONE , build_simple_avp }, */
+ {"diameteruri" , simple_avp , simple_avp , FT_STRING , BASE_NONE , build_simple_avp },
+ {"diameteridentity" , simple_avp , simple_avp , FT_STRING , BASE_NONE , build_simple_avp },
+ {"ipfilterrule" , simple_avp , simple_avp , FT_STRING , BASE_NONE , build_simple_avp },
+ {"qosfilterrule" , simple_avp , simple_avp , FT_STRING , BASE_NONE , build_simple_avp },
+ {"time" , time_avp , time_avp , FT_UINT32 , BASE_DEC , build_simple_avp },
{NULL, NULL, NULL, FT_NONE, BASE_NONE, NULL }
};
+
+
static guint strcase_hash(gconstpointer key) {
char* k = ep_strdup(key);
g_strdown(k);
@@ -895,7 +975,9 @@ extern int dictionary_load(void) {
ddict_enum_t* e;
value_string* vs = NULL;
const char* vend = a->vendor ? a->vendor : "None";
-
+ ddict_xmlpi_t* x;
+ void* avp_data = NULL;
+
if ((vnd = g_hash_table_lookup(vendors,vend))) {
value_string vndvs = {a->code,a->name};
g_array_append_val(vnd->vs_avps,vndvs);
@@ -914,11 +996,26 @@ extern int dictionary_load(void) {
vs = (void*)arr->data;
}
- if (! a->type || ! ( type = g_hash_table_lookup(build_dict.types,a->type) ) ) {
- type = bytes;
+ type = NULL;
+
+ for( x = d->xmlpis; x; x = x->next ) {
+ if ( (strcase_equal(x->name,"avp-proto") && strcase_equal(x->key,a->name))
+ || (a->type && strcase_equal(x->name,"type-proto") && strcase_equal(x->key,a->type))
+ ) {
+ static avp_type_t proto_type = {"proto", proto_avp, proto_avp, FT_UINT32, BASE_NONE, build_proto_avp};
+ type = &proto_type;
+
+ avp_data = x->value;
+ break;
+ }
}
- avp = type->build( type, a->code, vnd, a->name, vs);
+ if ( (!type) && a->type )
+ type = g_hash_table_lookup(build_dict.types,a->type);
+
+ if (!type) type = bytes;
+
+ avp = type->build( type, a->code, vnd, a->name, vs, avp_data);
g_hash_table_insert(build_dict.avps, a->name, avp);
{
@@ -948,6 +1045,8 @@ proto_reg_handoff_diameter(void)
static dissector_handle_t diameter_tcp_handle;
static dissector_handle_t diameter_handle;
+ data_handle = find_dissector("data");
+
if (!Initialized) {
diameter_tcp_handle = create_dissector_handle(dissect_diameter_tcp,
proto_diameter);