changeset 425:0c6e50a5291d

New app_diameap Diameter EAP Application
author Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
date Mon, 26 Jul 2010 18:00:24 +0900
parents 6c96605f5250
children 44541db912a2
files doc/app_diameap.conf.sample doc/eap_tls_plugin.diameap.conf.sample extensions/CMakeLists.txt extensions/app_diameap/CMakeLists.txt extensions/app_diameap/LICENSE extensions/app_diameap/README extensions/app_diameap/diameap.c extensions/app_diameap/diameap.h extensions/app_diameap/diameap.l extensions/app_diameap/diameap.sql extensions/app_diameap/diameap.y extensions/app_diameap/diameap_common.h extensions/app_diameap/diameap_defs.h extensions/app_diameap/diameap_eap.c extensions/app_diameap/diameap_eap.h extensions/app_diameap/diameap_eappacket.c extensions/app_diameap/diameap_eappacket.h extensions/app_diameap/diameap_init.c extensions/app_diameap/diameap_init.h extensions/app_diameap/diameap_mysql.c extensions/app_diameap/diameap_mysql.h extensions/app_diameap/diameap_plugins.c extensions/app_diameap/diameap_plugins.h extensions/app_diameap/diameap_server.c extensions/app_diameap/diameap_server.h extensions/app_diameap/diameap_tls.c extensions/app_diameap/diameap_tls.h extensions/app_diameap/diameap_user.c extensions/app_diameap/diameap_user.h extensions/app_diameap/libcrypt.c extensions/app_diameap/libcrypt.h extensions/app_diameap/libdiameap.h extensions/app_diameap/plugins.h extensions/app_diameap/plugins/CMakeLists.txt extensions/app_diameap/plugins/eap_identity/CMakeLists.txt extensions/app_diameap/plugins/eap_identity/eap_identity.c extensions/app_diameap/plugins/eap_md5/CMakeLists.txt extensions/app_diameap/plugins/eap_md5/eap_md5.c extensions/app_diameap/plugins/eap_tls/CMakeLists.txt extensions/app_diameap/plugins/eap_tls/eap_tls.c extensions/app_diameap/plugins/eap_tls/eap_tls.h extensions/app_diameap/plugins/eap_tls/eaptls.l extensions/app_diameap/plugins/eap_tls/eaptls.y
diffstat 43 files changed, 9721 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/app_diameap.conf.sample	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,39 @@
+##### a sample Configuration file for DiamEAP
+
+# MySQL Database settings
+# Specify connection parameters for DiamEAP MySQL database: 
+# - username and password to connect to the MySQL Server
+# - databaseserver : the MySQL server location. It can be the IP address or the host name where MySQL server is located. 'localhost' can be used as the location if the server is locatd in the same host than DiamEAP.
+# - database_name : the created database for DiamEAP.
+
+# Syntax :
+# DiamEAP_MySQL = "<username>" , "<password>" , "<databaseserver>" , "<database_name>";
+
+
+
+##### Extensible Authentication Protocol (EAP) Methods Plugins #####
+# An EAP method is identified by its EAP method name, EAP TYPE, VENDOR and path to its EAP Method Plugin. 
+# Optionally, path to a configuration file of plugin can also be provided. 
+# Location of plugins and their configuration files can be provided by the absolute pathor the relative path from the location configured in cmake.
+# An EAP Method Plugin can not be loaded twice. Only the first added method will be loaded.
+# Any EAP Method plugin with a same EAP_TYPE value than an already loaded one will be discarded.
+# EAP Methods are added in the same order they are added to the the configuration file.
+ 
+# Syntax : 
+# Load_plugin = "<EAP method name>":EAP_TYPE:VENDOR:"<Path to EAP method >":"<Path to configuration file>";
+#
+# Example:
+# Load_plugin = "EAP identity":1:0:"/plugins/eap_identity.emp":"";
+# Load_plugin = "EAP tls":13:0;"/plugins/eap_tls.emp":"/plugins/eaptls.conf";
+
+
+# In addition to authentication DiamEAP can be configured to check authorization of authenticated users. If set to 0 authorization is disabled, otherwise enabled.( by default disabled).
+Authorization = 1;
+
+# This parameter specify the maximum number of seconds provided to the access device for responding to an EAP request. (by default set to 30 seconds)
+#Multi_Round_Time_Out=30;
+
+# After receivin a number of invalid EAP packets, DiamEAP reject the authentication by responding with Failure Authentication. 
+# The default value of maximum number of invalid EAP packets is set to 5 packets. 
+# The value of maximum invalid EAP packets can be modified by adding a new value.
+#MAX_Invalid_EAP_Packets=5;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/eap_tls_plugin.diameap.conf.sample	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,10 @@
+#### a sample configuration file for EAP-TLS
+
+#Certificate and Private key files
+#Cred = "<Path to certificate>" : "<Path to private Key>";
+
+#CA file
+#CA = "<Path to CA file>";
+
+#CRL file
+#CRL = "<Path to CRL file>";
--- a/extensions/CMakeLists.txt	Mon Jul 26 15:01:45 2010 +0900
+++ b/extensions/CMakeLists.txt	Mon Jul 26 18:00:24 2010 +0900
@@ -63,7 +63,10 @@
 	   SUBDIRS(app_sip)
 	ENDIF (BUILD_APP_SIP)
 
-
+OPTION(BUILD_APP_DIAMEAP "Build app_diameap? (Diameter EAP Application - RFC 4072 )" OFF)
+	IF (BUILD_APP_DIAMEAP)
+	   SUBDIRS(app_diameap)
+	ENDIF (BUILD_APP_DIAMEAP)
 
 ####
 # Routing extensions
--- a/extensions/app_diameap/CMakeLists.txt	Mon Jul 26 15:01:45 2010 +0900
+++ b/extensions/app_diameap/CMakeLists.txt	Mon Jul 26 18:00:24 2010 +0900
@@ -1,1 +1,49 @@
+# The Diameter EAP Application extension
+PROJECT("Diameter EAP Application extension" C)
 
