aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorLuis Ontanon <luis.ontanon@gmail.com>2007-07-17 22:19:54 +0000
committerLuis Ontanon <luis.ontanon@gmail.com>2007-07-17 22:19:54 +0000
commite27b40f589b994f81848db86b9d868d58302b512 (patch)
tree3b4fe91bc13794ed90ad6fc882dc497f9d09db89 /epan
parent776820f3fbd1cb47904ba00436c8eecdc6ebc8bf (diff)
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
Diffstat (limited to 'epan')
-rw-r--r--epan/diam_dict.h2
-rw-r--r--epan/diam_dict.l30
-rw-r--r--epan/dissectors/packet-diameter.c302
3 files changed, 275 insertions, 59 deletions
diff --git a/epan/diam_dict.h b/epan/diam_dict.h
index 8e49bd9b26..a6b16c9022 100644
--- a/epan/diam_dict.h
+++ b/epan/diam_dict.h
@@ -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
diff --git a/epan/diam_dict.l b/epan/diam_dict.l
index 8cc2ef2221..b657513be2 100644
--- a/epan/diam_dict.l
+++ b/epan/diam_dict.l
@@ -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);
diff --git a/epan/dissectors/packet-diameter.c b/epan/dissectors/packet-diameter.c
index 46619ec0e7..e607b50b40 100644
--- a/epan/dissectors/packet-diameter.c
+++ b/epan/dissectors/packet-diameter.c
@@ -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)
};