Add Address decoding, two debug environment variables (WIRESHARK_DEBUG_DIAM_DICT_PARSER and WIRESHARK_DUMP_DIAM_DICT) and fix some issues pointed out by Martin

svn path=/trunk/; revision=22345
This commit is contained in:
Luis Ontanon 2007-07-17 22:19:54 +00:00
parent 776820f3fb
commit e27b40f589
3 changed files with 275 additions and 59 deletions

View File

@ -75,7 +75,7 @@ typedef struct _ddict_t {
} ddict_t;
extern void ddict_print(FILE* fh, ddict_t* d);
extern ddict_t* ddict_scan(const char* directory, const char* filename);
extern ddict_t* ddict_scan(const char* directory, const char* filename, int dbg);
extern void ddict_free(ddict_t* d);
#endif

View File

@ -41,6 +41,7 @@
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <stdarg.h>
#include "diam_dict.h"
typedef struct entity_t {
@ -53,11 +54,7 @@ typedef struct entity_t {
#define ATTR_STR(cont) do { D(("attr_str " #cont "\t" )); attr_str = &(cont); yy_push_state(GET_ATTR); } while(0)
#define IGNORE() do { D(("ignore: %s\t",yytext)); yy_push_state(IGNORE_ATTR); } while(0)
#ifdef DEBUG_DIAM_DICT
#define D(args) do { printf args ; fflush(stdout); } while(0)
#else
#define D(args)
#endif
#define D(args) ddict_debug args
#ifdef _WIN32
#define DDICT_DIRSEP "\\"
@ -95,6 +92,7 @@ static ddict_vendor_t* last_vnd;
static char** attr_str;
static unsigned* attr_uint;
static void ddict_debug(const char* fmt, ...);
static void append_to_buffer(char* txt, int len);
static FILE* ddict_open(const char*, const char*);
@ -500,6 +498,19 @@ description_attr description=\042
%%
int debugging = 0;
static void ddict_debug(const char* fmt, ...) {
va_list ap;
va_start(ap, fmt);
if (debugging) vfprintf(stderr, fmt, ap);
va_end(ap);
fflush(stderr);
}
static char* strbuf = NULL;
static char* write_ptr = NULL;
static char* read_ptr = NULL;
@ -559,7 +570,6 @@ static size_t string_input(char* buf, size_t max) {
static FILE* ddict_open(const char* system_directory, const char* filename) {
FILE* fh;
char* fname;
if (system_directory) {
int len = strlen(system_directory) + strlen(filename) + strlen(DDICT_DIRSEP) + 1;
fname = g_malloc(len);
@ -578,8 +588,10 @@ static FILE* ddict_open(const char* system_directory, const char* filename) {
return fh;
}
ddict_t* ddict_scan(const char* system_directory, const char* filename) {
ddict_t* ddict_scan(const char* system_directory, const char* filename, int dbg) {
debugging = dbg;
sys_dir = system_directory;
yyin = ddict_open(sys_dir,filename);
@ -756,7 +768,7 @@ int main(int argc, char** argv) {
return 1;
}
d = ddict_scan(dname,fname);
d = ddict_scan(dname,fname,1);
ddict_print(stdout, d);

View File

@ -101,6 +101,7 @@
typedef struct _diam_ctx_t {
proto_tree* tree;
packet_info* pinfo;
emem_tree_t* avps;
gboolean version_rfc;
} diam_ctx_t;
@ -110,9 +111,16 @@ typedef struct _avp_type_t avp_type_t;
typedef const char* (*diam_avp_dissector_t)(diam_ctx_t*, diam_avp_t*, tvbuff_t*);
typedef struct _diam_vnd_t {
guint32 code;
GArray* vs_avps;
GArray* vs_cmds;
} diam_vnd_t;
struct _diam_avp_t {
guint32 code;
guint32 vendor;
const diam_vnd_t* vendor;
diam_avp_dissector_t dissector_v16;
diam_avp_dissector_t dissector_rfc;
@ -121,12 +129,6 @@ struct _diam_avp_t {
void* type_data;
};
typedef struct _diam_vnd_t {
guint32 code;
GArray* vs_avps;
GArray* vs_cmds;
} diam_vnd_t;
#define VND_AVP_VS(v) ((value_string*)((v)->vs_avps->data))
#define VND_CMD_VS(v) ((value_string*)((v)->vs_cmds->data))
@ -137,7 +139,7 @@ typedef struct _diam_dictionary_t {
value_string* commands;
} diam_dictionary_t;
typedef diam_avp_t* (*avp_constructor_t)(const avp_type_t*, guint32 code, guint32 vendor, const char* name, value_string* vs);
typedef diam_avp_t* (*avp_constructor_t)(const avp_type_t*, guint32, const diam_vnd_t*, const char*, const value_string*);
struct _avp_type_t {
char* name;
@ -155,13 +157,22 @@ struct _build_dict {
GHashTable* avps;
};
typedef struct _address_avp_t {
gint ett;
int hf_address_type;
int hf_ipv4;
int hf_ipv6;
int hf_other;
} address_avp_t;
static const char* simple_avp(diam_ctx_t*, diam_avp_t*, tvbuff_t*);
static diam_avp_t unknown_avp = {0, 0, simple_avp, simple_avp, -1, -1, NULL };
static value_string no_vs[] = {{0, NULL} };
static GArray no_garr = { (void*)no_vs, 1 };
static diam_vnd_t unknown_vendor = { 0, &no_garr, &no_garr };
static diam_vnd_t unknown_vendor = { 0xffffffff, &no_garr, &no_garr };
static diam_vnd_t no_vnd = { 0, NULL, NULL };
static diam_avp_t unknown_avp = {0, &unknown_vendor, simple_avp, simple_avp, -1, -1, NULL };
static diam_dictionary_t dictionary = { NULL, NULL, NULL, NULL };
static struct _build_dict build_dict;
static value_string* vnd_short_vs;
@ -170,6 +181,34 @@ static const true_false_string reserved_set = {
"Unset"
};
static const value_string diameter_avp_data_addrfamily_vals[]= {
{1,"IPv4"},
{2,"IPv6"},
{3,"NSAP"},
{4,"HDLC"},
{5,"BBN"},
{6,"IEEE-802"},
{7,"E-163"},
{8,"E-164"},
{9,"F-69"},
{10,"X-121"},
{11,"IPX"},
{12,"Appletalk"},
{13,"Decnet4"},
{14,"Vines"},
{15,"E-164-NSAP"},
{16,"DNS"},
{17,"DistinguishedName"},
{18,"AS"},
{19,"XTPoIPv4"},
{20,"XTPoIPv6"},
{21,"XTPNative"},
{22,"FibrePortName"},
{23,"FibreNodeName"},
{24,"GWID"},
{0,NULL}
};
static int proto_diameter = -1;
static int hf_diameter_length = -1;
static int hf_diameter_code = -1;
@ -206,6 +245,8 @@ static gint ett_diameter = -1;
static gint ett_diameter_flags = -1;
static gint ett_diameter_avp_flags = -1;
static gint ett_diameter_avpinfo = -1;
static gint ett_unknown = -1;
static gint ett_err = -1;
static guint gbl_diameterTcpPort=TCP_PORT_DIAMETER;
static guint gbl_diameterSctpPort=SCTP_PORT_DIAMETER;
@ -230,7 +271,7 @@ static int dissect_diameter_avp(diam_ctx_t* c, tvbuff_t* tvb, int offset) {
guint32 vendor_flag = len & 0x80000000;
guint32 flags_bits_idx = (len & 0xE0000000) >> 29;
guint32 flags_bits = (len & 0xFF000000) >> 24;
guint32 vendorid = vendor_flag ? tvb_get_ntohl(tvb,offset+8) : 0;
guint32 vendorid = vendor_flag ? tvb_get_ntohl(tvb,offset+8) : 0 ;
emem_tree_key_t k[] = {
{1,&code},
{1,&vendorid},
@ -240,15 +281,25 @@ static int dissect_diameter_avp(diam_ctx_t* c, tvbuff_t* tvb, int offset) {
proto_item *pi, *avp_item;
proto_tree *avp_tree, *save_tree;
tvbuff_t* subtvb;
diam_vnd_t* vendor = vendor_flag ? &no_vnd : emem_tree_lookup32(dictionary.vnds,vendorid);
const diam_vnd_t* vendor;
value_string* vendor_avp_vs;
const char* code_str;
const char* avp_str;
len &= 0x00ffffff;
if (!a) a = &unknown_avp;
if (! vendor) vendor = &unknown_vendor;
if (!a) {
a = &unknown_avp;
if (vendor_flag) {
if (! (vendor = emem_tree_lookup32(dictionary.vnds,vendorid) ))
vendor = &unknown_vendor;
} else {
vendor = &no_vnd;
}
} else {
vendor = a->vendor;
}
vendor_avp_vs = VND_AVP_VS(vendor);
@ -258,6 +309,14 @@ static int dissect_diameter_avp(diam_ctx_t* c, tvbuff_t* tvb, int offset) {
pi = proto_tree_add_item(avp_tree,hf_diameter_avp_code,tvb,offset,4,FALSE);
code_str = val_to_str(code, vendor_avp_vs, "Unknown");
proto_item_append_text(pi," %s", code_str);
if (a == &unknown_avp) {
proto_tree* tu = proto_item_add_subtree(pi,ett_unknown);
proto_item* iu = proto_tree_add_text(tu,tvb,offset,4,"Unknown AVP, "
"if you know what this is you can add it to dictionary.xml");
expert_add_info_format(c->pinfo, iu, PI_UNDECODED, PI_WARN, "Unknown AVP");
}
offset += 4;
proto_item_set_text(avp_item,"AVP: %s(%u) l=%u f=%s", code_str, code, len, avpflags_str[flags_bits_idx]);
@ -286,7 +345,13 @@ static int dissect_diameter_avp(diam_ctx_t* c, tvbuff_t* tvb, int offset) {
if (vendor_flag) {
proto_item_append_text(avp_item," vnd=%s", val_to_str(vendorid, vnd_short_vs, "%d"));
proto_tree_add_item(avp_tree,hf_diameter_avp_vendor_id,tvb,offset,4,FALSE);
pi = proto_tree_add_item(avp_tree,hf_diameter_avp_vendor_id,tvb,offset,4,FALSE);
if (vendor == &unknown_vendor) {
proto_tree* tu = proto_item_add_subtree(pi,ett_unknown);
proto_item* iu = proto_tree_add_text(tu,tvb,offset,4,"Unknown Vendor, "
"if you know whose this is you can add it to dictionary.xml");
expert_add_info_format(c->pinfo, iu, PI_UNDECODED, PI_WARN, "Unknown Vendor");
}
offset += 4;
}
@ -309,6 +374,72 @@ static int dissect_diameter_avp(diam_ctx_t* c, tvbuff_t* tvb, int offset) {
}
static const char* address_rfc_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;
proto_item* pi = proto_tree_add_item(c->tree,a->hf_value,tvb,0,tvb_length_remaining(tvb,0),FALSE);
proto_tree* pt = proto_item_add_subtree(pi,t->ett);
guint32 addr_type = tvb_get_ntohs(tvb,0);
guint32 len = tvb_length_remaining(tvb,2);
proto_tree_add_item(pt,t->hf_address_type,tvb,0,2,FALSE);
switch (addr_type ) {
case 1:
if (len != 4) {
pi = proto_tree_add_text(pt,tvb,2,len,"Wrong length for IPv4 Address: %d instead of 4",len);
expert_add_info_format(c->pinfo, pi, PI_MALFORMED, PI_WARN, "Wrong length for IPv4 Address");
return "[Malformed]";
}
pi = proto_tree_add_item(pt,t->hf_ipv4,tvb,2,4,FALSE);
break;
case 2:
if (len != 16) {
pi = proto_tree_add_text(pt,tvb,2,len,"Wrong length for IPv6 Address: %d instead of 16",len);
expert_add_info_format(c->pinfo, pi, PI_MALFORMED, PI_WARN, "Wrong length for IPv6 Address");
return "[Malformed]";
}
pi = proto_tree_add_item(pt,t->hf_ipv6,tvb,2,16,FALSE);
break;
default:
pi = proto_tree_add_item(pt,t->hf_other,tvb,2,-1,FALSE);
pt = proto_item_add_subtree(pi,t->ett);
break;
}
proto_item_fill_label(pi->finfo, label);
label = strstr(label,": ")+2;
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;
proto_item* pi = proto_tree_add_item(c->tree,a->hf_value,tvb,0,tvb_length_remaining(tvb,0),FALSE);
proto_tree* pt = proto_item_add_subtree(pi,t->ett);
guint32 len = tvb_length_remaining(tvb,0);
switch (len) {
case 4:
pi = proto_tree_add_item(pt,t->hf_ipv4,tvb,2,4,FALSE);
break;
case 16:
pi = proto_tree_add_item(pt,t->hf_ipv6,tvb,2,16,FALSE);
break;
default:
pi = proto_tree_add_item(pt,t->hf_other,tvb,2,len,FALSE);
pt = proto_item_add_subtree(pi,t->ett);
expert_add_info_format(c->pinfo, pi, PI_MALFORMED, PI_NOTE,
"Bad Address Length (%u)", len);
break;
}
proto_item_fill_label(pi->finfo, label);
label = strstr(label,": ")+2;
return label;
}
static const char* simple_avp(diam_ctx_t* c, diam_avp_t* a, tvbuff_t* tvb) {
char* label = ep_alloc(ITEM_LABEL_LENGTH+1);
proto_item* pi = proto_tree_add_item(c->tree,a->hf_value,tvb,0,tvb_length_remaining(tvb,0),FALSE);
@ -335,13 +466,21 @@ static const char* grouped_avp(diam_ctx_t* c, diam_avp_t* a, tvbuff_t* tvb) {
return NULL;
}
static const char const* msgflags_str[] = {
"----", "---T", "--E-", "--ET",
"-P--", "-P-T", "-PE-", "-PET",
"R---", "R--T", "R-E-", "R-ET",
"RP--", "RP-T", "RPE-", "RPET"
};
static void dissect_diameter_common(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree) {
guint32 first_word = tvb_get_ntohl(tvb,0);
guint32 version = (first_word & 0xff000000) >> 24;
guint32 flags_bits = (tvb_get_ntohl(tvb,4) & 0xff000000) >> 24;
int packet_len = first_word & 0x00ffffff;
proto_item *pi;
proto_item *cmd_item, *version_item;
proto_item *pi, *cmd_item, *version_item;
proto_tree* diam_tree;
diam_ctx_t* c = ep_alloc0(sizeof(diam_ctx_t));
int offset;
value_string* cmd_vs;
@ -353,14 +492,15 @@ static void dissect_diameter_common(tvbuff_t* tvb, packet_info* pinfo, proto_tre
col_set_str(pinfo->cinfo, COL_PROTOCOL, "DIAMETER");
pi = proto_tree_add_item(tree,proto_diameter,tvb,0,-1,FALSE);
tree = proto_item_add_subtree(pi,ett_diameter);
diam_tree = proto_item_add_subtree(pi,ett_diameter);
c->tree = tree;
c->tree = diam_tree;
c->pinfo = pinfo;
version_item = proto_tree_add_item(tree,hf_diameter_version,tvb,0,1,FALSE);
proto_tree_add_item(tree,hf_diameter_length,tvb,1,3,FALSE);
version_item = proto_tree_add_item(diam_tree,hf_diameter_version,tvb,0,1,FALSE);
proto_tree_add_item(diam_tree,hf_diameter_length,tvb,1,3,FALSE);
pi = proto_tree_add_item(tree,hf_diameter_flags,tvb,4,1,FALSE);
pi = proto_tree_add_item(diam_tree,hf_diameter_flags,tvb,4,1,FALSE);
{
proto_tree* pt = proto_item_add_subtree(pi,ett_diameter_flags);
proto_tree_add_item(pt,hf_diameter_flags_request,tvb,4,1,FALSE);
@ -377,7 +517,7 @@ static void dissect_diameter_common(tvbuff_t* tvb, packet_info* pinfo, proto_tre
if(flags_bits & 0x01) proto_item_set_expert_flags(pi, PI_MALFORMED, PI_WARN);
}
cmd_item = proto_tree_add_item(tree,hf_diameter_code,tvb,5,3,FALSE);
cmd_item = proto_tree_add_item(diam_tree,hf_diameter_code,tvb,5,3,FALSE);
switch (version) {
case DIAMETER_V16: {
@ -389,30 +529,35 @@ static void dissect_diameter_common(tvbuff_t* tvb, packet_info* pinfo, proto_tre
}
cmd_vs = VND_CMD_VS(vendor);
proto_tree_add_item(tree, hf_diameter_vendor_id,tvb,8,4,FALSE);
proto_tree_add_item(diam_tree, hf_diameter_vendor_id,tvb,8,4,FALSE);
c->version_rfc = FALSE;
break;
}
case DIAMETER_RFC: {
cmd_vs = VND_CMD_VS(&no_vnd);
proto_tree_add_item(tree, hf_diameter_application_id,tvb,8,4,FALSE);
proto_tree_add_item(diam_tree, hf_diameter_application_id,tvb,8,4,FALSE);
c->version_rfc = TRUE;
break;
}
default:
expert_add_info_format(pinfo, version_item, PI_UNDECODED, PI_WARN, "Unknown Diameter Version");
{
proto_tree* pt = proto_item_add_subtree(version_item,ett_err);
proto_item* pi = proto_tree_add_text(pt,tvb,0,1,"Unknown Diameter Version (decoding as RFC 3588)");
expert_add_info_format(pinfo, pi, PI_UNDECODED, PI_WARN, "Unknown Diameter Version");
c->version_rfc = TRUE;
cmd_vs = VND_CMD_VS(&no_vnd);
break;
}
}
cmd_str = val_to_str(cmd, cmd_vs, "Unknown");
if (check_col(pinfo->cinfo, COL_INFO))
col_add_fstr(pinfo->cinfo, COL_INFO,
"cmd=%s(%d) %s=%s(%d) h2h=%x e2e=%x",
"cmd=%s(%d) flags=%s %s=%s(%d) h2h=%x e2e=%x",
cmd_str,
cmd,
msgflags_str[((flags_bits>>4)&0x0f)],
c->version_rfc ? "appl" : "vend",
val_to_str(fourth, c->version_rfc ? dictionary.applications : vnd_short_vs, "Unknown"),
fourth,
@ -421,8 +566,10 @@ static void dissect_diameter_common(tvbuff_t* tvb, packet_info* pinfo, proto_tre
proto_item_append_text(cmd_item," %s", cmd_str);
proto_tree_add_item(tree,hf_diameter_hopbyhopid,tvb,12,4,FALSE);
proto_tree_add_item(tree,hf_diameter_endtoendid,tvb,16,4,FALSE);
proto_tree_add_item(diam_tree,hf_diameter_hopbyhopid,tvb,12,4,FALSE);
proto_tree_add_item(diam_tree,hf_diameter_endtoendid,tvb,16,4,FALSE);
if (!tree) return;
offset = 20;
@ -491,14 +638,14 @@ static char* alnumerize(char* name) {
}
guint reginfo(int* hf_ptr,
const char* name,
const char* abbr,
const char* desc,
enum ftenum ft,
base_display_e base,
value_string* vs,
guint32 mask) {
static guint reginfo(int* hf_ptr,
const char* name,
const char* abbr,
const char* desc,
enum ftenum ft,
base_display_e base,
const value_string* vs,
guint32 mask) {
hf_register_info hf = { hf_ptr, {
name ? g_strdup(name) : g_strdup(abbr),
g_strdup(abbr),
@ -513,9 +660,13 @@ guint reginfo(int* hf_ptr,
return build_dict.hf->len - 1;
}
void basic_avp_reginfo(diam_avp_t* a, const char* name, enum ftenum ft, base_display_e base, value_string* vs) {
static void basic_avp_reginfo(diam_avp_t* a, const char* name, enum ftenum ft, base_display_e base, const value_string* vs) {
hf_register_info hf[] = {
{ &(a->hf_value), { NULL, NULL, ft, base, VALS(vs), 0x0, "", HFILL }}
{ &(a->hf_value), { NULL, NULL, ft, base, VALS(vs), 0x0,
a->vendor->code ?
g_strdup_printf("vendor=%d code=%d", a->vendor->code, a->code)
: g_strdup_printf("code=%d", a->code),
HFILL }}
};
gint* ettp = &(a->ett);
@ -526,11 +677,58 @@ void basic_avp_reginfo(diam_avp_t* a, const char* name, enum ftenum ft, base_dis
g_array_append_vals(build_dict.ett,&ettp,1);
}
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_) {
diam_avp_t* a = g_malloc0(sizeof(diam_avp_t));
address_avp_t* t = g_malloc(sizeof(address_avp_t));
gint* ettp = &(t->ett);
a->code = code;
a->vendor = vendor;
a->dissector_v16 = address_v16_avp;
a->dissector_rfc = address_rfc_avp;
a->ett = -1;
a->hf_value = -1;
a->type_data = t;
t->ett = -1;
t->hf_address_type = -1;
t->hf_ipv4 = -1;
t->hf_ipv6 = -1;
t->hf_other = -1;
basic_avp_reginfo(a,name,FT_BYTES,BASE_NONE,NULL);
reginfo(&(t->hf_address_type), ep_strdup_printf("%s Address Family",name),
alnumerize(ep_strdup_printf("diameter.%s.addr_family",name)),
"", FT_UINT16, BASE_DEC, diameter_avp_data_addrfamily_vals, 0);
reginfo(&(t->hf_ipv4), ep_strdup_printf("%s Address",name),
alnumerize(ep_strdup_printf("diameter.%s",name)),
"", FT_IPv4, BASE_NONE, NULL, 0);
reginfo(&(t->hf_ipv6), ep_strdup_printf("%s Address",name),
alnumerize(ep_strdup_printf("diameter.%s",name)),
"", FT_IPv6, BASE_NONE, NULL, 0);
reginfo(&(t->hf_other), ep_strdup_printf("%s Address",name),
alnumerize(ep_strdup_printf("diameter.%s",name)),
"", FT_BYTES, BASE_NONE, NULL, 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,
guint32 vendor,
const diam_vnd_t* vendor,
const char* name,
value_string* vs) {
const value_string* vs) {
diam_avp_t* a = g_malloc0(sizeof(diam_avp_t));
a->code = code;
a->vendor = vendor;
@ -551,13 +749,13 @@ static const avp_type_t basic_types[] = {
{"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 },
{"time" , simple_avp , simple_avp , FT_BYTES , 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" , simple_avp , simple_avp , FT_NONE , BASE_NONE , build_simple_avp },
{"diameteruri" , simple_avp , simple_avp , FT_STRING , BASE_NONE , 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 },
@ -587,6 +785,8 @@ extern int dictionary_load(void) {
ddict_cmd_t* c;
ddict_typedefn_t* t;
ddict_avp_t* a;
gboolean do_debug_parser = getenv("WIRESHARK_DEBUG_DIAM_DICT_PARSER") ? TRUE : FALSE;
gboolean do_dump_dict = getenv("WIRESHARK_DUMP_DIAM_DICT") ? TRUE : FALSE;
char* dir = ep_strdup_printf("%s" G_DIR_SEPARATOR_S "diameter" G_DIR_SEPARATOR_S, get_datafile_dir());
const avp_type_t* type;
const avp_type_t* bytes = basic_types;
@ -617,11 +817,13 @@ extern int dictionary_load(void) {
}
/* load the dictionary */
d = ddict_scan(dir,"dictionary.xml");
if (d == NULL) {
d = ddict_scan(dir,"dictionary.xml",do_debug_parser);
if (d == NULL) {
return 0;
}
if (do_dump_dict) ddict_print(stdout, d);
/* populate the types */
for (t = d->typedefns; t; t = t->next) {
const avp_type_t* parent = NULL;
@ -680,7 +882,7 @@ extern int dictionary_load(void) {
value_string item = {c->code,c->name};
g_array_append_val(vnd->vs_cmds,item);
} else {
g_warning("Diameter Dictionary: No Vendor: %s",c->vendor);
fprintf(stderr,"Diameter Dictionary: No Vendor: %s",c->vendor);
}
}
}
@ -695,7 +897,7 @@ extern int dictionary_load(void) {
value_string vndvs = {a->code,a->name};
g_array_append_val(vnd->vs_avps,vndvs);
} else {
g_warning("Diameter Dictionary: No Vendor: %s",vend);
fprintf(stderr,"Diameter Dictionary: No Vendor: %s",vend);
vnd = &unknown_vendor;
}
@ -713,7 +915,7 @@ extern int dictionary_load(void) {
type = bytes;
}
avp = type->build( type, a->code, vnd->code, a->name, vs);
avp = type->build( type, a->code, vnd, a->name, vs);
g_hash_table_insert(build_dict.avps, a->name, avp);
{
@ -865,6 +1067,8 @@ proto_register_diameter(void)
&ett_diameter_flags,
&ett_diameter_avp_flags,
&ett_diameter_avpinfo,
&ett_unknown,
&ett_err,
&(unknown_avp.ett)
};