+# Find MySQL 
+FIND_PACKAGE(MySQL REQUIRED)
+INCLUDE_DIRECTORIES(${MySQL_INCLUDE_DIR})
+
+# Parse plugins
+ADD_SUBDIRECTORY(plugins)
+
+# Parser 
+BISON_FILE(diameap.y)
+FLEX_FILE(diameap.l)
+SET_SOURCE_FILES_PROPERTIES(lex.diameap.c diameap.tab.c PROPERTIES COMPILE_FLAGS "-I \"${CMAKE_CURRENT_SOURCE_DIR}\"")
+
+
+set( diameapsrc
+    diameap_defs.h
+    diameap.h
+    diameap_server.h
+    diameap_plugins.h        
+    diameap_eap.h
+    plugins.h
+    diameap_eappacket.h
+    diameap_user.h
+    diameap.tab.h
+    diameap_init.h
+    diameap.tab.c
+    lex.diameap.c        
+    diameap.c
+    diameap_server.c
+    diameap_plugins.c
+    diameap_init.c
+    diameap_common.h
+    diameap_eappacket.c
+    libdiameap.h
+    diameap_eap.c
+    diameap_mysql.h
+    diameap_mysql.c
+    diameap_tls.h
+    diameap_tls.c
+    libcrypt.h
+    libcrypt.c
+    diameap_user.c
+)
+
+FD_ADD_EXTENSION(app_diameap ${diameapsrc})
+
+TARGET_LINK_LIBRARIES(app_diameap ${MySQL_LIBRARY})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/LICENSE	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,35 @@
+ Software License Agreement (BSD License)
+ Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+
+ Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ 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:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+ 2. 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.
+
+ 3. All advertising materials mentioning features or use of this software
+    must display the following acknowledgement:
+    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+
+ 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+ 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.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/README	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,117 @@
+DiamEAP (http://diameap.yagami.freediameter.net/)
+
+Copyright (c) 2009-2010 Souheil Ben Ayed, Teraoka Laboratory of Keio University and the WIDE Project.
+
+Author: Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+
+
+
+----- SUMMARY -----
+
+DiamEAP is an implementation of the Diameter Extensible Authentication Protocol (EAP) Application (RFC 4072).
+The Diameter protocol is a AAA protocol to securely carry Authentication, Authorization and Accounting informations between the AAA client and the AAA server.
+Diameter EAP Application is a Diameter application that supports authentication using Extensible Authentication Protocol (RFC 3748).  
+
+DiamEAP is designed to be extensible so that any new EAP method can be implemented separately as a shared library called 'EAP method plug-in'.
+Currently, DiamEAP comprises two EAP Methods plug-ins: 
+	- EAP MD5 plug-in : implementation of EAP-MD5 authentication method.
+	- EAP TLS plug-in : implementation of EAP-TLS authentication method .
+
+Other EAP methods are scheduled to be added in future releases. 	
+	
+DiamEAP is an extension for freeDiameter. Visit http://www.freediameter.net/ for more information on freeDiameter project.
+
+For more information on DiamEAP project, visit http://diameap.yagami.freediameter.net/
+
+
+
+----- REQUIREMENTS -----
+
+Some packages are required to compile DiamEAP from source.
+
+If you will install DiamEAP on Debian or Ubuntu system install the following packages: cmake flex bison libgnutls-dev libgcrypt-dev libmysqlclient-dev
+
+	$ sudo apt-get install cmake flex bison libgnutls-dev libgcrypt-dev libmysqlclient-dev
+
+
+
+----- INSTALLATION -----
+
+1- Add DiamEAP extension to freeDiameter. 
+	See freeDiameter documentation (http://www.freediameter.net/)
+
+2- Edit the extensions/CMakeList.txt file to add DiamEAP to freeDiameter.
+
+Add the following lines:
+   
+	  OPTION(BUILD_APP_DIAMEAP "Build DiamEAP? (Diameter EAP Application - RFC 4072)" OFF)
+	 	IF (BUILD_APP_DIAMEAP)
+	 	   ADD_SUBDIRECTORY(app_diameap)
+	 	ENDIF (BUILD_APP_DIAMEAP)
+
+Note: you can enable DiamEAP to be built with freeDiameter by setting the BUILD_APP_DIAMEAP to ON. If you enable it here you don't need to enable it when building freeDiameter.
+
+3- Enable DiamEAP by enabling BUILD_DIAMEAP option with CMake:
+
+cmake -DBUILD_DIAMEAP:BOOl=ON ../
+
+
+
+----- CONFIGURATION -----
+
+DiamEAP requires a configuration file to start the DiamEAP server. 
+It is advised to start by a copy of the sample file, and customize the configuration to fit your needs.
+A sample configuration file 'diameap.conf.sample' can be find in extensions/app_diameap/ or in doc/ folder of freeDiameter. 
+The file 'diameap.conf.sample' contains a description of all parameters that can be added to the DiamEAP configuration file.
+
+*Specify connection parameters to DiamEAP MySQL database:
+- username and password to connect to the MySQL Server
+- database server : address to MySQL server.
+- database name :  database for DiamEAP.
+
+Example:
+
+DiamEAP_MySQL = "UserName" , "MyPassword" , "localhost" , "drupal_ui";
+
+
+*Add EAP Method plug-ins to be loaded with DiamEAP server. Note that EAP Identity must be add.
+
+Example:
+
+Load_plugin = "EAP MD5":4:0:"extensions/app_diameap/plugins/eap_md5.emp":"";
+Load_plugin = "EAP TLS":13:0:"extensions/app_diameap/plugins/eap_tls.emp":"doc/eap_tls_plugin.app_diameap.conf";
+
+
+* Enable Authorization with DiamEAP.
+
+You can enable DiamEAP to check authorization of authenticated users. To enable authorization set authorization to 1. ( by default disabled).
+
+
+* Multiple round trips timeout
+
+This parameter indicates the maximum number of seconds provides the user to answer to a Diameter-EAP-Request. (by default set to 30 seconds)
+
+
+* Invalid EAP Packets
+
+This parameter defines the maximum number of invalid EAP packets that can be received before rejecting the connection. (by default set to 5 packets)
+
+
+For more documentation on configuring DiamEAP, visit the documentation page of the project : http://diameap.yagami.freediameter.net/documentation
+
+
+
+----- COPYRIGHT -----
+
+See LICENSE file for legal information on this software.
+
+
+
+----- CONTACT -----
+
+Author: Souheil Ben Ayed (souheil@tera.ics.keio.ac.jp)
+
+
+Current maintainers:
+-Souheil Ben Ayed (Teraoka Laboratory of Keio University) 	
+	souheil@tera.ics.keio.ac.jp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/diameap.c	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,85 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+#include "diameap_common.h"
+
+/* Define the entry point */
+EXTENSION_ENTRY("DiamEAP", diameap_main)
+;
+
+/* DiamEAP Configuration */
+static struct diameap_conf conf;
+struct diameap_conf * diameap_config = &conf;
+
+/* The entry point */
+static int diameap_main(char * conffile)
+{
+	TRACE_ENTRY("%p", conffile);
+
+	memset(diameap_config, 0, sizeof(struct diameap_conf));
+
+	/* Initialize configuration */
+	CHECK_FCT(diameap_init(conffile));
+
+	/* Start Diameter EAP Application (Back-end Authenticator ) */
+	CHECK_FCT(diameap_start_server());
+
+	/* Announce the support of Diameter EAP Application to other peers */
+	CHECK_FCT(fd_disp_app_support(dataobj_diameap_app, dataobj_diameap_ven, 1, 0));
+
+	TRACE_DEBUG(INFO,"%sDiameter EAP Application Extension started successfully.",DIAMEAP_EXTENSION);
+
+	return 0;
+}
+
+void fd_ext_fini(void)
+{
+	TRACE_DEBUG(FULL,"%sStopping the server",DIAMEAP_EXTENSION);
+	CHECK_FCT_DO(diameap_stop_server(),
+			{	TRACE_DEBUG(INFO,"%sStopping the server: Error occurred.",DIAMEAP_EXTENSION);});
+
+	if (db_conn)
+	{
+		TRACE_DEBUG(FULL,"%sDisconnecting from MySQL Server",DIAMEAP_EXTENSION);
+		diameap_mysql_disconnect();
+	}
+
+	TRACE_DEBUG(FULL,"%sUnloading EAP Methods plug-ins: Error occurred.",DIAMEAP_EXTENSION);
+	CHECK_FCT_DO(diameap_plugin_unload(),
+			{	TRACE_DEBUG(INFO,"%sUnloading EAP Methods plug-ins: Error occurred.",DIAMEAP_EXTENSION);});
+	return;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/diameap.h	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,76 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+
+#ifndef DIAMEAP_H_
+#define DIAMEAP_H_
+
+/* Structure to hold configuration of DiamEAP*/
+struct diameap_conf
+{
+	char *conffile; /* configuration file of the extension*/
+
+	int authorize; /* Set to 1 if provides Authorization. Otherwise set to 0. (by default set to 0)*/
+
+	u32 vendor_id; /* Vendor ID*/
+	u32 application_id; /* Diameter EAP Application ID. Value set to 5. */
+	u32 command_code; /* Diameter EAP Application Command Code. Value set to 268. */
+
+	char * diam_realm; /* Diameter realm of the peer */
+
+	/*Diameter EAP Server*/
+	int max_invalid_eap_packet;
+
+	//MySQL Database parameters
+
+	struct {
+		char *server;
+		char *user;
+		char *password;
+		char *database;
+	}db;
+
+	u32 multi_round_time_out;
+};
+
+/* The pointer to access DiamEAP configuration*/
+extern struct diameap_conf *diameap_config;
+
+/* Main function of DiamEAP extension */
+static int diameap_main(char * conffile);
+
+#endif /* DIAMEAP_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/diameap.l	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,124 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+
+
+/*Declarations and option settings*/
+%{
+#include <stdio.h>
+#include "diameap_common.h"
+#include "diameap.tab.h"
+ 
+#define YY_USER_ACTION { 						\
+	yylloc->first_line = yylloc->last_line = yylineno; \
+	yylloc->first_column = yylloc->last_column + 1; 		\
+	yylloc->last_column += yyleng +1;	\
+	}	
+ 
+%}
+
+
+
+%option noyywrap
+%option yylineno
+%option bison-bridge 
+%option bison-locations
+
+
+%%
+	/* List of patterns and actions */
+
+<*>\n			{				
+				yylloc->last_column=0; 
+				}
+
+<*>#.*$			{ }
+
+[ \t\n]+		{ 	
+			yylloc->last_column=0; 
+				/* ignore whitespace */ 
+			}
+
+\"([^\n\"]*)\"		{
+				yylval->str = strdup(yytext+1); /* Quoted String */
+				yylval->str[yyleng-2]='\0';
+				return iSTRING;
+			}
+
+
+[[:digit:]]+		{ 	/* Digital number */
+				yylval->val = atoi(yytext);
+				return NUM; /* Numeric value */ 
+			}
+
+(?i:"Load_Plugin")	{
+				return EAPMETHOD;
+			}
+
+(?i:"Authorization")		{ 
+				return AUTHORIZE;
+			}
+
+(?i:"DiamEAP_MySQL")		{ 
+				return DIAMEAP_MYSQL;
+			}
+			
+(?i:"MAX_Invalid_EAP_Packets")		{
+				return MAX_INVALID_EAP_PACKET;
+			}
+
+(?i:"Multi_Round_Time_Out")		{
+				return MULTI_ROUND_TIMEOUT;
+			}
+
+
+"="|";"|":"|","		{	
+				return yytext[0]; 
+			}
+
+	/* Unrecognized token or text */
+	
+<*>[[:alnum:]]+	 |					 
+<*>.	{ 
+				fprintf(stderr,"Unrecognized input text '%s'( on line %i column %i )\n", yytext, yylloc->first_line, yylloc->first_column); 
+			 	return LEX_ERROR; 
+			}
+
+%%
+/* Routines */
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/diameap.sql	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,52 @@
+#########################################################################
+#	diameap.sql							#
+#			DiamEAP extension				#
+#  		 Users Information Database schema           		#
+#  									#
+#  									#
+#									#
+# MySQL command to load the scrip:					#
+#    mysql> mysql -u username -p password diameap_ui <	diameap.sql	#
+#									#
+#########################################################################
+
+CREATE TABLE IF NOT EXISTS `authz` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `grp` int(11) NOT NULL,
+  `attribute` set('Service-Type','Callback-Number','Callback-Id','Idle-Timeout','Port-Limit','NAS-Filter-Rule','Filter-Id','Configuration-Token','QoS-Filter-Rule','Framed-Protocol','Framed-Routing','Framed-MTU','Framed-Compression','Framed-IP-Address','Framed-IP-Netmask','Framed-Route','Framed-Pool','Framed-Interface-Id','Framed-IPv6-Prefix','Framed-IPv6-Pool','Framed-IPv6-Route','Framed-IPX-Network','Framed-Appletalk-Link','Framed-Appletalk-Network','Framed-Appletalk-Zone') Not NULL DEFAULT 'Service-Type',
+  `op` set('==','>','>=','<','<=','!=','~=','=+','+==','+>','+>=','+<','+<=','+!=','+~=','==+','>+','>=+','<+','<=+','!=+') NOT NULL DEFAULT '==',
+  `value` char(255) NOT NULL,
+  PRIMARY KEY (`id`)
+);
+
+CREATE TABLE IF NOT EXISTS `authe` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `grp` int(11) NOT NULL,
+  `attribute` set('Authorization-Lifetime','Auth-Grace-Period','Auth-Session-State','Re-Auth-Request-Type','Session-Timeout','Multi-Round-Time-Out','Acct-Interim-Interval') NOT NULL DEFAULT 'Authorization-Lifetime',
+  `value` char(255) NOT NULL,
+  PRIMARY KEY (`id`)
+);
+
+CREATE TABLE IF NOT EXISTS `grp` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `grp_name` char(255) NOT NULL,
+  `active` set('Y','N') NOT NULL DEFAULT 'Y',
+  PRIMARY KEY (`id`)
+);
+
+CREATE TABLE IF NOT EXISTS `users` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `username` varchar(255) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
+  `eapmethod` tinyint(3) unsigned NOT NULL DEFAULT '0',
+  `vendor` int(11) NOT NULL DEFAULT '0',
+  `password` varchar(255) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
+  `active` enum('Y','N') CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL DEFAULT 'Y',
+  PRIMARY KEY (`id`)
+);
+
+CREATE TABLE IF NOT EXISTS `user_grp` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `user` int(11) NOT NULL,
+  `grp` int(11) NOT NULL,
+  PRIMARY KEY (`id`)
+);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/diameap.y	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,183 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+
+%{
+#include <stdio.h>
+#include "diameap_common.h"
+#include "diameap.tab.h"
+
+void yyerror (YYLTYPE *llocp, struct diameap_conf * config, const char *s);
+
+extern int yywrap();
+extern int yylex();
+
+
+/* The Lex parser prototype */
+int diameaplex(YYSTYPE *lvalp, YYLTYPE *llocp);
+
+
+%}
+
+%locations
+%parse-param {struct diameap_conf * config} 
+%pure_parser
+/*%defines */
+%error-verbose
+%debug 
+
+%union {
+	char *str;
+	int val;
+	char byte;
+}
+
+
+
+/* In case of error in the lexical analysis */
+%token 		LEX_ERROR
+
+%token 	<val>	NUM
+
+%token 	<str>	iSTRING
+
+%token  <byte>	iBYTE
+
+%token 		EAPMETHOD
+%token 		AUTHORIZE
+%token 		MODE
+%token 		DIAMEAP_MYSQL
+%token		MAX_INVALID_EAP_PACKET
+%token		MULTI_ROUND_TIMEOUT
+
+%%	
+
+confparams : 	/* empty */
+		| confparams EAPmethod
+		| confparams Authorize
+		| confparams DiamEAP_MySQL
+		| confparams MAX_Invalid_EAP_Packet
+		| confparams Multi_Round_Timeout
+		| confparams errors
+		{
+			yyerror(&yylloc, config, "Unrecognized configuration parameter.");
+			return EINVAL;
+		}
+		;
+
+errors :	LEX_ERROR
+		| error
+		;
+
+
+EAPmethod :	EAPMETHOD '=' iSTRING ':' NUM ':' NUM ':' iSTRING ':' iSTRING ';'
+		{
+		char * infile, *cfile;
+		FILE * fl;
+
+		infile = $9;
+		fl = fopen(infile, "r");
+		if ((fl == NULL) && (*infile != '/')) {
+			char * tmpfile=infile;
+			CHECK_MALLOC_DO( infile = malloc( strlen(tmpfile) + strlen(DEFAULT_EXTENSIONS_PATH) + 2 ),
+				{ yyerror (&yylloc, config, "Not enough memory"); YYERROR; } );
+			sprintf(infile, DEFAULT_EXTENSIONS_PATH "/%s", tmpfile);
+			free(tmpfile);
+			fl = fopen(infile, "r");
+		}
+		if (fl == NULL) {
+			int ret = errno;
+			TRACE_DEBUG(INFO, "Unable to open %s plugin file %s for reading: %s\n", $3, infile, strerror(ret));
+			yyerror (&yylloc, config, "Error adding EAP Plugin"); 
+			YYERROR;
+		}
+		fclose(fl);
+		
+		cfile = $11;
+
+		if(strlen(cfile)>0){
+			fl = fopen(cfile, "r");
+			if ((fl == NULL) && (*cfile != '/')) {
+				char * tmp = cfile;
+				CHECK_MALLOC_DO( cfile = malloc( strlen(tmp) + strlen(DEFAULT_EXTENSIONS_PATH) + 2 ),
+					{ yyerror (&yylloc, config, "Not enough memory"); YYERROR; } );
+				sprintf(cfile, DEFAULT_EXTENSIONS_PATH "/%s", tmp);
+				free(tmp);
+				fl = fopen(cfile, "r");
+			}
+			if (fl == NULL) {
+					
+			}
+			if(fl)
+				fclose(fl);
+		}		
+		
+		diameap_plugin_add($3,(char)$5,(char)$7,infile,cfile);
+		}
+		;
+
+Authorize :	AUTHORIZE '=' NUM ';'
+		{
+		if((int)$3)
+			config->authorize=1;
+		}
+		;
+			
+
+DiamEAP_MySQL :	DIAMEAP_MYSQL '=' iSTRING ',' iSTRING ',' iSTRING ',' iSTRING ';'
+		{
+		diameap_set_mysql_param($3,$5,$7,$9);
+		}
+		;
+
+MAX_Invalid_EAP_Packet : MAX_INVALID_EAP_PACKET '=' NUM ';'
+		{
+		config->max_invalid_eap_packet=(int)$3;
+		};
+
+Multi_Round_Timeout : MULTI_ROUND_TIMEOUT '=' NUM ';'
+		{
+		config->multi_round_time_out=(unsigned int)$3;
+		};
+				
+		
+%%
+
+void yyerror(YYLTYPE *llocp, struct diameap_conf * config,const char *str)
+{
+         fprintf(stderr,"Error in %s ( on line %i column %i -> line %i column %i) : %s\n",config->conffile, llocp->first_line, llocp->first_column, llocp->last_line, llocp->last_column, str);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/diameap_common.h	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,128 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+
+#ifndef DIAMEAP_COMMON_H_
+#define DIAMEAP_COMMON_H_
+
+#include "libdiameap.h"
+#include "libcrypt.h"
+#include "diameap.h"
+#include "diameap_plugins.h"
+#include "diameap_init.h"
+#include "diameap_eap.h"
+#include "diameap_server.h"
+#include <regex.h>
+
+
+
+/* Dictionary Object templates */
+extern struct dict_object * dataobj_diameap_cmd; /* Diameter-EAP-Request Command Code */
+extern struct dict_object * dataobj_diameap_app; /* Diameter EAP Application object */
+extern struct dict_object * dataobj_diameap_ven; /* Diameter EAP Application Vendor object */
+extern struct dict_object * dataobj_accounting_eap_auth_method;
+extern struct dict_object * dataobj_acct_interim_interval;
+extern struct dict_object * dataobj_auth_application_id;
+extern struct dict_object * dataobj_auth_grace_period;
+extern struct dict_object * dataobj_auth_request_type;
+extern struct dict_object * dataobj_auth_session_state;
+extern struct dict_object * dataobj_authorization_lifetime;
+extern struct dict_object * dataobj_callback_id;
+extern struct dict_object * dataobj_callback_number;
+extern struct dict_object * dataobj_called_station_id;
+extern struct dict_object * dataobj_calling_station_id;
+extern struct dict_object * dataobj_class;
+extern struct dict_object * dataobj_configuration_token;
+extern struct dict_object * dataobj_connect_info;
+extern struct dict_object * dataobj_destination_host;
+extern struct dict_object * dataobj_destination_realm;
+extern struct dict_object * dataobj_eap_master_session_key;
+extern struct dict_object * dataobj_eap_key_name;
+extern struct dict_object * dataobj_eap_payload;
+extern struct dict_object * dataobj_eap_reissued_payload;
+extern struct dict_object * dataobj_error_message;
+extern struct dict_object * dataobj_error_reporting_host;
+extern struct dict_object * dataobj_failed_avp;
+extern struct dict_object * dataobj_filter_id;
+extern struct dict_object * dataobj_framed_appletalk_link;
+extern struct dict_object * dataobj_framed_appletalk_network;
+extern struct dict_object * dataobj_framed_appletalk_zone;
+extern struct dict_object * dataobj_framed_compression;
+extern struct dict_object * dataobj_framed_interface_id;
+extern struct dict_object * dataobj_framed_ip_address;
+extern struct dict_object * dataobj_framed_ip_netmask;
+extern struct dict_object * dataobj_framed_ipv6_prefix;
+extern struct dict_object * dataobj_framed_ipv6_pool;
+extern struct dict_object * dataobj_framed_ipv6_route;
+extern struct dict_object * dataobj_framed_ipx_network;
+extern struct dict_object * dataobj_framed_mtu;
+extern struct dict_object * dataobj_framed_pool;
+extern struct dict_object * dataobj_framed_protocol;
+extern struct dict_object * dataobj_framed_route;
+extern struct dict_object * dataobj_framed_routing;
+extern struct dict_object * dataobj_idle_timeout;
+extern struct dict_object * dataobj_multi_round_time_out;
+extern struct dict_object * dataobj_nas_filter_rule;
+extern struct dict_object * dataobj_nas_identifier;
+extern struct dict_object * dataobj_nas_ip_address;
+extern struct dict_object * dataobj_nas_ipv6_address;
+extern struct dict_object * dataobj_nas_port;
+extern struct dict_object * dataobj_nas_port_id;
+extern struct dict_object * dataobj_nas_port_type;
+extern struct dict_object * dataobj_originating_line_info;
+extern struct dict_object * dataobj_origin_host;
+extern struct dict_object * dataobj_origin_realm;
+extern struct dict_object * dataobj_origin_state_id;
+extern struct dict_object * dataobj_port_limit;
+extern struct dict_object * dataobj_proxy_info;
+extern struct dict_object * dataobj_qos_filter_rule;
+extern struct dict_object * dataobj_re_auth_request_type;
+extern struct dict_object * dataobj_redirect_host;
+extern struct dict_object * dataobj_redirect_host_usage;
+extern struct dict_object * dataobj_redirect_max_cache_time;
+extern struct dict_object * dataobj_reply_message;
+extern struct dict_object * dataobj_result_code;
+extern struct dict_object * dataobj_route_record;
+extern struct dict_object * dataobj_service_type;
+extern struct dict_object * dataobj_session_id;
+extern struct dict_object * dataobj_session_timeout;
+extern struct dict_object * dataobj_state;
+extern struct dict_object * dataobj_tunneling;
+extern struct dict_object * dataobj_user_name;
+
+
+#endif /* DIAMEAP_COMMON_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/diameap_defs.h	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,220 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+
+#ifndef DIAMEAP_DEFS_H_
+#define DIAMEAP_DEFS_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+
+/************************************************/
+/*		Data Type Definition 					*/
+/************************************************/
+
+/* boolean Type */
+typedef enum
+{
+	FALSE = 0, TRUE = 1
+} boolean;
+
+/* Exact-width integer types */
+typedef int8_t s8;		/* signed char */
+typedef uint8_t u8;		/* unsigned char */
+typedef int16_t s16;	/* signed int */
+typedef uint16_t u16;	/* unsigned int */
+typedef int32_t s32;	/* signed long int */
+typedef uint32_t u32;	/* unsigned long int */
+typedef int64_t s64;	/* signed long long int */
+typedef uint64_t u64;	/* unsigned long long int */
+
+/************************************************/
+/*		Macros									*/
+/************************************************/
+
+/* Macros for manipulating data*/
+
+/* Retrieve signed/unsigned exact-width integer types */
+#define G8(v) (u8) (* (v) )
+
+#define G16BIGE(v) ( 	( (u16) (* (v)   ) <<  8 ) ^ \
+		      	( (u16) (*((v)+1))       ) )
+#define G16LITE(v) (	( (u16) (*((v)+1)) <<  8 ) ^ \
+		      	( (u16) (* (v)   )       ) )
+
+#define G24BIGE(v) (	( (u32) (* (v)   ) << 16 ) ^ \
+			( (u32) (*((v)+1)) <<  8 ) ^ \
+			( (u32) (*((v)+2))       ) )
+#define G24LITE(v) ( 	( (u32) (*((v)+2)) << 16 ) ^ \
+			( (u32) (*((v)+1)) <<  8 ) ^ \
+			( (u32) (* (v)   )       ) )
+
+#define G32BIGE(v) ( 	( (u32) (* (v)   ) << 24 ) ^ \
+			( (u32) (*((v)+1)) << 16 ) ^ \
+			( (u32) (*((v)+2)) <<  8 ) ^ \
+			( (u32) (*((v)+3))       ) )
+#define G32LITE(v) (	( (u32) (*((v)+3)) << 24 ) ^ \
+			( (u32) (*((v)+2)) << 16 ) ^ \
+			( (u32) (*((v)+1)) <<  8 ) ^ \
+			( (u32) (* (v)   )       ) )
+
+#define G64BIGE(v) ( 	( (u64) (* (v)   ) << 56 ) ^ \
+			( (u64) (*((v)+1)) << 48 ) ^ \
+			( (u64) (*((v)+2)) << 40 ) ^ \
+			( (u64) (*((v)+3)) << 32 ) ^ \
+			( (u64) (*((v)+4)) << 24 ) ^ \
+			( (u64) (*((v)+5)) << 16 ) ^ \
+			( (u64) (*((v)+6)) <<  8 ) ^ \
+			( (u64) (*((v)+7))       ) )
+#define G64LITE(v) (	( (u64) (*((v)+7)) << 56 ) ^ \
+			( (u64) (*((v)+6)) << 48 ) ^ \
+			( (u64) (*((v)+5)) << 40 ) ^ \
+			( (u64) (*((v)+4)) << 32 ) ^ \
+			( (u64) (*((v)+3)) << 24 ) ^ \
+			( (u64) (*((v)+2)) << 16 ) ^ \
+			( (u64) (*((v)+1)) <<  8 ) ^ \
+			( (u64) (* (v)   )       ) )
+
+/* Insert signed/unsigned exact-width integer types */
+/* v : pointer where to insert the data
+ * b : pointer of data to be inserted
+ */
+/* Insertion format
+ * BIGE : BIG ENDIAN
+ * LITE : LITTLE ENDIAN
+ */
+
+#define P8(v,b) do { \
+		u8 x = (b); \
+		u8 *d = (v); \
+		d[0] = (x&0xffU); \
+	} while (0)
+
+#define P16BIGE(v,b) do { \
+		u16 x = (b); \
+		u8 *d = (v); \
+		d[0] = ((x >> 8)&0xffU); \
+		d[1] = (x&0xffU); \
+	} while (0)
+
+#define P16LITE(v,b) do { \
+		u16 x = (b); \
+		u8 *d = (v); \
+		d[0] = (x&0xffU); \
+		d[1] = ((x >> 8)&0xffU); \
+	} while (0)
+
+#define P24BIGE(v, b)  do { \
+		u32 x = (b); \
+		u8 *d = (v); \
+		d[0] = ((x >> 16)&0xffU); \
+		d[1] = ((x >> 8)&0xffU); \
+		d[2] = ((x)&0xffU); \
+	} while (0)
+
+#define P24LITE(v, b)  do { \
+		u32 x = (b); \
+		u8 *d = (v); \
+		d[0] = ((x)&0xffU); \
+		d[1] = ((x >> 8)&0xffU); \
+		d[2] = ((x >> 16)&0xffU); \
+	} while (0)
+
+#define P32BIGE(v, b)  do { \
+		u32 x = (b); \
+		u8 *d = (v); \
+		d[0] = ((x >> 24)&0xffU); \
+		d[1] = ((x >> 16)&0xffU); \
+		d[2] = ((x >> 8)&0xffU); \
+		d[3] = ((x)&0xffU); \
+	} while (0)
+
+#define P32LITE(v, b)  do { \
+		u32 x = (b); \
+		u8 *d = (v); \
+		d[0] = ((x)&0xffU); \
+		d[1] = ((x >> 8)&0xffU); \
+		d[2] = ((x >> 16)&0xffU); \
+		d[3] = ((x >> 24)&0xffU); \
+	} while (0)
+
+#define P64BIGE(v, b) do { \
+		u64 x = (b); \
+		u8 *d = (v); \
+		d[0] = ((x >> 56)&0xffU); \
+		d[1] = ((x >> 48)&0xffU); \
+		d[2] = ((x >> 40)&0xffU); \
+		d[3] = ((x >> 32)&0xffU); \
+		d[4] = ((x >> 24)&0xffU); \
+		d[5] = ((x >> 16)&0xffU); \
+		d[6] = ((x >> 8)&0xffU); \
+		d[7] = ((x)&0xffU); \
+	} while (0)
+
+#define P64LITE(v, b) do { \
+		u64 x = (b); \
+		u8 *d = (v); \
+		d[0] = ((x)&0xffU); \
+		d[1] = ((x >> 8)&0xffU); \
+		d[2] = ((x >> 16)&0xffU); \
+		d[3] = ((x >> 24)&0xffU); \
+		d[4] = ((x >> 32)&0xffU); \
+		d[5] = ((x >> 40)&0xffU); \
+		d[6] = ((x >> 48)&0xffU); \
+		d[7] = ((x >> 56)&0xffU); \
+	} while (0)
+
+/*
+ * Insert data in a specified position
+ * a : (u8*) pointer where to insert the data
+ * f : (int) insert from this position
+ * l : (int) length of the data in byte to insert
+ * b : (u8*) pointer of data to be inserted
+ */
+
+#define U8COPY(a,f,l,b) do{ \
+			u8 * x = (a); \
+			u8 * y = (b); \
+			int i; \
+			for(i=0;i<l;i++) \
+			x[i+f]= y[i]; \
+		} while (0)
+
+
+#endif /*DIAMEAP_DEFS_H_*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/diameap_eap.c	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,596 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+#include "diameap_common.h"
+
+int diameap_eap_statemachine(struct eap_state_machine * eap_sm,
+		struct diameap_eap_interface * eap_i, boolean * non_fatal_error)
+{
+	TRACE_ENTRY("%p %p %p", eap_sm, eap_i, non_fatal_error);
+	int ret;
+
+	if ((eap_sm->eap_state == EAP_IDLE) && (eap_i->aaaEapResp == TRUE))
+	{
+		eap_sm->eap_state = EAP_RECEIVED;
+	}
+	while (!((eap_sm->eap_state == EAP_IDLE) || (eap_sm->eap_state == EAP_END)))
+	{
+		switch (eap_sm->eap_state)
+		{
+		case EAP_INITIALIZE:
+			if (eap_sm->rxResp == TRUE)
+			{
+				eap_sm->lastId = eap_sm->currentId;
+				eap_sm->currentId = eap_sm->respId;
+			}
+			else
+			{
+				eap_sm->lastId = -1;
+				eap_sm->currentId = -1;
+			}
+			if (eap_sm->rxResp == FALSE)
+			{
+				eap_sm->eap_state = EAP_SELECT_ACTION;
+			}
+			else if ((eap_sm->respMethod == TYPE_NAK) || (eap_sm->respMethod
+					== TYPE_EXPANDED_TYPES && eap_sm->respVendor == VENDOR_IETF
+					&& eap_sm->respVendorMethod == TYPE_NAK))
+			{
+				eap_sm->eap_state = EAP_NAK;
+			}
+			else
+			{
+				eap_sm->eap_state = EAP_PICK_UP_METHOD;
+			}
+			break;
+		case EAP_PICK_UP_METHOD:
+			if (diameap_ba_policydopickup(eap_sm->respMethod) == TRUE)
+			{
+				eap_sm->currentMethod = eap_sm->respMethod;
+
+				if (diameap_plugin_get(eap_sm->currentVendor,
+						eap_sm->currentMethod, &eap_sm->selectedMethod))
+				{
+					TRACE_DEBUG(INFO,"%sNo EAP Method plugin available for EAP Method {Type=%d, Vendor=%d}.",DIAMEAP_EXTENSION,eap_sm->currentMethod, eap_sm->currentVendor);
+				}
+				else
+				{
+					TRACE_DEBUG(FULL,"%sCurrent EAP Method {Type=%d, Vendor=%d} (EAP Method plugin selected).",DIAMEAP_EXTENSION,eap_sm->currentMethod, eap_sm->currentVendor);
+				}
+				eap_sm->currentVendor = VENDOR_IETF;
+				if (eap_sm->selectedMethod != NULL)
+				{
+					ret = (*eap_sm->selectedMethod->eap_method_initPickUp)(
+							eap_sm);
+					if (ret)
+					{
+						TRACE_DEBUG(INFO, "%sEAP Method InitPickUp returned error.",DIAMEAP_EXTENSION);
+						eap_sm->selectedMethod = NULL;
+						eap_sm->currentMethod = TYPE_NONE;
+					}
+				}
+			}
+			if (eap_sm->currentMethod == TYPE_NONE)
+			{
+				eap_sm->eap_state = EAP_SELECT_ACTION;
+			}
+			else
+			{
+				eap_sm->eap_state = EAP_METHOD_RESPONSE;
+			}
+			break;
+
+		case EAP_RECEIVED:
+			TRACE_DEBUG(FULL+1,"%s[EAP Protocol] New EAP Response received",DIAMEAP_EXTENSION)
+			;
+			diameap_eap_dump(FULL + 1, eap_i->aaaEapRespData);
+			if ((eap_sm->rxResp == TRUE) && (eap_sm->respId
+					== eap_sm->currentId) && ((eap_sm->respMethod
+					== eap_sm->currentMethod) || ((eap_sm->respMethod
+					== TYPE_EXPANDED_TYPES) && (eap_sm->respVendor
+					== VENDOR_IETF) && (eap_sm->respVendorMethod
+					== eap_sm->currentMethod))))
+			{
+				eap_sm->eap_state = EAP_INTEGRITY_CHECK;
+			}
+			else if ((eap_sm->rxResp == TRUE) && (eap_sm->respId
+					== eap_sm->currentId) && ((eap_sm->respMethod == TYPE_NAK)
+					|| (eap_sm->respMethod == TYPE_EXPANDED_TYPES
+							&& eap_sm->respVendor == VENDOR_IETF
+							&& eap_sm->respVendorMethod == TYPE_NAK))
+					&& (eap_sm->methodState == EAP_M_PROPOSED))
+			{
+				eap_sm->eap_state = EAP_NAK;
+			}
+			else
+			{
+				eap_sm->eap_state = EAP_DISCARD;
+			}
+			break;
+		case EAP_DISCARD:
+			TRACE_DEBUG(INFO,"%s[EAP Protocol] Invalid EAP Packet received (Non fatal error).",DIAMEAP_EXTENSION)
+			;
+			*non_fatal_error = TRUE;
+			eap_sm->eap_state = EAP_IDLE;
+			break;
+
+		case EAP_SEND_REQUEST:
+			TRACE_DEBUG(FULL+1,"%s[EAP Protocol] New EAP packet request created.",DIAMEAP_EXTENSION)
+			;
+			diameap_eap_dump(FULL, eap_i->aaaEapReqData);
+			eap_i->aaaEapResp = FALSE;
+			eap_i->aaaEapReq = TRUE;
+			eap_sm->eap_state = EAP_IDLE;
+			break;
+
+		case EAP_INTEGRITY_CHECK:
+			if ((*eap_sm->selectedMethod->eap_method_check)(eap_sm,
+					eap_i->aaaEapRespData) == FALSE)
+			{
+				TRACE_DEBUG(INFO,"%s[EAP Protocol] Invalid EAP packet received {Type=%d, Vendor=%d}. Integrity check failed (non fatal error).",DIAMEAP_EXTENSION,eap_sm->currentMethod,eap_sm->currentVendor);
+				//non_fata_error
+				*non_fatal_error = TRUE;
+				eap_sm->eap_state = EAP_IDLE;
+			}
+			else
+			{
+				eap_sm->eap_state = EAP_METHOD_RESPONSE;
+			}
+
+			break;
+		case EAP_METHOD_REQUEST:
+			eap_sm->lastId = eap_sm->currentId;
+			diameap_ba_nextid(eap_sm, &eap_sm->currentId);
+			CHECK_FCT((*eap_sm->selectedMethod->eap_method_buildReq)(
+							eap_sm, eap_sm->currentId,&eap_i->aaaEapReqData))
+			;
+			if (eap_sm->selectedMethod->eap_method_getTimeout)
+			{
+				if ((*eap_sm->selectedMethod->eap_method_getTimeout)(eap_sm,
+						&eap_i->aaaMethodTimeout))
+				{
+					TRACE_DEBUG(INFO,"%s[EAP Protocol] [%s plugin] getTimeout failed.",DIAMEAP_EXTENSION,eap_sm->selectedMethod->methodname);
+					eap_i->aaaMethodTimeout = 0;
+				}
+			}
+			else
+			{
+				eap_i->aaaMethodTimeout = 0;
+			}
+			eap_sm->eap_state = EAP_SEND_REQUEST;
+			break;
+
+		case EAP_METHOD_RESPONSE:
+			if (eap_sm->respMethod >= TYPE_EAP_MD5)
+			{
+				if (eap_sm->user.methodId < 0)
+				{
+					eap_sm->user.methodId = 0;
+					eap_sm->user.methods[eap_sm->user.methodId].vendor
+							= eap_sm->respVendor;
+					eap_sm->user.methods[eap_sm->user.methodId].method
+							= eap_sm->respMethod;
+					eap_sm->user.methodId++;
+
+				}
+				else if (!((eap_sm->user.methods[eap_sm->user.methodId - 1].vendor
+						== eap_sm->respVendor)
+						&& (eap_sm->user.methods[eap_sm->user.methodId - 1].method
+								== eap_sm->respMethod)))
+				{
+					eap_sm->user.methods[eap_sm->user.methodId].vendor
+							= eap_sm->respVendor;
+					eap_sm->user.methods[eap_sm->user.methodId].method
+							= eap_sm->respMethod;
+					eap_sm->user.methodId++;
+				}
+			}
+			if ((*eap_sm->selectedMethod->eap_method_process)(eap_sm,
+					eap_i->aaaEapRespData))
+			{
+				TRACE_DEBUG(INFO,"%s[EAP Protocol] [%s plugin] Authentication process failed.",DIAMEAP_EXTENSION,eap_sm->selectedMethod->methodname);
+				*non_fatal_error = TRUE;
+				eap_sm->eap_state = EAP_IDLE;
+
+			}else{
+			if ((*eap_sm->selectedMethod->eap_method_isDone)(eap_sm) == TRUE)
+			{
+				/*diameap_ba_PolicyUpdate();*/
+				eap_i->aaaEapKeyLength = 0;
+				if (eap_sm->selectedMethod->eap_method_getKey)
+				{
+					if ((*eap_sm->selectedMethod->eap_method_getKey)(eap_sm,
+							&eap_i->aaaEapKeyData, &eap_i->aaaEapKeyLength))
+					{
+						TRACE_DEBUG(INFO,"%s[EAP Protocol] Generating EAP Master Key failed.",DIAMEAP_EXTENSION,eap_sm->selectedMethod->methodname)
+						eap_i->aaaEapKeyLength = 0;
+						eap_i->aaaEapKeyAvailable = FALSE;
+					}
+					else
+					{
+						eap_i->aaaEapKeyAvailable = TRUE;
+					}
+				}
+				eap_sm->methodState = EAP_M_END;
+				eap_sm->eap_state = EAP_SELECT_ACTION;
+			}
+			else
+			{
+				eap_sm->methodState = EAP_M_CONTINUE;
+				eap_sm->eap_state = EAP_METHOD_REQUEST;
+			}
+			}
+			break;
+		case EAP_PROPOSE_METHOD:
+			if (diameap_ba_policygetnextmethod(eap_sm, &eap_sm->currentMethod,
+					&eap_sm->currentVendor))
+			{
+				TRACE_DEBUG(INFO,"%s[EAP Protocol] Selecting EAP Method plugin failed.",DIAMEAP_EXTENSION,eap_sm->selectedMethod->methodname);
+
+				*non_fatal_error = TRUE;
+				eap_sm->eap_state = EAP_END;
+
+			}
+			TRACE_DEBUG(FULL,"%s[EAP Protocol] Selecting EAP Method plugin: %s(%d). [user: %s]",DIAMEAP_EXTENSION,eap_sm->selectedMethod->methodname,eap_sm->selectedMethod->methodtype,eap_sm->user.userid)
+			;
+			if ((*eap_sm->selectedMethod->eap_method_init)(eap_sm))
+			{
+				TRACE_DEBUG(INFO,"%s[EAP Protocol] [%s plugin] Initializing EAP plugin failed.",DIAMEAP_EXTENSION,eap_sm->selectedMethod->methodname);
+			}
+
+			if ((eap_sm->currentMethod == TYPE_IDENTITY)
+					|| (eap_sm->currentMethod == TYPE_NOTIFICATION))
+			{
+				eap_sm->methodState = EAP_M_CONTINUE;
+			}
+			else
+			{
+				eap_sm->methodState = EAP_M_PROPOSED;
+			}
+			eap_sm->eap_state = EAP_METHOD_REQUEST;
+			break;
+		case EAP_NAK:
+			TRACE_DEBUG(FULL+1,"%s[EAP Protocol] EAP NAK Packet received.",DIAMEAP_EXTENSION)
+			;
+			if (eap_sm->selectedMethod->eap_method_free)
+			{
+				(*eap_sm->selectedMethod->eap_method_free)(eap_sm->methodData);
+				eap_sm->methodData = NULL;
+			}
+			else
+			{
+				if (eap_sm->methodData)
+				{
+					free(eap_sm->methodData);
+					eap_sm->methodData = NULL;
+				}
+			}
+			diameap_ba_policyupdate(eap_sm, eap_i->aaaEapRespData);
+			eap_sm->eap_state = EAP_SELECT_ACTION;
+			break;
+		case EAP_SELECT_ACTION:
+			CHECK_FCT(diameap_ba_policygetdecision(eap_sm, eap_i,&eap_sm->sm_decision))
+			;
+			switch (eap_sm->sm_decision)
+			{
+			case DECISION_CONTINUE:
+				eap_sm->eap_state = EAP_PROPOSE_METHOD;
+				break;
+			case DECISION_FAILURE:
+				TRACE_DEBUG(FULL,"%s[EAP Protocol] Authentication Failure [User: %s].",DIAMEAP_EXTENSION,eap_sm->user.userid)
+				;
+				eap_sm->lastId = eap_sm->currentId;
+				diameap_ba_nextid(eap_sm, &eap_sm->currentId);
+				CHECK_FCT(diameap_eap_new(EAP_FAILURE, (u8) eap_sm->currentId, TYPE_NONE, NULL, 0,&eap_i->aaaEapReqData))
+				;
+				eap_i->aaaFail = TRUE;
+				*non_fatal_error = FALSE;
+				eap_sm->eap_state = EAP_END;
+				if (eap_sm->methodData)
+				{
+					if (eap_sm->selectedMethod->eap_method_free)
+					{
+						(*eap_sm->selectedMethod->eap_method_free)(
+								eap_sm->methodData);
+						eap_sm->methodData = NULL;
+					}
+					else
+					{
+						free(eap_sm->methodData);
+						eap_sm->methodData = NULL;
+					}
+				}
+				break;
+			case DECISION_SUCCESS:
+				TRACE_DEBUG(FULL,"%s[EAP Protocol] Authentication Success [User: %s].",DIAMEAP_EXTENSION,eap_sm->user.userid)
+				;
+				eap_sm->lastId = eap_sm->currentId;
+				diameap_ba_nextid(eap_sm, &eap_sm->currentId);
+				CHECK_FCT(diameap_eap_new(EAP_SUCCESS, (u8) eap_sm->currentId, TYPE_NONE, NULL, 0,&eap_i->aaaEapReqData))
+				;
+				if (eap_i->aaaEapKeyData != NULL)
+				{
+					TRACE_DEBUG(FULL+1,"%s[EAP Protocol] EAP Key available [User: %s].",DIAMEAP_EXTENSION,eap_sm->user.userid);
+					eap_i->aaaEapKeyAvailable = TRUE;
+				}
+				else
+				{
+					TRACE_DEBUG(FULL+1,"%s[EAP Protocol] No EAP Key available [User: %s].",DIAMEAP_EXTENSION,eap_sm->user.userid);
+				}
+				eap_i->aaaSuccess = TRUE;
+				*non_fatal_error = FALSE;
+				eap_sm->eap_state = EAP_END;
+				if (eap_sm->selectedMethod->eap_method_free)
+				{
+					(*eap_sm->selectedMethod->eap_method_free)(
+							eap_sm->methodData);
+					eap_sm->methodData = NULL;
+				}
+				else
+				{
+					if (eap_sm->methodData)
+					{
+						free(eap_sm->methodData);
+						eap_sm->methodData = NULL;
+					}
+				}
+				break;
+			default:
+				TRACE_DEBUG(INFO,"%sIncorrect EAP Decision.(Please report this problem.)",DIAMEAP_EXTENSION)
+				;
+			}
+			break;
+		case EAP_END:
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static void diameap_ba_nextid(struct eap_state_machine * sm, int * id)
+{
+	TRACE_ENTRY("%p %p",sm,id);
+
+	if (sm->currentId < 0)
+	{
+		*id = (u8) (255 * rand() / RAND_MAX) & 0xFFU;
+	}
+	else
+	{
+		*id = (sm->currentId++) & 0xFFU;
+	}
+	if (*id == sm->lastId)
+	{
+		*id++;
+	}
+}
+
+static void diameap_ba_policyupdate(struct eap_state_machine * eap_sm,
+		struct eap_packet eapPacket)
+{
+	TRACE_ENTRY("%p %p",eap_sm, eapPacket);
+	if ((eap_sm->respMethod == TYPE_NAK))
+	{
+		int id;
+		eap_sm->user.pmethods = 0;
+		u32 vendor;
+		eap_type type;
+		u8 *data = (u8 *) eapPacket.data;
+		data += 5;
+		id = 5;
+		while (id < eapPacket.length)
+		{
+			vendor = VENDOR_IETF;
+			type = G8(data);
+			if (diameap_plugin_exist(vendor, type) == TRUE)
+			{
+				eap_sm->user.proposedmethods[id - 5].method = type;
+				eap_sm->user.proposedmethods[id - 5].vendor = vendor;
+				eap_sm->user.pmethods++;
+			}
+			data++;
+			id++;
+		}
+		eap_sm->user.methodId = -1;
+	}
+}
+
+static int diameap_ba_policygetnextmethod(struct eap_state_machine * eap_sm,
+		eap_type * eaptype, u32 * vendor)
+{
+	TRACE_ENTRY("%p %p %p",eap_sm,eaptype,vendor);
+	*vendor = 0;
+	*eaptype = TYPE_NONE;
+	eap_sm->selectedMethod = NULL;
+
+	if (eap_sm == NULL)
+	{
+		return EINVAL;
+	}
+
+	if (eap_sm->user.userid == NULL)
+	{
+		if ((eap_sm->currentMethod == TYPE_NONE))
+		{
+			*vendor = VENDOR_IETF;
+			*eaptype = TYPE_IDENTITY;
+			if (eap_sm->selectedMethod != NULL)
+			{
+				(*eap_sm->selectedMethod->eap_method_free)(eap_sm->methodData);
+				eap_sm->methodData = NULL;
+			}
+			CHECK_FCT(diameap_plugin_get(VENDOR_IETF,TYPE_IDENTITY,&eap_sm->selectedMethod));
+			return 0;
+		}
+
+		eap_sm->selectedMethod = NULL;
+		*vendor = 0;
+		*eaptype = TYPE_NONE;
+		return 0;
+	}
+
+	if (eap_sm->user.methodId == -1)
+	{
+		if (eap_sm->user.proposed_eap_method >= TYPE_EAP_MD5)
+		{
+			*vendor = eap_sm->user.proposed_eap_method_vendor;
+			if (*vendor == VENDOR_IETF)
+			{
+				*eaptype = eap_sm->user.proposed_eap_method;
+			}
+			else
+			{
+				*eaptype = TYPE_EXPANDED_TYPES;
+			}
+			if (eap_sm->selectedMethod != NULL)
+			{
+				(*eap_sm->selectedMethod->eap_method_free)(eap_sm->methodData);
+				eap_sm->methodData = NULL;
+			}
+			CHECK_FCT_DO(diameap_plugin_get(*vendor,*eaptype,&eap_sm->selectedMethod),
+					{	TRACE_DEBUG(INFO,"%s [EAP Protocol] Invalid EAP-TYPE %d (vendor %d)",DIAMEAP_EXTENSION,*eaptype,*vendor);return 1;});
+
+		}
+		eap_sm->user.proposed_eap_method = TYPE_NONE;
+	}
+	else
+	{
+		*vendor = eap_sm->user.proposedmethods[eap_sm->user.methodId].vendor;
+		if (eap_sm->user.proposedmethods[eap_sm->user.methodId].vendor
+				== VENDOR_IETF)
+		{
+			*eaptype
+					= eap_sm->user.proposedmethods[eap_sm->user.methodId].method;
+		}
+		else
+		{
+			*eaptype = TYPE_EXPANDED_TYPES;
+		}
+		if (eap_sm->selectedMethod != NULL)
+		{
+			(*eap_sm->selectedMethod->eap_method_free)(eap_sm->methodData);
+			eap_sm->methodData;
+		}
+		CHECK_FCT(diameap_plugin_get(eap_sm->user.proposedmethods[eap_sm->user.methodId].vendor,eap_sm->user.proposedmethods[eap_sm->user.methodId].method,&eap_sm->selectedMethod));
+
+		eap_sm->user.methodId++;
+	}
+
+	return 0;
+}
+
+static int diameap_ba_policygetdecision(struct eap_state_machine * eap_sm,
+		struct diameap_eap_interface * eap_i, decision * gdecision)
+{
+	TRACE_ENTRY("%p %p %p",eap_sm,eap_i,gdecision);
+
+	if (eap_sm->user.userid != NULL)
+	{
+
+		if (eap_sm->methodState == EAP_M_END)
+		{
+
+			if (eap_sm->respMethod == TYPE_IDENTITY)
+			{
+
+				*gdecision = DECISION_CONTINUE;
+				return 0;
+			}
+
+			if ((eap_sm->respMethod == TYPE_NAK) || ((eap_sm->respMethod
+					== TYPE_EXPANDED_TYPES) && (eap_sm->respVendor
+					== VENDOR_IETF) && (eap_sm->respVendorMethod == TYPE_NAK)))
+			{
+				goto SelectNextMethod;
+			}
+
+			if (eap_sm->user.success == TRUE)
+			{
+
+				*gdecision = DECISION_SUCCESS;
+			}
+			else
+			{
+
+				*gdecision = DECISION_FAILURE;
+			}
+
+		}
+		else
+		{
+			goto SelectNextMethod;
+		}
+		return 0;
+
+		SelectNextMethod: if ((eap_sm->user.methodId
+				== (MAXPROPOSEDMETHODS - 1))
+				|| ((eap_sm->user.proposedmethods[eap_sm->user.methodId + 1].method
+						== TYPE_NONE)
+						&& (eap_sm->user.proposedmethods[eap_sm->user.methodId
+								+ 1].vendor == VENDOR_IETF)))
+		{
+			TRACE_DEBUG(FULL+1,
+					"%s [EAP protocol] None of proposed EAP Methods authenticated the user.(FAILURE)",DIAMEAP_EXTENSION);
+			*gdecision = DECISION_FAILURE;
+			return 0;
+		}
+
+		eap_sm->user.methodId = 0;
+		*gdecision = DECISION_CONTINUE;
+		return 0;
+	}
+
+	if (eap_sm->currentMethod == TYPE_IDENTITY)
+	{
+		*gdecision = DECISION_FAILURE;
+		return 0;
+	}
+
+	*gdecision = DECISION_CONTINUE;
+	return 0;
+}
+
+static boolean diameap_ba_policydopickup(eap_type type)
+{
+	TRACE_ENTRY("%p",type);
+	if (type == TYPE_IDENTITY)
+	{
+		return TRUE;
+	}
+	return FALSE;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/diameap_eap.h	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,75 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+
+#ifndef DIAMEAP_EAP_H_
+#define DIAMEAP_EAP_H_
+
+
+/************************************************/
+/*		EAP AAA Interface						*/
+/************************************************/
+
+/* EAP Backend Authenticator State Machine */
+struct diameap_eap_interface
+{
+
+	/* Variables (AAA Interface to Backend Authenticator)*/
+	boolean aaaEapResp;
+	struct eap_packet aaaEapRespData;
+
+	/*Variables (Backend Authenticator to AAA Interface )*/
+	boolean aaaEapReq;
+	boolean aaaEapNoReq;
+	boolean aaaSuccess;
+	boolean aaaFail;
+	struct eap_packet aaaEapReqData;
+	u8 *aaaEapKeyData;
+	int aaaEapKeyLength;
+	boolean aaaEapKeyAvailable;
+	int aaaMethodTimeout;
+
+};
+
+int diameap_eap_statemachine(struct eap_state_machine * sm, struct diameap_eap_interface * eap_i, boolean * error);
+static void diameap_ba_nextid(struct eap_state_machine * sm, int * id);
+static void	diameap_ba_policyupdate(struct eap_state_machine * sm, struct eap_packet eapPacket);
+static int diameap_ba_policygetnextmethod(struct eap_state_machine * sm, eap_type * eaptype, u32 * vendor);
+static int diameap_ba_policygetdecision(struct eap_state_machine * sm,	struct diameap_eap_interface * eap_i, decision * gdecision);
+static boolean diameap_ba_policydopickup(eap_type type);
+
+#endif /* EAP_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/diameap_eappacket.c	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,309 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+
+#include "libdiameap.h"
+
+int diameap_eap_get_code(struct eap_packet eappacket, eap_code * eapcode)
+{
+	TRACE_ENTRY("%p %p",eappacket,eapcode);
+
+	if (eappacket.data == NULL)
+	{
+		*eapcode = ERROR;
+		TRACE_DEBUG(INFO,"%sEmpty data in EAP packet: no EAP Code to return.",DIAMEAP_EXTENSION);
+		return EINVAL;
+	}
+	if (eappacket.length < 1)
+	{
+		*eapcode = ERROR;
+		TRACE_DEBUG(INFO,"%sEAP packet length %d : no EAP Code to return.",DIAMEAP_EXTENSION, eappacket.length);
+		return EINVAL;
+	}
+	*eapcode = G8(eappacket.data);
+	return 0;
+}
+
+int diameap_eap_get_identifier(struct eap_packet eappacket, u8 * identifier)
+{
+	TRACE_ENTRY("%p %p",eappacket,identifier);
+	*identifier = 0;
+	if (eappacket.data == NULL)
+	{
+		TRACE_DEBUG(INFO,"%sEmpty data in EAP packet: no Identifier field to return.",DIAMEAP_EXTENSION);
+		return EINVAL;
+	}
+	if (eappacket.length < 2)
+	{
+		TRACE_DEBUG(INFO,"%sEAP packet length %d : no Identifier field to return.",DIAMEAP_EXTENSION, eappacket.length);
+		return EINVAL;
+	}
+	*identifier = G8(eappacket.data + 1);
+	return 0;
+}
+
+int diameap_eap_get_length(struct eap_packet eappacket, u16 *length)
+{
+	TRACE_ENTRY("%p %p",eappacket,length);
+	*length = 0;
+
+	if (eappacket.data == NULL)
+	{
+		TRACE_DEBUG(INFO,"%sEmpty data in EAP packet: no Length field to return.",DIAMEAP_EXTENSION);
+		return EINVAL;
+	}
+	if (eappacket.ulength < 4)
+	{
+		TRACE_DEBUG(INFO,"%sEAP packet length %d : no Length field to return.",DIAMEAP_EXTENSION, eappacket.length);
+		return EINVAL;
+	}
+	*length = (u16) G16BIGE((eappacket.data + 2));
+	return 0;
+}
+
+int diameap_eap_get_packetlength(struct eap_packet eappacket, u16 *length)
+{
+	TRACE_ENTRY("%p %p",eappacket,length);
+	if (eappacket.data == NULL)
+	{
+		TRACE_DEBUG(INFO,"%sEmpty data in EAP packet: no Length field to return.",DIAMEAP_EXTENSION);
+		return EINVAL;
+	}
+	*length = eappacket.ulength;
+	return 0;
+}
+
+int diameap_eap_get_type(struct eap_packet eappacket, eap_type * eaptype)
+{
+	TRACE_ENTRY("%p %p",eappacket,eaptype);
+	*eaptype = 0;
+
+	if (eappacket.data == NULL)
+	{
+		TRACE_DEBUG(INFO,"%sEmpty data in EAP packet: no EAP Type field to return.",DIAMEAP_EXTENSION);
+		return EINVAL;
+	}
+	if (eappacket.length < 5)
+	{
+		TRACE_DEBUG(INFO,"%sEAP packet length %d : no EAP Type field to return.",DIAMEAP_EXTENSION, eappacket.length);
+		return EINVAL;
+	}
+	*eaptype = (u32) G8(eappacket.data + 4);
+	return 0;
+}
+
+boolean diameap_eap_check_code(eap_code code)
+{
+	TRACE_ENTRY("%p",code);
+	if (code != EAP_REQUEST && code != EAP_RESPONSE && code != EAP_SUCCESS
+			&& code != EAP_FAILURE)
+	{
+		TRACE_DEBUG(FULL,"%sIncorrect EAP Code (%d).",DIAMEAP_EXTENSION,code);
+		return FALSE;
+	}
+	return TRUE;
+}
+
+int diameap_eap_get_packetdata(struct eap_packet eappacket, u8 ** data,
+		int *len)
+{
+	TRACE_ENTRY("%p %p",eappacket,data);
+	if (eappacket.length > 0)
+	{
+		*data = malloc(sizeof(u8) * eappacket.length);
+		U8COPY(*data,0,eappacket.length,eappacket.data);
+		*len = eappacket.length;
+		return 0;
+	}
+	TRACE_DEBUG(INFO,"%sEAP packet length=%d: empty or wrong EAP Packet.",DIAMEAP_EXTENSION, eappacket.length);
+	*data = NULL;
+	*len = 0;
+	return EINVAL;
+}
+
+int diameap_eap_get_data(struct eap_packet eappacket, u8 ** data, int * len)
+{
+	TRACE_ENTRY("%p %p",eappacket,data);
+	if (eappacket.length > 5)
+	{
+		*data = malloc(sizeof(u8) * (eappacket.length - 5));
+		U8COPY(*data,0,(eappacket.length-5),(eappacket.data+5));
+		*len = eappacket.length - 5;
+		return 0;
+	}
+	TRACE_DEBUG(INFO,"%sEAP packet length=%d: empty or wrong EAP Packet.",DIAMEAP_EXTENSION, eappacket.length);
+	*data = NULL;
+	*len = 0;
+
+	return EINVAL;
+}
+
+void diameap_eap_dump(int level, struct eap_packet eappacket)
+{
+	TRACE_ENTRY("%p %p",level,eappacket);
+	if (!TRACE_BOOL(level))
+		return;
+
+	if (eappacket.data == NULL)
+		return;
+	if (eappacket.length < 5)
+		return;
+	if (eappacket.ulength < 5)
+		return;
+
+	fd_log_debug("------------- Dump EAP Packet-------------\n");
+	int i;
+	fd_log_debug("\t -Code       : ");
+	eap_code code;
+	CHECK_FCT_DO(diameap_eap_get_code(eappacket,&code),return);
+	switch (code)
+	{
+	case 1:
+		fd_log_debug("Request\n");
+		break;
+	case 2:
+		fd_log_debug("Response\n");
+		break;
+	case 3:
+		fd_log_debug("Success\n");
+		break;
+	case 4:
+		fd_log_debug("Failure\n");
+		break;
+	default:
+		fd_log_debug("Error (EAP Code value [%d] not allowed)\n",code);
+		break;
+	}
+	u8 id;
+	CHECK_FCT_DO(diameap_eap_get_identifier(eappacket,&id),return);
+	fd_log_debug("\t -Identifier : %x \n", id);
+	u16 length;
+	CHECK_FCT_DO(diameap_eap_get_length(eappacket,&length),return);
+	fd_log_debug("\t -Length     : %d \n", (unsigned int)length);
+	if (eappacket.length > 4)
+	{
+		eap_type type;
+		CHECK_FCT_DO(diameap_eap_get_type(eappacket,&type),return);
+		fd_log_debug("\t -Type       : %d \n", type);
+	}
+	if (eappacket.length > 5)
+	{
+		fd_log_debug("\t -Data       : ");
+		for (i = 5; i < eappacket.length && i < 30; i++)
+		{
+			fd_log_debug("%02x ", G8(eappacket.data + i));
+		}
+		if(i+1<eappacket.length)
+			fd_log_debug("[...] (len=%d)",(unsigned int) length);
+		fd_log_debug("\n");
+	}
+	fd_log_debug("-------------End Dump EAP Packet-------------\n");
+}
+
+int diameap_eap_new(eap_code code, u8 id, eap_type type, u8 * data,
+		u16 dataLength, struct eap_packet *eappacket)
+{
+
+	TRACE_ENTRY("%p %p %p %p %p %p", code, id, type, data, dataLength,eappacket);
+
+	int length = 0;
+
+	//Initialize EAP Packet
+	eappacket->length = 0;
+	eappacket->ulength = 0;
+	eappacket->data = NULL;
+
+	if (diameap_eap_check_code(code) == FALSE)
+	{
+		TRACE_DEBUG(
+				INFO,
+				"%sWrong EAP Code. Only Request, Response, Success or Failure are permitted.",DIAMEAP_EXTENSION);
+		return EINVAL;
+	}
+
+	length += EAP_HEADER;
+	if (code == EAP_REQUEST || code == EAP_RESPONSE)
+	{ // EAP Packet code is either Request or Response
+		if (type == TYPE_NONE)
+		{
+			TRACE_DEBUG(INFO,
+					"%sUnable to create a new EAP Packet (Request or Response) without EAP Type field.",DIAMEAP_EXTENSION);
+			return EINVAL;
+		}
+		length += EAP_TYPE; // EAP Packet code
+		if (data != NULL)
+		{
+			length += dataLength;
+
+			if (length > (int) MAX_EAP_PACKET)
+			{
+
+				TRACE_DEBUG(INFO,
+						"%sUnable to add Data to EAP Packet. Data field length exceed allowed data size.", DIAMEAP_EXTENSION);
+				return EINVAL;
+			}
+			else
+			{
+
+				CHECK_MALLOC(eappacket->data=malloc(sizeof(u8)*length));
+				memset(eappacket->data, 0, sizeof(u8) * length);
+				U8COPY(eappacket->data, 5, dataLength, data);
+			}
+		}
+		else
+		{
+			CHECK_MALLOC(eappacket->data=malloc(sizeof(u8)*length));
+			memset(eappacket->data, 0, sizeof(u8) * length);
+		}
+		P8(eappacket->data + 4, type);
+	}
+	else
+	{ //EAP Packet code is SUCCESS or FAILURE
+		CHECK_MALLOC(eappacket->data=malloc(sizeof(u8)*length));
+		memset(eappacket->data, 0, sizeof(u8) * length);
+		//No Data filed
+		//No Type field
+	}
+	//Add Code and Identifier fields
+	P8(eappacket->data, code);
+	P8(eappacket->data + 1, id);
+	//Add length field
+	P16BIGE(eappacket->data + 2, length);
+	eappacket->length = length;
+	eappacket->ulength = length;
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/diameap_eappacket.h	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,258 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+
+#ifndef DIAMEAP_EAPPACKET_H_
+#define DIAMEAP_EAPPACKET_H_
+
+#include "diameap_defs.h"
+
+/*EAP Packet definition : the Extensible Authentication Protocol (RFC3748) */
+
+/* Define Length/Size */
+#define EAP_HEADER 4 	/* EAP Packet header size : 4 Bytes */
+#define EAP_TYPE 1 		/* EAP Type field size : 1 Byte */
+#define MAX_EAP_PACKET (u16)0xffff /* Maximum value allowed for an EAP Packet */
+
+/*EAP Packet Codes Type*/
+typedef enum
+{
+	ERROR = 0, 			/* EAP Packet Code should not be set to ERROR. Indicates a wrong Code value received. */
+	EAP_REQUEST = 1, 	/* EAP Request (value=1). */
+	EAP_RESPONSE = 2, 	/* EAP Response (value=2). */
+	EAP_SUCCESS = 3, 	/* EAP Success (value=3). */
+	EAP_FAILURE = 4 	/* EAP Failure (value=4). */
+} eap_code;
+
+/* EAP Packet */
+struct eap_packet
+{
+	u16 length; 	/* Length of data (equivalent to the length field). */
+	u16 ulength; 	/* Length of received or inserted bytes in the data pointer. */
+	u8 *data; 		/* Data buffer (including Code, Identifier, Length,  (also Type and Data fields if exists)). */
+};
+
+/* EAP Methods Types */
+typedef enum
+{
+	TYPE_NONE = 0, 			/* Indicate no method specified */
+	TYPE_IDENTITY = 1, 		/* EAP Identity (RFC3748) */
+	TYPE_NOTIFICATION = 2, 	/* EAP Notification (RFC3748) */
+	TYPE_NAK = 3, 			/* EAP NAK (RFC3748) */
+	TYPE_EAP_MD5 = 4,		/* EAP MD5 (RFC3748) */
+	TYPE_OTP = 5, 			/* EAP OTP (RFC3748) */
+	TYPE_GTC = 6, 			/* EAP GTC (RFC3748) */
+	TYPE_EAP_TLS = 13,		/* EAP TLS (RFC5216) */
+	TYPE_EXPANDED_TYPES = 254, 	/* EAP Expanded NAK (RFC3748) */
+	TYPE_EXPERIMENTAL_USE = 255	/* for Experimental use (RFC3748) */
+} eap_type;
+
+
+/* Function		:	diameap_eap_get_code
+ *
+ * Parameters:
+ * 	eapPacket 	: 	an EAP Packet
+ *	eapcode		:	On successful return, the EAP Code is stored here.
+ *
+ * Description:
+ * 	Get the EAP Code of an EAP Packet. If NULL EAP Packet or empty packet ERROR is stored in eapcode.
+ *
+ * Return value:
+ * 	0 			: 	if successful
+* 	EINVAL		:	if EAP Packet is NULL or empty
+ */
+
+int diameap_eap_get_code(struct eap_packet eapPacket, eap_code * eapcode);
+
+
+/* Function		:	diameap_eap_get_identifier
+ *
+ * Parameters:
+ * 	eapPacket 	: 	an EAP Packet
+ * 	identifier	:	on successful return, the identifier value is stored here.
+ *
+ * Description:
+ * 	Get the Identifier field of an EAP Packet.
+ *
+ * Return value:
+ * 	0 			: 	if successful
+ * 	EINVAL		: 	if the EAP Packet is NULL or the EAP identifier value is not valid or data length < 2
+ *
+ */
+
+int diameap_eap_get_identifier(struct eap_packet eapPacket, u8 * identifier);
+
+
+/* Function		:	diameap_eap_get_length
+ *
+ * Parameters:
+ *	eapPacket	: 	an EAP Packet
+ *	length		:	on successful return, the EAP Packet length field is stored here.
+ *
+ * Description:
+ *	Get the Length field of an EAP Packet
+ *
+ * Return value:
+ *	0			:	if successful
+ *	EINVAL		: 	if the data length < 4, or the EAP Packet is NULL.
+ */
+
+int diameap_eap_get_length(struct eap_packet eapPacket, u16 *length);
+
+
+/* Function		:	diameap_eap_get_packetlength
+ *
+ * Parameters:
+ *	eapPacket	: 	an EAP Packet
+ *	length		:	on successful return, the length of EAP Packet is stored here.
+ *
+ * Description:
+ *	Get the received or inserted length of Bytes in an EAP Packet.
+ *
+ * Return value:
+ *	0			: 	if successful
+ *	EINVAL		: 	if the EAP Packet is NULL
+ */
+
+int diameap_eap_get_packetlength(struct eap_packet eapPacket, u16 *length);
+
+
+/* Function		:	diameap_eap_get_type
+ *
+ * Parameters:
+ *	eapPacket	: 	an EAP Packet
+ *	eaptype		:	on successful return, the EAP Type field is stored here.
+ *
+ * Description:
+ *	Get the Type field of an EAP Packet.
+ *
+ * Return value:
+ *	0			:	if successful
+ *	EINVAL		:	if the EAP Packet is NULL or data length < 5
+ */
+
+int diameap_eap_get_type(struct eap_packet eapPacket,eap_type * eaptype);
+
+
+/* Function		:	diameap_eap_get_packetdata
+ *
+ * Parameters:
+ *	eapPacket	: 	an EAP Packet
+ *	eapdata		:	on successful return, the content of EAP Packet is stored here.
+ *	eapdatalen	:	on successful return, the length of EAP Packet is stored here.
+ *
+ * Description:
+ *	Get the data content of an EAP Packet.
+ *
+ * Return value:
+ *	0			: 	if successful
+ *	EINVAL		: 	if there is no data in the current EAP Packet (ulength<1)
+ */
+
+int diameap_eap_get_packetdata(struct eap_packet eapPacket, u8 ** data, int *len);
+
+
+/* Function		:	diameap_eap_get_data
+ *
+ * Parameters:
+ *	eapPacket	: 	an EAP Packet
+ *	data		:	on successful return, the content of data field is stored here.
+ *	datalen		:	on successful return, the length of data field is stored here.
+ *
+ * Description:
+ *	Return the Data field of an EAP Packet
+ *
+ * Return value:
+ *	0			: 	if successful
+ *	EINVAL		: 	if there is no data in the current EAP Packet (ulength<6)
+ */
+
+int diameap_eap_get_data(struct eap_packet eapPacket, u8 ** data, int * len);
+
+
+/* Function		:	diameap_eap_chech_code
+ *
+ * Parameters:
+ *	code		: 	an EAP Code value
+ *
+ * Description:
+ *	Check if the code value is valid or not
+ *
+ * Return value:
+ * 	TRUE		: 	if valid value
+ * 	FALSE		: 	if not valid value
+ *
+ */
+
+boolean diameap_eap_check_code(eap_code code);
+
+
+/* Function		:	diameap_eap_dump
+ *
+ * Parameters:
+ *	eapPacket	:	an EAP Packet
+ *	level		:	Debug level
+ *
+ * Description:
+ *	Dump the structure and the content of all the fields in this EAP Packet
+ *
+ */
+
+void diameap_eap_dump(int level, struct eap_packet eapPacket);
+
+
+/* Function		:	diameap_eap_new
+ *
+ * Parameters:
+ *	code		:	EAP CODE field value
+ *	id			:	EAP Identifier field value
+ *	type		:	(optional) EAP type field value if exist, otherwise NULL
+ *	data		:	(optional) EAP data field value if exist, otherwise NULL
+ *	dataLength	:	(optional) Length of the data to be inserted in the Packet, otherwise 0
+ *	eappacket	:	on successful return, pointer to eap packet is stored here.
+ * Description:
+ *	Create a new EAP Packet with the specified parameters and data
+ *
+ * Return value:
+ *	0			: 	if successful
+ *	EINVAL		:	Invalid parameter
+ */
+
+int diameap_eap_new(eap_code code, u8 id, eap_type type,
+		u8 * data, u16 dataLength, struct eap_packet *eappacket);
+
+#endif /* DIAMEAP_EAPPACKET_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/diameap_init.c	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,441 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+
+#include "diameap_common.h"
+
+/* Dictionary Object templates */
+struct dict_object * dataobj_diameap_cmd = NULL; /* Diameter-EAP-Request Command Code */
+struct dict_object * dataobj_diameap_app = NULL; /* Diameter EAP Application object */
+struct dict_object * dataobj_diameap_ven = NULL; /* Diameter EAP Application Vendor object */
+struct dict_object * dataobj_accounting_eap_auth_method = NULL;
+struct dict_object * dataobj_acct_interim_interval = NULL;
+struct dict_object * dataobj_auth_application_id = NULL;
+struct dict_object * dataobj_auth_grace_period = NULL;
+struct dict_object * dataobj_auth_request_type = NULL;
+struct dict_object * dataobj_auth_session_state = NULL;
+struct dict_object * dataobj_authorization_lifetime = NULL;
+struct dict_object * dataobj_callback_id = NULL;
+struct dict_object * dataobj_callback_number = NULL;
+struct dict_object * dataobj_called_station_id = NULL;
+struct dict_object * dataobj_calling_station_id = NULL;
+struct dict_object * dataobj_class = NULL;
+struct dict_object * dataobj_configuration_token = NULL;
+struct dict_object * dataobj_connect_info = NULL;
+struct dict_object * dataobj_destination_host = NULL;
+struct dict_object * dataobj_destination_realm = NULL;
+struct dict_object * dataobj_eap_master_session_key = NULL;
+struct dict_object * dataobj_eap_key_name = NULL;
+struct dict_object * dataobj_eap_payload = NULL;
+struct dict_object * dataobj_eap_reissued_payload = NULL;
+struct dict_object * dataobj_error_message = NULL;
+struct dict_object * dataobj_error_reporting_host = NULL;
+struct dict_object * dataobj_failed_avp = NULL;
+struct dict_object * dataobj_filter_id = NULL;
+struct dict_object * dataobj_framed_appletalk_link = NULL;
+struct dict_object * dataobj_framed_appletalk_network = NULL;
+struct dict_object * dataobj_framed_appletalk_zone = NULL;
+struct dict_object * dataobj_framed_compression = NULL;
+struct dict_object * dataobj_framed_interface_id = NULL;
+struct dict_object * dataobj_framed_ip_address = NULL;
+struct dict_object * dataobj_framed_ip_netmask = NULL;
+struct dict_object * dataobj_framed_ipv6_prefix = NULL;
+struct dict_object * dataobj_framed_ipv6_pool = NULL;
+struct dict_object * dataobj_framed_ipv6_route = NULL;
+struct dict_object * dataobj_framed_ipx_network = NULL;
+struct dict_object * dataobj_framed_mtu = NULL;
+struct dict_object * dataobj_framed_pool = NULL;
+struct dict_object * dataobj_framed_protocol = NULL;
+struct dict_object * dataobj_framed_route = NULL;
+struct dict_object * dataobj_framed_routing = NULL;
+struct dict_object * dataobj_idle_timeout = NULL;
+struct dict_object * dataobj_multi_round_time_out = NULL;
+struct dict_object * dataobj_nas_filter_rule = NULL;
+struct dict_object * dataobj_nas_identifier = NULL;
+struct dict_object * dataobj_nas_ip_address = NULL;
+struct dict_object * dataobj_nas_ipv6_address = NULL;
+struct dict_object * dataobj_nas_port = NULL;
+struct dict_object * dataobj_nas_port_id = NULL;
+struct dict_object * dataobj_nas_port_type = NULL;
+struct dict_object * dataobj_originating_line_info = NULL;
+struct dict_object * dataobj_origin_host = NULL;
+struct dict_object * dataobj_origin_realm = NULL;
+struct dict_object * dataobj_origin_state_id = NULL;
+struct dict_object * dataobj_port_limit = NULL;
+struct dict_object * dataobj_proxy_info = NULL;
+struct dict_object * dataobj_qos_filter_rule = NULL;
+struct dict_object * dataobj_re_auth_request_type = NULL;
+struct dict_object * dataobj_redirect_host = NULL;
+struct dict_object * dataobj_redirect_host_usage = NULL;
+struct dict_object * dataobj_redirect_max_cache_time = NULL;
+struct dict_object * dataobj_reply_message = NULL;
+struct dict_object * dataobj_result_code = NULL;
+struct dict_object * dataobj_route_record = NULL;
+struct dict_object * dataobj_service_type = NULL;
+struct dict_object * dataobj_session_id = NULL;
+struct dict_object * dataobj_session_timeout = NULL;
+struct dict_object * dataobj_state = NULL;
+struct dict_object * dataobj_tunneling = NULL;
+struct dict_object * dataobj_user_name = NULL;
+
+int diameap_init(char * conffile)
+{
+	TRACE_ENTRY("%p",conffile);
+
+	/* Initialize the diameap_config structure*/
+	CHECK_FCT(diameap_init_config(conffile));
+
+	if (diameap_config->conffile)
+	{
+		/* parse the configuration file*/
+		CHECK_FCT(diameap_parse_conffile());
+
+		/* Load EAP methods plug-ins */
+		CHECK_FCT(diameap_plugin_load());
+
+	}
+	else
+	{
+		TRACE_DEBUG(FULL,"%sNo EAP method plug-in available with a default configuration.",DIAMEAP_EXTENSION);
+	}
+
+	/* Initialize Dictionary templates */
+	CHECK_FCT(diameap_init_obj());
+
+	/* Initialize access to user's information Database */
+	CHECK_FCT(diameap_mysql_connect());
+
+	/* Dump DiamEAP extension configuration */
+	diameap_conf_dump();
+
+	return 0;
+}
+
+static int diameap_init_config(char * conffile)
+{
+	TRACE_ENTRY("%p",conffile);
+
+	if (conffile != NULL)
+	{
+		diameap_config->conffile = conffile;
+	}
+	else
+	{
+		TRACE_DEBUG(FULL,"%sNo configuration file provided with the DiamEAP extension: default parameters will be used.",DIAMEAP_EXTENSION);
+	}
+
+	diameap_config->application_id = 5;
+	diameap_config->vendor_id = 0;
+	diameap_config->command_code = 268;
+	diameap_config->diam_realm = strdup(fd_g_config->cnf_diamrlm);
+	diameap_config->max_invalid_eap_packet = 5;
+	diameap_config->multi_round_time_out = 30;
+	return 0;
+}
+
+static int diameap_init_obj(void)
+{
+
+	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_APPLICATION, APPLICATION_BY_ID, &(diameap_config->application_id),&dataobj_diameap_app, ENOENT));
+	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND,CMD_BY_CODE_R, &(diameap_config->command_code), &dataobj_diameap_cmd, ENOENT));
+	//	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_VENDOR,VENDOR_OF_APPLICATION, &dataobj_diameap_app, &dataobj_diameap_ven,ENOENT) );
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Accounting-EAP-Auth-Method", &dataobj_accounting_eap_auth_method,
+					ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Acct-Interim-Interval", &dataobj_acct_interim_interval, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Auth-Application-Id", &dataobj_auth_application_id, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Auth-Grace-Period", &dataobj_auth_grace_period, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Auth-Request-Type", &dataobj_auth_request_type, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Auth-Session-State", &dataobj_auth_session_state, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Authorization-Lifetime", &dataobj_authorization_lifetime, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Callback-Id", &dataobj_callback_id, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Callback-Number", &dataobj_callback_number, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Called-Station-Id", &dataobj_called_station_id, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Calling-Station-Id", &dataobj_calling_station_id, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Class", &dataobj_class, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Configuration-Token", &dataobj_configuration_token, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Connect-Info", &dataobj_connect_info, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Destination-Host", &dataobj_destination_host, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Destination-Realm", &dataobj_destination_realm, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"EAP-Master-Session-Key", &dataobj_eap_master_session_key, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"EAP-Key-Name", &dataobj_eap_key_name, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"EAP-Payload", &dataobj_eap_payload, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"EAP-Reissued-Payload", &dataobj_eap_reissued_payload, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Error-Message", &dataobj_error_message, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Error-Reporting-Host", &dataobj_error_reporting_host, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Failed-AVP", &dataobj_failed_avp, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Filter-Id", &dataobj_filter_id, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Framed-AppleTalk-Link", &dataobj_framed_appletalk_link, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Framed-AppleTalk-Network", &dataobj_framed_appletalk_network,
+					ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Framed-AppleTalk-Zone", &dataobj_framed_appletalk_zone, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Framed-Compression", &dataobj_framed_compression, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Framed-Interface-Id", &dataobj_framed_interface_id, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Framed-IP-Address", &dataobj_framed_ip_address, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Framed-IP-Netmask", &dataobj_framed_ip_netmask, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Framed-IPv6-Prefix", &dataobj_framed_ipv6_prefix, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Framed-IPv6-Pool", &dataobj_framed_ipv6_pool, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Framed-IPv6-Route", &dataobj_framed_ipv6_route, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Framed-IPX-Network", &dataobj_framed_ipx_network, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Framed-MTU", &dataobj_framed_mtu, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Framed-Pool", &dataobj_framed_pool, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Framed-Protocol", &dataobj_framed_protocol, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Framed-Route", &dataobj_framed_route, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Framed-Routing", &dataobj_framed_routing, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Idle-Timeout", &dataobj_idle_timeout, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Multi-Round-Time-Out", &dataobj_multi_round_time_out, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"NAS-Filter-Rule", &dataobj_nas_filter_rule, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"NAS-Identifier", &dataobj_nas_identifier, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"NAS-IP-Address", &dataobj_nas_ip_address, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"NAS-IPv6-Address", &dataobj_nas_ipv6_address, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"NAS-Port", &dataobj_nas_port, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"NAS-Port-Id", &dataobj_nas_port_id, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"NAS-Port-Type", &dataobj_nas_port_type, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Originating-Line-Info", &dataobj_originating_line_info, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Origin-Host", &dataobj_origin_host, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Origin-Realm", &dataobj_origin_realm, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Origin-State-Id", &dataobj_origin_state_id, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Port-Limit", &dataobj_port_limit, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Proxy-Info", &dataobj_proxy_info, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"QoS-Filter-Rule", &dataobj_qos_filter_rule, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Re-Auth-Request-Type", &dataobj_re_auth_request_type, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Redirect-Host", &dataobj_redirect_host, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Redirect-Host-Usage", &dataobj_redirect_host_usage, ENOENT));
+	CHECK_FCT(
+			fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Redirect-Max-Cache-Time",
+					&dataobj_redirect_max_cache_time, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Reply-Message", &dataobj_reply_message, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Result-Code", &dataobj_result_code, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Route-Record", &dataobj_route_record, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Service-Type", &dataobj_service_type, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Session-Id", &dataobj_session_id, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Session-Timeout", &dataobj_session_timeout, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"State", &dataobj_state, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"Tunneling", &dataobj_tunneling, ENOENT));
+	CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+					"User-Name", &dataobj_user_name, ENOENT));
+
+	return 0;
+}
+
+/* Parse the configuration file (using the yacc parser) */
+static int diameap_parse_conffile(void)
+{
+	if (!diameap_config->conffile)
+	{
+		TRACE_DEBUG (INFO,"%sNo configuration file to parse for DiamEAP Extension.",DIAMEAP_EXTENSION);
+		return EINVAL;
+	}
+	extern FILE * diameapin;
+
+	TRACE_DEBUG (FULL, "%sParsing configuration file: %s",DIAMEAP_EXTENSION, diameap_config->conffile);
+	diameapin = fopen(diameap_config->conffile, "r");
+	if (!diameapin)
+	{
+		TRACE_DEBUG(INFO,"%sUnable to open configuration file %s for reading: %s",DIAMEAP_EXTENSION, diameap_config->conffile, strerror(errno));
+		return errno;
+	}
+
+	/* call yacc parser */
+	CHECK_FCT(diameapparse(diameap_config));
+
+	/* close the file */
+	CHECK_FCT(fclose(diameapin));
+	return 0;
+}
+
+int diameap_set_mysql_param(char * user, char * passwd, char * server,
+		char * database)
+{
+	TRACE_ENTRY("%p %p %p %p",user,passwd,server,database);
+	if (user == NULL)
+	{
+		TRACE_DEBUG(INFO,"%sUnable to connect to MySQL Database Server: Empty user name or missing in the configuration file.",DIAMEAP_EXTENSION);
+		return EINVAL;
+	}
+
+	if (server == NULL)
+	{
+		TRACE_DEBUG(INFO,"%sUnable to connect to MySQL Database Server: MySQL Database Server address missing in the configuration file.",DIAMEAP_EXTENSION);
+		return EINVAL;
+	}
+	if (database == NULL)
+	{
+		TRACE_DEBUG(INFO,"%sUnable to connect to MySQL Database Server: MySQL Database name missing in configuration file.",DIAMEAP_EXTENSION);
+		return EINVAL;
+	}
+	diameap_config->db.user = user;
+	diameap_config->db.password = passwd;
+	diameap_config->db.server = server;
+	diameap_config->db.database = database;
+	return 0;
+}
+
+/* Connecting to MySQL Database */
+int diameap_mysql_connect(void)
+{
+	TRACE_ENTRY();
+	db_conn = mysql_init(NULL);
+	int mysql_reconnect_val=1;
+	mysql_options(db_conn,MYSQL_OPT_RECONNECT,&mysql_reconnect_val);
+	/* Connect to database */
+	if (!mysql_real_connect(db_conn, diameap_config->db.server,
+			diameap_config->db.user, diameap_config->db.password,
+			diameap_config->db.database, 0, NULL, 0))
+	{
+		TRACE_DEBUG(INFO,"%sConnection to MySQL Database Server failed: %s",DIAMEAP_EXTENSION, mysql_error(db_conn));
+		return errno;
+	}
+	return 0;
+}
+
+/* Reconnecting to MySQL Database */
+int diameap_mysql_reconnect()
+{
+	TRACE_ENTRY();
+	CHECK_POSIX(pthread_mutex_lock( &db_cs_mutex ));
+	if (db_conn == NULL)
+	{
+		TRACE_DEBUG(INFO,"%sReconnecting to MySQL server.",DIAMEAP_EXTENSION);
+		if(diameap_mysql_connect()==0){
+			TRACE_DEBUG(INFO,"%s Reconnected successfully to MySQL Server.",DIAMEAP_EXTENSION);
+		}else{
+			return 1;
+		}
+	}
+	CHECK_POSIX(pthread_mutex_unlock( &db_cs_mutex ));
+	return 0;
+
+}
+
+static void diameap_conf_dump(void)
+{
+
+	if (!TRACE_BOOL(INFO))
+		return;
+
+	fd_log_debug(
+			"-------- DiamEAP extension : Configuration parameters (Dump) -------------\n");
+	fd_log_debug("\t-Configuration file.....: %s\n", diameap_config->conffile);
+	fd_log_debug("\t-EAP Application Id.....: %u\n",
+			diameap_config->application_id);
+	fd_log_debug("\t-EAP Application Command: %u\n",
+			diameap_config->command_code);
+	fd_log_debug("\t-EAP Application Vendor.: %u\n", diameap_config->vendor_id);
+	fd_log_debug("\t-Max invalid EAP packets: %u\n", diameap_config->max_invalid_eap_packet);
+	fd_log_debug("\t-Multi-Round Timeout....: %u\n", diameap_config->multi_round_time_out);
+	if (diameap_config->db.user)
+	{
+		fd_log_debug("\t-MySQL Database Params..: \n\t\tUser .......:%s\n",
+				diameap_config->db.user);
+		fd_log_debug("\t\tServer .....:%s\n", diameap_config->db.server);
+		fd_log_debug("\t\tDatabase....:%s\n", diameap_config->db.database);
+	}
+
+	fd_log_debug("\t-EAP Method Plugins.....: \n");
+	diameap_plugin_dump();
+
+	fd_log_debug(
+			"-------- DiamEAP extension : Configuration parameters (End) ---------------\n");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/diameap_init.h	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,57 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+
+#ifndef DIAMEAP_INIT_H_
+#define DIAMEAP_INIT_H_
+
+/* Initialize the configuration of DiamEAP*/
+int diameap_init(char * conffile);
+
+/* Set default configuration */
+static int diameap_init_config(char *conffile);
+
+/* Parse the configuration file */
+static int diameap_parse_conffile(void);
+
+/* Initialize Dictionary objects templates */
+static int diameap_init_obj(void);
+
+/* Dump the configuration of DiamEAP */
+static void diameap_conf_dump(void);
+
+#endif /* DIAMEAP_INIT_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/diameap_mysql.c	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,237 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+#include "diameap_mysql.h"
+
+int diameap_get_eap_user(struct eap_user * user, char * username)
+{
+	TRACE_ENTRY("%p %p",user,username);
+	if (db_conn == NULL)
+	{
+		TRACE_DEBUG(INFO, "%sNot connected to the MySQL Database server.",DIAMEAP_EXTENSION);
+		if (diameap_mysql_reconnect())
+		{
+			return EINVAL;
+		}
+	}
+	mysql_thread_init();
+
+	MYSQL_RES *res;
+	MYSQL_ROW row;
+	char * query;
+	CHECK_MALLOC(query=(char *)malloc(sizeof(char)*255));
+
+	sprintf(
+			query,
+			"SELECT id,username,password,eapmethod, vendor FROM users WHERE  users.username='%s' and users.active='Y' ",
+			username);
+
+	CHECK_POSIX(pthread_mutex_lock( &db_cs_mutex ));
+
+	if (mysql_query(db_conn, query))
+	{
+		CHECK_POSIX(pthread_mutex_unlock( &db_cs_mutex ));
+		TRACE_DEBUG(INFO, "%sQuery execution fail. %s",DIAMEAP_EXTENSION, mysql_error(db_conn));
+		db_conn = NULL;
+		diameap_mysql_reconnect();
+		mysql_thread_end();
+		free(query);
+		query = NULL;
+		return EINVAL;
+	}
+
+	res = mysql_store_result(db_conn);
+
+	CHECK_POSIX(pthread_mutex_unlock( &db_cs_mutex ));
+
+	if ((row = mysql_fetch_row(res)) != NULL)
+	{
+
+		user->id = atoi(row[0]);
+		user->userid = strdup(row[1]);
+		user->useridLength = strlen(row[1]);
+		user->password = strdup(row[2]);
+		user->passwordLength = strlen(row[2]);
+		user->proposed_eap_method = atoi(row[3]);
+		user->proposed_eap_method_vendor = atoi(row[4]);
+
+		mysql_free_result(res);
+		mysql_thread_end();
+		free(query);
+		query = NULL;
+		return 0;
+	}
+
+	TRACE_DEBUG(INFO, "%sUser unavailable.",DIAMEAP_EXTENSION);
+	mysql_free_result(res);
+	mysql_thread_end();
+	free(query);
+	query = NULL;
+	return EINVAL;
+
+}
+
+int diameap_authentication_get_attribs(struct eap_user user,
+		struct fd_list * attribute_list)
+{
+
+	TRACE_ENTRY("%p %p",user,attribute_list);
+
+	if (db_conn == NULL)
+	{
+		TRACE_DEBUG(INFO, "%sNot connected to the MySQL Database server.",DIAMEAP_EXTENSION);
+		if (diameap_mysql_reconnect())
+		{
+			return EINVAL;
+		}
+	}
+
+	mysql_thread_init();
+	MYSQL_RES *res;
+	MYSQL_ROW row;
+	char * query;
+	CHECK_MALLOC(query=malloc(sizeof(char)*255));
+
+	sprintf(
+			query,
+			"SELECT `authe`.`attribute` ,`authe`.`value` FROM `authe` WHERE `authe`.`grp` IN ( SELECT `user_grp`.`grp` FROM `user_grp` WHERE `user_grp`.`user` = %d ) ",
+			user.id);
+
+	CHECK_POSIX(pthread_mutex_lock( &db_cs_mutex ));
+
+	if (mysql_query(db_conn, query))
+	{
+		CHECK_POSIX(pthread_mutex_unlock( &db_cs_mutex ));
+		TRACE_DEBUG(INFO, "%sQuery execution fail. %s",DIAMEAP_EXTENSION, mysql_error(db_conn));
+		db_conn = NULL;
+		diameap_mysql_reconnect();
+		mysql_thread_end();
+		free(query);
+		query = NULL;
+		return EINVAL;
+	}
+
+	res = mysql_store_result(db_conn);
+
+	CHECK_POSIX(pthread_mutex_unlock( &db_cs_mutex ));
+
+	while ((row = mysql_fetch_row(res)))
+	{
+		struct auth_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct auth_attribute)));
+		memset(attribute, 0, sizeof(struct auth_attribute));
+		fd_list_init(&attribute->chain, NULL);
+		attribute->attrib = strdup(row[0]);
+		attribute->op = NULL;
+		attribute->value = strdup(row[1]);
+		fd_list_insert_before(attribute_list, &attribute->chain);
+
+	}
+
+	mysql_free_result(res);
+	mysql_thread_end();
+	free(query);
+	query = NULL;
+	return 0;
+}
+
+int diameap_authorization_get_attribs(struct eap_user user,
+		struct fd_list * attribute_list)
+{
+	TRACE_ENTRY("%p %p",user,attribute_list);
+
+	if (db_conn == NULL)
+	{
+		TRACE_DEBUG(INFO, "%sNot connected to the MySQL Database server.",DIAMEAP_EXTENSION);
+		if (diameap_mysql_reconnect())
+		{
+			return EINVAL;
+		}
+	}
+
+	mysql_thread_init();
+
+	MYSQL_RES *res;
+	MYSQL_ROW row;
+	char * query;
+	CHECK_MALLOC(query=malloc(sizeof(char)*255));
+
+	sprintf(
+			query,
+			"SELECT `authz`.`attribute` , `authz`.`op` , `authz`.`value` FROM `authz` WHERE `authz`.`grp` IN ( SELECT `user_grp`.`grp` FROM `user_grp` WHERE `user_grp`.`user` = %d ) ",
+			user.id);
+
+	CHECK_POSIX(pthread_mutex_lock( &db_cs_mutex ));
+
+	if (mysql_query(db_conn, query))
+	{
+		CHECK_POSIX(pthread_mutex_unlock( &db_cs_mutex ));
+		TRACE_DEBUG(INFO, "%sQuery execution fail. %s",DIAMEAP_EXTENSION, mysql_error(db_conn));
+		db_conn = NULL;
+		diameap_mysql_reconnect();
+		mysql_thread_end();
+		free(query);
+		query = NULL;
+		return EINVAL;
+	}
+
+	res = mysql_store_result(db_conn);
+
+	CHECK_POSIX(pthread_mutex_unlock( &db_cs_mutex ));
+
+	while ((row = mysql_fetch_row(res)))
+	{
+		struct auth_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct auth_attribute)));
+		memset(attribute, 0, sizeof(struct auth_attribute));
+		fd_list_init(&attribute->chain, NULL);
+		attribute->attrib = strdup(row[0]);
+		attribute->op = strdup(row[1]);
+		attribute->value = strdup(row[2]);
+		fd_list_insert_before(attribute_list, &attribute->chain);
+	}
+
+	mysql_free_result(res);
+	mysql_thread_end();
+	free(query);
+	query = NULL;
+	return 0;
+}
+
+void diameap_mysql_disconnect(){
+	mysql_close(db_conn);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/diameap_mysql.h	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,69 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+
+#ifndef DIAMEAP_MYSQL_H_
+#define DIAMEAP_MYSQL_H_
+
+#include "libdiameap.h"
+#include <mysql.h>
+
+	/* MySQL Database connection */
+	MYSQL *db_conn;
+
+	static pthread_mutex_t db_cs_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+	int diameap_get_eap_user(struct eap_user * user, char * username);
+
+	int diameap_mysql_connect();
+
+	int diameap_mysql_reconnect();
+
+	int diameap_set_mysql_param(char * user, char * passwd, char * server, char * database);
+
+	void diameap_mysql_disconnect();
+
+	/**/
+	int diameap_authentication_get_attribs(struct eap_user user,
+			struct fd_list * attribute_list);
+
+	/**/
+	int diameap_authorization_get_attribs(struct eap_user user,
+			struct fd_list * attribute_list);
+
+
+#endif /* DIAMEAP_MYSQL_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/diameap_plugins.c	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,455 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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 CONTRIBUTfORS 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.
+ *****************************************************************************************************/
+
+#include "diameap_common.h"
+
+/********************************************/
+/*	Loading and initializing plug-ins		*/
+/********************************************/
+
+/* Add new plugin */
+int diameap_plugin_add(char * name, eap_type methodtype, u32 vendor,
+		char * filename, char * conffile)
+{
+	TRACE_ENTRY("%p %p %p %p %p", name, methodtype, vendor, filename, conffile);
+
+	/* Check the filename is valid */
+	CHECK_PARAMS(filename);
+
+	/* add new EAP method  in the list of plugins*/
+	{
+		struct plugin * plugin;
+		CHECK_MALLOC(plugin = malloc(sizeof(struct plugin)));
+		memset(plugin, 0, sizeof(struct plugin));
+		fd_list_init(&plugin->chain, plugin);
+		plugin->methodname = name;
+		plugin->methodtype = methodtype;
+		plugin->vendor = vendor;
+		plugin->pluginfile = filename;
+		plugin->conffile = conffile;
+		fd_list_insert_before(&plugins_list, &plugin->chain);
+	}
+
+	return 0;
+}
+
+/* Dump plugins list */
+void diameap_plugin_dump(void)
+{
+	struct fd_list * pl;
+
+	for (pl = plugins_list.next; pl != &plugins_list; pl = pl->next)
+	{
+		struct plugin * plugin = (struct plugin *) pl;
+		fd_log_debug("\t\t - %s plugin \t [Type: %i, Vendor: %i]  %sloaded\n", plugin->methodname,
+				plugin->methodtype,plugin->vendor, plugin->handler ? "" : "not ");
+	}
+}
+
+int diameap_plugin_get(u32 vendor, eap_type type, struct plugin ** getplugin)
+{
+	TRACE_ENTRY("%p %p %p",vendor,type,getplugin);
+	struct fd_list * pl;
+
+	for (pl = plugins_list.next; pl != &plugins_list; pl = pl->next)
+	{
+		struct plugin * plugin = (struct plugin *) pl;
+		if (plugin->methodtype == type && plugin->vendor == vendor)
+		{
+			*getplugin = plugin;
+			return 0;
+		}
+	}
+	return 1;
+}
+
+/* Load all method in the plugins list */
+int diameap_plugin_load(void)
+{
+
+	int ret;
+	struct fd_list * pl;
+
+	/* Loop on all plugins */
+
+	for (pl = plugins_list.next; pl != &plugins_list; pl = pl->next)
+	{
+		struct plugin * plugin = (struct plugin *) pl;
+		struct register_plugin * registerplugin;
+		int (*diameap_plugin_register)();
+
+		TRACE_DEBUG(FULL, "%sLoading EAP method plugin: %s",DIAMEAP_EXTENSION, plugin->methodname);
+
+		/* Load the method */
+		plugin->handler = dlopen(plugin->pluginfile, RTLD_LAZY | RTLD_GLOBAL);
+		if (plugin->handler == NULL)
+		{
+			TRACE_DEBUG(INFO, "%sLoading of plugin %s failed: %s",DIAMEAP_EXTENSION,
+					plugin->methodname, dlerror());
+			return EINVAL;
+		}
+
+		/* Defined register methods for this EAP method*/
+		diameap_plugin_register = (int(*)()) dlsym(plugin->handler,
+				"diameap_plugin_register");
+		if (!diameap_plugin_register)
+		{
+			TRACE_DEBUG(INFO,
+					"%s[%s plugin] Unable to register EAP method.",DIAMEAP_EXTENSION,
+					plugin->methodname, dlerror());
+			return EINVAL;
+		}
+
+		if ((*diameap_plugin_register)() != 0)
+		{
+			TRACE_DEBUG(INFO,
+					"%s[%s plugin] Unable to register EAP method plugin",DIAMEAP_EXTENSION,plugin->methodname);
+		}
+
+		int (*diameap_plugin_objects)(struct register_plugin **);
+
+		diameap_plugin_objects = (int(*)(struct register_plugin **)) dlsym(
+				plugin->handler, "diameap_plugin_objects");
+		if (!diameap_plugin_objects)
+		{
+			TRACE_DEBUG(INFO,
+					"%s[%s plugin] Unable to resolve symbol of the plugin: %s",DIAMEAP_EXTENSION,
+					plugin->methodname, dlerror());
+			return EINVAL;
+		}
+
+		if ((*diameap_plugin_objects)(&registerplugin) != 0)
+		{
+
+			TRACE_DEBUG(
+					INFO,
+					"%s[%s plugin] Unable to get objects description from the plug-in: %s",DIAMEAP_EXTENSION,
+					plugin->methodname, dlerror());
+			return EINVAL;
+		}
+
+		/* eap_method_configure method */
+		if (registerplugin->configure)
+		{
+			plugin->eap_method_configure = (int(*)(char *)) dlsym(
+					plugin->handler, registerplugin->configure);
+			if (plugin->eap_method_configure == NULL)
+			{
+				TRACE_DEBUG(
+						INFO,
+						"%s[%s plugin] Unable to resolve symbol for 'eap_method_configure': %s",DIAMEAP_EXTENSION,
+						plugin->methodname, dlerror());
+			}
+		}
+		else
+		{
+			plugin->eap_method_configure = NULL;
+			TRACE_DEBUG(FULL+1,"%s[%s plugin] Unavailable function 'eap_method_configure'",DIAMEAP_EXTENSION, plugin->methodname);
+		}
+
+		/* eap_method_init method */
+		if (registerplugin->init)
+		{
+			plugin->eap_method_init
+					= (int(*)(struct eap_state_machine *)) dlsym(
+							plugin->handler, registerplugin->init);
+			if (plugin->eap_method_init == NULL)
+			{
+				TRACE_DEBUG(
+						INFO,
+						"%s[%s plugin] Unable to resolve symbol for 'eap_method_init': %s",DIAMEAP_EXTENSION,
+						plugin->methodname, dlerror());
+				return EINVAL;
+			}
+		}
+		else
+		{
+			plugin->eap_method_init = NULL;
+			TRACE_DEBUG(INFO,"%s[%s plugin] Unavailable function 'eap_method_init'",DIAMEAP_EXTENSION, plugin->methodname);
+			return EINVAL;
+		}
+
+		/* eap_method_initPickUp method */
+		if (registerplugin->initPickUp)
+		{
+			plugin->eap_method_initPickUp
+					= (int(*)(struct eap_state_machine *)) dlsym(
+							plugin->handler, registerplugin->initPickUp);
+		}
+		else
+		{
+			plugin->eap_method_initPickUp = NULL;
+			TRACE_DEBUG(FULL+1,"%s[%s plugin] Unavailable function 'eap_method_initPickUp'",DIAMEAP_EXTENSION, plugin->methodname);
+		}
+
+		/* eap_method_buildReq method */
+		if (registerplugin->buildReq)
+		{
+			plugin->eap_method_buildReq = (int(*)(struct eap_state_machine *,
+					u8, struct eap_packet *)) dlsym(plugin->handler,
+					registerplugin->buildReq);
+			if (plugin->eap_method_buildReq == NULL)
+			{
+				TRACE_DEBUG(
+						INFO,
+						"%s[%s plugin] Unable to resolve symbol for 'eap_method_buildReq': %s",DIAMEAP_EXTENSION,
+						plugin->methodname, dlerror());
+				return EINVAL;
+			}
+		}
+		else
+		{
+			plugin->eap_method_buildReq = NULL;
+			TRACE_DEBUG(INFO,"%s[%s plugin] Unavailable function 'eap_method_buildReq'",DIAMEAP_EXTENSION, plugin->methodname);
+			return EINVAL;
+		}
+
+		/* eap_method_getTimeout method */
+		if (registerplugin->getTimeout)
+		{
+			plugin->eap_method_getTimeout = (int(*)(struct eap_state_machine *,
+					int *)) dlsym(plugin->handler, registerplugin->getTimeout);
+			if (plugin->eap_method_getTimeout == NULL)
+			{
+				TRACE_DEBUG(
+						INFO,
+						"%s[%s plugin] Unable to resolve symbol for 'eap_method_getTimeout': %s",DIAMEAP_EXTENSION,
+						plugin->methodname, dlerror());
+				return EINVAL;
+			}
+		}
+		else
+		{
+			plugin->eap_method_getTimeout = NULL;
+			TRACE_DEBUG(FULL+1,"%s[%s plugin] Unavailable function  'eap_method_getTimeout'",DIAMEAP_EXTENSION, plugin->methodname);
+		}
+
+		/* eap_method_check method */
+		if (registerplugin->check)
+		{
+			plugin->eap_method_check = (boolean(*)(struct eap_state_machine *,
+					struct eap_packet)) dlsym(plugin->handler,
+					registerplugin->check);
+			if (plugin->eap_method_check == NULL)
+			{
+				TRACE_DEBUG(
+						INFO,
+						"%s[%s plugin] Unable to resolve symbol for 'eap_method_check': %s",DIAMEAP_EXTENSION,
+						plugin->methodname, dlerror());
+				return EINVAL;
+			}
+		}
+		else
+		{
+			plugin->eap_method_check = NULL;
+			TRACE_DEBUG(INFO,"%s[%s plugin] Unavailable function 'eap_method_check'",DIAMEAP_EXTENSION, plugin->methodname);
+			return EINVAL;
+		}
+
+		/* eap_method_process method */
+		if (registerplugin->process)
+		{
+			plugin->eap_method_process = (int(*)(struct eap_state_machine *,
+					struct eap_packet)) dlsym(plugin->handler,
+					registerplugin->process);
+			if (plugin->eap_method_process == NULL)
+			{
+				TRACE_DEBUG(
+						INFO,
+						"%s[%s plugin] Unable to resolve symbol for 'eap_method_process': %s",DIAMEAP_EXTENSION,
+						plugin->methodname, dlerror());
+				return EINVAL;
+			}
+		}
+		else
+		{
+			plugin->eap_method_process = NULL;
+			TRACE_DEBUG(INFO,"%s[%s plugin] Unavailable function 'eap_method_process'",DIAMEAP_EXTENSION, plugin->methodname);
+			return EINVAL;
+		}
+
+		/* eap_method_isDone method */
+		if (registerplugin->isDone)
+		{
+			plugin->eap_method_isDone
+					= (boolean(*)(struct eap_state_machine *)) dlsym(
+							plugin->handler, registerplugin->isDone);
+			if (plugin->eap_method_isDone == NULL)
+			{
+				TRACE_DEBUG(
+						INFO,
+						"%s[%s plugin] Unable to resolve symbol for 'eap_method_isDone': %s",DIAMEAP_EXTENSION,
+						plugin->methodname, dlerror());
+				return EINVAL;
+			}
+		}
+		else
+		{
+			plugin->eap_method_isDone = NULL;
+			TRACE_DEBUG(INFO,"%s[%s plugin] Unavailable function 'eap_method_isDone'",DIAMEAP_EXTENSION, plugin->methodname);
+			return EINVAL;
+		}
+
+		/* eap_method_getKey method */
+		if (registerplugin->getKey)
+		{
+			plugin->eap_method_getKey = (int(*)(struct eap_state_machine *,
+					u8**, int*)) dlsym(plugin->handler, registerplugin->getKey);
+			if (plugin->eap_method_getKey == NULL)
+			{
+				TRACE_DEBUG(
+						INFO,
+						"%s[%s plugin] Unable to resolve symbol for 'eap_method_getKey': %s",DIAMEAP_EXTENSION,
+						plugin->methodname, dlerror());
+				return EINVAL;
+			}
+		}
+		else
+		{
+			plugin->eap_method_getKey = NULL;
+			TRACE_DEBUG(FULL+1,"%s[%s plugin] Unavailable function 'eap_method_getKey'",DIAMEAP_EXTENSION, plugin->methodname);
+		}
+
+		/* eap_method_unregister method */
+		if (registerplugin->unregister)
+		{
+			plugin->eap_method_unregister = (void(*)(void)) dlsym(
+					plugin->handler, registerplugin->unregister);
+			if (plugin->eap_method_unregister == NULL)
+			{
+				TRACE_DEBUG(
+						INFO,
+						"%s[%s plugin] Unable to resolve symbol for 'eap_method_unregister': %s",DIAMEAP_EXTENSION,
+						plugin->methodname, dlerror());
+				return EINVAL;
+			}
+		}
+		else
+		{
+			plugin->eap_method_unregister = NULL;
+			TRACE_DEBUG(FULL+1,"%s[%s plugin] Unavailable function 'eap_method_unregister'",DIAMEAP_EXTENSION, plugin->methodname);
+		}
+
+		/* eap_method_datafree method */
+		if (registerplugin->datafree)
+		{
+			plugin->eap_method_free = (void(*)(void *)) dlsym(plugin->handler,
+					registerplugin->datafree);
+			if (plugin->eap_method_free == NULL)
+			{
+				TRACE_DEBUG(
+						INFO,
+						"%s[%s plugin] Unable to resolve symbol for 'eap_method_datafree': %s",DIAMEAP_EXTENSION,
+						plugin->methodname, dlerror());
+				return EINVAL;
+			}
+		}
+		else
+		{
+			plugin->eap_method_free = NULL;
+			TRACE_DEBUG(FULL+1,"%s[%s plugin] Unavailable function 'eap_method_datafree'",DIAMEAP_EXTENSION, plugin->methodname);
+		}
+
+		if (plugin->eap_method_configure != NULL)
+		{
+			/* call the configuration method */
+			ret = (*plugin->eap_method_configure)(plugin->conffile);
+			if (ret != 0)
+			{
+				TRACE_DEBUG(
+						INFO,
+						"%s[%s plugin] Unable to configure the plugin",DIAMEAP_EXTENSION,
+						plugin->methodname);
+				return ret;
+			}
+		}
+
+		TRACE_DEBUG(FULL, "%s[%s plugin] Loaded successfully.",DIAMEAP_EXTENSION,
+				plugin->methodname);
+
+		/* load next method */
+	}
+
+	return 0;
+}
+
+boolean diameap_plugin_exist(u32 vendor, eap_type type)
+{
+
+	TRACE_ENTRY("%p %p",vendor,type);
+	struct fd_list * pl;
+
+	for (pl = plugins_list.next; pl != &plugins_list; pl = pl->next)
+	{
+		struct plugin * plugin = (struct plugin *) pl;
+		if (plugin->methodtype == type && plugin->vendor == vendor)
+		{
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
+
+int diameap_plugin_unload(void)
+{
+
+	while (!FD_IS_LIST_EMPTY(&plugins_list))
+	{
+		struct fd_list * plugin = plugins_list.next;
+		struct plugin * item = (struct plugin *) plugin;
+
+		fd_list_unlink(plugin);
+
+		if (item->eap_method_unregister != NULL)
+		{
+			(*item->eap_method_unregister)();
+		}
+
+		if (item->handler)
+		{
+			if (dlclose(item->handler) != 0)
+			{
+				TRACE_DEBUG (INFO, "%sFail to unload plugin %s : %s",DIAMEAP_EXTENSION, item->methodname, dlerror());
+			}
+		}
+
+		free(item->conffile);
+		free(item->pluginfile);
+		free(item);
+	}
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/diameap_plugins.h	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,67 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+
+#ifndef DIAMEAP_PLUGINS_H_
+#define DIAMEAP_PLUGINS_H_
+
+#include <dlfcn.h>
+
+
+
+static struct fd_list plugins_list = FD_LIST_INITIALIZER(plugins_list);
+
+/* Add a plug-in to the list of plugins*/
+int diameap_plugin_add(char * name, eap_type methodtype, u32 vendor, char * filename,
+		char * conffile);
+
+/* Dump all plug-ins (plugins_list)*/
+void diameap_plugin_dump();
+
+/* Return pointer to a plug-in */
+int diameap_plugin_get(u32 vendor,eap_type type, struct plugin ** getplugin);
+
+/* Load plug-ins */
+int diameap_plugin_load(void);
+
+/* Check if a plug-in exists for a given EAP method type */
+boolean diameap_plugin_exist(u32 vendor, eap_type type);
+
+/* Unload all plug-ins*/
+int diameap_plugin_unload(void);
+
+#endif /* DIAMEAP_PLUGINS_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/diameap_server.c	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,3389 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+#include "diameap_common.h"
+
+struct avp_max_occurences auth_avps[] =
+{
+{ "Service-Type", 1 },
+{ "Callback-Number", 1 },
+{ "Callback-Id", 1 },
+{ "Idle-Timeout", 1 },
+{ "Port-Limit", 1 },
+{ "NAS-Filter-Rule" - 1 },
+{ "Filter-Id", -1 },
+{ "Configuration-Token", -1 },
+{ "QoS-Filter-Rule", -1 },
+{ "Framed-Protocol", 1 },
+{ "Framed-Routing", 1 },
+{ "Framed-MTU", 1 },
+{ "Framed-Compression", -1 },
+{ "Framed-IP-Address", 1 },
+{ "Framed-IP-Netmask", 1 },
+{ "Framed-Route", -1 },
+{ "Framed-Pool", 1 },
+{ "Framed-Interface-Id", 1 },
+{ "Framed-IPv6-Prefix", -1 },
+{ "Framed-IPv6-Pool", 1 },
+{ "Framed-IPv6-Route", -1 },
+{ "Framed-IPX-Network", 1 },
+{ "Framed-Appletalk-Link", 1 },
+{ "Framed-Appletalk-Network", -1 },
+{ "Framed-Appletalk-Zone", 1 },
+{ "NAS-IPv6-Address", 0 },
+{ "NAS-Identifier", 0 },
+{ "NAS-IP-Address", 0 },
+{ "NAS-Port", 0 },
+{ "NAS-Port-Id", 0 },
+{ "NAS-Port-Type", 0 },
+{ "Called-Station-Id", 0 },
+{ "Calling-Station-Id", 0 },
+{ "Connect-Info", 0 },
+{ "Originating-Line-Info", 0 } };
+
+static int diameap_server_callback(struct msg ** rmsg, struct avp * ravp,
+		struct session * sess, enum disp_action * action)
+{
+	TRACE_ENTRY("%p %p %p %p", rmsg, ravp, sess, action);
+
+	struct diameap_sess_data_sm * diameap_sess_data = NULL;
+	struct diameap_state_machine * diameap_sm = NULL;
+	struct diameap_eap_interface eap_i;
+	struct msg *req, *ans;
+	boolean non_fatal_error = FALSE;
+
+	if (rmsg == NULL)
+		return EINVAL;
+
+	req = *rmsg;
+
+	CHECK_FCT_DO(fd_sess_state_retrieve(diameap_server_reg, sess, &diameap_sess_data),
+			{	TRACE_DEBUG(INFO,"%s retrieving session state failed.",DIAMEAP_EXTENSION); goto s_end;});
+
+	CHECK_MALLOC_DO(diameap_sm = malloc(sizeof(struct diameap_state_machine)),
+			goto s_end);
+	memset(diameap_sm, 0, sizeof(struct diameap_state_machine));
+
+	if (diameap_sess_data)
+	{
+		diameap_sm->state = DIAMEAP_RECEIVED;
+		diameap_sm->eap_sm.eap_state = EAP_IDLE;
+	}
+	else
+	{
+		diameap_sm->state = DIAMEAP_DISABLED;
+		diameap_sm->eap_sm.eap_state = EAP_INITIALIZE;
+	}
+
+	while (diameap_sm->state != DIAMEAP_IDLE && diameap_sm->state
+			!= DIAMEAP_END)
+	{
+		switch (diameap_sm->state)
+		{
+		case DIAMEAP_DISABLED:
+			if (rmsg)
+			{
+				diameap_sm->state = DIAMEAP_INITIALIZE;
+			}
+			else
+			{
+				TRACE_DEBUG(INFO,"%sReceived empty Diameter EAP Request message.",DIAMEAP_EXTENSION);
+				goto s_end;
+			}
+			break;
+
+		case DIAMEAP_INITIALIZE:
+
+			CHECK_FCT_DO(diameap_initialize_diameap_sm(diameap_sm,diameap_sess_data),
+					{	TRACE_DEBUG(INFO,"%s Initializing DiamEAP state machine failed.",DIAMEAP_EXTENSION); goto s_end;})
+			;
+			CHECK_FCT_DO(diameap_initialize_diameap_eap_interface(&eap_i),
+					{	TRACE_DEBUG(INFO,"%s Initializing DiamEAP-EAP Interface failed.",DIAMEAP_EXTENSION); goto s_end;})
+			;
+			TRACE_DEBUG(FULL+1,"%sParsing AVPs",DIAMEAP_EXTENSION)
+			;
+			CHECK_FCT_DO(diameap_parse_avps(diameap_sm, req, &eap_i), TRACE_DEBUG(INFO,"%s Unable to parse Diameter-EAP-Request AVPs.",DIAMEAP_EXTENSION))
+			;
+
+			if ((diameap_sm->result_code != 0))
+			{
+				diameap_sm->state = DIAMEAP_SEND_ERROR_MSG;
+			}
+			else
+			{
+				diameap_sm->state = DIAMEAP_AUTHENTICATION_VERIFY;
+			}
+			break;
+
+		case DIAMEAP_RECEIVED:
+
+			CHECK_FCT_DO(diameap_initialize_diameap_sm(diameap_sm,diameap_sess_data),
+					{	TRACE_DEBUG(INFO,"%s Initializing DiamEAP state machine failed.",DIAMEAP_EXTENSION); goto s_end;})
+			;
+			CHECK_FCT_DO(diameap_initialize_diameap_eap_interface(&eap_i),
+					{	TRACE_DEBUG(INFO,"%s Initializing DiamEAP-EAP Interface failed.",DIAMEAP_EXTENSION); goto s_end;})
+			;
+			TRACE_DEBUG(FULL+1,"%sParsing AVPs",DIAMEAP_EXTENSION)
+			;
+			CHECK_FCT_DO(diameap_parse_avps(diameap_sm, req, &eap_i), TRACE_DEBUG(INFO,"%s Unable to parse Diameter-EAP-Request AVPs.",DIAMEAP_EXTENSION))
+			;
+
+			if (diameap_sm->result_code != 0)
+			{
+				diameap_sm->state = DIAMEAP_SEND_ERROR_MSG;
+			}
+			else
+			{
+				diameap_sm->state = DIAMEAP_AUTHENTICATION_VERIFY;
+			}
+			break;
+
+		case DIAMEAP_AUTHENTICATION_VERIFY:
+		{
+
+			TRACE_DEBUG(FULL+1,"%sVerify authentication",DIAMEAP_EXTENSION);
+			CHECK_FCT_DO(diameap_eap_statemachine(&diameap_sm->eap_sm, &eap_i,&non_fatal_error),
+					{	TRACE_DEBUG(INFO,"%s EAP process failed.",DIAMEAP_EXTENSION); goto s_end;});
+
+			if (non_fatal_error == TRUE)
+			{
+				TRACE_DEBUG(FULL+1,"%sAuthentication verify finished with a non-fatal-error.",DIAMEAP_EXTENSION);
+				diameap_sm->state = DIAMEAP_SEND_ERROR_MSG;
+			}
+			else
+			{
+				diameap_sm->state = DIAMEAP_SELECT_DECISION;
+
+			}
+		}
+			break;
+
+		case DIAMEAP_SELECT_DECISION:
+
+			CHECK_FCT_DO( diameap_policy_decision(diameap_sm,eap_i),
+					goto s_end)
+			;
+
+			if ((eap_i.aaaSuccess == TRUE) && (diameap_sm->auth_request_val
+					== AUTHORIZE_AUTHENTICATE)
+					&& (diameap_sm->verify_authorization == FALSE))
+			{
+				diameap_sm->state = DIAMEAP_AUTHORIZATION_VERIFY;
+			}
+			else
+			{
+				diameap_sm->state = DIAMEAP_DIAMETER_EAP_ANSWER;
+			}
+			break;
+
+		case DIAMEAP_AUTHORIZATION_VERIFY:
+			diameap_sm->verify_authorization = TRUE;
+			TRACE_DEBUG(FULL+1,"%sVerify authorization",DIAMEAP_EXTENSION)
+			;
+			CHECK_FCT_DO(diameap_authorize(diameap_sm),
+					{	TRACE_DEBUG(INFO,"%s Authorization check process failed.",DIAMEAP_EXTENSION); goto s_end;})
+			;
+			diameap_sm->state = DIAMEAP_SELECT_DECISION;
+
+			break;
+
+		case DIAMEAP_DIAMETER_EAP_ANSWER:
+			TRACE_DEBUG(FULL+1,"%screate Diameter EAP Answer",DIAMEAP_EXTENSION)
+			;
+			CHECK_FCT_DO(fd_msg_new_answer_from_req(fd_g_config->cnf_dict, rmsg, 0),
+					goto s_end)
+			;
+			ans = *rmsg;
+			TRACE_DEBUG(FULL+1,"%sAdding AVPs to Diameter EAP Answer.",DIAMEAP_EXTENSION)
+			;
+			CHECK_FCT_DO( diameap_add_avps(diameap_sm, ans,req),
+					{	TRACE_DEBUG(INFO,"%s Unable to add AVPs to Diameter-EAP-Answer message.",DIAMEAP_EXTENSION);goto s_end;})
+			;
+			if (diameap_sm->authFailure == FALSE)
+			{
+				if (diameap_sm->eap_sm.user.id != 0)
+				{
+					TRACE_DEBUG(FULL+1,"%sSelect authentication attributes.",DIAMEAP_EXTENSION);
+					CHECK_FCT_DO(diameap_authentication_get_attribs(diameap_sm->eap_sm.user, &diameap_sm->attributes),
+							{	TRACE_DEBUG(INFO,"%s Unable to get user's session attributes.",DIAMEAP_EXTENSION); goto s_end;});
+					TRACE_DEBUG(FULL+1,"%sCreate answer authentication attributes.",DIAMEAP_EXTENSION);
+					CHECK_FCT_DO(diameap_answer_avp_attributes(diameap_sm),
+							{	TRACE_DEBUG(INFO,"% Unable to generate answer attributes.",DIAMEAP_EXTENSION); goto s_end;});
+				}
+
+				if (diameap_sm->authSuccess == FALSE)
+				{
+					diameap_sm->state = DIAMEAP_SEND_REQUEST;
+				}
+				else
+				{
+
+					diameap_sm->state = DIAMEAP_SEND_SUCCESS;
+				}
+			}
+			else
+			{
+				diameap_sm->state = DIAMEAP_SEND_FAILURE;
+			}
+			break;
+
+		case DIAMEAP_SEND_REQUEST:
+			TRACE_DEBUG(FULL+1,"%sAdding Result Code AVP to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
+			;
+			CHECK_FCT_DO( diameap_add_result_code(diameap_sm, ans, sess),
+					{	TRACE_DEBUG(INFO,"%s Adding Result-Code AVP failed.",DIAMEAP_EXTENSION); goto s_end;})
+			;
+			TRACE_DEBUG(FULL+1,"%sAdding EAP-Payload to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
+			;
+			CHECK_FCT_DO( diameap_add_eap_payload(diameap_sm, ans,eap_i),
+					{	TRACE_DEBUG(INFO,"%s Adding EAP-Payload AVP failed.",DIAMEAP_EXTENSION); goto s_end;})
+			;
+			TRACE_DEBUG(FULL+1,"%sStoring DiamEAP session data.",DIAMEAP_EXTENSION)
+			;
+			CHECK_MALLOC(diameap_sess_data = malloc(sizeof(struct diameap_sess_data_sm)))
+			;
+			memset(diameap_sess_data, 0, sizeof(struct diameap_sess_data_sm));
+			diameap_sess_data_new(diameap_sess_data, diameap_sm);
+
+			CHECK_FCT_DO(fd_sess_state_store(diameap_server_reg, sess, &diameap_sess_data),
+					{	TRACE_DEBUG(INFO,"%s Storing session state failed.",DIAMEAP_EXTENSION); goto s_end;})
+			;
+
+			CHECK_FCT_DO( diameap_send(rmsg),
+					goto s_end)
+			;
+
+			diameap_sm->state = DIAMEAP_IDLE;
+			break;
+
+		case DIAMEAP_SEND_FAILURE:
+			TRACE_DEBUG(FULL+1,"%sAdding Result Code AVP to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
+			;
+			CHECK_FCT_DO( diameap_add_result_code(diameap_sm, ans, sess),
+					{	TRACE_DEBUG(INFO,"%s Adding Result-Code AVP failed.",DIAMEAP_EXTENSION); goto s_end;})
+			;
+			TRACE_DEBUG(FULL+1,"%sAdding EAP-Payload to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
+			;
+			CHECK_FCT_DO( diameap_add_eap_payload(diameap_sm, ans,eap_i),
+					{	TRACE_DEBUG(INFO,"%s Adding EAP-Payload AVP failed.",DIAMEAP_EXTENSION); goto s_end;})
+			;
+
+			CHECK_FCT_DO( diameap_send(rmsg),
+					goto s_end)
+			;
+			diameap_sm->state = DIAMEAP_END;
+			break;
+
+		case DIAMEAP_SEND_SUCCESS:
+			TRACE_DEBUG(FULL+1,"%sAdding User session AVPs to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
+			;
+			CHECK_FCT_DO(diameap_add_user_sessions_avps(diameap_sm,ans),
+					{	TRACE_DEBUG(INFO,"%s Adding user's session AVPs failed.",DIAMEAP_EXTENSION); goto s_end;})
+			;
+
+			if (diameap_sm->auth_request_val == AUTHORIZE_AUTHENTICATE)
+			{
+				TRACE_DEBUG(FULL+1,"%sAdding Authorization AVPs to Diameter-EAP-Answer.",DIAMEAP_EXTENSION);
+				CHECK_FCT_DO(diameap_add_authorization_avps(diameap_sm,ans),
+						{	TRACE_DEBUG(INFO,"%s Adding Authorization AVPs failed.",DIAMEAP_EXTENSION); goto s_end;});
+			}
+			TRACE_DEBUG(FULL+1,"%sAdding Result Code AVP to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
+			;
+			CHECK_FCT_DO( diameap_add_result_code(diameap_sm, ans, sess),
+					{	TRACE_DEBUG(INFO,"%s Adding Result-Code AVP failed.",DIAMEAP_EXTENSION); goto s_end;})
+			;
+			TRACE_DEBUG(FULL+1,"%sAdding EAP-Payload to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
+			;
+			CHECK_FCT_DO( diameap_add_eap_payload(diameap_sm, ans,eap_i),
+					{	TRACE_DEBUG(INFO,"%s Adding EAP-Payload AVP failed.",DIAMEAP_EXTENSION); goto s_end;})
+			;
+			TRACE_DEBUG(FULL+1,"%sAdding EAP success AVPs AVPs to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
+			;
+			CHECK_FCT_DO( diameap_add_eap_success_avps(diameap_sm, ans, eap_i),
+					goto s_end)
+			;
+			TRACE_DEBUG(FULL+1,"%sAdding Accounting-EAP-Auth-Method AVPs to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
+			;
+			CHECK_FCT_DO(diameap_add_accounting_eap_auth_method(diameap_sm, ans),
+					{	TRACE_DEBUG(INFO,"%s Adding accounting AVP failed",DIAMEAP_EXTENSION); goto s_end;})
+			;
+			CHECK_FCT_DO( diameap_send(rmsg),
+					goto s_end)
+			;
+			diameap_sm->state = DIAMEAP_END;
+			break;
+
+		case DIAMEAP_SEND_ERROR_MSG:
+			diameap_sm->invalid_eappackets++;
+			if (diameap_sm->invalid_eappackets
+					== diameap_config->max_invalid_eap_packet)
+			{
+				diameap_sm->result_code = 4001;//DIAMETER_AUTHENTICATION_REJECTED
+				TRACE_DEBUG(FULL,"%s Maximum permitted invalid EAP Packet reached. Diameter Authentication Rejected.",DIAMEAP_EXTENSION);
+			}
+
+			CHECK_FCT_DO(fd_msg_new_answer_from_req(fd_g_config->cnf_dict, rmsg, 0),
+					goto s_end)
+			;
+
+			ans = *rmsg;
+			CHECK_FCT_DO( diameap_add_avps(diameap_sm, ans,req),
+					{	TRACE_DEBUG(INFO,"%s Adding AVPs to Diameter-EAP-Answer message failed.",DIAMEAP_EXTENSION);goto s_end;})
+			;
+			if ((non_fatal_error == TRUE) && (diameap_sm->result_code == 0))
+			{
+				diameap_sm->result_code = 1001;
+			}
+
+			if (diameap_sm->result_code == 1001)
+			{
+				CHECK_FCT_DO( diameap_add_eap_reissued_payload(ans,req), goto s_end);
+			}
+
+			if (diameap_sm->result_code == 5004)
+			{
+				CHECK_FCT_DO( fd_msg_avp_add( ans , MSG_BRW_LAST_CHILD, diameap_sm->failedavp ),goto s_end );
+			}
+
+			CHECK_FCT_DO( diameap_add_result_code(diameap_sm, ans, sess), goto s_end)
+			;
+
+			CHECK_FCT_DO( diameap_send(rmsg), goto s_end)
+			;
+			diameap_sm->state = DIAMEAP_IDLE;
+			break;
+
+		case DIAMEAP_END:
+
+			break;
+		}
+	}
+
+	diameap_free(diameap_sm);
+
+	s_end: return 0;
+}
+
+void diameap_cli_sess_cleanup(void * arg, char * sid)
+{
+
+	struct diameap_sess_data_sm * diameap_sess_data =
+			(struct diameap_sess_data_sm *) arg;
+	CHECK_PARAMS_DO( diameap_sess_data, return );
+
+	if (diameap_sess_data != NULL)
+	{
+		if (diameap_sess_data->methodData != NULL)
+		{
+			struct plugin * cplugin;
+			if (diameap_plugin_get(diameap_sess_data->currentVendor,
+					diameap_sess_data->currentMethod, &cplugin))
+			{
+				TRACE_DEBUG(INFO,"%sUnable to access EAP Method plugin {Type=%d, Vendor=%d}.",DIAMEAP_EXTENSION,diameap_sess_data->currentMethod,diameap_sess_data->currentVendor);
+			}
+
+			if (cplugin->eap_method_free)
+			{
+				(*cplugin->eap_method_free)(diameap_sess_data->methodData);
+				diameap_sess_data->methodData = NULL;
+			}
+			else
+			{
+				TRACE_DEBUG(FULL+1,"%s[%s plugin] datafree function not available.",DIAMEAP_EXTENSION,cplugin->methodname);
+				if (diameap_sess_data->methodData != NULL)
+				{
+					free(diameap_sess_data->methodData);
+					diameap_sess_data->methodData = NULL;
+				}
+			}
+			if (diameap_sess_data->methodData)
+			{
+				TRACE_DEBUG(INFO,"%sSession state was not been freed correctly!!!",DIAMEAP_EXTENSION);
+			}
+		}
+
+		if (diameap_sess_data->user.password != NULL)
+		{
+			free(diameap_sess_data->user.password);
+			diameap_sess_data->user.password = NULL;
+		}
+
+		if (diameap_sess_data->user.userid != NULL)
+		{
+			free(diameap_sess_data->user.userid);
+			diameap_sess_data->user.userid = NULL;
+		}
+		free(diameap_sess_data);
+		diameap_sess_data = NULL;
+	}
+}
+
+static int diameap_initialize_diameap_sm(
+		struct diameap_state_machine * diameap_sm,
+		struct diameap_sess_data_sm * diameap_sess_data)
+{
+	TRACE_ENTRY("%p %p", diameap_sm, diameap_sess_data);
+
+	int i;
+
+	/* Initialize Long Term Variables */
+	if (diameap_sess_data != NULL)
+	{
+		diameap_sm->invalid_eappackets = diameap_sess_data->invalid_eappackets;
+
+		/* Initialize eap state machine variables */
+		/*User*/
+		diameap_sm->eap_sm.user.id = diameap_sess_data->user.id;
+
+		if ((diameap_sess_data->user.userid != NULL)
+				&& (diameap_sess_data->user.useridLength > 0))
+		{
+			diameap_sm->eap_sm.user.useridLength
+					= diameap_sess_data->user.useridLength;
+			CHECK_MALLOC(diameap_sm->eap_sm.user.userid= malloc(diameap_sm->eap_sm.user.useridLength));
+			U8COPY(diameap_sm->eap_sm.user.userid,0,diameap_sm->eap_sm.user.useridLength,diameap_sess_data->user.userid);
+			free(diameap_sess_data->user.userid);
+			diameap_sess_data->user.userid = NULL;
+
+		}
+		else
+		{
+			TRACE_DEBUG(INFO,"%s user not identified yet.",DIAMEAP_EXTENSION);
+			diameap_sm->eap_sm.user.useridLength = 0;
+			diameap_sm->eap_sm.user.userid = NULL;
+		}
+
+		if ((diameap_sess_data->user.password != NULL)
+				&& (diameap_sess_data->user.passwordLength > 0))
+		{
+			diameap_sm->eap_sm.user.passwordLength
+					= diameap_sess_data->user.passwordLength;
+			CHECK_MALLOC(diameap_sm->eap_sm.user.password = malloc(diameap_sm->eap_sm.user.passwordLength));
+			U8COPY(diameap_sm->eap_sm.user.password,0,diameap_sm->eap_sm.user.passwordLength, diameap_sess_data->user.password);
+			free(diameap_sess_data->user.password);
+			diameap_sess_data->user.password = NULL;
+		}
+		else
+		{
+			diameap_sm->eap_sm.user.passwordLength = 0;
+			diameap_sm->eap_sm.user.password = NULL;
+		}
+
+		diameap_sm->eap_sm.user.methodId = diameap_sess_data->user.methodId;
+		for (i = 0; i < MAXMETHODS; i++)
+		{
+			diameap_sm->eap_sm.user.methods[i].method
+					= diameap_sess_data->user.methods[i].method;
+			diameap_sm->eap_sm.user.methods[i].vendor
+					= diameap_sess_data->user.methods[i].vendor;
+		}
+		for (i = 0; i < MAXPROPOSEDMETHODS; i++)
+		{
+			diameap_sm->eap_sm.user.proposedmethods[i].method
+					= diameap_sess_data->user.proposedmethods[i].method;
+			diameap_sm->eap_sm.user.proposedmethods[i].vendor
+					= diameap_sess_data->user.proposedmethods[i].vendor;
+		}
+
+		diameap_sm->eap_sm.user.pmethods = diameap_sess_data->user.pmethods;
+		diameap_sm->eap_sm.user.proposed_eap_method
+				= diameap_sess_data->user.proposed_eap_method;
+		diameap_sm->eap_sm.user.proposed_eap_method_vendor
+				= diameap_sess_data->user.proposed_eap_method_vendor;
+		diameap_sm->eap_sm.user.success = diameap_sess_data->user.success;
+
+		diameap_sm->eap_sm.currentId = diameap_sess_data->currentId;
+		diameap_sm->eap_sm.currentVendor = diameap_sess_data->currentVendor;
+		diameap_sm->eap_sm.lastId = diameap_sess_data->lastId;
+		diameap_sm->eap_sm.methodState = diameap_sess_data->methodState;
+		diameap_sm->eap_sm.currentMethod = diameap_sess_data->currentMethod;
+
+		diameap_sm->eap_sm.methodData = diameap_sess_data->methodData;
+		diameap_sess_data->methodData = NULL;
+
+		if (diameap_sm->eap_sm.currentMethod != TYPE_NONE)
+		{
+			diameap_plugin_get(diameap_sm->eap_sm.currentVendor,
+					diameap_sm->eap_sm.currentMethod,
+					&diameap_sm->eap_sm.selectedMethod);
+		}
+
+		/* free session data*/
+		free(diameap_sess_data);
+		diameap_sess_data = NULL;
+
+	}
+	else
+	{
+		diameap_sm->invalid_eappackets = 0;
+
+		/* Initialize eap state machine variables */
+		/*User*/
+		diameap_sm->eap_sm.user.id = 0;
+		diameap_sm->eap_sm.user.userid = NULL;
+		diameap_sm->eap_sm.user.useridLength = 0;
+		diameap_sm->eap_sm.user.password = NULL;
+		diameap_sm->eap_sm.user.passwordLength = 0;
+		diameap_sm->eap_sm.user.methodId = -1;
+		for (i = 0; i < MAXMETHODS; i++)
+		{
+			diameap_sm->eap_sm.user.methods[i].method = TYPE_NONE;
+			diameap_sm->eap_sm.user.methods[i].vendor = VENDOR_IETF;
+		}
+		for (i = 0; i < MAXPROPOSEDMETHODS; i++)
+		{
+			diameap_sm->eap_sm.user.proposedmethods[i].method = TYPE_NONE;
+			diameap_sm->eap_sm.user.proposedmethods[i].vendor = VENDOR_IETF;
+		}
+
+		diameap_sm->eap_sm.user.pmethods = -1;
+		diameap_sm->eap_sm.user.proposed_eap_method = TYPE_NONE;
+		diameap_sm->eap_sm.user.proposed_eap_method_vendor = VENDOR_IETF;
+		diameap_sm->eap_sm.user.success = FALSE;
+
+		diameap_sm->eap_sm.currentId = -1;
+		diameap_sm->eap_sm.currentVendor = VENDOR_IETF;
+		diameap_sm->eap_sm.lastId = -1;
+		diameap_sm->eap_sm.methodState = EAP_M_PROPOSED;
+
+		diameap_sm->eap_sm.currentMethod = TYPE_NONE;
+
+		diameap_sm->eap_sm.methodData = NULL;
+
+	}
+
+	diameap_sm->result_code = 0;
+	fd_list_init(&diameap_sm->attributes, NULL);
+	fd_list_init(&diameap_sm->req_attributes, NULL);
+	fd_list_init(&diameap_sm->ans_attributes, NULL);
+	diameap_sm->failedavp = NULL;
+	diameap_sm->auth_request_val = AUTHENTICATE_ONLY;
+	diameap_sm->verify_authorization = FALSE;
+	diameap_sm->authSuccess = FALSE;
+	diameap_sm->authFailure = FALSE;
+	diameap_sm->lastReqEAPavp = NULL;
+	diameap_sm->privateUser = FALSE;
+	diameap_sm->authorized = FALSE;
+
+	diameap_sm->eap_sm.rxResp = FALSE;
+	diameap_sm->eap_sm.respId = -1;
+	diameap_sm->eap_sm.respMethod = TYPE_NONE;
+	diameap_sm->eap_sm.respVendor = VENDOR_IETF;
+	diameap_sm->eap_sm.respVendorMethod = TYPE_NONE;
+
+	return 0;
+}
+
+static int diameap_initialize_diameap_eap_interface(
+		struct diameap_eap_interface * eap_i)
+{
+	TRACE_ENTRY("%p", eap_i);
+
+	//Initialize AAA-EAP Interface
+	eap_i->aaaEapResp = FALSE;
+	eap_i->aaaEapRespData.data = NULL;
+	//Initialize EAP-AAA Interface
+	eap_i->aaaEapReq = FALSE;
+	eap_i->aaaEapNoReq = FALSE;
+	eap_i->aaaSuccess = FALSE;
+	eap_i->aaaFail = FALSE;
+	eap_i->aaaEapReqData.data = NULL;
+	eap_i->aaaEapKeyData = NULL;
+	eap_i->aaaEapKeyAvailable = FALSE;
+	eap_i->aaaMethodTimeout = 0;
+
+	return 0;
+}
+
+static int diameap_parse_avps(struct diameap_state_machine * diameap_sm,
+		struct msg * req, struct diameap_eap_interface * eap_i)
+{
+	TRACE_ENTRY("%p %p %p",diameap_sm,req,eap_i);
+	struct avp * avp, *avp2;
+	struct avp_hdr * avpdata;
+	int ret;
+	int depth;
+
+	/* EAP-Payload data*/
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_eap_payload, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		CHECK_FCT(diameap_eappacket_new(&eap_i->aaaEapRespData, avpdata));
+		eap_i->aaaEapResp = TRUE;
+		u16 length;
+		diameap_eap_get_length(eap_i->aaaEapRespData, &length);
+		if (length >= 4)
+		{
+			eap_code code;
+			CHECK_FCT(diameap_eap_get_code(eap_i->aaaEapRespData,&code));
+
+			if (code != EAP_RESPONSE)
+			{
+				diameap_sm->result_code = 5004; /* DIAMETER_INVALID_AVP_VALUE 5004 */
+				struct avp * invalidavp;
+				union avp_value val;
+				CHECK_FCT( fd_msg_avp_new ( dataobj_eap_payload, 0, &invalidavp));
+				val.os.data = (char *) eap_i->aaaEapRespData.data;
+				val.os.len = eap_i->aaaEapRespData.length;
+				CHECK_FCT( fd_msg_avp_setvalue( invalidavp, &val ))
+				CHECK_FCT( diameap_failed_avp(diameap_sm, invalidavp));
+				TRACE_DEBUG(INFO,"%sIncorrect EAP Packet. EAP Code != Response.",DIAMEAP_EXTENSION);
+				return 0;
+			}
+			else
+			{
+				CHECK_FCT(diameap_parse_eap_resp(&diameap_sm->eap_sm,eap_i->aaaEapRespData));
+				if (diameap_sm->eap_sm.rxResp == FALSE)
+				{
+					diameap_sm->result_code = 1001; /*DIAMETER_MULTI_ROUND_AUTH*/
+					eap_i->aaaEapNoReq = TRUE;
+					eap_i->aaaEapResp = FALSE;
+				}
+			}
+		}
+		else
+		{
+			if (diameap_sm->eap_sm.currentMethod != TYPE_NONE)
+			{
+				diameap_sm->result_code = 5004; /* DIAMETER_INVALID_AVP_VALUE 5004 */
+				CHECK_FCT(diameap_failed_avp(diameap_sm, avp));
+				TRACE_DEBUG(INFO,"%sEAP packet length < Minimum EAP packet length.",DIAMEAP_EXTENSION);
+				return 1;
+			}
+			//EAP start received
+
+		}
+	}
+
+	/* User-Name AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_user_name, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "User-Name";
+		attribute->value.os.data = avpdata->avp_value->os.data;
+		attribute->value.os.len = avpdata->avp_value->os.len;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* EAP-Key-Name AVP */
+
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_eap_key_name, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "EAP-Key-Name";
+		attribute->value.os.data = avpdata->avp_value->os.data;
+		attribute->value.os.len = avpdata->avp_value->os.len;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Auth-Request-Type AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_auth_request_type, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		diameap_sm->auth_request_val = avpdata->avp_value->i32;
+	}
+
+	/* Authorization-Lifetime AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_authorization_lifetime, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Authorization-Lifetime";
+		attribute->value.u32 = avpdata->avp_value->u32;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Auth-Grace-Period AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_auth_grace_period, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Auth-Grace-Period";
+		attribute->value.u32 = avpdata->avp_value->u32;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Auth-Session-State AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_auth_session_state, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Auth-Session-State";
+		attribute->value.i32 = avpdata->avp_value->i32;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Origin-state-Id AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_origin_state_id, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Origin-state-Id AVP";
+		attribute->value.u32 = avpdata->avp_value->u32;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* NAS-Port AVP*/
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_nas_port, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "NAS-Port";
+		attribute->value.u32 = avpdata->avp_value->u32;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* NAS-Port-Id AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_nas_port_id, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "NAS-Port-Id";
+		attribute->value.os.data = avpdata->avp_value->os.data;
+		attribute->value.os.len = avpdata->avp_value->os.len;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* NAS-Port-Type AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_nas_port_type, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "NAS-Port-Type";
+		attribute->value.u32 = avpdata->avp_value->u32;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Called-Station-Id AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_called_station_id, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Called-Station-Id";
+		attribute->value.os.data = avpdata->avp_value->os.data;
+		attribute->value.os.len = avpdata->avp_value->os.len;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Calling-Station-Id AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_calling_station_id, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Calling-Station-Id";
+		attribute->value.os.data = avpdata->avp_value->os.data;
+		attribute->value.os.len = avpdata->avp_value->os.len;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Connect-Info AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_connect_info, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Connect-Info";
+		attribute->value.os.data = avpdata->avp_value->os.data;
+		attribute->value.os.len = avpdata->avp_value->os.len;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Originating-Line-Info AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_originating_line_info, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Originating-Line-Info";
+		attribute->value.os.data = avpdata->avp_value->os.data;
+		attribute->value.os.len = avpdata->avp_value->os.len;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Service-Type AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_service_type, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Service-Type";
+		attribute->value.u32 = avpdata->avp_value->u32;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Callback-Number AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_callback_number, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Callback-Number";
+		attribute->value.os.data = avpdata->avp_value->os.data;
+		attribute->value.os.len = avpdata->avp_value->os.len;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Port-Limit AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_port_limit, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Port-Limit";
+		attribute->value.u32 = avpdata->avp_value->u32;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Framed-Protocol AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_framed_protocol, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Framed-Protocol";
+		attribute->value.u32 = avpdata->avp_value->u32;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Framed-MTU AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_framed_mtu, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Framed-MTU";
+		attribute->value.u32 = avpdata->avp_value->u32;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Framed-Compression AVP */
+	avp = NULL;
+	avp2 = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_framed_compression, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		u32 Pi_Code = avpdata->avp_code;
+		int depth;
+		do
+		{
+			struct avp_attribute * attribute;
+			CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+			memset(attribute, 0, sizeof(struct avp_attribute));
+			fd_list_init(&attribute->chain, attribute);
+			attribute->attrib = "Framed-Compression";
+			attribute->value.u32 = avpdata->avp_value->u32;
+			fd_list_insert_before(&diameap_sm->req_attributes,
+					&attribute->chain);
+			ret = 0;
+			depth = 0;
+			ret = fd_msg_browse ( avp, MSG_BRW_NEXT, &avp2, &depth);
+			if (avp2 != NULL)
+			{
+				CHECK_FCT(fd_msg_avp_hdr(avp2, &avpdata));
+			}
+			avp = avp2;
+		} while ((avp2 != NULL) && (ret == 0) && (ret == 0)
+				&& (avpdata->avp_code == Pi_Code));
+	}
+
+	/* Framed-IP-Address AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_framed_ip_address, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Framed-IP-Address";
+		attribute->value.os.data = avpdata->avp_value->os.data;
+		attribute->value.os.len = avpdata->avp_value->os.len;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Framed-IP-Netmask AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_framed_ip_netmask, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Framed-IP-Netmask";
+		attribute->value.os.data = avpdata->avp_value->os.data;
+		attribute->value.os.len = avpdata->avp_value->os.len;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Framed-Interface-Id AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_framed_interface_id, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Framed-Interface-Id";
+		attribute->value.u64 = avpdata->avp_value->u64;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Framed-IPv6-Prefix AVP */
+	avp = NULL;
+	avp2 = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_framed_ipv6_prefix, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		u32 Pi_Code = avpdata->avp_code;
+		do
+		{
+			struct avp_attribute * attribute;
+			CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+			memset(attribute, 0, sizeof(struct avp_attribute));
+			fd_list_init(&attribute->chain, attribute);
+			attribute->attrib = "Framed-IPv6-Prefix";
+			attribute->value.u32 = avpdata->avp_value->u32;
+			fd_list_insert_before(&diameap_sm->req_attributes,
+					&attribute->chain);
+			ret = 0;
+			depth = 0;
+			ret = fd_msg_browse ( avp, MSG_BRW_NEXT, &avp2, &depth);
+			if (avp2 != NULL)
+			{
+				CHECK_FCT(fd_msg_avp_hdr(avp2, &avpdata));
+			}
+			avp = avp2;
+		} while ((avp2 != NULL) && (ret == 0) && (ret == 0)
+				&& (avpdata->avp_code == Pi_Code));
+	}
+
+	/* Tunneling AVP */
+	avp = NULL;
+	avp2 = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_tunneling, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		u32 Pi_Code = avpdata->avp_code;
+		int depth;
+		do
+		{
+			struct avp_attribute * attribute;
+			CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+			memset(attribute, 0, sizeof(struct avp_attribute));
+			fd_list_init(&attribute->chain, attribute);
+			attribute->attrib = "Tunneling";
+			//grouped AVP
+			fd_list_insert_before(&diameap_sm->req_attributes,
+					&attribute->chain);
+			ret = 0;
+			depth = 0;
+			ret = fd_msg_browse ( avp, MSG_BRW_NEXT, &avp2, &depth);
+			if (avp2 != NULL)
+			{
+				CHECK_FCT(fd_msg_avp_hdr(avp2, &avpdata));
+			}
+			avp = avp2;
+		} while ((avp2 != NULL) && (ret == 0) && (ret == 0)
+				&& (avpdata->avp_code == Pi_Code));
+	}
+
+	/* NAS-Identifier AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_nas_identifier, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "NAS-Identifier";
+		attribute->value.os.data = avpdata->avp_value->os.data;
+		attribute->value.os.len = avpdata->avp_value->os.len;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* NAS-IP-Address AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_nas_ip_address, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "NAS-IP-Address";
+		attribute->value.os.data = avpdata->avp_value->os.data;
+		attribute->value.os.len = avpdata->avp_value->os.len;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* NAS-IPv6-Address AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_nas_ipv6_address, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "NAS-IPv6-Address";
+		attribute->value.os.data = avpdata->avp_value->os.data;
+		attribute->value.os.len = avpdata->avp_value->os.len;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* State AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_state, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "State";
+		attribute->value.os.data = avpdata->avp_value->os.data;
+		attribute->value.os.len = avpdata->avp_value->os.len;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	return 0;
+}
+
+static int diameap_failed_avp(struct diameap_state_machine * diameap_sm,
+		struct avp * invalidavp)
+{
+	TRACE_ENTRY("%p %p",diameap_sm,invalidavp);
+	if (!invalidavp)
+		return EINVAL;
+
+	if (!diameap_sm)
+		return EINVAL;
+
+	if (diameap_sm->failedavp == NULL)
+	{
+		CHECK_FCT( fd_msg_avp_new( dataobj_failed_avp, 0, &diameap_sm->failedavp) );
+
+		CHECK_FCT( fd_msg_avp_add( diameap_sm->failedavp, MSG_BRW_LAST_CHILD, invalidavp ) );
+
+	}
+	else
+	{
+		//add multiple AVPs in Failed-AVP
+	}
+	return 0;
+}
+
+static int diameap_parse_eap_resp(struct eap_state_machine * eap_sm,
+		struct eap_packet eappacket)
+{
+	TRACE_ENTRY("%p %p",eap_sm, eappacket)
+
+	unsigned int len;
+
+	eap_sm->rxResp = FALSE;
+	eap_sm->respId = -1;
+	eap_sm->respMethod = TYPE_NONE;
+	eap_sm->respVendor = VENDOR_IETF;
+	eap_sm->respVendorMethod = TYPE_NONE;
+
+	if (eappacket.data == NULL)
+	{
+		TRACE_DEBUG(INFO,"%s Empty EAP packet",DIAMEAP_EXTENSION);
+		return 0;
+	}
+
+	u16 plength;
+	CHECK_FCT(diameap_eap_get_packetlength(eappacket,&plength));
+	if ((int) plength < EAP_HEADER)
+	{
+		TRACE_DEBUG(INFO,"%s EAP packet length less than EAP header.",DIAMEAP_EXTENSION);
+		return 0;
+	}
+
+	u16 length;
+	CHECK_FCT(diameap_eap_get_length(eappacket,&length));
+	if ((int) length < EAP_HEADER)
+	{
+		TRACE_DEBUG(INFO,"%sEAP packet length field less than EAP header.",DIAMEAP_EXTENSION);
+		return 0;
+	}
+
+	if (plength < length)
+	{
+		TRACE_DEBUG(INFO,"%sLength of received EAP packet is less than the value of the length field.",DIAMEAP_EXTENSION);
+		return 0;
+	}
+
+	eap_code code;
+	CHECK_FCT(diameap_eap_get_code(eappacket,&code));
+	if (code == EAP_REQUEST || code == EAP_SUCCESS || code == EAP_FAILURE)
+	{
+		TRACE_DEBUG(INFO,"%sOnly EAP Responses are accepted at EAP server side.",DIAMEAP_EXTENSION);
+		return 0;
+	}
+
+	u8 id;
+	CHECK_FCT(diameap_eap_get_identifier(eappacket,&id));
+	eap_sm->respId = id;
+
+	CHECK_FCT(diameap_eap_get_type(eappacket,&eap_sm->respMethod));
+	if ((eap_sm->methodState != EAP_M_PROPOSED) && (eap_sm->respMethod
+			== TYPE_NAK || eap_sm->respMethod == TYPE_EXPANDED_TYPES))
+	{
+		TRACE_DEBUG(INFO,"%sNAK or EXPANDED_NAK received after an EAP TYPE been selected",DIAMEAP_EXTENSION);
+		return 0;
+	}
+
+	if ((eap_sm->respMethod == TYPE_EXPANDED_TYPES) && (length < 20))
+	{
+		TRACE_DEBUG(INFO,"%s Truncated EAP Packet received.",DIAMEAP_EXTENSION);
+		return 0;
+	}
+
+	if ((eap_sm->respMethod == TYPE_NAK) && (eap_sm->currentMethod < 4))
+	{
+		TRACE_DEBUG(INFO,"%sNAK response not expected at this step (Only EAP type = 4 and above are accepted).",DIAMEAP_EXTENSION);
+		return 0;
+	}
+
+	if (eap_sm->respMethod == TYPE_EXPANDED_TYPES)
+	{
+		u8 *data = (u8 *) eappacket.data;
+		int len = 0;
+		u32 respVendor, respVendorMethod;
+		data += 5;
+		eap_sm->respVendor = G24BIGE(data);
+		data += 3;
+		eap_sm->respVendorMethod = G32BIGE(data);
+		data += 4;
+		/*		while ((length - 12) > (len * 8))
+		 {
+		 if (((eap_type) G8(data)) != TYPE_EXPANDED_TYPES)
+		 {
+		 return FALSE;
+		 }
+		 data += 1;
+		 respVendor = G24BIGE(data);
+		 data += 3;
+		 respVendorMethod = G32BIGE(data);
+		 eap_sm->user.proposedmethods[len].method = respVendor;
+		 eap_sm->user.proposedmethods[len].vendor = respVendorMethod;
+		 len++;
+		 data += 4;
+		 }
+		 eap_sm->user.methodId = 0;*/
+	}
+
+	eap_sm->rxResp = TRUE;
+	return 0;
+}
+
+static int diameap_eappacket_new(struct eap_packet * eappacket,
+		struct avp_hdr * avpdata)
+{
+	TRACE_ENTRY("%p %p",eappacket,avpdata);
+	eappacket->ulength = (u16) avpdata->avp_value->os.len;
+	eappacket->data = (u8 *) avpdata->avp_value->os.data;
+	diameap_eap_get_packetlength(*eappacket, &eappacket->length);
+	return 0;
+}
+
+static int diameap_sess_data_new(
+		struct diameap_sess_data_sm *diameap_sess_data,
+		struct diameap_state_machine *diameap_sm)
+{
+	if (!diameap_sm)
+		return EINVAL;
+
+	int i;
+
+	diameap_sess_data->invalid_eappackets = diameap_sm->invalid_eappackets;
+
+	diameap_sess_data->user.id = diameap_sm->eap_sm.user.id;
+
+	if ((diameap_sm->eap_sm.user.userid != NULL)
+			&& (diameap_sm->eap_sm.user.useridLength > 0))
+	{
+		diameap_sess_data->user.useridLength
+				= diameap_sm->eap_sm.user.useridLength;
+		CHECK_MALLOC(diameap_sess_data->user.userid= malloc(diameap_sess_data->user.useridLength));
+		U8COPY(diameap_sess_data->user.userid,0,diameap_sess_data->user.useridLength,diameap_sm->eap_sm.user.userid);
+		free(diameap_sm->eap_sm.user.userid);
+		diameap_sm->eap_sm.user.userid = NULL;
+
+	}
+	else
+	{
+		diameap_sess_data->user.useridLength = 0;
+		diameap_sess_data->user.userid = NULL;
+	}
+
+	if ((diameap_sm->eap_sm.user.password != NULL)
+			&& (diameap_sm->eap_sm.user.passwordLength > 0))
+	{
+		diameap_sess_data->user.passwordLength
+				= diameap_sm->eap_sm.user.passwordLength;
+		CHECK_MALLOC(diameap_sess_data->user.password = malloc(diameap_sess_data->user.passwordLength));
+		U8COPY(diameap_sess_data->user.password,0,diameap_sess_data->user.passwordLength,diameap_sm->eap_sm.user.password);
+		free(diameap_sm->eap_sm.user.password);
+		diameap_sm->eap_sm.user.password = NULL;
+	}
+	else
+	{
+		diameap_sess_data->user.passwordLength = 0;
+		diameap_sess_data->user.password = NULL;
+	}
+
+	diameap_sess_data->user.methodId = diameap_sm->eap_sm.user.methodId;
+	for (i = 0; i < MAXMETHODS; i++)
+	{
+		diameap_sess_data->user.methods[i].method
+				= diameap_sm->eap_sm.user.methods[i].method;
+		diameap_sess_data->user.methods[i].vendor
+				= diameap_sm->eap_sm.user.methods[i].vendor;
+	}
+
+	for (i = 0; i < MAXPROPOSEDMETHODS; i++)
+	{
+		diameap_sess_data->user.proposedmethods[i].method
+				= diameap_sm->eap_sm.user.proposedmethods[i].method;
+		diameap_sess_data->user.proposedmethods[i].vendor
+				= diameap_sm->eap_sm.user.proposedmethods[i].vendor;
+	}
+
+	diameap_sess_data->user.pmethods = diameap_sm->eap_sm.user.pmethods;
+	diameap_sess_data->user.proposed_eap_method
+			= diameap_sm->eap_sm.user.proposed_eap_method;
+	diameap_sess_data->user.proposed_eap_method_vendor
+			= diameap_sm->eap_sm.user.proposed_eap_method_vendor;
+	diameap_sess_data->user.success = diameap_sm->eap_sm.user.success;
+
+	diameap_sess_data->currentId = diameap_sm->eap_sm.currentId;
+	diameap_sess_data->currentMethod = diameap_sm->eap_sm.currentMethod;
+	diameap_sess_data->currentVendor = diameap_sm->eap_sm.currentVendor;
+	diameap_sess_data->lastId = diameap_sm->eap_sm.lastId;
+	diameap_sess_data->methodState = diameap_sm->eap_sm.methodState;
+
+	diameap_sess_data->methodData = diameap_sm->eap_sm.methodData;
+	diameap_sm->eap_sm.methodData = NULL;
+
+	return 0;
+}
+
+static void diameap_free(struct diameap_state_machine * diameap_sm)
+{
+
+	if (diameap_sm->eap_sm.user.userid != NULL)
+	{
+		free(diameap_sm->eap_sm.user.userid);
+		diameap_sm->eap_sm.user.userid = NULL;
+	}
+
+	if (diameap_sm->eap_sm.user.password != NULL)
+	{
+		free(diameap_sm->eap_sm.user.password);
+		diameap_sm->eap_sm.user.password = NULL;
+	}
+
+	diameap_sm->eap_sm.selectedMethod = NULL;
+
+	if (diameap_sm->eap_sm.methodData != NULL)
+	{
+
+		struct plugin * cplugin;
+		if (diameap_plugin_get(diameap_sm->eap_sm.currentVendor,
+				diameap_sm->eap_sm.currentMethod, &cplugin))
+		{
+			TRACE_DEBUG(INFO,"%sUnable to access EAP Method plugin {Type=%d, Vendor=%d}.",DIAMEAP_EXTENSION,diameap_sm->eap_sm.currentMethod,diameap_sm->eap_sm.currentVendor);
+		}
+
+		if (cplugin->eap_method_free)
+		{
+			(*cplugin->eap_method_free)(diameap_sm->eap_sm.methodData);
+			diameap_sm->eap_sm.methodData = NULL;
+		}
+		else
+		{
+			TRACE_DEBUG(INFO,"%s[%s plugin] datafree function not available.",DIAMEAP_EXTENSION,cplugin->methodname);
+			if (diameap_sm->eap_sm.methodData != NULL)
+			{
+				free(diameap_sm->eap_sm.methodData);
+				diameap_sm->eap_sm.methodData = NULL;
+			}
+		}
+		if (diameap_sm->eap_sm.methodData)
+		{
+			TRACE_DEBUG(INFO,"%sSession state was not been freed correctly!!!",DIAMEAP_EXTENSION);
+		}
+	}
+
+	if (diameap_sm->failedavp != NULL)
+	{
+		CHECK_FCT_DO(fd_msg_free(diameap_sm->failedavp), );
+	}
+
+	if (diameap_sm->lastReqEAPavp != NULL)
+	{
+		CHECK_FCT_DO(fd_msg_free(diameap_sm->lastReqEAPavp), );
+	}
+
+	CHECK_FCT_DO(diameap_unlink_attributes_lists(diameap_sm), );
+
+	if (diameap_sm != NULL)
+	{
+		free(diameap_sm);
+		diameap_sm = NULL;
+	}
+
+}
+
+static int diameap_unlink_attributes_lists(
+		struct diameap_state_machine * diameap_sm)
+{
+	TRACE_ENTRY("%p ", diameap_sm);
+	if (diameap_sm == NULL)
+	{
+		return EINVAL;
+	}
+
+	while (!FD_IS_LIST_EMPTY(&diameap_sm->attributes))
+	{
+		struct fd_list * item = (struct fd_list *) diameap_sm->attributes.next;
+		struct auth_attribute * auth = (struct auth_attribute *) item;
+		fd_list_unlink(item);
+		free_attrib(auth);
+	}
+
+	while (!FD_IS_LIST_EMPTY(&diameap_sm->req_attributes))
+	{
+		struct fd_list * item =
+				(struct fd_list *) diameap_sm->req_attributes.next;
+		struct avp_attribute * avp = (struct avp_attribute *) item;
+		fd_list_unlink(item);
+		free_avp_attrib(avp);
+	}
+
+	while (!FD_IS_LIST_EMPTY(&diameap_sm->ans_attributes))
+	{
+		struct fd_list * item =
+				(struct fd_list *) diameap_sm->ans_attributes.next;
+		struct avp_attribute * avp_ans = (struct avp_attribute *) item;
+		fd_list_unlink(item);
+		free_ans_attrib(avp_ans);
+	}
+
+	return 0;
+}
+
+static int diameap_answer_avp_attributes(
+		struct diameap_state_machine * diameap_sm)
+{
+	TRACE_ENTRY("%p",diameap_sm);
+
+	if (diameap_sm == NULL)
+	{
+		return EINVAL;
+	}
+	int ret1, ret2;
+	struct avp_attribute * avp_attrib;
+	struct avp_attribute * ans_attrib;
+	struct auth_attribute * auth_attrib;
+
+	/* Authorization-Lifetime */
+	{
+		CHECK_FCT(diameap_get_avp_attribute(&diameap_sm->req_attributes, "Authorization-Lifetime", &avp_attrib,1, &ret1));
+
+		CHECK_FCT(diameap_get_auth_attribute(&diameap_sm->attributes, "Authorization-Lifetime", &auth_attrib,1, &ret2));
+
+		if ((ret1 == 1) && (ret2 == 0) && (auth_attrib != NULL))
+		{
+
+			CHECK_MALLOC(ans_attrib = malloc(sizeof(struct avp_attribute)));
+
+			memset(ans_attrib, 0, sizeof(struct avp_attribute));
+
+			fd_list_init(&ans_attrib->chain, NULL);
+
+			ans_attrib->attrib = "Authorization-Lifetime";
+
+			ans_attrib->value.u32 = atoi(auth_attrib->value);
+
+			fd_list_insert_before(&diameap_sm->ans_attributes,
+					&ans_attrib->chain);
+
+			free_attrib(auth_attrib);
+
+		}
+		if ((ret1 == 0) && (ret2 == 1) && (avp_attrib != NULL))
+		{
+
+			CHECK_MALLOC(ans_attrib = malloc(sizeof(struct avp_attribute)));
+
+			memset(ans_attrib, 0, sizeof(struct avp_attribute));
+
+			fd_list_init(&ans_attrib->chain, NULL);
+
+			ans_attrib->attrib = "Authorization-Lifetime";
+
+			ans_attrib->value.u32 = avp_attrib->value.u32;
+
+			fd_list_insert_before(&diameap_sm->ans_attributes,
+					&ans_attrib->chain);
+
+			free_avp_attrib(avp_attrib);
+
+		}
+		if ((ret1 == 0) && (ret2 == 0) && (auth_attrib != NULL) && (avp_attrib
+				!= NULL))
+		{
+
+			CHECK_MALLOC(ans_attrib = malloc(sizeof(struct avp_attribute)));
+
+			memset(ans_attrib, 0, sizeof(struct avp_attribute));
+			fd_list_init(&ans_attrib->chain, NULL);
+			ans_attrib->attrib = "Authorization-Lifetime";
+			if (avp_attrib->value.u32 < atoi(auth_attrib->value))
+			{
+				ans_attrib->value.u32 = avp_attrib->value.u32;
+			}
+			else
+			{
+				ans_attrib->value.u32 = atoi(auth_attrib->value);
+			}
+			fd_list_insert_before(&diameap_sm->ans_attributes,
+					&ans_attrib->chain);
+			free_avp_attrib(avp_attrib);
+			free_attrib(auth_attrib);
+		}
+	}
+
+	/* Auth-Grace-Period */
+	{
+		CHECK_FCT(diameap_get_avp_attribute(&diameap_sm->req_attributes, "Auth-Grace-Period", &avp_attrib,1, &ret1));
+
+		CHECK_FCT(diameap_get_auth_attribute(&diameap_sm->attributes, "Auth-Grace-Period", &auth_attrib,1, &ret2));
+
+		if ((ret1 == 1) && (ret2 == 0) && (auth_attrib != NULL))
+		{
+			CHECK_MALLOC(ans_attrib = malloc(sizeof(struct avp_attribute)));
+			memset(ans_attrib, 0, sizeof(struct avp_attribute));
+			fd_list_init(&ans_attrib->chain, NULL);
+			ans_attrib->attrib = "Auth-Grace-Period";
+			ans_attrib->value.u32 = atoi(auth_attrib->value);
+			fd_list_insert_before(&diameap_sm->ans_attributes,
+					&ans_attrib->chain);
+			free_attrib(auth_attrib);
+		}
+		if ((ret1 == 0) && (ret2 == 1) && (avp_attrib != NULL))
+		{
+			CHECK_MALLOC(ans_attrib = malloc(sizeof(struct avp_attribute)));
+			memset(ans_attrib, 0, sizeof(struct avp_attribute));
+			fd_list_init(&ans_attrib->chain, NULL);
+			ans_attrib->attrib = "Auth-Grace-Period";
+			ans_attrib->value.u32 = avp_attrib->value.u32;
+			fd_list_insert_before(&diameap_sm->ans_attributes,
+					&ans_attrib->chain);
+			free_avp_attrib(avp_attrib);
+		}
+		if ((ret1 == 0) && (ret2 == 0) && (auth_attrib != NULL) && (avp_attrib
+				!= NULL))
+		{
+			CHECK_MALLOC(ans_attrib = malloc(sizeof(struct avp_attribute)));
+			memset(ans_attrib, 0, sizeof(struct avp_attribute));
+			fd_list_init(&ans_attrib->chain, NULL);
+			ans_attrib->attrib = "Auth-Grace-Period";
+			if (avp_attrib->value.u32 < atoi(auth_attrib->value))
+			{
+				ans_attrib->value.u32 = avp_attrib->value.u32;
+			}
+			else
+			{
+				ans_attrib->value.u32 = atoi(auth_attrib->value);
+			}
+			fd_list_insert_before(&diameap_sm->ans_attributes,
+					&ans_attrib->chain);
+			free_attrib(auth_attrib);
+			free_avp_attrib(avp_attrib);
+		}
+	}
+
+	/* Auth-Session-State */
+	{
+		CHECK_FCT(diameap_get_auth_attribute(&diameap_sm->attributes, "Auth-Session-State", &auth_attrib,1, &ret2));
+		if ((ret2 == 0) && (auth_attrib != NULL))
+		{
+			CHECK_MALLOC(ans_attrib = malloc(sizeof(struct avp_attribute)));
+			memset(ans_attrib, 0, sizeof(struct avp_attribute));
+			fd_list_init(&ans_attrib->chain, NULL);
+			ans_attrib->attrib = "Auth-Session-State";
+			ans_attrib->value.i32 = atoi(auth_attrib->value);
+			fd_list_insert_before(&diameap_sm->ans_attributes,
+					&ans_attrib->chain);
+			free_attrib(auth_attrib);
+		}
+	}
+
+	/* Re-Auth-Request-Type */
+	{
+		CHECK_FCT(diameap_get_auth_attribute(&diameap_sm->attributes, "Re-Auth-Request-Type", &auth_attrib,1, &ret2));
+		if ((ret2 == 0) && (auth_attrib != NULL))
+		{
+			CHECK_MALLOC(ans_attrib = malloc(sizeof(struct avp_attribute)));
+			memset(ans_attrib, 0, sizeof(struct avp_attribute));
+			fd_list_init(&ans_attrib->chain, NULL);
+			ans_attrib->attrib = "Re-Auth-Request-Type";
+			ans_attrib->value.i32 = atoi(auth_attrib->value);
+			fd_list_insert_before(&diameap_sm->ans_attributes,
+					&ans_attrib->chain);
+			free_attrib(auth_attrib);
+		}
+		else
+		{
+			ans_attrib = NULL;
+			CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes, "Authorization-Lifetime", &ans_attrib,0, &ret1));
+			if ((ret1 == 0) && (ans_attrib != NULL))
+			{
+				CHECK_MALLOC(ans_attrib = malloc(sizeof(struct avp_attribute)));
+				memset(ans_attrib, 0, sizeof(struct avp_attribute));
+				fd_list_init(&ans_attrib->chain, NULL);
+				ans_attrib->attrib = "Re-Auth-Request-Type";
+				ans_attrib->value.i32 = 0;
+				fd_list_insert_before(&diameap_sm->ans_attributes,
+						&ans_attrib->chain);
+			}
+		}
+	}
+
+	/* Session-Timeout */
+	{
+		CHECK_FCT(diameap_get_auth_attribute(&diameap_sm->attributes, "Session-Timeout", &auth_attrib,1, &ret2));
+		if ((ret2 == 0) && (auth_attrib != NULL))
+		{
+			CHECK_MALLOC(ans_attrib = malloc(sizeof(struct avp_attribute)));
+			memset(ans_attrib, 0, sizeof(struct avp_attribute));
+			fd_list_init(&ans_attrib->chain, NULL);
+			ans_attrib->attrib = "Session-Timeout";
+			ans_attrib->value.u32 = atoi(auth_attrib->value);
+			fd_list_insert_before(&diameap_sm->ans_attributes,
+					&ans_attrib->chain);
+			free_attrib(auth_attrib);
+		}
+	}
+
+	/* Multi-Round-Time-Out */
+	{
+		CHECK_FCT(diameap_get_auth_attribute(&diameap_sm->attributes, "Multi-Round-Time-Out", &auth_attrib,1, &ret2));
+		if ((ret2 == 0) && (auth_attrib != NULL))
+		{
+			CHECK_MALLOC(ans_attrib = malloc(sizeof(struct avp_attribute)));
+			memset(ans_attrib, 0, sizeof(struct avp_attribute));
+			fd_list_init(&ans_attrib->chain, NULL);
+			ans_attrib->attrib = "Multi-Round-Time-Out";
+			ans_attrib->value.u32 = atoi(auth_attrib->value);
+			fd_list_insert_before(&diameap_sm->ans_attributes,
+					&ans_attrib->chain);
+			free_attrib(auth_attrib);
+		}
+	}
+
+	/* Acct-Interim-Interval */
+	{
+		CHECK_FCT(diameap_get_auth_attribute(&diameap_sm->attributes, "Acct-Interim-Interval", &auth_attrib,1, &ret2));
+		if ((ret2 == 0) && (auth_attrib != NULL))
+		{
+			CHECK_MALLOC(ans_attrib = malloc(sizeof(struct avp_attribute)));
+			memset(ans_attrib, 0, sizeof(struct avp_attribute));
+			fd_list_init(&ans_attrib->chain, NULL);
+			ans_attrib->attrib = "Acct-Interim-Interval";
+			ans_attrib->value.u32 = atoi(auth_attrib->value);
+			fd_list_insert_before(&diameap_sm->ans_attributes,
+					&ans_attrib->chain);
+			free_attrib(auth_attrib);
+		}
+	}
+
+	return 0;
+}
+
+#define	DIAMEAP_STR	1
+#define	DIAMEAP_NUM	2
+
+#define DIAMEAP_OP_NO	0	//Not supported operator
+#define	DIAMEAP_OP_EQ	1	//==
+#define	DIAMEAP_OP_GT	2	//>
+#define	DIAMEAP_OP_LT	3	//<
+#define	DIAMEAP_OP_GE	4	//>=
+#define	DIAMEAP_OP_LE	5	//<=
+#define	DIAMEAP_OP_NE	6	//!=
+#define	DIAMEAP_OP_EX	7	//~=
+#define EQ(A,B) A==B ? TRUE : FALSE
+#define GT(A,B) A>B ? TRUE : FALSE
+#define GE(A,B) A>=B ? TRUE : FALSE
+#define LT(A,B) A<B ? TRUE : FALSE
+#define LE(A,B) A<=B ? TRUE : FALSE
+#define NE(A,B) A!=B ? TRUE : FALSE
+
+int diameap_get_operator(char *operator)
+{
+	TRACE_ENTRY("%p",operator);
+	if (strcmp(operator, "==") == 0)
+	{
+		return DIAMEAP_OP_EQ;
+	}
+	if (strcmp(operator, ">") == 0)
+	{
+		return DIAMEAP_OP_GT;
+	}
+	if (strcmp(operator, "<") == 0)
+	{
+		return DIAMEAP_OP_LT;
+	}
+	if (strcmp(operator, ">=") == 0)
+	{
+		return DIAMEAP_OP_GE;
+	}
+	if (strcmp(operator, "<=") == 0)
+	{
+		return DIAMEAP_OP_LE;
+	}
+	if (strcmp(operator, "!=") == 0)
+	{
+		return DIAMEAP_OP_NE;
+	}
+	if (strcmp(operator, "~=") == 0)
+	{
+		return DIAMEAP_OP_EX;
+	}
+	return DIAMEAP_OP_NO;
+}
+
+boolean is_operator(int format_type, char * operator)
+{
+	TRACE_ENTRY("%p %p",format_type,operator);
+	if ((format_type == DIAMEAP_STR) && (strcmp(operator, "==") == 0 || strcmp(
+			operator, "~=") == 0 || strcmp(operator, "!=") == 0))
+	{
+		return TRUE;
+	}
+	if ((format_type == DIAMEAP_NUM) && (strcmp(operator, "~=") != 0))
+	{
+		return TRUE;
+	}
+	return FALSE;
+}
+
+union avp_value diameap_get_num(char * num, enum dict_avp_basetype datatype)
+{
+	TRACE_ENTRY("%p %p",num,datatype);
+	union avp_value val;
+	switch (datatype)
+	{
+	case AVP_TYPE_INTEGER32://i32
+		val.i32 = atoi(num);
+		break;
+	case AVP_TYPE_INTEGER64://i64
+		val.i64 = atoll(num);
+		break;
+	case AVP_TYPE_UNSIGNED32://u32
+		val.u32 = strtoul(num, NULL, 10);
+		break;
+	case AVP_TYPE_UNSIGNED64://u64
+		val.u64 = strtoull(num, NULL, 10);
+		break;
+	case AVP_TYPE_FLOAT32://f32
+		val.f32 = atof(num);
+		break;
+	case AVP_TYPE_FLOAT64://f64
+		val.f64 = strtod(num, NULL);
+		break;
+	default:
+		TRACE_DEBUG(INFO, "%sUnknown AVP Base Type.",DIAMEAP_EXTENSION)
+		;
+	}
+	return val;
+}
+
+boolean diameap_check(union avp_value A, char * B, char * operator,
+		enum dict_avp_basetype datatype)
+{
+	TRACE_ENTRY("%p %p %p %p",A,B,operator,datatype);
+	if (((datatype == AVP_TYPE_OCTETSTRING) && (is_operator(DIAMEAP_STR,
+			operator) == TRUE)) || ((datatype != AVP_TYPE_OCTETSTRING)
+			&& (datatype != AVP_TYPE_GROUPED) && (is_operator(DIAMEAP_NUM,
+			operator) == TRUE)))
+	{
+		switch (diameap_get_operator(operator))
+		{
+		case DIAMEAP_OP_EQ:
+			if ((datatype == AVP_TYPE_OCTETSTRING) && (is_operator(DIAMEAP_STR,
+					operator) == TRUE))
+			{
+				if (strcmp(A.os.data, B) == 0)
+					return TRUE;
+				else
+					return FALSE;
+			}
+			else if ((datatype != AVP_TYPE_OCTETSTRING) && (datatype
+					!= AVP_TYPE_GROUPED) && (is_operator(DIAMEAP_NUM, operator)
+					== TRUE))
+			{
+
+				switch (datatype)
+				{
+				case AVP_TYPE_INTEGER32://i32
+					return EQ(A.i32,diameap_get_num(B, datatype).i32);
+					break;
+				case AVP_TYPE_INTEGER64://i64
+					return EQ(A.i64,diameap_get_num(B, datatype).i64);
+					break;
+				case AVP_TYPE_UNSIGNED32://u32
+					return EQ(A.u32,diameap_get_num(B, datatype).u32);
+					break;
+				case AVP_TYPE_UNSIGNED64://u64
+					return EQ(A.u64,diameap_get_num(B, datatype).u64);
+					break;
+				case AVP_TYPE_FLOAT32://f32
+					return EQ(A.f32,diameap_get_num(B, datatype).f32);
+					break;
+				case AVP_TYPE_FLOAT64://f64
+					return EQ(A.f64,diameap_get_num(B, datatype).f64);
+					break;
+				default:
+					return FALSE;
+				}
+			}
+			else
+			{
+				return FALSE;
+			}
+			break;
+		case DIAMEAP_OP_EX:
+		{
+			//string only
+			boolean authorized = FALSE;
+			if ((datatype == AVP_TYPE_OCTETSTRING) && (is_operator(DIAMEAP_STR,
+					operator) == TRUE))
+			{
+				regex_t rule_regexp;
+				regcomp(&rule_regexp, B, REG_EXTENDED | REG_NOSUB | REG_ICASE);
+				if (regexec(&rule_regexp, A.os.data, 0, NULL, 0) != 0)
+				{
+					authorized = FALSE;
+				}
+				else
+				{
+					authorized = TRUE;
+				}
+				regfree(&rule_regexp);
+			}
+			return authorized;
+		}
+		case DIAMEAP_OP_GT:
+
+			if ((datatype != AVP_TYPE_OCTETSTRING) && (datatype
+					!= AVP_TYPE_GROUPED) && (is_operator(DIAMEAP_NUM, operator)
+					== TRUE))
+			{
+				switch (datatype)
+				{
+				case AVP_TYPE_INTEGER32://i32
+					return GT(A.i32, diameap_get_num(B, datatype).i32);
+					break;
+				case AVP_TYPE_INTEGER64://i64
+					return GT(A.i64, diameap_get_num(B, datatype).i64);
+					break;
+				case AVP_TYPE_UNSIGNED32://u32
+					return GT(A.u32, diameap_get_num(B, datatype).u32);
+					break;
+				case AVP_TYPE_UNSIGNED64://u64
+					return GT(A.u64, diameap_get_num(B, datatype).u64);
+					break;
+				case AVP_TYPE_FLOAT32://f32
+					return GT(A.f32, diameap_get_num(B, datatype).f32);
+					break;
+				case AVP_TYPE_FLOAT64://f64
+					return GT(A.f64, diameap_get_num(B, datatype).f64);
+					break;
+				default:
+					return FALSE;
+				}
+			}
+			else
+			{
+				return FALSE;
+			}
+			break;
+		case DIAMEAP_OP_GE:
+			if ((datatype != AVP_TYPE_OCTETSTRING) && (datatype
+					!= AVP_TYPE_GROUPED) && (is_operator(DIAMEAP_NUM, operator)
+					== TRUE))
+			{
+				switch (datatype)
+				{
+				case AVP_TYPE_INTEGER32://i32
+					return GE(A.i32,diameap_get_num(B, datatype).i32);
+					break;
+				case AVP_TYPE_INTEGER64://i64
+					return GE(A.i64,diameap_get_num(B, datatype).i64);
+					break;
+				case AVP_TYPE_UNSIGNED32://u32
+					return GE(A.u32,diameap_get_num(B, datatype).u32);
+					break;
+				case AVP_TYPE_UNSIGNED64://u64
+					return GE(A.u64,diameap_get_num(B, datatype).u64);
+					break;
+				case AVP_TYPE_FLOAT32://f32
+					return GE(A.f32,diameap_get_num(B, datatype).f32);
+					break;
+				case AVP_TYPE_FLOAT64://f64
+					return GE(A.f64,diameap_get_num(B, datatype).f64);
+					break;
+				default:
+					return FALSE;
+				}
+			}
+			else
+			{
+				return FALSE;
+			}
+			break;
+		case DIAMEAP_OP_LT:
+			if ((datatype != AVP_TYPE_OCTETSTRING) && (datatype
+					!= AVP_TYPE_GROUPED) && (is_operator(DIAMEAP_NUM, operator)
+					== TRUE))
+			{
+				switch (datatype)
+				{
+				case AVP_TYPE_INTEGER32://i32
+					return LT(A.i32, diameap_get_num(B, datatype).i32);
+					break;
+				case AVP_TYPE_INTEGER64://i64
+					return LT(A.i64, diameap_get_num(B, datatype).i64);
+					break;
+				case AVP_TYPE_UNSIGNED32://u32
+					return LT(A.u32, diameap_get_num(B, datatype).u32);
+					break;
+				case AVP_TYPE_UNSIGNED64://u64
+					return LT(A.u64, diameap_get_num(B, datatype).u64);
+					break;
+				case AVP_TYPE_FLOAT32://f32
+					return LT(A.f32, diameap_get_num(B, datatype).f32);
+					break;
+				case AVP_TYPE_FLOAT64://f64
+					return LT(A.f64, diameap_get_num(B, datatype).f64);
+					break;
+				default:
+					return FALSE;
+				}
+			}
+			else
+			{
+				return FALSE;
+			}
+			break;
+		case DIAMEAP_OP_LE:
+			if ((datatype != AVP_TYPE_OCTETSTRING) && (datatype
+					!= AVP_TYPE_GROUPED) && (is_operator(DIAMEAP_NUM, operator)
+					== TRUE))
+			{
+				switch (datatype)
+				{
+				case AVP_TYPE_INTEGER32://i32
+					return LE(A.i32, diameap_get_num(B, datatype).i32);
+					break;
+				case AVP_TYPE_INTEGER64://i64
+					return LE(A.i64, diameap_get_num(B, datatype).i64);
+					break;
+				case AVP_TYPE_UNSIGNED32://u32
+					return LE(A.u32, diameap_get_num(B, datatype).u32);
+					break;
+				case AVP_TYPE_UNSIGNED64://u64
+					return LE(A.u64, diameap_get_num(B, datatype).u64);
+					break;
+				case AVP_TYPE_FLOAT32://f32
+					return LE(A.f32, diameap_get_num(B, datatype).f32);
+					break;
+				case AVP_TYPE_FLOAT64://f64
+					return LE(A.f64, diameap_get_num(B, datatype).f64);
+					break;
+				default:
+					return FALSE;
+				}
+			}
+			else
+			{
+				return FALSE;
+			}
+			break;
+		case DIAMEAP_OP_NE:
+			if ((datatype == AVP_TYPE_OCTETSTRING) && (is_operator(DIAMEAP_STR,
+					operator) == TRUE))
+			{
+				if (strcmp(A.os.data, B) != 0)
+					return TRUE;
+				else
+					return FALSE;
+			}
+			else if ((datatype != AVP_TYPE_OCTETSTRING) && (datatype
+					!= AVP_TYPE_GROUPED) && (is_operator(DIAMEAP_NUM, operator)
+					== TRUE))
+			{
+				switch (datatype)
+				{
+				case AVP_TYPE_INTEGER32://i32
+					return NE(A.i32, diameap_get_num(B, datatype).i32);
+					break;
+				case AVP_TYPE_INTEGER64://i64
+					return NE(A.i64, diameap_get_num(B, datatype).i64);
+					break;
+				case AVP_TYPE_UNSIGNED32://u32
+					return NE(A.u32, diameap_get_num(B, datatype).u32);
+					break;
+				case AVP_TYPE_UNSIGNED64://u64
+					return NE(A.u64, diameap_get_num(B, datatype).u64);
+					break;
+				case AVP_TYPE_FLOAT32://f32
+					return NE(A.f32, diameap_get_num(B, datatype).f32);
+					break;
+				case AVP_TYPE_FLOAT64://f64
+					return NE(A.f64, diameap_get_num(B, datatype).f64);
+					break;
+				default:
+					return FALSE;
+				}
+			}
+			else
+			{
+				return FALSE;
+			}
+			break;
+		}
+	}
+}
+
+char * diameap_attribute_operator(char * op, int * toadd, boolean *isrule)
+{
+	TRACE_ENTRY("%p %p %p",op,toadd,isrule);
+	char * attribute_op;
+
+	if (op[0] == '+')
+	{
+		*toadd = 1;
+	}
+	else if (op[strlen(op) - 1] == '+')
+	{
+		*toadd = 2;
+	}
+	else
+	{
+		*toadd = 0;
+	}
+
+	switch (*toadd)
+	{
+	case 1:
+		attribute_op = malloc(strlen(op));
+		memset(attribute_op, 0, strlen(op));
+		strncpy(attribute_op, op + 1, strlen(op) - 1);
+		attribute_op[strlen(op)] = '\0';
+		break;
+	case 2:
+		attribute_op = malloc(strlen(op));
+		memset(attribute_op, 0, strlen(op));
+		strncpy(attribute_op, op, strlen(op) - 1);
+		attribute_op[strlen(op)] = '\0';
+		break;
+	default:
+		attribute_op = malloc(strlen(op) + 1);
+		memset(attribute_op, 0, strlen(op) + 1);
+		strcpy(attribute_op, op);
+		attribute_op[strlen(op) + 1] = '\0';
+	}
+	if (strcmp(attribute_op, "=") == 0)
+	{
+		*isrule = FALSE;
+		*toadd = 2;
+	}
+	else
+	{
+		*isrule = TRUE;
+	}
+
+	return attribute_op;
+}
+
+int diameap_answer_set_attribute_valueA(union avp_value A, int *tofree,
+		enum dict_avp_basetype datatype, union avp_value * rval)
+{
+	TRACE_ENTRY("%p %p %p %p",A,tofree,datatype,rval);
+	if (datatype == AVP_TYPE_OCTETSTRING)
+	{
+		rval->os.data = strdup(A.os.data);
+
+		rval->os.len = A.os.len;
+
+		*tofree = 1;
+	}
+	else
+	{
+		*rval = A;
+	}
+	return 0;
+}
+int diameap_answer_set_attribute_valueB(char * B, int *tofree,
+		enum dict_avp_basetype datatype, union avp_value * rval)
+{
+	TRACE_ENTRY("%p %p %p %p",B,tofree,datatype,rval);
+	if (datatype == AVP_TYPE_OCTETSTRING)
+	{
+
+		rval->os.data = strdup(B);
+
+		rval->os.len = strlen(B);
+
+		*tofree = 1;
+	}
+	else
+	{
+
+		*rval = diameap_get_num(B, datatype);
+	}
+
+	return 0;
+}
+
+static int diameap_attribute_limits(char * attrib, int * max, int *ret)
+{
+	TRACE_ENTRY("%p %p %p",attrib,max,ret);
+	if (attrib == NULL)
+	{
+		return EINVAL;
+	}
+	int i;
+	for (i = 0; i < sizeof(auth_avps); i++)
+	{
+		if (strcmp(auth_avps[i].avp_attribute, attrib) == 0)
+		{
+			*max = auth_avps[i].max;
+			*ret = 0;
+			return 0;
+		}
+	}
+	*max = 0;
+	*ret = 1;
+	return 0;
+}
+
+static int diameap_answer_authorization_attributes(
+		struct diameap_state_machine * diameap_sm)
+{
+	TRACE_ENTRY("%p",diameap_sm);
+
+	if (diameap_sm == NULL)
+	{
+		return EINVAL;
+	}
+	boolean checked = TRUE;
+
+	struct fd_list * attrib;
+	struct auth_attribute * auth_attrib;
+	struct avp_attribute * avp_attrib;
+	int ret;
+
+	for (attrib = (&diameap_sm->attributes)->next; attrib
+			!= (&diameap_sm->attributes); attrib = attrib->next)
+	{
+		avp_attrib = NULL;
+		auth_attrib = (struct auth_attribute *) attrib;
+
+		int toadd = 0;
+		boolean isrule = FALSE;
+		char * op;
+
+		op = diameap_attribute_operator(auth_attrib->op, &toadd, &isrule);
+
+		struct dict_object * dobj;
+		struct dict_avp_data avpdata;
+		fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
+				auth_attrib->attrib, &dobj, ENOENT);
+		fd_dict_getval(dobj, &avpdata);
+
+		checked = TRUE;
+		if (isrule == TRUE)
+		{
+			CHECK_FCT(diameap_get_avp_attribute(&diameap_sm->req_attributes,auth_attrib->attrib,&avp_attrib,0,&ret));
+			if (ret == 0)
+			{
+				checked = diameap_check(avp_attrib->value, auth_attrib->value,
+						op, avpdata.avp_basetype);
+			}
+		}
+		if (checked == TRUE && toadd != 0)
+		{
+
+			struct avp_attribute * ans_attrib;
+			int max = 0;
+			diameap_attribute_limits(auth_attrib->attrib, &max, &ret);
+			if ((ret == 0) && (max != 0))
+			{
+				if (max == 1)//only one
+				{
+					int ret = 0;
+					diameap_get_ans_attribute(&diameap_sm->ans_attributes,
+							auth_attrib->attrib, &ans_attrib, 0, &ret);
+					if (ret == 1)
+					{
+						ans_attrib = NULL;
+						CHECK_MALLOC(ans_attrib = malloc(sizeof(struct avp_attribute)));
+						memset(ans_attrib, 0, sizeof(struct avp_attribute));
+						fd_list_init(&ans_attrib->chain, NULL);
+						ans_attrib->attrib = strdup(auth_attrib->attrib);
+						if (toadd == 1)
+						{
+							diameap_answer_set_attribute_valueA(
+									avp_attrib->value, &ans_attrib->tofree,
+									avpdata.avp_basetype, &ans_attrib->value);
+						}
+						else
+						{
+							diameap_answer_set_attribute_valueB(
+									auth_attrib->value, &ans_attrib->tofree,
+									avpdata.avp_basetype, &ans_attrib->value);
+						}
+						fd_list_insert_before(&diameap_sm->ans_attributes,
+								&ans_attrib->chain);
+
+					}
+					else
+					{
+						//an answer avp is already added
+					}
+				}
+				else
+				{
+					ans_attrib = NULL;
+					CHECK_MALLOC(ans_attrib = malloc(sizeof(struct avp_attribute)));
+					memset(ans_attrib, 0, sizeof(struct avp_attribute));
+					fd_list_init(&ans_attrib->chain, NULL);
+					ans_attrib->attrib = auth_attrib->attrib;
+					if (toadd == 1)
+					{
+						diameap_answer_set_attribute_valueA(avp_attrib->value,
+								&ans_attrib->tofree, avpdata.avp_basetype,
+								&ans_attrib->value);
+					}
+					else
+					{
+						diameap_answer_set_attribute_valueB(auth_attrib->value,
+								&ans_attrib->tofree, avpdata.avp_basetype,
+								&ans_attrib->value);
+					}
+					fd_list_insert_before(&diameap_sm->ans_attributes,
+							&ans_attrib->chain);
+				}
+			}
+		}
+		if (checked == FALSE)
+		{
+
+			diameap_sm->authorized = FALSE;
+			return 0;
+		}
+	}
+	diameap_sm->authorized = checked;
+	return 0;
+
+	return 0;
+}
+
+static int diameap_get_avp_attribute(struct fd_list * avp_attributes,
+		char * attribute, struct avp_attribute ** avp_attrib, int unlink,
+		int *ret)
+{
+	TRACE_ENTRY("%p %p %p %p %p", avp_attributes, attribute, avp_attrib, ret);
+	if (avp_attributes == NULL)
+	{
+		return EINVAL;
+	}
+	if (attribute == NULL)
+	{
+		return EINVAL;
+	}
+	struct fd_list * attrib;
+	for (attrib = avp_attributes->next; attrib != avp_attributes; attrib
+			= attrib->next)
+	{
+		*avp_attrib = (struct avp_attribute *) attrib;
+		if (strcmp((*avp_attrib)->attrib, attribute) == 0)
+		{
+			*ret = 0;
+			if (unlink == 1)
+			{
+				fd_list_unlink(&(*avp_attrib)->chain);
+			}
+			return 0;
+		}
+	}
+	*avp_attrib = NULL;
+	*ret = 1;
+	return 0;
+}
+
+static int diameap_get_auth_attribute(struct fd_list * auth_attributes,
+		char * attribute, struct auth_attribute ** auth_attrib, int unlink,
+		int *ret)
+{
+
+	TRACE_ENTRY("%p %p %p %p %p", auth_attributes, attribute, auth_attrib, ret);
+
+	if (auth_attributes == NULL)
+	{
+		return EINVAL;
+	}
+	if (attribute == NULL)
+	{
+		return EINVAL;
+	}
+
+	struct fd_list * attrib;
+
+	for (attrib = auth_attributes->next; attrib != auth_attributes; attrib
+			= attrib->next)
+	{
+		*auth_attrib = (struct auth_attribute *) attrib;
+		if (strcmp((*auth_attrib)->attrib, attribute) == 0)
+		{
+			*ret = 0;
+			if (unlink == 1)
+			{
+				fd_list_unlink(&(*auth_attrib)->chain);
+			}
+			return 0;
+		}
+	}
+	*auth_attrib = NULL;
+	*ret = 1;
+	return 0;
+}
+
+static int diameap_get_ans_attribute(struct fd_list * ans_attributes,
+		char * attribute, struct avp_attribute ** ans_attrib, int unlink,
+		int *ret)
+{
+	TRACE_ENTRY("%p %p %p %p %p", ans_attributes, attribute, ans_attrib, ret);
+	if (ans_attributes == NULL)
+	{
+		return EINVAL;
+	}
+	if (attribute == NULL)
+	{
+		return EINVAL;
+	}
+	struct fd_list * attrib;
+	for (attrib = ans_attributes->next; attrib != ans_attributes; attrib
+			= attrib->next)
+	{
+		*ans_attrib = (struct avp_attribute *) attrib;
+		if (strcmp((*ans_attrib)->attrib, attribute) == 0)
+		{
+			*ret = 0;
+			if (unlink == 1)
+			{
+				fd_list_unlink(&(*ans_attrib)->chain);
+			}
+			return 0;
+		}
+	}
+	*ans_attrib = NULL;
+	*ret = 1;
+	return 0;
+}
+
+static int diameap_policy_decision(struct diameap_state_machine * diameap_sm,
+		struct diameap_eap_interface eap_i)
+{
+	TRACE_ENTRY("%p %p",diameap_sm,eap_i);
+
+	if ((eap_i.aaaFail == TRUE) && (eap_i.aaaSuccess == TRUE))
+	{
+		TRACE_DEBUG(INFO,"%s Incorrect EAP decision. EAP process should not return both success and failure for the same session.(please report this problem.)",DIAMEAP_EXTENSION);
+		return -1;
+	}
+
+	if (eap_i.aaaFail == TRUE)
+	{
+		diameap_sm->result_code = 4001; /* DIAMETER_AUTHENTICATION_REJECTED 4001 */
+		diameap_sm->authFailure = TRUE;
+		TRACE_DEBUG(FULL+1,"%s Auth failure: Authentication Rejected ",DIAMEAP_EXTENSION);
+		return 0;
+	}
+
+	if (eap_i.aaaSuccess == FALSE)
+	{
+		diameap_sm->result_code = 1001; /* DIAMETER_MULTI_ROUND_AUTH 1001 */
+		return 0;
+	}
+
+	if (eap_i.aaaSuccess == TRUE)
+	{
+		if (diameap_sm->auth_request_val == AUTHORIZE_AUTHENTICATE)
+		{
+			if ((diameap_sm->verify_authorization == TRUE)
+					&& (diameap_sm->result_code == 0))
+			{
+				diameap_sm->result_code = 2001; /* DIAMETER_SUCCESS 2001 */
+				diameap_sm->authSuccess = TRUE;
+				TRACE_DEBUG(FULL+1,"%s Auth success: Authorization and Authentication ",DIAMEAP_EXTENSION);
+				return 0;
+			}
+			else
+			{
+				//
+			}
+		}
+		if (diameap_sm->auth_request_val == AUTHENTICATE_ONLY)
+		{
+			diameap_sm->result_code = 2001; /* DIAMETER_SUCCESS 2001 */
+			diameap_sm->authSuccess = TRUE;
+			TRACE_DEBUG(FULL+1,"%s Auth success: Authentication Only ",DIAMEAP_EXTENSION);
+			return 0;
+		}
+	}
+
+	return 0;
+}
+
+static int diameap_add_avps(struct diameap_state_machine * diameap_sm,
+		struct msg * ans, struct msg * req)
+{
+	TRACE_ENTRY("%p %p %p",diameap_sm,ans,req);
+
+	struct avp * avp, *avp2;
+	struct avp_hdr * avpdata;
+	union avp_value avp_val;
+	int ret = 0;
+
+	/* Origin-Host AVP and Origin-Realm AVP */
+	{
+		CHECK_FCT( fd_msg_add_origin ( ans, 0 ) );
+	}
+
+	/* Auth-Application-Id AVP */
+	{
+		CHECK_FCT(fd_msg_avp_new(dataobj_auth_application_id, 0, &avp));
+		avp_val.u32 = diameap_config->application_id;
+		CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+		CHECK_FCT(fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp));
+	}
+
+	/* Auth-Request-Type AVP
+	 * Enumerated values:
+	 * 	AUTHENTICATE_ONLY 1
+	 * 	AUTHORIZE_ONLY 2
+	 * 	AUTHORIZE_AUTHENTICATE 3 */
+	{
+		CHECK_FCT(fd_msg_avp_new(dataobj_auth_request_type, 0, &avp));
+		if (!diameap_config->authorize)
+		{
+			//AUTHENTICATE ONLY
+			avp_val.i32 = AUTHENTICATE_ONLY;
+		}
+		else
+		{
+			if (diameap_sm->auth_request_val == 3)
+			{
+				//AUTHORIZE_AUTHENTICATE
+				avp_val.i32 = AUTHORIZE_AUTHENTICATE;
+			}
+			else
+			{
+				//AUTHENTICATE_ONLY
+				avp_val.i32 = AUTHENTICATE_ONLY;
+			}
+		}
+		CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+		CHECK_FCT(fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp));
+	}
+
+	/* Proxy-Info AVP */
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_proxy_info, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr ( avp, &avpdata ) );
+		u32 proxy_info_code = avpdata->avp_code;
+		int depth;
+		do
+		{
+			ret = 0;
+			depth = 0;
+			CHECK_FCT(fd_msg_avp_hdr ( avp, &avpdata ) );
+			if (avpdata->avp_code == proxy_info_code)
+			{
+				CHECK_FCT(fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp));
+			}
+			ret = fd_msg_browse ( avp, MSG_BRW_NEXT, &avp2, &depth);
+			avp = avp2;
+		} while ((avp != NULL) && (ret == 0) && (ret == 0));
+	}
+
+	if (diameap_sm->eap_sm.user.userid)
+	{
+		/* User-Name AVP */
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_user_name, 0, &avp));
+
+			if (diameap_sm->privateUser == FALSE)
+			{
+
+				avp_val.os.data = diameap_sm->eap_sm.user.userid;
+				avp_val.os.len = diameap_sm->eap_sm.user.useridLength;
+				CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+				CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			}
+			else
+			{
+
+			}
+
+		}
+	}
+	return 0;
+}
+
+static int diameap_add_user_sessions_avps(
+		struct diameap_state_machine * diameap_sm, struct msg * ans)
+{
+	TRACE_ENTRY("%p %p",diameap_sm,ans);
+
+	struct avp * avp;
+	union avp_value avp_val;
+	int ret;
+
+	/* Authorization-Lifetime AVP */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Authorization-Lifetime",&ans_attrib,1,&ret));
+		if ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_authorization_lifetime, 0, &avp));
+			avp_val.u32 = ans_attrib->value.u32;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+		}
+	}
+
+	/* Auth-Grace-Period AVP */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Auth-Grace-Period",&ans_attrib,1,&ret));
+		if ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_auth_grace_period, 0, &avp));
+			avp_val.u32 = ans_attrib->value.u32;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+		}
+	}
+
+	/* Auth-Session-State AVP */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Auth-Session-State",&ans_attrib,1,&ret));
+		if ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_auth_session_state, 0, &avp));
+			avp_val.i32 = ans_attrib->value.i32;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+		}
+	}
+
+	/* Re-Auth-Request-Type AVP */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Re-Auth-Request-Type",&ans_attrib,1,&ret));
+		if ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_re_auth_request_type, 0, &avp));
+			avp_val.i32 = ans_attrib->value.i32;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+		}
+	}
+
+	/* Session-Timeout AVP */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Session-Timeout",&ans_attrib,1,&ret));
+		if ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_session_timeout, 0, &avp));
+			avp_val.u32 = ans_attrib->value.u32;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+		}
+	}
+
+	/* Acct-Interim-Interval AVP */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Acct-Interim-Interval",&ans_attrib,1,&ret));
+		if ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_acct_interim_interval, 0, &avp));
+			avp_val.u32 = ans_attrib->value.u32;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+		}
+	}
+	return 0;
+}
+
+static int diameap_add_authorization_avps(
+		struct diameap_state_machine * diameap_sm, struct msg * ans)
+{
+
+	TRACE_ENTRY("%p %p",diameap_sm, ans);
+
+	struct avp * avp;
+	union avp_value avp_val;
+	int ret;
+
+	if (diameap_sm == NULL)
+	{
+		return EINVAL;
+	}
+	if (ans == NULL)
+	{
+		return EINVAL;
+	}
+
+	/* Reply-Message */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Reply-Message",&ans_attrib,1,&ret));
+		while ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_reply_message, 0, &avp));
+			avp_val.os.data = ans_attrib->value.os.data;
+			avp_val.os.len = ans_attrib->value.os.len;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+			CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Reply-Message",&ans_attrib,1,&ret));
+		}
+
+	}
+
+	/* Service-Type */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Service-Type",&ans_attrib,1,&ret));
+		if ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_service_type, 0, &avp));
+			avp_val.i32 = ans_attrib->value.i32;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+		}
+	}
+
+	/* Callback-Number */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Callback-Number",&ans_attrib,1,&ret));
+		if ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_callback_number, 0, &avp));
+			avp_val.os.data = ans_attrib->value.os.data;
+			avp_val.os.len = ans_attrib->value.os.len;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+		}
+	}
+
+	/* Callback-Id */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Callback-Id",&ans_attrib,1,&ret));
+		if ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_callback_id, 0, &avp));
+			avp_val.os.data = ans_attrib->value.os.data;
+			avp_val.os.len = ans_attrib->value.os.len;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+		}
+	}
+
+	/* Idle-Timeout */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Idle-Timeout",&ans_attrib,1,&ret));
+		if ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_idle_timeout, 0, &avp));
+			avp_val.u32 = ans_attrib->value.u32;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+		}
+	}
+
+	/* NAS-Filter-Rule */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"NAS-Filter-Rule",&ans_attrib,1,&ret));
+		if ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_nas_filter_rule, 0, &avp));
+			avp_val.u32 = ans_attrib->value.u32;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+		}
+	}
+
+	/* Filter-Id */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Filter-Id",&ans_attrib,1,&ret));
+		while ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_filter_id, 0, &avp));
+			avp_val.os.data = ans_attrib->value.os.data;
+			avp_val.os.len = ans_attrib->value.os.len;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+			CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Filter-Id",&ans_attrib,1,&ret));
+		}
+
+	}
+
+	/* Configuration-Token */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Configuration-Token",&ans_attrib,1,&ret));
+		while ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_configuration_token, 0, &avp));
+			avp_val.os.data = ans_attrib->value.os.data;
+			avp_val.os.len = ans_attrib->value.os.len;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+			CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Configuration-Token",&ans_attrib,1,&ret));
+		}
+	}
+
+	/* QoS-Filter-Rule */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"QoS-Filter-Rule",&ans_attrib,1,&ret));
+		while ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_qos_filter_rule, 0, &avp));
+			avp_val.os.data = ans_attrib->value.os.data;
+			avp_val.os.len = ans_attrib->value.os.len;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+			CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"QoS-Filter-Rule",&ans_attrib,1,&ret));
+		}
+
+	}
+
+	/* Framed-Protocol */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-Protocol",&ans_attrib,1,&ret));
+		if ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_framed_protocol, 0, &avp));
+			avp_val.i32 = ans_attrib->value.i32;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+		}
+	}
+
+	/* Framed-Routing */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-Routing",&ans_attrib,1,&ret));
+		if ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_framed_routing, 0, &avp));
+			avp_val.i32 = ans_attrib->value.i32;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+		}
+
+	}
+
+	/* Framed-MTU */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-MTU",&ans_attrib,1,&ret));
+		if ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_framed_mtu, 0, &avp));
+			avp_val.u32 = ans_attrib->value.u32;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+		}
+	}
+
+	/* Framed-Compression */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-Compression",&ans_attrib,1,&ret));
+		while ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_framed_compression, 0, &avp));
+			avp_val.i32 = ans_attrib->value.i32;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+			CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-Compression",&ans_attrib,1,&ret));
+		}
+
+	}
+	/* Framed-IP-Address */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-IP-Address",&ans_attrib,1,&ret));
+		if ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_framed_ip_address, 0, &avp));
+			avp_val.os.data = ans_attrib->value.os.data;
+			avp_val.os.len = ans_attrib->value.os.len;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+		}
+	}
+
+	/* Framed-IP-Netmask */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-IP-Netmask",&ans_attrib,1,&ret));
+		if ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_framed_ip_netmask, 0, &avp));
+			avp_val.os.data = ans_attrib->value.os.data;
+			avp_val.os.len = ans_attrib->value.os.len;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+		}
+	}
+
+	/* Framed-Route */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-Route",&ans_attrib,1,&ret));
+		while ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_framed_route, 0, &avp));
+			avp_val.os.data = ans_attrib->value.os.data;
+			avp_val.os.len = ans_attrib->value.os.len;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+			CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-Route",&ans_attrib,1,&ret));
+		}
+	}
+
+	/* Framed-Pool */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-Pool",&ans_attrib,1,&ret));
+		if ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_framed_pool, 0, &avp));
+			avp_val.os.data = ans_attrib->value.os.data;
+			avp_val.os.len = ans_attrib->value.os.len;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+		}
+	}
+
+	/* Framed-Interface-Id */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-Interface-Id",&ans_attrib,1,&ret));
+		if ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_framed_interface_id, 0, &avp));
+			avp_val.u64 = ans_attrib->value.u64;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+		}
+	}
+
+	/* Framed-IPv6-Prefix */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-IPv6-Prefix",&ans_attrib,1,&ret));
+		while ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_framed_ipv6_prefix, 0, &avp));
+			avp_val.os.data = ans_attrib->value.os.data;
+			avp_val.os.len = ans_attrib->value.os.len;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+			CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-IPv6-Prefix",&ans_attrib,1,&ret));
+		}
+	}
+
+	/* Framed-IPv6-Route */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-IPv6-Route",&ans_attrib,1,&ret));
+		while ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_framed_ipv6_route, 0, &avp));
+			avp_val.os.data = ans_attrib->value.os.data;
+			avp_val.os.len = ans_attrib->value.os.len;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+			CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-IPv6-Route",&ans_attrib,1,&ret));
+		}
+	}
+
+	/* Framed-IPv6-Pool */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-IPv6-Pool",&ans_attrib,1,&ret));
+		if ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_framed_ipv6_pool, 0, &avp));
+			avp_val.os.data = ans_attrib->value.os.data;
+			avp_val.os.len = ans_attrib->value.os.len;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+		}
+	}
+
+	/* Framed-IPX-Network */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-IPX-Network",&ans_attrib,1,&ret));
+		if ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_framed_ipx_network, 0, &avp));
+			avp_val.u32 = ans_attrib->value.u32;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+		}
+
+	}
+	/* Framed-AppleTalk-Link */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-AppleTalk-Link",&ans_attrib,1,&ret));
+		if ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_framed_appletalk_link, 0, &avp));
+			avp_val.u32 = ans_attrib->value.u32;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+		}
+
+	}
+
+	/* Framed-AppleTalk-Network */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-AppleTalk-Network",&ans_attrib,1,&ret));
+		while ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_framed_appletalk_network, 0, &avp));
+			avp_val.u32 = ans_attrib->value.u32;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+			CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-AppleTalk-Network",&ans_attrib,1,&ret));
+		}
+
+	}
+
+	/* Framed-AppleTalk-Zone */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-AppleTalk-Zone",&ans_attrib,1,&ret));
+		if ((ret == 0) && (ans_attrib != NULL))
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_framed_appletalk_zone, 0, &avp));
+			avp_val.os.data = ans_attrib->value.os.data;
+			avp_val.os.len = ans_attrib->value.os.len;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_ans_attrib(ans_attrib);
+		}
+	}
+
+	/* Tunneling */
+	//
+
+	/* State */
+	//
+	return 0;
+}
+
+static int diameap_add_result_code(struct diameap_state_machine * diameap_sm,
+		struct msg * ans, struct session * sess)
+{
+	TRACE_ENTRY("%p %p",diameap_sm,ans);
+	struct avp * avp;
+	union avp_value avp_val;
+	int ret;
+
+	/* Result-Code AVP */
+	CHECK_FCT(fd_msg_avp_new(dataobj_result_code, 0, &avp));
+	avp_val.u32 = diameap_sm->result_code;
+	CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+	/* Add Result-Code AVP to the message */
+	CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+
+	/* Multi_Round_Time_Out AVP */
+	if (diameap_sm->result_code == 1001)
+	{
+		struct timespec sess_timeout;
+		CHECK_FCT(fd_msg_avp_new(dataobj_multi_round_time_out, 0, &avp));
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Multi-Round-Time-Out",&ans_attrib,1,&ret));
+		if ((ret == 0) && (ans_attrib != NULL))
+		{
+			avp_val.u32 = ans_attrib->value.u32;
+			/* Update the session timeout with multi-round-time-out value */
+			CHECK_SYS(clock_gettime(CLOCK_REALTIME,&sess_timeout));
+			sess_timeout.tv_sec += diameap_config->multi_round_time_out;
+			CHECK_FCT(fd_sess_settimeout(sess, &sess_timeout));
+			free_ans_attrib(ans_attrib);
+		}
+		else
+		{
+			avp_val.u32 = diameap_config->multi_round_time_out;
+			/* Update the session timeout with multi-round-time-out value */
+			CHECK_SYS(clock_gettime(CLOCK_REALTIME,&sess_timeout));
+			sess_timeout.tv_sec += diameap_config->multi_round_time_out;
+			CHECK_FCT(fd_sess_settimeout(sess, &sess_timeout));
+		}
+		CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+		CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+	}
+	return 0;
+}
+
+static int diameap_add_eap_payload(struct diameap_state_machine * diameap_sm,
+		struct msg * ans, struct diameap_eap_interface eap_i)
+{
+	TRACE_ENTRY("%p %p",diameap_sm,ans);
+	struct avp * avp;
+	union avp_value avp_val;
+	int ret;
+	u32 Framed_MTU = 1500; //1500 default value
+	u32 NAS_Port_Type_HeaderLength = 4;
+	int EAP_Max_Length = 0;
+
+	/* get Framed-MTU AVP value */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-MTU",&ans_attrib,0,&ret));
+		if ((ret == 0) && (ans_attrib != NULL))
+		{
+			Framed_MTU = ans_attrib->value.u32;
+		}
+	}
+
+	/* get NAS-Port-Type AVP value */
+	{
+		struct avp_attribute * ans_attrib;
+		CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"NAS-Port-Type",&ans_attrib,0,&ret));
+		if ((ret == 0) && (ans_attrib != NULL))
+		{
+			// = ans_attrib->value.i32;
+		}
+	}
+
+	//TD take the link type into consideration when calculating EAP_MAX_Length
+	EAP_Max_Length = Framed_MTU - NAS_Port_Type_HeaderLength;
+
+	if (eap_i.aaaEapReqData.length <= EAP_Max_Length)
+	{
+
+		/* EAP-Payload AVP */
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_eap_payload, 0, &avp));
+			avp_val.os.data = eap_i.aaaEapReqData.data;
+			avp_val.os.len = eap_i.aaaEapReqData.length;
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+
+			if (diameap_sm->lastReqEAPavp != NULL)
+			{
+				fd_msg_free(diameap_sm->lastReqEAPavp);
+				diameap_sm->lastReqEAPavp = NULL;
+			}
+
+			CHECK_FCT(fd_msg_avp_new(dataobj_eap_payload, 0, &diameap_sm->lastReqEAPavp));
+			avp_val.os.data = eap_i.aaaEapReqData.data;
+			avp_val.os.len = eap_i.aaaEapReqData.length;
+			CHECK_FCT(fd_msg_avp_setvalue(diameap_sm->lastReqEAPavp, &avp_val));
+
+		}
+	}
+	else
+	{
+		//if EAP Packet length > EAP_Max_Length
+	}
+	return 0;
+}
+
+static int diameap_send(struct msg ** rmsg)
+{
+	TRACE_ENTRY("%p",rmsg);
+	CHECK_FCT( fd_msg_send( rmsg, NULL, NULL));
+	return 0;
+}
+
+static int diameap_add_eap_success_avps(
+		struct diameap_state_machine * diameap_sm, struct msg * ans,
+		struct diameap_eap_interface eap_i)
+{
+	TRACE_ENTRY("%p %p %p",diameap_sm,ans,eap_i);
+	struct avp * avp;
+	union avp_value avp_val;
+	int ret;
+
+	/* EAP-Master-Session-Key AVP */
+	if (eap_i.aaaEapKeyAvailable == TRUE)
+	{
+		CHECK_FCT(fd_msg_avp_new(dataobj_eap_master_session_key, 0, &avp));
+		avp_val.os.data = eap_i.aaaEapKeyData;
+		avp_val.os.len = eap_i.aaaEapKeyLength;
+		CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+		CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+
+	}
+
+	/* EAP-Key-Name AVP */
+	struct avp_attribute * avp_attrib = NULL;
+
+	CHECK_FCT(diameap_get_avp_attribute(&diameap_sm->req_attributes,"EAP-Key-Name",&avp_attrib,1,&ret))
+	if ((avp_attrib != NULL) && (ret != 1))
+	{
+		if (avp_attrib->value.os.len == 0)
+		{
+			CHECK_FCT(fd_msg_avp_new(dataobj_eap_key_name, 0, &avp));
+			avp_val.os.data = " ";//
+			avp_val.os.len = 1;//
+			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+			free_avp_attrib(avp_attrib);
+		}
+	}
+
+	return 0;
+}
+
+int diameap_authorize(struct diameap_state_machine * diameap_sm)
+{
+	TRACE_ENTRY("%p",diameap_sm);
+
+	CHECK_FCT(diameap_authorization_get_attribs(diameap_sm->eap_sm.user, &diameap_sm->attributes));
+
+	diameap_sm->authorized = TRUE;
+
+	CHECK_FCT_DO(diameap_answer_authorization_attributes(diameap_sm),
+	);
+	if (diameap_sm->authorized == FALSE)
+	{
+		diameap_sm->result_code = 4001; /* DIAMETER_AUTHENTICATION_REJECTED 4001 */
+	}
+	return 0;
+}
+
+static int diameap_add_accounting_eap_auth_method(
+		struct diameap_state_machine * diameap_sm, struct msg * ans)
+{
+	TRACE_ENTRY("%p %p",diameap_sm,ans);
+	int i = 0;
+	struct avp * avp;
+	union avp_value avp_val;
+	/* Accounting-EAP-Auth-Method AVP */
+	while (i < diameap_sm->eap_sm.user.methodId)
+	{
+		CHECK_FCT(fd_msg_avp_new(dataobj_accounting_eap_auth_method, 0, &avp));
+
+		avp_val.u64 = (u64) (((diameap_sm->eap_sm.user.methods[i].vendor)
+				* pow((double) 2, (double) 32))
+				+ diameap_sm->eap_sm.user.methods[i].method);
+		CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
+		CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+		i++;
+	}
+	return 0;
+}
+
+static int diameap_add_eap_reissued_payload(struct msg * ans, struct msg * req)
+{
+	TRACE_ENTRY("%p %p", ans, req);
+	struct avp * avp, *re_avp;
+	union avp_value avp_val;
+	struct avp_hdr * avphdr;
+
+	if ((ans == NULL) || (req == NULL))
+	{
+		return EINVAL;
+	}
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_eap_payload, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT( fd_msg_avp_hdr(avp, &avphdr));
+		CHECK_FCT( fd_msg_avp_new(dataobj_eap_reissued_payload, 0, &re_avp));
+		avp_val.os.data = strdup(avphdr->avp_value->os.data);
+		avp_val.os.len = avphdr->avp_value->os.len;
+		CHECK_FCT(fd_msg_avp_setvalue(re_avp, &avp_val));
+		CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, re_avp ) );
+	}
+	else
+	{
+		TRACE_DEBUG(INFO,"%sUnable to find EAP-Payload AVP in received Diameter-EAP-Request.",DIAMEAP_EXTENSION);
+		return 1;
+	}
+
+	return 0;
+}
+
+int diameap_start_server(void)
+{
+	struct disp_when when;
+	int ret;
+	/*create handler for sessions */
+	CHECK_FCT(fd_sess_handler_create(&diameap_server_reg, diameap_cli_sess_cleanup));
+
+	/* Register the callback */
+	memset(&when, 0, sizeof(when));
+	when.command = dataobj_diameap_cmd;
+	when.app = dataobj_diameap_app;
+
+	/* Register the callback for EAP Application */
+	CHECK_FCT(fd_disp_register(diameap_server_callback, DISP_HOW_CC, &when,
+					&handle));
+
+	if (handle == NULL)
+	{
+		TRACE_DEBUG(INFO, "%sCannot register the callback !!!",DIAMEAP_EXTENSION);
+		return 1;
+	}
+	return 0;
+}
+
+static void free_attrib(struct auth_attribute * auth_attrib)
+{
+	if (auth_attrib == NULL)
+	{
+		return;
+	}
+	if (auth_attrib->attrib != NULL)
+	{
+		free(auth_attrib->attrib);
+		auth_attrib->attrib = NULL;
+	}
+	if (auth_attrib->op != NULL)
+	{
+		free(auth_attrib->op);
+		auth_attrib->op = NULL;
+	}
+	if (auth_attrib->value != NULL)
+	{
+		free(auth_attrib->value);
+		auth_attrib->value = NULL;
+	}
+	free(auth_attrib);
+	auth_attrib = NULL;
+}
+
+static void free_avp_attrib(struct avp_attribute * avp_attrib)
+{
+	free(avp_attrib);
+	avp_attrib = NULL;
+}
+
+static void free_ans_attrib(struct avp_attribute * ans_attrib)
+{
+	if (ans_attrib->tofree == 1)
+	{
+		free(ans_attrib->value.os.data);
+		ans_attrib->value.os.data = NULL;
+	}
+	free(ans_attrib);
+	ans_attrib = NULL;
+}
+
+int diameap_stop_server(void)
+{
+	CHECK_FCT(fd_sess_handler_destroy(&diameap_server_reg));
+	CHECK_FCT(fd_disp_unregister(&handle));
+
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/diameap_server.h	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,231 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+
+#ifndef DIAMEAP_SERVER_H_
+#define DIAMEAP_SERVER_H_
+
+/* handler for DiamEAP server callback */
+static struct disp_hdl * handle;
+
+/* session handler for DiamEAP sessions state machine */
+static struct session_handler * diameap_server_reg = NULL;
+
+/* session data structure to store */
+struct diameap_sess_data_sm
+{
+	int invalid_eappackets; /* Number of invalid EAP Packet received*/
+
+	eap_type currentMethod;
+	u32 currentVendor;
+	int currentId;
+	int lastId;
+	void * methodData;
+
+	u8 NAKproposedMethods[251];
+
+	eap_method_state methodState;
+
+	struct eap_user user;
+};
+
+typedef enum
+{
+	AUTHENTICATE_ONLY = 1, AUTHORIZE_ONLY = 2, AUTHORIZE_AUTHENTICATE = 3
+} auth_request;
+
+struct diameap_state_machine
+{
+	int invalid_eappackets; /* Number of invalid EAP Packet received*/
+	struct avp * lastReqEAPavp; //last EAP-Payload AVP
+
+	int result_code; /*Error number for Result_code*/
+	struct fd_list attributes; //database attributes
+	struct fd_list req_attributes; //attributes from DER
+	struct fd_list ans_attributes; //attributes to be set for DEA
+	struct avp * failedavp; /* The Failed-AVP AVP. should be update whenever a Failed AVP is encountered during authentication. */
+	struct eap_state_machine eap_sm; /* EAP State Machine */
+	auth_request auth_request_val; /*the Request Type of Auth-Request-Type AVP*/
+	boolean verify_authorization; /* Set to TRUE at the authorization state. Parameter used to indicate that authorization is performed.*/
+	boolean authSuccess; // Set to TRUE if client authenticated and authorized
+	boolean authFailure; //set to TRUE if client is not authenticated
+	boolean authorized; //set to TRUE if client is authorized
+	enum
+	{
+		DIAMEAP_DISABLED,
+		DIAMEAP_INITIALIZE,
+		DIAMEAP_RECEIVED,
+		DIAMEAP_IDLE,
+		DIAMEAP_AUTHENTICATION_VERIFY,
+		DIAMEAP_SEND_ERROR_MSG,
+		DIAMEAP_SELECT_DECISION,
+		DIAMEAP_DIAMETER_EAP_ANSWER,
+		DIAMEAP_END,
+		DIAMEAP_AUTHORIZATION_VERIFY,
+		DIAMEAP_SEND_REQUEST,
+		DIAMEAP_SEND_SUCCESS,
+		DIAMEAP_SEND_FAILURE
+
+	} state; // state of DiamEAP
+
+	boolean privateUser;//TD
+};
+
+struct avp_max_occurences
+{
+	char * avp_attribute;
+	int max; //-1 means no limits
+};
+
+
+
+/* start server */
+int diameap_start_server(void);
+
+/* stop server*/
+int diameap_stop_server(void);
+
+/* Initialize DiamEAP state machine variables */
+static int diameap_initialize_diameap_sm(
+		struct diameap_state_machine * diameap_sm,
+		struct diameap_sess_data_sm * diameap_sess_data);
+
+/* Initialize interface between the diameap and the eap states machines */
+static int diameap_initialize_diameap_eap_interface(
+		struct diameap_eap_interface * eap_i);
+
+/* Parse received message */
+static int diameap_parse_avps(struct diameap_state_machine * diameap_sm,
+		struct msg * req, struct diameap_eap_interface * eap_i);
+
+/* Add an avp to Failed_AVP AVP for answer message */
+static int diameap_failed_avp(struct diameap_state_machine * diameap_sm,
+		struct avp * invalidavp);
+
+/* Parse EAP Response */
+static int diameap_parse_eap_resp(struct eap_state_machine * eap_sm,
+		struct eap_packet eappacket);
+
+/* */
+static int diameap_eappacket_new(struct eap_packet * eapPacket,
+		struct avp_hdr * avpdata);
+
+/* */
+static int diameap_sess_data_new(
+		struct diameap_sess_data_sm *diameap_sess_data,
+		struct diameap_state_machine *diameap_sm);
+
+/* */
+static int diameap_unlink_attributes_lists(
+		struct diameap_state_machine * diameap_sm);
+
+/**/
+static int diameap_answer_avp_attributes(
+		struct diameap_state_machine * diameap_sm);
+
+/**/
+static int diameap_answer_authorization_attributes(
+		struct diameap_state_machine * diameap_sm);
+
+static void free_attrib(struct auth_attribute * auth_attrib);
+static void free_avp_attrib(struct avp_attribute * avp_attrib);
+static void free_ans_attrib(struct avp_attribute * ans_attrib);
+
+/* */
+static int diameap_get_avp_attribute(struct fd_list * avp_attributes,
+		char * attribute, struct avp_attribute ** avp_attrib, int unlink,
+		int *ret);
+
+/* */
+static int diameap_get_auth_attribute(struct fd_list * auth_attributes,
+		char * attribute, struct auth_attribute ** auth_attrib, int unlink,
+		int *ret);
+
+/**/
+static int diameap_get_ans_attribute(struct fd_list * ans_attributes,
+		char * attribute, struct avp_attribute ** ans_attrib, int unlink,
+		int *ret);
+
+/* */
+static int diameap_policy_decision(struct diameap_state_machine * diameap_sm,
+		struct diameap_eap_interface eap_i);
+
+/* */
+static int diameap_add_avps(struct diameap_state_machine * diameap_sm,
+		struct msg * ans, struct msg * req);
+
+/* */
+static int diameap_add_user_sessions_avps(
+		struct diameap_state_machine * diameap_sm, struct msg * ans);
+
+/* */
+static int diameap_add_result_code(struct diameap_state_machine * diameap_sm,
+		struct msg * ans, struct session * sess);
+
+/* */
+static int diameap_add_eap_payload(struct diameap_state_machine * diameap_sm,
+		struct msg * ans, struct diameap_eap_interface eap_i);
+
+/* */
+static int diameap_add_authorization_avps(struct diameap_state_machine * diameap_sm,
+		struct msg * ans);
+
+/* */
+static int diameap_send(struct msg ** rmsg);
+
+/* */
+static int diameap_add_eap_success_avps(
+		struct diameap_state_machine * diameap_sm, struct msg * ans,
+		struct diameap_eap_interface eap_i);
+
+/* */
+void diameap_cli_sess_cleanup(void * arg, char * sid);
+
+/* */
+static void diameap_free(struct diameap_state_machine * diameap_sm);
+
+/* */
+static void diameap_sess_data_free(
+		struct diameap_sess_data_sm * diameap_sess_data);
+
+/* */
+static int diameap_add_accounting_eap_auth_method(
+		struct diameap_state_machine * diameap_sm, struct msg * ans);
+
+/* */
+static int diameap_add_eap_reissued_payload(struct msg * ans,struct msg * req);
+#endif /* DIAMEAP_SERVER_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/diameap_tls.c	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,489 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+
+#include "diameap_tls.h"
+
+int diameap_tls_init(struct tls_config * tls_conf)
+{
+	int ret;
+	ret = gnutls_global_init();
+	if (ret < 0)
+	{
+		gnutls_perror(ret);
+	}
+
+	gnutls_global_set_log_function(diameap_tls_log);
+	//gnutls_global_set_log_level(9);
+
+
+	if(tls_conf->cafile ==NULL){
+		fprintf(stderr,"[DiamEAP extension] [EAP TLS] Missing certification authority (CA) certificates. Please provide CA configuration directive.\n"); 
+		return EINVAL;
+	}
+	if( !tls_conf->certfile || !tls_conf->keyfile){
+		fprintf(stderr,"[DiamEAP extension] [EAP TLS] Missing private Key. Please provide Cred configuration directive.\n"); 
+		return EINVAL;
+	}
+
+	ret = gnutls_certificate_allocate_credentials(&tls_conf->cert_cred);
+
+	if (ret < 0)
+	{
+		gnutls_perror(ret);
+		return ret;
+	}
+
+	ret = gnutls_certificate_set_x509_trust_file(tls_conf->cert_cred,
+			tls_conf->cafile, GNUTLS_X509_FMT_PEM);
+	if (ret < 0)
+	{
+		gnutls_perror(ret);
+		return ret;
+	}
+	if (tls_conf->crlfile)
+	{
+		ret = gnutls_certificate_set_x509_crl_file(tls_conf->cert_cred,
+				tls_conf->crlfile, GNUTLS_X509_FMT_PEM);
+		if (ret < 0)
+		{
+			gnutls_perror(ret);
+			return ret;
+		}
+	}
+
+	ret = gnutls_certificate_set_x509_key_file(tls_conf->cert_cred,
+			tls_conf->certfile, tls_conf->keyfile, GNUTLS_X509_FMT_PEM);
+	if (ret < 0)
+	{
+		gnutls_perror(ret);
+		return ret;
+	}
+	return 0;
+}
+
+void diameap_tls_log(int lev, const char * text)
+{
+	u8 * msg;
+	if (text == NULL)
+		return;
+	msg = strdup(text);
+	int i;
+	for (i = 0; (G8(text+i) != '\n') && (G8(text+i) != '\0'); i++)
+	{
+	}
+	P8((msg+i),'\0');
+	fprintf(stderr, "[DiamEAP extension] [EAP TLS] GNUTLS log[%d] : %s\n", lev, msg);
+	free(msg);
+}
+
+int diameap_tls_init_session(struct tls_config * tls_conf,
+		struct tls_data * data)
+{
+	int ret;
+	ret = gnutls_init(&data->session, GNUTLS_SERVER);
+	if (ret < 0)
+	{
+		gnutls_perror(ret);
+	}
+	ret = gnutls_set_default_priority(data->session);
+	if (ret < 0)
+	{
+		gnutls_perror(ret);
+	}
+
+	ret = gnutls_credentials_set(data->session, GNUTLS_CRD_CERTIFICATE,
+			tls_conf->cert_cred);
+	if (ret < 0)
+	{
+		gnutls_perror(ret);
+	}
+
+	/* request client certificate if any.
+	 */
+	gnutls_certificate_server_set_request(data->session, GNUTLS_CERT_REQUIRE); //GNUTLS_CERT_REQUEST);
+
+	gnutls_transport_set_pull_function(data->session, diameap_tls_receive);
+	gnutls_transport_set_push_function(data->session, diameap_tls_send);
+	gnutls_transport_set_ptr(data->session, (gnutls_transport_ptr) data);
+
+	gnutls_transport_set_lowat(data->session, 0);
+
+	return ret;
+}
+
+ssize_t diameap_tls_receive(gnutls_transport_ptr_t ptr, void *buffer,
+		size_t length)
+{
+	struct tls_data * data = (struct tls_data *) ptr;
+	if (data->p_length == 0)
+	{
+		errno = EWOULDBLOCK;
+		return -1;
+	}
+	if (length > data->p_length)
+	{
+		length = data->p_length;
+	}
+	memcpy(buffer, data->tlsResp.data + (data->tlsResp.datalength
+			- data->p_length), length);
+	data->p_length -= length;
+
+	return length;
+}
+
+ssize_t diameap_tls_send(gnutls_transport_ptr_t ptr, const void *buffer,
+		size_t length)
+{
+	int i;
+	struct tls_data * data = (struct tls_data *) ptr;
+	u8 * buff;
+
+	data->tlsReq.data = realloc(data->tlsReq.data, data->tlsReq.datalength
+			+ length);
+	U8COPY(data->tlsReq.data,data->tlsReq.datalength,length,(u8*)buffer);
+	data->tlsReq.datalength += length;
+
+	return length;
+}
+
+int diameap_tls_new(struct tls_msg * tlsmsg)
+{
+	if (!tlsmsg)
+	{
+		return EINVAL;
+	}
+	tlsmsg->flags = 0x00;
+	tlsmsg->length = 0;
+	tlsmsg->data = NULL;
+	tlsmsg->datalength = 0;
+	return 0;
+}
+
+int diameap_tls_get_flags(struct tls_msg tlsmsg, u8 * flags)
+{
+	*flags = tlsmsg.flags;
+	return 0;
+}
+
+int diameap_tls_set_flags(struct tls_msg * tlsmsg, u8 flags)
+{
+	if (!tlsmsg)
+	{
+		return EINVAL;
+	}
+	if ((flags & TLS_FLAG_LENGTH) == TLS_FLAG_LENGTH)
+	{
+		flags = flags ^ TLS_FLAG_LENGTH;
+	}
+	tlsmsg->flags = tlsmsg->flags | flags;
+	return 0;
+}
+
+int diameap_tls_get_message_length(struct tls_msg tlsmsg, u32 * length)
+{
+	if ((tlsmsg.flags & TLS_FLAG_LENGTH) == TLS_FLAG_LENGTH)
+	{
+		*length = tlsmsg.length;
+	}
+	else
+	{
+		*length = 0;
+	}
+	return 0;
+}
+
+int diameap_tls_set_message_length(struct tls_msg * tlsmsg, u32 length)
+{
+	if (!tlsmsg)
+	{
+		return EINVAL;
+	}
+	if (length > 0)
+	{
+		tlsmsg->length = length;
+		tlsmsg->flags = tlsmsg->flags | TLS_FLAG_LENGTH;
+	}
+	else
+	{
+		tlsmsg->length = 0;
+		if ((tlsmsg->flags & TLS_FLAG_LENGTH) == TLS_FLAG_LENGTH)
+		{
+			tlsmsg->flags = tlsmsg->flags ^ TLS_FLAG_LENGTH;
+		}
+	}
+	return 0;
+}
+
+int diameap_tls_get_data(struct tls_msg tlsmsg, u8** tls_data,
+		int * data_length)
+{
+	if (tlsmsg.datalength > 0)
+	{
+		*tls_data = malloc(sizeof(u8) * tlsmsg.datalength);
+		U8COPY(*tls_data,0,tlsmsg.datalength,tlsmsg.data);
+		*data_length = tlsmsg.datalength;
+	}
+	else
+	{
+		*tls_data = NULL;
+		*data_length = 0;
+	}
+	return 0;
+}
+
+int diameap_tls_set_data(struct tls_msg * tlsmsg, u8* tls_data, int data_length)
+{
+	if (!tlsmsg)
+	{
+		return EINVAL;
+	}
+	tlsmsg->data = malloc(sizeof(u8) * data_length);
+	U8COPY(tlsmsg->data,0,data_length,tls_data);
+	tlsmsg->datalength = data_length;
+	return 0;
+}
+
+/*
+ * data : returned data
+ * eaptls_data : the TLS_Data field
+ * length : the length of eaptls_data
+ * flags : combination of flags et set
+ */
+int diameap_tls_new_tls_packet(u8** data, int * len, struct tls_msg tlsmsg)
+{
+	int buflen, pos = 0;
+
+	buflen = 1;
+
+	if ((tlsmsg.flags & TLS_FLAG_LENGTH) == TLS_FLAG_LENGTH)
+	{
+		buflen += 4;
+	}
+
+	if (tlsmsg.datalength > 0)
+	{
+		buflen += tlsmsg.datalength;
+	}
+	*data = malloc(sizeof(u8) * buflen);
+	memset(*data, 0, sizeof(u8) * buflen);
+	P8(*data,tlsmsg.flags);
+	pos++;
+
+	if ((tlsmsg.flags & TLS_FLAG_LENGTH) == TLS_FLAG_LENGTH)
+	{
+		P32BIGE(*data+pos,tlsmsg.length);
+		pos += 4;
+	}
+	if (tlsmsg.data)
+	{
+		U8COPY(*data,pos,tlsmsg.datalength,tlsmsg.data);
+	}
+	*len = buflen;
+	return 0;
+}
+
+int diameap_set_tls(struct tls_msg * tlsmsg, u8 flags, u32 length,
+		u8 *tls_data, int data_length)
+{
+	diameap_tls_new(tlsmsg);
+	diameap_tls_set_flags(tlsmsg, flags);
+	diameap_tls_set_message_length(tlsmsg, length);
+	diameap_tls_set_data(tlsmsg, tls_data, data_length);
+	return 0;
+}
+
+int diameap_tls_parse(u8* data, int len, struct tls_msg * tlsmsg)
+{
+
+	if (data == NULL)
+		return;
+	int pos = 0;
+	diameap_tls_new(tlsmsg);
+	tlsmsg->flags = G8(data);
+	pos++;
+	if ((tlsmsg->flags & TLS_FLAG_LENGTH) == TLS_FLAG_LENGTH)
+	{
+		tlsmsg->length = G32BIGE(data+1);
+		pos = pos + 4;
+	}
+
+	if (len > pos)
+	{
+		tlsmsg->data = malloc(sizeof(u8) * (len - pos));
+		U8COPY(tlsmsg->data,0,(len-pos),data+pos);
+		tlsmsg->datalength = len - pos;
+	}
+	else
+	{
+		tlsmsg->data = NULL;
+		tlsmsg->datalength = 0;
+	}
+	return 0;
+}
+
+void diameap_tls_dump(struct tls_msg tlsmsg)
+{
+	u8 * data = NULL;
+	u32 len;
+	diameap_tls_get_data(tlsmsg, &data, &len);
+
+	fprintf(stderr, "-------------Dump EAP-TLS msg-------------\n");
+	u8 flags;
+	diameap_tls_get_flags(tlsmsg, &flags);
+	fprintf(stderr, "\t -flags       		: %02x ", flags);
+	if (flags & TLS_FLAG_LENGTH)
+		fprintf(stderr, " TLS_FLAG_LENGTH ");
+	if (flags & TLS_FLAG_MORE)
+		fprintf(stderr, " TLS_FLAG_MORE ");
+	if (flags & TLS_FLAG_START)
+		fprintf(stderr, " TLS_FLAG_START ");
+	fprintf(stderr, "\n");
+	if ((tlsmsg.flags & TLS_FLAG_LENGTH) == TLS_FLAG_LENGTH)
+	{
+		u32 length;
+		diameap_tls_get_message_length(tlsmsg, &length);
+		fprintf(stderr, "\t -TLS msg length	: %u (0x%02x%02x%02x%02x)\n",
+				length, (length >> 24) & 0xffU, (length >> 16) & 0xffU, (length
+						>> 8) & 0xffU, length & 0xffU);
+	}
+	fprintf(stderr, "\t -data length		: %d \n", len);
+	/*
+	if (len > 0)
+	{
+		int i;
+		fprintf(stderr, "\t -Data			: ");
+		for (i = 0; i < len; i++)
+		{
+			fprintf(stderr, "%02x ", G8(data + i));
+		}
+		fprintf(stderr, "\n");
+	}
+	*/
+	fprintf(stderr, "-------------End Dump EAP-TLS msg-------------\n");
+}
+
+int diameap_tls_initialize(struct tls_data * data)
+{
+	if (!data)
+	{
+		return EINVAL;
+	}
+	data->state = START;
+	data->more_tosend_length = 0;
+	data->more_toreceive = FALSE;
+	data->handshake = FALSE;
+	return 0;
+}
+
+int diameap_tls_reassemble(struct tls_msg * to, struct tls_msg from)
+{
+	u8 from_flag;
+	diameap_tls_get_flags(from, &from_flag);
+
+	if (from_flag & TLS_FLAG_LENGTH)
+	{
+		diameap_tls_new(to);
+		u32 length;
+		diameap_tls_get_message_length(from, &length);
+		diameap_tls_set_message_length(to, length);
+	}
+	diameap_tls_set_flags(to, from_flag);
+
+	u8 * tlsRespData;
+	u32 tlsRespDataLength;
+	diameap_tls_get_data(from, &tlsRespData, &tlsRespDataLength);
+	to->data = realloc(to->data, to->datalength + tlsRespDataLength);
+	U8COPY(to->data,to->datalength,tlsRespDataLength,tlsRespData);
+	to->datalength += tlsRespDataLength;
+	free(tlsRespData);
+	return 0;
+}
+
+int diameap_tls_copy(struct tls_msg * to, struct tls_msg from)
+{
+	u8 flag;
+	u32 length;
+	u8 * data;
+	diameap_tls_new(to);
+	diameap_tls_get_flags(from, &flag);
+	diameap_tls_set_flags(to, flag);
+	diameap_tls_get_message_length(from, &length);
+	diameap_tls_set_message_length(to, length);
+	length = 0;
+	diameap_tls_get_data(from, &data, &length);
+	diameap_tls_set_data(to, data, length);
+	return 0;
+}
+
+int diameap_tls_process_receive(struct tls_data * data)
+{
+	int ret;
+
+	data->p_length = data->tlsResp.datalength;
+	ret = gnutls_handshake(data->session);
+
+	if (ret < 0)
+	{
+		switch (ret)
+		{
+		case GNUTLS_E_AGAIN:
+			break;
+		case GNUTLS_E_INTERRUPTED:
+			fprintf(stderr, "[DiamEAP extension] [EAP TLS] gnutls handshake : GNUTLS_E_INTERRUPTED");
+			break;
+		case GNUTLS_E_GOT_APPLICATION_DATA:
+			fprintf(stderr,
+					"[DiamEAP extension] [EAP TLS] gnutls handshake : GNUTLS_E_GOT_APPLICATION_DATA");
+			break;
+		case GNUTLS_E_WARNING_ALERT_RECEIVED:
+			fprintf(stderr,
+					"[DiamEAP extension] [EAP TLS] gnutls handshake : GNUTLS_E_WARNING_ALERT_RECEIVED");
+			break;
+		}
+		if (ret != GNUTLS_E_AGAIN)
+		{
+			gnutls_perror(ret);
+		}
+	}
+	if (ret == GNUTLS_E_SUCCESS)
+	{
+		data->handshake = TRUE;
+	}
+	return 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/diameap_tls.h	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,120 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+
+#ifndef DIAMEAP_TLS_H_
+#define DIAMEAP_TLS_H_
+
+#include "diameap_defs.h"
+#include <gnutls/gnutls.h>
+#include <gcrypt.h>
+#include <errno.h>
+#include <pthread.h>
+
+GCRY_THREAD_OPTION_PTHREAD_IMPL;
+
+
+#define TLS_FLAG_LENGTH	0x80
+#define TLS_FLAG_MORE	0x40
+#define TLS_FLAG_START	0x20
+
+struct tls_config{
+	char * conffile;
+	//certificates
+	char * keyfile;
+	char * certfile;
+	char * cafile;
+	char * crlfile;
+
+	int max_size;
+
+	gnutls_certificate_credentials_t cert_cred;
+};
+
+struct tls_msg{
+	u8	flags;
+	u32 length;
+	u8 *data;
+	u32 datalength;
+};
+
+struct tls_data
+{
+	gnutls_session_t session;
+	enum { START, CONTINUE, SUCCESS, FAILURE } state;
+	struct tls_msg tlsReq;
+	int p_length; 			/* length of buffer still not returned to handshake */
+	struct tls_msg tlsResp;
+	int more_tosend_length;	/* 0 if no more fragment to send. Otherwise the length of the buff not yet sent */
+	boolean more_toreceive; /* TRUE if wait for more fragments. */
+	boolean handshake; 		/* TRUE if handshake terminated successful. */
+};
+
+int diameap_tls_init(struct tls_config * tls_conf );
+void diameap_tls_log(int lev, const char * text);
+int diameap_tls_init_session(struct tls_config * tls_conf, struct tls_data * data);
+int diameap_tls_new(struct tls_msg * tlsmsg);
+
+int diameap_tls_get_message_length(struct tls_msg tlsmsg, u32 * length);
+int diameap_tls_set_message_length(struct tls_msg * tlsmsg, u32 length);
+
+int diameap_tls_get_flags(struct tls_msg tlsmsg, u8 * flags);
+int diameap_tls_set_flags(struct tls_msg * tlsmsg, u8 flags);
+
+int diameap_tls_get_data(struct tls_msg tlsmsg, u8** tls_data, int * data_length);
+int diameap_tls_set_data(struct tls_msg * tlsmsg, u8* tls_data, int data_length);
+
+int diameap_tls_parse(u8* data, int length, struct tls_msg * tlsmsg);
+
+int diameap_tls_new_tls_packet(u8** data, int * len, struct tls_msg tlsmsg);
+
+int diameap_set_tls(struct tls_msg * tlsmsg, u8 flags, u32 length,u8 *tls_data, int data_length);
+
+void diameap_tls_dump(struct tls_msg tlsmsg);
+
+int diameap_tls_initialize(struct tls_data * data);
+
+int diameap_tls_reassemble(struct tls_msg * to,struct tls_msg from);
+
+int diameap_tls_copy(struct tls_msg * to,struct tls_msg from);
+
+int diameap_tls_process_receive(struct tls_data * data);
+
+ssize_t diameap_tls_receive(gnutls_transport_ptr_t data , void *buffer, size_t length);
+ssize_t diameap_tls_send(gnutls_transport_ptr_t data , const void *buffer, size_t length);
+
+#endif /* DIAMEAP_TLS_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/diameap_user.c	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,152 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+
+#include "libdiameap.h"
+
+int diameap_user_get_userid(struct eap_user user, u8* userid)
+{
+	TRACE_ENTRY("%p %p",user,userid);
+	if (user.userid == NULL)
+		return EINVAL;
+	userid = user.userid;
+	return 0;
+}
+
+int diameap_user_get_password(struct eap_user user, u8* password,u16 * passwordlength)
+{
+	TRACE_ENTRY("%p %p",user,password);
+	if (user.password == NULL)
+		return EINVAL;
+	password = user.password;
+	*passwordlength = user.passwordLength;
+	return 0;
+}
+
+int diameap_user_get_passwordlength(struct eap_user user, u16 * passwordlength)
+{
+	TRACE_ENTRY("%p %p",user,passwordlength);
+	if (user.password == NULL)
+		return EINVAL;
+	*passwordlength = user.passwordLength;
+	return 0;
+}
+
+int diameap_user_set_password(struct eap_user * user, u8 * password,
+		u16 passwordLength)
+{
+	TRACE_ENTRY("%p %p %p",user,password,passwordLength);
+	if (password == NULL)
+		return EINVAL;
+	if (passwordLength < 1)
+		return EINVAL;
+	user->password = password;
+	user->passwordLength = passwordLength;
+	return 0;
+}
+
+int diameap_user_set_userid(struct eap_user * user, u8 * userid,
+		u16 useridLength)
+{
+	TRACE_ENTRY("%p %p %p",user,userid,useridLength);
+	if (userid == NULL)
+		return EINVAL;
+	if (useridLength < 1)
+		return EINVAL;
+	user->userid = userid;
+	user->useridLength = useridLength;
+	return 0;
+}
+
+int diameap_user_get_methodid(struct eap_user user, int * methodid)
+{
+	TRACE_ENTRY("%p %p",user,methodid);
+	if (user.password == NULL)
+		return EINVAL;
+	*methodid = user.methodId;
+	return 0;
+}
+
+int diameap_user_set_methodid(struct eap_user * user, int methodId)
+{
+	TRACE_ENTRY("%p %p",user,methodId);
+	if (user->password == NULL)
+		return EINVAL;
+	if (methodId < 0)
+		return EINVAL;
+	user->methodId = methodId;
+	return 0;
+}
+
+boolean diameap_user_issuccess(struct eap_user user)
+{
+	TRACE_ENTRY("%p",user);
+	if (user.password == NULL)
+		return FALSE;
+	return user.success;
+}
+
+int diameap_user_set_success(struct eap_user * user)
+{
+	TRACE_ENTRY("%p",user);
+	if (user->password == NULL)
+		return EINVAL;
+	user->success = TRUE;
+	return 0;
+}
+
+int diameap_user_get_eap_method(struct eap_user user, int id,
+		struct eap_method *method)
+{
+	TRACE_ENTRY("%p %p %p",user,id,method);
+	if (sizeof(user.methods) >= (id - 1))
+		*method = user.methods[id];
+	return 0;
+}
+
+int diameap_user_set_eap_method(struct eap_user * user, int id,
+		struct eap_method method)
+{
+	TRACE_ENTRY("%p %p %p",user,id,method);
+	if (user->password == NULL)
+		return EINVAL;
+	if (sizeof(user->methods) < (id - 1))
+		return EINVAL;
+	user->methods[id].vendor = method.vendor;
+	user->methods[id].method = method.method;
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/diameap_user.h	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,98 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+
+#ifndef DIAMEAP_USER_H_
+#define DIAMEAP_USER_H_
+
+#define MAXMETHODS 8 	/*Maximum number of allowed methods */
+
+#define MAXPROPOSEDMETHODS 8 	/*Maximum number of allowed proposed methods */
+
+#define	VENDOR_IETF 0
+
+/*EAP User structure */
+struct eap_user
+{
+	int id;	/*user's identifier*/
+	u8 	*userid;	/*user's identity*/
+	u16	useridLength;	/*User's identity length*/
+	u8 	*password; /*user's password*/
+	u16 passwordLength;	/*Length of password*/
+
+	int methodId;	/*Current method Id*/
+	struct eap_method
+	{
+		u32 vendor;
+		eap_type method;
+	} methods[MAXMETHODS]; /*used method for authentication*/
+
+	struct proposed_eap_method
+	{
+		u32 vendor;
+		eap_type method;
+	} proposedmethods[MAXPROPOSEDMETHODS]; /* methods proposed throw NAK response or EXPANDED NAK*/
+	int pmethods; /*Number of accepted methods from peer's proposed methods*/
+
+	eap_type proposed_eap_method; /* Proposed EAP Method*/
+	u32 proposed_eap_method_vendor;
+	boolean success; /* Set to TRUE if User is authenticated successfully */
+};
+
+
+
+int diameap_user_get_password(struct eap_user user, u8 * password,u16 *length);
+
+int diameap_user_get_userid(struct eap_user user, u8 * userid);
+
+int diameap_user_set_password(struct eap_user * user, u8 * password, u16 Length);
+
+int diameap_user_set_userid(struct eap_user * user, u8 * userid, u16 Length);
+
+int diameap_user_get_methodid(struct eap_user user,int *methodId);
+
+int diameap_user_set_methodid(struct eap_user * user, int methodId);
+
+boolean diameap_user_issuccess(struct eap_user user);
+
+int diameap_user_set_success(struct eap_user * user);
+
+int diameap_user_get_eap_method(struct eap_user user, int id, struct eap_method * eapmethod);
+
+int diameap_user_set_eap_method(struct eap_user * user, int id, struct eap_method method);
+
+#endif /* DIAMEAP_USER_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/libcrypt.c	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,56 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+
+#include "libcrypt.h"
+
+int md5hash(void * buffer, int length, void * digest){
+
+	gcry_md_hd_t md5_ctx;
+
+	gcry_md_open ( &md5_ctx, GCRY_MD_MD5, 0);
+
+	if(!gcry_md_is_enabled(md5_ctx, GCRY_MD_MD5)){
+		fprintf(stderr,"[libcrypt] unable to initiate MD5 hash algorithm.\n");
+	}
+
+	gcry_md_write(md5_ctx,buffer,length);
+
+	memcpy (digest, gcry_md_read (md5_ctx, 0), 16);
+	gcry_md_close (md5_ctx);
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/libcrypt.h	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,51 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+
+#ifndef LIBCRYPT_H_
+#define LIBCRYPT_H_
+
+#include <gcrypt.h>
+#include <stdio.h>
+
+/* EAP-TLS*/
+#include "diameap_tls.h"
+
+
+int md5hash(void * buffer, int length, void * digest);
+
+#endif /* LIBCRYPT_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/libdiameap.h	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,186 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+
+#ifndef LIBDIAMEAP_H_
+#define LIBDIAMEAP_H_
+
+#include <freeDiameter/extension.h>
+
+#define DIAMEAP_EXTENSION "[DiamEAP extension] "
+
+#include "diameap_defs.h"
+#include "diameap_eappacket.h"
+#include "diameap_user.h"
+#include "diameap_mysql.h"
+
+#include <math.h>
+#include <dlfcn.h>
+
+
+/* authentication and authorization attributes  */
+
+struct auth_attribute
+{
+	struct fd_list chain;
+	char * attrib;
+	char * op;
+	char * value;
+};
+
+struct avp_attribute
+{
+	struct fd_list chain;
+	char * attrib;
+	union avp_value value;
+	int tofree;
+};
+
+
+/************************************************/
+/*		EAP Methods	plugins							*/
+/************************************************/
+
+/* The register functions of an EAP method */
+struct register_plugin
+{
+	char * configure;
+	char * init;
+	char * initPickUp;
+	char * buildReq;
+	char * isDone;
+	char * process;
+	char * check;
+	char * getTimeout;
+	char * getKey;
+	char * unregister;
+	char * datafree;
+};
+
+struct eap_state_machine;
+/* List of plugins to load ( only EAP methods declared in the configuration file will be loaded) */
+struct plugin
+{
+	struct fd_list chain; /* link in the list */
+	u32 vendor;	/* vendor*/
+	const char *methodname; /* name of the EAP method*/
+	eap_type methodtype; /* type number of the EAP method */
+	char *pluginfile; /* plugin filename */
+	char *conffile; /* optional configuration file name for the method */
+	void *handler; /* object returned by dlopen() */
+	int (*eap_method_configure)(char * configfile); /* (Optional) address of the eap_method_configure method */
+	int (*eap_method_init)(struct eap_state_machine *smd); /* address of the eap_method_init method */
+	int (*eap_method_initPickUp)(struct eap_state_machine *smd); /* address of the eap_method_initPickUp method */
+	int (*eap_method_buildReq)(struct eap_state_machine *smd,
+			u8 identifier,struct eap_packet * eapPacket); /* address of the eap_method_buildReq method */
+	int (*eap_method_getTimeout)(struct eap_state_machine *smd, int * timeout); /* address of the eap_method_getTimeout method */
+	boolean (*eap_method_check)(struct eap_state_machine *smd,
+			struct eap_packet eapRespData); /* address of the eap_method_check method */
+	int (*eap_method_process)(struct eap_state_machine *smd,
+			struct eap_packet eapRespData); /* address of the eap_method_process method */
+	boolean (*eap_method_isDone)(struct eap_state_machine *smd); /* address of the eap_method_isDone method */
+	int (*eap_method_getKey)(struct eap_state_machine *smd, u8 ** key,int *keylength); /* address of the eap_method_getKey method */
+	void (*eap_method_unregister)(void); /* (Optional) address of the eap_method_unregister method */
+	void (*eap_method_free)(void *); /* (Optional) address of the eap_method_datafree method */
+
+};
+
+
+/************************************************/
+/*		EAP State Machine						*/
+/************************************************/
+
+/* EAP Policy Decision */
+typedef enum
+{
+	DECISION_FAILURE = 0, DECISION_SUCCESS = 1, DECISION_CONTINUE = 2
+} decision;
+
+typedef enum
+{
+	EAP_M_END, EAP_M_CONTINUE, EAP_M_PROPOSED
+} eap_method_state;
+
+/* EAP Backend Authenticator State Machine (RFC4137) */
+/* Most of variables are described in the part 6 of the RFC 4137 */
+/* */
+struct eap_state_machine
+{
+	/*Local state Machine Variables*/
+
+	/* Long-Term (Maintained between Packets) */
+	eap_type currentMethod;
+	u32 currentVendor;
+	int currentId;
+	int lastId;
+	void * methodData;
+	struct plugin *selectedMethod;
+	u8 NAKproposedMethods[251];
+
+	eap_method_state methodState;
+
+	struct eap_user user;
+
+	/* Short-Term (Not Maintained between exchanged Diameter EAP messages)*/
+	boolean rxResp;
+	int respId;
+	eap_type respMethod;
+	int respVendorMethod;
+	u32 respVendor;
+	decision sm_decision;
+	enum
+	{
+		EAP_INITIALIZE,
+		EAP_PICK_UP_METHOD,
+		EAP_IDLE,
+		EAP_RECEIVED,
+		EAP_SEND_REQUEST,
+		EAP_INTEGRITY_CHECK,
+		EAP_METHOD_REQUEST,
+		EAP_METHOD_RESPONSE,
+		EAP_PROPOSE_METHOD,
+		EAP_NAK,
+		EAP_SELECT_ACTION,
+		EAP_END,
+		EAP_DISCARD
+	} eap_state;
+
+};
+
+
+
+#endif /* LIBDIAMEAP_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/plugins.h	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,82 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+
+#ifndef _PLUGINS_H
+#define _PLUGINS_H
+
+#include "libdiameap.h"
+#include "libcrypt.h"
+
+
+static struct register_plugin *registerplugin = NULL;
+
+static int isregistered = 0;
+
+/* Macro that define the register functions of an EAP method */
+#define REGISTER_METHOD(_methodName, _configFunction, _initFunction, _initPickUpFunction, _buildReqFunction, _getTimeoutFunction, _checkFunction, _processFunction, _isDoneFunction, _getKeyFunction, _unregisterFunction, _datafreeFunction  ) \
+int diameap_plugin_register() {	\
+		if (!isregistered){	\
+			registerplugin = malloc (sizeof(struct register_plugin)); \
+			if(registerplugin==NULL) \
+				fprintf(stderr,"[DiamEAP extension] Error in registering plug-in\t%s\n",strerror(errno)); \
+			memset(registerplugin, 0, sizeof(struct register_plugin)); \
+			if(_configFunction) registerplugin->configure=_configFunction;	\
+			if(_initFunction) registerplugin->init=_initFunction;	\
+			if(_initPickUpFunction) registerplugin->initPickUp=_initPickUpFunction;	\
+			if(_buildReqFunction) registerplugin->buildReq=_buildReqFunction;	\
+			if(_getTimeoutFunction) registerplugin->getTimeout=_getTimeoutFunction;	\
+			if(_checkFunction) registerplugin->check=_checkFunction;	\
+			if(_processFunction) registerplugin->process=_processFunction;	\
+			if(_isDoneFunction) registerplugin->isDone=_isDoneFunction;	\
+			if(_getKeyFunction) registerplugin->getKey=_getKeyFunction;	\
+			if(_unregisterFunction) registerplugin->unregister=_unregisterFunction;	\
+			if(_datafreeFunction) registerplugin->datafree=_datafreeFunction;	\
+			isregistered++; \
+		}else{ \
+			 fprintf(stderr, "Cannot register the " _methodName " plugin twice\n");	\
+			return EINVAL; \
+		} \
+		return 0; \
+	}	\
+int diameap_plugin_objects(struct register_plugin ** rplugin){ \
+*rplugin=registerplugin; \
+return 0; \
+} \
+
+
+#endif /*_PLUGINS_H*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/plugins/CMakeLists.txt	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,30 @@
+PROJECT("EAP Methods Plugins" C)
+
+SET(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR})
+
+MACRO(EAP_ADD_METHOD METHNAME)
+  ADD_LIBRARY(${METHNAME} MODULE ${ARGN})
+  SET_TARGET_PROPERTIES(${METHNAME} PROPERTIES PREFIX "" )
+  SET_TARGET_PROPERTIES(${METHNAME} PROPERTIES SUFFIX ".emp" )
+ENDMACRO(EAP_ADD_METHOD)
+
+###########################
+# EAP Methods Plugins Section
+
+# EAP Identity plugin
+OPTION(BUILD_IDENTITY "Build EAP Identity Plugin " ON)
+	IF (BUILD_IDENTITY)
+	   ADD_SUBDIRECTORY(eap_identity)
+	ENDIF (BUILD_IDENTITY)
+
+# EAP MD5 plugin
+OPTION(BUILD_EAP_MD5 "Build EAP-MD5 Plugin " OFF)
+	IF (BUILD_EAP_MD5)
+	   ADD_SUBDIRECTORY(eap_md5)
+	ENDIF (BUILD_EAP_MD5)
+
+# EAP TLS plugin
+OPTION(BUILD_EAP_TLS "Build EAP-TLS Plugin " OFF)
+	IF (BUILD_EAP_TLS)
+	   ADD_SUBDIRECTORY(eap_tls)
+	ENDIF (BUILD_EAP_TLS)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/plugins/eap_identity/CMakeLists.txt	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,4 @@
+# EAP Identity plugin
+PROJECT("EAP Identity Plugin" C)
+
+EAP_ADD_METHOD(eap_identity eap_identity.c)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/plugins/eap_identity/eap_identity.c	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,171 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+#include "../../plugins.h"
+
+struct identity_data
+{
+	enum
+	{
+		IDENTITY_CONTINUE, IDENTITY_SUCCESS, IDENTITY_FAILURE
+	} state;
+};
+
+int identity_init(struct eap_state_machine *smd);
+int identity_initPickUp(struct eap_state_machine *smd);
+int identity_buildReq(struct eap_state_machine *smd, u8 identity, struct eap_packet * eapPacket);
+boolean identity_check(struct eap_state_machine *smd, struct eap_packet eapRespData);
+int identity_process(struct eap_state_machine *smd, struct eap_packet eapRespData);
+boolean identity_isDone(struct eap_state_machine *smd);
+void identity_free(void * data);
+
+REGISTER_METHOD("identity", NULL, "identity_init", "identity_initPickUp", "identity_buildReq", NULL, "identity_check", "identity_process", "identity_isDone", NULL, NULL, "identity_free");
+
+
+int identity_init(struct eap_state_machine *smd)
+{
+	struct identity_data *data = NULL;
+	CHECK_MALLOC(data = malloc(sizeof(struct identity_data)));
+	memset(data, 0, sizeof(struct identity_data));
+	data->state = IDENTITY_CONTINUE;
+	smd->methodData = (struct identity_data*) data;
+
+	return 0;
+}
+
+int identity_initPickUp(struct eap_state_machine *smd)
+{
+	struct identity_data *data = NULL;
+	CHECK_MALLOC(data = malloc(sizeof(struct identity_data)));
+	memset(data, 0, sizeof(struct identity_data));
+	data->state = IDENTITY_CONTINUE;
+	smd->methodData = (struct identity_data*) data;
+	return 0;
+}
+
+int identity_buildReq(struct eap_state_machine *smd, u8 identity, struct eap_packet * eapPacket)
+{
+
+	CHECK_FCT(diameap_eap_new(EAP_REQUEST, identity, TYPE_IDENTITY, NULL, 0,eapPacket));
+	return 0;
+
+}
+
+
+boolean identity_check(struct eap_state_machine *smd, struct eap_packet eapPacket)
+{
+
+	if (eapPacket.data == NULL)
+	{
+		TRACE_DEBUG(INFO,"%s[EAP Identity plugin] Empty EAP packet received.",DIAMEAP_EXTENSION);
+		return FALSE;
+	}
+	eap_type type;
+	if(diameap_eap_get_type(eapPacket,&type)!=0){
+		return FALSE;
+	}
+	if (type == TYPE_IDENTITY)
+	{
+		u16 length;
+		CHECK_FCT(diameap_eap_get_length(eapPacket,&length));
+		if ((int)length < 6)
+		{
+			TRACE_DEBUG(INFO,"%s[EAP Identity plugin] Incorrect EAP packet received (length = %d ).",DIAMEAP_EXTENSION,length);
+			return FALSE;
+		}
+		if ((int)length > 1020)
+		{
+			TRACE_DEBUG(INFO,"%s[EAP Identity plugin] Incorrect EAP packet received (length = %d ).",DIAMEAP_EXTENSION,length);
+			return FALSE;
+		}
+		return TRUE;
+	}
+	return FALSE;
+}
+
+int identity_process(struct eap_state_machine *smd, struct eap_packet eapRespData)
+{
+	struct identity_data * data;
+	u16 length;
+	char * user;
+	u8 * Respdata;
+	int len,ret;
+
+	CHECK_FCT(diameap_eap_get_length(eapRespData,&length));
+	data = (struct identity_data*) smd->methodData;
+
+	CHECK_MALLOC(user=malloc(sizeof(char)*((int)length-4)));
+
+	diameap_eap_get_data(eapRespData,&Respdata,&len);
+	if(Respdata==NULL){
+		data->state = IDENTITY_FAILURE;
+		goto end;
+	}
+	U8COPY(user,0,len,Respdata);
+	user[length-5]='\0';
+
+	ret=diameap_get_eap_user(&(smd->user),user);
+
+	if(ret==0)
+	{
+		smd->user.methodId = -1;
+		data->state = IDENTITY_SUCCESS;
+	}else{
+		data->state = IDENTITY_FAILURE;
+	}
+end:
+	smd->methodData = data;
+	free(user);
+	user=NULL;
+	return 0;
+}
+
+boolean identity_isDone(struct eap_state_machine *smd)
+{
+	struct identity_data *data;
+	data = (struct identity_data*) smd->methodData;
+	if (data->state != IDENTITY_CONTINUE)
+		return TRUE;
+	else
+		return FALSE;
+}
+
+void identity_free(void * data)
+{
+	free(data);
+	data=NULL;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/plugins/eap_md5/CMakeLists.txt	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,4 @@
+# EAP MD5 Plugin
+PROJECT("EAP MD5 Plugin" C)
+
+EAP_ADD_METHOD(eap_md5 eap_md5.c)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/plugins/eap_md5/eap_md5.c	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,198 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+
+#include "../../plugins.h"
+#include <gcrypt.h>
+
+#define CHALLENGE_LEN	16
+
+struct eap_md5_data
+{
+	enum
+	{
+		EAP_MD5_CONTINUE, EAP_MD5_SUCCESS, EAP_MD5_FAILURE
+	} state;
+	u8 * challenge;
+};
+
+int eap_md5_configure(char * configfile);
+int eap_md5_init(struct eap_state_machine *smd);
+int eap_md5_initPickUp(struct eap_state_machine *smd);
+int eap_md5_buildReq(struct eap_state_machine *smd, u8 eap_md5,
+		struct eap_packet * eapPacket);
+boolean eap_md5_check(struct eap_state_machine *smd, struct eap_packet eapRespData);
+int eap_md5_process(struct eap_state_machine *smd, struct eap_packet eapRespData);
+boolean eap_md5_isDone(struct eap_state_machine *smd);
+void eap_md5_free(void * data);
+
+REGISTER_METHOD("eap_md5", "eap_md5_configure", "eap_md5_init", "eap_md5_initPickUp", "eap_md5_buildReq", NULL, "eap_md5_check", "eap_md5_process", "eap_md5_isDone", NULL, NULL, "eap_md5_free")
+;
+
+int eap_md5_configure(char * configfile)
+{
+	gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+
+	return 0;
+}
+
+int eap_md5_init(struct eap_state_machine *smd)
+{
+	struct eap_md5_data *data = NULL;
+	CHECK_MALLOC(data = malloc(sizeof(struct eap_md5_data)));
+	memset(data, 0, sizeof(struct eap_md5_data));
+	data->state = EAP_MD5_CONTINUE;
+	data->challenge = NULL;
+	smd->methodData = (struct eap_md5_data*) data;
+	return 0;
+}
+
+
+int eap_md5_buildReq(struct eap_state_machine *smd, u8 id,
+		struct eap_packet * eapPacket)
+{
+	struct eap_md5_data * data;
+	u8 *payload, *challenge;
+
+	data = (struct eap_md5_data *) smd->methodData;
+	CHECK_MALLOC( challenge=malloc(sizeof(u8)*CHALLENGE_LEN));
+	CHECK_MALLOC( payload=malloc(sizeof(u8)*(CHALLENGE_LEN+1)));
+	memset(payload, 0, sizeof(u8) * (CHALLENGE_LEN + 1));
+
+	gcry_create_nonce(challenge,CHALLENGE_LEN);
+	U8COPY(payload, 1, CHALLENGE_LEN, challenge);
+	payload[0] = (u8) CHALLENGE_LEN;
+	CHECK_FCT(diameap_eap_new(EAP_REQUEST, id, TYPE_EAP_MD5, payload, CHALLENGE_LEN
+					+ 1,eapPacket));
+	CHECK_MALLOC(data->challenge=realloc(data->challenge,sizeof(u8)*CHALLENGE_LEN));
+	U8COPY(data->challenge,0,CHALLENGE_LEN,challenge);
+
+	smd->methodData = data;
+
+	free(challenge);
+	challenge=NULL;
+	free(payload);
+	payload=NULL;
+
+	return 0;
+}
+
+
+boolean eap_md5_check(struct eap_state_machine *smd, struct eap_packet eapRespData)
+{
+	eap_type type;
+	if(diameap_eap_get_type(eapRespData,&type)!=0){
+		return FALSE;
+	}
+	if (type == TYPE_EAP_MD5)
+	{
+		u16 length;
+		CHECK_FCT(diameap_eap_get_length(eapRespData,&length));
+		if ((int) length < 6)
+		{
+			TRACE_DEBUG(INFO,"%s[EAP MD5 plugin] Incorrect EAP packet received (length = %d ).",DIAMEAP_EXTENSION,length);
+			return FALSE;
+		}
+		return TRUE;
+	}
+	return FALSE;
+}
+
+
+
+int eap_md5_process(struct eap_state_machine *smd, struct eap_packet eapRespData)
+{
+
+	struct eap_md5_data * data;
+	int wordlen = 0, i = 0;
+	u8 * word, *hash, id;
+	data = (struct eap_md5_data*) smd->methodData;
+	wordlen = 1 + smd->user.passwordLength + CHALLENGE_LEN;
+	CHECK_MALLOC(word = malloc(sizeof(u8)*wordlen));
+	memset(word, 0, sizeof(u8) * wordlen);
+	CHECK_FCT(diameap_eap_get_identifier(eapRespData,&id));
+	*word = id;
+	U8COPY(word,1,smd->user.passwordLength,smd->user.password);
+	U8COPY(word,1+smd->user.passwordLength,CHALLENGE_LEN,data->challenge);
+	CHECK_MALLOC(hash = malloc(sizeof(u8)*16));
+
+	md5hash(word, wordlen, hash);
+
+
+	for (i = 0; i < CHALLENGE_LEN; i++)
+	{
+		if (G8(hash + i) != G8(eapRespData.data + 6 + i))
+		{
+			data->state = EAP_MD5_FAILURE;
+		}
+	}
+
+	if (data->state != EAP_MD5_FAILURE)
+	{
+		data->state = EAP_MD5_SUCCESS;
+		smd->user.success = TRUE;
+	}
+
+	smd->methodData = data;
+	free(hash);
+	hash=NULL;
+	free(word);
+	word=NULL;
+	return 0;
+}
+
+boolean eap_md5_isDone(struct eap_state_machine *smd)
+{
+	struct eap_md5_data *data;
+	data = (struct eap_md5_data*) smd->methodData;
+	if (data->state != EAP_MD5_CONTINUE)
+	{
+		return TRUE;
+	}
+	return FALSE;
+}
+
+
+void eap_md5_free(void * mdata)
+{
+	struct eap_md5_data *data;
+	data = (struct eap_md5_data*) mdata;
+	free(data->challenge);
+	data->challenge=NULL;
+	free(data);
+	data=NULL;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/plugins/eap_tls/CMakeLists.txt	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,16 @@
+# The EAP-TLS Plugin
+PROJECT("EAP-TLS Plugin" C)
+
+# Parser for the configuration file 
+BISON_FILE(eaptls.y)
+FLEX_FILE(eaptls.l)
+
+SET_SOURCE_FILES_PROPERTIES(lex.eaptls.c eaptls.tab.c PROPERTIES COMPILE_FLAGS "-I \"${CMAKE_CURRENT_SOURCE_DIR}\"")
+
+EAP_ADD_METHOD(eap_tls
+    eap_tls.c
+    eap_tls.h    
+    lex.eaptls.c
+    eaptls.tab.c
+    eaptls.tab.h
+    )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/plugins/eap_tls/eap_tls.c	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,368 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+
+#include "eap_tls.h"
+
+int eap_tls_configure(char * configfile);
+int eap_tls_init(struct eap_state_machine *smd);
+int eap_tls_initPickUp(struct eap_state_machine *smd);
+int eap_tls_buildReq(struct eap_state_machine *smd, u8 eap_md5,
+		struct eap_packet * eapPacket);
+int eap_tls_getTimeout(struct eap_state_machine *smd, int * timeout);
+boolean eap_tls_check(struct eap_state_machine *smd,
+		struct eap_packet eapRespData);
+int eap_tls_process(struct eap_state_machine *smd,
+		struct eap_packet eapRespData);
+boolean eap_tls_isDone(struct eap_state_machine *smd);
+int eap_tls_getKey(struct eap_state_machine *smd, u8** key, int * keylen);
+void eap_tls_unregister(void);
+void eap_tls_free(void * data);
+
+REGISTER_METHOD("eap_tls", "eap_tls_configure", "eap_tls_init", "eap_tls_initPickUp", "eap_tls_buildReq", "eap_tls_getTimeout", "eap_tls_check", "eap_tls_process", "eap_tls_isDone", "eap_tls_getKey", "eap_tls_unregister", "eap_tls_free")
+;
+
+int eap_tls_configure(char * configfile)
+{
+	int ret;
+	extern FILE * eaptlsin;
+
+	if (configfile)
+	{
+		tls_global_conf.conffile = configfile;
+	}
+	tls_global_conf.certfile = NULL;
+	tls_global_conf.keyfile = NULL;
+	tls_global_conf.cafile = NULL;
+	tls_global_conf.crlfile = NULL;
+
+	/*Parse EAP TLS configuration file */
+	eaptlsin = fopen(tls_global_conf.conffile, "r");
+	if (!eaptlsin)
+	{
+		TRACE_DEBUG(INFO,"%s[EAP TLS plugin] Unable to open configuration file %s for reading: %s",DIAMEAP_EXTENSION, tls_global_conf.conffile, strerror(errno));
+		return errno;
+	}
+
+	/* call yacc parser */
+	CHECK_FCT(eaptlsparse(&tls_global_conf));
+
+
+	tls_global_conf.max_size = 1013;
+
+	/* Initializing GnuTLS library */
+	ret = diameap_tls_init(&tls_global_conf);
+
+	return ret;
+}
+
+int eap_tls_init(struct eap_state_machine *smd)
+{
+	int ret;
+	struct tls_data *data = NULL;
+	CHECK_MALLOC(data = malloc(sizeof(struct tls_data)));
+	memset(data, 0, sizeof(struct tls_data));
+	CHECK_FCT(diameap_tls_initialize(data));
+	ret = diameap_tls_init_session(&tls_global_conf, data);
+
+	smd->methodData = (struct tls_data*) data;
+	if (ret < 0)
+	{
+		return ret;
+	}
+	return 0;
+}
+
+int eap_tls_initPickUp(struct eap_state_machine *smd)
+{
+	return 0;
+}
+
+int eap_tls_buildReq(struct eap_state_machine *smd, u8 id,
+		struct eap_packet * eapPacket)
+{
+	struct tls_data * data;
+	data = (struct tls_data *) smd->methodData;
+
+	if (data->more_toreceive == TRUE)
+	{
+		CHECK_FCT(diameap_eap_tls_buildReq_ack(id,eapPacket));
+		return 0;
+	}
+
+	if (data->state == START)
+	{
+		CHECK_FCT(diameap_eap_tls_buildReq_start(id,eapPacket));
+		return 0;
+	}
+
+	if (data->state == CONTINUE)
+	{
+		diameap_eap_tls_buildReq_data(data, id, eapPacket);
+
+		smd->methodData = (struct tls_data*) data;
+		return 0;
+	}
+
+	return 0;
+}
+
+int eap_tls_getTimeout(struct eap_state_machine *smd, int * timeout)
+{
+	return 0;
+}
+
+boolean eap_tls_check(struct eap_state_machine *smd,
+		struct eap_packet eapRespData)
+{
+	eap_type type;
+	if(diameap_eap_get_type(eapRespData,&type)!=0){
+		goto cf;
+	}
+	if (type == TYPE_EAP_TLS)
+	{
+		return TRUE;
+	}
+cf:
+	TRACE_DEBUG(INFO,"%s[EAP TLS plugin] EAP-TLS check failed: Received EAP packet with different EAP-Type (Type = %d)",DIAMEAP_EXTENSION, type);
+	return FALSE;
+}
+
+int eap_tls_process(struct eap_state_machine *smd,
+		struct eap_packet eapRespData)
+{
+	struct tls_data * data;
+	data = (struct tls_data *) smd->methodData;
+	struct tls_msg tlsmsg;
+	CHECK_FCT(diameap_eap_tls_parse(&tlsmsg,eapRespData));
+
+	if ((tlsmsg.datalength == 0))
+	{
+		if (data->more_tosend_length > 0)
+		{
+			//ACK and more to send
+			return 0;
+		}
+		else
+		{
+			//Success
+			if (data->handshake == TRUE)
+			{
+				data->state = SUCCESS;
+				smd->user.success = TRUE;
+				smd->methodData = (struct tls_data*) data;
+				return 0;
+			}
+
+			return 0;
+		}
+
+	}
+
+	if (data->more_toreceive == TRUE)
+	{
+		//reassemble received fragment to TLS Response
+		CHECK_FCT(diameap_tls_reassemble(&data->tlsResp,tlsmsg));
+	}
+	else
+	{
+		//receive the first fragment or a complete TLS message
+		CHECK_FCT(diameap_tls_copy(&data->tlsResp,tlsmsg));
+	}
+
+	if (tlsmsg.flags & TLS_FLAG_MORE)
+	{
+		data->more_toreceive = TRUE;
+		smd->methodData = (struct tls_data*) data;
+		return 0;
+	}
+	else
+	{
+		//last fragment received
+		data->more_toreceive = FALSE;
+	}
+	data->state = CONTINUE;
+	diameap_tls_process_receive(data);
+
+	if (data->state == SUCCESS)
+	{
+		smd->user.success = TRUE;
+	}
+	smd->methodData = (struct tls_data*) data;
+	return 0;
+}
+
+boolean eap_tls_isDone(struct eap_state_machine *smd)
+{
+	struct tls_data * data;
+	data = (struct tls_data *) smd->methodData;
+	if (data->state == CONTINUE || data->state == START)
+	{
+		return FALSE;
+	}
+	return TRUE;
+}
+
+int eap_tls_getKey(struct eap_state_machine *smd, u8 ** key, int *keylen)
+{
+	struct tls_data * data;
+	data = (struct tls_data *) smd->methodData;
+	*key = malloc(64);
+	if (gnutls_prf(data->session, strlen("client EAP encryption"),
+			"client EAP encryption", 0, 0, NULL, 64, (char *) *key)
+			!= GNUTLS_E_SUCCESS)
+	{
+		free(*key);
+		*key = NULL;
+		*keylen = 0;
+		return 1;
+	}
+	else
+	{
+		*keylen = 64;
+	}
+
+	return 0;
+}
+
+void eap_tls_unregister(void)
+{
+	//
+}
+
+void eap_tls_free(void * mdata)
+{
+	struct tls_data *data;
+	data = (struct tls_data*) mdata;
+	gnutls_deinit(data->session);
+	if(data->tlsReq.data){
+		free(data->tlsReq.data);
+		data->tlsReq.data=NULL;
+	}
+	if(data->tlsResp.data){
+		free(data->tlsResp.data);
+		data->tlsResp.data=NULL;
+	}
+	free(data);
+	data=NULL;
+}
+
+//send TLS ACK Request (empty TLS msg)
+int diameap_eap_tls_buildReq_ack(u8 id, struct eap_packet * eapPacket)
+{
+	u8* payload;
+	struct tls_msg tlsmsg;
+	int len;
+	CHECK_FCT(diameap_tls_new(&tlsmsg));
+	CHECK_FCT(diameap_tls_new_tls_packet(&payload,&len,tlsmsg));
+	CHECK_FCT(diameap_eap_new(EAP_REQUEST,id,TYPE_EAP_TLS,payload,len,eapPacket));
+	return 0;
+}
+
+// parse EAP TLS msg
+int diameap_eap_tls_parse(struct tls_msg * tlsmsg, struct eap_packet eapPacket)
+{
+	u8 *datatls;
+	int len;
+
+	//initialize a new empty EAP TLS msg
+	diameap_tls_new(tlsmsg);
+	//retrieve the data field from EAP Packet
+	diameap_eap_get_data(eapPacket, &datatls, &len);
+	//parse EAP TLS msg
+	diameap_tls_parse(datatls, len, tlsmsg);
+	return 0;
+}
+
+int diameap_eap_tls_buildReq_start(u8 id, struct eap_packet * eapPacket)
+{
+	u8* payload;
+	struct tls_msg tlsmsg;
+	int len;
+	CHECK_FCT(diameap_tls_new(&tlsmsg));
+	CHECK_FCT(diameap_tls_set_flags(&tlsmsg,TLS_FLAG_START));
+	CHECK_FCT(diameap_tls_new_tls_packet(&payload,&len,tlsmsg));
+	CHECK_FCT(diameap_eap_new(EAP_REQUEST,id,TYPE_EAP_TLS,payload,len,eapPacket));
+	return 0;
+}
+
+int diameap_eap_tls_buildReq_data(struct tls_data * data, int id,
+		struct eap_packet * eapPacket)
+{
+	struct tls_msg tlsmsg;
+	u8* datatosend;
+	u8 * eaptls_data;
+	int length = 0;
+
+	diameap_tls_new(&tlsmsg);
+
+	if (data->more_tosend_length == 0)
+	{
+		//First fragment of message or the only fragment of message
+		data->more_tosend_length = data->tlsReq.datalength;
+	}
+	if (data->more_tosend_length > tls_global_conf.max_size)
+	{
+		//New fragment of message. Is not the last fragment.
+		length = tls_global_conf.max_size;
+		CHECK_FCT(diameap_tls_set_flags(&tlsmsg,TLS_FLAG_MORE));
+		if (data->more_tosend_length == data->tlsReq.datalength)
+		{
+			//The first fragment of message
+			CHECK_FCT(diameap_tls_set_message_length(&tlsmsg,data->tlsReq.datalength));//set L flag and length value
+		}
+	}
+	else
+	{
+		//The last fragment or the only fragment.
+		length = data->more_tosend_length;
+	}
+
+	datatosend = malloc(sizeof(u8) * length);
+	U8COPY(datatosend,0,length,data->tlsReq.data+(data->tlsReq.datalength-data->more_tosend_length));
+	data->more_tosend_length -= length;
+	CHECK_FCT(diameap_tls_set_data(&tlsmsg,datatosend,length));
+
+	CHECK_FCT(diameap_tls_new_tls_packet(&eaptls_data,&length,tlsmsg));
+	CHECK_FCT(diameap_eap_new(EAP_REQUEST,id,TYPE_EAP_TLS,eaptls_data,length,eapPacket));
+
+	if (data->more_tosend_length == 0)
+	{
+		diameap_tls_new(&data->tlsReq);
+	}
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/plugins/eap_tls/eap_tls.h	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,50 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+#ifndef EAP_TLS_H_
+#define EAP_TLS_H_
+
+#include "../../plugins.h"
+
+struct tls_config	tls_global_conf;
+
+int diameap_eap_tls_buildReq_ack(u8 id, struct eap_packet * eapPacket);
+int diameap_eap_tls_buildReq_start(u8 id, struct eap_packet * eapPacket);
+int diameap_eap_tls_buildReq_data(struct tls_data * data,int id,struct eap_packet * eapPacket);
+int diameap_eap_tls_parse(struct tls_msg * eaptls,struct eap_packet eapPacket);
+
+#endif /* EAP_TLS_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/plugins/eap_tls/eaptls.l	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,112 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+
+/*Declarations and option settings*/
+%{
+#include <stdio.h>
+#include "eaptls.tab.h"
+
+#define YY_USER_ACTION { 						\
+	yylloc->first_line = yylloc->last_line = yylineno; \
+	yylloc->first_column = yylloc->last_column + 1; 		\
+	yylloc->last_column += yyleng +1;	\
+	}	 
+%}
+
+%option noyywrap
+%option yylineno
+%option bison-bridge 
+%option bison-locations
+
+%%
+	/* List of patterns and actions */
+
+<*>\n			{				
+				yylloc->last_column=0; 
+			}
+
+
+<*>#.*$			{}
+
+
+[ \t\n]+		{
+				yylloc->last_column=0; 
+			}
+
+\"([^\n\"]*)\"	{ 	/* Quoted String */
+					yylval->str = strdup(yytext+1); 
+					yylval->str[yyleng-2]='\0';
+					return iSTRING;
+				}
+
+
+[[:digit:]]+	{ 	/* Digital number */
+					yylval->val = atoi(yytext);
+					return NUM; /* Numeric value */ 
+				}
+
+(?i:"Cred")	{
+				return CERTS;
+			}
+
+(?i:"CA")		{ 
+				return CAPATH;
+			}
+
+(?i:"CRL")		{ 
+				return CRLPATH;
+			}
+
+
+
+"="|";"|":"|","		{	/* Single characters for yyparse */ 
+				return yytext[0]; 
+			}
+
+	/* Unrecognized token or text */
+	
+<*>[[:alnum:]]+	 |					 
+<*>.	{ 
+				fprintf(stderr,"Unrecognized input text '%s'( on line %i column %i )\n", yytext, yylloc->first_line, yylloc->first_column); 
+			 	return LEX_ERROR; 
+			}
+
+%%
+/* Routines */
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_diameap/plugins/eap_tls/eaptls.y	Mon Jul 26 18:00:24 2010 +0900
@@ -0,0 +1,229 @@
+/*****************************************************************************************************
+ * Software License Agreement (BSD License)
+ * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
+ *
+ * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University and the WIDE Project
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
+ *
+ * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *****************************************************************************************************/
+
+%{
+#include <stdio.h>
+#include "eap_tls.h"
+#include "eaptls.tab.h"
+
+void yyerror (YYLTYPE *llocp, struct tls_config * config, const char *s);
+
+extern int yywrap();
+extern int yylex();
+
+
+/* The Lex parser prototype */
+int eaptlslex(YYSTYPE *lvalp, YYLTYPE *llocp);
+
+
+%}
+
+%locations
+%parse-param {struct tls_config * config} 
+%pure_parser
+/*%defines */
+%error-verbose
+%debug 
+
+%union {
+	char *str;
+	int val;
+	char byte;
+}
+
+
+
+/* In case of error in the lexical analysis */
+%token 		LEX_ERROR
+
+%token 	<val>	NUM
+
+%token 	<str>	iSTRING
+
+%token  <byte>	iBYTE
+
+%token 		CERTS
+%token 		CAPATH
+%token 		CRLPATH
+
+%%	
+
+confparams : 	/* empty */
+		| confparams CERTS_files
+		| confparams CA_file
+		| confparams CRL_file
+		| confparams errors
+		{
+			return EINVAL;
+		}
+		;
+
+errors :	LEX_ERROR
+		| error
+		;
+
+
+CERTS_files :	CERTS '=' iSTRING ':' iSTRING ';'
+		{
+		char * certfile, *keyfile;
+		FILE * fl;
+
+		certfile = $3;
+		keyfile = $5;
+		if(certfile == NULL){
+			TRACE_DEBUG(INFO,"%s[EAP TLS plugin] certificate file missing in configuration file",DIAMEAP_EXTENSION);
+			yyerror (&yylloc, config, "cert file missing"); 
+			YYERROR;
+		}
+		if(keyfile == NULL){
+			TRACE_DEBUG(INFO,"%s[EAP TLS plugin] privateKey file missing in configuration file",DIAMEAP_EXTENSION);
+			yyerror (&yylloc, config, "privateKey file missing"); 
+			YYERROR;
+		}
+		
+		fl = fopen(certfile, "r");
+		if ((fl == NULL) && (*certfile != '/')) {
+			char * tmpfile=certfile;
+			CHECK_MALLOC_DO( certfile = malloc( strlen(tmpfile) + strlen(DEFAULT_EXTENSIONS_PATH) + 2 ),
+				{ yyerror (&yylloc, config, "Not enough memory"); YYERROR; } );
+			sprintf(certfile, DEFAULT_EXTENSIONS_PATH "/%s", tmpfile);
+			free(tmpfile);
+			fl = fopen(certfile, "r");
+		}
+		if (fl == NULL) {
+			int ret = errno;
+			TRACE_DEBUG(INFO,"%s[EAP TLS plugin] Unable to open certificate file %s for reading",DIAMEAP_EXTENSION,certfile);
+			yyerror (&yylloc, config, "Error configuring certificate for EAP-TLS"); 
+			YYERROR;
+		}
+		fclose(fl);
+		
+		fl = fopen(keyfile, "r");
+		if ((fl == NULL) && (*keyfile != '/')) {
+			char * tmpfile=keyfile;
+			CHECK_MALLOC_DO( keyfile = malloc( strlen(tmpfile) + strlen(DEFAULT_EXTENSIONS_PATH) + 2 ),
+				{ yyerror (&yylloc, config, "Not enough memory"); YYERROR; } );
+			sprintf(keyfile, DEFAULT_EXTENSIONS_PATH "/%s", tmpfile);
+			free(tmpfile);
+			fl = fopen(keyfile, "r");
+		}
+		if (fl == NULL) {
+			int ret = errno;
+			TRACE_DEBUG(INFO,"%s[EAP TLS plugin] Unable to open privateKey file %s for reading",DIAMEAP_EXTENSION,keyfile);
+			yyerror (&yylloc, config, "Error configuring privateKey for EAP-TLS"); 
+			YYERROR;
+		}
+		fclose(fl);
+		
+		config->certfile = certfile;
+		config->keyfile = keyfile;
+		}
+		;
+		
+CA_file :	CAPATH '=' iSTRING ';'
+		{
+		char * cafile;
+		FILE * fl;
+
+		cafile = $3;
+
+		if(cafile == NULL){
+			TRACE_DEBUG(INFO,"%s[EAP TLS plugin] CA file missing in configuration file",DIAMEAP_EXTENSION);
+			yyerror (&yylloc, config, "cert file missing"); 
+			YYERROR;
+		}
+		
+		fl = fopen(cafile, "r");
+		if ((fl == NULL) && (*cafile != '/')) {
+			char * tmpfile=cafile;
+			CHECK_MALLOC_DO( cafile = malloc( strlen(tmpfile) + strlen(DEFAULT_EXTENSIONS_PATH) + 2 ),
+				{ yyerror (&yylloc, config, "Not enough memory"); YYERROR; } );
+			sprintf(cafile, DEFAULT_EXTENSIONS_PATH "/%s", tmpfile);
+			free(tmpfile);
+			fl = fopen(cafile, "r");
+		}
+		if (fl == NULL) {
+			int ret = errno;
+			TRACE_DEBUG(INFO,"%s[EAP TLS plugin] Unable to open CA file %s for reading",DIAMEAP_EXTENSION,cafile);
+			yyerror (&yylloc, config, "Error configuring CA file for EAP-TLS"); 
+			YYERROR;
+		}
+		fclose(fl);
+			config->cafile=$3;
+		}
+		;
+
+CRL_file :	CRLPATH '=' iSTRING ';'
+		{
+		char * crlfile;
+		FILE * fl;
+
+		crlfile = $3;
+
+		if(crlfile == NULL){
+			TRACE_DEBUG(FULL+1,"%s[EAP TLS plugin] CRL file missing in configuration file",DIAMEAP_EXTENSION);
+
+		}else{
+		
+			fl = fopen(crlfile, "r");
+			if ((fl == NULL) && (*crlfile != '/')) {
+				char * tmpfile=crlfile;
+				CHECK_MALLOC_DO( crlfile = malloc( strlen(tmpfile) + strlen(DEFAULT_EXTENSIONS_PATH) + 2 ),
+					{ yyerror (&yylloc, config, "Not enough memory"); YYERROR; } );
+				sprintf(crlfile, DEFAULT_EXTENSIONS_PATH "/%s", tmpfile);
+				free(tmpfile);
+				fl = fopen(crlfile, "r");
+			}
+			if (fl == NULL) {
+				int ret = errno;
+				TRACE_DEBUG(INFO,"%s[EAP TLS plugin] Unable to open CRL file %s for reading",DIAMEAP_EXTENSION,crlfile);
+				yyerror (&yylloc, config, "Error configuring CRL file for EAP-TLS"); 
+				YYERROR;
+			}
+			fclose(fl);	
+		}
+			config->crlfile=$3;
+		}
+		;
+			
+		
+%%
+
+void yyerror(YYLTYPE *llocp, struct tls_config * config,const char *str)
+{
+         fprintf(stderr,"Error in %s ( on line %i column %i -> line %i column %i) : %s\n",config->conffile, llocp->first_line, llocp->first_column, llocp->last_line, llocp->last_column, str);
+}
"Welcome to our mercurial repository"