Initial commit

Change-Id: I6a4444e3c193dae437cd7929f4c39aba7b749efa
diff --git a/extensions/dict_mip6a/dict_mip6a.c b/extensions/dict_mip6a/dict_mip6a.c
new file mode 100644
index 0000000..a31aeed
--- /dev/null
+++ b/extensions/dict_mip6a/dict_mip6a.c
@@ -0,0 +1,1094 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License)                                                               *
+* Author: Francois Bard <francois@tera.ics.keio.ac.jp>							 *
+*													 *
+* Copyright (c) 2010, Teraoka Laboratory, Keio University						 *
+* All rights reserved.											 *
+* 													 *
+* Redistribution and use of this software in source and binary forms, with or without modification, are  *
+* permitted provided that the following conditions are met:						 *
+* 													 *
+* * Redistributions of source code must retain the above 						 *
+*   copyright notice, this list of conditions and the 							 *
+*   following disclaimer.										 *
+*    													 *
+* * Redistributions in binary form must reproduce the above 						 *
+*   copyright notice, this list of conditions and the 							 *
+*   following disclaimer in the documentation and/or other						 *
+*   materials provided with the distribution.								 *
+* 													 *
+* * Neither the name of the Teraoka Laboratory nor the 							 *
+*   names of its contributors may be used to endorse or 						 *
+*   promote products derived from this software without 						 *
+*   specific prior written permission of Teraoka Laboratory 						 *
+*   													 *
+* 													 *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 	 *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 	 *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF   *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.								 *
+*********************************************************************************************************/
+
+/*
+
+The following table complete the one in RFC 5778, page 18. The AVPs are implemented below following the order of this table.
+We try to keep the structure of the grouped AVP by declaring the contained AVPs just before the grouped AVP they depend on.
+The number of '+' indicates the depth of the contained AVP.
+
+DEPTH	NAME					AVP	RFC		TYPE			NOTES
+
+	MIP6-Feature-Vector			124	5447		Unsigned64
+	User-Name				1	3588		UTF8String
+	Service-Selection			493	5778		UTF8String
+	MIP-MN-AAA-SPI				341	5778		Unsigned32
++	MIP-Home-Agent-Address			334	4004		Address
+++	Destination-Host			293	3588		DiameterIdentity
+++	Destination-Realm			283	3588		DiameterIdentity
++	MIP-Home-Agent-Host			348	4004		Grouped
++	MIP6-Home-Link-Prefix			125	5447		OctetString
+	MIP6-Agent-Info				486	5447		Grouped
++	MIP-Replay-Mode				346	4004		Enumerated
++	MIP-Algorithm-Type			345	4004		Enumerated
++	MIP-MN-HA-SPI				491	5778		Unsigned32
++	MIP-MSA-Lifetime			367	4004		Unsigned32
++	MIP-Session-Key				343	4004		OctetString
+	MIP-MN-HA-MSA				492	5778		Grouped			different from MIP-MN-to-HA-MSA (331)
+	MIP-Mobile-Node-Address			333	4004		Address
+	MIP-Careof-Address			487	5778		Address
+	MIP-Authenticator			488	5778		OctetString
+	MIP-MAC-Mobility-Data			489	5778		OctetString
+	MIP-Timestamp				490	5778		OctetString
+	Chargeable-User-Identity		89	5778		OctetString
+	MIP6-Auth-Mode				494	5778		Enumerated
+
+QoS AVPs (RFC 5777 - implemented in the corresponding dictionary)
+
+	QoS-Capability				578	5777		Grouped
+	QoS-Resources				508	5777		Grouped
+
+ACCOUNTING AVPs (section 6.21)
+
+	Accounting-Input-Octets			363	4004, 4005	Unsigned64
+	Accounting-Output-Octets		364	4004, 4005	Unsigned64
+	Accounting-Input-Packets		365	4004, 4005	Unsigned64
+	Accounting-Output-Packets		366	4004, 4005	Unsigned64
+	Acct-Multi-Session-Id			50	3588		UTF8String
+	Acct-Session-Time			46	2866, 4004	Unsigned32
+	MIP6-Feature-Vector			----------------------------------
+	MIP-Mobile-Node-Address			----------------------------------
+	MIP6-Agent-Info				----------------------------------
+	Chargeable-User-Identity		----------------------------------
+	Service-Selection			----------------------------------
+	QoS-Resources				----------------------------------
+	QoS-Capability				----------------------------------
+	MIP-Careof-Address			----------------------------------
+
+RADIUS AVPs (contained in the MIR/MIA)
+
+	NAS-Identifier				32	2865		radius (see avp)
+	NAS-IP-Address				4	2865            radius (see avp)
+	NAS-IPv6-Address			95	3162            radius (see avp)
+	NAS-Port-Type				61	2865            radius (see avp)
+	Called-Station-Id			30	2865            radius (see avp)
+	Calling-Station-Id			31	2865            radius (see avp)
+
+
+*/
+
+/****************************************************************************************************************************************
+*																	*
+* This table is a copy of the registry named "MIP6 Authentication Mode Registry" and managed by IANA.					*
+* source : http://www.iana.org/assignments/aaa-parameters/aaa-parameters.txt								*
+* up to date on october 2010														*
+*																	*
+*      Value          Token       Reference												*
+*        0       Reserved         [RFC5778]												*
+*        1       MIP6_AUTH_MN_AAA [RFC5778]												*
+*   2-4294967295 Unassigned														*
+*																	*
+****************************************************************************************************************************************/
+
+
+/*
+
+NOTES
+
+check for omissions !
+
+*/
+
+#include <freeDiameter/extension.h>
+
+#define CHECK_dict_new( _type, _data, _parent, _ref )	\
+	CHECK_FCT(  fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref))  );
+
+#define CHECK_dict_search( _type, _criteria, _what, _result )	\
+	CHECK_FCT(  fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+	char 			*avp_name;
+	enum rule_position	position;
+	int 			min;
+	int			max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+#define PARSE_loc_rules( _rulearray, _parent) {								\
+	int __ar;											\
+	for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) {			\
+		struct dict_rule_data __data = { NULL, 							\
+			(_rulearray)[__ar].position,							\
+			0, 										\
+			(_rulearray)[__ar].min,								\
+			(_rulearray)[__ar].max};							\
+		__data.rule_order = RULE_ORDER(__data.rule_position);					\
+		CHECK_FCT(  fd_dict_search( 								\
+			fd_g_config->cnf_dict,								\
+			DICT_AVP, 									\
+			AVP_BY_NAME, 									\
+			(_rulearray)[__ar].avp_name, 							\
+			&__data.rule_avp, 0 ) );							\
+		if ( !__data.rule_avp ) {								\
+			TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_name );		\
+			return ENOENT;									\
+		}											\
+		CHECK_FCT_DO( fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &__data, _parent, NULL),	\
+			{							        		\
+				TRACE_DEBUG(INFO, "Error on rule with AVP '%s'",      			\
+					 (_rulearray)[__ar].avp_name );		      			\
+				return EINVAL;					      			\
+			} );							      			\
+	}									      			\
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+		{ _str_, 		{ .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+		{ _str_, 		{ .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+
+/* Defines if there are any */
+
+//New Result-Code for MIP (RFC5778, Section 7.*)
+#define DIAMETER_SUCCESS_RELOCATE_HA 2009
+#define DIAMETER_ERROR_MIP6_AUTH_MODE 5041
+
+//Others
+#define MIP6_AUTH_MN_AAA 1
+
+/* Dictionary */
+
+int dict_mip6a_init(char * conffile)
+{
+	struct dict_object * mip6a;
+	{
+		struct dict_application_data data  = { 	8, "Diameter Mobile IPv6 Auth (MIP6A) Application" };
+		CHECK_dict_new( DICT_APPLICATION, &data , NULL, &mip6a);
+	}
+
+	/***************/
+	/* AVP section */
+	/***************/
+	{
+		/* Loading all the derived data formats */
+
+		struct dict_object * Address_type;
+		struct dict_object * UTF8String_type;
+		struct dict_object * DiameterIdentity_type;
+		struct dict_object * DiameterURI_type;
+		struct dict_object * Time_type;
+		
+		CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+		CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+		CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+		CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+		CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+
+	///////////////////////////////////////////
+	/* AVPs for Mobile IPv6 Auth Application */
+	///////////////////////////////////////////
+
+		/* MIP6-Feature-Vector - RFC 5447 */
+		{
+			/*
+
+			*/
+
+			struct dict_avp_data data = { 
+					124, 					/* Code */
+					0, 					/* Vendor */
+					"MIP6-Feature-Vector", 			/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_UNSIGNED64			/* base type of data */
+					};
+			
+			CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+		}
+
+		/* User-Name - RFC 3588 */
+
+			/*
+			Implemented in the base protocol
+			*/
+
+		/* Service-Selection - RFC 5778 */
+		{
+			/*
+
+			*/
+
+			struct dict_avp_data data = {
+					493, 					/* Code */
+					0, 					/* Vendor */
+					"Service-Selection",			/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_OCTETSTRING 			/* base type of data */
+					};
+
+			CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+		}
+
+		/* MIP-MN-AAA-SPI - RFC 5778 */
+		{
+			/*
+
+			*/
+
+			struct dict_avp_data data = {
+					341, 					/* Code */
+					0, 					/* Vendor */
+					"MIP-MN-AAA-SPI",			/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_UNSIGNED32 			/* base type of data */
+					};
+
+			CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+		}
+
+		/* Destination-Host - Base Protocol */
+
+			/*
+			Implemented in the base protocol
+			*/
+
+		/* Destination-Realm - Base Protocol */
+
+			/*
+			Implemented in the base protocol
+			*/
+
+		/* MIP-Home-Agent-Address - RFC 4004 */
+		{
+			/*
+
+			*/
+
+			struct dict_avp_data data = {
+					334, 					/* Code */
+					0, 					/* Vendor */
+					"MIP-Home-Agent-Address",		/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_OCTETSTRING			/* base type of data */
+					};
+
+			CHECK_dict_new( DICT_AVP, &data , Address_type, NULL);
+		}
+
+		/* MIP-Home-Agent-Host - RFC 4004 */
+		{
+			/*
+
+			*/
+			struct dict_object * avp;
+			struct dict_avp_data data = {
+					348, 					/* Code */
+					0, 					/* Vendor */
+					"MIP-Home-Agent-Host",			/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_GROUPED 			/* base type of data */
+					};
+
+			struct local_rules_definition rules[] =
+						{ 	 {  "Destination-Realm",	RULE_REQUIRED,	-1, 1 }
+							,{  "Destination-Host",		RULE_REQUIRED,	-1, 1 }
+						};
+
+			CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+			PARSE_loc_rules( rules, avp );
+		}
+
+		/* MIP6-Home-Link-Prefix - RFC 5447 */
+		{
+			/*
+
+			*/
+
+			struct dict_avp_data data = {
+					125, 					/* Code */
+					0, 					/* Vendor */
+					"MIP6-Home-Link-Prefix", 		/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_OCTETSTRING			/* base type of data */
+					};
+
+			CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+		}
+
+		/* MIP6-Agent-Info - RFC 5447*/
+		{
+			/*
+			
+			*/
+			struct dict_object * avp;
+			struct dict_avp_data data = { 
+					486, 					/* Code */
+					0, 					/* Vendor */
+					"MIP6-Agent-Info",			/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_GROUPED 			/* base type of data */
+					};
+
+			struct local_rules_definition rules[] = 
+						{ 	 {  "MIP-Home-Agent-Address", 		RULE_OPTIONAL, -1, 2 }
+							,{  "MIP-Home-Agent-Host",		RULE_OPTIONAL, -1, 1 }
+							,{  "MIP6-Home-Link-Prefix",		RULE_OPTIONAL, -1, 1 }
+						};
+			
+			CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+			PARSE_loc_rules( rules, avp );
+		}
+
+		/* MIP-Replay-Mode - RFC 5778 & 4004 */
+		{
+			/*
+
+			*/
+			struct dict_object * 	 type;
+			struct dict_type_data 	 tdata = { AVP_TYPE_INTEGER32, "Enumerated(MIP-Replay-Mode)", NULL, NULL, NULL };
+			struct dict_enumval_data t_0 = { "None", 	{ .i32 = 1 }};
+			struct dict_enumval_data t_1 = { "Timestamp", 	{ .i32 = 2 }};
+			struct dict_avp_data data = {
+					346, 					/* Code */
+					0, 					/* Vendor */
+					"MIP-Replay-Mode",			/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_INTEGER32 			/* base type of data */
+					};
+
+			/* Create the Enumerated type, and then the AVP */
+			CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+			CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL);
+			CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL);
+			CHECK_dict_new( DICT_AVP, &data , type, NULL);
+		}
+
+		/* MIP-Algorithm-Type - RFC 5778 & 4004 */
+		{
+			/*
+
+			*/
+			struct dict_object * 	 type;
+			struct dict_type_data 	 tdata = { AVP_TYPE_INTEGER32, "Enumerated(MIP-Algorithm-Type)", NULL, NULL, NULL };
+			struct dict_enumval_data t_2 = { "HMAC-SHA-1 [HMAC]", { .i32 = 2 }};
+			struct dict_avp_data data = {
+					345, 					/* Code */
+					0, 					/* Vendor */
+					"MIP-Algorithm-Type",			/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_INTEGER32 			/* base type of data */
+					};
+
+			/* Create the Enumerated type, and then the AVP */
+			CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+			CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL);
+			CHECK_dict_new( DICT_AVP, &data , type, NULL);
+		}
+
+		/* MIP-MN-HA-SPI - RFC 5778 */
+		{
+			/*
+
+			*/
+			struct dict_avp_data data = {
+					491, 					/* Code */
+					0, 					/* Vendor */
+					"MIP-MN-HA-SPI",			/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_UNSIGNED32 			/* base type of data */
+					};
+
+			CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+		}
+
+		/* MIP-MSA-Lifetime - RFC 4004 */
+		{
+			/*
+
+			*/
+			struct dict_avp_data data = {
+					367, 					/* Code */
+					0, 					/* Vendor */
+					"MIP-MSA-Lifetime",			/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_UNSIGNED32 			/* base type of data */
+					};
+
+			CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+		}
+
+		/* MIP-Session-Key - RFC 5778 */
+		{
+			/*
+
+			*/
+			struct dict_avp_data data = {
+					343, 					/* Code */
+					0, 					/* Vendor */
+					"MIP-Session-Key",			/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_OCTETSTRING 			/* base type of data */
+					};
+
+			CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+		}
+
+		/* MIP-MN-HA-MSA - RFC 5778 */
+		{
+			/*
+			
+			*/
+			struct dict_object * avp;
+			struct dict_avp_data data = { 
+					492, 					/* Code */
+					0, 					/* Vendor */
+					"MIP-MN-HA-MSA",			/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_GROUPED 			/* base type of data */
+					};
+
+			struct local_rules_definition rules[] = 
+						{ 	 {  "MIP-Session-Key", 		RULE_REQUIRED, -1, 1 }
+							,{  "MIP-MSA-Lifetime", 	RULE_REQUIRED, -1, 1 }
+							,{  "MIP-MN-HA-SPI", 		RULE_OPTIONAL, -1, 1 }
+							,{  "MIP-Algorithm-Type", 	RULE_OPTIONAL, -1, 1 }
+							,{  "MIP-Replay-Mode", 		RULE_OPTIONAL, -1, 1 }
+						};
+
+			CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+			PARSE_loc_rules( rules, avp );
+		}
+
+		/* MIP-Mobile-Node-Address - RFC 4004 */
+		{
+			/*
+
+			*/
+
+			struct dict_avp_data data = {
+					333, 					/* Code */
+					0, 					/* Vendor */
+					"MIP-Mobile-Node-Address",		/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_OCTETSTRING			/* base type of data */
+					};
+
+			CHECK_dict_new( DICT_AVP, &data , Address_type, NULL);
+		}
+
+		/* MIP-Careof-Address - RFC 5778 */
+		{
+			/*
+
+			*/
+			struct dict_avp_data data = {
+					487, 					/* Code */
+					0, 					/* Vendor */
+					"MIP-Careof-Address",			/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_OCTETSTRING 			/* base type of data */
+					};
+
+			CHECK_dict_new( DICT_AVP, &data , Address_type, NULL);
+		}
+
+		/* MIP-Authenticator - RFC 5778 */
+		{
+			/*
+			
+			*/
+			struct dict_avp_data data = { 
+					488, 					/* Code */
+					0, 					/* Vendor */
+					"MIP-Authenticator",			/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_OCTETSTRING 			/* base type of data */
+					};
+
+			CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+		}
+
+		/* MIP-MAC-Mobility-Data - RFC 5778 */
+		{
+			/*
+			
+			*/
+			struct dict_avp_data data = { 
+					489, 					/* Code */
+					0, 					/* Vendor */
+					"MIP-MAC-Mobility-Data",		/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_OCTETSTRING 			/* base type of data */
+					};
+
+			CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+		}
+
+		/* MIP-Timestamp - RFC 5778 */
+		{
+			/*
+			
+			*/
+			struct dict_avp_data data = { 
+					490, 					/* Code */
+					0, 					/* Vendor */
+					"MIP-Timestamp",			/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_OCTETSTRING 			/* base type of data */
+					};
+
+			CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+		}
+
+		/* Chargeable-User-Identity - RFC 5778 */
+		{
+			/*
+			
+			*/
+			struct dict_avp_data data = { 
+					89, 					/* Code */
+					0, 					/* Vendor */
+					"Chargeable-User-Identity",		/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_OCTETSTRING 			/* base type of data */
+					};
+
+			CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+		}
+
+		/* MIP6-Auth-Mode - RFC 5778 */
+		{
+			/*
+			
+			*/
+			struct dict_object * 	 type;
+			struct dict_type_data 	 tdata = { AVP_TYPE_INTEGER32, "Enumerated(MIP6-Auth-Mode)", NULL, NULL, NULL };
+			struct dict_enumval_data t_0 = { "None", 	{ .i32 = MIP6_AUTH_MN_AAA }};
+			struct dict_avp_data data = { 
+					494, 					/* Code */
+					0, 					/* Vendor */
+					"MIP6-Auth-Mode",			/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_INTEGER32 			/* base type of data */
+					};
+
+			/* Create the Enumerated type, and then the AVP */
+			CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+			CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL);
+			CHECK_dict_new( DICT_AVP, &data , type, NULL);
+		}
+
+	//////////////
+	/* QoS AVPs */
+	//////////////
+
+		/* QoS-Capability */
+
+			/*
+			Implemented in RFC 5777
+			*/
+
+		/* QoS-Resources */
+
+			/*
+			Implemented in RFC 5777
+			*/
+
+	/////////////////////
+	/* Accounting AVPs */
+	/////////////////////
+
+		/* Accounting-Input-Octets - RFC 4004 */
+		{
+			/*
+
+			*/
+			struct dict_avp_data data = {
+					363, 					/* Code */
+					0, 					/* Vendor */
+					"Accounting-Input-Octets",		/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_UNSIGNED64 			/* base type of data */
+					};
+
+			CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+		}
+
+		/* Accounting-Output-Octets - RFC 4004 */
+		{
+			/*
+
+			*/
+			struct dict_avp_data data = {
+					364, 					/* Code */
+					0, 					/* Vendor */
+					"Accounting-Output-Octets",		/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_UNSIGNED64 			/* base type of data */
+					};
+
+			CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+		}
+
+		/* Accounting-Input-Packets - RFC 4004 */
+		{
+			/*
+
+			*/
+			struct dict_avp_data data = {
+					365, 					/* Code */
+					0, 					/* Vendor */
+					"Accounting-Input-Packets",		/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_UNSIGNED64 			/* base type of data */
+					};
+
+			CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+		}
+
+		/* Accounting-Output-Packets - RFC 4004 */
+		{
+			/*
+
+			*/
+			struct dict_avp_data data = {
+					366, 					/* Code */
+					0, 					/* Vendor */
+					"Accounting-Output-Packets",		/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_UNSIGNED64 			/* base type of data */
+					};
+
+			CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+		}
+
+		/* Acct-Multi-Session-Id - RFC 3588 */
+
+			/*
+			Implemented in the base protocol
+			*/
+
+		/* Acct-Session-Time - RFC 4004 */
+		{
+			/*
+
+			*/
+			struct dict_avp_data data = {
+					46, 					/* Code */
+					0, 					/* Vendor */
+					"Acct-Session-Time",			/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_UNSIGNED32 			/* base type of data */
+					};
+
+			CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+		}
+
+	/////////////////////////////////////
+	/* Radius AVPs - used in MIR & MIA */
+	/////////////////////////////////////
+
+	/*
+	We used the following correspondences for determining the type of the Radius AVPs
+
+		Radius		Diameter
+
+		text		UTF8Sting
+		string		OctetString
+		address		Address
+		integer		Unsigned32
+		time		Time
+	*/
+
+
+		/* NAS-Identifier				32	3575 */
+		{
+			/*
+			string -> OctetString
+			*/
+
+			struct dict_avp_data data = {
+					32, 					/* Code */
+					0, 					/* Vendor */
+					"NAS-Identifier",			/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_OCTETSTRING			/* base type of data */
+					};
+
+			CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+		}
+
+		/* NAS-IP-Address				4	3575 */
+		{
+			/*
+			address -> Address
+			*/
+
+			struct dict_avp_data data = {
+					4, 					/* Code */
+					0, 					/* Vendor */
+					"NAS-IP-Address",			/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_OCTETSTRING			/* base type of data */
+					};
+
+			CHECK_dict_new( DICT_AVP, &data , Address_type, NULL);
+		}
+
+		/* NAS-IPv6-Address			95	3162 */
+		{
+			/*
+			address -> Address
+			*/
+
+			struct dict_avp_data data = {
+					95, 					/* Code */
+					0, 					/* Vendor */
+					"NAS-IPv6-Address",			/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_OCTETSTRING			/* base type of data */
+					};
+
+			CHECK_dict_new( DICT_AVP, &data , Address_type, NULL);
+		}
+
+		/* NAS-Port-Type			61	2865 */
+		{
+			/*
+			integer -> Unsigned32
+
+			   Value
+
+			      The Value field is four octets.  "Virtual" refers to a connection
+			      to the NAS via some transport protocol, instead of through a
+			      physical port.  For example, if a user telnetted into a NAS to
+			      authenticate himself as an Outbound-User, the Access-Request might
+			      include NAS-Port-Type = Virtual as a hint to the RADIUS server
+			      that the user was not on a physical port.
+
+			      0       Async
+			      1       Sync
+			      2       ISDN Sync
+			      3       ISDN Async V.120
+			      4       ISDN Async V.110
+			      5       Virtual
+			      6       PIAFS
+			      7       HDLC Clear Channel
+			      8       X.25
+			      9       X.75
+			      10      G.3 Fax
+			      11      SDSL - Symmetric DSL
+			      12      ADSL-CAP - Asymmetric DSL, Carrierless Amplitude Phase
+				      Modulation
+			      13      ADSL-DMT - Asymmetric DSL, Discrete Multi-Tone
+			      14      IDSL - ISDN Digital Subscriber Line
+			      15      Ethernet
+			      16      xDSL - Digital Subscriber Line of unknown type
+			      17      Cable
+			      18      Wireless - Other
+			      19      Wireless - IEEE 802.11
+
+			      PIAFS is a form of wireless ISDN commonly used in Japan, and
+			      stands for PHS (Personal Handyphone System) Internet Access Forum
+			      Standard (PIAFS).
+			*/
+
+			struct dict_avp_data data = {
+					61, 					/* Code */
+					0, 					/* Vendor */
+					"NAS-Port-Type",			/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_UNSIGNED32			/* base type of data */
+					};
+
+			CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+		}
+
+		/* Called-Station-Id			30	2865 */
+		{
+			/*
+			string -> OctetString
+			*/
+
+			struct dict_avp_data data = {
+					30, 					/* Code */
+					0, 					/* Vendor */
+					"Called-Station-Id",			/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_OCTETSTRING			/* base type of data */
+					};
+
+			CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+		}
+		/* Calling-Station-Id			31	2865 */
+		{
+			/*
+			string -> OctetString
+			*/
+
+			struct dict_avp_data data = {
+					31, 					/* Code */
+					0, 					/* Vendor */
+					"Calling-Station-Id",			/* Name */
+					AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, 	/* Fixed flags */
+					AVP_FLAG_MANDATORY,		 	/* Fixed flag values */
+					AVP_TYPE_OCTETSTRING			/* base type of data */
+					};
+
+			CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+		}
+	}
+
+/*******************/
+/* Command section */
+/*******************/
+
+	{
+		/* MIP6-Request (MIR) */
+		{
+			/*
+
+			The MIP6-Request (MIR), indicated by the Command-Code field set to
+			325 and the 'R' bit set in the Command Flags field, is sent by the
+			HA, acting as a Diameter client, in order to request the
+			authentication and authorization of an MN.
+
+			Although the HA provides the Diameter server with replay protection-
+			related information, the HA is responsible for the replay protection.
+
+			The message format is shown below.
+
+			<MIP6-Request> ::= < Diameter Header: 325, REQ, PXY >
+					   < Session-ID >
+					   { Auth-Application-Id }
+					   { User-Name }
+					   { Destination-Realm }
+					   { Origin-Host }
+					   { Origin-Realm }
+					   { Auth-Request-Type }
+					   [ Destination-Host ]
+					   [ Origin-State-Id ]
+					   [ NAS-Identifier ]
+					   [ NAS-IP-Address ]
+					   [ NAS-IPv6-Address ]
+					   [ NAS-Port-Type ]
+					   [ Called-Station-Id ]
+					   [ Calling-Station-Id ]
+					   [ MIP6-Feature-Vector ]
+					   { MIP6-Auth-Mode }
+					   [ MIP-MN-AAA-SPI ]
+					   [ MIP-MN-HA-SPI ]
+					1*2{ MIP-Mobile-Node-Address }
+					   { MIP6-Agent-Info }
+					   { MIP-Careof-Address }
+					   [ MIP-Authenticator ]
+					   [ MIP-MAC-Mobility-Data ]
+					   [ MIP-Timestamp ]
+					   [ QoS-Capability ]
+					 * [ QoS-Resources ]
+					   [ Chargeable-User-Identity ]
+					   [ Service-Selection ]
+					   [ Authorization-Lifetime ]
+					   [ Auth-Session-State ]
+					 * [ Proxy-Info ]
+					 * [ Route-Record ]
+					 * [ AVP ]
+
+			If the MN is both authenticated and authorized for the mobility
+			service, then the Auth-Request-Type AVP is set to the value
+			AUTHORIZE_AUTHENTICATE.  This is the case when the MIP6-Auth-Mode is
+			set to the value MIP6_AUTH_MN_AAA.
+
+			*/
+			struct dict_object * cmd;
+			struct dict_cmd_data data = {
+					325, 					/* Code */
+					"MIP6-Request", 			/* Name */
+					CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, 	/* Fixed flags */
+					CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE 						/* Fixed flag values */
+					};
+			struct local_rules_definition rules[] =
+						{ 	 {  "Session-Id", 			RULE_FIXED_HEAD, -1, 1 }
+							,{  "Auth-Application-Id", 		RULE_REQUIRED,   -1, 1 }
+							,{  "User-Name", 			RULE_REQUIRED,   -1, 1 }
+							,{  "Destination-Realm", 		RULE_REQUIRED,   -1, 1 }
+							,{  "Origin-Host", 			RULE_REQUIRED,   -1, 1 }
+							,{  "Origin-Realm", 			RULE_REQUIRED,   -1, 1 }
+							,{  "Auth-Request-Type", 		RULE_REQUIRED,   -1, 1 }
+							,{  "Destination-Host", 		RULE_OPTIONAL,   -1, 1 }
+							,{  "Origin-State-Id",	 		RULE_OPTIONAL,   -1, 1 }
+							,{  "NAS-Identifier", 			RULE_OPTIONAL,   -1, 1 }
+							,{  "NAS-IP-Address", 			RULE_OPTIONAL,   -1, 1 }
+							,{  "NAS-IPv6-Address", 		RULE_OPTIONAL,   -1, 1 }
+							,{  "NAS-Port-Type", 			RULE_OPTIONAL,   -1, 1 }
+							,{  "Called-Station-Id", 		RULE_OPTIONAL,   -1, 1 }
+							,{  "Calling-Station-Id", 		RULE_OPTIONAL,   -1, 1 }
+							,{  "MIP6-Feature-Vector", 		RULE_OPTIONAL,   -1, 1 }
+							,{  "MIP6-Auth-Mode", 			RULE_OPTIONAL,   -1, 1 }
+							,{  "MIP-MN-AAA-SPI", 			RULE_OPTIONAL,   -1, 1 }
+							,{  "MIP-MN-HA-SPI", 			RULE_OPTIONAL,   -1, 1 }
+							,{  "MIP-Mobile-Node-Address", 		RULE_OPTIONAL,    1, 2 }
+							,{  "MIP6-Agent-Info", 			RULE_OPTIONAL,   -1, 1 }
+							,{  "MIP-Careof-Address", 		RULE_OPTIONAL,   -1, 1 }
+							,{  "MIP-Authenticator", 		RULE_OPTIONAL,   -1, 1 }
+							,{  "MIP-MAC-Mobility-Data", 		RULE_OPTIONAL,   -1, 1 }
+							,{  "MIP-Timestamp", 			RULE_OPTIONAL,   -1, 1 }
+							,{  "QoS-Capability", 			RULE_OPTIONAL,   -1, 1 }
+							,{  "QoS-Resources", 			RULE_OPTIONAL,   -1, -1 }
+							,{  "Chargeable-User-Identity", 	RULE_OPTIONAL,   -1, 1 }
+							,{  "Service-Selection", 		RULE_OPTIONAL,   -1, 1 }
+							,{  "Authorization-Lifetime", 		RULE_OPTIONAL,   -1, 1 }
+							,{  "Auth-Session-State", 		RULE_OPTIONAL,   -1, 1 }
+							,{  "Proxy-Info", 			RULE_OPTIONAL,   -1, -1 }
+							,{  "Route-Record", 			RULE_OPTIONAL,   -1, -1 }
+						};
+
+			CHECK_dict_new( DICT_COMMAND, &data, mip6a, &cmd);
+			PARSE_loc_rules( rules, cmd );
+		}
+
+		/* MIP6-Answer (MIA) */
+		{
+			/*
+
+			The MIP6-Answer (MIA) message, indicated by the Command-Code field
+			set to 325 and the 'R' bit cleared in the Command Flags field, is
+			sent by the Diameter server in response to the MIP6-Request message.
+
+			The User-Name AVP MAY be included in the MIA if it is present in the
+			MIR.  The Result-Code AVP MAY contain one of the values defined in
+			Section 7, in addition to the values defined in [RFC3588].
+
+			An MIA message with the Result-Code AVP set to DIAMETER_SUCCESS MUST
+			include the MIP-Mobile-Node-Address AVP.
+
+			The message format is shown below.
+
+			<MIP6-Answer> ::= < Diameter Header: 325, PXY >
+					  < Session-Id >
+					  { Auth-Application-Id }
+					  { Result-Code }
+					  { Origin-Host }
+					  { Origin-Realm }
+					  { Auth-Request-Type }
+					  [ User-Name ]
+					  [ Authorization-Lifetime ]
+					  [ Auth-Session-State ]
+					  [ Error-Message ]
+					  [ Error-Reporting-Host ]
+					  [ Re-Auth-Request-Type ]
+					  [ MIP6-Feature-Vector ]
+					  [ MIP6-Agent-Info ]
+					*2[ MIP-Mobile-Node-Address ]
+					  [ MIP-MN-HA-MSA ]
+					* [ QoS-Resources ]
+					  [ Chargeable-User-Identity ]
+					  [ Service-Selection ]
+					  [ Origin-State-Id ]
+					* [ Proxy-Info ]
+					* [ Redirect-Host ]
+					  [ Redirect-Host-Usage ]
+					  [ Redirect-Max-Cache-Time ]
+					* [ Failed-AVP ]
+					* [ AVP ]
+
+			*/
+			struct dict_object * cmd;
+			struct dict_cmd_data data = {
+					325, 					/* Code */
+					"MIP6-Answer", 				/* Name */
+					CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, 	/* Fixed flags */
+					CMD_FLAG_PROXIABLE 			/* Fixed flag values */
+					};
+			struct local_rules_definition rules[] =
+						{ 	 {  "Session-Id", 			RULE_FIXED_HEAD, -1, 1 }
+							,{  "Auth-Application-Id", 		RULE_REQUIRED,   -1, 1 }
+							,{  "Result-Code", 			RULE_REQUIRED,   -1, 1 }
+							,{  "Origin-Host", 			RULE_REQUIRED,   -1, 1 }
+							,{  "Origin-Realm", 			RULE_REQUIRED,   -1, 1 }
+							,{  "Auth-Request-Type", 		RULE_REQUIRED,   -1, 1 }
+							,{  "User-Name", 			RULE_OPTIONAL,   -1, 1 }
+							,{  "Authorization-Lifetime", 		RULE_OPTIONAL,   -1, 1 }
+							,{  "Auth-Session-State", 		RULE_OPTIONAL,   -1, 1 }
+							,{  "Error-Message", 			RULE_OPTIONAL,   -1, 1 }
+							,{  "Error-Reporting-Host", 		RULE_OPTIONAL,   -1, 1 }
+							,{  "Re-Auth-Request-Type", 		RULE_OPTIONAL,   -1, 1 }
+							,{  "MIP6-Feature-Vector", 		RULE_OPTIONAL,   -1, 1 }
+							,{  "MIP6-Agent-Info", 			RULE_OPTIONAL,   -1, 1 }
+							,{  "MIP-Mobile-Node-Address", 		RULE_OPTIONAL,   -1, 2 }
+							,{  "MIP-MN-HA-MSA", 			RULE_OPTIONAL,   -1, 1 }
+							,{  "QoS-Resources", 			RULE_OPTIONAL,   -1, -1 }
+							,{  "Chargeable-User-Identity",		RULE_OPTIONAL,   -1, 1 }
+							,{  "Service-Selection", 		RULE_OPTIONAL,   -1, 1 }
+							,{  "Origin-State-Id", 			RULE_OPTIONAL,   -1, 1 }
+							,{  "Proxy-Info", 			RULE_OPTIONAL,   -1, -1 }
+							,{  "Redirect-Host", 			RULE_OPTIONAL,   -1, -1 }
+							,{  "Redirect-Host-Usage", 		RULE_OPTIONAL,   -1, 1 }
+							,{  "Redirect-Max-Cache-Time", 		RULE_OPTIONAL,   -1, 1 }
+							,{  "Failed-AVP", 			RULE_OPTIONAL,   -1, -1 }
+						};
+
+			CHECK_dict_new( DICT_COMMAND, &data, mip6a, &cmd);
+			PARSE_loc_rules( rules, cmd );
+		}
+	}
+	LOG_D( "Dictionary Extension 'Diameter Mobile IPv6 Auth (MIP6A)' initialized");
+	return 0;
+}
+EXTENSION_ENTRY("dict_mip6a", dict_mip6a_init, "dict_rfc5777");