From 5e290061f2690d39bad202179927049601bb4ca5 Mon Sep 17 00:00:00 2001 From: Luis Ontanon Date: Fri, 20 Jul 2007 00:15:17 +0000 Subject: [PATCH] - + + + + @@ -1608,18 +1612,17 @@ - + + + + + + + + + + + @@ -1676,66 +1679,65 @@ + + -1003 Charging-Rule-Definition Grouped + + + + + + + + + + + + + + - + + + + + + + @@ -1745,28 +1747,26 @@ Note: The AVP codes from 1119 to 1199 are reserved for TS 29.140 - + + + + + + + + + + + + + + + + + + + + @@ -1849,24 +1849,26 @@ Note: The AVP codes from 1119 to 1199 are reserved for TS 29.140 + + + + + + + + + + + + + + + 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 #include #include +#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]* @@ -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 %% {doctype} ; {doctype_end} ; @@ -185,8 +190,29 @@ description_attr description=\042 {comment_end} BEGIN LOADING; {xmlpi_start} BEGIN LOADING_XMLPI; -. ; -{xmlpi_end} BEGIN LOADING; +{whitespace} ; +{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_key_attr} BEGIN XMLPI_GETKEY; +{ndquot} { xmlpi->key = strdup(yytext); BEGIN XMLPI_ATTRS; } + +{xmlpi_value_attr} BEGIN XMLPI_GETVAL; +{ndquot} { xmlpi->value = strdup(yytext); BEGIN XMLPI_ATTRS; } + +. +{xmlpi_end} BEGIN LOADING; + {start_entity} BEGIN ENTITY; {entityname} { @@ -307,12 +333,6 @@ description_attr description=\042 {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 #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);