2000-07-30 07:16:11 +00:00
|
|
|
/* packet-diameter.c
|
2001-11-01 21:52:44 +00:00
|
|
|
* Routines for Diameter packet disassembly
|
2000-07-30 07:16:11 +00:00
|
|
|
*
|
2008-08-05 21:31:17 +00:00
|
|
|
* $Id$
|
2000-07-30 07:16:11 +00:00
|
|
|
*
|
2001-02-19 23:14:02 +00:00
|
|
|
* Copyright (c) 2001 by David Frascone <dave@frascone.com>
|
2008-08-05 21:03:46 +00:00
|
|
|
* Copyright (c) 2007 by Luis E. Garcia Ontanon <luis@ontanon.org>
|
2000-07-30 07:16:11 +00:00
|
|
|
*
|
2010-04-26 22:19:34 +00:00
|
|
|
* Support for Request-Answer tracking and Tapping
|
2008-11-15 15:52:39 +00:00
|
|
|
* introduced by Abhik Sarkar
|
|
|
|
*
|
2006-05-21 04:49:01 +00:00
|
|
|
* Wireshark - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@wireshark.org>
|
2001-05-27 21:38:46 +00:00
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
2000-07-30 07:16:11 +00:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
2004-03-21 23:10:31 +00:00
|
|
|
* References:
|
|
|
|
* 2004-03-11
|
|
|
|
* http://www.ietf.org/rfc/rfc3588.txt
|
|
|
|
* http://www.iana.org/assignments/radius-types
|
|
|
|
* http://www.ietf.org/internet-drafts/draft-ietf-aaa-diameter-cc-03.txt
|
|
|
|
* http://www.ietf.org/internet-drafts/draft-ietf-aaa-diameter-nasreq-14.txt
|
|
|
|
* http://www.ietf.org/internet-drafts/draft-ietf-aaa-diameter-mobileip-16.txt
|
|
|
|
* http://www.ietf.org/internet-drafts/draft-ietf-aaa-diameter-sip-app-01.txt
|
|
|
|
* http://www.ietf.org/html.charters/aaa-charter.html
|
2004-09-28 17:52:36 +00:00
|
|
|
* http://www.iana.org/assignments/address-family-numbers
|
|
|
|
* http://www.iana.org/assignments/enterprise-numbers
|
2004-10-08 09:35:56 +00:00
|
|
|
* http://www.iana.org/assignments/aaa-parameters
|
2004-09-28 17:52:36 +00:00
|
|
|
*/
|
2000-07-30 07:16:11 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <stdio.h>
|
2011-05-20 19:00:09 +00:00
|
|
|
#include <stdlib.h>
|
2000-11-17 21:00:40 +00:00
|
|
|
#include <string.h>
|
2004-02-21 04:26:29 +00:00
|
|
|
#include <errno.h>
|
2000-07-30 07:16:11 +00:00
|
|
|
#include <ctype.h>
|
2011-05-20 19:00:09 +00:00
|
|
|
|
2000-07-30 07:16:11 +00:00
|
|
|
#include <glib.h>
|
2011-05-20 19:00:09 +00:00
|
|
|
|
2002-01-21 07:37:49 +00:00
|
|
|
#include <epan/packet.h>
|
2011-05-20 19:00:09 +00:00
|
|
|
#include <epan/filesystem.h>
|
2004-09-27 22:55:15 +00:00
|
|
|
#include <epan/prefs.h>
|
2004-09-30 20:27:47 +00:00
|
|
|
#include <epan/sminmpec.h>
|
2005-08-20 13:02:08 +00:00
|
|
|
#include <epan/emem.h>
|
2006-07-03 21:18:36 +00:00
|
|
|
#include <epan/expert.h>
|
2008-11-15 15:52:39 +00:00
|
|
|
#include <epan/conversation.h>
|
|
|
|
#include <epan/tap.h>
|
2009-08-21 20:25:24 +00:00
|
|
|
#include <epan/diam_dict.h>
|
2004-02-21 10:29:52 +00:00
|
|
|
#include "packet-tcp.h"
|
2008-11-15 15:52:39 +00:00
|
|
|
#include "packet-diameter.h"
|
2000-07-30 07:16:11 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
/* Diameter Header Flags */
|
2010-10-18 15:56:06 +00:00
|
|
|
/* RPETrrrrCCCCCCCCCCCCCCCCCCCCCCCC */
|
2007-07-16 05:41:58 +00:00
|
|
|
#define DIAM_FLAGS_R 0x80
|
|
|
|
#define DIAM_FLAGS_P 0x40
|
|
|
|
#define DIAM_FLAGS_E 0x20
|
|
|
|
#define DIAM_FLAGS_T 0x10
|
|
|
|
#define DIAM_FLAGS_RESERVED4 0x08
|
|
|
|
#define DIAM_FLAGS_RESERVED5 0x04
|
|
|
|
#define DIAM_FLAGS_RESERVED6 0x02
|
|
|
|
#define DIAM_FLAGS_RESERVED7 0x01
|
|
|
|
#define DIAM_FLAGS_RESERVED 0x0f
|
|
|
|
|
|
|
|
#define DIAM_LENGTH_MASK 0x00ffffffl
|
|
|
|
#define DIAM_COMMAND_MASK DIAM_LENGTH_MASK
|
|
|
|
#define DIAM_GET_FLAGS(dh) ((dh.flagsCmdCode & ~DIAM_COMMAND_MASK) >> 24)
|
|
|
|
#define DIAM_GET_VERSION(dh) ((dh.versionLength & (~DIAM_LENGTH_MASK)) >> 24)
|
|
|
|
#define DIAM_GET_COMMAND(dh) (dh.flagsCmdCode & DIAM_COMMAND_MASK)
|
|
|
|
#define DIAM_GET_LENGTH(dh) (dh.versionLength & DIAM_LENGTH_MASK)
|
|
|
|
|
|
|
|
/* Diameter AVP Flags */
|
|
|
|
#define AVP_FLAGS_P 0x20
|
|
|
|
#define AVP_FLAGS_V 0x80
|
|
|
|
#define AVP_FLAGS_M 0x40
|
|
|
|
#define AVP_FLAGS_RESERVED3 0x10
|
|
|
|
#define AVP_FLAGS_RESERVED4 0x08
|
|
|
|
#define AVP_FLAGS_RESERVED5 0x04
|
|
|
|
#define AVP_FLAGS_RESERVED6 0x02
|
|
|
|
#define AVP_FLAGS_RESERVED7 0x01
|
|
|
|
#define AVP_FLAGS_RESERVED 0x1f /* 00011111 -- V M P X X X X X */
|
|
|
|
|
|
|
|
#define DIAMETER_V16 16
|
|
|
|
#define DIAMETER_RFC 1
|
|
|
|
|
|
|
|
typedef struct _diam_ctx_t {
|
|
|
|
proto_tree* tree;
|
2007-07-17 22:19:54 +00:00
|
|
|
packet_info* pinfo;
|
2007-07-16 05:41:58 +00:00
|
|
|
emem_tree_t* avps;
|
|
|
|
gboolean version_rfc;
|
|
|
|
} diam_ctx_t;
|
|
|
|
|
|
|
|
typedef struct _diam_avp_t diam_avp_t;
|
|
|
|
typedef struct _avp_type_t avp_type_t;
|
|
|
|
|
|
|
|
typedef const char* (*diam_avp_dissector_t)(diam_ctx_t*, diam_avp_t*, tvbuff_t*);
|
|
|
|
|
2007-07-17 22:19:54 +00:00
|
|
|
|
|
|
|
typedef struct _diam_vnd_t {
|
|
|
|
guint32 code;
|
|
|
|
GArray* vs_avps;
|
2010-05-24 14:20:53 +00:00
|
|
|
value_string_ext* vs_avps_ext;
|
2007-07-17 22:19:54 +00:00
|
|
|
GArray* vs_cmds;
|
|
|
|
} diam_vnd_t;
|
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
struct _diam_avp_t {
|
|
|
|
guint32 code;
|
2007-07-17 22:19:54 +00:00
|
|
|
const diam_vnd_t* vendor;
|
2007-07-16 05:41:58 +00:00
|
|
|
diam_avp_dissector_t dissector_v16;
|
|
|
|
diam_avp_dissector_t dissector_rfc;
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
gint ett;
|
|
|
|
int hf_value;
|
|
|
|
void* type_data;
|
2001-11-01 21:52:44 +00:00
|
|
|
};
|
|
|
|
|
2010-10-14 17:50:35 +00:00
|
|
|
#define VND_AVP_VS(v) ((value_string*)(void*)((v)->vs_avps->data))
|
|
|
|
#define VND_AVP_VS_LEN(v) ((v)->vs_avps->len)
|
|
|
|
#define VND_CMD_VS(v) ((value_string*)(void*)((v)->vs_cmds->data))
|
2007-07-16 05:41:58 +00:00
|
|
|
|
|
|
|
typedef struct _diam_dictionary_t {
|
|
|
|
emem_tree_t* avps;
|
|
|
|
emem_tree_t* vnds;
|
|
|
|
value_string* applications;
|
|
|
|
value_string* commands;
|
|
|
|
} diam_dictionary_t;
|
|
|
|
|
2007-07-20 00:15:17 +00:00
|
|
|
typedef diam_avp_t* (*avp_constructor_t)(const avp_type_t*, guint32, const diam_vnd_t*, const char*, const value_string*, void*);
|
2007-07-16 05:41:58 +00:00
|
|
|
|
|
|
|
struct _avp_type_t {
|
2008-06-25 03:05:19 +00:00
|
|
|
const char* name;
|
2007-07-16 05:41:58 +00:00
|
|
|
diam_avp_dissector_t v16;
|
|
|
|
diam_avp_dissector_t rfc;
|
|
|
|
enum ftenum ft;
|
2011-04-22 17:25:25 +00:00
|
|
|
int base;
|
2007-07-16 05:41:58 +00:00
|
|
|
avp_constructor_t build;
|
|
|
|
};
|
2000-07-30 07:16:11 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
struct _build_dict {
|
|
|
|
GArray* hf;
|
2008-07-15 21:06:31 +00:00
|
|
|
GPtrArray* ett;
|
2007-07-16 05:41:58 +00:00
|
|
|
GHashTable* types;
|
|
|
|
GHashTable* avps;
|
|
|
|
};
|
2000-07-30 07:16:11 +00:00
|
|
|
|
2007-07-17 22:19:54 +00:00
|
|
|
|
|
|
|
typedef struct _address_avp_t {
|
|
|
|
gint ett;
|
|
|
|
int hf_address_type;
|
|
|
|
int hf_ipv4;
|
|
|
|
int hf_ipv6;
|
|
|
|
int hf_other;
|
|
|
|
} address_avp_t;
|
|
|
|
|
2007-07-20 00:15:17 +00:00
|
|
|
typedef enum {
|
|
|
|
REASEMBLE_NEVER = 0,
|
2007-10-24 16:32:51 +00:00
|
|
|
REASEMBLE_AT_END,
|
2007-07-20 00:15:17 +00:00
|
|
|
REASEMBLE_BY_LENGTH
|
|
|
|
} avp_reassemble_mode_t;
|
|
|
|
|
|
|
|
typedef struct _proto_avp_t {
|
|
|
|
char* name;
|
|
|
|
dissector_handle_t handle;
|
2007-10-24 16:32:51 +00:00
|
|
|
avp_reassemble_mode_t reassemble_mode;
|
2007-07-20 00:15:17 +00:00
|
|
|
} proto_avp_t;
|
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
static const char* simple_avp(diam_ctx_t*, diam_avp_t*, tvbuff_t*);
|
2000-07-30 07:16:11 +00:00
|
|
|
|
2008-08-14 23:51:52 +00:00
|
|
|
static const value_string no_vs[] = {{0, NULL} };
|
2010-10-14 17:50:35 +00:00
|
|
|
static GArray no_garr = { (void*)no_vs, 0 };
|
|
|
|
static diam_vnd_t unknown_vendor = { 0xffffffff, &no_garr, NULL, &no_garr };
|
2010-05-24 14:20:53 +00:00
|
|
|
static diam_vnd_t no_vnd = { 0, NULL, NULL, NULL };
|
2007-07-17 22:19:54 +00:00
|
|
|
static diam_avp_t unknown_avp = {0, &unknown_vendor, simple_avp, simple_avp, -1, -1, NULL };
|
2007-07-20 11:39:09 +00:00
|
|
|
static GArray* all_cmds;
|
2007-07-16 05:41:58 +00:00
|
|
|
static diam_dictionary_t dictionary = { NULL, NULL, NULL, NULL };
|
|
|
|
static struct _build_dict build_dict;
|
2008-08-14 23:51:52 +00:00
|
|
|
static const value_string* vnd_short_vs;
|
2007-07-20 00:15:17 +00:00
|
|
|
static dissector_handle_t data_handle;
|
2009-06-26 05:48:03 +00:00
|
|
|
static dissector_handle_t eap_handle;
|
2007-07-20 00:15:17 +00:00
|
|
|
|
2007-07-17 22:19:54 +00:00
|
|
|
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}
|
|
|
|
};
|
2010-12-06 23:20:21 +00:00
|
|
|
static value_string_ext diameter_avp_data_addrfamily_vals_ext = VALUE_STRING_EXT_INIT(diameter_avp_data_addrfamily_vals);
|
2007-07-17 22:19:54 +00:00
|
|
|
|
2000-07-30 07:16:11 +00:00
|
|
|
static int proto_diameter = -1;
|
|
|
|
static int hf_diameter_length = -1;
|
|
|
|
static int hf_diameter_code = -1;
|
2001-04-10 21:49:23 +00:00
|
|
|
static int hf_diameter_hopbyhopid =-1;
|
|
|
|
static int hf_diameter_endtoendid =-1;
|
2001-02-19 23:14:02 +00:00
|
|
|
static int hf_diameter_version = -1;
|
|
|
|
static int hf_diameter_vendor_id = -1;
|
2004-10-08 09:35:56 +00:00
|
|
|
static int hf_diameter_application_id = -1;
|
2001-07-30 20:08:44 +00:00
|
|
|
static int hf_diameter_flags = -1;
|
|
|
|
static int hf_diameter_flags_request = -1;
|
|
|
|
static int hf_diameter_flags_proxyable = -1;
|
|
|
|
static int hf_diameter_flags_error = -1;
|
2004-03-21 23:10:31 +00:00
|
|
|
static int hf_diameter_flags_T = -1;
|
2001-07-30 20:08:44 +00:00
|
|
|
static int hf_diameter_flags_reserved4 = -1;
|
|
|
|
static int hf_diameter_flags_reserved5 = -1;
|
|
|
|
static int hf_diameter_flags_reserved6 = -1;
|
|
|
|
static int hf_diameter_flags_reserved7 = -1;
|
2001-02-19 23:14:02 +00:00
|
|
|
|
2007-07-10 17:45:11 +00:00
|
|
|
static int hf_diameter_avp = -1;
|
2007-07-16 05:41:58 +00:00
|
|
|
static int hf_diameter_avp_len = -1;
|
2001-02-19 23:14:02 +00:00
|
|
|
static int hf_diameter_avp_code = -1;
|
|
|
|
static int hf_diameter_avp_flags = -1;
|
2001-07-30 20:08:44 +00:00
|
|
|
static int hf_diameter_avp_flags_vendor_specific = -1;
|
|
|
|
static int hf_diameter_avp_flags_mandatory = -1;
|
|
|
|
static int hf_diameter_avp_flags_protected = -1;
|
|
|
|
static int hf_diameter_avp_flags_reserved3 = -1;
|
|
|
|
static int hf_diameter_avp_flags_reserved4 = -1;
|
|
|
|
static int hf_diameter_avp_flags_reserved5 = -1;
|
|
|
|
static int hf_diameter_avp_flags_reserved6 = -1;
|
|
|
|
static int hf_diameter_avp_flags_reserved7 = -1;
|
2001-02-19 23:14:02 +00:00
|
|
|
static int hf_diameter_avp_vendor_id = -1;
|
2007-07-27 18:32:09 +00:00
|
|
|
static int hf_diameter_avp_data_wrong_length = -1;
|
2001-02-19 23:14:02 +00:00
|
|
|
|
2008-11-15 15:52:39 +00:00
|
|
|
static int hf_diameter_answer_in = -1;
|
|
|
|
static int hf_diameter_answer_to = -1;
|
|
|
|
static int hf_diameter_answer_time = -1;
|
|
|
|
|
2012-03-13 15:06:40 +00:00
|
|
|
/* AVPs with special/extra decoding */
|
|
|
|
static int hf_framed_ipv6_prefix_reserved = -1;
|
|
|
|
static int hf_framed_ipv6_prefix_length = -1;
|
|
|
|
static int hf_framed_ipv6_prefix_bytes = -1;
|
|
|
|
static int hf_framed_ipv6_prefix_ipv6 = -1;
|
|
|
|
|
2000-07-30 07:16:11 +00:00
|
|
|
static gint ett_diameter = -1;
|
2001-07-30 20:08:44 +00:00
|
|
|
static gint ett_diameter_flags = -1;
|
|
|
|
static gint ett_diameter_avp_flags = -1;
|
2000-07-30 07:16:11 +00:00
|
|
|
static gint ett_diameter_avpinfo = -1;
|
2007-07-17 22:19:54 +00:00
|
|
|
static gint ett_unknown = -1;
|
|
|
|
static gint ett_err = -1;
|
2000-07-30 07:16:11 +00:00
|
|
|
|
2008-11-15 15:52:39 +00:00
|
|
|
/* Tap for Diameter */
|
|
|
|
static int diameter_tap = -1;
|
|
|
|
|
|
|
|
/* For conversations */
|
|
|
|
|
|
|
|
|
2007-10-24 15:04:01 +00:00
|
|
|
static dissector_handle_t diameter_tcp_handle;
|
2010-10-18 15:56:06 +00:00
|
|
|
static dissector_handle_t diameter_sctp_handle;
|
2007-10-24 15:04:01 +00:00
|
|
|
static range_t *global_diameter_tcp_port_range;
|
2010-10-18 15:56:06 +00:00
|
|
|
static range_t *global_diameter_sctp_port_range;
|
|
|
|
/* This is used for TCP and SCTP */
|
2008-09-19 17:39:44 +00:00
|
|
|
#define DEFAULT_DIAMETER_PORT_RANGE "3868"
|
2007-10-24 15:04:01 +00:00
|
|
|
|
2001-11-03 12:19:56 +00:00
|
|
|
/* desegmentation of Diameter over TCP */
|
|
|
|
static gboolean gbl_diameter_desegment = TRUE;
|
|
|
|
|
2008-01-27 21:06:33 +00:00
|
|
|
/* Dissector tables */
|
2008-01-28 19:55:20 +00:00
|
|
|
static dissector_table_t diameter_dissector_table;
|
2008-01-27 21:06:33 +00:00
|
|
|
static dissector_table_t diameter_3gpp_avp_dissector_table;
|
2010-05-07 11:08:56 +00:00
|
|
|
static dissector_table_t diameter_ericsson_avp_dissector_table;
|
2008-01-27 21:06:33 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
static const char* avpflags_str[] = {
|
|
|
|
"---",
|
|
|
|
"--P",
|
|
|
|
"-M-",
|
|
|
|
"-MP",
|
|
|
|
"V--",
|
|
|
|
"V-P",
|
|
|
|
"VM-",
|
|
|
|
"VMP",
|
|
|
|
};
|
2002-08-28 21:04:11 +00:00
|
|
|
|
2010-05-24 14:20:53 +00:00
|
|
|
static gint
|
|
|
|
compare_avps (gconstpointer a, gconstpointer b)
|
|
|
|
{
|
|
|
|
value_string* vsa = (value_string*)a;
|
|
|
|
value_string* vsb = (value_string*)b;
|
|
|
|
|
|
|
|
if(vsa->value > vsb->value)
|
|
|
|
return 1;
|
|
|
|
if(vsa->value < vsb->value)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-01-28 19:55:20 +00:00
|
|
|
/* Special decoding of some AVP:s */
|
|
|
|
|
|
|
|
static int
|
2012-03-13 14:43:45 +00:00
|
|
|
dissect_diameter_vendor_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
|
2008-07-15 21:06:31 +00:00
|
|
|
{
|
2008-01-28 19:55:20 +00:00
|
|
|
int offset = 0;
|
|
|
|
|
2011-10-06 03:35:44 +00:00
|
|
|
proto_tree_add_item(tree, hf_diameter_vendor_id, tvb, 0, 4, ENC_BIG_ENDIAN);
|
2008-01-28 19:55:20 +00:00
|
|
|
|
|
|
|
offset++;
|
|
|
|
return offset;
|
|
|
|
}
|
|
|
|
|
2009-06-26 05:48:03 +00:00
|
|
|
static int
|
2012-03-13 14:43:45 +00:00
|
|
|
dissect_diameter_eap_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
2010-10-18 15:56:06 +00:00
|
|
|
{
|
2009-06-26 05:48:03 +00:00
|
|
|
gboolean save_writable;
|
|
|
|
|
|
|
|
/* Ensure the packet is displayed as Diameter, not EAP */
|
|
|
|
save_writable = col_get_writable(pinfo->cinfo);
|
|
|
|
col_set_writable(pinfo->cinfo, FALSE);
|
|
|
|
|
|
|
|
call_dissector(eap_handle, tvb, pinfo, tree);
|
|
|
|
|
|
|
|
col_set_writable(pinfo->cinfo, save_writable);
|
|
|
|
return tvb_length(tvb);
|
|
|
|
}
|
2008-01-28 19:55:20 +00:00
|
|
|
|
2012-03-13 15:06:40 +00:00
|
|
|
/* From RFC 3162 section 2.3 */
|
|
|
|
static int
|
|
|
|
dissect_diameter_base_framed_ipv6_prefix(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
|
|
|
|
{
|
|
|
|
guint8 prefix_len, prefix_len_bytes;
|
|
|
|
|
|
|
|
proto_tree_add_item(tree, hf_framed_ipv6_prefix_reserved, tvb, 0, 1, ENC_BIG_ENDIAN);
|
|
|
|
proto_tree_add_item(tree, hf_framed_ipv6_prefix_length, tvb, 1, 1, ENC_BIG_ENDIAN);
|
|
|
|
|
|
|
|
prefix_len = tvb_get_guint8(tvb, 1);
|
|
|
|
prefix_len_bytes = prefix_len / 8;
|
|
|
|
if (prefix_len % 8)
|
|
|
|
prefix_len_bytes++;
|
|
|
|
|
|
|
|
proto_tree_add_item(tree, hf_framed_ipv6_prefix_bytes, tvb, 2, prefix_len_bytes, ENC_NA);
|
|
|
|
|
|
|
|
/* If we have a fully IPv6 address, display it as such */
|
|
|
|
if (prefix_len_bytes == 16)
|
|
|
|
proto_tree_add_item(tree, hf_framed_ipv6_prefix_ipv6, tvb, 2, prefix_len_bytes, ENC_NA);
|
|
|
|
|
|
|
|
return(prefix_len_bytes+2);
|
|
|
|
}
|
|
|
|
|
2007-07-27 18:32:09 +00:00
|
|
|
/* Dissect an AVP at offset */
|
2008-07-15 21:06:31 +00:00
|
|
|
static int
|
|
|
|
dissect_diameter_avp(diam_ctx_t* c, tvbuff_t* tvb, int offset)
|
|
|
|
{
|
2010-10-14 17:50:35 +00:00
|
|
|
guint32 code = tvb_get_ntohl(tvb,offset);
|
|
|
|
guint32 len = tvb_get_ntohl(tvb,offset+4);
|
|
|
|
guint32 vendor_flag = len & 0x80000000;
|
2007-07-16 05:41:58 +00:00
|
|
|
guint32 flags_bits_idx = (len & 0xE0000000) >> 29;
|
2010-10-14 17:50:35 +00:00
|
|
|
guint32 flags_bits = (len & 0xFF000000) >> 24;
|
|
|
|
guint32 vendorid = vendor_flag ? tvb_get_ntohl(tvb,offset+8) : 0 ;
|
|
|
|
emem_tree_key_t k[] = {
|
2007-07-16 05:41:58 +00:00
|
|
|
{1,&code},
|
|
|
|
{1,&vendorid},
|
|
|
|
{0,NULL}
|
|
|
|
};
|
2010-10-14 17:50:35 +00:00
|
|
|
diam_avp_t* a = emem_tree_lookup32_array(dictionary.avps,k);
|
2007-07-16 05:41:58 +00:00
|
|
|
proto_item *pi, *avp_item;
|
|
|
|
proto_tree *avp_tree, *save_tree;
|
|
|
|
tvbuff_t* subtvb;
|
2010-10-14 17:50:35 +00:00
|
|
|
diam_vnd_t* vendor;
|
2007-07-16 05:41:58 +00:00
|
|
|
const char* code_str;
|
|
|
|
const char* avp_str;
|
|
|
|
len &= 0x00ffffff;
|
2002-08-28 21:04:11 +00:00
|
|
|
|
2007-07-17 22:19:54 +00:00
|
|
|
if (!a) {
|
|
|
|
a = &unknown_avp;
|
|
|
|
|
2007-10-24 16:32:51 +00:00
|
|
|
if (vendor_flag) {
|
|
|
|
if (! (vendor = emem_tree_lookup32(dictionary.vnds,vendorid) ))
|
2007-07-17 22:19:54 +00:00
|
|
|
vendor = &unknown_vendor;
|
|
|
|
} else {
|
|
|
|
vendor = &no_vnd;
|
|
|
|
}
|
|
|
|
} else {
|
2010-10-14 17:50:35 +00:00
|
|
|
vendor = (diam_vnd_t *)a->vendor;
|
2007-07-17 22:19:54 +00:00
|
|
|
}
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2010-10-14 17:50:35 +00:00
|
|
|
if(vendor->vs_avps_ext == NULL) {
|
2010-05-24 14:20:53 +00:00
|
|
|
g_array_sort(vendor->vs_avps, compare_avps);
|
2010-10-18 15:56:06 +00:00
|
|
|
vendor->vs_avps_ext = value_string_ext_new(VND_AVP_VS(vendor), VND_AVP_VS_LEN(vendor)+1,
|
2011-05-18 23:24:50 +00:00
|
|
|
g_strdup_printf("diameter_vendor_%s",val_to_str_ext(vendorid, &sminmpec_values_ext, "Unknown")));
|
2010-05-24 14:20:53 +00:00
|
|
|
#if 0
|
2010-10-14 17:50:35 +00:00
|
|
|
{ /* Debug code */
|
|
|
|
value_string* vendor_avp_vs=VALUE_STRING_EXT_VS_P(vendor->vs_avps_ext);
|
|
|
|
gint i = 0;
|
2012-03-13 15:06:40 +00:00
|
|
|
while(vendor_avp_vs[i].strptr!=NULL) {
|
2010-10-14 17:50:35 +00:00
|
|
|
g_warning("%u %s",vendor_avp_vs[i].value,vendor_avp_vs[i].strptr);
|
|
|
|
i++;
|
|
|
|
}
|
2010-05-24 14:20:53 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-27 18:32:09 +00:00
|
|
|
/* Add root of tree for this AVP */
|
2011-10-04 22:44:31 +00:00
|
|
|
avp_item = proto_tree_add_item(c->tree,hf_diameter_avp,tvb,offset,len,ENC_NA);
|
2007-07-16 05:41:58 +00:00
|
|
|
avp_tree = proto_item_add_subtree(avp_item,a->ett);
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2011-10-06 03:35:44 +00:00
|
|
|
pi = proto_tree_add_item(avp_tree,hf_diameter_avp_code,tvb,offset,4,ENC_BIG_ENDIAN);
|
2010-10-14 17:50:35 +00:00
|
|
|
code_str = val_to_str_ext_const(code, vendor->vs_avps_ext, "Unknown");
|
2007-07-16 05:41:58 +00:00
|
|
|
proto_item_append_text(pi," %s", code_str);
|
2007-07-17 22:19:54 +00:00
|
|
|
|
2007-07-27 18:32:09 +00:00
|
|
|
/* Code */
|
2007-07-17 22:19:54 +00:00
|
|
|
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, "
|
2007-07-18 13:18:41 +00:00
|
|
|
"if you know what this is you can add it to dictionary.xml");
|
2007-07-20 11:39:09 +00:00
|
|
|
expert_add_info_format(c->pinfo, iu, PI_UNDECODED, PI_WARN,
|
|
|
|
"Unknown AVP %u (vendor=%s)", code,
|
2010-11-09 17:23:57 +00:00
|
|
|
val_to_str_ext(vendorid, &sminmpec_values_ext, "Unknown"));
|
2007-07-18 13:18:41 +00:00
|
|
|
PROTO_ITEM_SET_GENERATED(iu);
|
2007-07-17 22:19:54 +00:00
|
|
|
}
|
2007-10-24 16:32:51 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
offset += 4;
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
proto_item_set_text(avp_item,"AVP: %s(%u) l=%u f=%s", code_str, code, len, avpflags_str[flags_bits_idx]);
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-27 18:32:09 +00:00
|
|
|
/* Flags */
|
2011-10-06 03:35:44 +00:00
|
|
|
pi = proto_tree_add_item(avp_tree,hf_diameter_avp_flags,tvb,offset,1,ENC_BIG_ENDIAN);
|
2007-07-16 05:41:58 +00:00
|
|
|
{
|
|
|
|
proto_tree* flags_tree = proto_item_add_subtree(pi,ett_diameter_avp_flags);
|
2011-10-10 00:39:31 +00:00
|
|
|
proto_tree_add_item(flags_tree,hf_diameter_avp_flags_vendor_specific,tvb,offset,1,ENC_BIG_ENDIAN);
|
|
|
|
proto_tree_add_item(flags_tree,hf_diameter_avp_flags_mandatory,tvb,offset,1,ENC_BIG_ENDIAN);
|
|
|
|
proto_tree_add_item(flags_tree,hf_diameter_avp_flags_protected,tvb,offset,1,ENC_BIG_ENDIAN);
|
|
|
|
pi = proto_tree_add_item(flags_tree,hf_diameter_avp_flags_reserved3,tvb,offset,1,ENC_BIG_ENDIAN);
|
2007-07-16 05:41:58 +00:00
|
|
|
if(flags_bits & 0x10) proto_item_set_expert_flags(pi, PI_MALFORMED, PI_WARN);
|
2011-10-10 00:39:31 +00:00
|
|
|
pi = proto_tree_add_item(flags_tree,hf_diameter_avp_flags_reserved4,tvb,offset,1,ENC_BIG_ENDIAN);
|
2007-07-16 05:41:58 +00:00
|
|
|
if(flags_bits & 0x08) proto_item_set_expert_flags(pi, PI_MALFORMED, PI_WARN);
|
2011-10-10 00:39:31 +00:00
|
|
|
pi = proto_tree_add_item(flags_tree,hf_diameter_avp_flags_reserved5,tvb,offset,1,ENC_BIG_ENDIAN);
|
2007-07-16 05:41:58 +00:00
|
|
|
if(flags_bits & 0x04) proto_item_set_expert_flags(pi, PI_MALFORMED, PI_WARN);
|
2011-10-10 00:39:31 +00:00
|
|
|
proto_tree_add_item(flags_tree,hf_diameter_avp_flags_reserved6,tvb,offset,1,ENC_BIG_ENDIAN);
|
2007-07-16 05:41:58 +00:00
|
|
|
if(flags_bits & 0x02) proto_item_set_expert_flags(pi, PI_MALFORMED, PI_WARN);
|
2011-10-10 00:39:31 +00:00
|
|
|
proto_tree_add_item(flags_tree,hf_diameter_avp_flags_reserved7,tvb,offset,1,ENC_BIG_ENDIAN);
|
2007-07-16 05:41:58 +00:00
|
|
|
if(flags_bits & 0x01) proto_item_set_expert_flags(pi, PI_MALFORMED, PI_WARN);
|
2001-11-01 21:52:44 +00:00
|
|
|
}
|
2007-07-16 05:41:58 +00:00
|
|
|
offset += 1;
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-27 18:32:09 +00:00
|
|
|
/* Length */
|
2011-10-06 03:35:44 +00:00
|
|
|
proto_tree_add_item(avp_tree,hf_diameter_avp_len,tvb,offset,3,ENC_BIG_ENDIAN);
|
2007-07-16 05:41:58 +00:00
|
|
|
offset += 3;
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-27 18:32:09 +00:00
|
|
|
/* Vendor flag */
|
2007-07-16 05:41:58 +00:00
|
|
|
if (vendor_flag) {
|
|
|
|
proto_item_append_text(avp_item," vnd=%s", val_to_str(vendorid, vnd_short_vs, "%d"));
|
2011-10-06 03:35:44 +00:00
|
|
|
pi = proto_tree_add_item(avp_tree,hf_diameter_avp_vendor_id,tvb,offset,4,ENC_BIG_ENDIAN);
|
2007-07-17 22:19:54 +00:00
|
|
|
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, "
|
2007-07-18 13:18:41 +00:00
|
|
|
"if you know whose this is you can add it to dictionary.xml");
|
2007-07-17 22:19:54 +00:00
|
|
|
expert_add_info_format(c->pinfo, iu, PI_UNDECODED, PI_WARN, "Unknown Vendor");
|
2007-07-18 13:18:41 +00:00
|
|
|
PROTO_ITEM_SET_GENERATED(iu);
|
|
|
|
}
|
2007-07-16 05:41:58 +00:00
|
|
|
offset += 4;
|
2001-11-01 21:52:44 +00:00
|
|
|
}
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-27 18:32:09 +00:00
|
|
|
if ( len == (guint32)(vendor_flag ? 12 : 8) ) {
|
|
|
|
/* Data is empty so return now */
|
2008-02-18 19:10:50 +00:00
|
|
|
proto_item* iu = proto_tree_add_text(avp_tree,tvb,offset,0,"No data");
|
|
|
|
expert_add_info_format(c->pinfo, iu, PI_UNDECODED, PI_WARN, "Data is empty");
|
|
|
|
PROTO_ITEM_SET_GENERATED(iu);
|
2007-07-27 18:32:09 +00:00
|
|
|
return len;
|
|
|
|
}
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
subtvb = tvb_new_subset(tvb,offset,len-(8+(vendor_flag?4:0)),len-(8+(vendor_flag?4:0)));
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
save_tree = c->tree;
|
|
|
|
c->tree = avp_tree;
|
|
|
|
if (c->version_rfc) {
|
|
|
|
avp_str = a->dissector_rfc(c,a,subtvb);
|
|
|
|
} else {
|
|
|
|
avp_str = a->dissector_v16(c,a,subtvb);
|
2005-11-19 15:59:30 +00:00
|
|
|
}
|
2007-07-16 05:41:58 +00:00
|
|
|
c->tree = save_tree;
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
if (avp_str) proto_item_append_text(avp_item," val=%s", avp_str);
|
2001-11-03 04:09:46 +00:00
|
|
|
|
2008-01-27 21:06:33 +00:00
|
|
|
/* Call subdissectors for AVP:s */
|
2012-03-13 15:06:40 +00:00
|
|
|
switch (vendorid) {
|
2008-01-27 21:06:33 +00:00
|
|
|
case 0:
|
2010-12-20 05:35:29 +00:00
|
|
|
dissector_try_uint(diameter_dissector_table, code, subtvb, c->pinfo, avp_tree);
|
2008-01-27 21:06:33 +00:00
|
|
|
break;
|
2010-05-07 11:08:56 +00:00
|
|
|
case VENDOR_ERICSSON:
|
2010-12-20 05:35:29 +00:00
|
|
|
dissector_try_uint(diameter_ericsson_avp_dissector_table, code, subtvb, c->pinfo, avp_tree);
|
2010-05-07 11:08:56 +00:00
|
|
|
break;
|
|
|
|
case VENDOR_THE3GPP:
|
2010-12-20 05:35:29 +00:00
|
|
|
dissector_try_uint(diameter_3gpp_avp_dissector_table, code, subtvb, c->pinfo, avp_tree);
|
2008-01-27 21:06:33 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* Debug
|
|
|
|
proto_tree_add_text(avp_tree, subtvb, 0, -1, "AVP %u data, Vendor Id %u ",code,vendorid);
|
|
|
|
*/
|
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
return len;
|
|
|
|
}
|
2002-08-28 21:04:11 +00:00
|
|
|
|
2008-07-15 21:06:31 +00:00
|
|
|
static const char*
|
|
|
|
address_rfc_avp(diam_ctx_t* c, diam_avp_t* a, tvbuff_t* tvb)
|
|
|
|
{
|
2007-07-17 22:19:54 +00:00
|
|
|
char* label = ep_alloc(ITEM_LABEL_LENGTH+1);
|
|
|
|
address_avp_t* t = a->type_data;
|
2011-10-31 07:05:52 +00:00
|
|
|
proto_item* pi = proto_tree_add_item(c->tree,a->hf_value,tvb,0,tvb_length(tvb),ENC_BIG_ENDIAN);
|
2007-07-17 22:19:54 +00:00
|
|
|
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);
|
|
|
|
|
2011-10-31 07:05:52 +00:00
|
|
|
proto_tree_add_item(pt,t->hf_address_type,tvb,0,2,ENC_NA);
|
2007-07-17 22:19:54 +00:00
|
|
|
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]";
|
|
|
|
}
|
2011-11-02 01:53:37 +00:00
|
|
|
pi = proto_tree_add_item(pt,t->hf_ipv4,tvb,2,4,ENC_BIG_ENDIAN);
|
2007-07-17 22:19:54 +00:00
|
|
|
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]";
|
|
|
|
}
|
2011-10-31 07:05:52 +00:00
|
|
|
pi = proto_tree_add_item(pt,t->hf_ipv6,tvb,2,16,ENC_NA);
|
2007-07-17 22:19:54 +00:00
|
|
|
break;
|
|
|
|
default:
|
2011-10-31 07:05:52 +00:00
|
|
|
pi = proto_tree_add_item(pt,t->hf_other,tvb,2,-1,ENC_BIG_ENDIAN);
|
2007-07-17 22:19:54 +00:00
|
|
|
break;
|
|
|
|
}
|
2007-10-24 16:32:51 +00:00
|
|
|
|
2009-08-09 17:57:31 +00:00
|
|
|
proto_item_fill_label(PITEM_FINFO(pi), label);
|
2007-07-17 22:19:54 +00:00
|
|
|
label = strstr(label,": ")+2;
|
|
|
|
return label;
|
|
|
|
}
|
|
|
|
|
2008-07-15 21:06:31 +00:00
|
|
|
static const char*
|
|
|
|
proto_avp(diam_ctx_t* c, diam_avp_t* a, tvbuff_t* tvb)
|
2007-07-20 00:15:17 +00:00
|
|
|
{
|
|
|
|
proto_avp_t* t = a->type_data;
|
2007-10-24 16:32:51 +00:00
|
|
|
|
2007-07-20 00:15:17 +00:00
|
|
|
col_set_writable(c->pinfo->cinfo, FALSE);
|
|
|
|
|
|
|
|
if (!t->handle) {
|
|
|
|
t->handle = find_dissector(t->name);
|
|
|
|
if(!t->handle) t->handle = data_handle;
|
|
|
|
}
|
2007-10-24 16:32:51 +00:00
|
|
|
|
2007-07-20 00:15:17 +00:00
|
|
|
call_dissector(t->handle, tvb, c->pinfo, c->tree);
|
2007-10-24 16:32:51 +00:00
|
|
|
|
2007-07-20 00:15:17 +00:00
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
2008-07-15 21:06:31 +00:00
|
|
|
static const char*
|
|
|
|
time_avp(diam_ctx_t* c, diam_avp_t* a, tvbuff_t* tvb)
|
|
|
|
{
|
2007-10-23 05:50:00 +00:00
|
|
|
int len = tvb_length(tvb);
|
2011-02-08 02:38:51 +00:00
|
|
|
char* label = ep_alloc(ITEM_LABEL_LENGTH+1);
|
2007-07-20 00:15:17 +00:00
|
|
|
proto_item* pi;
|
2007-10-24 16:32:51 +00:00
|
|
|
|
2007-07-20 00:15:17 +00:00
|
|
|
if ( len != 4 ) {
|
2011-02-08 02:38:51 +00:00
|
|
|
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,
|
2008-07-15 21:06:31 +00:00
|
|
|
"Bad Timestamp Length (%u)", len);
|
2007-07-20 00:15:17 +00:00
|
|
|
return "[Malformed]";
|
|
|
|
}
|
2007-10-24 16:32:51 +00:00
|
|
|
|
2011-02-08 02:38:51 +00:00
|
|
|
pi = proto_tree_add_item(c->tree, (a->hf_value), tvb, 0, 4, ENC_TIME_NTP|ENC_BIG_ENDIAN);
|
|
|
|
proto_item_fill_label(PITEM_FINFO(pi), label);
|
|
|
|
label = strstr(label,": ")+2;
|
2007-07-20 00:15:17 +00:00
|
|
|
return label;
|
|
|
|
}
|
|
|
|
|
2008-07-15 21:06:31 +00:00
|
|
|
static const char*
|
|
|
|
address_v16_avp(diam_ctx_t* c, diam_avp_t* a, tvbuff_t* tvb)
|
|
|
|
{
|
2007-07-17 22:19:54 +00:00
|
|
|
char* label = ep_alloc(ITEM_LABEL_LENGTH+1);
|
|
|
|
address_avp_t* t = a->type_data;
|
2011-10-31 07:05:52 +00:00
|
|
|
proto_item* pi = proto_tree_add_item(c->tree,a->hf_value,tvb,0,tvb_length(tvb),ENC_BIG_ENDIAN);
|
2007-07-17 22:19:54 +00:00
|
|
|
proto_tree* pt = proto_item_add_subtree(pi,t->ett);
|
2007-10-23 05:50:00 +00:00
|
|
|
guint32 len = tvb_length(tvb);
|
2007-10-24 16:32:51 +00:00
|
|
|
|
2007-07-17 22:19:54 +00:00
|
|
|
switch (len) {
|
|
|
|
case 4:
|
2011-11-02 01:53:37 +00:00
|
|
|
pi = proto_tree_add_item(pt,t->hf_ipv4,tvb,0,4,ENC_BIG_ENDIAN);
|
2007-07-17 22:19:54 +00:00
|
|
|
break;
|
|
|
|
case 16:
|
2011-10-31 07:05:52 +00:00
|
|
|
pi = proto_tree_add_item(pt,t->hf_ipv6,tvb,0,16,ENC_NA);
|
2007-07-17 22:19:54 +00:00
|
|
|
break;
|
|
|
|
default:
|
2011-10-31 07:05:52 +00:00
|
|
|
pi = proto_tree_add_item(pt,t->hf_other,tvb,0,len,ENC_BIG_ENDIAN);
|
2007-07-17 22:19:54 +00:00
|
|
|
expert_add_info_format(c->pinfo, pi, PI_MALFORMED, PI_NOTE,
|
2008-07-15 21:06:31 +00:00
|
|
|
"Bad Address Length (%u)", len);
|
2007-10-24 16:32:51 +00:00
|
|
|
|
2007-07-17 22:19:54 +00:00
|
|
|
break;
|
|
|
|
}
|
2007-10-24 16:32:51 +00:00
|
|
|
|
2009-08-09 17:57:31 +00:00
|
|
|
proto_item_fill_label(PITEM_FINFO(pi), label);
|
2007-07-17 22:19:54 +00:00
|
|
|
label = strstr(label,": ")+2;
|
|
|
|
return label;
|
|
|
|
}
|
|
|
|
|
2008-07-15 21:06:31 +00:00
|
|
|
static const char*
|
|
|
|
simple_avp(diam_ctx_t* c, diam_avp_t* a, tvbuff_t* tvb)
|
|
|
|
{
|
2007-07-16 05:41:58 +00:00
|
|
|
char* label = ep_alloc(ITEM_LABEL_LENGTH+1);
|
2011-10-31 07:05:52 +00:00
|
|
|
proto_item* pi = proto_tree_add_item(c->tree,a->hf_value,tvb,0,tvb_length(tvb),ENC_BIG_ENDIAN);
|
|
|
|
proto_item_fill_label(PITEM_FINFO(pi), label);
|
|
|
|
label = strstr(label,": ")+2;
|
|
|
|
return label;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char*
|
|
|
|
utf8_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(tvb),ENC_UTF_8|ENC_BIG_ENDIAN);
|
2009-08-09 17:57:31 +00:00
|
|
|
proto_item_fill_label(PITEM_FINFO(pi), label);
|
2007-07-16 05:41:58 +00:00
|
|
|
label = strstr(label,": ")+2;
|
|
|
|
return label;
|
|
|
|
}
|
2005-04-26 08:15:45 +00:00
|
|
|
|
2008-07-15 21:06:31 +00:00
|
|
|
static const char*
|
2011-01-03 03:30:20 +00:00
|
|
|
integer32_avp(diam_ctx_t* c, diam_avp_t* a, tvbuff_t* tvb)
|
2008-07-15 21:06:31 +00:00
|
|
|
{
|
2011-01-03 08:21:35 +00:00
|
|
|
char* label;
|
2007-07-27 18:32:09 +00:00
|
|
|
proto_item* pi;
|
|
|
|
|
|
|
|
/* Verify length before adding */
|
|
|
|
gint length = tvb_length_remaining(tvb,0);
|
|
|
|
if (length == 4) {
|
2011-10-31 07:05:52 +00:00
|
|
|
pi= proto_tree_add_item(c->tree,a->hf_value,tvb,0,tvb_length_remaining(tvb,0),ENC_BIG_ENDIAN);
|
2011-01-03 08:21:35 +00:00
|
|
|
label = ep_alloc(ITEM_LABEL_LENGTH+1);
|
2009-08-09 17:57:31 +00:00
|
|
|
proto_item_fill_label(PITEM_FINFO(pi), label);
|
2007-07-27 18:32:09 +00:00
|
|
|
label = strstr(label,": ")+2;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
pi = proto_tree_add_bytes_format(c->tree, hf_diameter_avp_data_wrong_length,
|
Modify proto_tree_add_bytes_format() and proto_tree_add_bytes_format_value()
so that if the start_ptr is NULL the bytes are extracted from the given TVB
using the given offset and length.
Replace a bunch of:
proto_tree_add_bytes_format*(tree, hf, tvb, offset, length, tvb_get_ptr(tvb, offset, length), [...])
with:
proto_tree_add_bytes_format*(tree, hf, tvb, offset, length, NULL, [...])
svn path=/trunk/; revision=35896
2011-02-10 16:31:00 +00:00
|
|
|
tvb, 0, length, NULL,
|
2008-07-15 21:06:31 +00:00
|
|
|
"Error! Bad Integer32 Length");
|
|
|
|
expert_add_info_format(c->pinfo, pi, PI_MALFORMED, PI_NOTE,
|
|
|
|
"Bad Integer32 Length (%u)", length);
|
2007-07-27 18:32:09 +00:00
|
|
|
PROTO_ITEM_SET_GENERATED(pi);
|
2011-01-03 08:21:35 +00:00
|
|
|
label = NULL;
|
2007-07-27 18:32:09 +00:00
|
|
|
}
|
|
|
|
return label;
|
|
|
|
}
|
|
|
|
|
2011-01-03 03:30:20 +00:00
|
|
|
static const char*
|
|
|
|
integer64_avp(diam_ctx_t* c, diam_avp_t* a, tvbuff_t* tvb)
|
|
|
|
{
|
2011-01-03 08:21:35 +00:00
|
|
|
char* label;
|
2011-01-03 03:30:20 +00:00
|
|
|
proto_item* pi;
|
|
|
|
|
|
|
|
/* Verify length before adding */
|
|
|
|
gint length = tvb_length_remaining(tvb,0);
|
|
|
|
if (length == 8) {
|
2011-10-31 07:05:52 +00:00
|
|
|
pi= proto_tree_add_item(c->tree,a->hf_value,tvb,0,tvb_length_remaining(tvb,0),ENC_BIG_ENDIAN);
|
2011-01-03 08:21:35 +00:00
|
|
|
label = ep_alloc(ITEM_LABEL_LENGTH+1);
|
2011-01-03 03:30:20 +00:00
|
|
|
proto_item_fill_label(PITEM_FINFO(pi), label);
|
|
|
|
label = strstr(label,": ")+2;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
pi = proto_tree_add_bytes_format(c->tree, hf_diameter_avp_data_wrong_length,
|
Modify proto_tree_add_bytes_format() and proto_tree_add_bytes_format_value()
so that if the start_ptr is NULL the bytes are extracted from the given TVB
using the given offset and length.
Replace a bunch of:
proto_tree_add_bytes_format*(tree, hf, tvb, offset, length, tvb_get_ptr(tvb, offset, length), [...])
with:
proto_tree_add_bytes_format*(tree, hf, tvb, offset, length, NULL, [...])
svn path=/trunk/; revision=35896
2011-02-10 16:31:00 +00:00
|
|
|
tvb, 0, length, NULL,
|
2011-01-03 03:30:20 +00:00
|
|
|
"Error! Bad Integer64 Length");
|
|
|
|
expert_add_info_format(c->pinfo, pi, PI_MALFORMED, PI_NOTE,
|
|
|
|
"Bad Integer64 Length (%u)", length);
|
|
|
|
PROTO_ITEM_SET_GENERATED(pi);
|
2011-01-03 08:21:35 +00:00
|
|
|
label = NULL;
|
2011-01-03 03:30:20 +00:00
|
|
|
}
|
|
|
|
return label;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char*
|
|
|
|
unsigned32_avp(diam_ctx_t* c, diam_avp_t* a, tvbuff_t* tvb)
|
|
|
|
{
|
2011-01-03 08:21:35 +00:00
|
|
|
char* label;
|
2011-01-03 03:30:20 +00:00
|
|
|
proto_item* pi;
|
|
|
|
|
|
|
|
/* Verify length before adding */
|
|
|
|
gint length = tvb_length_remaining(tvb,0);
|
|
|
|
if (length == 4) {
|
2011-10-31 07:05:52 +00:00
|
|
|
pi= proto_tree_add_item(c->tree,a->hf_value,tvb,0,tvb_length_remaining(tvb,0),ENC_BIG_ENDIAN);
|
2011-01-03 08:21:35 +00:00
|
|
|
label = ep_alloc(ITEM_LABEL_LENGTH+1);
|
2011-01-03 03:30:20 +00:00
|
|
|
proto_item_fill_label(PITEM_FINFO(pi), label);
|
|
|
|
label = strstr(label,": ")+2;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
pi = proto_tree_add_bytes_format(c->tree, hf_diameter_avp_data_wrong_length,
|
Modify proto_tree_add_bytes_format() and proto_tree_add_bytes_format_value()
so that if the start_ptr is NULL the bytes are extracted from the given TVB
using the given offset and length.
Replace a bunch of:
proto_tree_add_bytes_format*(tree, hf, tvb, offset, length, tvb_get_ptr(tvb, offset, length), [...])
with:
proto_tree_add_bytes_format*(tree, hf, tvb, offset, length, NULL, [...])
svn path=/trunk/; revision=35896
2011-02-10 16:31:00 +00:00
|
|
|
tvb, 0, length, NULL,
|
2011-01-03 03:30:20 +00:00
|
|
|
"Error! Bad Unsigned32 Length");
|
|
|
|
expert_add_info_format(c->pinfo, pi, PI_MALFORMED, PI_NOTE,
|
|
|
|
"Bad Unsigned32 Length (%u)", length);
|
|
|
|
PROTO_ITEM_SET_GENERATED(pi);
|
2011-01-03 08:21:35 +00:00
|
|
|
label = NULL;
|
2011-01-03 03:30:20 +00:00
|
|
|
}
|
|
|
|
return label;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char*
|
|
|
|
unsigned64_avp(diam_ctx_t* c, diam_avp_t* a, tvbuff_t* tvb)
|
|
|
|
{
|
2011-01-03 08:21:35 +00:00
|
|
|
char* label;
|
2011-01-03 03:30:20 +00:00
|
|
|
proto_item* pi;
|
|
|
|
|
|
|
|
/* Verify length before adding */
|
|
|
|
gint length = tvb_length_remaining(tvb,0);
|
|
|
|
if (length == 8) {
|
2011-10-31 07:05:52 +00:00
|
|
|
pi= proto_tree_add_item(c->tree,a->hf_value,tvb,0,tvb_length_remaining(tvb,0),ENC_BIG_ENDIAN);
|
2011-01-03 08:21:35 +00:00
|
|
|
label = ep_alloc(ITEM_LABEL_LENGTH+1);
|
2011-01-03 03:30:20 +00:00
|
|
|
proto_item_fill_label(PITEM_FINFO(pi), label);
|
|
|
|
label = strstr(label,": ")+2;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
pi = proto_tree_add_bytes_format(c->tree, hf_diameter_avp_data_wrong_length,
|
Modify proto_tree_add_bytes_format() and proto_tree_add_bytes_format_value()
so that if the start_ptr is NULL the bytes are extracted from the given TVB
using the given offset and length.
Replace a bunch of:
proto_tree_add_bytes_format*(tree, hf, tvb, offset, length, tvb_get_ptr(tvb, offset, length), [...])
with:
proto_tree_add_bytes_format*(tree, hf, tvb, offset, length, NULL, [...])
svn path=/trunk/; revision=35896
2011-02-10 16:31:00 +00:00
|
|
|
tvb, 0, length, NULL,
|
2011-01-03 03:30:20 +00:00
|
|
|
"Error! Bad Unsigned64 Length");
|
|
|
|
expert_add_info_format(c->pinfo, pi, PI_MALFORMED, PI_NOTE,
|
|
|
|
"Bad Unsigned64 Length (%u)", length);
|
|
|
|
PROTO_ITEM_SET_GENERATED(pi);
|
2011-01-03 08:21:35 +00:00
|
|
|
label = NULL;
|
2011-01-03 03:30:20 +00:00
|
|
|
}
|
|
|
|
return label;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char*
|
|
|
|
float32_avp(diam_ctx_t* c, diam_avp_t* a, tvbuff_t* tvb)
|
|
|
|
{
|
2011-01-03 08:21:35 +00:00
|
|
|
char* label;
|
2011-01-03 03:30:20 +00:00
|
|
|
proto_item* pi;
|
|
|
|
|
|
|
|
/* Verify length before adding */
|
|
|
|
gint length = tvb_length_remaining(tvb,0);
|
|
|
|
if (length == 4) {
|
2011-10-31 07:05:52 +00:00
|
|
|
pi= proto_tree_add_item(c->tree,a->hf_value,tvb,0,tvb_length_remaining(tvb,0),ENC_BIG_ENDIAN);
|
2011-01-03 08:21:35 +00:00
|
|
|
label = ep_alloc(ITEM_LABEL_LENGTH+1);
|
2011-01-03 03:30:20 +00:00
|
|
|
proto_item_fill_label(PITEM_FINFO(pi), label);
|
|
|
|
label = strstr(label,": ")+2;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
pi = proto_tree_add_bytes_format(c->tree, hf_diameter_avp_data_wrong_length,
|
Modify proto_tree_add_bytes_format() and proto_tree_add_bytes_format_value()
so that if the start_ptr is NULL the bytes are extracted from the given TVB
using the given offset and length.
Replace a bunch of:
proto_tree_add_bytes_format*(tree, hf, tvb, offset, length, tvb_get_ptr(tvb, offset, length), [...])
with:
proto_tree_add_bytes_format*(tree, hf, tvb, offset, length, NULL, [...])
svn path=/trunk/; revision=35896
2011-02-10 16:31:00 +00:00
|
|
|
tvb, 0, length, NULL,
|
2011-01-03 03:30:20 +00:00
|
|
|
"Error! Bad Float32 Length");
|
|
|
|
expert_add_info_format(c->pinfo, pi, PI_MALFORMED, PI_NOTE,
|
|
|
|
"Bad Float32 Length (%u)", length);
|
|
|
|
PROTO_ITEM_SET_GENERATED(pi);
|
2011-01-03 08:21:35 +00:00
|
|
|
label = NULL;
|
2011-01-03 03:30:20 +00:00
|
|
|
}
|
|
|
|
return label;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char*
|
|
|
|
float64_avp(diam_ctx_t* c, diam_avp_t* a, tvbuff_t* tvb)
|
|
|
|
{
|
2011-01-03 08:21:35 +00:00
|
|
|
char* label;
|
2011-01-03 03:30:20 +00:00
|
|
|
proto_item* pi;
|
|
|
|
|
|
|
|
/* Verify length before adding */
|
|
|
|
gint length = tvb_length_remaining(tvb,0);
|
|
|
|
if (length == 8) {
|
2011-10-31 07:05:52 +00:00
|
|
|
pi= proto_tree_add_item(c->tree,a->hf_value,tvb,0,tvb_length_remaining(tvb,0),ENC_BIG_ENDIAN);
|
2011-01-03 08:21:35 +00:00
|
|
|
label = ep_alloc(ITEM_LABEL_LENGTH+1);
|
2011-01-03 03:30:20 +00:00
|
|
|
proto_item_fill_label(PITEM_FINFO(pi), label);
|
|
|
|
label = strstr(label,": ")+2;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
pi = proto_tree_add_bytes_format(c->tree, hf_diameter_avp_data_wrong_length,
|
Modify proto_tree_add_bytes_format() and proto_tree_add_bytes_format_value()
so that if the start_ptr is NULL the bytes are extracted from the given TVB
using the given offset and length.
Replace a bunch of:
proto_tree_add_bytes_format*(tree, hf, tvb, offset, length, tvb_get_ptr(tvb, offset, length), [...])
with:
proto_tree_add_bytes_format*(tree, hf, tvb, offset, length, NULL, [...])
svn path=/trunk/; revision=35896
2011-02-10 16:31:00 +00:00
|
|
|
tvb, 0, length, NULL,
|
2011-01-03 03:30:20 +00:00
|
|
|
"Error! Bad Float64 Length");
|
|
|
|
expert_add_info_format(c->pinfo, pi, PI_MALFORMED, PI_NOTE,
|
|
|
|
"Bad Float64 Length (%u)", length);
|
|
|
|
PROTO_ITEM_SET_GENERATED(pi);
|
2011-01-03 08:21:35 +00:00
|
|
|
label = NULL;
|
2011-01-03 03:30:20 +00:00
|
|
|
}
|
|
|
|
return label;
|
|
|
|
}
|
|
|
|
|
2008-07-15 21:06:31 +00:00
|
|
|
static const char*
|
|
|
|
grouped_avp(diam_ctx_t* c, diam_avp_t* a, tvbuff_t* tvb)
|
|
|
|
{
|
2007-07-16 05:41:58 +00:00
|
|
|
int offset = 0;
|
2007-10-23 05:50:00 +00:00
|
|
|
int len = tvb_length(tvb);
|
2011-10-31 07:05:52 +00:00
|
|
|
proto_item* pi = proto_tree_add_item(c->tree, a->hf_value, tvb , 0 , -1, ENC_BIG_ENDIAN);
|
2007-07-16 05:41:58 +00:00
|
|
|
proto_tree* pt = c->tree;
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
c->tree = proto_item_add_subtree(pi,a->ett);
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
while (offset < len) {
|
|
|
|
offset += dissect_diameter_avp(c, tvb, offset);
|
|
|
|
offset += (offset % 4) ? 4 - (offset % 4) : 0 ;
|
2001-11-01 21:52:44 +00:00
|
|
|
}
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
c->tree = pt;
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2001-11-01 21:52:44 +00:00
|
|
|
|
2007-07-18 15:07:45 +00:00
|
|
|
static const char* msgflags_str[] = {
|
2007-07-17 22:19:54 +00:00
|
|
|
"----", "---T", "--E-", "--ET",
|
|
|
|
"-P--", "-P-T", "-PE-", "-PET",
|
|
|
|
"R---", "R--T", "R-E-", "R-ET",
|
|
|
|
"RP--", "RP-T", "RPE-", "RPET"
|
|
|
|
};
|
|
|
|
|
2008-07-15 21:06:31 +00:00
|
|
|
static void
|
|
|
|
dissect_diameter_common(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree)
|
|
|
|
{
|
2007-07-16 05:41:58 +00:00
|
|
|
guint32 first_word = tvb_get_ntohl(tvb,0);
|
2007-07-17 21:29:18 +00:00
|
|
|
guint32 version = (first_word & 0xff000000) >> 24;
|
|
|
|
guint32 flags_bits = (tvb_get_ntohl(tvb,4) & 0xff000000) >> 24;
|
2007-07-16 05:41:58 +00:00
|
|
|
int packet_len = first_word & 0x00ffffff;
|
2007-07-20 11:39:09 +00:00
|
|
|
proto_item *pi, *cmd_item, *app_item, *version_item;
|
2007-07-17 22:19:54 +00:00
|
|
|
proto_tree* diam_tree;
|
2007-07-16 05:41:58 +00:00
|
|
|
diam_ctx_t* c = ep_alloc0(sizeof(diam_ctx_t));
|
|
|
|
int offset;
|
|
|
|
value_string* cmd_vs;
|
|
|
|
const char* cmd_str;
|
|
|
|
guint32 cmd = tvb_get_ntoh24(tvb,5);
|
|
|
|
guint32 fourth = tvb_get_ntohl(tvb,8);
|
2008-11-15 15:52:39 +00:00
|
|
|
guint32 hop_by_hop_id = 0;
|
|
|
|
conversation_t *conversation;
|
|
|
|
diameter_conv_info_t *diameter_conv_info;
|
|
|
|
diameter_req_ans_pair_t *diameter_pair;
|
|
|
|
proto_item *it;
|
|
|
|
nstime_t ns;
|
2010-10-19 15:21:05 +00:00
|
|
|
void* pd_save;
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2010-10-19 15:21:05 +00:00
|
|
|
pd_save = pinfo->private_data;
|
2009-08-09 06:26:46 +00:00
|
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "DIAMETER");
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2011-10-21 02:10:19 +00:00
|
|
|
pi = proto_tree_add_item(tree,proto_diameter,tvb,0,-1,ENC_NA);
|
2007-07-17 22:19:54 +00:00
|
|
|
diam_tree = proto_item_add_subtree(pi,ett_diameter);
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-17 22:19:54 +00:00
|
|
|
c->tree = diam_tree;
|
|
|
|
c->pinfo = pinfo;
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2011-10-06 03:35:44 +00:00
|
|
|
version_item = proto_tree_add_item(diam_tree,hf_diameter_version,tvb,0,1,ENC_BIG_ENDIAN);
|
|
|
|
proto_tree_add_item(diam_tree,hf_diameter_length,tvb,1,3,ENC_BIG_ENDIAN);
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2011-10-06 03:35:44 +00:00
|
|
|
pi = proto_tree_add_item(diam_tree,hf_diameter_flags,tvb,4,1,ENC_BIG_ENDIAN);
|
2007-07-16 05:41:58 +00:00
|
|
|
{
|
|
|
|
proto_tree* pt = proto_item_add_subtree(pi,ett_diameter_flags);
|
2011-10-10 00:39:31 +00:00
|
|
|
proto_tree_add_item(pt,hf_diameter_flags_request,tvb,4,1,ENC_BIG_ENDIAN);
|
|
|
|
proto_tree_add_item(pt,hf_diameter_flags_proxyable,tvb,4,1,ENC_BIG_ENDIAN);
|
|
|
|
proto_tree_add_item(pt,hf_diameter_flags_error,tvb,4,1,ENC_BIG_ENDIAN);
|
|
|
|
proto_tree_add_item(pt,hf_diameter_flags_T,tvb,4,1,ENC_BIG_ENDIAN);
|
|
|
|
proto_tree_add_item(pt,hf_diameter_flags_reserved4,tvb,4,1,ENC_BIG_ENDIAN);
|
2007-07-16 05:41:58 +00:00
|
|
|
if(flags_bits & 0x08) proto_item_set_expert_flags(pi, PI_MALFORMED, PI_WARN);
|
2011-10-10 00:39:31 +00:00
|
|
|
pi = proto_tree_add_item(pt,hf_diameter_flags_reserved5,tvb,4,1,ENC_BIG_ENDIAN);
|
2007-07-16 05:41:58 +00:00
|
|
|
if(flags_bits & 0x04) proto_item_set_expert_flags(pi, PI_MALFORMED, PI_WARN);
|
2011-10-10 00:39:31 +00:00
|
|
|
pi = proto_tree_add_item(pt,hf_diameter_flags_reserved6,tvb,4,1,ENC_BIG_ENDIAN);
|
2007-07-16 05:41:58 +00:00
|
|
|
if(flags_bits & 0x02) proto_item_set_expert_flags(pi, PI_MALFORMED, PI_WARN);
|
2011-10-10 00:39:31 +00:00
|
|
|
pi = proto_tree_add_item(pt,hf_diameter_flags_reserved7,tvb,4,1,ENC_BIG_ENDIAN);
|
2007-07-16 05:41:58 +00:00
|
|
|
if(flags_bits & 0x01) proto_item_set_expert_flags(pi, PI_MALFORMED, PI_WARN);
|
2001-11-01 21:52:44 +00:00
|
|
|
}
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2011-10-06 03:35:44 +00:00
|
|
|
cmd_item = proto_tree_add_item(diam_tree,hf_diameter_code,tvb,5,3,ENC_BIG_ENDIAN);
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
switch (version) {
|
|
|
|
case DIAMETER_V16: {
|
|
|
|
guint32 vendorid = tvb_get_ntohl(tvb,8);
|
|
|
|
diam_vnd_t* vendor;
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
if (! ( vendor = emem_tree_lookup32(dictionary.vnds,vendorid) ) ) {
|
|
|
|
vendor = &unknown_vendor;
|
|
|
|
}
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
cmd_vs = VND_CMD_VS(vendor);
|
2011-10-06 03:35:44 +00:00
|
|
|
proto_tree_add_item(diam_tree, hf_diameter_vendor_id,tvb,8,4,ENC_BIG_ENDIAN);
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
c->version_rfc = FALSE;
|
2005-11-19 15:59:30 +00:00
|
|
|
break;
|
2007-07-16 05:41:58 +00:00
|
|
|
}
|
|
|
|
case DIAMETER_RFC: {
|
2010-10-19 15:21:05 +00:00
|
|
|
guint32 application_id;
|
|
|
|
application_id = tvb_get_ntohl(tvb,8);
|
2008-07-15 21:06:31 +00:00
|
|
|
cmd_vs = (value_string*)(void*)all_cmds->data;
|
2010-10-19 15:21:05 +00:00
|
|
|
/* Store the application id to be used by subdissectors */
|
|
|
|
pinfo->private_data = &application_id;
|
2011-10-18 00:17:48 +00:00
|
|
|
app_item = proto_tree_add_item(diam_tree, hf_diameter_application_id,tvb,8,4,ENC_BIG_ENDIAN);
|
2007-07-20 11:39:09 +00:00
|
|
|
if (strcmp(val_to_str(tvb_get_ntohl(tvb, 8), dictionary.applications,
|
|
|
|
"Unknown"), "Unknown") == 0) {
|
|
|
|
proto_tree* tu = proto_item_add_subtree(app_item,ett_unknown);
|
|
|
|
proto_item* iu = proto_tree_add_text(tu,tvb, 8 ,4,"Unknown Application Id, "
|
|
|
|
"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 Application Id (%u)",
|
|
|
|
tvb_get_ntohl(tvb, 8));
|
|
|
|
PROTO_ITEM_SET_GENERATED(iu);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
c->version_rfc = TRUE;
|
2005-11-19 15:59:30 +00:00
|
|
|
break;
|
2007-07-16 05:41:58 +00:00
|
|
|
}
|
2005-11-19 15:59:30 +00:00
|
|
|
default:
|
2007-07-17 22:19:54 +00:00
|
|
|
{
|
|
|
|
proto_tree* pt = proto_item_add_subtree(version_item,ett_err);
|
2008-06-27 16:15:30 +00:00
|
|
|
proto_item* pi_local = proto_tree_add_text(pt,tvb,0,1,"Unknown Diameter Version (decoding as RFC 3588)");
|
|
|
|
expert_add_info_format(pinfo, pi_local, PI_UNDECODED, PI_WARN, "Unknown Diameter Version");
|
2007-07-18 13:18:41 +00:00
|
|
|
PROTO_ITEM_SET_GENERATED(pi);
|
2007-07-16 05:41:58 +00:00
|
|
|
c->version_rfc = TRUE;
|
|
|
|
cmd_vs = VND_CMD_VS(&no_vnd);
|
|
|
|
break;
|
2007-07-17 22:19:54 +00:00
|
|
|
}
|
2005-11-19 15:59:30 +00:00
|
|
|
}
|
2007-07-16 05:41:58 +00:00
|
|
|
cmd_str = val_to_str(cmd, cmd_vs, "Unknown");
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2010-09-15 16:16:23 +00:00
|
|
|
col_add_fstr(pinfo->cinfo, COL_INFO,
|
|
|
|
"cmd=%s%s(%d) flags=%s %s=%s(%d) h2h=%x e2e=%x",
|
|
|
|
cmd_str,
|
|
|
|
((flags_bits>>4)&0x08) ? "Request" : "Answer",
|
|
|
|
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,
|
|
|
|
tvb_get_ntohl(tvb,12),
|
|
|
|
tvb_get_ntohl(tvb,16));
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-20 11:39:09 +00:00
|
|
|
/* Append name to command item, warn if unknown */
|
2007-07-16 05:41:58 +00:00
|
|
|
proto_item_append_text(cmd_item," %s", cmd_str);
|
2007-07-20 11:39:09 +00:00
|
|
|
if (strcmp(cmd_str, "Unknown") == 0) {
|
|
|
|
proto_tree* tu = proto_item_add_subtree(cmd_item,ett_unknown);
|
|
|
|
proto_item* iu = proto_tree_add_text(tu,tvb, 5 ,3,"Unknown command, "
|
|
|
|
"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 command (%u)", cmd);
|
|
|
|
PROTO_ITEM_SET_GENERATED(iu);
|
|
|
|
}
|
2001-11-01 21:52:44 +00:00
|
|
|
|
2010-04-26 22:19:34 +00:00
|
|
|
|
2008-11-15 15:52:39 +00:00
|
|
|
hop_by_hop_id = tvb_get_ntohl(tvb, 12);
|
2011-10-06 03:35:44 +00:00
|
|
|
proto_tree_add_item(diam_tree,hf_diameter_hopbyhopid,tvb,12,4,ENC_BIG_ENDIAN);
|
|
|
|
proto_tree_add_item(diam_tree,hf_diameter_endtoendid,tvb,16,4,ENC_BIG_ENDIAN);
|
2007-07-17 22:19:54 +00:00
|
|
|
|
2008-11-15 15:52:39 +00:00
|
|
|
/* Conversation tracking stuff */
|
2010-04-26 22:19:34 +00:00
|
|
|
/*
|
2008-11-15 15:52:39 +00:00
|
|
|
* FIXME: Looking at epan/conversation.c it seems unlike that this will work properly in
|
|
|
|
* multi-homed SCTP connections. This will probably need to be fixed at some point.
|
|
|
|
*/
|
|
|
|
|
2010-05-13 18:28:34 +00:00
|
|
|
conversation = find_or_create_conversation(pinfo);
|
2008-11-15 15:52:39 +00:00
|
|
|
|
|
|
|
diameter_conv_info = conversation_get_proto_data(conversation, proto_diameter);
|
|
|
|
if (!diameter_conv_info) {
|
|
|
|
diameter_conv_info = se_alloc(sizeof(diameter_conv_info_t));
|
|
|
|
diameter_conv_info->pdus = se_tree_create_non_persistent(
|
|
|
|
EMEM_TREE_TYPE_RED_BLACK, "diameter_pdus");
|
|
|
|
|
|
|
|
conversation_add_proto_data(conversation, proto_diameter, diameter_conv_info);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!pinfo->fd->flags.visited) {
|
|
|
|
if (flags_bits & 0x80) {
|
|
|
|
/* This is a request */
|
|
|
|
diameter_pair = se_alloc(sizeof(diameter_req_ans_pair_t));
|
|
|
|
diameter_pair->hop_by_hop_id = hop_by_hop_id;
|
|
|
|
diameter_pair->cmd_code = cmd;
|
2010-03-06 20:54:58 +00:00
|
|
|
diameter_pair->result_code = 0;
|
2009-04-13 18:14:25 +00:00
|
|
|
diameter_pair->cmd_str = cmd_str;
|
2008-11-15 15:52:39 +00:00
|
|
|
diameter_pair->req_frame = pinfo->fd->num;
|
|
|
|
diameter_pair->ans_frame = 0;
|
|
|
|
diameter_pair->req_time = pinfo->fd->abs_ts;
|
|
|
|
se_tree_insert32(diameter_conv_info->pdus, hop_by_hop_id, (void *)diameter_pair);
|
|
|
|
} else {
|
|
|
|
diameter_pair = se_tree_lookup32(diameter_conv_info->pdus, hop_by_hop_id);
|
|
|
|
if (diameter_pair) {
|
|
|
|
diameter_pair->ans_frame = pinfo->fd->num;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
diameter_pair = se_tree_lookup32(diameter_conv_info->pdus, hop_by_hop_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!diameter_pair) {
|
|
|
|
/* create a "fake" diameter_pair structure */
|
|
|
|
diameter_pair = ep_alloc(sizeof(diameter_req_ans_pair_t));
|
2010-03-06 20:54:58 +00:00
|
|
|
diameter_pair->hop_by_hop_id = hop_by_hop_id;
|
|
|
|
diameter_pair->cmd_code = cmd;
|
|
|
|
diameter_pair->result_code = 0;
|
|
|
|
diameter_pair->cmd_str = cmd_str;
|
2008-11-15 15:52:39 +00:00
|
|
|
diameter_pair->req_frame = 0;
|
|
|
|
diameter_pair->ans_frame = 0;
|
|
|
|
diameter_pair->req_time = pinfo->fd->abs_ts;
|
|
|
|
}
|
2010-03-06 20:54:58 +00:00
|
|
|
diameter_pair->processing_request=(flags_bits & 0x80)!=0;
|
2008-11-15 15:52:39 +00:00
|
|
|
|
2007-07-17 22:19:54 +00:00
|
|
|
if (!tree) return;
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2008-11-15 15:52:39 +00:00
|
|
|
/* print state tracking info in the tree */
|
|
|
|
if (flags_bits & 0x80) {
|
|
|
|
/* This is a request */
|
|
|
|
if (diameter_pair->ans_frame) {
|
|
|
|
it = proto_tree_add_uint(diam_tree, hf_diameter_answer_in,
|
|
|
|
tvb, 0, 0, diameter_pair->ans_frame);
|
|
|
|
PROTO_ITEM_SET_GENERATED(it);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* This is an answer */
|
|
|
|
if (diameter_pair->req_frame) {
|
|
|
|
it = proto_tree_add_uint(diam_tree, hf_diameter_answer_to,
|
|
|
|
tvb, 0, 0, diameter_pair->req_frame);
|
|
|
|
PROTO_ITEM_SET_GENERATED(it);
|
|
|
|
|
|
|
|
nstime_delta(&ns, &pinfo->fd->abs_ts, &diameter_pair->req_time);
|
2010-04-26 22:19:34 +00:00
|
|
|
diameter_pair->srt_time = ns;
|
2008-11-15 15:52:39 +00:00
|
|
|
it = proto_tree_add_time(diam_tree, hf_diameter_answer_time, tvb, 0, 0, &ns);
|
|
|
|
PROTO_ITEM_SET_GENERATED(it);
|
|
|
|
/* TODO: Populate result_code in tap record from AVP 268 */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
offset = 20;
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-27 18:32:09 +00:00
|
|
|
/* Dissect AVPs until the end of the packet is reached */
|
2007-07-16 05:41:58 +00:00
|
|
|
while (offset < packet_len) {
|
|
|
|
offset += dissect_diameter_avp(c, tvb, offset);
|
2007-07-27 18:32:09 +00:00
|
|
|
|
|
|
|
/* Skip to next 4-byte boundary */
|
2007-07-16 05:41:58 +00:00
|
|
|
offset += (offset % 4) ? 4 - (offset % 4) : 0 ;
|
|
|
|
}
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2010-03-06 20:54:58 +00:00
|
|
|
|
|
|
|
/* Handle requests for which no answers were found and
|
|
|
|
* anawers for which no requests were found in the tap listener.
|
|
|
|
* In case if you don't need unpaired requests/answers use:
|
|
|
|
* if(diameter_pair->processing_request || !diameter_pair->req_frame)
|
|
|
|
* return;
|
|
|
|
*/
|
|
|
|
tap_queue_packet(diameter_tap, pinfo, diameter_pair);
|
2010-10-19 15:21:05 +00:00
|
|
|
|
|
|
|
pinfo->private_data = pd_save;
|
2007-07-16 05:41:58 +00:00
|
|
|
}
|
2001-11-01 21:52:44 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
static guint
|
|
|
|
get_diameter_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
|
2001-11-01 21:52:44 +00:00
|
|
|
{
|
2007-07-16 05:41:58 +00:00
|
|
|
/* Get the length of the Diameter packet. */
|
|
|
|
return tvb_get_ntoh24(tvb, offset + 1);
|
|
|
|
}
|
2001-11-01 21:52:44 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
static gboolean
|
|
|
|
check_diameter(tvbuff_t *tvb)
|
2001-11-01 21:52:44 +00:00
|
|
|
{
|
2007-11-08 22:36:19 +00:00
|
|
|
if (tvb_length(tvb) < 1)
|
2007-07-16 05:41:58 +00:00
|
|
|
return FALSE; /* not enough bytes to check the version */
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
if (tvb_get_guint8(tvb, 0) != 1)
|
|
|
|
return FALSE; /* not version 1 */
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
/*
|
|
|
|
* XXX - fetch length and make sure it's at least MIN_DIAMETER_SIZE?
|
|
|
|
* Fetch flags and check that none of the DIAM_FLAGS_RESERVED bits
|
|
|
|
* are set?
|
|
|
|
*/
|
|
|
|
return TRUE;
|
|
|
|
}
|
2001-11-01 21:52:44 +00:00
|
|
|
|
2008-04-05 05:41:59 +00:00
|
|
|
/************************************************/
|
|
|
|
/* Main dissection function */
|
2001-11-01 21:52:44 +00:00
|
|
|
static int
|
2007-07-16 05:41:58 +00:00
|
|
|
dissect_diameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
2001-11-01 21:52:44 +00:00
|
|
|
{
|
2007-07-16 05:41:58 +00:00
|
|
|
if (!check_diameter(tvb))
|
|
|
|
return 0;
|
|
|
|
dissect_diameter_common(tvb, pinfo, tree);
|
|
|
|
return tvb_length(tvb);
|
|
|
|
}
|
2001-11-01 21:52:44 +00:00
|
|
|
|
|
|
|
static void
|
2007-07-16 05:41:58 +00:00
|
|
|
dissect_diameter_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
2001-11-01 21:52:44 +00:00
|
|
|
{
|
2011-06-21 11:53:33 +00:00
|
|
|
/* Check if we have the start of a PDU or if this is segment */
|
2012-03-13 15:06:40 +00:00
|
|
|
if (!check_diameter(tvb)) {
|
2011-06-21 11:53:33 +00:00
|
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "DIAMETER");
|
|
|
|
col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
|
|
|
|
call_dissector(data_handle, tvb, pinfo, tree);
|
2012-03-13 15:06:40 +00:00
|
|
|
} else {
|
2011-06-21 11:53:33 +00:00
|
|
|
tcp_dissect_pdus(tvb, pinfo, tree, gbl_diameter_desegment, 4,
|
|
|
|
get_diameter_pdu_len, dissect_diameter_common);
|
|
|
|
}
|
2010-10-18 15:56:06 +00:00
|
|
|
}
|
2001-11-01 21:52:44 +00:00
|
|
|
|
2002-01-07 20:05:20 +00:00
|
|
|
|
2008-07-15 21:06:31 +00:00
|
|
|
static char*
|
|
|
|
alnumerize(char* name)
|
|
|
|
{
|
2007-07-16 05:41:58 +00:00
|
|
|
char* r = name;
|
|
|
|
char* w = name;
|
|
|
|
char c;
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
for (;(c = *r); r++) {
|
2007-10-24 02:12:46 +00:00
|
|
|
if (isalnum((unsigned char)c) || c == '_' || c == '-' || c == '.') {
|
2007-07-16 05:41:58 +00:00
|
|
|
*(w++) = c;
|
2001-11-01 21:52:44 +00:00
|
|
|
}
|
2001-07-30 20:08:44 +00:00
|
|
|
}
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
*w = '\0';
|
2001-02-19 23:14:02 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
return name;
|
2004-02-21 10:29:52 +00:00
|
|
|
}
|
|
|
|
|
2001-07-30 20:08:44 +00:00
|
|
|
|
2008-07-15 21:06:31 +00:00
|
|
|
static guint
|
|
|
|
reginfo(int* hf_ptr, const char* name, const char* abbr, const char* desc,
|
2010-11-15 21:05:03 +00:00
|
|
|
enum ftenum ft, base_display_e base, value_string_ext* vs_ext,
|
2008-07-15 21:06:31 +00:00
|
|
|
guint32 mask)
|
|
|
|
{
|
2007-07-16 05:41:58 +00:00
|
|
|
hf_register_info hf = { hf_ptr, {
|
2008-07-15 21:06:31 +00:00
|
|
|
name ? g_strdup(name) : g_strdup(abbr),
|
|
|
|
g_strdup(abbr),
|
|
|
|
ft,
|
|
|
|
base,
|
2010-11-15 21:05:03 +00:00
|
|
|
NULL,
|
2008-07-15 21:06:31 +00:00
|
|
|
mask,
|
2009-06-24 02:17:12 +00:00
|
|
|
g_strdup(desc),
|
2008-07-15 21:06:31 +00:00
|
|
|
HFILL }};
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2012-03-13 15:06:40 +00:00
|
|
|
if(vs_ext) {
|
2010-11-15 21:05:03 +00:00
|
|
|
hf.hfinfo.strings = vs_ext;
|
|
|
|
}
|
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
g_array_append_vals(build_dict.hf,&hf,1);
|
|
|
|
return build_dict.hf->len - 1;
|
|
|
|
}
|
2001-02-19 23:14:02 +00:00
|
|
|
|
2008-07-15 21:06:31 +00:00
|
|
|
static void
|
|
|
|
basic_avp_reginfo(diam_avp_t* a, const char* name, enum ftenum ft,
|
2010-11-10 20:11:38 +00:00
|
|
|
base_display_e base, value_string_ext* vs_ext)
|
2008-07-15 21:06:31 +00:00
|
|
|
{
|
|
|
|
hf_register_info hf[] = { { &(a->hf_value),
|
2010-11-10 20:11:38 +00:00
|
|
|
{ NULL, NULL, ft, base, NULL, 0x0,
|
2008-07-15 21:06:31 +00:00
|
|
|
a->vendor->code ?
|
|
|
|
g_strdup_printf("vendor=%d code=%d", a->vendor->code, a->code)
|
|
|
|
: g_strdup_printf("code=%d", a->code),
|
|
|
|
HFILL }}
|
2007-07-16 05:41:58 +00:00
|
|
|
};
|
|
|
|
gint* ettp = &(a->ett);
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
hf->hfinfo.name = g_strdup_printf("%s",name);
|
|
|
|
hf->hfinfo.abbrev = alnumerize(g_strdup_printf("diameter.%s",name));
|
2012-03-13 15:06:40 +00:00
|
|
|
if(vs_ext) {
|
2010-11-10 20:11:38 +00:00
|
|
|
hf->hfinfo.strings = vs_ext;
|
|
|
|
}
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
g_array_append_vals(build_dict.hf,hf,1);
|
2008-07-16 08:08:17 +00:00
|
|
|
g_ptr_array_add(build_dict.ett,ettp);
|
2007-07-16 05:41:58 +00:00
|
|
|
}
|
2002-08-28 21:04:11 +00:00
|
|
|
|
2008-07-15 21:06:31 +00:00
|
|
|
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_, void* data _U_)
|
|
|
|
{
|
2007-07-17 22:19:54 +00:00
|
|
|
diam_avp_t* a = g_malloc0(sizeof(diam_avp_t));
|
|
|
|
address_avp_t* t = g_malloc(sizeof(address_avp_t));
|
|
|
|
gint* ettp = &(t->ett);
|
2007-10-24 16:32:51 +00:00
|
|
|
|
2007-07-17 22:19:54 +00:00
|
|
|
a->code = code;
|
|
|
|
a->vendor = vendor;
|
2007-11-08 22:36:19 +00:00
|
|
|
/*
|
|
|
|
It seems like the radius AVP:s 1-255 will use the defs from RADIUS in which case:
|
|
|
|
http://www.ietf.org/rfc/rfc2865.txt?number=2865
|
|
|
|
Address
|
|
|
|
|
|
|
|
The Address field is four octets. The value 0xFFFFFFFF indicates
|
|
|
|
that the NAS Should allow the user to select an address (e.g.
|
|
|
|
Negotiated). The value 0xFFFFFFFE indicates that the NAS should
|
|
|
|
select an address for the user (e.g. Assigned from a pool of
|
|
|
|
addresses kept by the NAS). Other valid values indicate that the
|
|
|
|
NAS should use that value as the user's IP address.
|
|
|
|
Where as in Diameter:
|
|
|
|
RFC3588
|
|
|
|
Address
|
|
|
|
The Address format is derived from the OctetString AVP Base
|
|
|
|
Format. It is a discriminated union, representing, for example a
|
|
|
|
32-bit (IPv4) [IPV4] or 128-bit (IPv6) [IPV6] address, most
|
|
|
|
significant octet first. The first two octets of the Address
|
|
|
|
AVP represents the AddressType, which contains an Address Family
|
|
|
|
defined in [IANAADFAM]. The AddressType is used to discriminate
|
|
|
|
the content and format of the remaining octets.
|
|
|
|
|
|
|
|
*/
|
2007-07-17 22:19:54 +00:00
|
|
|
a->dissector_v16 = address_v16_avp;
|
2008-07-15 21:06:31 +00:00
|
|
|
if (code<256) {
|
2007-11-08 22:36:19 +00:00
|
|
|
a->dissector_rfc = address_v16_avp;
|
2008-07-15 21:06:31 +00:00
|
|
|
} else {
|
2007-11-08 22:36:19 +00:00
|
|
|
a->dissector_rfc = address_rfc_avp;
|
|
|
|
}
|
2007-07-17 22:19:54 +00:00
|
|
|
a->ett = -1;
|
|
|
|
a->hf_value = -1;
|
|
|
|
a->type_data = t;
|
2007-10-24 16:32:51 +00:00
|
|
|
|
2007-07-17 22:19:54 +00:00
|
|
|
t->ett = -1;
|
|
|
|
t->hf_address_type = -1;
|
|
|
|
t->hf_ipv4 = -1;
|
|
|
|
t->hf_ipv6 = -1;
|
|
|
|
t->hf_other = -1;
|
2007-10-24 16:32:51 +00:00
|
|
|
|
2007-07-17 22:19:54 +00:00
|
|
|
basic_avp_reginfo(a,name,FT_BYTES,BASE_NONE,NULL);
|
2007-10-24 16:32:51 +00:00
|
|
|
|
2007-07-17 22:19:54 +00:00
|
|
|
reginfo(&(t->hf_address_type), ep_strdup_printf("%s Address Family",name),
|
2008-07-15 21:06:31 +00:00
|
|
|
alnumerize(ep_strdup_printf("diameter.%s.addr_family",name)),
|
2010-11-15 21:05:03 +00:00
|
|
|
NULL, FT_UINT16, BASE_DEC|BASE_EXT_STRING, &diameter_avp_data_addrfamily_vals_ext, 0);
|
2007-10-24 16:32:51 +00:00
|
|
|
|
2007-07-17 22:19:54 +00:00
|
|
|
reginfo(&(t->hf_ipv4), ep_strdup_printf("%s Address",name),
|
2008-07-15 21:06:31 +00:00
|
|
|
alnumerize(ep_strdup_printf("diameter.%s",name)),
|
2009-06-24 02:17:12 +00:00
|
|
|
NULL, FT_IPv4, BASE_NONE, NULL, 0);
|
2007-10-24 16:32:51 +00:00
|
|
|
|
2007-07-17 22:19:54 +00:00
|
|
|
reginfo(&(t->hf_ipv6), ep_strdup_printf("%s Address",name),
|
2008-07-15 21:06:31 +00:00
|
|
|
alnumerize(ep_strdup_printf("diameter.%s",name)),
|
2009-06-24 02:17:12 +00:00
|
|
|
NULL, FT_IPv6, BASE_NONE, NULL, 0);
|
2007-10-24 16:32:51 +00:00
|
|
|
|
2007-07-17 22:19:54 +00:00
|
|
|
reginfo(&(t->hf_other), ep_strdup_printf("%s Address",name),
|
2008-07-15 21:06:31 +00:00
|
|
|
alnumerize(ep_strdup_printf("diameter.%s",name)),
|
2009-06-24 02:17:12 +00:00
|
|
|
NULL, FT_BYTES, BASE_NONE, NULL, 0);
|
2007-10-24 16:32:51 +00:00
|
|
|
|
2008-07-16 08:08:17 +00:00
|
|
|
g_ptr_array_add(build_dict.ett,ettp);
|
2007-10-24 16:32:51 +00:00
|
|
|
|
2007-07-17 22:19:54 +00:00
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
2008-07-15 21:06:31 +00:00
|
|
|
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)
|
|
|
|
{
|
2007-07-20 00:15:17 +00:00
|
|
|
diam_avp_t* a = g_malloc0(sizeof(diam_avp_t));
|
|
|
|
proto_avp_t* t = g_malloc0(sizeof(proto_avp_t));
|
|
|
|
gint* ettp = &(a->ett);
|
2007-10-24 16:32:51 +00:00
|
|
|
|
2007-07-20 00:15:17 +00:00
|
|
|
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;
|
2007-10-24 16:32:51 +00:00
|
|
|
|
2007-07-20 00:15:17 +00:00
|
|
|
t->name = data;
|
|
|
|
t->handle = NULL;
|
|
|
|
t->reassemble_mode = 0;
|
2007-10-24 16:32:51 +00:00
|
|
|
|
2008-07-16 08:08:17 +00:00
|
|
|
g_ptr_array_add(build_dict.ett,ettp);
|
2007-10-24 16:32:51 +00:00
|
|
|
|
2007-07-20 00:15:17 +00:00
|
|
|
return a;
|
|
|
|
}
|
2007-07-17 22:19:54 +00:00
|
|
|
|
2008-07-15 21:06:31 +00:00
|
|
|
static diam_avp_t*
|
|
|
|
build_simple_avp(const avp_type_t* type, guint32 code, const diam_vnd_t* vendor,
|
2010-10-18 15:56:06 +00:00
|
|
|
const char* name, const value_string* vs, void* data _U_)
|
2008-07-15 21:06:31 +00:00
|
|
|
{
|
2007-11-27 01:41:42 +00:00
|
|
|
diam_avp_t* a;
|
2010-11-10 20:11:38 +00:00
|
|
|
value_string_ext *vs_ext = NULL;
|
|
|
|
base_display_e base;
|
|
|
|
guint i = 0;
|
2007-11-27 01:41:42 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Only 32-bit or shorter integral types can have a list of values.
|
|
|
|
*/
|
2010-11-10 20:11:38 +00:00
|
|
|
base = type->base;
|
2007-11-27 01:41:42 +00:00
|
|
|
if (vs != NULL) {
|
|
|
|
switch (type->ft) {
|
|
|
|
|
|
|
|
case FT_UINT8:
|
|
|
|
case FT_UINT16:
|
|
|
|
case FT_UINT32:
|
|
|
|
case FT_INT8:
|
|
|
|
case FT_INT16:
|
|
|
|
case FT_INT32:
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2012-03-19 17:12:04 +00:00
|
|
|
fprintf(stderr,"Diameter Dictionary: AVP '%s' has a list of values but isn't of a 32-bit or shorter integral type\n",
|
2008-07-15 21:06:31 +00:00
|
|
|
name);
|
2007-11-27 01:41:42 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2010-11-10 20:11:38 +00:00
|
|
|
while (vs[i].strptr) {
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
vs_ext = value_string_ext_new((void*)vs, i+1, g_strdup_printf("%s_vals_ext",name));
|
|
|
|
base = base|BASE_EXT_STRING;
|
2007-11-27 01:41:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
a = g_malloc0(sizeof(diam_avp_t));
|
2007-07-16 05:41:58 +00:00
|
|
|
a->code = code;
|
|
|
|
a->vendor = vendor;
|
|
|
|
a->dissector_v16 = type->v16;
|
|
|
|
a->dissector_rfc = type->rfc;
|
|
|
|
a->ett = -1;
|
|
|
|
a->hf_value = -1;
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2010-11-10 20:11:38 +00:00
|
|
|
basic_avp_reginfo(a,name,type->ft,base,vs_ext);
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
return a;
|
|
|
|
}
|
2002-08-28 21:04:11 +00:00
|
|
|
|
2001-11-03 12:19:56 +00:00
|
|
|
|
2007-07-20 00:15:17 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
static const avp_type_t basic_types[] = {
|
2012-03-12 17:30:38 +00:00
|
|
|
{"octetstring" , simple_avp , simple_avp , FT_BYTES , BASE_NONE , build_simple_avp },
|
|
|
|
{"utf8string" , utf8_avp , utf8_avp , FT_STRING , BASE_NONE , build_simple_avp },
|
|
|
|
{"grouped" , grouped_avp , grouped_avp , FT_BYTES , BASE_NONE , build_simple_avp },
|
|
|
|
{"integer32" , integer32_avp , integer32_avp , FT_INT32 , BASE_DEC , build_simple_avp },
|
|
|
|
{"unsigned32" , unsigned32_avp , unsigned32_avp, FT_UINT32 , BASE_DEC , build_simple_avp },
|
|
|
|
{"integer64" , integer64_avp , integer64_avp , FT_INT64 , BASE_DEC , build_simple_avp },
|
|
|
|
{"unsigned64" , unsigned64_avp , unsigned64_avp, FT_UINT64 , BASE_DEC , build_simple_avp },
|
|
|
|
{"float32" , float32_avp , float32_avp , FT_FLOAT , BASE_NONE , build_simple_avp },
|
|
|
|
{"float64" , float64_avp , float64_avp , FT_DOUBLE , BASE_NONE , build_simple_avp },
|
|
|
|
{"ipaddress" , NULL , NULL , FT_NONE , BASE_NONE , build_address_avp },
|
|
|
|
{"diameteruri" , utf8_avp , utf8_avp , FT_STRING , BASE_NONE , build_simple_avp },
|
|
|
|
{"diameteridentity" , utf8_avp , utf8_avp , FT_STRING , BASE_NONE , build_simple_avp },
|
|
|
|
{"ipfilterrule" , utf8_avp , utf8_avp , FT_STRING , BASE_NONE , build_simple_avp },
|
|
|
|
{"qosfilterrule" , utf8_avp , utf8_avp , FT_STRING , BASE_NONE , build_simple_avp },
|
|
|
|
{"time" , time_avp , time_avp , FT_ABSOLUTE_TIME , ABSOLUTE_TIME_UTC , build_simple_avp },
|
2007-07-16 05:41:58 +00:00
|
|
|
{NULL, NULL, NULL, FT_NONE, BASE_NONE, NULL }
|
|
|
|
};
|
2004-02-21 10:29:52 +00:00
|
|
|
|
2007-07-20 00:15:17 +00:00
|
|
|
|
|
|
|
|
strcasecmp(), strncasecmp(), g_strcasecmp(), and g_strncasecmp() delenda
est. Use g_ascii_strcasecmp() and g_ascii_strncasecmp(), and supply our
own versions if they're missing from GLib (as is the case with GLib
1.x).
In the code to build the list of named fields for Diameter, don't use
g_strdown(); do our own g_ascii_-style upper-case to lower-case mapping
in the hash function and use g_ascii_strcasecmp() in the compare
function.
We do this because there is no guarantee that toupper(), tolower(), and
functions that use them will, for example, map between "I" and "i" in
all locales; in Turkish locales, for example, there are, in both
upper case and lower case, versions of "i" with and without a dot, and
the upper-case version of "i" is "I"-with-a-dot and the lower-case
version of "I" is "i"-without-a-dot. This causes strings that should
match not to match.
This finishes fixing bug 2010 - an earlier checkin prevented the crash
(as there are other ways to produce the same crash, e.g. a bogus
dictionary.xml file), but didn't fix the case-insensitive string matching.
svn path=/trunk/; revision=23623
2007-11-27 18:52:51 +00:00
|
|
|
/*
|
|
|
|
* This is like g_str_hash() (as of GLib 2.4.8), but it maps all
|
|
|
|
* upper-case ASCII characters to their ASCII lower-case equivalents.
|
|
|
|
* We can't use g_strdown(), as that doesn't do an ASCII mapping;
|
|
|
|
* in Turkish locales, for example, there are two lower-case "i"s
|
|
|
|
* and two upper-case "I"s, with and without dots - the ones with
|
|
|
|
* dots map between each other, as do the ones without dots, so "I"
|
|
|
|
* doesn't map to "i".
|
|
|
|
*/
|
2008-07-15 21:06:31 +00:00
|
|
|
static guint
|
|
|
|
strcase_hash(gconstpointer key)
|
|
|
|
{
|
strcasecmp(), strncasecmp(), g_strcasecmp(), and g_strncasecmp() delenda
est. Use g_ascii_strcasecmp() and g_ascii_strncasecmp(), and supply our
own versions if they're missing from GLib (as is the case with GLib
1.x).
In the code to build the list of named fields for Diameter, don't use
g_strdown(); do our own g_ascii_-style upper-case to lower-case mapping
in the hash function and use g_ascii_strcasecmp() in the compare
function.
We do this because there is no guarantee that toupper(), tolower(), and
functions that use them will, for example, map between "I" and "i" in
all locales; in Turkish locales, for example, there are, in both
upper case and lower case, versions of "i" with and without a dot, and
the upper-case version of "i" is "I"-with-a-dot and the lower-case
version of "I" is "i"-without-a-dot. This causes strings that should
match not to match.
This finishes fixing bug 2010 - an earlier checkin prevented the crash
(as there are other ways to produce the same crash, e.g. a bogus
dictionary.xml file), but didn't fix the case-insensitive string matching.
svn path=/trunk/; revision=23623
2007-11-27 18:52:51 +00:00
|
|
|
const char *p = key;
|
|
|
|
guint h = *p;
|
|
|
|
char c;
|
|
|
|
|
|
|
|
if (h) {
|
|
|
|
if (h >= 'A' && h <= 'Z')
|
|
|
|
h = h - 'A' + 'a';
|
|
|
|
for (p += 1; *p != '\0'; p++) {
|
|
|
|
c = *p;
|
|
|
|
if (c >= 'A' && c <= 'Z')
|
|
|
|
c = c - 'A' + 'a';
|
|
|
|
h = (h << 5) - h + c;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return h;
|
2001-11-03 12:19:56 +00:00
|
|
|
}
|
|
|
|
|
strcasecmp(), strncasecmp(), g_strcasecmp(), and g_strncasecmp() delenda
est. Use g_ascii_strcasecmp() and g_ascii_strncasecmp(), and supply our
own versions if they're missing from GLib (as is the case with GLib
1.x).
In the code to build the list of named fields for Diameter, don't use
g_strdown(); do our own g_ascii_-style upper-case to lower-case mapping
in the hash function and use g_ascii_strcasecmp() in the compare
function.
We do this because there is no guarantee that toupper(), tolower(), and
functions that use them will, for example, map between "I" and "i" in
all locales; in Turkish locales, for example, there are, in both
upper case and lower case, versions of "i" with and without a dot, and
the upper-case version of "i" is "I"-with-a-dot and the lower-case
version of "I" is "i"-without-a-dot. This causes strings that should
match not to match.
This finishes fixing bug 2010 - an earlier checkin prevented the crash
(as there are other ways to produce the same crash, e.g. a bogus
dictionary.xml file), but didn't fix the case-insensitive string matching.
svn path=/trunk/; revision=23623
2007-11-27 18:52:51 +00:00
|
|
|
/*
|
|
|
|
* Again, use g_ascii_strcasecmp(), not strcasecmp(), so that only ASCII
|
|
|
|
* letters are mapped, and they're mapped to the lower-case ASCII
|
|
|
|
* equivalents.
|
|
|
|
*/
|
2008-07-15 21:06:31 +00:00
|
|
|
static gboolean
|
|
|
|
strcase_equal(gconstpointer ka, gconstpointer kb)
|
|
|
|
{
|
strcasecmp(), strncasecmp(), g_strcasecmp(), and g_strncasecmp() delenda
est. Use g_ascii_strcasecmp() and g_ascii_strncasecmp(), and supply our
own versions if they're missing from GLib (as is the case with GLib
1.x).
In the code to build the list of named fields for Diameter, don't use
g_strdown(); do our own g_ascii_-style upper-case to lower-case mapping
in the hash function and use g_ascii_strcasecmp() in the compare
function.
We do this because there is no guarantee that toupper(), tolower(), and
functions that use them will, for example, map between "I" and "i" in
all locales; in Turkish locales, for example, there are, in both
upper case and lower case, versions of "i" with and without a dot, and
the upper-case version of "i" is "I"-with-a-dot and the lower-case
version of "I" is "i"-without-a-dot. This causes strings that should
match not to match.
This finishes fixing bug 2010 - an earlier checkin prevented the crash
(as there are other ways to produce the same crash, e.g. a bogus
dictionary.xml file), but didn't fix the case-insensitive string matching.
svn path=/trunk/; revision=23623
2007-11-27 18:52:51 +00:00
|
|
|
const char* a = ka;
|
|
|
|
const char* b = kb;
|
|
|
|
return g_ascii_strcasecmp(a,b) == 0;
|
2004-02-21 10:29:52 +00:00
|
|
|
}
|
2001-11-03 12:19:56 +00:00
|
|
|
|
2010-05-24 14:20:53 +00:00
|
|
|
|
2008-07-15 21:06:31 +00:00
|
|
|
static int
|
|
|
|
dictionary_load(void)
|
2008-04-05 05:41:59 +00:00
|
|
|
{
|
2007-07-16 05:41:58 +00:00
|
|
|
ddict_t* d;
|
|
|
|
ddict_application_t* p;
|
|
|
|
ddict_vendor_t* v;
|
|
|
|
ddict_cmd_t* c;
|
|
|
|
ddict_typedefn_t* t;
|
|
|
|
ddict_avp_t* a;
|
2007-07-17 22:19:54 +00:00
|
|
|
gboolean do_debug_parser = getenv("WIRESHARK_DEBUG_DIAM_DICT_PARSER") ? TRUE : FALSE;
|
|
|
|
gboolean do_dump_dict = getenv("WIRESHARK_DUMP_DIAM_DICT") ? TRUE : FALSE;
|
2007-07-16 05:41:58 +00:00
|
|
|
char* dir = ep_strdup_printf("%s" G_DIR_SEPARATOR_S "diameter" G_DIR_SEPARATOR_S, get_datafile_dir());
|
|
|
|
const avp_type_t* type;
|
2007-11-27 01:41:42 +00:00
|
|
|
const avp_type_t* octetstring = &basic_types[0];
|
2007-07-16 05:41:58 +00:00
|
|
|
diam_avp_t* avp;
|
|
|
|
GHashTable* vendors = g_hash_table_new(strcase_hash,strcase_equal);
|
|
|
|
diam_vnd_t* vnd;
|
|
|
|
GArray* vnd_shrt_arr = g_array_new(TRUE,TRUE,sizeof(value_string));
|
2001-02-19 23:14:02 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
build_dict.hf = g_array_new(FALSE,TRUE,sizeof(hf_register_info));
|
2008-07-15 21:06:31 +00:00
|
|
|
build_dict.ett = g_ptr_array_new();
|
2007-07-16 05:41:58 +00:00
|
|
|
build_dict.types = g_hash_table_new(strcase_hash,strcase_equal);
|
|
|
|
build_dict.avps = g_hash_table_new(strcase_hash,strcase_equal);
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
dictionary.vnds = pe_tree_create(EMEM_TREE_TYPE_RED_BLACK,"diameter_vnds");
|
|
|
|
dictionary.avps = pe_tree_create(EMEM_TREE_TYPE_RED_BLACK,"diameter_avps");
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
no_vnd.vs_cmds = g_array_new(TRUE,TRUE,sizeof(value_string));
|
|
|
|
no_vnd.vs_avps = g_array_new(TRUE,TRUE,sizeof(value_string));
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-20 11:39:09 +00:00
|
|
|
all_cmds = g_array_new(TRUE,TRUE,sizeof(value_string));
|
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
pe_tree_insert32(dictionary.vnds,0,&no_vnd);
|
2008-06-25 03:05:19 +00:00
|
|
|
g_hash_table_insert(vendors,(gchar *)"None",&no_vnd);
|
2001-11-02 10:09:51 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
/* initialize the types hash with the known basic types */
|
|
|
|
for (type = basic_types; type->name; type++) {
|
2008-06-25 03:05:19 +00:00
|
|
|
g_hash_table_insert(build_dict.types,(gchar *)type->name,(void*)type);
|
2007-07-16 05:41:58 +00:00
|
|
|
}
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
/* load the dictionary */
|
2007-10-24 16:32:51 +00:00
|
|
|
d = ddict_scan(dir,"dictionary.xml",do_debug_parser);
|
2007-07-17 22:19:54 +00:00
|
|
|
if (d == NULL) {
|
2007-07-17 21:29:18 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-07-17 22:19:54 +00:00
|
|
|
if (do_dump_dict) ddict_print(stdout, d);
|
2007-10-24 16:32:51 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
/* populate the types */
|
|
|
|
for (t = d->typedefns; t; t = t->next) {
|
|
|
|
const avp_type_t* parent = NULL;
|
|
|
|
/* try to get the parent type */
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2012-03-19 17:12:04 +00:00
|
|
|
if (t->name == NULL) {
|
|
|
|
fprintf(stderr,"Diameter Dictionary: Invalid Type (empty name): parent==%s\n",
|
|
|
|
t->parent ? t->parent : "(null)");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
if (g_hash_table_lookup(build_dict.types,t->name))
|
|
|
|
continue;
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
if (t->parent) {
|
|
|
|
parent = g_hash_table_lookup(build_dict.types,t->parent);
|
2002-01-31 01:55:14 +00:00
|
|
|
}
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-11-27 01:41:42 +00:00
|
|
|
if (!parent) parent = octetstring;
|
2007-07-17 21:29:18 +00:00
|
|
|
|
|
|
|
/* insert the parent type for this type */
|
2007-07-16 05:41:58 +00:00
|
|
|
g_hash_table_insert(build_dict.types,t->name,(void*)parent);
|
|
|
|
}
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
/* populate the applications */
|
|
|
|
if ((p = d->applications)) {
|
|
|
|
GArray* arr = g_array_new(TRUE,TRUE,sizeof(value_string));
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
for (; p; p = p->next) {
|
|
|
|
value_string item = {p->code,p->name};
|
|
|
|
g_array_append_val(arr,item);
|
2002-01-31 01:55:14 +00:00
|
|
|
}
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
dictionary.applications = (void*)arr->data;
|
|
|
|
g_array_free(arr,FALSE);
|
|
|
|
}
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
if ((v = d->vendors)) {
|
|
|
|
for ( ; v; v = v->next) {
|
|
|
|
value_string item = {v->code,v->name};
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2012-03-19 17:12:04 +00:00
|
|
|
if (v->name == NULL) {
|
|
|
|
fprintf(stderr,"Diameter Dictionary: Invalid Vendor (empty name): code==%d\n",v->code);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
if (g_hash_table_lookup(vendors,v->name))
|
|
|
|
continue;
|
2001-07-30 20:08:44 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
g_array_append_val(vnd_shrt_arr,item);
|
2004-03-21 23:19:36 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
vnd = g_malloc(sizeof(diam_vnd_t));
|
|
|
|
vnd->code = v->code;
|
|
|
|
vnd->vs_cmds = g_array_new(TRUE,TRUE,sizeof(value_string));
|
|
|
|
vnd->vs_avps = g_array_new(TRUE,TRUE,sizeof(value_string));
|
2010-10-14 17:50:35 +00:00
|
|
|
vnd->vs_avps_ext = NULL;
|
2007-07-16 05:41:58 +00:00
|
|
|
pe_tree_insert32(dictionary.vnds,vnd->code,vnd);
|
|
|
|
g_hash_table_insert(vendors,v->name,vnd);
|
2001-11-01 21:52:44 +00:00
|
|
|
}
|
2007-07-16 05:41:58 +00:00
|
|
|
}
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
vnd_short_vs = (void*)vnd_shrt_arr->data;
|
|
|
|
g_array_free(vnd_shrt_arr,FALSE);
|
|
|
|
|
|
|
|
if ((c = d->cmds)) {
|
|
|
|
for (; c; c = c->next) {
|
2012-03-19 17:12:04 +00:00
|
|
|
if (c->vendor == NULL) {
|
|
|
|
fprintf(stderr,"Diameter Dictionary: Invalid Vendor (empty name) for command %s\n",
|
|
|
|
c->name ? c->name : "(null)");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
if ((vnd = g_hash_table_lookup(vendors,c->vendor))) {
|
|
|
|
value_string item = {c->code,c->name};
|
|
|
|
g_array_append_val(vnd->vs_cmds,item);
|
2007-07-20 11:39:09 +00:00
|
|
|
/* Also add to all_cmds as used by RFC version */
|
|
|
|
g_array_append_val(all_cmds,item);
|
2007-07-16 05:41:58 +00:00
|
|
|
} else {
|
2012-03-19 17:12:04 +00:00
|
|
|
fprintf(stderr,"Diameter Dictionary: No Vendor: %s\n",c->vendor);
|
2006-07-03 21:18:36 +00:00
|
|
|
}
|
2007-07-16 05:41:58 +00:00
|
|
|
}
|
|
|
|
}
|
2007-07-17 21:29:18 +00:00
|
|
|
|
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
for (a = d->avps; a; a = a->next) {
|
|
|
|
ddict_enum_t* e;
|
|
|
|
value_string* vs = NULL;
|
|
|
|
const char* vend = a->vendor ? a->vendor : "None";
|
2007-07-20 00:15:17 +00:00
|
|
|
ddict_xmlpi_t* x;
|
|
|
|
void* avp_data = NULL;
|
2007-10-24 16:32:51 +00:00
|
|
|
|
2012-03-19 17:12:04 +00:00
|
|
|
if (a->name == NULL) {
|
|
|
|
fprintf(stderr,"Diameter Dictionary: Invalid AVP (empty name)\n");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
if ((vnd = g_hash_table_lookup(vendors,vend))) {
|
|
|
|
value_string vndvs = {a->code,a->name};
|
|
|
|
g_array_append_val(vnd->vs_avps,vndvs);
|
|
|
|
} else {
|
2012-03-19 17:12:04 +00:00
|
|
|
fprintf(stderr,"Diameter Dictionary: No Vendor: %s\n",vend);
|
2007-07-16 05:41:58 +00:00
|
|
|
vnd = &unknown_vendor;
|
|
|
|
}
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
if ((e = a->enums)) {
|
|
|
|
GArray* arr = g_array_new(TRUE,TRUE,sizeof(value_string));
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
for (; e; e = e->next) {
|
|
|
|
value_string item = {e->code,e->name};
|
|
|
|
g_array_append_val(arr,item);
|
|
|
|
}
|
2010-11-10 20:11:38 +00:00
|
|
|
g_array_sort(arr, compare_avps);
|
2007-07-16 05:41:58 +00:00
|
|
|
vs = (void*)arr->data;
|
|
|
|
}
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-20 00:15:17 +00:00
|
|
|
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))
|
|
|
|
) {
|
2007-10-24 16:32:51 +00:00
|
|
|
static avp_type_t proto_type = {"proto", proto_avp, proto_avp, FT_UINT32, BASE_NONE, build_proto_avp};
|
2007-07-20 00:15:17 +00:00
|
|
|
type = &proto_type;
|
2007-10-24 16:32:51 +00:00
|
|
|
|
2007-07-20 00:15:17 +00:00
|
|
|
avp_data = x->value;
|
|
|
|
break;
|
|
|
|
}
|
2007-07-16 05:41:58 +00:00
|
|
|
}
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-20 00:15:17 +00:00
|
|
|
if ( (!type) && a->type )
|
|
|
|
type = g_hash_table_lookup(build_dict.types,a->type);
|
2007-10-24 16:32:51 +00:00
|
|
|
|
2007-11-27 01:41:42 +00:00
|
|
|
if (!type) type = octetstring;
|
2007-07-20 00:15:17 +00:00
|
|
|
|
|
|
|
avp = type->build( type, a->code, vnd, a->name, vs, avp_data);
|
2007-11-27 01:41:42 +00:00
|
|
|
if (avp != NULL) {
|
|
|
|
g_hash_table_insert(build_dict.avps, a->name, avp);
|
|
|
|
|
|
|
|
{
|
|
|
|
emem_tree_key_t k[] = {
|
|
|
|
{ 1, &(a->code) },
|
|
|
|
{ 1, &(vnd->code) },
|
|
|
|
{ 0 , NULL }
|
|
|
|
};
|
|
|
|
pe_tree_insert32_array(dictionary.avps,k,avp);
|
|
|
|
}
|
2007-07-16 05:41:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
g_hash_table_destroy(build_dict.types);
|
|
|
|
g_hash_table_destroy(build_dict.avps);
|
|
|
|
g_hash_table_destroy(vendors);
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2001-02-23 19:26:26 +00:00
|
|
|
|
2007-10-24 15:04:01 +00:00
|
|
|
static void
|
2010-10-18 15:56:06 +00:00
|
|
|
tcp_range_delete_callback(guint32 port)
|
2007-10-24 15:04:01 +00:00
|
|
|
{
|
2010-12-20 05:35:29 +00:00
|
|
|
dissector_delete_uint("tcp.port", port, diameter_tcp_handle);
|
2007-10-24 15:04:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2010-10-18 15:56:06 +00:00
|
|
|
tcp_range_add_callback(guint32 port)
|
2007-10-24 15:04:01 +00:00
|
|
|
{
|
2010-12-20 05:35:29 +00:00
|
|
|
dissector_add_uint("tcp.port", port, diameter_tcp_handle);
|
2007-10-24 15:04:01 +00:00
|
|
|
}
|
2000-07-30 07:16:11 +00:00
|
|
|
|
2010-10-18 15:56:06 +00:00
|
|
|
static void
|
|
|
|
sctp_range_delete_callback(guint32 port)
|
|
|
|
{
|
2010-12-20 05:35:29 +00:00
|
|
|
dissector_delete_uint("sctp.port", port, diameter_sctp_handle);
|
2010-10-18 15:56:06 +00:00
|
|
|
}
|
2007-10-24 15:04:01 +00:00
|
|
|
|
2010-10-18 15:56:06 +00:00
|
|
|
static void
|
|
|
|
sctp_range_add_callback(guint32 port)
|
|
|
|
{
|
2010-12-20 05:35:29 +00:00
|
|
|
dissector_add_uint("sctp.port", port, diameter_sctp_handle);
|
2010-10-18 15:56:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* registration with the filtering engine */
|
2010-04-26 22:19:34 +00:00
|
|
|
void proto_reg_handoff_diameter(void);
|
2000-07-30 07:16:11 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
proto_register_diameter(void)
|
|
|
|
{
|
2007-07-16 05:41:58 +00:00
|
|
|
module_t *diameter_module;
|
2008-07-15 21:06:31 +00:00
|
|
|
guint i, ett_length;
|
2008-04-05 05:41:59 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
hf_register_info hf_base[] = {
|
|
|
|
{ &hf_diameter_version,
|
2001-07-30 20:08:44 +00:00
|
|
|
{ "Version", "diameter.version", FT_UINT8, BASE_HEX, NULL, 0x00,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
NULL, HFILL }},
|
2007-07-16 05:41:58 +00:00
|
|
|
{ &hf_diameter_length,
|
2001-07-30 20:08:44 +00:00
|
|
|
{ "Length","diameter.length", FT_UINT24, BASE_DEC, NULL, 0x0,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
NULL, HFILL }},
|
2007-07-16 05:41:58 +00:00
|
|
|
{ &hf_diameter_flags,
|
2001-07-30 20:08:44 +00:00
|
|
|
{ "Flags", "diameter.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
NULL, HFILL }},
|
2007-07-16 05:41:58 +00:00
|
|
|
{ &hf_diameter_flags_request,
|
2009-07-07 14:54:15 +00:00
|
|
|
{ "Request", "diameter.flags.request", FT_BOOLEAN, 8, TFS(&tfs_set_notset), DIAM_FLAGS_R,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
NULL, HFILL }},
|
2007-07-16 05:41:58 +00:00
|
|
|
{ &hf_diameter_flags_proxyable,
|
2009-07-07 14:54:15 +00:00
|
|
|
{ "Proxyable", "diameter.flags.proxyable", FT_BOOLEAN, 8, TFS(&tfs_set_notset), DIAM_FLAGS_P,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
NULL, HFILL }},
|
2007-07-16 05:41:58 +00:00
|
|
|
{ &hf_diameter_flags_error,
|
2009-07-07 14:54:15 +00:00
|
|
|
{ "Error","diameter.flags.error", FT_BOOLEAN, 8, TFS(&tfs_set_notset), DIAM_FLAGS_E,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
NULL, HFILL }},
|
2007-07-16 05:41:58 +00:00
|
|
|
{ &hf_diameter_flags_T,
|
2009-07-07 14:54:15 +00:00
|
|
|
{ "T(Potentially re-transmitted message)","diameter.flags.T", FT_BOOLEAN, 8, TFS(&tfs_set_notset),DIAM_FLAGS_T,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
NULL, HFILL }},
|
2007-07-16 05:41:58 +00:00
|
|
|
{ &hf_diameter_flags_reserved4,
|
2009-04-07 12:20:41 +00:00
|
|
|
{ "Reserved","diameter.flags.reserved4", FT_BOOLEAN, 8, TFS(&tfs_set_notset),
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
DIAM_FLAGS_RESERVED4, NULL, HFILL }},
|
2007-07-16 05:41:58 +00:00
|
|
|
{ &hf_diameter_flags_reserved5,
|
2009-04-07 12:20:41 +00:00
|
|
|
{ "Reserved","diameter.flags.reserved5", FT_BOOLEAN, 8, TFS(&tfs_set_notset),
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
DIAM_FLAGS_RESERVED5, NULL, HFILL }},
|
2007-07-16 05:41:58 +00:00
|
|
|
{ &hf_diameter_flags_reserved6,
|
2009-04-07 12:20:41 +00:00
|
|
|
{ "Reserved","diameter.flags.reserved6", FT_BOOLEAN, 8, TFS(&tfs_set_notset),
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
DIAM_FLAGS_RESERVED6, NULL, HFILL }},
|
2007-07-16 05:41:58 +00:00
|
|
|
{ &hf_diameter_flags_reserved7,
|
2009-04-07 12:20:41 +00:00
|
|
|
{ "Reserved","diameter.flags.reserved7", FT_BOOLEAN, 8, TFS(&tfs_set_notset),
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
DIAM_FLAGS_RESERVED7, NULL, HFILL }},
|
2007-07-16 05:41:58 +00:00
|
|
|
{ &hf_diameter_vendor_id,
|
2010-09-17 04:51:21 +00:00
|
|
|
{ "VendorId", "diameter.vendorId", FT_UINT32, BASE_DEC|BASE_EXT_STRING, &sminmpec_values_ext,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
0x0,NULL, HFILL }},
|
2007-07-16 05:41:58 +00:00
|
|
|
{ &hf_diameter_application_id,
|
|
|
|
{ "ApplicationId", "diameter.applicationId", FT_UINT32, BASE_DEC, dictionary.applications,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
0x0,NULL, HFILL }},
|
2007-07-16 05:41:58 +00:00
|
|
|
{ &hf_diameter_hopbyhopid,
|
2001-04-10 21:49:23 +00:00
|
|
|
{ "Hop-by-Hop Identifier", "diameter.hopbyhopid", FT_UINT32,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
BASE_HEX, NULL, 0x0, NULL, HFILL }},
|
2007-07-16 05:41:58 +00:00
|
|
|
{ &hf_diameter_endtoendid,
|
2002-08-28 21:04:11 +00:00
|
|
|
{ "End-to-End Identifier", "diameter.endtoendid", FT_UINT32,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
BASE_HEX, NULL, 0x0, NULL, HFILL }},
|
2007-07-16 05:41:58 +00:00
|
|
|
{ &hf_diameter_avp,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
{ "AVP","diameter.avp", FT_BYTES, BASE_NONE,
|
|
|
|
NULL, 0x0, NULL, HFILL }},
|
2007-07-16 05:41:58 +00:00
|
|
|
{ &hf_diameter_avp_len,
|
|
|
|
{ "AVP Length","diameter.avp.len", FT_UINT24, BASE_DEC,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
NULL, 0x0, NULL, HFILL }},
|
2007-07-16 05:41:58 +00:00
|
|
|
{ &hf_diameter_avp_flags,
|
2001-02-19 23:14:02 +00:00
|
|
|
{ "AVP Flags","diameter.avp.flags", FT_UINT8, BASE_HEX,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
NULL, 0x0, NULL, HFILL }},
|
2007-07-16 05:41:58 +00:00
|
|
|
{ &hf_diameter_avp_flags_vendor_specific,
|
2009-07-07 14:54:15 +00:00
|
|
|
{ "Vendor-Specific", "diameter.flags.vendorspecific", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AVP_FLAGS_V,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
NULL, HFILL }},
|
2007-07-16 05:41:58 +00:00
|
|
|
{ &hf_diameter_avp_flags_mandatory,
|
2009-07-07 14:54:15 +00:00
|
|
|
{ "Mandatory", "diameter.flags.mandatory", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AVP_FLAGS_M,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
NULL, HFILL }},
|
2007-07-16 05:41:58 +00:00
|
|
|
{ &hf_diameter_avp_flags_protected,
|
2009-07-07 14:54:15 +00:00
|
|
|
{ "Protected","diameter.avp.flags.protected", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AVP_FLAGS_P,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
NULL, HFILL }},
|
2007-07-16 05:41:58 +00:00
|
|
|
{ &hf_diameter_avp_flags_reserved3,
|
2009-04-07 12:20:41 +00:00
|
|
|
{ "Reserved","diameter.avp.flags.reserved3", FT_BOOLEAN, 8, TFS(&tfs_set_notset),
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
AVP_FLAGS_RESERVED3, NULL, HFILL }},
|
2007-07-16 05:41:58 +00:00
|
|
|
{ &hf_diameter_avp_flags_reserved4,
|
2009-04-07 12:20:41 +00:00
|
|
|
{ "Reserved","diameter.avp.flags.reserved4", FT_BOOLEAN, 8, TFS(&tfs_set_notset),
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
AVP_FLAGS_RESERVED4, NULL, HFILL }},
|
2007-07-16 05:41:58 +00:00
|
|
|
{ &hf_diameter_avp_flags_reserved5,
|
2009-04-07 12:20:41 +00:00
|
|
|
{ "Reserved","diameter.avp.flags.reserved5", FT_BOOLEAN, 8, TFS(&tfs_set_notset),
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
AVP_FLAGS_RESERVED5, NULL, HFILL }},
|
2007-07-16 05:41:58 +00:00
|
|
|
{ &hf_diameter_avp_flags_reserved6,
|
2009-04-07 12:20:41 +00:00
|
|
|
{ "Reserved","diameter.avp.flags.reserved6", FT_BOOLEAN, 8, TFS(&tfs_set_notset),
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
AVP_FLAGS_RESERVED6, NULL, HFILL }},
|
2007-07-16 05:41:58 +00:00
|
|
|
{ &hf_diameter_avp_flags_reserved7,
|
2009-04-07 12:20:41 +00:00
|
|
|
{ "Reserved","diameter.avp.flags.reserved7", FT_BOOLEAN, 8, TFS(&tfs_set_notset),
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
AVP_FLAGS_RESERVED7, NULL, HFILL }},
|
2007-07-16 05:41:58 +00:00
|
|
|
{ &hf_diameter_avp_vendor_id,
|
2010-09-17 04:51:21 +00:00
|
|
|
{ "AVP Vendor Id","diameter.avp.vendorId", FT_UINT32, BASE_DEC|BASE_EXT_STRING,
|
|
|
|
&sminmpec_values_ext, 0x0, NULL, HFILL }},
|
2007-07-16 05:41:58 +00:00
|
|
|
{ &(unknown_avp.hf_value),
|
|
|
|
{ "Value","diameter.avp.unknown", FT_BYTES, BASE_NONE,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
NULL, 0x0, NULL, HFILL }},
|
2007-07-27 18:32:09 +00:00
|
|
|
{ &hf_diameter_avp_data_wrong_length,
|
|
|
|
{ "Data","diameter.avp.invalid-data", FT_BYTES, BASE_NONE,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
NULL, 0x0, NULL, HFILL }},
|
2007-07-16 05:41:58 +00:00
|
|
|
{ &hf_diameter_code,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
{ "Command Code", "diameter.cmd.code", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
|
2007-07-16 05:41:58 +00:00
|
|
|
{ &hf_diameter_avp_code,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
{ "AVP Code", "diameter.avp.code", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
|
2008-11-15 15:52:39 +00:00
|
|
|
{ &hf_diameter_answer_in,
|
2009-07-07 09:02:59 +00:00
|
|
|
{ "Answer In", "diameter.answer_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
|
2008-11-15 15:52:39 +00:00
|
|
|
"The answer to this diameter request is in this frame", HFILL }},
|
|
|
|
{ &hf_diameter_answer_to,
|
2009-07-07 09:02:59 +00:00
|
|
|
{ "Request In", "diameter.answer_to", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
|
2008-11-15 15:52:39 +00:00
|
|
|
"This is an answer to the diameter request in this frame", HFILL }},
|
|
|
|
{ &hf_diameter_answer_time,
|
|
|
|
{ "Response Time", "diameter.resp_time", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
|
|
|
|
"The time between the request and the answer", HFILL }},
|
2012-03-13 15:06:40 +00:00
|
|
|
{ &hf_framed_ipv6_prefix_reserved,
|
|
|
|
{ "Framed IPv6 Prefix Reserved byte", "diameter.framed_ipv6_prefix_reserved",
|
|
|
|
FT_UINT8, BASE_HEX, NULL, 0,
|
|
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_framed_ipv6_prefix_length,
|
|
|
|
{ "Framed IPv6 Prefix length (in bits)", "diameter.framed_ipv6_prefix_length",
|
|
|
|
FT_UINT8, BASE_DEC, NULL, 0,
|
|
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_framed_ipv6_prefix_bytes,
|
|
|
|
{ "Framed IPv6 Prefix as a bytestring", "diameter.framed_ipv6_prefix_bytes",
|
|
|
|
FT_BYTES, BASE_NONE, NULL, 0,
|
|
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_framed_ipv6_prefix_ipv6,
|
|
|
|
{ "Framed IPv6 Prefix as an IPv6 address", "diameter.framed_ipv6_prefix_ipv6",
|
|
|
|
FT_IPv6, BASE_NONE, NULL, 0,
|
|
|
|
"This field is present only if the prefix length is 128", HFILL }}
|
2000-07-30 07:16:11 +00:00
|
|
|
};
|
2008-11-15 15:52:39 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
gint *ett_base[] = {
|
2000-07-30 07:16:11 +00:00
|
|
|
&ett_diameter,
|
2001-07-30 20:08:44 +00:00
|
|
|
&ett_diameter_flags,
|
|
|
|
&ett_diameter_avp_flags,
|
2007-07-16 05:41:58 +00:00
|
|
|
&ett_diameter_avpinfo,
|
2007-07-17 22:19:54 +00:00
|
|
|
&ett_unknown,
|
|
|
|
&ett_err,
|
2007-07-16 05:41:58 +00:00
|
|
|
&(unknown_avp.ett)
|
2000-07-30 07:16:11 +00:00
|
|
|
};
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2008-04-05 05:41:59 +00:00
|
|
|
dictionary_load();
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
g_array_append_vals(build_dict.hf, hf_base, array_length(hf_base));
|
2008-07-15 21:06:31 +00:00
|
|
|
ett_length = array_length(ett_base);
|
|
|
|
for (i = 0; i < ett_length; i++)
|
|
|
|
{
|
2008-07-16 08:08:17 +00:00
|
|
|
g_ptr_array_add(build_dict.ett, ett_base[i]);
|
2008-07-15 21:06:31 +00:00
|
|
|
}
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2005-11-19 15:59:30 +00:00
|
|
|
proto_diameter = proto_register_protocol ("Diameter Protocol", "DIAMETER", "diameter");
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2008-07-15 21:06:31 +00:00
|
|
|
proto_register_field_array(proto_diameter, (hf_register_info*)(void*)build_dict.hf->data, build_dict.hf->len);
|
|
|
|
proto_register_subtree_array((gint**)build_dict.ett->pdata, build_dict.ett->len);
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2007-07-16 05:41:58 +00:00
|
|
|
g_array_free(build_dict.hf,FALSE);
|
2008-07-15 21:06:31 +00:00
|
|
|
g_ptr_array_free(build_dict.ett,TRUE);
|
2001-01-03 06:56:03 +00:00
|
|
|
|
2006-05-23 05:48:00 +00:00
|
|
|
/* Allow dissector to find be found by name. */
|
|
|
|
new_register_dissector("diameter", dissect_diameter, proto_diameter);
|
2008-04-05 05:41:59 +00:00
|
|
|
|
2010-04-26 22:19:34 +00:00
|
|
|
/* Register dissector table(s) to do sub dissection of AVP:s ( OctetStrings) */
|
2010-06-09 20:24:23 +00:00
|
|
|
diameter_dissector_table = register_dissector_table("diameter.base", "DIAMETER_BASE_AVPS", FT_UINT32, BASE_DEC);
|
2008-01-27 21:06:33 +00:00
|
|
|
diameter_3gpp_avp_dissector_table = register_dissector_table("diameter.3gpp", "DIAMETER_3GPP_AVPS", FT_UINT32, BASE_DEC);
|
2010-05-07 11:08:56 +00:00
|
|
|
diameter_ericsson_avp_dissector_table = register_dissector_table("diameter.ericsson", "DIAMETER_ERICSSON_AVPS", FT_UINT32, BASE_DEC);
|
2006-05-23 05:48:00 +00:00
|
|
|
|
2007-10-24 15:04:01 +00:00
|
|
|
/* Set default TCP ports */
|
|
|
|
range_convert_str(&global_diameter_tcp_port_range, DEFAULT_DIAMETER_PORT_RANGE, MAX_UDP_PORT);
|
2010-10-18 15:56:06 +00:00
|
|
|
range_convert_str(&global_diameter_sctp_port_range, DEFAULT_DIAMETER_PORT_RANGE, MAX_SCTP_PORT);
|
2007-10-24 15:04:01 +00:00
|
|
|
|
2008-04-05 05:41:59 +00:00
|
|
|
/* Register configuration options for ports */
|
2001-01-03 07:53:48 +00:00
|
|
|
diameter_module = prefs_register_protocol(proto_diameter,
|
2008-07-15 21:06:31 +00:00
|
|
|
proto_reg_handoff_diameter);
|
2007-07-16 05:41:58 +00:00
|
|
|
|
2007-10-24 15:04:01 +00:00
|
|
|
prefs_register_range_preference(diameter_module, "tcp.ports", "Diameter TCP ports",
|
2008-07-15 21:06:31 +00:00
|
|
|
"TCP ports to be decoded as Diameter (default: "
|
|
|
|
DEFAULT_DIAMETER_PORT_RANGE ")",
|
|
|
|
&global_diameter_tcp_port_range, MAX_UDP_PORT);
|
2007-10-24 15:04:01 +00:00
|
|
|
|
2010-10-18 15:56:06 +00:00
|
|
|
prefs_register_range_preference(diameter_module, "sctp.ports",
|
|
|
|
"Diameter SCTP Ports",
|
|
|
|
"SCTP ports to be decoded as Diameter (default: "
|
|
|
|
DEFAULT_DIAMETER_PORT_RANGE ")",
|
|
|
|
&global_diameter_sctp_port_range, MAX_SCTP_PORT);
|
2006-03-15 06:16:12 +00:00
|
|
|
|
2001-11-03 12:19:56 +00:00
|
|
|
/* Desegmentation */
|
2002-01-15 10:01:21 +00:00
|
|
|
prefs_register_bool_preference(diameter_module, "desegment",
|
2008-07-15 21:06:31 +00:00
|
|
|
"Reassemble Diameter messages\nspanning multiple TCP segments",
|
|
|
|
"Whether the Diameter dissector should reassemble messages spanning multiple TCP segments."
|
|
|
|
" To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
|
|
|
|
&gbl_diameter_desegment);
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2008-07-15 21:06:31 +00:00
|
|
|
/* Register some preferences we no longer support, so we can report
|
|
|
|
* them as obsolete rather than just illegal.
|
|
|
|
*/
|
2007-10-24 15:04:01 +00:00
|
|
|
prefs_register_obsolete_preference(diameter_module, "version");
|
Allow a dissector to register preferences that it no longer supports as
obsolete; we silently ignore attempts to set those in a preferences
file, so that we don't spam the user with error messages caused by them
having saved preferences in an earlier release that contained those
preferences.
Make the Diameter and iSCSI dissectors register obsolete preferences.
Crash if some code tries to register a preferences module with a name
that contains something other than lower-case ASCII letters, numbers, or
underscores, or that has already been registered, or if some code tries
to register a preference with a name that contains something other than
lower-case ASCII letters, numbers, underscores, or periods, or that has
already been registered, so that we don't put code like that in a
release and have to shovel code into "prefs.c" to fix it up later. (The
problem with multiple modules or preferences with the same name should
be obvious; the problem with names with blanks, or upper-case letters,
or punctuation, is that they're a pain to type on the command line.)
svn path=/trunk/; revision=4148
2001-11-04 02:50:21 +00:00
|
|
|
prefs_register_obsolete_preference(diameter_module, "udp.port");
|
2007-10-24 15:04:01 +00:00
|
|
|
prefs_register_obsolete_preference(diameter_module, "tcp.port");
|
2010-10-18 15:56:06 +00:00
|
|
|
prefs_register_obsolete_preference(diameter_module, "sctp.port");
|
Allow a dissector to register preferences that it no longer supports as
obsolete; we silently ignore attempts to set those in a preferences
file, so that we don't spam the user with error messages caused by them
having saved preferences in an earlier release that contained those
preferences.
Make the Diameter and iSCSI dissectors register obsolete preferences.
Crash if some code tries to register a preferences module with a name
that contains something other than lower-case ASCII letters, numbers, or
underscores, or that has already been registered, or if some code tries
to register a preference with a name that contains something other than
lower-case ASCII letters, numbers, underscores, or periods, or that has
already been registered, so that we don't put code like that in a
release and have to shovel code into "prefs.c" to fix it up later. (The
problem with multiple modules or preferences with the same name should
be obvious; the problem with names with blanks, or upper-case letters,
or punctuation, is that they're a pain to type on the command line.)
svn path=/trunk/; revision=4148
2001-11-04 02:50:21 +00:00
|
|
|
prefs_register_obsolete_preference(diameter_module, "command_in_header");
|
2007-07-16 05:41:58 +00:00
|
|
|
prefs_register_obsolete_preference(diameter_module, "dictionary.name");
|
|
|
|
prefs_register_obsolete_preference(diameter_module, "dictionary.use");
|
|
|
|
prefs_register_obsolete_preference(diameter_module, "allow_zero_as_app_id");
|
|
|
|
prefs_register_obsolete_preference(diameter_module, "suppress_console_output");
|
2007-07-17 21:29:18 +00:00
|
|
|
|
2008-11-15 15:52:39 +00:00
|
|
|
/* Register tap */
|
|
|
|
diameter_tap = register_tap("diameter");
|
|
|
|
|
2001-11-01 21:52:44 +00:00
|
|
|
} /* proto_register_diameter */
|
2007-07-16 05:41:58 +00:00
|
|
|
|
2010-04-26 22:19:34 +00:00
|
|
|
void
|
|
|
|
proto_reg_handoff_diameter(void)
|
|
|
|
{
|
|
|
|
static gboolean Initialized=FALSE;
|
|
|
|
static range_t *diameter_tcp_port_range;
|
2010-10-18 15:56:06 +00:00
|
|
|
static range_t *diameter_sctp_port_range;
|
2010-04-26 22:19:34 +00:00
|
|
|
|
|
|
|
if (!Initialized) {
|
2010-10-18 15:56:06 +00:00
|
|
|
diameter_sctp_handle = find_dissector("diameter");
|
2010-04-26 22:19:34 +00:00
|
|
|
diameter_tcp_handle = create_dissector_handle(dissect_diameter_tcp,
|
|
|
|
proto_diameter);
|
|
|
|
data_handle = find_dissector("data");
|
|
|
|
eap_handle = find_dissector("eap");
|
2012-03-13 15:06:40 +00:00
|
|
|
|
2010-04-26 22:19:34 +00:00
|
|
|
/* Register special decoding for some AVP:s */
|
2012-03-13 15:06:40 +00:00
|
|
|
/* AVP Code: 97 Framed-IPv6-Address */
|
|
|
|
dissector_add_uint("diameter.base", 97,
|
|
|
|
new_create_dissector_handle(dissect_diameter_base_framed_ipv6_prefix, proto_diameter));
|
2010-04-26 22:19:34 +00:00
|
|
|
/* AVP Code: 266 Vendor-Id */
|
2010-12-20 05:35:29 +00:00
|
|
|
dissector_add_uint("diameter.base", 266,
|
2012-03-13 15:06:40 +00:00
|
|
|
new_create_dissector_handle(dissect_diameter_vendor_id, proto_diameter));
|
2010-04-26 22:19:34 +00:00
|
|
|
/* AVP Code: 462 EAP-Payload */
|
2010-12-20 05:35:29 +00:00
|
|
|
dissector_add_uint("diameter.base", 462,
|
2010-04-26 22:19:34 +00:00
|
|
|
new_create_dissector_handle(dissect_diameter_eap_payload, proto_diameter));
|
|
|
|
/* AVP Code: 463 EAP-Reissued-Payload */
|
2010-12-20 05:35:29 +00:00
|
|
|
dissector_add_uint("diameter.base", 463,
|
2010-04-26 22:19:34 +00:00
|
|
|
new_create_dissector_handle(dissect_diameter_eap_payload, proto_diameter));
|
|
|
|
|
|
|
|
Initialized=TRUE;
|
|
|
|
} else {
|
2010-10-18 15:56:06 +00:00
|
|
|
range_foreach(diameter_tcp_port_range, tcp_range_delete_callback);
|
|
|
|
range_foreach(diameter_sctp_port_range, sctp_range_delete_callback);
|
2010-04-26 22:19:34 +00:00
|
|
|
g_free(diameter_tcp_port_range);
|
2010-10-18 15:56:06 +00:00
|
|
|
g_free(diameter_sctp_port_range);
|
2010-04-26 22:19:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* set port for future deletes */
|
|
|
|
diameter_tcp_port_range = range_copy(global_diameter_tcp_port_range);
|
2010-10-18 15:56:06 +00:00
|
|
|
diameter_sctp_port_range = range_copy(global_diameter_sctp_port_range);
|
|
|
|
range_foreach(diameter_tcp_port_range, tcp_range_add_callback);
|
|
|
|
range_foreach(diameter_sctp_port_range, sctp_range_add_callback);
|
2010-04-26 22:19:34 +00:00
|
|
|
}
|
|
|
|
|