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:
parent
776820f3fb
commit
e27b40f589
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue