Ethereal-dev: Re: [Ethereal-dev] Major Diameter Changes . . . Part 2 - Diffs and dictionaries

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: David Frascone <dave@xxxxxxxxxxxx>
Date: Mon, 29 Oct 2001 22:16:50 -0600
Attached are the cvs diffs (diameter.diff), and the xml dictionary (*.xml,
*.dtd), and a sample dump (diammip1.gz).

The modified files in the diff are:

Makefile.am     - xmlstub added, dictionary added (hopefully properly)
Makefile.nmake  - xmlstub added.  I couldn't figure out where to put
		  the dictionary.

packet-mip.c	- Dissector is now registered by name.

packet-diameter-defs.h - Some was removed, but most remains as a static
	                 dictionary in case xml/the dynamic dictionary can
	 		 not be loaded.

packet-diameter.c - Many changes:  Support for XML dictionary, inline mobile-ip
		    now dissected.  

I'm also attaching diammip1 which is a dump with lots of diameter packets,
some containing mobile-ip to be processed.

I found some bugs in the mobile-ip dissector, and I'll be cleaning them 
up next.  (I've already e-mailed the author)

Is there any way to build under Windows with a free compiler (i.e. gcc)?
I'd be happy to test this stuff under Windows if I could :(


-Dave
? sunping.xml
? dictionary.dtd
? dictionary.xml
? mobileipv4.xml
? xmlstub.c
? xmlstub.h
? nasreq.xml
Index: Makefile.am
===================================================================
RCS file: /cvsroot/ethereal/Makefile.am,v
retrieving revision 1.372
diff -c -r1.372 Makefile.am
*** Makefile.am	2001/10/29 21:13:07	1.372
--- Makefile.am	2001/10/30 04:13:28
***************
*** 68,74 ****
  EXTRA_PROGRAMS = ethereal ethereal_static tethereal tethereal_static editcap mergecap dftest text2pcap
  EXTRA_SCRIPTS = idl2eth
  
! sysconf_DATA = manuf
  
  DISSECTOR_SRC = \
  	packet-aarp.c  \
--- 68,75 ----
  EXTRA_PROGRAMS = ethereal ethereal_static tethereal tethereal_static editcap mergecap dftest text2pcap
  EXTRA_SCRIPTS = idl2eth
  
! sysconf_DATA = manuf dictionary.dtd  dictionary.xml \
! 	sunping.xml mobileipv4.xml nasreq.xml
  
  DISSECTOR_SRC = \
  	packet-aarp.c  \
***************
*** 448,454 ****
  	x11-declarations.h \
  	x11-register-info.h \
  	xdlc.c         \
! 	xdlc.h
  
  BUILT_SOURCES = \
  	x11-declarations.h \
--- 449,457 ----
  	x11-declarations.h \
  	x11-register-info.h \
  	xdlc.c         \
! 	xdlc.h		\
! 	xmlstub.c         \
! 	xmlstub.h
  
  BUILT_SOURCES = \
  	x11-declarations.h \
***************
*** 808,813 ****
--- 811,821 ----
  	randpkt.c		\
  	rdps.c			\
  	TODO			\
+ 	dictionary.dtd		\
+ 	dictionary.xml		\
+ 	sunping.xml		\
+ 	mobileipv4.xml		\
+ 	nasreq.xml		\
  	x11-fields
  
  if SETUID_INSTALL
Index: Makefile.nmake
===================================================================
RCS file: /cvsroot/ethereal/Makefile.nmake,v
retrieving revision 1.134
diff -c -r1.134 Makefile.nmake
*** Makefile.nmake	2001/10/29 21:13:07	1.134
--- Makefile.nmake	2001/10/30 04:13:28
***************
*** 247,252 ****
--- 247,253 ----
  	register.obj     \
  	util.obj         \
  	xdlc.obj         \
+ 	xmlstub.obj	 \
  
  ethereal_OBJECTS = \
  	$(DISSECTOR_OBJECTS) \
Index: packet-diameter-defs.h
===================================================================
RCS file: /cvsroot/ethereal/packet-diameter-defs.h,v
retrieving revision 1.5
diff -c -r1.5 packet-diameter-defs.h
*** packet-diameter-defs.h	2001/07/30 20:08:44	1.5
--- packet-diameter-defs.h	2001/10/30 04:13:28
***************
*** 1,8 ****
  /*
   * Filename: packet-diameter-defs.h
-  * WARNING:  This file was automatically generated by dict2h.pl.  Modifications
-  *           will be erased by next invocation of dictionary parser.
   *
   * Generated: Fri Feb 23 13:04:15 2001
   */
  
--- 1,11 ----
  /*
   * Filename: packet-diameter-defs.h
   *
+  * This file contains the static definitions of the Diameter base protocol
+  * AVPs.  If libxml is in the LD_LIBRARY_PATH, and dictionary.xml exists,
+  * then it will not be used.
+  *
+  * $Id$
   * Generated: Fri Feb 23 13:04:15 2001
   */
  
***************
*** 12,37 ****
  
  /* Type to string table */
  
- 
- static value_string diameter_avp_type_vals[]={
- 	{  1, "OctetString" },
- 	{  2, "Integer32" },
- 	{  3, "Integer64" },
- 	{  4, "Unsigned32" },
- 	{  5, "Unsigned64" },
- 	{  6, "Float32" },
- 	{  7, "Float64" },
- 	{  8, "Float128" },
- 	{  9, "Grouped" },
- 	{ 10, "IpAddress" },
- 	{ 11, "Time" },
- 	{ 12, "UTF8String" },
- 	{ 13, "DiameterIdentity" },
- 	{ 14, "Enumerated" },
- 	{ 15, "IPFilterRule" },
- 	{ 16, "QOSFilterRule" },
- 	{0, (char *)NULL}
- };
  /* Attribute to String tables */
  static value_string diameter_service_type_vals[]={
     {5, "Outbound"},
--- 15,20 ----
***************
*** 99,104 ****
--- 82,88 ----
  	{529, "Ascend"},
  	{1584, "Bay Networks"},
  	{2636, "Juniper Networks"},
+         {5925, "ipUnplugged"},
  	{0,NULL}
  };
  
***************
*** 257,264 ****
  	{5, "Link Broken"},
  	{0,NULL}
  };
  
! static struct avp_info diameter_avps[] = {
  	/* Radius Attributes */
  	{  1, "User-Name",                DIAMETER_UTF8STRING,   (value_string *)NULL},
  	{  2, "User-Password",            DIAMETER_OCTET_STRING, (value_string *)NULL},
--- 241,264 ----
  	{5, "Link Broken"},
  	{0,NULL}
  };
+ 
+ static value_string diameter_mip_algorithm_type[] = {
+ 	{1, "MD5 Prefix/Suffix"},
+ 	{2, "HMAC-MD5"},
+ 	{3, "HMAC-SHA1"},
+ 	{0, NULL}
+ };
+ 
+ static value_string diameter_mip_replay_type[] = {
+ 	{1, "None"},
+ 	{2, "Nonce"},
+ 	{3, "Timestamp"},
+ 	{0, NULL}
+ };
+ 
+ 
  
! static struct old_avp_info old_diameter_avps[] = {
  	/* Radius Attributes */
  	{  1, "User-Name",                DIAMETER_UTF8STRING,   (value_string *)NULL},
  	{  2, "User-Password",            DIAMETER_OCTET_STRING, (value_string *)NULL},
***************
*** 349,355 ****
      { 278, "Origin-State-Id",             DIAMETER_UNSIGNED32,  (value_string *)NULL},
      { 269, "Product-Name",                DIAMETER_UTF8STRING,  (value_string *)NULL},
      { 280, "Proxy-Host",                  DIAMETER_IDENTITY,    (value_string *)NULL},
!     { 284, "Proxy-Info",                  DIAMETER_OCTET_STRING,(value_string *)NULL},
      { 292, "Redirect-Host",               DIAMETER_IDENTITY,    (value_string *)NULL},
      { 261, "Redirect-Host-Usage",         DIAMETER_ENUMERATED,  diameter_redirect_host_usage_vals}, 
      { 262, "Redirect-Max-Cache-Time",     DIAMETER_UNSIGNED32,  (value_string *)NULL},
--- 349,355 ----
      { 278, "Origin-State-Id",             DIAMETER_UNSIGNED32,  (value_string *)NULL},
      { 269, "Product-Name",                DIAMETER_UTF8STRING,  (value_string *)NULL},
      { 280, "Proxy-Host",                  DIAMETER_IDENTITY,    (value_string *)NULL},
!     { 284, "Proxy-Info",                  DIAMETER_GROUPED,     (value_string *)NULL},
      { 292, "Redirect-Host",               DIAMETER_IDENTITY,    (value_string *)NULL},
      { 261, "Redirect-Host-Usage",         DIAMETER_ENUMERATED,  diameter_redirect_host_usage_vals}, 
      { 262, "Redirect-Max-Cache-Time",     DIAMETER_UNSIGNED32,  (value_string *)NULL},
***************
*** 363,369 ****
      { 295, "Termination-Cause",           DIAMETER_ENUMERATED,  diameter_termination_cause_vals},
      { 266, "Vendor-Id",                   DIAMETER_ENUMERATED,  diameter_vendor_specific_vendors},
      { 260, "Vendor-Specific-Application-Id", DIAMETER_GROUPED, (value_string *)NULL},
! 	{0, (char *)NULL, 0, (value_string*)NULL}
  };
  
  
--- 363,396 ----
      { 295, "Termination-Cause",           DIAMETER_ENUMERATED,  diameter_termination_cause_vals},
      { 266, "Vendor-Id",                   DIAMETER_ENUMERATED,  diameter_vendor_specific_vendors},
      { 260, "Vendor-Specific-Application-Id", DIAMETER_GROUPED, (value_string *)NULL},
! /* Diameter Mobile IP AVPs */
!     { 318, "MIP-FA-to-HA-SPI",            DIAMETER_UNSIGNED32,     (value_string *)NULL},
!     { 319, "MIP-FA-to-MN-SPI",            DIAMETER_UNSIGNED32,     (value_string *)NULL},
!     { 320, "MIP-Reg-Request",             DIAMETER_MIP_REG_REQ,    (value_string *)NULL},
!     { 321, "MIP-Reg-Reply",               DIAMETER_OCTET_STRING,   (value_string *)NULL},
!     { 322, "MIP-MN-AAA-Auth",             DIAMETER_GROUPED,        (value_string *)NULL},
!     { 325, "MIP-MN-to-FA-KEY",            DIAMETER_GROUPED,        (value_string *)NULL},
!     { 326, "MIP-FA-to-MN-KEY",            DIAMETER_GROUPED,        (value_string *)NULL},
!     { 328, "MIP-FA-to-HA-KEY",            DIAMETER_GROUPED,        (value_string *)NULL},
!     { 329, "MIP-HA-to-FA-KEY",            DIAMETER_GROUPED,        (value_string *)NULL},
!     { 330, "MIP-Foreign-Agent-Host",      DIAMETER_IDENTITY,       (value_string *)NULL},
!     { 331, "MIP-MN-to-HA-KEY",            DIAMETER_GROUPED,        (value_string *)NULL},
!     { 333, "MIP-Mobile-Node-Address",     DIAMETER_IP_ADDRESS,     (value_string *)NULL},
!     { 334, "MIP-Home-Agent-Address",      DIAMETER_IP_ADDRESS,     (value_string *)NULL},
!     { 335, "MIP-Key-Material",            DIAMETER_OCTET_STRING,   (value_string *)NULL},
!     { 337, "MIP-Feature-Vector",          DIAMETER_UNSIGNED32,     (value_string *)NULL},
!     { 338, "MIP-Auth-Input-Data-Length",  DIAMETER_UNSIGNED32,     (value_string *)NULL},
!     { 339, "MIP-Authenticator-Length",    DIAMETER_UNSIGNED32,     (value_string *)NULL},
!     { 340, "MIP-Authenticator-Offset",    DIAMETER_UNSIGNED32,     (value_string *)NULL},
!     { 341, "MIP-MN-AAA-SPI",              DIAMETER_UNSIGNED32,     (value_string *)NULL},
!     { 342, "MIP-PEER-SPI",                DIAMETER_UNSIGNED32,     (value_string *)NULL},
!     { 343, "MIP-Session-Key",             DIAMETER_OCTET_STRING,   (value_string *)NULL},
!     { 344, "MIP-FA-Challenge",            DIAMETER_OCTET_STRING,   (value_string *)NULL},
!     { 345, "MIP-Algorithm-Type",          DIAMETER_ENUMERATED,     diameter_mip_algorithm_type},
!     { 346, "MIP-Algorithm-Type",          DIAMETER_ENUMERATED,     diameter_mip_replay_type},
!     { 347, "MIP-Filter-Rule",             DIAMETER_IP_FILTER_RULE, (value_string *)NULL},
!     { 398, "MIP-Key-Lifetime",            DIAMETER_UNSIGNED32,    (value_string *)NULL},
! {0, (char *)NULL, 0, (value_string*)NULL}
  };
  
  
***************
*** 378,383 ****
--- 405,413 ----
  	{282, "Disconnect-Peer"},
  	{258, "Re-Auth"},
  	{275, "Session-Termination"},
+ 	/* Mip Protocol */
+ 	{262, "Home-Agent-MIP"},
+ 	{260, "AA-Mobile-Node"},
  	{0, (char *)NULL}
  };
  
Index: packet-diameter.c
===================================================================
RCS file: /cvsroot/ethereal/packet-diameter.c,v
retrieving revision 1.27
diff -c -r1.27 packet-diameter.c
*** packet-diameter.c	2001/10/29 21:13:07	1.27
--- packet-diameter.c	2001/10/30 04:13:29
***************
*** 1,5 ****
  /* packet-diameter.c
!  * Routines for DIAMETER packet disassembly
   *
   * $Id: packet-diameter.c,v 1.27 2001/10/29 21:13:07 guy Exp $
   *
--- 1,5 ----
  /* packet-diameter.c
!  * Routines for Diameter packet disassembly
   *
   * $Id: packet-diameter.c,v 1.27 2001/10/29 21:13:07 guy Exp $
   *
***************
*** 41,52 ****
  #include <string.h>
  #include <ctype.h>
  #include <time.h>
  #include <glib.h>
  #include "packet.h"
  #include "resolv.h"
  #include "prefs.h"
  
! /* This must be defined before we include packet-diameter-defs.h s*/
  
  /* Valid data types */
  typedef enum {
--- 41,55 ----
  #include <string.h>
  #include <ctype.h>
  #include <time.h>
+ #include <dlfcn.h>
  #include <glib.h>
+ #include <filesystem.h>
+ #include <xmlstub.h>
  #include "packet.h"
  #include "resolv.h"
  #include "prefs.h"
  
! /* This must be defined before we include packet-diameter-defs.h */
  
  /* Valid data types */
  typedef enum {
***************
*** 68,84 ****
    DIAMETER_IDENTITY,           /* OctetString */
    DIAMETER_ENUMERATED,         /* Integer 32 */
    DIAMETER_IP_FILTER_RULE,     /* OctetString */
!   DIAMETER_QOS_FILTER_RULE     /* OctetString */
    
  } diameterDataType;
  
! typedef struct avp_info {
    guint32           code;
    gchar            *name;
    diameterDataType  type;
    value_string     *values;
  } avpInfo;
  
  #include "packet-diameter-defs.h"
  
  #define  NTP_TIME_DIFF                   (2208988800UL)
--- 71,155 ----
    DIAMETER_IDENTITY,           /* OctetString */
    DIAMETER_ENUMERATED,         /* Integer 32 */
    DIAMETER_IP_FILTER_RULE,     /* OctetString */
!   DIAMETER_QOS_FILTER_RULE,    /* OctetString */
!   DIAMETER_MIP_REG_REQ,        /* OctetString */
!   DIAMETER_VENDOR_ID,           /* Integer32  */
!   DIAMETER_APPLICATION_ID
    
  } diameterDataType;
  
! 
! static value_string TypeValues[]={
!   {  DIAMETER_OCTET_STRING,    "OctetString" },
!   {  DIAMETER_INTEGER32,       "Integer32" },
!   {  DIAMETER_INTEGER64,       "Integer64" },
!   {  DIAMETER_UNSIGNED32,      "Unsigned32" },
!   {  DIAMETER_UNSIGNED64,      "Unsigned64" },
!   {  DIAMETER_FLOAT32,         "Float32" },
!   {  DIAMETER_FLOAT64,         "Float64" },
!   {  DIAMETER_FLOAT128,        "Float128" },
!   {  DIAMETER_GROUPED,         "Grouped" },
!   {  DIAMETER_IP_ADDRESS,      "IpAddress" },
!   {  DIAMETER_TIME,            "Time" },
!   {  DIAMETER_UTF8STRING,      "UTF8String" },
!   {  DIAMETER_IDENTITY,        "DiameterIdentity" },
!   {  DIAMETER_ENUMERATED,      "Enumerated" },
!   {  DIAMETER_IP_FILTER_RULE,  "IPFilterRule" },
!   {  DIAMETER_QOS_FILTER_RULE, "QOSFilterRule" },
!   {  DIAMETER_MIP_REG_REQ,     "MIPRegistrationRequest"},
!   {  DIAMETER_VENDOR_ID,       "VendorId"},
!   {  DIAMETER_APPLICATION_ID,  "AppId"},
!   {0, (char *)NULL}
! };
! 
! typedef struct value_name {
!   guint32            value;
!   gchar             *name;
!   struct value_name *next;
! } ValueName;
! 
! typedef struct old_avp_info {
    guint32           code;
    gchar            *name;
    diameterDataType  type;
    value_string     *values;
+ } oldAvpInfo;
+ 
+ typedef struct avp_info {
+   guint32           code;
+   gchar            *name;
+   gchar            *vendorName;
+   diameterDataType  type;
+   ValueName        *values;
+   struct avp_info  *next;
  } avpInfo;
  
+ typedef struct command_code {
+   guint32              code;
+   gchar               *name;
+   gchar               *vendorString;
+   struct command_code *next;
+ } CommandCode;
+ 
+ typedef struct vendor_id {
+   guint32              id;
+   gchar               *name;
+   gchar               *longName;
+   struct vendor_id    *next;
+ } VendorId;
+ 
+ typedef struct application_id {
+   guint32              id;
+   gchar               *name;
+   struct application_id    *next;
+ } ApplicationId;
+ 
+ static avpInfo         *avpListHead=NULL;
+ static VendorId        *vendorListHead=NULL;
+ static CommandCode     *commandListHead=NULL;
+ static ApplicationId   *ApplicationIdHead=NULL;
+ 
+ 
  #include "packet-diameter-defs.h"
  
  #define  NTP_TIME_DIFF                   (2208988800UL)
***************
*** 147,152 ****
--- 218,226 ----
  static char gbl_diameterString[200];
  static int gbl_diameterTcpPort=TCP_PORT_DIAMETER;
  static int gbl_diameterSctpPort=SCTP_PORT_DIAMETER;
+ #define DIAMETER_DIR "diameter"
+ #define DICT_FN "dictionary.xml"
+ static gchar *gbl_diameterDictionary = NULL;
  
  typedef struct _e_diameterhdr {
    guint32  versionLength;
***************
*** 162,169 ****
    guint32 avp_vendorId;           /* optional */
  } e_avphdr;
  
- #define AUTHENTICATOR_LENGTH 12
- 
  /* Diameter Header Flags */
  /*                                      RPrrrrrrCCCCCCCCCCCCCCCCCCCCCCCC  */
  #define DIAM_FLAGS_R 0x80
--- 236,241 ----
***************
*** 195,233 ****
  #define AVP_FLAGS_RESERVED 0x1f          /* 00011111  -- V M P X X X X X */
  
  #define MIN_AVP_SIZE (sizeof(e_avphdr) - sizeof(guint32))
! #define MIN_DIAMETER_SIZE (sizeof(e_diameterhdr) + MIN_AVP_SIZE)
  
  static void dissect_avps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
  
  
  
  
! /* Diameter Manipulation Routines (mess with our strucutres) */
  
  diameterDataType
  diameter_avp_get_type(guint32 avpCode){
!   int i;
!   for (i=0; diameter_avps[i].name; i++) {
! 	if (avpCode == diameter_avps[i].code) {
  	  /* We found it! */
! 	  return diameter_avps[i].type;
  	}
    }
    /* If we don't find it, assume it's data */
!   g_warning("DIAMETER: Unable to find type for avpCode %d!", avpCode);
    return DIAMETER_OCTET_STRING;
  } /* diameter_avp_get_type */
  
  static gchar *
  diameter_avp_get_name(guint32 avpCode)
  {
    static gchar buffer[64];
  
!   int i;
!   for (i=0; diameter_avps[i].name; i++) {
! 	if (avpCode == diameter_avps[i].code) {
  	  /* We found it! */
! 	  return diameter_avps[i].name;
  	}
    }
    /* If we don't find it, build a name string */
--- 267,882 ----
  #define AVP_FLAGS_RESERVED 0x1f          /* 00011111  -- V M P X X X X X */
  
  #define MIN_AVP_SIZE (sizeof(e_avphdr) - sizeof(guint32))
! #define MIN_DIAMETER_SIZE (sizeof(e_diameterhdr))
  
  static void dissect_avps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
  
  
+ /*
+  * This routine will do a push-parse of the passed in
+  * filename.  This was taken almost verbatum from
+  * the xmlsoft examples.
+  */
+ static xmlDocPtr
+ xmlParseFilePush( char *filename, int checkValid) {
+   FILE *f;
+   xmlDocPtr doc=NULL;
+   int valid=0;
+   int res, size = 1024;
+   char chars[1024];
+   xmlParserCtxtPtr ctxt;
+ 	
+   /* I wonder what kind of a performance hit this is? */
+   *XmlStub.xmlDoValidityCheckingDefaultValue = checkValid;
+   
+   f = fopen(filename, "r");
+   if (f == NULL) {
+ 	g_warning("Diameter: Unable to open %s", filename);
+ 	return NULL;
+   }
+ 
+   res = fread(chars, 1, 4, f);
+   if (res > 0) {
+ 	ctxt = XmlStub.xmlCreatePushParserCtxt(NULL, NULL,
+ 										   chars, res, filename);
+ 	while ((res = fread(chars, 1, size-1, f)) > 0) {
+ 	  XmlStub.xmlParseChunk(ctxt, chars, res, 0);
+ 	}
+ 	XmlStub.xmlParseChunk(ctxt, chars, 0, 1);
+ 	doc = ctxt->myDoc;
+ 	valid=ctxt->valid;
+ 	XmlStub.xmlFreeParserCtxt(ctxt);
+   }
+   fclose(f); 
+ 
+   /* Check valid */
+   if (!valid) {
+ 	g_warning( "Error!  Invalid xml in %s!  Failed DTD check!",
+ 			   filename);
+ 	return NULL;
+   }
+   return doc;
+ } /* xmlParseFilePush */
+ 
+ /*
+  * This routine will add a static avp to the avp list.  It is
+  * only called when the XML dictionary fails to load properly.
+  */
+ static int
+ addStaticAVP(int code, gchar *name, diameterDataType type, value_string *values)
+ {
+   avpInfo *entry;
+   ValueName *vEntry=NULL;
+   int i;
+ 
+   /* Parse our values array, if we have one */
+   if (values) {
+ 	for (i=0; values[i].strptr != NULL; i++) {
+ 	  char *valueName=NULL, *valueCode=NULL;
+ 	  ValueName *ve = NULL;
+ 			
+ 	  ve = g_malloc(sizeof(ValueName));
+ 	  ve->name = strdup(values[i].strptr);
+ 	  ve->value = values[i].value;
+ 	  ve->next = vEntry;
+ 	  vEntry = ve;
+ 	}
+   } /* if values */
+ 
+ 	/* And, create the entry */
+   entry = (avpInfo *)g_malloc(sizeof(avpInfo));
+   entry->name = g_strdup(name);
+   entry->code = code;
+   entry->vendorName = NULL;
+   entry->type = type;
+   entry->values = vEntry;
+   if (vEntry)
+ 	entry->type = DIAMETER_INTEGER32;
+ 
+   return (0);
+ 	
+ } /* addStaticAVP */
+ 
+ /*
+  * This routine will parse an XML avp entry, and add it to our
+  * avp list.  If any values are present in the avp, it will
+  * add them too.
+  */
+ static int
+ xmlParseAVP(xmlDocPtr doc, xmlNodePtr cur)
+ {
+   char *name=NULL, *description=NULL, *code=NULL, *mayEncrypt=NULL,
+ 	*mandatory=NULL, *protected=NULL, *vendorBit=NULL, *vendorName = NULL,
+ 	*constrained=NULL;
+   char *type=NULL;
+   avpInfo *entry;
+   uint32_t avpType=0;
+   ValueName *vEntry=NULL;
+   int i;
+ 
+   /* First, get our properties */
+   name = XmlStub.xmlGetProp(cur, "name");
+   description = XmlStub.xmlGetProp(cur, "description");
+   code = XmlStub.xmlGetProp(cur, "code");
+   mayEncrypt = XmlStub.xmlGetProp(cur, "may-encrypt");
+   mandatory = XmlStub.xmlGetProp(cur, "mandatory");
+   protected = XmlStub.xmlGetProp(cur, "protected");
+   vendorBit = XmlStub.xmlGetProp(cur, "vendor-bit");
+   vendorName = XmlStub.xmlGetProp(cur, "vendor-id");
+   constrained = XmlStub.xmlGetProp(cur, "constrained");
+ 
+   cur = cur->xmlChildrenNode;
+ 
+   while (cur != NULL ) {
+ 	if (!strcasecmp((char *)cur->name, "type")) {
+ 	  type = XmlStub.xmlGetProp(cur, "type-name");
+ 	}
+ 	if (!strcasecmp((char *)cur->name, "enum")) {
+ 	  char *valueName=NULL, *valueCode=NULL;
+ 	  ValueName *ve = NULL;
+ 	  valueName = XmlStub.xmlGetProp(cur, "name");
+ 	  valueCode = XmlStub.xmlGetProp(cur, "code");
+ 			
+ 	  if (!valueName || !valueCode) {
+ 		g_warning( "Error, bad value on avp %s", name);
+ 		return (-1);
+ 	  }
+ 			
+ 	  ve = g_malloc(sizeof(ValueName));
+ 	  ve->name = strdup(valueName);
+ 	  ve->value = atol(valueCode);
+ 
+ 	  ve->next = vEntry;
+ 	  vEntry = ve;
+ 	}
+ 	if (!strcasecmp((char *)cur->name, "grouped")) {
+ 	  /* WORK Recurse here for grouped AVPs */
+ 	  type = "grouped";
+ 	}
+ 	cur=cur->next;
+   } /* while */
+ 
+ 	/*
+ 	 * Check for the AVP Type.
+ 	 */
+   if (type) {
+ 	for (i = 0; TypeValues[i].strptr; i++) {
+ 	  if (!strcasecmp(type, TypeValues[i].strptr)) {
+ 		avpType = TypeValues[i].value;
+ 		break;
+ 	  }
+ 	}
+ 
+ 	if (TypeValues[i].strptr == NULL) {
+ 	  g_warning( "Invalid Type field in dictionary! avp %s (%s)",  name, type);
+ 	  return (-1);
+ 	}
+   } else if (!vEntry) {
+ 	g_warning("Missing type/enum field in dictionary avpName=%s",
+ 			  name);
+ 	return (-1);
+   }
+ 
+   /* WORK - Handle flags  -- for validation later */
+ 	
+ 
+   /* And, create the entry */
+   entry = (avpInfo *)g_malloc(sizeof(avpInfo));
+   entry->name = g_strdup(name);
+   entry->code = atol(code);
+   if (vendorName) 
+ 	entry->vendorName = g_strdup(vendorName);
+   else
+ 	entry->vendorName = NULL;
+   entry->type = avpType;
+   entry->values = vEntry;
+   if (vEntry)
+ 	entry->type = DIAMETER_INTEGER32;
+ 
+   /* And, add it to the list */
+   entry->next = avpListHead;
+   avpListHead = entry;
+ 
+   return (0);
+ } /* xmlParseAVP */
+ 
+ /*
+  * This routine will add a command to the list of commands.
+  */
+ static int
+ addCommand(int code, char *name, char *vendorId)
+ {
+   CommandCode *entry;
+ 
+   /*
+    * Allocate the memory required for the dictionary.
+    */
+   entry = (CommandCode *) g_malloc(sizeof (CommandCode));
+ 
+   if (entry == NULL) {
+ 	g_warning("Unable to allocate memory");
+ 	return (-1);
+   }
+ 
+   /*
+    * Allocate memory for the AVPName and copy the name to the
+    * structure
+    */
+   entry->name = g_strdup(name);
+   entry->code = code;
+   if (vendorId)
+ 	entry->vendorString = g_strdup(vendorId);
+   else
+ 	entry->vendorString = NULL;
+ 
+   /* Add the entry to the list */
+   entry->next = commandListHead;
+   commandListHead = entry;
+ 
+   return 0;
+ } /* addCommand */
+ 
+ /*
+  * This routine will parse the XML command, and add it to our
+  * list of commands.
+  */
+ static int
+ xmlParseCommand(xmlDocPtr doc, xmlNodePtr cur)
+ {
+   uint32_t vendorId = 0;
+   char *name, *code, *vendorIdString;
+ 
+   /*
+    * Get the Attributes
+    */
+   name = XmlStub.xmlGetProp(cur, "name");
+   code = XmlStub.xmlGetProp(cur, "code");
+   if (!name || !code) {
+ 	g_warning("Invalid command.  Name or code missing!");
+ 	return -1;
+   }
+   vendorIdString = XmlStub.xmlGetProp(cur, "vendor-id");
+ 
+   if (!vendorIdString || !strcasecmp(vendorIdString, "None")) {
+ 	vendorIdString = NULL;
+   }
+ 
+   return (addCommand(atoi(code), name, vendorIdString));
+ } /* xmlParseCommand */
+ 
+ /* This routine adds an application to the name<-> id table */
+ static int
+ dictionaryAddApplication(char *name, int id)
+ {
+   ApplicationId *entry;
+ 
+   if (!name || (id <= 0)) {
+ 	g_warning( "Diameter Error: Inavlid application (name=%p, id=%d)",
+ 			   name, id);
+ 	return (-1);
+   } /* Sanity Checks */
+ 
+   entry = g_malloc(sizeof(ApplicationId));
+   if (!entry) {
+ 	g_warning( "Unable to allocate memory");
+ 	return (-1);
+   }
+ 	
+   entry->name = g_strdup(name);
+   entry->id = id;
+ 	
+   /* Add it to the list */
+   entry->next = ApplicationIdHead;
+   ApplicationIdHead = entry;
+ 
+   return 0;
+ } /* dictionaryAddApplication */
+ 
+ /*
+  * This routine will add a vendor to the vendors list
+  */
+ static int
+ addVendor(int id, gchar *name, gchar *longName)
+ {
+   VendorId *vendor;
+ 
+   /* add entry */
+   vendor=g_malloc(sizeof(VendorId));
+   if (!vendor) {
+ 	return (-1);
+   }
+ 
+   vendor->id = id;
+   vendor->name = g_strdup(name);
+   vendor->longName = g_strdup(longName);
+   vendor->next = vendorListHead;
+   vendorListHead = vendor;
+ 
+   return 0;
+ } /* addVendor */
+ 
+ /*
+  * This routine will pars in a XML vendor entry.
+  */
+ static int
+ xmlParseVendor(xmlDocPtr doc, xmlNodePtr cur)
+ {
+   char *name=NULL, *code=NULL, *id=NULL;
+ 
+   /* First, get our properties */
+   id = XmlStub.xmlGetProp(cur, "vendor-id");
+   name = XmlStub.xmlGetProp(cur, "name");
+   code = XmlStub.xmlGetProp(cur, "code");
+ 
+   if (!id || !name || !code) {
+ 	g_warning( "Invalid vendor section.  vendor-id, name, and code must be specified");
+ 	return -1;
+   }
+ 
+   return (addVendor(atoi(code), id, name));
+ } /* addVendor */
+ 
+ /*
+  * This routine will either parse in the base protocol, or an application.
+  */
+ static int
+ xmlDictionaryParseSegment(xmlDocPtr doc, xmlNodePtr cur, int base)
+ {
+   if (!base) {
+ 	char *name;
+ 	char *id;
+ 		
+ 	/* Add our application */
+ 	id = XmlStub.xmlGetProp(cur, "id");
+ 	name = XmlStub.xmlGetProp(cur, "name");
+ 		
+ 	if (!name || !id) {
+ 	  /* ERROR!!! */
+ 	  g_warning("Diameter: Invalid application!: name=\"%s\", id=\"%s\"",
+ 				name?name:"NULL", id?id:"NULL");
+ 	  return -1;
+ 	}
+ 		
+ 	/* Add the application */
+ 	if (dictionaryAddApplication(name, atol(id)) != 0) {
+ 	  /* ERROR! */
+ 	  return -1;
+ 	}
+   }
+ 
+ 	
+   /*
+    * Get segment values
+    */
+   cur = cur->xmlChildrenNode;
+   while (cur != NULL) {
+ 	if (!strcasecmp((char *)cur->name, "avp")) {
+ 	  /* we have an avp!!! */
+ 	  xmlParseAVP(doc, cur);
+ 	} else if (!strcasecmp((char *)cur->name, "vendor")) {
+ 	  /* we have a vendor */
+ 	  xmlParseVendor(doc, cur);
+ 	  /* For now, ignore typedefn and text */
+ 	} else if (!strcasecmp((char *)cur->name, "command")) {
+ 	  /* Found a command */
+ 	  xmlParseCommand(doc,cur);
+ 	} else if (!strcasecmp((char *)cur->name, "text")) {
+ 	} else if (!strcasecmp((char *)cur->name, "comment")) {
+ 	} else if (!strcasecmp((char *)cur->name, "typedefn")) {
+ 	  /* WORK -- parse in valid types . . . */
+ 	} else {
+ 	  /* IF we got here, we're an error */
+ 	  g_warning("Error!  expecting an avp or a typedefn (got \"%s\")",
+ 				cur->name);
+ 	  return (-1);
+ 	}
+ 	cur = cur->next;
+   } /* while */
+   return 0;
+ } /* xmlDictionaryParseSegment */
+ 
+ /*
+  * The main xml parse routine.  This will walk through an XML 
+  * dictionary that has been parsed by libxml.
+  */
+ static int
+ xmlDictionaryParse(xmlDocPtr doc, xmlNodePtr cur)
+ {
+   /* We should expect a base protocol, followed by multiple applicaitons */
+   while (cur != NULL) {
+ 	if (!strcasecmp((char *)cur->name, "base")) {
+ 	  /* Base protocol.  Descend and parse */
+ 	  xmlDictionaryParseSegment(doc, cur, 1);
+ 	} else if (!strcasecmp((char *)cur->name, "application")) {
+ 	  /* Application.  Descend and parse */
+ 	  xmlDictionaryParseSegment(doc, cur, 0);
+ 	} else if (!strcasecmp((char *)cur->name, "text")) {
+ 	  /* Ignore text */
+ 	} else {
+ 	  g_warning( "Diameter: XML Expecting a base or an application  (got \"%s\")",
+ 				 cur->name);
+ 	  return (-1);
+ 	}
+ 	cur = cur->next;
+   }
+ 
+   return 0;
+ 
+ } /* xmlDictionaryParse */
+ 
+ /*
+  * This routine will call libxml to parse in the dictionary.
+  */
+ static int
+ loadXMLDictionary()
+ {
+   xmlDocPtr doc;
+   xmlNodePtr cur;
+ 
+   /*
+    * build an XML tree from a the file;
+    */
+   XmlStub.xmlKeepBlanksDefault(0);                    /* Strip leading and trailing blanks */
+   XmlStub.xmlSubstituteEntitiesDefault(1);            /* Substitute entities automagically */
+   doc = xmlParseFilePush(gbl_diameterDictionary, 1);  /* Parse the XML (do validity checks)*/
+ 
+   /* Check for invalid xml */
+   if (doc == NULL) {
+ 	g_warning("Diameter: Unable to parse xmldictionary %s",
+ 			  gbl_diameterDictionary);
+ 	return -1;
+   }
+ 	
+   /*
+    * Check the document is of the right kind
+    */
+   cur = XmlStub.xmlDocGetRootElement(doc);
+   if (cur == NULL) {
+ 	g_warning("Diameter: Error: \"%s\": empty document",
+ 			  gbl_diameterDictionary);
+ 	XmlStub.xmlFreeDoc(doc);
+ 	return -1;
+   }
+   if (XmlStub.xmlStrcmp(cur->name, (const xmlChar *) "dictionary")) {
+ 	g_warning("Diameter: Error: \"%s\": document of the wrong type, root node != dictionary",
+ 			  gbl_diameterDictionary);
+ 	XmlStub.xmlFreeDoc(doc);
+ 	return -1;
+   }
+ 	
+   /*
+    * Ok, the dictionary has been parsed by libxml, and is valid.
+    * All we have to do now is read in our information.
+    */
+   if (xmlDictionaryParse(doc, cur->xmlChildrenNode) != 0) {
+ 	/* Error has already been printed */
+ 	return -1;
+   }
+ 
+   /* Once we're done parsing, free up the xml memory */
+   XmlStub.xmlFreeDoc(doc);
+ 
+   return 0;
  
+ } /* loadXMLDictionary */
+ 
+ /*
+  * Fallback routine.  In the event of ANY error when loading the XML
+  * dictionary, this routine will populate the new avp list structures
+  * with the old static data from packet-diameter-defs.h
+  */
+ static void
+ initializeDictionaryDefaults()
+ {
+   int i;
  
!   /* Add static vendors to list */
!   for(i=0; diameter_vendor_specific_vendors[i].strptr; i++) {
! 	addVendor(diameter_vendor_specific_vendors[i].value,
! 			  diameter_vendor_specific_vendors[i].strptr,
! 			  diameter_vendor_specific_vendors[i].strptr);
!   }
!   /* Add static commands to list. */
!   for(i=0; diameter_command_code_vals[i].strptr; i++) {
! 	addCommand(diameter_command_code_vals[i].value,
! 			   diameter_command_code_vals[i].strptr, NULL);
!   }
! 
!   /* Add static AVPs to list */
!   for (i=0; old_diameter_avps[i].name; i++) {
! 	addStaticAVP(old_diameter_avps[i].code,
! 				 old_diameter_avps[i].name,
! 				 old_diameter_avps[i].type,
! 				 old_diameter_avps[i].values);
!   }
! 
! } /* initializeDictionaryDefaults */
! 
! /* 
!  * This routine will attempt to load the XML dictionary, and on 
!  * failure, will call initializeDictionaryDefaults to load in
!  * our static dictionary.
!  */
! static void
! initializeDictionary()
! {
!   /*
!    * Using ugly ordering here.  If loadLibXML succeeds, then 
!    * loadXMLDictionary will be called.  This is one of the few times when
!    * I think this is prettier than the nested if alternative.
!    */
!   if (loadLibXML() ||
! 	  (loadXMLDictionary() != 0)) {
! 	/* Something failed.  Use the static dictionary */
! 	g_warning("Diameter: Using static dictionary! (Unable to use XML)");
! 	initializeDictionaryDefaults();
!   }
! } /* initializeDictionary */
! 
! 
! 
! /*
!  * These routines manipulate the diameter structures.
!  */
! 
! /* return command string, based on the code */
! static gchar *
! diameter_command_to_str(guint32 commandCode)
! {
!   CommandCode *probe;
!   static gchar buffer[64];
! 
!   for (probe=commandListHead; probe; probe=probe->next) {
! 	if (commandCode == probe->code) {
! 	  return probe->name;
! 	}
!   }
! 
!   snprintf(buffer, sizeof(buffer),
! 		   "Cmd-0x%08x", commandCode);
!   return buffer;
! }/*diameter_command_to_str */
! /* return vendor string, based on the id */
! static gchar *
! diameter_vendor_to_str(guint32 vendorId) {
!   VendorId *probe;
!   static gchar buffer[64];
! 
!   for (probe=vendorListHead; probe; probe=probe->next) {
! 	if (vendorId == probe->id) {
! 	  return probe->longName;
! 	}
!   }
! 
!   snprintf(buffer, sizeof(buffer),
! 		   "Vendor 0x%08x", vendorId);
!   return buffer;
! } /*diameter_vendor_to_str */
! /* return application string, based on the id */
! static gchar *
! diameter_app_to_str(guint32 vendorId) {
!   ApplicationId *probe;
!   static gchar buffer[64];
! 
!   for (probe=ApplicationIdHead; probe; probe=probe->next) {
! 	if (vendorId == probe->id) {
! 	  return probe->name;
! 	}
!   }
! 
!   snprintf(buffer, sizeof(buffer),
! 		   "AppId 0x%08x", vendorId);
!   return buffer;
! } /*diameter_app_to_str */
  
+ /* return an avp type, based on the code */
  diameterDataType
  diameter_avp_get_type(guint32 avpCode){
!   avpInfo *probe;
! 
!   for (probe=avpListHead; probe; probe=probe->next) {
! 	if (avpCode == probe->code) {
  	  /* We found it! */
! 	  return probe->type;
  	}
    }
+ 	
    /* If we don't find it, assume it's data */
!   g_warning("Diameter: Unable to find type for avpCode %d!", avpCode);
    return DIAMETER_OCTET_STRING;
  } /* diameter_avp_get_type */
  
+ /* return an avp name from the code */
  static gchar *
  diameter_avp_get_name(guint32 avpCode)
  {
    static gchar buffer[64];
+   avpInfo *probe;
  
!   for (probe=avpListHead; probe; probe=probe->next) {
! 	if (avpCode == probe->code) {
  	  /* We found it! */
! 	  return probe->name;
  	}
    }
    /* If we don't find it, build a name string */
***************
*** 239,251 ****
  {
    static gchar buffer[64];
  
!   int i;
!   for (i=0; diameter_avps[i].name; i++) {
! 	if (avpCode == diameter_avps[i].code) {
! 	  /* We found the code.  Now find the value! */
! 	  if (!diameter_avps[i].values) 
! 		break;
! 	  return val_to_str(avpValue, diameter_avps[i].values , "Unknown Value: 0x%08x");
  	}
    }
    /* If we don't find the avp, build a value string */
--- 888,905 ----
  {
    static gchar buffer[64];
  
!   avpInfo *probe;
! 
!   for (probe=avpListHead; probe; probe=probe->next) {
! 	if (avpCode == probe->code) {
! 	  ValueName *vprobe;
! 	  for(vprobe=probe->values; vprobe; vprobe=vprobe->next) {
! 		if (avpValue == vprobe->value) {
! 		  return vprobe->name;
! 		}
! 	  }
! 	  sprintf(buffer, "Unknown Value: 0x%08x", avpValue);
! 	  return buffer;
  	}
    }
    /* If we don't find the avp, build a value string */
***************
*** 296,301 ****
--- 950,966 ----
    gchar            commandString[64], vendorString[64];
    gint        i;
    guint      bpos;
+   static  int initialized=FALSE;
+ 
+   /*
+    * Only parse in dictionary if there are diameter packets to
+    * dissect.
+    */
+   if (!initialized) {
+ 	  /* Read in our dictionary, if it exists. */
+ 	  initializeDictionary();
+ 	  initialized=TRUE;
+   }
  	
    /* Make entries in Protocol column and Info column on summary display */
    if (check_col(pinfo->fd, COL_PROTOCOL)) 
***************
*** 315,321 ****
  
    if (dh.vendorId) {
  	strcpy(vendorString, 
! 		   val_to_str(dh.vendorId, diameter_vendor_specific_vendors, "Unknown Vendor: %08x"));
    } else {
  	strcpy(vendorString, "None");
    }
--- 980,986 ----
  
    if (dh.vendorId) {
  	strcpy(vendorString, 
! 		   diameter_vendor_to_str(dh.vendorId));
    } else {
  	strcpy(vendorString, "None");
    }
***************
*** 345,351 ****
    }
    
    /* Set up our commandString */
!   strcpy(commandString, val_to_str(commandCode, diameter_command_code_vals, "Unknown Command: 0x%08x"));
    if (flags & DIAM_FLAGS_R) 
  	strcat(commandString, "-Request");
    else
--- 1010,1016 ----
    }
    
    /* Set up our commandString */
!   strcpy(commandString, diameter_command_to_str(commandCode));
    if (flags & DIAM_FLAGS_R) 
  	strcat(commandString, "-Request");
    else
***************
*** 353,359 ****
  
    /* Short packet.  Should have at LEAST one avp */
    if (pktLength < MIN_DIAMETER_SIZE) {
! 	g_warning("DIAMETER: Packet too short: %d bytes less than min size (%d bytes))",
  			  pktLength, MIN_DIAMETER_SIZE);
  	BadPacket = TRUE;
    }
--- 1018,1024 ----
  
    /* Short packet.  Should have at LEAST one avp */
    if (pktLength < MIN_DIAMETER_SIZE) {
! 	g_warning("Diameter: Packet too short: %d bytes less than min size (%d bytes))",
  			  pktLength, MIN_DIAMETER_SIZE);
  	BadPacket = TRUE;
    }
***************
*** 361,377 ****
    /* And, check our reserved flags/version */
    if ((flags & DIAM_FLAGS_RESERVED) ||
  	  (version != 1)) {
! 	g_warning("DIAMETER: Bad packet: Bad Flags(0x%x) or Version(%u)",
  			  flags, version);
  	BadPacket = TRUE;
    }
  
    if (check_col(pinfo->fd, COL_INFO)) {
  	col_add_fstr(pinfo->fd, COL_INFO,
! 				 "%s%s%s%s: %s vendor=%s (hop-id=%d) (end-id=%d) RPE=%d%d%d",
  				 (BadPacket)?"***** Bad Packet!: ":"",
  				 (flags & DIAM_FLAGS_P)?"Proxyable ":"",
- 				 (flags & DIAM_FLAGS_R)?"Request":"Answer",
  				 (flags & DIAM_FLAGS_E)?" Error":"",
  				 commandString, vendorString,
  				 dh.hopByHopId, dh.endToEndId,
--- 1026,1041 ----
    /* And, check our reserved flags/version */
    if ((flags & DIAM_FLAGS_RESERVED) ||
  	  (version != 1)) {
! 	g_warning("Diameter: Bad packet: Bad Flags(0x%x) or Version(%u)",
  			  flags, version);
  	BadPacket = TRUE;
    }
  
    if (check_col(pinfo->fd, COL_INFO)) {
  	col_add_fstr(pinfo->fd, COL_INFO,
! 				 "%s%s%s: %s vendor=%s (hop-id=%d) (end-id=%d) RPE=%d%d%d",
  				 (BadPacket)?"***** Bad Packet!: ":"",
  				 (flags & DIAM_FLAGS_P)?"Proxyable ":"",
  				 (flags & DIAM_FLAGS_E)?" Error":"",
  				 commandString, vendorString,
  				 dh.hopByHopId, dh.endToEndId,
***************
*** 421,432 ****
  
  	/* Command Code */
  	proto_tree_add_uint_format(diameter_tree, hf_diameter_code,
! 						tvb, offset, 3, commandCode, "Command Code: %s", commandString);
  	offset += 3;
  
  	/* Vendor Id */
  	proto_tree_add_uint_format(diameter_tree,hf_diameter_vendor_id,
! 						tvb, offset, 4,	dh.vendorId, "Vendor-Id: %s", vendorString);
  	offset += 4;
  
  	/* Hop-by-hop Identifier */
--- 1085,1096 ----
  
  	/* Command Code */
  	proto_tree_add_uint_format(diameter_tree, hf_diameter_code,
! 							   tvb, offset, 3, commandCode, "Command Code: %s", commandString);
  	offset += 3;
  
  	/* Vendor Id */
  	proto_tree_add_uint_format(diameter_tree,hf_diameter_vendor_id,
! 							   tvb, offset, 4,	dh.vendorId, "Vendor-Id: %s", vendorString);
  	offset += 4;
  
  	/* Hop-by-hop Identifier */
***************
*** 464,469 ****
--- 1128,1191 ----
  } /* dissect_diameter */
  
  /*
+  * Call the mip_dissector, after saving our pinfo variables
+  * so it doesn't write to our column display.
+  */
+ static void
+ safe_dissect_mip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+ 				 size_t offset, size_t length)
+ {
+   static dissector_handle_t mip_handle;
+   static int mipInitialized=FALSE;
+   tvbuff_t *mip_tvb;
+   address save_dl_src;
+   address save_dl_dst;
+   address save_net_src;
+   address save_net_dst;
+   address save_src;
+   address save_dst;
+   gboolean save_in_error_pkt;
+ 
+   if (!mipInitialized) {
+ 	mip_handle = find_dissector("mip");
+ 	mipInitialized=TRUE;
+   }
+ 
+   mip_tvb = tvb_new_subset(tvb, offset,
+ 						   MIN(length, tvb_length(tvb)-offset),
+ 						   length);
+ 	
+   /* The contained packet is a MIP registration request;
+ 	 dissect it with the MIP dissector. */
+   col_set_writable(pinfo->fd, FALSE);
+ 
+   /* Also, save the current values of the addresses, and restore
+ 	 them when we're finished dissecting the contained packet, so
+ 	 that the address columns in the summary don't reflect the
+ 	 contained packet, but reflect this packet instead. */
+   save_dl_src = pinfo->dl_src;
+   save_dl_dst = pinfo->dl_dst;
+   save_net_src = pinfo->net_src;
+   save_net_dst = pinfo->net_dst;
+   save_src = pinfo->src;
+   save_dst = pinfo->dst;
+   save_in_error_pkt = pinfo->in_error_pkt;
+ 
+   call_dissector(mip_handle, mip_tvb, pinfo, tree);
+ 
+   /* Restore the "we're inside an error packet" flag. */
+   pinfo->in_error_pkt = save_in_error_pkt;
+   pinfo->dl_src = save_dl_src;
+   pinfo->dl_dst = save_dl_dst;
+   pinfo->net_src = save_net_src;
+   pinfo->net_dst = save_net_dst;
+   pinfo->src = save_src;
+   pinfo->dst = save_dst;
+ 
+ 
+ } /* safe_dissect_mip */
+ 
+ /*
   * This function will dissect the AVPs in a diameter packet.  It handles
   * all normal types, and even recursively calls itself for grouped AVPs
   */
***************
*** 482,487 ****
--- 1204,1210 ----
    size_t offset = 0 ;
    char dataBuffer[4096];
    tvbuff_t        *group_tvb;
+   tvbuff_t        *mip_tvb;
    proto_tree *group_tree;
    proto_item *grouptf;
    proto_item *avptf;
***************
*** 514,520 ****
  
  	/* Check for short packet */
  	if (packetLength < (long)MIN_AVP_SIZE) {
! 	  g_warning("DIAMETER: AVP Payload too short: %d bytes less than min size (%d bytes))",
  				packetLength, MIN_AVP_SIZE);
  	  BadPacket = TRUE;
  	  /* Don't even bother trying to parse a short packet. */
--- 1237,1243 ----
  
  	/* Check for short packet */
  	if (packetLength < (long)MIN_AVP_SIZE) {
! 	  g_warning("Diameter: AVP Payload too short: %d bytes less than min size (%d bytes))",
  				packetLength, MIN_AVP_SIZE);
  	  BadPacket = TRUE;
  	  /* Don't even bother trying to parse a short packet. */
***************
*** 562,568 ****
  
  	if (vendorId) {
  	  strcpy(vendorString, 
! 			 val_to_str(vendorId, diameter_vendor_specific_vendors, "Unknown Vendor: %08x"));
  	} else {
  	  vendorString[0]='\0';
  	}
--- 1285,1291 ----
  
  	if (vendorId) {
  	  strcpy(vendorString, 
! 			 diameter_vendor_to_str(vendorId));
  	} else {
  	  vendorString[0]='\0';
  	}
***************
*** 570,576 ****
  	/* Check for bad length */
  	if (avpLength < MIN_AVP_SIZE || 
  		((long)avpLength > packetLength)) {
! 	  g_warning("DIAMETER: AVP payload size invalid: avp_length: %d bytes,  "
  				"min: %d bytes,    packetLen: %d",
  				avpLength, MIN_AVP_SIZE, packetLength);
  	  BadPacket = TRUE;
--- 1293,1299 ----
  	/* Check for bad length */
  	if (avpLength < MIN_AVP_SIZE || 
  		((long)avpLength > packetLength)) {
! 	  g_warning("Diameter: AVP payload size invalid: avp_length: %d bytes,  "
  				"min: %d bytes,    packetLen: %d",
  				avpLength, MIN_AVP_SIZE, packetLength);
  	  BadPacket = TRUE;
***************
*** 578,584 ****
  
  	/* Check for bad flags */
  	if (flags & AVP_FLAGS_RESERVED) {
! 	  g_warning("DIAMETER: Invalid AVP: Reserved bit set.  flags = 0x%x,"
  				" resFl=0x%x",
  				flags, AVP_FLAGS_RESERVED);
  	  /* For now, don't set bad packet, since I'm accidentally setting a wrong bit */
--- 1301,1307 ----
  
  	/* Check for bad flags */
  	if (flags & AVP_FLAGS_RESERVED) {
! 	  g_warning("Diameter: Invalid AVP: Reserved bit set.  flags = 0x%x,"
  				" resFl=0x%x",
  				flags, AVP_FLAGS_RESERVED);
  	  /* For now, don't set bad packet, since I'm accidentally setting a wrong bit */
***************
*** 597,610 ****
  	
  	/* Check for out of bounds */
  	if (packetLength < 0) {
! 	  g_warning("DIAMETER: Bad AVP: Bad new length (%d bytes) ",
  				packetLength);
  	  BadPacket = TRUE;
  	}
  
  	/* Make avp Name & type */
! 	strcpy(avpTypeString, val_to_str(diameter_avp_get_type(avph.avp_code), diameter_avp_type_vals, 
! 								   "Unknown-Type: 0x%08x"));
  	strcpy(avpNameString, diameter_avp_get_name(avph.avp_code));
  
  	avptf = proto_tree_add_text(avp_tree, tvb,
--- 1320,1333 ----
  	
  	/* Check for out of bounds */
  	if (packetLength < 0) {
! 	  g_warning("Diameter: Bad AVP: Bad new length (%d bytes) ",
  				packetLength);
  	  BadPacket = TRUE;
  	}
  
  	/* Make avp Name & type */
! 	strcpy(avpTypeString, val_to_str(diameter_avp_get_type(avph.avp_code), TypeValues, 
! 									 "Unknown-Type: 0x%08x"));
  	strcpy(avpNameString, diameter_avp_get_name(avph.avp_code));
  
  	avptf = proto_tree_add_text(avp_tree, tvb,
***************
*** 618,624 ****
  	if (avpi_tree !=NULL) {
  	  /* Command Code */
  	  proto_tree_add_uint_format(avpi_tree, hf_diameter_avp_code,
! 						  tvb, offset, 4, avph.avp_code, "AVP Code: %s", avpNameString);
  	  offset += 4;
  		
  	  tf = proto_tree_add_uint_format(avpi_tree, hf_diameter_avp_flags, tvb,
--- 1341,1347 ----
  	if (avpi_tree !=NULL) {
  	  /* Command Code */
  	  proto_tree_add_uint_format(avpi_tree, hf_diameter_avp_code,
! 								 tvb, offset, 4, avph.avp_code, "AVP Code: %s", avpNameString);
  	  offset += 4;
  		
  	  tf = proto_tree_add_uint_format(avpi_tree, hf_diameter_avp_flags, tvb,
***************
*** 775,780 ****
--- 1498,1533 ----
  									 "Value: 0x%08x (%u): %s", data, data, valstr);
  		}
  		break;
+ 	  case DIAMETER_VENDOR_ID:
+ 		{
+ 		  guint32 data;
+ 		  
+ 		  memcpy(&data, dataBuffer, 4);
+ 		  data = ntohl(data);
+ 		  valstr = diameter_vendor_to_str(data);
+ 		  proto_tree_add_uint_format(avpi_tree, hf_diameter_avp_data_uint32,
+ 									 tvb, offset, avpDataLength, data,
+ 									 "%s (0x%08x)", valstr, data);
+ 		}
+ 		break;
+ 	  case DIAMETER_APPLICATION_ID:
+ 		{
+ 		  guint32 data;
+ 		  
+ 		  memcpy(&data, dataBuffer, 4);
+ 		  data = ntohl(data);
+ 		  valstr = diameter_app_to_str(data);
+ 		  proto_tree_add_uint_format(avpi_tree, hf_diameter_avp_data_uint32,
+ 									 tvb, offset, avpDataLength, data,
+ 									 "%s (0x%08x)", valstr, data);
+ 		}
+ 		break;
+ 	  case DIAMETER_MIP_REG_REQ:
+ 
+ 		/* Make a new tvb */
+ 		safe_dissect_mip(tvb, pinfo, avpi_tree, offset, avpDataLength);
+ 		break;
+ 
  	  default:
  	  case DIAMETER_OCTET_STRING:
  		proto_tree_add_bytes_format(avpi_tree, hf_diameter_avp_data_bytes,
***************
*** 794,829 ****
  void
  proto_reg_handoff_diameter(void)
  {
! 	static int Initialized=FALSE;
! 	static int TcpPort=0;
! 	static int SctpPort=0;
! 
! 	if (Initialized) {
! 		dissector_delete("tcp.port", TcpPort, dissect_diameter);
! 		dissector_delete("sctp.port", SctpPort, dissect_diameter);
! 	} else {
! 		Initialized=TRUE;
! 	}
! 
! 	/* set port for future deletes */
! 	TcpPort=gbl_diameterTcpPort;
! 	SctpPort=gbl_diameterSctpPort;
! 
! 	strcpy(gbl_diameterString, "Diameter Protocol");
  
!         /* g_warning ("Diameter: Adding tcp dissector to port %d",
! 		gbl_diameterTcpPort); */
! 	dissector_add("tcp.port", gbl_diameterTcpPort, dissect_diameter,
! 	    proto_diameter);
! 	dissector_add("sctp.port", gbl_diameterSctpPort,
! 	    dissect_diameter, proto_diameter);
  }
  
  /* registration with the filtering engine */
  void
  proto_register_diameter(void)
  {
- 
  	static hf_register_info hf[] = {
  		{ &hf_diameter_version,
  		  { "Version", "diameter.version", FT_UINT8, BASE_HEX, NULL, 0x00,
--- 1547,1581 ----
  void
  proto_reg_handoff_diameter(void)
  {
!   static int Initialized=FALSE;
!   static int TcpPort=0;
!   static int SctpPort=0;
! 
!   if (Initialized) {
! 	dissector_delete("tcp.port", TcpPort, dissect_diameter);
! 	dissector_delete("sctp.port", SctpPort, dissect_diameter);
!   } else {
! 	Initialized=TRUE;
!   }
  
!   /* set port for future deletes */
!   TcpPort=gbl_diameterTcpPort;
!   SctpPort=gbl_diameterSctpPort;
! 
!   strcpy(gbl_diameterString, "Diameter Protocol");
! 
!   /* g_warning ("Diameter: Adding tcp dissector to port %d",
! 	 gbl_diameterTcpPort); */
!   dissector_add("tcp.port", gbl_diameterTcpPort, dissect_diameter,
! 				proto_diameter);
!   dissector_add("sctp.port", gbl_diameterSctpPort,
! 				dissect_diameter, proto_diameter);
  }
  
  /* registration with the filtering engine */
  void
  proto_register_diameter(void)
  {
  	static hf_register_info hf[] = {
  		{ &hf_diameter_version,
  		  { "Version", "diameter.version", FT_UINT8, BASE_HEX, NULL, 0x00,
***************
*** 831,864 ****
  		{ &hf_diameter_length,
  		  { "Length","diameter.length", FT_UINT24, BASE_DEC, NULL, 0x0,
  		    "", HFILL }},
! 
  		{ &hf_diameter_flags,
  		  { "Flags", "diameter.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
  		    "", HFILL }},
  		{ &hf_diameter_flags_request,
! 		{ "Request", "diameter.flags.request", FT_BOOLEAN, 8, TFS(&flags_set_truth), DIAM_FLAGS_R,
  			"", HFILL }},
  		{ &hf_diameter_flags_proxyable,
! 		{ "Proxyable", "diameter.flags.proxyable", FT_BOOLEAN, 8, TFS(&flags_set_truth), DIAM_FLAGS_P,
  			"", HFILL }},
  		{ &hf_diameter_flags_error,
! 		{ "Error","diameter.flags.error", FT_BOOLEAN, 8, TFS(&flags_set_truth), DIAM_FLAGS_E,
  			"", HFILL }},
  		{ &hf_diameter_flags_reserved3,
! 		{ "Reserved","diameter.flags.reserved3", FT_BOOLEAN, 8, TFS(&reserved_set),
! 		  DIAM_FLAGS_RESERVED3, "", HFILL }},
  		{ &hf_diameter_flags_reserved4,
! 		{ "Reserved","diameter.flags.reserved4", FT_BOOLEAN, 8, TFS(&reserved_set),
! 		  DIAM_FLAGS_RESERVED4, "", HFILL }},
  		{ &hf_diameter_flags_reserved5,
! 		{ "Reserved","diameter.flags.reserved5", FT_BOOLEAN, 8, TFS(&reserved_set),
! 		  DIAM_FLAGS_RESERVED5, "", HFILL }},
  		{ &hf_diameter_flags_reserved6,
! 		{ "Reserved","diameter.flags.reserved6", FT_BOOLEAN, 8, TFS(&reserved_set),
! 		  DIAM_FLAGS_RESERVED6, "", HFILL }},
  		{ &hf_diameter_flags_reserved7,
! 		{ "Reserved","diameter.flags.reserved7", FT_BOOLEAN, 8, TFS(&reserved_set),
! 		  DIAM_FLAGS_RESERVED7, "", HFILL }},
  
  		{ &hf_diameter_code,
  		  { "Command Code","diameter.code", FT_UINT24, BASE_DEC,
--- 1583,1616 ----
  		{ &hf_diameter_length,
  		  { "Length","diameter.length", FT_UINT24, BASE_DEC, NULL, 0x0,
  		    "", HFILL }},
! 		
  		{ &hf_diameter_flags,
  		  { "Flags", "diameter.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
  		    "", HFILL }},
  		{ &hf_diameter_flags_request,
! 		  { "Request", "diameter.flags.request", FT_BOOLEAN, 8, TFS(&flags_set_truth), DIAM_FLAGS_R,
  			"", HFILL }},
  		{ &hf_diameter_flags_proxyable,
! 		  { "Proxyable", "diameter.flags.proxyable", FT_BOOLEAN, 8, TFS(&flags_set_truth), DIAM_FLAGS_P,
  			"", HFILL }},
  		{ &hf_diameter_flags_error,
! 		  { "Error","diameter.flags.error", FT_BOOLEAN, 8, TFS(&flags_set_truth), DIAM_FLAGS_E,
  			"", HFILL }},
  		{ &hf_diameter_flags_reserved3,
! 		  { "Reserved","diameter.flags.reserved3", FT_BOOLEAN, 8, TFS(&reserved_set),
! 			DIAM_FLAGS_RESERVED3, "", HFILL }},
  		{ &hf_diameter_flags_reserved4,
! 		  { "Reserved","diameter.flags.reserved4", FT_BOOLEAN, 8, TFS(&reserved_set),
! 			DIAM_FLAGS_RESERVED4, "", HFILL }},
  		{ &hf_diameter_flags_reserved5,
! 		  { "Reserved","diameter.flags.reserved5", FT_BOOLEAN, 8, TFS(&reserved_set),
! 			DIAM_FLAGS_RESERVED5, "", HFILL }},
  		{ &hf_diameter_flags_reserved6,
! 		  { "Reserved","diameter.flags.reserved6", FT_BOOLEAN, 8, TFS(&reserved_set),
! 			DIAM_FLAGS_RESERVED6, "", HFILL }},
  		{ &hf_diameter_flags_reserved7,
! 		  { "Reserved","diameter.flags.reserved7", FT_BOOLEAN, 8, TFS(&reserved_set),
! 			DIAM_FLAGS_RESERVED7, "", HFILL }},
  
  		{ &hf_diameter_code,
  		  { "Command Code","diameter.code", FT_UINT24, BASE_DEC,
***************
*** 872,878 ****
  		{ &hf_diameter_endtoendid,
  		  { "End-to-End Identifier", "diameter.endtoendid", FT_UINT32, 
  		    BASE_HEX, NULL, 0x0, "", HFILL }},
! 
  		{ &hf_diameter_avp_code,
  		  { "AVP Code","diameter.avp.code", FT_UINT32, BASE_DEC,
  		    NULL, 0x0, "", HFILL }},
--- 1624,1630 ----
  		{ &hf_diameter_endtoendid,
  		  { "End-to-End Identifier", "diameter.endtoendid", FT_UINT32, 
  		    BASE_HEX, NULL, 0x0, "", HFILL }},
! 		
  		{ &hf_diameter_avp_code,
  		  { "AVP Code","diameter.avp.code", FT_UINT32, BASE_DEC,
  		    NULL, 0x0, "", HFILL }},
***************
*** 885,913 ****
  		  { "AVP Flags","diameter.avp.flags", FT_UINT8, BASE_HEX,
  		    NULL, 0x0, "", HFILL }},
  		{ &hf_diameter_avp_flags_vendor_specific,
! 		{ "Vendor-Specific", "diameter.flags.vendorspecific", FT_BOOLEAN, 8, TFS(&flags_set_truth), AVP_FLAGS_V,
  			"", HFILL }},
  		{ &hf_diameter_avp_flags_mandatory,
! 		{ "Mandatory", "diameter.flags.mandatory", FT_BOOLEAN, 8, TFS(&flags_set_truth), AVP_FLAGS_M,
  			"", HFILL }},
  		{ &hf_diameter_avp_flags_protected,
! 		{ "Protected","diameter.avp.flags.protected", FT_BOOLEAN, 8, TFS(&flags_set_truth), AVP_FLAGS_P,
  			"", HFILL }},
  		{ &hf_diameter_avp_flags_reserved3,
! 		{ "Reserved","diameter.avp.flags.reserved3", FT_BOOLEAN, 8, TFS(&reserved_set),
! 		  AVP_FLAGS_RESERVED3,	"", HFILL }},
  		{ &hf_diameter_avp_flags_reserved4,
! 		{ "Reserved","diameter.avp.flags.reserved4", FT_BOOLEAN, 8, TFS(&reserved_set),
! 		  AVP_FLAGS_RESERVED4,	"", HFILL }},
  		{ &hf_diameter_avp_flags_reserved5,
! 		{ "Reserved","diameter.avp.flags.reserved5", FT_BOOLEAN, 8, TFS(&reserved_set),
! 		  AVP_FLAGS_RESERVED5,	"", HFILL }},
  		{ &hf_diameter_avp_flags_reserved6,
! 		{ "Reserved","diameter.avp.flags.reserved6", FT_BOOLEAN, 8, TFS(&reserved_set),
! 		  AVP_FLAGS_RESERVED6,	"", HFILL }},
  		{ &hf_diameter_avp_flags_reserved7,
! 		{ "Reserved","diameter.avp.flags.reserved7", FT_BOOLEAN, 8, TFS(&reserved_set),
! 		  AVP_FLAGS_RESERVED7,	"", HFILL }},
  		{ &hf_diameter_avp_vendor_id,
  		  { "AVP Vendor Id","diameter.avp.vendorId", FT_UINT32, BASE_DEC,
  		    NULL, 0x0, "", HFILL }},
--- 1637,1665 ----
  		  { "AVP Flags","diameter.avp.flags", FT_UINT8, BASE_HEX,
  		    NULL, 0x0, "", HFILL }},
  		{ &hf_diameter_avp_flags_vendor_specific,
! 		  { "Vendor-Specific", "diameter.flags.vendorspecific", FT_BOOLEAN, 8, TFS(&flags_set_truth), AVP_FLAGS_V,
  			"", HFILL }},
  		{ &hf_diameter_avp_flags_mandatory,
! 		  { "Mandatory", "diameter.flags.mandatory", FT_BOOLEAN, 8, TFS(&flags_set_truth), AVP_FLAGS_M,
  			"", HFILL }},
  		{ &hf_diameter_avp_flags_protected,
! 		  { "Protected","diameter.avp.flags.protected", FT_BOOLEAN, 8, TFS(&flags_set_truth), AVP_FLAGS_P,
  			"", HFILL }},
  		{ &hf_diameter_avp_flags_reserved3,
! 		  { "Reserved","diameter.avp.flags.reserved3", FT_BOOLEAN, 8, TFS(&reserved_set),
! 			AVP_FLAGS_RESERVED3,	"", HFILL }},
  		{ &hf_diameter_avp_flags_reserved4,
! 		  { "Reserved","diameter.avp.flags.reserved4", FT_BOOLEAN, 8, TFS(&reserved_set),
! 			AVP_FLAGS_RESERVED4,	"", HFILL }},
  		{ &hf_diameter_avp_flags_reserved5,
! 		  { "Reserved","diameter.avp.flags.reserved5", FT_BOOLEAN, 8, TFS(&reserved_set),
! 			AVP_FLAGS_RESERVED5,	"", HFILL }},
  		{ &hf_diameter_avp_flags_reserved6,
! 		  { "Reserved","diameter.avp.flags.reserved6", FT_BOOLEAN, 8, TFS(&reserved_set),
! 			AVP_FLAGS_RESERVED6,	"", HFILL }},
  		{ &hf_diameter_avp_flags_reserved7,
! 		  { "Reserved","diameter.avp.flags.reserved7", FT_BOOLEAN, 8, TFS(&reserved_set),
! 			AVP_FLAGS_RESERVED7,	"", HFILL }},
  		{ &hf_diameter_avp_vendor_id,
  		  { "AVP Vendor Id","diameter.avp.vendorId", FT_UINT32, BASE_DEC,
  		    NULL, 0x0, "", HFILL }},
***************
*** 926,932 ****
  		{ &hf_diameter_avp_data_bytes,
  		  { "AVP Data","diameter.avp.data.bytes", FT_BYTES, BASE_NONE,
  		    NULL, 0x0, "", HFILL }},
! 
  		{ &hf_diameter_avp_data_string,
  		  { "AVP Data","diameter.avp.data.string", FT_STRING, BASE_NONE,
  		    NULL, 0x0, "", HFILL }},
--- 1678,1684 ----
  		{ &hf_diameter_avp_data_bytes,
  		  { "AVP Data","diameter.avp.data.bytes", FT_BYTES, BASE_NONE,
  		    NULL, 0x0, "", HFILL }},
! 		
  		{ &hf_diameter_avp_data_string,
  		  { "AVP Data","diameter.avp.data.string", FT_STRING, BASE_NONE,
  		    NULL, 0x0, "", HFILL }},
***************
*** 951,971 ****
  	module_t *diameter_module;
  
  	proto_diameter = proto_register_protocol (gbl_diameterString,
! 	    "DIAMETER", "diameter");
  	proto_register_field_array(proto_diameter, hf, array_length(hf));
  	proto_register_subtree_array(ett, array_length(ett));
  
  	/* Register a configuration option for port */
  	diameter_module = prefs_register_protocol(proto_diameter,
! 	    proto_reg_handoff_diameter);
  	prefs_register_uint_preference(diameter_module, "tcp.port",
! 				       "DIAMETER TCP Port",
! 				       "Set the TCP port for DIAMETER messages",
! 				       10,
! 				       &gbl_diameterTcpPort);
  	prefs_register_uint_preference(diameter_module, "sctp.port",
! 				       "DIAMETER SCTP Port",
! 				       "Set the SCTP port for DIAMETER messages",
! 				       10,
! 				       &gbl_diameterSctpPort);
! }
--- 1703,1738 ----
  	module_t *diameter_module;
  
  	proto_diameter = proto_register_protocol (gbl_diameterString,
! 											  "Diameter", "diameter");
  	proto_register_field_array(proto_diameter, hf, array_length(hf));
  	proto_register_subtree_array(ett, array_length(ett));
  
  	/* Register a configuration option for port */
  	diameter_module = prefs_register_protocol(proto_diameter,
! 											  proto_reg_handoff_diameter);
  	prefs_register_uint_preference(diameter_module, "tcp.port",
! 								   "Diameter TCP Port",
! 								   "Set the TCP port for Diameter messages",
! 								   10,
! 								   &gbl_diameterTcpPort);
  	prefs_register_uint_preference(diameter_module, "sctp.port",
! 								   "Diameter SCTP Port",
! 								   "Set the SCTP port for Diameter messages",
! 								   10,
! 								   &gbl_diameterSctpPort);
! 	/*
! 	 * Build our default dictionary filename
! 	 */
! 	if (! gbl_diameterDictionary) {
! 		gbl_diameterDictionary = (gchar *) g_malloc(strlen(get_datafile_dir()) +
! 													1 + strlen(DICT_FN) + 1); /* slash + fn + null */
! 		sprintf(gbl_diameterDictionary, "%s" G_DIR_SEPARATOR_S "%s",
! 				get_datafile_dir(), DICT_FN );
! 	}
! 	/* Now register it's preferences so it can be changed. */
! 	prefs_register_string_preference(diameter_module, "dictionary.name",
! 									 "Diameter XML Dictionary",
! 									 "Set the dictionary used for Diameter messages",
! 									 &gbl_diameterDictionary);
! 
! } /* proto_register_diameter */
Index: packet-mip.c
===================================================================
RCS file: /cvsroot/ethereal/packet-mip.c,v
retrieving revision 1.19
diff -c -r1.19 packet-mip.c
*** packet-mip.c	2001/09/14 07:10:05	1.19
--- packet-mip.c	2001/10/30 04:13:30
***************
*** 386,391 ****
--- 386,394 ----
  /* Register the protocol name and description */
  	proto_mip = proto_register_protocol("Mobile IP", "Mobile IP", "mip");
  
+ /* Register the dissector */
+ 	register_dissector("mip", dissect_mip, proto_mip);
+ 
  /* Required function calls to register the header fields and subtrees used */
  	proto_register_field_array(proto_mip, hf, array_length(hf));
  	proto_register_subtree_array(ett, array_length(ett));

Attachment: diammip1.gz
Description: application/gunzip

<?xml version="1.0" encoding="UTF-8"?>
<!--
   $Log: dictionary.dtd,v $
   Revision 1.1  2001/08/24 18:04:44  chaos
   Added per Mark's request

   Revision 1.3  2001/07/31 17:43:36  chaos
   Oops, forgot to turn on validity checking.  Fixed some errors found with validity checking turned on

   Revision 1.2  2001/07/31 16:56:15  chaos
   Lots of changes to support flags like in the draft, and to support commands

-->
<!ELEMENT dictionary (base, application*)>
<!ELEMENT base (command*, vendor*, typedefn+, avp+)>
<!ATTLIST base 
	uri CDATA #IMPLIED
>

<!ELEMENT application (command*, vendor*, typedefn*, avp*)>
<!ATTLIST application
	id CDATA #REQUIRED
	name CDATA #IMPLIED
	uri CDATA #IMPLIED
>
<!ELEMENT command (#PCDATA)>
<!ATTLIST command
	name CDATA #REQUIRED
	code CDATA #REQUIRED
	vendor-id IDREF #IMPLIED
>
<!ELEMENT vendor EMPTY>
<!ATTLIST vendor
	vendor-id ID #REQUIRED
	code CDATA #REQUIRED
	name CDATA #IMPLIED
>
<!ELEMENT typedefn EMPTY>
<!ATTLIST typedefn
	type-name ID #REQUIRED
	type-parent IDREF #IMPLIED
	description CDATA #IMPLIED
>
<!ELEMENT avp ((type | grouped), (enum*))>
<!ATTLIST avp
	name ID #REQUIRED
	description CDATA #IMPLIED
	code CDATA #REQUIRED
	may-encrypt (yes | no) "yes"
	mandatory (must | may | mustnot | shouldnot) "may"
	protected (must | may | mustnot | shouldnot) "may"
	vendor-bit (must | may | mustnot | shouldnot) "mustnot"
	vendor-id IDREF #IMPLIED
	constrained (true | false) "false"
>
<!ELEMENT type EMPTY>
<!ATTLIST type
	type-name IDREF #REQUIRED
>
<!ELEMENT grouped (gavp+)>
<!ELEMENT gavp EMPTY>
<!ATTLIST gavp
	name IDREF #REQUIRED
>
<!ELEMENT enum EMPTY>
<!ATTLIST enum
	name CDATA #REQUIRED
	code CDATA #REQUIRED
>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dictionary SYSTEM "dictionary.dtd" [
	<!ENTITY nasreq SYSTEM "nasreq.xml">
	<!ENTITY mobileipv4 SYSTEM "mobileipv4.xml">
	<!ENTITY sunping SYSTEM "sunping.xml">
]>
<dictionary>
	<base uri="ftp://ftp.ietf.org/internet-drafts/draft-ietf-aaa-diameter-07.txt";>
		<!--
  $Log: dictionary.xml,v $
  Revision 1.7  2001/08/24 18:03:24  chaos
  Mark's Changes

  Revision 1.6  2001/07/31 19:13:55  chaos
  Missed a couple of MIP AVPs

  Revision 1.5  2001/07/31 19:09:22  chaos
  Added Mobile-Ip and Sun Ping Extension

  Revision 1.4  2001/07/31 17:43:25  chaos
  Oops, forgot to turn on validity checking.  Fixed some errors found with validity checking turned on

  Revision 1.3  2001/07/31 16:56:31  chaos
  Added commands, and validated with xmllint

  Revision 1.2  2001/07/31 16:29:34  chaos
  Checking in some changes to verify log and ident strings

-->
		<!-- *********************** Commands ***************************** -->
		<!-- Diameter Base Protocol Command Codes -->
		<command name="Abort-Session" code="274" vendor-id="None">
			<!-- Maybe some avp stuff here one day -->
		</command>
		<command name="Accounting" code="271" vendor-id="None"/>
		<command name="Capabilities-Exchange" code="257" vendor-id="None"/>
		<command name="Device-Watchdog" code="280" vendor-id="None"/>
		<command name="Disconnect-Peer" code="282" vendor-id="None"/>
		<command name="Re-Auth" code="258" vendor-id="None"/>
		<command name="Session-Termination" code="275" vendor-id="None"/>
		<!-- ********************** End Commands ************************** -->

		<!-- ************************* Vendors **************************** -->
		<vendor vendor-id="None" code="0" name="None"/>
		<vendor vendor-id="Merit" code="61" name="Merit Networks"/>
		<vendor vendor-id="Sun" code="42" name="Sun Microsystems, Inc."/>
		<vendor vendor-id="USR" code="429" name="US Robotics Corp."/>
		<!-- *********************** End Vendors ************************** -->

		<!-- ************************ typedefn's ************************** -->
		<typedefn type-name="OctetString"/>
		<!--
         The data contains arbitrary data of variable length. Unless
         otherwise noted, the AVP Length field MUST be set to at least 9
         (13 if the 'V' bit is enabled).  Data used to transmit (human
         readable) character string data uses the UTF-8 [24] character
         set and is NOT NULL-terminated. The minimum Length field MUST
         be 9, but can be set to any value up to 65504 bytes. AVP Values
         of this type that do not align on a 32-bit boundary MUST have
         the necessary padding.
	 -->
		<typedefn type-name="UTF8String" type-parent="OctetString"/>
		<!--
         The UTF8String format is derived from the OctetString AVP Base
         Format. This is a human readable string represented using the
         ISO/IEC IS 10646-1 character set, encoded as an OctetString
         using the UTF-8 [29] transformation format described in RFC
         2279.

         Since additional code points are added by amendments to the
         10646 standard from time to time, implementations MUST be
         prepared to encounter any code point from 0x00000001 to
         0x7fffffff. Byte sequences that do not correspond to the valid
         UTF-8 encoding of a code point or are outside this range are
         prohibited. Note that since a code point of 0x00000000 is
         prohibited, no octet will contain a value of 0x00.

         The use of control codes SHOULD be avoided. When it is
         necessary to represent a newline, the control code sequence CR
         LF SHOULD be used.

         The use of leading or trailing white space SHOULD be avoided.

         For code points not directly supported by user interface
         hardware or software, an alternative means of entry and
         display, such as hexadecimal, MAY be provided.

         For information encoded in 7-bit US-ASCII, the UTF-8 encoding
         is identical to the US-ASCII encoding.

         UTF-8 may require multiple bytes to represent a single
         character / code point; thus the length of a UTF8String in
         octets may be different from the number of characters encoded.

         Note that the size of an UTF8String is measured in octets, not
         characters.

         The UTF8String MUST not contain any octets with a value of
         zero.
        -->
		<typedefn type-name="IPAddress" type-parent="OctetString"/>
		<!--
         The IPAddress format is derived from the OctetString AVP Base
         Format. It represents 32 bit (IPv4) [17] or 128 bit (IPv6) [16]
         address, most significant octet first. The format of the
         address (IPv4 or IPv6) is determined by the length. If the
         attribute value is an IPv4 address, the AVP Length field MUST
         be 12 (16 if 'V' bit is enabled), otherwise the AVP Length
         field MUST be set to 24 (28 if the 'V' bit is enabled) for IPv6
         addresses.
	 -->
		<typedefn type-name="DiameterIdentity" type-parent="OctetString"/>
		<!--
         The DiameterIdentity format is derived from the OctetString AVP
         Base Format.  It uses the UTF-8 encoding and has the same
         requirements as the UTF8String.  In addition, it must follow
         the Uniform Resource Identifiers (URI) syntax [29] rules
         specified below:

            Diameter-Identity  = fqdn [ port ] [ transport ]
                                 [ protocol ]

            aaa-protocol       = ( "diameter" | "radius" | "tacacs+" )

            protocol           = ";protocol=" aaa-protocol
                                 ; If absent, the default AAA protocol
                                 ; is diameter.

            fqdn               = Fully Qualified Host Name

            port               = ":" 1*DIGIT
                                 ; One of the ports used to listen for
                                 ; incoming connections. ; If absent,
                                 ; the default Diameter port (TBD) is
                                 ; assumed.

            transport-protocol = ( "tcp" | "sctp" | "udp" )

            transport          = ";transport=" transport-protocol

                                 ; One of the transports used to listen
                                 ; for incoming connections. If absent,
                                 ; the default SCTP [26] protocol is
                                 ; assumed. UDP MUST NOT be used when
                                 ; the aaa-protocol field is set to
                                 ; diameter.

            The following are examples of valid Diameter host
            identities:

               host.abc.com;transport=tcp
               host.abc.com:6666;transport=tcp
               aaa://host.abc.com;protocol=diameter
               aaa://host.abc.com:6666;protocol=diameter
               aaa://host.abc.com:6666;transport=tcp;protocol=diameter
               aaa://host.abc.com:1813;transport=udp;protocol=radius

         Since multiple Diameter processes on a single host cannot
         listen for incoming connections on the same port on a given
         protocol, the DiameterIdentity is guaranteed to be unique per
         host.

         A Diameter node MAY advertise different identities on each
         connection, via the CER and CEA's Origin-Host AVP, but the same
         identity MUST be used throughout the duration of a connection.

         When comparing AVPs of this format, it is necessary to add any
         absent fields with the default values prior to the comparison.
         For example, diameter-host.abc.com would be expanded to
         aaa://diameter/diameter-host.abc.com:TBD;protocol=sctp.
        -->
		<typedefn type-name="IPFilterRule" type-parent="OctetString"/>
		<!--
         The IPFilterRule format is derived from the OctetString AVP
         Base Format.  It uses the UTF-8 encoding and has the same
         requirements as the UTF8String. Packets may be filtered based
         on the following information that is associated with it:

            Direction                          (in or out)
            Source and destination IP address  (possibly masked)
            Protocol
            Source and destination port        (lists or ranges)
            TCP flags
            IP fragment flag
            IP options
            ICMP types

         Rules for the appropriate direction are evaluated in order,
         with the first matched rule terminating the evaluation.  Each
         packet is evaluated once. If no rule matches, the packet is
         dropped if the last rule evaluated was a permit, and passed if
         the last rule was a deny.

         IPFilterRule filters MUST follow the format:

            action dir proto from src to dst [options]

            action       permit - Allow packets that match the rule.
                         deny   - Drop packets that match the rule.

            dir          "in" is from the terminal, "out" is to the
                         terminal.

            proto        An IP protocol specified by number.  The "ip"
                         keyword means any protocol will match.

            src and dst  <address/mask> [ports]

                         The <address/mask> may be specified as:
                         ipno       An IPv4 or IPv6 number in dotted-
                                    quad or canonical IPv6 form. Only
                                    this exact IP number will match the
                                    rule.
                         ipno/bits  An IP number as above with a mask
                                    width of the form 1.2.3.4/24.  In
                                    this case all IP numbers from
                                    1.2.3.0 to 1.2.3.255 will match.
                                    The bit width MUST be valid for the
                                    IP version and the IP number MUST
                                    NOT have bits set beyond the mask.

                         The sense of the match can be inverted by
                         preceding an address with the not modifier,
                         causing all other addresses to be matched
                         instead.  This does not affect the selection of
                         port numbers.

                            The keyword "any" is 0.0.0.0/0 or the IPv6
                            equivalent.  The keyword "assigned" is the
                            address or set of addresses assigned to the
                            terminal.  The first rule SHOULD be "deny in
                            ip !assigned".

                         With the TCP, UDP and SCTP protocols, optional
                         ports may be specified as:

                            {port|port-port}[,port[,...]]

                         The `-' notation specifies a range of ports
                         (including boundaries).

                         Fragmented packets which have a non-zero offset
                         (i.e. not the first fragment) will never match
                         a rule which has one or more port
                         specifications.  See the frag option for
                         details on matching fragmented packets.

            options:
               frag    Match if the packet is a fragment and this is not
                       the first fragment of the datagram.  frag may not
                       be used in conjunction with either tcpflags or
                       TCP/UDP port specifications.

               ipoptions spec
                       Match if the IP header contains the comma
                       separated list of options specified in spec. The
                       supported IP options are:

                       ssrr (strict source route), lsrr (loose source
                       route), rr (record packet route) and ts
                       (timestamp). The absence of a particular option
                       may be denoted with a `!'.

               tcpoptions spec
                       Match if the TCP header contains the comma
                       separated list of options specified in spec. The
                       supported TCP options are:

                       mss (maximum segment size), window (tcp window
                       advertisement), sack (selective ack), ts (rfc1323
                       timestamp) and cc (rfc1644 t/tcp connection
                       count).  The absence of a particular option may
                       be denoted with a `!'.

               established
                       TCP packets only. Match packets that have the RST
                       or ACK bits set.

               setup   TCP packets only. Match packets that have the SYN
                       bit set but no ACK bit.

               tcpflags spec
                       TCP packets only. Match if the TCP header
                       contains the comma separated list of flags
                       specified in spec. The supported TCP flags are:

                       fin, syn, rst, psh, ack and urg. The absence of a
                       particular flag may be denoted with a `!'. A rule
                       which contains a tcpflags specification can never
                       match a fragmented packet which has a non-zero
                       offset.  See the frag option for details on
                       matching fragmented packets.

               icmptypes types
                       ICMP packets only.  Match if the ICMP type is in
                       the list types. The list may be specified as any
                       combination of ranges or individual types
                       separated by commas.  The supported ICMP types
                       are:

                       echo reply (0), destination unreachable (3),
                       source quench (4), redirect (5), echo request
                       (8), router advertisement (9), router
                       solicitation (10), time-to-live exceeded (11), IP
                       header bad (12), timestamp request (13),
                       timestamp reply (14), information request (15),
                       information reply (16), address mask request (17)
                       and address mask reply (18).

         There is one kind of packet that the access device MUST always
         discard, that is an IP fragment with a fragment offset of one.
         This is a valid packet, but it only has one use, to try to
         circumvent firewalls.

            An access device that is unable to interpret or apply a deny
            rule MUST terminate the session.  An access device that is
            unable to interpret or apply a permit rule MAY apply a more
            restrictive rule.  An access device MAY apply deny rules of
            its own before the supplied rules, for example to protect
            the access device owner's infrastructure.

         The rule syntax is a modified subset of ipfw(8) from FreeBSD,
         and the ipfw.c code may provide a useful base for
         implementations.
        -->
		<typedefn type-name="QOSFilterRule" type-parent="OctetString"/>
		<!--
         The QosFilterRule format is derived from the OctetString AVP
         Base Format.  It uses the UTF-8 encoding and has the same
         requirements as the UTF8String. Packets may be marked or
         metered based on the following information that is associated
         with it:

            Direction                          (in or out)
            Source and destination IP address  (possibly masked)
            Protocol
            Source and destination port        (lists or ranges)
            DSCP values                        (no mask or range)

         Rules for the appropriate direction are evaluated in order,
         with the first matched rule terminating the evaluation.  Each
         packet is evaluated once. If no rule matches, the packet is
         treated as best effort.

         QoSFilterRule filters MUST follow the format:

            action dir proto from src to dst [options]

                         tag    - Mark packet with a specific DSCP [49].
                                  The DSCP option MUST be included.

                         meter  - Meter traffic. The metering options
                                  MUST be included.

            dir          "in" is from the terminal, "out" is to the
                         terminal.

            proto        An IP protocol specified by number.  The "ip"
                         keyword means any protocol will match.

            src and dst  <address/mask> [ports]

                         The <address/mask> may be specified as:
                         ipno       An IPv4 or IPv6 number in dotted-
                                    quad or canonical IPv6 form. Only
                                    this exact IP number will match the
                                    rule.
                         ipno/bits  An IP number as above with a mask
                                    width of the form 1.2.3.4/24.  In
                                    this case all IP numbers from
                                    1.2.3.0 to 1.2.3.255 will match.
                                    The bit width MUST be valid for the
                                    IP version and the IP number MUST
                                    NOT have bits set beyond the mask.

                         The sense of the match can be inverted by
                         preceding an address with the not modifier,
                         causing all other addresses to be matched
                         instead.  This does not affect the selection of
                         port numbers.

                            The keyword "any" is 0.0.0.0/0 or the IPv6
                            equivalent.  The keyword "assigned" is the
                            address or set of addresses assigned to the
                            terminal.  The first rule SHOULD be "deny in
                            ip !assigned".

                         With the TCP, UDP and SCTP protocols, optional
                         ports may be specified as:

                            {port|port-port}[,port[,...]]

                         The `-' notation specifies a range of ports
                         (including boundaries).

            options:

               DSCP <color>
                       color values as defined in [49]. Exact matching
                       of DSCP values is required (no masks or ranges).
                       the "deny" can replace the color_under or
                       color_over values in the meter action for rate-
                       dependent packet drop.

               metering <rate> <color_under> <color_over>
                       The metering option provides Assured Forwarding,
                       as defined in [50], and MUST be present if the
                       action is set to meter. The rate option is the
                       throughput, in bits per second, which is used by
                       the access device to mark packets. Traffic above
                       the rate is marked with the color_over codepoint,
                       while traffic under the rate is marked with the
                       color_under codepoint. The color_under and
                       color_over options contain the drop preferences,
                       and MUST conform to the recommended codepoint
                       keywords described in [50] (e.g. AF13).

                       The metering option also supports the strict
                       limit on traffic required by Expedited
                       Forwarding, as defined in [51]. The color_over
                       option may contain the keyword "drop" to prevent
                       forwarding of traffic that exceeds the rate
                       parameter.

         The rule syntax is a modified subset of ipfw(8) from FreeBSD,
         and the ipfw.c code may provide a useful base for
         implementations.

        -->
		<typedefn type-name="MIPRegistrationRequest" type-parent="OctetString"/>

		<typedefn type-name="Integer32"/>
		<!--
         32 bit signed value, in network byte order. The AVP Length
         field MUST be set to 12 (16 if the 'V' bit is enabled).
	-->
		<typedefn type-name="VendorId" type-parent="Integer32"/>
		<typedefn type-name="AppId" type-parent="Integer32"/>
		<typedefn type-name="Integer64"/>
		<!--
         64 bit signed value, in network byte order. The AVP Length
         field MUST be set to 16 (20 if the 'V' bit is enabled).
        -->
		<typedefn type-name="Unsigned32"/>
		<!--
         32 bit unsigned value, in network byte order. The AVP Length
         field MUST be set to 12 (16 if the 'V' bit is enabled).
         Unsigned32 values used to transmit time data contains the four
         most significant octets returned from NTP [18], in network byte
         order.
	-->
		<typedefn type-name="Time"/>
		<!--
         The Time format is derived from the Unsigned32 AVP Base Format.
         This is 32 bit unsigned value containing the four most
         significant octets returned from NTP [18], in network byte
         order.

         This represent the number of seconds since 0h on 1 January 1900
         with respect to the Coordinated Universal Time (UTC).

         On 6h 28m 16s UTC, 7 February 2036 the time value will
         overflow.  NTP [18] describes a procedure to extend the time to
         2104.
        -->
		<typedefn type-name="Unsigned64"/>
		<!--
         64 bit unsigned value, in network byte order. The AVP Length
         field MUST be set to 16 (20 if the 'V' bit is enabled).
	-->
		<!-- ************************* End Typedefns ************************ -->
		<!-- ******************* DIAMETER BASE PROTOCOL AVPS ************************ -->
		<avp name="Accounting-Interim-Interval" code="482" mandatory="must" may-encrypt="yes" vendor-bit="mustnot">
			<type type-name="Unsigned32"/>
		</avp>
		<avp name="Accounting-Multi-Session-Id" code="50" mandatory="must" protected="may" may-encrypt="yes" vendor-bit="mustnot">
			<type type-name="Unsigned32"/>
		</avp>
		<avp name="Accounting-Record-Number" code="485" mandatory="must" may-encrypt="yes" vendor-bit="mustnot">
			<type type-name="Unsigned32"/>
		</avp>
		<avp name="Accounting-Record-Type" code="480" mandatory="must" may-encrypt="yes" vendor-bit="mustnot">
			<type type-name="Unsigned32"/>
			<enum name="Event Record" code="1"/>
			<enum name="Start Record" code="2"/>
			<enum name="Interim Record" code="3"/>
			<enum name="Stop Record" code="4"/>
		</avp>
		<avp name="Accounting-Session-Id" code="44" mandatory="must" protected="may" may-encrypt="yes" vendor-bit="mustnot">
			<type type-name="Unsigned32"/>
		</avp>
		<avp name="Acct-Application-Id" code="259" mandatory="must" protected="mustnot" may-encrypt="no" vendor-bit="mustnot">
			<type type-name="AppId"/>
		</avp>
		<avp name="Alternate-Peer" code="275" mandatory="must" protected="mustnot" may-encrypt="no" vendor-bit="mustnot">
			<type type-name="DiameterIdentity"/>
		</avp>
		<avp name="Auth-Application-Id" code="258" mandatory="must" protected="mustnot" may-encrypt="no" vendor-bit="mustnot">
			<type type-name="AppId"/>
		</avp>
		<avp name="Auth-Request-Type" code="274" mandatory="must" protected="mustnot" may-encrypt="no" vendor-bit="mustnot">
			<type type-name="Unsigned32"/>
			<enum name="Authenticate Only" code="1"/>
			<enum name="Authorize Only" code="2"/>
			<enum name="Authorize Authenticate" code="3"/>
		</avp>
		<avp name="Authorization-Lifetime" code="291" mandatory="must" may-encrypt="no" vendor-bit="mustnot">
			<type type-name="Integer32"/>
		</avp>
		<avp name="Auth-Grace-Period" code="276" mandatory="must" may-encrypt="no" vendor-bit="mustnot">
			<type type-name="Unsigned32"/>
		</avp>
		<avp name="Auth-Session-State" code="277" mandatory="must" may-encrypt="no" vendor-bit="mustnot">
			<type type-name="Unsigned32"/>
			<enum name="State Maintained" code="0"/>
			<enum name="No State Maintained" code="0"/>
		</avp>
		<avp name="Re-Auth-Request-Type" code="285" mandatory="must" may-encrypt="no" vendor-bit="mustnot">
			<type type-name="Unsigned32"/>
			<enum name="Authorize Only" code="0"/>
			<enum name="Authorize Authenticate" code="1"/>
		</avp>
		<avp name="Destination-Host" code="293" mandatory="must" protected="mustnot" may-encrypt="no" vendor-bit="mustnot">
			<type type-name="DiameterIdentity"/>
		</avp>
		<avp name="Destination-Realm" code="283" mandatory="must" protected="mustnot" may-encrypt="no" vendor-bit="mustnot">
			<type type-name="UTF8String"/>
		</avp>
		<avp name="Disconnect-Cause" code="273" mandatory="must" protected="mustnot" may-encrypt="no" vendor-bit="mustnot">
			<type type-name="Unsigned32"/>
			<enum name="Rebooting" code="0"/>
			<enum name="Busy" code="2"/>
			<enum name="Do not want to talk to you" code="2"/>
		</avp>
		<avp name="Error-Message" code="281" mandatory="must" protected="mustnot" may-encrypt="no" vendor-bit="mustnot">
			<type type-name="UTF8String"/>
		</avp>
		<avp name="Error-Reporting-Host" code="294" mandatory="must" protected="mustnot" may-encrypt="no" vendor-bit="mustnot">
			<type type-name="DiameterIdentity"/>
		</avp>
		<avp name="Failed-AVP" code="279" mandatory="must" may-encrypt="no" vendor-bit="mustnot">
			<type type-name="OctetString"/>
		</avp>
		<avp name="Firmware-Revision" code="267" mandatory="must" protected="mustnot" may-encrypt="no" vendor-bit="mustnot">
			<type type-name="Unsigned32"/>
		</avp>
		<avp name="Host-IP-Address" code="257" mandatory="must" protected="mustnot" may-encrypt="no" vendor-bit="mustnot">
			<type type-name="IPAddress"/>
		</avp>
		<avp name="Multi-Round-Time-Out" code="272" mandatory="must" may-encrypt="yes" vendor-bit="mustnot">
			<type type-name="Unsigned32"/>
		</avp>
		<avp name="Origin-Host" code="264" mandatory="must" may-encrypt="no" protected="mustnot" vendor-bit="mustnot">
			<type type-name="DiameterIdentity"/>
		</avp>
		<avp name="Origin-Realm" code="296" mandatory="must" may-encrypt="no" protected="mustnot" vendor-bit="mustnot">
			<type type-name="UTF8String"/>
		</avp>
		<avp name="Origin-State-Id" code="278" mandatory="must" protected="mustnot" vendor-bit="mustnot">
			<type type-name="Unsigned32"/>
		</avp>
		<avp name="Product-Name" code="269" mandatory="mustnot" may-encrypt="no" protected="mustnot" vendor-bit="mustnot">
			<type type-name="UTF8String"/>
		</avp>
		<avp name="Proxy-Host" code="280" mandatory="must" may-encrypt="no" protected="mustnot" vendor-bit="mustnot">
			<type type-name="DiameterIdentity"/>
		</avp>
		<avp name="Proxy-Info" code="284" mandatory="must" may-encrypt="no" protected="mustnot" vendor-bit="mustnot">
			<type type-name="OctetString"/>
		</avp>
		<avp name="Redirect-Host" code="292" mandatory="must" may-encrypt="no" protected="mustnot" vendor-bit="mustnot">
			<type type-name="DiameterIdentity"/>
		</avp>
		<avp name="Redirect-Host-Usage" code="261" mandatory="must" may-encrypt="no" protected="mustnot" vendor-bit="mustnot">
			<type type-name="Unsigned32"/>
			<enum name="Don't Care" code="0"/>
			<enum name="All Session" code="1"/>
			<enum name="All Realm" code="2"/>
			<enum name="Realm and Application" code="3"/>
			<enum name="All Application" code="4"/>
			<enum name="All Host" code="5"/>
		</avp>
		<avp name="Redirect-Max-Cache-Time" code="262" mandatory="must" may-encrypt="no" protected="mustnot" vendor-bit="mustnot">
			<type type-name="Unsigned32"/>
		</avp>
		<avp name="Result-Code" code="268" mandatory="must" may-encrypt="no" protected="mustnot" vendor-bit="mustnot">
			<type type-name="Unsigned32"/>
		</avp>
		<avp name="Route-Record" code="282" mandatory="must" may-encrypt="no" protected="mustnot" vendor-bit="mustnot">
			<type type-name="DiameterIdentity"/>
		</avp>
		<avp name="Session-Id" code="263" mandatory="must" protected="mustnot" vendor-bit="mustnot">
			<type type-name="UTF8String"/>
		</avp>
		<avp name="Session-Binding" code="270" mandatory="must" protected="mustnot" vendor-bit="mustnot">
			<type type-name="Unsigned32"/>
		</avp>
		<avp name="Session-Server-Failover" code="271" mandatory="must" protected="mustnot" vendor-bit="mustnot">
			<type type-name="Unsigned32"/>
			<enum name="Refuse Service" code="0"/>
			<enum name="Try Again" code="1"/>
			<enum name="Allow Service" code="2"/>
			<enum name="Try Again / Allow Service" code="3"/>
		</avp>
		<avp name="Source-Route" code="286" mandatory="must" may-encrypt="no" protected="mustnot" vendor-bit="mustnot">
			<type type-name="DiameterIdentity"/>
		</avp>
		<avp name="Supported-Vendor-Id" code="265" mandatory="must" may-encrypt="no" protected="mustnot" vendor-bit="mustnot">
			<type type-name="VendorId"/>
		</avp>
		<avp name="Termination-Cause" code="295" mandatory="must" may-encrypt="no" protected="mustnot" vendor-bit="mustnot">
			<type type-name="Unsigned32"/>
			<enum name="Logout" code="1"/>
			<enum name="Service Not Provided" code="2"/>
			<enum name="Bad Answer" code="3"/>
			<enum name="Administrative" code="4"/>
			<enum name="Link Broken" code="5"/>
		</avp>
		<avp name="Vendor-Id" code="266" mandatory="must" may-encrypt="no" protected="mustnot" vendor-bit="mustnot">
			<type type-name="VendorId"/>
		</avp>
		<avp name="Vendor-Specific-Application-Id" code="260" mandatory="must" may-encrypt="no" protected="mustnot" vendor-bit="mustnot">
			<grouped>
				<gavp name="Vendor-Id"/>
				<gavp name="Auth-Application-Id"/>
				<gavp name="Acct-Application-Id"/>
			</grouped>
		</avp>
		<avp name="Example-AVP" code="999999" mandatory="mustnot" vendor-bit="may">
			<grouped>
				<gavp name="Origin-Host"/>
				<gavp name="Host-IP-Address"/>
			</grouped>
		</avp>
		<!-- ************************ END DIAMETER BASE PROTOCOL AVPS ******************* -->
	</base>

	&nasreq;
	&mobileipv4;
	&sunping;
	
</dictionary>
<?xml version="1.0" encoding="UTF-8"?>

	<application id="4" name="Mobile IPv4 Application" uri="ftp://ftp.ietf.org/internet-drafts/draft-ietf-aaa-diameter-mobileip-07.txt";>

		<!-- Mobile-IPv4 Application -->
		<command name="AA-Mobile-Node" code="260" vendor-id="None"/>
		<command name="Home-Agent-MIP" code="262" vendor-id="None"/>

		<!-- ************************** Mobile-IPv4 AVPS ********************* -->
		<avp name="MIP-Filter-Rule" code="347" mandatory="must" vendor-bit="mustnot" may-encrypt="yes">
			<type type-name="IPFilterRule"/>
		</avp>
		<avp name="MIP-Auth-Input-Data-Length" code="338" mandatory="must" vendor-bit="mustnot" may-encrypt="yes">
			<type type-name="Unsigned32"/>
		</avp>
		<avp name="MIP-Authenticator-Length" code="339" mandatory="must" vendor-bit="mustnot" may-encrypt="yes">
			<type type-name="Unsigned32"/>
		</avp>
		<avp name="MIP-Authenticator-Offset" code="340" mandatory="must" vendor-bit="mustnot" may-encrypt="yes">
			<type type-name="Unsigned32"/>
		</avp>
		<avp name="MIP-FA-Challenge" code="344" mandatory="must" vendor-bit="mustnot" may-encrypt="yes">
			<type type-name="OctetString"/>
		</avp>
		<avp name="MIP-Feature-Vector" code="337" mandatory="must" vendor-bit="mustnot" may-encrypt="yes">
			<type type-name="Unsigned32"/>
		</avp>
		<avp name="MIP-Foreign-Agent-Host" code="330" mandatory="must" vendor-bit="mustnot" may-encrypt="yes">
			<type type-name="DiameterIdentity"/>
		</avp>
		<avp name="MIP-Home-Agent-Address" code="334" mandatory="must" vendor-bit="mustnot" may-encrypt="yes">
			<type type-name="IPAddress"/>
		</avp>
		<avp name="MIP-MN-AAA-Auth" code="322" mandatory="must" vendor-bit="mustnot" may-encrypt="yes">
			<grouped>
				<gavp name="MIP-MN-AAA-SPI"/>
				<gavp name="MIP-Auth-Input-Data-Length"/>
				<gavp name="MIP-Authenticator-Length"/>
				<gavp name="MIP-Authenticator-Offset"/>
			</grouped>
		</avp>
		<avp name="MIP-MN-AAA-SPI" code="341" mandatory="must" vendor-bit="mustnot" may-encrypt="yes">
			<type type-name="Unsigned32"/>
		</avp>
		<avp name="MIP-Mobile-Node-Address" code="333" mandatory="must" vendor-bit="mustnot" may-encrypt="yes">
			<type type-name="IPAddress"/>
		</avp>
		<avp name="MIP-Previous-FA-Addr" code="336" mandatory="must" vendor-bit="mustnot" may-encrypt="yes">
			<type type-name="IPAddress"/>
		</avp>
		<avp name="MIP-Previous-FA-Host" code="335" mandatory="must" vendor-bit="mustnot" may-encrypt="yes">
			<type type-name="DiameterIdentity"/>
		</avp>
		<avp name="MIP-Reg-Request" code="320" mandatory="must" vendor-bit="mustnot" may-encrypt="yes">
			<type type-name="MIPRegistrationRequest"/>
		</avp>
		<avp name="MIP-Reg-Reply" code="321" mandatory="must" vendor-bit="mustnot" may-encrypt="yes">
			<type type-name="OctetString"/>
		</avp>
		<!-- ************************ END Mobile-IPv4 AVPS ******************* -->

	</application>
<?xml version="1.0" encoding="UTF-8"?>

	<application id="1" name="NASREQ Application" uri="ftp://ftp.ietf.org/internet-drafts/draft-calhoun-diameter-nasreq-06.txt";>

		<command name="AA-Request" code="260" vendor-id="None"/>
		<command name="AA-Answer" code="260" vendor-id="None"/>

		<!-- ************************* RADIUS AVPs ************************ -->
		<avp name="User-Name" code="1">
			<type type-name="UTF8String"/>
		</avp>
		<avp name="User-Password" code="2">
			<type type-name="OctetString"/>
		</avp>
		<avp name="CHAP-Password" code="3">
			<type type-name="OctetString"/>
		</avp>
		<avp name="NAS-IP-Address" code="4">
			<type type-name="IPAddress"/>
		</avp>
		<avp name="NAS-Port" code="5">
			<type type-name="Integer32"/>
		</avp>
		<avp name="Service-Type" code="6">
			<type type-name="Unsigned32"/>
			<enum name="Labels" code="3"/>
			<enum name="RSVP" code="1"/>
			<enum name="TOS" code="2"/>
		</avp>
		<avp name="Framed-Protocol" code="7">
			<type type-name="Unsigned32"/>
			<enum name="ARA" code="3"/>
			<enum name="Ascend-ARA" code="255"/>
			<enum name="COMB" code="260"/>
			<enum name="EURAW" code="257"/>
			<enum name="EUUI" code="258"/>
			<enum name="FR" code="261"/>
			<enum name="Gandalf" code="4"/>
			<enum name="MPP" code="256"/>
			<enum name="PPP" code="1"/>
			<enum name="SLIP" code="2"/>
			<enum name="X25" code="259"/>
			<enum name="Xylogics" code="5"/>
		</avp>
		<avp name="Framed-IP-Address" code="8">
			<type type-name="IPAddress"/>
		</avp>
		<avp name="Framed-IP-Netmask" code="9">
			<type type-name="IPAddress"/>
		</avp>
		<avp name="Framed-Routing" code="10">
			<type type-name="Unsigned32"/>
			<enum name="Broadcast" code="1"/>
			<enum name="Broadcast-Listen" code="3"/>
			<enum name="Listen" code="2"/>
			<enum name="None" code="0"/>
		</avp>
		<avp name="Filter-Id" code="11">
			<type type-name="UTF8String"/>
		</avp>
		<avp name="Framed-MTU" code="12">
			<type type-name="Integer32"/>
		</avp>
		<avp name="Framed-Compression" code="13">
			<type type-name="Unsigned32"/>
			<enum name="IPX-Header-Compression" code="2"/>
			<enum name="None" code="0"/>
			<enum name="Van-Jacobson-TCP-IP" code="1"/>
		</avp>
		<avp name="Login-IP-Host" code="14">
			<type type-name="IPAddress"/>
		</avp>
		<avp name="Login-Service" code="15">
			<type type-name="Unsigned32"/>
			<enum name="LAT" code="4"/>
			<enum name="PortMaster" code="3"/>
			<enum name="Rlogin" code="1"/>
			<enum name="TCP-Clear" code="2"/>
			<enum name="Telnet" code="0"/>
			<enum name="X25-PAD" code="5"/>
			<enum name="X25-T3POS" code="6"/>
		</avp>
		<avp name="Login-TCP-Port" code="16">
			<type type-name="Integer32"/>
		</avp>
		<avp name="Old-Password" code="17">
			<type type-name="OctetString"/>
		</avp>
		<avp name="Reply-Message" code="18">
			<type type-name="UTF8String"/>
		</avp>
		<avp name="Callback-Number" code="19">
			<type type-name="OctetString"/>
		</avp>
		<avp name="Callback-Id" code="20">
			<type type-name="OctetString"/>
		</avp>
		<avp name="Framed-Route" code="22">
			<type type-name="UTF8String"/>
		</avp>
		<avp name="Framed-IPX-Network" code="23">
			<type type-name="OctetString"/>
		</avp>
		<avp name="State" code="24">
			<type type-name="OctetString"/>
		</avp>
		<avp name="Class" code="25">
			<type type-name="OctetString"/>
		</avp>
		<avp name="Vendor-Specific" code="26">
			<type type-name="Unsigned32"/>
			<!-- Should vendors be enum'ed? -->
		</avp>
		<avp name="Session-Timeout" code="27">
			<type type-name="Integer32"/>
		</avp>
		<avp name="Idle-Timeout" code="28">
			<type type-name="Integer32"/>
		</avp>
		<avp name="Termination-Action" code="29">
			<type type-name="Unsigned32"/>
			<enum name="Default" code="0"/>
			<enum name="RADIUS-Request" code="1"/>
		</avp>
		<avp name="Called-Station-Id" code="30">
			<type type-name="OctetString"/>
		</avp>
		<avp name="Calling-Station-Id" code="31">
			<type type-name="OctetString"/>
		</avp>
		<avp name="NAS-Identifier" code="32">
			<type type-name="OctetString"/>
		</avp>
		<avp name="Proxy-State" code="33">
			<type type-name="OctetString"/>
		</avp>
		<avp name="Login-LAT-Service" code="34">
			<type type-name="OctetString"/>
		</avp>
		<avp name="Login-LAT-Node" code="35">
			<type type-name="OctetString"/>
		</avp>
		<avp name="Login-LAT-Group" code="36">
			<type type-name="OctetString"/>
		</avp>
		<avp name="Framed-AppleTalk-Link" code="37">
			<type type-name="Integer32"/>
		</avp>
		<avp name="Framed-AppleTalk-Network" code="38">
			<type type-name="Integer32"/>
		</avp>
		<avp name="Framed-AppleTalk-Zone" code="39">
			<type type-name="OctetString"/>
		</avp>
		<avp name="Acct-Status-Type" code="40">
			<type type-name="Unsigned32"/>
			<enum name="Accounting-Off" code="8"/>
			<enum name="Accounting-On" code="7"/>
			<enum name="Alive" code="3"/>
			<enum name="Cancel" code="6"/>
			<enum name="Modem-Start" code="4"/>
			<enum name="Modem-Stop" code="5"/>
			<enum name="Start" code="1"/>
			<enum name="Stop" code="2"/>
		</avp>
		<avp name="Acct-Delay-Time" code="41">
			<type type-name="Integer32"/>
		</avp>
		<avp name="Acct-Input-Octets" code="42">
			<type type-name="Integer32"/>
		</avp>
		<avp name="Acct-Output-Octets" code="43">
			<type type-name="Integer32"/>
		</avp>
		<avp name="Acct-Session-Id" code="44" mandatory="must">
			<type type-name="OctetString"/>
		</avp>
		<avp name="Acct-Authentic" code="45">
			<type type-name="Unsigned32"/>
			<enum name="Local" code="2"/>
			<enum name="None" code="0"/>
			<enum name="RADIUS" code="1"/>
		</avp>
		<avp name="Acct-Session-Time" code="46">
			<type type-name="Integer32"/>
		</avp>
		<avp name="Acct-Input-Packets" code="47">
			<type type-name="Integer32"/>
		</avp>
		<avp name="Acct-Output-Packets" code="48">
			<type type-name="Integer32"/>
		</avp>
		<avp name="Acct-Terminate-Cause" code="49">
			<type type-name="Unsigned32"/>
			<enum name="Admin-Reboot" code="7"/>
			<enum name="Admin-Reset" code="6"/>
			<enum name="Callback" code="16"/>
			<enum name="Host-Request" code="18"/>
			<enum name="Idle-Timeout" code="4"/>
			<enum name="Lost-Carrier" code="2"/>
			<enum name="Lost-Service" code="3"/>
			<enum name="NAS-Error" code="9"/>
			<enum name="NAS-Reboot" code="11"/>
			<enum name="NAS-Request" code="10"/>
			<enum name="Port-Error" code="8"/>
			<enum name="Port-Preempted" code="13"/>
			<enum name="Port-Suspended" code="14"/>
			<enum name="Port-Unneeded" code="12"/>
			<enum name="Service-Unavailable" code="15"/>
			<enum name="Session-Timeout" code="5"/>
			<enum name="User-Error" code="17"/>
			<enum name="User-Request" code="1"/>
		</avp>
		<avp name="Acct-Multi-Session-Id" code="50">
			<type type-name="OctetString"/>
		</avp>
		<avp name="Acct-Link-Count" code="51">
			<type type-name="Integer32"/>
		</avp>
		<avp name="CHAP-Challenge" code="60">
			<type type-name="OctetString"/>
		</avp>
		<avp name="NAS-Port-Type" code="61">
			<type type-name="Unsigned32"/>
			<enum name="Async" code="0"/>
			<enum name="HDLC-Clear-Channel" code="7"/>
			<enum name="ISDN-Async-v110" code="4"/>
			<enum name="ISDN-Async-v120" code="3"/>
			<enum name="ISDN-Sync" code="2"/>
			<enum name="PIAFS" code="6"/>
			<enum name="Sync" code="1"/>
			<enum name="Virtual" code="5"/>
			<enum name="X25" code="8"/>
			<enum name="X75" code="9"/>
		</avp>
		<avp name="Port-Limit" code="62">
			<type type-name="Integer32"/>
		</avp>
		<avp name="Login-LAT-Port" code="63">
			<type type-name="OctetString"/>
		</avp>
		<avp name="Tunnel-Type" code="64">
			<type type-name="Unsigned32"/>
			<enum name="PPTP" code="1"/>
			<enum name="L2F" code="2"/>
			<enum name="L2TP" code="3"/>
			<enum name="ATMP" code="4"/>
			<enum name="VTP" code="5"/>
			<enum name="AH" code="6"/>
			<enum name="IP-IP-Encap" code="7"/>
			<enum name="MIN-IP-IP" code="8"/>
			<enum name="ESP" code="9"/>
			<enum name="GRE" code="10"/>
			<enum name="DVS" code="11"/>
			<enum name="IP-IP" code="12"/>
		</avp>
		<avp name="Tunnel-Medium-Type" code="65">
			<type type-name="Unsigned32"/>
			<enum name="IPv4" code="1"/>
			<enum name="IPv6" code="2"/>
			<enum name="NSAP" code="3"/>
			<enum name="HDLC" code="4"/>
			<enum name="BBN" code="5"/>
			<enum name="IEEE-802" code="6"/>
			<enum name="E-163" code="7"/>
			<enum name="E-164" code="8"/>
			<enum name="F-69" code="9"/>
			<enum name="X-121" code="10"/>
			<enum name="IPX" code="11"/>
			<enum name="Appletalk-802" code="12"/>
			<enum name="Decnet4" code="13"/>
			<enum name="Vines" code="14"/>
			<enum name="E-164-NSAP" code="15"/>
		</avp>
		<avp name="Tunnel-Client-Endpoint" code="66">
			<type type-name="OctetString"/>
		</avp>
		<avp name="Tunnel-Server-Endpoint" code="67">
			<type type-name="OctetString"/>
		</avp>
		<avp name="Tunnel-Connection-ID" code="68">
			<type type-name="OctetString"/>
		</avp>
		<avp name="Tunnel-Password" code="69">
			<type type-name="OctetString"/>
		</avp>
		<avp name="Tunnel-Assignment-Id" code="82">
			<type type-name="OctetString"/>
		</avp>

	</application>
<?xml version="1.0" encoding="UTF-8"?>
	<application id="555" name="Sun Ping Application" uri="ftp://ftp.ietf.org/internet-drafts/draft-calhoun-diameter-sun-ping-02.txt";>
		<!-- *********************** Commands ***************************** -->
		<!-- Sun Ping Extension -->
		<command name="Ping" code="511" vendor-id="Sun"/>
		<!-- ********************** End Commands ************************** -->
		<!-- ************************ Sun Ping Extension AVPS ******************* -->
		<avp name="Ping-Timestamp-Secs" code="1" vendor-id="Sun" mandatory="mustnot" vendor-bit="must">
			<type type-name="Unsigned32"/>
		</avp>
		<avp name="Ping-Timestamp-Usecs" code="2" vendor-id="Sun" mandatory="mustnot" vendor-bit="must">
			<type type-name="Unsigned32"/>
		</avp>
		<avp name="Ping-Timestamp" code="3" vendor-id="Sun" mandatory="mustnot" vendor-bit="must">
			<grouped>
				<gavp name="Ping-Timestamp-Secs"/>
				<gavp name="Ping-Timestamp-Usecs"/>
			</grouped>
		</avp>
		<!-- ********************** End Sun Ping Extension AVPS ***************** -->
		<!-- ************************ Sun PING Extension AVPs ***************************-->
	</application>